summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEndi S. Dewata <edewata@redhat.com>2016-03-17 15:23:34 +0100
committerEndi S. Dewata <edewata@redhat.com>2016-04-02 07:48:58 +0200
commit9eba5f33f04348ee4b243d3fc0d095268f824115 (patch)
tree67dddaf27686f295f5ae478dccab9c8ad2b7cb15
parent9bd9548d5c1718ad8159f2134f170649c092a581 (diff)
downloadpki-9eba5f33f04348ee4b243d3fc0d095268f824115.tar.gz
pki-9eba5f33f04348ee4b243d3fc0d095268f824115.tar.xz
pki-9eba5f33f04348ee4b243d3fc0d095268f824115.zip
Added support for cloning 3rd-party CA certificates.
The installation code has been modified such that it imports all CA certificates from the PKCS #12 file for cloning before the server is started using certutil. The user certificates will continue to be imported using the existing JSS code after the server is started. This is necessary since JSS is unable to preserve the CA certificate nicknames. The PKCS12Util has been modified to support multiple certificates with the same nicknames. The pki pkcs12-cert-find has been modified to show certificate ID and another field indicating whether the certificate has a key. The pki pkcs12-cert-export has been modified to accept either certificate nickname or ID. The pki pkcs12-import has been modified to provide options for importing only user certificates or CA certificates. https://fedorahosted.org/pki/ticket/1742
-rw-r--r--base/common/python/pki/cli/pkcs12.py186
-rw-r--r--base/common/python/pki/nssdb.py13
-rw-r--r--base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertCLI.java15
-rw-r--r--base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertExportCLI.java54
-rw-r--r--base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertFindCLI.java10
-rw-r--r--base/server/python/pki/server/deployment/scriptlets/security_databases.py19
-rw-r--r--base/util/src/netscape/security/pkcs/PKCS12.java43
-rw-r--r--base/util/src/netscape/security/pkcs/PKCS12CertInfo.java10
-rw-r--r--base/util/src/netscape/security/pkcs/PKCS12Util.java53
9 files changed, 271 insertions, 132 deletions
diff --git a/base/common/python/pki/cli/pkcs12.py b/base/common/python/pki/cli/pkcs12.py
index dc890c1a5..eaca3c6f8 100644
--- a/base/common/python/pki/cli/pkcs12.py
+++ b/base/common/python/pki/cli/pkcs12.py
@@ -53,6 +53,8 @@ class PKCS12ImportCLI(pki.cli.CLI):
print(' --pkcs12-password <password> Password for the PKCS #12 file.')
print(' --pkcs12-password-file <path> containing the PKCS #12 password.')
print(' --no-trust-flags Do not include trust flags')
+ print(' --no-user-certs Do not import user certificates')
+ print(' --no-ca-certs Do not import CA certificates')
print(' -v, --verbose Run in verbose mode.')
print(' --debug Run in debug mode.')
print(' --help Show help message.')
@@ -63,7 +65,8 @@ class PKCS12ImportCLI(pki.cli.CLI):
try:
opts, _ = getopt.gnu_getopt(args, 'v', [
'pkcs12-file=', 'pkcs12-password=', 'pkcs12-password-file=',
- 'no-trust-flags', 'verbose', 'debug', 'help'])
+ 'no-trust-flags', 'no-user-certs', 'no-ca-certs',
+ 'verbose', 'debug', 'help'])
except getopt.GetoptError as e:
print('ERROR: ' + str(e))
@@ -74,6 +77,9 @@ class PKCS12ImportCLI(pki.cli.CLI):
pkcs12_password = None
password_file = None
no_trust_flags = False
+ import_user_certs = True
+ import_ca_certs = True
+ debug = False
for o, a in opts:
if o == '--pkcs12-file':
@@ -88,9 +94,18 @@ class PKCS12ImportCLI(pki.cli.CLI):
elif o == '--no-trust-flags':
no_trust_flags = True
+ elif o == '--no-user-certs':
+ import_user_certs = False
+
+ elif o == '--no-ca-certs':
+ import_ca_certs = False
+
elif o in ('-v', '--verbose'):
self.set_verbose(True)
+ elif o == '--debug':
+ debug = True
+
elif o == '--help':
self.print_help()
sys.exit()
@@ -119,13 +134,11 @@ class PKCS12ImportCLI(pki.cli.CLI):
if main_cli.verbose:
print('Getting certificate infos in PKCS #12 file')
- ca_certs = []
- user_certs = []
+ 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:
@@ -144,33 +157,28 @@ class PKCS12ImportCLI(pki.cli.CLI):
if no_trust_flags:
cmd.extend(['--no-trust-flags'])
- main_cli.execute_java(cmd, stdout=f)
+ if self.verbose:
+ cmd.extend(['--verbose'])
- # determine cert types
- with open(output_file, 'r') as f:
+ if debug:
+ cmd.extend(['--debug'])
- cert_info = None
+ main_cli.execute_java(cmd, stdout=f)
- for line in f.readlines():
+ # parse results
+ with open(output_file, 'r') as f:
- match = re.match(r' Nickname: (.*)$', line)
+ for line in f:
+ match = re.match(r' Certificate ID: (.*)$', 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)
+ cert_info['id'] = match.group(1)
+ certs.append(cert_info)
continue
- match = re.match(r' Key ID: (.*)$', line)
+ match = re.match(r' Nickname: (.*)$', line)
if match:
- cert_info['key_id'] = match.group(1)
+ cert_info['nickname'] = match.group(1)
continue
match = re.match(r' Trust Flags: (.*)$', line)
@@ -178,74 +186,112 @@ class PKCS12ImportCLI(pki.cli.CLI):
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)
+ match = re.match(r' Has Key: (.*)$', line)
+ if match:
+ cert_info['has_key'] = match.group(1) == 'true'
+ continue
- cert_file = os.path.join(tmpdir, 'ca-cert.pem')
+ finally:
+ shutil.rmtree(tmpdir)
- nssdb = pki.nssdb.NSSDatabase(
- main_cli.database,
- token=main_cli.token,
- password=main_cli.password,
- password_file=main_cli.password_file)
+ # import CA certificates if requested
+ if import_ca_certs:
- for cert_info in ca_certs:
+ if main_cli.verbose:
+ print('Importing CA certificates')
- nickname = cert_info['nickname']
- trust_flags = cert_info['trust_flags']
+ tmpdir = tempfile.mkdtemp()
- if main_cli.verbose:
- print('Exporting %s from PKCS #12 file' % nickname)
+ try:
+ cert_file = os.path.join(tmpdir, 'ca-cert.pem')
- cmd = ['pkcs12-cert-export']
+ nssdb = pki.nssdb.NSSDatabase(
+ main_cli.database,
+ token=main_cli.token,
+ password=main_cli.password,
+ password_file=main_cli.password_file)
- if pkcs12_file:
- cmd.extend(['--pkcs12-file', pkcs12_file])
+ for cert_info in certs:
- if pkcs12_password:
- cmd.extend(['--pkcs12-password', pkcs12_password])
+ has_key = cert_info['has_key']
+ if has_key:
+ continue
- if password_file:
- cmd.extend(['--pkcs12-password-file', password_file])
+ cert_id = cert_info['id']
+ nickname = cert_info['nickname']
+ trust_flags = cert_info['trust_flags']
- cmd.extend(['--cert-file', cert_file, nickname])
+ if main_cli.verbose:
+ print('Exporting %s (%s) from PKCS #12 file' % (nickname, cert_id))
- main_cli.execute_java(cmd)
+ cmd = ['pkcs12-cert-export']
- if main_cli.verbose:
- print('Importing %s' % nickname)
+ if pkcs12_file:
+ cmd.extend(['--pkcs12-file', pkcs12_file])
- nssdb.add_cert(nickname, cert_file, trust_flags)
+ if pkcs12_password:
+ cmd.extend(['--pkcs12-password', pkcs12_password])
- finally:
- shutil.rmtree(tmpdir)
+ if password_file:
+ cmd.extend(['--pkcs12-password-file', password_file])
+
+ cmd.extend(['--cert-file', cert_file])
+
+ cmd.extend(['--cert-id', cert_id])
+
+ if self.verbose:
+ cmd.extend(['--verbose'])
+
+ if debug:
+ cmd.extend(['--debug'])
+
+ 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)
+
+ # import user certificates if requested
+ if import_user_certs:
+
+ if main_cli.verbose:
+ print('Importing user certificates')
+
+ nicknames = []
+ for cert_info in certs:
+
+ has_key = cert_info['has_key']
+ if not has_key:
+ continue
+
+ nickname = cert_info['nickname']
+ if nickname not in nicknames:
+ nicknames.append(nickname)
- # importing user certs
+ cmd = ['pkcs12-import']
- nicknames = []
- for cert_info in user_certs:
- nicknames.append(cert_info['nickname'])
+ if pkcs12_file:
+ cmd.extend(['--pkcs12-file', pkcs12_file])
- cmd = ['pkcs12-import']
+ if pkcs12_password:
+ cmd.extend(['--pkcs12-password', pkcs12_password])
- if pkcs12_file:
- cmd.extend(['--pkcs12-file', pkcs12_file])
+ if password_file:
+ cmd.extend(['--pkcs12-password-file', password_file])
- if pkcs12_password:
- cmd.extend(['--pkcs12-password', pkcs12_password])
+ if no_trust_flags:
+ cmd.extend(['--no-trust-flags'])
- if password_file:
- cmd.extend(['--pkcs12-password-file', password_file])
+ if self.verbose:
+ cmd.extend(['--verbose'])
- if no_trust_flags:
- cmd.extend(['--no-trust-flags'])
+ if debug:
+ cmd.extend(['--debug'])
- cmd.extend(nicknames)
+ cmd.extend(nicknames)
- main_cli.execute_java(cmd)
+ main_cli.execute_java(cmd)
diff --git a/base/common/python/pki/nssdb.py b/base/common/python/pki/nssdb.py
index e6aa0a6c2..f4ce1f240 100644
--- a/base/common/python/pki/nssdb.py
+++ b/base/common/python/pki/nssdb.py
@@ -512,8 +512,11 @@ class NSSDatabase(object):
finally:
shutil.rmtree(tmpdir)
- def import_pkcs12(self, pkcs12_file, pkcs12_password=None,
- pkcs12_password_file=None):
+ def import_pkcs12(self, pkcs12_file,
+ pkcs12_password=None,
+ pkcs12_password_file=None,
+ no_user_certs=False,
+ no_ca_certs=False):
tmpdir = tempfile.mkdtemp()
@@ -544,6 +547,12 @@ class NSSDatabase(object):
'--pkcs12-password-file', password_file
])
+ if no_user_certs:
+ cmd.extend(['--no-user-certs'])
+
+ if no_ca_certs:
+ cmd.extend(['--no-ca-certs'])
+
subprocess.check_call(cmd)
finally:
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 1ed88b1fa..fe7092c00 100644
--- a/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertCLI.java
@@ -18,9 +18,12 @@
package com.netscape.cmstools.pkcs12;
+import java.math.BigInteger;
+
import com.netscape.certsrv.dbs.certdb.CertId;
import com.netscape.cmstools.cli.CLI;
+import netscape.security.pkcs.PKCS12;
import netscape.security.pkcs.PKCS12CertInfo;
/**
@@ -37,18 +40,20 @@ public class PKCS12CertCLI extends CLI {
addModule(new PKCS12CertRemoveCLI(this));
}
- public static void printCertInfo(PKCS12CertInfo certInfo) throws Exception {
+ public static void printCertInfo(PKCS12 pkcs12, PKCS12CertInfo certInfo) throws Exception {
+
+ BigInteger id = certInfo.getID();
+ System.out.println(" Certificate ID: " + id.toString(16));
+
System.out.println(" Serial Number: " + new CertId(certInfo.getCert().getSerialNumber()).toHexString());
System.out.println(" Nickname: " + certInfo.getNickname());
System.out.println(" Subject DN: " + certInfo.getCert().getSubjectDN());
System.out.println(" Issuer DN: " + certInfo.getCert().getIssuerDN());
- if (certInfo.getKeyID() != null) {
- System.out.println(" Key ID: " + certInfo.getKeyID().toString(16));
- }
-
if (certInfo.getTrustFlags() != null) {
System.out.println(" Trust Flags: " + certInfo.getTrustFlags());
}
+
+ System.out.println(" Has Key: " + (pkcs12.getKeyInfoByID(id) != null));
}
}
diff --git a/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertExportCLI.java b/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertExportCLI.java
index 04e2b7b6f..8fb526d48 100644
--- a/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertExportCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertExportCLI.java
@@ -22,6 +22,9 @@ import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.PrintStream;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -50,7 +53,7 @@ public class PKCS12CertExportCLI extends CLI {
}
public void printHelp() {
- formatter.printHelp(getFullName() + " [OPTIONS...] <nickname>", options);
+ formatter.printHelp(getFullName() + " [OPTIONS...] [nickname]", options);
}
public void createOptions() {
@@ -70,6 +73,10 @@ public class PKCS12CertExportCLI extends CLI {
option.setArgName("path");
options.addOption(option);
+ option = new Option(null, "cert-id", true, "Certificate ID to export");
+ option.setArgName("ID");
+ options.addOption(option);
+
options.addOption("v", "verbose", false, "Run in verbose mode.");
options.addOption(null, "debug", false, "Run in debug mode.");
options.addOption(null, "help", false, "Show help message.");
@@ -104,14 +111,28 @@ public class PKCS12CertExportCLI extends CLI {
}
String[] cmdArgs = cmd.getArgs();
+ String id = cmd.getOptionValue("cert-id");
- if (cmdArgs.length < 1) {
- System.err.println("Error: Missing certificate nickname.");
+ if (cmdArgs.length < 1 && id == null) {
+ System.err.println("Error: Missing certificate nickname or ID.");
printHelp();
System.exit(-1);
}
- String nickname = cmdArgs[0];
+ if (cmdArgs.length >= 1 && id != null) {
+ System.err.println("Error: Certificate nickname and ID are mutually exclusive.");
+ printHelp();
+ System.exit(-1);
+ }
+
+ String nickname = null;
+ BigInteger certID = null;
+
+ if (cmdArgs.length >= 1) {
+ nickname = cmdArgs[0];
+ } else {
+ certID = new BigInteger(id, 16);
+ }
String pkcs12File = cmd.getOptionValue("pkcs12-file");
@@ -153,17 +174,30 @@ public class PKCS12CertExportCLI extends CLI {
PKCS12Util util = new PKCS12Util();
PKCS12 pkcs12 = util.loadFromFile(pkcs12File, password);
- PKCS12CertInfo certInfo = pkcs12.getCertInfoByNickname(nickname);
- if (certInfo == null) {
+ Collection<PKCS12CertInfo> certInfos = new ArrayList<PKCS12CertInfo>();
+
+ if (nickname != null) {
+ certInfos.addAll(pkcs12.getCertInfosByNickname(nickname));
+
+ } else {
+ PKCS12CertInfo certInfo = pkcs12.getCertInfoByID(certID);
+ if (certInfo != null) {
+ certInfos.add(certInfo);
+ }
+ }
+
+ if (certInfos.isEmpty()) {
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-----");
+ for (PKCS12CertInfo certInfo : certInfos) {
+ X509CertImpl cert = certInfo.getCert();
+ os.println("-----BEGIN CERTIFICATE-----");
+ os.print(Utils.base64encode(cert.getEncoded()));
+ os.println("-----END CERTIFICATE-----");
+ }
}
} finally {
diff --git a/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertFindCLI.java b/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertFindCLI.java
index a97933188..9bb4ad3ba 100644
--- a/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertFindCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/pkcs12/PKCS12CertFindCLI.java
@@ -133,17 +133,17 @@ public class PKCS12CertFindCLI extends CLI {
Password password = new Password(passwordString.toCharArray());
- Collection<PKCS12CertInfo> certInfos;
+ PKCS12 pkcs12;
try {
PKCS12Util util = new PKCS12Util();
- PKCS12 pkcs12 = util.loadFromFile(filename, password);
-
- certInfos = pkcs12.getCertInfos();
+ pkcs12 = util.loadFromFile(filename, password);
} finally {
password.clear();
}
+ Collection<PKCS12CertInfo> certInfos = pkcs12.getCertInfos();
+
MainCLI.printMessage(certInfos.size() + " entries found");
if (certInfos.size() == 0) return;
@@ -156,7 +156,7 @@ public class PKCS12CertFindCLI extends CLI {
System.out.println();
}
- PKCS12CertCLI.printCertInfo(certInfo);
+ PKCS12CertCLI.printCertInfo(pkcs12, certInfo);
}
}
}
diff --git a/base/server/python/pki/server/deployment/scriptlets/security_databases.py b/base/server/python/pki/server/deployment/scriptlets/security_databases.py
index 0c3d606de..00df1eb33 100644
--- a/base/server/python/pki/server/deployment/scriptlets/security_databases.py
+++ b/base/server/python/pki/server/deployment/scriptlets/security_databases.py
@@ -109,6 +109,25 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
if external_certs_path is not None:
self.update_external_certs_conf(external_certs_path, deployer)
+ # import CA certificates from PKCS #12 file for cloning
+ pki_clone_pkcs12_path = deployer.mdict['pki_clone_pkcs12_path']
+
+ if pki_clone_pkcs12_path:
+
+ pki_clone_pkcs12_password = deployer.mdict[
+ 'pki_clone_pkcs12_password']
+ if not pki_clone_pkcs12_password:
+ raise Exception('Missing pki_clone_pkcs12_password property.')
+
+ nssdb = pki.nssdb.NSSDatabase(
+ directory=deployer.mdict['pki_database_path'],
+ password_file=deployer.mdict['pki_shared_pfile'])
+
+ nssdb.import_pkcs12(
+ pkcs12_file=pki_clone_pkcs12_path,
+ pkcs12_password=pki_clone_pkcs12_password,
+ no_user_certs=True)
+
if len(deployer.instance.tomcat_instance_subsystems()) < 2:
# only create a self signed cert for a new instance
#
diff --git a/base/util/src/netscape/security/pkcs/PKCS12.java b/base/util/src/netscape/security/pkcs/PKCS12.java
index 4f2f1600b..6c7880aa8 100644
--- a/base/util/src/netscape/security/pkcs/PKCS12.java
+++ b/base/util/src/netscape/security/pkcs/PKCS12.java
@@ -18,6 +18,7 @@
package netscape.security.pkcs;
import java.math.BigInteger;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -141,7 +142,7 @@ public class PKCS12 {
Map<BigInteger, PKCS12KeyInfo> keyInfosByID = new LinkedHashMap<BigInteger, PKCS12KeyInfo>();
- Map<String, PKCS12CertInfo> certInfosByNickname = new LinkedHashMap<String, PKCS12CertInfo>();
+ Map<BigInteger, PKCS12CertInfo> certInfosByID = new LinkedHashMap<BigInteger, PKCS12CertInfo>();
public PKCS12() {
}
@@ -163,28 +164,42 @@ public class PKCS12 {
}
public Collection<PKCS12CertInfo> getCertInfos() {
- return certInfosByNickname.values();
+ return certInfosByID.values();
}
public void addCertInfo(PKCS12CertInfo certInfo, boolean replace) {
- String nickname = certInfo.nickname;
- if (!replace && certInfosByNickname.containsKey(nickname))
+ BigInteger id = certInfo.getID();
+
+ if (!replace && certInfosByID.containsKey(id))
return;
- certInfosByNickname.put(nickname, certInfo);
+ certInfosByID.put(id, certInfo);
}
- public PKCS12CertInfo getCertInfoByNickname(String nickname) {
- return certInfosByNickname.get(nickname);
+ public PKCS12CertInfo getCertInfoByID(BigInteger id) {
+ return certInfosByID.get(id);
}
- public PKCS12CertInfo removeCertInfoByNickname(String nickname) {
- // remove cert
- PKCS12CertInfo certInfo = certInfosByNickname.remove(nickname);
- if (certInfo == null) return null;
+ public Collection<PKCS12CertInfo> getCertInfosByNickname(String nickname) {
+
+ Collection<PKCS12CertInfo> result = new ArrayList<PKCS12CertInfo>();
- // remove private key
- keyInfosByID.remove(certInfo.getKeyID());
- return certInfo;
+ for (PKCS12CertInfo certInfo : certInfosByID.values()) {
+ if (!nickname.equals(certInfo.getNickname())) continue;
+ result.add(certInfo);
+ }
+
+ return result;
+ }
+
+ public void removeCertInfoByNickname(String nickname) {
+
+ Collection<PKCS12CertInfo> result = getCertInfosByNickname(nickname);
+
+ for (PKCS12CertInfo certInfo : result) {
+ // remove cert and key
+ certInfosByID.remove(certInfo.getID());
+ keyInfosByID.remove(certInfo.getID());
+ }
}
}
diff --git a/base/util/src/netscape/security/pkcs/PKCS12CertInfo.java b/base/util/src/netscape/security/pkcs/PKCS12CertInfo.java
index 3ac643eb1..ec7b0e332 100644
--- a/base/util/src/netscape/security/pkcs/PKCS12CertInfo.java
+++ b/base/util/src/netscape/security/pkcs/PKCS12CertInfo.java
@@ -23,7 +23,7 @@ import netscape.security.x509.X509CertImpl;
public class PKCS12CertInfo {
- BigInteger keyID;
+ BigInteger id;
X509CertImpl cert;
String nickname;
String trustFlags;
@@ -31,12 +31,12 @@ public class PKCS12CertInfo {
public PKCS12CertInfo() {
}
- public BigInteger getKeyID() {
- return keyID;
+ public BigInteger getID() {
+ return id;
}
- public void setKeyID(BigInteger keyID) {
- this.keyID = keyID;
+ public void setID(BigInteger id) {
+ this.id = id;
}
public X509CertImpl getCert() {
diff --git a/base/util/src/netscape/security/pkcs/PKCS12Util.java b/base/util/src/netscape/security/pkcs/PKCS12Util.java
index 35b9ed598..7c9ab2fb4 100644
--- a/base/util/src/netscape/security/pkcs/PKCS12Util.java
+++ b/base/util/src/netscape/security/pkcs/PKCS12Util.java
@@ -28,6 +28,7 @@ import java.security.MessageDigest;
import java.security.Principal;
import java.security.PublicKey;
import java.security.cert.CertificateException;
+import java.util.Collection;
import java.util.logging.Logger;
import org.mozilla.jss.CryptoManager;
@@ -160,7 +161,7 @@ public class PKCS12Util {
safeContents.addElement(safeBag);
}
- BigInteger createLocalKeyID(X509Certificate cert) throws Exception {
+ BigInteger createLocalID(X509Certificate cert) throws Exception {
// SHA1 hash of the X509Cert DER encoding
byte[] certDer = cert.getEncoded();
@@ -209,12 +210,12 @@ public class PKCS12Util {
attrs.addElement(nicknameAttr);
- if (certInfo.keyID != null) {
+ if (certInfo.getID() != null) {
SEQUENCE localKeyAttr = new SEQUENCE();
localKeyAttr.addElement(SafeBag.LOCAL_KEY_ID);
SET localKeySet = new SET();
- localKeySet.addElement(new OCTET_STRING(certInfo.keyID.toByteArray()));
+ localKeySet.addElement(new OCTET_STRING(certInfo.id.toByteArray()));
localKeyAttr.addElement(localKeySet);
attrs.addElement(localKeyAttr);
@@ -250,24 +251,28 @@ public class PKCS12Util {
public void loadCertFromNSS(PKCS12 pkcs12, String nickname) throws Exception {
CryptoManager cm = CryptoManager.getInstance();
- X509Certificate cert = cm.findCertByNickname(nickname);
- loadCertChainFromNSS(pkcs12, cert);
+
+ X509Certificate[] certs = cm.findCertsByNickname(nickname);
+ for (X509Certificate cert : certs) {
+ loadCertChainFromNSS(pkcs12, cert);
+ }
}
- public void loadCertFromNSS(PKCS12 pkcs12, X509Certificate cert, BigInteger keyID, boolean replace) throws Exception {
+ public void loadCertFromNSS(PKCS12 pkcs12, X509Certificate cert, BigInteger id, boolean replace) throws Exception {
String nickname = cert.getNickname();
logger.info("Loading certificate \"" + nickname + "\" from NSS database");
PKCS12CertInfo certInfo = new PKCS12CertInfo();
- certInfo.keyID = keyID;
+ certInfo.id = id;
certInfo.nickname = nickname;
certInfo.cert = new X509CertImpl(cert.getEncoded());
certInfo.trustFlags = getTrustFlags(cert);
+
pkcs12.addCertInfo(certInfo, replace);
}
- public void loadCertKeyFromNSS(PKCS12 pkcs12, X509Certificate cert, BigInteger keyID) throws Exception {
+ public void loadCertKeyFromNSS(PKCS12 pkcs12, X509Certificate cert, BigInteger id) throws Exception {
String nickname = cert.getNickname();
logger.info("Loading private key for certificate \"" + nickname + "\" from NSS database");
@@ -279,7 +284,7 @@ public class PKCS12Util {
logger.fine("Certificate \"" + nickname + "\" has private key");
PKCS12KeyInfo keyInfo = new PKCS12KeyInfo();
- keyInfo.id = keyID;
+ keyInfo.id = id;
keyInfo.subjectDN = cert.getSubjectDN().toString();
byte[] privateData = getEncodedKey(privateKey);
@@ -297,17 +302,20 @@ public class PKCS12Util {
CryptoManager cm = CryptoManager.getInstance();
- BigInteger keyID = createLocalKeyID(cert);
+ BigInteger id = createLocalID(cert);
- // load cert with key
- loadCertFromNSS(pkcs12, cert, keyID, true);
- loadCertKeyFromNSS(pkcs12, cert, keyID);
+ // load cert key if exists
+ loadCertKeyFromNSS(pkcs12, cert, id);
+
+ // load cert
+ loadCertFromNSS(pkcs12, cert, id, true);
// 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, null, false);
+ BigInteger cid = createLocalID(c);
+ loadCertFromNSS(pkcs12, c, cid, false);
}
}
@@ -379,7 +387,7 @@ public class PKCS12Util {
OCTET_STRING keyID = (OCTET_STRING) new OCTET_STRING.Template().decode(bis);
keyInfo.id = new BigInteger(1, keyID.toByteArray());
- logger.fine("Key ID: " + keyInfo.id.toString(16));
+ logger.fine("ID: " + keyInfo.id.toString(16));
}
}
@@ -428,8 +436,8 @@ public class PKCS12Util {
ByteArrayInputStream bis = new ByteArrayInputStream(value.getEncoded());
OCTET_STRING keyID = (OCTET_STRING) new OCTET_STRING.Template().decode(bis);
- certInfo.keyID = new BigInteger(1, keyID.toByteArray());
- logger.fine("Key ID: " + certInfo.keyID.toString(16));
+ certInfo.id = new BigInteger(1, keyID.toByteArray());
+ logger.fine("ID: " + certInfo.id.toString(16));
} else if (oid.equals(PKCS12.CERT_TRUST_FLAGS_OID) && trustFlagsEnabled) {
@@ -596,8 +604,8 @@ public class PKCS12Util {
CryptoManager cm = CryptoManager.getInstance();
X509Certificate cert;
- BigInteger keyID = certInfo.getKeyID();
- PKCS12KeyInfo keyInfo = keyID == null ? null : pkcs12.getKeyInfoByID(keyID);
+ BigInteger id = certInfo.getID();
+ PKCS12KeyInfo keyInfo = pkcs12.getKeyInfoByID(id);
if (keyInfo != null) { // cert has key
logger.fine("Importing user key for " + certInfo.nickname);
@@ -608,6 +616,7 @@ public class PKCS12Util {
} else { // cert has no key
logger.fine("Importing CA certificate " + certInfo.nickname);
+ // Note: JSS does not preserve CA certificate nickname
cert = cm.importCACertPackage(certInfo.cert.getEncoded());
}
@@ -616,8 +625,10 @@ public class PKCS12Util {
}
public void storeCertIntoNSS(PKCS12 pkcs12, String nickname) throws Exception {
- PKCS12CertInfo certInfo = pkcs12.getCertInfoByNickname(nickname);
- storeCertIntoNSS(pkcs12, certInfo);
+ Collection<PKCS12CertInfo> certInfos = pkcs12.getCertInfosByNickname(nickname);
+ for (PKCS12CertInfo certInfo : certInfos) {
+ storeCertIntoNSS(pkcs12, certInfo);
+ }
}
public void storeIntoNSS(PKCS12 pkcs12) throws Exception {