diff options
author | Viktor Dukhovni <openssl-users@dukhovni.org> | 2016-03-18 22:09:41 -0400 |
---|---|---|
committer | Viktor Dukhovni <openssl-users@dukhovni.org> | 2016-04-03 11:35:35 -0400 |
commit | fbb82a60dcbe820714a246ab3e7617eaf3a7b656 (patch) | |
tree | 261c976e4e3d6dbea776b0fb54c635bd2a10eebd | |
parent | 70dd3c6593d87e4cbb56b485717cb2cfff730f3e (diff) |
Move peer chain security checks into x509_vfy.c
A new X509_VERIFY_PARAM_set_auth_level() function sets the
authentication security level. For verification of SSL peers, this
is automatically set from the SSL security level. Otherwise, for
now, the authentication security level remains at (effectively) 0
by default.
The new "-auth_level" verify(1) option is available in all the
command-line tools that support the standard verify(1) options.
New verify(1) tests added to check enforcement of chain signature
and public key security levels. Also added new tests of enforcement
of the verify_depth limit.
Updated documentation.
Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
31 files changed, 543 insertions, 73 deletions
diff --git a/apps/apps.h b/apps/apps.h index 434ca54b7d..a310dd2b78 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -180,6 +180,7 @@ void wait_for_async(SSL *s); OPT_V_POLICY_PRINT, OPT_V_CHECK_SS_SIG, OPT_V_TRUSTED_FIRST, \ OPT_V_SUITEB_128_ONLY, OPT_V_SUITEB_128, OPT_V_SUITEB_192, \ OPT_V_PARTIAL_CHAIN, OPT_V_NO_ALT_CHAINS, OPT_V_NO_CHECK_TIME, \ + OPT_V_VERIFY_AUTH_LEVEL, \ OPT_V__LAST # define OPT_V_OPTIONS \ @@ -187,8 +188,10 @@ void wait_for_async(SSL *s); { "purpose", OPT_V_PURPOSE, 's', \ "certificate chain purpose"}, \ { "verify_name", OPT_V_VERIFY_NAME, 's', "verification policy name"}, \ - { "verify_depth", OPT_V_VERIFY_DEPTH, 'p', \ - "chain depth limit"}, \ + { "verify_depth", OPT_V_VERIFY_DEPTH, 'n', \ + "chain depth limit" }, \ + { "auth_level", OPT_V_VERIFY_AUTH_LEVEL, 'n', \ + "chain authentication security level" }, \ { "attime", OPT_V_ATTIME, 'M', "verification epoch time" }, \ { "verify_hostname", OPT_V_VERIFY_HOSTNAME, 's', \ "expected peer hostname" }, \ @@ -235,6 +238,7 @@ void wait_for_async(SSL *s); case OPT_V_PURPOSE: \ case OPT_V_VERIFY_NAME: \ case OPT_V_VERIFY_DEPTH: \ + case OPT_V_VERIFY_AUTH_LEVEL: \ case OPT_V_ATTIME: \ case OPT_V_VERIFY_HOSTNAME: \ case OPT_V_VERIFY_EMAIL: \ diff --git a/apps/opt.c b/apps/opt.c index af994bb743..462894a938 100644 --- a/apps/opt.c +++ b/apps/opt.c @@ -526,6 +526,11 @@ int opt_verify(int opt, X509_VERIFY_PARAM *vpm) if (i >= 0) X509_VERIFY_PARAM_set_depth(vpm, i); break; + case OPT_V_VERIFY_AUTH_LEVEL: + i = atoi(opt_arg()); + if (i >= 0) + X509_VERIFY_PARAM_set_auth_level(vpm, i); + break; case OPT_V_ATTIME: if (!opt_imax(opt_arg(), &t)) return 0; diff --git a/crypto/x509/x509_lcl.h b/crypto/x509/x509_lcl.h index 0726201e8f..603c17737f 100644 --- a/crypto/x509/x509_lcl.h +++ b/crypto/x509/x509_lcl.h @@ -70,6 +70,7 @@ struct X509_VERIFY_PARAM_st { int purpose; /* purpose to check untrusted certificates */ int trust; /* trust setting to check */ int depth; /* Verify depth */ + int auth_level; /* Security level for chain verification */ STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */ /* Peer identity details */ STACK_OF(OPENSSL_STRING) *hosts; /* Set of acceptable names */ diff --git a/crypto/x509/x509_txt.c b/crypto/x509/x509_txt.c index f7f27e97ef..8a9a7f0444 100644 --- a/crypto/x509/x509_txt.c +++ b/crypto/x509/x509_txt.c @@ -203,6 +203,12 @@ const char *X509_verify_cert_error_string(long n) return ("IP address mismatch"); case X509_V_ERR_DANE_NO_MATCH: return ("No matching DANE TLSA records"); + case X509_V_ERR_EE_KEY_TOO_SMALL: + return ("EE certificate key too weak"); + case X509_V_ERR_CA_KEY_TOO_SMALL: + return ("CA certificate key too weak"); + case X509_V_ERR_CA_MD_TOO_WEAK: + return ("CA signature digest algorithm too weak"); default: /* Printing an error number into a static buffer is not thread-safe */ diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 92f1c5c447..10fbeeff6d 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -126,6 +126,8 @@ static int check_cert(X509_STORE_CTX *ctx); static int check_policy(X509_STORE_CTX *ctx); static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); static int check_dane_issuer(X509_STORE_CTX *ctx, int depth); +static int check_key_level(X509_STORE_CTX *ctx, X509 *cert); +static int check_sig_level(X509_STORE_CTX *ctx, X509 *cert); static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, unsigned int *preasons, X509_CRL *crl, X509 *x); @@ -221,6 +223,35 @@ static int verify_cb_crl(X509_STORE_CTX *ctx, int err) return ctx->verify_cb(0, ctx); } +static int check_auth_level(X509_STORE_CTX *ctx) +{ + int i; + int num = sk_X509_num(ctx->chain); + + if (ctx->param->auth_level <= 0) + return 1; + + for (i = 0; i < num; ++i) { + X509 *cert = sk_X509_value(ctx->chain, i); + + /* + * We've already checked the security of the leaf key, so here we only + * check the security of issuer keys. + */ + if (i > 0 && !check_key_level(ctx, cert) && + verify_cb_cert(ctx, cert, i, X509_V_ERR_CA_KEY_TOO_SMALL) == 0) + return 0; + /* + * We also check the signature algorithm security of all certificates + * except those of the trust anchor at index num-1. + */ + if (i < num - 1 && !check_sig_level(ctx, cert) && + verify_cb_cert(ctx, cert, i, X509_V_ERR_CA_MD_TOO_WEAK) == 0) + return 0; + } + return 1; +} + static int verify_chain(X509_STORE_CTX *ctx) { int err; @@ -232,6 +263,7 @@ static int verify_chain(X509_STORE_CTX *ctx) */ if ((ok = build_chain(ctx)) == 0 || (ok = check_chain_extensions(ctx)) == 0 || + (ok = check_auth_level(ctx)) == 0 || (ok = check_name_constraints(ctx)) == 0 || (ok = check_id(ctx)) == 0 || 1) X509_get_pubkey_parameters(NULL, ctx->chain); @@ -294,6 +326,11 @@ int X509_verify_cert(X509_STORE_CTX *ctx) X509_up_ref(ctx->cert); ctx->num_untrusted = 1; + /* If the peer's public key is too weak, we can stop early. */ + if (!check_key_level(ctx, ctx->cert) && + !verify_cb_cert(ctx, ctx->cert, 0, X509_V_ERR_EE_KEY_TOO_SMALL)) + return 0; + /* * If dane->trecs is an empty stack, we'll fail, since the user enabled * DANE. If none of the TLSA records were usable, and it makes sense to @@ -308,20 +345,19 @@ int X509_verify_cert(X509_STORE_CTX *ctx) /* * Given a STACK_OF(X509) find the issuer of cert (if any) */ - static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) { int i; - X509 *issuer, *rv = NULL;; + for (i = 0; i < sk_X509_num(sk); i++) { - issuer = sk_X509_value(sk, i); - if (ctx->check_issued(ctx, x, issuer)) { - rv = issuer; - if (x509_check_cert_time(ctx, rv, -1)) - break; - } + X509 *issuer = sk_X509_value(sk, i); + + if (!ctx->check_issued(ctx, x, issuer)) + continue; + if (x509_check_cert_time(ctx, issuer, -1)) + return issuer; } - return rv; + return NULL; } /* Given a possible certificate and issuer check them */ @@ -2656,6 +2692,19 @@ static int dane_verify(X509_STORE_CTX *ctx) return verify_chain(ctx); } +/* Get issuer, without duplicate suppression */ +static int get_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *cert) +{ + STACK_OF(X509) *saved_chain = ctx->chain; + int ok; + + ctx->chain = NULL; + ok = ctx->get_issuer(issuer, ctx, cert); + ctx->chain = saved_chain; + + return ok; +} + static int build_chain(X509_STORE_CTX *ctx) { struct dane_st *dane = (struct dane_st *)ctx->dane; @@ -2735,12 +2784,19 @@ static int build_chain(X509_STORE_CTX *ctx) /* * Look in the trust store if enabled for first lookup, or we've run - * out of untrusted issuers and search here is not disabled. When - * we exceed the depth limit, we simulate absence of a match. + * out of untrusted issuers and search here is not disabled. When we + * reach the depth limit, we stop extending the chain, if by that point + * we've not found a trust-anchor, any trusted chain would be too long. + * + * The error reported to the application verify callback is at the + * maximal valid depth with the current certificate equal to the last + * not ultimately-trusted issuer. For example, with verify_depth = 0, + * the callback will report errors at depth=1 when the immediate issuer + * of the leaf certificate is not a trust anchor. No attempt will be + * made to locate an issuer for that certificate, since such a chain + * would be a-priori too long. */ if ((search & S_DOTRUSTED) != 0) { - STACK_OF(X509) *hide = ctx->chain; - i = num = sk_X509_num(ctx->chain); if ((search & S_DOALTERNATE) != 0) { /* @@ -2762,10 +2818,7 @@ static int build_chain(X509_STORE_CTX *ctx) } x = sk_X509_value(ctx->chain, i-1); - /* Suppress duplicate suppression */ - ctx->chain = NULL; - ok = (depth < num) ? 0 : ctx->get_issuer(&xtmp, ctx, x); - ctx->chain = hide; + ok = (depth < num) ? 0 : get_issuer(&xtmp, ctx, x); if (ok < 0) { trust = X509_TRUST_REJECTED; @@ -2892,12 +2945,12 @@ static int build_chain(X509_STORE_CTX *ctx) num = sk_X509_num(ctx->chain); OPENSSL_assert(num == ctx->num_untrusted); x = sk_X509_value(ctx->chain, num-1); - xtmp = (depth < num) ? NULL : find_issuer(ctx, sktmp, x); /* * Once we run out of untrusted issuers, we stop looking for more * and start looking only in the trust store if enabled. */ + xtmp = (ss || depth < num) ? NULL : find_issuer(ctx, sktmp, x); if (xtmp == NULL) { search &= ~S_DOUNTRUSTED; if (may_trusted) @@ -2905,23 +2958,21 @@ static int build_chain(X509_STORE_CTX *ctx) continue; } - if (!sk_X509_push(ctx->chain, x = xtmp)) { + /* Drop this issuer from future consideration */ + (void) sk_X509_delete_ptr(sktmp, xtmp); + + if (!sk_X509_push(ctx->chain, xtmp)) { X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE); trust = X509_TRUST_REJECTED; search = 0; continue; } - X509_up_ref(x); + + X509_up_ref(x = xtmp); ++ctx->num_untrusted; ss = cert_self_signed(xtmp); /* - * Not strictly necessary, but saves cycles looking at the same - * certificates over and over. - */ - (void) sk_X509_delete_ptr(sktmp, x); - - /* * Check for DANE-TA trust of the topmost untrusted certificate. */ switch (trust = check_dane_issuer(ctx, ctx->num_untrusted - 1)) { @@ -2974,3 +3025,60 @@ static int build_chain(X509_STORE_CTX *ctx) X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY); } } + +static const int minbits_table[] = { 80, 112, 128, 192, 256 }; +static const int NUM_AUTH_LEVELS = OSSL_NELEM(minbits_table); + +/* + * Check whether the public key of ``cert`` meets the security level of + * ``ctx``. + * + * Returns 1 on success, 0 otherwise. + */ +static int check_key_level(X509_STORE_CTX *ctx, X509 *cert) +{ + EVP_PKEY *pkey = X509_get0_pubkey(cert); + int level = ctx->param->auth_level; + + /* Unsupported or malformed keys are not secure */ + if (pkey == NULL) + return 0; + + if (level <= 0) + return 1; + if (level > NUM_AUTH_LEVELS) + level = NUM_AUTH_LEVELS; + + return EVP_PKEY_security_bits(pkey) >= minbits_table[level - 1]; +} + +/* + * Check whether the signature digest algorithm of ``cert`` meets the security + * level of ``ctx``. Should not be checked for trust anchors (whether + * self-signed or otherwise). + * + * Returns 1 on success, 0 otherwise. + */ +static int check_sig_level(X509_STORE_CTX *ctx, X509 *cert) +{ + int nid = X509_get_signature_nid(cert); + int mdnid = NID_undef; + int secbits = -1; + int level = ctx->param->auth_level; + + if (level <= 0) + return 1; + if (level > NUM_AUTH_LEVELS) + level = NUM_AUTH_LEVELS; + + /* Lookup signature algorithm digest */ + if (nid && OBJ_find_sigid_algs(nid, &mdnid, NULL)) { + const EVP_MD *md; + + /* Assume 4 bits of collision resistance for each hash octet */ + if (mdnid != NID_undef && (md = EVP_get_digestbynid(mdnid)) != NULL) + secbits = EVP_MD_size(md) * 4; + } + + return secbits >= minbits_table[level - 1]; +} diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c index 41b0fde4a5..4a0bed021c 100644 --- a/crypto/x509/x509_vpm.c +++ b/crypto/x509/x509_vpm.c @@ -140,6 +140,7 @@ static void x509_verify_param_zero(X509_VERIFY_PARAM *param) param->inh_flags = 0; param->flags = 0; param->depth = -1; + param->auth_level = -1; /* -1 means unset, 0 is explicit */ sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); param->policies = NULL; sk_OPENSSL_STRING_pop_free(param->hosts, str_free); @@ -245,6 +246,7 @@ int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, x509_verify_param_copy(purpose, 0); x509_verify_param_copy(trust, X509_TRUST_DEFAULT); x509_verify_param_copy(depth, -1); + x509_verify_param_copy(auth_level, -1); /* If overwrite or check time not set, copy across */ @@ -368,6 +370,11 @@ void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth) param->depth = depth; } +void X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level) +{ + param->auth_level = auth_level; +} + void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) { param->check_time = t; @@ -493,6 +500,11 @@ int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) return param->depth; } +int X509_VERIFY_PARAM_get_auth_level(const X509_VERIFY_PARAM *param) +{ + return param->auth_level; +} + const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param) { return param->name; @@ -515,6 +527,7 @@ static const X509_VERIFY_PARAM default_table[] = { 0, /* purpose */ 0, /* trust */ 100, /* depth */ + -1, /* auth_level */ NULL, /* policies */ vpm_empty_id}, { @@ -525,6 +538,7 @@ static const X509_VERIFY_PARAM default_table[] = { X509_PURPOSE_SMIME_SIGN, /* purpose */ X509_TRUST_EMAIL, /* trust */ -1, /* depth */ + -1, /* auth_level */ NULL, /* policies */ vpm_empty_id}, { @@ -535,6 +549,7 @@ static const X509_VERIFY_PARAM default_table[] = { X509_PURPOSE_SMIME_SIGN, /* purpose */ X509_TRUST_EMAIL, /* trust */ -1, /* depth */ + -1, /* auth_level */ NULL, /* policies */ vpm_empty_id}, { @@ -545,6 +560,7 @@ static const X509_VERIFY_PARAM default_table[] = { X509_PURPOSE_SSL_CLIENT, /* purpose */ X509_TRUST_SSL_CLIENT, /* trust */ -1, /* depth */ + -1, /* auth_level */ NULL, /* policies */ vpm_empty_id}, { @@ -555,6 +571,7 @@ static const X509_VERIFY_PARAM default_table[] = { X509_PURPOSE_SSL_SERVER, /* purpose */ X509_TRUST_SSL_SERVER, /* trust */ -1, /* depth */ + -1, /* auth_level */ NULL, /* policies */ vpm_empty_id} }; diff --git a/doc/apps/cms.pod b/doc/apps/cms.pod index 36e6b3ca3a..42c351489c 100644 --- a/doc/apps/cms.pod +++ b/doc/apps/cms.pod @@ -58,6 +58,7 @@ B<openssl> B<cms> [B<-trusted_first>] [B<-no_alt_chains>] [B<-use_deltas>] +[B<-auth_level num>] [B<-verify_depth num>] [B<-verify_email email>] [B<-verify_hostname hostname>] @@ -475,8 +476,8 @@ B<-explicit_policy>, B<-extended_crl>, B<-ignore_critical>, B<-inhibit_any>, B<-inhibit_map>, B<-no_alt_chains>, B<-partial_chain>, B<-policy>, B<-policy_check>, B<-policy_print>, B<-purpose>, B<-suiteB_128>, B<-suiteB_128_only>, B<-suiteB_192>, B<-trusted_first>, B<-use_deltas>, -B<-verify_depth>, B<-verify_email>, B<-verify_hostname>, B<-verify_ip>, -B<-verify_name>, B<-x509_strict> +B<-auth_level>, B<-verify_depth>, B<-verify_email>, B<-verify_hostname>, +B<-verify_ip>, B<-verify_name>, B<-x509_strict> Set various certificate chain validation options. See the L<verify(1)> manual page for details. diff --git a/doc/apps/ocsp.pod b/doc/apps/ocsp.pod index be195bcb30..c796fd5966 100644 --- a/doc/apps/ocsp.pod +++ b/doc/apps/ocsp.pod @@ -53,6 +53,7 @@ B<openssl> B<ocsp> [B<-trusted_first>] [B<-no_alt_chains>] [B<-use_deltas>] +[B<-auth_level num>] [B<-verify_depth num>] [B<-verify_email email>] [B<-verify_hostname hostname>] @@ -197,11 +198,11 @@ B<-explicit_policy>, B<-extended_crl>, B<-ignore_critical>, B<-inhibit_any>, B<-inhibit_map>, B<-no_alt_chains>, B<-partial_chain>, B<-policy>, B<-policy_check>, B<-policy_print>, B<-purpose>, B<-suiteB_128>, B<-suiteB_128_only>, B<-suiteB_192>, B<-trusted_first>, B<-use_deltas>, -B<-verify_depth>, B<-verify_email>, B<-verify_hostname>, B<-verify_ip>, -B<-verify_name>, B<-x509_strict> +B<-auth_level>, B<-verify_depth>, B<-verify_email>, B<-verify_hostname>, +B<-verify_ip>, B<-verify_name>, B<-x509_strict> Set different certificate verification options. -See L<B<verify>|verify(1)> manual page for details. +See L<verify(1)> manual page for details. =item B<-verify_other file> diff --git a/doc/apps/s_client.pod b/doc/apps/s_client.pod index 1873293ea8..881fbcfefe 100644 --- a/doc/apps/s_client.pod +++ b/doc/apps/s_client.pod @@ -45,6 +45,7 @@ B<openssl> B<s_client> [B<-trusted_first>] [B<-no_alt_chains>] [B<-use_deltas>] +[B<-auth_level num>] [B<-verify_depth num>] [B<-verify_email email>] [B<-verify_hostname hostname>] @@ -229,8 +230,8 @@ B<-explicit_policy>, B<-extended_crl>, B<-ignore_critical>, B<-inhibit_any>, B<-inhibit_map>, B<-no_alt_chains>, B<-partial_chain>, B<-policy>, B<-policy_check>, B<-policy_print>, B<-purpose>, B<-suiteB_128>, B<-suiteB_128_only>, B<-suiteB_192>, B<-trusted_first>, B<-use_deltas>, -B<-verify_depth>, B<-verify_email>, B<-verify_hostname>, B<-verify_ip>, -B<-verify_name>, B<-x509_strict> +B<-auth_level>, B<-verify_depth>, B<-verify_email>, B<-verify_hostname>, +B<-verify_ip>, B<-verify_name>, B<-x509_strict> Set various certificate chain validation options. See the L<verify(1)> manual page for details. diff --git a/doc/apps/s_server.pod b/doc/apps/s_server.pod index 25e544468a..08554f4530 100644 --- a/doc/apps/s_server.pod +++ b/doc/apps/s_server.pod @@ -55,6 +55,7 @@ B<openssl> B<s_server> [B<-trusted_first>] [B<-no_alt_chains>] [B<-use_deltas>] +[B<-auth_level num>] [B<-verify_depth num>] [B<-verify_return_error>] [B<-verify_email email>] @@ -234,8 +235,8 @@ B<-explicit_policy>, B<-extended_crl>, B<-ignore_critical>, B<-inhibit_any>, B<-inhibit_map>, B<-no_alt_chains>, B<-partial_chain>, B<-policy>, B<-policy_check>, B<-policy_print>, B<-purpose>, B<-suiteB_128>, B<-suiteB_128_only>, B<-suiteB_192>, B<-trusted_first>, B<-use_deltas>, -B<-verify_depth>, B<-verify_email>, B<-verify_hostname>, B<-verify_ip>, -B<-verify_name>, B<-x509_strict> +B<-auth_level>, B<-verify_depth>, B<-verify_email>, B<-verify_hostname>, +B<-verify_ip>, B<-verify_name>, B<-x509_strict> Set different peer certificate verification options. See the L<verify(1)> manual page for details. diff --git a/doc/apps/smime.pod b/doc/apps/smime.pod index 418d8faa2d..e6323ad0b0 100644 --- a/doc/apps/smime.pod +++ b/doc/apps/smime.pod @@ -40,6 +40,7 @@ B<openssl> B<smime> [B<-trusted_first>] [B<-no_alt_chains>] [B<-use_deltas>] +[B<-auth_level num>] [B<-verify_depth num>] [B<-verify_email email>] [B<-verify_hostname hostname>] @@ -307,8 +308,8 @@ B<-explicit_policy>, B<-extended_crl>, B<-ignore_critical>, B<-inhibit_any>, B<-inhibit_map>, B<-no_alt_chains>, B<-partial_chain>, B<-policy>, B<-policy_check>, B<-policy_print>, B<-purpose>, B<-suiteB_128>, B<-suiteB_128_only>, B<-suiteB_192>, B<-trusted_first>, B<-use_deltas>, -B<-verify_depth>, B<-verify_email>, B<-verify_hostname>, B<-verify_ip>, -B<-verify_name>, B<-x509_strict> +B<-auth_level>, B<-verify_depth>, B<-verify_email>, B<-verify_hostname>, +B<-verify_ip>, B<-verify_name>, B<-x509_strict> Set various options of certificate chain verification. See L<verify(1)> manual page for details. diff --git a/doc/apps/ts.pod b/doc/apps/ts.pod index 93ea9e059a..e64e5fcf34 100644 --- a/doc/apps/ts.pod +++ b/doc/apps/ts.pod @@ -73,6 +73,7 @@ I<verify options:> [-suiteB_192] [-trusted_first] [-use_deltas] +[-auth_level num] [-verify_depth num] [-verify_email email] [-verify_hostname hostname] @@ -371,17 +372,15 @@ all intermediate CA certificates unless the response includes them. =item I<verify options> -The options [-attime timestamp], [-check_ss_sig], [-crl_check], -[-crl_check_all], [-explicit_policy], [-extended_crl], -[-ignore_critical], [-inhibit_any], [-inhibit_map], -[-issuer_checks], [-no_alt_chains], [-no_check_time], -[-partial_chain], [-policy arg], [-policy_check], -[-policy_print], [-purpose purpose], [-suiteB_128], -[-suiteB_128_only], [-suiteB_192], [-trusted_first], -[-use_deltas], [-verify_depth num], [-verify_email email], -[-verify_hostname hostname], [-verify_ip ip], [-verify_name name], -and [-x509_strict] can be used to control timestamp verification. -See L<verify(1)>. +The options B<-attime timestamp>, B<-check_ss_sig>, B<-crl_check>, +B<-crl_check_all>, B<-explicit_policy>, B<-extended_crl>, B<-ignore_critical>, +B<-inhibit_any>, B<-inhibit_map>, B<-issuer_checks>, B<-no_alt_chains>, +B<-no_check_time>, B<-partial_chain>, B<-policy>, B<-policy_check>, +B<-policy_print>, B<-purpose>, B<-suiteB_128>, B<-suiteB_128_only>, +B<-suiteB_192>, B<-trusted_first>, B<-use_deltas>, B<-auth_level>, +B<-verify_depth>, B<-verify_email>, B<-verify_hostname>, B<-verify_ip>, +B<-verify_name>, and B<-x509_strict> can be used to control timestamp +verification. See L<verify(1)>. =back diff --git a/doc/apps/verify.pod b/doc/apps/verify.pod index ecde35fe8a..96d6be4a4d 100644 --- a/doc/apps/verify.pod +++ b/doc/apps/verify.pod @@ -38,6 +38,7 @@ B<openssl> B<verify> [B<-trusted file>] [B<-use_deltas>] [B<-verbose>] +[B<-auth_level level>] [B<-verify_depth num>] [B<-verify_email email>] [B<-verify_hostname hostname>] @@ -227,9 +228,30 @@ Enable support for delta CRLs. Print extra information about the operations being performed. +=item B<-auth_level level> + +Set the certificate chain authentication security level to B<level>. +The authentication security level determines the acceptable signature and +public key strength when verifying certificate chains. +For a certificate chain to validate, the public keys of all the certificates +must meet the specified security B<level>. +The signature algorithm security level is enforced for all the certificates in +the chain except for the chain's I<trust anchor>, which is either directly +trusted or validated by means other than its signature. +See L<SSL_CTX_set_security_level(3)> for the definitions of the available +levels. +The default security level is -1, or "not set". +At security level 0 or lower all algorithms are acceptable. +Security level 1 requires at least 80-bit-equivalent security and is broadly +interoperable, though it will, for example, reject MD5 signatures or RSA keys +shorter than 1024 bits. + =item B<-verify_depth num> -Limit the maximum depth of the certificate chain to B<num> certificates. +Limit the certificate chain to B<num> intermediate CA certificates. +A maximal depth chain can have up to B<num+2> certificates, since neither the +end-entity certificate nor the trust-anchor certificate count against the +B<-verify_depth> limit. =item B<-verify_email email> diff --git a/doc/crypto/X509_VERIFY_PARAM_set_flags.pod b/doc/crypto/X509_VERIFY_PARAM_set_flags.pod index 6fb33edd91..04f521506f 100644 --- a/doc/crypto/X509_VERIFY_PARAM_set_flags.pod +++ b/doc/crypto/X509_VERIFY_PARAM_set_flags.pod @@ -2,15 +2,16 @@ =head1 NAME -X509_VERIFY_PARAM_set_flags, X509_VERIFY_PARAM_clear_flags, X509_VERIFY_PARAM_get_flags, X509_VERIFY_PARAM_set_purpose, X509_VERIFY_PARAM_set_trust, X509_VERIFY_PARAM_set_depth, X509_VERIFY_PARAM_get_depth, X509_VERIFY_PARAM_set_time, X509_VERIFY_PARAM_add0_policy, X509_VERIFY_PARAM_set1_policies, X509_VERIFY_PARAM_set1_host, X509_VERIFY_PARAM_add1_host, X509_VERIFY_PARAM_set_hostflags, X509_VERIFY_PARAM_get0_peername, X509_VERIFY_PARAM_set1_email, X509_VERIFY_PARAM_set1_ip, X509_VERIFY_PARAM_set1_ip_asc - X509 verification parameters +X509_VERIFY_PARAM_set_flags, X509_VERIFY_PARAM_clear_flags, X509_VERIFY_PARAM_get_flags, X509_VERIFY_PARAM_set_purpose, X509_VERIFY_PARAM_set_trust, X509_VERIFY_PARAM_set_depth, X509_VERIFY_PARAM_get_depth, X509_VERIFY_PARAM_set_auth_level, X509_VERIFY_PARAM_get_auth_level, X509_VERIFY_PARAM_set_time, X509_VERIFY_PARAM_add0_policy, X509_VERIFY_PARAM_set1_policies, X509_VERIFY_PARAM_set1_host, X509_VERIFY_PARAM_add1_host, X509_VERIFY_PARAM_set_hostflags, X509_VERIFY_PARAM_get0_peername, X509_VERIFY_PARAM_set1_email, X509_VERIFY_PARAM_set1_ip, X509_VERIFY_PARAM_set1_ip_asc - X509 verification parameters =head1 SYNOPSIS #include <openssl/x509_vfy.h> - int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags); + int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, + unsigned long flags); int X509_VERIFY_PARAM_c |