[openssl] master update

dev at ddvo.net dev at ddvo.net
Sat Sep 26 12:05:15 UTC 2020


The branch master has been updated
       via  4ff993d7912516a2fd1d5c1e97a6f26a4644c1c6 (commit)
       via  cf61b97d5fb9208ac254e999d86b1cf40c12b442 (commit)
       via  37326895b75297071560eb09d167f3ac90af71b4 (commit)
       via  7d5ea3fecbfb12cdbcfce32cc4ea00b96ee4218d (commit)
      from  4f5b222b84432a11c44d8c9a11c7fa98351db79b (commit)


- Log -----------------------------------------------------------------
commit 4ff993d7912516a2fd1d5c1e97a6f26a4644c1c6
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Tue Sep 22 08:36:22 2020 +0200

    Implement treatment of id-pkix-ocsp-no-check extension for OCSP_basic_verify()
    
    Fixes #7761
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/12947)

commit cf61b97d5fb9208ac254e999d86b1cf40c12b442
Author: Tomas Mraz <tmraz at fedoraproject.org>
Date:   Wed Sep 23 09:43:43 2020 +0200

    Generate a certificate with critical id-pkix-ocsp-nocheck extension
    
    Reviewed-by: David von Oheimb <david.von.oheimb at siemens.com>
    (Merged from https://github.com/openssl/openssl/pull/12947)

commit 37326895b75297071560eb09d167f3ac90af71b4
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Tue Sep 22 08:31:17 2020 +0200

    OCSP_resp_find_status.pod: Slightly improve the documentation of various flags
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/12947)

commit 7d5ea3fecbfb12cdbcfce32cc4ea00b96ee4218d
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Tue Sep 22 08:18:31 2020 +0200

    OCSP_resp_find_status.pod: Replace function arg references B<...> by I<...>
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/12947)

-----------------------------------------------------------------------

Summary of changes:
 crypto/ocsp/ocsp_vfy.c                     |  19 +++--
 crypto/x509/v3_purp.c                      |   1 +
 doc/man3/OCSP_resp_find_status.pod         | 109 +++++++++++++++--------------
 test/certs/ee-cert-crit-unknown-ext.pem    |  20 ++++++
 test/certs/ee-cert-noncrit-unknown-ext.pem |  20 ++++++
 test/certs/ee-cert-ocsp-nocheck.pem        |  20 ++++++
 test/certs/mkcert.sh                       |  36 +++++++++-
 test/certs/setup.sh                        |   9 +++
 test/recipes/25-test_verify.t              |  11 ++-
 9 files changed, 185 insertions(+), 60 deletions(-)
 create mode 100644 test/certs/ee-cert-crit-unknown-ext.pem
 create mode 100644 test/certs/ee-cert-noncrit-unknown-ext.pem
 create mode 100644 test/certs/ee-cert-ocsp-nocheck.pem

diff --git a/crypto/ocsp/ocsp_vfy.c b/crypto/ocsp/ocsp_vfy.c
index 92512829c9..0cd59f9221 100644
--- a/crypto/ocsp/ocsp_vfy.c
+++ b/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 */
diff --git a/crypto/x509/v3_purp.c b/crypto/x509/v3_purp.c
index 8b0dfd9759..fd512419f0 100644
--- a/crypto/x509/v3_purp.c
+++ b/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 */
diff --git a/doc/man3/OCSP_resp_find_status.pod b/doc/man3/OCSP_resp_find_status.pod
index 7dd90837b6..7c16b8c889 100644
--- a/doc/man3/OCSP_resp_find_status.pod
+++ b/doc/man3/OCSP_resp_find_status.pod
@@ -60,12 +60,12 @@ OCSP_basic_verify
 
 =head1 DESCRIPTION
 
-OCSP_resp_find_status() searches B<bs> for an OCSP response for B<id>. If it is
-successful the fields of the response are returned in B<*status>, B<*reason>,
-B<*revtime>, B<*thisupd> and B<*nextupd>.  The B<*status> value will be one of
+OCSP_resp_find_status() searches I<bs> for an OCSP response for I<id>. If it is
+successful the fields of the response are returned in I<*status>, I<*reason>,
+I<*revtime>, I<*thisupd> and I<*nextupd>.  The I<*status> value will be one of
 B<V_OCSP_CERTSTATUS_GOOD>, B<V_OCSP_CERTSTATUS_REVOKED> or
