Generalize sbgp_sia_location() to x509_location()
authortb <tb@openbsd.org>
Tue, 12 Apr 2022 08:45:34 +0000 (08:45 +0000)
committertb <tb@openbsd.org>
Tue, 12 Apr 2022 08:45:34 +0000 (08:45 +0000)
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
usr.sbin/rpki-client/extern.h
usr.sbin/rpki-client/x509.c

index 0254d66..2eb1601 100644 (file)
@@ -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 <job@openbsd.org>
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -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;
                }
index ac72ace..13cfc26 100644 (file)
@@ -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 <kristaps@bsd.lv>
  *
@@ -22,6 +22,7 @@
 #include <sys/time.h>
 
 #include <openssl/x509.h>
+#include <openssl/x509v3.h>
 
 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);
index c7d8235..3c162c0 100644 (file)
@@ -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 <claudio@openbsd.org>
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -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.