diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/ts/ts_rsp_sign.c | 10 | ||||
| -rw-r--r-- | src/lib/libcrypto/ts/ts_rsp_verify.c | 11 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_cmp.c | 4 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_internal.h | 6 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_lcl.h | 12 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_purp.c | 10 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_verify.c | 172 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_verify.h | 3 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.c | 56 |
9 files changed, 149 insertions, 135 deletions
diff --git a/src/lib/libcrypto/ts/ts_rsp_sign.c b/src/lib/libcrypto/ts/ts_rsp_sign.c index 828407aa4b..cbd7039abe 100644 --- a/src/lib/libcrypto/ts/ts_rsp_sign.c +++ b/src/lib/libcrypto/ts/ts_rsp_sign.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ts_rsp_sign.c,v 1.24 2021/11/01 20:53:08 tb Exp $ */ | 1 | /* $OpenBSD: ts_rsp_sign.c,v 1.25 2021/11/04 23:52:34 beck Exp $ */ |
| 2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL | 2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL |
| 3 | * project 2002. | 3 | * project 2002. |
| 4 | */ | 4 | */ |
| @@ -849,14 +849,18 @@ ESS_CERT_ID_new_init(X509 *cert, int issuer_needed) | |||
| 849 | { | 849 | { |
| 850 | ESS_CERT_ID *cid = NULL; | 850 | ESS_CERT_ID *cid = NULL; |
| 851 | GENERAL_NAME *name = NULL; | 851 | GENERAL_NAME *name = NULL; |
| 852 | unsigned char cert_hash[TS_HASH_LEN]; | ||
| 852 | 853 | ||
| 853 | /* Recompute SHA1 hash of certificate if necessary (side effect). */ | 854 | /* Recompute SHA1 hash of certificate if necessary (side effect). */ |
| 854 | X509_check_purpose(cert, -1, 0); | 855 | X509_check_purpose(cert, -1, 0); |
| 855 | 856 | ||
| 856 | if (!(cid = ESS_CERT_ID_new())) | 857 | if (!(cid = ESS_CERT_ID_new())) |
| 857 | goto err; | 858 | goto err; |
| 858 | if (!ASN1_OCTET_STRING_set(cid->hash, cert->sha1_hash, | 859 | |
| 859 | sizeof(cert->sha1_hash))) | 860 | if (!X509_digest(cert, TS_HASH_EVP, cert_hash, NULL)) |
| 861 | goto err; | ||
| 862 | |||
| 863 | if (!ASN1_OCTET_STRING_set(cid->hash, cert_hash, sizeof(cert_hash))) | ||
| 860 | goto err; | 864 | goto err; |
| 861 | 865 | ||
| 862 | /* Setting the issuer/serial if requested. */ | 866 | /* Setting the issuer/serial if requested. */ |
diff --git a/src/lib/libcrypto/ts/ts_rsp_verify.c b/src/lib/libcrypto/ts/ts_rsp_verify.c index 2e72ff47ae..07578945cb 100644 --- a/src/lib/libcrypto/ts/ts_rsp_verify.c +++ b/src/lib/libcrypto/ts/ts_rsp_verify.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ts_rsp_verify.c,v 1.22 2021/11/01 20:53:08 tb Exp $ */ | 1 | /* $OpenBSD: ts_rsp_verify.c,v 1.23 2021/11/04 23:52:34 beck Exp $ */ |
| 2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL | 2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL |
| 3 | * project 2002. | 3 | * project 2002. |
| 4 | */ | 4 | */ |
| @@ -325,10 +325,14 @@ static int | |||
| 325 | TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) | 325 | TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) |
| 326 | { | 326 | { |
| 327 | int i; | 327 | int i; |
| 328 | unsigned char cert_hash[TS_HASH_LEN]; | ||
| 328 | 329 | ||
| 329 | if (!cert_ids || !cert) | 330 | if (!cert_ids || !cert) |
| 330 | return -1; | 331 | return -1; |
| 331 | 332 | ||
| 333 | if (!X509_digest(cert, TS_HASH_EVP, cert_hash, NULL)) | ||
| 334 | return -1; | ||
| 335 | |||
| 332 | /* Recompute SHA1 hash of certificate if necessary (side effect). */ | 336 | /* Recompute SHA1 hash of certificate if necessary (side effect). */ |
| 333 | X509_check_purpose(cert, -1, 0); | 337 | X509_check_purpose(cert, -1, 0); |
| 334 | 338 | ||
| @@ -337,9 +341,8 @@ TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) | |||
| 337 | ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i); | 341 | ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i); |
| 338 | 342 | ||
| 339 | /* Check the SHA-1 hash first. */ | 343 | /* Check the SHA-1 hash first. */ |
| 340 | if (cid->hash->length == sizeof(cert->sha1_hash) && | 344 | if (cid->hash->length == TS_HASH_LEN && !memcmp(cid->hash->data, |
| 341 | !memcmp(cid->hash->data, cert->sha1_hash, | 345 | cert_hash, TS_HASH_LEN)) { |
| 342 | sizeof(cert->sha1_hash))) { | ||
| 343 | /* Check the issuer/serial as well if specified. */ | 346 | /* Check the issuer/serial as well if specified. */ |
| 344 | ESS_ISSUER_SERIAL *is = cid->issuer_serial; | 347 | ESS_ISSUER_SERIAL *is = cid->issuer_serial; |
| 345 | if (!is || !TS_issuer_serial_cmp(is, cert->cert_info)) | 348 | if (!is || !TS_issuer_serial_cmp(is, cert->cert_info)) |
diff --git a/src/lib/libcrypto/x509/x509_cmp.c b/src/lib/libcrypto/x509/x509_cmp.c index 134a082730..bc944b71d7 100644 --- a/src/lib/libcrypto/x509/x509_cmp.c +++ b/src/lib/libcrypto/x509/x509_cmp.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_cmp.c,v 1.36 2021/11/01 20:53:08 tb Exp $ */ | 1 | /* $OpenBSD: x509_cmp.c,v 1.37 2021/11/04 23:52:34 beck Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -215,7 +215,7 @@ X509_cmp(const X509 *a, const X509 *b) | |||
| 215 | X509_check_purpose((X509 *)a, -1, 0); | 215 | X509_check_purpose((X509 *)a, -1, 0); |
| 216 | X509_check_purpose((X509 *)b, -1, 0); | 216 | X509_check_purpose((X509 *)b, -1, 0); |
| 217 | 217 | ||
| 218 | return memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH); | 218 | return memcmp(a->hash, b->hash, X509_CERT_HASH_LEN); |
| 219 | } | 219 | } |
| 220 | #endif | 220 | #endif |
| 221 | 221 | ||
diff --git a/src/lib/libcrypto/x509/x509_internal.h b/src/lib/libcrypto/x509/x509_internal.h index 7ca67a853b..a9b584b13e 100644 --- a/src/lib/libcrypto/x509/x509_internal.h +++ b/src/lib/libcrypto/x509/x509_internal.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_internal.h,v 1.14 2021/11/01 20:53:08 tb Exp $ */ | 1 | /* $OpenBSD: x509_internal.h,v 1.15 2021/11/04 23:52:34 beck Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
| 4 | * | 4 | * |
| @@ -96,8 +96,7 @@ int x509_vfy_callback_indicate_success(X509_STORE_CTX *ctx); | |||
| 96 | void x509v3_cache_extensions(X509 *x); | 96 | void x509v3_cache_extensions(X509 *x); |
| 97 | X509 *x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x); | 97 | X509 *x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x); |
| 98 | 98 | ||
| 99 | int x509_verify_asn1_time_to_tm(const ASN1_TIME *atime, struct tm *tm, | 99 | time_t x509_verify_asn1_time_to_time_t(const ASN1_TIME *atime, int notafter); |
| 100 | int notafter); | ||
| 101 | 100 | ||
| 102 | struct x509_verify_ctx *x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc); | 101 | struct x509_verify_ctx *x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc); |
| 103 | 102 | ||
| @@ -132,6 +131,7 @@ int x509_constraints_check(struct x509_constraints_names *names, | |||
| 132 | struct x509_constraints_names *excluded, int *error); | 131 | struct x509_constraints_names *excluded, int *error); |
| 133 | int x509_constraints_chain(STACK_OF(X509) *chain, int *error, | 132 | int x509_constraints_chain(STACK_OF(X509) *chain, int *error, |
| 134 | int *depth); | 133 | int *depth); |
| 134 | void x509_verify_cert_info_populate(X509 *cert); | ||
| 135 | 135 | ||
| 136 | __END_HIDDEN_DECLS | 136 | __END_HIDDEN_DECLS |
| 137 | 137 | ||
diff --git a/src/lib/libcrypto/x509/x509_lcl.h b/src/lib/libcrypto/x509/x509_lcl.h index 1b352aee78..804fff48fc 100644 --- a/src/lib/libcrypto/x509/x509_lcl.h +++ b/src/lib/libcrypto/x509/x509_lcl.h | |||
| @@ -61,6 +61,12 @@ | |||
| 61 | 61 | ||
| 62 | __BEGIN_HIDDEN_DECLS | 62 | __BEGIN_HIDDEN_DECLS |
| 63 | 63 | ||
| 64 | #define TS_HASH_EVP EVP_sha1() | ||
| 65 | #define TS_HASH_LEN SHA_DIGEST_LENGTH | ||
| 66 | |||
| 67 | #define X509_CERT_HASH_EVP EVP_sha512() | ||
| 68 | #define X509_CERT_HASH_LEN SHA512_DIGEST_LENGTH | ||
| 69 | |||
| 64 | struct X509_pubkey_st { | 70 | struct X509_pubkey_st { |
| 65 | X509_ALGOR *algor; | 71 | X509_ALGOR *algor; |
| 66 | ASN1_BIT_STRING *public_key; | 72 | ASN1_BIT_STRING *public_key; |
| @@ -177,9 +183,9 @@ struct x509_st { | |||
| 177 | STACK_OF(IPAddressFamily) *rfc3779_addr; | 183 | STACK_OF(IPAddressFamily) *rfc3779_addr; |
| 178 | struct ASIdentifiers_st *rfc3779_asid; | 184 | struct ASIdentifiers_st *rfc3779_asid; |
| 179 | #endif | 185 | #endif |
| 180 | #ifndef OPENSSL_NO_SHA | 186 | unsigned char hash[X509_CERT_HASH_LEN]; |
| 181 | unsigned char sha1_hash[SHA_DIGEST_LENGTH]; | 187 | time_t not_before; |
| 182 | #endif | 188 | time_t not_after; |
| 183 | X509_CERT_AUX *aux; | 189 | X509_CERT_AUX *aux; |
| 184 | } /* X509 */; | 190 | } /* X509 */; |
| 185 | 191 | ||
diff --git a/src/lib/libcrypto/x509/x509_purp.c b/src/lib/libcrypto/x509/x509_purp.c index 67a7b51fb1..a05c0388ac 100644 --- a/src/lib/libcrypto/x509/x509_purp.c +++ b/src/lib/libcrypto/x509/x509_purp.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_purp.c,v 1.12 2021/11/01 20:53:08 tb Exp $ */ | 1 | /* $OpenBSD: x509_purp.c,v 1.13 2021/11/04 23:52:34 beck Exp $ */ |
| 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
| 3 | * project 2001. | 3 | * project 2001. |
| 4 | */ | 4 | */ |
| @@ -65,6 +65,7 @@ | |||
| 65 | #include <openssl/x509v3.h> | 65 | #include <openssl/x509v3.h> |
| 66 | #include <openssl/x509_vfy.h> | 66 | #include <openssl/x509_vfy.h> |
| 67 | 67 | ||
| 68 | #include "x509_internal.h" | ||
| 68 | #include "x509_lcl.h" | 69 | #include "x509_lcl.h" |
| 69 | 70 | ||
| 70 | #define V1_ROOT (EXFLAG_V1|EXFLAG_SS) | 71 | #define V1_ROOT (EXFLAG_V1|EXFLAG_SS) |
| @@ -449,9 +450,7 @@ x509v3_cache_extensions(X509 *x) | |||
| 449 | if (x->ex_flags & EXFLAG_SET) | 450 | if (x->ex_flags & EXFLAG_SET) |
| 450 | return; | 451 | return; |
| 451 | 452 | ||
| 452 | #ifndef OPENSSL_NO_SHA | 453 | X509_digest(x, X509_CERT_HASH_EVP, x->hash, NULL); |
| 453 | X509_digest(x, EVP_sha1(), x->sha1_hash, NULL); | ||
| 454 | #endif | ||
| 455 | 454 | ||
| 456 | /* V1 should mean no extensions ... */ | 455 | /* V1 should mean no extensions ... */ |
| 457 | if (!X509_get_version(x)) | 456 | if (!X509_get_version(x)) |
| @@ -618,6 +617,9 @@ x509v3_cache_extensions(X509 *x) | |||
| 618 | break; | 617 | break; |
| 619 | } | 618 | } |
| 620 | } | 619 | } |
| 620 | |||
| 621 | x509_verify_cert_info_populate(x); | ||
| 622 | |||
| 621 | x->ex_flags |= EXFLAG_SET; | 623 | x->ex_flags |= EXFLAG_SET; |
| 622 | } | 624 | } |
| 623 | 625 | ||
diff --git a/src/lib/libcrypto/x509/x509_verify.c b/src/lib/libcrypto/x509/x509_verify.c index 8bcc647149..b9ba2bee3c 100644 --- a/src/lib/libcrypto/x509/x509_verify.c +++ b/src/lib/libcrypto/x509/x509_verify.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_verify.c,v 1.50 2021/10/26 15:14:18 job Exp $ */ | 1 | /* $OpenBSD: x509_verify.c,v 1.51 2021/11/04 23:52:34 beck Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org> |
| 4 | * | 4 | * |
| @@ -38,7 +38,58 @@ static int x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert, | |||
| 38 | size_t depth, int error, int ok); | 38 | size_t depth, int error, int ok); |
| 39 | static void x509_verify_chain_free(struct x509_verify_chain *chain); | 39 | static void x509_verify_chain_free(struct x509_verify_chain *chain); |
| 40 | 40 | ||
| 41 | #define X509_VERIFY_CERT_HASH (EVP_sha512()) | 41 | /* |
| 42 | * Parse an asn1 to a representable time_t as per RFC 5280 rules. | ||
| 43 | * Returns -1 if that can't be done for any reason. | ||
| 44 | */ | ||
| 45 | time_t | ||
| 46 | x509_verify_asn1_time_to_time_t(const ASN1_TIME *atime, int notAfter) | ||
| 47 | { | ||
| 48 | struct tm tm = { 0 }; | ||
| 49 | int type; | ||
| 50 | |||
| 51 | type = ASN1_time_parse(atime->data, atime->length, &tm, atime->type); | ||
| 52 | if (type == -1) | ||
| 53 | return -1; | ||
| 54 | |||
| 55 | /* RFC 5280 section 4.1.2.5 */ | ||
| 56 | if (tm.tm_year < 150 && type != V_ASN1_UTCTIME) | ||
| 57 | return -1; | ||
| 58 | if (tm.tm_year >= 150 && type != V_ASN1_GENERALIZEDTIME) | ||
| 59 | return -1; | ||
| 60 | |||
| 61 | if (notAfter) { | ||
| 62 | /* | ||
| 63 | * If we are a completely broken operating system with a | ||
| 64 | * 32 bit time_t, and we have been told this is a notAfter | ||
| 65 | * date, limit the date to a 32 bit representable value. | ||
| 66 | */ | ||
| 67 | if (!ASN1_time_tm_clamp_notafter(&tm)) | ||
| 68 | return -1; | ||
| 69 | } | ||
| 70 | |||
| 71 | /* | ||
| 72 | * Defensively fail if the time string is not representable as | ||
| 73 | * a time_t. A time_t must be sane if you care about times after | ||
| 74 | * Jan 19 2038. | ||
| 75 | */ | ||
| 76 | return timegm(&tm); | ||
| 77 | } | ||
| 78 | |||
| 79 | /* | ||
| 80 | * Cache certificate hash, and values parsed out of an X509. | ||
| 81 | * called from cache_extensions() | ||
| 82 | */ | ||
| 83 | void | ||
| 84 | x509_verify_cert_info_populate(X509 *cert) | ||
| 85 | { | ||
| 86 | /* | ||
| 87 | * Parse and save the cert times, or remember that they | ||
| 88 | * are unacceptable/unparsable. | ||
| 89 | */ | ||
| 90 | cert->not_before = x509_verify_asn1_time_to_time_t(X509_get_notBefore(cert), 0); | ||
| 91 | cert->not_after = x509_verify_asn1_time_to_time_t(X509_get_notAfter(cert), 1); | ||
| 92 | } | ||
| 42 | 93 | ||
| 43 | struct x509_verify_chain * | 94 | struct x509_verify_chain * |
| 44 | x509_verify_chain_new(void) | 95 | x509_verify_chain_new(void) |
| @@ -194,6 +245,7 @@ x509_verify_cert_cache_extensions(X509 *cert) { | |||
| 194 | } | 245 | } |
| 195 | if (cert->ex_flags & EXFLAG_INVALID) | 246 | if (cert->ex_flags & EXFLAG_INVALID) |
| 196 | return 0; | 247 | return 0; |
| 248 | |||
| 197 | return (cert->ex_flags & EXFLAG_SET); | 249 | return (cert->ex_flags & EXFLAG_SET); |
| 198 | } | 250 | } |
| 199 | 251 | ||
| @@ -455,22 +507,15 @@ x509_verify_potential_parent(struct x509_verify_ctx *ctx, X509 *parent, | |||
| 455 | } | 507 | } |
| 456 | 508 | ||
| 457 | static int | 509 | static int |
| 458 | x509_verify_parent_signature(X509 *parent, X509 *child, | 510 | x509_verify_parent_signature(X509 *parent, X509 *child, int *error) |
| 459 | unsigned char *child_md, int *error) | ||
| 460 | { | 511 | { |
| 461 | unsigned char parent_md[EVP_MAX_MD_SIZE] = { 0 }; | ||
| 462 | EVP_PKEY *pkey; | 512 | EVP_PKEY *pkey; |
| 463 | int cached; | 513 | int cached; |
| 464 | int ret = 0; | 514 | int ret = 0; |
| 465 | 515 | ||
| 466 | /* Use cached value if we have it */ | 516 | /* Use cached value if we have it */ |
| 467 | if (child_md != NULL) { | 517 | if ((cached = x509_issuer_cache_find(parent->hash, child->hash)) >= 0) |
| 468 | if (!X509_digest(parent, X509_VERIFY_CERT_HASH, parent_md, | 518 | return cached; |
| 469 | NULL)) | ||
| 470 | return 0; | ||
| 471 | if ((cached = x509_issuer_cache_find(parent_md, child_md)) >= 0) | ||
| 472 | return cached; | ||
| 473 | } | ||
| 474 | 519 | ||
| 475 | /* Check signature. Did parent sign child? */ | 520 | /* Check signature. Did parent sign child? */ |
| 476 | if ((pkey = X509_get_pubkey(parent)) == NULL) { | 521 | if ((pkey = X509_get_pubkey(parent)) == NULL) { |
| @@ -483,8 +528,7 @@ x509_verify_parent_signature(X509 *parent, X509 *child, | |||
| 483 | ret = 1; | 528 | ret = 1; |
| 484 | 529 | ||
| 485 | /* Add result to cache */ | 530 | /* Add result to cache */ |
| 486 | if (child_md != NULL) | 531 | x509_issuer_cache_add(parent->hash, child->hash, ret); |
| 487 | x509_issuer_cache_add(parent_md, child_md, ret); | ||
| 488 | 532 | ||
| 489 | EVP_PKEY_free(pkey); | 533 | EVP_PKEY_free(pkey); |
| 490 | 534 | ||
| @@ -493,8 +537,8 @@ x509_verify_parent_signature(X509 *parent, X509 *child, | |||
| 493 | 537 | ||
| 494 | static int | 538 | static int |
| 495 | x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert, | 539 | x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert, |
| 496 | unsigned char *cert_md, int is_root_cert, X509 *candidate, | 540 | int is_root_cert, X509 *candidate, struct x509_verify_chain *current_chain, |
| 497 | struct x509_verify_chain *current_chain, int full_chain) | 541 | int full_chain) |
| 498 | { | 542 | { |
| 499 | int depth = sk_X509_num(current_chain->certs); | 543 | int depth = sk_X509_num(current_chain->certs); |
| 500 | struct x509_verify_chain *new_chain; | 544 | struct x509_verify_chain *new_chain; |
| @@ -514,8 +558,7 @@ x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert, | |||
| 514 | return 0; | 558 | return 0; |
| 515 | } | 559 | } |
| 516 | 560 | ||
| 517 | if (!x509_verify_parent_signature(candidate, cert, cert_md, | 561 | if (!x509_verify_parent_signature(candidate, cert, &ctx->error)) { |
| 518 | &ctx->error)) { | ||
| 519 | if (!x509_verify_cert_error(ctx, candidate, depth, | 562 | if (!x509_verify_cert_error(ctx, candidate, depth, |
| 520 | ctx->error, 0)) | 563 | ctx->error, 0)) |
| 521 | return 0; | 564 | return 0; |
| @@ -579,7 +622,6 @@ static void | |||
| 579 | x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, | 622 | x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, |
| 580 | struct x509_verify_chain *current_chain, int full_chain) | 623 | struct x509_verify_chain *current_chain, int full_chain) |
| 581 | { | 624 | { |
| 582 | unsigned char cert_md[EVP_MAX_MD_SIZE] = { 0 }; | ||
| 583 | X509 *candidate; | 625 | X509 *candidate; |
| 584 | int i, depth, count, ret, is_root; | 626 | int i, depth, count, ret, is_root; |
| 585 | 627 | ||
| @@ -600,11 +642,6 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, | |||
| 600 | X509_V_ERR_CERT_CHAIN_TOO_LONG, 0)) | 642 | X509_V_ERR_CERT_CHAIN_TOO_LONG, 0)) |
| 601 | return; | 643 | return; |
| 602 | 644 | ||
| 603 | if (!X509_digest(cert, X509_VERIFY_CERT_HASH, cert_md, NULL) && | ||
| 604 | !x509_verify_cert_error(ctx, cert, depth, | ||
| 605 | X509_V_ERR_UNSPECIFIED, 0)) | ||
| 606 | return; | ||
| 607 | |||
| 608 | count = ctx->chains_count; | 645 | count = ctx->chains_count; |
| 609 | 646 | ||
| 610 | ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; | 647 | ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; |
| @@ -640,7 +677,7 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, | |||
| 640 | is_root = !full_chain || | 677 | is_root = !full_chain || |
| 641 | x509_verify_cert_self_signed(candidate); | 678 | x509_verify_cert_self_signed(candidate); |
| 642 | x509_verify_consider_candidate(ctx, cert, | 679 | x509_verify_consider_candidate(ctx, cert, |
| 643 | cert_md, is_root, candidate, current_chain, | 680 | is_root, candidate, current_chain, |
| 644 | full_chain); | 681 | full_chain); |
| 645 | } | 682 | } |
| 646 | X509_free(candidate); | 683 | X509_free(candidate); |
| @@ -653,7 +690,7 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, | |||
| 653 | is_root = !full_chain || | 690 | is_root = !full_chain || |
| 654 | x509_verify_cert_self_signed(candidate); | 691 | x509_verify_cert_self_signed(candidate); |
| 655 | x509_verify_consider_candidate(ctx, cert, | 692 | x509_verify_consider_candidate(ctx, cert, |
| 656 | cert_md, is_root, candidate, current_chain, | 693 | is_root, candidate, current_chain, |
| 657 | full_chain); | 694 | full_chain); |
| 658 | } | 695 | } |
| 659 | } | 696 | } |
| @@ -665,7 +702,7 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, | |||
| 665 | candidate = sk_X509_value(ctx->intermediates, i); | 702 | candidate = sk_X509_value(ctx->intermediates, i); |
| 666 | if (x509_verify_potential_parent(ctx, candidate, cert)) { | 703 | if (x509_verify_potential_parent(ctx, candidate, cert)) { |
| 667 | x509_verify_consider_candidate(ctx, cert, | 704 | x509_verify_consider_candidate(ctx, cert, |
| 668 | cert_md, 0, candidate, current_chain, | 705 | 0, candidate, current_chain, |
| 669 | full_chain); | 706 | full_chain); |
| 670 | } | 707 | } |
| 671 | } | 708 | } |
| @@ -748,47 +785,9 @@ x509_verify_set_check_time(struct x509_verify_ctx *ctx) { | |||
| 748 | return 1; | 785 | return 1; |
| 749 | } | 786 | } |
| 750 | 787 | ||
| 751 | int | ||
| 752 | x509_verify_asn1_time_to_tm(const ASN1_TIME *atime, struct tm *tm, int notafter) | ||
| 753 | { | ||
| 754 | int type; | ||
| 755 | |||
| 756 | type = ASN1_time_parse(atime->data, atime->length, tm, atime->type); | ||
| 757 | if (type == -1) | ||
| 758 | return 0; | ||
| 759 | |||
| 760 | /* RFC 5280 section 4.1.2.5 */ | ||
| 761 | if (tm->tm_year < 150 && type != V_ASN1_UTCTIME) | ||
| 762 | return 0; | ||
| 763 | if (tm->tm_year >= 150 && type != V_ASN1_GENERALIZEDTIME) | ||
| 764 | return 0; | ||
| 765 | |||
| 766 | if (notafter) { | ||
| 767 | /* | ||
| 768 | * If we are a completely broken operating system with a | ||
| 769 | * 32 bit time_t, and we have been told this is a notafter | ||
| 770 | * date, limit the date to a 32 bit representable value. | ||
| 771 | */ | ||
| 772 | if (!ASN1_time_tm_clamp_notafter(tm)) | ||
| 773 | return 0; | ||
| 774 | } | ||
| 775 | |||
| 776 | /* | ||
| 777 | * Defensively fail if the time string is not representable as | ||
| 778 | * a time_t. A time_t must be sane if you care about times after | ||
| 779 | * Jan 19 2038. | ||
| 780 | */ | ||
| 781 | if (timegm(tm) == -1) | ||
| 782 | return 0; | ||
| 783 | |||
| 784 | return 1; | ||
| 785 | } | ||
| 786 | |||
| 787 | static int | 788 | static int |
| 788 | x509_verify_cert_time(int is_notafter, const ASN1_TIME *cert_asn1, | 789 | x509_verify_cert_times(X509 *cert, time_t *cmp_time, int *error) |
| 789 | time_t *cmp_time, int *error) | ||
| 790 | { | 790 | { |
| 791 | struct tm cert_tm, when_tm; | ||
| 792 | time_t when; | 791 | time_t when; |
| 793 | 792 | ||
| 794 | if (cmp_time == NULL) | 793 | if (cmp_time == NULL) |
| @@ -796,29 +795,21 @@ x509_verify_cert_time(int is_notafter, const ASN1_TIME *cert_asn1, | |||
| 796 | else | 795 | else |
| 797 | when = *cmp_time; | 796 | when = *cmp_time; |
| 798 | 797 | ||
| 799 | if (!x509_verify_asn1_time_to_tm(cert_asn1, &cert_tm, | 798 | if (cert->not_before == -1) { |
| 800 | is_notafter)) { | 799 | *error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; |
| 801 | *error = is_notafter ? | ||
| 802 | X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD : | ||
| 803 | X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; | ||
| 804 | return 0; | 800 | return 0; |
| 805 | } | 801 | } |
| 806 | 802 | if (when < cert->not_before) { | |
| 807 | if (gmtime_r(&when, &when_tm) == NULL) { | 803 | *error = X509_V_ERR_CERT_NOT_YET_VALID; |
| 808 | *error = X509_V_ERR_UNSPECIFIED; | ||
| 809 | return 0; | 804 | return 0; |
| 810 | } | 805 | } |
| 811 | 806 | if (cert->not_after == -1) { | |
| 812 | if (is_notafter) { | 807 | *error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; |
| 813 | if (ASN1_time_tm_cmp(&cert_tm, &when_tm) == -1) { | 808 | return 0; |
| 814 | *error = X509_V_ERR_CERT_HAS_EXPIRED; | 809 | } |
| 815 | return 0; | 810 | if (when > cert->not_after) { |
| 816 | } | 811 | *error = X509_V_ERR_CERT_HAS_EXPIRED; |
| 817 | } else { | 812 | return 0; |
| 818 | if (ASN1_time_tm_cmp(&cert_tm, &when_tm) == 1) { | ||
| 819 | *error = X509_V_ERR_CERT_NOT_YET_VALID; | ||
| 820 | return 0; | ||
| 821 | } | ||
| 822 | } | 813 | } |
| 823 | 814 | ||
| 824 | return 1; | 815 | return 1; |
| @@ -924,15 +915,8 @@ x509_verify_cert_valid(struct x509_verify_ctx *ctx, X509 *cert, | |||
| 924 | } | 915 | } |
| 925 | 916 | ||
| 926 | if (x509_verify_set_check_time(ctx)) { | 917 | if (x509_verify_set_check_time(ctx)) { |
| 927 | if (!x509_verify_cert_time(0, X509_get_notBefore(cert), | 918 | if (!x509_verify_cert_times(cert, ctx->check_time, |
| 928 | ctx->check_time, &ctx->error)) { | 919 | &ctx->error)) { |
| 929 | if (!x509_verify_cert_error(ctx, cert, depth, | ||
| 930 | ctx->error, 0)) | ||
| 931 | return 0; | ||
| 932 | } | ||
| 933 | |||
| 934 | if (!x509_verify_cert_time(1, X509_get_notAfter(cert), | ||
| 935 | ctx->check_time, &ctx->error)) { | ||
| 936 | if (!x509_verify_cert_error(ctx, cert, depth, | 920 | if (!x509_verify_cert_error(ctx, cert, depth, |
| 937 | ctx->error, 0)) | 921 | ctx->error, 0)) |
| 938 | return 0; | 922 | return 0; |
diff --git a/src/lib/libcrypto/x509/x509_verify.h b/src/lib/libcrypto/x509/x509_verify.h index a097404f2e..d8d2cb0b5f 100644 --- a/src/lib/libcrypto/x509/x509_verify.h +++ b/src/lib/libcrypto/x509/x509_verify.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_verify.h,v 1.1 2020/09/13 15:06:17 beck Exp $ */ | 1 | /* $OpenBSD: x509_verify.h,v 1.2 2021/11/04 23:52:34 beck Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
| 4 | * | 4 | * |
| @@ -19,6 +19,7 @@ | |||
| 19 | 19 | ||
| 20 | #ifdef LIBRESSL_INTERNAL | 20 | #ifdef LIBRESSL_INTERNAL |
| 21 | struct x509_verify_ctx; | 21 | struct x509_verify_ctx; |
| 22 | struct x509_verify_cert_info; | ||
| 22 | typedef struct x509_verify_ctx X509_VERIFY_CTX; | 23 | typedef struct x509_verify_ctx X509_VERIFY_CTX; |
| 23 | 24 | ||
| 24 | X509_VERIFY_CTX *x509_verify_ctx_new(STACK_OF(X509) *roots); | 25 | X509_VERIFY_CTX *x509_verify_ctx_new(STACK_OF(X509) *roots); |
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c index 664474139c..3b0d6dfa35 100644 --- a/src/lib/libcrypto/x509/x509_vfy.c +++ b/src/lib/libcrypto/x509/x509_vfy.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_vfy.c,v 1.93 2021/11/01 20:53:08 tb Exp $ */ | 1 | /* $OpenBSD: x509_vfy.c,v 1.94 2021/11/04 23:52:34 beck Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -1843,6 +1843,18 @@ verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err) | |||
| 1843 | return ctx->verify_cb(0, ctx); | 1843 | return ctx->verify_cb(0, ctx); |
| 1844 | } | 1844 | } |
| 1845 | 1845 | ||
| 1846 | |||
| 1847 | /* Mimic OpenSSL '0 for failure' ick */ | ||
| 1848 | static int | ||
| 1849 | time_t_bogocmp(time_t a, time_t b) | ||
| 1850 | { | ||
| 1851 | if (a == -1 || b == -1) | ||
| 1852 | return 0; | ||
| 1853 | if (a <= b) | ||
| 1854 | return -1; | ||
| 1855 | return 1; | ||
| 1856 | } | ||
| 1857 | |||
| 1846 | /* | 1858 | /* |
| 1847 | * Check certificate validity times. | 1859 | * Check certificate validity times. |
| 1848 | * | 1860 | * |
| @@ -1854,17 +1866,21 @@ verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err) | |||
| 1854 | int | 1866 | int |
| 1855 | x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) | 1867 | x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) |
| 1856 | { | 1868 | { |
| 1857 | time_t *ptime; | 1869 | time_t ptime; |
| 1858 | int i; | 1870 | int i; |
| 1859 | 1871 | ||
| 1860 | if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) | 1872 | if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) |
| 1861 | ptime = &ctx->param->check_time; | 1873 | ptime = ctx->param->check_time; |
| 1862 | else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) | 1874 | else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) |
| 1863 | return 1; | 1875 | return 1; |
| 1864 | else | 1876 | else |
| 1865 | ptime = NULL; | 1877 | ptime = time(NULL); |
| 1878 | |||
| 1879 | if (x->ex_flags & EXFLAG_SET) | ||
| 1880 | i = time_t_bogocmp(x->not_before, ptime); | ||
| 1881 | else | ||
| 1882 | i = X509_cmp_time(X509_get_notBefore(x), &ptime); | ||
| 1866 | 1883 | ||
| 1867 | i = X509_cmp_time(X509_get_notBefore(x), ptime); | ||
| 1868 | if (i >= 0 && depth < 0) | 1884 | if (i >= 0 && depth < 0) |
| 1869 | return 0; | 1885 | return 0; |
| 1870 | if (i == 0 && !verify_cb_cert(ctx, x, depth, | 1886 | if (i == 0 && !verify_cb_cert(ctx, x, depth, |
| @@ -1874,7 +1890,11 @@ x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) | |||
| 1874 | X509_V_ERR_CERT_NOT_YET_VALID)) | 1890 | X509_V_ERR_CERT_NOT_YET_VALID)) |
| 1875 | return 0; | 1891 | return 0; |
| 1876 | 1892 | ||
| 1877 | i = X509_cmp_time_internal(X509_get_notAfter(x), ptime, 1); | 1893 | if (x->ex_flags & EXFLAG_SET) |
| 1894 | i = time_t_bogocmp(x->not_after, ptime); | ||
| 1895 | else | ||
| 1896 | i = X509_cmp_time_internal(X509_get_notAfter(x), &ptime, 1); | ||
| 1897 | |||
| 1878 | if (i <= 0 && depth < 0) | 1898 | if (i <= 0 && depth < 0) |
| 1879 | return 0; | 1899 | return 0; |
| 1880 | if (i == 0 && !verify_cb_cert(ctx, x, depth, | 1900 | if (i == 0 && !verify_cb_cert(ctx, x, depth, |
| @@ -1883,6 +1903,7 @@ x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) | |||
| 1883 | if (i < 0 && !verify_cb_cert(ctx, x, depth, | 1903 | if (i < 0 && !verify_cb_cert(ctx, x, depth, |
| 1884 | X509_V_ERR_CERT_HAS_EXPIRED)) | 1904 | X509_V_ERR_CERT_HAS_EXPIRED)) |
| 1885 | return 0; | 1905 | return 0; |
| 1906 | |||
| 1886 | return 1; | 1907 | return 1; |
| 1887 | } | 1908 | } |
| 1888 | 1909 | ||
| @@ -1994,30 +2015,23 @@ X509_cmp_current_time(const ASN1_TIME *ctm) | |||
| 1994 | * 0 on error. | 2015 | * 0 on error. |
| 1995 | */ | 2016 | */ |
| 1996 | static int | 2017 | static int |
| 1997 | X509_cmp_time_internal(const ASN1_TIME *ctm, time_t *cmp_time, int clamp_notafter) | 2018 | X509_cmp_time_internal(const ASN1_TIME *ctm, time_t *cmp_time, int is_notafter) |
| 1998 | { | 2019 | { |
| 1999 | time_t compare; | 2020 | time_t compare, cert_time; |
| 2000 | struct tm tm1, tm2; | ||
| 2001 | int ret = 0; | ||
| 2002 | 2021 | ||
| 2003 | if (cmp_time == NULL) | 2022 | if (cmp_time == NULL) |
| 2004 | compare = time(NULL); | 2023 | compare = time(NULL); |
| 2005 | else | 2024 | else |
| 2006 | compare = *cmp_time; | 2025 | compare = *cmp_time; |
| 2007 | 2026 | ||
| 2008 | memset(&tm1, 0, sizeof(tm1)); | 2027 | if ((cert_time = x509_verify_asn1_time_to_time_t(ctm, is_notafter)) == |
| 2028 | -1) | ||
| 2029 | return 0; /* invalid time */ | ||
| 2009 | 2030 | ||
| 2010 | if (!x509_verify_asn1_time_to_tm(ctm, &tm1, clamp_notafter)) | 2031 | if (cert_time <= compare) |
| 2011 | goto out; /* invalid time */ | 2032 | return -1; /* 0 is used for error, so map same to less than */ |
| 2012 | 2033 | ||
| 2013 | if (gmtime_r(&compare, &tm2) == NULL) | 2034 | return 1; |
| 2014 | goto out; | ||
| 2015 | |||
| 2016 | ret = ASN1_time_tm_cmp(&tm1, &tm2); | ||
| 2017 | if (ret == 0) | ||
| 2018 | ret = -1; /* 0 is used for error, so map same to less than */ | ||
| 2019 | out: | ||
| 2020 | return (ret); | ||
| 2021 | } | 2035 | } |
| 2022 | 2036 | ||
| 2023 | int | 2037 | int |