-B<V_OCSP_CERTSTATUS_UNKNOWN>. The B<*reason> and B<*revtime> fields are only
-set if the status is B<V_OCSP_CERTSTATUS_REVOKED>. If set the B<*reason> field
+B<V_OCSP_CERTSTATUS_UNKNOWN>. The I<*reason> and I<*revtime> fields are only
+set if the status is B<V_OCSP_CERTSTATUS_REVOKED>. If set the I<*reason> field
 will be set to the revocation reason which will be one of
 B<OCSP_REVOKED_STATUS_NOSTATUS>, B<OCSP_REVOKED_STATUS_UNSPECIFIED>,
 B<OCSP_REVOKED_STATUS_KEYCOMPROMISE>, B<OCSP_REVOKED_STATUS_CACOMPROMISE>,
@@ -73,88 +73,91 @@ B<OCSP_REVOKED_STATUS_AFFILIATIONCHANGED>, B<OCSP_REVOKED_STATUS_SUPERSEDED>,
 B<OCSP_REVOKED_STATUS_CESSATIONOFOPERATION>,
 B<OCSP_REVOKED_STATUS_CERTIFICATEHOLD> or B<OCSP_REVOKED_STATUS_REMOVEFROMCRL>.
 
-OCSP_resp_count() returns the number of B<OCSP_SINGLERESP> structures in B<bs>.
+OCSP_resp_count() returns the number of B<OCSP_SINGLERESP> structures in I<bs>.
 
-OCSP_resp_get0() returns the B<OCSP_SINGLERESP> structure in B<bs>
-corresponding to index B<idx>. Where B<idx> runs from 0 to
+OCSP_resp_get0() returns the B<OCSP_SINGLERESP> structure in I<bs>
+corresponding to index I<idx>. Where I<idx> runs from 0 to
 OCSP_resp_count(bs) - 1.
 
-OCSP_resp_find() searches B<bs> for B<id> and returns the index of the first
-matching entry after B<last> or starting from the beginning if B<last> is -1.
+OCSP_resp_find() searches I<bs> for I<id> and returns the index of the first
+matching entry after I<last> or starting from the beginning if I<last> is -1.
 
-OCSP_single_get0_status() extracts the fields of B<single> in B<*reason>,
-B<*revtime>, B<*thisupd> and B<*nextupd>.
+OCSP_single_get0_status() extracts the fields of I<single> in I<*reason>,
+I<*revtime>, I<*thisupd> and I<*nextupd>.
 
 OCSP_resp_get0_produced_at() extracts the B<producedAt> field from the
-single response B<bs>.
+single response I<bs>.
 
-OCSP_resp_get0_signature() returns the signature from B<bs>.
+OCSP_resp_get0_signature() returns the signature from I<bs>.
 
-OCSP_resp_get0_tbs_sigalg() returns the B<signatureAlgorithm> from B<bs>.
+OCSP_resp_get0_tbs_sigalg() returns the B<signatureAlgorithm> from I<bs>.
 
-OCSP_resp_get0_respdata() returns the B<tbsResponseData> from B<bs>.
+OCSP_resp_get0_respdata() returns the B<tbsResponseData> from I<bs>.
 
-OCSP_resp_get0_certs() returns any certificates included in B<bs>.
+OCSP_resp_get0_certs() returns any certificates included in I<bs>.
 
 OCSP_resp_get0_signer() attempts to retrieve the certificate that directly
-signed B<bs>.  The OCSP protocol does not require that this certificate
+signed I<bs>.  The OCSP protocol does not require that this certificate
 is included in the B<certs> field of the response, so additional certificates
-can be supplied in B<extra_certs> if the certificates that may have
+can be supplied via the I<extra_certs> if the certificates that may have
 signed the response are known via some out-of-band mechanism.
 
-OCSP_resp_get0_id() gets the responder id of B<bs>. If the responder ID is
-a name then <*pname> is set to the name and B<*pid> is set to NULL. If the
-responder ID is by key ID then B<*pid> is set to the key ID and B<*pname>
-is set to NULL. OCSP_resp_get1_id() leaves ownership of B<*pid> and B<*pname>
+OCSP_resp_get0_id() gets the responder id of I<bs>. If the responder ID is
+a name then <*pname> is set to the name and I<*pid> is set to NULL. If the
+responder ID is by key ID then I<*pid> is set to the key ID and I<*pname>
+is set to NULL. OCSP_resp_get1_id() leaves ownership of I<*pid> and I<*pname>
 with the caller, who is responsible for freeing them. Both functions return 1
 in case of success and 0 in case of failure. If OCSP_resp_get1_id() returns 0,
 no freeing of the results is necessary.
 
