Download raw body.
rpki-client: fix BGPsec router EKU handling
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:
rpki-client: fix BGPsec router EKU handling