Blob Blame History Raw
From b058ded6f9708edc601041077339947f0f87c19f Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Tue, 15 Nov 2016 21:32:53 +0100
Subject: [PATCH 1/2] Fixed problem installing subordinate CA with HSM in FIPS
 mode.

Due to certutil issue (bug #1393668) the installation code has
been modified to import certificates into the NSS database in
two steps. This workaround is needed to install subordinate CA
with HSM in FIPS mode.

First, the certificate will be imported into the HSM using the
HSM password without the trust attributes. Then, the certificate
will be imported into the internal token using the internal token
password with the trust attributes.

https://fedorahosted.org/pki/ticket/2543
(cherry picked from commit 0bef3bbcc5c5cb2d6fb3f0d231c4f5b7fac5ca3b)
---
 base/common/python/pki/nssdb.py           | 51 ++++++++++++++++++++++++-------
 base/server/python/pki/server/__init__.py |  3 +-
 2 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/base/common/python/pki/nssdb.py b/base/common/python/pki/nssdb.py
index c044ba1..430cacd 100644
--- a/base/common/python/pki/nssdb.py
+++ b/base/common/python/pki/nssdb.py
@@ -99,7 +99,8 @@ def get_file_type(filename):
 
 class NSSDatabase(object):
 
-    def __init__(self, directory=None, token=None, password=None, password_file=None):
+    def __init__(self, directory=None, token=None, password=None, password_file=None,
+                 internal_password=None, internal_password_file=None):
 
         if not directory:
             directory = os.path.join(os.path.expanduser("~"), '.dogtag', 'nssdb')
@@ -124,25 +125,53 @@ class NSSDatabase(object):
         else:
             raise Exception('Missing NSS database password')
 
+        if internal_password:
+            # Store the specified internal token into password file.
+            self.internal_password_file = os.path.join(self.tmpdir, 'internal_password.txt')
+            with open(self.internal_password_file, 'w') as f:
+                f.write(internal_password)
+
+        elif internal_password_file:
+            # Use the specified internal token password file.
+            self.internal_password_file = internal_password_file
+
+        else:
+            # By default use the same password for both internal token and HSM.
+            self.internal_password_file = self.password_file
+
     def close(self):
         shutil.rmtree(self.tmpdir)
 
     def add_cert(self, nickname, cert_file, trust_attributes=',,'):
-        cmd = [
-            'certutil',
-            '-A',
-            '-d', self.directory
-        ]
 
+        # Add cert in two steps due to bug #1393668.
+
+        # First, import cert into HSM without trust attributes.
         if self.token:
-            cmd.extend(['-h', self.token])
+            cmd = [
+                'certutil',
+                '-A',
+                '-d', self.directory,
+                '-h', self.token,
+                '-f', self.password_file,
+                '-n', nickname,
+                '-i', cert_file,
+                '-t', ''
+            ]
 
-        cmd.extend([
-            '-f', self.password_file,
+            # Ignore return code due to bug #1393668.
+            subprocess.call(cmd)
+
+        # Then, import cert into internal token with trust attributes.
+        cmd = [
+            'certutil',
+            '-A',
+            '-d', self.directory,
+            '-f', self.internal_password_file,
             '-n', nickname,
             '-i', cert_file,
             '-t', trust_attributes
-        ])
+        ]
 
         subprocess.check_call(cmd)
 
@@ -584,7 +613,7 @@ class NSSDatabase(object):
                 else:
                     n = '%s #%d' % (nickname, counter)
 
-                self.add_cert(n, cert_file, trust_attributes)
+                self.add_cert(n, cert_file, trust_attributes=trust_attributes)
                 nicks.append(n)
 
                 counter += 1
diff --git a/base/server/python/pki/server/__init__.py b/base/server/python/pki/server/__init__.py
index 13b3258..d556312 100644
--- a/base/server/python/pki/server/__init__.py
+++ b/base/server/python/pki/server/__init__.py
@@ -654,7 +654,8 @@ class PKIInstance(object):
         return pki.nssdb.NSSDatabase(
             directory=self.nssdb_dir,
             token=token,
-            password=self.get_token_password(token))
+            password=self.get_token_password(token),
+            internal_password=self.get_token_password())
 
     def external_cert_exists(self, nickname, token):
         for cert in self.external_certs:
-- 
2.9.3


From c8553a5308e23b66cee7fc1a357042f99d07b0c7 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 16 Nov 2016 03:42:49 +0100
Subject: [PATCH 2/2] Fixed hanging subordinate CA with HSM installation in
 FIPS mode.

When installing subordinate CA with HSM, the installer calls the
pki CLI (which is implemented using JSS) to validate the imported
CA certificate in HSM. Normally, the HSM password is specified as
CLI parameter, but in FIPS mode JSS requires both the HSM and the
internal token passwords. Since the CLI only takes one password,
JSS will prompt for the missing one on the console causing the
installation to hang.

As a temporary solution, the pki-server subsystem-cert-validate
command has been modified to validate certificates stored in the
internal token only and it will use the internal token password,
so only a single password is required. Further investigation in
CLI/JSS/NSS is needed to support validating certificates in HSM
without password prompts.

https://fedorahosted.org/pki/ticket/2543
(cherry picked from commit 65013d222a9e612aaaaf49ee03ceed5d6c154f59)
---
 base/server/python/pki/server/cli/subsystem.py | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/base/server/python/pki/server/cli/subsystem.py b/base/server/python/pki/server/cli/subsystem.py
index 42da26e..04461f2 100644
--- a/base/server/python/pki/server/cli/subsystem.py
+++ b/base/server/python/pki/server/cli/subsystem.py
@@ -951,11 +951,8 @@ class SubsystemCertValidateCLI(pki.cli.CLI):
 
         print('  Token: %s' % token)
 
-        if token and token.lower() in ['internal', 'internal key storage token']:
-            token = None
-
-        # get token password and store in temporary file
-        passwd = instance.get_token_password(token)
+        # get internal token password and store in temporary file
+        passwd = instance.get_token_password()
 
         pwfile_handle, pwfile_path = mkstemp()
         os.write(pwfile_handle, passwd)
@@ -964,15 +961,13 @@ class SubsystemCertValidateCLI(pki.cli.CLI):
         try:
             cmd = ['pki',
                    '-d', instance.nssdb_dir,
-                   '-C', pwfile_path]
-
-            if token:
-                cmd.extend(['--token', token])
+                   '-C', pwfile_path,
+                   'client-cert-validate',
+                   nickname,
+                   '--certusage', usage]
 
-            cmd.extend(['client-cert-validate',
-                        nickname,
-                        '--certusage', usage
-                       ])
+            if self.verbose:
+                print('Command: %s' % cmd)
 
             subprocess.check_output(cmd, stderr=subprocess.STDOUT)
             print('  Status: VALID')
-- 
2.9.3