-OCSP_check_validity() checks the validity of B<thisupd> and B<nextupd> values
-which will be typically obtained from OCSP_resp_find_status() or
-OCSP_single_get0_status(). If B<sec> is nonzero it indicates how many seconds
-leeway should be allowed in the check. If B<maxsec> is positive it indicates
-the maximum age of B<thisupd> in seconds.
+OCSP_check_validity() checks the validity of its I<thisupd> and I<nextupd>
+arguments, which will be typically obtained from OCSP_resp_find_status() or
+OCSP_single_get0_status(). If I<sec> is nonzero it indicates how many seconds
+leeway should be allowed in the check. If I<maxsec> is positive it indicates
+the maximum age of I<thisupd> in seconds.
 
-OCSP_basic_verify() checks that the basic response message B<bs> is correctly
-signed and that the signer certificate can be validated. It takes B<st> as
-the trusted store and B<certs> as a set of untrusted intermediate certificates.
+OCSP_basic_verify() checks that the basic response message I<bs> is correctly
+signed and that the signer certificate can be validated. It takes I<st> as
+the trusted store and I<certs> as a set of untrusted intermediate certificates.
 The function first tries to find the signer certificate of the response
-in B<certs>. It also searches the certificates the responder may have included
-in B<bs> unless the B<flags> contain B<OCSP_NOINTERN>.
+in I<certs>. It then searches the certificates the responder may have included
+in I<bs> unless I<flags> contains B<OCSP_NOINTERN>.
 It fails if the signer certificate cannot be found.
-Next, the function checks the signature of B<bs> and fails on error
-unless the B<flags> contain B<OCSP_NOSIGS>. Then the function already returns
-success if the B<flags> contain B<OCSP_NOVERIFY> or if the signer certificate
-was found in B<certs> and the B<flags> contain B<OCSP_TRUSTOTHER>.
+Next, unless I<flags> contains B<OCSP_NOSIGS>, the function checks
+the signature of I<bs> and fails on error. Then the function already returns
+success if I<flags> contains B<OCSP_NOVERIFY> or if the signer certificate
+was found in I<certs> and I<flags> contains B<OCSP_TRUSTOTHER>.
 Otherwise the function continues by validating the signer certificate.
-If B<flags> contains B<OCSP_PARTIAL_CHAIN>, intermediate CA certificates
-in B<st> are trust-anchors.
+If I<flags> contains B<OCSP_PARTIAL_CHAIN> it takes intermediate CA
+certificates in I<st> as trust anchors.
 For more details, see the description of B<X509_V_FLAG_PARTIAL_CHAIN>
 in L<X509_VERIFY_PARAM_set_flags(3)/VERIFICATION FLAGS>.
-To this end, all certificates in B<cert> and in B<bs> are considered as
-untrusted certificates for the construction of the validation path for the
-signer certificate unless the B<OCSP_NOCHAIN> flag is set. After successful path
+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
 criteria including potential delegation. If this does not succeed and the
-B<flags> do not contain B<OCSP_NOEXPLICIT> the function checks for explicit
+B<OCSP_NOEXPLICIT> flag is not set the function checks for explicit
 trust for OCSP signing in the root CA certificate.
 
 =head1 RETURN VALUES
 
-OCSP_resp_find_status() returns 1 if B<id> is found in B<bs> and 0 otherwise.
+OCSP_resp_find_status() returns 1 if I<id> is found in I<bs> and 0 otherwise.
 
 OCSP_resp_count() returns the total number of B<OCSP_SINGLERESP> fields in
-B<bs>.
+I<bs>.
 
 OCSP_resp_get0() returns a pointer to an B<OCSP_SINGLERESP> structure or
-B<NULL> if B<idx> is out of range.
+NULL if I<idx> is out of range.
 
-OCSP_resp_find() returns the index of B<id> in B<bs> (which may be 0) or -1 if
-B<id> was not found.
+OCSP_resp_find() returns the index of I<id> in I<bs> (which may be 0) or -1 if
+I<id> was not found.
 
-OCSP_single_get0_status() returns the status of B<single> or -1 if an error
+OCSP_single_get0_status() returns the status of I<single> or -1 if an error
 occurred.
 
 OCSP_resp_get0_signer() returns 1 if the signing certificate was located,
@@ -171,15 +174,15 @@ can then take appropriate action based on the status of the certificate.
 
 An OCSP response for a certificate contains B<thisUpdate> and B<nextUpdate>
 fields. Normally the current time should be between these two values. To
