Download raw body.
rpki-client: add an AIA handler for all certs
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,
rpki-client: add an AIA handler for all certs