summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. David von Oheimb <dev@ddvo.net>2024-12-09 22:22:24 +0100
committerDr. David von Oheimb <dev@ddvo.net>2024-12-13 08:26:19 +0100
commita82c2bf5c9db9d00f16281b48c1e1430a6cfd76e (patch)
tree68fd626c3ffc7f31a293a66577ffc8501c72bb05
parentFix the intermittent lhash_test failure on Windows (diff)
downloadopenssl-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.in4
-rw-r--r--doc/man1/openssl-s_client.pod.in12
-rw-r--r--doc/man1/openssl-s_server.pod.in4
-rw-r--r--doc/man1/openssl-verification-options.pod204
-rw-r--r--doc/man3/SSL_CTX_new.pod10
-rw-r--r--doc/man3/X509_STORE_CTX_new.pod18
-rw-r--r--test/recipes/25-test_verify.t8
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)]),