[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Pki-devel] [PATCH] 692 Added workaround for JSS limitation in pki pkcs12-import.



Currently JSS is unable to import CA certificates while preserving
their nicknames. As a workaround, the pki pkcs12-import has been
modified such that it exports individual CA certificates from PKCS
The remaining user certificates will continue to be imported using
JSS.

A new pki pkcs12-cert-export command has been added to export
individual certificates from PKCS #12 file into PEM files.

The pki pkcs12-import has been modified to take a list of nicknames
of the certificates to be imported into NSS database.

https://fedorahosted.org/pki/ticket/1742

Note:

This patch depends on patch #690 and #691.

This patch completes the fix of this ticket as described in the following page except for the third-party certificate handling (see discussion below):
http://pki.fedoraproject.org/wiki/Exporting_System_Certificates

To test this patch, install a CA with externally signed CA:
http://pki.fedoraproject.org/wiki/Installing_CA_with_Externaly-Signed_CA_Certificate

Then clone the CA:
http://pki.fedoraproject.org/wiki/Installing_CA_Clone

Verify that the certificates on the master and replica are identical including their nicknames.

To handle proxy certificate for IPA, we can either implement the cs.thirdparty.cert properties as described in the above page, but IPA would have to add the properties during the installation. Also IPA would have to add the properties to all existing installations. Then IPA needs to call pki-server ca-clone-prepare to export the certificates for cloning. If the properties exist, the command will need to export the third-party certificates into the PKCS #12 file along with other CA certs. Then IPA will need to add the same properties into the clone.

Or, IPA can manage the proxy certificate themselves. Since IPA has already added the proxy cert into master, IPA can also add the proxy cert into the PKCS #12 file generated by pki-server ca-clone-prepare using this command:

pki -d /var/lib/pki/pki-tomcat/alias -C nssdb-password.txt \
 pkcs12-cert-add "subsystemCert cert-pki-tomcat" \
  --pkcs12 pki-server.p12 \
  --pkcs12-password-file password.txt

With the second option there's no further changes required in PKI.

--
Endi S. Dewata
>From f69eebb3fc15f5357330dcbe952704859378be50 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata redhat com>
Date: Thu, 25 Feb 2016 21:31:24 +0100
Subject: [PATCH] Added workaround for JSS limitation in pki pkcs12-import.

Currently JSS is unable to import CA certificates while preserving
their nicknames. As a workaround, the pki pkcs12-import has been
modified such that it exports individual CA certificates from PKCS
The remaining user certificates will continue to be imported using
JSS.

A new pki pkcs12-cert-export command has been added to export
individual certificates from PKCS #12 file into PEM files.

The pki pkcs12-import has been modified to take a list of nicknames
of the certificates to be imported into NSS database.

https://fedorahosted.org/pki/ticket/1742
---
 base/common/python/pki/cli/pkcs12.py               | 127 +++++++++++++++++++++
 base/common/python/pki/nssdb.py                    |  76 ++++++++----
 .../netscape/cmstools/pkcs12/PKCS12CertCLI.java    |   3 +-
 ...CS12ImportCLI.java => PKCS12CertExportCLI.java} |  66 ++++++++---
 .../netscape/cmstools/pkcs12/PKCS12ImportCLI.java  |  16 ++-
 .../src/netscape/security/pkcs/PKCS12Util.java     |  65 +++++------
 6 files changed, 278 insertions(+), 75 deletions(-)
 copy base/java-tools/src/com/netscape/cmstools/pkcs12/{PKCS12ImportCLI.java => PKCS12CertExportCLI.java} (65%)

diff --git a/base/common/python/pki/cli/pkcs12.py b/base/common/python/pki/cli/pkcs12.py
index c0bf9aff0fdfacbeb2d30326e668b450ff2bc983..a57dfd9bafe0827bcd3ddb9b5e1c447cf9d4e6cb 100644
--- a/base/common/python/pki/cli/pkcs12.py
+++ b/base/common/python/pki/cli/pkcs12.py
@@ -21,9 +21,14 @@
 from __future__ import absolute_import
 from __future__ import print_function
 import getopt
