summaryrefslogtreecommitdiffstats
path: root/base/server/cms/src/com
diff options
context:
space:
mode:
Diffstat (limited to 'base/server/cms/src/com')
-rw-r--r--base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java1140
-rw-r--r--base/server/cms/src/com/netscape/cms/profile/common/BasicProfile.java28
-rw-r--r--base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java426
-rw-r--r--base/server/cms/src/com/netscape/cms/profile/constraint/CMCUserSignedSubjectNameConstraint.java141
-rw-r--r--base/server/cms/src/com/netscape/cms/profile/def/CMCUserSignedSubjectNameDefault.java159
-rw-r--r--base/server/cms/src/com/netscape/cms/profile/def/EnrollDefault.java5
-rw-r--r--base/server/cms/src/com/netscape/cms/profile/input/CMCCertReqInput.java21
-rw-r--r--base/server/cms/src/com/netscape/cms/profile/input/CertReqInput.java36
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java28
9 files changed, 1832 insertions, 152 deletions
diff --git a/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java b/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java
new file mode 100644
index 000000000..a72ce5863
--- /dev/null
+++ b/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java
@@ -0,0 +1,1140 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+// package statement //
+///////////////////////
+
+package com.netscape.cms.authentication;
+
+///////////////////////
+// import statements //
+///////////////////////
+
+/* cert server imports */
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.PublicKey;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.CryptoManager.NotInitializedException;
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.DigestAlgorithm;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.pkcs10.CertificationRequest;
+import org.mozilla.jss.pkcs11.PK11ECPublicKey;
+import org.mozilla.jss.pkcs11.PK11PubKey;
+import org.mozilla.jss.pkix.cert.Certificate;
+import org.mozilla.jss.pkix.cert.CertificateInfo;
+import org.mozilla.jss.pkix.cmc.PKIData;
+import org.mozilla.jss.pkix.cmc.TaggedAttribute;
+import org.mozilla.jss.pkix.cmc.TaggedCertificationRequest;
+import org.mozilla.jss.pkix.cmc.TaggedRequest;
+import org.mozilla.jss.pkix.cms.EncapsulatedContentInfo;
+import org.mozilla.jss.pkix.cms.IssuerAndSerialNumber;
+import org.mozilla.jss.pkix.cms.SignedData;
+import org.mozilla.jss.pkix.cms.SignerIdentifier;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.pkix.primitive.Name;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.EInvalidCredentials;
+import com.netscape.certsrv.authentication.EMissingCredential;
+import com.netscape.certsrv.authentication.IAuthCredentials;
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.logging.AuditEvent;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileAuthenticator;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+import com.netscape.cmsutil.util.Utils;
+
+import netscape.security.pkcs.PKCS10;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
+//import com.netscape.cmscore.util.*;
+//////////////////////
+// class definition //
+//////////////////////
+
+/**
+ * User Signed CMC authentication plug-in
+ * note:
+ * - this version differs from CMCAuth in that it allows non-agent users
+ * to sign own cmc requests; It is expected to be used with
+ * CMCUserSignedSubjectNameDefault and CMCUserSignedSubjectNameConstraint
+ * so that the resulting cert will bear the same subjectDN of that of the CMC
+ * signing cert
+ * - it originates from CMCAuth with modification for user-signed cmc
+ * @author cfu - user signed cmc authentication
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
+ IProfileAuthenticator {
+
+ ////////////////////////
+ // default parameters //
+ ////////////////////////
+
+ /////////////////////////////
+ // IAuthManager parameters //
+ /////////////////////////////
+
+ /* authentication plug-in configuration store */
+ private IConfigStore mConfig;
+ private static final String HEADER = "-----BEGIN NEW CERTIFICATE REQUEST-----";
+ private static final String TRAILER = "-----END NEW CERTIFICATE REQUEST-----";
+ public static final String TOKEN_CERT_SERIAL = "certSerialToRevoke";
+ public static final String REASON_CODE = "reasonCode";
+ /* authentication plug-in name */
+ private String mImplName = null;
+
+ /* authentication plug-in instance name */
+ private String mName = null;
+
+ /* authentication plug-in fields */
+
+ /* Holds authentication plug-in fields accepted by this implementation.
+ * This list is passed to the configuration console so configuration
+ * for instances of this implementation can be configured through the
+ * console.
+ */
+ protected static String[] mConfigParams =
+ new String[] {};
+
+ /* authentication plug-in values */
+
+ /* authentication plug-in properties */
+
+ /* required credentials to authenticate. UID and CMC are strings. */
+ public static final String CRED_CMC = "cmcRequest";
+
+ protected static String[] mRequiredCreds = {};
+
+ ////////////////////////////////////
+ // IExtendedPluginInfo parameters //
+ ////////////////////////////////////
+
+ /* Vector of extendedPluginInfo strings */
+ protected static Vector<String> mExtendedPluginInfo = null;
+ //public static final String AGENT_AUTHMGR_ID = "agentAuthMgr";
+ //public static final String AGENT_PLUGIN_ID = "agentAuthPlugin";
+
+ /* actual help messages */
+ static {
+ mExtendedPluginInfo = new Vector<String>();
+
+ mExtendedPluginInfo
+ .add(IExtendedPluginInfo.HELP_TEXT +
+ ";Authenticate the CMC request. The \"Authentication Instance ID\" must be named \"CMCUserSignedAuth\"");
+ mExtendedPluginInfo.add(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-authentication");
+ }
+
+ ///////////////////////
+ // Logger parameters //
+ ///////////////////////
+
+ /* the system's logger */
+ private ILogger mLogger = CMS.getLogger();
+
+ /* signed audit parameters */
+ private ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+ private final static String SIGNED_AUDIT_ENROLLMENT_REQUEST_TYPE =
+ "enrollment";
+ private final static String SIGNED_AUDIT_REVOCATION_REQUEST_TYPE =
+ "revocation";
+
+ /////////////////////
+ // default methods //
+ /////////////////////
+
+ /**
+ * Default constructor, initialization must follow.
+ */
+ public CMCUserSignedAuth() {
+ }
+
+ //////////////////////////
+ // IAuthManager methods //
+ //////////////////////////
+
+ /**
+ * Initializes the CMCUserSignedAuth authentication plug-in.
+ * <p>
+ *
+ * @param name The name for this authentication plug-in instance.
+ * @param implName The name of the authentication plug-in.
+ * @param config - The configuration store for this instance.
+ * @exception EBaseException If an error occurs during initialization.
+ */
+ public void init(String name, String implName, IConfigStore config)
+ throws EBaseException {
+ mName = name;
+ mImplName = implName;
+ mConfig = config;
+
+ log(ILogger.LL_INFO, "Initialization complete!");
+ }
+
+ /**
+ * Authenticates user by their CMC;
+ * resulting AuthToken sets a TOKEN_SUBJECT for the subject name.
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CMC_USER_SIGNED_REQUEST_SIG_VERIFY used when CMC (user-pre-signed) cert
+ * requests or revocation requests are submitted and signature is verified
+ * </ul>
+ *
+ * @param authCred Authentication credentials, CRED_UID and CRED_CMC.
+ * @return an AuthToken
+ * @exception com.netscape.certsrv.authentication.EMissingCredential
+ * If a required authentication credential is missing.
+ * @exception com.netscape.certsrv.authentication.EInvalidCredentials
+ * If credentials failed authentication.
+ * @exception com.netscape.certsrv.base.EBaseException
+ * If an internal error occurred.
+ * @see com.netscape.certsrv.authentication.AuthToken
+ */
+ public IAuthToken authenticate(IAuthCredentials authCred) throws EMissingCredential, EInvalidCredentials,
+ EBaseException {
+ String method = "CMCUserSignedAuth: authenticate: ";
+ CMS.debug(method + "begins");
+
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditReqType = ILogger.UNIDENTIFIED;
+ String auditCertSubject = ILogger.UNIDENTIFIED;
+ String auditSignerInfo = ILogger.UNIDENTIFIED;
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ // get the CMC.
+
+ Object argblock = authCred.getArgBlock();
+ Object returnVal = null;
+ if (argblock == null) {
+ returnVal = authCred.get("cert_request");
+ if (returnVal == null)
+ returnVal = authCred.get(CRED_CMC);
+ } else {
+ returnVal = authCred.get("cert_request");
+ if (returnVal == null)
+ returnVal = authCred.getArgBlock().get(CRED_CMC);
+ }
+ String cmc = (String) returnVal;
+ if (cmc == null) {
+ CMS.debug(method + " Authentication failed. Missing CMC.");
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo);
+
+ audit(auditMessage);
+
+ throw new EMissingCredential(CMS.getUserMessage(
+ "CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_CMC));
+ }
+
+ if (cmc.equals("")) {
+ log(ILogger.LL_FAILURE,
+ "cmc : attempted login with empty CMC.");
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo);
+
+ audit(auditMessage);
+
+ throw new EInvalidCredentials(CMS.getUserMessage(
+ "CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ // authenticate by checking CMC.
+
+ // everything OK.
+ // now formulate the certificate info.
+ // set the subject name at a minimum.
+ // set anything else like version, extensions, etc.
+ // if nothing except subject name is set the rest of
+ // cert info will be filled in by policies and CA defaults.
+
+ AuthToken authToken = new AuthToken(this);
+
+ try {
+ String asciiBASE64Blob;
+
+ int startIndex = cmc.indexOf(HEADER);
+ int endIndex = cmc.indexOf(TRAILER);
+ if (startIndex != -1 && endIndex != -1) {
+ startIndex = startIndex + HEADER.length();
+ asciiBASE64Blob = cmc.substring(startIndex, endIndex);
+ } else
+ asciiBASE64Blob = cmc;
+
+ byte[] cmcBlob = CMS.AtoB(asciiBASE64Blob);
+ ByteArrayInputStream cmcBlobIn = new
+ ByteArrayInputStream(cmcBlob);
+
+ org.mozilla.jss.pkix.cms.ContentInfo cmcReq =
+ (org.mozilla.jss.pkix.cms.ContentInfo)
+ org.mozilla.jss.pkix.cms.ContentInfo.getTemplate().decode(
+ cmcBlobIn);
+
+ if (!cmcReq.getContentType().equals(
+ org.mozilla.jss.pkix.cms.ContentInfo.SIGNED_DATA) ||
+ !cmcReq.hasContent()) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo);
+
+ audit(auditMessage);
+
+ // throw new ECMSGWException(CMSGWResources.NO_CMC_CONTENT);
+
+ throw new EBaseException("NO_CMC_CONTENT");
+ }
+
+ SignedData cmcFullReq = (SignedData)
+ cmcReq.getInterpretedContent();
+
+ IConfigStore cmc_config = CMS.getConfigStore();
+ boolean checkSignerInfo =
+ cmc_config.getBoolean("cmc.signerInfo.verify", true);
+ String userid = "defUser";
+ String uid = "defUser";
+ if (checkSignerInfo) {
+ IAuthToken userToken = verifySignerInfo(authToken, cmcFullReq);
+ if (userToken == null) {
+ CMS.debug(method + " authenticate() userToken null");
+ throw new EBaseException(method + " verifySignerInfo failure");
+ }
+ userid = userToken.getInString("userid");
+ uid = userToken.getInString("cn");
+ } else {
+ CMS.debug(method + " authenticate() signerInfo verification bypassed");
+ }
+ // reset value of auditSignerInfo
+ if (uid != null) {
+ auditSignerInfo = uid.trim();
+ }
+
+ EncapsulatedContentInfo ci = cmcFullReq.getContentInfo();
+
+ OBJECT_IDENTIFIER id = ci.getContentType();
+
+ if (!id.equals(OBJECT_IDENTIFIER.id_cct_PKIData) ||
+ !ci.hasContent()) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo);
+
+ audit(auditMessage);
+
+ // throw new ECMSGWException(
+ // CMSGWResources.NO_PKIDATA);
+
+ throw new EBaseException("NO_PKIDATA");
+ }
+
+ OCTET_STRING content = ci.getContent();
+
+ ByteArrayInputStream s = new
+ ByteArrayInputStream(content.toByteArray());
+ PKIData pkiData = (PKIData) (new PKIData.Template()).decode(s);
+
+ SEQUENCE reqSequence = pkiData.getReqSequence();
+
+ int numReqs = reqSequence.size();
+
+ if (numReqs == 0) {
+ CMS.debug(method + "numReqs 0, assume revocation request");
+ // revocation request
+
+ // reset value of auditReqType
+ auditReqType = SIGNED_AUDIT_REVOCATION_REQUEST_TYPE;
+
+ SEQUENCE controlSequence = pkiData.getControlSequence();
+ int controlSize = controlSequence.size();
+
+ if (controlSize > 0) {
+ for (int i = 0; i < controlSize; i++) {
+ TaggedAttribute taggedAttribute =
+ (TaggedAttribute) controlSequence.elementAt(i);
+ OBJECT_IDENTIFIER type = taggedAttribute.getType();
+
+ if (type.equals(
+ OBJECT_IDENTIFIER.id_cmc_revokeRequest)) {
+/* TODO: user-signed revocation to be handled in next ticket
+ // if( i ==1 ) {
+ // taggedAttribute.getType() ==
+ // OBJECT_IDENTIFIER.id_cmc_revokeRequest
+ // }
+
+ SET values = taggedAttribute.getValues();
+ int numVals = values.size();
+ BigInteger[] bigIntArray = null;
+
+ bigIntArray = new BigInteger[numVals];
+ for (int j = 0; j < numVals; j++) {
+ // serialNumber INTEGER
+
+ // SEQUENCE RevRequest = (SEQUENCE)
+ // values.elementAt(j);
+ byte[] encoded = ASN1Util.encode(
+ values.elementAt(j));
+ org.mozilla.jss.asn1.ASN1Template template = new
+ org.mozilla.jss.pkix.cmmf.RevRequest.Template();
+ org.mozilla.jss.pkix.cmmf.RevRequest revRequest =
+ (org.mozilla.jss.pkix.cmmf.RevRequest)
+ ASN1Util.decode(template, encoded);
+
+ // SEQUENCE RevRequest = (SEQUENCE)
+ // ASN1Util.decode(
+ // SEQUENCE.getTemplate(),
+ // ASN1Util.encode(
+ // values.elementAt(j)));
+
+ // SEQUENCE RevRequest =
+ // values.elementAt(j);
+ // int revReqSize = RevRequest.size();
+ // if( revReqSize > 3 ) {
+ // INTEGER serialNumber =
+ // new INTEGER((long)0);
+ // }
+
+ INTEGER temp = revRequest.getSerialNumber();
+
+ bigIntArray[j] = temp;
+ authToken.set(TOKEN_CERT_SERIAL, bigIntArray);
+
+ long reasonCode = revRequest.getReason().getValue();
+ Integer IntObject = Integer.valueOf((int) reasonCode);
+ authToken.set(REASON_CODE, IntObject);
+
+ authToken.set("uid", uid);
+ authToken.set("userid", userid);
+ }
+*/
+ }
+ }
+
+ }
+ } else {
+ CMS.debug(method + "numReqs not 0, assume enrollment request");
+ // enrollment request
+
+ // reset value of auditReqType
+ auditReqType = SIGNED_AUDIT_ENROLLMENT_REQUEST_TYPE;
+
+ X509CertInfo[] certInfoArray = new X509CertInfo[numReqs];
+ String[] reqIdArray = new String[numReqs];
+
+ for (int i = 0; i < numReqs; i++) {
+ // decode message.
+ TaggedRequest taggedRequest =
+ (TaggedRequest) reqSequence.elementAt(i);
+
+ TaggedRequest.Type type = taggedRequest.getType();
+
+ if (type.equals(TaggedRequest.PKCS10)) {
+ CMS.debug(method + " type is PKCS10");
+ authToken.set("cert_request_type", "cmc-pkcs10");
+
+ TaggedCertificationRequest tcr =
+ taggedRequest.getTcr();
+ int p10Id = tcr.getBodyPartID().intValue();
+
+ reqIdArray[i] = String.valueOf(p10Id);
+
+ CertificationRequest p10 =
+ tcr.getCertificationRequest();
+
+ // transfer to sun class
+ ByteArrayOutputStream ostream =
+ new ByteArrayOutputStream();
+
+ p10.encode(ostream);
+ boolean sigver = true;
+ boolean tokenSwitched = false;
+ CryptoManager cm = null;
+ CryptoToken signToken = null;
+ CryptoToken savedToken = null;
+
+ // for PKCS10, "sigver" would offer the POP
+ sigver = CMS.getConfigStore().getBoolean("ca.requestVerify.enabled", true);
+ try {
+ cm = CryptoManager.getInstance();
+ if (sigver == true) {
+ String tokenName =
+ CMS.getConfigStore().getString("ca.requestVerify.token", CryptoUtil.INTERNAL_TOKEN_NAME);
+ savedToken = cm.getThreadToken();
+ signToken = CryptoUtil.getCryptoToken(tokenName);
+ if (!savedToken.getName().equals(signToken.getName())) {
+ cm.setThreadToken(signToken);
+ tokenSwitched = true;
+ }
+ }
+
+ PKCS10 pkcs10 =
+ new PKCS10(ostream.toByteArray(), sigver);
+
+ // xxx do we need to do anything else?
+ X509CertInfo certInfo =
+ CMS.getDefaultX509CertInfo();
+
+ // fillPKCS10(certInfo,pkcs10,authToken,null);
+
+ // authToken.set(
+ // pkcs10.getSubjectPublicKeyInfo());
+
+ X500Name tempName = pkcs10.getSubjectName();
+
+ // reset value of auditCertSubject
+ if (tempName != null) {
+ auditCertSubject =
+ tempName.toString().trim();
+ if (auditCertSubject.equals("")) {
+ auditCertSubject =
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+ authToken.set(AuthToken.TOKEN_CERT_SUBJECT,
+ tempName.toString());
+ }
+
+ authToken.set("uid", uid);
+ authToken.set("userid", userid);
+
+ certInfoArray[i] = certInfo;
+ } catch (Exception e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo);
+
+ audit(auditMessage);
+
+ //throw new ECMSGWException(
+ //CMSGWResources.ERROR_PKCS101, e.toString());
+
+ e.printStackTrace();
+ throw new EBaseException(e.toString());
+ } finally {
+ if ((sigver == true) && (tokenSwitched == true)){
+ cm.setThreadToken(savedToken);
+ }
+ }
+ } else if (type.equals(TaggedRequest.CRMF)) {
+
+ CMS.debug(method + " type is CRMF");
+ authToken.set("cert_request_type", "cmc-crmf");
+ try {
+ CertReqMsg crm =
+ taggedRequest.getCrm();
+ CertRequest certReq = crm.getCertReq();
+ INTEGER reqID = certReq.getCertReqId();
+ reqIdArray[i] = reqID.toString();
+ CertTemplate template = certReq.getCertTemplate();
+ Name name = template.getSubject();
+
+ // xxx do we need to do anything else?
+ X509CertInfo certInfo =
+ CMS.getDefaultX509CertInfo();
+
+ // reset value of auditCertSubject
+ if (name != null) {
+ String ss = name.getRFC1485();
+
+ auditCertSubject = ss;
+ if (auditCertSubject.equals("")) {
+ auditCertSubject =
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ authToken.set(AuthToken.TOKEN_CERT_SUBJECT, ss);
+ authToken.set("uid", uid);
+ authToken.set("userid", userid);
+ }
+ certInfoArray[i] = certInfo;
+ } catch (Exception e) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo);
+
+ audit(auditMessage);
+
+ //throw new ECMSGWException(
+ //CMSGWResources.ERROR_PKCS101, e.toString());
+
+ e.printStackTrace();
+ throw new EBaseException(e.toString());
+ }
+ }
+
+ // authToken.set(AgentAuthentication.CRED_CERT, new
+ // com.netscape.certsrv.usrgrp.Certificates(
+ // x509Certs));
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug(method + e);
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo);
+
+ audit(auditMessage);
+
+ //Debug.printStackTrace(e);
+ throw new EInvalidCredentials(CMS.getUserMessage(
+ "CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo);
+
+ audit(auditMessage);
+
+ CMS.debug(method + "ends successfully; returning authToken");
+ 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,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo);
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ } catch (EInvalidCredentials eAudit2) {
+ CMS.debug(method + eAudit2);
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo);
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit2;
+ } catch (EBaseException eAudit3) {
+ CMS.debug(method + eAudit3);
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditReqType,
+ auditCertSubject,
+ auditSignerInfo);
+
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit3;
+ }
+ }
+
+ /**
+ * Returns a list of configuration parameter names.
+ * The list is passed to the configuration console so instances of
+ * this implementation can be configured through the console.
+ * <p>
+ *
+ * @return String array of configuration parameter names.
+ */
+ public String[] getConfigParams() {
+ return (mConfigParams);
+ }
+
+ /**
+ * gets the configuration substore used by this authentication
+ * plug-in
+ * <p>
+ *
+ * @return configuration store
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * gets the plug-in name of this authentication plug-in.
+ */
+ public String getImplName() {
+ return mImplName;
+ }
+
+ /**
+ * gets the name of this authentication plug-in instance
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * get the list of required credentials.
+ * <p>
+ *
+ * @return list of required credentials as strings.
+ */
+ public String[] getRequiredCreds() {
+ return (mRequiredCreds);
+ }
+
+ /**
+ * prepares for shutdown.
+ */
+ public void shutdown() {
+ }
+
+ /////////////////////////////////
+ // IExtendedPluginInfo methods //
+ /////////////////////////////////
+
+ /**
+ * Activate the help system.
+ * <p>
+ *
+ * @return help messages
+ */
+ public String[] getExtendedPluginInfo() {
+ String method = "CMCUserSignedAuth: getExtendedPluginInfo: ";
+ CMS.debug(method + " begins");
+ String[] s = Utils.getStringArrayFromVector(mExtendedPluginInfo);
+
+ CMS.debug(method + " s.length = " + s.length);
+ for (int i = 0; i < s.length; i++) {
+ CMS.debug("" + i + " " + s[i]);
+ }
+ return s;
+ }
+
+ ////////////////////
+ // Logger methods //
+ ////////////////////
+
+ /**
+ * Logs a message for this class in the system log file.
+ * <p>
+ *
+ * @param level The log level.
+ * @param msg The message to log.
+ * @see com.netscape.certsrv.logging.ILogger
+ */
+ protected void log(int level, String msg) {
+ if (mLogger == null)
+ return;
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHENTICATION,
+ level, "CMC User Signed Authentication: " + msg);
+ }
+
+ protected IAuthToken verifySignerInfo(AuthToken authToken, SignedData cmcFullReq) throws EBaseException {
+ String method = "CMCUserSignedAuth: verifySignerInfo: ";
+ CMS.debug(method + "begins");
+
+ EncapsulatedContentInfo ci = cmcFullReq.getContentInfo();
+ OBJECT_IDENTIFIER id = ci.getContentType();
+ OCTET_STRING content = ci.getContent();
+
+ boolean tokenSwitched = false;
+ CryptoToken signToken = null;
+ CryptoToken savedToken = null;
+ CryptoManager cm = null;
+ try {
+ cm = CryptoManager.getInstance();
+ ByteArrayInputStream s = new ByteArrayInputStream(content.toByteArray());
+ PKIData pkiData = (PKIData) (new PKIData.Template()).decode(s);
+
+ SET dais = cmcFullReq.getDigestAlgorithmIdentifiers();
+ int numDig = dais.size();
+ Hashtable<String, byte[]> digs = new Hashtable<String, byte[]>();
+
+ //if request key is used for signing, there MUST be only one signerInfo
+ //object in the signedData object.
+ for (int i = 0; i < numDig; i++) {
+ AlgorithmIdentifier dai =
+ (AlgorithmIdentifier) dais.elementAt(i);
+ String name =
+ DigestAlgorithm.fromOID(dai.getOID()).toString();
+
+ MessageDigest md =
+ MessageDigest.getInstance(name);
+
+ byte[] digest = md.digest(content.toByteArray());
+
+ digs.put(name, digest);
+ }
+
+ SET sis = cmcFullReq.getSignerInfos();
+ int numSis = sis.size();
+
+ for (int i = 0; i < numSis; i++) {
+ org.mozilla.jss.pkix.cms.SignerInfo si = (org.mozilla.jss.pkix.cms.SignerInfo) sis.elementAt(i);
+
+ String name = si.getDigestAlgorithm().toString();
+ byte[] digest = digs.get(name);
+
+ if (digest == null) {
+ MessageDigest md = MessageDigest.getInstance(name);
+ ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+
+ pkiData.encode(ostream);
+ digest = md.digest(ostream.toByteArray());
+
+ }
+ // signed by previously certified signature key
+ SignerIdentifier sid = si.getSignerIdentifier();
+ // TODO: need to handle signing key being the matching key from
+ // the request
+ if (sid.getType().equals(SignerIdentifier.ISSUER_AND_SERIALNUMBER)) {
+ IssuerAndSerialNumber issuerAndSerialNumber = sid.getIssuerAndSerialNumber();
+ // find from the certs in the signedData
+ java.security.cert.X509Certificate cert = null;
+
+ if (cmcFullReq.hasCertificates()) {
+ SET certs = cmcFullReq.getCertificates();
+ int numCerts = certs.size();
+ java.security.cert.X509Certificate[] x509Certs = new java.security.cert.X509Certificate[1];
+ byte[] certByteArray = new byte[0];
+ for (int j = 0; j < numCerts; j++) {
+ Certificate certJss = (Certificate) certs.elementAt(j);
+ CertificateInfo certI = certJss.getInfo();
+ Name issuer = certI.getIssuer();
+
+ byte[] issuerB = ASN1Util.encode(issuer);
+CMS.debug(method + "issuer = " + new String(issuerB));
+ INTEGER sn = certI.getSerialNumber();
+ // if this cert is the signer cert, not a cert in the chain
+ if (new String(issuerB).equals(new String(
+ ASN1Util.encode(issuerAndSerialNumber.getIssuer())))
+ && sn.toString().equals(issuerAndSerialNumber.getSerialNumber().toString())) {
+ ByteArrayOutputStream os = new
+ ByteArrayOutputStream();
+
+ certJss.encode(os);
+ certByteArray = os.toByteArray();
+
+ X509CertImpl tempcert = new X509CertImpl(os.toByteArray());
+
+ cert = tempcert;
+ x509Certs[0] = cert;
+ // xxx validate the cert length
+
+ }
+ }
+ CMS.debug(method + "start checking signature");
+ if (cert == null) {
+ // find from certDB
+ CMS.debug(method + "verifying signature");
+ si.verify(digest, id);
+ } else {
+ CMS.debug(method + "found signing cert... verifying");
+ PublicKey signKey = cert.getPublicKey();
+ PrivateKey.Type keyType = null;
+ String alg = signKey.getAlgorithm();
+
+ PK11PubKey pubK = null;
+ if (alg.equals("RSA")) {
+ CMS.debug(method + "signing key alg=RSA");
+ keyType = PrivateKey.RSA;
+ pubK = PK11PubKey.fromRaw(keyType, ((X509Key) signKey).getKey());
+ } else if (alg.equals("EC")) {
+ CMS.debug(method + "signing key alg=EC");
+ keyType = PrivateKey.EC;
+ byte publicKeyData[] = ((X509Key) signKey).getEncoded();
+ pubK = PK11ECPublicKey.fromSPKI(/*keyType,*/ publicKeyData);
+ } else {
+ CMS.debug(method + "unsupported signature algorithm: " + alg);
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ }
+
+ String tokenName =
+ CMS.getConfigStore().getString("ca.requestVerify.token", CryptoUtil.INTERNAL_TOKEN_NAME);
+ // by default JSS will use internal crypto token
+ if (!CryptoUtil.isInternalToken(tokenName)) {
+ savedToken = cm.getThreadToken();
+ signToken = CryptoUtil.getCryptoToken(tokenName);
+ if(signToken != null) {
+ cm.setThreadToken(signToken);
+ tokenSwitched = true;
+ CMS.debug(method + "verifySignerInfo token switched:"+ tokenName);
+ } else {
+ CMS.debug(method + "verifySignerInfo token not found:"+ tokenName+ ", trying internal");
+ }
+ }
+
+ CMS.debug(method + "verifying signature with public key");
+ si.verify(digest, id, pubK);
+ }
+ CMS.debug(method + "finished checking signature");
+ // verify signer's certificate using the revocator
+ if (!cm.isCertValid(certByteArray, true, CryptoManager.CertUsage.SSLClient)) {
+ CMS.debug(method + "CMC signature failed to be verified");
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ } else {
+ CMS.debug(method + "CMC signature verified; but signer not yet;");
+ }
+ // At this point, the signature has been verified;
+
+ 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());
+ authToken.set(IAuthManager.CRED_CMC_SIGNING_CERT, certSerial.toString());
+ tempToken.set("cn", CN);
+
+ return tempToken;
+
+ }
+
+ } else {
+ CMS.debug(method + "unsupported SignerIdentifier type");
+ }
+ }
+ } catch (InvalidBERException e) {
+ CMS.debug(method + e.toString());
+ } catch (IOException e) {
+ CMS.debug(method + e.toString());
+ } catch (NotInitializedException e) {
+ CMS.debug(method + e.toString());
+ } catch (Exception e) {
+ CMS.debug(method + e.toString());
+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+ } finally {
+ if ((tokenSwitched == true) && (savedToken != null)){
+ cm.setThreadToken(savedToken);
+ CMS.debug(method + "verifySignerInfo token restored");
+ }
+ }
+ return null;
+
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ return null;
+ }
+
+ // Profile-related methods
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ }
+
+ /**
+ * Retrieves the localizable name of this policy.
+ */
+ public String getName(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_AUTHENTICATION_CMS_SIGN_NAME");
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ */
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_AUTHENTICATION_CMS_SIGN_TEXT");
+ }
+
+ /**
+ * Retrieves a list of names of the value parameter.
+ */
+ public Enumeration<String> getValueNames() {
+ Vector<String> v = new Vector<String>();
+ v.addElement("cert_request");
+ return v.elements();
+ }
+
+ public boolean isValueWriteable(String name) {
+ return false;
+ }
+
+ /**
+ * Retrieves the descriptor of the given value
+ * parameter by name.
+ */
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(CRED_CMC)) {
+ return new Descriptor(IDescriptor.STRING_LIST, null, null,
+ "CMC request");
+ }
+ return null;
+ }
+
+ public void populate(IAuthToken token, IRequest request)
+ throws EProfileException {
+ request.setExtData(IProfileAuthenticator.AUTHENTICATED_NAME,
+ token.getInString(AuthToken.TOKEN_CERT_SUBJECT));
+ }
+
+ public boolean isSSLClientRequired() {
+ return false;
+ }
+
+ /**
+ * Signed Audit Log
+ *
+ * This method is called to store messages to the signed audit log.
+ * <P>
+ *
+ * @param msg signed audit log message
+ */
+ private void audit(String msg) {
+ // in this case, do NOT strip preceding/trailing whitespace
+ // from passed-in String parameters
+
+ if (mSignedAuditLogger == null) {
+ return;
+ }
+
+ mSignedAuditLogger.log(ILogger.EV_SIGNED_AUDIT,
+ null,
+ ILogger.S_SIGNED_AUDIT,
+ ILogger.LL_SECURITY,
+ msg);
+ }
+
+ protected void audit(AuditEvent event) {
+
+ String template = event.getMessage();
+ Object[] params = event.getParameters();
+
+ String message = CMS.getLogMessage(template, params);
+
+ audit(message);
+ }
+
+ /**
+ * Signed Audit Log Subject ID
+ *
+ * This method is called to obtain the "SubjectID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @return id string containing the signed audit log message SubjectID
+ */
+ private String auditSubjectID() {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String subjectID = null;
+
+ // Initialize subjectID
+ SessionContext auditContext = SessionContext.getExistingContext();
+
+ if (auditContext != null) {
+ subjectID = (String)
+ auditContext.get(SessionContext.USER_ID);
+
+ if (subjectID != null) {
+ subjectID = subjectID.trim();
+ } else {
+ subjectID = ILogger.NONROLEUSER;
+ }
+ } else {
+ subjectID = ILogger.UNIDENTIFIED;
+ }
+
+ return subjectID;
+ }
+}
diff --git a/base/server/cms/src/com/netscape/cms/profile/common/BasicProfile.java b/base/server/cms/src/com/netscape/cms/profile/common/BasicProfile.java
index e6fc045e5..e47c72295 100644
--- a/base/server/cms/src/com/netscape/cms/profile/common/BasicProfile.java
+++ b/base/server/cms/src/com/netscape/cms/profile/common/BasicProfile.java
@@ -783,6 +783,8 @@ public abstract class BasicProfile implements IProfile {
boolean createConfig)
throws EProfileException {
+ String method = "BasicProfile: createProfilePolicy: ";
+ CMS.debug(method + "begins");
// String setId ex: policyset.set1
// String id Id of policy : examples: p1,p2,p3
// String defaultClassId : id of the default plugin ex: validityDefaultImpl
@@ -911,19 +913,18 @@ public abstract class BasicProfile implements IProfile {
}
}
}
-
String defaultRoot = id + "." + PROP_DEFAULT;
String constraintRoot = id + "." + PROP_CONSTRAINT;
IPluginInfo defInfo = mRegistry.getPluginInfo("defaultPolicy",
defaultClassId);
if (defInfo == null) {
- CMS.debug("BasicProfile: Cannot find " + defaultClassId);
+ CMS.debug(method + " Cannot find " + defaultClassId);
throw new EProfileException("Cannot find " + defaultClassId);
}
String defaultClass = defInfo.getClassName();
- CMS.debug("BasicProfile: loading default class " + defaultClass);
+ CMS.debug(method + " loading default class " + defaultClass);
IPolicyDefault def = null;
try {
@@ -931,7 +932,7 @@ public abstract class BasicProfile implements IProfile {
Class.forName(defaultClass).newInstance();
} catch (Exception e) {
// throw Exception
- CMS.debug("BasicProfile: default policy " +
+ CMS.debug(method + " default policy " +
defaultClass + " " + e.toString());
}
if (def == null) {
@@ -941,24 +942,30 @@ public abstract class BasicProfile implements IProfile {
defStore = policyStore.getSubStore(defaultRoot);
def.init(this, defStore);
+ CMS.debug(method + " default class initialized.");
}
IPluginInfo conInfo = mRegistry.getPluginInfo("constraintPolicy",
constraintClassId);
+ if (conInfo == null) {
+ CMS.debug(method + " Cannot find " + constraintClassId);
+ throw new EProfileException("Cannot find " + constraintClassId);
+ }
String constraintClass = conInfo.getClassName();
- IPolicyConstraint constraint = null;
+ CMS.debug(method + " loading constraint class " + constraintClass);
+ IPolicyConstraint constraint = null;
try {
constraint = (IPolicyConstraint)
Class.forName(constraintClass).newInstance();
} catch (Exception e) {
// throw Exception
- CMS.debug("BasicProfile: constraint policy " +
+ CMS.debug(method + " constraint policy " +
constraintClass + " " + e.toString());
}
ProfilePolicy policy = null;
if (constraint == null) {
- CMS.debug("BasicProfile: failed to create " + constraintClass);
+ CMS.debug(method + " failed to create " + constraintClass);
} else {
IConfigStore conStore = null;
@@ -966,9 +973,11 @@ public abstract class BasicProfile implements IProfile {
constraint.init(this, conStore);
policy = new ProfilePolicy(id, def, constraint);
policies.addElement(policy);
+ CMS.debug(method + " constraint class initialized.");
}
if (createConfig) {
+ CMS.debug(method + " createConfig true; creating...");
String list = null;
try {
@@ -996,8 +1005,10 @@ public abstract class BasicProfile implements IProfile {
CMS.debug("BasicProfile: commiting config store " +
e.toString());
}
+ CMS.debug(method + " config created.");
}
+ CMS.debug(method + "ends");
return policy;
}
@@ -1091,9 +1102,10 @@ public abstract class BasicProfile implements IProfile {
*/
public void populate(IRequest request)
throws EProfileException {
+ String method = "BasicProfile: populate: ";
String setId = getPolicySetId(request);
Vector<IProfilePolicy> policies = getPolicies(setId);
- CMS.debug("BasicProfile: populate() policy setid =" + setId);
+ CMS.debug(method + "policy setid =" + setId);
for (int i = 0; i < policies.size(); i++) {
IProfilePolicy policy = policies.elementAt(i);
diff --git a/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java b/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
index 1c44e2cd8..57f07d1bd 100644
--- a/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
+++ b/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
@@ -71,6 +71,7 @@ import org.mozilla.jss.pkix.primitive.Name;
import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthManager;
import com.netscape.certsrv.authentication.IAuthToken;
import com.netscape.certsrv.authentication.ISharedToken;
import com.netscape.certsrv.authority.IAuthority;
@@ -110,6 +111,7 @@ import netscape.security.x509.CertificateX509Key;
import netscape.security.x509.Extension;
import netscape.security.x509.Extensions;
import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
import netscape.security.x509.X509CertInfo;
import netscape.security.x509.X509Key;
@@ -144,7 +146,8 @@ public abstract class EnrollProfile extends BasicProfile
*/
public IRequest[] createRequests(IProfileContext ctx, Locale locale)
throws EProfileException {
- String method = "EnrollProfile: createRequests";
+
+ String method = "EnrollProfile: createRequests: ";
CMS.debug(method + "begins");
// determine how many requests should be created
@@ -171,13 +174,20 @@ public abstract class EnrollProfile extends BasicProfile
}
TaggedRequest[] cmc_msgs = null;
if (cert_request_type != null && cert_request_type.startsWith("cmc")) {
- /*
- * TODO: cfu: Phase 2: check if CMCAuth pre-signed request passed.
- * if not, identityProofV2 and/or identification controls
- * are required;
- */
+
+ // donePOI true means Proof-Of-Identity is already done.
+ // if the auth manager is the CMCUserSignedAuth, then
+ // the new cert will eventually have the same subject as the
+ // user signing cert
+ // if the auth manager is the CMCAuth (agent pre-approved),
+ // then no changes
+ boolean donePOI = false;
+ String signingUserSerial = ctx.get(IAuthManager.CRED_CMC_SIGNING_CERT);
+ if (signingUserSerial != null) {
+ donePOI = true;
+ }
// catch for invalid request
- cmc_msgs = parseCMC(locale, cert_request);
+ cmc_msgs = parseCMC(locale, cert_request, donePOI);
if (cmc_msgs == null) {
CMS.debug(method + "parseCMC returns cmc_msgs null");
return null;
@@ -209,7 +219,7 @@ public abstract class EnrollProfile extends BasicProfile
} else {
result[i].setExtData(REQUEST_SEQ_NUM, Integer.valueOf(i));
if ((cmc_msgs != null) && (cmc_msgs[i] != null)) {
- CMS.debug("EnrollProfile: createRequests: setting cmc TaggedRequest in request");
+ CMS.debug(method + "setting cmc TaggedRequest in request");
result[i].setExtData(
CTX_CERT_REQUEST,
ASN1Util.encode(cmc_msgs[i]));
@@ -221,9 +231,6 @@ public abstract class EnrollProfile extends BasicProfile
// set requested CA
result[i].setExtData(IRequest.AUTHORITY_ID, ctx.get(REQUEST_AUTHORITY_ID));
-
- // set user data
- result[i].setExtData(IRequest.USER_DATA, ctx.get(REQUEST_USER_DATA));
}
return result;
}
@@ -300,7 +307,7 @@ public abstract class EnrollProfile extends BasicProfile
req.setExtData(REQUEST_EXTENSIONS,
new CertificateExtensions());
- CMS.debug("EnrollProfile: createRequest " +
+ CMS.debug("EnrollProfile: createEnrollmentRequest " +
req.getRequestId());
} catch (EBaseException e) {
// raise exception?
@@ -469,6 +476,7 @@ public abstract class EnrollProfile extends BasicProfile
IRequestQueue queue = getRequestQueue();
String msg = "";
+ CMS.debug(method + "begins");
boolean popChallengeRequired =
request.getExtDataInBoolean("cmc_POPchallengeRequired", false);
@@ -485,7 +493,7 @@ public abstract class EnrollProfile extends BasicProfile
}
if (token == null){
- CMS.debug(method + " auth token is null");
+ CMS.debug(method + " auth token is null; agent manual approval required;");
CMS.debug(method + " validating request");
validate(request);
try {
@@ -500,6 +508,7 @@ public abstract class EnrollProfile extends BasicProfile
// this is encryptedPOP case; defer to require decryptedPOP
CMS.debug(method + " popChallengeRequired, defer to enforce decryptedPOP");
validate(request);
+
CMS.debug(method + " about to call setPOPchallenge");
try {
setPOPchallenge(request);
@@ -521,40 +530,38 @@ public abstract class EnrollProfile extends BasicProfile
}
}
- /*
- * parseCMC
- * @throws EProfileException in case of error
- * note: returing "null" doesn't mean failure
+ /**
+ * getPKIDataFromCMCblob
+ *
+ * @param certReqBlob cmc b64 encoded blob
+ * @return PKIData
*/
- public TaggedRequest[] parseCMC(Locale locale, String certreq)
+ public PKIData getPKIDataFromCMCblob(Locale locale, String certReqBlob)
throws EProfileException {
- String method = "EnrollProfile: parseCMC: ";
+ String method = "EnrollProfile: getPKIDataFromCMCblob: ";
String msg = ""; // for capturing debug and throw info
/* cert request must not be null */
- if (certreq == null) {
- msg = method + "certreq null";
+ if (certReqBlob == null) {
+ msg = method + "certReqBlob null";
CMS.debug(msg);
throw new EProfileException(
CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST") +
msg);
}
- //CMS.debug(method + " Start parseCMC(): " + certreq);
+ //CMS.debug(method + " Start: " + certReqBlob);
CMS.debug(method + "starts");
- TaggedRequest msgs[] = null;
-
- String creq = normalizeCertReq(certreq);
+ String creq = normalizeCertReq(certReqBlob);
try {
byte data[] = CMS.AtoB(creq);
- ByteArrayInputStream cmcBlobIn =
- new ByteArrayInputStream(data);
+ ByteArrayInputStream cmcBlobIn = new ByteArrayInputStream(data);
- org.mozilla.jss.pkix.cms.ContentInfo cmcReq = (org.mozilla.jss.pkix.cms.ContentInfo)
- org.mozilla.jss.pkix.cms.ContentInfo.getTemplate().decode(cmcBlobIn);
- org.mozilla.jss.pkix.cms.SignedData cmcFullReq =
- (org.mozilla.jss.pkix.cms.SignedData) cmcReq.getInterpretedContent();
+ org.mozilla.jss.pkix.cms.ContentInfo cmcReq = (org.mozilla.jss.pkix.cms.ContentInfo) org.mozilla.jss.pkix.cms.ContentInfo
+ .getTemplate().decode(cmcBlobIn);
+ org.mozilla.jss.pkix.cms.SignedData cmcFullReq = (org.mozilla.jss.pkix.cms.SignedData) cmcReq
+ .getInterpretedContent();
org.mozilla.jss.pkix.cms.EncapsulatedContentInfo ci = cmcFullReq.getContentInfo();
OCTET_STRING content = ci.getContent();
@@ -564,6 +571,104 @@ public abstract class EnrollProfile extends BasicProfile
mCMCData = pkiData;
//PKIData pkiData = (PKIData)
// (new PKIData.Template()).decode(cmcBlobIn);
+
+ return pkiData;
+ } catch (Exception e) {
+ CMS.debug(method + e);
+ throw new EProfileException(
+ CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"), e);
+ }
+ }
+
+ public static CertificateSubjectName getCMCSigningCertSNfromCertSerial(
+ String certSerial) throws Exception {
+ X509CertImpl userCert = getCMCSigningCertFromCertSerial(certSerial);
+
+ if (userCert != null) {
+ return userCert.getSubjectObj();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * getCMCSigningCertFromCertSerial is to be used when authentication
+ * was done with CMCUserSignedAuth where the resulting
+ * authToken contains
+ * IAuthManager.CRED_CMC_SIGNING_CERT, serial number
+ * This method takes the serial number
+ * and finds the cert from the CA's certdb
+ */
+ public static X509CertImpl getCMCSigningCertFromCertSerial(
+ String certSerial) throws Exception {
+ String method = "EnrollProfile: getCMCSigningCertFromCertSerial: ";
+ String msg = "";
+
+ X509CertImpl userCert = null;
+
+ if (certSerial == null || certSerial.equals("")) {
+ msg = method + "certSerial empty";
+ CMS.debug(msg);
+ throw new Exception(msg);
+ }
+
+ // for CMCUserSignedAuth, the signing user is the subject of
+ // the new cert
+ ICertificateAuthority authority = (ICertificateAuthority) CMS.getSubsystem(CMS.SUBSYSTEM_CA);
+ try {
+ BigInteger serialNo = new BigInteger(certSerial);
+ userCert = authority.getCertificateRepository().getX509Certificate(serialNo);
+ } catch (NumberFormatException e) {
+ msg = method + e;
+ CMS.debug(msg);
+ throw new Exception(msg);
+ } catch (EBaseException e) {
+ msg = method + e + "; signing user cert not found: serial=" + certSerial;
+ CMS.debug(msg);
+ throw new Exception(msg);
+ }
+
+ if (userCert != null) {
+ msg = method + "signing user cert found; serial=" + certSerial;
+ CMS.debug(msg);
+ } else {
+ msg = method + "signing user cert not found: serial=" + certSerial;
+ CMS.debug(msg);
+ throw new Exception(msg);
+ }
+
+ return userCert;
+ }
+
+ /*
+ * parseCMC
+ * @throws EProfileException in case of error
+ * note: returing "null" doesn't mean failure
+ */
+ public TaggedRequest[] parseCMC(Locale locale, String certreq)
+ throws EProfileException {
+ return parseCMC(locale, certreq, false);
+ }
+ public TaggedRequest[] parseCMC(Locale locale, String certreq, boolean donePOI)
+ throws EProfileException {
+
+ String method = "EnrollProfile: parseCMC: ";
+ String msg = ""; // for capturing debug and throw info
+ //CMS.debug(method + " Start parseCMC(): " + certreq);
+ CMS.debug(method + "starts");
+
+ /* cert request must not be null */
+ if (certreq == null) {
+ msg = method + "certreq null";
+ CMS.debug(msg);
+ throw new EProfileException(
+ CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST") +
+ msg);
+ }
+
+ TaggedRequest msgs[] = null;
+ try {
+ PKIData pkiData = getPKIDataFromCMCblob(locale, certreq);
SEQUENCE controlSeq = pkiData.getControlSequence();
int numcontrols = controlSeq.size();
SEQUENCE reqSeq = pkiData.getReqSequence();
@@ -571,6 +676,7 @@ public abstract class EnrollProfile extends BasicProfile
UTF8String ident_s = null;
SessionContext context = SessionContext.getContext();
if (!context.containsKey("numOfControls")) {
+ CMS.debug(method + "numcontrols="+ numcontrols);
if (numcontrols > 0) {
context.put("numOfControls", Integer.valueOf(numcontrols));
TaggedAttribute[] attributes = new TaggedAttribute[numcontrols];
@@ -587,56 +693,45 @@ public abstract class EnrollProfile extends BasicProfile
boolean id_cmc_idPOPLinkRandom = false;
SET vals = null;
+ /**
+ * pre-process all controls --
+ * the postponed processing is so that we can capture
+ * the identification, if included
+ */
+ CMS.debug(method + "about to pre-process controls");
for (int i = 0; i < numcontrols; i++) {
attributes[i] = (TaggedAttribute) controlSeq.elementAt(i);
OBJECT_IDENTIFIER oid = attributes[i].getType();
if (oid.equals(OBJECT_IDENTIFIER.id_cmc_decryptedPOP)) {
- CMS.debug(method + " decryptedPOP found");
+ CMS.debug(method + " id_cmc_decryptedPOP found");
id_cmc_decryptedPOP = true;
decPopVals = attributes[i].getValues();
} else if (oid.equals(OBJECT_IDENTIFIER.id_cmc_identification)) {
+ CMS.debug(method + " id_cmc_identification found");
id_cmc_identification = true;
ident = attributes[i].getValues();
} else if (oid.equals(OBJECT_IDENTIFIER.id_cmc_identityProofV2)) {
+ CMS.debug(method + " id_cmc_identityProofV2 found");
id_cmc_identityProofV2 = true;
attr = attributes[i];
} else if (oid.equals(OBJECT_IDENTIFIER.id_cmc_identityProof)) {
+ CMS.debug(method + " id_cmc_identityProof found");
id_cmc_identityProof = true;
attr = attributes[i];
} else if (oid.equals(OBJECT_IDENTIFIER.id_cmc_idPOPLinkRandom)) {
- CMS.debug(method + "id_cmc_idPOPLinkRandom true");
+ CMS.debug(method + "id_cmc_idPOPLinkRandom found");
id_cmc_idPOPLinkRandom = true;
vals = attributes[i].getValues();
} else {
+ CMS.debug(method + "unknown control found");
context.put(attributes[i].getType(), attributes[i]);
}
} //for
/**
* now do the actual control processing
- * (the postponed processing is so that we can capture
- * the identification, if included)
*/
-
- if (id_cmc_decryptedPOP) {
- if (decPopVals != null) {
-
- DecryptedPOP decPop = (DecryptedPOP) (ASN1Util.decode(DecryptedPOP.getTemplate(),
- ASN1Util.encode(decPopVals.elementAt(0))));
- CMS.debug(method + "DecryptedPOP encoded");
-
- Integer reqId = verifyDecryptedPOP(locale, decPop);
- if (reqId != null) {
- context.put("decryptedPopReqId", reqId);
- }
- } else { //decPopVals == null
- msg = "id_cmc_decryptedPOP contains invalid DecryptedPOP";
- CMS.debug(method + msg);
- SEQUENCE bpids = getRequestBpids(reqSeq);
- context.put("decryptedPOP", bpids);
- }
- return null;
- }
+ CMS.debug(method + "processing controls...");
if (id_cmc_identification) {
if (ident == null) {
@@ -666,8 +761,22 @@ public abstract class EnrollProfile extends BasicProfile
}
}
- // either V2 or not V2; can't be both
- if (id_cmc_identityProofV2 && (attr != null)) {
+ // checking Proof Of Identity, if not pre-signed
+
+ if (donePOI) {
+ // for logging purposes
+ if (id_cmc_identityProofV2) {
+ CMS.debug(method
+ + "pre-signed CMC request, but id_cmc_identityProofV2 found...ignore; no further proof of identification check");
+ } else if (id_cmc_identityProof) {
+ CMS.debug(method
+ + "pre-signed CMC request, but id_cmc_identityProof found...ignore; no further proof of identification check");
+ } else {
+ CMS.debug(method + "pre-signed CMC request; no further proof of identification check");
+ }
+ } else if (id_cmc_identityProofV2 && (attr != null)) {
+ // either V2 or not V2; can't be both
+ CMS.debug(method + "not pre-signed CMC request; calling verifyIdentityProofV2;");
if (!id_cmc_identification) {
SEQUENCE bpids = getRequestBpids(reqSeq);
context.put("identification", bpids);
@@ -685,23 +794,57 @@ public abstract class EnrollProfile extends BasicProfile
SEQUENCE bpids = getRequestBpids(reqSeq);
context.put("identityProofV2", bpids);
- msg = " in verifyIdentityProofV2";
+ msg = " after verifyIdentityProofV2";
CMS.debug(method + msg);
throw new EProfileException(CMS.getUserMessage(locale,
- "CMS_POI_VERIFICATION_ERROR")+ msg);
+ "CMS_POI_VERIFICATION_ERROR") + msg);
+ } else {
+ CMS.debug(method + "passed verifyIdentityProofV2; Proof of Identity successful;");
}
} else if (id_cmc_identityProof && (attr != null)) {
+ CMS.debug(method + "not pre-signed CMC request; calling verifyIdentityProof;");
boolean valid = verifyIdentityProof(attr,
reqSeq);
if (!valid) {
SEQUENCE bpids = getRequestBpids(reqSeq);
context.put("identityProof", bpids);
- msg = " in verifyIdentityProof";
+ msg = " after verifyIdentityProof";
CMS.debug(method + msg);
throw new EProfileException(CMS.getUserMessage(locale,
- "CMS_POI_VERIFICATION_ERROR")+ msg);
+ "CMS_POI_VERIFICATION_ERROR") + msg);
+ } else {
+ CMS.debug(method + "passed verifyIdentityProof; Proof of Identity successful;");
}
+ } else {
+ msg = "not pre-signed CMC request; missing Proof of Identification control";
+ CMS.debug(method + msg);
+ throw new EProfileException(CMS.getUserMessage(locale,
+ "CMS_POI_VERIFICATION_ERROR") + ":" + method + msg);
+ }
+
+ if (id_cmc_decryptedPOP) {
+ if (decPopVals != null) {
+
+ DecryptedPOP decPop = (DecryptedPOP) (ASN1Util.decode(DecryptedPOP.getTemplate(),
+ ASN1Util.encode(decPopVals.elementAt(0))));
+ CMS.debug(method + "DecryptedPOP encoded");
+
+ Integer reqId = verifyDecryptedPOP(locale, decPop);
+ if (reqId != null) {
+ context.put("cmcDecryptedPopReqId", reqId);
+ }
+ } else { //decPopVals == null
+ msg = "id_cmc_decryptedPOP contains invalid DecryptedPOP";
+ CMS.debug(method + msg);
+ SEQUENCE bpids = getRequestBpids(reqSeq);
+ context.put("decryptedPOP", bpids);
+ }
+
+ // decryptedPOP is expected to return null;
+ // POPLinkWitnessV2 would have to be checked in
+ // round one, if required
+ return null;
}
if (id_cmc_idPOPLinkRandom && vals != null) {
@@ -725,61 +868,65 @@ public abstract class EnrollProfile extends BasicProfile
}
}
- int nummsgs = reqSeq.size();
- if (nummsgs > 0) {
+ /**
+ * in CS.cfg, cmc.popLinkWitnessRequired=true
+ * will enforce popLinkWitness (or V2);
+ */
+ boolean popLinkWitnessRequired = false;
+ try {
+ String configName = "cmc.popLinkWitnessRequired";
+ CMS.debug(method + "getting :" + configName);
+ popLinkWitnessRequired = CMS.getConfigStore().getBoolean(configName, false);
+ } catch (Exception e) {
+ // unlikely to get here
+ msg = method + " Failed to retrieve cmc.popLinkWitnessRequired";
+ CMS.debug(msg);
+ throw new EProfileException(method + msg);
+ }
+ int nummsgs = reqSeq.size();
+ if (!popLinkWitnessRequired) {
+ CMS.debug(method + "popLinkWitnessRequired false, skip check");
+ } else if (nummsgs > 0) {
+ CMS.debug(method + "cmc.popLinkWitnessRequired is true");
+ CMS.debug(method + "nummsgs =" + nummsgs);
msgs = new TaggedRequest[reqSeq.size()];
SEQUENCE bpids = new SEQUENCE();
- /* TODO: add this in CS.cfg later: cmc.popLinkWitnessRequired=true
- // enforce popLinkWitness (or V2)
- boolean popLinkWitnessRequired = true;
- try {
- String configName = "cmc.popLinkWitnessRequired";
- CMS.debug(method + "getting :" + configName);
- popLinkWitnessRequired = CMS.getConfigStore().getBoolean(configName, true);
- CMS.debug(method + "cmc.popLinkWitnessRequired is " + popLinkWitnessRequired);
- } catch (Exception e) {
- // unlikely to get here
- msg = method + " Failed to retrieve cmc.popLinkWitnessRequired";
- CMS.debug(msg);
- throw new EProfileException(method + msg);
- }
-*/
-
boolean valid = true;
for (int i = 0; i < nummsgs; i++) {
msgs[i] = (TaggedRequest) reqSeq.elementAt(i);
if (!context.containsKey("POPLinkWitnessV2") &&
!context.containsKey("POPLinkWitness")) {
- if (randomSeed != null) {
- // verifyPOPLinkWitness() will determine if this is
- // POPLinkWitnessV2 or POPLinkWitness
- // If failure, context is set in verifyPOPLinkWitness
- valid = verifyPOPLinkWitness(ident_s, randomSeed, msgs[i], bpids, context);
- if (valid == false) {
- if (context.containsKey("POPLinkWitnessV2"))
- msg = " in POPLinkWitnessV2";
- else if (context.containsKey("POPLinkWitness"))
- msg = " in POPLinkWitness";
- else
- msg = " unspecified failure from verifyPOPLinkWitness";
-
- CMS.debug(method + msg);
- throw new EProfileException(CMS.getUserMessage(locale,
- "MS_POP_LINK_WITNESS_VERIFICATION_ERROR")+ msg);
- }
- /* TODO: for next cmc ticket, eliminate the extra trip of parseCMC if possible, or figure a way out to bypass this on 2nd trip
- } else if (popLinkWitnessRequired == true) {
- //popLinkWitnessRequired == true, must have randomSeed
- CMS.debug(method + "popLinkWitness(V2) required; no randomSeed found");
+ CMS.debug(method + "popLinkWitness(V2) required");
+ if (randomSeed == null) {
+ CMS.debug(method + "no randomSeed found");
context.put("POPLinkWitnessV2", bpids);
- return null;*/
- } //randomSeed != null
+ return null;
+ }
+
+ // verifyPOPLinkWitness() will determine if this is
+ // POPLinkWitnessV2 or POPLinkWitness
+ // If failure, context is set in verifyPOPLinkWitness
+ valid = verifyPOPLinkWitness(ident_s, randomSeed, msgs[i], bpids, context);
+ if (valid == false) {
+ if (context.containsKey("POPLinkWitnessV2"))
+ msg = " in POPLinkWitnessV2";
+ else if (context.containsKey("POPLinkWitness"))
+ msg = " in POPLinkWitness";
+ else
+ msg = " unspecified failure from verifyPOPLinkWitness";
+
+ CMS.debug(method + msg);
+ throw new EProfileException(CMS.getUserMessage(locale,
+ "CMS_POP_LINK_WITNESS_VERIFICATION_ERROR") + msg);
+ }
}
- }
- } else
+ } //for
+ } else {
+ CMS.debug(method + "nummsgs 0; returning...");
return null;
+ }
CMS.debug(method + "ends");
return msgs;
@@ -1398,6 +1545,9 @@ public abstract class EnrollProfile extends BasicProfile
public void fillTaggedRequest(Locale locale, TaggedRequest tagreq, X509CertInfo info,
IRequest req)
throws EProfileException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+
String method = "EnrollProfile: fillTaggedRequest: ";
CMS.debug(method + "begins");
TaggedRequest.Type type = tagreq.getType();
@@ -1409,16 +1559,19 @@ public abstract class EnrollProfile extends BasicProfile
}
if (type.equals(TaggedRequest.PKCS10)) {
- CMS.debug(method + " TaggedRequest type == pkcs10");
+ String methodPos = method + "PKCS10: ";
+ CMS.debug(methodPos + " TaggedRequest type == pkcs10");
boolean sigver = true;
boolean tokenSwitched = false;
CryptoManager cm = null;
CryptoToken signToken = null;
CryptoToken savedToken = null;
try {
+ // for PKCS10, "sigver" would provide the POP
sigver = CMS.getConfigStore().getBoolean("ca.requestVerify.enabled", true);
cm = CryptoManager.getInstance();
if (sigver == true) {
+ CMS.debug(methodPos + "sigver true, POP is to be verified");
String tokenName =
CMS.getConfigStore().getString("ca.requestVerify.token", CryptoUtil.INTERNAL_TOKEN_NAME);
savedToken = cm.getThreadToken();
@@ -1427,6 +1580,12 @@ public abstract class EnrollProfile extends BasicProfile
cm.setThreadToken(signToken);
tokenSwitched = true;
}
+ } else {
+ // normally, you would not get here, as you almost always
+ // would want to verify the PKCS10 signature when it's
+ // already there instead of taking a 2nd trip
+ CMS.debug(methodPos + "sigver false, POP is not to be verified now, but instead will be challenged");
+ req.setExtData("cmc_POPchallengeRequired", "true");
}
TaggedCertificationRequest tcr = tagreq.getTcr();
@@ -1440,13 +1599,17 @@ public abstract class EnrollProfile extends BasicProfile
fillPKCS10(locale, pkcs10, info, req);
} catch (Exception e) {
CMS.debug(method + e);
+ // this will throw
+ popFailed(locale, auditSubjectID, auditMessage, e);
} finally {
if ((sigver == true) && (tokenSwitched == true)){
cm.setThreadToken(savedToken);
}
}
+ CMS.debug(methodPos + "done");
} else if (type.equals(TaggedRequest.CRMF)) {
- CMS.debug(method + " TaggedRequest type == crmf");
+ String methodPos = method + "CRMF: ";
+ CMS.debug(methodPos + " TaggedRequest type == crmf");
CertReqMsg crm = tagreq.getCrm();
SessionContext context = SessionContext.getContext();
Integer nums = (Integer) (context.get("numOfControls"));
@@ -1454,12 +1617,12 @@ public abstract class EnrollProfile extends BasicProfile
boolean verifyAllow = false; //disable RA by default
try {
String configName = "cmc.lraPopWitness.verify.allow";
- CMS.debug(method + "getting :" + configName);
+ CMS.debug(methodPos + "getting :" + configName);
verifyAllow = CMS.getConfigStore().getBoolean(configName, false);
- CMS.debug(method + "cmc.lraPopWitness.verify.allow is " + verifyAllow);
+ CMS.debug(methodPos + "cmc.lraPopWitness.verify.allow is " + verifyAllow);
} catch (Exception e) {
// unlikely to get here
- String msg = method + " Failed to retrieve cmc.lraPopWitness.verify.allow";
+ String msg = methodPos + " Failed to retrieve cmc.lraPopWitness.verify.allow";
CMS.debug(msg);
throw new EProfileException(method + msg);
}
@@ -1471,23 +1634,23 @@ public abstract class EnrollProfile extends BasicProfile
parseLRAPopWitness(locale, crm, attr);
} else {
CMS.debug(
- method + " verify POP in CMC because LRA POP Witness control attribute doesnt exist in the CMC request.");
+ methodPos + " verify POP in CMC because LRA POP Witness control attribute doesnt exist in the CMC request.");
if (crm.hasPop()) {
- CMS.debug(method + " hasPop true");
+ CMS.debug(methodPos + " hasPop true");
verifyPOP(locale, crm);
} else { // no signing POP, then do it the hard way
- CMS.debug(method + "hasPop false, need to challenge");
+ CMS.debug(methodPos + "hasPop false, need to challenge");
req.setExtData("cmc_POPchallengeRequired", "true");
}
}
} else {
CMS.debug(
- method + " verify POP in CMC because LRA POP Witness control attribute doesnt exist in the CMC request.");
+ methodPos + " verify POP in CMC because LRA POP Witness control attribute doesnt exist in the CMC request.");
if (crm.hasPop()) {
- CMS.debug(method + " hasPop true");
+ CMS.debug(methodPos + " hasPop true");
verifyPOP(locale, crm);
} else { // no signing POP, then do it the hard way
- CMS.debug(method + "hasPop false, need to challenge");
+ CMS.debug(methodPos + "hasPop false, need to challenge");
req.setExtData("cmc_POPchallengeRequired", "true");
}
}
@@ -1495,10 +1658,10 @@ public abstract class EnrollProfile extends BasicProfile
} else { //!verifyAllow
if (crm.hasPop()) {
- CMS.debug(method + " hasPop true");
+ CMS.debug(methodPos + " hasPop true");
verifyPOP(locale, crm);
} else { // no signing POP, then do it the hard way
- CMS.debug(method + "hasPop false, need to challenge");
+ CMS.debug(methodPos + "hasPop false, need to challenge");
req.setExtData("cmc_POPchallengeRequired", "true");
}
}
@@ -1835,6 +1998,8 @@ public abstract class EnrollProfile extends BasicProfile
public void fillPKCS10(Locale locale, PKCS10 pkcs10, X509CertInfo info, IRequest req)
throws EProfileException {
+ String method = "EnrollProfile: fillPKCS10: ";
+ CMS.debug(method + "begins");
X509Key key = pkcs10.getSubjectPublicKeyInfo();
try {
@@ -1869,7 +2034,7 @@ public abstract class EnrollProfile extends BasicProfile
PKCS10Attribute p10Attr = p10Attrs.getAttribute(CertificateExtensions.NAME);
if (p10Attr != null && p10Attr.getAttributeId().equals(
PKCS9Attribute.EXTENSION_REQUEST_OID)) {
- CMS.debug("Found PKCS10 extension");
+ CMS.debug(method + "Found PKCS10 extension");
Extensions exts0 = (Extensions)
(p10Attr.getAttributeValue());
DerOutputStream extOut = new DerOutputStream();
@@ -1879,24 +2044,22 @@ public abstract class EnrollProfile extends BasicProfile
DerInputStream extIn = new DerInputStream(extB);
CertificateExtensions exts = new CertificateExtensions(extIn);
if (exts != null) {
- CMS.debug("Set extensions " + exts);
+ CMS.debug(method + "Set extensions " + exts);
// info.set(X509CertInfo.EXTENSIONS, exts);
req.setExtData(REQUEST_EXTENSIONS, exts);
}
} else {
- CMS.debug("PKCS10 extension Not Found");
+ CMS.debug(method + "PKCS10 extension Not Found");
}
}
- CMS.debug("Finish parsePKCS10 - " + pkcs10.getSubjectName());
+ CMS.debug(method + "Finish parsePKCS10 - " + pkcs10.getSubjectName());
} catch (IOException e) {
- CMS.debug("EnrollProfile: Unable to fill PKCS #10: " + e);
- CMS.debug(e);
+ CMS.debug(method + "Unable to fill PKCS #10: " + e);
throw new EProfileException(
CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"), e);
} catch (CertificateException e) {
- CMS.debug("EnrollProfile: Unable to fill PKCS #10: " + e);
- CMS.debug(e);
+ CMS.debug(method + "Unable to fill PKCS #10: " + e);
throw new EProfileException(
CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"), e);
}
@@ -2074,8 +2237,11 @@ public abstract class EnrollProfile extends BasicProfile
public void populate(IRequest request)
throws EProfileException {
- super.populate(request);
+ String method = "EnrollProfile: populate: ";
+ CMS.debug(method + "begins");
+
+ super.populate(request);
}
/**
@@ -2240,7 +2406,7 @@ public abstract class EnrollProfile extends BasicProfile
public void verifyPOP(Locale locale, CertReqMsg certReqMsg)
throws EProfileException {
String method = "EnrollProfile: verifyPOP: ";
- CMS.debug(method + "for signing keys");
+ CMS.debug(method + "for signing keys begins.");
String auditMessage = null;
String auditSubjectID = auditSubjectID();
@@ -2261,10 +2427,10 @@ public abstract class EnrollProfile extends BasicProfile
CryptoToken verifyToken = null;
String tokenName = CMS.getConfigStore().getString("ca.requestVerify.token", CryptoUtil.INTERNAL_TOKEN_NAME);
if (CryptoUtil.isInternalToken(tokenName)) {
- CMS.debug("POP verification using internal token");
+ CMS.debug(method + "POP verification using internal token");
certReqMsg.verify();
} else {
- CMS.debug("POP verification using token:" + tokenName);
+ CMS.debug(method + "POP verification using token:" + tokenName);
verifyToken = CryptoUtil.getCryptoToken(tokenName);
certReqMsg.verify(verifyToken);
}
@@ -2279,7 +2445,7 @@ public abstract class EnrollProfile extends BasicProfile
CMS.debug(method + "Unable to verify POP: " + e);
popFailed(locale, auditSubjectID, auditMessage, e);
}
- CMS.debug(method + "ends.");
+ CMS.debug(method + "done.");
}
private void popFailed(Locale locale, String auditSubjectID, String auditMessage)
diff --git a/base/server/cms/src/com/netscape/cms/profile/constraint/CMCUserSignedSubjectNameConstraint.java b/base/server/cms/src/com/netscape/cms/profile/constraint/CMCUserSignedSubjectNameConstraint.java
new file mode 100644
index 000000000..c71b6704e
--- /dev/null
+++ b/base/server/cms/src/com/netscape/cms/profile/constraint/CMCUserSignedSubjectNameConstraint.java
@@ -0,0 +1,141 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.profile.constraint;
+
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+import com.netscape.cms.profile.def.CMCUserSignedSubjectNameDefault;
+
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+
+/**
+ * This class implements the user subject name constraint for user-signed cmc requests.
+ * It makes sure the signing cert's subjectDN and the rsulting cert match
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class CMCUserSignedSubjectNameConstraint extends EnrollConstraint {
+
+ public CMCUserSignedSubjectNameConstraint() {
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ return null;
+ }
+
+ public String getDefaultConfig(String name) {
+ return null;
+ }
+
+ /**
+ * Validates the request. The request is not modified
+ * during the validation. User encoded subject name
+ * is copied into the certificate template.
+ */
+ public void validate(IRequest request, X509CertInfo info)
+ throws ERejectException {
+ String method = "CMCUserSignedSubjectNameConstraint: ";
+ String msg = "";
+
+ CMS.debug(method + "validate start");
+ CertificateSubjectName infoCertSN = null;
+ CertificateSubjectName authTokenCertSN = null;
+
+
+ try {
+ infoCertSN = (CertificateSubjectName) info.get(X509CertInfo.SUBJECT);
+ if (infoCertSN == null) {
+ msg = method + "infoCertSN null";
+ CMS.debug(msg);
+ throw new Exception(msg);
+ }
+ CMS.debug(method + "validate user subject ="+
+ infoCertSN.toString());
+ String certSerial = request.getExtDataInString(IAuthManager.CRED_CMC_SIGNING_CERT);
+ if (certSerial == null) {
+ msg = method + "certSerial null";
+ CMS.debug(msg);
+ throw new Exception(msg);
+ }
+ authTokenCertSN =
+ EnrollProfile.getCMCSigningCertSNfromCertSerial(certSerial);
+ if (authTokenCertSN == null) {
+ msg = method + "authTokenCertSN null";
+ CMS.debug(msg);
+ throw new Exception(msg);
+ }
+ X500Name infoCertName = (X500Name) infoCertSN.get(CertificateSubjectName.DN_NAME);
+ if (infoCertName == null) {
+ msg = method + "infoCertName null";
+ CMS.debug(msg);
+ throw new Exception(msg);
+ }
+ X500Name authTokenCertName = (X500Name) authTokenCertSN.get(CertificateSubjectName.DN_NAME);
+ if (authTokenCertName == null) {
+ msg = method + "authTokenCertName null";
+ CMS.debug(msg);
+ throw new Exception(msg);
+ }
+ if (infoCertName.equals(authTokenCertName)) {
+ CMS.debug(method + "names match");
+ } else {
+ msg = method + "names do not match";
+ CMS.debug(msg);
+ throw new Exception(msg);
+ }
+
+ } catch (Exception e) {
+ throw new ERejectException(
+ CMS.getUserMessage(getLocale(request),
+ "CMS_PROFILE_SUBJECT_NAME_NOT_MATCHED") + e);
+ }
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale,
+ "CMS_PROFILE_CONSTRAINT_CMC_USER_SIGNED_SUBJECT_NAME_TEXT");
+ }
+
+ public boolean isApplicable(IPolicyDefault def) {
+ String method = "CMCUserSignedSubjectNameConstraint: isApplicable: ";
+ if (def instanceof CMCUserSignedSubjectNameDefault) {
+ CMS.debug(method + "true");
+ return true;
+ }
+ CMS.debug(method + "false");
+ return false;
+ }
+}
diff --git a/base/server/cms/src/com/netscape/cms/profile/def/CMCUserSignedSubjectNameDefault.java b/base/server/cms/src/com/netscape/cms/profile/def/CMCUserSignedSubjectNameDefault.java
new file mode 100644
index 000000000..a0816ea7e
--- /dev/null
+++ b/base/server/cms/src/com/netscape/cms/profile/def/CMCUserSignedSubjectNameDefault.java
@@ -0,0 +1,159 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.profile.def;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthManager;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.common.EnrollProfile;
+
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+
+/**
+ * This class implements an enrollment default policy
+ * that populates a CMC signing user's subject name
+ * into the certificate template.
+ *
+ * @author cfu
+ * @version $Revision$, $Date$
+ */
+public class CMCUserSignedSubjectNameDefault extends EnrollDefault {
+
+ public static final String VAL_NAME = "name";
+
+ public CMCUserSignedSubjectNameDefault() {
+ super();
+ addValueName(VAL_NAME);
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ super.init(profile, config);
+ }
+
+ public IDescriptor getValueDescriptor(Locale locale, String name) {
+ if (name.equals(VAL_NAME)) {
+ return new Descriptor(IDescriptor.STRING, null, null,
+ CMS.getUserMessage(locale, "CMS_PROFILE_SUBJECT_NAME"));
+ } else {
+ return null;
+ }
+ }
+
+ public void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_NAME)) {
+ X500Name x500name = null;
+
+ try {
+ x500name = new X500Name(value);
+ } catch (IOException e) {
+ CMS.debug(e.toString());
+ // failed to build x500 name
+ }
+ CMS.debug("SubjectNameDefault: setValue name=" + x500name);
+ try {
+ info.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(x500name));
+ } catch (Exception e) {
+ // failed to insert subject name
+ CMS.debug("CMCUserSignedSubjectNameDefault: setValue " + e.toString());
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException {
+ if (name == null) {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ if (name.equals(VAL_NAME)) {
+ CertificateSubjectName sn = null;
+
+ try {
+ sn = (CertificateSubjectName)
+ info.get(X509CertInfo.SUBJECT);
+ return sn.toString();
+ } catch (Exception e) {
+ // nothing
+ }
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ } else {
+ throw new EPropertyException(CMS.getUserMessage(
+ locale, "CMS_INVALID_PROPERTY", name));
+ }
+ }
+
+ public String getText(Locale locale) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_CMC_USER_SIGNED_SUBJECT_NAME");
+ }
+
+ /**
+ * Populates the request with this policy default.
+ */
+ public void populate(IRequest request, X509CertInfo info)
+ throws EProfileException {
+ String method = "CMCUserSignedSubjectNameDefault: populate: ";
+ String msg = "";
+ CMS.debug(method + "begins");
+
+ String signingUserSerial = request.getExtDataInString(IAuthManager.CRED_CMC_SIGNING_CERT);
+ if (info == null) {
+ msg = method + "info null";
+ CMS.debug(msg);
+ throw new EProfileException(msg);
+ }
+
+ CertificateSubjectName certSN = null;
+ try {
+ certSN = EnrollProfile.getCMCSigningCertSNfromCertSerial(signingUserSerial);
+ info.set(X509CertInfo.SUBJECT, certSN);
+ CMS.debug(method + "subjectDN set in X509CertInfo");
+ } catch (Exception e) {
+ msg = method + "exception thrown:" + e;
+ throw new EProfileException(e.toString());
+ }
+ request.setExtData(IEnrollProfile.REQUEST_CERTINFO, info);
+ CMS.debug(method + "ends");
+ }
+}
diff --git a/base/server/cms/src/com/netscape/cms/profile/def/EnrollDefault.java b/base/server/cms/src/com/netscape/cms/profile/def/EnrollDefault.java
index 00d669e37..1d5bfc4f8 100644
--- a/base/server/cms/src/com/netscape/cms/profile/def/EnrollDefault.java
+++ b/base/server/cms/src/com/netscape/cms/profile/def/EnrollDefault.java
@@ -214,17 +214,18 @@ public abstract class EnrollDefault implements IPolicyDefault, ICertInfoPolicyDe
*/
public void populate(IRequest request)
throws EProfileException {
+ String method = "EnrollDefault: populate: ";
String name = getClass().getName();
name = name.substring(name.lastIndexOf('.') + 1);
- CMS.debug(name + ": populate start");
+ CMS.debug(method + name + ": start");
X509CertInfo info =
request.getExtDataInCertInfo(IEnrollProfile.REQUEST_CERTINFO);
populate(request, info);
request.setExtData(IEnrollProfile.REQUEST_CERTINFO, info);
- CMS.debug(name + ": populate end");
+ CMS.debug(method + name + ": end");
}
public void addValueName(String name) {
diff --git a/base/server/cms/src/com/netscape/cms/profile/input/CMCCertReqInput.java b/base/server/cms/src/com/netscape/cms/profile/input/CMCCertReqInput.java
index a62d6e9f7..0a9cae173 100644
--- a/base/server/cms/src/com/netscape/cms/profile/input/CMCCertReqInput.java
+++ b/base/server/cms/src/com/netscape/cms/profile/input/CMCCertReqInput.java
@@ -21,6 +21,8 @@ import java.util.Locale;
import netscape.security.x509.X509CertInfo;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.pkix.cmc.PKIData;
import org.mozilla.jss.pkix.cmc.TaggedRequest;
import com.netscape.certsrv.apps.CMS;
@@ -85,19 +87,32 @@ public class CMCCertReqInput extends EnrollInput implements IProfileInput {
*/
public void populate(IProfileContext ctx, IRequest request)
throws EProfileException {
+ String method = "CMCCertReqInput: populate: ";
+ CMS.debug(method + "begins");
+
String cert_request = ctx.get(VAL_CERT_REQUEST);
X509CertInfo info =
request.getExtDataInCertInfo(EnrollProfile.REQUEST_CERTINFO);
if (cert_request == null) {
- CMS.debug("CMCCertReqInput: populate - invalid certificate request");
+ CMS.debug(method + "invalid certificate request");
throw new EProfileException(CMS.getUserMessage(
getLocale(request), "CMS_PROFILE_NO_CERT_REQ"));
}
- TaggedRequest msgs[] = mEnrollProfile.parseCMC(getLocale(request), cert_request);
+ // cfu: getPKIDataFromCMCblob() is extracted from parseCMC
+ // so it's less confusing
+ //TaggedRequest msgs[] = mEnrollProfile.parseCMC(getLocale(request), cert_request);
+ PKIData pkiData = mEnrollProfile.getPKIDataFromCMCblob(getLocale(request), cert_request);
+ SEQUENCE reqSeq = pkiData.getReqSequence();
+ int nummsgs = reqSeq.size(); // for now we only handle one anyways
+ CMS.debug(method + "pkiData.getReqSequence() called; nummsgs =" + nummsgs);
+ TaggedRequest[] msgs = new TaggedRequest[reqSeq.size()];
+ for (int i = 0; i < nummsgs; i++) {
+ msgs[i] = (TaggedRequest) reqSeq.elementAt(i);
+ }
if (msgs == null) {
- CMS.debug("CMCCertReqInput: populate - parseCMC returns null TaggedRequest msgs");
+ CMS.debug(method + "TaggedRequest msgs null after getPKIDataFromCMCblob");
return;
}
// This profile only handle the first request in CRMF
diff --git a/base/server/cms/src/com/netscape/cms/profile/input/CertReqInput.java b/base/server/cms/src/com/netscape/cms/profile/input/CertReqInput.java
index e67f5b501..fabd2aa7c 100644
--- a/base/server/cms/src/com/netscape/cms/profile/input/CertReqInput.java
+++ b/base/server/cms/src/com/netscape/cms/profile/input/CertReqInput.java
@@ -19,10 +19,8 @@ package com.netscape.cms.profile.input;
import java.util.Locale;
-import netscape.security.pkcs.PKCS10;
-import netscape.security.util.DerInputStream;
-import netscape.security.x509.X509CertInfo;
-
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.pkix.cmc.PKIData;
import org.mozilla.jss.pkix.cmc.TaggedRequest;
import org.mozilla.jss.pkix.crmf.CertReqMsg;
@@ -37,6 +35,10 @@ import com.netscape.certsrv.property.IDescriptor;
import com.netscape.certsrv.request.IRequest;
import com.netscape.cms.profile.common.EnrollProfile;
+import netscape.security.pkcs.PKCS10;
+import netscape.security.util.DerInputStream;
+import netscape.security.x509.X509CertInfo;
+
/**
* This class implements the certificate request input.
* This input populates 2 main fields to the enrollment page:
@@ -89,13 +91,16 @@ public class CertReqInput extends EnrollInput implements IProfileInput {
*/
public void populate(IProfileContext ctx, IRequest request)
throws EProfileException {
+ String method = "CertReqInput: populate: ";
+ CMS.debug(method + "begins");
+
String cert_request_type = ctx.get(VAL_CERT_REQUEST_TYPE);
String cert_request = ctx.get(VAL_CERT_REQUEST);
X509CertInfo info =
request.getExtDataInCertInfo(EnrollProfile.REQUEST_CERTINFO);
if (cert_request_type == null) {
- CMS.debug("CertReqInput: populate - invalid cert request type " +
+ CMS.debug(method + "invalid cert request type " +
"");
throw new EProfileException(
CMS.getUserMessage(getLocale(request),
@@ -103,12 +108,14 @@ public class CertReqInput extends EnrollInput implements IProfileInput {
""));
}
if (cert_request == null) {
- CMS.debug("CertReqInput: populate - invalid certificate request");
+ CMS.debug(method + "invalid certificate request");
throw new EProfileException(CMS.getUserMessage(
getLocale(request), "CMS_PROFILE_NO_CERT_REQ"));
}
if (cert_request_type.equals(EnrollProfile.REQ_TYPE_PKCS10)) {
+ CMS.debug(method + "cert_request_type= REQ_TYPE_PKCS10");
+
PKCS10 pkcs10 = mEnrollProfile.parsePKCS10(getLocale(request), cert_request);
if (pkcs10 == null) {
@@ -118,6 +125,7 @@ public class CertReqInput extends EnrollInput implements IProfileInput {
mEnrollProfile.fillPKCS10(getLocale(request), pkcs10, info, request);
} else if (cert_request_type.startsWith(EnrollProfile.REQ_TYPE_KEYGEN)) {
+ CMS.debug(method + "cert_request_type= REQ_TYPE_KEYGEN");
DerInputStream keygen = mEnrollProfile.parseKeyGen(getLocale(request), cert_request);
if (keygen == null) {
@@ -127,6 +135,7 @@ public class CertReqInput extends EnrollInput implements IProfileInput {
mEnrollProfile.fillKeyGen(getLocale(request), keygen, info, request);
} else if (cert_request_type.startsWith(EnrollProfile.REQ_TYPE_CRMF)) {
+ CMS.debug(method + "cert_request_type= REQ_TYPE_CRMF");
CertReqMsg msgs[] = mEnrollProfile.parseCRMF(getLocale(request), cert_request);
if (msgs == null) {
@@ -142,7 +151,18 @@ public class CertReqInput extends EnrollInput implements IProfileInput {
mEnrollProfile.fillCertReqMsg(getLocale(request), msgs[seqNum.intValue()], info, request
);
} else if (cert_request_type.startsWith(EnrollProfile.REQ_TYPE_CMC)) {
- TaggedRequest msgs[] = mEnrollProfile.parseCMC(getLocale(request), cert_request);
+ CMS.debug(method + "cert_request_type= REQ_TYPE_CMC");
+ // cfu: getPKIDataFromCMCblob() is extracted from parseCMC
+ // so it's less confusing
+ //TaggedRequest msgs[] = mEnrollProfile.parseCMC(getLocale(request), cert_request);
+ PKIData pkiData = mEnrollProfile.getPKIDataFromCMCblob(getLocale(request), cert_request);
+ SEQUENCE reqSeq = pkiData.getReqSequence();
+ int nummsgs = reqSeq.size(); // for now we only handle one anyways
+ CMS.debug(method + "pkiData.getReqSequence() called; nummsgs =" + nummsgs);
+ TaggedRequest[] msgs = new TaggedRequest[reqSeq.size()];
+ for (int i = 0; i < nummsgs; i++) {
+ msgs[i] = (TaggedRequest) reqSeq.elementAt(i);
+ }
if (msgs == null) {
throw new EProfileException(CMS.getUserMessage(
@@ -159,7 +179,7 @@ public class CertReqInput extends EnrollInput implements IProfileInput {
mEnrollProfile.fillTaggedRequest(getLocale(request), msgs[seqNum.intValue()], info, request);
} else {
// error
- CMS.debug("CertReqInput: populate - invalid cert request type " +
+ CMS.debug(method + "invalid cert request type " +
cert_request_type);
throw new EProfileException(
CMS.getUserMessage(getLocale(request),
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 26ca2a4cc..1e128d0a2 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
@@ -39,6 +39,7 @@ import org.mozilla.jss.pkix.cmc.OtherInfo;
import org.mozilla.jss.pkix.cmc.TaggedAttribute;
import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthManager;
import com.netscape.certsrv.authentication.IAuthToken;
import com.netscape.certsrv.authorization.AuthzToken;
import com.netscape.certsrv.base.EBaseException;
@@ -443,6 +444,18 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
///////////////////////////////////////////////
// create request
///////////////////////////////////////////////
+ String tmpCertSerialS = ctx.get(IAuthManager.CRED_CMC_SIGNING_CERT);
+ if (tmpCertSerialS != null) {
+ // unlikely to happenm, but do this just in case
+ CMS.debug("ProfileSubmitCMCServlet: found existing CRED_CMC_SIGNING_CERT in ctx for CMCUserSignedAuth:" + tmpCertSerialS);
+ CMS.debug("ProfileSubmitCMCServlet: null it out");
+ ctx.set(IAuthManager.CRED_CMC_SIGNING_CERT, "");
+ }
+ String signingCertSerialS = (String) authToken.get(IAuthManager.CRED_CMC_SIGNING_CERT);
+ if (signingCertSerialS != null) {
+ CMS.debug("ProfileSubmitCMCServlet: setting CRED_CMC_SIGNING_CERT in ctx for CMCUserSignedAuth");
+ ctx.set(IAuthManager.CRED_CMC_SIGNING_CERT, signingCertSerialS);
+ }
try {
reqs = profile.createRequests(ctx, locale);
} catch (EProfileException e) {
@@ -512,7 +525,7 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
IRequest provedReq = null;
if (reqs == null) {
// handling DecryptedPOP request here
- Integer reqID = (Integer) context.get("decryptedPopReqId");
+ Integer reqID = (Integer) context.get("cmcDecryptedPopReqId");
provedReq = profile.getRequestQueue().findRequest(new RequestId(reqID.toString()));
if (provedReq == null) {
@@ -568,6 +581,19 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
}
}
}
+
+ tmpCertSerialS = reqs[k].getExtDataInString(IAuthManager.CRED_CMC_SIGNING_CERT);
+ if (tmpCertSerialS != null) {
+ // unlikely to happenm, but do this just in case
+ CMS.debug("ProfileSubmitCMCServlet: found existing CRED_CMC_SIGNING_CERT in request for CMCUserSignedAuth:" + tmpCertSerialS);
+ CMS.debug("ProfileSubmitCMCServlet: null it out");
+ reqs[k].setExtData(IAuthManager.CRED_CMC_SIGNING_CERT, "");
+ }
+ // put CMCUserSignedAuth authToken in request
+ if (signingCertSerialS != null) {
+ CMS.debug("ProfileSubmitCMCServlet: setting CRED_CMC_SIGNING_CERT in request for CMCUserSignedAuth");
+ reqs[k].setExtData(IAuthManager.CRED_CMC_SIGNING_CERT, signingCertSerialS);
+ }
}
// put profile framework parameters into the request