Emit SKI in the JSON output and improve flow in x509_get_pubkey()
authorjob <job@openbsd.org>
Tue, 12 Oct 2021 15:16:45 +0000 (15:16 +0000)
committerjob <job@openbsd.org>
Tue, 12 Oct 2021 15:16:45 +0000 (15:16 +0000)
OK claudio@

usr.sbin/rpki-client/cert.c
usr.sbin/rpki-client/extern.h
usr.sbin/rpki-client/output-json.c
usr.sbin/rpki-client/x509.c

index 8c17ffa..bc89f58 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cert.c,v 1.37 2021/10/11 16:50:03 job Exp $ */
+/*     $OpenBSD: cert.c,v 1.38 2021/10/12 15:16:45 job Exp $ */
 /*
  * Copyright (c) 2021 Job Snijders <job@openbsd.org>
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -1081,9 +1081,9 @@ cert_parse_inner(X509 **xp, const char *fn, int ta)
                }
                break;
        case CERT_PURPOSE_BGPSEC_ROUTER:
-               p.res->bgpsec_pubkey = x509_get_bgpsec_pubkey(x, p.fn);
-               if (p.res->bgpsec_pubkey == NULL) {
-                       warnx("%s: x509_get_bgpsec_pubkey failed", p.fn);
+               p.res->pubkey = x509_get_pubkey(x, p.fn);
+               if (p.res->pubkey == NULL) {
+                       warnx("%s: x509_get_pubkey failed", p.fn);
                        goto out;
                }
                if (p.res->ipsz > 0) {
@@ -1217,7 +1217,7 @@ cert_free(struct cert *p)
        free(p->aki);
        free(p->ski);
        free(p->tal);
-       free(p->bgpsec_pubkey);
+       free(p->pubkey);
        X509_free(p->x509);
        free(p);
 }
@@ -1277,7 +1277,7 @@ cert_buffer(struct ibuf *b, const struct cert *p)
        io_str_buffer(b, p->aki);
        io_str_buffer(b, p->ski);
        io_str_buffer(b, p->tal);
-       io_str_buffer(b, p->bgpsec_pubkey);
+       io_str_buffer(b, p->pubkey);
 }
 
 static void
@@ -1351,7 +1351,7 @@ cert_read(int fd)
        io_str_read(fd, &p->ski);
        assert(p->ski);
        io_str_read(fd, &p->tal);
-       io_str_read(fd, &p->bgpsec_pubkey);
+       io_str_read(fd, &p->pubkey);
 
        return p;
 }
@@ -1390,10 +1390,12 @@ insert_brk(struct brk_tree *tree, struct cert *cert, int asid)
 
        b->asid = asid;
        b->expires = cert->expires;
-       if ((b->key = strdup(cert->bgpsec_pubkey)) == NULL)
-               err(1, NULL);
        if ((b->tal = strdup(cert->tal)) == NULL)
                err(1, NULL);
+       if ((b->ski = strdup(cert->ski)) == NULL)
+               err(1, NULL);
+       if ((b->pubkey = strdup(cert->pubkey)) == NULL)
+               err(1, NULL);
 
        /*
         * Check if a similar BRK already exists in the tree. If the found BRK
@@ -1408,7 +1410,8 @@ insert_brk(struct brk_tree *tree, struct cert *cert, int asid)
                        found->tal = b->tal;
                        b->tal = NULL;
                }
-               free(b->key);
+               free(b->ski);
+               free(b->pubkey);
                free(b->tal);
                free(b);
        }
@@ -1442,12 +1445,20 @@ cert_insert_brks(struct brk_tree *tree, struct cert *cert)
 static inline int
 brkcmp(struct brk *a, struct brk *b)
 {
+       int rv;
+
        if (a->asid > b->asid)
                return 1;
        if (a->asid < b->asid)
                return -1;
 
-       return strcmp(a->key, b->key);
+       rv = strcmp(a->ski, b->ski);
+       if (rv > 0)
+               return 1;
+       if (rv < 0)
+               return -1;
+
+       return strcmp(a->pubkey, b->pubkey);
 }
 
 RB_GENERATE(brk_tree, brk, entry, brkcmp);
index b8cc212..a740981 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: extern.h,v 1.71 2021/10/11 16:50:03 job Exp $ */
+/*     $OpenBSD: extern.h,v 1.72 2021/10/12 15:16:45 job Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -127,7 +127,7 @@ struct cert {
        char            *ski; /* SKI */
        char            *tal; /* basename of TAL for this cert */
        enum cert_purpose        purpose; /* Certificate Purpose (BGPSec or CA) */
-       char            *bgpsec_pubkey; /* BGPsec Router Key */
+       char            *pubkey; /* Subject Public Key Info */
        int              valid; /* validated resources */
        X509            *x509; /* the cert */
        time_t           expires; /* do not use after */
