Hi all,

RFC 6487 section 4.8.8.2 mandates that the SIA extension must be
present, and contain *at least* an instance of accessMethod
id-ad-signedObject. The below changeset enforces this requirement.

OK?

Index: aspa.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/aspa.c,v
retrieving revision 1.6
diff -u -p -r1.6 aspa.c
--- aspa.c      2 Nov 2022 10:04:41 -0000       1.6
+++ aspa.c      3 Nov 2022 15:12:26 -0000
@@ -207,11 +207,14 @@ aspa_parse(X509 **x509, const char *fn, 
                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;
        }
 
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.157
diff -u -p -r1.157 extern.h
--- extern.h    2 Nov 2022 12:43:02 -0000       1.157
+++ extern.h    3 Nov 2022 15:12:27 -0000
@@ -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 i
 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 **);
Index: gbr.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/gbr.c,v
retrieving revision 1.16
diff -u -p -r1.16 gbr.c
--- gbr.c       11 May 2022 21:19:06 -0000      1.16
+++ gbr.c       3 Nov 2022 15:12:27 -0000
@@ -67,11 +67,14 @@ gbr_parse(X509 **x509, const char *fn, c
                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;
        }
 
Index: mft.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/mft.c,v
retrieving revision 1.76
diff -u -p -r1.76 mft.c
--- mft.c       2 Nov 2022 12:43:02 -0000       1.76
+++ mft.c       3 Nov 2022 15:12:27 -0000
@@ -368,11 +368,14 @@ mft_parse(X509 **x509, const char *fn, c
                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;
        }
 
Index: print.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/print.c,v
retrieving revision 1.17
diff -u -p -r1.17 print.c
--- print.c     2 Nov 2022 12:43:02 -0000       1.17
+++ print.c     3 Nov 2022 15:12:27 -0000
@@ -337,6 +337,7 @@ mft_print(const X509 *x, const struct mf
                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 mf
                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,12 +390,14 @@ roa_print(const X509 *x, const struct ro
                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);
        }
@@ -432,6 +436,7 @@ gbr_print(const X509 *x, const struct gb
                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 +454,7 @@ gbr_print(const X509 *x, const struct gb
                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 +586,7 @@ aspa_print(const X509 *x, const struct a
                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 +606,7 @@ aspa_print(const X509 *x, const struct a
                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 +689,7 @@ tak_print(const X509 *x, const struct ta
                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 +698,7 @@ tak_print(const X509 *x, const struct ta
                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);
        }
 
Index: roa.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/roa.c,v
retrieving revision 1.54
diff -u -p -r1.54 roa.c
--- roa.c       2 Nov 2022 10:04:41 -0000       1.54
+++ roa.c       3 Nov 2022 15:12:27 -0000
@@ -222,11 +222,14 @@ roa_parse(X509 **x509, const char *fn, c
                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;
        }
 
Index: tak.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/tak.c,v
retrieving revision 1.1
diff -u -p -r1.1 tak.c
--- tak.c       2 Nov 2022 12:43:02 -0000       1.1
+++ tak.c       3 Nov 2022 15:12:27 -0000
@@ -247,11 +247,14 @@ tak_parse(X509 **x509, const char *fn, c
                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;
        }
 
Index: x509.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/x509.c,v
retrieving revision 1.53
diff -u -p -r1.53 x509.c
--- x509.c      2 Nov 2022 12:43:02 -0000       1.53
+++ x509.c      3 Nov 2022 15:12:27 -0000
@@ -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,
        },
@@ -368,6 +373,54 @@ out:
        AUTHORITY_INFO_ACCESS_free(info);
        return rc;
 }
+
+/*
+ * 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;
+       }
+
+       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) {
+                       if (!x509_location(fn, "SIA: signedObject", "rsync://",
+                           ad->location, sia))
+                               goto out;
+               }
+       }
+
+       if (sia == NULL) {
+               warnx("%s: RFC 6487 section 4.8.8: SIA: missing signedObject",
+                   fn);
+               goto out;
+       }
+
+       rc = 1;
+ out:
+       AUTHORITY_INFO_ACCESS_free(info);
+       return rc;
+}
+
 
 /*
  * Extract the expire time (not-after) of a certificate.

Reply via email to