summaryrefslogtreecommitdiffstats
path: root/ipaserver/install
diff options
context:
space:
mode:
authorFraser Tweedale <ftweedal@redhat.com>2016-10-13 17:12:31 +1000
committerDavid Kupka <dkupka@redhat.com>2016-11-10 10:21:47 +0100
commitdb116f73fe5fc199bb2e28103cf5e3e2a24eab4c (patch)
treeff1a043b376ec4d98b6399040a868e8b45725ee0 /ipaserver/install
parentc57dc890b2bf447ab575f2e91249179bce3f05d5 (diff)
x509: use python-cryptography to process certs
Update x509.load_certificate and related functions to return python-cryptography ``Certificate`` objects. Update the call sites accordingly, including removal of NSS initialisation code. Also update GeneralName parsing code to return python-cryptography GeneralName values, for consistency with other code that processes GeneralNames. The new function, `get_san_general_names`, and associated helper functions, can be removed when python-cryptography provides a way to deal with unrecognised critical extensions. Part of: https://fedorahosted.org/freeipa/ticket/6398 Reviewed-By: Jan Cholasta <jcholast@redhat.com> Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
Diffstat (limited to 'ipaserver/install')
-rw-r--r--ipaserver/install/ca.py2
-rw-r--r--ipaserver/install/cainstance.py25
-rw-r--r--ipaserver/install/certs.py9
-rw-r--r--ipaserver/install/installutils.py14
-rw-r--r--ipaserver/install/ipa_cacert_manage.py103
-rw-r--r--ipaserver/install/krainstance.py2
6 files changed, 74 insertions, 81 deletions
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
index 88ec6277f..921e49495 100644
--- a/ipaserver/install/ca.py
+++ b/ipaserver/install/ca.py
@@ -102,7 +102,7 @@ def install_check(standalone, replica_config, options):
cert = db.get_cert_from_db(nickname)
if not cert:
continue
- subject = DN(str(x509.get_subject(cert)))
+ subject = DN(x509.load_certificate(cert).subject)
if subject in (DN('CN=Certificate Authority', subject_base),
DN('CN=IPA RA', subject_base)):
raise ScriptError(
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 1b7acef70..7b26e749e 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -554,9 +554,9 @@ class CAInstance(DogtagInstance):
config.set("CA", "pki_req_ext_data", "1E0A00530075006200430041")
elif self.external == 2:
- cert = x509.load_certificate_from_file(self.cert_file)
cert_file = tempfile.NamedTemporaryFile()
- x509.write_certificate(cert.der_data, cert_file.name)
+ with open(self.cert_file) as f:
+ x509.write_certificate(f.read(), cert_file.name)
cert_file.flush()
result = ipautil.run(
@@ -778,7 +778,7 @@ class CAInstance(DogtagInstance):
userstate=["1"],
userCertificate=[cert_data],
description=['2;%s;%s;%s' % (
- cert.serial_number,
+ cert.serial,
DN(('CN', 'Certificate Authority'), self.subject_base),
DN(('CN', 'IPA RA'), self.subject_base))])
conn.add_entry(entry)
@@ -1674,8 +1674,9 @@ def update_people_entry(dercert):
is needed when a certificate is renewed.
"""
def make_filter(dercert):
- subject = x509.get_subject(dercert, datatype=x509.DER)
- issuer = x509.get_issuer(dercert, datatype=x509.DER)
+ cert = x509.load_certificate(dercert, datatype=x509.DER)
+ subject = DN(cert.subject)
+ issuer = DN(cert.issuer)
return ldap2.ldap2.combine_filters(
[
ldap2.ldap2.make_filter({'objectClass': 'inetOrgPerson'}),
@@ -1686,9 +1687,10 @@ def update_people_entry(dercert):
ldap2.ldap2.MATCH_ALL)
def make_entry(dercert, entry):
- serial_number = x509.get_serial_number(dercert, datatype=x509.DER)
- subject = x509.get_subject(dercert, datatype=x509.DER)
- issuer = x509.get_issuer(dercert, datatype=x509.DER)
+ cert = x509.load_certificate(dercert, datatype=x509.DER)
+ serial_number = cert.serial
+ subject = DN(cert.subject)
+ issuer = DN(cert.issuer)
entry['usercertificate'].append(dercert)
entry['description'] = '2;%d;%s;%s' % (serial_number, issuer, subject)
return entry
@@ -1702,15 +1704,16 @@ def update_authority_entry(dercert):
serial number to match the given cert.
"""
def make_filter(dercert):
- subject = x509.get_subject(dercert, datatype=x509.DER)
+ cert = x509.load_certificate(dercert, datatype=x509.DER)
+ subject = str(DN(cert.subject))
return ldap2.ldap2.make_filter(
dict(objectclass='authority', authoritydn=subject),
rules=ldap2.ldap2.MATCH_ALL,
)
def make_entry(dercert, entry):
- serial_number = x509.get_serial_number(dercert, datatype=x509.DER)
- entry['authoritySerial'] = serial_number
+ cert = x509.load_certificate(dercert, datatype=x509.DER)
+ entry['authoritySerial'] = cert.serial
return entry
return __update_entry_from_cert(make_filter, make_entry, dercert)
diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
index 31fd36cc3..a73025099 100644
--- a/ipaserver/install/certs.py
+++ b/ipaserver/install/certs.py
@@ -60,9 +60,8 @@ def get_cert_nickname(cert):
representation of the first RDN in the subject and subject_dn
is a DN object.
"""
- nsscert = x509.load_certificate(cert)
- subject = str(nsscert.subject)
- dn = DN(subject)
+ cert_obj = x509.load_certificate(cert)
+ dn = DN(cert_obj.subject)
return (str(dn[0]), dn)
@@ -304,8 +303,8 @@ class CertDB(object):
return
cert = self.get_cert_from_db(nickname)
- nsscert = x509.load_certificate(cert, dbdir=self.secdir)
- subject = str(nsscert.subject)
+ cert_obj = x509.load_certificate(cert)
+ subject = str(DN(cert_obj.subject))
certmonger.add_principal(request_id, principal)
certmonger.add_subject(request_id, subject)
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index fb9579a07..bee501a6e 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -921,10 +921,9 @@ def load_pkcs12(cert_files, key_password, key_nickname, ca_cert_files,
if ca_cert is None:
ca_cert = cert
- nss_cert = x509.load_certificate(cert, x509.DER)
- subject = DN(str(nss_cert.subject))
- issuer = DN(str(nss_cert.issuer))
- del nss_cert
+ cert_obj = x509.load_certificate(cert, x509.DER)
+ subject = DN(cert_obj.subject)
+ issuer = DN(cert_obj.issuer)
if subject == issuer:
break
@@ -1046,10 +1045,9 @@ def load_external_cert(files, subject_base):
for nickname, _trust_flags in nssdb.list_certs():
cert = nssdb.get_cert(nickname, pem=True)
- nss_cert = x509.load_certificate(cert)
- subject = DN(str(nss_cert.subject))
- issuer = DN(str(nss_cert.issuer))
- del nss_cert
+ cert_obj = x509.load_certificate(cert)
+ subject = DN(cert_obj.subject)
+ issuer = DN(cert_obj.issuer)
cache[nickname] = (cert, subject, issuer)
if subject == ca_subject:
diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py
index af08ba68c..0dcb70fea 100644
--- a/ipaserver/install/ipa_cacert_manage.py
+++ b/ipaserver/install/ipa_cacert_manage.py
@@ -21,8 +21,7 @@ from __future__ import print_function
import os
from optparse import OptionGroup
-from nss import nss
-from nss.error import NSPRError
+from cryptography.hazmat.primitives import serialization
import gssapi
from ipapython import admintool, certmonger, ipautil
@@ -187,7 +186,7 @@ class CACertManage(admintool.AdminTool):
"--external-cert-file=/path/to/signed_certificate "
"--external-cert-file=/path/to/external_ca_certificate")
- def renew_external_step_2(self, ca, old_cert):
+ def renew_external_step_2(self, ca, old_cert_der):
print("Importing the renewed CA certificate, please wait")
options = self.options
@@ -195,55 +194,54 @@ class CACertManage(admintool.AdminTool):
cert_file, ca_file = installutils.load_external_cert(
options.external_cert_files, x509.subject_base())
- nss_cert = None
- nss.nss_init(paths.PKI_TOMCAT_ALIAS_DIR)
- try:
- nss_cert = x509.load_certificate(old_cert, x509.DER)
- subject = nss_cert.subject
- der_subject = x509.get_der_subject(old_cert, x509.DER)
- #pylint: disable=E1101
- pkinfo = nss_cert.subject_public_key_info.format()
- #pylint: enable=E1101
-
- nss_cert = x509.load_certificate_from_file(cert_file.name)
- cert = nss_cert.der_data
- if nss_cert.subject != subject:
- raise admintool.ScriptError(
- "Subject name mismatch (visit "
- "http://www.freeipa.org/page/Troubleshooting for "
- "troubleshooting guide)")
- if x509.get_der_subject(cert, x509.DER) != der_subject:
- raise admintool.ScriptError(
- "Subject name encoding mismatch (visit "
- "http://www.freeipa.org/page/Troubleshooting for "
- "troubleshooting guide)")
- #pylint: disable=E1101
- if nss_cert.subject_public_key_info.format() != pkinfo:
- raise admintool.ScriptError(
- "Subject public key info mismatch (visit "
- "http://www.freeipa.org/page/Troubleshooting for "
- "troubleshooting guide)")
- #pylint: enable=E1101
- finally:
- del nss_cert
- nss.nss_shutdown()
+ old_cert_obj = x509.load_certificate(old_cert_der, x509.DER)
+ old_der_subject = x509.get_der_subject(old_cert_der, x509.DER)
+ old_spki = old_cert_obj.public_key().public_bytes(
+ serialization.Encoding.DER,
+ serialization.PublicFormat.SubjectPublicKeyInfo
+ )
+
+ with open(cert_file.name) as f:
+ new_cert_data = f.read()
+ new_cert_der = x509.normalize_certificate(new_cert_data)
+ new_cert_obj = x509.load_certificate(new_cert_der, x509.DER)
+ new_der_subject = x509.get_der_subject(new_cert_der, x509.DER)
+ new_spki = new_cert_obj.public_key().public_bytes(
+ serialization.Encoding.DER,
+ serialization.PublicFormat.SubjectPublicKeyInfo
+ )
+
+ if new_cert_obj.subject != old_cert_obj.subject:
+ raise admintool.ScriptError(
+ "Subject name mismatch (visit "
+ "http://www.freeipa.org/page/Troubleshooting for "
+ "troubleshooting guide)")
+ if new_der_subject != old_der_subject:
+ raise admintool.ScriptError(
+ "Subject name encoding mismatch (visit "
+ "http://www.freeipa.org/page/Troubleshooting for "
+ "troubleshooting guide)")
+ if new_spki != old_spki:
+ raise admintool.ScriptError(
+ "Subject public key info mismatch (visit "
+ "http://www.freeipa.org/page/Troubleshooting for "
+ "troubleshooting guide)")
with certs.NSSDatabase() as tmpdb:
pw = ipautil.write_tmp_file(ipautil.ipa_generate_password())
tmpdb.create_db(pw.name)
- tmpdb.add_cert(old_cert, 'IPA CA', 'C,,')
+ tmpdb.add_cert(old_cert_der, 'IPA CA', 'C,,')
try:
- tmpdb.add_cert(cert, 'IPA CA', 'C,,')
+ tmpdb.add_cert(new_cert_der, 'IPA CA', 'C,,')
except ipautil.CalledProcessError as e:
raise admintool.ScriptError(
"Not compatible with the current CA certificate: %s" % e)
ca_certs = x509.load_certificate_list_from_file(ca_file.name)
for ca_cert in ca_certs:
- tmpdb.add_cert(ca_cert.der_data, str(ca_cert.subject), 'C,,')
- del ca_certs
- del ca_cert
+ data = ca_cert.public_bytes(serialization.Encoding.DER)
+ tmpdb.add_cert(data, str(DN(ca_cert.subject)), 'C,,')
try:
tmpdb.verify_ca_cert_validity('IPA CA')
@@ -266,14 +264,14 @@ class CACertManage(admintool.AdminTool):
('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
try:
entry = conn.get_entry(dn, ['usercertificate'])
- entry['usercertificate'] = [cert]
+ entry['usercertificate'] = [new_cert_der]
conn.update_entry(entry)
except errors.NotFound:
entry = conn.make_entry(
dn,
objectclass=['top', 'pkiuser', 'nscontainer'],
cn=[self.cert_nickname],
- usercertificate=[cert])
+ usercertificate=[new_cert_der])
conn.add_entry(entry)
except errors.EmptyModlist:
pass
@@ -313,21 +311,16 @@ class CACertManage(admintool.AdminTool):
options = self.options
cert_filename = self.args[1]
- nss_cert = None
try:
- try:
- nss_cert = x509.load_certificate_from_file(cert_filename)
- except IOError as e:
- raise admintool.ScriptError(
- "Can't open \"%s\": %s" % (cert_filename, e))
- except (TypeError, NSPRError, ValueError) as e:
- raise admintool.ScriptError("Not a valid certificate: %s" % e)
- subject = nss_cert.subject
- cert = nss_cert.der_data
- finally:
- del nss_cert
+ cert_obj = x509.load_certificate_from_file(cert_filename)
+ except IOError as e:
+ raise admintool.ScriptError(
+ "Can't open \"%s\": %s" % (cert_filename, e))
+ except (TypeError, ValueError) as e:
+ raise admintool.ScriptError("Not a valid certificate: %s" % e)
+ cert = cert_obj.public_bytes(serialization.Encoding.DER)
- nickname = options.nickname or str(subject)
+ nickname = options.nickname or str(DN(cert_obj.subject))
ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2,
api.env.basedn,
diff --git a/ipaserver/install/krainstance.py b/ipaserver/install/krainstance.py
index 315057808..77f23c1c3 100644
--- a/ipaserver/install/krainstance.py
+++ b/ipaserver/install/krainstance.py
@@ -297,7 +297,7 @@ class KRAInstance(DogtagInstance):
usertype=["undefined"],
userCertificate=[cert_data],
description=['2;%s;%s;%s' % (
- cert.serial_number,
+ cert.serial,
DN(('CN', 'Certificate Authority'), self.subject_base),
DN(('CN', 'IPA RA'), self.subject_base))])
conn.add_entry(entry)