Browse Source

Implement treatment of id-pkix-ocsp-no-check extension for OCSP_basic_verify()

Fixes #7761

Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/12947)
Dr. David von Oheimb 3 years ago
parent
commit
4ff993d791

+ 14 - 5
crypto/ocsp/ocsp_vfy.c

@@ -26,7 +26,8 @@ static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req,
                                 unsigned long flags);
 
 /* Returns 1 on success, 0 on failure, or -1 on fatal error */
-static int ocsp_verify_signer(X509 *signer, X509_STORE *st, unsigned long flags,
+static int ocsp_verify_signer(X509 *signer, int response,
+                              X509_STORE *st, unsigned long flags,
                               STACK_OF(X509) *untrusted, STACK_OF(X509) **chain)
 {
     X509_STORE_CTX *ctx = X509_STORE_CTX_new();
@@ -41,9 +42,17 @@ static int ocsp_verify_signer(X509 *signer, X509_STORE *st, unsigned long flags,
         OCSPerr(0, ERR_R_X509_LIB);
         goto end;
     }
-    if ((flags & OCSP_PARTIAL_CHAIN) != 0
-            && (vp = X509_STORE_CTX_get0_param(ctx)) != NULL)
+    if ((vp = X509_STORE_CTX_get0_param(ctx)) == NULL)
+        goto end;
+    if ((flags & OCSP_PARTIAL_CHAIN) != 0)
         X509_VERIFY_PARAM_set_flags(vp, X509_V_FLAG_PARTIAL_CHAIN);
+    if (response
+            && X509_get_ext_by_NID(signer, NID_id_pkix_OCSP_noCheck, -1) >= 0)
+        /*
+         * Locally disable revocation status checking for OCSP responder cert.
+         * Done here for CRLs; TODO should be done also for OCSP-based checks.
+         */
+        X509_VERIFY_PARAM_clear_flags(vp, X509_V_FLAG_CRL_CHECK);
     X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER);
     X509_STORE_CTX_set_trust(ctx, X509_TRUST_OCSP_REQUEST);
     /* TODO: why is X509_TRUST_OCSP_REQUEST set? Seems to get ignored. */
@@ -117,7 +126,7 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
         } else {
             untrusted = bs->certs;
         }
