summaryrefslogtreecommitdiffstats
path: root/base/common/python/pki/nssdb.py
diff options
context:
space:
mode:
authorDinesh Prasanth M K <dmoluguw@redhat.com>2017-07-11 21:53:05 -0400
committerDinesh Prasanth M K <dmoluguw@redhat.com>2017-07-13 16:08:24 -0400
commit38afcf8a28b97516ba21f8fefa5057ddd34dc75c (patch)
tree17892d19a9958925c951c6b89499900ced86d07c /base/common/python/pki/nssdb.py
parentd0a880bd9e50a9e90fb4c5c10ee8a48b8b5c0357 (diff)
downloadpki-38afcf8a28b97516ba21f8fefa5057ddd34dc75c.tar.gz
pki-38afcf8a28b97516ba21f8fefa5057ddd34dc75c.tar.xz
pki-38afcf8a28b97516ba21f8fefa5057ddd34dc75c.zip
Temp SSL Certificate Creation - Offline System Certificate RenewalHEADmaster
`pki-server subsystem-cert-renew` can be used to generate a temporary SSL cert (Signed by CA) and replace the expired SSL cert in NSS DB. This helps to bring up the PKI server temporarily. The online System Certificate renewal procedure can then be used without backdating the system to update other system certificates. Ticket: https://pagure.io/dogtagpki/issue/2776 Change-Id: I411586e70f80029b76890e24425331d657ac71e9
Diffstat (limited to 'base/common/python/pki/nssdb.py')
-rw-r--r--base/common/python/pki/nssdb.py231
1 files changed, 180 insertions, 51 deletions
diff --git a/base/common/python/pki/nssdb.py b/base/common/python/pki/nssdb.py
index cad89081e..3c0ac0682 100644
--- a/base/common/python/pki/nssdb.py
+++ b/base/common/python/pki/nssdb.py
@@ -1,5 +1,6 @@
# Authors:
# Endi S. Dewata <edewata@redhat.com>
+# Dinesh Prasnath M K <dmoluguw@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
@@ -294,7 +295,6 @@ class NSSDatabase(object):
exts = []
for generic_ext in generic_exts:
-
data_file = os.path.join(tmpdir, 'csr-ext-%d' % counter)
with open(data_file, 'w') as f:
f.write(generic_ext['data'])
@@ -339,95 +339,224 @@ class NSSDatabase(object):
finally:
shutil.rmtree(tmpdir)
- def create_self_signed_ca_cert(self, subject_dn, request_file, cert_file,
- serial='1', validity=240):
-
+ def create_cert(self, request_file, cert_file, serial, issuer=None,
+ key_usage_ext=None, basic_constraints_ext=None,
+ aki_ext=None, ski_ext=None, aia_ext=None, ext_key_usage_ext=None,
+ validity=None):
cmd = [
'certutil',
'-C',
- '-x',
'-d', self.directory
]
+ # Check if it's self signed
+ if issuer:
+ cmd.extend(['-c', issuer])
+ else:
+ cmd.extend('-x')
+
if self.token:
cmd.extend(['-h', self.token])
cmd.extend([
'-f', self.password_file,
- '-c', subject_dn,
'-a',
'-i', request_file,
'-o', cert_file,
- '-m', serial,
- '-v', str(validity),
- '--keyUsage', 'digitalSignature,nonRepudiation,certSigning,crlSigning,critical',
- '-2',
- '-3',
- '--extSKID',
- '--extAIA'
+ '-m', serial
])
- p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
+ if validity:
+ cmd.extend(['-v', str(validity)])
keystroke = ''
- # Is this a CA certificate [y/N]?
- keystroke += 'y\n'
+ if aki_ext:
+ cmd.extend(['-3'])
+
+ # Enter value for the authKeyID extension [y/N]
+ if 'auth_key_id' in aki_ext:
+ keystroke += 'y\n'
+
+ # Enter value for the key identifier fields,enter to omit:
+ keystroke += aki_ext['auth_key_id']
+
+ keystroke += '\n'
+
+ # Select one of the following general name type:
+ # TODO: General Name type isn't used as of now for AKI
+ keystroke += '0\n'
+
+ if 'auth_cert_serial' in aki_ext:
+ keystroke += aki_ext['auth_cert_serial']
+
+ keystroke += '\n'
+
+ # Is this a critical extension [y/N]?
+ if 'critical' in aki_ext and aki_ext['critical']:
+ keystroke += 'y'
+
+ keystroke += '\n'
+
+ # Key Usage Constraints
+ if key_usage_ext:
+
+ cmd.extend(['--keyUsage'])
+
+ usages = []
+ for usage in key_usage_ext:
+ if key_usage_ext[usage]:
+ usages.append(usage)
+
+ cmd.extend([','.join(usages)])
- # Enter the path length constraint, enter to skip [<0 for unlimited path]:
- keystroke += '\n'
+ # Extended key usage
+ if ext_key_usage_ext:
+ cmd.extend(['--extKeyUsage'])
+ usages = []
+ for usage in ext_key_usage_ext:
+ if ext_key_usage_ext[usage]:
+ usages.append(usage)
- # Is this a critical extension [y/N]?
- keystroke += 'y\n'
+ cmd.extend([','.join(usages)])
- # Enter value for the authKeyID extension [y/N]?
- keystroke += 'y\n'
+ # Basic constraints
+ if basic_constraints_ext:
- # TODO: generate SHA1 ID (see APolicyRule.formSHA1KeyId())
- # Enter value for the key identifier fields,enter to omit:
- keystroke += '2d:7e:83:37:75:5a:fd:0e:8d:52:a3:70:16:93:36:b8:4a:d6:84:9f\n'
+ cmd.extend(['-2'])
- # Select one of the following general name type:
- keystroke += '0\n'
+ # Is this a CA certificate [y/N]?
+ if basic_constraints_ext['ca']:
+ keystroke += 'y'
- # Enter value for the authCertSerial field, enter to omit:
- keystroke += '\n'
+ keystroke += '\n'
- # Is this a critical extension [y/N]?
- keystroke += '\n'
+ # Enter the path length constraint, enter to skip [<0 for unlimited path]:
+ if basic_constraints_ext['path_length']:
+ keystroke += basic_constraints_ext['path_length']
- # TODO: generate SHA1 ID (see APolicyRule.formSHA1KeyId())
- # Adding Subject Key ID extension.
- # Enter value for the key identifier fields,enter to omit:
- keystroke += '2d:7e:83:37:75:5a:fd:0e:8d:52:a3:70:16:93:36:b8:4a:d6:84:9f\n'
+ keystroke += '\n'
- # Is this a critical extension [y/N]?
- keystroke += '\n'
+ # Is this a critical extension [y/N]?
+ if basic_constraints_ext['critical']:
+ keystroke += 'y'
- # Enter access method type for Authority Information Access extension:
- keystroke += '2\n'
+ keystroke += '\n'
- # Select one of the following general name type:
- keystroke += '7\n'
+ if ski_ext:
+ cmd.extend(['--extSKID'])
- # TODO: replace with actual hostname name and port number
- # Enter data:
- keystroke += 'http://server.example.com:8080/ca/ocsp\n'
+ # Adding Subject Key ID extension.
+ # Enter value for the key identifier fields,enter to omit:
+ if 'sk_id' in ski_ext:
+ keystroke += ski_ext['sk_id']
- # Select one of the following general name type:
- keystroke += '0\n'
+ keystroke += '\n'
- # Add another location to the Authority Information Access extension [y/N]
- keystroke += '\n'
+ # Is this a critical extension [y/N]?
+ if 'critical' in ski_ext and ski_ext['critical']:
+ keystroke += 'y'
- # Is this a critical extension [y/N]?
- keystroke += '\n'
+ keystroke += '\n'
+
+ if aia_ext:
+ cmd.extend(['--extAIA'])
+
+ # To ensure whether this is the first AIA being added
+ firstentry = True
+
+ # Enter access method type for Authority Information Access extension:
+ for s in aia_ext:
+ if not firstentry:
+ keystroke += 'y\n'
+
+ # 1. CA Issuers
+ if s == 'ca_issuers':
+ keystroke += '1'
+
+ # 2. OCSP
+ if s == 'ocsp':
+ keystroke += '2'
+ keystroke += '\n'
+ for gn in aia_ext[s]['uri']:
+ # 7. URI
+ keystroke += '7\n'
+ # Enter data
+ keystroke += gn + '\n'
+
+ # Any other number to finish
+ keystroke += '0\n'
+
+ # One entry is done.
+ firstentry = False
+
+ # Add another location to the Authority Information Access extension [y/N]
+ keystroke += '\n'
+
+ # Is this a critical extension [y/N]?
+ if 'critical' in aia_ext and aia_ext['critical']:
+ keystroke += 'y'
+
+ keystroke += '\n'
+
+ p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
p.communicate(keystroke)
rc = p.wait()
+ return rc
+
+ def create_self_signed_ca_cert(self, request_file, cert_file,
+ serial='1', validity=240):
+
+ # --keyUsage
+ key_usage_ext = {
+ 'digitalSignature': True,
+ 'nonRepudiation': True,
+ 'certSigning': True,
+ 'crlSigning': True,
+ 'critical': True
+ }
+
+ # -2
+ basic_constraints_ext = {
+ 'path_length': None
+ }
+
+ # FIXME: do not hard-code AKI extension
+ # -3
+ aki_ext = {
+ 'auth_key_id': '0x2d7e8337755afd0e8d52a370169336b84ad6849f'
+ }
+
+ # FIXME: do not hard-code SKI extension
+ # --extSKID
+ ski_ext = {
+ 'sk_id': '0x2d7e8337755afd0e8d52a370169336b84ad6849f'
+ }
+
+ # FIXME: do not hard-code AIA extension
+ # --extAIA
+ aia_ext = {
+ 'ocsp': {
+ 'uri': ['http://server.example.com:8080/ca/ocsp']
+ }
+
+ }
+
+ rc = self.create_cert(
+ request_file=request_file,
+ cert_file=cert_file,
+ serial=serial,
+ validity=validity,
+ key_usage_ext=key_usage_ext,
+ basic_constraints_ext=basic_constraints_ext,
+ aki_ext=aki_ext,
+ ski_ext=ski_ext,
+ aia_ext=aia_ext)
+
if rc:
raise Exception('Failed to generate self-signed CA certificate. RC: %d' % rc)