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

Re: [Pki-devel] [PATCH] 807-809 Fixed PKCS #12 import for cloning.



On 8/3/2016 7:39 PM, Endi Sukma Dewata wrote:
To fix cloning issue in IPA the security_database.py has been
modified to import all certificates and keys in the PKCS #12 file
before the PKI server is started. Since the PKCS #12 generated by
IPA may not contain the certificate trust flags, the script will
also reset the trust flags on the imported certificates (i.e.
CT,C,C for CA certificate and u,u,Pu for audit certificate).

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

Patch #808 has been updated to add pkcs12.show_certs() and nssdb.show_certs(). Patch #809 has been rebased.

--
Endi S. Dewata
>From 9372c37219e403b3a66f2ab7c47c582971138779 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata redhat com>
Date: Mon, 1 Aug 2016 22:35:32 +0200
Subject: [PATCH] Added log messages for certificate import during cloning.

To help troubleshooting cloning issues the security_databases.py
has been modified to log the content of the PKCS #12 file before
import and the NSS database after import.

https://fedorahosted.org/pki/ticket/2424
---
 base/common/python/pki/nssdb.py                    | 10 ++++
 base/common/python/pki/pkcs12.py                   | 68 ++++++++++++++++++++++
 .../deployment/scriptlets/security_databases.py    | 38 +++++++++---
 3 files changed, 109 insertions(+), 7 deletions(-)
 create mode 100644 base/common/python/pki/pkcs12.py

diff --git a/base/common/python/pki/nssdb.py b/base/common/python/pki/nssdb.py
index a0b0302140f6928fa809afaeedd62471ddb0afde..ed456540b7174284a0b933f5a589560812fa168e 100644
--- a/base/common/python/pki/nssdb.py
+++ b/base/common/python/pki/nssdb.py
@@ -398,6 +398,16 @@ class NSSDatabase(object):
         if rc:
             raise Exception('Failed to generate self-signed CA certificate. RC: %d' % rc)
 
+    def show_certs(self):
+
+        cmd = [
+            'certutil',
+            '-L',
+            '-d', self.directory
+        ]
+
+        subprocess.check_call(cmd)
+
     def get_cert(self, nickname, output_format='pem'):
 
         if output_format == 'pem':
diff --git a/base/common/python/pki/pkcs12.py b/base/common/python/pki/pkcs12.py
new file mode 100644
index 0000000000000000000000000000000000000000..aeb6d625e1ac18d6bb06e060d6fa7a095e2ab912
--- /dev/null
+++ b/base/common/python/pki/pkcs12.py
@@ -0,0 +1,68 @@
+# Authors:
+#     Endi S. Dewata <edewata redhat com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the Lesser GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+
+from __future__ import absolute_import
+import os
+import shutil
+import subprocess
+import tempfile
+
+
+class PKCS12(object):
+
+    def __init__(self, path, password=None, password_file=None, nssdb=None):
+
+        self.path = path
+        self.nssdb = nssdb
+
+        self.tmpdir = tempfile.mkdtemp()
+
+        if password:
+            self.password_file = os.path.join(self.tmpdir, 'password.txt')
+            with open(self.password_file, 'w') as f:
+                f.write(password)
+
+        elif password_file:
+            self.password_file = password_file
+
+        else:
+            raise Exception('Missing NSS database password')
+
+    def close(self):
+        shutil.rmtree(self.tmpdir)
+
+    def show_certs(self):
+
+        cmd = ['pki']
+
+        if self.nssdb:
+            cmd.extend([
+                '-d', self.nssdb.directory,
+                '-C', self.nssdb.password_file
+            ])
+
+        cmd.extend([
+            'pkcs12-cert-find',
+            '--pkcs12-file', self.path,
+            '--pkcs12-password-file', self.password_file
+        ])
+
+        subprocess.check_call(cmd)
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 18fc3e1efb9ebf64308f7fdf7f647c9ac973ba35..c0cfe27e9b04b0dd2688f170d2f357b771882e3f 100644
--- a/base/server/python/pki/server/deployment/scriptlets/security_databases.py
+++ b/base/server/python/pki/server/deployment/scriptlets/security_databases.py
@@ -19,9 +19,11 @@
 #
 
 from __future__ import absolute_import
+from __future__ import print_function
 
 import os
 import pki.nssdb
+import pki.pkcs12
 import pki.server
 
 # PKI Deployment Imports