-account for clock skew the B<maxsec> field can be set to nonzero in
+account for clock skew the I<maxsec> field can be set to nonzero in
 OCSP_check_validity(). Some responders do not set the B<nextUpdate> field, this
 would otherwise mean an ancient response would be considered valid: the
-B<maxsec> parameter to OCSP_check_validity() can be used to limit the permitted
+I<maxsec> parameter to OCSP_check_validity() can be used to limit the permitted
 age of responses.
 
-The values written to B<*revtime>, B<*thisupd> and B<*nextupd> by
+The values written to I<*revtime>, I<*thisupd> and I<*nextupd> by
 OCSP_resp_find_status() and OCSP_single_get0_status() are internal pointers
-which B<MUST NOT> be freed up by the calling application. Any or all of these
+which MUST NOT be freed up by the calling application. Any or all of these
 parameters can be set to NULL if their value is not required.
 
 =head1 SEE ALSO
diff --git a/test/certs/ee-cert-crit-unknown-ext.pem b/test/certs/ee-cert-crit-unknown-ext.pem
new file mode 100644
index 0000000000..34f69357c1
--- /dev/null
+++ b/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-----
diff --git a/test/certs/ee-cert-noncrit-unknown-ext.pem b/test/certs/ee-cert-noncrit-unknown-ext.pem
new file mode 100644
index 0000000000..8c4695a5d8
--- /dev/null
+++ b/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-----
diff --git a/test/certs/ee-cert-ocsp-nocheck.pem b/test/certs/ee-cert-ocsp-nocheck.pem
new file mode 100644
index 0000000000..d70ffa7553
--- /dev/null
+++ b/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-----
diff --git a/test/certs/mkcert.sh b/test/certs/mkcert.sh
index 32fd5874d9..a564e30c6b 100755
--- a/test/certs/mkcert.sh
+++ b/test/certs/mkcert.sh
@@ -233,6 +233,40 @@ genee() {
 	    -set_serial 2 -days "${DAYS}" "$@"
 }
 
+geneeextra() {
+    local OPTIND=1
+    local purpose=serverAuth
+
+    while getopts p: o
+    do
+        case $o in
+        p) purpose="$OPTARG";;
+        *) echo "Usage: $0 geneeextra [-p EKU] cn keyname certname cakeyname cacertname extraext" >&2
+           return 1;;
+        esac
+    done
+
+    shift $((OPTIND - 1))
+    local cn=$1; shift
+    local key=$1; shift
+    local cert=$1; shift
+    local cakey=$1; shift
+    local ca=$1; shift
+    local extraext=$1; shift
+
+    exts=$(printf "%s\n%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
+	    "subjectKeyIdentifier = hash" \
+	    "authorityKeyIdentifier = keyid, issuer" \
+	    "basicConstraints = CA:false" \
+	    "extendedKeyUsage = $purpose" \
+	    "subjectAltName = @alts"\
+	    "$extraext" "DNS=${cn}")
+    csr=$(req "$key" "CN = $cn") || return 1
+    echo "$csr" |
+	cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
+	    -set_serial 2 -days "${DAYS}" "$@"
+}
+
 geneenocsr() {
     local OPTIND=1
     local purpose=serverAuth
@@ -241,7 +275,7 @@ geneenocsr() {
     do
         case $o in
         p) purpose="$OPTARG";;
-        *) echo "Usage: $0 genee [-p EKU] cn certname cakeyname cacertname" >&2
+        *) echo "Usage: $0 geneenocsr [-p EKU] cn certname cakeyname cacertname" >&2
            return 1;;
         esac
     done
diff --git a/test/certs/setup.sh b/test/certs/setup.sh
index ee3d678219..eb7f77e231 100755
--- a/test/certs/setup.sh
+++ b/test/certs/setup.sh
@@ -400,3 +400,12 @@ OPENSSL_SIGALG=ED448 OPENSSL_KEYALG=ed448 ./mkcert.sh genroot "Root Ed448" \
     root-ed448-key root-ed448-cert
 OPENSSL_SIGALG=ED448 OPENSSL_KEYALG=ed448 ./mkcert.sh genee ed448 \
     server-ed448-key server-ed448-cert root-ed448-key root-ed448-cert
+
+# 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"
diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t
index 6d8f78c978..9bbabd0fa3 100644
--- a/test/recipes/25-test_verify.t
+++ b/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)]),


More information about the openssl-commits mailing list