forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
modsign: Extract signing cert from CONFIG_MODULE_SIG_KEY if needed
Where an external PEM file or PKCS#11 URI is given, we can get the cert from it for ourselves instead of making the user drop signing_key.x509 in place for us. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> Signed-off-by: David Howells <dhowells@redhat.com>
- Loading branch information
Showing
5 changed files
with
181 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
/* Extract X.509 certificate in DER form from PKCS#11 or PEM. | ||
* | ||
* Copyright © 2014 Red Hat, Inc. All Rights Reserved. | ||
* Copyright © 2015 Intel Corporation. | ||
* | ||
* Authors: David Howells <dhowells@redhat.com> | ||
* David Woodhouse <dwmw2@infradead.org> | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public Licence | ||
* as published by the Free Software Foundation; either version | ||
* 2 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 <getopt.h> | ||
#include <err.h> | ||
#include <arpa/inet.h> | ||
#include <openssl/bio.h> | ||
#include <openssl/evp.h> | ||
#include <openssl/pem.h> | ||
#include <openssl/pkcs7.h> | ||
#include <openssl/err.h> | ||
#include <openssl/engine.h> | ||
|
||
#define PKEY_ID_PKCS7 2 | ||
|
||
static __attribute__((noreturn)) | ||
void format(void) | ||
{ | ||
fprintf(stderr, | ||
"Usage: scripts/extract-cert <source> <dest>\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 const char *key_pass; | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
char *cert_src, *cert_dst; | ||
X509 *x509; | ||
BIO *b; | ||
|
||
OpenSSL_add_all_algorithms(); | ||
ERR_load_crypto_strings(); | ||
ERR_clear_error(); | ||
|
||
key_pass = getenv("KBUILD_SIGN_PIN"); | ||
|
||
if (argc != 3) | ||
format(); | ||
|
||
cert_src = argv[1]; | ||
cert_dst = argv[2]; | ||
|
||
if (!strncmp(cert_src, "pkcs11:", 7)) { | ||
ENGINE *e; | ||
struct { | ||
const char *cert_id; | ||
X509 *cert; | ||
} parms; | ||
|
||
parms.cert_id = cert_src; | ||
parms.cert = NULL; | ||
|
||
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"); | ||
ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &parms, NULL, 1); | ||
ERR(!parms.cert, "Get X.509 from PKCS#11"); | ||
x509 = parms.cert; | ||
} else { | ||
b = BIO_new_file(cert_src, "rb"); | ||
ERR(!b, "%s", cert_src); | ||
x509 = PEM_read_bio_X509(b, NULL, NULL, NULL); | ||
ERR(!x509, "%s", cert_src); | ||
BIO_free(b); | ||
} | ||
|
||
b = BIO_new_file(cert_dst, "wb"); | ||
ERR(!b, "%s", cert_dst); | ||
ERR(!i2d_X509_bio(b, x509), cert_dst); | ||
BIO_free(b); | ||
|
||
return 0; | ||
} |