Add some restrictions to manifest object profile
authorjob <job@openbsd.org>
Sun, 28 Mar 2021 16:22:17 +0000 (16:22 +0000)
committerjob <job@openbsd.org>
Sun, 28 Mar 2021 16:22:17 +0000 (16:22 +0000)
OK tb@, feedback from claudio@

regress/usr.sbin/rpki-client/test-mft.c
usr.sbin/rpki-client/extern.h
usr.sbin/rpki-client/mft.c

index cab2d3c..6e48d1a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: test-mft.c,v 1.11 2021/02/16 08:53:53 job Exp $ */
+/*     $Id: test-mft.c,v 1.12 2021/03/28 16:22:17 job Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -55,6 +55,7 @@ mft_print(const struct mft *p)
        printf("Subject key identifier: %s\n", p->ski);
        printf("Authority key identifier: %s\n", p->aki);
        printf("Authority info access: %s\n", p->aia);
+       printf("Manifest Number: %s\n", p->seqnum);
        for (i = 0; i < p->filesz; i++) {
                b64_ntop(p->files[i].hash, sizeof(p->files[i].hash),
                    hash, sizeof(hash));
index 03f6d89..0074022 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: extern.h,v 1.56 2021/03/25 12:18:45 claudio Exp $ */
+/*     $OpenBSD: extern.h,v 1.57 2021/03/28 16:22:17 job Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -156,6 +156,7 @@ struct mft {
        struct mftfile  *files; /* file and hash */
        size_t           filesz; /* number of filenames */
        int              stale; /* if a stale manifest */
+       char            *seqnum; /* manifestNumber */
        char            *aia; /* AIA */
        char            *aki; /* AKI */
        char            *ski; /* SKI */
index 214f857..195b993 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mft.c,v 1.30 2021/03/27 18:12:15 job Exp $ */
+/*     $OpenBSD: mft.c,v 1.31 2021/03/28 16:22:17 job Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <unistd.h>
 
+#include <openssl/bn.h>
 #include <openssl/asn1.h>
 #include <openssl/sha.h>
 #include <openssl/x509.h>
@@ -257,6 +258,8 @@ mft_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
        ASN1_SEQUENCE_ANY       *seq;
        const ASN1_TYPE         *t;
        const ASN1_GENERALIZEDTIME *from, *until;
+       BIGNUM                  *mft_seqnum = NULL;
+       long                     mft_version;
        int                      i, rc = -1;
 
        if ((seq = d2i_ASN1_SEQUENCE_ANY(NULL, &d, dsz)) == NULL) {
@@ -265,7 +268,7 @@ mft_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
                goto out;
        }
 
-       /* The version is optional. */
+       /* The profile version is optional. */
 
        if (sk_ASN1_TYPE_num(seq) != 5 &&
            sk_ASN1_TYPE_num(seq) != 6) {
@@ -275,7 +278,7 @@ mft_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
                goto out;
        }
 
-       /* Start with optional version. */
+       /* Start with optional profile version. */
 
        i = 0;
        if (sk_ASN1_TYPE_num(seq) == 6) {
@@ -286,6 +289,16 @@ mft_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
                            p->fn, ASN1_tag2str(t->type), t->type);
                        goto out;
                }
+
+               if (t->value.integer == NULL)
+                       goto out;
+
+               mft_version = ASN1_INTEGER_get(t->value.integer);
+               if (mft_version != 0) {
+                       warnx("%s: RFC 6486 section 4.2.1: version: "
+                           "want 0, have %ld", p->fn, mft_version);
+                       goto out;
+               }
        }
 
        /* Now the manifest sequence number. */
@@ -298,6 +311,30 @@ mft_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
                goto out;
        }
 
+       mft_seqnum = ASN1_INTEGER_to_BN(t->value.integer, NULL);
+       if (mft_seqnum == NULL) {
+               warnx("%s: ASN1_INTEGER_to_BN error", p->fn);
+               goto out;
+       }
+
+       if (BN_is_negative(mft_seqnum)) {
+               warnx("%s: RFC 6486 section 4.2.1: manifestNumber: "
+                   "want positive integer, have negative.", p->fn);
+               goto out;
+       }
+
+       if (BN_num_bytes(mft_seqnum) > 20) {
+               warnx("%s: RFC 6486 section 4.2.1: manifestNumber: "
+                   "want 20 or less than octets, have more.", p->fn);
+               goto out;
+       }
+
+       p->res->seqnum = BN_bn2hex(mft_seqnum);
+       if (p->res->seqnum == NULL) {
+               warnx("%s: BN_bn2hex error", p->fn);
+               goto out;
+       }
+
        /*
         * Timestamps: this and next update time.
         * Validate that the current date falls into this interval.
@@ -363,6 +400,7 @@ mft_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
        rc = 1;
 out:
        sk_ASN1_TYPE_pop_free(seq, ASN1_TYPE_free);
+       BN_free(mft_seqnum);
        return rc;
 }
 
@@ -485,6 +523,7 @@ mft_free(struct mft *p)
        free(p->ski);
        free(p->file);
        free(p->files);
+       free(p->seqnum);
        free(p);
 }