+import os
+import re
+import shutil
 import sys
+import tempfile
 
 import pki.cli
+import pki.nssdb
 
 
 class PKCS12CLI(pki.cli.CLI):
@@ -107,6 +112,126 @@ class PKCS12ImportCLI(pki.cli.CLI):
 
         main_cli = self.parent.parent
 
+        # Due to JSS limitation, CA certificates need to be imported
+        # using certutil in order to preserve the nickname stored in
+        # the PKCS #12 file.
+
+        if main_cli.verbose:
+            print('Getting certificate infos in PKCS #12 file')
+
+        ca_certs = []
+        user_certs = []
+
+        tmpdir = tempfile.mkdtemp()
+
+        try:
+
+            # find all certs in PKCS #12 file
+            output_file = os.path.join(tmpdir, 'pkcs12-cert-find.txt')
+            with open(output_file, 'wb') as f:
+
+                cmd = ['pkcs12-cert-find']
+
+                if pkcs12_file:
+                    cmd.extend(['--pkcs12', pkcs12_file])
+
+                if pkcs12_password:
+                    cmd.extend(['--pkcs12-password', pkcs12_password])
+
+                if password_file:
+                    cmd.extend(['--pkcs12-password-file', password_file])
+
+                if no_trust_flags:
+                    cmd.extend(['--no-trust-flags'])
+
+                main_cli.execute_java(cmd, stdout=f)
+
+            # determine cert types
+            with open(output_file, 'r') as f:
+
+                cert_info = None
+
+                for line in f.readlines():
+
+                    match = re.match(r'  Nickname: (.*)$', line)
+                    if match:
+                        # store previous cert
+                        if cert_info:
+                            if 'key_id' in cert_info:
+                                # if cert has key, it's a user cert
+                                user_certs.append(cert_info)
+                            else:
+                                # otherwise it's a CA cert
+                                ca_certs.append(cert_info)
+
+                        cert_info = {}
+                        cert_info['nickname'] = match.group(1)
+                        continue
+
+                    match = re.match(r'  Key ID: (.*)$', line)
+                    if match:
+                        cert_info['key_id'] = match.group(1)
+                        continue
+
+                    match = re.match(r'  Trust Flags: (.*)$', line)
+                    if match:
+                        cert_info['trust_flags'] = match.group(1)
+                        continue
+
+                # store last cert
+                if cert_info:
+                    if 'key_id' in cert_info:
+                        # if cert has key, it's a user cert
+                        user_certs.append(cert_info)
+                    else:
+                        # otherwise it's a CA cert
+                        ca_certs.append(cert_info)
+
+            cert_file = os.path.join(tmpdir, 'ca-cert.pem')
+
+            nssdb = pki.nssdb.NSSDatabase(
+                main_cli.database,
+                token=main_cli.token,
+                password=main_cli.password,
+                password_file=main_cli.password_file)
+
+            for cert_info in ca_certs:
+
+                nickname = cert_info['nickname']
+                trust_flags = cert_info['trust_flags']
+
+                if main_cli.verbose:
+                    print('Exporting %s from PKCS #12 file' % nickname)
+
+                cmd = ['pkcs12-cert-export']
+
+                if pkcs12_file:
+                    cmd.extend(['--pkcs12', pkcs12_file])
+
+                if pkcs12_password:
+                    cmd.extend(['--pkcs12-password', pkcs12_password])
+
+                if password_file:
+                    cmd.extend(['--pkcs12-password-file', password_file])
+
+                cmd.extend(['--cert-file', cert_file, nickname])
+
+                main_cli.execute_java(cmd)
+
+                if main_cli.verbose:
+                    print('Importing %s' % nickname)
+
+                nssdb.add_cert(nickname, cert_file, trust_flags)
+
+        finally:
+            shutil.rmtree(tmpdir)
+
+        # importing user certs
+
+        nicknames = []
+        for cert_info in user_certs:
+            nicknames.append(cert_info['nickname'])
+
         cmd = ['pkcs12-import']
 
         if pkcs12_file:
