From 7a0252247e860806d6456e997149602c9750206a Mon Sep 17 00:00:00 2001 From: Christina Fu Date: Tue, 15 Jan 2013 23:59:24 -0800 Subject: https://fedorahosted.org/pki/ticket/362 RFE: CMC ECC --- base/ca/shared/profiles/ca/caCMCUserCert.cfg | 2 +- base/ca/shared/profiles/ca/caFullCMCUserCert.cfg | 2 +- base/ca/shared/profiles/ca/caOtherCert.cfg | 2 +- base/ca/shared/profiles/ca/caSimpleCMCUserCert.cfg | 2 +- .../com/netscape/cms/authentication/CMCAuth.java | 63 ++- .../netscape/cms/profile/common/EnrollProfile.java | 37 +- .../cms/profile/input/CMCCertReqInput.java | 1 + .../src/com/netscape/cmstools/CMCRequest.java | 144 ++++-- .../src/com/netscape/cmstools/CMCRevoke.java | 73 +-- .../src/com/netscape/cmstools/CRMFPopClient.java | 558 ++++++++++++--------- .../src/com/netscape/cmstools/HttpClient.java | 65 ++- .../src/com/netscape/cmstools/PKCS10Client.java | 295 ++++++++--- base/util/src/netscape/security/pkcs/PKCS10.java | 9 +- .../src/netscape/security/x509/X509CRLImpl.java | 8 + 14 files changed, 871 insertions(+), 390 deletions(-) diff --git a/base/ca/shared/profiles/ca/caCMCUserCert.cfg b/base/ca/shared/profiles/ca/caCMCUserCert.cfg index 8d402f771..e703f0cd3 100644 --- a/base/ca/shared/profiles/ca/caCMCUserCert.cfg +++ b/base/ca/shared/profiles/ca/caCMCUserCert.cfg @@ -31,7 +31,7 @@ policyset.cmcUserCertSet.2.default.params.startTime=0 policyset.cmcUserCertSet.3.constraint.class_id=keyConstraintImpl policyset.cmcUserCertSet.3.constraint.name=Key Constraint policyset.cmcUserCertSet.3.constraint.params.keyType=- -policyset.cmcUserCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096 +policyset.cmcUserCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096,nistp256,nistp521 policyset.cmcUserCertSet.3.default.class_id=userKeyDefaultImpl policyset.cmcUserCertSet.3.default.name=Key Default policyset.cmcUserCertSet.4.constraint.class_id=noConstraintImpl diff --git a/base/ca/shared/profiles/ca/caFullCMCUserCert.cfg b/base/ca/shared/profiles/ca/caFullCMCUserCert.cfg index c9507b56f..2276f5000 100644 --- a/base/ca/shared/profiles/ca/caFullCMCUserCert.cfg +++ b/base/ca/shared/profiles/ca/caFullCMCUserCert.cfg @@ -29,7 +29,7 @@ policyset.cmcUserCertSet.2.default.params.range=180 policyset.cmcUserCertSet.2.default.params.startTime=0 policyset.cmcUserCertSet.3.constraint.class_id=keyConstraintImpl policyset.cmcUserCertSet.3.constraint.name=Key Constraint -policyset.cmcUserCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096 +policyset.cmcUserCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096,nistp256,nistp521 policyset.cmcUserCertSet.3.constraint.params.keyType=- policyset.cmcUserCertSet.3.default.class_id=userKeyDefaultImpl policyset.cmcUserCertSet.3.default.name=Key Default diff --git a/base/ca/shared/profiles/ca/caOtherCert.cfg b/base/ca/shared/profiles/ca/caOtherCert.cfg index 305a37b92..38c03bb89 100644 --- a/base/ca/shared/profiles/ca/caOtherCert.cfg +++ b/base/ca/shared/profiles/ca/caOtherCert.cfg @@ -76,7 +76,7 @@ policyset.otherCertSet.7.constraint.name=No Constraint policyset.otherCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl policyset.otherCertSet.7.default.name=Extended Key Usage Extension Default policyset.otherCertSet.7.default.params.exKeyUsageCritical=false -policyset.otherCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.1 +policyset.otherCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2 policyset.otherCertSet.8.constraint.class_id=signingAlgConstraintImpl policyset.otherCertSet.8.constraint.name=No Constraint policyset.otherCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC diff --git a/base/ca/shared/profiles/ca/caSimpleCMCUserCert.cfg b/base/ca/shared/profiles/ca/caSimpleCMCUserCert.cfg index a823bab10..f470a1dc2 100644 --- a/base/ca/shared/profiles/ca/caSimpleCMCUserCert.cfg +++ b/base/ca/shared/profiles/ca/caSimpleCMCUserCert.cfg @@ -28,7 +28,7 @@ policyset.cmcUserCertSet.2.default.params.range=180 policyset.cmcUserCertSet.2.default.params.startTime=0 policyset.cmcUserCertSet.3.constraint.class_id=keyConstraintImpl policyset.cmcUserCertSet.3.constraint.name=Key Constraint -policyset.cmcUserCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096 +policyset.cmcUserCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096,nistp256,nistp521 policyset.cmcUserCertSet.3.constraint.params.keyType=- policyset.cmcUserCertSet.3.default.class_id=userKeyDefaultImpl policyset.cmcUserCertSet.3.default.name=Key Default diff --git a/base/common/src/com/netscape/cms/authentication/CMCAuth.java b/base/common/src/com/netscape/cms/authentication/CMCAuth.java index 2844601f4..6ce4c26dd 100644 --- a/base/common/src/com/netscape/cms/authentication/CMCAuth.java +++ b/base/common/src/com/netscape/cms/authentication/CMCAuth.java @@ -41,8 +41,11 @@ import netscape.security.x509.X500Name; import netscape.security.x509.X509CertImpl; import netscape.security.x509.X509CertInfo; import netscape.security.x509.X509Key; +import netscape.security.util.DerValue; import org.mozilla.jss.CryptoManager; +import org.mozilla.jss.crypto.CryptoToken; +import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; @@ -53,6 +56,7 @@ import org.mozilla.jss.asn1.SET; import org.mozilla.jss.crypto.DigestAlgorithm; import org.mozilla.jss.pkcs10.CertificationRequest; import org.mozilla.jss.pkcs11.PK11PubKey; +import org.mozilla.jss.pkcs11.PK11ECPublicKey; import org.mozilla.jss.pkix.cert.Certificate; import org.mozilla.jss.pkix.cert.CertificateInfo; import org.mozilla.jss.pkix.cmc.PKIData; @@ -351,6 +355,10 @@ public class CMCAuth implements IAuthManager, IExtendedPluginInfo, String uid = "defUser"; if (checkSignerInfo) { IAuthToken agentToken = verifySignerInfo(authToken, cmcFullReq); + if (agentToken == null) { + CMS.debug("CMCAuth: authenticate() agentToken null"); + throw new EBaseException("CMCAuth: agent verifySignerInfo failure"); + } userid = agentToken.getInString("userid"); uid = agentToken.getInString("cn"); } else { @@ -481,7 +489,7 @@ public class CMCAuth implements IAuthManager, IExtendedPluginInfo, TaggedRequest.Type type = taggedRequest.getType(); if (type.equals(TaggedRequest.PKCS10)) { - CMS.debug("CMCAuth: in PKCS10"); + CMS.debug("CMCAuth: type is PKCS10"); TaggedCertificationRequest tcr = taggedRequest.getTcr(); int p10Id = tcr.getBodyPartID().intValue(); @@ -496,9 +504,31 @@ public class CMCAuth implements IAuthManager, IExtendedPluginInfo, new ByteArrayOutputStream(); p10.encode(ostream); + boolean sigver = true; + boolean tokenSwitched = false; + CryptoManager cm = null; + CryptoToken signToken = null; + CryptoToken savedToken = null; + sigver = CMS.getConfigStore().getBoolean("ca.requestVerify.enabled", true); try { + cm = CryptoManager.getInstance(); + if (sigver == true) { + String tokenName = + CMS.getConfigStore().getString("ca.requestVerify.token", "internal"); + savedToken = cm.getThreadToken(); + if (tokenName.equals("internal")) { + signToken = cm.getInternalCryptoToken(); + } else { + signToken = cm.getTokenByName(tokenName); + } + if (!savedToken.getName().equals(signToken.getName())) { + cm.setThreadToken(signToken); + tokenSwitched = true; + } + } + PKCS10 pkcs10 = - new PKCS10(ostream.toByteArray()); + new PKCS10(ostream.toByteArray(), sigver); // xxx do we need to do anything else? X509CertInfo certInfo = @@ -544,10 +574,14 @@ public class CMCAuth implements IAuthManager, IExtendedPluginInfo, e.printStackTrace(); throw new EBaseException(e.toString()); - } + } finally { + if ((sigver == true) && (tokenSwitched == true)){ + cm.setThreadToken(savedToken); + } + } } else if (type.equals(TaggedRequest.CRMF)) { - CMS.debug("CMCAuth: in CRMF"); + CMS.debug("CMCAuth: type is CRMF"); try { CertReqMsg crm = taggedRequest.getCrm(); @@ -859,8 +893,26 @@ public class CMCAuth implements IAuthManager, IExtendedPluginInfo, CMS.debug("CMCAuth: verifying signature"); si.verify(digest, id); } else { + CMS.debug("CMCAuth: found signing cert... verifying"); PublicKey signKey = cert.getPublicKey(); - PK11PubKey pubK = PK11PubKey.fromSPKI(((X509Key) signKey).getKey()); + PrivateKey.Type keyType = null; + String alg = signKey.getAlgorithm(); + + PK11PubKey pubK = null; + if (alg.equals("RSA")) { + CMS.debug("CMCAuth: signing key alg=RSA"); + keyType = PrivateKey.RSA; + pubK = PK11PubKey.fromRaw(keyType, ((X509Key) signKey).getKey()); + } else if (alg.equals("EC")) { + CMS.debug("CMCAuth: signing key alg=EC"); + keyType = PrivateKey.EC; + byte publicKeyData[] = ((X509Key) signKey).getEncoded(); + pubK = (PK11PubKey) PK11ECPublicKey.fromSPKI(/*keyType,*/ publicKeyData); + } else if (alg.equals("DSA")) { + CMS.debug("CMCAuth: signing key alg=DSA"); + keyType = PrivateKey.DSA; + pubK = PK11PubKey.fromSPKI(/*keyType,*/ ((X509Key) signKey).getKey()); + } CMS.debug("CMCAuth: verifying signature with public key"); si.verify(digest, id, pubK); @@ -905,6 +957,7 @@ public class CMCAuth implements IAuthManager, IExtendedPluginInfo, } catch (IOException e) { CMS.debug("CMCAuth: " + e.toString()); } catch (Exception e) { + CMS.debug("CMCAuth: " + e.toString()); throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL")); } return null; diff --git a/base/common/src/com/netscape/cms/profile/common/EnrollProfile.java b/base/common/src/com/netscape/cms/profile/common/EnrollProfile.java index 6fbdddb69..5b3457961 100644 --- a/base/common/src/com/netscape/cms/profile/common/EnrollProfile.java +++ b/base/common/src/com/netscape/cms/profile/common/EnrollProfile.java @@ -661,23 +661,57 @@ public abstract class EnrollProfile extends BasicProfile IRequest req) throws EProfileException { TaggedRequest.Type type = tagreq.getType(); + if (type == null) { + CMS.debug("EnrollProfile: fillTaggedRequest: 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"); + boolean sigver = true; + boolean tokenSwitched = false; + CryptoManager cm = null; + CryptoToken signToken = null; + CryptoToken savedToken = null; try { + sigver = CMS.getConfigStore().getBoolean("ca.requestVerify.enabled", true); + cm = CryptoManager.getInstance(); + if (sigver == true) { + String tokenName = + CMS.getConfigStore().getString("ca.requestVerify.token", "internal"); + savedToken = cm.getThreadToken(); + if (tokenName.equals("internal")) { + signToken = cm.getInternalCryptoToken(); + } else { + signToken = cm.getTokenByName(tokenName); + } + if (!savedToken.getName().equals(signToken.getName())) { + cm.setThreadToken(signToken); + tokenSwitched = true; + } + } + TaggedCertificationRequest tcr = tagreq.getTcr(); CertificationRequest p10 = tcr.getCertificationRequest(); ByteArrayOutputStream ostream = new ByteArrayOutputStream(); p10.encode(ostream); - PKCS10 pkcs10 = new PKCS10(ostream.toByteArray()); + PKCS10 pkcs10 = new PKCS10(ostream.toByteArray(), sigver); req.setExtData("bodyPartId", tcr.getBodyPartID()); fillPKCS10(locale, pkcs10, info, req); } catch (Exception e) { CMS.debug("EnrollProfile: fillTaggedRequest " + e.toString()); + } finally { + if ((sigver == true) && (tokenSwitched == true)){ + cm.setThreadToken(savedToken); + } } } else if (type.equals(TaggedRequest.CRMF)) { + CMS.debug("EnrollProfile: fillTaggedRequest: TaggedRequest type == crmf"); CertReqMsg crm = tagreq.getCrm(); SessionContext context = SessionContext.getContext(); Integer nums = (Integer) (context.get("numOfControls")); @@ -699,6 +733,7 @@ public abstract class EnrollProfile extends BasicProfile fillCertReqMsg(locale, crm, info, req); } else { + CMS.debug("EnrollProfile: fillTaggedRequest: unsupported type (not CRMF or PKCS10)"); throw new EProfileException( CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST")); } diff --git a/base/common/src/com/netscape/cms/profile/input/CMCCertReqInput.java b/base/common/src/com/netscape/cms/profile/input/CMCCertReqInput.java index 8ce1be3ee..a62d6e9f7 100644 --- a/base/common/src/com/netscape/cms/profile/input/CMCCertReqInput.java +++ b/base/common/src/com/netscape/cms/profile/input/CMCCertReqInput.java @@ -97,6 +97,7 @@ public class CMCCertReqInput extends EnrollInput implements IProfileInput { TaggedRequest msgs[] = mEnrollProfile.parseCMC(getLocale(request), cert_request); if (msgs == null) { + CMS.debug("CMCCertReqInput: populate - parseCMC returns null TaggedRequest msgs"); return; } // This profile only handle the first request in CRMF diff --git a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java index 159759517..c2382d671 100644 --- a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java +++ b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java @@ -52,6 +52,7 @@ import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.SET; import org.mozilla.jss.asn1.UTF8String; import org.mozilla.jss.crypto.CryptoToken; +import org.mozilla.jss.crypto.CryptoStore; import org.mozilla.jss.crypto.DigestAlgorithm; import org.mozilla.jss.crypto.ObjectNotFoundException; import org.mozilla.jss.crypto.SignatureAlgorithm; @@ -95,6 +96,7 @@ public class CMCRequest { public static final String PR_REQUEST_CMC = "CMC"; public static final String PR_REQUEST_CRMF = "CRMF"; + public static final String PR_INTERNAL_TOKEN_NAME = "internal"; public static final int ARGC = 1; public static final String HEADER = "-----BEGIN NEW CERTIFICATE REQUEST-----"; @@ -104,20 +106,20 @@ public class CMCRequest { } - public static X509Certificate getCertificate(String tokenname, + public static X509Certificate getCertificate(String tokenName, String nickname) throws Exception { CryptoManager manager = CryptoManager.getInstance(); CryptoToken token = null; - if (tokenname.equals("internal")) { + if (tokenName.equals(PR_INTERNAL_TOKEN_NAME)) { token = manager.getInternalKeyStorageToken(); } else { - token = manager.getTokenByName(tokenname); + token = manager.getTokenByName(tokenName); } StringBuffer certname = new StringBuffer(); if (!token.equals(manager.getInternalKeyStorageToken())) { - certname.append(tokenname); + certname.append(tokenName); certname.append(":"); } certname.append(nickname); @@ -128,16 +130,18 @@ public class CMCRequest { } } - public static java.security.PrivateKey getPrivateKey(String tokenname, String nickname) + public static java.security.PrivateKey getPrivateKey(String tokenName, String nickname) throws Exception { - X509Certificate cert = getCertificate(tokenname, nickname); + X509Certificate cert = getCertificate(tokenName, nickname); + if (cert != null) + System.out.println("got signing cert"); return CryptoManager.getInstance().findPrivKeyByCert(cert); } /** - * getCMCBlob create and return the enrollent request. + * getCMCBlob create and return the enrollment request. *

