summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2023-06-25 13:52:27 +0000
committertb <>2023-06-25 13:52:27 +0000
commit8919d61b9c2ddf1361401516b4966661c64921e2 (patch)
tree0a021ec29597e06c18b7ca843457986e9d026455
parentee2a1487217437d0cbc8d2cba036b6b755509997 (diff)
downloadopenbsd-8919d61b9c2ddf1361401516b4966661c64921e2.tar.gz
openbsd-8919d61b9c2ddf1361401516b4966661c64921e2.tar.bz2
openbsd-8919d61b9c2ddf1361401516b4966661c64921e2.zip
Check for duplicate X.509v3 extension OIDs
Per RFC 5280, 4.2: A certificate MUST NOT include more than one instance of a particular extension. This implements such a check in x509v3_cache_extensions() by sorting the list of extensions and looking for duplicate neighbors. This sidesteps complications from extensions we do not know about and keeps algorithmic complexity reasonable. If the check fails, EXFLAG_INVALID is set on the certificate, which means that the verifier will not validate it. ok jsing
-rw-r--r--src/lib/libcrypto/x509/x509_purp.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/src/lib/libcrypto/x509/x509_purp.c b/src/lib/libcrypto/x509/x509_purp.c
index 75d229b03b..f7bc7ea538 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.26 2023/06/20 14:21:19 tb Exp $ */ 1/* $OpenBSD: x509_purp.c,v 1.27 2023/06/25 13:52:27 tb 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 */
@@ -441,6 +441,47 @@ setup_crldp(X509 *x)
441 setup_dp(x, sk_DIST_POINT_value(x->crldp, i)); 441 setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
442} 442}
443 443
444static int
445x509_extension_oid_cmp(const X509_EXTENSION *const *a,
446 const X509_EXTENSION *const *b)
447{
448 return OBJ_cmp((*a)->object, (*b)->object);
449}
450
451static int
452x509_extension_oids_are_unique(X509 *x509)
453{
454 STACK_OF(X509_EXTENSION) *exts = NULL;
455 const X509_EXTENSION *prev_ext, *curr_ext;
456 int i;
457 int ret = 0;
458
459 if (X509_get_ext_count(x509) <= 1)
460 goto done;
461
462 if ((exts = sk_X509_EXTENSION_dup(x509->cert_info->extensions)) == NULL)
463 goto err;
464
465 (void)sk_X509_EXTENSION_set_cmp_func(exts, x509_extension_oid_cmp);
466 sk_X509_EXTENSION_sort(exts);
467
468 prev_ext = sk_X509_EXTENSION_value(exts, 0);
469 for (i = 1; i < sk_X509_EXTENSION_num(exts); i++) {
470 curr_ext = sk_X509_EXTENSION_value(exts, i);
471 if (x509_extension_oid_cmp(&prev_ext, &curr_ext) == 0)
472 goto err;
473 prev_ext = curr_ext;
474 }
475
476 done:
477 ret = 1;
478
479 err:
480 sk_X509_EXTENSION_free(exts);
481
482 return ret;
483}
484
444static void 485static void
445x509v3_cache_extensions_internal(X509 *x) 486x509v3_cache_extensions_internal(X509 *x)
446{ 487{
@@ -612,6 +653,9 @@ x509v3_cache_extensions_internal(X509 *x)
612 } 653 }
613 } 654 }
614 655
656 if (!x509_extension_oids_are_unique(x))
657 x->ex_flags |= EXFLAG_INVALID;
658
615 x509_verify_cert_info_populate(x); 659 x509_verify_cert_info_populate(x);
616 660
617 x->ex_flags |= EXFLAG_SET; 661 x->ex_flags |= EXFLAG_SET;