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>
This commit is contained in:
James Bottomley 2017-10-28 14:21:24 +01:00
parent 62c9352519
commit efc424c8ee
4 changed files with 76 additions and 6 deletions

View file

@ -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;

View file

@ -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,

View file

@ -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;

View file

@ -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,6 +548,9 @@ int main(int argc, char **argv)
if (fileio_read_file(ctx, ctx->infilename, &ctx->data, &ctx->data_len))
return EXIT_FAILURE;
if (engine)
ctx->key = fileio_read_engine_key(engine, keyfilename);
else
ctx->key = fileio_read_pkey(keyfilename);
if (!ctx->key)
return EXIT_FAILURE;