Skip to content

Commit

Permalink
Improve the documentation of cert path building and validation
Browse files Browse the repository at this point in the history
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from #13735)
  • Loading branch information
DDvO committed Jun 8, 2021
1 parent 2576b9c commit f9ac6f6
Show file tree
Hide file tree
Showing 12 changed files with 372 additions and 244 deletions.
8 changes: 4 additions & 4 deletions crypto/x509/v3_purp.c
Original file line number Diff line number Diff line change
Expand Up @@ -894,10 +894,10 @@ static int no_check_purpose(const X509_PURPOSE *xp, const X509 *x,
* This can be used to prune a set of possible issuer certificates which
* have been looked up using some simple method such as by subject name.
* These are:
* 1. Check issuer_name(subject) == subject_name(issuer)
* 2. If akid(subject) exists, check that it matches issuer
* 3. Check that issuer public key algorithm matches subject signature algorithm
* 4. Check that any key_usage(issuer) allows certificate signing
* 1. issuer_name(subject) == subject_name(issuer)
* 2. If akid(subject) exists, it matches the respective issuer fields.
* 3. subject signature algorithm == issuer public key algorithm
* 4. If key_usage(issuer) exists, it allows for signing subject.
* Note that this does not include actually checking the signature.
* Returns 0 for OK, or positive for reason for mismatch
* where reason codes match those for X509_verify_cert().
Expand Down
3 changes: 2 additions & 1 deletion crypto/x509/x509_vfy.c
Original file line number Diff line number Diff line change
Expand Up @@ -3007,7 +3007,8 @@ static int build_chain(X509_STORE_CTX *ctx)
#define S_DOTRUSTED (1 << 1) /* Search trusted store */
#define S_DOALTERNATE (1 << 2) /* Retry with pruned alternate chain */
/*
* Set up search policy, untrusted if possible, trusted-first if enabled.
* Set up search policy, untrusted if possible, trusted-first if enabled,
* which is the default.
* If we're doing DANE and not doing PKIX-TA/PKIX-EE, we never look in the
* trust_store, otherwise we might look there first. If not trusted-first,
* and alternate chains are not disabled, try building an alternate chain
Expand Down
344 changes: 288 additions & 56 deletions doc/man1/openssl-verification-options.pod

Large diffs are not rendered by default.

43 changes: 13 additions & 30 deletions doc/man1/openssl-verify.pod.in
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ openssl-verify - certificate verification command

B<openssl> B<verify>
[B<-help>]
[B<-CRLfile> I<file>]
[B<-CRLfile> I<filename>|I<uri>]
[B<-crl_download>]
[B<-show_chain>]
[B<-verbose>]
[B<-trusted> I<file>]
[B<-untrusted> I<file>]
[B<-trusted> I<filename>|I<uri>]
[B<-untrusted> I<filename>|I<uri>]
[B<-vfyopt> I<nm>:I<v>]
{- $OpenSSL::safe::opt_name_synopsis -}
{- $OpenSSL::safe::opt_trust_synopsis -}
Expand All @@ -36,11 +36,11 @@ problems, this program attempts to display all of them.

Print out a usage message.

=item B<-CRLfile> I<file>
=item B<-CRLfile> I<filename>|I<uri>

The file or URI should contain one or more CRLs in PEM or DER format.
This option can be specified more than once to include CRLs from multiple
I<file>s.
sources.

=item B<-crl_download>

Expand All @@ -56,19 +56,19 @@ flagged as "untrusted".

Print extra information about the operations being performed.

=item B<-trusted> I<file>
=item B<-trusted> I<filename>|I<uri>

A file or URI of (more or less) trusted certificates.
See L<openssl-verification-options(1)> for more information on trust settings.

A file or URI of trusted certificates in PEM, DER, or PKCS#12 format.
This option can be specified more than once to load certificates from multiple
I<file>s.
sources.

=item B<-untrusted> I<file>
=item B<-untrusted> I<filename>|I<uri>

A file or URI of untrusted certificates in PEM, DER, or PKCS#12 format
to use for chain building.
A file or URI of untrusted certificates to use for chain building.
This option can be specified more than once to load certificates from multiple
I<file>s.

sources.

=item B<-vfyopt> I<nm>:I<v>

Expand Down Expand Up @@ -126,23 +126,6 @@ F<< <openssl/x509_vfy.h> >>.
This command ignores many errors, in order to allow all the problems with a
certificate chain to be determined.

=head1 BUGS

Although the issuer checks are a considerable improvement over the old
technique they still suffer from limitations in the underlying X509_LOOKUP
API. One consequence of this is that trusted certificates with matching
subject name must either appear in a file (as specified by the B<-CAfile>
option), a directory (as specified by B<-CApath>), or a store (as specified
by B<-CAstore>). If they occur in more than one location then only the
certificates in the file will be recognised.

Previous versions of OpenSSL assume certificates with matching subject
name are identical and mishandled them.

Previous versions of this documentation swapped the meaning of the
B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT> and
B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY> error codes.

=head1 SEE ALSO

L<openssl-verification-options(1)>,
Expand Down
134 changes: 9 additions & 125 deletions doc/man1/openssl-x509.pod.in
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,9 @@ Prints the OCSP responder address(es) if any.

=item B<-purpose>

This option performs tests on the certificate extensions and prints
the results. For a more complete description see the
L</CERTIFICATE EXTENSIONS> section.
This option performs tests on the certificate extensions and outputs
the results. For a more complete description see
L<openssl-verification-options(1)/Certificate Extensions>.

=item B<-pubkey>

Expand Down Expand Up @@ -518,7 +518,7 @@ Trust settings currently are only used with a root CA.
They allow a finer control over the purposes the root CA can be used for.
For example, a CA may be trusted for SSL client but not SSL server use.

See the description in L<openssl-verify(1)> for more information
See L<openssl-verification-options(1)> for more information
on the meaning of trust settings.

Future versions of OpenSSL will recognize trust settings on any
Expand All @@ -545,21 +545,18 @@ Clears all the permitted or trusted uses of the certificate.

=item B<-addtrust> I<arg>

Adds a trusted certificate use.
Any object name can be used here but currently only B<clientAuth> (SSL client
use), B<serverAuth> (SSL server use), B<emailProtection> (S/MIME email)
and B<anyExtendedKeyUsage> are used.
As of OpenSSL 1.1.0, the last of these blocks all purposes when rejected or
enables all purposes when trusted.
Other OpenSSL applications may define additional uses.
Adds an allowed trust anchor purpose.
Any object name can be used here but currently only those
listed in L<openssl-verification-options(1)/Trust Anchors> are supported.
Other OpenSSL applications may define additional purposes.

=item B<-clrreject>

Clears all the prohibited or rejected uses of the certificate.

=item B<-addreject> I<arg>

Adds a prohibited use.
Adds a prohibited trust anchor purpose.
It accepts the same values as the B<-addtrust> option.

=back
Expand Down Expand Up @@ -732,119 +729,6 @@ The B<-email> option searches the subject name and the subject alternative
name extension. Only unique email addresses will be printed out: it will
not print the same address more than once.

=head1 CERTIFICATE EXTENSIONS

The B<-purpose> option checks the certificate extensions and determines
what the certificate can be used for. The actual checks done are rather
complex and include various hacks and workarounds to handle broken
certificates and software.

The same code is used when verifying untrusted certificates in chains
so this section is useful if a chain is rejected by the verify code.

The basicConstraints extension CA flag is used to determine whether the
certificate can be used as a CA. If the CA flag is true then it is a CA,
if the CA flag is false then it is not a CA. B<All> CAs should have the
CA flag set to true.

If the basicConstraints extension is absent then the certificate is
considered to be a "possible CA" other extensions are checked according
to the intended use of the certificate. A warning is given in this case
because the certificate should really not be regarded as a CA: however
it is allowed to be a CA to work around some broken software.

If the certificate is a V1 certificate (and thus has no extensions) and
it is self-signed it is also assumed to be a CA but a warning is again
given: this is to work around the problem of Verisign roots which are V1
self-signed certificates.

If the keyUsage extension is present then additional restraints are
made on the uses of the certificate. A CA certificate B<must> have the
keyCertSign bit set if the keyUsage extension is present.

The extended key usage 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 test is given below. The comments about
basicConstraints and keyUsage and V1 certificates above apply to B<all>
CA certificates.


=over 4

=item B<SSL Client>

The extended key usage extension must be absent or include the "web client
authentication" OID. keyUsage must be absent or it must have the
digitalSignature bit set. Netscape certificate type must be absent or it must
have the SSL client bit set.

=item B<SSL Client CA>

The extended key usage extension must be absent or include the "web client
authentication" OID. 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.

=item B<SSL Server>

The extended key usage extension must be absent or include the "web server
authentication" and/or one of the SGC OIDs. keyUsage must be absent or it
must have the digitalSignature, the keyEncipherment set or both bits set.
Netscape certificate type must be absent or have the SSL server bit set.

=item B<SSL Server CA>

The extended key usage extension must be absent or include the "web server
authentication" and/or one of the SGC OIDs. 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.

=item B<Netscape SSL Server>

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
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>

The extended key usage extension must be absent or include the "email
protection" OID. Netscape certificate type must be absent or should have the
S/MIME bit set. If the S/MIME bit is not set in 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>

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<S/MIME Encryption>

In addition to the common S/MIME tests the keyEncipherment bit must be set
if the keyUsage extension is present.

=item B<S/MIME CA>

The extended key usage extension must be absent or include the "email
protection" OID. 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.

=item B<CRL Signing>

The keyUsage extension must be absent or it must have the CRL signing bit
set.

=item B<CRL Signing CA>

The normal CA tests apply. Except in this case the basicConstraints extension
must be present.

=back

=head1 BUGS

It is possible to produce invalid certificates or requests by specifying the
Expand Down
7 changes: 5 additions & 2 deletions doc/man3/SSL_CTX_add1_chain_cert.pod
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ SSL_CTX_clear_chain_certs() clears any existing chain associated with the
current certificate of B<ctx>. (This is implemented by calling
SSL_CTX_set0_chain() with B<sk> set to B<NULL>).

SSL_CTX_build_cert_chain() builds the certificate chain for B<ctx> normally
this uses the chain store or the verify store if the chain store is not set.
SSL_CTX_build_cert_chain() builds the certificate chain for B<ctx>.
Normally this uses the chain store
or the verify store if the chain store is not set.
If the function is successful the built chain will replace any existing chain.
The B<flags> parameter can be set to B<SSL_BUILD_CHAIN_FLAG_UNTRUSTED> to use
existing chain certificates as untrusted CAs, B<SSL_BUILD_CHAIN_FLAG_NO_ROOT>
Expand All @@ -63,6 +64,8 @@ sanity checking and rearranging them if necessary), the flag
B<SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR> ignores any errors during verification:
if flag B<SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR> is also set verification errors
are cleared from the error queue.
Details of the chain building process are described in
L<openssl-verification-options(1)/Certification Path Building>.

Each of these functions operates on the I<current> end entity
(i.e. server or client) certificate. This is the last certificate loaded or
Expand Down
15 changes: 7 additions & 8 deletions doc/man3/SSL_CTX_load_verify_locations.pod
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ locations for B<ctx>, at which CA certificates for verification purposes
are located. The certificates available via B<CAfile>, B<CApath> and
B<CAstore> are trusted.

Details of the certificate verification and chain checking process are
described in L<openssl-verification-options(1)/Certification Path Validation>.

SSL_CTX_set_default_verify_paths() specifies that the default locations from
which CA certificates are loaded should be used. There is one default directory,
one default file and one default store.
Expand Down Expand Up @@ -85,14 +88,10 @@ The certificates in B<CApath> are only looked up when required, e.g. when
building the certificate chain or when actually performing the verification
of a peer certificate.

When looking up CA certificates, the OpenSSL library will first search the
certificates in B<CAfile>, then those in B<CApath>. Certificate matching
is done based on the subject name, the key identifier (if present), and the
serial number as taken from the certificate to be verified. If these data
do not match, the next certificate will be tried. If a first certificate
matching the parameters is found, the verification process will be performed;
no other certificates for the same parameters will be searched in case of
failure.
When looking up CA certificates for chain building, the OpenSSL library
will search for suitable certificates first in B<CAfile>, then in B<CApath>.
Details of the chain building process are described in
L<openssl-verification-options(1)/Certification Path Building>.

If B<CAstore> is not NULL, it's a URI for to a store, which may
represent a single container or a whole catalogue of containers.
Expand Down
3 changes: 3 additions & 0 deletions doc/man3/SSL_CTX_set1_verify_cert_store.pod
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ the server's certificate chain and a SSL/TLS server will use it to verify
any client certificate chain.

The chain store is used to build the certificate chain.
Details of the chain building and checking process are described in
L<openssl-verification-options(1)/Certification Path Building> and
L<openssl-verification-options(1)/Certification Path Validation>.

If the mode B<SSL_MODE_NO_AUTO_CHAIN> is set or a certificate chain is
configured already (for example using the functions such as
Expand Down
6 changes: 6 additions & 0 deletions doc/man3/X509_STORE_CTX_get_error.pod
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,12 @@ If an unrecognised error code is passed to X509_verify_cert_error_string() the
numerical value of the unknown code is returned in a static buffer. This is not
thread safe but will never happen unless an invalid code is passed.

=head1 BUGS

Previous versions of this documentation swapped the meaning of the
B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT> and
B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY> error codes.

=head1 SEE ALSO

L<X509_verify_cert(3)>, L<X509_STORE_CTX_verify(3)>,
Expand Down

0 comments on commit f9ac6f6

Please sign in to comment.