mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Simplify NSSDatabase password file handling
https://fedorahosted.org/freeipa/ticket/5959 Signed-off-by: Simo Sorce <simo@redhat.com> Reviewed-By: Jan Cholasta <jcholast@redhat.com>
This commit is contained in:
parent
d124e307f3
commit
f648c5631a
@ -97,6 +97,7 @@ class NSSDatabase(object):
|
|||||||
else:
|
else:
|
||||||
self.secdir = nssdir
|
self.secdir = nssdir
|
||||||
self._is_temporary = False
|
self._is_temporary = False
|
||||||
|
self.pwd_file = os.path.join(self.secdir, 'pwdfile.txt')
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
if self._is_temporary:
|
if self._is_temporary:
|
||||||
@ -145,7 +146,7 @@ class NSSDatabase(object):
|
|||||||
os.makedirs(self.secdir, dirmode)
|
os.makedirs(self.secdir, dirmode)
|
||||||
|
|
||||||
if password_filename is None:
|
if password_filename is None:
|
||||||
password_filename = os.path.join(self.secdir, 'pwdfile.txt')
|
password_filename = self.pwd_file
|
||||||
|
|
||||||
if not os.path.exists(password_filename):
|
if not os.path.exists(password_filename):
|
||||||
# Create the password file for this db
|
# Create the password file for this db
|
||||||
@ -218,12 +219,11 @@ class NSSDatabase(object):
|
|||||||
|
|
||||||
return root_nicknames
|
return root_nicknames
|
||||||
|
|
||||||
def export_pkcs12(self, nickname, pkcs12_filename, db_password_filename,
|
def export_pkcs12(self, nickname, pkcs12_filename, pkcs12_passwd=None):
|
||||||
pkcs12_passwd=None):
|
|
||||||
args = [PK12UTIL, "-d", self.secdir,
|
args = [PK12UTIL, "-d", self.secdir,
|
||||||
"-o", pkcs12_filename,
|
"-o", pkcs12_filename,
|
||||||
"-n", nickname,
|
"-n", nickname,
|
||||||
"-k", db_password_filename]
|
"-k", self.pwd_file]
|
||||||
pkcs12_password_file = None
|
pkcs12_password_file = None
|
||||||
if pkcs12_passwd is not None:
|
if pkcs12_passwd is not None:
|
||||||
pkcs12_password_file = ipautil.write_tmp_file(pkcs12_passwd + '\n')
|
pkcs12_password_file = ipautil.write_tmp_file(pkcs12_passwd + '\n')
|
||||||
@ -243,11 +243,10 @@ class NSSDatabase(object):
|
|||||||
if pkcs12_password_file is not None:
|
if pkcs12_password_file is not None:
|
||||||
pkcs12_password_file.close()
|
pkcs12_password_file.close()
|
||||||
|
|
||||||
def import_pkcs12(self, pkcs12_filename, db_password_filename,
|
def import_pkcs12(self, pkcs12_filename, pkcs12_passwd=None):
|
||||||
pkcs12_passwd=None):
|
|
||||||
args = [PK12UTIL, "-d", self.secdir,
|
args = [PK12UTIL, "-d", self.secdir,
|
||||||
"-i", pkcs12_filename,
|
"-i", pkcs12_filename,
|
||||||
"-k", db_password_filename, '-v']
|
"-k", self.pwd_file, '-v']
|
||||||
pkcs12_password_file = None
|
pkcs12_password_file = None
|
||||||
if pkcs12_passwd is not None:
|
if pkcs12_passwd is not None:
|
||||||
pkcs12_password_file = ipautil.write_tmp_file(pkcs12_passwd + '\n')
|
pkcs12_password_file = ipautil.write_tmp_file(pkcs12_passwd + '\n')
|
||||||
@ -267,8 +266,8 @@ class NSSDatabase(object):
|
|||||||
if pkcs12_password_file is not None:
|
if pkcs12_password_file is not None:
|
||||||
pkcs12_password_file.close()
|
pkcs12_password_file.close()
|
||||||
|
|
||||||
def import_files(self, files, db_password_filename, import_keys=False,
|
def import_files(self, files, import_keys=False, key_password=None,
|
||||||
key_password=None, key_nickname=None):
|
key_nickname=None):
|
||||||
"""
|
"""
|
||||||
Import certificates and a single private key from multiple files
|
Import certificates and a single private key from multiple files
|
||||||
|
|
||||||
@ -276,8 +275,6 @@ class NSSDatabase(object):
|
|||||||
PKCS#8 and raw private key and PKCS#12 formats.
|
PKCS#8 and raw private key and PKCS#12 formats.
|
||||||
|
|
||||||
:param files: Names of files to import
|
:param files: Names of files to import
|
||||||
:param db_password_filename: Name of file containing the database
|
|
||||||
password
|
|
||||||
:param import_keys: Whether to import private keys
|
:param import_keys: Whether to import private keys
|
||||||
:param key_password: Password to decrypt private keys
|
:param key_password: Password to decrypt private keys
|
||||||
:param key_nickname: Nickname of the private key to import from PKCS#12
|
:param key_nickname: Nickname of the private key to import from PKCS#12
|
||||||
@ -352,7 +349,7 @@ class NSSDatabase(object):
|
|||||||
args = [
|
args = [
|
||||||
OPENSSL, 'pkcs8',
|
OPENSSL, 'pkcs8',
|
||||||
'-topk8',
|
'-topk8',
|
||||||
'-passout', 'file:' + db_password_filename,
|
'-passout', 'file:' + self.pwd_file,
|
||||||
]
|
]
|
||||||
if ((label != 'PRIVATE KEY' and key_password) or
|
if ((label != 'PRIVATE KEY' and key_password) or
|
||||||
label == 'ENCRYPTED PRIVATE KEY'):
|
label == 'ENCRYPTED PRIVATE KEY'):
|
||||||
@ -390,8 +387,7 @@ class NSSDatabase(object):
|
|||||||
# Try to import the file as PKCS#12 file
|
# Try to import the file as PKCS#12 file
|
||||||
if import_keys:
|
if import_keys:
|
||||||
try:
|
try:
|
||||||
self.import_pkcs12(
|
self.import_pkcs12(filename, key_password)
|
||||||
filename, db_password_filename, key_password)
|
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@ -442,7 +438,7 @@ class NSSDatabase(object):
|
|||||||
'-export',
|
'-export',
|
||||||
'-in', in_file.name,
|
'-in', in_file.name,
|
||||||
'-out', out_file.name,
|
'-out', out_file.name,
|
||||||
'-passin', 'file:' + db_password_filename,
|
'-passin', 'file:' + self.pwd_file,
|
||||||
'-passout', 'file:' + out_pwdfile.name,
|
'-passout', 'file:' + out_pwdfile.name,
|
||||||
]
|
]
|
||||||
try:
|
try:
|
||||||
@ -452,8 +448,7 @@ class NSSDatabase(object):
|
|||||||
"No matching certificate found for private key from %s" %
|
"No matching certificate found for private key from %s" %
|
||||||
key_file)
|
key_file)
|
||||||
|
|
||||||
self.import_pkcs12(out_file.name, db_password_filename,
|
self.import_pkcs12(out_file.name, out_password)
|
||||||
out_password)
|
|
||||||
|
|
||||||
def trust_root_cert(self, root_nickname, trust_flags=None):
|
def trust_root_cert(self, root_nickname, trust_flags=None):
|
||||||
if root_nickname[:7] == "Builtin":
|
if root_nickname[:7] == "Builtin":
|
||||||
|
@ -83,7 +83,6 @@ class CertDB(object):
|
|||||||
self.realm = realm
|
self.realm = realm
|
||||||
|
|
||||||
self.noise_fname = self.secdir + "/noise.txt"
|
self.noise_fname = self.secdir + "/noise.txt"
|
||||||
self.passwd_fname = self.secdir + "/pwdfile.txt"
|
|
||||||
self.certdb_fname = self.secdir + "/cert8.db"
|
self.certdb_fname = self.secdir + "/cert8.db"
|
||||||
self.keydb_fname = self.secdir + "/key3.db"
|
self.keydb_fname = self.secdir + "/key3.db"
|
||||||
self.secmod_fname = self.secdir + "/secmod.db"
|
self.secmod_fname = self.secdir + "/secmod.db"
|
||||||
@ -119,6 +118,10 @@ class CertDB(object):
|
|||||||
ca_subject = ipautil.dn_attribute_property('_ca_subject')
|
ca_subject = ipautil.dn_attribute_property('_ca_subject')
|
||||||
subject_base = ipautil.dn_attribute_property('_subject_base')
|
subject_base = ipautil.dn_attribute_property('_subject_base')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def passwd_fname(self):
|
||||||
|
return self.nssdb.pwd_file
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
if self.reqdir is not None:
|
if self.reqdir is not None:
|
||||||
shutil.rmtree(self.reqdir, ignore_errors=True)
|
shutil.rmtree(self.reqdir, ignore_errors=True)
|
||||||
@ -189,7 +192,7 @@ class CertDB(object):
|
|||||||
ipautil.backup_file(self.certdb_fname)
|
ipautil.backup_file(self.certdb_fname)
|
||||||
ipautil.backup_file(self.keydb_fname)
|
ipautil.backup_file(self.keydb_fname)
|
||||||
ipautil.backup_file(self.secmod_fname)
|
ipautil.backup_file(self.secmod_fname)
|
||||||
self.nssdb.create_db(self.passwd_fname)
|
self.nssdb.create_db()
|
||||||
self.set_perms(self.passwd_fname, write=True)
|
self.set_perms(self.passwd_fname, write=True)
|
||||||
|
|
||||||
def list_certs(self):
|
def list_certs(self):
|
||||||
@ -510,7 +513,7 @@ class CertDB(object):
|
|||||||
return self.nssdb.find_server_certs()
|
return self.nssdb.find_server_certs()
|
||||||
|
|
||||||
def import_pkcs12(self, pkcs12_fname, pkcs12_passwd=None):
|
def import_pkcs12(self, pkcs12_fname, pkcs12_passwd=None):
|
||||||
return self.nssdb.import_pkcs12(pkcs12_fname, self.passwd_fname,
|
return self.nssdb.import_pkcs12(pkcs12_fname,
|
||||||
pkcs12_passwd=pkcs12_passwd)
|
pkcs12_passwd=pkcs12_passwd)
|
||||||
|
|
||||||
def export_pkcs12(self, pkcs12_fname, pkcs12_pwd_fname, nickname=None):
|
def export_pkcs12(self, pkcs12_fname, pkcs12_pwd_fname, nickname=None):
|
||||||
|
@ -1003,19 +1003,16 @@ def load_pkcs12(cert_files, key_password, key_nickname, ca_cert_files,
|
|||||||
the CA certificate of the CA that issued the server certificate
|
the CA certificate of the CA that issued the server certificate
|
||||||
"""
|
"""
|
||||||
with certs.NSSDatabase() as nssdb:
|
with certs.NSSDatabase() as nssdb:
|
||||||
db_password = ipautil.ipa_generate_password()
|
nssdb.create_db()
|
||||||
db_pwdfile = ipautil.write_tmp_file(db_password)
|
|
||||||
nssdb.create_db(db_pwdfile.name)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
nssdb.import_files(cert_files, db_pwdfile.name,
|
nssdb.import_files(cert_files, True, key_password, key_nickname)
|
||||||
True, key_password, key_nickname)
|
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
raise ScriptError(str(e))
|
raise ScriptError(str(e))
|
||||||
|
|
||||||
if ca_cert_files:
|
if ca_cert_files:
|
||||||
try:
|
try:
|
||||||
nssdb.import_files(ca_cert_files, db_pwdfile.name)
|
nssdb.import_files(ca_cert_files)
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
raise ScriptError(str(e))
|
raise ScriptError(str(e))
|
||||||
|
|
||||||
@ -1068,7 +1065,7 @@ def load_pkcs12(cert_files, key_password, key_nickname, ca_cert_files,
|
|||||||
'-o', out_file.name,
|
'-o', out_file.name,
|
||||||
'-n', key_nickname,
|
'-n', key_nickname,
|
||||||
'-d', nssdb.secdir,
|
'-d', nssdb.secdir,
|
||||||
'-k', db_pwdfile.name,
|
'-k', nssdb.pwd_file,
|
||||||
'-w', out_pwdfile.name,
|
'-w', out_pwdfile.name,
|
||||||
]
|
]
|
||||||
ipautil.run(args)
|
ipautil.run(args)
|
||||||
@ -1143,12 +1140,10 @@ def load_external_cert(files, ca_subject):
|
|||||||
with the external CA certificate chain
|
with the external CA certificate chain
|
||||||
"""
|
"""
|
||||||
with certs.NSSDatabase() as nssdb:
|
with certs.NSSDatabase() as nssdb:
|
||||||
db_password = ipautil.ipa_generate_password()
|
nssdb.create_db()
|
||||||
db_pwdfile = ipautil.write_tmp_file(db_password)
|
|
||||||
nssdb.create_db(db_pwdfile.name)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
nssdb.import_files(files, db_pwdfile.name)
|
nssdb.import_files(files)
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
raise ScriptError(str(e))
|
raise ScriptError(str(e))
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ import optparse # pylint: disable=deprecated-module
|
|||||||
|
|
||||||
from ipaplatform.constants import constants
|
from ipaplatform.constants import constants
|
||||||
from ipaplatform.paths import paths
|
from ipaplatform.paths import paths
|
||||||
from ipapython import admintool, ipautil
|
from ipapython import admintool
|
||||||
from ipapython.certdb import get_ca_nickname, NSSDatabase
|
from ipapython.certdb import get_ca_nickname, NSSDatabase
|
||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
from ipalib import api, errors
|
from ipalib import api, errors
|
||||||
@ -164,14 +164,11 @@ class ServerCertInstall(admintool.AdminTool):
|
|||||||
def check_chain(self, pkcs12_filename, pkcs12_pin, nssdb):
|
def check_chain(self, pkcs12_filename, pkcs12_pin, nssdb):
|
||||||
# create a temp nssdb
|
# create a temp nssdb
|
||||||
with NSSDatabase() as tempnssdb:
|
with NSSDatabase() as tempnssdb:
|
||||||
db_password = ipautil.ipa_generate_password()
|
tempnssdb.create_db()
|
||||||
db_pwdfile = ipautil.write_tmp_file(db_password)
|
|
||||||
tempnssdb.create_db(db_pwdfile.name)
|
|
||||||
|
|
||||||
# import the PKCS12 file, then delete all CA certificates
|
# import the PKCS12 file, then delete all CA certificates
|
||||||
# this leaves only the server certs in the temp db
|
# this leaves only the server certs in the temp db
|
||||||
tempnssdb.import_pkcs12(
|
tempnssdb.import_pkcs12(pkcs12_filename, pkcs12_pin)
|
||||||
pkcs12_filename, db_pwdfile.name, pkcs12_pin)
|
|
||||||
for nickname, flags in tempnssdb.list_certs():
|
for nickname, flags in tempnssdb.list_certs():
|
||||||
if 'u' not in flags:
|
if 'u' not in flags:
|
||||||
while tempnssdb.has_nickname(nickname):
|
while tempnssdb.has_nickname(nickname):
|
||||||
|
@ -54,9 +54,8 @@ def install_check(api, replica_config, options):
|
|||||||
return
|
return
|
||||||
|
|
||||||
with certdb.NSSDatabase() as tmpdb:
|
with certdb.NSSDatabase() as tmpdb:
|
||||||
pw = ipautil.write_tmp_file(ipautil.ipa_generate_password())
|
tmpdb.create_db()
|
||||||
tmpdb.create_db(pw.name)
|
tmpdb.import_pkcs12(replica_config.dir + "/cacert.p12",
|
||||||
tmpdb.import_pkcs12(replica_config.dir + "/cacert.p12", pw.name,
|
|
||||||
replica_config.dirman_password)
|
replica_config.dirman_password)
|
||||||
kra_cert_nicknames = [
|
kra_cert_nicknames = [
|
||||||
"storageCert cert-pki-kra", "transportCert cert-pki-kra",
|
"storageCert cert-pki-kra", "transportCert cert-pki-kra",
|
||||||
|
@ -37,8 +37,7 @@ class update_ra_cert_store(Updater):
|
|||||||
return False, []
|
return False, []
|
||||||
else:
|
else:
|
||||||
# Create the DB
|
# Create the DB
|
||||||
newdb.create_db(os.path.join(paths.IPA_RADB_DIR, 'pwdfile.txt'),
|
newdb.create_db(user=constants.HTTPD_USER,
|
||||||
user=constants.HTTPD_USER,
|
|
||||||
group=constants.HTTPD_GROUP,
|
group=constants.HTTPD_GROUP,
|
||||||
mode=0o751, backup=True)
|
mode=0o751, backup=True)
|
||||||
|
|
||||||
@ -58,18 +57,16 @@ class update_ra_cert_store(Updater):
|
|||||||
"chain: {}".format(name, str(e)))
|
"chain: {}".format(name, str(e)))
|
||||||
|
|
||||||
# As the last step export/import/delete the RA Cert
|
# As the last step export/import/delete the RA Cert
|
||||||
ipa_httpd_pwdfile = os.path.join(paths.HTTPD_ALIAS_DIR, 'pwdfile.txt')
|
|
||||||
ipa_radb_pwdfile = os.path.join(paths.IPA_RADB_DIR, 'pwdfile.txt')
|
|
||||||
pw = binascii.hexlify(os.urandom(10))
|
pw = binascii.hexlify(os.urandom(10))
|
||||||
p12file = os.path.join(paths.IPA_RADB_DIR, 'ipaCert.p12')
|
p12file = os.path.join(paths.IPA_RADB_DIR, 'ipaCert.p12')
|
||||||
olddb.export_pkcs12('ipaCert', p12file, ipa_httpd_pwdfile, pw)
|
olddb.export_pkcs12('ipaCert', p12file, pw)
|
||||||
newdb.import_pkcs12(p12file, ipa_radb_pwdfile, pw)
|
newdb.import_pkcs12(p12file, pw)
|
||||||
|
|
||||||
certmonger.stop_tracking(secdir=olddb.secdir,
|
certmonger.stop_tracking(secdir=olddb.secdir,
|
||||||
nickname='ipaCert')
|
nickname='ipaCert')
|
||||||
certmonger.start_tracking(secdir=newdb.secdir,
|
certmonger.start_tracking(secdir=newdb.secdir,
|
||||||
nickname='ipaCert',
|
nickname='ipaCert',
|
||||||
password_file=ipa_radb_pwdfile)
|
password_file=newdb.pwd_file)
|
||||||
|
|
||||||
olddb.delete_cert('ipaCert')
|
olddb.delete_cert('ipaCert')
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user