summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJob Snijders <job@cvs.openbsd.org>2022-11-04 09:43:14 +0000
committerJob Snijders <job@cvs.openbsd.org>2022-11-04 09:43:14 +0000
commit663972c47aa61292de03a32b2ad8390ac5e00eca (patch)
tree9a318dd93a8ef80962691b218b6d61edc6e97815
parent7d5ffd488437dd0b1bbc4e51c7141e73840c6635 (diff)
Check the SIA signedObject in ROA/MFT/ASPA/TAK/GBR EE certificates
Unfortunately we can't yet error out when accessMethods other than signedObject are encountered in the SubjectInformationAccess extension because there is pollution in the ecosystem. OK tb@
-rw-r--r--usr.sbin/rpki-client/aspa.c10
-rw-r--r--usr.sbin/rpki-client/extern.h8
-rw-r--r--usr.sbin/rpki-client/gbr.c10
-rw-r--r--usr.sbin/rpki-client/mft.c10
-rw-r--r--usr.sbin/rpki-client/print.c13
-rw-r--r--usr.sbin/rpki-client/roa.c10
-rw-r--r--usr.sbin/rpki-client/tak.c9
-rw-r--r--usr.sbin/rpki-client/x509.c56
8 files changed, 108 insertions, 18 deletions
diff --git a/usr.sbin/rpki-client/aspa.c b/usr.sbin/rpki-client/aspa.c
index 5ed3d9a8324..aab730b8ce4 100644
--- a/usr.sbin/rpki-client/aspa.c
+++ b/usr.sbin/rpki-client/aspa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aspa.c,v 1.6 2022/11/02 10:04:41 tb Exp $ */
+/* $OpenBSD: aspa.c,v 1.7 2022/11/04 09:43:13 job Exp $ */
/*
* Copyright (c) 2022 Job Snijders <job@fastly.com>
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
@@ -207,11 +207,14 @@ aspa_parse(X509 **x509, const char *fn, const unsigned char *der, size_t len)
goto out;
if (!x509_get_aki(*x509, fn, &p.res->aki))
goto out;
+ if (!x509_get_sia(*x509, fn, &p.res->sia))
+ goto out;
if (!x509_get_ski(*x509, fn, &p.res->ski))
goto out;
- if (p.res->aia == NULL || p.res->aki == NULL || p.res->ski == NULL) {
+ if (p.res->aia == NULL || p.res->aki == NULL || p.res->sia == NULL ||
+ p.res->ski == NULL) {
warnx("%s: RFC 6487 section 4.8: "
- "missing AIA, AKI or SKI X509 extension", fn);
+ "missing AIA, AKI, SIA, or SKI X509 extension", fn);
goto out;
}
@@ -268,6 +271,7 @@ aspa_free(struct aspa *p)
free(p->aia);
free(p->aki);
+ free(p->sia);
free(p->ski);
free(p->providers);
free(p);
diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h
index 96d0025596d..022544841bc 100644
--- a/usr.sbin/rpki-client/extern.h
+++ b/usr.sbin/rpki-client/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.157 2022/11/02 12:43:02 job Exp $ */
+/* $OpenBSD: extern.h,v 1.158 2022/11/04 09:43:13 job Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -213,6 +213,7 @@ struct mft {
char *seqnum; /* manifestNumber */
char *aia; /* AIA */
char *aki; /* AKI */
+ char *sia; /* SIA signedObject */
char *ski; /* SKI */
char *crl; /* CRL file name */
unsigned char crlhash[SHA256_DIGEST_LENGTH];
@@ -248,6 +249,7 @@ struct roa {
int valid; /* validated resources */
char *aia; /* AIA */
char *aki; /* AKI */
+ char *sia; /* SIA signedObject */
char *ski; /* SKI */
time_t expires; /* do not use after */
};
@@ -298,6 +300,7 @@ struct tak {
struct takey *successor;
char *aia; /* AIA */
char *aki; /* AKI */
+ char *sia; /* SIA signed Object */
char *ski; /* SKI */
time_t expires; /* Not After of the TAK EE */
};
@@ -309,6 +312,7 @@ struct gbr {
char *vcard;
char *aia; /* AIA */
char *aki; /* AKI */
+ char *sia; /* SIA signedObject */
char *ski; /* SKI */
};
@@ -325,6 +329,7 @@ struct aspa {
int talid; /* TAL the ASPA is chained up to */
char *aia; /* AIA */
char *aki; /* AKI */
+ char *sia; /* SIA signedObject */
char *ski; /* SKI */
uint32_t custasid; /* the customerASID */
struct aspa_provider *providers; /* the providers */
@@ -737,6 +742,7 @@ struct ibuf *io_buf_recvfd(int, struct ibuf **);
void x509_init_oid(void);
int x509_get_aia(X509 *, const char *, char **);
int x509_get_aki(X509 *, const char *, char **);
+int x509_get_sia(X509 *, const char *, char **);
int x509_get_ski(X509 *, const char *, char **);
int x509_get_expire(X509 *, const char *, time_t *);
int x509_get_crl(X509 *, const char *, char **);
diff --git a/usr.sbin/rpki-client/gbr.c b/usr.sbin/rpki-client/gbr.c
index db0616fc89c..5cce58552ce 100644
--- a/usr.sbin/rpki-client/gbr.c
+++ b/usr.sbin/rpki-client/gbr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gbr.c,v 1.16 2022/05/11 21:19:06 job Exp $ */
+/* $OpenBSD: gbr.c,v 1.17 2022/11/04 09:43:13 job Exp $ */
/*
* Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
*
@@ -67,11 +67,14 @@ gbr_parse(X509 **x509, const char *fn, const unsigned char *der, size_t len)
goto out;
if (!x509_get_aki(*x509, fn, &p.res->aki))
goto out;
+ if (!x509_get_sia(*x509, fn, &p.res->sia))
+ goto out;
if (!x509_get_ski(*x509, fn, &p.res->ski))
goto out;
- if (p.res->aia == NULL || p.res->aki == NULL || p.res->ski == NULL) {
+ if (p.res->aia == NULL || p.res->aki == NULL || p.res->sia == NULL ||
+ p.res->ski == NULL) {
warnx("%s: RFC 6487 section 4.8: "
- "missing AIA, AKI or SKI X509 extension", fn);
+ "missing AIA, AKI, SIA or SKI X509 extension", fn);
goto out;
}
@@ -101,6 +104,7 @@ gbr_free(struct gbr *p)
return;
free(p->aia);
free(p->aki);
+ free(p->sia);
free(p->ski);
free(p->vcard);
free(p);
diff --git a/usr.sbin/rpki-client/mft.c b/usr.sbin/rpki-client/mft.c
index 7fde67f823f..b86775e7705 100644
--- a/usr.sbin/rpki-client/mft.c
+++ b/usr.sbin/rpki-client/mft.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mft.c,v 1.76 2022/11/02 12:43:02 job Exp $ */
+/* $OpenBSD: mft.c,v 1.77 2022/11/04 09:43:13 job Exp $ */
/*
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -368,11 +368,14 @@ mft_parse(X509 **x509, const char *fn, const unsigned char *der, size_t len)
goto out;
if (!x509_get_aki(*x509, fn, &p.res->aki))
goto out;
+ if (!x509_get_sia(*x509, fn, &p.res->sia))
+ goto out;
if (!x509_get_ski(*x509, fn, &p.res->ski))
goto out;
- if (p.res->aia == NULL || p.res->aki == NULL || p.res->ski == NULL) {
+ if (p.res->aia == NULL || p.res->aki == NULL || p.res->sia == NULL ||
+ p.res->ski == NULL) {
warnx("%s: RFC 6487 section 4.8: "
- "missing AIA, AKI or SKI X509 extension", fn);
+ "missing AIA, AKI, SIA, or SKI X509 extension", fn);
goto out;
}
@@ -433,6 +436,7 @@ mft_free(struct mft *p)
free(p->aia);
free(p->aki);
+ free(p->sia);
free(p->ski);
free(p->path);
free(p->files);
diff --git a/usr.sbin/rpki-client/print.c b/usr.sbin/rpki-client/print.c
index b56bd99d02f..e38411ad705 100644
--- a/usr.sbin/rpki-client/print.c
+++ b/usr.sbin/rpki-client/print.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: print.c,v 1.17 2022/11/02 12:43:02 job Exp $ */
+/* $OpenBSD: print.c,v 1.18 2022/11/04 09:43:13 job Exp $ */
/*
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -337,6 +337,7 @@ mft_print(const X509 *x, const struct mft *p)
x509_print(x);
printf("\t\"aki\": \"%s\",\n", pretty_key_id(p->aki));
printf("\t\"aia\": \"%s\",\n", p->aia);
+ printf("\t\"sia\": \"%s\",\n", p->sia);
printf("\t\"manifest_number\": \"%s\",\n", p->seqnum);
printf("\t\"valid_since\": %lld,\n", (long long)p->valid_since);
printf("\t\"valid_until\": %lld,\n", (long long)p->valid_until);
@@ -345,6 +346,7 @@ mft_print(const X509 *x, const struct mft *p)
printf("Authority key identifier: %s\n", pretty_key_id(p->aki));
x509_print(x);
printf("Authority info access: %s\n", p->aia);
+ printf("Subject info access: %s\n", p->sia);
printf("Manifest Number: %s\n", p->seqnum);
printf("Manifest valid since: %s\n", time2str(p->valid_since));
printf("Manifest valid until: %s\n", time2str(p->valid_until));
@@ -388,14 +390,17 @@ roa_print(const X509 *x, const struct roa *p)
x509_print(x);
printf("\t\"aki\": \"%s\",\n", pretty_key_id(p->aki));
printf("\t\"aia\": \"%s\",\n", p->aia);
+ printf("\t\"sia\": \"%s\",\n", p->sia);
printf("\t\"valid_until\": %lld,\n", (long long)p->expires);
} else {
printf("Subject key identifier: %s\n", pretty_key_id(p->ski));
x509_print(x);
printf("Authority key identifier: %s\n", pretty_key_id(p->aki));
printf("Authority info access: %s\n", p->aia);
+ printf("Subject info access: %s\n", p->sia);
printf("ROA valid until: %s\n", time2str(p->expires));
printf("asID: %u\n", p->asid);
+ printf("IP address blocks:\n");
}
for (i = 0; i < p->ipsz; i++) {
@@ -432,6 +437,7 @@ gbr_print(const X509 *x, const struct gbr *p)
x509_print(x);
printf("\t\"aki\": \"%s\",\n", pretty_key_id(p->aki));
printf("\t\"aia\": \"%s\",\n", p->aia);
+ printf("\t\"sia\": \"%s\",\n", p->sia);
printf("\t\"vcard\": \"");
for (i = 0; i < strlen(p->vcard); i++) {
if (p->vcard[i] == '"')
@@ -449,6 +455,7 @@ gbr_print(const X509 *x, const struct gbr *p)
x509_print(x);
printf("Authority key identifier: %s\n", pretty_key_id(p->aki));
printf("Authority info access: %s\n", p->aia);
+ printf("Subject info access: %s\n", p->sia);
printf("vcard:\n%s", p->vcard);
}
}
@@ -580,6 +587,7 @@ aspa_print(const X509 *x, const struct aspa *p)
x509_print(x);
printf("\t\"aki\": \"%s\",\n", pretty_key_id(p->aki));
printf("\t\"aia\": \"%s\",\n", p->aia);
+ printf("\t\"sia\": \"%s\",\n", p->sia);
printf("\t\"customer_asid\": %u,\n", p->custasid);
printf("\t\"provider_set\": [\n");
for (i = 0; i < p->providersz; i++) {
@@ -599,6 +607,7 @@ aspa_print(const X509 *x, const struct aspa *p)
x509_print(x);
printf("Authority key identifier: %s\n", pretty_key_id(p->aki));
printf("Authority info access: %s\n", p->aia);
+ printf("Subject info access: %s\n", p->sia);
printf("Customer AS: %u\n", p->custasid);
printf("Provider Set:\n");
for (i = 0; i < p->providersz; i++) {
@@ -681,6 +690,7 @@ tak_print(const X509 *x, const struct tak *p)
x509_print(x);
printf("\t\"aki\": \"%s\",\n", pretty_key_id(p->aki));
printf("\t\"aia\": \"%s\",\n", p->aia);
+ printf("\t\"sia\": \"%s\",\n", p->sia);
printf("\t\"valid_until\": %lld,\n", (long long)p->expires);
printf("\t\"takeys\": [\n");
} else {
@@ -689,6 +699,7 @@ tak_print(const X509 *x, const struct tak *p)
x509_print(x);
printf("Authority key identifier: %s\n", pretty_key_id(p->aki));
printf("Authority info access: %s\n", p->aia);
+ printf("Subject info access: %s\n", p->sia);
printf("TAK EE certificate valid until: %s\n", tbuf);
}
diff --git a/usr.sbin/rpki-client/roa.c b/usr.sbin/rpki-client/roa.c
index 982ab600cdd..4a40126531d 100644
--- a/usr.sbin/rpki-client/roa.c
+++ b/usr.sbin/rpki-client/roa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: roa.c,v 1.54 2022/11/02 10:04:41 tb Exp $ */
+/* $OpenBSD: roa.c,v 1.55 2022/11/04 09:43:13 job Exp $ */
/*
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -222,11 +222,14 @@ roa_parse(X509 **x509, const char *fn, const unsigned char *der, size_t len)
goto out;
if (!x509_get_aki(*x509, fn, &p.res->aki))
goto out;
+ if (!x509_get_sia(*x509, fn, &p.res->sia))
+ goto out;
if (!x509_get_ski(*x509, fn, &p.res->ski))
goto out;
- if (p.res->aia == NULL || p.res->aki == NULL || p.res->ski == NULL) {
+ if (p.res->aia == NULL || p.res->aki == NULL || p.res->sia == NULL ||
+ p.res->ski == NULL) {
warnx("%s: RFC 6487 section 4.8: "
- "missing AIA, AKI or SKI X509 extension", fn);
+ "missing AIA, AKI, SIA, or SKI X509 extension", fn);
goto out;
}
@@ -287,6 +290,7 @@ roa_free(struct roa *p)
return;
free(p->aia);
free(p->aki);
+ free(p->sia);
free(p->ski);
free(p->ips);
free(p);
diff --git a/usr.sbin/rpki-client/tak.c b/usr.sbin/rpki-client/tak.c
index d621acac31e..cd1f643fc2b 100644
--- a/usr.sbin/rpki-client/tak.c
+++ b/usr.sbin/rpki-client/tak.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tak.c,v 1.1 2022/11/02 12:43:02 job Exp $ */
+/* $OpenBSD: tak.c,v 1.2 2022/11/04 09:43:13 job Exp $ */
/*
* Copyright (c) 2022 Job Snijders <job@fastly.com>
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
@@ -247,11 +247,14 @@ tak_parse(X509 **x509, const char *fn, const unsigned char *der, size_t len)
goto out;
if (!x509_get_aki(*x509, fn, &p.res->aki))
goto out;
+ if (!x509_get_sia(*x509, fn, &p.res->sia))
+ goto out;
if (!x509_get_ski(*x509, fn, &p.res->ski))
goto out;
- if (p.res->aia == NULL || p.res->aki == NULL || p.res->ski == NULL) {
+ if (p.res->aia == NULL || p.res->aki == NULL || p.res->sia == NULL ||
+ p.res->ski == NULL) {
warnx("%s: RFC 6487 section 4.8: "
- "missing AIA, AKI or SKI X509 extension", fn);
+ "missing AIA, AKI, SIA, or SKI X509 extension", fn);
goto out;
}
diff --git a/usr.sbin/rpki-client/x509.c b/usr.sbin/rpki-client/x509.c
index 7ebf9e8e529..efa9d691a38 100644
--- a/usr.sbin/rpki-client/x509.c
+++ b/usr.sbin/rpki-client/x509.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: x509.c,v 1.53 2022/11/02 12:43:02 job Exp $ */
+/* $OpenBSD: x509.c,v 1.54 2022/11/04 09:43:13 job Exp $ */
/*
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
@@ -34,6 +34,7 @@
ASN1_OBJECT *certpol_oid; /* id-cp-ipAddr-asNumber cert policy */
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) */
ASN1_OBJECT *notify_oid; /* 1.3.6.1.5.5.7.48.13 (rpkiNotify) */
ASN1_OBJECT *roa_oid; /* id-ct-routeOriginAuthz CMS content type */
ASN1_OBJECT *mft_oid; /* id-ct-rpkiManifest CMS content type */
@@ -64,6 +65,10 @@ static const struct {
.ptr = &manifest_oid,
},
{
+ .oid = "1.3.6.1.5.5.7.48.11",
+ .ptr = &signedobj_oid,
+ },
+ {
.oid = "1.3.6.1.5.5.7.48.13",
.ptr = &notify_oid,
},
@@ -370,6 +375,55 @@ out:
}
/*
+ * Parse the Subject Information Access (SIA) extension
+ * See RFC 6487, section 4.8.8 for details.
+ * Returns NULL on failure, on success returns the SIA signedObject URI
+ * (which has to be freed after use).
+ */
+int
+x509_get_sia(X509 *x, const char *fn, char **sia)
+{
+ ACCESS_DESCRIPTION *ad;
+ AUTHORITY_INFO_ACCESS *info;
+ ASN1_OBJECT *oid;
+ int i, crit, rc = 0;
+
+ *sia = NULL;
+
+ info = X509_get_ext_d2i(x, NID_sinfo_access, &crit, NULL);
+ if (info == NULL)
+ return 1;
+
+ if (crit != 0) {
+ warnx("%s: RFC 6487 section 4.8.8: "
+ "SIA: extension not non-critical", fn);
+ goto out;
+ }
+
+ /*
+ * RFC 6487 4.8.8.2 disallows other accessMethods, however they
+ * do exist in the wild.
+ */
+ for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
+ ad = sk_ACCESS_DESCRIPTION_value(info, i);
+ oid = ad->method;
+
+ if (OBJ_cmp(oid, signedobj_oid) != 0)
+ continue;
+
+ /* XXX: correctly deal with other (non-rsync) protocols. */
+ if (!x509_location(fn, "SIA: signedObject", "rsync://",
+ ad->location, sia))
+ goto out;
+ }
+
+ rc = 1;
+ out:
+ AUTHORITY_INFO_ACCESS_free(info);
+ return rc;
+}
+
+/*
* Extract the expire time (not-after) of a certificate.
*/
int