From: Theo Buehler Subject: rpki-client: add an AIA handler for all certs To: tech@openbsd.org Date: Mon, 30 Jun 2025 09:56:32 +0200 Here's a replacement for x509_get_aia(). This is quite similar to the SIA handling we already have in cert.c - I have tried to deduplicate the SIA and AIA handlers, but it's not entirely trivial to do this nicely, so I left it straightforward and dumb. Our x509_get_aia() is slightly incorrect in that it only accepts a single accessMethod. cert_aia() fixes this and like cert_sia() it will use the first rsync method it encounter;. Of course, this will only really be fixed once I remove x509_get_aia() later. I haven't hooked this into cert_parse_ee_cert() yet since that will happen for free after a few more steps. diff --git a/usr.sbin/rpki-client/cert.c b/usr.sbin/rpki-client/cert.c index 5239080306b..451d9114c60 100644 --- a/usr.sbin/rpki-client/cert.c +++ b/usr.sbin/rpki-client/cert.c @@ -31,6 +31,7 @@ #include "extern.h" extern ASN1_OBJECT *bgpsec_oid; /* id-kp-bgpsec-router Key Purpose */ +extern ASN1_OBJECT *caissuers_oid; /* 1.3.6.1.5.5.7.48.2 (caIssuers) */ extern ASN1_OBJECT *certpol_oid; /* id-cp-ipAddr-asNumber cert policy */ extern ASN1_OBJECT *carepo_oid; /* 1.3.6.1.5.5.7.48.5 (caRepository) */ extern ASN1_OBJECT *manifest_oid; /* 1.3.6.1.5.5.7.48.10 (rpkiManifest) */ @@ -500,6 +501,86 @@ sbgp_ipaddrblk(const char *fn, struct cert *cert, X509_EXTENSION *ext) return rc; } +/* + * Parse "Authority Information Access" extension for non-TA certs, + * RFC 6487, section 4.8.7. + * Returns zero on failure, non-zero on success. + */ +static int +cert_aia(const char *fn, struct cert *cert, X509_EXTENSION *ext) +{ + AUTHORITY_INFO_ACCESS *aia = NULL; + ACCESS_DESCRIPTION *ad; + ASN1_OBJECT *oid; + char *caissuers = NULL; + int i, rc = 0; + + assert(cert->aia == NULL); + + if (cert->purpose == CERT_PURPOSE_TA) { + warnx("%s: RFC 6487 section 4.8.7: AIA must be absent from " + "a self-signed certificate", fn); + goto out; + } + + if (X509_EXTENSION_get_critical(ext)) { + warnx("%s: RFC 6487 section 4.8.7: SIA: " + "extension not non-critical", fn); + goto out; + } + + if ((aia = X509V3_EXT_d2i(ext)) == NULL) { + warnx("%s: RFC 6487 section 4.8.7: SIA: failed extension parse", + fn); + goto out; + } + + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(aia); i++) { + ad = sk_ACCESS_DESCRIPTION_value(aia, i); + + oid = ad->method; + + if (OBJ_cmp(oid, caissuers_oid) == 0) { + if (!x509_location(fn, "AIA: caIssuers", ad->location, + &caissuers)) + goto out; + if (cert->aia == NULL && strncasecmp(caissuers, + RSYNC_PROTO, RSYNC_PROTO_LEN) == 0) { + cert->aia = caissuers; + caissuers = NULL; + continue; + } + /* + * XXX - unclear how to check "Other accessMethod URIs + * referencing the same object MAY be included". + */ + if (verbose) + warnx("%s: RFC 6487 section 4.8.7: AIA: " + "ignoring location %s", fn, caissuers); + free(caissuers); + caissuers = NULL; + } else { + char buf[128]; + + OBJ_obj2txt(buf, sizeof(buf), oid, 0); + warnx("%s: RFC 6487 section 4.8.7: unexpected" + " accessMethod: %s", fn, buf); + goto out; + } + } + + if (cert->aia == NULL) { + warnx("%s: RFC 6487 section 4.8.7: AIA: expected caIssuers " + "accessMethod with rsync protocol", fn); + goto out; + } + + rc = 1; + out: + AUTHORITY_INFO_ACCESS_free(aia); + return rc; +} + /* * Parse "Subject Information Access" extension for a CA cert, * RFC 6487, section 4.8.8.1 and RFC 8182, section 3.2. @@ -1200,6 +1281,8 @@ cert_parse_pre(const char *fn, const unsigned char *der, size_t len) case NID_info_access: if (aia++ > 0) goto dup; + if (!cert_aia(fn, cert, ext)) + goto out; break; case NID_sinfo_access: if (sia++ > 0) @@ -1247,8 +1330,6 @@ cert_parse_pre(const char *fn, const unsigned char *der, size_t len) goto out; if (!x509_get_ski(x, fn, &cert->ski)) goto out; - if (!x509_get_aia(x, fn, &cert->aia)) - goto out; if (!x509_get_crl(x, fn, &cert->crl)) goto out; if (!x509_get_notbefore(x, fn, &cert->notbefore)) diff --git a/usr.sbin/rpki-client/x509.c b/usr.sbin/rpki-client/x509.c index c58b0fed2f7..b9ca11db25a 100644 --- a/usr.sbin/rpki-client/x509.c +++ b/usr.sbin/rpki-client/x509.c @@ -29,6 +29,7 @@ #include "extern.h" ASN1_OBJECT *certpol_oid; /* id-cp-ipAddr-asNumber cert policy */ +ASN1_OBJECT *caissuers_oid; /* 1.3.6.1.5.5.7.48.2 (caIssuers) */ ASN1_OBJECT *carepo_oid; /* 1.3.6.1.5.5.7.48.5 (caRepository) */ ASN1_OBJECT *manifest_oid; /* 1.3.6.1.5.5.7.48.10 (rpkiManifest) */ ASN1_OBJECT *signedobj_oid; /* 1.3.6.1.5.5.7.48.11 (signedObject) */ @@ -54,6 +55,10 @@ static const struct { .oid = "1.3.6.1.5.5.7.14.2", .ptr = &certpol_oid, }, + { + .oid = "1.3.6.1.5.5.7.48.2", + .ptr = &caissuers_oid, + }, { .oid = "1.3.6.1.5.5.7.48.5", .ptr = &carepo_oid,