diff options
Diffstat (limited to 'base/java-tools/src')
3 files changed, 213 insertions, 72 deletions
diff --git a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java index ac523ad24..6e27cb100 100644 --- a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java +++ b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java @@ -103,6 +103,9 @@ import com.netscape.cmsutil.util.HMACDigest; import com.netscape.cmsutil.util.Utils; import netscape.security.pkcs.PKCS10; +import netscape.security.x509.KeyIdentifier; +import netscape.security.x509.PKIXExtensions; +import netscape.security.x509.SubjectKeyIdentifierExtension; import netscape.security.x509.X500Name; import netscape.security.x509.X509CertImpl; @@ -121,6 +124,7 @@ public class CMCRequest { public static final int ARGC = 1; public static final String HEADER = "-----BEGIN"; public static final String TRAILER = "-----END"; + public static SubjectKeyIdentifierExtension skiExtn = null; void cleanArgs(String[] s) { @@ -193,7 +197,7 @@ public class CMCRequest { } /** - * signData signs the request PKIData + * signData signs the request PKIData using existing cert * * @param signerCert the certificate of the authorized signer of the CMC revocation request. * @param nickname the nickname of the certificate inside the token. @@ -212,6 +216,15 @@ public class CMCRequest { SignedData req = null; System.out.println(method + "begins: "); + if (signerCert == null || + tokenName == null || + nickname == null || + manager == null || + pkidata == null) { + System.out.println(method + "method parameters cannot be null"); + System.exit(1); + } + try { java.security.PrivateKey privKey = null; SignerIdentifier si = null; @@ -232,7 +245,72 @@ public class CMCRequest { privKey = getPrivateKey(tokenName, nickname); if (privKey != null) System.out.println(method + " got signer privKey"); + else { + System.out.println(method + " signer privKey not foudn on token"); + System.exit(1); + } + + org.mozilla.jss.crypto.X509Certificate[] certChain = manager.buildCertificateChain(signerCert); + req = createSignedData(privKey, si, certChain, pkidata); + + System.out.println(method + "signed request generated."); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + + return req; + } + + /* + * signData self-signs the PKIData using the private key that matches + * the public key in the request + */ + static SignedData signData( + java.security.PrivateKey privKey, + PKIData pkidata) { + String method = "signData for selfSign: "; + System.out.println(method + "begins: "); + SignedData req = null; + + if (privKey == null || + pkidata == null) { + System.out.println(method + "method parameters cannot be null"); + System.exit(1); + } + + KeyIdentifier keyIdObj = null; + try { + keyIdObj = (KeyIdentifier) skiExtn.get(SubjectKeyIdentifierExtension.KEY_ID); + SignerIdentifier si = new SignerIdentifier( + SignerIdentifier.SUBJECT_KEY_IDENTIFIER, + null, new OCTET_STRING(keyIdObj.getIdentifier())); + req = createSignedData(privKey, si, null /*certChain*/, pkidata); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + return req; + } + static SignedData createSignedData( + java.security.PrivateKey privKey, + SignerIdentifier signerId, + org.mozilla.jss.crypto.X509Certificate[] certChain, + PKIData pkidata) { + + String method = "createSignedData: "; + System.out.println(method + "begins"); + if (privKey == null || + signerId == null || + pkidata == null) { + // certChain could be null + System.out.println(method + "method parameters cannot be null"); + System.exit(1); + } + + SignedData req = null; + try { EncapsulatedContentInfo ci = new EncapsulatedContentInfo(OBJECT_IDENTIFIER.id_cct_PKIData, pkidata); DigestAlgorithm digestAlg = null; SignatureAlgorithm signAlg = getSigningAlgFromPrivate(privKey); @@ -251,11 +329,18 @@ public class CMCRequest { pkidata.encode(ostream); digest = SHADigest.digest(ostream.toByteArray()); } catch (NoSuchAlgorithmException e) { - System.out.println(e); System.exit(1);} + 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, + SignerInfo signInfo = new SignerInfo(signerId, null, null, + OBJECT_IDENTIFIER.id_cct_PKIData, digest, signAlg, (org.mozilla.jss.crypto.PrivateKey) privKey); + + String digestAlgName = signInfo.getDigestEncryptionAlgorithm().toString(); + System.out.println(method + "digest algorithm =" + digestAlgName); + SET signInfos = new SET(); signInfos.addElement(signInfo); @@ -266,21 +351,20 @@ public class CMCRequest { 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); + if (certChain != null) { + System.out.println(method + "building cert chain"); + for (int i = 0; i < certChain.length; i++) { + ANY cert = new ANY(certChain[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; } @@ -325,6 +409,7 @@ public class CMCRequest { * @return request in PKIData */ static PKIData createPKIData( + String selfSign, String[] rValue, String format, String transactionMgtEnable, String transactionMgtId, String identificationEnable, String identification, @@ -387,13 +472,26 @@ public class CMCRequest { } certReqMsg = (CertReqMsg) crmfMsgs.elementAt(0); + CertRequest certReq = certReqMsg.getCertReq(); + CertTemplate certTemplate = certReq.getCertTemplate(); + if (selfSign.equals("true")) { + skiExtn = (SubjectKeyIdentifierExtension) CryptoUtil.getExtensionFromCertTemplate( + certTemplate, + PKIXExtensions.SubjectKey_Id); + if (skiExtn != null) { + System.out.println(method + + " SubjectKeyIdentifier extension found in self-signed request"); + } else { + System.out.println(method + + " SubjectKeyIdentifier extension missing in self-signed request"); + System.exit(1); + } + } if (popLinkWitnessV2Enable.equals("true")) { System.out.println(method + "popLinkWitnessV2 enabled. reconstructing crmf"); //crmf reconstruction to include PopLinkWitnessV2 control - CertRequest certReq = certReqMsg.getCertReq(); INTEGER certReqId = certReq.getCertReqId(); - CertTemplate certTemplate = certReq.getCertTemplate(); SEQUENCE controls = certReq.getControls(); controls.addElement(new AVA(OBJECT_IDENTIFIER.id_cmc_popLinkWitnessV2, popLinkWitnessV2Control)); @@ -449,6 +547,22 @@ public class CMCRequest { System.out.println(method + " Excception:" + e2.toString()); System.exit(1); } + + if (selfSign.equals("true")) { + try { + skiExtn = (SubjectKeyIdentifierExtension) CryptoUtil.getExtensionFromPKCS10( + pkcs, "SubjectKeyIdentifier"); + } catch (IOException e) { + System.out.println(method + "getting SubjectKeyIdentifiere..." + e); + } + + if (skiExtn != null) { + System.out.println(method + " SubjectKeyIdentifier extension found"); + } else { + System.out.println(method + " SubjectKeyIdentifier extension missing"); + System.exit(1); + } + } ByteArrayInputStream crInputStream = new ByteArrayInputStream( pkcs.toByteArray()); CertificationRequest cr = (CertificationRequest) CertificationRequest.getTemplate() @@ -661,8 +775,13 @@ public class CMCRequest { 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("#selfSign: if selfSign is true, the CMC request will be"); + System.out.println("#signed with the pairing private key of the request;"); + System.out.println("#and in which case the nickname will be ignored"); System.out.println("nickname=CMS Agent Certificate"); System.out.println(""); + System.out.println("selfSign=false"); + System.out.println(""); System.out.println("#dbdir: directory for cert8.db, key3.db and secmod.db"); System.out.println("dbdir=./"); System.out.println(""); @@ -1700,6 +1819,7 @@ public class CMCRequest { String popLinkWitnessV2Enable = "false", popLinkWitnessV2keyGenAlg = "SHA256", popLinkWitnessV2macAlg = "SHA256"; String popLinkWitnessEnable = "false"; String bodyPartIDs = null, lraPopWitnessEnable = "false"; + String selfSign = "false"; System.out.println(""); @@ -1760,6 +1880,8 @@ public class CMCRequest { decryptedPopEnable = val; } else if (name.equals("encryptedPopResponseFile")) { encryptedPopResponseFile = val; + } else if (name.equals("request.selfSign")) { + selfSign = val; } else if (name.equals("request.privKeyId")) { privKeyId = val; } else if (name.equals("decryptedPopRequestFile")) { @@ -1846,7 +1968,7 @@ public class CMCRequest { printUsage(); } - if (nickname == null) { + if (!selfSign.equals("true") && nickname == null) { System.out.println("Missing nickname."); printUsage(); } @@ -1898,14 +2020,14 @@ public class CMCRequest { System.out.println("got signerCert: "+ certname.toString()); } - //cfu ContentInfo cmcblob = null; PKIData pkidata = null; PrivateKey privk = null; - if (decryptedPopEnable.equalsIgnoreCase("true") || + if (selfSign.equalsIgnoreCase("true") || + decryptedPopEnable.equalsIgnoreCase("true") || popLinkWitnessV2Enable.equalsIgnoreCase("true")) { if (privKeyId == null) { - System.out.println("ecryptedPop.enable or popLinkWitnessV2 true, but privKeyId not specified."); + System.out.println("selfSign or ecryptedPop.enable or popLinkWitnessV2 true, but privKeyId not specified."); printUsage(); } else { System.out.println("got request privKeyId: " + privKeyId); @@ -2095,6 +2217,7 @@ public class CMCRequest { // create the request PKIData pkidata = createPKIData( + selfSign, requests, format, transactionMgtEnable, transactionMgtId, identificationEnable, identification, @@ -2114,7 +2237,16 @@ public class CMCRequest { } // sign the request - SignedData signedData = signData(signerCert, tokenName, nickname, cm, pkidata); + SignedData signedData = null; + if (selfSign.equalsIgnoreCase("true")) { + // selfSign signes with private key + System.out.println("selfSign is true..."); + signedData = signData(privk, pkidata); + } else { + // none selfSign signes with existing cert + System.out.println("selfSign is false..."); + signedData = signData(signerCert, tokenName, nickname, cm, pkidata); + } if (signedData == null) { System.out.println("signData() returns null. Exiting with error"); System.exit(1); diff --git a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java index d0e5c2784..0057a1d52 100644 --- a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java +++ b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java @@ -86,6 +86,8 @@ import com.netscape.cmsutil.util.HMACDigest; import com.netscape.cmsutil.util.Utils; import netscape.security.util.WrappingParams; +import netscape.security.x509.KeyIdentifier; +import netscape.security.x509.PKIXExtensions; import netscape.security.x509.X500Name; /** @@ -196,6 +198,8 @@ public class CRMFPopClient { option.setArgName("keySet"); options.addOption(option); + options.addOption("y", false, "for Self-signed cmc."); + options.addOption("v", "verbose", false, "Run in verbose mode."); options.addOption(null, "help", false, "Show help message."); @@ -214,6 +218,9 @@ public class CRMFPopClient { System.out.println(" -k <true|false> Attribute value encoding in subject DN (default: false)"); System.out.println(" - true: enabled"); System.out.println(" - false: disabled"); + System.out.println(" -y <true|false> Add SubjectKeyIdentifier extension in case of self-signed CMC requests (default: false)"); + System.out.println(" - true: enabled"); + System.out.println(" - false: disabled"); System.out.println(" -a <rsa|ec> Key algorithm (default: rsa)"); System.out.println(" - rsa: RSA"); System.out.println(" - ec: ECC"); @@ -320,6 +327,8 @@ public class CRMFPopClient { int sensitive = Integer.parseInt(cmd.getOptionValue("s", "-1")); int extractable = Integer.parseInt(cmd.getOptionValue("e", "-1")); + boolean self_sign = cmd.hasOption("y"); + // get the key wrapping mechanism boolean keyWrap = true; if (cmd.hasOption("g")) { @@ -516,6 +525,7 @@ public class CRMFPopClient { if (verbose) System.out.println("Creating certificate request"); CertRequest certRequest = client.createCertRequest( + self_sign, token, transportCert, algorithm, keyPair, subject, archivalMechanism, wrappingKeySet); @@ -629,6 +639,19 @@ public class CRMFPopClient { Name subject, String archivalMechanism, String wrappingKeySet) throws Exception { + return createCertRequest(false, token, transportCert, algorithm, keyPair, + subject, archivalMechanism, wrappingKeySet); + } + + public CertRequest createCertRequest( + boolean self_sign, + CryptoToken token, + X509Certificate transportCert, + String algorithm, + KeyPair keyPair, + Name subject, + String archivalMechanism, + String wrappingKeySet) throws Exception { EncryptionAlgorithm encryptAlg = null; if (wrappingKeySet == null) { @@ -663,6 +686,15 @@ public class CRMFPopClient { seq.addElement(new AVA(OBJECT_IDENTIFIER.id_cmc_idPOPLinkWitness, ostr)); */ + if (self_sign) { // per rfc 5272 + System.out.println("CRMFPopClient: self_sign true. Generating SubjectKeyIdentifier extension."); + KeyIdentifier subjKeyId = CryptoUtil.createKeyIdentifier(keyPair); + OBJECT_IDENTIFIER oid = new OBJECT_IDENTIFIER(PKIXExtensions.SubjectKey_Id.toString()); + SEQUENCE extns = new SEQUENCE(); + extns.addElement(new AVA(oid, new OCTET_STRING(subjKeyId.getIdentifier()))); + certTemplate.setExtensions(extns); + } + return new CertRequest(new INTEGER(1), certTemplate, seq); } diff --git a/base/java-tools/src/com/netscape/cmstools/PKCS10Client.java b/base/java-tools/src/com/netscape/cmstools/PKCS10Client.java index fd1d08749..795c24be0 100644 --- a/base/java-tools/src/com/netscape/cmstools/PKCS10Client.java +++ b/base/java-tools/src/com/netscape/cmstools/PKCS10Client.java @@ -17,19 +17,15 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.cmstools; -import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.security.KeyPair; -import java.security.PublicKey; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.asn1.BMPString; -import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.PrintableString; -import org.mozilla.jss.asn1.SET; import org.mozilla.jss.asn1.TeletexString; import org.mozilla.jss.asn1.UTF8String; import org.mozilla.jss.asn1.UniversalString; @@ -37,20 +33,17 @@ import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.KeyPairAlgorithm; import org.mozilla.jss.crypto.KeyPairGenerator; import org.mozilla.jss.crypto.PrivateKey; -import org.mozilla.jss.crypto.SignatureAlgorithm; -import org.mozilla.jss.pkcs10.CertificationRequest; -import org.mozilla.jss.pkcs10.CertificationRequestInfo; import org.mozilla.jss.pkix.primitive.AVA; import org.mozilla.jss.pkix.primitive.Name; -import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo; import org.mozilla.jss.util.Password; import com.netscape.cmsutil.crypto.CryptoUtil; -import com.netscape.cmsutil.util.Utils; import netscape.security.pkcs.PKCS10; +import netscape.security.x509.Extensions; +import netscape.security.x509.KeyIdentifier; +import netscape.security.x509.SubjectKeyIdentifierExtension; import netscape.security.x509.X500Name; -import netscape.security.x509.X509Key; /** * Generates an ECC or RSA key pair in the security database, constructs a @@ -91,6 +84,8 @@ public class PKCS10Client { " -x <true for SSL cert that does ECDH ECDSA; false otherwise; default false>\n"); System.out.println( " available ECC curve names (if provided by the crypto module): nistp256 (secp256r1),nistp384 (secp384r1),nistp521 (secp521r1),nistk163 (sect163k1),sect163r1,nistb163 (sect163r2),sect193r1,sect193r2,nistk233 (sect233k1),nistb233 (sect233r1),sect239k1,nistk283 (sect283k1),nistb283 (sect283r1),nistk409 (sect409k1),nistb409 (sect409r1),nistk571 (sect571k1),nistb571 (sect571r1),secp160k1,secp160r1,secp160r2,secp192k1,nistp192 (secp192r1, prime192v1),secp224k1,nistp224 (secp224r1),secp256k1,prime192v2,prime192v3,prime239v1,prime239v2,prime239v3,c2pnb163v1,c2pnb163v2,c2pnb163v3,c2pnb176v1,c2tnb191v1,c2tnb191v2,c2tnb191v3,c2pnb208w1,c2tnb239v1,c2tnb239v2,c2tnb239v3,c2pnb272w1,c2pnb304w1,c2tnb359w1,c2pnb368w1,c2tnb431r1,secp112r1,secp112r2,secp128r1,secp128r2,sect113r1,sect113r2,sect131r1,sect131r2\n"); + System.out.println( + "In addition: -y <true for adding SubjectKeyIdentifier extensionfor self-signed cmc requests; false otherwise; default false>\n"); } public static void main(String args[]) throws Exception { @@ -105,6 +100,8 @@ public class PKCS10Client { boolean ec_ssl_ecdh = false; int rsa_keylen = 2048; + boolean self_sign = false; + if (args.length < 4) { printUsage(); System.exit(1); @@ -171,6 +168,12 @@ public class PKCS10Client { subjectName = args[i+1]; } else if (name.equals("-h")) { tokenName = args[i+1]; + } else if (name.equals("-y")) { + String temp = args[i+1]; + if (temp.equals("true")) + self_sign = true; + else + self_sign = false; } else { System.out.println("Unrecognized argument(" + i + "): " + name); @@ -273,55 +276,29 @@ public class PKCS10Client { Attribute attr = new Attribute(OBJECT_IDENTIFIER.id_cmc_idPOPLinkWitness, ostr); ***/ - SET attributes = new SET(); - //attributes.addElement(attr); - Name n = getJssName(enable_encoding, subjectName); - SubjectPublicKeyInfo subjectPub = new SubjectPublicKeyInfo(pair.getPublic()); - System.out.println("PKCS10Client: pair.getPublic() called."); - CertificationRequestInfo certReqInfo = - new CertificationRequestInfo(new INTEGER(0), n, subjectPub, attributes); - System.out.println("PKCS10Client: CertificationRequestInfo() created."); - String b64E = ""; - if (alg.equals("rsa")) { - CertificationRequest certRequest = null; - certRequest = new CertificationRequest(certReqInfo, - pair.getPrivate(), SignatureAlgorithm.RSASignatureWithSHA256Digest); - System.out.println("PKCS10Client: CertificationRequest created."); + Extensions extns = new Extensions(); + if (self_sign) { // per rfc 5272 + System.out.println("PKCS10Client: self_sign true. Generating SubjectKeyIdentifier extension."); + KeyIdentifier subjKeyId = CryptoUtil.createKeyIdentifier(pair); + SubjectKeyIdentifierExtension extn = new SubjectKeyIdentifierExtension(false, + subjKeyId.getIdentifier()); + extns.add(extn); + } - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - certRequest.encode(bos); - byte[] bb = bos.toByteArray(); + String b64E = ""; + PKCS10 certReq = CryptoUtil.createCertificationRequest( + subjectName, pair, extns); - System.out.println("PKCS10Client: calling Utils.b64encode."); - b64E = Utils.base64encode(bb); - System.out.println("PKCS10Client: b64encode completes."); - } else { // "ec" + if (certReq == null) { + System.out.println("PKCS10Client: cert request null"); + System.exit(1); + } else + System.out.println("PKCS10Client: CertificationRequest created."); + byte[] certReqb = certReq.toByteArray(); + b64E = CryptoUtil.base64Encode(certReqb); - CryptoToken t = cm.getThreadToken(); - System.out.println("PKCS10Client: token is: "+ t.getName()); - PublicKey pubk = pair.getPublic(); - if (pubk == null) { - System.out.println("PKCS10Client: pubk null."); - System.exit(1); - } - X509Key xKey = null; - byte pubk_encoded[] = pubk.getEncoded(); - xKey = CryptoUtil.getPublicX509ECCKey(pubk_encoded); - System.out.println("PKCS10Client: calling CryptoUtil.createCertificationRequest"); - PKCS10 certReq = CryptoUtil.createCertificationRequest( - subjectName, xKey, (org.mozilla.jss.crypto.PrivateKey) pair.getPrivate(), - "SHA256withEC"); - - System.out.println("PKCS10Client: created cert request"); - if (certReq == null) { - System.out.println("PKCS10Client: cert request null"); - System.exit(1); - } else - System.out.println("PKCS10Client: cert request not null"); - byte[] certReqb = certReq.toByteArray(); - b64E = CryptoUtil.base64Encode(certReqb); - } + System.out.println("PKCS10Client: b64encode completes."); // print out keyid to be used in cmc popLinkWitnessV2 PrivateKey privateKey = (PrivateKey) pair.getPrivate(); |
