>From a8fe431dc77f03a8237ec0820c02c542762ecb9f Mon Sep 17 00:00:00 2001
From: Christina Fu <cfu@redhat.com>
Date: Wed, 15 Oct 2014 10:30:31 -0700
Subject: [PATCH] Bug1151147 issuerDN encoding correction

---
 base/ca/src/com/netscape/ca/CAService.java         | 13 ++++++--
 .../src/com/netscape/ca/CertificateAuthority.java  | 39 +++++++++++++++++++++-
 .../netscape/certsrv/ca/ICertificateAuthority.java |  5 +++
 .../netscape/cms/profile/common/EnrollProfile.java | 16 +++++++--
 .../com/netscape/cms/servlet/csadmin/CertUtil.java | 16 +++++++--
 .../com/netscape/cmsutil/crypto/CryptoUtil.java    | 18 ++++++++--
 .../src/netscape/security/x509/X509CertImpl.java   |  8 +++++
 .../src/netscape/security/x509/X509CertInfo.java   |  8 +++++
 8 files changed, 114 insertions(+), 9 deletions(-)

diff --git a/base/ca/src/com/netscape/ca/CAService.java b/base/ca/src/com/netscape/ca/CAService.java
index 1977850..6edaf2a 100644
--- a/base/ca/src/com/netscape/ca/CAService.java
+++ b/base/ca/src/com/netscape/ca/CAService.java
@@ -821,8 +821,17 @@ public class CAService implements ICAService, IService {
         }
 
         try {
-            certi.set(X509CertInfo.ISSUER,
-                    new CertificateIssuerName(mCA.getX500Name()));
+            if (mCA.getIssuerObj() != null) {
+                // this ensures the isserDN has the same encoding as the
+                // subjectDN of the CA signing cert
+                CMS.debug("CAService: issueX509Cert: setting issuerDN using exact CA signing cert subjectDN encoding");
+                certi.set(X509CertInfo.ISSUER,
+                        mCA.getIssuerObj());
+            } else {
+                CMS.debug("CAService: issueX509Cert: mCA.getIssuerObj() is null, creating new CertificateIssuerName");
+                certi.set(X509CertInfo.ISSUER,
+                        new CertificateIssuerName(mCA.getX500Name()));
+            }
         } catch (CertificateException e) {
             mCA.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_SET_ISSUER", e.toString()));
             throw new ECAException(CMS.getUserMessage("CMS_CA_SET_ISSUER_FAILED", rid));
diff --git a/base/ca/src/com/netscape/ca/CertificateAuthority.java b/base/ca/src/com/netscape/ca/CertificateAuthority.java
index 73ce6df..6529611 100644
--- a/base/ca/src/com/netscape/ca/CertificateAuthority.java
+++ b/base/ca/src/com/netscape/ca/CertificateAuthority.java
@@ -43,6 +43,8 @@ import netscape.security.util.DerOutputStream;
 import netscape.security.util.DerValue;
 import netscape.security.x509.AlgorithmId;
 import netscape.security.x509.CertificateChain;
+import netscape.security.x509.CertificateIssuerName;
+import netscape.security.x509.CertificateSubjectName;
 import netscape.security.x509.CertificateVersion;
 import netscape.security.x509.X500Name;
 import netscape.security.x509.X509CRLImpl;
@@ -143,6 +145,8 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori
     protected SigningUnit mOCSPSigningUnit;
     protected SigningUnit mCRLSigningUnit;
 
+    protected CertificateIssuerName mIssuerObj = null;
+    protected CertificateSubjectName mSubjectObj = null;
     protected X500Name mName = null;
     protected X500Name mCRLName = null;
     protected X500Name mOCSPName = null;
@@ -888,6 +892,14 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori
         return mName;
     }
 
+    public CertificateIssuerName getIssuerObj() {
+       return mIssuerObj;
+    }
+
+    public CertificateSubjectName getSubjectObj() {
+       return mSubjectObj;
+    }
+
     public X500Name getCRLX500Name() {
         return mCRLName;
     }
@@ -1199,6 +1211,21 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori
             IConfigStore caSigningCfg =
                     mConfig.getSubStore(PROP_SIGNING_SUBSTORE);
 
+            String caSigningCertStr = caSigningCfg.getString("cert", "");
+            if (caSigningCertStr.equals("")) {
+                CMS.debug("CertificateAuthority:initSigUnit: ca.signing.cert not found");
+            } else { //ca cert found
+                CMS.debug("CertificateAuthority:initSigUnit: ca cert found");
+                mCaCert = new X509CertImpl(CMS.AtoB(caSigningCertStr));
+                // this ensures the isserDN and subjectDN have the same encoding
+                // as that of the CA signing cert
+                CMS.debug("CertificateAuthority: initSigUnit 1- setting mIssuerObj and mSubjectObj");
+                mSubjectObj = mCaCert.getSubjectObj();
+                // this mIssuerObj is the "issuerDN" obj for the certs this CA
+                // issues, NOT necessarily the isserDN obj of the CA signing cert
+                mIssuerObj = new CertificateIssuerName((X500Name)mSubjectObj.get(CertificateIssuerName.DN_NAME));
+            }
+
             mSigningUnit.init(this, caSigningCfg);
             CMS.debug("CA signing unit inited");
 