@@ -121,4 +246,6 @@ class PKCS12ImportCLI(pki.cli.CLI):
         if no_trust_flags:
             cmd.extend(['--no-trust-flags'])
 
+        cmd.extend(nicknames)
+
         main_cli.execute_java(cmd)
diff --git a/base/common/python/pki/nssdb.py b/base/common/python/pki/nssdb.py
index e290727bad4cee9861a39592aac0ae3695ddaee0..b2cf9f1cf0ceaa06a5b1df193bd9aef9da0525f7 100644
--- a/base/common/python/pki/nssdb.py
+++ b/base/common/python/pki/nssdb.py
@@ -98,7 +98,11 @@ def get_file_type(filename):
 
 class NSSDatabase(object):
 
-    def __init__(self, directory, token='internal', password=None, password_file=None):
+    def __init__(self, directory=None, token=None, password=None, password_file=None):
+
+        if not directory:
+            directory = os.path.join(os.path.expanduser("~"), '.dogtag', 'nssdb')
+
         self.directory = directory
         self.token = token
 
@@ -122,13 +126,18 @@ class NSSDatabase(object):
         cmd = [
             'certutil',
             '-A',
-            '-d', self.directory,
-            '-h', self.token,
+            '-d', self.directory
+        ]
+
+        if self.token:
+            cmd.extend(['-h', self.token])
+
+        cmd.extend([
             '-f', self.password_file,
             '-n', nickname,
             '-i', cert_file,
             '-t', trust_attributes
-        ]
+        ])
 
         subprocess.check_call(cmd)
 
@@ -136,12 +145,17 @@ class NSSDatabase(object):
         cmd = [
             'certutil',
             '-M',
-            '-d', self.directory,
-            '-h', self.token,
+            '-d', self.directory
+        ]
+
+        if self.token:
+            cmd.extend(['-h', self.token])
+
+        cmd.extend([
             '-f', self.password_file,
             '-n', nickname,
             '-t', trust_attributes
-        ]
+        ])
 
         subprocess.check_call(cmd)
 
@@ -174,13 +188,18 @@ class NSSDatabase(object):
             cmd = [
                 'certutil',
                 '-R',
-                '-d', self.directory,
-                '-h', self.token,
+                '-d', self.directory
+            ]
+
+            if self.token:
+                cmd.extend(['-h', self.token])
+
+            cmd.extend([
                 '-f', self.password_file,
                 '-s', subject_dn,
                 '-o', binary_request_file,
                 '-z', noise_file
-            ]
+            ])
 
             if key_type:
                 cmd.extend(['-k', key_type])
@@ -222,8 +241,13 @@ class NSSDatabase(object):
             'certutil',
             '-C',
             '-x',
-            '-d', self.directory,
-            '-h', self.token,
+            '-d', self.directory
+        ]
+
+        if self.token:
+            cmd.extend(['-h', self.token])
+
+        cmd.extend([
             '-f', self.password_file,
             '-c', subject_dn,
             '-a',
@@ -236,7 +260,7 @@ class NSSDatabase(object):
             '-3',
             '--extSKID',
             '--extAIA'
-        ]
+        ])
 
         p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                              stderr=subprocess.STDOUT)
@@ -316,12 +340,17 @@ class NSSDatabase(object):
         cmd = [
             'certutil',
             '-L',
-            '-d', self.directory,
-            '-h', self.token,
+            '-d', self.directory
+        ]
+
+        if self.token:
+            cmd.extend(['-h', self.token])
+
+        cmd.extend([
             '-f', self.password_file,
             '-n', nickname,
             output_format_option
-        ]
+        ])
 
         cert_data = subprocess.check_output(cmd)
 
