diff options
author | Dr. David von Oheimb <dev@ddvo.net> | 2024-12-09 22:22:24 +0100 |
---|---|---|
committer | Dr. David von Oheimb <dev@ddvo.net> | 2024-12-13 08:26:19 +0100 |
commit | a82c2bf5c9db9d00f16281b48c1e1430a6cfd76e (patch) | |
tree | 68fd626c3ffc7f31a293a66577ffc8501c72bb05 | |
parent | Fix the intermittent lhash_test failure on Windows (diff) | |
download | openssl-a82c2bf5c9db9d00f16281b48c1e1430a6cfd76e.tar.xz openssl-a82c2bf5c9db9d00f16281b48c1e1430a6cfd76e.zip |
X509: document non-standard behavior checking EKU extensions in CA and TA certs
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/26142)
-rw-r--r-- | doc/man1/openssl-cms.pod.in | 4 | ||||
-rw-r--r-- | doc/man1/openssl-s_client.pod.in | 12 | ||||
-rw-r--r-- | doc/man1/openssl-s_server.pod.in | 4 | ||||
-rw-r--r-- | doc/man1/openssl-verification-options.pod | 204 | ||||
-rw-r--r-- | doc/man3/SSL_CTX_new.pod | 10 | ||||
-rw-r--r-- | doc/man3/X509_STORE_CTX_new.pod | 18 | ||||
-rw-r--r-- | test/recipes/25-test_verify.t | 8 |
7 files changed, 163 insertions, 97 deletions
diff --git a/doc/man1/openssl-cms.pod.in b/doc/man1/openssl-cms.pod.in index f6b3a4c7d6..db8517f94c 100644 --- a/doc/man1/openssl-cms.pod.in +++ b/doc/man1/openssl-cms.pod.in @@ -192,6 +192,10 @@ to the output file. Verify signed data. Expects a signed data on input and outputs the signed data. Both clear text and opaque signing is supported. +By default, validation of signer certificates and their chain +is done w.r.t. the S/MIME signing (C<smimesign>) purpose. +For details see L<openssl-verification-options(1)/Certificate Extensions>. + =item B<-resign> Resign a message: take an existing message and one or more new signers. diff --git a/doc/man1/openssl-s_client.pod.in b/doc/man1/openssl-s_client.pod.in index 75934e714b..8e685d3551 100644 --- a/doc/man1/openssl-s_client.pod.in +++ b/doc/man1/openssl-s_client.pod.in @@ -303,14 +303,20 @@ see L<openssl-passphrase-options(1)>. The verify depth to use. This specifies the maximum length of the server certificate chain and turns on server certificate verification. -Currently the verify operation continues after errors so all the problems +Unless the B<-verify_return_error> option is given, +the verify operation continues after errors so all the problems with a certificate chain can be seen. As a side effect the connection will never fail due to a server certificate verify failure. +By default, validation of server certificates and their chain +is done w.r.t. the (D)TLS Server (C<sslserver>) purpose. +For details see L<openssl-verification-options(1)/Certificate Extensions>. + =item B<-verify_return_error> -Return verification errors instead of continuing. This will typically -abort the handshake with a fatal error. +Turns on server certificate verification, like with B<-verify>, +but returns verification errors instead of continuing. +This will typically abort the handshake with a fatal error. =item B<-verify_quiet> diff --git a/doc/man1/openssl-s_server.pod.in b/doc/man1/openssl-s_server.pod.in index d683c1a797..0d8dd9bd0a 100644 --- a/doc/man1/openssl-s_server.pod.in +++ b/doc/man1/openssl-s_server.pod.in @@ -212,6 +212,10 @@ must supply a certificate or an error occurs. If the cipher suite cannot request a client certificate (for example an anonymous cipher suite or PSK) this option has no effect. +By default, validation of any supplied client certificate and its chain +is done w.r.t. the (D)TLS Client (C<sslclient>) purpose. +For details see L<openssl-verification-options(1)/Certificate Extensions>. + =item B<-cert> I<infile> The certificate to use, most servers cipher suites require the use of a diff --git a/doc/man1/openssl-verification-options.pod b/doc/man1/openssl-verification-options.pod index 38ae58d83d..676fbb38a5 100644 --- a/doc/man1/openssl-verification-options.pod +++ b/doc/man1/openssl-verification-options.pod @@ -24,8 +24,9 @@ The most important of them are detailed in the following sections. In a nutshell, a valid chain of certificates needs to be built up and verified starting from the I<target certificate> that is to be verified and ending in a certificate that due to some policy is trusted. -Verification is done relative to the given I<purpose>, which is the intended use -of the target certificate, such as SSL server, or by default for any purpose. +Certificate validation can be performed in the context of a I<purpose>, which +is a high-level specification of the intended use of the target certificate, +such as C<sslserver> for TLS servers, or (by default) for any purpose. The details of how each OpenSSL command handles errors are documented on the specific command page. @@ -150,16 +151,17 @@ the chain components and their links are checked thoroughly. The first step is to check that each certificate is well-formed. Part of these checks are enabled only if the B<-x509_strict> option is given. -The second step is to check the extensions of every untrusted certificate -for consistency with the supplied purpose. -If the B<-purpose> option is not given then no such checks are done -except for SSL/TLS connection setup, -where by default C<sslserver> or C<sslclient>, are checked. -The target or "leaf" certificate, as well as any other untrusted certificates, -must have extensions compatible with the specified purpose. -All certificates except the target or "leaf" must also be valid CA certificates. -The precise extensions required are described in more detail in -L<openssl-x509(1)/CERTIFICATE EXTENSIONS>. +The second step is to check the X.509v3 extensions of every certificate +for consistency with the intended specific purpose, if any. +If the B<-purpose> option is not given then no such checks are done except for +CMS signature checking, where by default C<smimesign> is checked, and SSL/(D)TLS +connection setup, where by default C<sslserver> or C<sslclient> are checked. +The X.509v3 extensions of the target or "leaf" certificate +must be compatible with the specified purpose. +All other certificates down the chain are checked to be valid CA certificates, +and possibly also further non-standard checks are performed. +The precise extensions required are described in detail +in the L</Certificate Extensions> section below. The third step is to check the trust settings on the last certificate (which typically is a self-signed root CA certificate). @@ -455,13 +457,16 @@ Set policy variable inhibit-policy-mapping (see RFC5280). =item B<-purpose> I<purpose> -The intended use for the certificate. -Currently defined purposes are C<sslclient>, C<sslserver>, C<nssslserver>, +A high-level specification of the intended use of the target certificate. +Currently predefined purposes are C<sslclient>, C<sslserver>, C<nssslserver>, C<smimesign>, C<smimeencrypt>, C<crlsign>, C<ocsphelper>, C<timestampsign>, C<codesign> and C<any>. If peer certificate verification is enabled, by default the TLS implementation -as well as the commands B<s_client> and B<s_server> check for consistency -with TLS server or TLS client use, respectively. +and thus the commands L<openssl-s_client(1)> and L<openssl-s_server(1)> +check for consistency with +TLS server (C<sslserver>) or TLS client use (C<sslclient>), respectively. +By default, CMS signature validation, which can be done via L<openssl-cms(1)>, +checks for consistency with S/MIME signing use (C<smimesign>). While IETF RFC 5280 says that B<id-kp-serverAuth> and B<id-kp-clientAuth> are only for WWW use, in practice they are used for all kinds of TLS clients @@ -491,19 +496,20 @@ the subject certificate. =item B<-verify_name> I<name> -Use default verification policies like trust model and required certificate -policies identified by I<name>. +Use a set of verification parameters, also known as verification method, +identified by I<name>. The currently predefined methods are named C<ssl_client>, +C<ssl_server>, C<smime_sign> with alias C<pkcs7>, C<code_sign>, and C<default>. +These mimic the combinations of purpose and trust settings used in SSL/(D)TLS, +CMS/PKCS7 (including S/MIME), and code signing. + +The verification parameters include the trust model, various flags that can +partly be set also via other command-line options, and the verification purpose, +which in turn implies certificate key usage and extended key usage requirements. + The trust model determines which auxiliary trust or reject OIDs are applicable to verifying the given certificate chain. They can be given using the B<-addtrust> and B<-addreject> options for L<openssl-x509(1)>. -Supported policy names include: B<default>, B<pkcs7>, B<smime_sign>, -B<ssl_client>, B<ssl_server>. -These mimics the combinations of purpose and trust settings used in SSL, CMS -and S/MIME. -As of OpenSSL 1.1.0, the trust model is inferred from the purpose when not -specified, so the B<-verify_name> options are functionally equivalent to the -corresponding B<-purpose> settings. =back @@ -548,9 +554,8 @@ This option has no effect and is retained for backward compatibility only. =head2 Certificate Extensions -Options like B<-purpose> lead to checking the certificate extensions, -which determine what the target certificate and intermediate CA certificates -can be used for. +Options like B<-purpose> and B<-verify_name> trigger the processing of specific +certificate extensions, which determine what certificates can be used for. =head3 Basic Constraints @@ -574,87 +579,127 @@ keyCertSign bit set if the keyUsage extension is present. =head3 Extended Key Usage -The extKeyUsage (EKU) extension places additional restrictions on the -certificate uses. If this extension is present (whether critical or not) -the key can only be used for the purposes specified. - -A complete description of each check is given below. The comments about +The extKeyUsage (EKU) extension places additional restrictions on +certificate use. If this extension is present (whether critical or not) +in an end-entity certficiate, the key is allowed only for the uses specified, +while the special EKU B<anyExtendedKeyUsage> allows for all uses. + +Note that according to RFC 5280 section 4.2.1.12, +the Extended Key Usage extension will appear only in end-entity certificates, +and consequently the standard certification path validation described +in its section 6 does not include EKU checks for CA certificates. +The CA/Browser Forum requires for TLS server, S/MIME, and code signing use +the presence of respective EKUs in subordinate CA certificates (while excluding +them for root CA certificates), while taking over from RFC 5280 +the certificate validity concept and certificate path validation. + +For historic reasons, OpenSSL has its own way of interpreting and checking +EKU extensions on CA certificates, which may change in the future. +It does not require the presence of EKU extensions in CA certificates, +but in case the verification purpose is +C<sslclient>, C<nssslserver>, C<sslserver>, C<smimesign>, or C<smimeencrypt>, +it checks that any present EKU extension (that does not contain +B<anyExtendedKeyUsage>) contains the respective EKU as detailed below. +Moreover, it does these checks even for trust anchor certificates. + +=head3 Checks Implied by Specific Predefined Policies + +A specific description of each check is given below. The comments about basicConstraints and keyUsage and X.509v1 certificates above apply to B<all> CA certificates. - =over 4 -=item B<SSL Client> +=item B<(D)TLS Client> (C<sslclient>) -The extended key usage extension must be absent or include the "web client -authentication" OID. The keyUsage extension must be absent or it must have the -digitalSignature bit set. The Netscape certificate type must be absent -or it must have the SSL client bit set. +Any given extended key usage extension must allow for C<clientAuth> +("TLS WWW client authentication"). -=item B<SSL Client CA> +For target certificates, +the key usage must allow for C<digitalSignature> and/or C<keyAgreement>. +The Netscape certificate type must be absent or have the SSL client bit set. -The extended key usage extension must be absent or include the "web client -authentication" OID. -The Netscape certificate type must be absent or it must have the SSL CA bit set. -This is used as a work around if the basicConstraints extension is absent. +For all other certificates the normal CA checks apply. In addition, +the Netscape certificate type must be absent or have the SSL CA bit set. +This is used as a workaround if the basicConstraints extension is absent. -=item B<SSL Server> +=item B<(D)TLS Server> (C<sslserver>) -The extended key usage extension must be absent or include the "web server -authentication" and/or one of the SGC OIDs. The keyUsage extension must be -absent or it -must have the digitalSignature, the keyEncipherment set or both bits set. -The Netscape certificate type must be absent or have the SSL server bit set. +Any given extended key usage extension must allow for C<serverAuth> +("TLS WWW server authentication") and/or include one of the SGC OIDs. -=item B<SSL Server CA> +For target certificates, the key usage must +allow for C<digitalSignature>, C<keyEncipherment>, and/or C<keyAgreement>. +The Netscape certificate type must be absent or have the SSL server bit set. -The extended key usage extension must be absent or include the "web server -authentication" and/or one of the SGC OIDs. The Netscape certificate type must -be absent or the SSL CA bit must be set. -This is used as a work around if the basicConstraints extension is absent. +For all other certificates the normal CA checks apply. In addition, +the Netscape certificate type must be absent or have the SSL CA bit set. +This is used as a workaround if the basicConstraints extension is absent. -=item B<Netscape SSL Server> +=item B<Netscape SSL Server> (C<nssslserver>) -For Netscape SSL clients to connect to an SSL server it must have the -keyEncipherment bit set if the keyUsage extension is present. This isn't +In addition to what has been described for B<sslserver>, for a Netscape +SSL client to connect to an SSL server, its EE certficate must have the +B<keyEncipherment> bit set if the keyUsage extension is present. This isn't always valid because some cipher suites use the key for digital signing. Otherwise it is the same as a normal SSL server. -=item B<Common S/MIME Client Tests> +=item B<Common S/MIME Checks> + +Any given extended key usage extension must allow for C<emailProtection>. -The extended key usage extension must be absent or include the "email -protection" OID. The Netscape certificate type must be absent or should have the -S/MIME bit set. If the S/MIME bit is not set in the Netscape certificate type +For target certificates, +the Netscape certificate type must be absent or should have the S/MIME bit set. +If the S/MIME bit is not set in the Netscape certificate type then the SSL client bit is tolerated as an alternative but a warning is shown. This is because some Verisign certificates don't set the S/MIME bit. -=item B<S/MIME Signing> +For all other certificates the normal CA checks apply. In addition, +the Netscape certificate type must be absent or have the S/MIME CA bit set. +This is used as a workaround if the basicConstraints extension is absent. + +=item B<S/MIME Signing> (C<smimesign>) + +In addition to the common S/MIME checks, for target certficiates +the key usage must allow for C<digitalSignature> and/or B<nonRepudiation>. + +=item B<S/MIME Encryption> (C<smimeencrypt>) + +In addition to the common S/MIME checks, for target certficiates +the key usage must allow for C<keyEncipherment>. + +=item B<CRL Signing> (C<crlsign>) + +For target certificates, the key usage must allow for C<cRLSign>. + +For all other certifcates the normal CA checks apply. +Except in this case the basicConstraints extension must be present. -In addition to the common S/MIME client tests the digitalSignature bit or -the nonRepudiation bit must be set if the keyUsage extension is present. +=item B<OCSP Helper> (C<ocsphelper>) -=item B<S/MIME Encryption> +For target certificates, no checks are performed at this stage, +but special checks apply; see L<OCSP_basic_verify(3)>. -In addition to the common S/MIME tests the keyEncipherment bit must be set -if the keyUsage extension is present. +For all other certifcates the normal CA checks apply. -=item B<S/MIME CA> +=item B<Timestamp Signing> (C<timestampsign>) -The extended key usage extension must be absent or include the "email -protection" OID. The Netscape certificate type must be absent or must have the -S/MIME CA bit set. -This is used as a work around if the basicConstraints extension is absent. +For target certificates, if the key usage extension is present, it must include +C<digitalSignature> and/or C<nonRepudiation> and must not include other bits. +The EKU extension must be present and contain C<timeStamping> only. +Moreover, it must be marked as critical. -=item B<CRL Signing> +For all other certifcates the normal CA checks apply. -The keyUsage extension must be absent or it must have the CRL signing bit -set. +=item B<Code Signing> (C<codesign>) -=item B<CRL Signing CA> +For target certificates, +the key usage extension must be present and marked critical and +include <digitalSignature>, but must not include C<keyCertSign> nor C<cRLSign>. +The EKU extension must be present and contain C<codeSign>, +but must not include C<anyExtendedKeyUsage> nor C<serverAuth>. -The normal CA tests apply. Except in this case the basicConstraints extension -must be present. +For all other certifcates the normal CA checks apply. =back @@ -671,6 +716,7 @@ only the first one (in the mentioned order of locations) is recognised. =head1 SEE ALSO L<X509_verify_cert(3)>, +L<OCSP_basic_verify(3)>, L<openssl-verify(1)>, L<openssl-ocsp(1)>, L<openssl-ts(1)>, diff --git a/doc/man3/SSL_CTX_new.pod b/doc/man3/SSL_CTX_new.pod index f467f93659..627d9e7f0d 100644 --- a/doc/man3/SSL_CTX_new.pod +++ b/doc/man3/SSL_CTX_new.pod @@ -104,10 +104,12 @@ On session establishment, by default, no peer credentials verification is done. This must be explicitly requested, typically using L<SSL_CTX_set_verify(3)>. For verifying peer certificates many options can be set using various functions such as L<SSL_CTX_load_verify_locations(3)> and L<SSL_CTX_set1_param(3)>. -The L<X509_VERIFY_PARAM_set_purpose(3)> function can be used, also in conjunction -with L<SSL_CTX_get0_param(3)>, to set the intended purpose of the session. -The default is B<X509_PURPOSE_SSL_SERVER> on the client side + +The SSL/(D)TLS implementation uses the L<X509_STORE_CTX_set_default(3)> +function to prepare checks for B<X509_PURPOSE_SSL_SERVER> on the client side and B<X509_PURPOSE_SSL_CLIENT> on the server side. +The L<X509_VERIFY_PARAM_set_purpose(3)> function can be used, also in conjunction +with L<SSL_CTX_get0_param(3)>, to override the default purpose of the session. The SSL_CTX object uses I<method> as the connection method. Three method variants are available: a generic method (for either client or @@ -228,7 +230,7 @@ SSL_CTX_up_ref() returns 1 for success and 0 for failure. =head1 SEE ALSO -L<SSL_CTX_set_options(3)>, L<SSL_CTX_free(3)>, +L<SSL_CTX_set_options(3)>, L<SSL_CTX_free(3)>, L<X509_STORE_CTX_set_default(3)>, SSL_CTX_set_verify(3), L<SSL_CTX_set1_param(3)>, L<SSL_CTX_get0_param(3)>, L<SSL_connect(3)>, L<SSL_accept(3)>, L<SSL_CTX_set_min_proto_version(3)>, L<ssl(7)>, L<SSL_set_connect_state(3)> diff --git a/doc/man3/X509_STORE_CTX_new.pod b/doc/man3/X509_STORE_CTX_new.pod index 50781c0e85..c219cee9d6 100644 --- a/doc/man3/X509_STORE_CTX_new.pod +++ b/doc/man3/X509_STORE_CTX_new.pod @@ -85,7 +85,10 @@ If I<ctx> is NULL nothing is done. X509_STORE_CTX_init() sets up I<ctx> for a subsequent verification operation. X509_STORE_CTX_init() initializes the internal state and resources of the -X509_STORE_CTX, and must be called before each call to L<X509_verify_cert(3)> or +given I<ctx>. Among others, it sets the verification parameters associcated +with the method name C<default>, which includes the C<any> purpose, +and takes over callback function pointers from I<trust_store> (unless NULL). +It must be called before each call to L<X509_verify_cert(3)> or L<X509_STORE_CTX_verify(3)>, i.e., a context is only good for one verification. If you want to verify a further certificate or chain with the same I<ctx> then you must call X509_STORE_CTX_init() again. @@ -176,12 +179,13 @@ by I<ctx> to be I<chain>. Ownership of the chain is transferred to I<ctx>, and so it should not be free'd by the caller. -X509_STORE_CTX_set_default() looks up and sets the default verification -method to I<name>. This uses the function X509_VERIFY_PARAM_lookup() to -find an appropriate set of parameters from the purpose identifier I<name>. -Currently defined purposes are C<sslclient>, C<sslserver>, C<nssslserver>, -C<smimesign>, C<smimeencrypt>, C<crlsign>, C<ocsphelper>, C<timestampsign>, -and C<any>. +X509_STORE_CTX_set_default() looks up and sets the default verification method. +This uses the function X509_VERIFY_PARAM_lookup() to find +the set of parameters associated with the given verification method I<name>. +Among others, the parameters determine the trust model and verification purpose. +More detail, including the list of currently predefined methods, +is described for the B<-verify_name> command-line option +in L<openssl-verification-options(1)/Verification Options>. X509_STORE_CTX_set_verify() provides the capability for overriding the default verify function. This function is responsible for verifying chain signatures and diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t index 1c8fce86fd..80e9026556 100644 --- a/test/recipes/25-test_verify.t +++ b/test/recipes/25-test_verify.t @@ -61,7 +61,7 @@ ok(verify("ee-cert-ocsp-nocheck", "", ["root-cert"], ["ca-cert"]), ok(verify("ee-cert", "sslserver", [qw(sroot-cert)], [qw(ca-cert)]), "accept server purpose"); ok(!verify("ee-cert", "sslserver", [qw(croot-cert)], [qw(ca-cert)]), - "fail client purpose"); + "fail client purpose"); # beware, questionable non-standard EKU check on trust anchor ok(verify("ee-cert", "sslserver", [qw(root+serverAuth)], [qw(ca-cert)]), "accept server trust"); ok(verify("ee-cert", "sslserver", [qw(sroot+serverAuth)], [qw(ca-cert)]), @@ -81,7 +81,7 @@ ok(verify("ee-cert", "sslserver", [qw(root-clientAuth)], [qw(ca-cert)]), ok(verify("ee-cert", "sslserver", [qw(sroot-clientAuth)], [qw(ca-cert)]), "accept client mistrust with server purpose"); ok(!verify("ee-cert", "sslserver", [qw(croot-clientAuth)], [qw(ca-cert)]), - "fail client mistrust with client purpose"); + "fail client mistrust with client purpose"); # beware, questionable non-standard EKU check on trust anchor # Inapplicable trust ok(!verify("ee-cert", "sslserver", [qw(root+clientAuth)], [qw(ca-cert)]), "fail client trust"); @@ -150,7 +150,7 @@ ok(!verify("ee-cert", "sslserver", [qw(root-expired)], [qw(ca-cert)]), ok(verify("ee-cert", "sslserver", [qw(sca-cert)], [], "-partial_chain"), "accept partial chain with server purpose"); ok(!verify("ee-cert", "sslserver", [qw(cca-cert)], [], "-partial_chain"), - "fail partial chain with client purpose"); + "fail partial chain with client purpose"); # beware, questionable non-standard EKU check on trust anchor ok(verify("ee-cert", "sslserver", [qw(ca+serverAuth)], [], "-partial_chain"), "accept server trust partial chain"); ok(verify("ee-cert", "sslserver", [qw(cca+serverAuth)], [], "-partial_chain"), @@ -188,7 +188,7 @@ ok(verify("ee-cert", "sslserver", [qw(root-cert cca+serverAuth)], [qw(ca-cert)]) ok(verify("ee-cert", "sslserver", [qw(root-cert cca+anyEKU)], [qw(ca-cert)]), "accept wildcard trust and client purpose"); ok(!verify("ee-cert", "sslserver", [qw(root-cert cca-cert)], [qw(ca-cert)]), - "fail client purpose"); + "fail client purpose intermediate trusted"); # beware, questionable non-standard EKU check on trust anchor ok(!verify("ee-cert", "sslserver", [qw(root-cert ca-anyEKU)], [qw(ca-cert)]), "fail wildcard mistrust"); ok(!verify("ee-cert", "sslserver", [qw(root-cert ca-serverAuth)], [qw(ca-cert)]), |