summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjob <job@openbsd.org>2021-02-16 07:58:30 +0000
committerjob <job@openbsd.org>2021-02-16 07:58:30 +0000
commitebd5581623e41f42ead738fa0f7a54b09b976cc9 (patch)
tree9ab4ecdc55119cd951bec73eb35a5d5636afb93b
parentuse rtalloc_mpath in pf_route and pf_route6. (diff)
downloadwireguard-openbsd-ebd5581623e41f42ead738fa0f7a54b09b976cc9.tar.xz
wireguard-openbsd-ebd5581623e41f42ead738fa0f7a54b09b976cc9.zip
get Authority Information Access (AIA) from CA & EE certs
In the context of the RPKI, the AIA extension identifies the publication point of the certificate of the issuer of the certificate in which the extension appears. A single reference to the publication point of the immediate superior certificate MUST be present, except for a "self-signed" certificate. Thanks tb@ for review OK claudio@
-rw-r--r--usr.sbin/rpki-client/cert.c10
-rw-r--r--usr.sbin/rpki-client/extern.h18
-rw-r--r--usr.sbin/rpki-client/gbr.c6
-rw-r--r--usr.sbin/rpki-client/mft.c10
-rw-r--r--usr.sbin/rpki-client/roa.c10
-rw-r--r--usr.sbin/rpki-client/x509.c77
6 files changed, 101 insertions, 30 deletions
diff --git a/usr.sbin/rpki-client/cert.c b/usr.sbin/rpki-client/cert.c
index 130794eed28..6e3d7bf7a22 100644
--- a/usr.sbin/rpki-client/cert.c
+++ b/usr.sbin/rpki-client/cert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cert.c,v 1.25 2021/02/08 09:22:53 claudio Exp $ */
+/* $OpenBSD: cert.c,v 1.26 2021/02/16 07:58:30 job Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -1079,6 +1079,11 @@ cert_parse_inner(X509 **xp, const char *fn, int ta)
case NID_crl_distribution_points:
/* ignored here, handled later */
break;
+ case NID_info_access:
+ free(p.res->aia);
+ p.res->aia = x509_get_aia(x, p.fn);
+ c = (p.res->aia != NULL);
+ break;
case NID_authority_key_identifier:
free(p.res->aki);
p.res->aki = x509_get_aki_ext(ext, p.fn);
@@ -1223,6 +1228,7 @@ cert_free(struct cert *p)
free(p->notify);
free(p->ips);
free(p->as);
+ free(p->aia);
free(p->aki);
free(p->ski);
X509_free(p->x509);
@@ -1279,6 +1285,7 @@ cert_buffer(struct ibuf *b, const struct cert *p)
io_str_buffer(b, p->notify);
io_str_buffer(b, p->repo);
io_str_buffer(b, p->crl);
+ io_str_buffer(b, p->aia);
io_str_buffer(b, p->aki);
io_str_buffer(b, p->ski);
}
@@ -1347,6 +1354,7 @@ cert_read(int fd)
io_str_read(fd, &p->notify);
io_str_read(fd, &p->repo);
io_str_read(fd, &p->crl);
+ io_str_read(fd, &p->aia);
io_str_read(fd, &p->aki);
io_str_read(fd, &p->ski);
assert(p->ski);
diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h
index edd446e882a..9b17ee73212 100644
--- a/usr.sbin/rpki-client/extern.h
+++ b/usr.sbin/rpki-client/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.42 2021/02/08 09:22:53 claudio Exp $ */
+/* $OpenBSD: extern.h,v 1.43 2021/02/16 07:58:30 job Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -116,6 +116,7 @@ struct cert {
char *mft; /* manifest (rsync:// uri) */
char *notify; /* RRDP notify (https:// uri) */
char *crl; /* CRL location (rsync:// or NULL) */
+ char *aia; /* AIA (or NULL, for trust anchor) */
char *aki; /* AKI (or NULL, for trust anchor) */
char *ski; /* SKI */
int valid; /* validated resources */
@@ -155,8 +156,9 @@ struct mft {
struct mftfile *files; /* file and hash */
size_t filesz; /* number of filenames */
int stale; /* if a stale manifest */
- char *ski; /* SKI */
+ char *aia; /* AIA */
char *aki; /* AKI */
+ char *ski; /* SKI */
};
/*
@@ -181,8 +183,9 @@ struct roa {
struct roa_ip *ips; /* IP prefixes */
size_t ipsz; /* number of IP prefixes */
int valid; /* validated resources */
- char *ski; /* SKI */
+ char *aia; /* AIA */
char *aki; /* AKI */
+ char *ski; /* SKI */
char *tal; /* basename of TAL for this cert */
};
@@ -191,8 +194,9 @@ struct roa {
*/
struct gbr {
char *vcard;
- char *ski; /* SKI */
+ char *aia; /* AIA */
char *aki; /* AKI */
+ char *ski; /* SKI */
};
/*
@@ -248,7 +252,7 @@ struct auth *auth_find(struct auth_tree *, const char *);
/*
* Resource types specified by the RPKI profiles.
- * There are others (e.g., gbr) that we don't consider.
+ * There might be others we don't consider.
*/
enum rtype {
RTYPE_EOF = 0,
@@ -418,9 +422,11 @@ void io_str_read(int, char **);
/* X509 helpers. */
+char *x509_get_aia(X509 *, const char *);
char *x509_get_aki_ext(X509_EXTENSION *, const char *);
char *x509_get_ski_ext(X509_EXTENSION *, const char *);
-int x509_get_ski_aki(X509 *, const char *, char **, char **);
+int x509_get_extensions(X509 *, const char *, char **, char **,
+ char **);
char *x509_get_crl(X509 *, const char *);
char *x509_crl_get_aki(X509_CRL *);
diff --git a/usr.sbin/rpki-client/gbr.c b/usr.sbin/rpki-client/gbr.c
index 550f11e18ba..0d5e304b764 100644
--- a/usr.sbin/rpki-client/gbr.c
+++ b/usr.sbin/rpki-client/gbr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gbr.c,v 1.4 2021/02/04 08:58:19 claudio Exp $ */
+/* $OpenBSD: gbr.c,v 1.5 2021/02/16 07:58:30 job Exp $ */
/*
* Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
*
@@ -62,7 +62,8 @@ gbr_parse(X509 **x509, const char *fn)
err(1, NULL);
if ((p.res->vcard = strndup(cms, cmsz)) == NULL)
err(1, NULL);
- if (!x509_get_ski_aki(*x509, fn, &p.res->ski, &p.res->aki)) {
+ if (!x509_get_extensions(*x509, fn, &p.res->ski, &p.res->aki,
+ &p.res->aia)) {
gbr_free(p.res);
X509_free(*x509);
*x509 = NULL;
@@ -83,6 +84,7 @@ gbr_free(struct gbr *p)
if (p == NULL)
return;
+ free(p->aia);
free(p->aki);
free(p->ski);
free(p->vcard);
diff --git a/usr.sbin/rpki-client/mft.c b/usr.sbin/rpki-client/mft.c
index 6e357c3397f..de903b5d65a 100644
--- a/usr.sbin/rpki-client/mft.c
+++ b/usr.sbin/rpki-client/mft.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mft.c,v 1.25 2021/02/04 08:58:19 claudio Exp $ */
+/* $OpenBSD: mft.c,v 1.26 2021/02/16 07:58:30 job Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -395,7 +395,8 @@ mft_parse(X509 **x509, const char *fn)
err(1, NULL);
if ((p.res->file = strdup(fn)) == NULL)
err(1, NULL);
- if (!x509_get_ski_aki(*x509, fn, &p.res->ski, &p.res->aki))
+ if (!x509_get_extensions(*x509, fn, &p.res->ski, &p.res->aki,
+ &p.res->aia))
goto out;
/*
@@ -509,6 +510,7 @@ mft_free(struct mft *p)
for (i = 0; i < p->filesz; i++)
free(p->files[i].file);
+ free(p->aia);
free(p->aki);
free(p->ski);
free(p->file);
@@ -534,6 +536,7 @@ mft_buffer(struct ibuf *b, const struct mft *p)
io_simple_buffer(b, p->files[i].hash, SHA256_DIGEST_LENGTH);
}
+ io_str_buffer(b, p->aia);
io_str_buffer(b, p->aki);
io_str_buffer(b, p->ski);
}
@@ -564,9 +567,10 @@ mft_read(int fd)
io_simple_read(fd, p->files[i].hash, SHA256_DIGEST_LENGTH);
}
+ io_str_read(fd, &p->aia);
io_str_read(fd, &p->aki);
io_str_read(fd, &p->ski);
- assert(p->aki && p->ski);
+ assert(p->aia && p->aki && p->ski);
return p;
}
diff --git a/usr.sbin/rpki-client/roa.c b/usr.sbin/rpki-client/roa.c
index 0b9e61d5483..1ee9187e828 100644
--- a/usr.sbin/rpki-client/roa.c
+++ b/usr.sbin/rpki-client/roa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: roa.c,v 1.13 2021/02/04 08:58:19 claudio Exp $ */
+/* $OpenBSD: roa.c,v 1.14 2021/02/16 07:58:30 job Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -349,7 +349,8 @@ roa_parse(X509 **x509, const char *fn)
if ((p.res = calloc(1, sizeof(struct roa))) == NULL)
err(1, NULL);
- if (!x509_get_ski_aki(*x509, fn, &p.res->ski, &p.res->aki))
+ if (!x509_get_extensions(*x509, fn, &p.res->ski, &p.res->aki,
+ &p.res->aia))
goto out;
if (!roa_parse_econtent(cms, cmsz, &p))
goto out;
@@ -377,6 +378,7 @@ roa_free(struct roa *p)
if (p == NULL)
return;
+ free(p->aia);
free(p->aki);
free(p->ski);
free(p->ips);
@@ -405,6 +407,7 @@ roa_buffer(struct ibuf *b, const struct roa *p)
ip_addr_buffer(b, &p->ips[i].addr);
}
+ io_str_buffer(b, p->aia);
io_str_buffer(b, p->aki);
io_str_buffer(b, p->ski);
io_str_buffer(b, p->tal);
@@ -439,10 +442,11 @@ roa_read(int fd)
ip_addr_read(fd, &p->ips[i].addr);
}
+ io_str_read(fd, &p->aia);
io_str_read(fd, &p->aki);
io_str_read(fd, &p->ski);
io_str_read(fd, &p->tal);
- assert(p->aki && p->ski && p->tal);
+ assert(p->aia && p->aki && p->ski && p->tal);
return p;
}
diff --git a/usr.sbin/rpki-client/x509.c b/usr.sbin/rpki-client/x509.c
index d14a4ac5550..89a99e3ff14 100644
--- a/usr.sbin/rpki-client/x509.c
+++ b/usr.sbin/rpki-client/x509.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: x509.c,v 1.14 2020/09/12 15:46:48 claudio Exp $ */
+/* $OpenBSD: x509.c,v 1.15 2021/02/16 07:58:30 job Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -169,18 +169,66 @@ out:
}
/*
- * Wraps around x509_get_ski_ext and x509_get_aki_ext.
+ * Parse the Authority Information Access (AIA) extension
+ * See RFC 6487, section 4.8.7 for details.
+ * Returns NULL on failure, on success returns the AIA URI
+ * (which has to be freed after use).
+ */
+char *
+x509_get_aia(X509 *x, const char *fn)
+{
+ ACCESS_DESCRIPTION *ad;
+ AUTHORITY_INFO_ACCESS *info;
+ char *aia = NULL;
+
+ info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL);
+ if (info == NULL) {
+ warnx("%s: RFC 6487 section 4.8.7: AIA: extension missing", fn);
+ return NULL;
+ }
+ if (sk_ACCESS_DESCRIPTION_num(info) != 1) {
+ warnx("%s: RFC 6487 section 4.8.7: AIA: "
+ "want 1 element, have %d", fn,
+ sk_ACCESS_DESCRIPTION_num(info));
+ goto out;
+ }
+
+ ad = sk_ACCESS_DESCRIPTION_value(info, 0);
+ if (OBJ_obj2nid(ad->method) != NID_ad_ca_issuers) {
+ warnx("%s: RFC 6487 section 4.8.7: AIA: "
+ "expected caIssuers, have %d", fn, OBJ_obj2nid(ad->method));
+ goto out;
+ }
+ if (ad->location->type != GEN_URI) {
+ warnx("%s: RFC 6487 section 4.8.7: AIA: "
+ "want GEN_URI type, have %d", fn, ad->location->type);
+ goto out;
+ }
+
+ aia = strndup(
+ ASN1_STRING_get0_data(ad->location->d.uniformResourceIdentifier),
+ ASN1_STRING_length(ad->location->d.uniformResourceIdentifier));
+ if (aia == NULL)
+ err(1, NULL);
+
+out:
+ AUTHORITY_INFO_ACCESS_free(info);
+ return aia;
+}
+
+/*
+ * Wraps around x509_get_ski_ext, x509_get_aki_ext, and x509_get_aia.
* Returns zero on failure (out pointers are NULL) or non-zero on
* success (out pointers must be freed).
*/
int
-x509_get_ski_aki(X509 *x, const char *fn, char **ski, char **aki)
+x509_get_extensions(X509 *x, const char *fn, char **aia, char **aki, char **ski)
{
X509_EXTENSION *ext = NULL;
const ASN1_OBJECT *obj;
int extsz, i;
- *ski = *aki = NULL;
+ *aia = *aki = *ski = NULL;
if ((extsz = X509_get_ext_count(x)) < 0)
cryptoerrx("X509_get_ext_count");
@@ -199,21 +247,20 @@ x509_get_ski_aki(X509 *x, const char *fn, char **ski, char **aki)
free(*aki);
*aki = x509_get_aki_ext(ext, fn);
break;
+ case NID_info_access:
+ free(*aia);
+ *aia = x509_get_aia(x, fn);
+ break;
}
}
- if (*aki == NULL) {
- cryptowarnx("%s: RFC 6487 section 4.8.3: AKI: "
- "missing AKI X509 extension", fn);
- free(*ski);
- *ski = NULL;
- return 0;
- }
- if (*ski == NULL) {
- cryptowarnx("%s: RFC 6487 section 4.8.2: AKI: "
- "missing SKI X509 extension", fn);
+ if (*aia == NULL || *aki == NULL || *ski == NULL) {
+ cryptowarnx("%s: RFC 6487 section 4.8: "
+ "missing AIA, AKI or SKI X509 extension", fn);
+ free(*aia);
free(*aki);
- *aki = NULL;
+ free(*ski);
+ *aia = *aki = *ski = NULL;
return 0;
}