summaryrefslogtreecommitdiffstats
path: root/pki/base/common/src/com/netscape/cmscore/security/KeyCertUtil.java
diff options
context:
space:
mode:
Diffstat (limited to 'pki/base/common/src/com/netscape/cmscore/security/KeyCertUtil.java')
-rw-r--r--pki/base/common/src/com/netscape/cmscore/security/KeyCertUtil.java1088
1 files changed, 1088 insertions, 0 deletions
diff --git a/pki/base/common/src/com/netscape/cmscore/security/KeyCertUtil.java b/pki/base/common/src/com/netscape/cmscore/security/KeyCertUtil.java
new file mode 100644
index 000000000..4f551cd26
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/security/KeyCertUtil.java
@@ -0,0 +1,1088 @@
+// --- 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.cmscore.security;
+
+
+import org.mozilla.jss.asn1.*;
+
+import java.security.PrivateKey;
+import java.security.*;
+import java.util.*;
+import java.security.interfaces.*;
+import java.io.IOException;
+import java.io.*;
+import java.security.cert.CertificateException;
+import org.mozilla.jss.crypto.KeyPairGenerator;
+import org.mozilla.jss.crypto.*;
+import java.math.*;
+//import java.security.cert.*;
+import org.mozilla.jss.crypto.X509Certificate;
+//import netscape.security.provider.DSAPublicKey;
+// ADDED next line by MLH on 1/9/99
+// REMOVED the line added by MLH on 1/10/99
+//import netscape.security.provider.RSAPublicKey;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.pkcs11.*;
+import org.mozilla.jss.util.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.crypto.Signature;
+import org.mozilla.jss.CryptoManager.NotInitializedException;
+import org.mozilla.jss.CryptoManager.NicknameConflictException;
+import org.mozilla.jss.CryptoManager.UserCertConflictException;
+import java.security.cert.CertificateEncodingException;
+import netscape.ldap.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.cmscore.cert.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmsutil.crypto.*;
+
+
+/**
+ * This class provides all the base methods to generate the key for different
+ * kinds of certificates.
+ *
+ * @author Christine Ho
+ * @version $Revision$, $Date$
+ */
+public class KeyCertUtil {
+
+ public static final String CA_SIGNINGCERT_NICKNAME = "caSigningCert";
+ private static final int MAX_DOMESTIC_SSL_KEY_LEN = 4096;
+ private static final int MAX_EXPORT_SSL_KEY_LEN = 512;
+ private static final int MIN_DSA_KEY_LEN = 512;
+ private static final int MAX_DSA_KEY_LEN = 1024;
+
+ public static void checkCertificateExt(String ext) throws EBaseException {
+ byte[] b = null;
+
+ if (ext != null) {
+ try {
+
+ b = (byte[]) (com.netscape.osutil.OSUtil.AtoB(ext));
+ // this b can be "Extension" Or "SEQUENCE OF Extension"
+ DerValue b_der = new DerValue(b);
+
+ while (b_der.data.available() != 0) {
+ Extension de = new Extension(b_der.data.getDerValue());
+ }
+ } catch (IOException e) {
+ try {
+ Extension de = new Extension(new DerValue(b));
+ } catch (IOException ex) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_CERT_EXTENSION"));
+ }
+ }
+ }
+ }
+
+ public static String getTokenNames(CryptoManager manager)
+ throws TokenException {
+ String tokenList = "";
+ Enumeration tokens = manager.getExternalTokens();
+ int num = 0;
+
+ while (tokens.hasMoreElements()) {
+ CryptoToken c = (CryptoToken) tokens.nextElement();
+
+ if (num++ == 0)
+ tokenList = tokenList + c.getName();
+ else
+ tokenList = tokenList + "," + c.getName();
+ }
+
+ if (tokenList.equals(""))
+ return Constants.PR_INTERNAL_TOKEN;
+ else
+ return (tokenList + "," + Constants.PR_INTERNAL_TOKEN);
+ }
+
+ public static String base64Encode(byte[] bytes) throws IOException {
+ // All this streaming is lame, but Base64OutputStream needs a
+ // PrintStream
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ Base64OutputStream b64 = new Base64OutputStream(new
+ PrintStream(new
+ FilterOutputStream(output)
+ )
+ );
+
+ b64.write(bytes);
+ b64.flush();
+
+ // This is internationally safe because Base64 chars are
+ // contained within 8859_1
+ return output.toString("8859_1");
+ }
+
+ public static byte[] makeDSSParms(BigInteger P, BigInteger Q, BigInteger G)
+ throws IOException {
+
+ // Write P, Q, G to a DER stream
+ DerOutputStream contents = new DerOutputStream();
+
+ contents.putInteger(new BigInt(P));
+ contents.putInteger(new BigInt(Q));
+ contents.putInteger(new BigInt(G));
+
+ // Make a sequence from the PQG stream
+ DerOutputStream sequence = new DerOutputStream();
+
+ sequence.write(DerValue.tag_Sequence, contents);
+
+ return sequence.toByteArray();
+ }
+
+ public static PrivateKey getPrivateKey(String tokenname, String nickname)
+ throws TokenException, EBaseException,
+ NoSuchTokenException, NotInitializedException, CertificateException,
+ CertificateEncodingException, EBaseException, ObjectNotFoundException {
+
+ /*
+ String caNickname = store.getString("ca.signing.tokenname");
+ String tokenName = store.getString("ca.signing.cacertnickname");
+ */
+ X509Certificate cert = getCertificate(tokenname, nickname);
+
+ return CryptoManager.getInstance().findPrivKeyByCert(cert);
+ }
+
+ public static String getCertSubjectName(String tokenname, String nickname)
+ throws TokenException, EBaseException, NoSuchTokenException,
+ NotInitializedException, CertificateException,
+ CertificateEncodingException, EBaseException {
+
+ X509Certificate cert = getCertificate(tokenname, nickname);
+ X509CertImpl impl = new X509CertImpl(cert.getEncoded());
+
+ return impl.getSubjectDN().getName();
+ }
+
+ public static X509CertImpl signCert(PrivateKey privateKey, X509CertInfo certInfo,
+ SignatureAlgorithm sigAlg)
+ throws NoSuchTokenException, EBaseException, NotInitializedException {
+ try {
+ CertificateAlgorithmId sId = (CertificateAlgorithmId)
+ certInfo.get(X509CertInfo.ALGORITHM_ID);
+ AlgorithmId sigAlgId =
+ (AlgorithmId) sId.get(CertificateAlgorithmId.ALGORITHM);
+
+ org.mozilla.jss.crypto.PrivateKey priKey =
+ (org.mozilla.jss.crypto.PrivateKey) privateKey;
+ CryptoToken token = priKey.getOwningToken();
+
+ DerOutputStream tmp = new DerOutputStream();
+ DerOutputStream out = new DerOutputStream();
+
+ certInfo.encode(tmp);
+
+ Signature signer = token.getSignatureContext(sigAlg);
+
+ signer.initSign(priKey);
+ signer.update(tmp.toByteArray());
+ byte signed[] = signer.sign();
+
+ sigAlgId.encode(tmp);
+ tmp.putBitString(signed);
+
+ out.write(DerValue.tag_Sequence, tmp);
+
+ X509CertImpl signedCert = new X509CertImpl(out.toByteArray());
+
+ return signedCert;
+ } catch (IOException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_SIGNED_FAILED", e.toString()));
+ } catch (NoSuchAlgorithmException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED", e.toString()));
+ } catch (TokenException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_ERROR_1", e.toString()));
+ } catch (SignatureException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_SIGNED_FAILED", e.toString()));
+ } catch (InvalidKeyException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1", e.toString()));
+ } catch (CertificateException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR", e.toString()));
+ }
+ }
+
+ public static SignatureAlgorithm getSigningAlgorithm(String keyType) {
+ SignatureAlgorithm sAlg = null;
+
+ if (keyType.equals("RSA"))
+ sAlg = SignatureAlgorithm.RSASignatureWithMD5Digest;
+ else
+ sAlg = SignatureAlgorithm.DSASignatureWithSHA1Digest;
+
+ return sAlg;
+ }
+
+ public static SignatureAlgorithm getSigningAlgorithm(String keyType, String hashtype) {
+ SignatureAlgorithm sAlg = null;
+
+ if (keyType.equals("RSA")) {
+ if (hashtype.equals("MD2"))
+ sAlg = SignatureAlgorithm.RSASignatureWithMD2Digest;
+ else if (hashtype.equals("MD5"))
+ sAlg = SignatureAlgorithm.RSASignatureWithMD5Digest;
+ else if (hashtype.equals("SHA1"))
+ sAlg = SignatureAlgorithm.RSASignatureWithSHA1Digest;
+ else if (hashtype.equals("SHA256"))
+ sAlg = SignatureAlgorithm.RSASignatureWithSHA256Digest;
+ else if (hashtype.equals("SHA512"))
+ sAlg = SignatureAlgorithm.RSASignatureWithSHA512Digest;
+ } else {
+ sAlg = SignatureAlgorithm.DSASignatureWithSHA1Digest;
+ }
+
+ return sAlg;
+ }
+
+ public static AlgorithmId getAlgorithmId(String algname, IConfigStore store)
+ throws EBaseException {
+ try {
+
+ if (algname.equals("DSA")) {
+ byte[] p = store.getByteArray("ca.dsaP", null);
+ byte[] q = store.getByteArray("ca.dsaQ", null);
+ byte[] g = store.getByteArray("ca.dsaG", null);
+
+ if (p != null && q != null && g != null) {
+ BigInteger P = new BigInteger(p);
+ BigInteger Q = new BigInteger(q);
+ BigInteger G = new BigInteger(g);
+
+ return new AlgIdDSA(P, Q, G);
+ }
+ }
+ return AlgorithmId.getAlgorithmId(algname);
+ } catch (NoSuchAlgorithmException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED"));
+ }
+ }
+
+ public static X509Certificate getCertificate(String tokenname,
+ String nickname) throws NotInitializedException, NoSuchTokenException,
+ EBaseException, TokenException {
+ CryptoManager manager = CryptoManager.getInstance();
+ CryptoToken token = null;
+
+ if (tokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME)) {
+ 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 EBaseException(CMS.getUserMessage("CMS_BASE_CA_SIGNINGCERT_NOT_FOUND"));
+ }
+ }
+
+ public static KeyPair getKeyPair(String tokenname, String nickname)
+ throws NotInitializedException, NoSuchTokenException, TokenException,
+ ObjectNotFoundException, EBaseException {
+ X509Certificate cert = getCertificate(tokenname, nickname);
+ PrivateKey priKey =
+ CryptoManager.getInstance().findPrivKeyByCert(cert);
+ PublicKey publicKey = cert.getPublicKey();
+
+ return new KeyPair(publicKey, priKey);
+ }
+
+ public static PQGParams getPQG(int keysize) {
+ try {
+ return PQGParams.generate(keysize);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public static PQGParams getCAPQG(int keysize, IConfigStore store)
+ throws EBaseException {
+ if (store != null) {
+ try {
+ int pqgKeySize = store.getInteger("ca.dsaPQG.keyLength", 0);
+
+ if ((pqgKeySize > 0) && (pqgKeySize == keysize)) {
+ byte[] p = store.getByteArray("ca.dsaP", null);
+ byte[] q = store.getByteArray("ca.dsaQ", null);
+ byte[] g = store.getByteArray("ca.dsaG", null);
+ byte[] seed = store.getByteArray("ca.dsaSeed", null);
+ byte[] H = store.getByteArray("ca.dsaH", null);
+ int counter = store.getInteger("ca.dsaCounter", 0);
+
+ if (p != null && q != null && g != null) {
+ BigInteger P = new BigInteger(p);
+ BigInteger Q = new BigInteger(q);
+ BigInteger G = new BigInteger(g);
+ BigInteger pqgSeed = new BigInteger(seed);
+ BigInteger pqgH = new BigInteger(H);
+
+ return new PQGParams(P, Q, G, pqgSeed, counter, pqgH);
+ }
+ }
+ PQGParams pqg = PQGParams.generate(keysize);
+
+ store.putInteger("ca.dsaPQG.keyLength", keysize);
+ store.putString("ca.dsaP", KeyCertUtil.base64Encode(
+ pqg.getP().toByteArray()));
+ store.putString("ca.dsaQ", KeyCertUtil.base64Encode(
+ pqg.getQ().toByteArray()));
+ store.putString("ca.dsaG", KeyCertUtil.base64Encode(
+ pqg.getG().toByteArray()));
+ store.putString("ca.dsaSeed", KeyCertUtil.base64Encode(
+ pqg.getSeed().toByteArray()));
+ store.putInteger("ca.dsaCounter", pqg.getCounter());
+ store.putString("ca.dsaH", KeyCertUtil.base64Encode(
+ pqg.getH().toByteArray()));
+ store.putString("ca.DSSParms",
+ KeyCertUtil.base64Encode(
+ KeyCertUtil.makeDSSParms(pqg.getP(), pqg.getQ(), pqg.getG())));
+ store.commit(false);
+ return pqg;
+ } catch (IOException ee) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_PQG_GEN_FAILED"));
+ } catch (EBaseException ee) {
+ throw ee;
+ } catch (PQGParamGenException ee) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_PQG_GEN_FAILED"));
+ }
+ }
+ return null;
+ }
+
+ public static KeyPair generateKeyPair(CryptoToken token,
+ KeyPairAlgorithm kpAlg, int keySize, PQGParams pqg)
+ throws NoSuchAlgorithmException, TokenException, InvalidAlgorithmParameterException,
+ InvalidParameterException, PQGParamGenException {
+
+ KeyPairGenerator kpGen = token.getKeyPairGenerator(kpAlg);
+
+ if (kpAlg == KeyPairAlgorithm.DSA) {
+ if (pqg == null) {
+ kpGen.initialize(keySize);
+ } else {
+ kpGen.initialize(pqg);
+ }
+ } else {
+ kpGen.initialize(keySize);
+ }
+
+ if (pqg == null) {
+ return kpGen.genKeyPair();
+ } else {
+ // DSA
+ KeyPair kp = null;
+
+ do {
+ // 602548 NSS bug - to overcome it, we use isBadDSAKeyPair
+ kp = kpGen.genKeyPair();
+ }
+ while (isBadDSAKeyPair(kp));
+ return kp;
+ }
+ }
+
+ /**
+ * Test for a DSA key pair that will trigger a bug in NSS.
+ * The problem occurs when the first byte of the key is 0. This
+ * happens when the value otherwise would have been negative, and a
+ * zero byte is prepended to force it to be positive.
+ * This is blackflag bug 602548.
+ */
+ public static boolean isBadDSAKeyPair(KeyPair pair) {
+ try {
+ byte[] pubkBytes = pair.getPublic().getEncoded();
+ SEQUENCE.Template outerSeq = new SEQUENCE.Template();
+
+ outerSeq.addElement(new ANY.Template()); // algid
+ outerSeq.addElement(new BIT_STRING.Template()); // key value
+ SEQUENCE seq = (SEQUENCE) ASN1Util.decode(outerSeq, pubkBytes);
+
+ BIT_STRING bs = (BIT_STRING) seq.elementAt(1);
+ byte[] bits = bs.getBits();
+ ByteArrayInputStream bitstream = new ByteArrayInputStream(bs.getBits());
+ ASN1Header wrapper = new ASN1Header(bitstream);
+ byte[] valBytes = new byte[ (int) wrapper.getContentLength() ];
+
+ ASN1Util.readFully(valBytes, bitstream);
+
+ boolean isBroken = (valBytes[0] == 0);
+
+ return isBroken;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public static KeyPair generateKeyPair(String tokenName, String alg,
+ int keySize, PQGParams pqg) throws EBaseException {
+
+ CryptoToken token = null;
+
+ if (tokenName.equalsIgnoreCase(Constants.PR_INTERNAL_TOKEN))
+ tokenName = Constants.PR_INTERNAL_TOKEN_NAME;
+
+ try {
+ if (tokenName.equalsIgnoreCase(Constants.PR_INTERNAL_TOKEN)) {
+ token = CryptoManager.getInstance().getInternalKeyStorageToken();
+ } else {
+ token = CryptoManager.getInstance().getTokenByName(tokenName);
+ }
+ } catch (NoSuchTokenException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_NOT_FOUND", tokenName));
+ } catch (NotInitializedException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CRYPTOMANAGER_UNINITIALIZED"));
+ }
+
+ KeyPairAlgorithm kpAlg = null;
+
+ if (alg.equals("RSA"))
+ kpAlg = KeyPairAlgorithm.RSA;
+ else
+ kpAlg = KeyPairAlgorithm.DSA;
+
+ try {
+ KeyPair kp = generateKeyPair(token, kpAlg, keySize, pqg);
+
+ return kp;
+ } catch (InvalidParameterException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEYSIZE_PARAMS",
+ "" + keySize));
+ } catch (PQGParamGenException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_PQG_GEN_FAILED"));
+ } catch (NoSuchAlgorithmException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED",
+ kpAlg.toString()));
+ } catch (TokenException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_ERROR_1", e.toString()));
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED", "DSA"));
+ }
+ }
+
+ public static PKCS10 getCertRequest(String subjectName, KeyPair keyPair)
+ throws NoSuchAlgorithmException, NoSuchProviderException,
+ InvalidKeyException, IOException, CertificateException,
+ SignatureException {
+ PublicKey pubk = keyPair.getPublic();
+ X509Key key = convertPublicKeyToX509Key(pubk);
+ String alg;
+
+ if (pubk instanceof RSAPublicKey) {
+ alg = "MD5/RSA";
+ } else if (pubk instanceof PK11ECPublicKey) {
+ alg = "SHA256withEC";
+ } else {
+ alg = "DSA";
+ }
+ java.security.Signature sig =
+ java.security.Signature.getInstance(alg, "Mozilla-JSS");
+
+ sig.initSign(keyPair.getPrivate());
+
+ PKCS10 pkcs10 = new PKCS10(key);
+
+ X500Name name = new X500Name(subjectName);
+ X500Signer signer = new X500Signer(sig, name);
+
+ pkcs10.encodeAndSign(signer);
+
+ return pkcs10;
+ }
+
+ public static PKCS10 getCertRequest(String subjectName, KeyPair
+ keyPair, Extensions
+ exts)
+ throws NoSuchAlgorithmException, NoSuchProviderException,
+ InvalidKeyException, IOException, CertificateException,
+ SignatureException {
+ PublicKey pubk = keyPair.getPublic();
+ X509Key key = convertPublicKeyToX509Key(pubk);
+ String alg;
+
+ if (pubk instanceof RSAPublicKey) {
+ alg = "MD5/RSA";
+ } else if (pubk instanceof PK11ECPublicKey) {
+ alg = "SHA256withEC";
+ } else {
+ alg = "DSA";
+ }
+ java.security.Signature sig =
+ java.security.Signature.getInstance(alg, "Mozilla-JSS");
+
+ sig.initSign(keyPair.getPrivate());
+
+ PKCS10 pkcs10 = null;
+
+ if (exts != null) {
+ PKCS10Attribute attr = new
+ PKCS10Attribute(PKCS9Attribute.EXTENSION_REQUEST_OID,
+ (CertAttrSet) exts);
+ PKCS10Attributes attrs = new PKCS10Attributes();
+
+ attrs.setAttribute(attr.getAttributeValue().getName(), attr);
+
+ pkcs10 = new PKCS10(key, attrs);
+ } else {
+ pkcs10 = new PKCS10(key);
+ }
+
+ X500Name name = new X500Name(subjectName);
+ X500Signer signer = new X500Signer(sig, name);
+
+ pkcs10.encodeAndSign(signer);
+
+ return pkcs10;
+ }
+
+ public static X509Key convertPublicKeyToX509Key(PublicKey pubk)
+ throws InvalidKeyException {
+
+ X509Key xKey;
+
+ if (pubk instanceof RSAPublicKey) {
+ RSAPublicKey rsaKey = (RSAPublicKey) pubk;
+
+ // REMOVED constructors from parameters by MLH on 1/9/99
+ xKey = new netscape.security.provider.RSAPublicKey(
+ new BigInt(rsaKey.getModulus()),
+ new BigInt(rsaKey.getPublicExponent()));
+ } else if (pubk instanceof PK11ECPublicKey) {
+ byte encoded[] = pubk.getEncoded();
+ xKey = CryptoUtil.getPublicX509ECCKey(encoded);
+
+ } else {
+ DSAPublicKey dsaKey = (DSAPublicKey) pubk;
+ DSAParams params = dsaKey.getParams();
+
+ xKey = new netscape.security.provider.DSAPublicKey(
+ dsaKey.getY(),
+ params.getP(),
+ params.getQ(),
+ params.getG());
+ }
+ return xKey;
+ }
+
+ public static X509Certificate
+ importCert(X509CertImpl signedCert, String nickname,
+ String certType) throws NotInitializedException, TokenException,
+ CertificateEncodingException, UserCertConflictException,
+ NicknameConflictException, NoSuchItemOnTokenException, CertificateException {
+
+ return importCert(signedCert.getEncoded(), nickname, certType);
+ }
+
+ public static X509Certificate
+ importCert(String b64E, String nickname, String certType)
+ throws NotInitializedException, TokenException,
+ CertificateEncodingException, UserCertConflictException,
+ NicknameConflictException, NoSuchItemOnTokenException, CertificateException {
+
+ byte b[] = b64E.getBytes();
+ X509Certificate cert = getInternalCertificate(b, nickname, certType);
+
+ if (cert instanceof InternalCertificate) {
+ setTrust(certType, (InternalCertificate) cert);
+ }
+ return cert;
+ }
+
+ public static X509Certificate
+ importCert(byte[] b, String nickname, String certType)
+ throws NotInitializedException, TokenException,
+ CertificateEncodingException, UserCertConflictException,
+ NicknameConflictException, NoSuchItemOnTokenException, CertificateException {
+
+ X509Certificate cert = getInternalCertificate(b, nickname, certType);
+
+ if (cert instanceof InternalCertificate) {
+ setTrust(certType, (InternalCertificate) cert);
+ }
+ return cert;
+ }
+
+ public static X509Certificate getInternalCertificate(byte[] b, String nickname, String certType)
+ throws NotInitializedException, TokenException, CertificateEncodingException,
+ UserCertConflictException, NicknameConflictException, NoSuchItemOnTokenException,
+ CertificateException {
+ X509Certificate cert = null;
+
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ cert = CryptoManager.getInstance().importUserCACertPackage(b,
+ nickname);
+ } else if (certType.equals(Constants.PR_RA_SIGNING_CERT) ||
+ certType.equals(Constants.PR_KRA_TRANSPORT_CERT) ||
+ certType.equals(Constants.PR_OCSP_SIGNING_CERT) ||
+ certType.equals(Constants.PR_SERVER_CERT) ||
+ certType.equals(Constants.PR_SERVER_CERT_RADM) ||
+ certType.equals(Constants.PR_OTHER_CERT) ||
+ certType.equals(Constants.PR_SUBSYSTEM_CERT)) {
+ cert = CryptoManager.getInstance().importCertPackage(b,
+ nickname);
+ } else if (certType.equals(Constants.PR_SERVER_CERT_CHAIN)) {
+ cert = CryptoManager.getInstance().importCACertPackage(b);
+ } else if (certType.equals(Constants.PR_TRUSTED_CA_CERT)) {
+ cert = CryptoManager.getInstance().importCACertPackage(b);
+ X509Certificate[] certchain = CryptoManager.getInstance().buildCertificateChain(cert);
+
+ if (certchain != null) {
+ cert = certchain[certchain.length - 1];
+ }
+ }
+ return cert;
+ }
+
+ public static void setTrust(String certType, InternalCertificate inCert) {
+ if (certType.equals(Constants.PR_CA_SIGNING_CERT)) {
+ int flag = InternalCertificate.VALID_CA |
+ InternalCertificate.TRUSTED_CA |
+ InternalCertificate.USER |
+ InternalCertificate.TRUSTED_CLIENT_CA;
+
+ inCert.setSSLTrust(flag);
+ inCert.setObjectSigningTrust(flag);
+ inCert.setEmailTrust(flag);
+ } else if (certType.equals(Constants.PR_RA_SIGNING_CERT)) {
+ int flag = InternalCertificate.USER | InternalCertificate.VALID_CA;
+
+ inCert.setSSLTrust(flag);
+ inCert.setObjectSigningTrust(flag);
+ inCert.setEmailTrust(flag);
+ } else if (certType.equals(Constants.PR_OCSP_SIGNING_CERT)) {
+ int flag = InternalCertificate.USER | InternalCertificate.VALID_CA;
+
+ inCert.setSSLTrust(flag);
+ inCert.setObjectSigningTrust(flag);
+ inCert.setEmailTrust(flag);
+ } else if (certType.equals(Constants.PR_SERVER_CERT) ||
+ certType.equals(Constants.PR_SUBSYSTEM_CERT)) {
+ int flag = InternalCertificate.USER | InternalCertificate.VALID_CA;
+
+ inCert.setSSLTrust(flag);
+ inCert.setObjectSigningTrust(flag);
+ inCert.setEmailTrust(flag);
+ } else if (certType.equals(Constants.PR_TRUSTED_CA_CERT)) {
+ inCert.setSSLTrust(InternalCertificate.TRUSTED_CA | InternalCertificate.TRUSTED_CLIENT_CA |
+ InternalCertificate.VALID_CA);
+ //inCert.setEmailTrust(InternalCertificate.TRUSTED_CA);
+
+ // cannot set this bit. If set, then the cert will not appear when you called getCACerts().
+ //inCert.setObjectSigningTrust(InternalCertificate.TRUSTED_CA);
+ }
+ }
+
+ public static byte[] convertB64EToByteArray(String b64E)
+ throws CertificateException, IOException {
+ String str = CertUtils.stripCertBrackets(b64E);
+ byte bCert[] = (byte[]) (com.netscape.osutil.OSUtil.AtoB(str));
+
+ /*
+ java.security.cert.X509Certificate cert =
+ java.security.cert.X509Certificate.getInstance(bCert);
+ return cert;
+ */
+ return bCert;
+ }
+
+ /**
+ * ASN.1 structure:
+ * 0 30 142: SEQUENCE {
+ * 3 30 69: SEQUENCE {
+ * 5 06 3: OBJECT IDENTIFIER issuerAltName (2 5 29 18)
+ * 10 04 62: OCTET STRING
+ * : 30 3C 82 01 61 82 01 61 A4 10 30 0E 31 0C 30 0A
+ * : 06 03 55 04 03 13 03 64 73 61 87 04 01 01 01 01
+ * : 86 01 61 81 14 74 68 6F 6D 61 73 6B 40 6E 65 74
+ * : 73 63 61 70 65 2E 63 6F 6D 88 03 29 01 01
+ * : }
+ * 74 30 69: SEQUENCE {
+ * 76 06 3: OBJECT IDENTIFIER subjectAltName (2 5 29 17)
+ * 81 04 62: OCTET STRING
+ * : 30 3C 82 01 61 82 01 61 A4 10 30 0E 31 0C 30 0A
+ * : 06 03 55 04 03 13 03 64 73 61 87 04 01 01 01 01
+ * : 86 01 61 81 14 74 68 6F 6D 61 73 6B 40 6E 65 74
+ * : 73 63 61 70 65 2E 63 6F 6D 88 03 29 01 01
+ * : }
+ * : }
+ * Uses the following to test with configuration wizard:
+ * MIGOMEUGA1UdEQQ+MDyCAWGCAWGkEDAOMQwwCgYDVQQDEwNkc2GHBAEBAQGGAWGB
+ * FHRob21hc2tAbmV0c2NhcGUuY29tiAMpAQEwRQYDVR0SBD4wPIIBYYIBYaQQMA4x
+ * DDAKBgNVBAMTA2RzYYcEAQEBAYYBYYEUdGhvbWFza0BuZXRzY2FwZS5jb22IAykB
+ * AQ==
+ */
+ public static void setDERExtension(
+ CertificateExtensions ext, KeyCertData properties)
+ throws IOException {
+
+ String b64E = properties.getDerExtension();
+
+ if (b64E != null) {
+ byte[] b = (byte[]) (com.netscape.osutil.OSUtil.AtoB(b64E));
+
+ // this b can be "Extension" Or "SEQUENCE OF Extension"
+ try {
+ DerValue b_der = new DerValue(b);
+
+ while (b_der.data.available() != 0) {
+ Extension de = new Extension(b_der.data.getDerValue());
+
+ ext.set(de.getExtensionId().toString(), de);
+ }
+ } catch (IOException e) {
+ Extension de = new Extension(new DerValue(b));
+
+ ext.set(de.getExtensionId().toString(), de);
+ }
+ }
+ }
+
+ public static void setBasicConstraintsExtension(
+ CertificateExtensions ext, KeyCertData properties)
+ throws IOException {
+ String isCA = properties.isCA();
+ String certLen = properties.getCertLen();
+
+ if (isCA == null)
+ return; // isCA is not optional
+ if (isCA.equals("null"))
+ return; // no BasicConstraints requested
+ if ((isCA == null) && (certLen == null))
+ return;
+ int len = 0;
+ boolean bool = false;
+
+ if ((certLen == null) || (certLen.equals("")))
+ len = 0;
+ else
+ len = Integer.parseInt(certLen);
+
+ if ((isCA == null) || (isCA.equals("")) ||
+ (isCA.equals(Constants.FALSE)))
+ bool = false;
+ else
+ bool = true;
+
+ BasicConstraintsExtension basic = new BasicConstraintsExtension(
+ bool, len);
+
+ ext.set(BasicConstraintsExtension.NAME, basic);
+ }
+
+ public static void setExtendedKeyUsageExtension(
+ CertificateExtensions ext, KeyCertData properties) throws IOException,
+ CertificateException {
+ ExtendedKeyUsageExtension ns = new ExtendedKeyUsageExtension();
+ boolean anyExt = false;
+
+ String sslClient = properties.getSSLClientBit();
+
+ if ((sslClient != null) && (sslClient.equals(Constants.TRUE))) {
+ ns.addOID(new ObjectIdentifier("1.3.6.1.5.5.7.3.2"));
+ anyExt = true;
+ }
+
+ String sslServer = properties.getSSLServerBit();
+
+ if ((sslServer != null) && (sslServer.equals(Constants.TRUE))) {
+ ns.addOID(new ObjectIdentifier("1.3.6.1.5.5.7.3.1"));
+ anyExt = true;
+ }
+
+ String sslMail = properties.getSSLMailBit();
+
+ if ((sslMail != null) && (sslMail.equals(Constants.TRUE))) {
+ ns.addOID(new ObjectIdentifier("1.3.6.1.5.5.7.3.4"));
+ anyExt = true;
+ }
+
+ String objectSigning = properties.getObjectSigningBit();
+
+ if ((objectSigning != null) && (objectSigning.equals(Constants.TRUE))) {
+ ns.addOID(new ObjectIdentifier("1.3.6.1.5.5.7.3.3"));
+ anyExt = true;
+ }
+
+ String timestamping = properties.getTimeStampingBit();
+ if ((timestamping != null) && (timestamping.equals(Constants.TRUE))) {
+ ns.addOID(new ObjectIdentifier("1.3.6.1.5.5.7.3.8"));
+ anyExt = true;
+ }
+
+ String ocspSigning = properties.getOCSPSigning();
+
+ if ((ocspSigning != null) && (ocspSigning.equals(Constants.TRUE))) {
+ ns.addOID(new ObjectIdentifier("1.3.6.1.5.5.7.3.9"));
+ anyExt = true;
+ }
+
+ if (anyExt)
+ ext.set(ExtendedKeyUsageExtension.NAME, ns);
+ }
+
+ public static void setNetscapeCertificateExtension(
+ CertificateExtensions ext, KeyCertData properties) throws IOException,
+ CertificateException {
+
+ NSCertTypeExtension ns = new NSCertTypeExtension();
+ boolean anyExt = false;
+
+ String sslClient = properties.getSSLClientBit();
+
+ if ((sslClient != null) && (sslClient.equals(Constants.TRUE))) {
+ ns.set(NSCertTypeExtension.SSL_CLIENT, new Boolean(true));
+ anyExt = true;
+ }
+
+ String sslServer = properties.getSSLServerBit();
+
+ if ((sslServer != null) && (sslServer.equals(Constants.TRUE))) {
+ ns.set(NSCertTypeExtension.SSL_SERVER, new Boolean(true));
+ anyExt = true;
+ }
+
+ String sslMail = properties.getSSLMailBit();
+
+ if ((sslMail != null) && (sslMail.equals(Constants.TRUE))) {
+ ns.set(NSCertTypeExtension.EMAIL, new Boolean(true));
+ anyExt = true;
+ }
+
+ String sslCA = properties.getSSLCABit();
+
+ if ((sslCA != null) && (sslCA.equals(Constants.TRUE))) {
+ ns.set(NSCertTypeExtension.SSL_CA, new Boolean(true));
+ anyExt = true;
+ }
+
+ String objectSigning = properties.getObjectSigningBit();
+
+ if ((objectSigning != null) && (objectSigning.equals(Constants.TRUE))) {
+ ns.set(NSCertTypeExtension.OBJECT_SIGNING, new Boolean(true));
+ anyExt = true;
+ }
+
+ String mailCA = properties.getMailCABit();
+
+ if ((mailCA != null) && (mailCA.equals(Constants.TRUE))) {
+ ns.set(NSCertTypeExtension.EMAIL_CA, new Boolean(true));
+ anyExt = true;
+ }
+
+ String objectSigningCA = properties.getObjectSigningCABit();
+
+ if ((objectSigningCA != null) && (objectSigningCA.equals(Constants.TRUE))) {
+ ns.set(NSCertTypeExtension.OBJECT_SIGNING_CA, new Boolean(true));
+ anyExt = true;
+ }
+ if (anyExt)
+ ext.set(NSCertTypeExtension.NAME, ns);
+ }
+
+ public static void setOCSPNoCheck(KeyPair keypair,
+ CertificateExtensions ext, KeyCertData properties) throws IOException,
+ NoSuchAlgorithmException, InvalidKeyException {
+ String noCheck = properties.getOCSPNoCheck();
+
+ if ((noCheck != null) && (noCheck.equals(Constants.TRUE))) {
+ OCSPNoCheckExtension noCheckExt =
+ new OCSPNoCheckExtension();
+
+ ext.set(OCSPNoCheckExtension.NAME, noCheckExt);
+ }
+ }
+
+ public static void setOCSPSigning(KeyPair keypair,
+ CertificateExtensions ext, KeyCertData properties) throws IOException,
+ NoSuchAlgorithmException, InvalidKeyException {
+ String signing = properties.getOCSPSigning();
+
+ if ((signing != null) && (signing.equals(Constants.TRUE))) {
+ Vector oidSet = new Vector();
+ oidSet.addElement(
+ ObjectIdentifier.getObjectIdentifier(
+ ExtendedKeyUsageExtension.OID_OCSPSigning));
+ ExtendedKeyUsageExtension ocspExt =
+ new ExtendedKeyUsageExtension(false, oidSet);
+ ext.set(ExtendedKeyUsageExtension.NAME, ocspExt);
+ }
+ }
+
+ public static void setAuthInfoAccess(KeyPair keypair,
+ CertificateExtensions ext, KeyCertData properties) throws IOException,
+ NoSuchAlgorithmException, InvalidKeyException {
+ String aia = properties.getAIA();
+
+ if ((aia != null) && (aia.equals(Constants.TRUE))) {
+ String hostname = CMS.getEENonSSLHost();
+ String port = CMS.getEENonSSLPort();
+ AuthInfoAccessExtension aiaExt = new AuthInfoAccessExtension(false);
+ if (hostname != null && port != null) {
+ String location = "http://"+hostname+":"+port+"/ca/ocsp";
+ GeneralName ocspName = new GeneralName(new URIName(location));
+ aiaExt.addAccessDescription(AuthInfoAccessExtension.METHOD_OCSP, ocspName);
+ }
+
+ ext.set(AuthInfoAccessExtension.NAME, aiaExt);
+ }
+ }
+
+ public static void setAuthorityKeyIdentifier(KeyPair keypair,
+ CertificateExtensions ext, KeyCertData properties) throws IOException,
+ NoSuchAlgorithmException, InvalidKeyException {
+ String aki = properties.getAKI();
+
+ if ((aki != null) && (aki.equals(Constants.TRUE))) {
+ KeyIdentifier id = createKeyIdentifier(keypair);
+ AuthorityKeyIdentifierExtension akiExt =
+ new AuthorityKeyIdentifierExtension(id, null, null);
+
+ ext.set(AuthorityKeyIdentifierExtension.NAME, akiExt);
+ }
+ }
+
+ public static void setSubjectKeyIdentifier(KeyPair keypair,
+ CertificateExtensions ext,
+ KeyCertData properties) throws IOException, NoSuchAlgorithmException,
+ InvalidKeyException {
+ String ski = properties.getSKI();
+
+ if ((ski != null) && (ski.equals(Constants.TRUE))) {
+ KeyIdentifier id = createKeyIdentifier(keypair);
+ SubjectKeyIdentifierExtension skiExt =
+ new SubjectKeyIdentifierExtension(id.getIdentifier());
+
+ ext.set(SubjectKeyIdentifierExtension.NAME, skiExt);
+ }
+ }
+
+ public static void setKeyUsageExtension(CertificateExtensions ext,
+ KeyUsageExtension keyUsage) throws IOException {
+ ext.set(KeyUsageExtension.NAME, keyUsage);
+ }
+
+ public static KeyIdentifier createKeyIdentifier(KeyPair keypair)
+ throws NoSuchAlgorithmException, InvalidKeyException {
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+ X509Key subjectKeyInfo = convertPublicKeyToX509Key(
+ keypair.getPublic());
+
+ //md.update(subjectKeyInfo.getEncoded());
+ md.update(subjectKeyInfo.getKey());
+ return new KeyIdentifier(md.digest());
+ }
+
+ public static BigInteger getSerialNumber(LDAPConnection conn, String baseDN)
+ throws LDAPException {
+ String dn = "ou=certificateRepository,ou=ca," + baseDN;
+ BigInteger serialno = null;
+ LDAPEntry entry = conn.read(dn);
+ String serialnoStr = (String) entry.getAttribute(
+ "serialno").getStringValues().nextElement();
+
+ serialno = BigIntegerMapper.BigIntegerFromDB(serialnoStr);
+ LDAPAttribute attr = new LDAPAttribute("serialno");
+
+ attr.addValue(BigIntegerMapper.BigIntegerToDB(
+ serialno.add(new BigInteger("1"))));
+ LDAPModification mod = new LDAPModification(
+ LDAPModification.REPLACE, attr);
+
+ conn.modify(dn, mod);
+
+ return serialno;
+ }
+
+ public static void setSerialNumber(LDAPConnection conn,
+ String baseDN, BigInteger serial)
+ throws LDAPException {
+ String dn = "ou=certificateRepository,ou=ca," + baseDN;
+ LDAPAttribute attr = new LDAPAttribute("serialno");
+
+ // the serial number should already be set
+ attr.addValue(BigIntegerMapper.BigIntegerToDB(
+ serial));
+ LDAPModification mod = new LDAPModification(
+ LDAPModification.REPLACE, attr);
+
+ conn.modify(dn, mod);
+
+ }
+
+ public static void addCertToDB(LDAPConnection conn, String dn, X509CertImpl cert)
+ throws LDAPException, EBaseException {
+ BigInteger serialno = cert.getSerialNumber();
+ X509CertImplMapper mapper = new X509CertImplMapper();
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+
+ mapper.mapObjectToLDAPAttributeSet(null, null,
+ cert, attrs);
+ attrs.add(new LDAPAttribute("objectclass", "top"));
+ attrs.add(new LDAPAttribute("objectclass",
+ "certificateRecord"));
+ attrs.add(new LDAPAttribute("serialno",
+ BigIntegerMapper.BigIntegerToDB(
+ serialno)));
+ attrs.add(new LDAPAttribute("dateOfCreate",
+ DateMapper.dateToDB((CMS.getCurrentDate()))));
+ attrs.add(new LDAPAttribute("dateOfModify",
+ DateMapper.dateToDB((CMS.getCurrentDate()))));
+ attrs.add(new LDAPAttribute("certStatus",
+ "VALID"));
+ attrs.add(new LDAPAttribute("autoRenew",
+ "ENABLED"));
+ attrs.add(new LDAPAttribute("issuedBy",
+ "installation"));
+ LDAPEntry entry = new LDAPEntry("cn=" + serialno.toString() + "," + dn, attrs);
+
+ conn.add(entry);
+ }
+
+ public static CertificateExtensions getExtensions(String tokenname, String nickname)
+ throws NotInitializedException, TokenException, ObjectNotFoundException,
+ IOException, CertificateException {
+ String fullnickname = nickname;
+
+ if (!tokenname.equals(Constants.PR_INTERNAL_TOKEN_NAME))
+ fullnickname = tokenname + ":" + nickname;
+ CryptoManager manager = CryptoManager.getInstance();
+ X509Certificate cert = manager.findCertByNickname(fullnickname);
+ X509CertImpl impl = new X509CertImpl(cert.getEncoded());
+ X509CertInfo info = (X509CertInfo) impl.get(X509CertImpl.NAME + "." + X509CertImpl.INFO);
+
+ return (CertificateExtensions) info.get(X509CertInfo.EXTENSIONS);
+ }
+}