@@ -236,7 +236,8 @@ struct brk {
        RB_ENTRY(brk)    entry;
        uint32_t         asid;
        char            *tal; /* basename of TAL for this key */
-       uint8_t         *key; /* raw P-256 ECDSA public key */
+       char            *ski; /* Subject Key Identifier */
+       char            *pubkey; /* Subject Public Key Info */
        time_t           expires; /* transitive expiry moment */
 };
 /*
@@ -551,7 +552,7 @@ char                *x509_get_ski(X509 *, const char *);
 time_t          x509_get_expire(X509 *, const char *);
 char           *x509_get_crl(X509 *, const char *);
 char           *x509_crl_get_aki(X509_CRL *, const char *);
-char           *x509_get_bgpsec_pubkey(X509 *, const char *);
+char           *x509_get_pubkey(X509 *, const char *);
 enum cert_purpose       x509_get_purpose(X509 *, const char *);
 
 /* Output! */
index e226231..eee39d9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: output-json.c,v 1.18 2021/10/11 16:50:03 job Exp $ */
+/*     $OpenBSD: output-json.c,v 1.19 2021/10/12 15:16:45 job Exp $ */
 /*
  * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
  *
@@ -122,8 +122,9 @@ output_json(FILE *out, struct vrp_tree *vrps, struct brk_tree *brks,
                }
                first = 0;
 
-               if (fprintf(out, "\t\t{ \"asn\": %u, \"key\": \"%s\", \"ta\": "
-                   "\"%s\", \"expires\": %lld }", b->asid, b->key, b->tal,
+               if (fprintf(out, "\t\t{ \"asn\": %u, \"ski\": \"%s\", "
+                   "\"pubkey\": \"%s\", \"ta\": \"%s\", \"expires\": %lld }",
+                   b->asid, b->ski, b->pubkey, b->tal,
                    (long long)b->expires) < 0)
                        return -1;
        }
index 5ba36fc..50fae61 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: x509.c,v 1.24 2021/10/11 16:50:04 job Exp $ */
+/*     $OpenBSD: x509.c,v 1.25 2021/10/12 15:16:45 job Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -180,32 +180,32 @@ x509_get_purpose(X509 *x, const char *fn)
 }
 
 /*
- * Extract ECDSA key from a BGPsec Router Certificate.
- * Returns NULL on failure, on success return public key,
+ * Extract Subject Public Key Info (SPKI) from BGPsec X.509 Certificate.
+ * Returns NULL on failure, on success return the SPKI as base64 encoded pubkey
  */
 char *
-x509_get_bgpsec_pubkey(X509 *x, const char *fn)
+x509_get_pubkey(X509 *x, const char *fn)
 {
-       EVP_PKEY        *pubkey;
+       EVP_PKEY        *evp;
        EC_KEY          *ec;
        int              nid;
        const char      *cname;
-       int              keylen;
-       uint8_t         *key = NULL;
+       uint8_t         *pubkey = NULL;
        char            *res = NULL;
+       int              len;
 
-       pubkey = X509_get0_pubkey(x);
-       if (pubkey == NULL) {
+       evp = X509_get0_pubkey(x);
+       if (evp == NULL) {
                warnx("%s: X509_get_pubkey failed in %s", fn, __func__);
                goto out;
        }
-       if (EVP_PKEY_base_id(pubkey) != EVP_PKEY_EC) {
+       if (EVP_PKEY_base_id(evp) != EVP_PKEY_EC) {
                warnx("%s: Expected EVP_PKEY_EC, got %d", fn,
-                   EVP_PKEY_base_id(pubkey));
+                   EVP_PKEY_base_id(evp));
                goto out;
        }
 
-       ec = EVP_PKEY_get0_EC_KEY(pubkey);
+       ec = EVP_PKEY_get0_EC_KEY(evp);
        if (ec == NULL) {
                warnx("%s: Incorrect key type", fn);
                goto out;
@@ -224,17 +224,17 @@ x509_get_bgpsec_pubkey(X509 *x, const char *fn)
                goto out;
        }
 
-       keylen = i2o_ECPublicKey(ec, &key);
-       if (keylen <= 0) {
-               warnx("%s: i2o_ECPublicKey failed in %s", fn, __func__);
+       len = i2d_PUBKEY(evp, &pubkey);
+       if (len <= 0) {
+               warnx("%s: i2d_PUBKEY failed in %s", fn, __func__);
                goto out;
        }
 
-       if (base64_encode(key, keylen, &res) == -1)
+       if (base64_encode(pubkey, len, &res) == -1)
                errx(1, "base64_encode failed in %s", __func__);
 
  out:
-       free(key);
+       free(pubkey);
        return res;
 }