-        ret = ocsp_verify_signer(signer, st, flags, untrusted, &chain);
+        ret = ocsp_verify_signer(signer, 1, st, flags, untrusted, &chain);
         if (ret <= 0)
             goto end;
         if ((flags & OCSP_NOCHECKS) != 0) {
@@ -390,7 +399,7 @@ int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs,
         return 0; /* not returning 'ret' here for backward compatibility*/
     if ((flags & OCSP_NOVERIFY) != 0)
         return 1;
-    return ocsp_verify_signer(signer, store, flags,
+    return ocsp_verify_signer(signer, 0, store, flags,
                               (flags & OCSP_NOCHAIN) != 0 ?
                               NULL : req->optionalSignature->certs, NULL) > 0;
     /* using '> 0' here to avoid breaking backward compatibility returning -1 */

+ 1 - 0
crypto/x509/v3_purp.c

@@ -283,6 +283,7 @@ int X509_supported_extension(X509_EXTENSION *ex)
         NID_sbgp_ipAddrBlock,   /* 290 */
         NID_sbgp_autonomousSysNum, /* 291 */
 #endif
+        NID_id_pkix_OCSP_noCheck, /* 369 */
         NID_policy_constraints, /* 401 */
         NID_proxyCertInfo,      /* 663 */
         NID_name_constraints,   /* 666 */

+ 2 - 0
doc/man3/OCSP_resp_find_status.pod

@@ -135,6 +135,8 @@ in L<X509_VERIFY_PARAM_set_flags(3)/VERIFICATION FLAGS>.
 If I<flags> contains B<OCSP_NOCHAIN> it ignores all certificates in I<certs>
 and in I<bs>, else it takes them as untrusted intermediate CA certificates
 and uses them for constructing the validation path for the signer certificate.
+Certicate revocation status checks using CRLs is disabled during path validation
+if the signer certificate contains the B<id-pkix-ocsp-no-check> extension.
 After successful path
 validation the function returns success if the B<OCSP_NOCHECKS> flag is set.
 Otherwise it verifies that the signer certificate meets the OCSP issuer

+ 20 - 0
test/certs/ee-cert-crit-unknown-ext.pem

@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDMDCCAhigAwIBAgIBAjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDDAJDQTAg
+Fw0yMDA5MjMxMDM5MTNaGA8yMTIwMDkyNDEwMzkxM1owGTEXMBUGA1UEAwwOc2Vy
+dmVyLmV4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCo/4lY
+YYWu3tssD9Vz++K3qBt6dWAr1H08c3a1rt6TL38kkG3JHPSKOM2fooAWVsu0LLuT
+5Rcf/w3GQ/4xNPgo2HXpo7uIgu+jcuJTYgVFTeAxl++qnRDSWA2eBp4yuxsIVl1l
+Dz9mjsI2oBH/wFk1/Ukc3RxCMwZ4rgQ4I+XndWfTlK1aqUAfrFkQ9QzBZK1KxMY1
+U7OWaoIbFYvRmavknm+UqtKW5Vf7jJFkijwkFsbSGb6CYBM7YrDtPh2zyvlr3zG5
+ep5LR2inKcc/SuIiJ7TvkGPX79ByST5brbkb1Ctvhmjd1XMSuEPJ3EEPoqNGT4tn
+iIQPYf55NB9KiR+3AgMBAAGjgYwwgYkwHQYDVR0OBBYEFOeb4iqtimw6y3ZR5Y4H
+mCKX4XOiMB8GA1UdIwQYMBaAFLQRM/HX4l73U54gIhBPhga/H8leMAkGA1UdEwQC
+MAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwGQYDVR0RBBIwEIIOc2VydmVyLmV4YW1w
+bGUwDAYDKgMEAQH/BAIFADANBgkqhkiG9w0BAQsFAAOCAQEAOjBX/mPKtROMdd3S
+jGMxScTndXy+OMCTGmRMpFGrR8yQAgUDhcPytxN7FU+5Uo1qaV6+9xH9Q80mtJ6i
+Db5qHdxAw/1CTDKMzVUU3eVq1AMPbERSC/JYSeQct+rQ0N4QfOjEpTXnVMbeaL+Q
+yCsetPK2I8o8e63wuCYgWWIFQtszunGnKdbF60n9MI8uAryaCCDUptOdXIiHBDIW
+1ZLnhAAr9RvwK5+ph4pBefHMC9P/tZ/eB14kszaAPBhv8cJKEvM6dgboEbU1KMoz
+VY7rT7+7rTE6/2AoL6c5z+RE0oC/UE/i1vgEjO9GwBuL9QVhmkt7ejJR0+oM9EqA
+0l7sxw==
+-----END CERTIFICATE-----

+ 20 - 0
test/certs/ee-cert-noncrit-unknown-ext.pem

@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDLTCCAhWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDDAJDQTAg
+Fw0yMDA5MjMxMDM5NTJaGA8yMTIwMDkyNDEwMzk1MlowGTEXMBUGA1UEAwwOc2Vy
+dmVyLmV4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCo/4lY
+YYWu3tssD9Vz++K3qBt6dWAr1H08c3a1rt6TL38kkG3JHPSKOM2fooAWVsu0LLuT
+5Rcf/w3GQ/4xNPgo2HXpo7uIgu+jcuJTYgVFTeAxl++qnRDSWA2eBp4yuxsIVl1l
+Dz9mjsI2oBH/wFk1/Ukc3RxCMwZ4rgQ4I+XndWfTlK1aqUAfrFkQ9QzBZK1KxMY1
+U7OWaoIbFYvRmavknm+UqtKW5Vf7jJFkijwkFsbSGb6CYBM7YrDtPh2zyvlr3zG5
+ep5LR2inKcc/SuIiJ7TvkGPX79ByST5brbkb1Ctvhmjd1XMSuEPJ3EEPoqNGT4tn
+iIQPYf55NB9KiR+3AgMBAAGjgYkwgYYwHQYDVR0OBBYEFOeb4iqtimw6y3ZR5Y4H
+mCKX4XOiMB8GA1UdIwQYMBaAFLQRM/HX4l73U54gIhBPhga/H8leMAkGA1UdEwQC
+MAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwGQYDVR0RBBIwEIIOc2VydmVyLmV4YW1w
+bGUwCQYDKgMEBAIFADANBgkqhkiG9w0BAQsFAAOCAQEAGPgQHSiAqGMAur2KW4BS
+opArthSh7ZT1wVEX0lP5lI/BUv/Q1YYnKEWuR9o+8vP1w4gUhFzg9Zrwj3rCNoC5
+x2JipZt8kRo5ycXv4tzr6V4n1zSgGByjradc0VEfuqmw1WpxvLoHeV9hbiXFQf8/
+PiLVF5BZ0ZSJjTDqMWfqYGSZnWqLglAqhZtHXkdaGIS+MJ2MhwPaUgLNATzptJ4a
+fjUF9apbCLtz0UzvojF/Wmby/fzbnPbKDyV6P8IzsfLgrH9NXN/9OBG5evVZo4PR
+32eZwgjdftu64b2QwoZi0dInHOwJO30UfgkeypYTjnQLSXhrz56EPu9sWCNGXs61
+LA==
+-----END CERTIFICATE-----

+ 20 - 0
test/certs/ee-cert-ocsp-nocheck.pem

@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDNjCCAh6gAwIBAgIBAjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDDAJDQTAg
+Fw0yMDA5MjMxMDM4NDlaGA8yMTIwMDkyNDEwMzg0OVowGTEXMBUGA1UEAwwOc2Vy
+dmVyLmV4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCo/4lY
+YYWu3tssD9Vz++K3qBt6dWAr1H08c3a1rt6TL38kkG3JHPSKOM2fooAWVsu0LLuT
+5Rcf/w3GQ/4xNPgo2HXpo7uIgu+jcuJTYgVFTeAxl++qnRDSWA2eBp4yuxsIVl1l
+Dz9mjsI2oBH/wFk1/Ukc3RxCMwZ4rgQ4I+XndWfTlK1aqUAfrFkQ9QzBZK1KxMY1
+U7OWaoIbFYvRmavknm+UqtKW5Vf7jJFkijwkFsbSGb6CYBM7YrDtPh2zyvlr3zG5
+ep5LR2inKcc/SuIiJ7TvkGPX79ByST5brbkb1Ctvhmjd1XMSuEPJ3EEPoqNGT4tn
+iIQPYf55NB9KiR+3AgMBAAGjgZIwgY8wHQYDVR0OBBYEFOeb4iqtimw6y3ZR5Y4H
+mCKX4XOiMB8GA1UdIwQYMBaAFLQRM/HX4l73U54gIhBPhga/H8leMAkGA1UdEwQC
+MAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwGQYDVR0RBBIwEIIOc2VydmVyLmV4YW1w
+bGUwEgYJKwYBBQUHMAEFAQH/BAIFADANBgkqhkiG9w0BAQsFAAOCAQEADK7EvoaQ
+Q/hwA48Vt+umuaquwUTn7IP5eWD6TivgTxnx5Qj1vqCC4AqZF4L8fV4RW2kXhbW+
+gwJIWr0w2EzzZnaObJK/zWyXdb+fpyLsl65BAABDjm2GVZEuX7Zvm+4cJ9mUozWz
+/r1d4x9s2bmuo+6S3HH+ceXhyYPHnMc9gkzLubMZp7yO9FaDNmC9UoSnv1W0Ijkf
+D+jV4ErjON9eCuFTt7xxa9xVNCnB1shXLvoyiGd9yCyO4cScpxNPl3/VY9kx5W2G
+OeRYsJw4DZOY6hRkJq2ftDiOsDWiAXBkWuItf0hynOkSyBh1bcW+h94iBZ9uB1X+
+LRAbn7Qf3ITyCw==
+-----END CERTIFICATE-----

+ 7 - 1
test/certs/setup.sh

@@ -401,5 +401,11 @@ OPENSSL_SIGALG=ED448 OPENSSL_KEYALG=ed448 ./mkcert.sh genroot "Root Ed448" \
 OPENSSL_SIGALG=ED448 OPENSSL_KEYALG=ed448 ./mkcert.sh genee ed448 \
     server-ed448-key server-ed448-cert root-ed448-key root-ed448-cert
 
-# Cert with id-pkix-ocsp-no-check
+# non-critical unknown extension
+./mkcert.sh geneeextra server.example ee-key ee-cert-noncrit-unknown-ext ca-key ca-cert "1.2.3.4=DER:05:00"
+
+# critical unknown extension
+./mkcert.sh geneeextra server.example ee-key ee-cert-crit-unknown-ext ca-key ca-cert "1.2.3.4=critical,DER:05:00"
+
+# critical id-pkix-ocsp-no-check extension
 ./mkcert.sh geneeextra server.example ee-key ee-cert-ocsp-nocheck ca-key ca-cert "1.3.6.1.5.5.7.48.1.5=critical,DER:05:00"

+ 10 - 1
test/recipes/25-test_verify.t

@@ -27,7 +27,7 @@ sub verify {
     run(app([@args]));
 }
 
-plan tests => 148;
+plan tests => 151;
 
 # Canonical success
 ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]),
@@ -45,6 +45,15 @@ ok(!verify("ee-cert", "sslserver", [qw(root-cert2)], [qw(ca-cert)]),
 ok(!verify("ee-cert", "sslserver", [qw(root-name2)], [qw(ca-cert)]),
    "fail wrong root DN");
 
+# Critical extensions
+
+ok(verify("ee-cert-noncrit-unknown-ext", "sslserver", [qw(root-cert)], [qw(ca-cert)]),
+   "accept non-critical unknown extension");
+ok(!verify("ee-cert-crit-unknown-ext", "sslserver", [qw(root-cert)], [qw(ca-cert)]),
+   "reject critical unknown extension");
+ok(verify("ee-cert-ocsp-nocheck", "sslserver", [qw(root-cert)], [qw(ca-cert)]),
+   "accept critical OCSP No Check");
+
 # Explicit trust/purpose combinations
 #
 ok(verify("ee-cert", "sslserver", [qw(sroot-cert)], [qw(ca-cert)]),