summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/ca/shared/conf/CS.cfg3
-rw-r--r--base/common/src/com/netscape/certsrv/base/SessionContext.java7
-rw-r--r--base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java220
-rw-r--r--base/server/cms/src/com/netscape/cms/profile/constraint/UniqueKeyConstraint.java8
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/base/CMSServlet.java10
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java7
-rw-r--r--base/server/cmsbundle/src/LogMessages.properties4
7 files changed, 175 insertions, 84 deletions
diff --git a/base/ca/shared/conf/CS.cfg b/base/ca/shared/conf/CS.cfg
index d1bf7db0b..4da7429b3 100644
--- a/base/ca/shared/conf/CS.cfg
+++ b/base/ca/shared/conf/CS.cfg
@@ -734,11 +734,10 @@ ca.publish.rule.instance.LdapXCertRule.pluginName=Rule
ca.publish.rule.instance.LdapXCertRule.predicate=
ca.publish.rule.instance.LdapXCertRule.publisher=LdapCrossCertPairPublisher
ca.publish.rule.instance.LdapXCertRule.type=xcert
-cmc.cert.confirmRequired=false
cmc.popLinkWitnessRequired=false
-cmc.revokeCert.verify=true
cmc.revokeCert.sharedSecret.class=com.netscape.cms.authentication.SharedSecret
cmc.sharedSecret.class=com.netscape.cms.authentication.SharedSecret
+cmc.token=internal
cms.passwordlist=internaldb,replicationdb
cms.password.ignore.publishing.failure=true
cms.version=@APPLICATION_VERSION_MAJOR@.@APPLICATION_VERSION_MINOR@
diff --git a/base/common/src/com/netscape/certsrv/base/SessionContext.java b/base/common/src/com/netscape/certsrv/base/SessionContext.java
index 8bcb3c11e..9323e6e33 100644
--- a/base/common/src/com/netscape/certsrv/base/SessionContext.java
+++ b/base/common/src/com/netscape/certsrv/base/SessionContext.java
@@ -56,6 +56,13 @@ public class SessionContext extends Hashtable<Object, Object> {
* Principal name object of the signed CMC request
*/
public static final String CMC_SIGNER_PRINCIPAL = "cmcSignerPrincipal";
+ public static final String CMC_SIGNER_INFO = "cmcSignerInfo";
+ public static final String CMC_REQUEST_CERT_SUBJECT = "cmcRequestCertSubject";
+
+ /**
+ * authenticated SSL client certificate
+ */
+ public static final String SSL_CLIENT_CERT = "sslClientCert";
/**
* User object of the authenticated user in the current thread.
diff --git a/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java b/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java
index 2e4d6dccc..6c3ee8f93 100644
--- a/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java
+++ b/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java
@@ -28,6 +28,7 @@ package com.netscape.cms.authentication;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.security.cert.X509Certificate;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.PublicKey;
@@ -260,11 +261,27 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
CMS.debug(method + "begins");
String auditMessage = null;
- String auditSubjectID = auditSubjectID();
+ String auditSubjectID = getAuditSubjectID();
String auditReqType = ILogger.UNIDENTIFIED;
- String auditCertSubject = ILogger.UNIDENTIFIED;
+ String requestCertSubject = ILogger.UNIDENTIFIED;
String auditSignerInfo = ILogger.UNIDENTIFIED;
+ SessionContext auditContext = SessionContext.getExistingContext();
+
+ // create audit context if clientCert exists
+ X509Certificate clientCert =
+ (X509Certificate) auditContext.get(SessionContext.SSL_CLIENT_CERT);
+ // null is okay, as it is not required in case of self-sign;
+ // will be checked later
+ if (clientCert != null) {
+ try {
+ createAuditSubjectFromCert(auditContext, clientCert);
+ } catch (IOException e) {
+ //unlikely, and not necessarily required at this point
+ CMS.debug("CMSUserSignedAuth: authenticate: after createAuditSubjectFromCert call; " + e);
+ }
+ }
+
// ensure that any low-level exceptions are reported
// to the signed audit log and stored as failures
try {
@@ -296,8 +313,6 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
throw new EInvalidCredentials(msg);
}
- SessionContext auditContext = SessionContext.getExistingContext();
-
// authenticate by checking CMC.
// everything OK.
@@ -364,13 +379,13 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
}
// reset value of auditSignerInfo
if (uid != null && !uid.equals(ILogger.UNIDENTIFIED)) {
- CMS.debug(method + "setting auditSignerInfo to uid:" + uid.trim());
- auditSignerInfo = uid.trim();
+ //CMS.debug(method + "setting auditSignerInfo to uid:" + uid.trim());
+ //auditSignerInfo = uid.trim();
auditSubjectID = uid.trim();
authToken.set(IAuthToken.USER_ID, auditSubjectID);
} else if (userid != null && !userid.equals(ILogger.UNIDENTIFIED)) {
- CMS.debug(method + "setting auditSignerInfo to userid:" + userid);
- auditSignerInfo = userid.trim();
+ //CMS.debug(method + "setting auditSignerInfo to userid:" + userid);
+ //auditSignerInfo = userid.trim();
auditSubjectID = userid.trim();
authToken.set(IAuthToken.USER_ID, auditSubjectID);
}
@@ -538,16 +553,17 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
}
PKCS10 pkcs10 = new PKCS10(ostream.toByteArray(), sigver);
- // reset value of auditCertSubject
+ // reset value of requestCertSubject
X500Name tempName = pkcs10.getSubjectName();
CMS.debug(method + "request subject name=" + tempName.toString());
if (tempName != null) {
- auditCertSubject = tempName.toString().trim();
- if (auditCertSubject.equals("")) {
- auditCertSubject = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ requestCertSubject = tempName.toString().trim();
+ if (requestCertSubject.equals("")) {
+ requestCertSubject = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
}
authToken.set(AuthToken.TOKEN_CERT_SUBJECT,
- auditCertSubject/*tempName.toString()*/);
+ requestCertSubject/*tempName.toString()*/);
+ auditContext.put(SessionContext.CMC_REQUEST_CERT_SUBJECT, requestCertSubject);
}
if (selfSigned) {
@@ -632,17 +648,18 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
// xxx do we need to do anything else?
X509CertInfo certInfo = CMS.getDefaultX509CertInfo();
- // reset value of auditCertSubject
+ // reset value of requestCertSubject
if (name != null) {
String ss = name.getRFC1485();
- CMS.debug(method + "setting auditCertSubject to: " + ss);
- auditCertSubject = ss;
- if (auditCertSubject.equals("")) {
- auditCertSubject = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ CMS.debug(method + "setting requestCertSubject to: " + ss);
+ requestCertSubject = ss;
+ if (requestCertSubject.equals("")) {
+ requestCertSubject = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
}
authToken.set(AuthToken.TOKEN_CERT_SUBJECT, ss);
+ auditContext.put(SessionContext.CMC_REQUEST_CERT_SUBJECT, requestCertSubject);
//authToken.set("uid", uid);
//authToken.set("userid", userid);
}
@@ -696,10 +713,15 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
authToken.set("uid", uid);
authToken.set("userid", userid);
+ } catch (EMissingCredential e) {
+ throw e;
+ } catch (EInvalidCredentials e) {
+ throw e;
} catch (Exception e) {
- CMS.debug(method + e);
+ //CMS.debug(method + e);
//Debug.printStackTrace(e);
- throw new EInvalidCredentials(e.toString());
+ //throw new EInvalidCredentials(e.toString());
+ throw e;
}
// For accuracy, make sure revocation by shared secret doesn't
@@ -709,11 +731,11 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
// store a message in the signed audit log file
auditMessage = CMS.getLogMessage(
AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS,
- auditSubjectID,
+ getAuditSubjectID(),
ILogger.SUCCESS,
auditReqType,
- auditCertSubject,
- auditSignerInfo);
+ getRequestCertSubject(auditContext),
+ getAuditSignerInfo(auditContext));
audit(auditMessage);
} else {
@@ -725,17 +747,6 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
return authToken;
} catch (EMissingCredential eAudit1) {
CMS.debug(method + eAudit1);
- // store a message in the signed audit log file
- auditMessage = CMS.getLogMessage(
- AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE,
- auditSubjectID,
- ILogger.FAILURE,
- auditReqType,
- auditCertSubject,
- auditSignerInfo,
- eAudit1.toString());
-
- audit(auditMessage);
// rethrow the specific exception to be handled later
throw eAudit1;
@@ -744,11 +755,11 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
// store a message in the signed audit log file
auditMessage = CMS.getLogMessage(
AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE,
- auditSubjectID,
+ getAuditSubjectID(),
ILogger.FAILURE,
auditReqType,
- auditCertSubject,
- auditSignerInfo,
+ getRequestCertSubject(auditContext),
+ getAuditSignerInfo(auditContext),
eAudit2.toString());
audit(auditMessage);
@@ -760,11 +771,11 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
// store a message in the signed audit log file
auditMessage = CMS.getLogMessage(
AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE,
- auditSubjectID,
+ getAuditSubjectID(),
ILogger.FAILURE,
auditReqType,
- auditCertSubject,
- auditSignerInfo,
+ getRequestCertSubject(auditContext),
+ getAuditSignerInfo(auditContext),
eAudit3.toString());
audit(auditMessage);
@@ -776,17 +787,17 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
// store a message in the signed audit log file
auditMessage = CMS.getLogMessage(
AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE,
- auditSubjectID,
+ getAuditSubjectID(),
ILogger.FAILURE,
auditReqType,
- auditCertSubject,
- auditSignerInfo,
+ getRequestCertSubject(auditContext),
+ getAuditSignerInfo(auditContext),
eAudit4.toString());
audit(auditMessage);
- // rethrow the specific exception to be handled later
- throw eAudit4;
+ // rethrow the exception to be handled later
+ throw new EBaseException(eAudit4);
}
}
@@ -935,8 +946,9 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
SessionContext auditContext, // to capture info in case of failure
AuthToken authToken,
SignedData cmcFullReq)
- throws EBaseException {
+ throws EBaseException, EInvalidCredentials, EMissingCredential {
String method = "CMCUserSignedAuth: verifySignerInfo: ";
+ String msg = "";
CMS.debug(method + "begins");
EncapsulatedContentInfo ci = cmcFullReq.getContentInfo();
OBJECT_IDENTIFIER id = ci.getContentType();
@@ -1001,7 +1013,7 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
if (cmcFullReq.hasCertificates()) {
SET certs = cmcFullReq.getCertificates();
int numCerts = certs.size();
- java.security.cert.X509Certificate[] x509Certs = new java.security.cert.X509Certificate[1];
+ X509Certificate[] x509Certs = new X509Certificate[1];
byte[] certByteArray = new byte[0];
for (int j = 0; j < numCerts; j++) {
Certificate certJss = (Certificate) certs.elementAt(j);
@@ -1029,25 +1041,44 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
}
CMS.debug(method + "start checking signature");
- String CN = null;
if (cert == null) {
// find from certDB
CMS.debug(method + "verifying signature");
si.verify(digest, id);
} else {
- CMS.debug(method + "found signing cert... verifying");
+ CMS.debug(method + "found CMC signing cert... verifying");
+
+ X509Certificate clientCert =
+ (X509Certificate) auditContext.get(SessionContext.SSL_CLIENT_CERT);
+ // user-signed case requires ssl client authentication
+ if (clientCert == null) {
+ createAuditSubjectFromCert(auditContext, x509Certs[0]);
+ msg = "missing SSL client authentication certificate;";
+ CMS.debug(method + msg);
+ s.close();
+ throw new EMissingCredential(
+ CMS.getUserMessage("CMS_AUTHENTICATION_NO_CERT"));
+ }
+ netscape.security.x509.X500Name clientPrincipal =
+ (X500Name) clientCert.getSubjectDN();
- // capture auditSubjectID first in case of failure
- netscape.security.x509.X500Name principal =
+ netscape.security.x509.X500Name cmcPrincipal =
(X500Name) x509Certs[0].getSubjectDN();
// capture signer principal to be checked against
// cert subject principal later in CMCOutputTemplate
// in case of user signed revocation
- auditContext.put(SessionContext.CMC_SIGNER_PRINCIPAL, principal);
- CN = principal.getCommonName(); //tempToken.get("userid");
- CMS.debug(method + " Principal name = " + CN);
- auditContext.put(SessionContext.USER_ID, CN);
+ auditContext.put(SessionContext.CMC_SIGNER_PRINCIPAL, cmcPrincipal);
+ auditContext.put(SessionContext.CMC_SIGNER_INFO, cmcPrincipal.getCommonName());
+
+ // check ssl client cert against cmc signer
+ if (!clientPrincipal.equals(cmcPrincipal)) {
+ msg = "SSL client authentication certificate and CMC signer do not match";
+ CMS.debug(method + msg);
+ s.close();
+ throw new EInvalidCredentials(
+ CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL") + ":" + msg);
+ }
PublicKey signKey = cert.getPublicKey();
PrivateKey.Type keyType = null;
@@ -1064,10 +1095,11 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
byte publicKeyData[] = ((X509Key) signKey).getEncoded();
pubK = PK11ECPublicKey.fromSPKI(/*keyType,*/ publicKeyData);
} else {
- CMS.debug(method + "unsupported signature algorithm: " + alg);
+ msg = "unsupported signature algorithm: " + alg;
+ CMS.debug(method + msg);
s.close();
throw new EInvalidCredentials(
- CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL") + ":" + msg);
}
String tokenName = CMS.getConfigStore().getString("ca.requestVerify.token",
@@ -1095,9 +1127,10 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
// ...or not; I think it just checks usage and
// validity, but not revocation status
if (!cm.isCertValid(certByteArray, true, CryptoManager.CertUsage.SSLClient)) {
- CMS.debug(method + "CMC signature failed to be verified");
+ msg = "CMC signing cert is invalid";
+ CMS.debug(method + msg);
s.close();
- throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL") + ":" + msg);
} else {
CMS.debug(method + "CMC signature verified; but signer not yet;");
}
@@ -1105,28 +1138,28 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
// now check revocation status of the cert
if (CMS.isRevoked(x509Certs)) {
- CMS.debug(method + "CMC signing cert is a revoked certificate");
+ msg = "CMC signing cert is a revoked certificate";
+ CMS.debug(method + msg);
s.close();
- throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL") + ":" + msg);
}
try { //do this again anyways
cert.checkValidity();
} catch (CertificateExpiredException e) {
- CMS.debug(method + "CMC signing cert is an expired certificate");
+ msg = "CMC signing cert is an expired certificate";
+ CMS.debug(method + msg);
s.close();
- throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL") + ":" + msg);
} catch (Exception e) {
CMS.debug(method + e.toString());
s.close();
- throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL") + ":" + e.toString());
}
IAuthToken tempToken = new AuthToken(null);
-/*
netscape.security.x509.X500Name tempPrincipal = (X500Name) x509Certs[0].getSubjectDN();
String CN = tempPrincipal.getCommonName(); //tempToken.get("userid");
CMS.debug(method + " Principal name = " + CN);
-*/
BigInteger certSerial = x509Certs[0].getSerialNumber();
CMS.debug(method + " verified cert serial=" + certSerial.toString());
@@ -1137,7 +1170,9 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
return tempToken;
} else {
- CMS.debug(method + "no certificate found in cmcFullReq");
+ msg = "no certificate found in cmcFullReq";
+ CMS.debug(method + msg);
+ throw new EMissingCredential(msg);
}
} else if (sid.getType().equals(SignerIdentifier.SUBJECT_KEY_IDENTIFIER)) {
CMS.debug(method + "SignerIdentifier type: SUBJECT_KEY_IDENTIFIER");
@@ -1150,19 +1185,20 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
s.close();
return tempToken;
} else {
- CMS.debug(method + "unsupported SignerIdentifier type");
+ msg = "unsupported SignerIdentifier type";
+ CMS.debug(method + msg);
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL") + ":" + msg);
}
} //for
+ } catch (EMissingCredential e) {
+ throw e;
+ } catch (EInvalidCredentials e) {
+ throw e;
} catch (InvalidBERException e) {
- CMS.debug(method + e.toString());
- } catch (IOException e) {
- CMS.debug(method + e.toString());
- } catch (NotInitializedException e) {
- CMS.debug(method + e.toString());
+ CMS.debug(method + e);
} catch (Exception e) {
- CMS.debug(method + e.toString());
- throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ CMS.debug(method + e);
} finally {
if ((tokenSwitched == true) && (savedToken != null)) {
cm.setThreadToken(savedToken);
@@ -1173,6 +1209,21 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
}
+ private void createAuditSubjectFromCert (
+ SessionContext auditContext,
+ X509Certificate cert)
+ throws IOException {
+ String method = "CMCUserSignedAuth:createAuditSubjectFromCert: ";
+
+ // capture auditSubjectID first in case of failure
+ netscape.security.x509.X500Name principal =
+ (X500Name) cert.getSubjectDN();
+
+ String CN = principal.getCommonName();
+ CMS.debug(method + " Principal name = " + CN);
+ auditContext.put(SessionContext.USER_ID, CN);
+ }
+
public String[] getExtendedPluginInfo(Locale locale) {
return null;
}
@@ -1274,7 +1325,7 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
*
* @return id string containing the signed audit log message SubjectID
*/
- private String auditSubjectID() {
+ private String getAuditSubjectID() {
// if no signed audit object exists, bail
if (mSignedAuditLogger == null) {
return null;
@@ -1299,4 +1350,21 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
return subjectID;
}
+
+ private String getAuditSignerInfo(SessionContext auditContext) {
+ String signerSubject = (String)auditContext.get(SessionContext.CMC_SIGNER_INFO);
+ if (signerSubject == null)
+ signerSubject = "$Unidentified$";
+
+ return signerSubject;
+ }
+
+ private String getRequestCertSubject(SessionContext auditContext) {
+ String certSubject = (String)auditContext.get(SessionContext.CMC_REQUEST_CERT_SUBJECT);
+ if (certSubject == null)
+ certSubject = "$Unidentified$";
+
+ return certSubject;
+ }
+
}
diff --git a/base/server/cms/src/com/netscape/cms/profile/constraint/UniqueKeyConstraint.java b/base/server/cms/src/com/netscape/cms/profile/constraint/UniqueKeyConstraint.java
index 33cc7a9c6..030995a72 100644
--- a/base/server/cms/src/com/netscape/cms/profile/constraint/UniqueKeyConstraint.java
+++ b/base/server/cms/src/com/netscape/cms/profile/constraint/UniqueKeyConstraint.java
@@ -219,12 +219,14 @@ public class UniqueKeyConstraint extends EnrollConstraint {
Date origNotAfter = null;
boolean first = true;
while (e != null && e.hasMoreElements()) {
+ CMS.debug(method + msg);
ICertRecord rec = e.nextElement();
BigInteger serial = rec.getSerialNumber();
+ msg = msg + "existing cert with same key found: " + serial.toString() + ";";
if (rec.getStatus().equals(ICertRecord.STATUS_REVOKED)
|| rec.getStatus().equals(ICertRecord.STATUS_REVOKED_EXPIRED)) {
- msg = msg + "revoked cert cannot be renewed: serial=" + serial.toString() + ";";
+ msg = msg + "revoked cert cannot be renewed;";
CMS.debug(method + msg);
rejected = true;
// this has to break
@@ -232,7 +234,7 @@ public class UniqueKeyConstraint extends EnrollConstraint {
}
if (!rec.getStatus().equals(ICertRecord.STATUS_VALID)
&& !rec.getStatus().equals(ICertRecord.STATUS_EXPIRED)) {
- CMS.debug(method + "invalid cert cannot be renewed; continue:" + serial.toString());
+ CMS.debug(method + "invalid cert cannot be renewed; continue;" + serial.toString());
// can still find another one to renew
continue;
}
@@ -297,7 +299,7 @@ public class UniqueKeyConstraint extends EnrollConstraint {
} // (size > 0)
if (rejected == true) {
- CMS.debug(method + " rejected");
+ CMS.debug(method + " rejected: " + msg);
throw new ERejectException(msg);
} else {
CMS.debug(method + " approved");
diff --git a/base/server/cms/src/com/netscape/cms/servlet/base/CMSServlet.java b/base/server/cms/src/com/netscape/cms/servlet/base/CMSServlet.java
index 9dc74701a..65dc06aa3 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/base/CMSServlet.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/base/CMSServlet.java
@@ -843,6 +843,10 @@ public abstract class CMSServlet extends HttpServlet {
* get ssl client authenticated certificate
*/
protected X509Certificate getSSLClientCertificate(HttpServletRequest httpReq) throws EBaseException {
+ return getSSLClientCertificate(httpReq, true);
+ }
+
+ protected X509Certificate getSSLClientCertificate(HttpServletRequest httpReq, boolean clientCertRequired) throws EBaseException {
X509Certificate cert = null;
@@ -855,7 +859,11 @@ public abstract class CMSServlet extends HttpServlet {
X509Certificate[] allCerts = (X509Certificate[]) httpReq.getAttribute(CERT_ATTR);
if (allCerts == null || allCerts.length == 0) {
- throw new EBaseException("You did not provide a valid certificate for this operation");
+ if (!clientCertRequired) {
+ return null;
+ } else {
+ throw new EBaseException("You did not provide a valid certificate for this operation");
+ }
}
cert = allCerts[0];
diff --git a/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java b/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java
index 330b5ff66..73195e916 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java
@@ -19,6 +19,7 @@ package com.netscape.cms.servlet.profile;
import java.io.InputStream;
import java.io.OutputStream;
+import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.Locale;
@@ -169,6 +170,12 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
String authMgrID = authenticator.getName();
SessionContext sc = SessionContext.getContext();
+ X509Certificate clientCert =
+ getSSLClientCertificate(request, false /*cert may not be required*/);
+ if (clientCert != null) {
+ sc.put(SessionContext.SSL_CLIENT_CERT, clientCert);
+ }
+
try {
authToken = authenticator.authenticate(credentials);
if (sc != null) {
diff --git a/base/server/cmsbundle/src/LogMessages.properties b/base/server/cmsbundle/src/LogMessages.properties
index 949009880..5e51440eb 100644
--- a/base/server/cmsbundle/src/LogMessages.properties
+++ b/base/server/cmsbundle/src/LogMessages.properties
@@ -2208,10 +2208,10 @@ LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY_5=<type=CMC_SIGNED_REQUEST_SI
# are submitted and signature is verified
# ReqType must be the request type (enrollment, or revocation)
# CertSubject must be the certificate subject name of the certificate request
-# SignerInfo must be a unique String representation for the signer
+# CMCSignerInfo must be a unique String representation for the CMC request signer
#
LOGGING_SIGNED_AUDIT_CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS_5=<type=CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS>:[AuditEvent=CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS][SubjectID={0}][Outcome={1}][ReqType={2}][CertSubject={3}][SignerInfo={4}] User signed CMC request signature verification success
-LOGGING_SIGNED_AUDIT_CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE_6=<type=CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE>:[AuditEvent=CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE][SubjectID={0}][Outcome={1}][ReqType={2}][CertSubject={3}][SignerInfo={4}][info={5}] User signed CMC request signature verification failure
+LOGGING_SIGNED_AUDIT_CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE_6=<type=CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE>:[AuditEvent=CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE][SubjectID={0}][Outcome={1}][ReqType={2}][CertSubject={3}][CMCSignerInfo={4}][info={5}] User signed CMC request signature verification failure
# LOGGING_SIGNED_AUDIT_COMPUTE_RANDOM_DATA_REQUEST
# - used for TPS to TKS to get random challenge data