Multiple -trusted/-untrusted/-CRLfile options in verify

It is sometimes useful (especially in automated tests) to supply
multiple trusted or untrusted certificates via separate files rather
than have to prepare a single file containing them all.

To that end, change verify(1) to accept these options zero or more
times.  Also automatically set -no-CAfile and -no-CApath when
-trusted is specified.

Improve verify(1) documentation, which could still use some work.

Reviewed-by: Richard Levitte <levitte@openssl.org>
This commit is contained in:
Viktor Dukhovni 2016-01-16 01:15:02 -05:00
parent 0996dc5440
commit feb2f53edc
3 changed files with 88 additions and 62 deletions

View File

@ -115,7 +115,6 @@ int verify_main(int argc, char **argv)
X509_VERIFY_PARAM *vpm = NULL; X509_VERIFY_PARAM *vpm = NULL;
char *prog, *CApath = NULL, *CAfile = NULL; char *prog, *CApath = NULL, *CAfile = NULL;
int noCApath = 0, noCAfile = 0; int noCApath = 0, noCAfile = 0;
char *untfile = NULL, *trustfile = NULL, *crlfile = NULL;
int vpmtouched = 0, crl_download = 0, show_chain = 0, i = 0, ret = 1; int vpmtouched = 0, crl_download = 0, show_chain = 0, i = 0, ret = 1;
OPTION_CHOICE o; OPTION_CHOICE o;
@ -167,13 +166,24 @@ int verify_main(int argc, char **argv)
noCAfile = 1; noCAfile = 1;
break; break;
case OPT_UNTRUSTED: case OPT_UNTRUSTED:
untfile = opt_arg(); /* Zero or more times */
if (!load_certs(opt_arg(), &untrusted, FORMAT_PEM, NULL, e,
"untrusted certificates"))
goto end;
break; break;
case OPT_TRUSTED: case OPT_TRUSTED:
trustfile = opt_arg(); /* Zero or more times */
noCAfile = 1;
noCApath = 1;
if (!load_certs(opt_arg(), &trusted, FORMAT_PEM, NULL, e,
"trusted certificates"))
goto end;
break; break;
case OPT_CRLFILE: case OPT_CRLFILE:
crlfile = opt_arg(); /* Zero or more times */
if (!load_crls(opt_arg(), &crls, FORMAT_PEM, NULL, e,
"other CRLs"))
goto end;
break; break;
case OPT_CRL_DOWNLOAD: case OPT_CRL_DOWNLOAD:
crl_download = 1; crl_download = 1;
@ -182,6 +192,7 @@ int verify_main(int argc, char **argv)
show_chain = 1; show_chain = 1;
break; break;
case OPT_ENGINE: case OPT_ENGINE:
/* Specify *before* -trusted/-untrusted/-CRLfile */
e = setup_engine(opt_arg(), 0); e = setup_engine(opt_arg(), 0);
break; break;
case OPT_VERBOSE: case OPT_VERBOSE:
@ -191,7 +202,7 @@ int verify_main(int argc, char **argv)
} }
argc = opt_num_rest(); argc = opt_num_rest();
argv = opt_rest(); argv = opt_rest();
if (trustfile && (CAfile || CApath)) { if (trusted != NULL && (CAfile || CApath)) {
BIO_printf(bio_err, BIO_printf(bio_err,
"%s: Cannot use -trusted with -CAfile or -CApath\n", "%s: Cannot use -trusted with -CAfile or -CApath\n",
prog); prog);
@ -207,23 +218,6 @@ int verify_main(int argc, char **argv)
ERR_clear_error(); ERR_clear_error();
if (untfile) {
if (!load_certs(untfile, &untrusted, FORMAT_PEM, NULL, e,
"untrusted certificates"))
goto end;
}
if (trustfile) {
if (!load_certs(trustfile, &trusted, FORMAT_PEM, NULL, e,
"trusted certificates"))
goto end;
}
if (crlfile) {
if (!load_crls(crlfile, &crls, FORMAT_PEM, NULL, e, "other CRLs"))
goto end;
}
if (crl_download) if (crl_download)
store_setup_crl_download(store); store_setup_crl_download(store);

View File

@ -17,6 +17,7 @@ B<openssl> B<verify>
[B<-crl_download>] [B<-crl_download>]
[B<-crl_check>] [B<-crl_check>]
[B<-crl_check_all>] [B<-crl_check_all>]
[B<-engine id>]
[B<-explicit_policy>] [B<-explicit_policy>]
[B<-extended_crl>] [B<-extended_crl>]
[B<-help>] [B<-help>]
@ -59,8 +60,8 @@ The B<verify> command verifies certificate chains.
=item B<-CAfile file> =item B<-CAfile file>
A file of trusted certificates. The file should contain multiple certificates A B<file> of trusted certificates.
in PEM format concatenated together. The file should contain one or more certificates in PEM format.
=item B<-CApath directory> =item B<-CApath directory>
@ -91,7 +92,11 @@ because it doesn't add any security.
=item B<-CRLfile file> =item B<-CRLfile file>
File containing one or more CRL's (in PEM format) to load. The B<file> should contain one or more CRLs in PEM format.
This option can be specified more than once to include CRLs from multiple
B<files>.
If you want to enable an B<engine> via the B<-engine> option, that option has
to be specified before this one.
=item B<-crl_download> =item B<-crl_download>
@ -107,6 +112,15 @@ If a valid CRL cannot be found an error occurs.
Checks the validity of B<all> certificates in the chain by attempting Checks the validity of B<all> certificates in the chain by attempting
to look up valid CRLs. to look up valid CRLs.
=item B<-engine id>
Specifying an engine B<id> will cause L<verify(1)> to attempt to load the
specified engine.
The engine will then be set as the default for all its supported algorithms.
If you want to load certificates or CRLs that require engine support via any of
the B<-trusted>, B<-untrusted> or B<-CRLfile> options, the B<-engine> option
must be specified before those options.
=item B<-explicit_policy> =item B<-explicit_policy>
Set policy variable require-explicit-policy (see RFC5280). Set policy variable require-explicit-policy (see RFC5280).
@ -144,7 +158,9 @@ rejections may take place.
=item B<-partial_chain> =item B<-partial_chain>
Allow partial certificate chain if at least one certificate is in trusted store. Allow verification to succeed even if a I<complete> chain cannot be built to a
self-signed trust-anchor, provided it is possible to construct a chain to a
trusted certificate that might not be self-signed.
=item B<-policy arg> =item B<-policy arg>
@ -178,9 +194,10 @@ P-256 and P-384.
=item B<-trusted_first> =item B<-trusted_first>
Use certificates in CA file or CA directory before certificates in untrusted When constructing the certificate chain, use the trusted certificates specified
file when building the trust chain to verify certificates. via B<-CAfile>, B<-CApath> or B<-trusted> before any certificates specified via
This is mainly useful in environments with Bridge CA or Cross-Certified CAs. B<-untrusted>.
This can be useful in environments with Bridge or Cross-Certified CAs.
=item B<-no_alt_chains> =item B<-no_alt_chains>
@ -192,17 +209,29 @@ behaviour to match that of OpenSSL versions prior to 1.1.0.
=item B<-untrusted file> =item B<-untrusted file>
A file of untrusted certificates. The file should contain one or more A B<file> of additional untrusted certificates (intermediate issuer CAs) used
certificates in PEM format. to constuct a certificate chain from the subject certificate to a trust-anchor.
The B<file> should contain one or more certificates in PEM format.
This option can be specified more than once to include untrusted certiificates
from multiple B<files>.
If you want to enable an B<engine> via the B<-engine> option, that option has
to be specified before this one.
=item B<-trusted file> =item B<-trusted file>
A file of trusted certificates. The file contain one or more A B<file> of trusted certificates, which must be self-signed, unless the
certificates in PEM format. B<-partial_chain> option is specified.
With this option, no additional (e.g., default) certificate lists The B<file> contain one or more certificates in PEM format.
are consulted. That is, the only trusted issuers are those listed With this option, no additional (e.g., default) certificate lists are
in B<file>. consulted.
This option cannot be used with the B<-CAfile> or B<-CApath> options. That is, the only trust-anchors are those listed in B<file>.
This option can be specified more than once to include trusted certificates
from multiple B<files>.
This option implies the B<-no-CAfile> and B<-no-CApath> options.
This option cannot be used in combination with either of the B<-CAfile> or
B<-CApath> options.
If you want to enable an B<engine> via the B<-engine> option, that option has
to be specified before this one.
=item B<-use_deltas> =item B<-use_deltas>
@ -233,9 +262,15 @@ the subject certificate.
=item B<-verify_name name> =item B<-verify_name name>
Use default verification options like trust model and required certificate Use default verification policies like trust model and required certificate
policies identified by B<name>. policies identified by B<name>.
Supported usages include: default, pkcs7, smime_sign, ssl_client, ssl_server. Supported policy names include: B<default>, B<pkcs7>, B<smime_sign>,
B<ssl_client>, B<ssl_server>.
This checks not only the purpose of the leaf certificate, but also the
trust settings of the trusted CAs.
When in doubt, use this option rather than B<-purpose>.
The B<-verify_name> option more closely matches how certificates are checked in
e.g. SSL and S/MIME.
=item B<-x509_strict> =item B<-x509_strict>
@ -277,20 +312,21 @@ determined.
The verify operation consists of a number of separate steps. The verify operation consists of a number of separate steps.
Firstly a certificate chain is built up starting from the supplied certificate Firstly a certificate chain is built up starting from the supplied certificate
and ending in the root CA. It is an error if the whole chain cannot be built and ending in the root CA.
up. The chain is built up by looking up the issuers certificate of the current It is an error if the whole chain cannot be built up.
certificate. If a certificate is found which is its own issuer it is assumed The chain is built up by looking up the issuers certificate of the current
to be the root CA. certificate.
If a certificate is found which is its own issuer it is assumed to be the root
CA.
The process of 'looking up the issuers certificate' itself involves a number The process of 'looking up the issuers certificate' itself involves a number of
of steps. steps.
Ater all certificates Ater all certificates whose subject name matches the issuer name of the current
whose subject name matches the issuer name of the current certificate are certificate are subject to further tests.
subject to further tests. The relevant authority key identifier components The relevant authority key identifier components of the current certificate (if
of the current certificate (if present) must match the subject key identifier present) must match the subject key identifier (if present) and issuer and
(if present) and issuer and serial number of the candidate issuer, in addition serial number of the candidate issuer, in addition the keyUsage extension of
the keyUsage extension of the candidate issuer (if present) must permit the candidate issuer (if present) must permit certificate signing.
certificate signing.
The lookup first looks in the list of untrusted certificates and if no match The lookup first looks in the list of untrusted certificates and if no match
is found the remaining lookups are from the trusted certificates. The root CA is found the remaining lookups are from the trusted certificates. The root CA
@ -305,10 +341,10 @@ compatible with the supplied purpose and all other certificates must also be val
CA certificates. The precise extensions required are described in more detail in CA certificates. The precise extensions required are described in more detail in
the B<CERTIFICATE EXTENSIONS> section of the B<x509> utility. the B<CERTIFICATE EXTENSIONS> section of the B<x509> utility.
The third operation is to check the trust settings on the root CA. The root The third operation is to check the trust settings on the root CA. The root CA
CA should be trusted for the supplied purpose. For compatibility with previous should be trusted for the supplied purpose.
versions of OpenSSL, a certificate with no trust settings is considered For compatibility with previous versions of OpenSSL, a certificate with no
to be valid for all purposes. trust settings is considered to be valid for all purposes.
The final operation is to check the validity of the certificate chain. The validity The final operation is to check the validity of the certificate chain. The validity
period is checked against the current system time and the notBefore and notAfter period is checked against the current system time and the notBefore and notAfter
@ -333,7 +369,7 @@ problem was detected starting with zero for the certificate being verified itsel
then 1 for the CA that signed the certificate and so on. Finally a text version then 1 for the CA that signed the certificate and so on. Finally a text version
of the error number is presented. of the error number is presented.
An exhaustive list of the error codes and messages is shown below, this also An partial list of the error codes and messages is shown below, this also
includes the name of the error code as defined in the header file x509_vfy.h includes the name of the error code as defined in the header file x509_vfy.h
Some of the error codes are defined but never returned: these are described Some of the error codes are defined but never returned: these are described
as "unused". as "unused".

View File

@ -8,10 +8,6 @@ use OpenSSL::Test qw/:DEFAULT top_dir top_file/;
setup("test_verify"); setup("test_verify");
# Note for now, at most one trusted and one untrusted PEM file can be
# specified. The verify(1) option parser does not accumulate content
# from multiple trusted or untrusted files.
#
sub verify { sub verify {
my ($cert, $vname, $trusted, $untrusted, @opts) = @_; my ($cert, $vname, $trusted, $untrusted, @opts) = @_;
my @args = qw(openssl verify -verify_name); my @args = qw(openssl verify -verify_name);