Blame SOURCES/0003-Fixed-logic-for-setting-admin-cert-signing-algorithm.patch

f332ec
From fb9acc2c02ad35443eb8b6ac0f2279dddd9449ab Mon Sep 17 00:00:00 2001
f332ec
From: Ade Lee <alee@redhat.com>
f332ec
Date: Wed, 30 Oct 2013 15:50:28 -0400
f332ec
Subject: [PATCH 3/6] Fixed logic for setting admin cert signing algorithm
f332ec
f332ec
Should now be SHA256 by default.
f332ec
Bugzilla BZ 1024445
f332ec
---
f332ec
 base/ca/shared/conf/CS.cfg.in                      |   1 +
f332ec
 base/ca/shared/profiles/ca/caAdminCert.cfg         |   2 +-
f332ec
 .../com/netscape/cms/servlet/csadmin/CertUtil.java | 123 +++++++++++++--------
f332ec
 3 files changed, 81 insertions(+), 45 deletions(-)
f332ec
f332ec
diff --git a/base/ca/shared/conf/CS.cfg.in b/base/ca/shared/conf/CS.cfg.in
f332ec
index c1acc57..cca5209 100644
f332ec
--- a/base/ca/shared/conf/CS.cfg.in
f332ec
+++ b/base/ca/shared/conf/CS.cfg.in
f332ec
@@ -660,6 +660,7 @@ ca.notification.requestInQ.senderEmail=
f332ec
 ca.ocsp_signing.cacertnickname=ocspSigningCert cert-[PKI_INSTANCE_ID]
f332ec
 ca.ocsp_signing.defaultSigningAlgorithm=SHA256withRSA
f332ec
 ca.ocsp_signing.tokenname=internal
f332ec
+ca.profiles.defaultSigningAlgsAllowed==SHA256withRSA,SHA1withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA256withEC,SHA1withEC,SHA384withEC,SHA512withEC
f332ec
 ca.publish.createOwnDNEntry=false
f332ec
 ca.publish.queue.enable=true
f332ec
 ca.publish.queue.maxNumberOfThreads=3
f332ec
diff --git a/base/ca/shared/profiles/ca/caAdminCert.cfg b/base/ca/shared/profiles/ca/caAdminCert.cfg
f332ec
index c44079a..cd29703 100644
f332ec
--- a/base/ca/shared/profiles/ca/caAdminCert.cfg
f332ec
+++ b/base/ca/shared/profiles/ca/caAdminCert.cfg
f332ec
@@ -81,7 +81,7 @@ policyset.adminCertSet.7.default.params.exKeyUsageCritical=false
f332ec
 policyset.adminCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
f332ec
 policyset.adminCertSet.8.constraint.class_id=signingAlgConstraintImpl
f332ec
 policyset.adminCertSet.8.constraint.name=No Constraint
f332ec
-policyset.adminCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
f332ec
+policyset.adminCertSet.8.constraint.params.signingAlgsAllowed=SHA256withRSA,SHA1withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA256withEC,SHA1withEC,SHA384withEC,SHA512withEC
f332ec
 policyset.adminCertSet.8.default.class_id=signingAlgDefaultImpl
f332ec
 policyset.adminCertSet.8.default.name=Signing Alg
f332ec
 policyset.adminCertSet.8.default.params.signingAlg=-
f332ec
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java b/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java
f332ec
index 789c0aa..1936b2c 100644
f332ec
--- a/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java
f332ec
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java
f332ec
@@ -17,14 +17,15 @@
f332ec
 // --- END COPYRIGHT BLOCK ---
f332ec
 package com.netscape.cms.servlet.csadmin;
f332ec
 
f332ec
-import java.io.BufferedReader;
f332ec
 import java.io.ByteArrayInputStream;
f332ec
-import java.io.DataInputStream;
f332ec
 import java.io.FileInputStream;
f332ec
+import java.io.FileNotFoundException;
f332ec
 import java.io.IOException;
f332ec
-import java.io.InputStreamReader;
f332ec
 import java.math.BigInteger;
