b80204
From c95cff5899e2975b16db61b811b626742e5e7114 Mon Sep 17 00:00:00 2001
b80204
From: Christina Fu <cfu@redhat.com>
b80204
Date: Mon, 1 May 2017 17:48:33 -0700
b80204
Subject: [PATCH 01/10] Bug 1447145 - CMC: cmc.popLinkWitnessRequired=false
b80204
 would cause error This patch would fix the issue.  It also adds the
b80204
 CMCUserSignedAuth authentication instance that was missed in the CS.cfg
b80204
b80204
---
b80204
 base/ca/shared/conf/CS.cfg                                        | 1 +
b80204
 .../cms/src/com/netscape/cms/profile/common/EnrollProfile.java    | 8 +++-----
b80204
 2 files changed, 4 insertions(+), 5 deletions(-)
b80204
b80204
diff --git a/base/ca/shared/conf/CS.cfg b/base/ca/shared/conf/CS.cfg
b80204
index 078abee..3eb5b1b 100644
b80204
--- a/base/ca/shared/conf/CS.cfg
b80204
+++ b/base/ca/shared/conf/CS.cfg
b80204
@@ -180,6 +180,7 @@ auths.impl.SessionAuthentication.class=com.netscape.cms.authentication.SessionAu
b80204
 auths.instance.TokenAuth.pluginName=TokenAuth
b80204
 auths.instance.AgentCertAuth.agentGroup=Certificate Manager Agents
b80204
 auths.instance.AgentCertAuth.pluginName=AgentCertAuth
b80204
+auths.instance.CMCUserSignedAuth.pluginName=CMCUserSignedAuth
b80204
 auths.instance.raCertAuth.agentGroup=Registration Manager Agents
b80204
 auths.instance.raCertAuth.pluginName=AgentCertAuth
b80204
 auths.instance.flatFileAuth.pluginName=FlatFileAuth
b80204
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
b80204
index 57f07d1..7d52fc8 100644
b80204
--- a/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
b80204
+++ b/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
b80204
@@ -885,10 +885,7 @@ public abstract class EnrollProfile extends BasicProfile
b80204
             }
b80204
 
b80204
             int nummsgs = reqSeq.size();
