aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2017-10-28 14:21:24 +0100
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2017-10-28 14:21:24 +0100
commitefc424c8eea2c398e4371320b4d7266898675ac8 (patch)
treedd0cdb0e5fa8a42db9eef26c3d62176a48ba7c94
parent62c9352519e1a21d2e6423a2e39354cb05d56c44 (diff)
downloadsbsigntools-efc424c8eea2c398e4371320b4d7266898675ac8.tar.gz
sbsign, sbvarsign: support engine based private keys
Add the ability to specify an engine to read the keyfile. For safety, we don't do the full dynamic engine support, but only use engines configured for use by the platform. Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--src/fileio.c50
-rw-r--r--src/fileio.h1
-rw-r--r--src/sbsign.c16
-rw-r--r--src/sbvarsign.c15
4 files changed, 76 insertions, 6 deletions
diff --git a/src/fileio.c b/src/fileio.c
index faab3b7..032eb1e 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -39,6 +39,7 @@
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <openssl/err.h>
+#include <openssl/engine.h>
#include <ccan/talloc/talloc.h>
#include <ccan/read_write_all/read_write_all.h>
@@ -47,6 +48,55 @@
#define FLAG_NOERROR (1<<0)
+static int ui_read(UI *ui, UI_STRING *uis)
+{
+ char password[128];
+
+ if (UI_get_string_type(uis) != UIT_PROMPT)
+ return 0;
+
+ EVP_read_pw_string(password, sizeof(password), "Enter engine key pass phrase:", 0);
+ UI_set_result(ui, uis, password);
+ return 1;
+}
+
+EVP_PKEY *fileio_read_engine_key(const char *engine, const char *filename)
+{
+ UI_METHOD *ui;
+ ENGINE *e;
+ EVP_PKEY *pkey = NULL;
+
+ ENGINE_load_builtin_engines();
+ e = ENGINE_by_id(engine);
+
+ if (!e) {
+ fprintf(stderr, "Failed to load engine: %s\n", engine);
+ ERR_print_errors_fp(stderr);
+ return NULL;
+ }
+
+ ui = UI_create_method("sbsigntools");
+ if (!ui) {
+ fprintf(stderr, "Failed to create UI method\n");
+ ERR_print_errors_fp(stderr);
+ goto out_free;
+ }
+ UI_method_set_reader(ui, ui_read);
+
+ if (!ENGINE_init(e)) {
+ fprintf(stderr, "Failed to initialize engine %s\n", engine);
+ ERR_print_errors_fp(stderr);
+ goto out_free;
+ }
+
+ pkey = ENGINE_load_private_key(e, filename, ui, NULL);
+ ENGINE_finish(e);
+
+ out_free:
+ ENGINE_free(e);
+ return pkey;
+}
+
EVP_PKEY *fileio_read_pkey(const char *filename)
{
EVP_PKEY *key = NULL;
diff --git a/src/fileio.h b/src/fileio.h
index 52c3c12..b3ed22c 100644
--- a/src/fileio.h
+++ b/src/fileio.h
@@ -38,6 +38,7 @@
#include <openssl/x509.h>
EVP_PKEY *fileio_read_pkey(const char *filename);
+EVP_PKEY *fileio_read_engine_key(const char *engine, const char *filename);
X509 *fileio_read_cert(const char *filename);
int fileio_read_file(void *ctx, const char *filename,
diff --git a/src/sbsign.c b/src/sbsign.c
index 406472e..ff1fdfd 100644
--- a/src/sbsign.c
+++ b/src/sbsign.c
@@ -74,6 +74,7 @@ static struct option options[] = {
{ "verbose", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' },
+ { "engine", required_argument, NULL, 'e'},
{ NULL, 0, NULL, 0 },
};
@@ -83,6 +84,7 @@ static void usage(void)
"<efi-boot-image>\n"
"Sign an EFI boot image for use with secure boot.\n\n"
"Options:\n"
+ "\t--engine <eng> use the specified engine to load the key\n"
"\t--key <keyfile> signing key (PEM-encoded RSA "
"private key)\n"
"\t--cert <certfile> certificate (x509 certificate)\n"
@@ -112,19 +114,21 @@ static void set_default_outfilename(struct sign_context *ctx)
int main(int argc, char **argv)
{
- const char *keyfilename, *certfilename;
+ const char *keyfilename, *certfilename, *engine;
struct sign_context *ctx;
uint8_t *buf, *tmp;
int rc, c, sigsize;
+ EVP_PKEY *pkey;
ctx = talloc_zero(NULL, struct sign_context);
keyfilename = NULL;
certfilename = NULL;
+ engine = NULL;
for (;;) {
int idx;
- c = getopt_long(argc, argv, "o:c:k:dvVh", options, &idx);
+ c = getopt_long(argc, argv, "o:c:k:dvVhe:", options, &idx);
if (c == -1)
break;
@@ -150,6 +154,9 @@ int main(int argc, char **argv)
case 'h':
usage();
return EXIT_SUCCESS;
+ case 'e':
+ engine = optarg;
+ break;
}
}
@@ -190,7 +197,10 @@ int main(int argc, char **argv)
* module isn't present). In either case ignore the errors
* (malloc will cause other failures out lower down */
ERR_clear_error();
- EVP_PKEY *pkey = fileio_read_pkey(keyfilename);
+ if (engine)
+ pkey = fileio_read_engine_key(engine, keyfilename);
+ else
+ pkey = fileio_read_pkey(keyfilename);
if (!pkey)
return EXIT_FAILURE;
diff --git a/src/sbvarsign.c b/src/sbvarsign.c
index b45cccb..7dcbe51 100644
--- a/src/sbvarsign.c
+++ b/src/sbvarsign.c
@@ -398,6 +398,7 @@ static struct option options[] = {
{ "verbose", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' },
+ { "engine", required_argument, NULL, 'e'},
{ NULL, 0, NULL, 0 },
};
@@ -409,6 +410,7 @@ void usage(void)
"<var-name> <var-data-file>\n"
"Sign a blob of data for use in SetVariable().\n\n"
"Options:\n"
+ "\t--engine <eng> use the specified engine to load the key\n"
"\t--key <keyfile> signing key (PEM-encoded RSA "
"private key)\n"
"\t--cert <certfile> certificate (x509 certificate)\n"
@@ -437,7 +439,7 @@ static void version(void)
int main(int argc, char **argv)
{
- const char *guid_str, *attr_str, *varname;
+ const char *guid_str, *attr_str, *varname, *engine;
const char *keyfilename, *certfilename;
struct varsign_context *ctx;
bool include_attrs;
@@ -447,13 +449,14 @@ int main(int argc, char **argv)
keyfilename = NULL;
certfilename = NULL;
+ engine = NULL;
guid_str = NULL;
attr_str= NULL;
include_attrs = false;
for (;;) {
int idx;
- c = getopt_long(argc, argv, "o:g:a:k:c:ivVh", options, &idx);
+ c = getopt_long(argc, argv, "o:g:a:k:c:ivVhe:", options, &idx);
if (c == -1)
break;
@@ -485,6 +488,9 @@ int main(int argc, char **argv)
case 'h':
usage();
return EXIT_SUCCESS;
+ case 'e':
+ engine = optarg;
+ break;
}
}
@@ -542,7 +548,10 @@ int main(int argc, char **argv)
if (fileio_read_file(ctx, ctx->infilename, &ctx->data, &ctx->data_len))
return EXIT_FAILURE;
- ctx->key = fileio_read_pkey(keyfilename);
+ if (engine)
+ ctx->key = fileio_read_engine_key(engine, keyfilename);
+ else
+ ctx->key = fileio_read_pkey(keyfilename);
if (!ctx->key)
return EXIT_FAILURE;