summaryrefslogtreecommitdiff
path: root/usr.sbin/rpki-client/x509.c
diff options
context:
space:
mode:
authorJob Snijders <job@cvs.openbsd.org>2021-10-11 16:50:05 +0000
committerJob Snijders <job@cvs.openbsd.org>2021-10-11 16:50:05 +0000
commite0a681aae99762b798cb9d65d37e4f21b04b763b (patch)
treea5d43365e7f81952e8ce985784b022f7716c1281 /usr.sbin/rpki-client/x509.c
parenta8cba88dc0cb0ad94ffc57d7c08ad35d2c511a27 (diff)
Add support for BGPsec Router Certificates (RFC 8209)
BGPsec router keys are extracted from RPKI certificates and emitted via the JSON output in base64 encoded form. OK tb@ claudio@
Diffstat (limited to 'usr.sbin/rpki-client/x509.c')
-rw-r--r--usr.sbin/rpki-client/x509.c62
1 files changed, 61 insertions, 1 deletions
diff --git a/usr.sbin/rpki-client/x509.c b/usr.sbin/rpki-client/x509.c
index 4e27686ac4c..5ba36fce4c5 100644
--- a/usr.sbin/rpki-client/x509.c
+++ b/usr.sbin/rpki-client/x509.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: x509.c,v 1.23 2021/10/07 08:30:39 claudio Exp $ */
+/* $OpenBSD: x509.c,v 1.24 2021/10/11 16:50:04 job Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -24,6 +24,7 @@
#include <string.h>
#include <unistd.h>
+#include <openssl/evp.h>
#include <openssl/x509v3.h>
#include "extern.h"
@@ -88,6 +89,7 @@ x509_get_aki(X509 *x, int ta, const char *fn)
}
res = hex_encode(d, dsz);
+
out:
AUTHORITY_KEYID_free(akid);
return res;
@@ -177,6 +179,64 @@ x509_get_purpose(X509 *x, const char *fn)
return purpose;
}
+/*
+ * Extract ECDSA key from a BGPsec Router Certificate.
+ * Returns NULL on failure, on success return public key,
+ */
+char *
+x509_get_bgpsec_pubkey(X509 *x, const char *fn)
+{
+ EVP_PKEY *pubkey;
+ EC_KEY *ec;
+ int nid;
+ const char *cname;
+ int keylen;
+ uint8_t *key = NULL;
+ char *res = NULL;
+
+ pubkey = X509_get0_pubkey(x);
+ if (pubkey == NULL) {
+ warnx("%s: X509_get_pubkey failed in %s", fn, __func__);
+ goto out;
+ }
+ if (EVP_PKEY_base_id(pubkey) != EVP_PKEY_EC) {
+ warnx("%s: Expected EVP_PKEY_EC, got %d", fn,
+ EVP_PKEY_base_id(pubkey));
+ goto out;
+ }
+
+ ec = EVP_PKEY_get0_EC_KEY(pubkey);
+ if (ec == NULL) {
+ warnx("%s: Incorrect key type", fn);
+ goto out;
+ }
+
+ nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
+ if (nid != NID_X9_62_prime256v1) {
+ if ((cname = EC_curve_nid2nist(nid)) == NULL)
+ cname = OBJ_nid2sn(nid);
+ warnx("%s: Expected P-256, got %s", fn, cname);
+ goto out;
+ }
+
+ if (!EC_KEY_check_key(ec)) {
+ warnx("%s: EC_KEY_check_key failed in %s", fn, __func__);
+ goto out;
+ }
+
+ keylen = i2o_ECPublicKey(ec, &key);
+ if (keylen <= 0) {
+ warnx("%s: i2o_ECPublicKey failed in %s", fn, __func__);
+ goto out;
+ }
+
+ if (base64_encode(key, keylen, &res) == -1)
+ errx(1, "base64_encode failed in %s", __func__);
+
+ out:
+ free(key);
+ return res;
+}
/*
* Parse the Authority Information Access (AIA) extension