diff options
Diffstat (limited to 'base/java-tools/src/com/netscape/cmstools/CMCRequest.java')
-rw-r--r-- | base/java-tools/src/com/netscape/cmstools/CMCRequest.java | 1100 |
1 files changed, 1100 insertions, 0 deletions
diff --git a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java new file mode 100644 index 000000000..9c5b74c05 --- /dev/null +++ b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java @@ -0,0 +1,1100 @@ +// --- 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.cmstools; + + +import org.mozilla.jss.pkix.cmc.*; +import org.mozilla.jss.pkix.cms.*; +import org.mozilla.jss.pkix.cert.*; +import org.mozilla.jss.pkix.primitive.*; +import org.mozilla.jss.asn1.*; +import org.mozilla.jss.pkcs10.*; +import org.mozilla.jss.pkcs11.*; +import org.mozilla.jss.crypto.*; +import org.mozilla.jss.pkix.crmf.*; +import org.mozilla.jss.pkix.cmmf.*; +import org.mozilla.jss.CryptoManager; +import org.mozilla.jss.crypto.CryptoToken; +import org.mozilla.jss.crypto.SignatureAlgorithm; +import org.mozilla.jss.crypto.DigestAlgorithm; +import org.mozilla.jss.crypto.X509Certificate; +import org.mozilla.jss.util.*; + +import org.mozilla.jss.*; + +import netscape.security.util.*; +import netscape.security.x509.*; +import netscape.security.pkcs.PKCS10; + +import java.security.*; +import java.security.cert.CertificateException; +import java.math.*; +import java.security.Principal; +import java.lang.*; +import java.lang.reflect.*; +import java.io.*; +import java.util.*; + +import com.netscape.cmsutil.util.*; + + +/** + * Tool for creating CMC full request + * + * <P> + * @version $Revision$, $Date$ + * + */ +public class CMCRequest { + + public static final String PR_REQUEST_CMC = "CMC"; + public static final String PR_REQUEST_CRMF = "CRMF"; + + public static final int ARGC = 1; + private static final String CERTDB = "cert8.db"; + private static final String KEYDB = "key3.db"; + public static final String HEADER = "-----BEGIN NEW CERTIFICATE REQUEST-----"; + public static final String TRAILER = "-----END NEW CERTIFICATE REQUEST-----"; + + void cleanArgs(String[] s) { + + } + + public static X509Certificate getCertificate(String tokenname, + String nickname) throws Exception { + CryptoManager manager = CryptoManager.getInstance(); + CryptoToken token = null; + + if (tokenname.equals("internal")) { + token = manager.getInternalKeyStorageToken(); + } else { + token = manager.getTokenByName(tokenname); + } + StringBuffer certname = new StringBuffer(); + + if (!token.equals(manager.getInternalKeyStorageToken())) { + certname.append(tokenname); + certname.append(":"); + } + certname.append(nickname); + try { + return manager.findCertByNickname(certname.toString()); + } catch (ObjectNotFoundException e) { + throw new IOException("Signing Certificate not found"); + } + } + + public static java.security.PrivateKey getPrivateKey(String tokenname, String nickname) + throws Exception { + + X509Certificate cert = getCertificate(tokenname, nickname); + + return CryptoManager.getInstance().findPrivKeyByCert(cert); + } + + + /** + * getCMCBlob create and return the enrollent request. + * <P> + * @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 + */ + static ContentInfo getCMCBlob(X509Certificate signerCert, String nickname, + String[] rValue, String format, CryptoManager manager, String transactionMgtEnable, + String transactionMgtId, String identityProofEnable, String identityProofSharedSecret, + SEQUENCE controlSeq, SEQUENCE otherMsgSeq, int bpid) { + + String tokenname = "internal"; + + ContentInfo fullEnrollmentReq = null; + try { + java.security.PrivateKey privKey = null; + SignerIdentifier si = null; + + BigInteger serialno = signerCert.getSerialNumber(); + byte[] certB = signerCert.getEncoded(); + X509CertImpl impl = new X509CertImpl(certB); + X500Name issuerName = (X500Name) impl.getIssuerDN(); + byte[] issuerByte = issuerName.getEncoded(); + ByteArrayInputStream istream = new ByteArrayInputStream(issuerByte); + + Name issuer = (Name) Name.getTemplate().decode(istream); + IssuerAndSerialNumber ias = new IssuerAndSerialNumber( + issuer, new INTEGER(serialno.toString())); + + si = new SignerIdentifier( + SignerIdentifier.ISSUER_AND_SERIALNUMBER, ias, null); + privKey = getPrivateKey(tokenname, nickname); + + TaggedRequest trq = null; + PKCS10 pkcs = null; + CertReqMsg certReqMsg = null; + + // create CMC req + SEQUENCE reqSequence = new SEQUENCE(); + try { + for (int k=0; k<rValue.length; k++) { + String asciiBASE64Blob = rValue[k]; + byte[] decodedBytes = com.netscape.osutil.OSUtil.AtoB(asciiBASE64Blob); + + if (format.equals("crmf")) { + ByteArrayInputStream reqBlob = + new ByteArrayInputStream(decodedBytes); + SEQUENCE crmfMsgs = null; + try { + crmfMsgs = (SEQUENCE)new SEQUENCE.OF_Template(new + CertReqMsg.Template()).decode(reqBlob); + } catch (InvalidBERException ee) { + System.out.println("This is not a crmf request. Or this request has an error."); + System.exit(1); + } + int nummsgs = crmfMsgs.size(); + certReqMsg = (CertReqMsg)crmfMsgs.elementAt(0); + trq = new TaggedRequest(TaggedRequest.CRMF, null, + certReqMsg); + } else if (format.equals("pkcs10")) { + try { + pkcs = new PKCS10(decodedBytes); + } catch (IllegalArgumentException e) { + System.out.println("This is not a PKCS10 request."); + System.exit(1); + } + ByteArrayInputStream crInputStream = new ByteArrayInputStream( + pkcs.toByteArray()); + CertificationRequest cr = (CertificationRequest) + CertificationRequest.getTemplate().decode(crInputStream); + TaggedCertificationRequest tcr = new TaggedCertificationRequest( + new INTEGER(bpid++), cr); + trq = new + TaggedRequest(TaggedRequest.PKCS10, tcr, null); + } else { + System.out.println("Unrecognized request format: "+format); + System.exit(1); + } + reqSequence.addElement(trq); + } + } catch (IOException e) { + throw new IOException("Internal Error - " + e.toString()); + } catch (SignatureException e) { + throw new IOException("Internal Error - " + e.toString()); + } catch (NoSuchAlgorithmException e) { + throw new IOException("Internal Error - " + e.toString()); + } + + if (transactionMgtEnable.equals("true")) + bpid = addTransactionAttr(bpid, controlSeq, transactionMgtId, format, + pkcs, certReqMsg); + + if (identityProofEnable.equals("true")) + bpid = addIdentityProofAttr(bpid, controlSeq, reqSequence, + 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 = SignatureAlgorithm.RSASignatureWithSHA1Digest; + org.mozilla.jss.crypto.PrivateKey.Type signingKeyType = ((org.mozilla.jss.crypto.PrivateKey) privKey).getType(); + + 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((OutputStream) 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(com.netscape.osutil.OSUtil.BtoA(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) { + e.printStackTrace(); + System.exit(1); + } + return fullEnrollmentReq; + } + + static void printUsage() { + System.out.println(""); + System.out.println("Usage: CMCRequest <configuration file>"); + System.out.println("For example, CMCRequest CMCRequest.cfg"); + System.out.println(""); + System.out.println("The configuration file should look like as follows:"); + 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(""); + System.out.println("#output: full path for the CMC request in binary format"); + System.out.println("output=/u/doc/cmcReq"); + System.out.println(""); + System.out.println("#nickname: nickname for agent certificate which will be used"); + System.out.println("#to sign the CMC full request."); + 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(""); + System.out.println("#password: password for cert8.db which stores the agent"); + System.out.println("#certificate"); + System.out.println("password=pass"); + System.out.println(""); + System.out.println("#format: request format, either pkcs10 or crmf"); + System.out.println("format=crmf"); + 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(""); + System.out.println("#confirmCertAcceptance.serial: The serial number for"); + System.out.println("#confirmCertAcceptance control"); + System.out.println("confirmCertAcceptance.serial=3"); + System.out.println(""); + System.out.println("#confirmCertAcceptance.issuer: The issuer name for"); + System.out.println("#confirmCertAcceptance control"); + System.out.println("confirmCertAcceptance.issuer=cn=Certificate Manager,c=us"); + 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(""); + System.out.println("#getCert.serial: The serial number for getCert control"); + System.out.println("getCert.serial=3"); + System.out.println(""); + System.out.println("#getCert.issuer: The issuer name for getCert control"); + System.out.println("getCert.issuer=cn=Certificate Manager,c=us"); + 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(""); + 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(""); + System.out.println("#transactionMgt.id: transaction identifier. Verisign recommend"); + System.out.println("#transactionId to be MD5 hash of publicKey."); + System.out.println("transactionMgt.id="); + 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(""); + 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(""); + System.out.println("#revRequest.nickname: The nickname for the revoke certificate"); + System.out.println("revRequest.nickname=newuser's 102504a ID"); + System.out.println(""); + System.out.println("#revRequest.issuer: The issuer name for the certificate being"); + System.out.println("#revoked."); + System.out.println("revRequest.issuer=cn=Certificate Manager,c=us"); + System.out.println(""); + System.out.println("#revRequest.serial: The serial number for the certificate being"); + System.out.println("#revoked."); + System.out.println("revRequest.serial=61"); + System.out.println(""); + System.out.println("#revRequest.reason: The reason for revoking this certificate: "); + System.out.println("# unspecified, keyCompromise, caCompromise,"); + System.out.println("# affiliationChanged, superseded, cessationOfOperation,"); + System.out.println("# certificateHold, removeFromCRL"); + System.out.println("revRequest.reason=unspecified"); + System.out.println(""); + System.out.println("#revRequest.sharedSecret: The sharedSecret"); + System.out.println("revRequest.sharedSecret="); + System.out.println(""); + System.out.println("#revRequest.comment: The human readable comment"); + System.out.println("revRequest.comment="); + System.out.println(""); + System.out.println("#revRequest.invalidityDatePresent: if true, the current time will be the"); + System.out.println("# invalidityDate. If false, no invalidityDate"); + System.out.println("# is present."); + System.out.println("revRequest.invalidityDatePresent=false"); + System.out.println(""); + System.out.println("#identityProof.enable: if true, then the request will contain"); + System.out.println("#this control. Otherwise, false."); + System.out.println("identityProof.enable=true"); + System.out.println(""); + System.out.println("#identityProof.sharedSecret: Shared Secret"); + System.out.println("identityProof.sharedSecret=testing"); + System.out.println(""); + System.out.println("#popLinkWitness.enable: if true, then the request will contain"); + System.out.println("#this control. Otherwise, false."); + System.out.println("#If you want to test this control, make sure to use CRMFPopClient "); + System.out.println("# to generate the CRMF request which will include the "); + System.out.println("#idPOPLinkWitness attribute in the controls section of the "); + System.out.println("#CertRequest structure."); + System.out.println("popLinkWitness.enable=false"); + 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(""); + System.out.println("#LraPopWitness.bodyPartIDs: List of body part IDs"); + System.out.println("#Each id is separated by space."); + System.out.println("LraPopWitness.bodyPartIDs=1"); + System.exit(1); + } + + private static int addLraPopWitnessAttr(int bpid, SEQUENCE seq, String bodyPartIDs) { + StringTokenizer tokenizer = new StringTokenizer(bodyPartIDs, " "); + SEQUENCE bodyList = new SEQUENCE(); + while (tokenizer.hasMoreTokens()) { + String s = (String)tokenizer.nextToken(); + bodyList.addElement(new INTEGER(s)); + } + LraPopWitness lra = new LraPopWitness(new INTEGER(0), bodyList); + TaggedAttribute cont = new TaggedAttribute(new + INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_lraPOPWitness, lra); + System.out.println("Successfully create LRA POP witness control. bpid = "+(bpid-1)); + System.out.println(""); + seq.addElement(cont); + return bpid; + } + + private static int addConfirmCertAttr(int bpid, SEQUENCE seq, String confirmCertIssuer, + String confirmCertSerial) { + try { + INTEGER serial = new INTEGER(confirmCertSerial); + X500Name issuername = new X500Name(confirmCertIssuer); + byte[] issuerbyte = issuername.getEncoded(); + ANY issuern = new ANY(issuerbyte); + CMCCertId cmcCertId = new CMCCertId(issuern, serial, null); + TaggedAttribute cmcCertIdControl = new TaggedAttribute(new + INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_idConfirmCertAcceptance, cmcCertId); + System.out.println("Successfully create confirm certificate acceptance control. bpid = "+(bpid-1)); + System.out.println(""); + seq.addElement(cmcCertIdControl); + } catch (Exception e) { + System.out.println("Error in creating confirm certificate acceptance control. Check the parameters."); + System.exit(1); + } + return bpid; + } + + private static ENUMERATED toCRLReason(String str) { + if (str.equalsIgnoreCase("unspecified")) { + return RevRequest.unspecified; + } else if (str.equalsIgnoreCase("keyCompromise")) { + return RevRequest.keyCompromise; + } else if (str.equalsIgnoreCase("caCompromise")) { + return RevRequest.cACompromise; + } else if (str.equalsIgnoreCase("affiliationChanged")) { + return RevRequest.affiliationChanged; + } else if (str.equalsIgnoreCase("superseded")) { + return RevRequest.superseded; + } else if (str.equalsIgnoreCase("cessationOfOperation")) { + return RevRequest.cessationOfOperation; + } else if (str.equalsIgnoreCase("certificateHold")) { + return RevRequest.certificateHold; + } else if (str.equalsIgnoreCase("removeFromCRL")) { + return RevRequest.removeFromCRL; + } + + System.out.println("Unrecognized CRL reason"); + System.exit(1); + + return RevRequest.unspecified; + } + + private static int addIdentityProofAttr(int bpid, SEQUENCE seq, SEQUENCE reqSequence, + String sharedSecret) { + byte[] b = ASN1Util.encode(reqSequence); + byte[] key = null; + byte[] finalDigest = null; + try { + MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1"); + key = SHA1Digest.digest(sharedSecret.getBytes()); + } catch (NoSuchAlgorithmException ex) { + System.out.println( "CMCRequest::addIdentityProofAttr() - " + + "No such algorithm!" ); + return -1; + } + + try { + MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1"); + HMACDigest hmacDigest = new HMACDigest(SHA1Digest, key); + hmacDigest.update(b); + finalDigest = hmacDigest.digest(); + } catch (NoSuchAlgorithmException ex) { + } + + TaggedAttribute identityProof = new TaggedAttribute(new + INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_identityProof, + new OCTET_STRING(finalDigest)); + seq.addElement(identityProof); + System.out.println("Identity Proof control: "); + System.out.print(" Value: "); + for (int i=0; i<finalDigest.length; i++) { + System.out.print(finalDigest[i]+" "); + } + System.out.println(""); + System.out.println("Successfully create identityProof control. bpid = "+(bpid-1)); + System.out.println(""); + return bpid; + } + + private static int addRevRequestAttr(int bpid, SEQUENCE seq, SEQUENCE otherMsgSeq, String nickname, + String revRequestIssuer, String revRequestSerial, String revRequestReason, + String revRequestSharedSecret, String revRequestComment, String invalidityDatePresent, + CryptoManager manager) { + try { + if (nickname.length() <= 0) { + System.out.println("The nickname for the certificate being revoked is null"); + System.exit(1); + } + String nickname1 = nickname; + UTF8String comment = null; + OCTET_STRING sharedSecret = null; + GeneralizedTime d = null; + X500Name subjectname = new X500Name(revRequestIssuer); + INTEGER snumber = new INTEGER(revRequestSerial); + ENUMERATED reason = toCRLReason(revRequestReason); + if (revRequestSharedSecret.length() > 0) + sharedSecret = new OCTET_STRING(revRequestSharedSecret.getBytes()); + if (revRequestComment.length() > 0) + comment = new UTF8String(revRequestComment); + if (invalidityDatePresent.equals("true")) + d = new GeneralizedTime(new Date()); + RevRequest revRequest = + new RevRequest(new ANY(subjectname.getEncoded()), snumber, + reason, d, sharedSecret, comment); + int revokeBpid = bpid; + TaggedAttribute revRequestControl = new TaggedAttribute( + new INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_revokeRequest, revRequest); + seq.addElement(revRequestControl); + + if (sharedSecret != null) { + System.out.println("Successfully create revRequest control. bpid = "+(bpid-1)); + System.out.println(""); + return bpid; + } + + EncapsulatedContentInfo revokeContent = new EncapsulatedContentInfo( + OBJECT_IDENTIFIER.id_cct_PKIData, revRequestControl); + DigestAlgorithm digestAlg1 = null; + SignatureAlgorithm signAlg1 = SignatureAlgorithm.RSASignatureWithSHA1Digest; + java.security.PrivateKey revokePrivKey = null; + X509Certificate revokeCert = null; + try { + revokeCert = manager.findCertByNickname(nickname1); + } catch (ObjectNotFoundException e) { + System.out.println("Certificate not found: "+nickname1); + System.exit(1); + } + revokePrivKey = manager.findPrivKeyByCert(revokeCert); + org.mozilla.jss.crypto.PrivateKey.Type signingKeyType1 = + ((org.mozilla.jss.crypto.PrivateKey) revokePrivKey).getType(); + if (signingKeyType1.equals(org.mozilla.jss.crypto.PrivateKey.Type.DSA)) + signAlg1 = SignatureAlgorithm.DSASignatureWithSHA1Digest; + + MessageDigest rSHADigest = null; + byte[] rdigest = null; + try { + rSHADigest = MessageDigest.getInstance("SHA1"); + digestAlg1 = DigestAlgorithm.SHA1; + + ByteArrayOutputStream ostream = new ByteArrayOutputStream(); + + revRequestControl.encode((OutputStream) ostream); + rdigest = rSHADigest.digest(ostream.toByteArray()); + } catch (NoSuchAlgorithmException e) { + } + + ByteArrayInputStream bistream = + new ByteArrayInputStream(subjectname.getEncoded()); + Name iname = (Name)Name.getTemplate().decode(bistream); + IssuerAndSerialNumber ias1 = new IssuerAndSerialNumber(iname, snumber); + + SignerIdentifier rsi = new SignerIdentifier( + SignerIdentifier.ISSUER_AND_SERIALNUMBER, ias1, null); + + SignerInfo signInfo1 = new SignerInfo(rsi, null, null, + OBJECT_IDENTIFIER.id_cct_PKIData, rdigest, signAlg1, + (org.mozilla.jss.crypto.PrivateKey) revokePrivKey); + + SET signInfos1 = new SET(); + signInfos1.addElement(signInfo1); + SET digestAlgs1 = new SET(); + if (digestAlg1 != null) { + AlgorithmIdentifier ai1 = new AlgorithmIdentifier(digestAlg1.toOID(), null); + digestAlgs1.addElement(ai1); + } + + org.mozilla.jss.crypto.X509Certificate[] revokeCertChain = + manager.buildCertificateChain(revokeCert); + SET certs1 = new SET(); + for (int i=0; i<revokeCertChain.length; i++) { + ANY cert1 = new ANY(revokeCertChain[i].getEncoded()); + certs1.addElement(cert1); + } + + SignedData sData = new SignedData(digestAlgs1, revokeContent, certs1, null, signInfos1); + OBJECT_IDENTIFIER signedDataOID = new OBJECT_IDENTIFIER("1.2.840.113549.1.7.2"); + ByteArrayOutputStream bos1 = new ByteArrayOutputStream(); + sData.encode(bos1); + OtherMsg otherMsg = new OtherMsg(new INTEGER(revokeBpid), signedDataOID, new ANY(bos1.toByteArray())); + otherMsgSeq.addElement(otherMsg); + System.out.println("Successfully create revRequest control. bpid = "+(bpid-1)); + System.out.println(""); + } catch (Exception e) { + System.out.println("Error in creating revRequest control. Check the parameters."); + System.exit(1); + } + + return bpid; + } + + private static int addGetCertAttr(int bpid, SEQUENCE seq, String issuer, String serial) { + try { + INTEGER serialno = new INTEGER(serial); + X500Name issuername = new X500Name(issuer); + byte[] issuerbyte = issuername.getEncoded(); + ANY issuern = new ANY(issuerbyte); + GetCert getCert = new GetCert(issuern, serialno); + TaggedAttribute getCertControl = new TaggedAttribute(new + INTEGER(bpid++), + OBJECT_IDENTIFIER.id_cmc_getCert, getCert); + System.out.println("Successfully create get certificate control. bpid = "+(bpid-1)); + System.out.println(""); + seq.addElement(getCertControl); + } catch (Exception e) { + System.out.println("Error in creating get certificate control. Check the parameters."); + System.exit(1); + } + + return bpid; + } + + private static int addDataReturnAttr(int bpid, SEQUENCE seq, String str) { + try { + byte bvalue[] = str.getBytes(); + System.out.println("Data Return Control: "); + String ss = " Value: "; + for (int m=0; m<bvalue.length; m++) { + ss = ss+bvalue[m]+" "; + } + System.out.println(ss); + OCTET_STRING s = new OCTET_STRING(bvalue); + TaggedAttribute dataReturnControl = new TaggedAttribute(new + INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_dataReturn, s); + seq.addElement(dataReturnControl); + System.out.println("Successfully create data return control. bpid = "+(bpid-1)); + System.out.println(""); + } catch (Exception e) { + System.out.println("Error in creating data return control. Check the parameters."); + System.exit(1); + } + + return bpid; + } + + private static int addTransactionAttr(int bpid, SEQUENCE seq, String id, String format, + PKCS10 pkcs, CertReqMsg certReqMsg) { + byte[] transId = null; + Date date = new Date(); + String salt = "lala123" + date.toString(); + if (id == null || id.equals("")) { + try { + MessageDigest MD5Digest = MessageDigest.getInstance("MD5"); + if (format.equals("crmf")) { + CertRequest certreq = certReqMsg.getCertReq(); + CertTemplate certTemplate = certreq.getCertTemplate(); + SubjectPublicKeyInfo pkinfo = certTemplate.getPublicKey(); + BIT_STRING bitString = pkinfo.getSubjectPublicKey(); + byte[] b = bitString.getBits(); + transId = MD5Digest.digest(b); + } else if (format.equals("pkcs10")) { + transId = MD5Digest.digest(pkcs.getSubjectPublicKeyInfo().getKey()); + } + } catch (Exception ex) { + transId = salt.getBytes(); + } + } else { + transId = id.getBytes(); + } + + if( transId == null ) { + System.out.println( "CMCRequest::addTransactionAttr() - " + + "transId is null!" ); + return -1; + } + + INTEGER ii = new INTEGER(1, transId); + TaggedAttribute transactionId = new TaggedAttribute(new + INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_transactionId, ii); + System.out.println("Transaction ID control: "); + System.out.println(" Value: "+ii.toString()); + System.out.println("Successfully create transaction management control. bpid = "+(bpid-1)); + System.out.println(""); + + seq.addElement(transactionId); + + return bpid; + } + + private static int addSenderNonceAttr(int bpid, SEQUENCE seq, String nonce) { + byte[] dig; + String sn = nonce; + if (nonce == null || nonce.equals("")) { + // Verisign has transactionID,senderNonce + Date date = new Date(); + String salt = "lala123" + date.toString(); + + try { + MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1"); + + dig = SHA1Digest.digest(salt.getBytes()); + } catch (NoSuchAlgorithmException ex) { + dig = salt.getBytes(); + } + + sn = com.netscape.osutil.OSUtil.BtoA(dig); + } + byte bb[] = sn.getBytes(); + System.out.println("SenderNonce control: "); + String ss = " Value: "; + for (int m=0; m<bb.length; m++) { + ss = ss+bb[m]+" "; + } + System.out.println(ss); + TaggedAttribute senderNonce = new TaggedAttribute(new + INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_senderNonce, + new OCTET_STRING(sn.getBytes())); + System.out.println("Successfully create sender nonce control. bpid = "+(bpid-1)); + System.out.println(""); + seq.addElement(senderNonce); + return bpid; + } + + private static int addPopLinkWitnessAttr(int bpid, SEQUENCE controlSeq) { +byte[] seed = +{0x10, 0x53, 0x42, 0x24, 0x1a, 0x2a, 0x35, 0x3c, + 0x7a, 0x52, 0x54, 0x56, 0x71, 0x65, 0x66, 0x4c, + 0x51, 0x34, 0x35, 0x23, 0x3c, 0x42, 0x43, 0x45, + 0x61, 0x4f, 0x6e, 0x43, 0x1e, 0x2a, 0x2b, 0x31, + 0x32, 0x34, 0x35, 0x36, 0x55, 0x51, 0x48, 0x14, + 0x16, 0x29, 0x41, 0x42, 0x43, 0x7b, 0x63, 0x44, + 0x6a, 0x12, 0x6b, 0x3c, 0x4c, 0x3f, 0x00, 0x14, + 0x51, 0x61, 0x15, 0x22, 0x23, 0x5f, 0x5e, 0x69}; + + TaggedAttribute idPOPLinkRandom = new TaggedAttribute(new + INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_idPOPLinkRandom, + new OCTET_STRING(seed)); + controlSeq.addElement(idPOPLinkRandom); + System.out.println("Successfully create PopLinkWitness control. bpid = "+(bpid-1)); + System.out.println(""); + return bpid; + } + + public static void main(String[]s) { + String numRequests=null; + String dbdir=null, nickname=null; + String ifilename=null, ofilename=null, password=null, format=null; + FileOutputStream outputBlob = null; + String confirmCertEnable = "false", confirmCertIssuer = null, confirmCertSerial = null; + String getCertEnable = "false", getCertIssuer = null, getCertSerial = null; + String dataReturnEnable = "false", dataReturnData = null; + String transactionMgtEnable = "false", transactionMgtId = null; + String senderNonceEnable = "false", senderNonce = null; + String revCertNickname = ""; + String revRequestEnable = "false", revRequestIssuer = null, revRequestSerial= null; + String revRequestReason = null, revRequestSharedSecret = null, revRequestComment = null; + String revRequestInvalidityDatePresent = "false"; + String identityProofEnable = "false", identityProofSharedSecret = null; + String popLinkWitnessEnable = "false"; + String bodyPartIDs = null, lraPopWitnessEnable = "false"; + + System.out.println(""); + + // Check that the correct # of arguments were submitted to the program + if( s.length != ( ARGC ) ) { + System.out.println("Wrong number of parameters:" + s.length); + printUsage(); + } + + String configFile = s[0]; + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader( + new BufferedInputStream( + new FileInputStream( + configFile)))); + } catch (FileNotFoundException e) { + System.out.println("CMCRequest: can't find configuration file: "+configFile); + printUsage(); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + + try { + String str = ""; + while ((str = reader.readLine()) != null) { + str = str.trim(); + if (!str.startsWith("#") && str.length() > 0) { + int index = str.indexOf("="); + String name = ""; + String val = ""; + if (index == -1) { + System.out.println("Error in configuration file: "+str); + System.exit(1); + } + name = str.substring(0, index); + if (index != str.length()-1) + val = str.substring(index+1); + + if (name.equals("format")) { + format = val; + } else if (name.equals("dbdir")) { + dbdir = val; + } else if (name.equals("nickname")) { + nickname = val; + } else if (name.equals("password")) { + password = val; + } else if (name.equals("output")) { + ofilename = val; + } else if (name.equals("input")) { + ifilename = val; + } else if (name.equals("confirmCertAcceptance.serial")) { + confirmCertSerial = val; + } else if (name.equals("confirmCertAcceptance.issuer")) { + confirmCertIssuer = val; + } else if (name.equals("confirmCertAcceptance.enable")) { + confirmCertEnable = val; + } else if (name.equals("getCert.enable")) { + getCertEnable = val; + } else if (name.equals("getCert.issuer")) { + getCertIssuer = val; + } else if (name.equals("getCert.serial")) { + getCertSerial = val; + } else if (name.equals("dataReturn.enable")) { + dataReturnEnable = val; + } else if (name.equals("dataReturn.data")) { + dataReturnData = val; + } else if (name.equals("transactionMgt.enable")) { + transactionMgtEnable = val; + } else if (name.equals("transactionMgt.id")) { + transactionMgtId = val; + } else if (name.equals("senderNonce.enable")) { + senderNonceEnable = val; + } else if (name.equals("senderNonce")) { + senderNonce = val; + } else if (name.equals("revRequest.enable")) { + revRequestEnable = val; + } else if (name.equals("revRequest.issuer")) { + revRequestIssuer = val; + } else if (name.equals("revRequest.serial")) { + revRequestSerial = val; + } else if (name.equals("revRequest.reason")) { + revRequestReason = val; + } else if (name.equals("revRequest.sharedSecret")) { + revRequestSharedSecret = val; + } else if (name.equals("revRequest.comment")) { + revRequestComment = val; + } else if (name.equals("revRequest.invalidityDatePresent")) { + revRequestInvalidityDatePresent = val; + } else if (name.equals("revRequest.nickname")) { + revCertNickname = val; + } else if (name.equals("identityProof.enable")) { + identityProofEnable = val; + } else if (name.equals("identityProof.sharedSecret")) { + identityProofSharedSecret = val; + } else if (name.equals("popLinkWitness.enable")) { + popLinkWitnessEnable = val; + } else if (name.equals("LraPopWitness.enable")) { + lraPopWitnessEnable = val; + } else if (name.equals("LraPopWitness.bodyPartIDs")) { + bodyPartIDs = val; + } else if (name.equals("numRequests")) { + numRequests = val; + } + } + } + } catch (Exception e) { + e.printStackTrace(); + 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 = (String)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(); + } + + if (nickname == null) { + System.out.println("Missing nickname."); + printUsage(); + } + + try { + // initialize CryptoManager + if (dbdir == null) + dbdir = "."; + String mPrefix = ""; + System.out.println("cert/key prefix = " + mPrefix); + System.out.println("path = " + dbdir); + CryptoManager.InitializationValues vals = + new CryptoManager.InitializationValues(dbdir, mPrefix, + mPrefix, "secmod.db"); + + CryptoManager.initialize(vals); + CryptoManager cm = CryptoManager.getInstance(); + CryptoToken token = cm.getInternalKeyStorageToken(); + Password pass = new Password(password.toCharArray()); + + token.login(pass); + CryptoStore store = token.getCryptoStore(); + X509Certificate[] list = store.getCertificates(); + X509Certificate signerCert = null; + + signerCert = cm.findCertByNickname(nickname); + + 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 = new String(); + String asciiBASE64Blob = new String(); + + try { + while ((asciiBASE64BlobChunk = inputBlob.readLine()) != null) { + if (!(asciiBASE64BlobChunk.startsWith(HEADER)) && + !(asciiBASE64BlobChunk.startsWith(TRAILER))) { + asciiBASE64Blob += asciiBASE64BlobChunk.trim(); + } + } + requests[i] = asciiBASE64Blob; + } 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); + } + } + + 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 (lraPopWitnessEnable.equalsIgnoreCase("true")) { + if (bodyPartIDs.length() == 0) { + System.out.println("Illegal parameters for Lra Pop Witness 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); + } + + 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, revCertNickname, + revRequestIssuer, revRequestSerial, revRequestReason, revRequestSharedSecret, + revRequestComment, revRequestInvalidityDatePresent, cm); + } + + ContentInfo cmcblob = getCMCBlob(signerCert, nickname, requests, format, + cm, transactionMgtEnable, transactionMgtId, identityProofEnable, + identityProofSharedSecret, controlSeq, otherMsgSeq, bpid); + + // (6) Finally, print the actual CMC blob to the + // specified output file + FileOutputStream os = null; + try { + os = new FileOutputStream(ofilename); + cmcblob.encode(os); + System.out.println(""); + System.out.println(""); + System.out.println("The CMC enrollment request in binary format is stored in "+ + ofilename+"."); + } catch (IOException e) { + System.out.println("CMCRequest: unable to open file " +ofilename+ + " for writing:\n" + e); + } + + try { + os.close(); + } catch (IOException e) { + System.out.println("CMCRequest: Unexpected error " + + "encountered while attempting to close() " + + "\n" + e); + } + + }catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + } +} |