Compare commits
No commits in common. "master" and "v0.9.2" have entirely different histories.
18 changed files with 45 additions and 206 deletions
16
README
16
README
|
@ -8,21 +8,7 @@ sbsigntool - Signing utility for UEFI secure boot
|
||||||
|
|
||||||
See file ./INSTALL for building and installation instructions.
|
See file ./INSTALL for building and installation instructions.
|
||||||
|
|
||||||
Original development was done at:
|
Main git repository:
|
||||||
git://kernel.ubuntu.com/jk/sbsigntool.git
|
git://kernel.ubuntu.com/jk/sbsigntool.git
|
||||||
|
|
||||||
The current maintained fork resides at:
|
|
||||||
|
|
||||||
https://git.kernel.org/pub/scm/linux/kernel/git/jejb/sbsigntools.git/
|
|
||||||
|
|
||||||
And a very low volume mailing list for bugs and patches is setup at
|
|
||||||
|
|
||||||
sbsigntools@groups.io
|
|
||||||
|
|
||||||
Thanks to groups.io policies, non-members can post to this list, but
|
|
||||||
non-member postings are moderated until released (so they won't show
|
|
||||||
up immediately). The list archives are available:
|
|
||||||
|
|
||||||
https://groups.io/g/sbsigntools/topics
|
|
||||||
|
|
||||||
sbsigntool is free software. See the file COPYING for copying conditions.
|
sbsigntool is free software. See the file COPYING for copying conditions.
|
||||||
|
|
13
configure.ac
13
configure.ac
|
@ -1,4 +1,4 @@
|
||||||
AC_INIT([sbsigntool], [0.9.5], [James.Bottomley@HansenPartnership.com])
|
AC_INIT([sbsigntool], [0.9.2], [James.Bottomley@HansenPartnership.com])
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE()
|
AM_INIT_AUTOMAKE()
|
||||||
|
|
||||||
|
@ -55,12 +55,9 @@ AC_DEFINE_UNQUOTED(HAVE_LITTLE_ENDIAN, $little_endian, [Little-endian system])
|
||||||
AC_DEFINE_UNQUOTED(HAVE_BIG_ENDIAN, $big_endian, [Big-endian system])
|
AC_DEFINE_UNQUOTED(HAVE_BIG_ENDIAN, $big_endian, [Big-endian system])
|
||||||
|
|
||||||
PKG_PROG_PKG_CONFIG()
|
PKG_PROG_PKG_CONFIG()
|
||||||
PKG_CHECK_MODULES(libcrypto, [libcrypto >= 3.0.0],
|
PKG_CHECK_MODULES(libcrypto, libcrypto,
|
||||||
[ac_have_openssl3=1],
|
[],
|
||||||
[PKG_CHECK_MODULES(libcrypto, libcrypto,
|
AC_MSG_ERROR([libcrypto (from the OpenSSL package) is required]))
|
||||||
[],
|
|
||||||
AC_MSG_ERROR([libcrypto (from the OpenSSL package) is required]))])
|
|
||||||
AM_CONDITIONAL(HAVE_OPENSSL3, test "$ac_have_openssl3" = "1")
|
|
||||||
|
|
||||||
PKG_CHECK_MODULES(uuid, uuid,
|
PKG_CHECK_MODULES(uuid, uuid,
|
||||||
[],
|
[],
|
||||||
|
@ -68,7 +65,7 @@ PKG_CHECK_MODULES(uuid, uuid,
|
||||||
|
|
||||||
dnl gnu-efi headers require extra include dirs
|
dnl gnu-efi headers require extra include dirs
|
||||||
EFI_ARCH=$(uname -m | sed 's/i.86/ia32/;s/arm.*/arm/')
|
EFI_ARCH=$(uname -m | sed 's/i.86/ia32/;s/arm.*/arm/')
|
||||||
AM_CONDITIONAL(TEST_BINARY_FORMAT, [ test "$EFI_ARCH" = "arm" -o "$EFI_ARCH" = "aarch64" -o "$EFI_ARCH" = riscv64 ])
|
AM_CONDITIONAL(TEST_BINARY_FORMAT, [ test "$EFI_ARCH" = "arm" -o "$EFI_ARCH" = "aarch64" ])
|
||||||
|
|
||||||
##
|
##
|
||||||
# no consistent view of where gnu-efi should dump the efi stuff, so find it
|
# no consistent view of where gnu-efi should dump the efi stuff, so find it
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
|
|
||||||
man1_MANS = sbsign.1 sbverify.1 sbattach.1 sbvarsign.1 sbsiglist.1 \
|
man1_MANS = sbsign.1 sbverify.1 sbattach.1 sbvarsign.1 sbsiglist.1
|
||||||
sbkeysync.1
|
|
||||||
|
|
||||||
EXTRA_DIST = sbsign.1.in sbverify.1.in sbattach.1.in \
|
EXTRA_DIST = sbsign.1.in sbverify.1.in sbattach.1.in \
|
||||||
sbvarsign.1.in sbsiglist.1.in sbkeysync.1.in
|
sbvarsign.1.in sbsiglist.1.in
|
||||||
CLEANFILES = $(man1_MANS)
|
CLEANFILES = $(man1_MANS)
|
||||||
|
|
||||||
$(builddir)/%.1: $(srcdir)/%.1.in $(top_builddir)/src/%
|
$(builddir)/%.1: $(srcdir)/%.1.in $(top_builddir)/src/%
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[name]
|
|
||||||
sbkeysync - UEFI secure boot key synchronization tool
|
|
|
@ -4,14 +4,10 @@ bin_PROGRAMS = sbsign sbverify sbattach sbvarsign sbsiglist sbkeysync
|
||||||
coff_headers = coff/external.h coff/pe.h
|
coff_headers = coff/external.h coff/pe.h
|
||||||
AM_CFLAGS = -Wall -Wextra --std=gnu99
|
AM_CFLAGS = -Wall -Wextra --std=gnu99
|
||||||
|
|
||||||
if HAVE_OPENSSL3
|
|
||||||
AM_CFLAGS += -DOPENSSL_API_COMPAT=0x10100000L
|
|
||||||
endif
|
|
||||||
|
|
||||||
common_SOURCES = idc.c idc.h image.c image.h fileio.c fileio.h \
|
common_SOURCES = idc.c idc.h image.c image.h fileio.c fileio.h \
|
||||||
efivars.h $(coff_headers)
|
efivars.h $(coff_headers)
|
||||||
common_LDADD = ../lib/ccan/libccan.a $(libcrypto_LIBS)
|
common_LDADD = ../lib/ccan/libccan.a $(libcrypto_LIBS)
|
||||||
common_CFLAGS = -I$(top_srcdir)/lib/ccan/ -Werror
|
common_CFLAGS = -I$(top_srcdir)/lib/ccan/
|
||||||
|
|
||||||
sbsign_SOURCES = sbsign.c $(common_SOURCES)
|
sbsign_SOURCES = sbsign.c $(common_SOURCES)
|
||||||
sbsign_LDADD = $(common_LDADD)
|
sbsign_LDADD = $(common_LDADD)
|
||||||
|
|
|
@ -152,7 +152,6 @@
|
||||||
#define IMAGE_FILE_MACHINE_TRICORE 0x0520
|
#define IMAGE_FILE_MACHINE_TRICORE 0x0520
|
||||||
#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169
|
#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169
|
||||||
#define IMAGE_FILE_MACHINE_AARCH64 0xaa64
|
#define IMAGE_FILE_MACHINE_AARCH64 0xaa64
|
||||||
#define IMAGE_FILE_MACHINE_RISCV64 0x5064
|
|
||||||
|
|
||||||
#define IMAGE_SUBSYSTEM_UNKNOWN 0
|
#define IMAGE_SUBSYSTEM_UNKNOWN 0
|
||||||
#define IMAGE_SUBSYSTEM_NATIVE 1
|
#define IMAGE_SUBSYSTEM_NATIVE 1
|
||||||
|
|
10
src/idc.c
10
src/idc.c
|
@ -189,7 +189,7 @@ int IDC_set(PKCS7 *p7, PKCS7_SIGNER_INFO *si, struct image *image)
|
||||||
|
|
||||||
idc->data->type = OBJ_nid2obj(peid_nid);
|
idc->data->type = OBJ_nid2obj(peid_nid);
|
||||||
idc->data->value = ASN1_TYPE_new();
|
idc->data->value = ASN1_TYPE_new();
|
||||||
type_set_sequence(image, idc->data->value, peid, ASN1_ITEM_rptr(IDC_PEID));
|
type_set_sequence(image, idc->data->value, peid, &IDC_PEID_it);
|
||||||
|
|
||||||
idc->digest->alg->parameter = ASN1_TYPE_new();
|
idc->digest->alg->parameter = ASN1_TYPE_new();
|
||||||
idc->digest->alg->algorithm = OBJ_nid2obj(NID_sha256);
|
idc->digest->alg->algorithm = OBJ_nid2obj(NID_sha256);
|
||||||
|
@ -238,11 +238,7 @@ struct idc *IDC_get(PKCS7 *p7, BIO *bio)
|
||||||
|
|
||||||
/* extract the idc from the signed PKCS7 'other' data */
|
/* extract the idc from the signed PKCS7 'other' data */
|
||||||
str = p7->d.sign->contents->d.other->value.asn1_string;
|
str = p7->d.sign->contents->d.other->value.asn1_string;
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
||||||
idcbuf = buf = ASN1_STRING_data(str);
|
idcbuf = buf = ASN1_STRING_data(str);
|
||||||
#else
|
|
||||||
idcbuf = buf = ASN1_STRING_get0_data(str);
|
|
||||||
#endif
|
|
||||||
idc = d2i_IDC(NULL, &buf, ASN1_STRING_length(str));
|
idc = d2i_IDC(NULL, &buf, ASN1_STRING_length(str));
|
||||||
|
|
||||||
/* If we were passed a BIO, write the idc data, minus type and length,
|
/* If we were passed a BIO, write the idc data, minus type and length,
|
||||||
|
@ -293,11 +289,7 @@ int IDC_check_hash(struct idc *idc, struct image *image)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check hash against the one we calculated from the image */
|
/* check hash against the one we calculated from the image */
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
||||||
buf = ASN1_STRING_data(str);
|
buf = ASN1_STRING_data(str);
|
||||||
#else
|
|
||||||
buf = ASN1_STRING_get0_data(str);
|
|
||||||
#endif
|
|
||||||
if (memcmp(buf, sha, sizeof(sha))) {
|
if (memcmp(buf, sha, sizeof(sha))) {
|
||||||
fprintf(stderr, "Hash doesn't match image\n");
|
fprintf(stderr, "Hash doesn't match image\n");
|
||||||
fprintf(stderr, " got: %s\n", sha256_str(buf));
|
fprintf(stderr, " got: %s\n", sha256_str(buf));
|
||||||
|
|
|
@ -162,6 +162,7 @@ static void image_pecoff_update_checksum(struct image *image)
|
||||||
{
|
{
|
||||||
bool is_signed = image->sigsize && image->sigbuf;
|
bool is_signed = image->sigsize && image->sigbuf;
|
||||||
uint32_t checksum;
|
uint32_t checksum;
|
||||||
|
struct cert_table_header *cert_table = image->cert_table;
|
||||||
|
|
||||||
/* We carefully only include the signature data in the checksum (and
|
/* We carefully only include the signature data in the checksum (and
|
||||||
* in the file length) if we're outputting the signature. Otherwise,
|
* in the file length) if we're outputting the signature. Otherwise,
|
||||||
|
@ -179,13 +180,16 @@ static void image_pecoff_update_checksum(struct image *image)
|
||||||
(void *)(image->checksum + 1));
|
(void *)(image->checksum + 1));
|
||||||
|
|
||||||
if (is_signed) {
|
if (is_signed) {
|
||||||
|
checksum = csum_bytes(checksum,
|
||||||
|
cert_table, sizeof(*cert_table));
|
||||||
|
|
||||||
checksum = csum_bytes(checksum, image->sigbuf, image->sigsize);
|
checksum = csum_bytes(checksum, image->sigbuf, image->sigsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
checksum += image->data_size;
|
checksum += image->data_size;
|
||||||
|
|
||||||
if (is_signed)
|
if (is_signed)
|
||||||
checksum += image->sigsize;
|
checksum += sizeof(*cert_table) + image->sigsize;
|
||||||
|
|
||||||
*(image->checksum) = cpu_to_le32(checksum);
|
*(image->checksum) = cpu_to_le32(checksum);
|
||||||
}
|
}
|
||||||
|
@ -239,7 +243,6 @@ static int image_pecoff_parse(struct image *image)
|
||||||
switch (magic) {
|
switch (magic) {
|
||||||
case IMAGE_FILE_MACHINE_AMD64:
|
case IMAGE_FILE_MACHINE_AMD64:
|
||||||
case IMAGE_FILE_MACHINE_AARCH64:
|
case IMAGE_FILE_MACHINE_AARCH64:
|
||||||
case IMAGE_FILE_MACHINE_RISCV64:
|
|
||||||
rc = image_pecoff_parse_64(image);
|
rc = image_pecoff_parse_64(image);
|
||||||
break;
|
break;
|
||||||
case IMAGE_FILE_MACHINE_I386:
|
case IMAGE_FILE_MACHINE_I386:
|
||||||
|
|
|
@ -233,11 +233,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
ERR_load_crypto_strings();
|
ERR_load_crypto_strings();
|
||||||
OpenSSL_add_all_digests();
|
OpenSSL_add_all_digests();
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
||||||
OPENSSL_config(NULL);
|
OPENSSL_config(NULL);
|
||||||
#else
|
|
||||||
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
|
|
||||||
#endif
|
|
||||||
/* here we may get highly unlikely failures or we'll get a
|
/* here we may get highly unlikely failures or we'll get a
|
||||||
* complaint about FIPS signatures (usually becuase the FIPS
|
* complaint about FIPS signatures (usually becuase the FIPS
|
||||||
* module isn't present). In either case ignore the errors
|
* module isn't present). In either case ignore the errors
|
||||||
|
|
|
@ -54,11 +54,9 @@
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
#include "efivars.h"
|
#include "efivars.h"
|
||||||
|
|
||||||
static struct statfs statfstype;
|
|
||||||
|
|
||||||
#define EFIVARS_MOUNTPOINT "/sys/firmware/efi/efivars"
|
#define EFIVARS_MOUNTPOINT "/sys/firmware/efi/efivars"
|
||||||
#define PSTORE_FSTYPE ((typeof(statfstype.f_type))0x6165676C)
|
#define PSTORE_FSTYPE 0x6165676C
|
||||||
#define EFIVARS_FSTYPE ((typeof(statfstype.f_type))0xde5e81e4)
|
#define EFIVARS_FSTYPE 0xde5e81e4
|
||||||
|
|
||||||
#define EFI_IMAGE_SECURITY_DATABASE_GUID \
|
#define EFI_IMAGE_SECURITY_DATABASE_GUID \
|
||||||
{ 0xd719b2cb, 0x3d3a, 0x4596, \
|
{ 0xd719b2cb, 0x3d3a, 0x4596, \
|
||||||
|
@ -210,11 +208,7 @@ static int x509_key_parse(struct key *key, uint8_t *data, size_t len)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
key->id_len = ASN1_STRING_length(serial);
|
key->id_len = ASN1_STRING_length(serial);
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
||||||
key->id = talloc_memdup(key, ASN1_STRING_data(serial), key->id_len);
|
key->id = talloc_memdup(key, ASN1_STRING_data(serial), key->id_len);
|
||||||
#else
|
|
||||||
key->id = talloc_memdup(key, ASN1_STRING_get0_data(serial), key->id_len);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
key->description = talloc_array(key, char, description_len);
|
key->description = talloc_array(key, char, description_len);
|
||||||
X509_NAME_oneline(X509_get_subject_name(x509),
|
X509_NAME_oneline(X509_get_subject_name(x509),
|
||||||
|
@ -889,12 +883,10 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
bool use_default_keystore_dirs;
|
bool use_default_keystore_dirs;
|
||||||
struct sync_context *ctx;
|
struct sync_context *ctx;
|
||||||
int rc;
|
|
||||||
|
|
||||||
use_default_keystore_dirs = true;
|
use_default_keystore_dirs = true;
|
||||||
ctx = talloc_zero(NULL, struct sync_context);
|
ctx = talloc_zero(NULL, struct sync_context);
|
||||||
list_head_init(&ctx->new_keys);
|
list_head_init(&ctx->new_keys);
|
||||||
rc = EXIT_SUCCESS;
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int idx, c;
|
int idx, c;
|
||||||
|
@ -938,11 +930,7 @@ int main(int argc, char **argv)
|
||||||
ERR_load_crypto_strings();
|
ERR_load_crypto_strings();
|
||||||
OpenSSL_add_all_digests();
|
OpenSSL_add_all_digests();
|
||||||
OpenSSL_add_all_ciphers();
|
OpenSSL_add_all_ciphers();
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
||||||
OPENSSL_config(NULL);
|
OPENSSL_config(NULL);
|
||||||
#else
|
|
||||||
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
|
|
||||||
#endif
|
|
||||||
/* here we may get highly unlikely failures or we'll get a
|
/* here we may get highly unlikely failures or we'll get a
|
||||||
* complaint about FIPS signatures (usually becuase the FIPS
|
* complaint about FIPS signatures (usually becuase the FIPS
|
||||||
* module isn't present). In either case ignore the errors
|
* module isn't present). In either case ignore the errors
|
||||||
|
@ -987,10 +975,10 @@ int main(int argc, char **argv)
|
||||||
if (ctx->verbose)
|
if (ctx->verbose)
|
||||||
print_new_keys(ctx);
|
print_new_keys(ctx);
|
||||||
|
|
||||||
if (!ctx->dry_run && insert_new_keys(ctx))
|
if (!ctx->dry_run)
|
||||||
rc = EXIT_FAILURE;
|
insert_new_keys(ctx);
|
||||||
|
|
||||||
talloc_free(ctx);
|
talloc_free(ctx);
|
||||||
|
|
||||||
return rc;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
54
src/sbsign.c
54
src/sbsign.c
|
@ -49,8 +49,6 @@
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/asn1.h>
|
#include <openssl/asn1.h>
|
||||||
#include <openssl/asn1t.h>
|
#include <openssl/asn1t.h>
|
||||||
#include <openssl/bio.h>
|
|
||||||
#include <openssl/x509.h>
|
|
||||||
|
|
||||||
#include <ccan/talloc/talloc.h>
|
#include <ccan/talloc/talloc.h>
|
||||||
|
|
||||||
|
@ -77,7 +75,6 @@ static struct option options[] = {
|
||||||
{ "help", no_argument, NULL, 'h' },
|
{ "help", no_argument, NULL, 'h' },
|
||||||
{ "version", no_argument, NULL, 'V' },
|
{ "version", no_argument, NULL, 'V' },
|
||||||
{ "engine", required_argument, NULL, 'e'},
|
{ "engine", required_argument, NULL, 'e'},
|
||||||
{ "addcert", required_argument, NULL, 'a'},
|
|
||||||
{ NULL, 0, NULL, 0 },
|
{ NULL, 0, NULL, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -91,7 +88,6 @@ static void usage(void)
|
||||||
"\t--key <keyfile> signing key (PEM-encoded RSA "
|
"\t--key <keyfile> signing key (PEM-encoded RSA "
|
||||||
"private key)\n"
|
"private key)\n"
|
||||||
"\t--cert <certfile> certificate (x509 certificate)\n"
|
"\t--cert <certfile> certificate (x509 certificate)\n"
|
||||||
"\t--addcert <addcertfile> additional intermediate certificates in a file\n"
|
|
||||||
"\t--detached write a detached signature, instead of\n"
|
"\t--detached write a detached signature, instead of\n"
|
||||||
"\t a signed binary\n"
|
"\t a signed binary\n"
|
||||||
"\t--output <file> write signed data to <file>\n"
|
"\t--output <file> write signed data to <file>\n"
|
||||||
|
@ -116,43 +112,9 @@ static void set_default_outfilename(struct sign_context *ctx)
|
||||||
ctx->infilename, extension);
|
ctx->infilename, extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int add_intermediate_certs(PKCS7 *p7, const char *filename)
|
|
||||||
{
|
|
||||||
STACK_OF(X509_INFO) *certs;
|
|
||||||
X509_INFO *cert;
|
|
||||||
BIO *bio = NULL;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
bio = BIO_new(BIO_s_file());
|
|
||||||
if (!bio || BIO_read_filename(bio, filename) <=0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"error in reading intermediate certificates file\n");
|
|
||||||
ERR_print_errors_fp(stderr);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
certs = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
|
|
||||||
if (!certs) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"error in parsing intermediate certificates file\n");
|
|
||||||
ERR_print_errors_fp(stderr);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < sk_X509_INFO_num(certs); i++) {
|
|
||||||
cert = sk_X509_INFO_value(certs, i);
|
|
||||||
PKCS7_add_certificate(p7, cert->x509);
|
|
||||||
}
|
|
||||||
|
|
||||||
sk_X509_INFO_pop_free(certs, X509_INFO_free);
|
|
||||||
BIO_free_all(bio);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
const char *keyfilename, *certfilename, *addcertfilename, *engine;
|
const char *keyfilename, *certfilename, *engine;
|
||||||
struct sign_context *ctx;
|
struct sign_context *ctx;
|
||||||
uint8_t *buf, *tmp;
|
uint8_t *buf, *tmp;
|
||||||
int rc, c, sigsize;
|
int rc, c, sigsize;
|
||||||
|
@ -162,12 +124,11 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
keyfilename = NULL;
|
keyfilename = NULL;
|
||||||
certfilename = NULL;
|
certfilename = NULL;
|
||||||
addcertfilename = NULL;
|
|
||||||
engine = NULL;
|
engine = NULL;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int idx;
|
int idx;
|
||||||
c = getopt_long(argc, argv, "o:c:k:dvVhe:a:", options, &idx);
|
c = getopt_long(argc, argv, "o:c:k:dvVhe:", options, &idx);
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -196,9 +157,6 @@ int main(int argc, char **argv)
|
||||||
case 'e':
|
case 'e':
|
||||||
engine = optarg;
|
engine = optarg;
|
||||||
break;
|
break;
|
||||||
case 'a':
|
|
||||||
addcertfilename = optarg;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,14 +189,9 @@ int main(int argc, char **argv)
|
||||||
talloc_steal(ctx, ctx->image);
|
talloc_steal(ctx, ctx->image);
|
||||||
|
|
||||||
ERR_load_crypto_strings();
|
ERR_load_crypto_strings();
|
||||||
ERR_load_BIO_strings();
|
|
||||||
OpenSSL_add_all_digests();
|
OpenSSL_add_all_digests();
|
||||||
OpenSSL_add_all_ciphers();
|
OpenSSL_add_all_ciphers();
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
||||||
OPENSSL_config(NULL);
|
OPENSSL_config(NULL);
|
||||||
#else
|
|
||||||
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
|
|
||||||
#endif
|
|
||||||
/* here we may get highly unlikely failures or we'll get a
|
/* here we may get highly unlikely failures or we'll get a
|
||||||
* complaint about FIPS signatures (usually becuase the FIPS
|
* complaint about FIPS signatures (usually becuase the FIPS
|
||||||
* module isn't present). In either case ignore the errors
|
* module isn't present). In either case ignore the errors
|
||||||
|
@ -275,9 +228,6 @@ int main(int argc, char **argv)
|
||||||
if (rc)
|
if (rc)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
if (addcertfilename && add_intermediate_certs(p7, addcertfilename))
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
|
|
||||||
sigsize = i2d_PKCS7(p7, NULL);
|
sigsize = i2d_PKCS7(p7, NULL);
|
||||||
tmp = buf = talloc_array(ctx->image, uint8_t, sigsize);
|
tmp = buf = talloc_array(ctx->image, uint8_t, sigsize);
|
||||||
i2d_PKCS7(p7, &tmp);
|
i2d_PKCS7(p7, &tmp);
|
||||||
|
|
|
@ -105,6 +105,7 @@ static uint32_t default_attrs = EFI_VARIABLE_NON_VOLATILE |
|
||||||
static uint32_t attr_invalid = 0xffffffffu;
|
static uint32_t attr_invalid = 0xffffffffu;
|
||||||
static const char *attr_prefix = "EFI_VARIABLE_";
|
static const char *attr_prefix = "EFI_VARIABLE_";
|
||||||
|
|
||||||
|
static const EFI_GUID default_guid = EFI_GLOBAL_VARIABLE;
|
||||||
static const EFI_GUID cert_pkcs7_guid = EFI_CERT_TYPE_PKCS7_GUID;
|
static const EFI_GUID cert_pkcs7_guid = EFI_CERT_TYPE_PKCS7_GUID;
|
||||||
|
|
||||||
static void set_default_outfilename(struct varsign_context *ctx)
|
static void set_default_outfilename(struct varsign_context *ctx)
|
||||||
|
@ -211,7 +212,7 @@ static int set_timestamp(EFI_TIME *timestamp)
|
||||||
/* copy to our EFI-specific time structure. Other fields (Nanosecond,
|
/* copy to our EFI-specific time structure. Other fields (Nanosecond,
|
||||||
* TimeZone, Daylight and Pad) are defined to be zero */
|
* TimeZone, Daylight and Pad) are defined to be zero */
|
||||||
memset(timestamp, 0, sizeof(*timestamp));
|
memset(timestamp, 0, sizeof(*timestamp));
|
||||||
timestamp->Year = 1900 + tm->tm_year;
|
timestamp->Year = tm->tm_year;
|
||||||
timestamp->Month = tm->tm_mon;
|
timestamp->Month = tm->tm_mon;
|
||||||
timestamp->Day = tm->tm_mday;
|
timestamp->Day = tm->tm_mday;
|
||||||
timestamp->Hour = tm->tm_hour;
|
timestamp->Hour = tm->tm_hour;
|
||||||
|
@ -251,7 +252,7 @@ static int add_auth_descriptor(struct varsign_context *ctx)
|
||||||
md = EVP_get_digestbyname("SHA256");
|
md = EVP_get_digestbyname("SHA256");
|
||||||
|
|
||||||
p7 = PKCS7_new();
|
p7 = PKCS7_new();
|
||||||
flags = PKCS7_BINARY | PKCS7_DETACHED | PKCS7_NOSMIMECAP | PKCS7_NOATTR;;
|
flags = PKCS7_BINARY | PKCS7_DETACHED | PKCS7_NOSMIMECAP;;
|
||||||
PKCS7_set_type(p7, NID_pkcs7_signed);
|
PKCS7_set_type(p7, NID_pkcs7_signed);
|
||||||
|
|
||||||
PKCS7_content_new(p7, NID_pkcs7_data);
|
PKCS7_content_new(p7, NID_pkcs7_data);
|
||||||
|
@ -332,7 +333,7 @@ int write_signed(struct varsign_context *ctx, int include_attrs)
|
||||||
printf("Wrote signed data:\n");
|
printf("Wrote signed data:\n");
|
||||||
if (include_attrs) {
|
if (include_attrs) {
|
||||||
i = sizeof(ctx->var_attrs);
|
i = sizeof(ctx->var_attrs);
|
||||||
printf(" [%04lx:%04zx] attrs\n", 0l, i);
|
printf(" [%04zx:%04zx] attrs\n", 0l, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(" [%04zx:%04x] authentication descriptor\n",
|
printf(" [%04zx:%04x] authentication descriptor\n",
|
||||||
|
@ -512,11 +513,7 @@ int main(int argc, char **argv)
|
||||||
OpenSSL_add_all_digests();
|
OpenSSL_add_all_digests();
|
||||||
OpenSSL_add_all_ciphers();
|
OpenSSL_add_all_ciphers();
|
||||||
ERR_load_crypto_strings();
|
ERR_load_crypto_strings();
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
||||||
OPENSSL_config(NULL);
|
OPENSSL_config(NULL);
|
||||||
#else
|
|
||||||
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
|
|
||||||
#endif
|
|
||||||
/* here we may get highly unlikely failures or we'll get a
|
/* here we may get highly unlikely failures or we'll get a
|
||||||
* complaint about FIPS signatures (usually becuase the FIPS
|
* complaint about FIPS signatures (usually becuase the FIPS
|
||||||
* module isn't present). In either case ignore the errors
|
* module isn't present). In either case ignore the errors
|
||||||
|
|
|
@ -210,7 +210,8 @@ static int x509_verify_cb(int status, X509_STORE_CTX *ctx)
|
||||||
== XKU_CODE_SIGN)
|
== XKU_CODE_SIGN)
|
||||||
status = 1;
|
status = 1;
|
||||||
|
|
||||||
else if (err == X509_V_ERR_CERT_UNTRUSTED ||
|
else if (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY ||
|
||||||
|
err == X509_V_ERR_CERT_UNTRUSTED ||
|
||||||
err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT ||
|
err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT ||
|
||||||
err == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE) {
|
err == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE) {
|
||||||
/* all certs given with the --cert argument are trusted */
|
/* all certs given with the --cert argument are trusted */
|
||||||
|
@ -220,7 +221,6 @@ static int x509_verify_cb(int status, X509_STORE_CTX *ctx)
|
||||||
} else if (err == X509_V_ERR_CERT_HAS_EXPIRED ||
|
} else if (err == X509_V_ERR_CERT_HAS_EXPIRED ||
|
||||||
err == X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD ||
|
err == X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD ||
|
||||||
err == X509_V_ERR_CERT_NOT_YET_VALID ||
|
err == X509_V_ERR_CERT_NOT_YET_VALID ||
|
||||||
err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY ||
|
|
||||||
err == X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD)
|
err == X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD)
|
||||||
/* UEFI explicitly allows expired certificates */
|
/* UEFI explicitly allows expired certificates */
|
||||||
status = 1;
|
status = 1;
|
||||||
|
@ -239,7 +239,7 @@ int main(int argc, char **argv)
|
||||||
uint8_t *sig_buf;
|
uint8_t *sig_buf;
|
||||||
size_t sig_size;
|
size_t sig_size;
|
||||||
struct idc *idc;
|
struct idc *idc;
|
||||||
int verbose;
|
bool verbose;
|
||||||
BIO *idcbio;
|
BIO *idcbio;
|
||||||
PKCS7 *p7;
|
PKCS7 *p7;
|
||||||
int sig_count = 0;
|
int sig_count = 0;
|
||||||
|
@ -247,16 +247,12 @@ int main(int argc, char **argv)
|
||||||
status = VERIFY_FAIL;
|
status = VERIFY_FAIL;
|
||||||
certs = X509_STORE_new();
|
certs = X509_STORE_new();
|
||||||
list = 0;
|
list = 0;
|
||||||
verbose = 0;
|
verbose = false;
|
||||||
detached_sig_filename = NULL;
|
detached_sig_filename = NULL;
|
||||||
|
|
||||||
OpenSSL_add_all_digests();
|
OpenSSL_add_all_digests();
|
||||||
ERR_load_crypto_strings();
|
ERR_load_crypto_strings();
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
||||||
OPENSSL_config(NULL);
|
OPENSSL_config(NULL);
|
||||||
#else
|
|
||||||
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
|
|
||||||
#endif
|
|
||||||
/* here we may get highly unlikely failures or we'll get a
|
/* here we may get highly unlikely failures or we'll get a
|
||||||
* complaint about FIPS signatures (usually becuase the FIPS
|
* complaint about FIPS signatures (usually becuase the FIPS
|
||||||
* module isn't present). In either case ignore the errors
|
* module isn't present). In either case ignore the errors
|
||||||
|
@ -282,7 +278,7 @@ int main(int argc, char **argv)
|
||||||
list = 1;
|
list = 1;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
verbose++;
|
verbose = true;
|
||||||
break;
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
version();
|
version();
|
||||||
|
@ -337,8 +333,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
if (verbose || list) {
|
if (verbose || list) {
|
||||||
print_signature_info(p7);
|
print_signature_info(p7);
|
||||||
if (verbose > 1)
|
//print_certificate_store_certs(certs);
|
||||||
print_certificate_store_certs(certs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list)
|
if (list)
|
||||||
|
|
|
@ -3,10 +3,6 @@ AUTOMAKE_OPTIONS = parallel-tests
|
||||||
|
|
||||||
test_key = private-key.rsa
|
test_key = private-key.rsa
|
||||||
test_cert = public-cert.pem
|
test_cert = public-cert.pem
|
||||||
ca_key = ca-key.ec
|
|
||||||
ca_cert = ca-cert.pem
|
|
||||||
int_key = int-key.ec
|
|
||||||
int_cert = int-cert.pem
|
|
||||||
test_arches = $(EFI_ARCH)
|
test_arches = $(EFI_ARCH)
|
||||||
|
|
||||||
check_PROGRAMS = test.pecoff
|
check_PROGRAMS = test.pecoff
|
||||||
|
@ -35,25 +31,11 @@ check_SCRIPTS = test-wrapper.sh
|
||||||
|
|
||||||
AM_CFLAGS=-fpic -I/usr/include/efi -I/usr/include/efi/$(EFI_ARCH)
|
AM_CFLAGS=-fpic -I/usr/include/efi -I/usr/include/efi/$(EFI_ARCH)
|
||||||
|
|
||||||
%.rsa: Makefile
|
$(test_key): Makefile
|
||||||
openssl genrsa -out $@ 2048
|
openssl genrsa -out $@ 2048
|
||||||
|
|
||||||
%.ec: Makefile
|
$(test_cert): $(test_key) Makefile
|
||||||
openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:prime256v1 -out $@
|
openssl req -x509 -sha256 -subj '/' -new -key $< -out $@
|
||||||
|
|
||||||
$(ca_cert): $(ca_key) Makefile
|
|
||||||
openssl req -x509 -days 1 -sha256 -subj '/CN=CA Key/' -new -key $< -out $@
|
|
||||||
|
|
||||||
$(int_cert): $(int_key) $(ca_cert) Makefile
|
|
||||||
openssl req -new -subj '/CN=Intermediate Certificate/' -key $< -out tmp.req
|
|
||||||
echo -e "[ca]\nbasicConstraints = critical, CA:true\n" > ca.cnf
|
|
||||||
openssl x509 -req -sha256 -CA $(ca_cert) -CAkey $(ca_key) -in tmp.req -set_serial 1 -days 1 -extfile ca.cnf -extensions ca -out $@
|
|
||||||
-rm -f tmp.req ca.cnf
|
|
||||||
|
|
||||||
$(test_cert): $(test_key) $(int_cert) Makefile
|
|
||||||
openssl req -new -subj '/CN=Signer Certificate/' -key $< -out tmp.req
|
|
||||||
openssl x509 -req -sha256 -CA $(int_cert) -CAkey $(int_key) -in tmp.req -set_serial 1 -days 1 -out $@
|
|
||||||
-rm -f tmp.req
|
|
||||||
|
|
||||||
TESTS = sign-verify.sh \
|
TESTS = sign-verify.sh \
|
||||||
sign-verify-detached.sh \
|
sign-verify-detached.sh \
|
||||||
|
@ -83,5 +65,4 @@ AM_TESTS_ENVIRONMENT = TEST_ARCHES='$(test_arches)'; export TEST_ARCHES;
|
||||||
SH_LOG_COMPILER = $(srcdir)/test-wrapper.sh
|
SH_LOG_COMPILER = $(srcdir)/test-wrapper.sh
|
||||||
|
|
||||||
EXTRA_DIST = test.S $(TESTS) $(check_SCRIPTS)
|
EXTRA_DIST = test.S $(TESTS) $(check_SCRIPTS)
|
||||||
CLEANFILES = $(test_key) $(test_cert) $(int_key) $(int_cert) $(ca_key) \
|
CLEANFILES = $(test_key) $(test_cert)
|
||||||
$(ca_cert)
|
|
||||||
|
|
|
@ -3,19 +3,7 @@
|
||||||
sig="test.sig"
|
sig="test.sig"
|
||||||
signed="test.signed"
|
signed="test.signed"
|
||||||
|
|
||||||
"$sbsign" --cert "$cert" --key "$key" --detached --output "$sig" "$image" || exit 1
|
"$sbsign" --cert "$cert" --key "$key" --detached --output "$sig" "$image"
|
||||||
cp "$image" "$signed" || exit 1
|
cp "$image" "$signed"
|
||||||
"$sbattach" --attach "$sig" "$signed" || exit 1
|
"$sbattach" --attach "$sig" "$signed"
|
||||||
"$sbverify" --cert "$cert" "$signed" || exit 1
|
"$sbverify" --cert "$cert" "$signed"
|
||||||
"$sbverify" --cert "$intcert" "$signed" || exit 1
|
|
||||||
# there's no intermediate cert in the image so it can't chain to the ca which
|
|
||||||
# is why this should fail
|
|
||||||
"$sbverify" --cert "$cacert" "$signed" && exit 1
|
|
||||||
|
|
||||||
# now add intermediates
|
|
||||||
"$sbsign" --cert "$cert" --key "$key" --addcert "$intcert" --detached --output "$sig" "$image" || exit 1
|
|
||||||
cp "$image" "$signed" || exit 1
|
|
||||||
"$sbattach" --attach "$sig" "$signed" || exit 1
|
|
||||||
"$sbverify" --cert "$cert" "$signed" || exit 1
|
|
||||||
"$sbverify" --cert "$intcert" "$signed" || exit 1
|
|
||||||
"$sbverify" --cert "$cacert" "$signed" || exit 1
|
|
||||||
|
|
|
@ -2,16 +2,5 @@
|
||||||
|
|
||||||
sig="test.sig"
|
sig="test.sig"
|
||||||
|
|
||||||
"$sbsign" --cert "$cert" --key "$key" --detached --output $sig "$image" || exit 1
|
"$sbsign" --cert "$cert" --key "$key" --detached --output $sig "$image"
|
||||||
"$sbverify" --cert "$cert" --detached $sig "$image" || exit 1
|
"$sbverify" --cert "$cert" --detached $sig "$image"
|
||||||
"$sbverify" --cert "$intcert" --detached $sig "$image" || exit 1
|
|
||||||
# should fail because no intermediate
|
|
||||||
"$sbverify" --cert "$cacert" --detached $sig "$image" && exit 1
|
|
||||||
|
|
||||||
# now make sure everything succeeds with the intermediate added
|
|
||||||
"$sbsign" --cert "$cert" --key "$key" --addcert "$intcert" --detached --output $sig "$image" || exit 1
|
|
||||||
"$sbverify" --cert "$cert" --detached $sig "$image" || exit 1
|
|
||||||
"$sbverify" --cert "$intcert" --detached $sig "$image" || exit 1
|
|
||||||
"$sbverify" --cert "$cacert" --detached $sig "$image" || exit 1
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
|
|
|
@ -2,16 +2,5 @@
|
||||||
|
|
||||||
signed="test.signed"
|
signed="test.signed"
|
||||||
|
|
||||||
"$sbsign" --cert "$cert" --key "$key" --output "$signed" "$image" || exit 1
|
"$sbsign" --cert "$cert" --key "$key" --output "$signed" "$image"
|
||||||
"$sbverify" --cert "$cert" "$signed" || exit 1
|
"$sbverify" --cert "$cert" "$signed"
|
||||||
"$sbverify" --cert "$intcert" "$signed" || exit 1
|
|
||||||
# there's no intermediate cert in the image so it can't chain to the ca which
|
|
||||||
# is why this should fail
|
|
||||||
"$sbverify" --cert "$cacert" "$signed" && exit 1
|
|
||||||
|
|
||||||
# now add the intermediates and each level should succeed
|
|
||||||
"$sbsign" --cert "$cert" --addcert "$intcert" --key "$key" --output "$signed" "$image" || exit 1
|
|
||||||
"$sbverify" --cert "$cert" "$signed" || exit 1
|
|
||||||
"$sbverify" --cert "$intcert" "$signed" || exit 1
|
|
||||||
"$sbverify" --cert "$cacert" "$signed" || exit 1
|
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,8 @@ sbattach=$bindir/sbattach
|
||||||
|
|
||||||
key="$datadir/private-key.rsa"
|
key="$datadir/private-key.rsa"
|
||||||
cert="$datadir/public-cert.pem"
|
cert="$datadir/public-cert.pem"
|
||||||
intkey="$datadir/int-key.ec"
|
|
||||||
intcert="$datadir/int-cert.pem"
|
|
||||||
cakey="$datadir/ca-key.ec"
|
|
||||||
cacert="$datadir/ca-cert.pem"
|
|
||||||
|
|
||||||
export basedir datadir bindir sbsign sbverify sbattach key cert intkey intcert cakey cacert
|
export basedir datadir bindir sbsign sbverify sbattach key cert
|
||||||
|
|
||||||
# 'test' needs to be an absolute path, as we will cd to a temporary
|
# 'test' needs to be an absolute path, as we will cd to a temporary
|
||||||
# directory before running the test
|
# directory before running the test
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue