summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Luebbe <jlu@pengutronix.de>2020-08-11 16:13:43 +0200
committerJan Luebbe <jlu@pengutronix.de>2020-08-13 10:58:07 +0200
commita6179b2827fe5e7fc4533f0c3ed2a331a4d7254c (patch)
tree4b2e9cbbaab8a3033448b6e47c31ead18ca84591
parent1f3b85a94e27f8de104d66c3b39447c0c9d87724 (diff)
downloadextract-cert-a6179b2827fe5e7fc4533f0c3ed2a331a4d7254c.tar.gz
extract-cert-a6179b2827fe5e7fc4533f0c3ed2a331a4d7254c.tar.xz
Add spki-hash helper0.2
This gets the public key from the PKCS#11 engine an calculates the SPKI hash. Signed-off-by: Jan Luebbe <jlu@pengutronix.de>
-rw-r--r--meson.build8
-rw-r--r--spki-hash.c139
2 files changed, 146 insertions, 1 deletions
diff --git a/meson.build b/meson.build
index 0ba4ef7..994fecb 100644
--- a/meson.build
+++ b/meson.build
@@ -2,6 +2,12 @@ project('extract-cert', 'c',
version : '0.1',
default_options : ['warning_level=3'])
+openssl_dep = dependency('openssl')
+
executable('extract-cert',
'extract-cert.c',
- install : true, dependencies : dependency('openssl'))
+ install : true, dependencies : openssl_dep)
+
+executable('spki-hash',
+ 'spki-hash.c',
+ install : true, dependencies : openssl_dep)
diff --git a/spki-hash.c b/spki-hash.c
new file mode 100644
index 0000000..7d82cf1
--- /dev/null
+++ b/spki-hash.c
@@ -0,0 +1,139 @@
+/* Hash SPKI from PKCS#11 or PEM.
+ *
+ * Copyright © 2014-2015 Red Hat, Inc. All Rights Reserved.
+ * Copyright © 2015 Intel Corporation.
+ * Copyright © 2020 Pengutronix e.K.
+ *
+ * Authors: David Howells <dhowells@redhat.com>
+ * David Woodhouse <dwmw2@infradead.org>
+ * Jan Luebbe <jlu@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the licence, or (at your option) any later version.
+ */
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <err.h>
+#include <openssl/bio.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/engine.h>
+
+#define PKEY_ID_PKCS7 2
+
+static __attribute__((noreturn))
+void format(void)
+{
+ fprintf(stderr,
+ "Usage: scripts/spki-hash <source>\n");
+ exit(2);
+}
+
+static void display_openssl_errors(int l)
+{
+ const char *file;
+ char buf[120];
+ int e, line;
+
+ if (ERR_peek_error() == 0)
+ return;
+ fprintf(stderr, "At main.c:%d:\n", l);
+
+ while ((e = ERR_get_error_line(&file, &line))) {
+ ERR_error_string(e, buf);
+ fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line);
+ }
+}
+
+static void drain_openssl_errors(void)
+{
+ const char *file;
+ int line;
+
+ if (ERR_peek_error() == 0)
+ return;
+ while (ERR_get_error_line(&file, &line)) {}
+}
+
+#define ERR(cond, fmt, ...) \
+ do { \
+ bool __cond = (cond); \
+ display_openssl_errors(__LINE__); \
+ if (__cond) { \
+ err(1, fmt, ## __VA_ARGS__); \
+ } \
+ } while(0)
+
+
+static void do_hash_pkey(EVP_PKEY *pkey) {
+ BIO *spki;
+ void *spki_data;
+ size_t spki_len;
+ unsigned char md[SHA256_DIGEST_LENGTH];
+
+ spki = BIO_new(BIO_s_mem());
+ i2d_PUBKEY_bio(spki, pkey);
+
+ spki_len = BIO_get_mem_data(spki, &spki_data);
+ if (!EVP_Digest(spki_data, spki_len, md, NULL, EVP_sha256(), NULL)) {
+ ERR(1, "EVP_Digest");
+ }
+
+ for (size_t i = 0; i < sizeof(md); i++) {
+ printf("%02X", md[i]);
+ }
+ printf("\n");
+}
+
+static const char *key_pass;
+
+int main(int argc, char **argv)
+{
+ char *src;
+ EVP_PKEY *key;
+
+ OpenSSL_add_all_algorithms();
+ ERR_load_crypto_strings();
+ ERR_clear_error();
+
+ key_pass = getenv("KBUILD_SIGN_PIN");
+
+ if (argc != 2)
+ format();
+
+ src = argv[1];
+
+ if (!strncmp(src, "pkcs11:", 7)) {
+ ENGINE *e;
+ ENGINE_load_builtin_engines();
+ drain_openssl_errors();
+ e = ENGINE_by_id("pkcs11");
+ ERR(!e, "Load PKCS#11 ENGINE");
+ if (ENGINE_init(e))
+ drain_openssl_errors();
+ else
+ ERR(1, "ENGINE_init");
+ if (key_pass)
+ ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN");
+
+ key = ENGINE_load_public_key(e, src, NULL, NULL);
+ ERR(!key, "ENGINE_load_public_key");
+ } else {
+ BIO *b;
+
+ b = BIO_new_file(src, "rb");
+ ERR(!b, "%s", src);
+
+ key = PEM_read_bio_PUBKEY(b, NULL, NULL, NULL);
+ ERR(!key, "ENGINE_load_public_key");
+ }
+ do_hash_pkey(key);
+
+ return 0;
+}