diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2019-01-05 13:16:27 -0800 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2019-01-05 13:16:27 -0800 |
commit | 0844b10e7681a10caa42fb728838974f76bf7c96 (patch) | |
tree | abbf82ce150215ad25f9f679b11f41279c57d39c | |
parent | ff81e553dc7c59963c81b3ab435ecabcf461d3cd (diff) | |
download | efitools-0844b10e7681a10caa42fb728838974f76bf7c96.tar.gz |
factor out variable signing code
Since we have two uses of the code, consolidate into a library routine
so the signing can be done in a single place.
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r-- | efi-updatevar.c | 19 | ||||
-rw-r--r-- | include/openssl_sign.h | 8 | ||||
-rw-r--r-- | lib/Makefile | 2 | ||||
-rw-r--r-- | lib/openssl_sign.c | 69 | ||||
-rw-r--r-- | sign-efi-sig-list.c | 51 |
5 files changed, 90 insertions, 59 deletions
diff --git a/efi-updatevar.c b/efi-updatevar.c index bbea1e2..ffbbe99 100644 --- a/efi-updatevar.c +++ b/efi-updatevar.c @@ -24,6 +24,7 @@ #include <efi.h> #include <kernel_efivars.h> +#include <openssl_sign.h> #include <guid.h> #include <sha256.h> #include <version.h> @@ -321,6 +322,9 @@ main(int argc, char *argv[]) EFI_TIME timestamp; time_t t; + unsigned char *tmp; + int sigsize; + struct tm *tm; memset(×tamp, 0, sizeof(timestamp)); time(&t); @@ -353,17 +357,7 @@ main(int argc, char *argv[]) ptr += sizeof(timestamp); memcpy(ptr, buf, st.st_size); - BIO *bio = BIO_new_mem_buf(signbuf, signbuflen); - PKCS7 *p7 = PKCS7_sign(NULL, NULL, NULL, bio, - PKCS7_BINARY | PKCS7_PARTIAL - | PKCS7_DETACHED | PKCS7_NOATTR); - const EVP_MD *md = EVP_get_digestbyname("SHA256"); - PKCS7_sign_add_signer(p7, X, pkey, md, PKCS7_BINARY - | PKCS7_DETACHED | PKCS7_NOATTR); - PKCS7_final(p7, bio, PKCS7_BINARY | PKCS7_DETACHED | PKCS7_NOATTR); - - - int sigsize = i2d_PKCS7(p7, NULL); + sign_efi_var_ssl(signbuf, signbuflen, pkey, X, &tmp, &sigsize); EFI_VARIABLE_AUTHENTICATION_2 *var_auth = malloc(sizeof(EFI_VARIABLE_AUTHENTICATION_2) + sigsize); var_auth->TimeStamp = timestamp; @@ -371,8 +365,7 @@ main(int argc, char *argv[]) var_auth->AuthInfo.Hdr.dwLength = sigsize + OFFSET_OF(WIN_CERTIFICATE_UEFI_GUID, CertData); var_auth->AuthInfo.Hdr.wRevision = 0x0200; var_auth->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID; - unsigned char *tmp = var_auth->AuthInfo.CertData; - i2d_PKCS7(p7, &tmp); + memcpy(var_auth->AuthInfo.CertData, tmp, sigsize); ERR_print_errors_fp(stderr); /* new update now consists of two parts: the diff --git a/include/openssl_sign.h b/include/openssl_sign.h new file mode 100644 index 0000000..7c58539 --- /dev/null +++ b/include/openssl_sign.h @@ -0,0 +1,8 @@ +#include <openssl/pem.h> + +int +sign_efi_var(char *payload, int payload_size, char *keyfile, char *certfile, + unsigned char **sig, int *sigsize); +int +sign_efi_var_ssl(char *payload, int payload_size, EVP_PKEY *pkey, X509 *cert, + unsigned char **sig, int *sigsize); diff --git a/lib/Makefile b/lib/Makefile index ded03f7..68279cf 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -2,7 +2,7 @@ FILES = simple_file.o pecoff.o guid.o sha256.o console.o \ execute.o configtable.o shell.o security_policy.o \ shim_protocol.o pkcs7verify.o -LIBFILES = $(FILES) kernel_efivars.o +LIBFILES = $(FILES) kernel_efivars.o openssl_sign.o EFILIBFILES = $(patsubst %.o,%.efi.o,$(FILES)) variables.o include ../Make.rules diff --git a/lib/openssl_sign.c b/lib/openssl_sign.c new file mode 100644 index 0000000..90e319e --- /dev/null +++ b/lib/openssl_sign.c @@ -0,0 +1,69 @@ +/* + * Copyright 2019 <James.Bottomley@HansenPartnership.com> + * + * see COPYING file + */ + +#include <openssl/pem.h> +#include <openssl/err.h> +#include <openssl/sha.h> + +#include <openssl_sign.h> + +int +sign_efi_var_ssl(char *payload, int payload_size, EVP_PKEY *pkey, X509 *cert, + unsigned char **sig, int *sigsize) +{ + BIO *bio_data = BIO_new_mem_buf(payload, payload_size); + PKCS7 *p7; + + p7 = PKCS7_sign(NULL, NULL, NULL, bio_data, PKCS7_BINARY|PKCS7_PARTIAL|PKCS7_DETACHED|PKCS7_NOATTR); + const EVP_MD *md = EVP_get_digestbyname("SHA256"); + PKCS7_sign_add_signer(p7, cert, pkey, md, PKCS7_BINARY|PKCS7_DETACHED|PKCS7_NOATTR); + PKCS7_final(p7, bio_data, PKCS7_BINARY|PKCS7_DETACHED|PKCS7_NOATTR); + + *sig = NULL; + *sigsize = i2d_PKCS7(p7, sig); + PKCS7_free(p7); + ERR_print_errors_fp(stdout); + + return 0; +} + +int +sign_efi_var(char *payload, int payload_size, char *keyfile, char *certfile, + unsigned char **sig, int *sigsize) +{ + int ret; + + ERR_load_crypto_strings(); + OpenSSL_add_all_digests(); + OpenSSL_add_all_ciphers(); + /* here we may get highly unlikely failures or we'll get a + * complaint about FIPS signatures (usually becuase the FIPS + * module isn't present). In either case ignore the errors + * (malloc will cause other failures out lower down */ + ERR_clear_error(); + + BIO *cert_bio = BIO_new_file(certfile, "r"); + X509 *cert = PEM_read_bio_X509(cert_bio, NULL, NULL, NULL); + if (!cert) { + ERR_print_errors_fp(stdout); + fprintf(stderr, "error reading certificate %s\n", certfile); + return 1; + } + + BIO *privkey_bio = BIO_new_file(keyfile, "r"); + EVP_PKEY *pkey = PEM_read_bio_PrivateKey(privkey_bio, NULL, NULL, NULL); + if (!pkey) { + ERR_print_errors_fp(stdout); + fprintf(stderr, "error reading private key %s\n", keyfile); + return 1; + } + ret = sign_efi_var_ssl(payload, payload_size, pkey, cert, + sig, sigsize); + EVP_PKEY_free(pkey); + X509_free(cert); + + return ret; +} diff --git a/sign-efi-sig-list.c b/sign-efi-sig-list.c index e19ef97..cce8926 100644 --- a/sign-efi-sig-list.c +++ b/sign-efi-sig-list.c @@ -23,13 +23,10 @@ #include <unistd.h> #include <wchar.h> -#include <openssl/pem.h> -#include <openssl/err.h> -#include <openssl/sha.h> - #include <variables.h> #include <guid.h> #include <version.h> +#include <openssl_sign.h> static void usage(const char *progname) @@ -228,8 +225,6 @@ main(int argc, char *argv[]) goto output; } - PKCS7 *p7; - if (signedinput) { struct stat sti; int infile = open(signedinput, O_RDONLY); @@ -247,39 +242,9 @@ main(int argc, char *argv[]) fprintf(stderr, "Doing signing, need certificate and key\n"); exit(1); } - - ERR_load_crypto_strings(); - OpenSSL_add_all_digests(); - OpenSSL_add_all_ciphers(); - /* here we may get highly unlikely failures or we'll get a - * complaint about FIPS signatures (usually becuase the FIPS - * module isn't present). In either case ignore the errors - * (malloc will cause other failures out lower down */ - ERR_clear_error(); - - BIO *cert_bio = BIO_new_file(certfile, "r"); - X509 *cert = PEM_read_bio_X509(cert_bio, NULL, NULL, NULL); - if (!cert) { - fprintf(stderr, "error reading certificate %s\n", certfile); - exit(1); - } - - BIO *privkey_bio = BIO_new_file(keyfile, "r"); - EVP_PKEY *pkey = PEM_read_bio_PrivateKey(privkey_bio, NULL, NULL, NULL); - if (!pkey) { - fprintf(stderr, "error reading private key %s\n", keyfile); + if (sign_efi_var(signbuf, signbuflen, keyfile, certfile, + &sigbuf, &sigsize)) exit(1); - } - - BIO *bio_data = BIO_new_mem_buf(signbuf, signbuflen); - - p7 = PKCS7_sign(NULL, NULL, NULL, bio_data, PKCS7_BINARY|PKCS7_PARTIAL|PKCS7_DETACHED|PKCS7_NOATTR); - const EVP_MD *md = EVP_get_digestbyname("SHA256"); - PKCS7_sign_add_signer(p7, cert, pkey, md, PKCS7_BINARY|PKCS7_DETACHED|PKCS7_NOATTR); - PKCS7_final(p7, bio_data, PKCS7_BINARY|PKCS7_DETACHED|PKCS7_NOATTR); - - - sigsize = i2d_PKCS7(p7, NULL); } printf("Signature of size %d\n", sigsize); @@ -291,14 +256,10 @@ main(int argc, char *argv[]) var_auth->AuthInfo.Hdr.wRevision = 0x0200; var_auth->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID; - if (signedinput) { - memcpy(var_auth->AuthInfo.CertData, sigbuf, sigsize); - sigbuf = var_auth->AuthInfo.CertData; - } else { - sigbuf = var_auth->AuthInfo.CertData; + memcpy(var_auth->AuthInfo.CertData, sigbuf, sigsize); + sigbuf = var_auth->AuthInfo.CertData; + if (!signedinput) { printf("Signature at: %ld\n", sigbuf - (unsigned char *)var_auth); - i2d_PKCS7(p7, &sigbuf); - ERR_print_errors_fp(stdout); } out = var_auth; |