From: Theo Buehler Subject: rpki-client: fix BGPsec router EKU handling To: tech@openbsd.org Date: Sat, 8 Jun 2024 20:05:00 +0200 The semantics of EKU is that we need to find the purpose we're looking for, and not care about the others. There are legitimate reasons for allowing other EKUs. The lot of the 3 BGPsec certs out there are still recognized with this diff since all of them only have a single keyPurposeId. Index: x509.c =================================================================== RCS file: /cvs/src/usr.sbin/rpki-client/x509.c,v diff -u -p -r1.97 x509.c --- x509.c 8 Jun 2024 13:32:30 -0000 1.97 +++ x509.c 8 Jun 2024 17:52:45 -0000 @@ -275,7 +275,7 @@ x509_get_purpose(X509 *x, const char *fn { BASIC_CONSTRAINTS *bc = NULL; EXTENDED_KEY_USAGE *eku = NULL; - int crit, ext_flags, is_ca; + int crit, ext_flags, i, is_ca; enum cert_purpose purpose = CERT_PURPOSE_INVALID; if (!x509_cache_extensions(x, fn)) @@ -353,20 +353,15 @@ x509_get_purpose(X509 *x, const char *fn } /* - * XXX - this isn't quite correct: other EKU OIDs are allowed per - * RFC 8209, section 3.1.3.2, e.g., anyEKU could potentially help - * avoid tripping up validators that don't know about the BGPsec - * router purpose. Drop check or downgrade from error to warning? + * Per RFC 8209, section 3.1.3.2 the id-kp-bgpsec-router OID must be + * present and others are allowed, which we need not recognize. This + * matches RFC 5280, section 4.2.1.12. */ - if (sk_ASN1_OBJECT_num(eku) != 1) { - warnx("%s: EKU: expected 1 purpose, have %d", fn, - sk_ASN1_OBJECT_num(eku)); - goto out; - } - - if (OBJ_cmp(bgpsec_oid, sk_ASN1_OBJECT_value(eku, 0)) == 0) { - purpose = CERT_PURPOSE_BGPSEC_ROUTER; - goto out; + for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) { + if (OBJ_cmp(bgpsec_oid, sk_ASN1_OBJECT_value(eku, i)) == 0) { + purpose = CERT_PURPOSE_BGPSEC_ROUTER; + break; + } } out: