diff --git a/freeipa.spec.in b/freeipa.spec.in index aa69bd246..40ca377bf 100755 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -407,6 +407,7 @@ BuildRequires: python3-pylint BuildRequires: python3-pytest-multihost BuildRequires: python3-pytest-sourceorder BuildRequires: python3-qrcode-core >= 5.0.0 +BuildRequires: python3-pyOpenSSL BuildRequires: python3-samba BuildRequires: python3-six BuildRequires: python3-sss @@ -877,6 +878,7 @@ Requires: python3-netifaces >= 0.10.4 Requires: python3-pyasn1 >= 0.3.2-2 Requires: python3-pyasn1-modules >= 0.3.2-2 Requires: python3-pyusb +Requires: python3-pyOpenSSL Requires: python3-qrcode-core >= 5.0.0 Requires: python3-requests Requires: python3-six diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py index 36a0e8cb3..61dfde5fe 100644 --- a/ipaserver/plugins/cert.py +++ b/ipaserver/plugins/cert.py @@ -30,6 +30,7 @@ import cryptography.x509 from cryptography.hazmat.primitives import hashes, serialization from dns import resolver, reversename import six +import sys from ipalib import Command, Str, Int, Flag, StrEnum, SerialNumber from ipalib import api @@ -1617,7 +1618,19 @@ class cert_find(Search, CertMethod): ) def _get_cert_key(self, cert): - return (DN(cert.issuer), cert.serial_number) + # for cert-find with a certificate value + if isinstance(cert, x509.IPACertificate): + return (DN(cert.issuer), cert.serial_number) + + issuer = [] + for oid, value in cert.get_issuer().get_components(): + issuer.append( + '{}={}'.format(oid.decode('utf-8'), value.decode('utf-8')) + ) + issuer = ','.join(issuer) + # Use this to flip from OpenSSL reverse to X500 ordering + issuer = DN(issuer).x500_text() + return (DN(issuer), cert.get_serial_number()) def _cert_search(self, pkey_only, **options): result = collections.OrderedDict() @@ -1737,6 +1750,11 @@ class cert_find(Search, CertMethod): return result, False, complete def _ldap_search(self, all, pkey_only, no_members, **options): + # defer import of the OpenSSL module to not affect the requests + # module which will use pyopenssl if this is available. + if sys.modules.get('OpenSSL.SSL', False) is None: + del sys.modules["OpenSSL.SSL"] + import OpenSSL.crypto ldap = self.api.Backend.ldap2 filters = [] @@ -1795,12 +1813,14 @@ class cert_find(Search, CertMethod): ca_enabled = getattr(context, 'ca_enabled') for entry in entries: for attr in ('usercertificate', 'usercertificate;binary'): - for cert in entry.get(attr, []): + for der in entry.raw.get(attr, []): + cert = OpenSSL.crypto.load_certificate( + OpenSSL.crypto.FILETYPE_ASN1, der) cert_key = self._get_cert_key(cert) try: obj = result[cert_key] except KeyError: - obj = {'serial_number': cert.serial_number} + obj = {'serial_number': cert.get_serial_number()} if not pkey_only and (all or not ca_enabled): # Retrieving certificate details is now deferred # until after all certificates are collected.