* * @param signerCert the certificate of the authorized signer of the CMC revocation request. @@ -146,12 +150,12 @@ public class CMCRequest { * @param format either crmf or pkcs10 * @return the CMC enrollment request encoded in base64 */ - static ContentInfo getCMCBlob(X509Certificate signerCert, String nickname, + static ContentInfo getCMCBlob(X509Certificate signerCert, String tokenName, 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"; + System.out.println("in getCMCBlob"); ContentInfo fullEnrollmentReq = null; try { @@ -171,7 +175,9 @@ public class CMCRequest { si = new SignerIdentifier( SignerIdentifier.ISSUER_AND_SERIALNUMBER, ias, null); - privKey = getPrivateKey(tokenname, nickname); + privKey = getPrivateKey(tokenName, nickname); + if (privKey != null) + System.out.println("getCMCBlob: got privKey"); TaggedRequest trq = null; PKCS10 pkcs = null; @@ -181,10 +187,12 @@ public class CMCRequest { SEQUENCE reqSequence = new SEQUENCE(); try { for (int k = 0; k < rValue.length; 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); SEQUENCE crmfMsgs = null; @@ -192,7 +200,7 @@ public class CMCRequest { 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.out.println("getCMCBlob: This is not a crmf request. Or this request has an error."); System.exit(1); } certReqMsg = (CertReqMsg) crmfMsgs.elementAt(0); @@ -200,9 +208,9 @@ public class CMCRequest { certReqMsg); } else if (format.equals("pkcs10")) { try { - pkcs = new PKCS10(decodedBytes); - } catch (IllegalArgumentException e) { - System.out.println("This is not a PKCS10 request."); + pkcs = new PKCS10(decodedBytes, true); + } catch (Exception e2) { + System.out.println("getCMCBlob: Excception:"+e2.toString()); System.exit(1); } ByteArrayInputStream crInputStream = new ByteArrayInputStream( @@ -214,17 +222,14 @@ public class CMCRequest { trq = new TaggedRequest(TaggedRequest.PKCS10, tcr, null); } else { - System.out.println("Unrecognized request format: " + format); + System.out.println("getCMCBlob: 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()); + } catch (Exception e) { + System.out.println("getCMCBlob: Exception:"+ e.toString()); + System.exit(1); } if (transactionMgtEnable.equals("true")) @@ -241,12 +246,16 @@ public class CMCRequest { 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)) + 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; @@ -322,6 +331,9 @@ public class CMCRequest { 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("#tokenname: name of token where agent signing cert can be found (default is internal)"); + System.out.println("tokenname=internal"); + 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"); @@ -539,7 +551,7 @@ public class CMCRequest { return bpid; } - private static int addRevRequestAttr(int bpid, SEQUENCE seq, SEQUENCE otherMsgSeq, String nickname, + private static int addRevRequestAttr(int bpid, SEQUENCE seq, SEQUENCE otherMsgSeq, CryptoToken token, String tokenName, String nickname, String revRequestIssuer, String revRequestSerial, String revRequestReason, String revRequestSharedSecret, String revRequestComment, String invalidityDatePresent, CryptoManager manager) { @@ -578,24 +590,42 @@ public class CMCRequest { EncapsulatedContentInfo revokeContent = new EncapsulatedContentInfo( OBJECT_IDENTIFIER.id_cct_PKIData, revRequestControl); - DigestAlgorithm digestAlg1 = null; - SignatureAlgorithm signAlg1 = SignatureAlgorithm.RSASignatureWithSHA1Digest; + + StringBuffer certname = new StringBuffer(); + + if (!token.equals(manager.getInternalKeyStorageToken())) { + certname.append(tokenName); + certname.append(":"); + } + certname.append(nickname); java.security.PrivateKey revokePrivKey = null; X509Certificate revokeCert = null; + System.out.println("finding cert:"+certname.toString()); try { - revokeCert = manager.findCertByNickname(nickname1); + revokeCert = manager.findCertByNickname(certname.toString()); } catch (ObjectNotFoundException e) { - System.out.println("Certificate not found: " + nickname1); + System.out.println("Certificate not found: "+nickname1); + System.exit(1); + } catch (Exception e2) { + System.out.println("Certificate not found: "+e2.toString()); System.exit(1); } + System.out.println("finding private key for cert:"+certname.toString()); 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)) + ((org.mozilla.jss.crypto.PrivateKey) revokePrivKey).getType(); + SignatureAlgorithm signAlg1 = null; + if (signingKeyType1.equals(org.mozilla.jss.crypto.PrivateKey.Type.RSA)) { + signAlg1 = SignatureAlgorithm.RSASignatureWithSHA1Digest; + } else if (signingKeyType1.equals(org.mozilla.jss.crypto.PrivateKey.Type.EC)) { + signAlg1 = SignatureAlgorithm.ECSignatureWithSHA1Digest; + } else if (signingKeyType1.equals(org.mozilla.jss.crypto.PrivateKey.Type.DSA)) { signAlg1 = SignatureAlgorithm.DSASignatureWithSHA1Digest; + } MessageDigest rSHADigest = null; byte[] rdigest = null; + DigestAlgorithm digestAlg1 = null; try { rSHADigest = MessageDigest.getInstance("SHA1"); digestAlg1 = DigestAlgorithm.SHA1; @@ -644,7 +674,7 @@ public class CMCRequest { 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.out.println("Error in creating revRequest control. Check the parameters. Exception="+ e.toString()); System.exit(1); } @@ -798,6 +828,7 @@ public class CMCRequest { public static void main(String[] s) { String numRequests = null; String dbdir = null, nickname = null; + String tokenName = PR_INTERNAL_TOKEN_NAME; String ifilename = null, ofilename = null, password = null, format = null; String confirmCertEnable = "false", confirmCertIssuer = null, confirmCertSerial = null; String getCertEnable = "false", getCertIssuer = null, getCertSerial = null; @@ -855,6 +886,8 @@ public class CMCRequest { format = val; } else if (name.equals("dbdir")) { dbdir = val; + } else if (name.equals("tokenname")) { + tokenName = val; } else if (name.equals("nickname")) { nickname = val; } else if (name.equals("password")) { @@ -979,19 +1012,48 @@ public class CMCRequest { 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.initialize(dbdir); + CryptoToken token = null; CryptoManager cm = CryptoManager.getInstance(); - CryptoToken token = cm.getInternalKeyStorageToken(); + System.out.println("CryptoManger initialized"); + + if ((tokenName == null) || (tokenName.equals(""))) { + token = cm.getInternalKeyStorageToken(); + tokenName = PR_INTERNAL_TOKEN_NAME; + } else { + token = cm.getTokenByName(tokenName); + } + cm.setThreadToken(token); + Password pass = new Password(password.toCharArray()); - token.login(pass); + try { + token.login(pass); + System.out.println("token "+ tokenName + " logged in..."); + } catch (Exception e) { + System.out.println("login Exception: " + e.toString()); + System.exit(1); + } + + CryptoStore store = token.getCryptoStore(); + X509Certificate[] list = store.getCertificates(); X509Certificate signerCert = null; - signerCert = cm.findCertByNickname(nickname); + StringBuffer certname = new StringBuffer(); + if (!token.equals(cm.getInternalKeyStorageToken())) { + certname.append(tokenName); + certname.append(":"); + } + certname.append(nickname); + signerCert = cm.findCertByNickname(certname.toString()); + if (signerCert != null) { + System.out.println("got signerCert: "+ certname.toString()); + } String[] requests = new String[num]; for (int i = 0; i < num; i++) { @@ -1091,12 +1153,12 @@ public class CMCRequest { System.exit(1); } - bpid = addRevRequestAttr(bpid, controlSeq, otherMsgSeq, revCertNickname, + bpid = addRevRequestAttr(bpid, controlSeq, otherMsgSeq, token, tokenName, revCertNickname, revRequestIssuer, revRequestSerial, revRequestReason, revRequestSharedSecret, revRequestComment, revRequestInvalidityDatePresent, cm); } - ContentInfo cmcblob = getCMCBlob(signerCert, nickname, requests, format, + ContentInfo cmcblob = getCMCBlob(signerCert, tokenName, nickname, requests, format, cm, transactionMgtEnable, transactionMgtId, identityProofEnable, identityProofSharedSecret, controlSeq, otherMsgSeq, bpid); diff --git a/base/java-tools/src/com/netscape/cmstools/CMCRevoke.java b/base/java-tools/src/com/netscape/cmstools/CMCRevoke.java index aaf9fbb17..3f9d81113 100644 --- a/base/java-tools/src/com/netscape/cmstools/CMCRevoke.java +++ b/base/java-tools/src/com/netscape/cmstools/CMCRevoke.java @@ -68,11 +68,11 @@ import com.netscape.cmsutil.util.Utils; * @version $Revision$, $Date$ */ public class CMCRevoke { - public static final int ARGC = 7; + public static final int ARGC = 8; public static final String HEADER = "-----BEGIN NEW CERTIFICATE REQUEST-----"; public static final String TRAILER = "-----END NEW CERTIFICATE REQUEST-----"; static String dValue = null, nValue = null, iValue = null, sValue = null, mValue = null, hValue = null, - cValue = null; + pValue = null, cValue = null; public static final String CMS_BASE_CA_SIGNINGCERT_NOT_FOUND = "CA signing certificate not found"; public static final String PR_INTERNAL_TOKEN_NAME = "internal"; @@ -110,7 +110,8 @@ public class CMCRevoke { "-i " + "-s " + "-m " + - "-h " + + "-p " + + "-h " + "-c "); for (int i = 0; i < s.length; i++) { System.out.println(i + ":" + s[i]); @@ -131,6 +132,8 @@ public class CMCRevoke { sValue = cleanArgs(s[i].substring(2)); } else if (s[i].startsWith("-m")) { mValue = cleanArgs(s[i].substring(2)); + } else if (s[i].startsWith("-p")) { + pValue = cleanArgs(s[i].substring(2)); } else if (s[i].startsWith("-h")) { hValue = cleanArgs(s[i].substring(2)); } else if (s[i].startsWith("-c")) { @@ -138,14 +141,17 @@ public class CMCRevoke { } } - // optional parameter + // optional parameters if (cValue == null) cValue = ""; + if (hValue == null) + hValue = ""; + if (dValue == null - || nValue == null || iValue == null || sValue == null || mValue == null || hValue == null) + || nValue == null || iValue == null || sValue == null || mValue == null || pValue == null) bWrongParam = true; else if (dValue.length() == 0 || nValue.length() == 0 || iValue.length() == 0 || - sValue.length() == 0 || mValue.length() == 0 || hValue.length() == 0) + sValue.length() == 0 || mValue.length() == 0 || pValue.length() == 0) bWrongParam = true; if (bWrongParam == true) { @@ -155,7 +161,8 @@ public class CMCRevoke { "-i " + "-s " + "-m " + - "-h " + + "-p " + + "-h " + "-c "); for (i = 0; i < s.length; i++) { System.out.println(i + ":" + s[i]); @@ -167,21 +174,26 @@ public class CMCRevoke { // initialize CryptoManager mPath = dValue; System.out.println("cert/key prefix = " + mPrefix); - System.out.println("path = " + mPath); + System.out.println("path = " + mPath); CryptoManager.InitializationValues vals = - new CryptoManager.InitializationValues(mPath, mPrefix, mPrefix, "secmod.db"); + new CryptoManager.InitializationValues(mPath, mPrefix, mPrefix, "secmod.db"); CryptoManager.initialize(vals); - + CryptoManager cm = CryptoManager.getInstance(); - CryptoToken token = cm.getInternalKeyStorageToken(); - Password pass = new Password(hValue.toCharArray()); + CryptoToken token = null; + if ((hValue == null) || (hValue.equals(""))) { + token = cm.getInternalKeyStorageToken(); + hValue = PR_INTERNAL_TOKEN_NAME; + } else { + token = cm.getTokenByName(hValue); + } + + Password pass = new Password(pValue.toCharArray()); token.login(pass); - X509Certificate signerCert = null; - - signerCert = cm.findCertByNickname(nValue); - String outBlob = createRevokeReq(signerCert, cm, nValue); + X509Certificate signerCert = getCertificate(cm, hValue, nValue); + String outBlob = createRevokeReq(hValue, signerCert, cm); printCMCRevokeRequest(outBlob); } catch (Exception e) { @@ -258,28 +270,28 @@ public class CMCRevoke { certname.append(":"); } certname.append(nickname); + System.out.println("CMCRevoke: searching for certificate nickname:"+ + certname.toString()); try { return manager.findCertByNickname(certname.toString()); } catch (ObjectNotFoundException e) { - throw new Exception(CMS_BASE_CA_SIGNINGCERT_NOT_FOUND); + throw new Exception("Signing Certificate not found"); } } /** * createRevokeReq create and return the revocation request. *

- * + * @tokenname name of the token * @param signerCert the certificate of the authorized signer of the CMC revocation request. * @param manager the crypto manger. - * @param nValue the nickname of the certificate inside the token. * @return the CMC revocation request encoded in base64 */ - static String createRevokeReq(X509Certificate signerCert, CryptoManager manager, String nValue) { + static String createRevokeReq(String tokenname, X509Certificate signerCert, CryptoManager manager) { java.security.PrivateKey privKey = null; SignerIdentifier si = null; ContentInfo fullEnrollmentReq = null; - String tokenname = "internal"; String asciiBASE64Blob = null; try { @@ -295,9 +307,8 @@ public class CMCRevoke { IssuerAndSerialNumber ias = new IssuerAndSerialNumber(issuer, new INTEGER(serialno.toString())); si = new SignerIdentifier(SignerIdentifier.ISSUER_AND_SERIALNUMBER, ias, null); - X509Certificate cert = getCertificate(manager, tokenname, nValue); - privKey = manager.findPrivKeyByCert(cert); + privKey = manager.findPrivKeyByCert(signerCert); if (privKey == null) { System.out.println("CMCRevoke::createRevokeReq() - " + @@ -338,7 +349,7 @@ public class CMCRevoke { //org.mozilla.jss.pkix.cmmf.RevRequest.unspecified, new ENUMERATED((new Integer(mValue)).longValue()), null, - new OCTET_STRING(hValue.getBytes()), + new OCTET_STRING(pValue.getBytes()), new UTF8String(cValue.toCharArray())); //byte[] encoded = ASN1Util.encode(lRevokeRequest); //org.mozilla.jss.asn1.ASN1Template template = new org.mozilla.jss.pkix.cmmf.RevRequest.Template(); @@ -358,12 +369,16 @@ public class CMCRevoke { 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)) + 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; diff --git a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java index 5c4110b1d..204d234c0 100644 --- a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java +++ b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java @@ -20,15 +20,18 @@ package com.netscape.cmstools; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.FileReader; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.PrintStream; import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder; import java.security.KeyPair; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.Date; import netscape.security.x509.X500Name; @@ -40,12 +43,14 @@ import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.PrintableString; import org.mozilla.jss.asn1.SEQUENCE; +import org.mozilla.jss.crypto.AlreadyInitializedException; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.IVParameterSpec; import org.mozilla.jss.crypto.KeyGenAlgorithm; import org.mozilla.jss.crypto.KeyGenerator; import org.mozilla.jss.crypto.KeyPairAlgorithm; import org.mozilla.jss.crypto.KeyPairGenerator; +import org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.*; import org.mozilla.jss.crypto.KeyWrapAlgorithm; import org.mozilla.jss.crypto.KeyWrapper; import org.mozilla.jss.crypto.Signature; @@ -68,52 +73,13 @@ import org.mozilla.jss.util.Password; import com.netscape.cmsutil.util.HMACDigest; import com.netscape.cmsutil.util.Utils; +import com.netscape.cmsutil.crypto.CryptoUtil; +import com.netscape.certsrv.apps.CMS; /** * A command-line utility used to generate a Certificate Request Message * Format (CRMF) request with proof of possesion (POP). * - * Usage: - * - *

- *     CRMFPopClient  TOKEN_PWD
- *                    PROFILE_NAME HOST PORT USER_NAME REQUESTOR_NAME
- *                    POP_OPTION
- *                    SUBJECT_DN [OUTPUT_CERT_REQ]
- *
- *                    ---  or  ---
- *
- *     CRMFPopClient  TOKEN_PWD
- *                    POP_OPTION
- *                    OUTPUT_CERT_REQ SUBJECT_DN
- *
- *
- *     where POP_OPTION can be [POP_SUCCESS or POP_FAIL or POP_NONE]
- * 
- *

- * Examples: - * - *

- *     CRMFPopClient  password123
- *                    caEncUserCert host.example.com 1026 MyUid MyUid
- *                    [POP_SUCCESS or POP_FAIL or POP_NONE]
- *                    CN=MyTest,C=US,UID=MyUid
- *
- *                    ---  or  ---
- *
- *     CRMFPopClient  password123
- *                    caEncUserCert host.example.com 1026 joe joe
- *                    [POP_SUCCESS or POP_FAIL or POP_NONE]
- *                    CN=MyTest,C=US,UID=MyUid OUTPUT_CERT_REQ
- *
- *                    ---  or  ---
- *
- *     CRMFPopClient  password123
- *                    [POP_SUCCESS or POP_FAIL or POP_NONE]
- *                    OUTPUT_CERT_REQ CN=MyTest,C=US,UID=MyUid
- * 
- *

- * *

  * IMPORTANT:  The file "transport.txt" needs to be created to contain the
  *             transport certificate in its base64 encoded format.  This
@@ -127,36 +93,17 @@ import com.netscape.cmsutil.util.Utils;
 public class CRMFPopClient {
 
     private static void usage() {
-        System.out.println("");
-        System.out.println("Description:  A command-line utility used to generate a");
-        System.out.println("              Certificate Request Message Format (CRMF)");
-        System.out.println("              request with proof of possesion (POP).\n\n");
-        System.out.println("Usage:");
-        System.out.println("");
-        System.out.println("    CRMFPopClient TOKEN_PWD");
-        System.out.println("                  PROFILE_NAME HOST PORT USER_NAME REQUESTOR_NAME");
-        System.out.println("                  POP_OPTION");
-        System.out.println("                  SUBJECT_DN  [OUTPUT_CERT_REQ]   \n");
-        System.out.println("                  ---  or  ---\n");
-        System.out.println("    CRMFPopClient TOKEN_PWD");
-        System.out.println("                  POP_OPTION");
-        System.out.println("                  OUTPUT_CERT_REQ SUBJECT_DN\n\n");
-        System.out.println("    where POP_OPTION can be [POP_SUCCESS or POP_FAIL or POP_NONE]\n\n");
-        System.out.println("Examples:");
-        System.out.println("");
-        System.out.println("    CRMFPopClient password123");
-        System.out.println("                  caEncUserCert host.example.com 1026 MyUid MyUid");
-        System.out.println("                  [POP_SUCCESS or POP_FAIL or POP_NONE]");
-        System.out.println("                  CN=MyTest,C=US,UID=MyUid\n");
-        System.out.println("                  ---  or  ---\n");
-        System.out.println("    CRMFPopClient password123");
-        System.out.println("                  caEncUserCert host.example.com 1026 MyUid myUid");
-        System.out.println("                  [POP_SUCCESS or POP_FAIL or POP_NONE]");
-        System.out.println("                  CN=MyTest,C=US,UID=MyUid OUTPUT_CERT_REQ\n");
-        System.out.println("                  ---  or  ---\n");
-        System.out.println("    CRMFPopClient password123");
-        System.out.println("                  [POP_SUCCESS or POP_FAIL or POP_NONE]");
-        System.out.println("                  OUTPUT_CERT_REQ CN=MyTest,C=US,UID=MyUid");
+
+        System.out.println("Usage: CRMFPopClient -d  -p  -h  -o  -n  -a  -l  -c  -m  -f  -u  -r  -q  \n");
+        System.out.println("    Optionally, for ECC key generation per definition in JSS pkcs11.PK11KeyPairGenerator:\n");
+        System.out.println("    -t \n");
+        System.out.println("    -s <1 for sensitive; 0 for non-sensitive; -1 temporaryPairMode dependent; default is -1>\n");
+        System.out.println("    -e <1 for extractable; 0 for non-extractable; -1 token dependent; default is -1>\n");
+        System.out.println("    Also optional for ECC key generation:\n");
+        System.out.println("    -x \n");
+        System.out.println(" note: '-x true' can only be used with POP_NONE");
+        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("\n");
         System.out.println("IMPORTANT:  The file \"transport.txt\" needs to be created to contain the");
         System.out.println("            transport certificate in its base64 encoded format.  This");
@@ -193,73 +140,138 @@ public class CRMFPopClient {
 
     public static void main(String args[]) {
 
-        int argsLen = getRealArgsLength(args);
-
-        // System.out.println("args length " + argsLen);
+//        int argsLen =  getRealArgsLength(args);
 
-        System.out.println("\n\nProof Of Possession Utility....");
+        System.out.println("\n\nCRMF Proof Of Possession Utility....");
         System.out.println("");
 
-        if (argsLen == 0 || (argsLen != 8 && argsLen != 9 && argsLen != 10 && argsLen != 4)) {
-            usage();
-            return;
+        if (args.length < 4)
+        {
+             usage();
+             System.exit(1);
         }
 
         String DB_DIR = "./";
-        String TOKEN_PWD = args[0];
-        int KEY_LEN = 1024;
+        String TOKEN_PWD = null;
+        String TOKEN_NAME = null;
+
+        // "rsa" or "ec"
+        String alg = "rsa";
+
+        /* default RSA key size */
+        int RSA_keylen = 2048;
+        /* default ECC key curve name */
+        String ECC_curve = "nistp256";
+        boolean ec_temporary = true; /* session if true; token if false */
+        int ec_sensitive = -1; /* -1, 0, or 1 */
+        int ec_extractable = -1; /* -1, 0, or 1 */
+        boolean ec_ssl_ecdh = false;
 
         int PORT = 0;
         String USER_NAME = null;
         String REQUESTOR_NAME = null;
         String PROFILE_NAME = null;
-
-        String HOST = null;
+ 
+        // format: "host:port"
+        String HOST_PORT = null; 
         String SUBJ_DN = null;
+        int doServerHit = 0;
 
-        if (argsLen >= 8) {
-            PROFILE_NAME = args[1];
-            HOST = args[2];
-
-            PORT = Integer.parseInt(args[3]);
-
-            USER_NAME = args[4];
-            REQUESTOR_NAME = args[5];
-
-            SUBJ_DN = args[7];
-
-        }
-
-        String POP_OPTION = null;
-        String OUTPUT_CERT_REQ = null;
-
-        if (argsLen == 4)
-            POP_OPTION = args[1];
-        else
-            POP_OPTION = args[6];
-
-        int doServerHit = 1;
-
-        if (argsLen >= 9) {
-            OUTPUT_CERT_REQ = args[8];
-        }
-
-        if (argsLen == 4) {
-            doServerHit = 0;
-            OUTPUT_CERT_REQ = args[2];
-            SUBJ_DN = args[3];
-        }
-
+        // POP_NONE, POP_SUCCESS, or POP_FAIL
+        String POP_OPTION = "POP_SUCCESS";
         int dont_do_pop = 0;
 
-        if (POP_OPTION.equals("POP_NONE")) {
-            dont_do_pop = 1;
-        }
+        String REQ_OUT_FILE = null;
+
+        for (int i=0; i
@@ -66,32 +74,104 @@ public class PKCS10Client {
 
     private static void printUsage() {
         System.out.println(
-                "Usage: PKCS10Client -p  -d  -o  -s \n");
+                "Usage: PKCS10Client -d  -h  -p  -a  -l  -c  -o  -n \n");
+        System.out.println(
+                "    Optionally, for ECC key generation per definition in JSS pkcs11.PK11KeyPairGenerator:\n");
+        System.out.println(
+                "    -t \n");
+        System.out.println(
+                "    -s <1 for sensitive; 0 for non-sensitive; -1 temporaryPairMode dependent; default is -1>\n");
+        System.out.println(
+                "    -e <1 for extractable; 0 for non-extractable; -1 token dependent; default is -1>\n");
+        System.out.println(
+                "    Also optional for ECC key generation:\n");
+        System.out.println(
+                "    -x \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");
     }
 
     public static void main(String args[]) throws Exception {
-        String dbdir = null, ofilename = null, password = null, subjectName = null;
+        String dbdir = null, ofilename = null, password = null, subjectName = null, type = null, tokenName = null;
+
+        String alg = "rsa";
+        String ecc_curve = "nistp256";
+        boolean ec_temporary = false; /* session if true; token if false */
+        int ec_sensitive = -1; /* -1, 0, or 1 */
+        int ec_extractable = -1; /* -1, 0, or 1 */
+        boolean ec_ssl_ecdh = false;
+        int rsa_keylen = 2048;
 
-        if (args.length != 8) {
+        if (args.length < 4) {
             printUsage();
             System.exit(1);
         }
 
-        for (int i = 0; i < args.length; i++) {
+        for (int i = 0; i < args.length; i+=2) {
             String name = args[i];
+
             if (name.equals("-p")) {
-                password = args[i + 1];
+                password = args[i+1];
             } else if (name.equals("-d")) {
-                dbdir = args[i + 1];
-            } else if (name.equals("-o")) {
-                ofilename = args[i + 1];
+                dbdir = args[i+1];
+            } else if (name.equals("-a")) {
+                alg = args[i+1];
+                if (!alg.equals("rsa") && !alg.equals("ec")) {
+                    System.out.println("PKCS10Client: ERROR: invalid algorithm: " + alg);
+                    System.exit(1);
+                }
+            } else if (name.equals("-x")) {
+                String temp = args[i+1];
+                if (temp.equals("true"))
+                    ec_ssl_ecdh = true;
+                else
+                    ec_ssl_ecdh = false;
+            } else if (name.equals("-t")) {
+                String temp = args[i+1];
+                if (temp.equals("true"))
+                    ec_temporary = true;
+                else
+                    ec_temporary = false;
             } else if (name.equals("-s")) {
-                subjectName = args[i + 1];
+                String ec_sensitive_s = args[i+1];
+                ec_sensitive = Integer.parseInt(ec_sensitive_s);
+                if ((ec_sensitive != 0) && 
+                    (ec_sensitive != 1) &&
+                    (ec_sensitive != -1)) {
+                      System.out.println("PKCS10Client: Illegal input parameters for -s.");
+                      printUsage();
+                      System.exit(1);
+                    }
+            } else if (name.equals("-e")) {
+                String ec_extractable_s = args[i+1];
+                ec_extractable = Integer.parseInt(ec_extractable_s);
+                if ((ec_extractable != 0) && 
+                    (ec_extractable != 1) &&
+                    (ec_extractable != -1)) {
+                      System.out.println("PKCS10Client: Illegal input parameters for -e.");
+                      printUsage();
+                      System.exit(1);
+                    }
+            } else if (name.equals("-c")) {
+                ecc_curve = args[i+1];
+            } else if (name.equals("-l")) {
+                rsa_keylen = Integer.parseInt(args[i+1]);
+            } else if (name.equals("-o")) {
+                ofilename = args[i+1];
+            } else if (name.equals("-n")) {
+                subjectName = args[i+1];
+            } else if (name.equals("-h")) {
+                tokenName = args[i+1];
+            } else {
+                System.out.println("Unrecognized argument(" + i + "): "
+                    + name);
+                printUsage();
+                System.exit(1);
             }
         }
 
         if (password == null || ofilename == null || subjectName == null) {
-            System.out.println("Illegal input parameters.");
+            System.out.println("PKCS10Client: Illegal input parameters.");
             printUsage();
             System.exit(1);
         }
@@ -99,31 +179,74 @@ public class PKCS10Client {
         if (dbdir == null)
             dbdir = ".";
 
-        String mPrefix = "";
-        CryptoManager.InitializationValues vals =
+        try { 
+            // initialize CryptoManager
+            String mPrefix = "";
+            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);
-        KeyPairGenerator kg = token.getKeyPairGenerator(KeyPairAlgorithm.RSA);
-        kg.initialize(1024);
-        KeyPair pair = kg.genKeyPair();
-
-        // Add idPOPLinkWitness control
-        String secretValue = "testing";
-        byte[] key1 = null;
-        byte[] finalDigest = null;
-        MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1");
-        key1 = SHA1Digest.digest(secretValue.getBytes());
-
-        /* seed */
-        byte[] b =
-        { 0x10, 0x53, 0x42, 0x24, 0x1a, 0x2a, 0x35, 0x3c,
+            CryptoManager.initialize(vals);
+            CryptoToken token = null;
+            CryptoManager cm = CryptoManager.getInstance();
+            if ((tokenName == null) || (tokenName.equals(""))) {
+                token = cm.getInternalKeyStorageToken();
+                tokenName = "NSS Certificate DB";
+            } else {
+                token = cm.getTokenByName(tokenName);
+            }
+            cm.setThreadToken(token);
+
+            Password pass = new Password(password.toCharArray());
+
+            try {
+                token.login(pass);
+                System.out.println("PKCS10Client: token "+ tokenName + " logged in...");
+            } catch (Exception e) {
+                System.out.println("PKCS10Client: login Exception: " + e.toString());
+                System.exit(1);
+            }
+
+            KeyPair pair = null;
+
+            if (alg.equals("rsa")) {
+                KeyPairGenerator kg = token.getKeyPairGenerator(KeyPairAlgorithm.RSA); 
+                kg.initialize(rsa_keylen);
+                pair = kg.genKeyPair(); 
+            }  else if (alg.equals("ec")) {
+                // used with SSL server cert that does ECDH ECDSA
+                org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage usages_mask_ECDH[] = {
+                    org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN,
+                    org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN_RECOVER
+                };
+
+                // used for other certs including SSL server cert that does ECDHE ECDSA
+                org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage usages_mask[] = {
+                  org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.DERIVE
+                };
+
+                pair = CryptoUtil.generateECCKeyPair(tokenName,  ecc_curve ,
+                       null,
+                       usages_mask, ec_temporary /*temporary*/,
+                       ec_sensitive /*sensitive*/, ec_extractable /*extractable*/);
+                if (pair == null) {
+                    System.out.println("PKCS10Client: pair null.");
+                    System.exit(1);
+                }
+            }
+
+            System.out.println("PKCS10Client: key pair generated."); //key pair generated");
+
+            // Add idPOPLinkWitness control
+            String secretValue = "testing";
+            byte[] key1 = null;
+            byte[] finalDigest = null;
+            MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1");
+            key1 = SHA1Digest.digest(secretValue.getBytes());
+
+            /* seed */
+            byte[] b =
+            { 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,
@@ -132,37 +255,83 @@ public class PKCS10Client {
                 0x6a, 0x12, 0x6b, 0x3c, 0x4c, 0x3f, 0x00, 0x14,
                 0x51, 0x61, 0x15, 0x22, 0x23, 0x5f, 0x5e, 0x69 };
 
-        HMACDigest hmacDigest = new HMACDigest(SHA1Digest, key1);
-        hmacDigest.update(b);
-        finalDigest = hmacDigest.digest();
+            HMACDigest hmacDigest = new HMACDigest(SHA1Digest, key1);
+            hmacDigest.update(b);
+            finalDigest = hmacDigest.digest();
 
-        OCTET_STRING ostr = new OCTET_STRING(finalDigest);
-        Attribute attr = new Attribute(OBJECT_IDENTIFIER.id_cmc_idPOPLinkWitness, ostr);
+            OCTET_STRING ostr = new OCTET_STRING(finalDigest);
+            Attribute attr = new Attribute(OBJECT_IDENTIFIER.id_cmc_idPOPLinkWitness, ostr);
 
-        SET attributes = new SET();
-        attributes.addElement(attr);
-        Name n = getJssName(subjectName);
-        SubjectPublicKeyInfo subjectPub = new SubjectPublicKeyInfo(pair.getPublic());
-        CertificationRequestInfo certReqInfo =
+            SET attributes = new SET();
+            attributes.addElement(attr);
+            Name n = getJssName(subjectName);
+            SubjectPublicKeyInfo subjectPub = new SubjectPublicKeyInfo(pair.getPublic());
+            System.out.println("PKCS10Client: pair.getPublic() called.");
+            CertificationRequestInfo certReqInfo =
                 new CertificationRequestInfo(new INTEGER(0), n, subjectPub, attributes);
-        CertificationRequest certRequest = new CertificationRequest(certReqInfo,
-                pair.getPrivate(), SignatureAlgorithm.RSASignatureWithMD5Digest);
-
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        certRequest.encode(bos);
-        byte[] bb = bos.toByteArray();
-
-        String b64E = Utils.base64encode(bb);
-
-        System.out.println("");
-        System.out.println(b64E);
-        System.out.println("");
+            System.out.println("PKCS10Client: CertificationRequestInfo() created.");
 
-        PrintStream ps = null;
-        ps = new PrintStream(new FileOutputStream(ofilename));
-        ps.println(b64E);
-        ps.flush();
-        ps.close();
+            String b64E = "";
+            if (alg.equals("rsa")) {
+                CertificationRequest certRequest = null;
+                certRequest = new CertificationRequest(certReqInfo,
+                pair.getPrivate(), SignatureAlgorithm.RSASignatureWithMD5Digest);
+                System.out.println("PKCS10Client: CertificationRequest created.");
+                if (certRequest == null) {
+                    System.out.println("PKCS10Client: certRequest null.");
+                    System.exit(1);
+                } else
+                    System.out.println("PKCS10Client: certRequest not null.");
+
+                ByteArrayOutputStream bos = new ByteArrayOutputStream();
+                certRequest.encode(bos);
+                byte[] bb = bos.toByteArray();
+
+                System.out.println("PKCS10Client: calling BtoA().");
+                b64E = CMS.BtoA(bb);
+                System.out.println("PKCS10Client: BtoA() completes.");
+            } else { // "ec"
+
+                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("-----BEGIN NEW CERTIFICATE REQUEST-----");
+            System.out.println(b64E);
+            System.out.println("-----END NEW CERTIFICATE REQUEST-----");
+    
+            PrintStream ps = null;
+            ps = new PrintStream(new FileOutputStream(ofilename));
+            ps.println("-----BEGIN NEW CERTIFICATE REQUEST-----");
+            ps.println(b64E);
+            ps.println("-----END NEW CERTIFICATE REQUEST-----");
+            ps.flush();
+            ps.close();
+            System.out.println("PKCS10Client: done. Request written to file: "+ ofilename);
+        } catch (Exception e) {
+            System.out.println("PKCS10Client: Exception caught: "+e.toString());
+        }
 
     }
 
@@ -174,8 +343,8 @@ public class PKCS10Client {
             x5Name = new X500Name(dn);
         } catch (IOException e) {
 
-            System.out.println("Illegal Subject Name:  " + dn + " Error: " + e.toString());
-            System.out.println("Filling in default Subject Name......");
+            System.out.println("PKCS10Client: Illegal Subject Name:  " + dn + " Error: " + e.toString());
+            System.out.println("PKCS10Client: Filling in default Subject Name......");
             return null;
         }
 
@@ -237,7 +406,7 @@ public class PKCS10Client {
                     continue;
                 }
             } catch (Exception e) {
-                System.out.println("Error constructing RDN: " + rdnStr + " Error: " + e.toString());
+                System.out.println("PKCS10Client: Error constructing RDN: " + rdnStr + " Error: " + e.toString());
                 continue;
             }
         }
diff --git a/base/util/src/netscape/security/pkcs/PKCS10.java b/base/util/src/netscape/security/pkcs/PKCS10.java
index 2d1c8eadb..4dd9f0f52 100644
--- a/base/util/src/netscape/security/pkcs/PKCS10.java
+++ b/base/util/src/netscape/security/pkcs/PKCS10.java
@@ -156,6 +156,10 @@ public class PKCS10 {
         byte val1[] = seq[0].data.getDerValue().toByteArray();
         subjectPublicKeyInfo = X509Key.parse(new DerValue(val1));
         PublicKey publicKey = X509Key.parsePublicKey(new DerValue(val1));
+        if (publicKey == null) {
+            System.out.println("PKCS10: publicKey null");
+            throw new SignatureException ("publicKey null");
+        }
 
         // Cope with a somewhat common illegal PKCS #10 format
         if (seq[0].data.available() != 0)
@@ -191,10 +195,13 @@ public class PKCS10 {
 
                 sig.initVerify(publicKey);
                 sig.update(data);
-                if (!sig.verify(sigData))
+                if (!sig.verify(sigData)) {
+                System.out.println("PKCS10: sig.verify() failed");
                     throw new SignatureException("Invalid PKCS #10 signature");
+                }
             }
         } catch (InvalidKeyException e) {
+            System.out.println("PKCS10: "+ e.toString());
             throw new SignatureException("invalid key");
         }
     }
diff --git a/base/util/src/netscape/security/x509/X509CRLImpl.java b/base/util/src/netscape/security/x509/X509CRLImpl.java
index 46c3edfcf..843cba8e2 100755
--- a/base/util/src/netscape/security/x509/X509CRLImpl.java
+++ b/base/util/src/netscape/security/x509/X509CRLImpl.java
@@ -413,6 +413,14 @@ public class X509CRLImpl extends X509CRL {
                 sigAlg = "SHA1/RSA";
             } else if (sigAlg.equals("SHA1withDSA")) {
                 sigAlg = "SHA1/DSA";
+            } else if (sigAlg.equals("SHA1withEC")) {
+                sigAlg = "SHA1/EC";
+            } else if (sigAlg.equals("SHA256withEC")) {
+                sigAlg = "SHA256/EC";
+            } else if (sigAlg.equals("SHA384withEC")) {
+                sigAlg = "SHA384/EC";
+            } else if (sigAlg.equals("SHA512withEC")) {
+                sigAlg = "SHA512/EC";
             }
         }
         sigVerf = Signature.getInstance(sigAlg, sigProvider);
-- 
cgit