summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/ca/shared/conf/CS.cfg2
-rw-r--r--base/java-tools/src/com/netscape/cmstools/CMCRequest.java892
-rw-r--r--base/java-tools/src/com/netscape/cmstools/CMCResponse.java26
-rw-r--r--base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java7
-rw-r--r--base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java388
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java140
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java102
-rw-r--r--base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java70
8 files changed, 1300 insertions, 327 deletions
diff --git a/base/ca/shared/conf/CS.cfg b/base/ca/shared/conf/CS.cfg
index 2d7cb9895..e8003603b 100644
--- a/base/ca/shared/conf/CS.cfg
+++ b/base/ca/shared/conf/CS.cfg
@@ -731,7 +731,7 @@ 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.lraPopWitness.verify.allow=true
+cmc.lraPopWitness.verify.allow=false
cmc.revokeCert.verify=true
cmc.revokeCert.sharedSecret.class=com.netscape.cms.authentication.SharedSecret
cmc.sharedSecret.class=com.netscape.cms.authentication.SharedSecret
diff --git a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
index bca569bab..a2aca8ad1 100644
--- a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
+++ b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
@@ -31,6 +31,8 @@ import java.io.PrintStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
import java.util.Date;
import java.util.StringTokenizer;
@@ -50,22 +52,33 @@ import org.mozilla.jss.asn1.UTF8String;
import org.mozilla.jss.crypto.CryptoToken;
import org.mozilla.jss.crypto.DigestAlgorithm;
import org.mozilla.jss.crypto.ObjectNotFoundException;
+import org.mozilla.jss.crypto.PrivateKey;
import org.mozilla.jss.crypto.SignatureAlgorithm;
+import org.mozilla.jss.crypto.SymmetricKey;
import org.mozilla.jss.crypto.X509Certificate;
import org.mozilla.jss.pkcs10.CertificationRequest;
import org.mozilla.jss.pkix.cmc.CMCCertId;
+import org.mozilla.jss.pkix.cmc.CMCStatusInfo;
+import org.mozilla.jss.pkix.cmc.DecryptedPOP;
+import org.mozilla.jss.pkix.cmc.EncryptedPOP;
import org.mozilla.jss.pkix.cmc.GetCert;
import org.mozilla.jss.pkix.cmc.IdentityProofV2;
import org.mozilla.jss.pkix.cmc.LraPopWitness;
+import org.mozilla.jss.pkix.cmc.OtherInfo;
import org.mozilla.jss.pkix.cmc.OtherMsg;
import org.mozilla.jss.pkix.cmc.PKIData;
+import org.mozilla.jss.pkix.cmc.PendInfo;
+import org.mozilla.jss.pkix.cmc.ResponseBody;
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.cmmf.RevRequest;
import org.mozilla.jss.pkix.cms.ContentInfo;
import org.mozilla.jss.pkix.cms.EncapsulatedContentInfo;
+import org.mozilla.jss.pkix.cms.EncryptedContentInfo;
+import org.mozilla.jss.pkix.cms.EnvelopedData;
import org.mozilla.jss.pkix.cms.IssuerAndSerialNumber;
+import org.mozilla.jss.pkix.cms.RecipientInfo;
import org.mozilla.jss.pkix.cms.SignedData;
import org.mozilla.jss.pkix.cms.SignerIdentifier;
import org.mozilla.jss.pkix.cms.SignerInfo;
@@ -129,33 +142,31 @@ public class CMCRequest {
X509Certificate cert = getCertificate(tokenName, nickname);
if (cert != null)
- System.out.println("got signing cert");
+ System.out.println("getPrivateKey: got signing cert");
return CryptoManager.getInstance().findPrivKeyByCert(cert);
}
/**
- * getCMCBlob create and return the enrollment request.
- * <P>
+ * signData signs the request PKIData
*
* @param signerCert the certificate of the authorized signer of the CMC revocation request.
* @param nickname the nickname of the certificate inside the token.
- * @param rValue CRMF/PKCS10 request.
- * @param format either crmf or pkcs10
- * @return the CMC enrollment request encoded in base64
+ * @param pkidata the request PKIData to be signed
+ *
+ * @return the SignedData
+ *
*/
- static ContentInfo getCMCBlob(X509Certificate signerCert, String tokenName, String nickname,
- String[] rValue, String format, CryptoManager manager, String transactionMgtEnable,
- String transactionMgtId,
- String identificationEnable, String identification,
- String identityProofEnable, String identityProofSharedSecret,
- String identityProofV2Enable, String identityProofV2SharedSecret,
- String identityProofV2hashAlg, String identityProofV2macAlg,
- SEQUENCE controlSeq, SEQUENCE otherMsgSeq, int bpid) {
-
- System.out.println("in getCMCBlob");
+ static SignedData signData(
+ X509Certificate signerCert,
+ String tokenName,
+ String nickname,
+ CryptoManager manager,
+ PKIData pkidata) {
+ String method = "signData: ";
+ SignedData req = null;
+ System.out.println(method + "begins: ");
- ContentInfo fullEnrollmentReq = null;
try {
java.security.PrivateKey privKey = null;
SignerIdentifier si = null;
@@ -175,8 +186,122 @@ public class CMCRequest {
SignerIdentifier.ISSUER_AND_SERIALNUMBER, ias, null);
privKey = getPrivateKey(tokenName, nickname);
if (privKey != null)
- System.out.println("getCMCBlob: got privKey");
+ System.out.println(method + " got signer privKey");
+
+ EncapsulatedContentInfo ci = new EncapsulatedContentInfo(OBJECT_IDENTIFIER.id_cct_PKIData, pkidata);
+ DigestAlgorithm digestAlg = null;
+ SignatureAlgorithm signAlg = null;
+ org.mozilla.jss.crypto.PrivateKey.Type signingKeyType = ((org.mozilla.jss.crypto.PrivateKey) privKey)
+ .getType();
+ if (signingKeyType.equals(org.mozilla.jss.crypto.PrivateKey.Type.RSA)) {
+ signAlg = SignatureAlgorithm.RSASignatureWithSHA256Digest;
+ } else if (signingKeyType.equals(org.mozilla.jss.crypto.PrivateKey.Type.EC)) {
+ signAlg = SignatureAlgorithm.ECSignatureWithSHA256Digest;
+ } else {
+ System.out.println("Algorithm not supported");
+ return null;
+ }
+
+ MessageDigest SHADigest = null;
+
+ byte[] digest = null;
+ try {
+ SHADigest = MessageDigest.getInstance("SHA256");
+ digestAlg = DigestAlgorithm.SHA256;
+
+ ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+
+ pkidata.encode(ostream);
+ digest = SHADigest.digest(ostream.toByteArray());
+ } catch (NoSuchAlgorithmException e) {
+ System.out.println(e); System.exit(1);}
+ System.out.println(method + "digest created for pkidata");
+
+ SignerInfo signInfo = new SignerInfo(si, null, null, OBJECT_IDENTIFIER.id_cct_PKIData, digest, signAlg,
+ (org.mozilla.jss.crypto.PrivateKey) privKey);
+ SET signInfos = new SET();
+ signInfos.addElement(signInfo);
+
+ SET digestAlgs = new SET();
+
+ if (digestAlg != null) {
+ AlgorithmIdentifier ai = new AlgorithmIdentifier(digestAlg.toOID(), null);
+ digestAlgs.addElement(ai);
+ }
+
+ org.mozilla.jss.crypto.X509Certificate[] agentChain = manager.buildCertificateChain(signerCert);
+ SET certs = new SET();
+
+ for (int i = 0; i < agentChain.length; i++) {
+ ANY cert = new ANY(agentChain[i].getEncoded());
+ certs.addElement(cert);
+ }
+
+ req = new SignedData(digestAlgs, ci, certs, null, signInfos);
+ System.out.println(method + "signed request generated.");
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ return req;
+ }
+
+ /**
+ * getCMCBlob create and return the enrollment request.
+ *
+ * @return the CMC enrollment request encoded in base64
+ *
+ */
+ static ContentInfo getCMCBlob(SignedData req) {
+ String method = "getCMCBlob: ";
+ System.out.println(method + "begins");
+ ContentInfo fullEnrollmentReq = new ContentInfo(req);
+ try {
+ ByteArrayOutputStream bs = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(bs);
+
+ if (fullEnrollmentReq != null) {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ fullEnrollmentReq.encode(os);
+ ps.print(Utils.base64encode(os.toByteArray()));
+ }
+ String asciiBASE64Blob = bs.toString();
+
+ System.out.println("");
+ System.out.println("The CMC enrollment request in base-64 encoded format:");
+ System.out.println("");
+ System.out.println(asciiBASE64Blob);
+ } catch (Exception e) {
+ System.out.println(method + " Exception:" + e.toString());
+ System.exit(1);
+ }
+ return fullEnrollmentReq;
+ }
+
+ /**
+ * createPKIData creates PKIData
+ *
+ * @param rValue CRMF/PKCS10 request.
+ * @param format either crmf or pkcs10
+ * @return request in PKIData
+ */
+ static PKIData createPKIData(
+ String[] rValue, String format, String transactionMgtEnable,
+ String transactionMgtId,
+ String identificationEnable, String identification,
+ String identityProofEnable, String identityProofSharedSecret,
+ String identityProofV2Enable, String witnessSharedSecret,
+ String identityProofV2hashAlg, String identityProofV2macAlg,
+ SEQUENCE controlSeq, SEQUENCE otherMsgSeq, int bpid) {
+
+ String method = "createPKIData: ";
+
+ System.out.println(method + "begins");
+ PKIData pkidata = null;
+
+ try {
TaggedRequest trq = null;
PKCS10 pkcs = null;
CertReqMsg certReqMsg = null;
@@ -185,20 +310,18 @@ public class CMCRequest {
SEQUENCE reqSequence = new SEQUENCE();
try {
for (int k = 0; k < rValue.length; k++) {
- System.out.println("k="+ k);
+ System.out.println("k=" + k);
String asciiBASE64Blob = rValue[k];
byte[] decodedBytes = Utils.base64decode(asciiBASE64Blob);
if (format.equals("crmf")) {
- System.out.println("getCMCBlob: format: crmf");
- ByteArrayInputStream reqBlob =
- new ByteArrayInputStream(decodedBytes);
+ System.out.println(method + " format: crmf");
+ ByteArrayInputStream reqBlob = new ByteArrayInputStream(decodedBytes);
SEQUENCE crmfMsgs = null;
try {
- crmfMsgs = (SEQUENCE) new SEQUENCE.OF_Template(new
- CertReqMsg.Template()).decode(reqBlob);
+ crmfMsgs = (SEQUENCE) new SEQUENCE.OF_Template(new CertReqMsg.Template()).decode(reqBlob);
} catch (InvalidBERException ee) {
- System.out.println("getCMCBlob: This is not a crmf request. Or this request has an error.");
+ System.out.println(method + " This is not a crmf request. Or this request has an error.");
System.exit(1);
}
certReqMsg = (CertReqMsg) crmfMsgs.elementAt(0);
@@ -208,25 +331,24 @@ public class CMCRequest {
try {
pkcs = new PKCS10(decodedBytes, true);
} catch (Exception e2) {
- System.out.println("getCMCBlob: Excception:"+e2.toString());
+ System.out.println(method + " Excception:" + e2.toString());
System.exit(1);
}
ByteArrayInputStream crInputStream = new ByteArrayInputStream(
pkcs.toByteArray());
- CertificationRequest cr = (CertificationRequest)
- CertificationRequest.getTemplate().decode(crInputStream);
+ CertificationRequest cr = (CertificationRequest) CertificationRequest.getTemplate()
+ .decode(crInputStream);
TaggedCertificationRequest tcr = new TaggedCertificationRequest(
new INTEGER(bpid++), cr);
- trq = new
- TaggedRequest(TaggedRequest.PKCS10, tcr, null);
+ trq = new TaggedRequest(TaggedRequest.PKCS10, tcr, null);
} else {
- System.out.println("getCMCBlob: Unrecognized request format: " + format);
+ System.out.println(method + " Unrecognized request format: " + format);
System.exit(1);
}
reqSequence.addElement(trq);
}
} catch (Exception e) {
- System.out.println("getCMCBlob: Exception:"+ e.toString());
+ System.out.println(method + " Exception:" + e.toString());
System.exit(1);
}
@@ -242,7 +364,7 @@ public class CMCRequest {
// if both, V2 takes precedence
if (identityProofV2Enable.equals("true")) {
bpid = addIdentityProofV2Attr(bpid, controlSeq, reqSequence,
- identityProofV2SharedSecret,
+ witnessSharedSecret,
(identificationEnable.equals("true")) ? identification : null,
identityProofV2hashAlg, identityProofV2macAlg);
} else if (identityProofEnable.equals("true")) {
@@ -250,77 +372,12 @@ public class CMCRequest {
identityProofSharedSecret);
}
- PKIData pkidata = new PKIData(controlSeq, reqSequence, new SEQUENCE(), otherMsgSeq);
-
- EncapsulatedContentInfo ci = new
- EncapsulatedContentInfo(OBJECT_IDENTIFIER.id_cct_PKIData, pkidata);
- // SHA1 is the default digest Alg for now.
- DigestAlgorithm digestAlg = null;
- SignatureAlgorithm signAlg = null;
- org.mozilla.jss.crypto.PrivateKey.Type signingKeyType = ((org.mozilla.jss.crypto.PrivateKey) privKey).getType();
- if (signingKeyType.equals(org.mozilla.jss.crypto.PrivateKey.Type.RSA)) {
- signAlg = SignatureAlgorithm.RSASignatureWithSHA1Digest;
- } else if (signingKeyType.equals(org.mozilla.jss.crypto.PrivateKey.Type.EC)) {
- signAlg = SignatureAlgorithm.ECSignatureWithSHA1Digest;
- } else if (signingKeyType.equals(org.mozilla.jss.crypto.PrivateKey.Type.DSA)) {
- signAlg = SignatureAlgorithm.DSASignatureWithSHA1Digest;
- }
-
- MessageDigest SHADigest = null;
-
- byte[] digest = null;
- try {
- SHADigest = MessageDigest.getInstance("SHA1");
- digestAlg = DigestAlgorithm.SHA1;
-
- ByteArrayOutputStream ostream = new ByteArrayOutputStream();
-
- pkidata.encode(ostream);
- digest = SHADigest.digest(ostream.toByteArray());
- } catch (NoSuchAlgorithmException e) {
- }
- SignerInfo signInfo = new
- SignerInfo(si, null, null, OBJECT_IDENTIFIER.id_cct_PKIData, digest, signAlg,
- (org.mozilla.jss.crypto.PrivateKey) privKey);
- SET signInfos = new SET();
- signInfos.addElement(signInfo);
-
- SET digestAlgs = new SET();
-
- if (digestAlg != null) {
- AlgorithmIdentifier ai = new AlgorithmIdentifier(digestAlg.toOID(), null);
- digestAlgs.addElement(ai);
- }
-
- org.mozilla.jss.crypto.X509Certificate[] agentChain = manager.buildCertificateChain(signerCert);
- SET certs = new SET();
-
- for (int i = 0; i < agentChain.length; i++) {
- ANY cert = new ANY(agentChain[i].getEncoded());
- certs.addElement(cert);
- }
- SignedData req = new SignedData(digestAlgs, ci, certs, null, signInfos);
- fullEnrollmentReq = new ContentInfo(req);
- ByteArrayOutputStream bs = new ByteArrayOutputStream();
- PrintStream ps = new PrintStream(bs);
-
- if (fullEnrollmentReq != null) {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
-
- fullEnrollmentReq.encode(os);
- ps.print(Utils.base64encode(os.toByteArray()));
- }
- String asciiBASE64Blob = bs.toString();
-
- System.out.println("");
- System.out.println("The CMC enrollment request in base-64 encoded format:");
- System.out.println("");
- System.out.println(asciiBASE64Blob);
+ pkidata = new PKIData(controlSeq, reqSequence, new SEQUENCE(), otherMsgSeq);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
- return fullEnrollmentReq;
+ return pkidata;
}
static void printUsage() {
@@ -330,16 +387,29 @@ public class CMCRequest {
System.out.println("");
System.out.println("The configuration file should look like as follows:");
System.out.println("");
+ System.out.println("#decryptedPop.enable: if true, this is in response to an encryptedPOP request from the server from previous request;");
+ System.out.println("# most all options other than the following are ignored:");
+ System.out.println("# encryptedPopResponseFile, privKeyId, decryptedPopRequestFile");
+ System.out.println("# where");
+ System.out.println("# encryptPopResponse was the output from previous request, and is now an input to the new request that is about to be generated");
+ System.out.println("# decryptedPopRequestFile is the output that is to be sent to the server as 2nd trip request in response to encryptedPOP");
+ System.out.println("# privKeyId: used for decrypting the encryptedPOP and creating decryptedPOP");
+ System.out.println("");
+ System.out.println("decryptedPop.enable=false");
+ System.out.println("encryptedPopResponseFile=cmc.resp");
+ System.out.println("request.privKeyId=");
+ System.out.println("decryptedPopRequestFile=cmc.decreyptedPOP.req");
+ System.out.println("");
System.out.println("#numRequests: Total number of PKCS10 requests or CRMF requests.");
System.out.println("numRequests=1");
System.out.println("");
System.out.println("#input: full path for the PKCS10 request or CRMF request,");
System.out.println("#the content must be in Base-64 encoded format");
System.out.println("#Multiple files are supported. They must be separated by space.");
- System.out.println("input=crmf1");
+ System.out.println("input=crmf.req");
System.out.println("");
System.out.println("#output: full path for the CMC request in binary format");
- System.out.println("output=/u/doc/cmcReq");
+ System.out.println("output=cmc.req");
System.out.println("");
System.out.println("#tokenname: name of token where agent signing cert can be found (default is internal)");
System.out.println("tokenname=internal");
@@ -349,7 +419,7 @@ public class CMCRequest {
System.out.println("nickname=CMS Agent Certificate");
System.out.println("");
System.out.println("#dbdir: directory for cert8.db, key3.db and secmod.db");
- System.out.println("dbdir=/u/smith/.netscape");
+ System.out.println("dbdir=./");
System.out.println("");
System.out.println("#password: password for cert8.db which stores the agent");
System.out.println("#certificate");
@@ -360,7 +430,7 @@ public class CMCRequest {
System.out.println("");
System.out.println("#confirmCertAcceptance.enable: if true, then the request will");
System.out.println("#contain this control. Otherwise, false.");
- System.out.println("confirmCertAcceptance.enable=true");
+ System.out.println("confirmCertAcceptance.enable=false");
System.out.println("");
System.out.println("#confirmCertAcceptance.serial: The serial number for");
System.out.println("#confirmCertAcceptance control");
@@ -372,7 +442,7 @@ public class CMCRequest {
System.out.println("");
System.out.println("#getCert.enable: if true, then the request will contain this");
System.out.println("#control. Otherwise, false.");
- System.out.println("getCert.enable=true");
+ System.out.println("getCert.enable=false");
System.out.println("");
System.out.println("#getCert.serial: The serial number for getCert control");
System.out.println("getCert.serial=3");
@@ -382,14 +452,14 @@ public class CMCRequest {
System.out.println("");
System.out.println("#dataReturn.enable: if true, then the request will contain");
System.out.println("#this control. Otherwise, false.");
- System.out.println("dataReturn.enable=true");
+ System.out.println("dataReturn.enable=false");
System.out.println("");
System.out.println("#dataReturn.data: data contained in the control.");
System.out.println("dataReturn.data=test");
System.out.println("");
System.out.println("#transactionMgt.enable: if true, then the request will contain");
System.out.println("#this control. Otherwise, false.");
- System.out.println("transactionMgt.enable=true");
+ System.out.println("transactionMgt.enable=false");
System.out.println("");
System.out.println("#transactionMgt.id: transaction identifier. Verisign recommend");
System.out.println("#transactionId to be MD5 hash of publicKey.");
@@ -397,14 +467,14 @@ public class CMCRequest {
System.out.println("");
System.out.println("#senderNonce.enable: if true, then the request will contain this");
System.out.println("#control. Otherwise, false.");
- System.out.println("senderNonce.enable=true");
+ System.out.println("senderNonce.enable=false");
System.out.println("");
System.out.println("#senderNonce.id: sender nonce");
System.out.println("senderNonce.id=");
System.out.println("");
System.out.println("#revRequest.enable: if true, then the request will contain this");
System.out.println("#control. Otherwise, false.");
- System.out.println("revRequest.enable=true");
+ System.out.println("revRequest.enable=false");
System.out.println("");
System.out.println("#revRequest.nickname: The nickname for the revoke certificate");
System.out.println("revRequest.nickname=newuser's 102504a ID");
@@ -439,15 +509,15 @@ public class CMCRequest {
System.out.println("#Note that if both identityProof and identityProofV2");
System.out.println("# are enabled, identityProofV2 takes precedence; Only one of them can be active at a time");
System.out.println("#Supported hashAlg are:");
- System.out.println("# SHA-1, SHA-256, SHA-384, and SHA-512");
+ System.out.println("# SHA-256, SHA-384, and SHA-512");
System.out.println("#Supported macAlg are:");
- System.out.println("# SHA-1-HMAC, SHA-256-HMAC, SHA-384-HMAC, and SHA-512-HMAC");
+ System.out.println("# SHA-256-HMAC, SHA-384-HMAC, and SHA-512-HMAC");
System.out.println("identityProofV2.enable=false");
System.out.println("identityProofV2.hashAlg=SHA-256");
System.out.println("identityProofV2.macAlg=SHA-256-HMAC");
System.out.println("");
- System.out.println("#identityProofV2.sharedSecret: Shared Secret");
- System.out.println("identityProofV2.sharedSecret=testing");
+ System.out.println("#witness.sharedSecret: Shared Secret");
+ System.out.println("witness.sharedSecret=testing");
System.out.println("");
System.out.println("#identification works with identityProofV2");
System.out.println("identification.enable=false");
@@ -471,7 +541,7 @@ public class CMCRequest {
System.out.println("");
System.out.println("#LraPopWitness.enable: if true, then the request will contain this");
System.out.println("#control. Otherwise, false.");
- System.out.println("LraPopWitness.enable=true");
+ System.out.println("LraPopWitness.enable=false");
System.out.println("");
System.out.println("#LraPopWitness.bodyPartIDs: List of body part IDs");
System.out.println("#Each id is separated by space.");
@@ -550,7 +620,7 @@ public class CMCRequest {
* @param sharedSecret shared secret
* @param hashAlgString hash algorithm
* @param macAlgString mac algorithm
- * cfu
+ * @author cfu
*/
private static int addIdentityProofV2Attr(int bpid,
SEQUENCE seq, SEQUENCE reqSequence,
@@ -926,7 +996,7 @@ public class CMCRequest {
* @param seq
* @param ident
* @return
- * cfu
+ * @author cfu
*/
private static int addIdentificationAttr(int bpid, SEQUENCE seq, String ident) {
UTF8String ident_s = null;
@@ -973,11 +1043,273 @@ public class CMCRequest {
return bpid;
}
+ /**
+ * processEncryptedPopResponse parses previous CMC response
+ * and returns the encryptedPop
+ *
+ * @param prevResponse file
+ * @param privKey
+ * @return encryptedPop and reqIdString in Object[]
+ * @author cfu
+ */
+ private static Object[] processEncryptedPopResponse(
+ String prevResponse) {
+ // the values to be returned
+ EncryptedPOP encryptedPop = null;
+ String reqIdString = null; // capture the requestId;
+
+ String method = "processEncryptedPopResponse: ";
+ System.out.println(method + " begins.");
+
+ byte[] bb = new byte[10000];
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(prevResponse);
+ while (fis.available() > 0)
+ fis.read(bb, 0, 10000);
+ } catch (Exception e) {
+ System.out.println(method + "Error reading the response. Exception: " + e.toString());
+ System.exit(1);
+ }
+ System.out.println(method + " previous response read.");
+
+ org.mozilla.jss.pkix.cms.SignedData cmcFullResp = null;
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(bb);
+ org.mozilla.jss.pkix.cms.ContentInfo cii = (org.mozilla.jss.pkix.cms.ContentInfo) org.mozilla.jss.pkix.cms.ContentInfo
+ .getTemplate().decode(bis);
+
+ cmcFullResp = (org.mozilla.jss.pkix.cms.SignedData) cii.getInterpretedContent();
+ EncapsulatedContentInfo ci = cmcFullResp.getContentInfo();
+ OBJECT_IDENTIFIER id = ci.getContentType();
+ OBJECT_IDENTIFIER dataid = new OBJECT_IDENTIFIER("1.2.840.113549.1.7.1");
+ if (!id.equals(OBJECT_IDENTIFIER.id_cct_PKIResponse) && !id.equals(dataid)) {
+ System.out.println(method + "Invalid CMC Response Format");
+ }
+
+ if (!ci.hasContent())
+ return null;
+
+ OCTET_STRING content1 = ci.getContent();
+ ByteArrayInputStream bbis = new ByteArrayInputStream(content1.toByteArray());
+ ResponseBody responseBody = (ResponseBody) (new ResponseBody.Template()).decode(bbis);
+ SEQUENCE controlSequence = responseBody.getControlSequence();
+ int numControls = controlSequence.size();
+ System.out.println(method + "Number of controls is " + numControls);
+
+ for (int i = 0; i < numControls; i++) {
+ TaggedAttribute taggedAttr = (TaggedAttribute) controlSequence.elementAt(i);
+ OBJECT_IDENTIFIER type = taggedAttr.getType();
+
+ if (type.equals(OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo)) {
+ System.out.println(method + "Control #" + i + ": CMCStatusInfo");
+ System.out.println(method + " OID: " + type.toString());
+ SET sts = taggedAttr.getValues();
+ int numSts = sts.size();
+ for (int j = 0; j < numSts; j++) {
+ CMCStatusInfo cst = (CMCStatusInfo) ASN1Util.decode(CMCStatusInfo.getTemplate(),
+ ASN1Util.encode(sts.elementAt(j)));
+ SEQUENCE seq = cst.getBodyList();
+ StringBuilder s = new StringBuilder(" BodyList: ");
+ for (int k = 0; k < seq.size(); k++) {
+ INTEGER n = (INTEGER) seq.elementAt(k);
+ s.append(n.toString() + " ");
+ }
+ System.out.println(method + s);
+ int st = cst.getStatus();
+ if (st != CMCStatusInfo.SUCCESS && st != CMCStatusInfo.CONFIRM_REQUIRED) {
+ String stString = cst.getStatusString();
+ if (stString != null)
+ System.out.println(method + " Status String: " + stString);
+ OtherInfo oi = cst.getOtherInfo();
+ OtherInfo.Type t = oi.getType();
+ if (t == OtherInfo.FAIL) {
+ System.out.println(method + " OtherInfo type: FAIL");
+ System.out.println(method
+ + " not what we expected, because encryptedPOP.enable is true!!!! exit now");
+ System.exit(1);
+ } else if (t == OtherInfo.PEND) {
+ System.out.println(method + " OtherInfo type: PEND");
+ PendInfo pi = oi.getPendInfo();
+ if (pi == null) {
+ System.out.println(method + "PendInfo null...skipping");
+ continue;
+ } else
+ System.out.println(method + "PendInfo present...processing...");
+ if (pi.getPendTime() != null) {
+ String datePattern = "dd/MMM/yyyy:HH:mm:ss z";
+ SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);
+ Date d = pi.getPendTime().toDate();
+ System.out.println(method + " Date: " + dateFormat.format(d));
+ }
+ OCTET_STRING pendToken = pi.getPendToken();
+ if (pendToken != null) {
+ byte reqId[] = pendToken.toByteArray();
+ reqIdString = new String(reqId);
+ System.out.println(method + " Pending request id: " + reqIdString);
+ } else {
+ System.out.println(method + "missing pendToken in response");
+ System.exit(1);
+ }
+ System.out.println(method + " what we expected, as encryptedPOP.enable is true;");
+ }
+ } else if (st == CMCStatusInfo.SUCCESS) {
+ System.out.println(method + " Status: SUCCESS");
+ System.out.println(
+ method + " not what we expected, because encryptedPOP.enable is true!!!! exit now");
+ System.exit(1);
+ }
+ }
+ } else if (type.equals(OBJECT_IDENTIFIER.id_cmc_encryptedPOP)) {
+ // bingo
+ System.out.println(method + "Control #" + i + ": CMC encrypted POP");
+ System.out.println(method + " OID: " + type.toString());
+ SET encryptedPOPvals = taggedAttr.getValues();
+
+ encryptedPop = (EncryptedPOP) (ASN1Util.decode(EncryptedPOP.getTemplate(),
+ ASN1Util.encode(encryptedPOPvals.elementAt(0))));
+ System.out.println(method + "encryptedPOP decoded successfully");
+
+ } // we don't expect any other controls
+ } //for
+ } catch (Exception e) {
+ System.out.println(method + e);
+ System.exit(1);
+ }
+
+ System.out.println(method + "ends");
+ return new Object[] { encryptedPop, reqIdString };
+ }
+
+ /**
+ * constructDecryptedPopRequest constructs request PKIData for DecryptedPOP
+ *
+ * @param encryptedPopInfo {EncryptedPOP, reqIdString}
+ * @param privKey
+ * @return request PKIData
+ * @author cfu
+ */
+ private static PKIData constructDecryptedPopRequest(
+ Object[] encryptedPopInfo,
+ String tokenName,
+ PrivateKey privKey) {
+ PKIData pkidata = null;
+ DecryptedPOP decryptedPop = null;
+
+ String method = "constructDecryptedPopRequest: ";
+ System.out.println(method + "begins");
+ if ((encryptedPopInfo == null) || (privKey == null)) {
+ System.out.println(method + "input params encryptedPopInfo and privKey cannot be null");
+ System.exit(1);
+ }
+
+ EncryptedPOP encryptedPop = (EncryptedPOP) encryptedPopInfo[0];
+ String reqIdString = (String) encryptedPopInfo[1];
+ if ((encryptedPop == null) || (reqIdString == null)) {
+ System.out.println(method + "encryptedPopInfo content encryptedPop and reqIdString cannot be null");
+ System.exit(1);
+ }
+
+ try {
+ TaggedRequest request = encryptedPop.getRequest();
+ AlgorithmIdentifier thePOPAlgID = encryptedPop.getThePOPAlgID();
+ AlgorithmIdentifier witnessAlgID = encryptedPop.getWitnessAlgID();
+ OCTET_STRING witness = encryptedPop.getWitness();
+ ContentInfo cms = encryptedPop.getContentInfo();
+ EnvelopedData envData = (EnvelopedData) cms.getInterpretedContent();
+ EncryptedContentInfo encCI = envData.getEncryptedContentInfo();
+ SET recipients = envData.getRecipientInfos();
+ RecipientInfo recipient = (RecipientInfo) (ASN1Util.decode(RecipientInfo.getTemplate(),
+ ASN1Util.encode(recipients.elementAt(0))));
+ System.out.println(method + " previous response parsed.");
+
+ CryptoToken token = CryptoUtil.getKeyStorageToken(tokenName);
+ SymmetricKey symKey = CryptoUtil.unwrap(
+ token,
+ SymmetricKey.Usage.DECRYPT,
+ privKey,
+ recipient.getEncryptedKey().toByteArray());
+ if (symKey == null) {
+ System.out.println(method + "symKey returned null from CryptoUtil.unwrap(). Abort!");
+ System.exit(1);
+ }
+ System.out.println(method + "symKey unwrapped.");
+
+ byte challenge[] = CryptoUtil.decryptUsingSymmetricKey(
+ token,
+ encCI.getEncryptedContent().toByteArray(),
+ symKey);
+ if (challenge == null) {
+ System.out
+ .println(method + "challenge returned null from CryptoUtil.decryptUsingSymmetricKey(). Abort!");
+ System.exit(1);
+ }
+ System.out.println(method + "challenge decrypted.");
+
+ // now verify the witness
+ try {
+ MessageDigest hash = MessageDigest.getInstance(CryptoUtil.getNameFromHashAlgorithm(witnessAlgID));
+ byte[] digest = hash.digest(challenge);
+ boolean witnessChecked = Arrays.equals(digest, witness.toByteArray());
+ if (witnessChecked) {
+ System.out.println(method + "Yay! witness verified");
+ } else {
+ System.out.println(method + "Oops! witness failed to verify. Must abort!");
+ System.exit(1);
+ }
+ } catch (Exception ex) {
+ System.out.println(method + ex);
+ System.exit(1);
+ }
+
+ // now calculate the POP Proof Value
+ byte[] popProofValue = null;
+ try {
+ System.out.println(method + "calculating POP Proof Value");
+ MessageDigest SHA2Digest = MessageDigest.getInstance("SHA256");
+ HMACDigest hmacDigest = new HMACDigest(SHA2Digest, challenge);
+ hmacDigest.update(ASN1Util.encode(request));
+ popProofValue = hmacDigest.digest();
+ } catch (Exception ex) {
+ System.out.println(method + "calculating POP Proof Value failed: " + ex);
+ System.exit(1);
+ }
+
+ int bpid = 1;
+ // now construct DecryptedPOP
+ System.out.println(method + "constructing DecryptedPOP...");
+ decryptedPop = new DecryptedPOP(new INTEGER(reqIdString), thePOPAlgID, new OCTET_STRING(popProofValue));
+ System.out.println(method + "DecryptedPOP constructed successfully");
+ System.out.println(method + "adding decryptedPop control");
+ TaggedAttribute decPop = new TaggedAttribute(new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_decryptedPOP,
+ decryptedPop);
+
+ SEQUENCE reqSequence = new SEQUENCE();
+ reqSequence.addElement(request); //stuff original req
+
+ SEQUENCE controlSeq = new SEQUENCE();
+ controlSeq.addElement(decPop);
+ System.out.println(method + "decryptedPop control added");
+
+ SEQUENCE otherMsgSeq = new SEQUENCE();
+
+ pkidata = new PKIData(controlSeq, reqSequence, new SEQUENCE(), otherMsgSeq);
+ } catch (Exception e) {
+ System.out.println(method + e);
+ System.exit(1);
+ }
+
+ System.out.println(method + " completes.");
+ return pkidata;
+ }
+
public static void main(String[] s) {
String numRequests = null;
String dbdir = null, nickname = null;
String tokenName = null;
String ifilename = null, ofilename = null, password = null, format = null;
+ String decryptedPopEnable = "false", encryptedPopResponseFile=null, privKeyId = null, decryptedPopRequestFile= null;
String confirmCertEnable = "false", confirmCertIssuer = null, confirmCertSerial = null;
String getCertEnable = "false", getCertIssuer = null, getCertSerial = null;
String dataReturnEnable = "false", dataReturnData = null;
@@ -989,7 +1321,7 @@ public class CMCRequest {
String revRequestInvalidityDatePresent = "false";
String identificationEnable = "false", identification = null;
String identityProofEnable = "false", identityProofSharedSecret = null;
- String identityProofV2Enable = "false", identityProofV2SharedSecret = null, identityProofV2hashAlg = "SHA256", identityProofV2macAlg = "SHA256";
+ String identityProofV2Enable = "false", witnessSharedSecret = null, identityProofV2hashAlg = "SHA256", identityProofV2macAlg = "SHA256";
String popLinkWitnessEnable = "false";
String bodyPartIDs = null, lraPopWitnessEnable = "false";
@@ -1046,6 +1378,14 @@ public class CMCRequest {
ofilename = val;
} else if (name.equals("input")) {
ifilename = val;
+ } else if (name.equals("decryptedPop.enable")) {
+ decryptedPopEnable = val;
+ } else if (name.equals("encryptedPopResponseFile")) {
+ encryptedPopResponseFile = val;
+ } else if (name.equals("request.privKeyId")) {
+ privKeyId = val;
+ } else if (name.equals("decryptedPopRequestFile")) {
+ decryptedPopRequestFile = val;
} else if (name.equals("confirmCertAcceptance.serial")) {
confirmCertSerial = val;
} else if (name.equals("confirmCertAcceptance.issuer")) {
@@ -1092,8 +1432,8 @@ public class CMCRequest {
identification = val;
} else if (name.equals("identityProofV2.enable")) {
identityProofV2Enable = val;
- } else if (name.equals("identityProofV2.sharedSecret")) {
- identityProofV2SharedSecret = val;
+ } else if (name.equals("witness.sharedSecret")) {
+ witnessSharedSecret = val;
} else if (name.equals("identityProofV2.hashAlg")) {
identityProofV2hashAlg = val;
} else if (name.equals("identityProofV2.macAlg")) {
@@ -1118,45 +1458,6 @@ public class CMCRequest {
printUsage();
}
- if (ifilename == null) {
- System.out.println("Missing input filename for PKCS10 or CRMF.");
- printUsage();
- }
-
- int num = 0;
- if (numRequests == null) {
- System.out.println("Missing numRequests.");
- printUsage();
- } else {
- try {
- num = Integer.parseInt(numRequests);
- } catch (Exception ee) {
- System.out.println("numRequests must be integer");
- System.exit(1);
- }
- }
-
- StringTokenizer tokenizer = new StringTokenizer(ifilename, " ");
- String[] ifiles = new String[num];
- for (int i = 0; i < num; i++) {
- String ss = tokenizer.nextToken();
- ifiles[i] = ss;
- if (ss == null) {
- System.out.println("Missing input file for the request.");
- System.exit(1);
- }
- }
-
- if (ofilename == null) {
- System.out.println("Missing output filename for the CMC request.");
- printUsage();
- }
-
- if (format == null) {
- System.out.println("Missing format.");
- printUsage();
- }
-
if (password == null) {
System.out.println("Missing password.");
printUsage();
@@ -1214,116 +1515,223 @@ public class CMCRequest {
System.out.println("got signerCert: "+ certname.toString());
}
- String[] requests = new String[num];
- for (int i = 0; i < num; i++) {
- BufferedReader inputBlob = null;
- try {
- inputBlob = new BufferedReader(new InputStreamReader(
- new BufferedInputStream(new FileInputStream(ifiles[i]))));
- } catch (FileNotFoundException e) {
- System.out.println("CMCRequest: can't find file " +
- ifiles[i] + ":\n" + e);
- } catch (Exception e) {
- e.printStackTrace();
- System.exit(1);
- }
- // (3) Read the entire contents of the specified BASE 64 encoded
- // blob into a String() object throwing away any
- // headers beginning with HEADER and any trailers beginning
- // with TRAILER
- String asciiBASE64BlobChunk = "";
- StringBuffer asciiBASE64Blob = new StringBuffer();
-
- try {
- while ((asciiBASE64BlobChunk = inputBlob.readLine()) != null) {
- if (!(asciiBASE64BlobChunk.startsWith(HEADER)) &&
- !(asciiBASE64BlobChunk.startsWith(TRAILER))) {
- asciiBASE64Blob.append(asciiBASE64BlobChunk.trim());
- }
+ //cfu
+ ContentInfo cmcblob = null;
+ PKIData pkidata = null;
+ if (decryptedPopEnable.equalsIgnoreCase("true")) {
+ PrivateKey privk = null;
+ if (privKeyId == null) {
+ System.out.println("ecryptedPop.enable = true, but privKeyId not specified.");
+ printUsage();
+ } else {
+ System.out.println("got privKeyId: " + privKeyId);
+
+ byte[] keyIDb = CryptoUtil.string2byte(privKeyId);
+
+ privk = CryptoUtil.findPrivateKeyFromID(keyIDb);
+
+ if (privk != null) {
+ System.out.println("got private key");
+ // now we can use this to decrypt encryptedPOP
+ } else {
+ System.out.println("error getting private key null");
+ System.exit(1);
}
- requests[i] = asciiBASE64Blob.toString();
- } catch (IOException e) {
- System.out.println("CMCRequest: Unexpected BASE64 " +
- "encoded error encountered in readLine():\n" +
- e);
}
- // (4) Close the DataInputStream() object
- try {
- inputBlob.close();
- } catch (IOException e) {
- System.out.println("CMCRequest(): Unexpected BASE64 " +
- "encoded error encountered in close():\n" + e);
+
+ if (encryptedPopResponseFile == null) {
+ System.out.println("ecryptedPop.enable = true, but encryptedPopResponseFile is not specified.");
+ printUsage();
}
- }
- SEQUENCE controlSeq = new SEQUENCE();
- int bpid = 1;
- if (confirmCertEnable.equalsIgnoreCase("true")) {
- if (confirmCertIssuer.length() == 0 || confirmCertSerial.length() == 0) {
- System.out.println("Illegal parameters for confirm certificate acceptance control");
+ if (decryptedPopRequestFile == null) {
+ System.out.println("ecryptedPop.enable = true, but decryptedPopRequestFile is not specified.");
printUsage();
+ }
+ ofilename = decryptedPopRequestFile;
+
+ // now start processing decryptedPOP
+ Object[] encryptedPopInfo = processEncryptedPopResponse(encryptedPopResponseFile);
+ if (encryptedPopInfo == null) {
+ System.out.println("processEncryptedPopResponse() returns null");
System.exit(1);
}
- bpid = addConfirmCertAttr(bpid, controlSeq, confirmCertIssuer, confirmCertSerial);
- }
+ pkidata = constructDecryptedPopRequest(encryptedPopInfo, tokenName, privk);
- if (lraPopWitnessEnable.equalsIgnoreCase("true")) {
- if (bodyPartIDs.length() == 0) {
- System.out.println("Illegal parameters for Lra Pop Witness control");
- printUsage();
+ if (pkidata == null) {
+ System.out.println("after constructDecryptedPopRequest, pkidata null. no good");
System.exit(1);
}
+ } else { // !decryptedPopEnable
- bpid = addLraPopWitnessAttr(bpid, controlSeq, bodyPartIDs);
- }
+ if (ifilename == null) {
+ System.out.println("Missing input filename for PKCS10 or CRMF.");
+ printUsage();
+ }
- if (getCertEnable.equalsIgnoreCase("true")) {
- if (getCertIssuer.length() == 0 || getCertSerial.length() == 0) {
- System.out.println("Illegal parameters for get certificate control");
+ int num = 0;
+ if (numRequests == null) {
+ System.out.println("Missing numRequests.");
printUsage();
- System.exit(1);
+ } else {
+ try {
+ num = Integer.parseInt(numRequests);
+ } catch (Exception ee) {
+ System.out.println("numRequests must be integer");
+ System.exit(1);
+ }
}
- bpid = addGetCertAttr(bpid, controlSeq, getCertIssuer, getCertSerial);
- }
+ StringTokenizer tokenizer = new StringTokenizer(ifilename, " ");
+ String[] ifiles = new String[num];
+ for (int i = 0; i < num; i++) {
+ String ss = tokenizer.nextToken();
+ ifiles[i] = ss;
+ if (ss == null) {
+ System.out.println("Missing input file for the request.");
+ System.exit(1);
+ }
+ }
- if (dataReturnEnable.equalsIgnoreCase("true")) {
- if (dataReturnData.length() == 0) {
- System.out.println("Illegal parameters for data return control");
+ if (ofilename == null) {
+ System.out.println("Missing output filename for the CMC request.");
printUsage();
- System.exit(1);
}
- bpid = addDataReturnAttr(bpid, controlSeq, dataReturnData);
- }
+ if (format == null) {
+ System.out.println("Missing format.");
+ printUsage();
+ }
+ String[] requests = new String[num];
+ for (int i = 0; i < num; i++) {
+ BufferedReader inputBlob = null;
+ try {
+ inputBlob = new BufferedReader(new InputStreamReader(
+ new BufferedInputStream(new FileInputStream(ifiles[i]))));
+ } catch (FileNotFoundException e) {
+ System.out.println("CMCRequest: can't find file " +
+ ifiles[i] + ":\n" + e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ // (3) Read the entire contents of the specified BASE 64 encoded
+ // blob into a String() object throwing away any
+ // headers beginning with HEADER and any trailers beginning
+ // with TRAILER
+ String asciiBASE64BlobChunk = "";
+ StringBuffer asciiBASE64Blob = new StringBuffer();
+
+ try {
+ while ((asciiBASE64BlobChunk = inputBlob.readLine()) != null) {
+ if (!(asciiBASE64BlobChunk.startsWith(HEADER)) &&
+ !(asciiBASE64BlobChunk.startsWith(TRAILER))) {
+ asciiBASE64Blob.append(asciiBASE64BlobChunk.trim());
+ }
+ }
+ requests[i] = asciiBASE64Blob.toString();
+ } catch (IOException e) {
+ System.out.println("CMCRequest: Unexpected BASE64 " +
+ "encoded error encountered in readLine():\n" +
+ e);
+ }
+ // (4) Close the DataInputStream() object
+ try {
+ inputBlob.close();
+ } catch (IOException e) {
+ System.out.println("CMCRequest(): Unexpected BASE64 " +
+ "encoded error encountered in close():\n" + e);
+ }
+ }
- if (senderNonceEnable.equalsIgnoreCase("true"))
- bpid = addSenderNonceAttr(bpid, controlSeq, senderNonce);
+ SEQUENCE controlSeq = new SEQUENCE();
+ int bpid = 1;
+ if (confirmCertEnable.equalsIgnoreCase("true")) {
+ if (confirmCertIssuer.length() == 0 || confirmCertSerial.length() == 0) {
+ System.out.println("Illegal parameters for confirm certificate acceptance control");
+ printUsage();
+ System.exit(1);
+ }
+ bpid = addConfirmCertAttr(bpid, controlSeq, confirmCertIssuer, confirmCertSerial);
+ }
- if (popLinkWitnessEnable.equalsIgnoreCase("true"))
- bpid = addPopLinkWitnessAttr(bpid, controlSeq);
+ if (lraPopWitnessEnable.equalsIgnoreCase("true")) {
+ if (bodyPartIDs.length() == 0) {
+ System.out.println("Illegal parameters for Lra Pop Witness control");
+ printUsage();
+ System.exit(1);
+ }
- SEQUENCE otherMsgSeq = new SEQUENCE();
- if (revRequestEnable.equalsIgnoreCase("true")) {
- if (revRequestIssuer.length() == 0 || revRequestSerial.length() == 0 ||
- revRequestReason.length() == 0) {
- System.out.println("Illegal parameters for revRequest control");
- printUsage();
- System.exit(1);
+ bpid = addLraPopWitnessAttr(bpid, controlSeq, bodyPartIDs);
+ }
+
+ if (getCertEnable.equalsIgnoreCase("true")) {
+ if (getCertIssuer.length() == 0 || getCertSerial.length() == 0) {
+ System.out.println("Illegal parameters for get certificate control");
+ printUsage();
+ System.exit(1);
+ }
+
+ bpid = addGetCertAttr(bpid, controlSeq, getCertIssuer, getCertSerial);
}
- bpid = addRevRequestAttr(bpid, controlSeq, otherMsgSeq, token, tokenName, revCertNickname,
- revRequestIssuer, revRequestSerial, revRequestReason, revRequestSharedSecret,
- revRequestComment, revRequestInvalidityDatePresent, cm);
+ if (dataReturnEnable.equalsIgnoreCase("true")) {
+ if (dataReturnData.length() == 0) {
+ System.out.println("Illegal parameters for data return control");
+ printUsage();
+ System.exit(1);
+ }
+
+ bpid = addDataReturnAttr(bpid, controlSeq, dataReturnData);
+ }
+
+ if (senderNonceEnable.equalsIgnoreCase("true"))
+ bpid = addSenderNonceAttr(bpid, controlSeq, senderNonce);
+
+ if (popLinkWitnessEnable.equalsIgnoreCase("true"))
+ bpid = addPopLinkWitnessAttr(bpid, controlSeq);
+
+ SEQUENCE otherMsgSeq = new SEQUENCE();
+ if (revRequestEnable.equalsIgnoreCase("true")) {
+ if (revRequestIssuer.length() == 0 || revRequestSerial.length() == 0 ||
+ revRequestReason.length() == 0) {
+ System.out.println("Illegal parameters for revRequest control");
+ printUsage();
+ System.exit(1);
+ }
+
+ bpid = addRevRequestAttr(bpid, controlSeq, otherMsgSeq, token, tokenName, revCertNickname,
+ revRequestIssuer, revRequestSerial, revRequestReason, revRequestSharedSecret,
+ revRequestComment, revRequestInvalidityDatePresent, cm);
+ }
+
+ // create the request PKIData
+ pkidata = createPKIData(
+ requests,
+ format, transactionMgtEnable, transactionMgtId,
+ identificationEnable, identification,
+ identityProofEnable, identityProofSharedSecret,
+ identityProofV2Enable, witnessSharedSecret,
+ identityProofV2hashAlg, identityProofV2macAlg,
+ controlSeq, otherMsgSeq, bpid);
+
+ if (pkidata == null) {
+ System.out.println("pkidata null after createPKIData(). Exiting with error");
+ System.exit(1);
+ }
}
- ContentInfo cmcblob = getCMCBlob(signerCert, tokenName, nickname, requests, format,
- cm, transactionMgtEnable, transactionMgtId,
- identificationEnable, identification,
- identityProofEnable, identityProofSharedSecret,
- identityProofV2Enable, identityProofV2SharedSecret,
- identityProofV2hashAlg, identityProofV2macAlg,
- controlSeq, otherMsgSeq, bpid);
+ // sign the request
+ SignedData signedData = signData(signerCert, tokenName, nickname, cm, pkidata);
+ if (signedData == null) {
+ System.out.println("signData() returns null. Exiting with error");
+ System.exit(1);
+ }
+ cmcblob = getCMCBlob(signedData);
+ if (cmcblob == null) {
+ System.out.println("getCMCBlob() returns null. Exiting with error");
+ System.exit(1);
+ }
// (6) Finally, print the actual CMC blob to the
// specified output file
diff --git a/base/java-tools/src/com/netscape/cmstools/CMCResponse.java b/base/java-tools/src/com/netscape/cmstools/CMCResponse.java
index 7bbba8797..4c7493443 100644
--- a/base/java-tools/src/com/netscape/cmstools/CMCResponse.java
+++ b/base/java-tools/src/com/netscape/cmstools/CMCResponse.java
@@ -34,6 +34,7 @@ import org.mozilla.jss.asn1.SEQUENCE;
import org.mozilla.jss.asn1.SET;
import org.mozilla.jss.pkix.cert.Certificate;
import org.mozilla.jss.pkix.cmc.CMCStatusInfo;
+import org.mozilla.jss.pkix.cmc.EncryptedPOP;
import org.mozilla.jss.pkix.cmc.OtherInfo;
import org.mozilla.jss.pkix.cmc.PendInfo;
import org.mozilla.jss.pkix.cmc.ResponseBody;
@@ -140,12 +141,27 @@ public class CMCResponse {
else if (t == OtherInfo.PEND) {
System.out.println(" OtherInfo type: PEND");
PendInfo pi = oi.getPendInfo();
+ if (pi == null) {
+ System.out.println("PendInfo null...skipping");
+ continue;
+ } else
+ System.out.println("PendInfo present...processing...");
if (pi.getPendTime() != null) {
String datePattern = "dd/MMM/yyyy:HH:mm:ss z";
SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);
Date d = pi.getPendTime().toDate();
System.out.println(" Date: " + dateFormat.format(d));
}
+ OCTET_STRING pendToken = pi.getPendToken();
+ if (pendToken != null) {
+ byte reqId[] = pendToken.toByteArray();
+ String reqIdString = new String(reqId);
+ System.out.println(" Pending request id: " + reqIdString);
+ } else {
+ System.out.println("pendToken not in response");
+ System.exit(1);
+ }
+
}
} else if (st == CMCStatusInfo.SUCCESS) {
System.out.println(" Status: SUCCESS");
@@ -200,6 +216,16 @@ public class CMCResponse {
s.append(" ");
}
System.out.println(s);
+ } else if (type.equals(OBJECT_IDENTIFIER.id_cmc_encryptedPOP)) {
+ System.out.println("Control #" + i + ": CMC encrypted POP");
+ System.out.println(" OID: " + type.toString());
+ SET encryptedPOPvals = taggedAttr.getValues();
+
+ EncryptedPOP encryptedPOP =
+ (EncryptedPOP) (ASN1Util.decode(EncryptedPOP.getTemplate(),
+ ASN1Util.encode(encryptedPOPvals.elementAt(0))));
+ System.out.println("after encryptedPOP encode");
+
}
}
} catch (Exception e) {
diff --git a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
index 5e53bee67..fafe956e7 100644
--- a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
+++ b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
@@ -433,6 +433,13 @@ public class CRMFPopClient {
throw new Exception("Unknown algorithm: " + algorithm);
}
+ // print out keyid to be used in cmc decryptPOP
+ PrivateKey privateKey = (PrivateKey) keyPair.getPrivate();
+ @SuppressWarnings("deprecation")
+ byte id[] = privateKey.getUniqueID();
+ String kid = CryptoUtil.byte2string(id);
+ System.out.println("Keypair private key id: " + kid);
+
if (verbose) System.out.println("Creating certificate request");
CertRequest certRequest = client.createCertRequest(token, transportCert, algorithm, keyPair, subject);
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 972d89f6a..5c07ecbc4 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
@@ -24,10 +24,13 @@ import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
import java.security.cert.CertificateException;
+import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.Locale;
+import java.util.Random;
import java.util.StringTokenizer;
import org.mozilla.jss.CryptoManager;
@@ -43,8 +46,11 @@ import org.mozilla.jss.asn1.UTF8String;
import org.mozilla.jss.crypto.CryptoToken;
import org.mozilla.jss.crypto.DigestAlgorithm;
import org.mozilla.jss.crypto.HMACAlgorithm;
+import org.mozilla.jss.crypto.PrivateKey;
+import org.mozilla.jss.crypto.SymmetricKey;
import org.mozilla.jss.pkcs10.CertificationRequest;
import org.mozilla.jss.pkcs10.CertificationRequestInfo;
+import org.mozilla.jss.pkix.cmc.DecryptedPOP;
import org.mozilla.jss.pkix.cmc.IdentityProofV2;
import org.mozilla.jss.pkix.cmc.LraPopWitness;
import org.mozilla.jss.pkix.cmc.OtherMsg;
@@ -78,6 +84,7 @@ import com.netscape.certsrv.profile.IEnrollProfile;
import com.netscape.certsrv.profile.IProfileContext;
import com.netscape.certsrv.request.IRequest;
import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
import com.netscape.cmsutil.crypto.CryptoUtil;
import com.netscape.cmsutil.util.HMACDigest;
@@ -162,13 +169,19 @@ public abstract class EnrollProfile extends BasicProfile
num_requests = msgs.length;
}
+ 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;
+ */
// catch for invalid request
- TaggedRequest[] msgs = parseCMC(locale, cert_request);
- if (msgs == null)
+ cmc_msgs = parseCMC(locale, cert_request);
+ if (cmc_msgs == null)
return null;
else
- num_requests = msgs.length;
+ num_requests = cmc_msgs.length;
}
// only 1 request for renewal
@@ -191,6 +204,12 @@ public abstract class EnrollProfile extends BasicProfile
result[i].setExtData(REQUEST_SEQ_NUM, renewal_seq_num);
} 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");
+ result[i].setExtData(
+ CTX_CERT_REQUEST,
+ ASN1Util.encode(cmc_msgs[i]));
+ }
}
if (locale != null) {
result[i].setExtData(REQUEST_LOCALE, locale.getLanguage());
@@ -325,6 +344,93 @@ public abstract class EnrollProfile extends BasicProfile
}
/**
+ * setPOPchallenge generates a POP challenge and sets necessary info in request
+ * for composing encryptedPOP later
+ *
+ * @param IRequest the request
+ * @author cfu
+ */
+ public void setPOPchallenge(IRequest req) throws EBaseException {
+ String method = "EnrollProfile: setPOPchallenge: ";
+
+ CMS.debug(method + " getting user public key in request");
+ byte[] req_key_data = req.getExtDataInByteArray(IEnrollProfile.REQUEST_KEY);
+ netscape.security.x509.CertificateX509Key pubKey = null;
+ if (req_key_data != null) {
+ CMS.debug(method + "found user public key in request");
+
+ // generate a challenge of 64 bytes;
+ Random random = new Random();
+ byte[] challenge = new byte[64];
+ random.nextBytes(challenge);
+
+ ICertificateAuthority authority = (ICertificateAuthority) getAuthority();
+ PublicKey issuanceProtPubKey = authority.getIssuanceProtPubKey();
+ if (issuanceProtPubKey != null)
+ CMS.debug(method + "issuanceProtPubKey not null");
+ else
+ CMS.debug(method + "issuanceProtPubKey null");
+
+ String msg = "";
+ try {
+ CryptoToken token = null;
+ String tokenName = CMS.getConfigStore().getString("cmc.token", CryptoUtil.INTERNAL_TOKEN_NAME);
+ token = CryptoUtil.getCryptoToken(tokenName);
+
+ PublicKey userPubKey = X509Key.parsePublicKey(new DerValue(req_key_data));
+
+ SymmetricKey symKey = CryptoUtil.generateKey(token);
+ byte[] pop_encreyptedData = CryptoUtil.encryptUsingSymmetricKey(
+ token, symKey, challenge);
+ if (pop_encreyptedData == null) {
+ msg = method + "pop_encreyptedData null";
+ CMS.debug(msg);
+ throw new Exception(msg);
+ }
+
+ byte[] pop_sysPubEncreyptedSession = CryptoUtil.wrapUsingPublicKey(
+ token, issuanceProtPubKey, symKey);
+ if (pop_sysPubEncreyptedSession == null) {
+ msg = method + "pop_sysPubEncreyptedSession null";
+ CMS.debug(msg);
+ throw new Exception(msg);
+ }
+
+ byte[] pop_userPubEncreyptedSession = CryptoUtil.wrapUsingPublicKey(
+ token, userPubKey, symKey);
+ if (pop_userPubEncreyptedSession == null) {
+ msg = method + "pop_userPubEncreyptedSession null";
+ CMS.debug(msg);
+ throw new Exception(msg);
+ }
+ CMS.debug(method + "POP challenge fields generated successfully...setting request extData");
+
+ req.setExtData("pop_encreyptedData", pop_encreyptedData);
+
+ req.setExtData("pop_sysPubEncreyptedSession", pop_sysPubEncreyptedSession);
+
+ req.setExtData("pop_userPubEncreyptedSession", pop_userPubEncreyptedSession);
+
+ // now compute and set witness
+ CMS.debug(method + "now compute and set witness");
+ String hashName = CryptoUtil.getDefaultHashAlgName();
+ CMS.debug(method + "hashName is " + hashName);
+ MessageDigest hash = MessageDigest.getInstance(hashName);
+ byte[] witness = hash.digest(challenge);
+ req.setExtData("pop_witness", witness);
+
+ } catch (Exception e) {
+ CMS.debug(method + e);
+ throw new EBaseException(e.toString());
+ }
+
+ } else {
+ CMS.debug(method + " public key not found in request");
+ throw new EBaseException(method + " public key not found in request");
+ }
+ }
+
+ /**
* This method is called after the user submits the
* request from the end-entity page.
*/
@@ -341,8 +447,14 @@ public abstract class EnrollProfile extends BasicProfile
// process request
// }
// }
+ String method = "EnrollProfile: submit: ";
IRequestQueue queue = getRequestQueue();
+ String msg = "";
+
+ boolean popChallengeRequired =
+ request.getExtDataInBoolean("cmc_POPchallengeRequired", false);
+ CMS.debug(method + "popChallengeRequired =" + popChallengeRequired);
// this profile queues request that is authenticated
// by NoAuth
@@ -350,26 +462,42 @@ public abstract class EnrollProfile extends BasicProfile
queue.updateRequest(request);
} catch (EBaseException e) {
// save request to disk
- CMS.debug("EnrollProfile: Unable to update request: " + e);
+ CMS.debug(method + " Unable to update request: " + e);
CMS.debug(e);
}
- if (token == null) {
- CMS.debug("EnrollProfile: auth token is null");
- CMS.debug("EnrollProfile: validating request");
+ if (token == null){
+ CMS.debug(method + " auth token is null");
+ CMS.debug(method + " validating request");
validate(request);
try {
queue.updateRequest(request);
} catch (EBaseException e) {
- CMS.debug("EnrollProfile: Unable to update request after validation: " + e);
- CMS.debug(e);
+ msg = method + " Unable to update request after validation: " + e;
+ CMS.debug(msg);
+ throw new EProfileException(msg);
}
-
throw new EDeferException("defer request");
+ } else if (popChallengeRequired) {
+ // 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);
+ queue.updateRequest(request);
+ } catch (EBaseException e) {
+ msg = method + e;
+ CMS.debug(msg);
+ throw new EProfileException(msg);
+ }
+
+ throw new EDeferException("EnrollProfile: submit: encryptedPOP defer request");
+
} else {
// this profile executes request that is authenticated
// by non NoAuth
- CMS.debug("EnrollProfile: auth token is not null");
+ CMS.debug(method + " auth token is not null");
validate(request);
execute(request);
}
@@ -377,14 +505,16 @@ public abstract class EnrollProfile extends BasicProfile
public TaggedRequest[] parseCMC(Locale locale, String certreq)
throws EProfileException {
+
+ String method = "EnrollProfile: parseCMC: ";
/* cert request must not be null */
if (certreq == null) {
- CMS.debug("EnrollProfile: parseCMC() certreq null");
+ CMS.debug(method + "certreq null");
throw new EProfileException(
CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"));
}
- //CMS.debug("EnrollProfile: Start parseCMC(): " + certreq);
- CMS.debug("EnrollProfile.parseCMC(): start");
+ //CMS.debug(method + " Start parseCMC(): " + certreq);
+ CMS.debug(method + "starts");
TaggedRequest msgs[] = null;
@@ -416,6 +546,8 @@ public abstract class EnrollProfile extends BasicProfile
if (numcontrols > 0) {
context.put("numOfControls", Integer.valueOf(numcontrols));
TaggedAttribute[] attributes = new TaggedAttribute[numcontrols];
+ boolean id_cmc_decryptedPOP = false;
+ SET decPopVals = null;
boolean id_cmc_identification = false;
SET ident = null;
@@ -430,7 +562,11 @@ public abstract class EnrollProfile extends BasicProfile
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_identification)) {
+ if (oid.equals(OBJECT_IDENTIFIER.id_cmc_decryptedPOP)) {
+ CMS.debug(method + " decryptedPOP found");
+ id_cmc_decryptedPOP = true;
+ decPopVals = attributes[i].getValues();
+ } else if (oid.equals(OBJECT_IDENTIFIER.id_cmc_identification)) {
id_cmc_identification = true;
ident = attributes[i].getValues();
} else if (oid.equals(OBJECT_IDENTIFIER.id_cmc_identityProofV2)) {
@@ -460,6 +596,19 @@ public abstract class EnrollProfile extends BasicProfile
*/
UTF8String ident_s = null;
+ if (id_cmc_decryptedPOP && (decPopVals != null)) {
+
+ DecryptedPOP decPop = (DecryptedPOP) (ASN1Util.decode(DecryptedPOP.getTemplate(),
+ ASN1Util.encode(decPopVals.elementAt(0))));
+ CMS.debug(method + "DecryptedPOP encoded");
+
+ Integer reqId = verifyDecryptedPOP(decPop);
+ if (reqId != null) {
+ context.put("decryptedPopReqId", reqId);
+ }
+ return null;
+ }
+
if (id_cmc_identification) {
ident_s = (UTF8String) (ASN1Util.decode(UTF8String.getTemplate(),
ASN1Util.encode(ident.elementAt(0))));
@@ -523,16 +672,111 @@ public abstract class EnrollProfile extends BasicProfile
} else
return null;
- CMS.debug("EnrollProfile.parseCMC: end");
+ CMS.debug(method + "ends");
return msgs;
} catch (Exception e) {
- CMS.debug("EnrollProfile: Unable to parse CMC request: " + e);
- CMS.debug(e);
+ CMS.debug(method + "Unable to parse CMC request: " + e);
throw new EProfileException(
CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"), e);
}
}
+ /**
+ * verifyDecryptedPOP verifies the POP challenge provided in
+ * DecryptedPOP and returns the matching requestID
+ *
+ * @author cfu
+ */
+ private Integer verifyDecryptedPOP(DecryptedPOP decPop) {
+ String method = "EnrollProfile: verifyDecryptedPOP: ";
+ CMS.debug(method + "begins");
+
+ INTEGER iBody = decPop.getBodyPartID();
+ CMS.debug(method + "request id from decryptedPOP =" +
+ iBody.toString());
+ Integer reqId = new Integer(iBody.toString());
+
+ OCTET_STRING witness_os = decPop.getWitness();
+
+ IRequestQueue reqQueue = getRequestQueue();
+ IRequest req = null;
+ try {
+ req = reqQueue.findRequest(new RequestId(reqId));
+ } catch (Exception e) {
+ CMS.debug(method + e);
+ return null;
+ }
+
+ // now verify the POP witness
+ byte[] pop_encreyptedData = req.getExtDataInByteArray("pop_encreyptedData");
+ if (pop_encreyptedData == null) {
+ CMS.debug(method +
+ "pop_encreyptedData not found in request:" + reqId.toString());
+ return null;
+ }
+
+ byte[] pop_sysPubEncreyptedSession = req.getExtDataInByteArray("pop_sysPubEncreyptedSession");
+ if (pop_sysPubEncreyptedSession == null) {
+ CMS.debug(method +
+ "pop_sysPubEncreyptedSession not found in request:" + reqId.toString());
+ return null;
+ }
+
+ byte[] cmc_msg = req.getExtDataInByteArray(IEnrollProfile.CTX_CERT_REQUEST);
+ if (pop_sysPubEncreyptedSession == null) {
+ CMS.debug(method +
+ "pop_sysPubEncreyptedSession not found in request:" +
+ reqId.toString());
+ return null;
+ }
+
+ ICertificateAuthority authority = (ICertificateAuthority) getAuthority();
+ PrivateKey issuanceProtPrivKey = authority.getIssuanceProtPrivKey();
+ if (issuanceProtPrivKey != null)
+ CMS.debug(method + "issuanceProtPrivKey not null");
+ else
+ CMS.debug(method + "issuanceProtPrivKey null");
+
+ try {
+ CryptoToken token = null;
+ String tokenName = CMS.getConfigStore().getString("cmc.token", CryptoUtil.INTERNAL_TOKEN_NAME);
+ token = CryptoUtil.getKeyStorageToken(tokenName);
+
+ SymmetricKey symKey = CryptoUtil.unwrap(
+ token,
+ SymmetricKey.Usage.DECRYPT,
+ issuanceProtPrivKey,
+ pop_sysPubEncreyptedSession);
+ byte[] challenge_b = CryptoUtil.decryptUsingSymmetricKey(
+ token, pop_encreyptedData, symKey);
+ if (challenge_b == null) {
+ CMS.debug(method + "decryptUsingSymmetricKey returned null");
+ return null;
+ }
+
+ MessageDigest digest = MessageDigest.getInstance(CryptoUtil.getDefaultHashAlgName());
+ HMACDigest hmacDigest = new HMACDigest(digest, challenge_b);
+ hmacDigest.update(cmc_msg);
+ byte[] proofValue = hmacDigest.digest();
+ boolean witnessChecked = Arrays.equals(proofValue, witness_os.toByteArray());
+ if (!witnessChecked) {
+ CMS.debug(method + "POP challenge witness verification failure");
+ return null;
+ }
+ } catch (Exception e) {
+ CMS.debug(method + e);
+ return null;
+ }
+
+ CMS.debug(method + "POP challenge verified!");
+ req.setExtData("cmc_POPchallengeRequired", "false");
+
+ CMS.debug(method + "cmc_POPchallengeRequired set back to false");
+ CMS.debug(method + "ends");
+
+ return reqId;
+ }
+
private boolean verifyPOPLinkWitness(byte[] randomSeed, TaggedRequest req,
SEQUENCE bpids) {
ISharedToken tokenClass = null;
@@ -711,7 +955,7 @@ public abstract class EnrollProfile extends BasicProfile
* @param ident value of the id_cmc_identification control
* @param reqSeq requestSequence of the PKI request PKIData
* @return boolean true if the witness values correctly verified
- * cfu
+ * @author cfu
*/
private boolean verifyIdentityProofV2(
TaggedAttribute attr,
@@ -769,8 +1013,8 @@ public abstract class EnrollProfile extends BasicProfile
CMS.debug(method + " Failed to retrieve shared secret");
return false;
}
- // cfu REMOVE
- CMS.debug(method + "Shared Secret returned by tokenClass:" + token);
+
+ // CMS.debug(method + "Shared Secret returned by tokenClass:" + token);
try {
IdentityProofV2 idV2val = (IdentityProofV2) (ASN1Util.decode(IdentityProofV2.getTemplate(),
ASN1Util.encode(vals.elementAt(0))));
@@ -851,16 +1095,17 @@ public abstract class EnrollProfile extends BasicProfile
public void fillTaggedRequest(Locale locale, TaggedRequest tagreq, X509CertInfo info,
IRequest req)
throws EProfileException {
+ String method = "EnrollProfile: fillTaggedRequest: ";
TaggedRequest.Type type = tagreq.getType();
if (type == null) {
- CMS.debug("EnrollProfile: fillTaggedRequest: TaggedRequest type == null");
+ CMS.debug(method + "TaggedRequest type == null");
throw new EProfileException(
CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST")+
"TaggedRequest type null");
}
if (type.equals(TaggedRequest.PKCS10)) {
- CMS.debug("EnrollProfile: fillTaggedRequest: TaggedRequest type == pkcs10");
+ CMS.debug(method + " TaggedRequest type == pkcs10");
boolean sigver = true;
boolean tokenSwitched = false;
CryptoManager cm = null;
@@ -890,36 +1135,73 @@ public abstract class EnrollProfile extends BasicProfile
req.setExtData("bodyPartId", tcr.getBodyPartID());
fillPKCS10(locale, pkcs10, info, req);
} catch (Exception e) {
- CMS.debug("EnrollProfile: fillTaggedRequest " + e);
+ CMS.debug(method + e);
} finally {
if ((sigver == true) && (tokenSwitched == true)){
cm.setThreadToken(savedToken);
}
}
} else if (type.equals(TaggedRequest.CRMF)) {
- CMS.debug("EnrollProfile: fillTaggedRequest: TaggedRequest type == crmf");
+ CMS.debug(method + " TaggedRequest type == crmf");
CertReqMsg crm = tagreq.getCrm();
SessionContext context = SessionContext.getContext();
Integer nums = (Integer) (context.get("numOfControls"));
- // check if the LRA POP Witness Control attribute exists
- if (nums != null && nums.intValue() > 0) {
- TaggedAttribute attr =
- (TaggedAttribute) (context.get(OBJECT_IDENTIFIER.id_cmc_lraPOPWitness));
- if (attr != null) {
- parseLRAPopWitness(locale, crm, attr);
+ boolean verifyAllow = false; //disable RA by default
+ try {
+ String configName = "cmc.lraPopWitness.verify.allow";
+ CMS.debug(method + "getting :" + configName);
+ verifyAllow = CMS.getConfigStore().getBoolean(configName, false);
+ CMS.debug(method + "cmc.lraPopWitness.verify.allow is " + verifyAllow);
+ } catch (Exception e) {
+ // unlikely to get here
+ String msg = method + " Failed to retrieve cmc.lraPopWitness.verify.allow";
+ CMS.debug(msg);
+ throw new EProfileException(method + msg);
+ }
+ if (verifyAllow) {
+ // check if the LRA POP Witness Control attribute exists
+ if (nums != null && nums.intValue() > 0) {
+ TaggedAttribute attr = (TaggedAttribute) (context.get(OBJECT_IDENTIFIER.id_cmc_lraPOPWitness));
+ if (attr != null) {
+ parseLRAPopWitness(locale, crm, attr);
+ } else {
+ CMS.debug(
+ method + " verify POP in CMC because LRA POP Witness control attribute doesnt exist in the CMC request.");
+ if (crm.hasPop()) {
+ CMS.debug(method + " hasPop true");
+ verifyPOP(locale, crm);
+ } else { // no signing POP, then do it the hard way
+ CMS.debug(method + "hasPop false, need to challenge");
+ req.setExtData("cmc_POPchallengeRequired", "true");
+ }
+ }
} else {
- CMS.debug("EnrollProfile: verify POP in CMC because LRA POP Witness control attribute doesnt exist in the CMC request.");
+ CMS.debug(
+ method + " verify POP in CMC because LRA POP Witness control attribute doesnt exist in the CMC request.");
+ if (crm.hasPop()) {
+ CMS.debug(method + " hasPop true");
+ verifyPOP(locale, crm);
+ } else { // no signing POP, then do it the hard way
+ CMS.debug(method + "hasPop false, need to challenge");
+ req.setExtData("cmc_POPchallengeRequired", "true");
+ }
+ }
+
+ } else { //!verifyAllow
+
+ if (crm.hasPop()) {
+ CMS.debug(method + " hasPop true");
verifyPOP(locale, crm);
+ } else { // no signing POP, then do it the hard way
+ CMS.debug(method + "hasPop false, need to challenge");
+ req.setExtData("cmc_POPchallengeRequired", "true");
}
- } else {
- CMS.debug("EnrollProfile: verify POP in CMC because LRA POP Witness control attribute doesnt exist in the CMC request.");
- verifyPOP(locale, crm);
}
fillCertReqMsg(locale, crm, info, req);
} else {
- CMS.debug("EnrollProfile: fillTaggedRequest: unsupported type (not CRMF or PKCS10)");
+ CMS.debug(method + " unsupported type (not CRMF or PKCS10)");
throw new EProfileException(
CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST"));
}
@@ -1648,25 +1930,30 @@ public abstract class EnrollProfile extends BasicProfile
return profileID;
}
+ /*
+ * verifyPOP - CRMF POP verification for signing keys
+ */
public void verifyPOP(Locale locale, CertReqMsg certReqMsg)
throws EProfileException {
- CMS.debug("EnrollProfile ::in verifyPOP");
+ String method = "EnrollProfile: verifyPOP: ";
+ CMS.debug(method + "for signing keys");
String auditMessage = null;
String auditSubjectID = auditSubjectID();
if (!certReqMsg.hasPop()) {
- return;
+ CMS.debug(method + "missing pop.");
+ popFailed(locale, auditSubjectID, auditMessage);
}
ProofOfPossession pop = certReqMsg.getPop();
ProofOfPossession.Type popType = pop.getType();
if (popType != ProofOfPossession.SIGNATURE) {
- return;
+ CMS.debug(method + "pop type is not ProofOfPossession.SIGNATURE.");
+ popFailed(locale, auditSubjectID, auditMessage);
}
try {
- CryptoManager cm = CryptoManager.getInstance();
CryptoToken verifyToken = null;
String tokenName = CMS.getConfigStore().getString("ca.requestVerify.token", CryptoUtil.INTERNAL_TOKEN_NAME);
if (CryptoUtil.isInternalToken(tokenName)) {
@@ -1685,9 +1972,18 @@ public abstract class EnrollProfile extends BasicProfile
ILogger.SUCCESS);
audit(auditMessage);
} catch (Exception e) {
+ CMS.debug(method + "Unable to verify POP: " + e);
+ popFailed(locale, auditSubjectID, auditMessage, e);
+ }
+ CMS.debug(method + "ends.");
+ }
- CMS.debug("EnrollProfile: Unable to verify POP: " + e);
- CMS.debug(e);
+ private void popFailed(Locale locale, String auditSubjectID, String auditMessage)
+ throws EProfileException {
+ popFailed(locale, auditSubjectID, auditMessage, null);
+ }
+ private void popFailed(Locale locale, String auditSubjectID, String auditMessage, Exception e)
+ throws EProfileException {
// store a message in the signed audit log file
auditMessage = CMS.getLogMessage(
@@ -1697,8 +1993,12 @@ public abstract class EnrollProfile extends BasicProfile
audit(auditMessage);
- throw new EProfileException(CMS.getUserMessage(locale,
+ if (e != null) {
+ throw new EProfileException(CMS.getUserMessage(locale,
"CMS_POP_VERIFICATION_ERROR"), e);
- }
+ } else {
+ throw new EProfileException(CMS.getUserMessage(locale,
+ "CMS_POP_VERIFICATION_ERROR"));
+ }
}
}
diff --git a/base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java b/base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java
index f1320f44a..f5bef2a87 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java
@@ -30,16 +30,6 @@ import java.util.Hashtable;
import javax.servlet.http.HttpServletResponse;
-import netscape.security.x509.CRLExtensions;
-import netscape.security.x509.CRLReasonExtension;
-import netscape.security.x509.CertificateChain;
-import netscape.security.x509.InvalidityDateExtension;
-import netscape.security.x509.RevocationReason;
-import netscape.security.x509.RevokedCertImpl;
-import netscape.security.x509.X500Name;
-import netscape.security.x509.X509CertImpl;
-import netscape.security.x509.X509Key;
-
import org.mozilla.jss.CryptoManager;
import org.mozilla.jss.asn1.ANY;
import org.mozilla.jss.asn1.ASN1Util;
@@ -58,15 +48,18 @@ import org.mozilla.jss.pkcs11.PK11PubKey;
import org.mozilla.jss.pkix.cert.Certificate;
import org.mozilla.jss.pkix.cmc.CMCCertId;
import org.mozilla.jss.pkix.cmc.CMCStatusInfo;
+import org.mozilla.jss.pkix.cmc.EncryptedPOP;
import org.mozilla.jss.pkix.cmc.GetCert;
import org.mozilla.jss.pkix.cmc.OtherInfo;
import org.mozilla.jss.pkix.cmc.OtherMsg;
import org.mozilla.jss.pkix.cmc.PendInfo;
import org.mozilla.jss.pkix.cmc.ResponseBody;
import org.mozilla.jss.pkix.cmc.TaggedAttribute;
+import org.mozilla.jss.pkix.cmc.TaggedRequest;
import org.mozilla.jss.pkix.cmmf.RevRequest;
import org.mozilla.jss.pkix.cms.ContentInfo;
import org.mozilla.jss.pkix.cms.EncapsulatedContentInfo;
+import org.mozilla.jss.pkix.cms.EnvelopedData;
import org.mozilla.jss.pkix.cms.IssuerAndSerialNumber;
import org.mozilla.jss.pkix.cms.SignedData;
import org.mozilla.jss.pkix.cms.SignerIdentifier;
@@ -89,6 +82,17 @@ import com.netscape.certsrv.request.IRequest;
import com.netscape.certsrv.request.IRequestQueue;
import com.netscape.certsrv.request.RequestId;
import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.InvalidityDateExtension;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
/**
* Utility CMCOutputTemplate
@@ -142,6 +146,10 @@ public class CMCOutputTemplate {
public void createFullResponse(HttpServletResponse resp, IRequest[] reqs,
String cert_request_type, int[] error_codes) {
+ String method = "CMCOutputTemplate: createFullResponse: ";
+ CMS.debug(method +
+ "begins with cert_request_type=" +
+ cert_request_type);
SEQUENCE controlSeq = new SEQUENCE();
SEQUENCE cmsSeq = new SEQUENCE();
@@ -176,22 +184,33 @@ public class CMCOutputTemplate {
OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
controlSeq.addElement(tagattr);
} else if (cert_request_type.equals("cmc")) {
+ CMS.debug(method + " processing cmc");
pending_bpids = new SEQUENCE();
success_bpids = new SEQUENCE();
failed_bpids = new SEQUENCE();
+ EncryptedPOP encPop = null;
if (reqs != null) {
for (int i = 0; i < reqs.length; i++) {
+ CMS.debug(method + " error_codes[i]=" + error_codes[i]);
if (error_codes[i] == 0) {
success_bpids.addElement(new INTEGER(
reqs[i].getExtDataInBigInteger("bodyPartId")));
} else if (error_codes[i] == 2) {
pending_bpids.addElement(new INTEGER(
reqs[i].getExtDataInBigInteger("bodyPartId")));
+ try {
+ encPop = constructEncryptedPop(reqs[i]);
+ } catch (Exception e) {
+ CMS.debug(method + e);
+ return;
+ }
} else {
failed_bpids.addElement(new INTEGER(
reqs[i].getExtDataInBigInteger("bodyPartId")));
}
}
+ } else {
+ CMS.debug(method + " reqs null. why?");
}
TaggedAttribute tagattr = null;
@@ -221,8 +240,25 @@ public class CMCOutputTemplate {
}
if (pending_bpids.size() > 0) {
+ // handle encryptedPOP control first
+
+ if (encPop != null) {
+ CMS.debug(method + "adding encPop");
+ tagattr = new TaggedAttribute(
+ new INTEGER(bpid++),
+ OBJECT_IDENTIFIER.id_cmc_encryptedPOP,
+ encPop);
+ controlSeq.addElement(tagattr);
+ CMS.debug(method + "encPop added");
+ }
+
+ String reqId = reqs[0].getRequestId().toString();
+ OtherInfo otherInfo = null;
+ PendInfo pendInfo = new PendInfo(reqId, new Date());
+ otherInfo = new OtherInfo(OtherInfo.PEND, null,
+ pendInfo);
cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.PENDING,
- pending_bpids, (String) null, null);
+ pending_bpids, (String) null, otherInfo);
tagattr = new TaggedAttribute(
new INTEGER(bpid++),
OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
@@ -238,7 +274,7 @@ public class CMCOutputTemplate {
} catch (Exception e) {
}
if (confirmRequired) {
- CMS.debug("CMCOutputTemplate: confirmRequired in the request");
+ CMS.debug(method + " confirmRequired in the request");
cmcStatusInfo =
new CMCStatusInfo(CMCStatusInfo.CONFIRM_REQUIRED,
success_bpids, (String) null, null);
@@ -270,13 +306,14 @@ public class CMCOutputTemplate {
// deal with controls
Integer nums = (Integer) (context.get("numOfControls"));
if (nums != null && nums.intValue() > 0) {
+ CMS.debug(method + " processing controls");
TaggedAttribute attr =
(TaggedAttribute) (context.get(OBJECT_IDENTIFIER.id_cmc_getCert));
if (attr != null) {
try {
processGetCertControl(attr, certs);
} catch (EBaseException ee) {
- CMS.debug("CMCOutputTemplate: " + ee.toString());
+ CMS.debug(method + ee.toString());
OtherInfo otherInfo1 = new OtherInfo(OtherInfo.FAIL,
new INTEGER(OtherInfo.BAD_CERT_ID), null);
SEQUENCE bpids1 = new SEQUENCE();
@@ -342,6 +379,10 @@ public class CMCOutputTemplate {
ResponseBody respBody = new ResponseBody(controlSeq,
cmsSeq, otherMsgSeq);
+ if (respBody != null)
+ CMS.debug(method + " after new ResponseBody, respBody not null");
+ else
+ CMS.debug(method + " after new ResponseBody, respBody null");
ContentInfo contentInfo = getContentInfo(respBody, certs);
ByteArrayOutputStream fos = new ByteArrayOutputStream();
@@ -354,18 +395,79 @@ public class CMCOutputTemplate {
OutputStream os = resp.getOutputStream();
os.write(contentBytes);
os.flush();
+ CMS.debug(method + "ends");
} catch (java.security.cert.CertificateEncodingException e) {
- CMS.debug("CMCOutputTemplate exception: " + e.toString());
+ CMS.debug(method + e.toString());
} catch (InvalidBERException e) {
- CMS.debug("CMCOutputTemplate exception: " + e.toString());
+ CMS.debug(method + e.toString());
} catch (IOException e) {
- CMS.debug("CMCOutputTemplate exception: " + e.toString());
+ CMS.debug(method + e.toString());
} catch (Exception e) {
- CMS.debug("Exception: " + e.toString());
+ CMS.debug(method + e.toString());
+ }
+ }
+
+ /**
+ * constructEncryptedPop pulls cmc pop challenge fields out of the request
+ * and constructs an EncryptedPOP
+ * to be included in the response later
+ *
+ * @author cfu
+ */
+ public EncryptedPOP constructEncryptedPop(IRequest req)
+ throws EBaseException {
+ String method = "CMCOutputTemplate: constructEncryptedPop: ";
+ CMS.debug(method + "begins");
+ EncryptedPOP encPop = null;
+
+ boolean popChallengeRequired = req.getExtDataInBoolean("cmc_POPchallengeRequired", false);
+ if (!popChallengeRequired) {
+ CMS.debug(method + "popChallengeRequired false");
+ return null;
}
+ CMS.debug(method + "popChallengeRequired true");
+ byte[] cmc_msg = req.getExtDataInByteArray(IEnrollProfile.CTX_CERT_REQUEST);
+ byte[] pop_encreyptedData = req.getExtDataInByteArray("pop_encreyptedData");
+ //don't need this for encryptedPOP, but need to check for existence anyway
+ byte[] pop_sysPubEncreyptedSession = req.getExtDataInByteArray("pop_sysPubEncreyptedSession");
+ byte[] pop_userPubEncreyptedSession = req.getExtDataInByteArray("pop_userPubEncreyptedSession");
+ if ((pop_encreyptedData != null) &&
+ (pop_sysPubEncreyptedSession != null) &&
+ (pop_userPubEncreyptedSession != null)) {
+ // generate encryptedPOP here
+ // algs are hard-coded for now
+
+ try {
+ EnvelopedData envData = CryptoUtil.createEnvelopedData(
+ pop_encreyptedData,
+ pop_userPubEncreyptedSession);
+ ContentInfo ci = new ContentInfo(envData);
+ CMS.debug(method + "now we can compose encryptedPOP");
+
+ TaggedRequest.Template tReqTemplate = new TaggedRequest.Template();
+ TaggedRequest tReq = (TaggedRequest) tReqTemplate.decode(
+ new ByteArrayInputStream(cmc_msg));
+
+ encPop = new EncryptedPOP(
+ tReq,
+ ci,
+ CryptoUtil.getDefaultEncAlg(),
+ CryptoUtil.getDefaultHashAlg(),
+ new OCTET_STRING(req.getExtDataInByteArray("pop_witness")));
+
+ } catch (Exception e) {
+ CMS.debug(method + " excepton:" + e);
+ throw new EBaseException(method + " excepton:" + e);
+ }
+
+ }
+
+ return encPop;
}
private ContentInfo getContentInfo(ResponseBody respBody, SET certs) {
+ String method = "CMCOutputTemplate: getContentInfo: ";
+ CMS.debug(method + "begins");
try {
ICertificateAuthority ca = null;
// add CA cert chain
@@ -442,10 +544,10 @@ public class CMCOutputTemplate {
enContentInfo, certs, null, signInfos);
ContentInfo contentInfo = new ContentInfo(signedData);
- CMS.debug("CMCOutputTemplate::getContentInfo() - done");
+ CMS.debug(method + " - done");
return contentInfo;
} catch (Exception e) {
- CMS.debug("CMCOutputTemplate: Failed to create CMCContentInfo. Exception: " + e.toString());
+ CMS.debug(method + " Failed to create CMCContentInfo. Exception: " + e.toString());
}
return null;
}
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 619103190..c233e415b 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
@@ -28,8 +28,6 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import netscape.security.x509.X509CertImpl;
-
import org.mozilla.jss.asn1.ASN1Util;
import org.mozilla.jss.asn1.INTEGER;
import org.mozilla.jss.asn1.InvalidBERException;
@@ -58,6 +56,7 @@ import com.netscape.certsrv.profile.IProfileInput;
import com.netscape.certsrv.profile.IProfileSubsystem;
import com.netscape.certsrv.request.INotify;
import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestId;
import com.netscape.certsrv.request.RequestStatus;
import com.netscape.cms.servlet.common.AuthCredentials;
import com.netscape.cms.servlet.common.CMCOutputTemplate;
@@ -65,6 +64,8 @@ import com.netscape.cms.servlet.common.CMSRequest;
import com.netscape.cms.servlet.common.CMSTemplate;
import com.netscape.cmsutil.util.Utils;
+import netscape.security.x509.X509CertImpl;
+
/**
* This servlet submits end-user request into the profile framework.
*
@@ -478,12 +479,13 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
TaggedAttribute attr =
(TaggedAttribute) (context.get(OBJECT_IDENTIFIER.id_cmc_lraPOPWitness));
if (attr != null) {
- boolean verifyAllow = true;
+ boolean verifyAllow = false; //disable RA by default
try {
verifyAllow = CMS.getConfigStore().getBoolean(
- "cmc.lraPopWitness.verify.allow", true);
+ "cmc.lraPopWitness.verify.allow", false);
} catch (EBaseException ee) {
}
+ CMS.debug("ProfileSubmitCMCServlet: cmc.lraPopWitness.verify.allow is " + verifyAllow);
if (!verifyAllow) {
LraPopWitness lraPop = null;
@@ -507,23 +509,34 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
}
}
- // for CMC, requests may be zero. Then check if controls exist.
+ // For CMC, requests may be zero. Then check if controls exist.
+ // In case of decryptedPOP, request already exists, find it and
+ // put in provedReq.
+ IRequest provedReq = null;
if (reqs == null) {
- Integer nums = (Integer) (context.get("numOfControls"));
- CMCOutputTemplate template = new CMCOutputTemplate();
- // if there is only one control GetCert, then simple response
- // must be returned.
- if (nums != null && nums.intValue() == 1) {
- TaggedAttribute attr1 = (TaggedAttribute) (context.get(OBJECT_IDENTIFIER.id_cmc_getCert));
- if (attr1 != null) {
- template.createSimpleResponse(response, reqs);
+ // handling DecryptedPOP request here
+ Integer reqID = (Integer) context.get("decryptedPopReqId");
+ provedReq = profile.getRequestQueue().findRequest(new RequestId(reqID.toString()));
+ if (provedReq == null) {
+
+ Integer nums = (Integer) (context.get("numOfControls"));
+ CMCOutputTemplate template = new CMCOutputTemplate();
+ // if there is only one control GetCert, then simple response
+ // must be returned.
+ if (nums != null && nums.intValue() == 1) {
+ TaggedAttribute attr1 = (TaggedAttribute) (context.get(OBJECT_IDENTIFIER.id_cmc_getCert));
+ if (attr1 != null) {
+ template.createSimpleResponse(response, reqs);
+ } else
+ template.createFullResponse(response, reqs,
+ cert_request_type, null);
} else
template.createFullResponse(response, reqs,
cert_request_type, null);
- } else
- template.createFullResponse(response, reqs,
- cert_request_type, null);
- return;
+ return;
+ } else {
+ CMS.debug("ProfileSubmitCMCServlet: provedReq not null");
+ }
}
String errorCode = null;
@@ -532,7 +545,7 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
///////////////////////////////////////////////
// populate request
///////////////////////////////////////////////
- for (int k = 0; k < reqs.length; k++) {
+ for (int k = 0; (provedReq == null) &&(k < reqs.length); k++) {
// adding parameters to request
setInputsIntoRequest(request, profile, reqs[k]);
@@ -626,7 +639,7 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
OtherInfo.INTERNAL_CA_ERROR, s);
return;
}
- }
+ } //for
String auditMessage = null;
String auditSubjectID = auditSubjectID();
@@ -640,7 +653,8 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
int error_codes[] = null;
if (reqs != null && reqs.length > 0)
error_codes = new int[reqs.length];
- for (int k = 0; k < reqs.length; k++) {
+
+ for (int k = 0; (provedReq == null) && (k < reqs.length); k++) {
try {
// reset the "auditRequesterID"
auditRequesterID = auditRequesterID(reqs[k]);
@@ -680,6 +694,7 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
}
} catch (EDeferException e) {
// return defer message to the user
+ CMS.debug("ProfileSubmitCMCServlet: set request to PENDING");
reqs[k].setRequestStatus(RequestStatus.PENDING);
// need to notify
INotify notify = profile.getRequestQueue().getPendingNotify();
@@ -752,6 +767,53 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
error_codes[k] = 0;
}
+ // handle provedReq
+ if (provedReq != null) {
+ error_codes = new int[1];
+ auditRequesterID = auditRequesterID(provedReq);
+ try {
+ profile.execute(provedReq);
+ reqs = new IRequest[1];
+ reqs[0] = provedReq;
+ reqs[0].setRequestStatus(RequestStatus.COMPLETE);
+ profile.getRequestQueue().markAsServiced(provedReq);
+ CMS.debug("ProfileSubmitCMCServlet: provedReq set to complete");
+
+ // reset the "auditInfoCertValue"
+ auditInfoCertValue = auditInfoCertValue(reqs[0]);
+
+ if (auditInfoCertValue != null) {
+ if (!(auditInfoCertValue.equals(
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE))) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_ACCEPTANCE,
+ auditInfoCertValue);
+
+ audit(auditMessage);
+ }
+ }
+ } catch (ERejectException e) {
+ // return error to the user
+ provedReq.setRequestStatus(RequestStatus.REJECTED);
+ CMS.debug("ProfileSubmitCMCServlet: provedReq submit " + e.toString());
+ errorCode = "3";
+ errorReason = CMS.getUserMessage(locale,
+ "CMS_PROFILE_REJECTED",
+ e.toString());
+ } catch (Exception e) {
+ // return error to the user
+ CMS.debug("ProfileSubmitCMCServlet: provedReq submit " + e.toString());
+ errorCode = "1";
+ errorReason = CMS.getUserMessage(locale,
+ "CMS_INTERNAL_ERROR");
+ }
+ }
+
if (errorCode != null) {
// create the CMC full enrollment response
CMCOutputTemplate template = new CMCOutputTemplate();
diff --git a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
index e3a378ebc..716a3f23f 100644
--- a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
+++ b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
@@ -55,10 +55,13 @@ import org.mozilla.jss.asn1.ANY;
import org.mozilla.jss.asn1.ASN1Util;
import org.mozilla.jss.asn1.ASN1Value;
import org.mozilla.jss.asn1.BIT_STRING;
+import org.mozilla.jss.asn1.INTEGER;
import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.NULL;
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.Algorithm;
import org.mozilla.jss.crypto.BadPaddingException;
import org.mozilla.jss.crypto.Cipher;
@@ -89,7 +92,11 @@ import org.mozilla.jss.crypto.X509Certificate;
import org.mozilla.jss.pkcs11.PK11ECPublicKey;
import org.mozilla.jss.pkcs11.PK11PubKey;
import org.mozilla.jss.pkcs12.PasswordConverter;
-import org.mozilla.jss.pkcs7.EncryptedContentInfo;
+import org.mozilla.jss.pkcs7.IssuerAndSerialNumber;
+import org.mozilla.jss.pkcs7.RecipientInfo;
+import org.mozilla.jss.pkix.cms.ContentInfo;
+import org.mozilla.jss.pkix.cms.EncryptedContentInfo;
+import org.mozilla.jss.pkix.cms.EnvelopedData;
import org.mozilla.jss.pkix.crmf.CertReqMsg;
import org.mozilla.jss.pkix.crmf.CertRequest;
import org.mozilla.jss.pkix.crmf.CertTemplate;
@@ -2391,6 +2398,41 @@ public class CryptoUtil {
}
/**
+ * for CMC encryptedPOP
+ */
+ public static EnvelopedData createEnvelopedData(byte[] encContent, byte[] encSymKey)
+ throws Exception {
+ String method = "CryptoUtl: createEnvelopedData: ";
+ System.out.println(method + "begins");
+
+ EncryptedContentInfo encCInfo = new EncryptedContentInfo(
+ ContentInfo.DATA,
+ getDefaultEncAlg(),
+ new OCTET_STRING(encContent));
+
+ Name name = new Name();
+ name.addCommonName("unUsedIssuerName"); //unused; okay for cmc EncryptedPOP
+ RecipientInfo recipient = new RecipientInfo(
+ new INTEGER(0), //per rfc2315
+ new IssuerAndSerialNumber(name, new INTEGER(0)), //unUsed
+ new AlgorithmIdentifier(RSA_ENCRYPTION, new NULL()),
+ new OCTET_STRING(encSymKey));
+
+ SET recipients = new SET();
+ recipients.addElement(recipient);
+
+ EnvelopedData envData = new EnvelopedData(
+ new INTEGER(0),
+ recipients,
+ encCInfo);
+
+ return envData;
+ }
+
+ /* PKCS 1 - rsaEncryption */
+ public static OBJECT_IDENTIFIER RSA_ENCRYPTION = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 1, 1 });
+
+ /**
* The following are convenience routines for quick preliminary
* feature development or test programs that would just take
* the defaults
@@ -2538,6 +2580,32 @@ public class CryptoUtil {
}
return oid;
}
+
+ /**
+ * getNameFromHashAlgorithm returns the hashing algorithm name
+ * from input Algorithm
+ *
+ * @param ai the hashing algorithm AlgorithmIdentifier
+ * @return name of the hashing algorithm
+ *
+ */
+ public static String getNameFromHashAlgorithm(AlgorithmIdentifier ai)
+ throws NoSuchAlgorithmException {
+ OBJECT_IDENTIFIER oid = null;
+
+ System.out.println("CryptoUtil: getNameFromHashAlgorithm: " + ai.getOID().toString());
+ if (ai != null) {
+ if (ai.getOID().equals((DigestAlgorithm.SHA256).toOID())) {
+ return "SHA-256";
+ } else if (ai.getOID().equals((DigestAlgorithm.SHA384).toOID())) {
+ return "SHA-384";
+ } else if (ai.getOID().equals((DigestAlgorithm.SHA512).toOID())) {
+ return "SHA-512";
+ }
+ }
+ throw new NoSuchAlgorithmException();
+ }
+
}
// START ENABLE_ECC