URL: https://github.com/freeipa/freeipa/pull/446
Author: stlaz
 Title: #446: Add password file to certutil calls in ipapython.certdb module
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/446/head:pr446
git checkout pr446
From 301a98b12f6c0d61a7af1d5ff807520cff760f91 Mon Sep 17 00:00:00 2001
From: Stanislav Laznicka <slazn...@redhat.com>
Date: Tue, 6 Dec 2016 09:14:54 +0100
Subject: [PATCH 1/2] Add password to certutil calls in NSSDatabase

NSSDatabases should call certutil with a password. Also, removed
`password_filename` argument from `.create_db()`.

https://fedorahosted.org/freeipa/ticket/5695
---
 install/tools/ipa-replica-conncheck    |  9 +--------
 ipaclient/install/client.py            | 17 +++--------------
 ipapython/certdb.py                    | 20 +++++++-------------
 ipaserver/install/cainstance.py        | 23 +++++++++++++++++++++++
 ipaserver/install/ipa_cacert_manage.py |  6 ++----
 ipaserver/install/server/upgrade.py    |  6 ++++++
 6 files changed, 42 insertions(+), 39 deletions(-)

diff --git a/install/tools/ipa-replica-conncheck b/install/tools/ipa-replica-conncheck
index 04e23de..fdbd4f3 100755
--- a/install/tools/ipa-replica-conncheck
+++ b/install/tools/ipa-replica-conncheck
@@ -542,12 +542,7 @@ def main():
 
                 with certdb.NSSDatabase(nss_dir) as nss_db:
                     if options.ca_cert_file:
-                        nss_dir = nss_db.secdir
-
-                        password = ipautil.ipa_generate_password()
-                        password_file = ipautil.write_tmp_file(password)
-                        nss_db.create_db(password_file.name)
-
+                        nss_db.create_db()
                         ca_certs = x509.load_certificate_list_from_file(
                             options.ca_cert_file)
                         for ca_cert in ca_certs:
@@ -555,8 +550,6 @@ def main():
                                 serialization.Encoding.DER)
                             nss_db.add_cert(
                                 data, str(DN(ca_cert.subject)), 'C,,')
-                    else:
-                        nss_dir = None
 
                     api.bootstrap(context='client',
                                   confdir=paths.ETC_IPA,
diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
index 2b01b0d..e43ec7b 100644
--- a/ipaclient/install/client.py
+++ b/ipaclient/install/client.py
@@ -2284,18 +2284,8 @@ def install_check(options):
 
 def create_ipa_nssdb():
     db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR)
-    pwdfile = os.path.join(db.secdir, 'pwdfile.txt')
-
-    ipautil.backup_file(pwdfile)
-    ipautil.backup_file(os.path.join(db.secdir, 'cert8.db'))
-    ipautil.backup_file(os.path.join(db.secdir, 'key3.db'))
-    ipautil.backup_file(os.path.join(db.secdir, 'secmod.db'))
-
-    with open(pwdfile, 'w') as f:
-        f.write(ipautil.ipa_generate_password())
-    os.chmod(pwdfile, 0o600)
-
-    db.create_db(pwdfile)
+    db.create_db(backup=True)
+    os.chmod(db.pwd_file, 0o600)
     os.chmod(os.path.join(db.secdir, 'cert8.db'), 0o644)
     os.chmod(os.path.join(db.secdir, 'key3.db'), 0o644)
     os.chmod(os.path.join(db.secdir, 'secmod.db'), 0o644)
@@ -2667,8 +2657,7 @@ def _install(options):
             for cert in ca_certs
         ]
         try:
-            pwd_file = ipautil.write_tmp_file(ipautil.ipa_generate_password())
-            tmp_db.create_db(pwd_file.name)
+            tmp_db.create_db()
 
             for i, cert in enumerate(ca_certs):
                 tmp_db.add_cert(cert, 'CA certificate %d' % (i + 1), 'C,,')
diff --git a/ipapython/certdb.py b/ipapython/certdb.py
index a6bfcbc..73387cf 100644
--- a/ipapython/certdb.py
+++ b/ipapython/certdb.py
@@ -17,7 +17,6 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
-import binascii
 import os
 import io
 import pwd