b80204
-            if (!popLinkWitnessRequired) {
b80204
-                CMS.debug(method + "popLinkWitnessRequired false, skip check");
b80204
-            } else if (nummsgs > 0) {
b80204
-                CMS.debug(method + "cmc.popLinkWitnessRequired is true");
b80204
+            if (nummsgs > 0) {
b80204
                 CMS.debug(method + "nummsgs =" + nummsgs);
b80204
                 msgs = new TaggedRequest[reqSeq.size()];
b80204
                 SEQUENCE bpids = new SEQUENCE();
b80204
@@ -896,7 +893,8 @@ public abstract class EnrollProfile extends BasicProfile
b80204
                 boolean valid = true;
b80204
                 for (int i = 0; i < nummsgs; i++) {
b80204
                     msgs[i] = (TaggedRequest) reqSeq.elementAt(i);
b80204
-                    if (!context.containsKey("POPLinkWitnessV2") &&
b80204
+                    if (popLinkWitnessRequired &&
b80204
+                            !context.containsKey("POPLinkWitnessV2") &&
b80204
                             !context.containsKey("POPLinkWitness")) {
b80204
                         CMS.debug(method + "popLinkWitness(V2) required");
b80204
                         if (randomSeed == null) {
b80204
-- 
b80204
1.8.3.1
b80204
b80204
b80204
From 220e35d2b5610cb051831b990451b3b3ff53604e Mon Sep 17 00:00:00 2001
b80204
From: Fraser Tweedale <ftweedal@redhat.com>
b80204
Date: Tue, 2 May 2017 21:44:36 +1000
b80204
Subject: [PATCH 02/10] CAInfoService: retrieve info from KRA
b80204
b80204
The CAInfoService returns CA configuration info, including
b80204
KRA-related values the CA clients may need to know (e.g. for
b80204
generating a CRMF cert request that will cause keys to be archived
b80204
in KRA).  Currently that information is statically configured and
b80204
does not respect the actual configuration of the KRA.
b80204
b80204
Update the service to retrieve info from the KRA, which is queried
b80204
according to the KRA Connector configuration.  After the KRA has
b80204
been successfully contacted, the recorded KRA-related settings are
b80204
regarded as authoritative.
b80204
b80204
The KRA is contacted ONLY if the current info is NOT authoritative,
b80204
otherwise the currently recorded values are used.  This means that
b80204
any change to relevant KRA configuration (which should occur seldom
b80204
if ever) necessitates restart of the CA subsystem.
b80204
b80204
If this is unsuccessful (e.g. if the KRA is down or the connector is
b80204
misconfigured) we use the default values, which may be incorrect.
b80204
b80204
Fixes: https://pagure.io/dogtagpki/issue/2665
b80204
Change-Id: I30a37c42ef9327471e8cce8a171f79f388fec746
b80204
---
b80204
 .../org/dogtagpki/server/rest/CAInfoService.java   | 143 ++++++++++++++++++---
b80204
 1 file changed, 126 insertions(+), 17 deletions(-)
b80204
b80204
diff --git a/base/server/cms/src/org/dogtagpki/server/rest/CAInfoService.java b/base/server/cms/src/org/dogtagpki/server/rest/CAInfoService.java
b80204
index f4724a6..398f499 100644
b80204
--- a/base/server/cms/src/org/dogtagpki/server/rest/CAInfoService.java
b80204
+++ b/base/server/cms/src/org/dogtagpki/server/rest/CAInfoService.java
b80204
@@ -18,26 +18,63 @@
b80204
 
b80204
 package org.dogtagpki.server.rest;
b80204
 
b80204
+import java.net.MalformedURLException;
b80204
+import java.net.URISyntaxException;
b80204
+
b80204
 import javax.servlet.http.HttpSession;
b80204
 import javax.ws.rs.core.Response;
b80204
 
b80204
 import org.dogtagpki.common.CAInfo;
b80204
 import org.dogtagpki.common.CAInfoResource;
b80204
+import org.dogtagpki.common.KRAInfo;
b80204
+import org.dogtagpki.common.KRAInfoClient;
b80204
 import org.slf4j.Logger;
b80204
 import org.slf4j.LoggerFactory;
b80204
 
b80204
 import com.netscape.certsrv.apps.CMS;
b80204
 import com.netscape.certsrv.base.EBaseException;
b80204
 import com.netscape.certsrv.base.IConfigStore;
b80204
+import com.netscape.certsrv.base.PKIException;
b80204
+import com.netscape.certsrv.client.ClientConfig;
b80204
+import com.netscape.certsrv.client.PKIClient;
b80204
+import com.netscape.certsrv.system.KRAConnectorInfo;
b80204
+import com.netscape.cms.servlet.admin.KRAConnectorProcessor;
b80204
 import com.netscape.cms.servlet.base.PKIService;
b80204
 
b80204
 /**
b80204
  * @author Ade Lee
b80204
+ *
b80204
+ * This class returns CA info, including KRA-related values the CA
b80204
+ * clients may need to know (e.g. for generating a CRMF cert request
b80204
+ * that will cause keys to be archived in KRA).
b80204
+ *
b80204
+ * The KRA-related info is read from the KRAInfoService, which is
b80204
+ * queried according to the KRA Connector configuration.  After
b80204
+ * the KRAInfoService has been successfully contacted, the recorded
b80204
+ * KRA-related settings are regarded as authoritative.
b80204
+ *
b80204
+ * The KRA is contacted ONLY if the current info is NOT
b80204
+ * authoritative, otherwise the currently recorded values are used.
b80204
+ * This means that any change to relevant KRA configuration (which
b80204
+ * should occur seldom if ever) necessitates restart of the CA
b80204
+ * subsystem.
b80204
+ *
b80204
+ * If this is unsuccessful (e.g. if the KRA is down or the
b80204
+ * connector is misconfigured) we use the default values, which
b80204
+ * may be incorrect.
b80204
  */
b80204
 public class CAInfoService extends PKIService implements CAInfoResource {
b80204
 
b80204
     private static Logger logger = LoggerFactory.getLogger(InfoService.class);
b80204
 
b80204
+    // is the current KRA-related info authoritative?
b80204
+    private static boolean kraInfoAuthoritative = false;
b80204
+
b80204
+    // KRA-related fields (the initial values are only used if we
b80204
+    // did not yet receive authoritative info from KRA)
b80204
+    private static String archivalMechanism = KRAInfoService.KEYWRAP_MECHANISM;
b80204
+    private static String wrappingKeySet = "0";
b80204
+
b80204
     @Override
b80204
     public Response getInfo() throws Exception {
b80204
 
b80204
@@ -45,30 +82,102 @@ public class CAInfoService extends PKIService implements CAInfoResource {
b80204
         logger.debug("CAInfoService.getInfo(): session: " + session.getId());
b80204
 
b80204
         CAInfo info = new CAInfo();
b80204
-        String archivalMechanism = getArchivalMechanism();
b80204
-
b80204
-        if (archivalMechanism != null)
b80204
-            info.setArchivalMechanism(getArchivalMechanism());
b80204
 
b80204
-        info.setWrappingKeySet(getWrappingKeySet());
b80204
+        addKRAInfo(info);
b80204
 
b80204
         return createOKResponse(info);
b80204
     }
b80204
 
b80204
-    String getArchivalMechanism() throws EBaseException {
b80204
-        IConfigStore cs = CMS.getConfigStore();
b80204
-        boolean kra_present = cs.getBoolean("ca.connector.KRA.enable", false);
b80204
-        if (!kra_present) return null;
b80204
-
b80204
-        boolean encrypt_archival = cs.getBoolean("kra.allowEncDecrypt.archival", false);
b80204
-        return encrypt_archival ? KRAInfoService.ENCRYPT_MECHANISM : KRAInfoService.KEYWRAP_MECHANISM;
b80204
+    /**
b80204
+     * Add KRA fields if KRA is configured, querying the KRA
b80204
+     * if necessary.
b80204
+     *
b80204
+     * Apart from reading 'headers', this method doesn't access
b80204
+     * any instance data.
b80204
+     */
b80204
+    private void addKRAInfo(CAInfo info) {
b80204
+        KRAConnectorInfo connInfo = null;
b80204
+        try {
b80204
+            KRAConnectorProcessor processor =
b80204
+                new KRAConnectorProcessor(getLocale(headers));
b80204
+            connInfo = processor.getConnectorInfo();
b80204
+        } catch (Throwable e) {
b80204
+            // connInfo remains as null
b80204
+        }
b80204
+        boolean kraEnabled =
b80204
+            connInfo != null
b80204
+            && "true".equalsIgnoreCase(connInfo.getEnable());
b80204
+
b80204
+        if (kraEnabled) {
b80204
+            if (!kraInfoAuthoritative) {
b80204
+                // KRA is enabled but we are yet to successfully
b80204
+                // query the KRA-related info.  Do it now.
b80204
+                queryKRAInfo(connInfo);
b80204
+            }
b80204
+
b80204
+            info.setArchivalMechanism(archivalMechanism);
b80204
+            info.setWrappingKeySet(wrappingKeySet);
b80204
+        }
b80204
     }
b80204
 
b80204
-    String getWrappingKeySet() throws EBaseException {
b80204
-        IConfigStore cs = CMS.getConfigStore();
b80204
-        boolean kra_present = cs.getBoolean("ca.connector.KRA.enable", false);
b80204
-        if (!kra_present) return null;
b80204
+    private static void queryKRAInfo(KRAConnectorInfo connInfo) {
b80204
+        try {
b80204
+            KRAInfo kraInfo = getKRAInfoClient(connInfo).getInfo();
b80204
+
b80204
+            archivalMechanism = kraInfo.getArchivalMechanism();
b80204
+
b80204
+            // request succeeded; the KRA is 10.4 or higher,
b80204
+            // therefore supports key set v1
b80204
+            wrappingKeySet = "1";
b80204
+
b80204
+            // mark info as authoritative
b80204
+            kraInfoAuthoritative = true;
b80204
+        } catch (PKIException e) {
b80204
+            if (e.getCode() == 404) {
b80204
+                // The KRAInfoResource was added in 10.4,
b80204
+                // so we are talking to a pre-10.4 KRA
b80204
+
b80204
+                // pre-10.4 only supports key set v0
b80204
+                wrappingKeySet = "0";
b80204
+
b80204
+                // pre-10.4 KRA does not advertise the archival
b80204
+                // mechanism; look for the old knob in CA's config
b80204
+                // or fall back to the default
b80204
+                IConfigStore cs = CMS.getConfigStore();
b80204
+                boolean encrypt_archival;
b80204
+                try {
b80204
+                    encrypt_archival = cs.getBoolean(
b80204
+                        "kra.allowEncDecrypt.archival", false);
b80204
+                } catch (EBaseException e1) {
b80204
+                    encrypt_archival = false;
b80204
+                }
b80204
+                archivalMechanism = encrypt_archival
b80204
+                    ? KRAInfoService.ENCRYPT_MECHANISM
b80204
+                    : KRAInfoService.KEYWRAP_MECHANISM;
b80204
+
b80204
+                // mark info as authoritative
b80204
+                kraInfoAuthoritative = true;
b80204
+            } else {
b80204
+                CMS.debug("Failed to retrieve archive wrapping information from the CA: " + e);
b80204
+                CMS.debug(e);
b80204
+            }
b80204
+        } catch (Throwable e) {
b80204
+            CMS.debug("Failed to retrieve archive wrapping information from the CA: " + e);
b80204
+            CMS.debug(e);
b80204
+        }
b80204
+    }
b80204
 
b80204
-        return cs.getString("kra.wrappingKeySet", "1");
b80204
+    /**
b80204
+     * Construct KRAInfoClient given KRAConnectorInfo
b80204
+     */
b80204
+    private static KRAInfoClient getKRAInfoClient(KRAConnectorInfo connInfo)
b80204
+            throws MalformedURLException, URISyntaxException, EBaseException {
b80204
+        ClientConfig config = new ClientConfig();
b80204
+        int port = Integer.parseInt(connInfo.getPort());
b80204
+        config.setServerURL("https", connInfo.getHost(), port);
b80204
+        config.setCertDatabase(
b80204
+            CMS.getConfigStore().getString("instanceRoot") + "/alias");
b80204
+        return new KRAInfoClient(new PKIClient(config), "kra");
b80204
     }
b80204
+
b80204
 }
b80204
-- 
b80204
1.8.3.1
b80204
b80204
b80204
From c64d6331d52dcf07108226c5dff26bd8b6c41e70 Mon Sep 17 00:00:00 2001
b80204
From: Christian Heimes <cheimes@redhat.com>
b80204
Date: Thu, 4 May 2017 10:36:49 +0200
b80204
Subject: [PATCH 03/10] pki.authority: Don't send header as POST body
b80204
b80204
pki.authority was mistakenly sending headers as POST body instead of
b80204
sending an empty POST body with right headers.
b80204
b80204
Change-Id: I6a5089e55233cf72f4d8e79832150e7c45f0fdae
b80204
Signed-off-by: Christian Heimes <cheimes@redhat.com>
b80204
---
b80204
 base/common/python/pki/authority.py | 14 +++++++-------
b80204
 1 file changed, 7 insertions(+), 7 deletions(-)
b80204
b80204
diff --git a/base/common/python/pki/authority.py b/base/common/python/pki/authority.py
b80204
index 9fa459c..0d83a4b 100644
b80204
--- a/base/common/python/pki/authority.py
b80204
+++ b/base/common/python/pki/authority.py
b80204
@@ -140,7 +140,7 @@ class AuthorityClient(object):
b80204
         url = self.ca_url + '/' + str(aid)
b80204
         headers = {'Content-type': 'application/json',
b80204
                    'Accept': 'application/json'}
b80204
-        r = self.connection.get(url, headers)
b80204
+        r = self.connection.get(url, headers=headers)
b80204
         return AuthorityData.from_json(r.json())
b80204
 
b80204
     @pki.handle_exceptions()
b80204
@@ -167,7 +167,7 @@ class AuthorityClient(object):
b80204
             raise ValueError(
b80204
                 "Invalid format passed in - PEM or DER expected.")
b80204
 
b80204
-        r = self.connection.get(url, headers)
b80204
+        r = self.connection.get(url, headers=headers)
b80204
         return r.text
b80204
 
b80204
     @pki.handle_exceptions()
b80204
@@ -189,7 +189,7 @@ class AuthorityClient(object):
b80204
         elif output_format == "PKCS7":
b80204
             headers['Accept'] = "application/pkcs7-mime"
b80204
 
b80204
-        r = self.connection.get(url, headers)
b80204
+        r = self.connection.get(url, headers=headers)
b80204
         return r.text
b80204
 
b80204
     @pki.handle_exceptions()
b80204
@@ -238,7 +238,7 @@ class AuthorityClient(object):
b80204
         response = self.connection.post(
b80204
             self.ca_url,
b80204
             create_request,
b80204
-            headers)
b80204
+            headers=headers)
b80204
 
b80204
         new_ca = AuthorityData.from_json(response.json())
b80204
         return new_ca
b80204
@@ -257,7 +257,7 @@ class AuthorityClient(object):
b80204
         headers = {'Content-type': 'application/json',
b80204
                    'Accept': 'application/json'}
b80204
 
b80204
-        self.connection.post(url, headers)
b80204
+        self.connection.post(url, None, headers=headers)
b80204
 
b80204
     @pki.handle_exceptions()
b80204
     def disable_ca(self, aid):
b80204
@@ -272,7 +272,7 @@ class AuthorityClient(object):
b80204
         headers = {'Content-type': 'application/json',
b80204
                    'Accept': 'application/json'}
b80204
 
b80204
-        self.connection.post(url, headers)
b80204
+        self.connection.post(url, None, headers=headers)
b80204
 
b80204
     @pki.handle_exceptions()
b80204
     def delete_ca(self, aid):
b80204
@@ -287,7 +287,7 @@ class AuthorityClient(object):
b80204
         headers = {'Content-type': 'application/json',
b80204
                    'Accept': 'application/json'}
b80204
 
b80204
-        self.connection.delete(url, headers)
b80204
+        self.connection.delete(url, headers=headers)
b80204
 
b80204
 
b80204
 encoder.NOTYPES['AuthorityData'] = AuthorityData
b80204
-- 
b80204
1.8.3.1
b80204
b80204
b80204
From 62a78bfa227b5e75a7cb931d7e65e824f5fe01ec Mon Sep 17 00:00:00 2001
b80204
From: Fraser Tweedale <ftweedal@redhat.com>
b80204
Date: Fri, 5 May 2017 19:54:15 +1000
b80204
Subject: [PATCH 04/10] Fix PKCS #12 import during clone installation
b80204
b80204
PKCS #12 export was updated to use AES / PBES2 encryption for the
b80204
key bags, but an import code path used when spawning a clone was
b80204
missed, and now fails (because it doesn't grok PBES2).
b80204
b80204
Update it to use CryptoStore.importEncryptedPrivateKeyInfo()
b80204
instead, fixing the problem.
b80204
b80204
Fixes: https://pagure.io/dogtagpki/issue/2677
b80204
Change-Id: I11f26ae8a4811f27690541f2c70b3a2adb6264e9
b80204
---
b80204
 .../cms/servlet/csadmin/ConfigurationUtils.java    | 32 +++++++---------------
b80204
 1 file changed, 10 insertions(+), 22 deletions(-)
b80204
b80204
diff --git a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
b80204
index ee1984b..07c64af 100644
b80204
--- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
b80204
+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
b80204
@@ -886,9 +886,7 @@ public class ConfigurationUtils {
b80204
                 if (oid.equals(SafeBag.PKCS8_SHROUDED_KEY_BAG)) {
b80204
 
b80204
                     CMS.debug("  - Bag #" + j + ": key");
b80204
-                    EncryptedPrivateKeyInfo privkeyinfo =
b80204
-                            (EncryptedPrivateKeyInfo) bag.getInterpretedBagContent();
b80204
-                    PrivateKeyInfo pkeyinfo = privkeyinfo.decrypt(password, new PasswordConverter());
b80204
+                    byte[] epki = bag.getBagContent().getEncoded();
b80204
 
b80204
                     SET bagAttrs = bag.getBagAttributes();
b80204
                     String subjectDN = null;
b80204
@@ -910,9 +908,10 @@ public class ConfigurationUtils {
b80204
                         }
b80204
                     }
b80204
 
b80204
-                    // pkeyinfo_v stores private key (PrivateKeyInfo) and subject DN (String)
b80204
+                    // pkeyinfo_v stores EncryptedPrivateKeyInfo
b80204
+                    // (byte[]) and subject DN (String)
b80204
                     Vector<Object> pkeyinfo_v = new Vector<Object>();
b80204
-                    pkeyinfo_v.addElement(pkeyinfo);
b80204
+                    pkeyinfo_v.addElement(epki);
b80204
                     if (subjectDN != null)
b80204
                         pkeyinfo_v.addElement(subjectDN);
b80204
 
b80204
@@ -971,7 +970,7 @@ public class ConfigurationUtils {
b80204
             }
b80204
         }
b80204
 
b80204
-        importKeyCert(pkeyinfo_collection, cert_collection);
b80204
+        importKeyCert(password, pkeyinfo_collection, cert_collection);
b80204
     }
b80204
 
b80204
     public static void verifySystemCertificates() throws Exception {
b80204
@@ -1012,6 +1011,7 @@ public class ConfigurationUtils {
b80204
     }
b80204
 
b80204
     public static void importKeyCert(
b80204
+            Password password,
b80204
             Vector<Vector<Object>> pkeyinfo_collection,
b80204
             Vector<Vector<Object>> cert_collection
b80204
             ) throws Exception {
b80204
@@ -1028,7 +1028,7 @@ public class ConfigurationUtils {
b80204
         CMS.debug("Importing new keys:");
b80204
         for (int i = 0; i < pkeyinfo_collection.size(); i++) {
b80204
             Vector<Object> pkeyinfo_v = pkeyinfo_collection.elementAt(i);
b80204
-            PrivateKeyInfo pkeyinfo = (PrivateKeyInfo) pkeyinfo_v.elementAt(0);
b80204
+            byte[] epki = (byte[]) pkeyinfo_v.elementAt(0);
b80204
             String nickname = (String) pkeyinfo_v.elementAt(1);
b80204
             CMS.debug("- Key: " + nickname);
b80204
 
b80204
@@ -1037,11 +1037,6 @@ public class ConfigurationUtils {
b80204
                 continue;
b80204
             }
b80204
 
b80204
-            // encode private key
b80204
-            ByteArrayOutputStream bos = new ByteArrayOutputStream();
b80204
-            pkeyinfo.encode(bos);
b80204
-            byte[] pkey = bos.toByteArray();
b80204
-
b80204
             CMS.debug("  Find cert with subject DN " + nickname);
b80204
             // TODO: use better mechanism to find the cert
b80204
             byte[] x509cert = getX509Cert(nickname, cert_collection);
b80204
@@ -1063,16 +1058,9 @@ public class ConfigurationUtils {
b80204
                 // this is OK
b80204
             }
b80204
 
b80204
-            // encrypt private key
b80204
-            SymmetricKey sk = CryptoUtil.generateKey(token, KeyGenAlgorithm.DES3, 0, null, true);
b80204
-            byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
b80204
-            IVParameterSpec param = new IVParameterSpec(iv);
b80204
-            byte[] encpkey = CryptoUtil.encryptUsingSymmetricKey(token, sk, pkey, EncryptionAlgorithm.DES3_CBC_PAD, param);
b80204
-
b80204
-            // unwrap private key to load into database
b80204
-            KeyWrapper wrapper = token.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD);
b80204
-            wrapper.initUnwrap(sk, param);
b80204
-            wrapper.unwrapPrivate(encpkey, getPrivateKeyType(publicKey), publicKey);
b80204
+            // import private key into database
b80204
+            store.importEncryptedPrivateKeyInfo(
b80204
+                new PasswordConverter(), password, nickname, publicKey, epki);
b80204
         }
b80204
 
b80204
         CMS.debug("Importing new certificates:");
b80204
-- 
b80204
1.8.3.1
b80204
b80204
b80204
From 3fb95590cdf0e45418fa0be7a020691567ef152a Mon Sep 17 00:00:00 2001
b80204
From: Fraser Tweedale <ftweedal@redhat.com>
b80204
Date: Fri, 5 May 2017 20:13:07 +1000
b80204
Subject: [PATCH 05/10] Delete unused methods
b80204
b80204
Change-Id: I81d3aa98a05208b2f5b1be3700c2e0759b387203
b80204
---
b80204
 .../cms/servlet/csadmin/ConfigurationUtils.java    | 103 ---------------------
b80204
 1 file changed, 103 deletions(-)
b80204
b80204
diff --git a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
b80204
index 07c64af..c9a375f 100644
b80204
--- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
b80204
+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
b80204
@@ -1203,13 +1203,6 @@ public class ConfigurationUtils {
b80204
         return null;
b80204
     }
b80204
 
b80204
-    public static org.mozilla.jss.crypto.PrivateKey.Type getPrivateKeyType(PublicKey pubkey) {
b80204
-        if (pubkey.getAlgorithm().equals("EC")) {
b80204
-            return org.mozilla.jss.crypto.PrivateKey.Type.EC;
b80204
-        }
b80204
-        return org.mozilla.jss.crypto.PrivateKey.Type.RSA;
b80204
-    }
b80204
-
b80204
     public static boolean isCASigningCert(String name) throws EBaseException {
b80204
         IConfigStore cs = CMS.getConfigStore();
b80204
         try {
b80204
@@ -3495,102 +3488,6 @@ public class ConfigurationUtils {
b80204
         }
b80204
     }
b80204
 
b80204
-    public static void addKeyBag(PrivateKey pkey, X509Certificate x509cert,
b80204
-            Password pass, byte[] localKeyId, SEQUENCE safeContents)
b80204
-            throws NoSuchAlgorithmException, InvalidBERException, InvalidKeyException,
b80204
-            InvalidAlgorithmParameterException, NotInitializedException, TokenException, IllegalStateException,
b80204
-            IllegalBlockSizeException, BadPaddingException, CharConversionException {
b80204
-
b80204
-        PasswordConverter passConverter = new PasswordConverter();
b80204
-
b80204
-        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
b80204
-        byte salt[] = random.generateSeed(4); // 4 bytes salt
b80204
-        byte[] priData = getEncodedKey(pkey);
b80204
-
b80204
-        PrivateKeyInfo pki = (PrivateKeyInfo)
b80204
-                ASN1Util.decode(PrivateKeyInfo.getTemplate(), priData);
b80204
-        ASN1Value key = EncryptedPrivateKeyInfo.createPBE(
b80204
-                PBEAlgorithm.PBE_SHA1_DES3_CBC,
b80204
-                pass, salt, 1, passConverter, pki);
b80204
-        SET keyAttrs = createBagAttrs(
b80204
-                x509cert.getSubjectDN().toString(), localKeyId);
b80204
-        SafeBag keyBag = new SafeBag(SafeBag.PKCS8_SHROUDED_KEY_BAG,
b80204
-                key, keyAttrs);
b80204
-        safeContents.addElement(keyBag);
b80204
-
b80204
-    }
b80204
-
b80204
-    public static byte[] addCertBag(X509Certificate x509cert, String nickname,
b80204
-            SEQUENCE safeContents) throws CertificateEncodingException, NoSuchAlgorithmException,
b80204
-            CharConversionException {
b80204
-        byte[] localKeyId = null;
b80204
-
b80204
-        ASN1Value cert = new OCTET_STRING(x509cert.getEncoded());
b80204
-        localKeyId = createLocalKeyId(x509cert);
b80204
-        SET certAttrs = null;
b80204
-        if (nickname != null)
b80204
-            certAttrs = createBagAttrs(nickname, localKeyId);
b80204
-        SafeBag certBag = new SafeBag(SafeBag.CERT_BAG,
b80204
-                new CertBag(CertBag.X509_CERT_TYPE, cert), certAttrs);
b80204
-        safeContents.addElement(certBag);
b80204
-
b80204
-        return localKeyId;
b80204
-    }
b80204
-
b80204
-    public static byte[] getEncodedKey(PrivateKey pkey) throws NotInitializedException, NoSuchAlgorithmException,
b80204
-            TokenException, IllegalStateException, CharConversionException, InvalidKeyException,
b80204
-            InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
b80204
-        CryptoManager cm = CryptoManager.getInstance();
b80204
-        CryptoToken token = cm.getInternalKeyStorageToken();
b80204
-        KeyGenerator kg = token.getKeyGenerator(KeyGenAlgorithm.DES3);
b80204
-        SymmetricKey sk = kg.generate();
b80204
-        KeyWrapper wrapper = token.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD);
b80204
-        byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
b80204
-        IVParameterSpec param = new IVParameterSpec(iv);
b80204
-        wrapper.initWrap(sk, param);
b80204
-        byte[] enckey = wrapper.wrap(pkey);
b80204
-        Cipher c = token.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD);
b80204
-        c.initDecrypt(sk, param);
b80204
-        byte[] recovered = c.doFinal(enckey);
b80204
-        return recovered;
b80204
-    }
b80204
-
b80204
-    public static byte[] createLocalKeyId(X509Certificate cert)
b80204
-            throws NoSuchAlgorithmException, CertificateEncodingException {
b80204
-
b80204
-        // SHA1 hash of the X509Cert der encoding
b80204
-        byte certDer[] = cert.getEncoded();
b80204
-
b80204
-        MessageDigest md = MessageDigest.getInstance("SHA");
b80204
-
b80204
-        md.update(certDer);
b80204
-        return md.digest();
b80204
-
b80204
-    }
b80204
-
b80204
-    public static SET createBagAttrs(String nickName, byte localKeyId[]) throws CharConversionException {
b80204
-
b80204
-        SET attrs = new SET();
b80204
-        SEQUENCE nickNameAttr = new SEQUENCE();
b80204
-
b80204
-        nickNameAttr.addElement(SafeBag.FRIENDLY_NAME);
b80204
-        SET nickNameSet = new SET();
b80204
-
b80204
-        nickNameSet.addElement(new BMPString(nickName));
b80204
-        nickNameAttr.addElement(nickNameSet);
b80204
-        attrs.addElement(nickNameAttr);
b80204
-        SEQUENCE localKeyAttr = new SEQUENCE();
b80204
-
b80204
-        localKeyAttr.addElement(SafeBag.LOCAL_KEY_ID);
b80204
-        SET localKeySet = new SET();
b80204
-
b80204
-        localKeySet.addElement(new OCTET_STRING(localKeyId));
b80204
-        localKeyAttr.addElement(localKeySet);
b80204
-        attrs.addElement(localKeyAttr);
b80204
-        return attrs;
b80204
-
b80204
-    }
b80204
-
b80204
     public static void createAdminCertificate(String certRequest, String certRequestType, String subject)
b80204
             throws Exception {
b80204
         IConfigStore cs = CMS.getConfigStore();
b80204
-- 
b80204
1.8.3.1
b80204
b80204
b80204
From f26b3aaee1cf36941f387b464b937ffee1403048 Mon Sep 17 00:00:00 2001
b80204
From: Jack Magne <jmagne@dhcp-16-206.sjc.redhat.com>
b80204
Date: Fri, 5 May 2017 11:44:17 -0700
b80204
Subject: [PATCH 06/10] Non server keygen issue in SCP03.
b80204
b80204
Ticket 1663 Add SCP03 support: https://pagure.io/dogtagpki/issue/1663
b80204
b80204
We discovered a minor issue when trying to log values that don't exist when performing the non server side keygen case. For instance , we don't need to generate a kek session key in this case, and we were trying to print info about it to the logs. This fix allows this case to work without issue.
b80204
---
b80204
 .../server/tps/channel/SecureChannel.java          |  4 +-
b80204
 .../server/tps/processor/TPSProcessor.java         | 51 +++++++++++++++-------
b80204
 2 files changed, 37 insertions(+), 18 deletions(-)
b80204
b80204
diff --git a/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java b/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java
b80204
index fc5472c..5e5646b 100644
b80204
--- a/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java
b80204
+++ b/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java
b80204
@@ -148,8 +148,8 @@ public class SecureChannel {
b80204
 
b80204
         CMS.debug("SecureChannel.SecureChannel: For SCP03. :  ");
b80204
 
b80204
-        CMS.debug("kekDesKey: " + kekDesKey.toHexString());
b80204
-        CMS.debug("keyCheck: " + keyCheck.toHexString());
b80204
+        if (keyCheck != null)
b80204
+            CMS.debug("keyCheck: " + keyCheck.toHexString());
b80204
 
b80204
         this.platProtInfo = platformInfo;
b80204
         this.processor = processor;
b80204
diff --git a/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java b/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java
b80204
index 0cfac59..0f96915 100644
b80204
--- a/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java
b80204
+++ b/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java
b80204
@@ -33,6 +33,8 @@ import java.util.List;
b80204
 import java.util.Map;
b80204
 import java.util.Set;
b80204
 
b80204
+import netscape.security.x509.RevocationReason;
b80204
+
b80204
 import org.dogtagpki.server.tps.TPSSession;
b80204
 import org.dogtagpki.server.tps.TPSSubsystem;
b80204
 import org.dogtagpki.server.tps.authentication.AuthUIParameter;
b80204
@@ -100,8 +102,6 @@ import com.netscape.cms.servlet.tks.SecureChannelProtocol;
b80204
 import com.netscape.cmsutil.crypto.CryptoUtil;
b80204
 import com.netscape.symkey.SessionKey;
b80204
 
b80204
-import netscape.security.x509.RevocationReason;
b80204
-
b80204
 public class TPSProcessor {
b80204
 
b80204
     public static final int RESULT_NO_ERROR = 0;
b80204
@@ -923,20 +923,39 @@ public class TPSProcessor {
b80204
             TPSBuffer drmDesKeyBuff = resp.getDRM_Trans_DesKey();
b80204
             TPSBuffer kekDesKeyBuff = resp.getKekWrappedDesKey();
b80204
 
b80204
-            CMS.debug(method + " encSessionKeyBuff: " + encSessionKeyBuff.toHexString());
b80204
-            CMS.debug(method + " kekSessionKeyBuff: " + kekSessionKeyBuff.toHexString());
b80204
-            CMS.debug(method + " macSessionKeyBuff: " + macSessionKeyBuff.toHexString());
b80204
-            CMS.debug(method + " hostCryptogramBuff: " + hostCryptogramBuff.toHexString());
b80204
-            CMS.debug(method + " keyCheckBuff: " + keyCheckBuff.toHexString());
b80204
-            CMS.debug(method + " drmDessKeyBuff: " + drmDesKeyBuff.toHexString());
b80204
-            CMS.debug(method + " kekDesKeyBuff: " + kekDesKeyBuff.toHexString());
b80204
-
b80204
-            encSessionKeySCP03 = (PK11SymKey) protocol.unwrapWrappedSymKeyOnToken(token, sharedSecret,
b80204
-                    encSessionKeyBuff.toBytesArray(), false, SymmetricKey.AES);
b80204
-            macSessionKeySCP03 = (PK11SymKey) protocol.unwrapWrappedSymKeyOnToken(token, sharedSecret,
b80204
-                    macSessionKeyBuff.toBytesArray(), false, SymmetricKey.AES);
b80204
-            kekSessionKeySCP03 = (PK11SymKey) protocol.unwrapWrappedSymKeyOnToken(token, sharedSecret,
b80204
-                    kekSessionKeyBuff.toBytesArray(), false, SymmetricKey.AES);
b80204
+            if (encSessionKeyBuff != null)
b80204
+                CMS.debug(method + " encSessionKeyBuff: " + encSessionKeyBuff.toHexString());
b80204
+
b80204
+            if (kekSessionKeyBuff != null)
b80204
+                CMS.debug(method + " kekSessionKeyBuff: " + kekSessionKeyBuff.toHexString());
b80204
+
b80204
+            if (macSessionKeyBuff != null)
b80204
+                CMS.debug(method + " macSessionKeyBuff: " + macSessionKeyBuff.toHexString());
b80204
+
b80204
+            if (hostCryptogramBuff != null)
b80204
+                CMS.debug(method + " hostCryptogramBuff: " + hostCryptogramBuff.toHexString());
b80204
+
b80204
+            if (keyCheckBuff != null)
b80204
+                CMS.debug(method + " keyCheckBuff: " + keyCheckBuff.toHexString());
b80204
+
b80204
+            if (drmDesKeyBuff != null)
b80204
+                CMS.debug(method + " drmDessKeyBuff: " + drmDesKeyBuff.toHexString());
b80204
+
b80204
+            if (kekDesKeyBuff != null)
b80204
+                CMS.debug(method + " kekDesKeyBuff: " + kekDesKeyBuff.toHexString());
b80204
+
b80204
+
b80204
+            if (encSessionKeyBuff != null)
b80204
+                encSessionKeySCP03 = (PK11SymKey) protocol.unwrapWrappedSymKeyOnToken(token, sharedSecret,
b80204
+                        encSessionKeyBuff.toBytesArray(), false, SymmetricKey.AES);
b80204
+
b80204
+            if (macSessionKeyBuff != null)
b80204
+                macSessionKeySCP03 = (PK11SymKey) protocol.unwrapWrappedSymKeyOnToken(token, sharedSecret,
b80204
+                        macSessionKeyBuff.toBytesArray(), false, SymmetricKey.AES);
b80204
+
b80204
+            if (kekSessionKeyBuff != null)
b80204
+                kekSessionKeySCP03 = (PK11SymKey) protocol.unwrapWrappedSymKeyOnToken(token, sharedSecret,
b80204
+                        kekSessionKeyBuff.toBytesArray(), false, SymmetricKey.AES);
b80204
 
b80204
             channel = new SecureChannel(this, encSessionKeySCP03, macSessionKeySCP03, kekSessionKeySCP03,
b80204
                     drmDesKeyBuff, kekDesKeyBuff,
b80204
-- 
b80204
1.8.3.1
b80204
b80204
b80204
From f84bfab30647ae1492fcdca0a026bfa4d91350c9 Mon Sep 17 00:00:00 2001
b80204
From: Ade Lee <alee@redhat.com>
b80204
Date: Mon, 1 May 2017 15:56:58 -0400
b80204
Subject: [PATCH 07/10] Make sure generated asym keys are extractable
b80204
b80204
In HSMs, we were not able to retrieve asym keys that were
b80204
generated from the AsymKeyGenService, because the right
b80204
flags were not set (ie. set like in the server side
b80204
keygen case).
b80204
b80204
To do this, I extracted the key generation function from
b80204
NetKeygenService to KeyRecoveryAuthority, so that it could
b80204
be used by both services.
b80204
b80204
Bugzilla BZ# 1386303
b80204
b80204
Change-Id: I13b5f4b602217a685acada94091e91df75e25eff
b80204
---
b80204
 .../certsrv/kra/IKeyRecoveryAuthority.java         |  17 ++
b80204
 .../src/com/netscape/kra/AsymKeyGenService.java    |  23 +--
b80204
 .../src/com/netscape/kra/KeyRecoveryAuthority.java | 184 ++++++++++++++++++++
b80204
 .../src/com/netscape/kra/NetkeyKeygenService.java  | 185 +--------------------
b80204
 4 files changed, 213 insertions(+), 196 deletions(-)
b80204
b80204
diff --git a/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java b/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java
b80204
index a12d773..4f709e9 100644
b80204
--- a/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java
b80204
+++ b/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java
b80204
@@ -17,12 +17,15 @@
b80204
 // --- END COPYRIGHT BLOCK ---
b80204
 package com.netscape.certsrv.kra;
b80204
 
b80204
+import java.security.KeyPair;
b80204
 import java.util.Enumeration;
b80204
 import java.util.Hashtable;
b80204
 import java.util.Vector;
b80204
 
b80204
 import org.dogtagpki.legacy.policy.IPolicyProcessor;
b80204
 import org.mozilla.jss.crypto.CryptoToken;
b80204
+import org.mozilla.jss.crypto.KeyPairGeneratorSpi;
b80204
+import org.mozilla.jss.crypto.PQGParams;
b80204
 
b80204
 import com.netscape.certsrv.base.EBaseException;
b80204
 import com.netscape.certsrv.base.ISubsystem;
b80204
@@ -337,4 +340,18 @@ public interface IKeyRecoveryAuthority extends ISubsystem {
b80204
      * @return
b80204
      */
b80204
     public boolean isRetrievalSynchronous(String realm);
b80204
+
b80204
+    /**
b80204
+     * Generate an asymmetric key pair.
b80204
+     *
b80204
+     * @param alg
b80204
+     * @param keySize
b80204
+     * @param keyCurve
b80204
+     * @param pqg
b80204
+     * @param usageList - RSA only for now
b80204
+     * @return key pair
b80204
+     * @throws EBaseException
b80204
+     */
b80204
+    public KeyPair generateKeyPair(String alg, int keySize, String keyCurve,
b80204
+            PQGParams pqg, KeyPairGeneratorSpi.Usage[] usageList) throws EBaseException;
b80204
 }
b80204
diff --git a/base/kra/src/com/netscape/kra/AsymKeyGenService.java b/base/kra/src/com/netscape/kra/AsymKeyGenService.java
b80204
index 9528972..7351d50 100644
b80204
--- a/base/kra/src/com/netscape/kra/AsymKeyGenService.java
b80204
+++ b/base/kra/src/com/netscape/kra/AsymKeyGenService.java
b80204
@@ -19,14 +19,10 @@ package com.netscape.kra;
b80204
 
b80204
 import java.math.BigInteger;
b80204
 import java.security.KeyPair;
b80204
-import java.security.NoSuchAlgorithmException;
b80204
 
b80204
 import org.mozilla.jss.crypto.CryptoToken;
b80204
-import org.mozilla.jss.crypto.KeyPairAlgorithm;
b80204
-import org.mozilla.jss.crypto.KeyPairGenerator;
b80204
 import org.mozilla.jss.crypto.KeyPairGeneratorSpi;
b80204
 import org.mozilla.jss.crypto.PrivateKey;
b80204
-import org.mozilla.jss.crypto.TokenException;
b80204
 
b80204
 import com.netscape.certsrv.apps.CMS;
b80204
 import com.netscape.certsrv.base.EBaseException;
b80204
@@ -42,7 +38,6 @@ import com.netscape.certsrv.request.IRequest;
b80204
 import com.netscape.certsrv.request.IService;
b80204
 import com.netscape.certsrv.request.RequestId;
b80204
 import com.netscape.certsrv.security.IStorageKeyUnit;
b80204
-import com.netscape.cms.servlet.key.KeyRequestDAO;
b80204
 import com.netscape.cmscore.dbs.KeyRecord;
b80204
 
b80204
 import netscape.security.util.WrappingParams;
b80204
@@ -132,8 +127,6 @@ public class AsymKeyGenService implements IService {
b80204
         CMS.debug("AsymKeyGenService.serviceRequest. Request id: " + request.getRequestId());
b80204
         CMS.debug("AsymKeyGenService.serviceRequest algorithm: " + algorithm);
b80204
 
b80204
-        KeyPairAlgorithm keyPairAlgorithm = KeyRequestDAO.ASYMKEY_GEN_ALGORITHMS.get(algorithm.toUpperCase());
b80204
-
b80204
         String owner = request.getExtDataInString(IRequest.ATTR_REQUEST_OWNER);
b80204
         String auditSubjectID = owner;
b80204
 
b80204
@@ -141,16 +134,18 @@ public class AsymKeyGenService implements IService {
b80204
         CryptoToken token = kra.getKeygenToken();
b80204
 
b80204
         // Generating the asymmetric keys
b80204
-        KeyPairGenerator keyPairGen = null;
b80204
         KeyPair kp = null;
b80204
 
b80204
         try {
b80204
-            keyPairGen = token.getKeyPairGenerator(keyPairAlgorithm);
b80204
-            keyPairGen.initialize(keySize);
b80204
-            if (usageList != null)
b80204
-                keyPairGen.setKeyPairUsages(usageList, usageList);
b80204
-            kp = keyPairGen.genKeyPair();
b80204
-        } catch (NoSuchAlgorithmException | TokenException e) {
b80204
+            kp = kra.generateKeyPair(
b80204
+                    algorithm.toUpperCase(),
b80204
+                    keySize,
b80204
+                    null, // keyCurve for ECC, not yet supported
b80204
+                    null, // PQG not yet supported
b80204
+                    usageList
b80204
+                 );
b80204
+
b80204
+        } catch (EBaseException e) {
b80204
             CMS.debugStackTrace();
b80204
             auditAsymKeyGenRequestProcessed(auditSubjectID, ILogger.FAILURE, request.getRequestId(),
b80204
                     clientKeyId, null, "Failed to generate Asymmetric key");
b80204
diff --git a/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java b/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java
b80204
index ec920e6..54953d1 100644
b80204
--- a/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java
b80204
+++ b/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java
b80204
@@ -20,6 +20,10 @@ package com.netscape.kra;
b80204
 import java.io.ByteArrayOutputStream;
b80204
 import java.io.IOException;
b80204
 import java.math.BigInteger;
b80204
+import java.security.InvalidAlgorithmParameterException;
b80204
+import java.security.InvalidParameterException;
b80204
+import java.security.KeyPair;
b80204
+import java.security.NoSuchAlgorithmException;
b80204
 import java.security.cert.CertificateEncodingException;
b80204
 import java.security.cert.CertificateException;
b80204
 import java.security.cert.X509Certificate;
b80204
@@ -32,6 +36,12 @@ import org.dogtagpki.legacy.kra.KRAPolicy;
b80204
 import org.dogtagpki.legacy.policy.IPolicyProcessor;
b80204
 import org.mozilla.jss.NoSuchTokenException;
b80204
 import org.mozilla.jss.crypto.CryptoToken;
b80204
+import org.mozilla.jss.crypto.KeyPairAlgorithm;
b80204
+import org.mozilla.jss.crypto.KeyPairGenerator;
b80204
+import org.mozilla.jss.crypto.KeyPairGeneratorSpi;
b80204
+import org.mozilla.jss.crypto.PQGParamGenException;
b80204
+import org.mozilla.jss.crypto.PQGParams;
b80204
+import org.mozilla.jss.crypto.TokenException;
b80204
 
b80204
 import com.netscape.certsrv.apps.CMS;
b80204
 import com.netscape.certsrv.authority.IAuthority;
b80204
@@ -1816,4 +1826,178 @@ public class KeyRecoveryAuthority implements IAuthority, IKeyService, IKeyRecove
b80204
 
b80204
         return agents;
b80204
     }
b80204
+
b80204
+    public KeyPair generateKeyPair(String alg, int keySize, String keyCurve,
b80204
+            PQGParams pqg, KeyPairGeneratorSpi.Usage[] usageList) throws EBaseException {
b80204
+        KeyPairAlgorithm kpAlg = null;
b80204
+
b80204
+        if (alg.equals("RSA"))
b80204
+            kpAlg = KeyPairAlgorithm.RSA;
b80204
+        else if (alg.equals("EC"))
b80204
+            kpAlg = KeyPairAlgorithm.EC;
b80204
+        else
b80204
+            kpAlg = KeyPairAlgorithm.DSA;
b80204
+
b80204
+        try {
b80204
+            KeyPair kp = generateKeyPair(kpAlg, keySize, keyCurve, pqg, usageList);
b80204
+
b80204
+            return kp;
b80204
+        } catch (InvalidParameterException e) {
b80204
+            throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEYSIZE_PARAMS",
b80204
+                        "" + keySize));
b80204
+        } catch (PQGParamGenException e) {
b80204
+            throw new EBaseException(CMS.getUserMessage("CMS_BASE_PQG_GEN_FAILED"));
b80204
+        } catch (NoSuchAlgorithmException e) {
b80204
+            throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED",
b80204
+                        kpAlg.toString()));
b80204
+        } catch (TokenException e) {
b80204
+            throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_ERROR_1", e.toString()));
b80204
+        } catch (InvalidAlgorithmParameterException e) {
b80204
+            throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED", "DSA"));
b80204
+        }
b80204
+    }
b80204
+
b80204
+    public KeyPair generateKeyPair(
b80204
+            KeyPairAlgorithm kpAlg, int keySize, String keyCurve, PQGParams pqg,
b80204
+            KeyPairGeneratorSpi.Usage[] usageList )
b80204
+            throws NoSuchAlgorithmException, TokenException, InvalidAlgorithmParameterException,
b80204
+            InvalidParameterException, PQGParamGenException {
b80204
+
b80204
+        CryptoToken token = getKeygenToken();
b80204
+
b80204
+        CMS.debug("NetkeyKeygenService: key pair is to be generated on slot: " + token.getName());
b80204
+
b80204
+        /*
b80204
+           make it temporary so can work with HSM
b80204
+           netHSM works with
b80204
+              temporary == true
b80204
+              sensitive == <do not specify>
b80204
+              extractable == <do not specify>
b80204
+           LunaSA2 works with
b80204
+              temporary == true
b80204
+              sensitive == true
b80204
+              extractable == true
b80204
+        */
b80204
+        KeyPairGenerator kpGen = token.getKeyPairGenerator(kpAlg);
b80204
+        IConfigStore config = CMS.getConfigStore();
b80204
+        IConfigStore kgConfig = config.getSubStore("kra.keygen");
b80204
+        boolean tp = false;
b80204
+        boolean sp = false;
b80204
+        boolean ep = false;
b80204
+        if ((kgConfig != null) && (!kgConfig.equals(""))) {
b80204
+            try {
b80204
+                tp = kgConfig.getBoolean("temporaryPairs", false);
b80204
+                sp = kgConfig.getBoolean("sensitivePairs", false);
b80204
+                ep = kgConfig.getBoolean("extractablePairs", false);
b80204
+                CMS.debug("NetkeyKeygenService: found config store: kra.keygen");
b80204
+                // by default, let nethsm work
b80204
+                if ((tp == false) && (sp == false) && (ep == false)) {
b80204
+                    if (kpAlg == KeyPairAlgorithm.EC) {
b80204
+                        // set to what works for nethsm
b80204
+                        tp = true;
b80204
+                        sp = false;
b80204
+                        ep = true;
b80204
+                    } else
b80204
+                        tp = true;
b80204
+                    }
b80204
+            } catch (Exception e) {
b80204
+                CMS.debug("NetkeyKeygenService: kgConfig.getBoolean failed");
b80204
+                // by default, let nethsm work
b80204
+                tp = true;
b80204
+            }
b80204
+        } else {
b80204
+            // by default, let nethsm work
b80204
+            CMS.debug("NetkeyKeygenService: cannot find config store: kra.keygen, assume temporaryPairs==true");
b80204
+            if (kpAlg == KeyPairAlgorithm.EC) {
b80204
+                // set to what works for nethsm
b80204
+                tp = true;
b80204
+                sp = false;
b80204
+                ep = true;
b80204
+            } else {
b80204
+                tp = true;
b80204
+            }
b80204
+        }
b80204
+
b80204
+        if (kpAlg == KeyPairAlgorithm.EC) {
b80204
+
b80204
+            boolean isECDHE = false;
b80204
+            KeyPair pair = null;
b80204
+
b80204
+            // used with isECDHE == true
b80204
+            org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage usages_mask_ECDSA[] = {
b80204
+                org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.DERIVE
b80204
+            };
b80204
+
b80204
+            // used with isECDHE == false
b80204
+            org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage usages_mask_ECDH[] = {
b80204
+                org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN,
b80204
+                org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN_RECOVER
b80204
+            };
b80204
+
b80204
+            try {
b80204
+                pair = CryptoUtil.generateECCKeyPair(token.getName(),
b80204
+                    keyCurve /*ECC_curve default*/,
b80204
+                    null,
b80204
+                    (isECDHE==true) ? usages_mask_ECDSA: usages_mask_ECDH,
b80204
+                    tp /*temporary*/, sp? 1:0 /*sensitive*/, ep? 1:0 /*extractable*/);
b80204
+                CMS.debug("NetkeyKeygenService: after key pair generation" );
b80204
+            } catch (Exception e) {
b80204
+                CMS.debug("NetkeyKeygenService: key pair generation with exception:"+e.toString());
b80204
+            }
b80204
+            return pair;
b80204
+
b80204
+        } else { // !EC
b80204
+            //only specified to "true" will it be set
b80204
+            if (tp == true) {
b80204
+                CMS.debug("NetkeyKeygenService: setting temporaryPairs to true");
b80204
+                kpGen.temporaryPairs(true);
b80204
+            }
b80204
+
b80204
+            if (sp == true) {
b80204
+                CMS.debug("NetkeyKeygenService: setting sensitivePairs to true");
b80204
+                kpGen.sensitivePairs(true);
b80204
+            }
b80204
+
b80204
+            if (ep == true) {
b80204
+                CMS.debug("NetkeyKeygenService: setting extractablePairs to true");
b80204
+                kpGen.extractablePairs(true);
b80204
+            }
b80204
+
b80204
+            if (kpAlg == KeyPairAlgorithm.DSA) {
b80204
+                if (pqg == null) {
b80204
+                    kpGen.initialize(keySize);
b80204
+                } else {
b80204
+                    kpGen.initialize(pqg);
b80204
+                }
b80204
+            } else {
b80204
+                kpGen.initialize(keySize);
b80204
+            }
b80204
+
b80204
+            if (usageList != null)
b80204
+                kpGen.setKeyPairUsages(usageList, usageList);
b80204
+
b80204
+            if (pqg == null) {
b80204
+                KeyPair kp = null;
b80204
+                synchronized (new Object()) {
b80204
+                    CMS.debug("NetkeyKeygenService: key pair generation begins");
b80204
+                    kp = kpGen.genKeyPair();
b80204
+                    CMS.debug("NetkeyKeygenService: key pair generation done");
b80204
+                    addEntropy(true);
b80204
+                }
b80204
+                return kp;
b80204
+            } else {
b80204
+                // DSA
b80204
+                KeyPair kp = null;
b80204
+
b80204
+                /* no DSA for now... netkey prototype
b80204
+                do {
b80204
+                    // 602548 NSS bug - to overcome it, we use isBadDSAKeyPair
b80204
+                    kp = kpGen.genKeyPair();
b80204
+                }
b80204
+                while (isBadDSAKeyPair(kp));
b80204
+                */
b80204
+                return kp;
b80204
+            }
b80204
+        }
b80204
+    }
b80204
 }
b80204
diff --git a/base/kra/src/com/netscape/kra/NetkeyKeygenService.java b/base/kra/src/com/netscape/kra/NetkeyKeygenService.java
b80204
index e09eb42..f068a4a 100644
b80204
--- a/base/kra/src/com/netscape/kra/NetkeyKeygenService.java
b80204
+++ b/base/kra/src/com/netscape/kra/NetkeyKeygenService.java
b80204
@@ -23,11 +23,8 @@ import java.io.FilterOutputStream;
b80204
 import java.io.IOException;
b80204
 import java.io.PrintStream;
b80204
 import java.math.BigInteger;
b80204
-import java.security.InvalidAlgorithmParameterException;
b80204
 import java.security.InvalidKeyException;
b80204
-import java.security.InvalidParameterException;
b80204
 import java.security.KeyPair;
b80204
-import java.security.NoSuchAlgorithmException;
b80204
 import java.security.SecureRandom;
b80204
 
b80204
 import org.mozilla.jss.asn1.ASN1Util;
b80204
@@ -35,21 +32,15 @@ import org.mozilla.jss.crypto.CryptoToken;
b80204
 import org.mozilla.jss.crypto.EncryptionAlgorithm;
b80204
 import org.mozilla.jss.crypto.IVParameterSpec;
b80204
 import org.mozilla.jss.crypto.KeyGenAlgorithm;
b80204
-import org.mozilla.jss.crypto.KeyPairAlgorithm;
b80204
-import org.mozilla.jss.crypto.KeyPairGenerator;
b80204
 import org.mozilla.jss.crypto.KeyWrapAlgorithm;
b80204
-import org.mozilla.jss.crypto.PQGParamGenException;
b80204
-import org.mozilla.jss.crypto.PQGParams;
b80204
 import org.mozilla.jss.crypto.PrivateKey;
b80204
 import org.mozilla.jss.crypto.SymmetricKey;
b80204
-import org.mozilla.jss.crypto.TokenException;
b80204
 import org.mozilla.jss.pkcs11.PK11SymKey;
b80204
 import org.mozilla.jss.pkix.crmf.PKIArchiveOptions;
b80204
 import org.mozilla.jss.util.Base64OutputStream;
b80204
 
b80204
 import com.netscape.certsrv.apps.CMS;
b80204
 import com.netscape.certsrv.base.EBaseException;
b80204
-import com.netscape.certsrv.base.IConfigStore;
b80204
 import com.netscape.certsrv.base.MetaInfo;
b80204
 import com.netscape.certsrv.base.SessionContext;
b80204
 import com.netscape.certsrv.dbs.keydb.IKeyRecord;
b80204
@@ -122,177 +113,6 @@ public class NetkeyKeygenService implements IService {
b80204
         return archOpts;
b80204
     }
b80204
 
b80204
-    public KeyPair generateKeyPair(
b80204
-            KeyPairAlgorithm kpAlg, int keySize, String keyCurve, PQGParams pqg)
b80204
-            throws NoSuchAlgorithmException, TokenException, InvalidAlgorithmParameterException,
b80204
-            InvalidParameterException, PQGParamGenException {
b80204
-
b80204
-        CryptoToken token = mKRA.getKeygenToken();
b80204
-
b80204
-        CMS.debug("NetkeyKeygenService: key pair is to be generated on slot: " + token.getName());
b80204
-
b80204
-        /*
b80204
-           make it temporary so can work with HSM
b80204
-           netHSM works with
b80204
-              temporary == true
b80204
-              sensitive == <do not specify>
b80204
-              extractable == <do not specify>
b80204
-           LunaSA2 works with
b80204
-              temporary == true
b80204
-              sensitive == true
b80204
-              extractable == true
b80204
-        */
b80204
-        KeyPairGenerator kpGen = token.getKeyPairGenerator(kpAlg);
b80204
-        IConfigStore config = CMS.getConfigStore();
b80204
-        IConfigStore kgConfig = config.getSubStore("kra.keygen");
b80204
-        boolean tp = false;
b80204
-        boolean sp = false;
b80204
-        boolean ep = false;
b80204
-        if ((kgConfig != null) && (!kgConfig.equals(""))) {
b80204
-            try {
b80204
-                tp = kgConfig.getBoolean("temporaryPairs", false);
b80204
-                sp = kgConfig.getBoolean("sensitivePairs", false);
b80204
-                ep = kgConfig.getBoolean("extractablePairs", false);
b80204
-                CMS.debug("NetkeyKeygenService: found config store: kra.keygen");
b80204
-                // by default, let nethsm work
b80204
-                if ((tp == false) && (sp == false) && (ep == false)) {
b80204
-                    if (kpAlg == KeyPairAlgorithm.EC) {
b80204
-                        // set to what works for nethsm
b80204
-                        tp = true;
b80204
-                        sp = false;
b80204
-                        ep = true;
b80204
-                    } else
b80204
-                        tp = true;
b80204
-                    }
b80204
-            } catch (Exception e) {
b80204
-                CMS.debug("NetkeyKeygenService: kgConfig.getBoolean failed");
b80204
-                // by default, let nethsm work
b80204
-                tp = true;
b80204
-            }
b80204
-        } else {
b80204
-            // by default, let nethsm work
b80204
-            CMS.debug("NetkeyKeygenService: cannot find config store: kra.keygen, assume temporaryPairs==true");
b80204
-            if (kpAlg == KeyPairAlgorithm.EC) {
b80204
-                // set to what works for nethsm
b80204
-                tp = true;
b80204
-                sp = false;
b80204
-                ep = true;
b80204
-            } else {
b80204
-                tp = true;
b80204
-            }
b80204
-        }
b80204
-
b80204
-        if (kpAlg == KeyPairAlgorithm.EC) {
b80204
-
b80204
-            boolean isECDHE = false;
b80204
-            KeyPair pair = null;
b80204
-
b80204
-            // used with isECDHE == true
b80204
-            org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage usages_mask_ECDSA[] = {
b80204
-                org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.DERIVE
b80204
-            };
b80204
-
b80204
-            // used with isECDHE == false
b80204
-            org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage usages_mask_ECDH[] = {
b80204
-                org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN,
b80204
-                org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN_RECOVER
b80204
-            };
b80204
-
b80204
-            try {
b80204
-                pair = CryptoUtil.generateECCKeyPair(token.getName(),
b80204
-                    keyCurve /*ECC_curve default*/,
b80204
-                    null,
b80204
-                    (isECDHE==true) ? usages_mask_ECDSA: usages_mask_ECDH,
b80204
-                    tp /*temporary*/, sp? 1:0 /*sensitive*/, ep? 1:0 /*extractable*/);
b80204
-                CMS.debug("NetkeyKeygenService: after key pair generation" );
b80204
-            } catch (Exception e) {
b80204
-                CMS.debug("NetkeyKeygenService: key pair generation with exception:"+e.toString());
b80204
-            }
b80204
-            return pair;
b80204
-
b80204
-        } else { // !EC
b80204
-            //only specified to "true" will it be set
b80204
-            if (tp == true) {
b80204
-                CMS.debug("NetkeyKeygenService: setting temporaryPairs to true");
b80204
-                kpGen.temporaryPairs(true);
b80204
-            }
b80204
-
b80204
-            if (sp == true) {
b80204
-                CMS.debug("NetkeyKeygenService: setting sensitivePairs to true");
b80204
-                kpGen.sensitivePairs(true);
b80204
-            }
b80204
-
b80204
-            if (ep == true) {
b80204
-                CMS.debug("NetkeyKeygenService: setting extractablePairs to true");
b80204
-                kpGen.extractablePairs(true);
b80204
-            }
b80204
-
b80204
-            if (kpAlg == KeyPairAlgorithm.DSA) {
b80204
-                if (pqg == null) {
b80204
-                    kpGen.initialize(keySize);
b80204
-                } else {
b80204
-                    kpGen.initialize(pqg);
b80204
-                }
b80204
-            } else {
b80204
-                kpGen.initialize(keySize);
b80204
-            }
b80204
-
b80204
-            if (pqg == null) {
b80204
-                KeyPair kp = null;
b80204
-                synchronized (new Object()) {
b80204
-                    CMS.debug("NetkeyKeygenService: key pair generation begins");
b80204
-                    kp = kpGen.genKeyPair();
b80204
-                    CMS.debug("NetkeyKeygenService: key pair generation done");
b80204
-                    mKRA.addEntropy(true);
b80204
-                }
b80204
-                return kp;
b80204
-            } else {
b80204
-                // DSA
b80204
-                KeyPair kp = null;
b80204
-
b80204
-                /* no DSA for now... netkey prototype
b80204
-                do {
b80204
-                    // 602548 NSS bug - to overcome it, we use isBadDSAKeyPair
b80204
-                    kp = kpGen.genKeyPair();
b80204
-                }
b80204
-                while (isBadDSAKeyPair(kp));
b80204
-                */
b80204
-                return kp;
b80204
-            }
b80204
-        }
b80204
-    }
b80204
-
b80204
-    public KeyPair generateKeyPair(String alg,
b80204
-            int keySize, String keyCurve,  PQGParams pqg) throws EBaseException {
b80204
-
b80204
-        KeyPairAlgorithm kpAlg = null;
b80204
-
b80204
-        if (alg.equals("RSA"))
b80204
-            kpAlg = KeyPairAlgorithm.RSA;
b80204
-        else if (alg.equals("EC"))
b80204
-            kpAlg = KeyPairAlgorithm.EC;
b80204
-        else
b80204
-            kpAlg = KeyPairAlgorithm.DSA;
b80204
-
b80204
-        try {
b80204
-            KeyPair kp = generateKeyPair(kpAlg, keySize, keyCurve, pqg);
b80204
-
b80204
-            return kp;
b80204
-        } catch (InvalidParameterException e) {
b80204
-            throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEYSIZE_PARAMS",
b80204
-                        "" + keySize));
b80204
-        } catch (PQGParamGenException e) {
b80204
-            throw new EBaseException(CMS.getUserMessage("CMS_BASE_PQG_GEN_FAILED"));
b80204
-        } catch (NoSuchAlgorithmException e) {
b80204
-            throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED",
b80204
-                        kpAlg.toString()));
b80204
-        } catch (TokenException e) {
b80204
-            throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_ERROR_1", e.toString()));
b80204
-        } catch (InvalidAlgorithmParameterException e) {
b80204
-            throw new EBaseException(CMS.getUserMessage("CMS_BASE_ALG_NOT_SUPPORTED", "DSA"));
b80204
-        }
b80204
-    }
b80204
-
b80204
     private static String base64Encode(byte[] bytes) throws IOException {
b80204
         // All this streaming is lame, but Base64OutputStream needs a
b80204
         // PrintStream
b80204
@@ -430,10 +250,11 @@ public class NetkeyKeygenService implements IService {
b80204
 
b80204
             CMS.debug("NetkeyKeygenService: about to generate key pair");
b80204
 
b80204
-            keypair = generateKeyPair(rKeytype /* rKeytype: "RSA" or "EC" */,
b80204
+            keypair = mKRA.generateKeyPair(rKeytype /* rKeytype: "RSA" or "EC" */,
b80204
                 keysize /*Integer.parseInt(len)*/,
b80204
                 rKeycurve /* for "EC" only */,
b80204
-                null /*pqgParams*/);
b80204
+                null /*pqgParams*/,
b80204
+                null /* usageList*/);
b80204
 
b80204
             if (keypair == null) {
b80204
                 CMS.debug("NetkeyKeygenService: failed generating key pair for " + rCUID + ":" + rUserid);
b80204
-- 
b80204
1.8.3.1
b80204
b80204
b80204
From bea446868e282955d9c70028be657530eaccbe29 Mon Sep 17 00:00:00 2001
b80204
From: Ade Lee <alee@redhat.com>
b80204
Date: Mon, 1 May 2017 18:25:59 -0400
b80204
Subject: [PATCH 08/10] Use AES-CBC in storage unit for archival in key
b80204
 wrapping
b80204
b80204
When AES-KW or AES-KWP is not available, we need to be sure to use
b80204
a key wrap algorithm that is available for keywrap.  This would
b80204
be AES-CBC.  Removes some TODOs.
b80204
b80204
Refactor so that getWrappingParams is only defined on the StorageUnit,
b80204
which is where it makes sense in any case.
b80204
b80204
Part of Bugzilla BZ# 1386303
b80204
b80204
Change-Id: I28711f7fe0a00e9d12d26c6e170fb125418d6d51
b80204
---
b80204
 .../src/com/netscape/certsrv/security/IEncryptionUnit.java   |  2 --
b80204
 .../src/com/netscape/certsrv/security/IStorageKeyUnit.java   |  6 ++++++
b80204
 base/kra/src/com/netscape/kra/AsymKeyGenService.java         | 11 +++--------
b80204
 base/kra/src/com/netscape/kra/EncryptionUnit.java            |  2 --
b80204
 base/kra/src/com/netscape/kra/EnrollmentService.java         |  2 +-
b80204
 base/kra/src/com/netscape/kra/NetkeyKeygenService.java       |  7 +++++--
b80204
 base/kra/src/com/netscape/kra/SecurityDataProcessor.java     |  2 +-
b80204
 base/kra/src/com/netscape/kra/StorageKeyUnit.java            | 12 +++++++++++-
b80204
 base/kra/src/com/netscape/kra/SymKeyGenService.java          |  7 +++++--
b80204
 base/kra/src/com/netscape/kra/TransportKeyUnit.java          |  4 ----
b80204
 10 files changed, 32 insertions(+), 23 deletions(-)
b80204
b80204
diff --git a/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java b/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java
b80204
index add15cb..e55713d 100644
b80204
--- a/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java
b80204
+++ b/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java
b80204
@@ -63,7 +63,5 @@ public interface IEncryptionUnit extends IToken {
b80204
             SymmetricKey.Usage usage, WrappingParams params) throws Exception;
b80204
 
b80204
 
b80204
-    public WrappingParams getWrappingParams() throws Exception;
b80204
-
b80204
     public WrappingParams getOldWrappingParams();
b80204
 }
b80204
diff --git a/base/common/src/com/netscape/certsrv/security/IStorageKeyUnit.java b/base/common/src/com/netscape/certsrv/security/IStorageKeyUnit.java
b80204
index cd94143..bfc6012 100644
b80204
--- a/base/common/src/com/netscape/certsrv/security/IStorageKeyUnit.java
b80204
+++ b/base/common/src/com/netscape/certsrv/security/IStorageKeyUnit.java
b80204
@@ -174,4 +174,10 @@ public interface IStorageKeyUnit extends IEncryptionUnit {
b80204
     public PrivateKey unwrap(byte privateKey[], PublicKey pubKey, boolean temporary,
b80204
             WrappingParams params) throws Exception;
b80204
 
b80204
+    /**
b80204
+     * Get the wrapping parameters for this storage unit
b80204
+     *
b80204
+     */
b80204
+    public WrappingParams getWrappingParams(boolean encrypt) throws Exception;
b80204
+
b80204
 }
b80204
diff --git a/base/kra/src/com/netscape/kra/AsymKeyGenService.java b/base/kra/src/com/netscape/kra/AsymKeyGenService.java
b80204
index 7351d50..cfee504 100644
b80204
--- a/base/kra/src/com/netscape/kra/AsymKeyGenService.java
b80204
+++ b/base/kra/src/com/netscape/kra/AsymKeyGenService.java
b80204
@@ -20,7 +20,6 @@ package com.netscape.kra;
b80204
 import java.math.BigInteger;
b80204
 import java.security.KeyPair;
b80204
 
b80204
-import org.mozilla.jss.crypto.CryptoToken;
b80204
 import org.mozilla.jss.crypto.KeyPairGeneratorSpi;
b80204
 import org.mozilla.jss.crypto.PrivateKey;
b80204
 
b80204
@@ -68,7 +67,7 @@ public class AsymKeyGenService implements IService {
b80204
 
b80204
     @Override
b80204
     public boolean serviceRequest(IRequest request) throws EBaseException {
b80204
-        IConfigStore cs = CMS.getConfigStore();
b80204
+        IConfigStore configStore = CMS.getConfigStore();
b80204
         String clientKeyId = request.getExtDataInString(IRequest.SECURITY_DATA_CLIENT_KEY_ID);
b80204
         String algorithm = request.getExtDataInString(IRequest.KEY_GEN_ALGORITHM);
b80204
 
b80204
@@ -77,7 +76,7 @@ public class AsymKeyGenService implements IService {
b80204
 
b80204
         String realm = request.getRealm();
b80204
 
b80204
-        boolean allowEncDecrypt_archival = cs.getBoolean("kra.allowEncDecrypt.archival", false);
b80204
+        boolean allowEncDecrypt_archival = configStore.getBoolean("kra.allowEncDecrypt.archival", false);
b80204
 
b80204
         KeyPairGeneratorSpi.Usage[] usageList = null;
b80204
         String usageStr = request.getExtDataInString(IRequest.KEY_GEN_USAGES);
b80204
@@ -130,9 +129,6 @@ public class AsymKeyGenService implements IService {
b80204
         String owner = request.getExtDataInString(IRequest.ATTR_REQUEST_OWNER);
b80204
         String auditSubjectID = owner;
b80204
 
b80204
-        // Get the token
b80204
-        CryptoToken token = kra.getKeygenToken();
b80204
-
b80204
         // Generating the asymmetric keys
b80204
         KeyPair kp = null;
b80204
 
b80204
@@ -162,8 +158,7 @@ public class AsymKeyGenService implements IService {
b80204
         WrappingParams params = null;
b80204
 
b80204
         try {
b80204
-            // TODO(alee) What happens if key wrap algorithm is not supported?
b80204
-            params = storageUnit.getWrappingParams();
b80204
+            params = storageUnit.getWrappingParams(allowEncDecrypt_archival);
b80204
             privateSecurityData = storageUnit.wrap((PrivateKey) kp.getPrivate(), params);
b80204
         } catch (Exception e) {
b80204
             CMS.debug("Failed to generate security data to archive: " + e);
b80204
diff --git a/base/kra/src/com/netscape/kra/EncryptionUnit.java b/base/kra/src/com/netscape/kra/EncryptionUnit.java
b80204
index 02a4ca1..b460c9e 100644
b80204
--- a/base/kra/src/com/netscape/kra/EncryptionUnit.java
b80204
+++ b/base/kra/src/com/netscape/kra/EncryptionUnit.java
b80204
@@ -67,8 +67,6 @@ public abstract class EncryptionUnit implements IEncryptionUnit {
b80204
 
b80204
     public abstract PrivateKey getPrivateKey(org.mozilla.jss.crypto.X509Certificate cert);
b80204
 
b80204
-    public abstract WrappingParams getWrappingParams() throws Exception;
b80204
-
b80204
     public WrappingParams getOldWrappingParams() {
b80204
         return new WrappingParams(
b80204
                 SymmetricKey.DES3, KeyGenAlgorithm.DES3, 168,
b80204
diff --git a/base/kra/src/com/netscape/kra/EnrollmentService.java b/base/kra/src/com/netscape/kra/EnrollmentService.java
b80204
index a200c34..e413a06 100644
b80204
--- a/base/kra/src/com/netscape/kra/EnrollmentService.java
b80204
+++ b/base/kra/src/com/netscape/kra/EnrollmentService.java
b80204
@@ -396,7 +396,7 @@ public class EnrollmentService implements IService {
b80204
             WrappingParams params =  null;
b80204
 
b80204
             try {
b80204
-                params = mStorageUnit.getWrappingParams();
b80204
+                params = mStorageUnit.getWrappingParams(allowEncDecrypt_archival);
b80204
                 if (allowEncDecrypt_archival == true) {
b80204
                     privateKeyData = mStorageUnit.encryptInternalPrivate(unwrapped, params);
b80204
                 } else {
b80204
diff --git a/base/kra/src/com/netscape/kra/NetkeyKeygenService.java b/base/kra/src/com/netscape/kra/NetkeyKeygenService.java
b80204
index f068a4a..636e93e 100644
b80204
--- a/base/kra/src/com/netscape/kra/NetkeyKeygenService.java
b80204
+++ b/base/kra/src/com/netscape/kra/NetkeyKeygenService.java
b80204
@@ -41,6 +41,7 @@ import org.mozilla.jss.util.Base64OutputStream;
b80204
 
b80204
 import com.netscape.certsrv.apps.CMS;
b80204
 import com.netscape.certsrv.base.EBaseException;
b80204
+import com.netscape.certsrv.base.IConfigStore;
b80204
 import com.netscape.certsrv.base.MetaInfo;
b80204
 import com.netscape.certsrv.base.SessionContext;
b80204
 import com.netscape.certsrv.dbs.keydb.IKeyRecord;
b80204
@@ -155,6 +156,9 @@ public class NetkeyKeygenService implements IService {
b80204
 
b80204
         IVParameterSpec algParam = new IVParameterSpec(iv);
b80204
 
b80204
+        IConfigStore configStore = CMS.getConfigStore();
b80204
+        boolean allowEncDecrypt_archival = configStore.getBoolean("kra.allowEncDecrypt.archival", false);
b80204
+
b80204
         wrapped_des_key = null;
b80204
         boolean archive = true;
b80204
         byte[] publicKeyData = null;
b80204
@@ -405,8 +409,7 @@ public class NetkeyKeygenService implements IService {
b80204
                     WrappingParams params = null;
b80204
 
b80204
                     try {
b80204
-                        // TODO(alee)  What happens if key wrap algorithm is not supported?
b80204
-                        params = mStorageUnit.getWrappingParams();
b80204
+                        params = mStorageUnit.getWrappingParams(allowEncDecrypt_archival);
b80204
                         privateKeyData = mStorageUnit.wrap((org.mozilla.jss.crypto.PrivateKey) privKey, params);
b80204
                     } catch (Exception e) {
b80204
                         request.setExtData(IRequest.RESULT, Integer.valueOf(4));
b80204
diff --git a/base/kra/src/com/netscape/kra/SecurityDataProcessor.java b/base/kra/src/com/netscape/kra/SecurityDataProcessor.java
b80204
index 701b611..95d07c4 100644
b80204
--- a/base/kra/src/com/netscape/kra/SecurityDataProcessor.java
b80204
+++ b/base/kra/src/com/netscape/kra/SecurityDataProcessor.java
b80204
@@ -217,7 +217,7 @@ public class SecurityDataProcessor {
b80204
         boolean doEncrypt = false;
b80204
 
b80204
         try {
b80204
-            params = storageUnit.getWrappingParams();
b80204
+            params = storageUnit.getWrappingParams(allowEncDecrypt_archival);
b80204
             if (securitySymKey != null && unwrapped == null) {
b80204
                 privateSecurityData = storageUnit.wrap(securitySymKey, params);
b80204
             } else if (unwrapped != null && allowEncDecrypt_archival == true) {
b80204
diff --git a/base/kra/src/com/netscape/kra/StorageKeyUnit.java b/base/kra/src/com/netscape/kra/StorageKeyUnit.java
b80204
index 3e7f1de..1df30f6 100644
b80204
--- a/base/kra/src/com/netscape/kra/StorageKeyUnit.java
b80204
+++ b/base/kra/src/com/netscape/kra/StorageKeyUnit.java
b80204
@@ -133,7 +133,7 @@ public class StorageKeyUnit extends EncryptionUnit implements
b80204
         throw new EBaseException(CMS.getUserMessage("CMS_INVALID_OPERATION"));
b80204
     }
b80204
 
b80204
-    public WrappingParams getWrappingParams() throws Exception {
b80204
+    public WrappingParams getWrappingParams(boolean encrypt) throws Exception {
b80204
         String choice = null;
b80204
         try {
b80204
             choice = mConfig.getString(PROP_WRAPPING_CHOICE);
b80204
@@ -177,6 +177,16 @@ public class StorageKeyUnit extends EncryptionUnit implements
b80204
                 KeyRecordParser.OUT_PL_WRAP_IV_LEN);
b80204
         if (iv != null) params.setPayloadWrappingIV(new IVParameterSpec(iv));
b80204
 
b80204
+        if (encrypt) {
b80204
+            // Some HSMs have not yet implemented AES-KW.  Use AES-CBC-PAD instead
b80204
+            if (params.getPayloadWrapAlgorithm().equals(KeyWrapAlgorithm.AES_KEY_WRAP) ||
b80204
+                params.getPayloadWrapAlgorithm().equals(KeyWrapAlgorithm.AES_KEY_WRAP_PAD)) {
b80204
+                params.setPayloadWrapAlgorithm(KeyWrapAlgorithm.AES_CBC_PAD);
b80204
+                iv = CryptoUtil.getNonceData(16);
b80204
+                params.setPayloadWrappingIV(new IVParameterSpec(iv));
b80204
+            }
b80204
+        }
b80204
+
b80204
         return params;
b80204
     }
b80204
 
b80204
diff --git a/base/kra/src/com/netscape/kra/SymKeyGenService.java b/base/kra/src/com/netscape/kra/SymKeyGenService.java
b80204
index c1830ec..bf350d5 100644
b80204
--- a/base/kra/src/com/netscape/kra/SymKeyGenService.java
b80204
+++ b/base/kra/src/com/netscape/kra/SymKeyGenService.java
b80204
@@ -29,6 +29,7 @@ import org.mozilla.jss.crypto.SymmetricKey;
b80204
 
b80204
 import com.netscape.certsrv.apps.CMS;
b80204
 import com.netscape.certsrv.base.EBaseException;
b80204
+import com.netscape.certsrv.base.IConfigStore;
b80204
 import com.netscape.certsrv.dbs.keydb.IKeyRecord;
b80204
 import com.netscape.certsrv.dbs.keydb.IKeyRepository;
b80204
 import com.netscape.certsrv.key.KeyRequestResource;
b80204
@@ -107,6 +108,9 @@ public class SymKeyGenService implements IService {
b80204
             throw new EBaseException("Bad data in SymKeyGenService.serviceRequest");
b80204
         }
b80204
 
b80204
+        IConfigStore configStore = CMS.getConfigStore();
b80204
+        boolean allowEncDecrypt_archival = configStore.getBoolean("kra.allowEncDecrypt.archival", false);
b80204
+
b80204
         CryptoToken token = mStorageUnit.getToken();
b80204
         KeyGenAlgorithm kgAlg = KeyRequestDAO.SYMKEY_GEN_ALGORITHMS.get(algorithm);
b80204
         if (kgAlg == null) {
b80204
@@ -170,8 +174,7 @@ public class SymKeyGenService implements IService {
b80204
         }
b80204
 
b80204
         try {
b80204
-            // TODO(alee) what happens if key wrap algorithm is not supported?
b80204
-            params = mStorageUnit.getWrappingParams();
b80204
+            params = mStorageUnit.getWrappingParams(allowEncDecrypt_archival);
b80204
             privateSecurityData = mStorageUnit.wrap(sk, params);
b80204
         } catch (Exception e) {
b80204
             CMS.debug("Failed to generate security data to archive: " + e);
b80204
diff --git a/base/kra/src/com/netscape/kra/TransportKeyUnit.java b/base/kra/src/com/netscape/kra/TransportKeyUnit.java
b80204
index 513c0b2..fc66e66 100644
b80204
--- a/base/kra/src/com/netscape/kra/TransportKeyUnit.java
b80204
+++ b/base/kra/src/com/netscape/kra/TransportKeyUnit.java
b80204
@@ -115,10 +115,6 @@ public class TransportKeyUnit extends EncryptionUnit implements
b80204
         }
b80204
     }
b80204
 
b80204
-    public WrappingParams getWrappingParams() {
b80204
-        return getOldWrappingParams();
b80204
-    }
b80204
-
b80204
     public CryptoToken getInternalToken() {
b80204
         try {
b80204
             return CryptoManager.getInstance().getInternalKeyStorageToken();
b80204
-- 
b80204
1.8.3.1
b80204
b80204
b80204
From 00c17b3e2f81c9df12e1a89fc85dc2e3d4c3a2b1 Mon Sep 17 00:00:00 2001
b80204
From: Ade Lee <alee@redhat.com>
b80204
Date: Fri, 5 May 2017 21:30:15 -0400
b80204
Subject: [PATCH 09/10] Fix symmetic key retrieval in HSM
b80204
b80204
When using an HSM, AES KeyWrapping is not available and so
b80204
some different code paths were exercised.  Fixing bugs in those
b80204
paths uncovered a case where we were calling unwrapSymmetric()
b80204
with bits and not bytes for the key length.
b80204
b80204
This does not matter for 3DES, where JSS expects a length of 0,
b80204
but very much matters for AES.  Fixing this - and the KeyClient
b80204
to actually use the returned wrapping algorithm to unwrap, allows
b80204
us now to return generated symmetric keys correctly.
b80204
b80204
Bugzilla BZ#1448521
b80204
Pagure: 2690
b80204
b80204
Change-Id: I2c5c87e28f6f36798b16de238bbaa21da90e7890
b80204
---
b80204
 base/common/src/com/netscape/certsrv/key/KeyClient.java   |  4 ++--
b80204
 base/kra/src/com/netscape/kra/EncryptionUnit.java         |  2 +-
b80204
 base/kra/src/com/netscape/kra/SecurityDataProcessor.java  | 12 ++++++++++++
b80204
 base/kra/src/com/netscape/kra/TransportKeyUnit.java       |  4 ++--
b80204
 base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java |  4 ++--
b80204
 5 files changed, 19 insertions(+), 7 deletions(-)
b80204
b80204
diff --git a/base/common/src/com/netscape/certsrv/key/KeyClient.java b/base/common/src/com/netscape/certsrv/key/KeyClient.java
b80204
index 2c99e1c..9a69372 100644
b80204
--- a/base/common/src/com/netscape/certsrv/key/KeyClient.java
b80204
+++ b/base/common/src/com/netscape/certsrv/key/KeyClient.java
b80204
@@ -429,7 +429,7 @@ public class KeyClient extends Client {
b80204
             bytes = crypto.unwrapSymmetricKeyWithSessionKey(
b80204
                     data.getEncryptedData(),
b80204
                     sessionKey,
b80204
-                    wrapAlgorithm,
b80204
+                    KeyWrapAlgorithm.fromString(data.getWrapAlgorithm()),
b80204
                     data.getNonceData(),
b80204
                     data.getAlgorithm(),
b80204
                     data.getSize());
b80204
@@ -446,7 +446,7 @@ public class KeyClient extends Client {
b80204
             bytes = crypto.unwrapAsymmetricKeyWithSessionKey(
b80204
                     data.getEncryptedData(),
b80204
                     sessionKey,
b80204
-                    wrapAlgorithm,
b80204
+                    KeyWrapAlgorithm.fromString(data.getWrapAlgorithm()),
b80204
                     data.getNonceData(),
b80204
                     pubKey);
b80204
         }
b80204
diff --git a/base/kra/src/com/netscape/kra/EncryptionUnit.java b/base/kra/src/com/netscape/kra/EncryptionUnit.java
b80204
index b460c9e..eb8a2f8 100644
b80204
--- a/base/kra/src/com/netscape/kra/EncryptionUnit.java
b80204
+++ b/base/kra/src/com/netscape/kra/EncryptionUnit.java
b80204
@@ -84,7 +84,7 @@ public abstract class EncryptionUnit implements IEncryptionUnit {
b80204
         return CryptoUtil.unwrap(
b80204
                 token,
b80204
                 params.getSkType(),
b80204
-                0,
b80204
+                params.getSkType().equals(SymmetricKey.DES3)? 0: params.getSkLength(),
b80204
                 usage, wrappingKey,
b80204
                 encSymmKey,
b80204
                 params.getSkWrapAlgorithm());
b80204
diff --git a/base/kra/src/com/netscape/kra/SecurityDataProcessor.java b/base/kra/src/com/netscape/kra/SecurityDataProcessor.java
b80204
index 95d07c4..344f376 100644
b80204
--- a/base/kra/src/com/netscape/kra/SecurityDataProcessor.java
b80204
+++ b/base/kra/src/com/netscape/kra/SecurityDataProcessor.java
b80204
@@ -411,6 +411,18 @@ public class SecurityDataProcessor {
b80204
         String payloadWrapName = (String) params.get(IRequest.SECURITY_DATA_PL_WRAPPING_NAME);
b80204
         String transportKeyAlgo = transportUnit.getCertificate().getPublicKey().getAlgorithm();
b80204
 
b80204
+        if (allowEncDecrypt_recovery) {
b80204
+            if (payloadWrapName == null) {
b80204
+                // assume old client
b80204
+                payloadWrapName = "DES3/CBC/Pad";
b80204
+            } else if (payloadWrapName.equals("AES KeyWrap/Padding") ||
b80204
+                    payloadWrapName.equals("AES KeyWrap")) {
b80204
+                // Some HSMs have not implemented AES-KW yet
b80204
+                // Make sure we select an algorithm that is supported.
b80204
+                payloadWrapName = "AES/CBC/PKCS5Padding";
b80204
+            }
b80204
+        }
b80204
+
b80204
         byte[] iv = null;
b80204
         byte[] iv_wrap = null;
b80204
         try {
b80204
diff --git a/base/kra/src/com/netscape/kra/TransportKeyUnit.java b/base/kra/src/com/netscape/kra/TransportKeyUnit.java
b80204
index fc66e66..d0ad8b3 100644
b80204
--- a/base/kra/src/com/netscape/kra/TransportKeyUnit.java
b80204
+++ b/base/kra/src/com/netscape/kra/TransportKeyUnit.java
b80204
@@ -289,7 +289,7 @@ public class TransportKeyUnit extends EncryptionUnit implements
b80204
         SymmetricKey sk = CryptoUtil.unwrap(
b80204
                 token,
b80204
                 params.getSkType(),
b80204
-                0,
b80204
+                params.getSkType().equals(SymmetricKey.DES3)? 0: params.getSkLength(),
b80204
                 SymmetricKey.Usage.DECRYPT,
b80204
                 wrappingKey,
b80204
                 encSymmKey,
b80204
@@ -360,7 +360,7 @@ public class TransportKeyUnit extends EncryptionUnit implements
b80204
         SymmetricKey sk = CryptoUtil.unwrap(
b80204
                 token,
b80204
                 params.getSkType(),
b80204
-                0,
b80204
+                params.getSkType().equals(SymmetricKey.DES3)? 0: params.getSkLength(),
b80204
                 SymmetricKey.Usage.UNWRAP,
b80204
                 wrappingKey,
b80204
                 encSymmKey,
b80204
diff --git a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
b80204
index d22856d..e529a0f 100644
b80204
--- a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
b80204
+++ b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
b80204
@@ -2346,7 +2346,7 @@ public class CryptoUtil {
b80204
             KeyWrapAlgorithm wrapAlgorithm, IVParameterSpec wrappingIV) throws Exception {
b80204
         KeyWrapper wrapper = token.getKeyWrapper(wrapAlgorithm);
b80204
         wrapper.initUnwrap(wrappingKey, wrappingIV);
b80204
-        return wrapper.unwrapSymmetric(wrappedData, keyType, usage, strength);
b80204
+        return wrapper.unwrapSymmetric(wrappedData, keyType, usage, strength/8);
b80204
     }
b80204
 
b80204
     public static SymmetricKey unwrap(CryptoToken token, SymmetricKey.Type keyType,
b80204
@@ -2355,7 +2355,7 @@ public class CryptoUtil {
b80204
         KeyWrapper keyWrapper = token.getKeyWrapper(wrapAlgorithm);
b80204
         keyWrapper.initUnwrap(wrappingKey, null);
b80204
 
b80204
-        return keyWrapper.unwrapSymmetric(wrappedData, keyType, usage, strength);
b80204
+        return keyWrapper.unwrapSymmetric(wrappedData, keyType, usage, strength/8);
b80204
     }
b80204
 
b80204
     public static PrivateKey unwrap(CryptoToken token, PublicKey pubKey, boolean temporary,
b80204
-- 
b80204
1.8.3.1
b80204
b80204
b80204
From c0bb0ee8e36a85673e30352a7205414b215196a5 Mon Sep 17 00:00:00 2001
b80204
From: Christian Heimes <cheimes@redhat.com>
b80204
Date: Mon, 8 May 2017 18:53:26 +0200
b80204
Subject: [PATCH 10/10] pkispawn: wait after final restart
b80204
b80204
The finalization scriptlet now waits after service has been restarted.
b80204
b80204
Change-Id: Id462728386b9d7e6b3364e1651ef6676115dd1de
b80204
Bugzilla: BZ#1446364
b80204
Pagure: 2644
b80204
Signed-off-by: Christian Heimes <cheimes@redhat.com>
b80204
---
b80204
 .travis/40-spawn-ca                                                | 5 -----
b80204
 .travis/50-spawn-kra                                               | 5 -----
b80204
 .../server/python/pki/server/deployment/scriptlets/finalization.py | 7 +++++++
b80204
 3 files changed, 7 insertions(+), 10 deletions(-)
b80204
b80204
diff --git a/.travis/40-spawn-ca b/.travis/40-spawn-ca
b80204
index d6771db..d57e6b7 100755
b80204
--- a/.travis/40-spawn-ca
b80204
+++ b/.travis/40-spawn-ca
b80204
@@ -2,8 +2,3 @@
b80204
 set -e
b80204
 
b80204
 pkispawn -vv -f ${BUILDDIR}/pki/.travis/pki.cfg -s CA
b80204
-
b80204
-echo "Waiting for port 8080"
b80204
-for i in {1..20}; do
b80204
-    curl http://localhost:8080 && break || sleep 1
b80204
-done
b80204
diff --git a/.travis/50-spawn-kra b/.travis/50-spawn-kra
b80204
index 93f2f4c..f7e8fc1 100755
b80204
--- a/.travis/50-spawn-kra
b80204
+++ b/.travis/50-spawn-kra
b80204
@@ -2,8 +2,3 @@
b80204
 set -e
b80204
 
b80204
 pkispawn -vv -f ${BUILDDIR}/pki/.travis/pki.cfg -s KRA
b80204
-
b80204
-echo "Waiting for port 8080"
b80204
-for i in {1..20}; do
b80204
-    curl http://localhost:8080 && break || sleep 1
b80204
-done
b80204
diff --git a/base/server/python/pki/server/deployment/scriptlets/finalization.py b/base/server/python/pki/server/deployment/scriptlets/finalization.py
b80204
index 3dc7f66..941691c 100644
b80204
--- a/base/server/python/pki/server/deployment/scriptlets/finalization.py
b80204
+++ b/base/server/python/pki/server/deployment/scriptlets/finalization.py
b80204
@@ -57,6 +57,13 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
b80204
         # Optionally, programmatically 'restart' the configured PKI instance
b80204
         if config.str2bool(deployer.mdict['pki_restart_configured_instance']):
b80204
             deployer.systemd.restart()
b80204
+            # wait for startup
b80204
+            status = deployer.instance.wait_for_startup(60)
b80204
+            if status is None:
b80204
+                config.pki_log.error(
b80204
+                    "server failed to restart",
b80204
+                    extra=config.PKI_INDENTATION_LEVEL_1)
b80204
+                raise RuntimeError("server failed to restart")
b80204
 
b80204
         # Optionally, 'purge' the entire temporary client infrastructure
b80204
         # including the client NSS security databases and password files
b80204
-- 
b80204
1.8.3.1
b80204