f332ec
 import java.util.Date;
f332ec
+import java.util.Iterator;
f332ec
+import java.util.Properties;
f332ec
+import java.util.Set;
f332ec
 
f332ec
 import javax.servlet.http.HttpServletResponse;
f332ec
 
f332ec
@@ -36,6 +37,8 @@ import netscape.security.x509.X509CertImpl;
f332ec
 import netscape.security.x509.X509CertInfo;
f332ec
 import netscape.security.x509.X509Key;
f332ec
 
f332ec
+import org.apache.commons.lang.ArrayUtils;
f332ec
+import org.apache.commons.lang.StringUtils;
f332ec
 import org.apache.velocity.context.Context;
f332ec
 import org.mozilla.jss.CryptoManager;
f332ec
 import org.mozilla.jss.crypto.PrivateKey;
f332ec
@@ -271,52 +274,84 @@ public class CertUtil {
f332ec
     }
f332ec
 
f332ec
     /**
f332ec
-     * reads from the admin cert profile caAdminCert.profile and takes the first
f332ec
-     * entry in the list of allowed algorithms. Users that wish a different algorithm
f332ec
-     * can specify it in the profile using default.params.signingAlg
f332ec
+     * reads from the admin cert profile caAdminCert.profile and determines the algorithm as follows:
f332ec
+     *
f332ec
+     * 1.  First gets list of allowed algorithms from profile (constraint.params.signingAlgsAllowed)
f332ec
+     *     If entry does not exist, uses entry "ca.profiles.defaultSigningAlgsAllowed" from CS.cfg
f332ec
+     *     If that entry does not exist, uses basic default
f332ec
+     *
f332ec
+     * 2.  Gets default.params.signingAlg from profile.
f332ec
+     *     If entry does not exist or equals "-", selects first algorithm in allowed algorithm list 
f332ec
+     *     that matches CA signing key type
f332ec
+     *     Otherwise returns entry if it matches signing CA key type.
f332ec
+     *
f332ec
+     * @throws EBaseException
f332ec
+     * @throws IOException
f332ec
+     * @throws FileNotFoundException
f332ec
      */
f332ec
 