@@ -104,9 +106,12 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                 directory=deployer.mdict['pki_database_path'],
                 password_file=deployer.mdict['pki_shared_pfile'])
 
-            nssdb.import_pkcs12(
-                pkcs12_file=pki_server_pkcs12_path,
-                pkcs12_password=pki_server_pkcs12_password)
+            try:
+                nssdb.import_pkcs12(
+                    pkcs12_file=pki_server_pkcs12_path,
+                    pkcs12_password=pki_server_pkcs12_password)
+            finally:
+                nssdb.close()
 
             # update external CA file (if needed)
             external_certs_path = deployer.mdict['pki_server_external_certs_path']
@@ -127,10 +132,29 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                 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)
+            try:
+                print('Importing certificates from %s:' % pki_clone_pkcs12_path)
+                pkcs12 = pki.pkcs12.PKCS12(
+                    path=pki_clone_pkcs12_path,
+                    password=pki_clone_pkcs12_password,
+                    nssdb=nssdb)
+
+                try:
+                    pkcs12.show_certs()
+                finally:
+                    pkcs12.close()
+
+                # Import certificates
+                nssdb.import_pkcs12(
+                    pkcs12_file=pki_clone_pkcs12_path,
+                    pkcs12_password=pki_clone_pkcs12_password,
+                    no_user_certs=True)
+
+                print('Imported certificates in %s:' % deployer.mdict['pki_database_path'])
+                nssdb.show_certs()
+
+            finally:
+                nssdb.close()
 
         if len(deployer.instance.tomcat_instance_subsystems()) < 2:
 
-- 
2.5.5

>From 3662f49869369080e472736cee0c77735ed319b1 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata redhat com>
Date: Mon, 1 Aug 2016 22:35:32 +0200
Subject: [PATCH] Fixed PKCS #12 import for cloning.

To fix cloning issue in IPA the security_database.py has been
modified to import all certificates and keys in the PKCS #12 file
before the PKI server is started. Since the PKCS #12 generated by
IPA may not contain the certificate trust flags, the script will
also reset the trust flags on the imported certificates (i.e.
CT,C,C for CA certificate and u,u,Pu for audit certificate).

The ConfigurationUtils.restoreCertsFromP12() is now redundant and
it should be removed in the future, but for now it has been
modified to set the same trust flags on imported certificates.

The CryptoUtil.importCertificateChain() has also been modified to
set the same trust flags on imported certificates.

