191880b Use the OpenSSL certificate parser in cert-find

Authored and Committed by rcritten 2 years ago
    Use the OpenSSL certificate parser in cert-find
    
    cert-find is a rather complex beast because it not only
    looks for certificates in the optional CA but within the
    IPA LDAP database as well. It has a process to deduplicate
    the certificates since any PKI issued certificates will
    also be associated with an IPA record.
    
    In order to obtain the data to deduplicate the certificates
    the cert from LDAP must be parser for issuer and serial number.
    ipaldap has automation to determine the datatype of an
    attribute and will use the python-cryptography engine to
    decode a certificate automatically if you access
    entry['usercertificate'].
    
    The downside is that this is comparatively slow. Here is the
    parse time in microseconds:
    
    OpenSSL.crypto 175
    pyasn1 1010
    python-cryptography 3136
    
    The python-cryptography time is fine if you're parsing one
    certificate but if the LDAP search returns a lot of certificates,
    say in the thousands, then those microseconds add up quickly.
    In testing it took ~17 seconds to parse 5k certificates.
    
    It's hard to overstate just how much better the cryptography
    Python interface is. In the case of OpenSSL really the only
    certificate fields easily available are serial number, subject
    and issuer. And the subject/issuer are in the OpenSSL reverse
    format which doesn't compare nicely to the cryptography format.
    The DN module can correct this.
    
    Fortunately for cert-find we only need serial number and issuer,
    so the OpenSSL module fine. It takes ~2 seconds.
    
    pyasn1 is also relatively faster but switch to it would require
    subtantially more effort for less payback.
    
    cert-find when there are a lot of certificates has been
    historically slow. It isn't related to the CA which returns
    large sets (well, 5k anyway) in a second or two. It was the
    LDAP comparision adding tens of seconds to the runtime.
    
    CLI times from before and after:
    
    original:
    
    -------------------------------
    Number of entries returned 5011
    -------------------------------
    real    0m21.155s
    user    0m0.835s
    sys     0m0.159s
    
    using OpenSSL:
    
    real    0m5.747s
    user    0m0.864s
    sys     0m0.148s
    
    OpenSSL is forcibly lazy-loaded so it doesn't conflict with
    python-requests.  See ipaserver/wsgi.py for the gory details.
    
    Fixes: https://pagure.io/freeipa/issue/9331
    
    Signed-off-by: Rob Crittenden <rcritten@redhat.com>
    Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
    Reviewed-By: Antonio Torres <antorres@redhat.com>
    
        
file modified
+2 -0
file modified
+23 -3