@@ -1295,11 +1322,21 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori
             }
             mOCSPCertChain = new CertificateChain(ocspImplchain);
             CMS.debug("in init - got OCSP chain from JSS.");
-            // init issuer name - take name from the cert.
 
             mCaX509Cert = mSigningUnit.getCert();
             mCaCert = new X509CertImpl(mCaX509Cert.getEncoded());
             getCASigningAlgorithms();
+            mSubjectObj = mCaCert.getSubjectObj();
+            if (mSubjectObj != null) {
+                // this ensures the isserDN and subjectDN have the same encoding
+                // as that of the CA signing cert
+                CMS.debug("CertificateAuthority: initSigUnit - setting mIssuerObj and mSubjectObj");
+                // this mIssuerObj is the "issuerDN" obj for the certs this CA
+                // issues, NOT necessarily the isserDN obj of the CA signing cert
+                // unless the CA is self-signed
+                mIssuerObj =
+                        new CertificateIssuerName((X500Name)mSubjectObj.get(CertificateIssuerName.DN_NAME));
+            }
             mName = (X500Name) mCaCert.getSubjectDN();
 
             mCRLX509Cert = mCRLSigningUnit.getCert();
diff --git a/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java b/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java
index 39f336b..f87f154 100644
--- a/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java
+++ b/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java
@@ -23,6 +23,8 @@ import java.util.Map;
 import javax.servlet.http.HttpServletRequest;
 
 import netscape.security.x509.CertificateChain;
+import netscape.security.x509.CertificateIssuerName;
+import netscape.security.x509.CertificateSubjectName;
 import netscape.security.x509.CertificateVersion;
 import netscape.security.x509.X500Name;
 import netscape.security.x509.X509CRLImpl;
@@ -510,4 +512,7 @@ public interface ICertificateAuthority extends ISubsystem {
      * @return processed times for OCSP requests
      */
     public long getOCSPTotalData();
+
+    public CertificateIssuerName getIssuerObj();
+    public CertificateSubjectName getSubjectObj();
 }
diff --git a/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java b/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
index ca665ba..9e89e69 100644
--- a/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
+++ b/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
@@ -88,6 +88,7 @@ import com.netscape.certsrv.authority.IAuthority;
 import com.netscape.certsrv.base.EBaseException;
 import com.netscape.certsrv.base.EPropertyNotFound;
 import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.ca.ICertificateAuthority;
 import com.netscape.certsrv.logging.ILogger;
 import com.netscape.certsrv.profile.EDeferException;
 import com.netscape.certsrv.profile.EProfileException;
@@ -220,8 +221,19 @@ public abstract class EnrollProfile extends BasicProfile
                     new CertificateVersion(CertificateVersion.V3));
             info.set(X509CertInfo.SERIAL_NUMBER,
                     new CertificateSerialNumber(new BigInteger("0")));