https://fedorahosted.org/pki/ticket/2424
---
 .../cms/servlet/csadmin/ConfigurationUtils.java    |  9 +++-
 .../deployment/scriptlets/security_databases.py    | 13 ++++-
 .../com/netscape/cmsutil/crypto/CryptoUtil.java    | 60 ++++++++++++----------
 3 files changed, 51 insertions(+), 31 deletions(-)

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
index fe65bb855a24702c2248d03059716d4246d70d0a..34948822b593dd8bf03ff4db81a3d232c65da291 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
@@ -834,7 +834,8 @@ public class ConfigurationUtils {
             BadPaddingException, NotInitializedException, NicknameConflictException, UserCertConflictException,
             NoSuchItemOnTokenException, InvalidBERException, IOException {
 
-        // TODO: refactor into a PKCS #12 utility class
+        // TODO: The PKCS #12 file is already imported in security_database.py.
+        // This method should be removed.
 
         byte b[] = new byte[1000000];
         FileInputStream fis = new FileInputStream(p12File);
@@ -1109,10 +1110,14 @@ public class ConfigurationUtils {
                 InternalCertificate icert = (InternalCertificate) xcert;
 
                 if (isCASigningCert) {
-                    // we need to change the trust attribute to CT
+                    // set trust flags to CT,C,C
                     icert.setSSLTrust(InternalCertificate.TRUSTED_CA
                             | InternalCertificate.TRUSTED_CLIENT_CA
                             | InternalCertificate.VALID_CA);
+                    icert.setEmailTrust(InternalCertificate.TRUSTED_CA
+                            | InternalCertificate.VALID_CA);
+                    icert.setObjectSigningTrust(InternalCertificate.TRUSTED_CA
+                            | InternalCertificate.VALID_CA);
 
                 } else if (isAuditSigningCert(name)) {
                     icert.setObjectSigningTrust(InternalCertificate.USER
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 c0cfe27e9b04b0dd2688f170d2f357b771882e3f..444f7b56dda024574b56b2df81235a9642dd7713 100644
--- a/base/server/python/pki/server/deployment/scriptlets/security_databases.py
+++ b/base/server/python/pki/server/deployment/scriptlets/security_databases.py
@@ -147,8 +147,17 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                 # Import certificates
                 nssdb.import_pkcs12(
                     pkcs12_file=pki_clone_pkcs12_path,
-                    pkcs12_password=pki_clone_pkcs12_password,
-                    no_user_certs=True)
+                    pkcs12_password=pki_clone_pkcs12_password)
+
+                # Set certificate trust flags
+                if subsystem.type == 'CA':
+                    nssdb.modify_cert(
+                        nickname=deployer.mdict['pki_ca_signing_nickname'],
+                        trust_attributes='CTu,Cu,Cu')
+
+                nssdb.modify_cert(
+                    nickname=deployer.mdict['pki_audit_signing_nickname'],
+                    trust_attributes='u,u,Pu')
 
                 print('Imported certificates in %s:' % deployer.mdict['pki_database_path'])
                 nssdb.show_certs()
diff --git a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
index 9cabdc5cc459afc0ab2b60450d29fa14e384f58d..b02c363e2af150cb4c74d394dd00d6d8650b0c58 100644
--- a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
+++ b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
@@ -47,33 +47,6 @@ import java.util.Random;
 import java.util.StringTokenizer;
 import java.util.Vector;
 
-import netscape.security.pkcs.PKCS10;
-import netscape.security.pkcs.PKCS10Attribute;
-import netscape.security.pkcs.PKCS10Attributes;
-import netscape.security.pkcs.PKCS7;
-import netscape.security.pkcs.PKCS9Attribute;
-import netscape.security.util.BigInt;
-import netscape.security.util.DerInputStream;
-import netscape.security.util.DerOutputStream;
-import netscape.security.util.DerValue;
-import netscape.security.util.ObjectIdentifier;
-import netscape.security.x509.AlgorithmId;
-import netscape.security.x509.CertificateAlgorithmId;
-import netscape.security.x509.CertificateChain;
-import netscape.security.x509.CertificateExtensions;
-import netscape.security.x509.CertificateIssuerName;
-import netscape.security.x509.CertificateSerialNumber;
-import netscape.security.x509.CertificateSubjectName;
-import netscape.security.x509.CertificateValidity;
-import netscape.security.x509.CertificateVersion;
-import netscape.security.x509.CertificateX509Key;
-import netscape.security.x509.Extensions;
-import netscape.security.x509.X500Name;
-import netscape.security.x509.X500Signer;
-import netscape.security.x509.X509CertImpl;
-import netscape.security.x509.X509CertInfo;
-import netscape.security.x509.X509Key;
-
 import org.mozilla.jss.CryptoManager;
 import org.mozilla.jss.CryptoManager.NotInitializedException;
 import org.mozilla.jss.NoSuchTokenException;
@@ -132,6 +105,33 @@ import org.mozilla.jss.util.Password;
 import com.netscape.cmsutil.util.Cert;
 import com.netscape.cmsutil.util.Utils;
 
+import netscape.security.pkcs.PKCS10;
+import netscape.security.pkcs.PKCS10Attribute;
+import netscape.security.pkcs.PKCS10Attributes;
+import netscape.security.pkcs.PKCS7;
+import netscape.security.pkcs.PKCS9Attribute;
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertificateAlgorithmId;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateIssuerName;
+import netscape.security.x509.CertificateSerialNumber;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.Extensions;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X500Signer;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
 @SuppressWarnings("serial")
 public class CryptoUtil {
 
@@ -1164,10 +1164,16 @@ public class CryptoUtil {
         if (certchains != null) {
             cert = certchains[certchains.length - 1];
         }
+
+        // set trust flags to CT,C,C
         InternalCertificate icert = (InternalCertificate) cert;
         icert.setSSLTrust(InternalCertificate.TRUSTED_CA
                                     | InternalCertificate.TRUSTED_CLIENT_CA
                                     | InternalCertificate.VALID_CA);
+        icert.setEmailTrust(InternalCertificate.TRUSTED_CA
+                | InternalCertificate.VALID_CA);
+        icert.setObjectSigningTrust(InternalCertificate.TRUSTED_CA
+                | InternalCertificate.VALID_CA);
     }
 
     public static SEQUENCE parseCRMFMsgs(byte cert_request[])
-- 
2.5.5


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