f332ec
-    public static String getAdminProfileAlgorithm(IConfigStore config) {
f332ec
-        String algorithm = "SHA256withRSA";
f332ec
-        try {
f332ec
-            String caSigningKeyType = config.getString("preop.cert.signing.keytype", "rsa");
f332ec
-            String pfile = config.getString("profile.caAdminCert.config");
f332ec
-            FileInputStream fis = new FileInputStream(pfile);
f332ec
-            DataInputStream in = new DataInputStream(fis);
f332ec
-            BufferedReader br = new BufferedReader(new InputStreamReader(in));
f332ec
-
f332ec
-            String strLine;
f332ec
-            while ((strLine = br.readLine()) != null) {
f332ec
-                String marker2 = "default.params.signingAlg=";
f332ec
-                int indx = strLine.indexOf(marker2);
f332ec
-                if (indx != -1) {
f332ec
-                    String alg = strLine.substring(indx + marker2.length());
f332ec
-                    if ((alg.length() > 0) && (!alg.equals("-"))) {
f332ec
-                        algorithm = alg;
f332ec
-                        break;
f332ec
-                    }
f332ec
-                    ;
f332ec
-                }
f332ec
-                ;
f332ec
-
f332ec
-                String marker = "signingAlgsAllowed=";
f332ec
-                indx = strLine.indexOf(marker);
f332ec
-                if (indx != -1) {
f332ec
-                    String[] algs = strLine.substring(indx + marker.length()).split(",");
f332ec
-                    for (int i = 0; i < algs.length; i++) {
f332ec
-                        if ((caSigningKeyType.equals("rsa") && (algs[i].indexOf("RSA") != -1)) ||
f332ec
-                                (caSigningKeyType.equals("ecc") && (algs[i].indexOf("EC") != -1))) {
f332ec
-                            algorithm = algs[i];
f332ec
-                            break;
f332ec
-                        }
f332ec
-                    }
f332ec
+    public static String getAdminProfileAlgorithm(IConfigStore config) throws EBaseException, FileNotFoundException,
f332ec
+            IOException {
f332ec
+        String caSigningKeyType = config.getString("preop.cert.signing.keytype", "rsa");
f332ec
+        String pfile = config.getString("profile.caAdminCert.config");
f332ec
+        Properties props = new Properties();
f332ec
+        props.load(new FileInputStream(pfile));
f332ec
+
f332ec
+        Set<String> keys = props.stringPropertyNames();
f332ec
+        Iterator<String> iter = keys.iterator();
f332ec
+        String defaultAlg = null;
f332ec
+        String[] algsAllowed = null;
f332ec
+
f332ec
+        while (iter.hasNext()) {
f332ec
+            String key = iter.next();
f332ec
+            if (key.endsWith("default.params.signingAlg")) {
f332ec
+                defaultAlg = props.getProperty(key);
f332ec
+            }
f332ec
+            if (key.endsWith("constraint.params.signingAlgsAllowed")) {
f332ec
+                algsAllowed = StringUtils.split(props.getProperty(key), ",");
f332ec
+            }
f332ec
+        }
f332ec
+
f332ec
+        if (algsAllowed == null) { //algsAllowed not defined in profile, use a global setting
f332ec
+            algsAllowed = StringUtils.split(config.getString("ca.profiles.defaultSigningAlgsAllowed",
f332ec
+                    "SHA256withRSA,SHA256withEC,SHA1withDSA"), ",");
f332ec
+        }
f332ec
+
f332ec
+        if (ArrayUtils.isEmpty(algsAllowed)) {
f332ec
+            throw new EBaseException("No allowed signing algorithms defined.");
f332ec
+        }
f332ec
+
f332ec
+        if (StringUtils.isNotEmpty(defaultAlg) && !defaultAlg.equals("-")) {
f332ec
+            // check if the defined default algorithm is valid
f332ec
+            if (! isAlgorithmValid(caSigningKeyType, defaultAlg)) {
f332ec
+                throw new EBaseException("Administrator cert cannot be signed by specfied algorithm." +
f332ec
+                                         "Algorithm incompatible with signing key");
f332ec
+            }
f332ec
+
f332ec
+            for (String alg : algsAllowed) {
f332ec
+                if (defaultAlg.trim().equals(alg.trim())) {
f332ec
+                    return defaultAlg;
f332ec
                 }
f332ec
             }
f332ec
-            in.close();
f332ec
-        } catch (Exception e) {
f332ec
-            CMS.debug("getAdminProfleAlgorithm: exception: " + e);
f332ec
+            throw new EBaseException(
f332ec
+                    "Administrator Certificate cannot be signed by the specified algorithm " +
f332ec
+                    "as it is not one of the allowed signing algorithms.  Check the admin cert profile.");
f332ec
         }
f332ec
-        return algorithm;
f332ec
+
f332ec
+        // no algorithm specified.  Pick the first allowed algorithm.
f332ec
+        for (String alg : algsAllowed) {
f332ec
+            if (isAlgorithmValid(caSigningKeyType, alg)) return alg;
f332ec
+        }
f332ec
+
f332ec
+        throw new EBaseException(
f332ec
+                "Admin certificate cannot be signed by any of the specified possible algorithms." +
f332ec
+                "Algorithm is incompatible with the CA signing key type" );
f332ec
+    }
f332ec
+
f332ec
+    private static boolean isAlgorithmValid(String signingKeyType, String algorithm) {
f332ec
+       return ((signingKeyType.equals("rsa") && algorithm.contains("RSA")) ||
f332ec
+               (signingKeyType.equals("ecc") && algorithm.contains("EC"))  ||
f332ec
+               (signingKeyType.equals("dsa") && algorithm.contains("DSA")));
f332ec
     }
f332ec
 
f332ec
     public static X509CertImpl createLocalCert(IConfigStore config, X509Key x509key,
f332ec
-- 
f332ec
1.8.3.1
f332ec