@@ -335,11 +364,16 @@ class NSSDatabase(object):
         cmd = [
             'certutil',
             '-D',
-            '-d', self.directory,
-            '-h', self.token,
+            '-d', self.directory
+        ]
+
+        if self.token:
+            cmd.extend(['-h', self.token])
+
+        cmd.extend([
             '-f', self.password_file,
             '-n', nickname
-        ]
+        ])
 
         subprocess.check_call(cmd)
 
@@ -476,7 +510,7 @@ class NSSDatabase(object):
                 '-C', self.password_file
             ]
 
-            if self.token and self.token != 'internal':
+            if self.token:
                 cmd.extend(['--token', self.token])
 
             cmd.extend([
@@ -513,7 +547,7 @@ class NSSDatabase(object):
                 '-C', self.password_file
             ]
 
-            if self.token and self.token != 'internal':
+            if self.token:
                 cmd.extend(['--token', self.token])
 
             cmd.extend(['pkcs12-export'])
diff --git a/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertCLI.java b/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertCLI.java
index 934b799dc0da58797034ee1e0106e915314e7148..1ed88b1fa40f90594498f8c24d02d011e4f86c20 100644
--- a/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertCLI.java
@@ -32,6 +32,7 @@ public class PKCS12CertCLI extends CLI {
         super("cert", "PKCS #12 certificate management commands", parent);
 
         addModule(new PKCS12CertAddCLI(this));
+        addModule(new PKCS12CertExportCLI(this));
         addModule(new PKCS12CertFindCLI(this));
         addModule(new PKCS12CertRemoveCLI(this));
     }
@@ -47,7 +48,7 @@ public class PKCS12CertCLI extends CLI {
         }
 
         if (certInfo.getTrustFlags() != null) {
-            System.out.println("  Trust flags: " + certInfo.getTrustFlags());
+            System.out.println("  Trust Flags: " + certInfo.getTrustFlags());
         }
     }
 }
diff --git a/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12ImportCLI.java b/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertExportCLI.java
similarity index 65%
copy from base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12ImportCLI.java
copy to base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertExportCLI.java
index 3e42efcbcf79db65018f21d287afe6e112292dd2..c8ceab75778d0a8e257d36b240b91056104a1f91 100644
--- a/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12ImportCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertExportCLI.java
@@ -15,36 +15,42 @@
 // (C) 2016 Red Hat, Inc.
 // All rights reserved.
 // --- END COPYRIGHT BLOCK ---
+
 package com.netscape.cmstools.pkcs12;
 
 import java.io.BufferedReader;
+import java.io.FileOutputStream;
 import java.io.FileReader;
+import java.io.PrintStream;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Option;
+import org.apache.commons.cli.ParseException;
 import org.mozilla.jss.util.Password;
 
 import com.netscape.cmstools.cli.CLI;
-import com.netscape.cmstools.cli.MainCLI;
+import com.netscape.cmsutil.util.Utils;
 
 import netscape.security.pkcs.PKCS12;
+import netscape.security.pkcs.PKCS12CertInfo;
 import netscape.security.pkcs.PKCS12Util;
+import netscape.security.x509.X509CertImpl;
 
 /**
- * Tool for importing NSS database from PKCS #12 file
+ * @author Endi S. Dewata
  */
