From 99722211582103bd5185b21c5fde3cab44783c84 Mon Sep 17 00:00:00 2001 From: Fraser Tweedale Date: Fri, 25 Sep 2015 09:00:29 -0400 Subject: [PATCH] [EXPERIMENTAL] Lightweight CAs: find cert by issuer and serial --- .../src/com/netscape/ca/CertificateAuthority.java | 56 ++++++++++++++-------- base/ca/src/com/netscape/ca/SigningUnit.java | 28 +++++++++-- base/server/share/conf/schema-authority.ldif | 7 +-- base/server/share/conf/schema.ldif | 7 +-- 4 files changed, 69 insertions(+), 29 deletions(-) diff --git a/base/ca/src/com/netscape/ca/CertificateAuthority.java b/base/ca/src/com/netscape/ca/CertificateAuthority.java index e9ac6a9712f58e8024623956d3a6dce6a718a9db..b07276d0929e22d67531a3eac2ec62438626e220 100644 --- a/base/ca/src/com/netscape/ca/CertificateAuthority.java +++ b/base/ca/src/com/netscape/ca/CertificateAuthority.java @@ -167,6 +167,8 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori protected AuthorityID authorityParentID = null; protected String authorityDescription = null; protected boolean authorityEnabled = true; + protected X500Name authorityIssuerDN = null; + protected BigInteger authoritySerial = null; protected ISubsystem mOwner = null; protected IConfigStore mConfig = null; @@ -278,7 +280,9 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori AuthorityID parentAID, String signingKeyNickname, String authorityDescription, - boolean authorityEnabled + boolean authorityEnabled, + X500Name issuerDN, + BigInteger serial ) throws EBaseException { setId(hostCA.getId()); this.hostCA = hostCA; @@ -286,6 +290,8 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori this.authorityParentID = parentAID; this.authorityDescription = authorityDescription; this.authorityEnabled = authorityEnabled; + this.authorityIssuerDN = issuerDN; + this.authoritySerial = serial; mNickname = signingKeyNickname; init(hostCA.mOwner, hostCA.mConfig); } @@ -1333,7 +1339,9 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori mIssuerObj = new CertificateIssuerName((X500Name)mSubjectObj.get(CertificateIssuerName.DN_NAME)); } - mSigningUnit.init(this, caSigningCfg, mNickname); + mSigningUnit.init( + this, caSigningCfg, mNickname, + authorityIssuerDN, authoritySerial); CMS.debug("CA signing unit inited"); // for identrus @@ -1955,9 +1963,11 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori LDAPAttribute nickAttr = entry.getAttribute("authorityKeyNickname"); LDAPAttribute dnAttr = entry.getAttribute("authorityDN"); LDAPAttribute parentAIDAttr = entry.getAttribute("authorityParentID"); - LDAPAttribute parentDNAttr = entry.getAttribute("authorityParentDN"); + LDAPAttribute issuerDNAttr = entry.getAttribute("authorityIssuerDN"); + LDAPAttribute serialAttr = entry.getAttribute("authoritySerial"); - if (aidAttr == null || nickAttr == null || dnAttr == null) + if (aidAttr == null || nickAttr == null || dnAttr == null + || issuerDNAttr == null || serialAttr == null) throw new ECAException("Malformed authority object; required attribute(s) missing: " + entry.getDN()); AuthorityID aid = new AuthorityID((String) @@ -1983,14 +1993,18 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori continue; } - @SuppressWarnings("unused") - X500Name parentDN = null; - if (parentDNAttr != null) { - try { - parentDN = new X500Name((String) parentDNAttr.getStringValues().nextElement()); - } catch (IOException e) { - throw new ECAException("Malformed authority object; invalid authorityParentDN: " + entry.getDN()); - } + X500Name issuerDN = null; + try { + issuerDN = new X500Name((String) issuerDNAttr.getStringValues().nextElement()); + } catch (IOException e) { + throw new ECAException("Malformed authority object; invalid authorityIssuerDN: " + entry.getDN()); + } + + BigInteger serial = null; + try { + serial = new BigInteger((String) serialAttr.getStringValues().nextElement()); + } catch (NumberFormatException e) { + throw new ECAException("Malformed authority object; invalid serial: " + entry.getDN()); } String keyNick = (String) nickAttr.getStringValues().nextElement(); @@ -2008,7 +2022,8 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori } CertificateAuthority ca = new CertificateAuthority( - this, aid, parentAID, keyNick, desc, enabled); + this, aid, parentAID, keyNick, desc, enabled, + issuerDN, serial); caMap.put(aid, ca); } } catch (LDAPException e) { @@ -2423,9 +2438,9 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori String dn = "cn=" + aidString + ",ou=authorities,ou=" + getId() + "," + getDBSubsystem().getBaseDN(); CMS.debug("createSubCA: DN = " + dn); - String parentDNString = null; + String issuerDNString = null; try { - parentDNString = mName.toLdapDNString(); + issuerDNString = mName.toLdapDNString(); } catch (IOException e) { throw new EBaseException("Failed to convert issuer DN to string: " + e); } @@ -2437,7 +2452,7 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori new LDAPAttribute("authorityKeyNickname", nickname), new LDAPAttribute("authorityEnabled", "TRUE"), new LDAPAttribute("authorityDN", subjectDN), - new LDAPAttribute("authorityParentDN", parentDNString) + new LDAPAttribute("authorityParentDN", issuerDNString) }; LDAPAttributeSet attrSet = new LDAPAttributeSet(attrs); if (this.authorityID != null) @@ -2452,6 +2467,7 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori dbFactory.init(CMS.getConfigStore().getSubStore("internaldb")); LDAPConnection conn = dbFactory.getConn(); + X509CertImpl cert = null; try { // add entry to database conn.add(ldapEntry); @@ -2474,8 +2490,7 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori cs.put(".profile", "caCert.profile"); cs.put(".dn", subjectDN); cs.put(".keyalgorithm", algName); - X509CertImpl cert = - CertUtil.createLocalCertWithCA(cs, x509key, "", "", "local", this); + cert = CertUtil.createLocalCertWithCA(cs, x509key, "", "", "local", this); // Add certificate to nssdb cryptoManager.importCertPackage(cert.getEncoded(), nickname); @@ -2492,7 +2507,8 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori } return new CertificateAuthority( - hostCA, aid, this.authorityID, nickname, description, true); + hostCA, aid, this.authorityID, nickname, description, true, + mName /* this CA is the issuer */, cert.getSerialNumber()); } /** @@ -2530,6 +2546,8 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori new LDAPAttribute("authorityKeyNickname", getNickname()), new LDAPAttribute("authorityEnabled", "TRUE"), new LDAPAttribute("authorityDN", dnString), + new LDAPAttribute("authorityIssuerDN", mIssuerObj.toString()), + new LDAPAttribute("authoritySerial", mCaCert.getSerialNumber().toString()), new LDAPAttribute("description", desc) }; LDAPAttributeSet attrSet = new LDAPAttributeSet(attrs); diff --git a/base/ca/src/com/netscape/ca/SigningUnit.java b/base/ca/src/com/netscape/ca/SigningUnit.java index 0410bd2909bc71ca7d7443b3c9db0b085d62eaea..9fd3687eb01553fbc1701772da75c8ada186a175 100644 --- a/base/ca/src/com/netscape/ca/SigningUnit.java +++ b/base/ca/src/com/netscape/ca/SigningUnit.java @@ -17,6 +17,8 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.ca; +import java.io.IOException; +import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; @@ -25,9 +27,11 @@ import java.security.SignatureException; import netscape.security.x509.AlgorithmId; import netscape.security.x509.X509CertImpl; import netscape.security.x509.X509Key; +import netscape.security.x509.X500Name; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.NoSuchTokenException; +import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.ObjectNotFoundException; import org.mozilla.jss.crypto.PrivateKey; @@ -126,10 +130,11 @@ public final class SigningUnit implements ISigningUnit { public void init(ISubsystem owner, IConfigStore config) throws EBaseException { - init(owner, config, null); + init(owner, config, null, null, null); } - public void init(ISubsystem owner, IConfigStore config, String nickname) + public void init(ISubsystem owner, IConfigStore config, + String nickname, X500Name issuerDN, BigInteger serial) throws EBaseException { mOwner = owner; mConfig = config; @@ -165,8 +170,23 @@ public final class SigningUnit implements ISigningUnit { mToken.login(cb); // ONE_TIME by default. - mCert = mManager.findCertByNickname(mNickname); - CMS.debug("Found cert by nickname: '" + mNickname + "' with serial number: " + mCert.getSerialNumber()); + byte[] derIssuer = null; + if (issuerDN != null) { + try { + derIssuer = issuerDN.getEncoded(); + } catch (IOException e) { + CMS.debug("Error getting DER encoding of issuer DN; falling back to nickname"); + } + } + + if (derIssuer != null && serial != null) { + mCert = mManager.findCertByIssuerAndSerialNumber( + derIssuer, new INTEGER(serial)); + CMS.debug("Found cert by issuer: '" + issuerDN + "' and serial number: " + serial); + } else { + mCert = mManager.findCertByNickname(mNickname); + CMS.debug("Found cert by nickname: '" + mNickname + "' with serial number: " + mCert.getSerialNumber()); + } mCertImpl = new X509CertImpl(mCert.getEncoded()); CMS.debug("converted to x509CertImpl"); diff --git a/base/server/share/conf/schema-authority.ldif b/base/server/share/conf/schema-authority.ldif index 7d261f18fbc9475983bf93b1cddcc184d7f9d178..fb831c9b40cb79fbc17867c0e2904d288f205207 100644 --- a/base/server/share/conf/schema-authority.ldif +++ b/base/server/share/conf/schema-authority.ldif @@ -3,6 +3,7 @@ attributeTypes: ( authorityID-oid NAME 'authorityID' DESC 'Authority ID' SYNTAX attributeTypes: ( authorityKeyNickname-oid NAME 'authorityKeyNickname' DESC 'Authority key nickname' SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 X-ORIGIN 'user-defined' ) attributeTypes: ( authorityParentID-oid NAME 'authorityParentID' DESC 'Authority Parent ID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'user defined' ) attributeTypes: ( authorityEnabled-oid NAME 'authorityEnabled' DESC 'Authority Enabled' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 X-ORIGIN 'user defined' ) -attributeTypes: ( authorityDN-oid NAME 'authorityDN' DESC 'Authority Enabled' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'user defined' ) -attributeTypes: ( authorityParentDN-oid NAME 'authorityParentDN' DESC 'Authority Enabled' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'user defined' ) -objectClasses: ( authority-oid NAME 'authority' DESC 'Certificate Authority' SUP top STRUCTURAL MUST ( cn $ authorityID $ authorityKeyNickname $ authorityEnabled $ authorityDN ) MAY ( authorityParentID $ authorityParentDN $ description ) X-ORIGIN 'user defined' ) +attributeTypes: ( authorityDN-oid NAME 'authorityDN' DESC 'Authority Subject DN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'user defined' ) +attributeTypes: ( authorityIssuerDN-oid NAME 'authorityIssuerDN' DESC 'Authority Issuer DN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'user defined' ) +attributeTypes: ( authoritySerial-oid NAME 'authoritySerial' DESC 'Authority Serial Number' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'user defined' ) +objectClasses: ( authority-oid NAME 'authority' DESC 'Certificate Authority' SUP top STRUCTURAL MUST ( cn $ authorityID $ authorityKeyNickname $ authorityEnabled $ authorityDN $ authorityIssuerDN $ authoritySerial ) MAY ( authorityParentID $ description ) X-ORIGIN 'user defined' ) diff --git a/base/server/share/conf/schema.ldif b/base/server/share/conf/schema.ldif index a15601ae7a362635bc398b92b9bfda1c72f0dfc8..cbba4bfcd7798fec6bcd72200b7ec6b1e71d946a 100644 --- a/base/server/share/conf/schema.ldif +++ b/base/server/share/conf/schema.ldif @@ -675,8 +675,9 @@ attributeTypes: ( authorityID-oid NAME 'authorityID' DESC 'Authority ID' SYNTAX attributeTypes: ( authorityKeyNickname-oid NAME 'authorityKeyNickname' DESC 'Authority key nickname' SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 X-ORIGIN 'user-defined' ) attributeTypes: ( authorityParentID-oid NAME 'authorityParentID' DESC 'Authority Parent ID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'user defined' ) attributeTypes: ( authorityEnabled-oid NAME 'authorityEnabled' DESC 'Authority Enabled' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 X-ORIGIN 'user defined' ) -attributeTypes: ( authorityDN-oid NAME 'authorityDN' DESC 'Authority Enabled' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'user defined' ) -attributeTypes: ( authorityParentDN-oid NAME 'authorityParentDN' DESC 'Authority Enabled' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'user defined' ) +attributeTypes: ( authorityDN-oid NAME 'authorityDN' DESC 'Authority Subject DN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'user defined' ) +attributeTypes: ( authorityIssuerDN-oid NAME 'authorityParentDN' DESC 'Authority Issuer DN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'user defined' ) +attributeTypes: ( authoritySerial-oid NAME 'authoritySerial' DESC 'Authority Serial Number' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'user defined' ) - add: objectClasses -objectClasses: ( authority-oid NAME 'authority' DESC 'Certificate Authority' SUP top STRUCTURAL MUST ( cn $ authorityID $ authorityKeyNickname $ authorityEnabled $ authorityDN ) MAY ( authorityParentID $ authorityParentDN $ description ) X-ORIGIN 'user defined' ) +objectClasses: ( authority-oid NAME 'authority' DESC 'Certificate Authority' SUP top STRUCTURAL MUST ( cn $ authorityID $ authorityKeyNickname $ authorityEnabled $ authorityDN $ authorityIssuerDN $ authoritySerial ) MAY ( authorityParentID $ description ) X-ORIGIN 'user defined' ) -- 2.4.3