@@ -112,13 +111,12 @@ def __exit__(self, type, value, tb):
     def run_certutil(self, args, stdin=None, **kwargs):
         new_args = [CERTUTIL, "-d", self.secdir]
         new_args = new_args + args
+        new_args.extend(['-f', self.pwd_file])
         return ipautil.run(new_args, stdin, **kwargs)
 
-    def create_db(self, password_filename=None, user=None, group=None,
-                  mode=None, backup=False):
+    def create_db(self, user=None, group=None, mode=None, backup=False):
         """Create cert DB
 
-        :param password_filename: Name of file containing the database password
         :param user: User owner the secdir
         :param group: Group owner of the secdir
         :param mode: Mode of the secdir
@@ -145,19 +143,15 @@ def create_db(self, password_filename=None, user=None, group=None,
         if not os.path.exists(self.secdir):
             os.makedirs(self.secdir, dirmode)
 
-        if password_filename is None:
-            password_filename = self.pwd_file
-
-        if not os.path.exists(password_filename):
+        if not os.path.exists(self.pwd_file):
             # Create the password file for this db
-            hex_str = binascii.hexlify(os.urandom(10))
-            with io.open(os.open(password_filename,
+            with io.open(os.open(self.pwd_file,
                                  os.O_CREAT | os.O_WRONLY,
-                                 filemode), 'wb', closefd=True) as f:
-                f.write(hex_str)
+                                 filemode), 'w', closefd=True) as f:
+                f.write(ipautil.ipa_generate_password())
                 f.flush()
 
-        self.run_certutil(["-N", "-f", password_filename])
+        self.run_certutil(["-N", "-f", self.pwd_file])
 
         # Finally fix up perms
         os.chown(self.secdir, uid, gid)
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 1b7ada4..52485b9 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -394,6 +394,8 @@ def configure_instance(self, host_name, dm_password, admin_password,
                 self.step("creating installation admin user", self.setup_admin)
             self.step("configuring certificate server instance",
                       self.__spawn_instance)
+            self.step("exporting Dogtag certificate store pin",
+                      self.create_certstore_passwdfile)
             self.step("stopping certificate server instance to update CS.cfg", self.stop_instance)
             self.step("backing up CS.cfg", self.backup_config)
             self.step("disabling nonces", self.__disable_nonce)
@@ -627,6 +629,27 @@ def backup_config(self):
         except Exception as e:
             root_logger.warning("Failed to backup CS.cfg: %s", e)
 
+    def create_certstore_passwdfile(self):
+        """
+        This method creates a 'pwdfile.txt' file in the Dogtag certificate
+        store so that this file can be assumed and used for NSSDatabase/CertDB
+        operations in 'certutil' calls.
+        """
+        passwd = None
+        token = 'internal'
+        with open(paths.PKI_TOMCAT_PASSWORD_CONF, 'r') as f:
+            for line in f:
+                (tok, pin) = line.split('=', 1)
+                if token == tok:
+                    passwd = pin.strip()
+                    break
+            else:
+                raise RuntimeError(
+                    "The password to the 'internal' token of the Dogtag "
+                    "certificate store was not found.")
+        db = certs.CertDB(self.realm, nssdir=paths.PKI_TOMCAT_ALIAS_DIR)
+        db.create_passwd_file(passwd)
+
     def __update_topology(self):
         ld = ldapupdate.LDAPUpdate(ldapi=True, sub_dict={
             'SUFFIX': api.env.basedn,
diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py
index e47d104..dc44836 100644
--- a/ipaserver/install/ipa_cacert_manage.py
+++ b/ipaserver/install/ipa_cacert_manage.py
@@ -230,8 +230,7 @@ def renew_external_step_2(self, ca, old_cert_der):
                 "troubleshooting guide)")
 
         with certs.NSSDatabase() as tmpdb:
-            pw = ipautil.write_tmp_file(ipautil.ipa_generate_password())
-            tmpdb.create_db(pw.name)
+            tmpdb.create_db()
             tmpdb.add_cert(old_cert_der, 'IPA CA', 'C,,')
 
             try:
@@ -330,8 +329,7 @@ def install(self):
                                               False)
 
         with certs.NSSDatabase() as tmpdb:
-            pw = ipautil.write_tmp_file(ipautil.ipa_generate_password())
-            tmpdb.create_db(pw.name)
+            tmpdb.create_db()
             tmpdb.add_cert(cert, nickname, 'C,,')
             for ca_cert, ca_nickname, ca_trust_flags in ca_certs:
                 tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags)
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index 509f196..6683b5e 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -1543,6 +1543,12 @@ def upgrade_configuration():
             api.env.realm, paths.IPA_RADB_DIR, host_name=api.env.host)
     ca_running = ca.is_running()
 
+    # create passswd.txt file in PKI_TOMCAT_ALIAS_DIR if it does not exist
+    # this file will be required on most actions over this NSS DB in FIPS
+    if not os.path.exists(os.path.join(
+            paths.PKI_TOMCAT_ALIAS_DIR, 'pwdfile.txt')):
+        ca.create_certstore_passwdfile()
+
     with installutils.stopped_service('pki-tomcatd', 'pki-tomcat'):
         # Dogtag must be stopped to be able to backup CS.cfg config
         ca.backup_config()

From 8a13b39515990e0567a1b64e2c1cab92c94e481f Mon Sep 17 00:00:00 2001
From: Stanislav Laznicka <slazn...@redhat.com>
Date: Fri, 6 Jan 2017 14:19:12 +0100
Subject: [PATCH 2/2] custodiainstance: don't use IPA-specific CertDB

Replaced CertDB with NSSDatabase.
---
 ipaserver/install/custodiainstance.py | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py
index a0bb399..1be5399 100644
--- a/ipaserver/install/custodiainstance.py
+++ b/ipaserver/install/custodiainstance.py
@@ -2,16 +2,16 @@
 
 from ipaserver.secrets.kem import IPAKEMKeys
 from ipaserver.secrets.client import CustodiaClient
-from ipaserver.install.certs import CertDB
 from ipaplatform.paths import paths
 from ipaplatform.constants import constants
 from ipaserver.install.service import SimpleServiceInstance
 from ipapython import ipautil
 from ipapython.ipa_log_manager import root_logger
+from ipapython.certdb import NSSDatabase
 from ipaserver.install import installutils
 from ipaserver.install import ldapupdate
 from ipaserver.install import sysupgrade
-from base64 import b64encode, b64decode
+from base64 import b64decode
 from jwcrypto.common import json_decode
 import functools
 import shutil
@@ -129,13 +129,9 @@ def __get_keys(self, ca_host, cacerts_file, cacerts_pwd, data):
 
         # Temporary nssdb
         tmpnssdir = tempfile.mkdtemp(dir=paths.TMP)
+        tmpdb = NSSDatabase(tmpnssdir)
+        tmpdb.create_db()
         try:
-            # Temporary nssdb password
-            nsspwfile = os.path.join(tmpnssdir, 'nsspwfile')
-            with open(nsspwfile, 'w+') as f:
-                f.write(b64encode(os.urandom(16)))
-                f.flush()
-
             # Cert file password
             crtpwfile = os.path.join(tmpnssdir, 'crtpwfile')
             with open(crtpwfile, 'w+') as f:
@@ -152,21 +148,20 @@ def __get_keys(self, ca_host, cacerts_file, cacerts_pwd, data):
                 with open(pk12file, 'w+') as f:
                     f.write(b64decode(v['pkcs12 data']))
                 ipautil.run([paths.PK12UTIL,
-                             '-d', tmpnssdir,
-                             '-k', nsspwfile,
+                             '-d', tmpdb.secdir,
+                             '-k', tmpdb.pwd_file,
                              '-n', nickname,
                              '-i', pk12file,
                              '-w', pk12pwfile])
 
             # Add CA certificates
-            tmpdb = CertDB(self.realm, nssdir=tmpnssdir)
             self.suffix = ipautil.realm_to_suffix(self.realm)
             self.import_ca_certs(tmpdb, True)
 
             # Now that we gathered all certs, re-export
             ipautil.run([paths.PKCS12EXPORT,
-                         '-d', tmpnssdir,
-                         '-p', nsspwfile,
+                         '-d', tmpdb.secdir,
+                         '-p', tmpdb.pwd_file,
                          '-w', crtpwfile,
                          '-o', cacerts_file])
 
-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to