-public class PKCS12ImportCLI extends CLI {
+public class PKCS12CertExportCLI extends CLI {
 
-    public PKCS12ImportCLI(PKCS12CLI certCLI) {
-        super("import", "Import PKCS #12 file into NSS database", certCLI);
+    public PKCS12CertExportCLI(PKCS12CertCLI certCLI) {
+        super("export", "Export certificate from PKCS #12 file", certCLI);
 
         createOptions();
     }
 
     public void printHelp() {
-        formatter.printHelp(getFullName() + " [OPTIONS...]", options);
+        formatter.printHelp(getFullName() + " [OPTIONS...] <nickname>", options);
     }
 
     public void createOptions() {
@@ -60,7 +66,9 @@ public class PKCS12ImportCLI extends CLI {
         option.setArgName("path");
         options.addOption(option);
 
-        options.addOption(null, "no-trust-flags", false, "Do not include trust flags");
+        option = new Option(null, "cert-file", true, "Certificate file");
+        option.setArgName("path");
+        options.addOption(option);
 
         options.addOption("v", "verbose", false, "Run in verbose mode.");
         options.addOption(null, "debug", false, "Run in debug mode.");
@@ -72,8 +80,8 @@ public class PKCS12ImportCLI extends CLI {
         CommandLine cmd = null;
 
         try {
-            cmd = parser.parse(options, args, true);
-        } catch (Exception e) {
+            cmd = parser.parse(options, args);
+        } catch (ParseException e) {
             System.err.println("Error: " + e.getMessage());
             printHelp();
             System.exit(-1);
@@ -95,9 +103,19 @@ public class PKCS12ImportCLI extends CLI {
             Logger.getLogger("netscape").setLevel(Level.FINE);
         }
 
-        String filename = cmd.getOptionValue("pkcs12");
+        String[] cmdArgs = cmd.getArgs();
 
-        if (filename == null) {
+        if (cmdArgs.length < 1) {
+            System.err.println("Error: Missing certificate nickname.");
+            printHelp();
+            System.exit(-1);
+        }
+
+        String nickname = cmdArgs[0];
+
+        String pkcs12File = cmd.getOptionValue("pkcs12");
+
+        if (pkcs12File == null) {
             System.err.println("Error: Missing PKCS #12 file.");
             printHelp();
             System.exit(-1);
@@ -123,19 +141,33 @@ public class PKCS12ImportCLI extends CLI {
 
         Password password = new Password(passwordString.toCharArray());
 
-        boolean trustFlagsEnabled = !cmd.hasOption("no-trust-flags");
+        String certFile = cmd.getOptionValue("cert-file");
+
+        if (certFile == null) {
+            System.err.println("Error: Missing certificate file.");
+            printHelp();
+            System.exit(-1);
+        }
 
         try {
             PKCS12Util util = new PKCS12Util();
-            util.setTrustFlagsEnabled(trustFlagsEnabled);
+            PKCS12 pkcs12 = util.loadFromFile(pkcs12File, password);
 
-            PKCS12 pkcs12 = util.loadFromFile(filename, password);
-            util.storeIntoNSS(pkcs12, password);
+            PKCS12CertInfo certInfo = pkcs12.getCertInfoByNickname(nickname);
+            if (certInfo == null) {
+                System.err.println("Error: Certificate not found.");
+                System.exit(-1);
+            }
+
+            X509CertImpl cert = certInfo.getCert();
+            try (PrintStream os = new PrintStream(new FileOutputStream(certFile))) {
+                os.println("-----BEGIN CERTIFICATE-----");
+                os.print(Utils.base64encode(cert.getEncoded()));
+                os.println("-----END CERTIFICATE-----");
+            }
 
         } finally {
             password.clear();
         }
-
-        MainCLI.printMessage("Import complete");
     }
 }
diff --git a/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12ImportCLI.java b/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12ImportCLI.java
index 3e42efcbcf79db65018f21d287afe6e112292dd2..bdd8f52bc0a53824189e03df3c047a3b11c83bcf 100644
--- a/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12ImportCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12ImportCLI.java
@@ -44,7 +44,7 @@ public class PKCS12ImportCLI extends CLI {
     }
 
     public void printHelp() {
-        formatter.printHelp(getFullName() + " [OPTIONS...]", options);
+        formatter.printHelp(getFullName() + " [OPTIONS...] [nicknames...]", options);
     }
 
     public void createOptions() {
@@ -95,6 +95,7 @@ public class PKCS12ImportCLI extends CLI {
             Logger.getLogger("netscape").setLevel(Level.FINE);
         }
 
+        String[] nicknames = cmd.getArgs();
         String filename = cmd.getOptionValue("pkcs12");
 
         if (filename == null) {
@@ -130,7 +131,18 @@ public class PKCS12ImportCLI extends CLI {
             util.setTrustFlagsEnabled(trustFlagsEnabled);
 
             PKCS12 pkcs12 = util.loadFromFile(filename, password);
-            util.storeIntoNSS(pkcs12, password);
+
+            if (nicknames.length == 0) {
+                // store all certificates
+                util.storeIntoNSS(pkcs12);
+
+            } else {
+                // load specified certificates
+                for (String nickname : nicknames) {
+                    util.storeCertIntoNSS(pkcs12, nickname);
+                }
+            }
+
 
         } finally {
             password.clear();
diff --git a/base/util/src/netscape/security/pkcs/PKCS12Util.java b/base/util/src/netscape/security/pkcs/PKCS12Util.java
index 665998e2fed640b8f99add3b5645f9094415ce06..b2c8f8667a4dddc4f2a565bb8fe7488cf8c3d6ce 100644
--- a/base/util/src/netscape/security/pkcs/PKCS12Util.java
+++ b/base/util/src/netscape/security/pkcs/PKCS12Util.java
@@ -209,14 +209,16 @@ public class PKCS12Util {
 
         attrs.addElement(nicknameAttr);
 
-        SEQUENCE localKeyAttr = new SEQUENCE();
-        localKeyAttr.addElement(SafeBag.LOCAL_KEY_ID);
+        if (certInfo.keyID != null) {
+            SEQUENCE localKeyAttr = new SEQUENCE();
+            localKeyAttr.addElement(SafeBag.LOCAL_KEY_ID);
 
-        SET localKeySet = new SET();
-        localKeySet.addElement(new OCTET_STRING(certInfo.keyID.toByteArray()));
-        localKeyAttr.addElement(localKeySet);
+            SET localKeySet = new SET();
+            localKeySet.addElement(new OCTET_STRING(certInfo.keyID.toByteArray()));
+            localKeyAttr.addElement(localKeySet);
 
-        attrs.addElement(localKeyAttr);
+            attrs.addElement(localKeyAttr);
+        }
 
         if (certInfo.trustFlags != null && trustFlagsEnabled) {
             SEQUENCE trustFlagsAttr = new SEQUENCE();
@@ -252,13 +254,11 @@ public class PKCS12Util {
         loadCertChainFromNSS(pkcs12, cert);
     }
 
-    public void loadCertFromNSS(PKCS12 pkcs12, X509Certificate cert) throws Exception {
+    public void loadCertFromNSS(PKCS12 pkcs12, X509Certificate cert, BigInteger keyID) throws Exception {
 
         String nickname = cert.getNickname();
         logger.info("Loading certificate \"" + nickname + "\" from NSS database");
 
-        BigInteger keyID = createLocalKeyID(cert);
-
         PKCS12CertInfo certInfo = new PKCS12CertInfo();
         certInfo.keyID = keyID;
         certInfo.nickname = nickname;
@@ -267,7 +267,7 @@ public class PKCS12Util {
         pkcs12.addCertInfo(certInfo);
     }
 
-    public void loadCertKeyFromNSS(PKCS12 pkcs12, X509Certificate cert) throws Exception {
+    public void loadCertKeyFromNSS(PKCS12 pkcs12, X509Certificate cert, BigInteger keyID) throws Exception {
 
         String nickname = cert.getNickname();
         logger.info("Loading private key for certificate \"" + nickname + "\" from NSS database");
@@ -278,10 +278,8 @@ public class PKCS12Util {
             PrivateKey privateKey = cm.findPrivKeyByCert(cert);
             logger.fine("Certificate \"" + nickname + "\" has private key");
 
-            PKCS12CertInfo certInfo = pkcs12.getCertInfoByNickname(nickname);
-
             PKCS12KeyInfo keyInfo = new PKCS12KeyInfo();
-            keyInfo.id = certInfo.getKeyID();
+            keyInfo.id = keyID;
             keyInfo.subjectDN = cert.getSubjectDN().toString();
 
             byte[] privateData = getEncodedKey(privateKey);
@@ -299,15 +297,17 @@ public class PKCS12Util {
 
         CryptoManager cm = CryptoManager.getInstance();
 
+        BigInteger keyID = createLocalKeyID(cert);
+
         // load cert with key
-        loadCertFromNSS(pkcs12, cert);
-        loadCertKeyFromNSS(pkcs12, cert);
+        loadCertFromNSS(pkcs12, cert, keyID);
+        loadCertKeyFromNSS(pkcs12, cert, keyID);
 
         // load parent certs without key
         X509Certificate[] certChain = cm.buildCertificateChain(cert);
         for (int i = 1; i < certChain.length; i++) {
             X509Certificate c = certChain[i];
-            loadCertFromNSS(pkcs12, c);
+            loadCertFromNSS(pkcs12, c, null);
         }
     }
 
@@ -591,21 +591,19 @@ public class PKCS12Util {
         wrapper.unwrapPrivate(encpkey, getPrivateKeyType(publicKey), publicKey);
     }
 
-    public void importKeys(PKCS12 pkcs12) throws Exception {
-
-        for (PKCS12KeyInfo keyInfo : pkcs12.getKeyInfos()) {
-            importKey(pkcs12, keyInfo);
-        }
-    }
-
-    public void importCert(PKCS12 pkcs12, PKCS12CertInfo certInfo) throws Exception {
+    public void storeCertIntoNSS(PKCS12 pkcs12, PKCS12CertInfo certInfo) throws Exception {
 
         CryptoManager cm = CryptoManager.getInstance();
 
         X509Certificate cert;
+        BigInteger keyID = certInfo.getKeyID();
+        PKCS12KeyInfo keyInfo = keyID == null ? null : pkcs12.getKeyInfoByID(keyID);
 
-        if (pkcs12.getKeyInfoByID(certInfo.getKeyID()) != null) { // cert has key
-            logger.fine("Importing user CA certificate " + certInfo.nickname);
+        if (keyInfo != null) { // cert has key
+            logger.fine("Importing user key for " + certInfo.nickname);
+            importKey(pkcs12, keyInfo);
+
+            logger.fine("Importing user certificate " + certInfo.nickname);
             cert = cm.importUserCACertPackage(certInfo.cert.getEncoded(), certInfo.nickname);
 
         } else { // cert has no key
@@ -617,18 +615,17 @@ public class PKCS12Util {
             setTrustFlags(cert, certInfo.trustFlags);
     }
 
-    public void importCerts(PKCS12 pkcs12) throws Exception {
-
-        for (PKCS12CertInfo certInfo : pkcs12.getCertInfos()) {
-            importCert(pkcs12, certInfo);
-        }
+    public void storeCertIntoNSS(PKCS12 pkcs12, String nickname) throws Exception {
+        PKCS12CertInfo certInfo = pkcs12.getCertInfoByNickname(nickname);
+        storeCertIntoNSS(pkcs12, certInfo);
     }
 
-    public void storeIntoNSS(PKCS12 pkcs12, Password password) throws Exception {
+    public void storeIntoNSS(PKCS12 pkcs12) throws Exception {
 
         logger.info("Storing data into NSS database");
 
-        importKeys(pkcs12);
-        importCerts(pkcs12);
+        for (PKCS12CertInfo certInfo : pkcs12.getCertInfos()) {
+            storeCertIntoNSS(pkcs12, certInfo);
+        }
     }
 }
-- 
2.4.3


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]