summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristina Fu <cfu@redhat.com>2017-06-14 14:57:10 -0700
committerChristina Fu <cfu@redhat.com>2017-06-15 12:03:14 -0700
commit63c9582009b3858a6878863b9658d04c9aad45c1 (patch)
tree82210aa52c0e4ab00b8f9412767afeaf4010b6d8
parent1f9db90b4f490f615a67a0f2d26b378345c6ab6a (diff)
downloadpki-63c9582009b3858a6878863b9658d04c9aad45c1.tar.gz
pki-63c9582009b3858a6878863b9658d04c9aad45c1.tar.xz
pki-63c9582009b3858a6878863b9658d04c9aad45c1.zip
Ticket#2737 CMC: check HTTPS client authentication cert against CMC signer
This patch adds enforcement in CMCUserSignedAuth to make sure SSL client authentication is performed and the authenticated cert matches that of the CMC signing cert. Some auditing adjustments are also done.
-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