Search code examples
openssl

openssl do not recognize CRL from HTTP


have a strange issue. When using local CRL files for verifying certificate, everything is ok, but verification fails when done using HTTP (to the same file). This happens regardless of Content-Type, returned by Apache2 - either application/pem-certificate-chain or text/plain give the same result. I have no ideas, where and what need to be fixed - whether this is misconfiguration in Apache (which?!) or error/feature of openssl? Will appreciate any ideas on how to fix this. Thank you.

Local verification (even full chain is verifiable):

root@pkibox:~/simki# openssl verify -CAfile certs/za-fullchain.crt -crl_check -CRLfile crl/crl-a1.pem certs/za.crt
certs/za.crt: OK
root@pkibox:~/simki# openssl verify -CAfile certs/za-fullchain.crt -crl_check_all -CRLfile crl/crl-a1.pem -CRLfile crl/crl-r1.pem certs/za.crt
certs/za.crt: OK

BUT when trying to access this same file over HTTP, I receive error from openssl:

root@pkibox:~/simki# openssl verify -CAfile certs/za-fullchain.crt -crl_check -crl_download certs/za.crt
Unable to load CRL via CDP
802B4BD0EF7F0000:error:1E80006E:HTTP routines:OSSL_HTTP_REQ_CTX_nbio:missing asn1 encoding:../crypto/http/http_client.c:755:
802B4BD0EF7F0000:error:1E800067:HTTP routines:OSSL_HTTP_REQ_CTX_exchange:error receiving:../crypto/http/http_client.c:874:server=http://pki.xxx.net:80
O = SIM, OU = SIM NOC, CN = za
error 3 at 0 depth lookup: unable to get certificate CRL
error certs/za.crt: verification failed

while Apache logs clearly says that file accessed:

pki.xxx.net:80 192.168.255.5 - - [17/Apr/2023:06:24:02 +0000] "GET /crl-a1.pem HTTP/1.0" 200 918 "-" "-"

and cURL test passes successfully:

root@pkibox:~/simki# curl -v http://pki.xxx.net/crl-a1.pem
*   Trying 192.168.255.5:80...
* Connected to pki.xxx.net (192.168.255.5) port 80 (#0)
> GET /crl-a1.pem HTTP/1.1
> Host: pki.xxx.net
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Mon, 17 Apr 2023 06:23:58 GMT
< Server: Apache/2.4.52 (Ubuntu)
< Last-Modified: Mon, 17 Apr 2023 06:18:28 GMT
< ETag: "286-5f98228c77597"
< Accept-Ranges: bytes
< Content-Length: 646
< Content-Type: application/pem-certificate-chain
<
-----BEGIN X509 CRL-----
MIIBszCBnAIBATANBgkqhkiG9w0BAQsFADA5MQwwCgYDVQQKDANSSU0xEDAOBgNV
BAsMB1JJTSBOT0MxFzAVBgNVBAMMDlJJTSBTaWduaW5nIEExFw0yMzA0MTcwNjE3
[ ... ]
nBLzoS7VkQ==
-----END X509 CRL-----
* Connection #0 to host pki.xxx.net left intact

Certificate itself is ok, verifiable using openssl and contains CRL URI:

root@pkibox:~/simki# openssl x509 -in certs/za.crt -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1 (0x1)
        [ ... ]
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Non Repudiation, Key Encipherment
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Extended Key Usage:
                TLS Web Client Authentication
            [ ... ]
            X509v3 CRL Distribution Points:
                Full Name:
                  URI:http://pki.xxx.net/crl-a1.pem
    [ ... ]

and the same for CRL PEM:

root@pkibox:~/simki# openssl crl -in /var/www/simki/crl-a1.pem -noout -text
Certificate Revocation List (CRL):
        Version 2 (0x1)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: O = SIM, OU = SIM NOC, CN = SIM Signing A1
        Last Update: Apr 17 06:17:27 2023 GMT
        Next Update: Apr 16 06:17:27 2024 GMT
        CRL extensions:
            X509v3 Authority Key Identifier:
                6E:5B:C0:D1:03:41:D2:65:49:89:47:F9:D4:48:D5:5E:68:A8:F4:6F
            X509v3 CRL Number:
                1
No Revoked Certificates.
    Signature Algorithm: sha256WithRSAEncryption
[ ... ]

Solution

  • This isn't really programming or development but rfc5280 says

       If the DistributionPointName contains a general name of type URI, the
       following semantics MUST be assumed: the URI is a pointer to the
       current CRL for the associated reasons and will be issued by the
       associated cRLIssuer.  When the HTTP or FTP URI scheme is used, the
       URI MUST point to a single DER encoded CRL as specified in
       [RFC2585].  HTTP server implementations accessed via the URI SHOULD
       specify the media type application/pkix-crl in the content-type
       header field of the response.  ...
    

    Note DER not PEM. For HTTP openssl doesn't check the media-type (aka Content-Type) in the header, but the actual content must be that specified for application/pkix-crl which is DER.

    application/pem-certificate-chain is registered by a different protocol (ACME) for a different purpose (issuing a cert to its subject/owner), and moreover it must contain only cert(s) not CRL(s).

    PS: you should be aware that many programs nowadays, particularly Chrome and Firefox, don't download or use CRLs. OCSP is now more common -- particularly 'stapled' OCSP carried in the TLS handshake, with no extra connections or roundtrips -- though far from universal. CABforum has for a while required AIA.OCSPresponder but not required CRLDP in leaf certs for the web. And even for programs like OpenSSL that (can) use CRL, a CA that updates CRL only yearly won't usefully protect against use of invalid certs, especially since nowadays most leaf certs can't have validity-period much more than a year to start with. But those considerations are definitely not programming or development and thus don't belong here.