-            info.set(X509CertInfo.ISSUER,
-                    new CertificateIssuerName(issuerName));
+            ICertificateAuthority authority =
+                    (ICertificateAuthority) getAuthority();
+            if (authority.getIssuerObj() != null) {
+                // this ensures the isserDN has the same encoding as the
+                // subjectDN of the CA signing cert
+                CMS.debug("EnrollProfile: setDefaultCertInfo: setting issuerDN using exact CA signing cert subjectDN encoding");
+                info.set(X509CertInfo.ISSUER,
+                        authority.getIssuerObj());
+            } else {
+                CMS.debug("EnrollProfile: setDefaultCertInfo: authority.getIssuerObj() is null, creating new CertificateIssuerName");
+                info.set(X509CertInfo.ISSUER,
+                        new CertificateIssuerName(issuerName));
+            }
             info.set(X509CertInfo.KEY,
                     new CertificateX509Key(X509Key.parse(new DerValue(dummykey))));
             info.set(X509CertInfo.SUBJECT,
diff --git a/base/server/cms/src/com/netscape/cms/servlet/csadmin/CertUtil.java b/base/server/cms/src/com/netscape/cms/servlet/csadmin/CertUtil.java
index ede632e..22f0929 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/CertUtil.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/CertUtil.java
@@ -31,6 +31,7 @@ import javax.servlet.http.HttpServletResponse;
 
 import netscape.security.pkcs.PKCS10;
 import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateIssuerName;
 import netscape.security.x509.X500Name;
 import netscape.security.x509.X509CertImpl;
 import netscape.security.x509.X509CertInfo;
@@ -390,6 +391,7 @@ public class CertUtil {
             cr = ca.getCertificateRepository();
             BigInteger serialNo = cr.getNextSerialNumber();
             if (type.equals("selfsign")) {
+                CMS.debug("Creating local certificate... selfsign cert");
                 CMS.debug("Creating local certificate... issuerdn=" + dn);
                 CMS.debug("Creating local certificate... dn=" + dn);
                 info = CryptoUtil.createX509CertInfo(x509key, serialNo, dn, dn, date, date, keyAlgorithm);
@@ -397,8 +399,18 @@ public class CertUtil {
                 String issuerdn = config.getString("preop.cert.signing.dn", "");
                 CMS.debug("Creating local certificate... issuerdn=" + issuerdn);
                 CMS.debug("Creating local certificate... dn=" + dn);
-
-                info = CryptoUtil.createX509CertInfo(x509key, serialNo, issuerdn, dn, date, date, keyAlgorithm);
+                if (ca.getIssuerObj() != null) {
+                    // this ensures the isserDN has the same encoding as the
+                    // subjectDN of the CA signing cert
+                    CMS.debug("Creating local certificate...  setting issuerDN using exact CA signing cert subjectDN encoding");
+                    CertificateIssuerName issuerdnObj =
+                        ca.getIssuerObj();
+
+                    info = CryptoUtil.createX509CertInfo(x509key, serialNo, issuerdnObj, dn, date, date, keyAlgorithm);
+                } else {
+                    CMS.debug("Creating local certificate... ca.getIssuerObj() is null, creating new CertificateIssuerName");
+                    info = CryptoUtil.createX509CertInfo(x509key, serialNo, issuerdn, dn, date, date, keyAlgorithm);
+                }
             }
             CMS.debug("Cert Template: " + info.toString());
 
diff --git a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
index 5e8e323..c87ebb1 100644
--- a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
+++ b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
@@ -1050,14 +1050,28 @@ public class CryptoUtil {
             CertificateException,
             InvalidKeyException,
             NoSuchAlgorithmException {
+            CertificateIssuerName issuernameObj =
+                    new CertificateIssuerName(new X500Name(issuername));
+            return createX509CertInfo(x509key, serialno, issuernameObj, subjname, notBefore, notAfter, alg);
+    }
+
+    public static X509CertInfo createX509CertInfo(X509Key x509key,
+            BigInteger serialno, CertificateIssuerName issuernameObj, String subjname,
+            Date notBefore, Date notAfter, String alg)
+            throws IOException,
+            CertificateException,
+            InvalidKeyException,
+            NoSuchAlgorithmException {
         X509CertInfo info = new X509CertInfo();
 
         info.set(X509CertInfo.VERSION, new
                 CertificateVersion(CertificateVersion.V3));
         info.set(X509CertInfo.SERIAL_NUMBER, new
                 CertificateSerialNumber(serialno));
-        info.set(X509CertInfo.ISSUER, new
-                CertificateIssuerName(new X500Name(issuername)));
+        if (issuernameObj != null) {
+            info.set(X509CertInfo.ISSUER,
+                    issuernameObj);
+        }
         info.set(X509CertInfo.SUBJECT, new
                 CertificateSubjectName(new X500Name(subjname)));
         info.set(X509CertInfo.VALIDITY, new
diff --git a/base/util/src/netscape/security/x509/X509CertImpl.java b/base/util/src/netscape/security/x509/X509CertImpl.java
index 111cd3b..a021ee1 100755
--- a/base/util/src/netscape/security/x509/X509CertImpl.java
+++ b/base/util/src/netscape/security/x509/X509CertImpl.java
@@ -725,6 +725,10 @@ public class X509CertImpl extends X509Certificate
         }
     }
 
+    public CertificateSubjectName getSubjectObj() {
+        return info.getSubjectObj();
+    }
+
     /**
      * Gets the issuer distinguished name from the certificate.
      *
@@ -743,6 +747,10 @@ public class X509CertImpl extends X509Certificate
         }
     }
 
+    public CertificateIssuerName getIssuerObj() {
+        return info.getIssuerObj();
+    }
+
     /**
      * Gets the notBefore date from the validity period of the certificate.
      *
diff --git a/base/util/src/netscape/security/x509/X509CertInfo.java b/base/util/src/netscape/security/x509/X509CertInfo.java
index 2ad17eb..29757ec 100644
--- a/base/util/src/netscape/security/x509/X509CertInfo.java
+++ b/base/util/src/netscape/security/x509/X509CertInfo.java
@@ -873,6 +873,10 @@ public class X509CertInfo implements CertAttrSet, Serializable {
         issuer = (CertificateIssuerName) val;
     }
 
+    public CertificateIssuerName getIssuerObj() {
+        return issuer;
+    }
+
     /**
      * Set the validity interval of the certificate.
      *
@@ -901,6 +905,10 @@ public class X509CertInfo implements CertAttrSet, Serializable {
         subject = (CertificateSubjectName) val;
     }
 
+    public CertificateSubjectName getSubjectObj() {
+        return subject;
+    }
+
     /**
      * Set the public key in the certificate.
      *
-- 
1.8.3.1

