From 33e36affb48d3c88db1b4e58c5040ead002ef0e1 Mon Sep 17 00:00:00 2001 From: tb Date: Tue, 12 Apr 2022 08:45:34 +0000 Subject: [PATCH] Generalize sbgp_sia_location() to x509_location() AIA and CRL URIs can reuse the code in sbgp_sia_location and thus get the same checks as the SIA locations. This eliminates some more duplication and makes the checks more stringent in that embedded NULs and "./" are no longer allowed. ok claudio --- usr.sbin/rpki-client/cert.c | 42 +++------------------- usr.sbin/rpki-client/extern.h | 5 ++- usr.sbin/rpki-client/x509.c | 68 +++++++++++++++++++---------------- 3 files changed, 45 insertions(+), 70 deletions(-) diff --git a/usr.sbin/rpki-client/cert.c b/usr.sbin/rpki-client/cert.c index 0254d669b96..2eb1601fb25 100644 --- a/usr.sbin/rpki-client/cert.c +++ b/usr.sbin/rpki-client/cert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cert.c,v 1.66 2022/04/11 10:39:45 tb Exp $ */ +/* $OpenBSD: cert.c,v 1.67 2022/04/12 08:45:34 tb Exp $ */ /* * Copyright (c) 2021 Job Snijders * Copyright (c) 2019 Kristaps Dzonsons @@ -124,40 +124,6 @@ sbgp_addr(struct parse *p, return append_ip(p, ip); } -/* - * Extract and validate a SIA accessLocation, RFC 6487, 4.8.8 and RFC 8192, 3.2. - * Returns 0 on failure and 1 on success. - */ -static int -sbgp_sia_location(const char *fn, const char *descr, const char *proto, - GENERAL_NAME *location, char **out) -{ - ASN1_IA5STRING *uri; - - if (*out != NULL) { - warnx("%s: RFC 6487 section 4.8.8: SIA: %s already specified", - fn, descr); - return 0; - } - - if (location->type != GEN_URI) { - warnx("%s: RFC 6487 section 4.8.8: SIA: %s not URI", fn, descr); - return 0; - } - - uri = location->d.uniformResourceIdentifier; - - if (!valid_uri(uri->data, uri->length, proto)) { - warnx("%s: RFC 6487 section 4.8.8: bad %s location", fn, descr); - return 0; - } - - if ((*out = strndup(uri->data, uri->length)) == NULL) - err(1, NULL); - - return 1; -} - /* * Parse "Subject Information Access" extension, RFC 6487 4.8.8. * Returns zero on failure, non-zero on success. @@ -188,15 +154,15 @@ sbgp_sia(struct parse *p, X509_EXTENSION *ext) oid = ad->method; if (OBJ_cmp(oid, carepo_oid) == 0) { - if (!sbgp_sia_location(p->fn, "caRepository", + if (!x509_location(p->fn, "SIA: caRepository", "rsync://", ad->location, &p->res->repo)) goto out; } else if (OBJ_cmp(oid, manifest_oid) == 0) { - if (!sbgp_sia_location(p->fn, "rpkiManifest", + if (!x509_location(p->fn, "SIA: rpkiManifest", "rsync://", ad->location, &p->res->mft)) goto out; } else if (OBJ_cmp(oid, notify_oid) == 0) { - if (!sbgp_sia_location(p->fn, "rpkiNotify", + if (!x509_location(p->fn, "SIA: rpkiNotify", "https://", ad->location, &p->res->notify)) goto out; } diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h index ac72ace9b39..13cfc262868 100644 --- a/usr.sbin/rpki-client/extern.h +++ b/usr.sbin/rpki-client/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.125 2022/04/04 16:02:54 claudio Exp $ */ +/* $OpenBSD: extern.h,v 1.126 2022/04/12 08:45:34 tb Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -22,6 +22,7 @@ #include #include +#include enum cert_as_type { CERT_AS_ID, /* single identifier */ @@ -589,6 +590,8 @@ char *x509_get_pubkey(X509 *, const char *); enum cert_purpose x509_get_purpose(X509 *, const char *); int x509_get_time(const ASN1_TIME *, time_t *); char *x509_convert_seqnum(const char *, const ASN1_INTEGER *); +int x509_location(const char *, const char *, const char *, + GENERAL_NAME *, char **); /* printers */ char *time2str(time_t); diff --git a/usr.sbin/rpki-client/x509.c b/usr.sbin/rpki-client/x509.c index c7d82354df4..3c162c0bab6 100644 --- a/usr.sbin/rpki-client/x509.c +++ b/usr.sbin/rpki-client/x509.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x509.c,v 1.39 2022/04/08 15:29:59 claudio Exp $ */ +/* $OpenBSD: x509.c,v 1.40 2022/04/12 08:45:34 tb Exp $ */ /* * Copyright (c) 2021 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -306,24 +306,10 @@ x509_get_aia(X509 *x, const char *fn, char **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; - } - if (ASN1_STRING_length(ad->location->d.uniformResourceIdentifier) - > MAX_URI_LENGTH) { - warnx("%s: RFC 6487 section 4.8.7: AIA: " - "URI exceeds max length of %d", fn, MAX_URI_LENGTH); + if (!x509_location(fn, "AIA: caIssuers", NULL, ad->location, aia)) 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); rc = 1; out: @@ -405,23 +391,9 @@ x509_get_crl(X509 *x, const char *fn, char **crl) } name = sk_GENERAL_NAME_value(dp->distpoint->name.fullname, 0); - if (name->type != GEN_URI) { - warnx("%s: RFC 6487 section 4.8.6: CRL: " - "want URI type, have %d", fn, name->type); - goto out; - } - if (ASN1_STRING_length(name->d.uniformResourceIdentifier) - > MAX_URI_LENGTH) { - warnx("%s: RFC 6487 section 4.8.6: CRL: " - "URI exceeds max length of %d", fn, MAX_URI_LENGTH); + if (!x509_location(fn, "CRL distribution point", NULL, name, crl)) goto out; - } - - *crl = strndup(ASN1_STRING_get0_data(name->d.uniformResourceIdentifier), - ASN1_STRING_length(name->d.uniformResourceIdentifier)); - if (*crl == NULL) - err(1, NULL); rc = 1; out: @@ -503,6 +475,40 @@ x509_get_time(const ASN1_TIME *at, time_t *t) return 1; } +/* + * Extract and validate an accessLocation, RFC 6487, 4.8 and RFC 8192, 3.2. + * Returns 0 on failure and 1 on success. + */ +int +x509_location(const char *fn, const char *descr, const char *proto, + GENERAL_NAME *location, char **out) +{ + ASN1_IA5STRING *uri; + + if (*out != NULL) { + warnx("%s: RFC 6487 section 4.8: %s already specified", fn, + descr); + return 0; + } + + if (location->type != GEN_URI) { + warnx("%s: RFC 6487 section 4.8: %s not URI", fn, descr); + return 0; + } + + uri = location->d.uniformResourceIdentifier; + + if (!valid_uri(uri->data, uri->length, proto)) { + warnx("%s: RFC 6487 section 4.8: %s bad location", fn, descr); + return 0; + } + + if ((*out = strndup(uri->data, uri->length)) == NULL) + err(1, NULL); + + return 1; +} + /* * Convert an ASN1_INTEGER into a hexstring. * Returned string needs to be freed by the caller. -- 2.20.1