sbsign, sbattach, sbverify: add multiple signature support
sbsign will sign an already signed binary (adding a signature at the end) sbverify has a new mode --list, for listing all the signatures and sbattach takes a --signum argument for --remove or --detach. Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
6b493361c2
commit
f6115a8045
5 changed files with 211 additions and 128 deletions
139
src/image.c
139
src/image.c
|
@ -129,6 +129,11 @@ static int image_pecoff_parse_64(struct image *image)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int align_up(int size, int align)
|
||||||
|
{
|
||||||
|
return (size + align - 1) & ~(align - 1);
|
||||||
|
}
|
||||||
|
|
||||||
static int image_pecoff_parse(struct image *image)
|
static int image_pecoff_parse(struct image *image)
|
||||||
{
|
{
|
||||||
struct cert_table_header *cert_table;
|
struct cert_table_header *cert_table;
|
||||||
|
@ -224,12 +229,12 @@ static int image_pecoff_parse(struct image *image)
|
||||||
image->cert_table = cert_table;
|
image->cert_table = cert_table;
|
||||||
|
|
||||||
/* if we have a valid cert table header, populate sigbuf as a shadow
|
/* if we have a valid cert table header, populate sigbuf as a shadow
|
||||||
* copy of the cert table */
|
* copy of the cert tables */
|
||||||
if (cert_table && cert_table->revision == CERT_TABLE_REVISION &&
|
if (cert_table && cert_table->revision == CERT_TABLE_REVISION &&
|
||||||
cert_table->type == CERT_TABLE_TYPE_PKCS &&
|
cert_table->type == CERT_TABLE_TYPE_PKCS &&
|
||||||
cert_table->size < size) {
|
cert_table->size < size) {
|
||||||
image->sigsize = cert_table->size;
|
image->sigsize = image->data_dir_sigtable->size;
|
||||||
image->sigbuf = talloc_memdup(image, cert_table + 1,
|
image->sigbuf = talloc_memdup(image, cert_table,
|
||||||
image->sigsize);
|
image->sigsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,11 +244,6 @@ static int image_pecoff_parse(struct image *image)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int align_up(int size, int align)
|
|
||||||
{
|
|
||||||
return (size + align - 1) & ~(align - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cmp_regions(const void *p1, const void *p2)
|
static int cmp_regions(const void *p1, const void *p2)
|
||||||
{
|
{
|
||||||
const struct region *r1 = p1, *r2 = p2;
|
const struct region *r1 = p1, *r2 = p2;
|
||||||
|
@ -482,48 +482,106 @@ int image_hash_sha256(struct image *image, uint8_t digest[])
|
||||||
|
|
||||||
int image_add_signature(struct image *image, void *sig, int size)
|
int image_add_signature(struct image *image, void *sig, int size)
|
||||||
{
|
{
|
||||||
/* we only support one signature at present */
|
struct cert_table_header *cth;
|
||||||
|
int tot_size = size + sizeof(*cth);
|
||||||
|
int aligned_size = align_up(tot_size, 8);
|
||||||
|
void *start;
|
||||||
|
|
||||||
if (image->sigbuf) {
|
if (image->sigbuf) {
|
||||||
fprintf(stderr, "warning: overwriting existing signature\n");
|
fprintf(stderr, "Image was already signed; adding additional signature\n");
|
||||||
talloc_free(image->sigbuf);
|
image->sigbuf = talloc_realloc(image, image->sigbuf, uint8_t,
|
||||||
|
image->sigsize + aligned_size);
|
||||||
|
start = image->sigbuf + image->sigsize;
|
||||||
|
image->sigsize += aligned_size;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Signing Unsigned original image\n");
|
||||||
|
start = image->sigbuf = talloc_array(image, uint8_t, aligned_size);
|
||||||
|
image->sigsize = aligned_size;
|
||||||
}
|
}
|
||||||
image->sigbuf = sig;
|
cth = start;
|
||||||
image->sigsize = size;
|
start += sizeof(*cth);
|
||||||
|
memset(cth, 0 , sizeof(*cth));
|
||||||
|
cth->size = tot_size;
|
||||||
|
cth->revision = CERT_TABLE_REVISION;
|
||||||
|
cth->type = CERT_TABLE_TYPE_PKCS;
|
||||||
|
memcpy(start, sig, size);
|
||||||
|
if (aligned_size != tot_size)
|
||||||
|
memset(start + size, 0, aligned_size - tot_size);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void image_remove_signature(struct image *image)
|
int image_get_signature(struct image *image, int signum,
|
||||||
|
uint8_t **buf, size_t *size)
|
||||||
{
|
{
|
||||||
if (image->sigbuf)
|
struct cert_table_header *header;
|
||||||
|
void *addr = (void *)image->sigbuf;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!image->sigbuf) {
|
||||||
|
fprintf(stderr, "No signature table present\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
header = addr;
|
||||||
|
for (i = 0; i < signum; i++) {
|
||||||
|
addr += align_up(header->size, 8);
|
||||||
|
header = addr;
|
||||||
|
}
|
||||||
|
if (addr >= ((void *)image->sigbuf +
|
||||||
|
image->sigsize))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*buf = (void *)(header + 1);
|
||||||
|
*size = header->size - sizeof(*header);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int image_remove_signature(struct image *image, int signum)
|
||||||
|
{
|
||||||
|
uint8_t *buf;
|
||||||
|
size_t size, aligned_size;
|
||||||
|
int rc = image_get_signature(image, signum, &buf, &size);
|
||||||
|
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
buf -= sizeof(struct cert_table_header);
|
||||||
|
size += sizeof(struct cert_table_header);
|
||||||
|
aligned_size = align_up(size, 8);
|
||||||
|
|
||||||
|
/* is signature at the end? */
|
||||||
|
if (buf + aligned_size >= (uint8_t *)image->sigbuf + image->sigsize) {
|
||||||
|
/* only one signature? */
|
||||||
|
if (image->sigbuf == buf) {
|
||||||
talloc_free(image->sigbuf);
|
talloc_free(image->sigbuf);
|
||||||
image->sigbuf = NULL;
|
image->sigbuf = NULL;
|
||||||
image->sigsize = 0;
|
image->sigsize = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* sig is in the middle ... just copy the rest over it */
|
||||||
|
memmove(buf, buf + aligned_size, image->sigsize -
|
||||||
|
((void *)buf - image->sigbuf) - aligned_size);
|
||||||
|
}
|
||||||
|
image->sigsize -= aligned_size;
|
||||||
|
image->sigbuf = talloc_realloc(image, image->sigbuf, uint8_t,
|
||||||
|
image->sigsize);
|
||||||
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int image_write(struct image *image, const char *filename)
|
int image_write(struct image *image, const char *filename)
|
||||||
{
|
{
|
||||||
struct cert_table_header cert_table_header;
|
int fd, rc;
|
||||||
int fd, rc, len, padlen;
|
|
||||||
bool is_signed;
|
bool is_signed;
|
||||||
uint8_t pad[8];
|
|
||||||
|
|
||||||
is_signed = image->sigbuf && image->sigsize;
|
is_signed = image->sigbuf && image->sigsize;
|
||||||
padlen = 0;
|
|
||||||
|
|
||||||
/* optionally update the image to contain signature data */
|
/* optionally update the image to contain signature data */
|
||||||
if (is_signed) {
|
if (is_signed) {
|
||||||
cert_table_header.size = image->sigsize +
|
|
||||||
sizeof(cert_table_header);
|
|
||||||
cert_table_header.revision = CERT_TABLE_REVISION;
|
|
||||||
cert_table_header.type = CERT_TABLE_TYPE_PKCS;
|
|
||||||
|
|
||||||
len = sizeof(cert_table_header) + image->sigsize;
|
|
||||||
|
|
||||||
/* pad to sizeof(pad)-byte boundary */
|
|
||||||
padlen = align_up(len, sizeof(pad)) - len;
|
|
||||||
|
|
||||||
image->data_dir_sigtable->addr = image->data_size;
|
image->data_dir_sigtable->addr = image->data_size;
|
||||||
image->data_dir_sigtable->size = len + padlen;
|
image->data_dir_sigtable->size = image->sigsize;
|
||||||
} else {
|
} else {
|
||||||
image->data_dir_sigtable->addr = 0;
|
image->data_dir_sigtable->addr = 0;
|
||||||
image->data_dir_sigtable->size = 0;
|
image->data_dir_sigtable->size = 0;
|
||||||
|
@ -541,25 +599,24 @@ int image_write(struct image *image, const char *filename)
|
||||||
if (!is_signed)
|
if (!is_signed)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rc = write_all(fd, &cert_table_header, sizeof(cert_table_header));
|
|
||||||
if (!rc)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
rc = write_all(fd, image->sigbuf, image->sigsize);
|
rc = write_all(fd, image->sigbuf, image->sigsize);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (padlen) {
|
|
||||||
memset(pad, 0, sizeof(pad));
|
|
||||||
rc = write_all(fd, pad, padlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
close(fd);
|
close(fd);
|
||||||
return !rc;
|
return !rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int image_write_detached(struct image *image, const char *filename)
|
int image_write_detached(struct image *image, int signum, const char *filename)
|
||||||
{
|
{
|
||||||
return fileio_write_file(filename, image->sigbuf, image->sigsize);
|
uint8_t *sig;
|
||||||
|
size_t len;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = image_get_signature(image, signum, &sig, &len);
|
||||||
|
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
return fileio_write_file(filename, sig, len);
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,9 +107,11 @@ struct image *image_load(const char *filename);
|
||||||
|
|
||||||
int image_hash_sha256(struct image *image, uint8_t digest[]);
|
int image_hash_sha256(struct image *image, uint8_t digest[]);
|
||||||
int image_add_signature(struct image *, void *sig, int size);
|
int image_add_signature(struct image *, void *sig, int size);
|
||||||
void image_remove_signature(struct image *image);
|
int image_get_signature(struct image *image, int signum,
|
||||||
|
uint8_t **buf, size_t *size);
|
||||||
|
int image_remove_signature(struct image *image, int signum);
|
||||||
int image_write(struct image *image, const char *filename);
|
int image_write(struct image *image, const char *filename);
|
||||||
int image_write_detached(struct image *image, const char *filename);
|
int image_write_detached(struct image *image, int signum, const char *filename);
|
||||||
|
|
||||||
#endif /* IMAGE_H */
|
#endif /* IMAGE_H */
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ static struct option options[] = {
|
||||||
{ "remove", no_argument, NULL, 'r' },
|
{ "remove", no_argument, NULL, 'r' },
|
||||||
{ "help", no_argument, NULL, 'h' },
|
{ "help", no_argument, NULL, 'h' },
|
||||||
{ "version", no_argument, NULL, 'V' },
|
{ "version", no_argument, NULL, 'V' },
|
||||||
|
{ "signum", required_argument, NULL, 's' },
|
||||||
{ NULL, 0, NULL, 0 },
|
{ NULL, 0, NULL, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -80,7 +81,9 @@ static void usage(void)
|
||||||
"\t--detach <sigfile> copy the boot image's signature table\n"
|
"\t--detach <sigfile> copy the boot image's signature table\n"
|
||||||
"\t to <sigfile>\n"
|
"\t to <sigfile>\n"
|
||||||
"\t--remove remove the boot image's signature\n"
|
"\t--remove remove the boot image's signature\n"
|
||||||
"\t table from the original file\n",
|
"\t table from the original file\n"
|
||||||
|
"\t--signum signature to operate on (defaults to\n"
|
||||||
|
"\t first)\n",
|
||||||
toolname, toolname, toolname);
|
toolname, toolname, toolname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,9 +92,9 @@ static void version(void)
|
||||||
printf("%s %s\n", toolname, VERSION);
|
printf("%s %s\n", toolname, VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int detach_sig(struct image *image, const char *sig_filename)
|
static int detach_sig(struct image *image, int signum, const char *sig_filename)
|
||||||
{
|
{
|
||||||
return image_write_detached(image, sig_filename);
|
return image_write_detached(image, signum, sig_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int attach_sig(struct image *image, const char *image_filename,
|
static int attach_sig(struct image *image, const char *image_filename,
|
||||||
|
@ -137,11 +140,18 @@ out:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int remove_sig(struct image *image, const char *image_filename)
|
static int remove_sig(struct image *image, int signum,
|
||||||
|
const char *image_filename)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
image_remove_signature(image);
|
rc = image_remove_signature(image, signum);
|
||||||
|
|
||||||
|
if (rc) {
|
||||||
|
fprintf(stderr, "Error, image has no signature at %d\n",
|
||||||
|
signum + 1);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
rc = image_write(image, image_filename);
|
rc = image_write(image, image_filename);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@ -163,7 +173,7 @@ int main(int argc, char **argv)
|
||||||
struct image *image;
|
struct image *image;
|
||||||
enum action action;
|
enum action action;
|
||||||
bool remove;
|
bool remove;
|
||||||
int c, rc;
|
int c, rc, signum = 0;
|
||||||
|
|
||||||
action = ACTION_NONE;
|
action = ACTION_NONE;
|
||||||
sig_filename = NULL;
|
sig_filename = NULL;
|
||||||
|
@ -171,7 +181,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int idx;
|
int idx;
|
||||||
c = getopt_long(argc, argv, "a:d:rhV", options, &idx);
|
c = getopt_long(argc, argv, "a:d:s:rhV", options, &idx);
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -186,6 +196,10 @@ int main(int argc, char **argv)
|
||||||
action = (c == 'a') ? ACTION_ATTACH : ACTION_DETACH;
|
action = (c == 'a') ? ACTION_ATTACH : ACTION_DETACH;
|
||||||
sig_filename = optarg;
|
sig_filename = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 's':
|
||||||
|
/* humans count from 1 not zero */
|
||||||
|
signum = atoi(optarg) - 1;
|
||||||
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
remove = true;
|
remove = true;
|
||||||
break;
|
break;
|
||||||
|
@ -236,13 +250,13 @@ int main(int argc, char **argv)
|
||||||
rc = attach_sig(image, image_filename, sig_filename);
|
rc = attach_sig(image, image_filename, sig_filename);
|
||||||
|
|
||||||
else if (action == ACTION_DETACH)
|
else if (action == ACTION_DETACH)
|
||||||
rc = detach_sig(image, sig_filename);
|
rc = detach_sig(image, signum, sig_filename);
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (remove)
|
if (remove)
|
||||||
rc = remove_sig(image, image_filename);
|
rc = remove_sig(image, signum, image_filename);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
talloc_free(image);
|
talloc_free(image);
|
||||||
|
|
12
src/sbsign.c
12
src/sbsign.c
|
@ -223,9 +223,15 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
image_add_signature(ctx->image, buf, sigsize);
|
image_add_signature(ctx->image, buf, sigsize);
|
||||||
|
|
||||||
if (ctx->detached)
|
if (ctx->detached) {
|
||||||
image_write_detached(ctx->image, ctx->outfilename);
|
int i;
|
||||||
else
|
uint8_t *buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
for (i = 0; !image_get_signature(ctx->image, i, &buf, &len); i++)
|
||||||
|
;
|
||||||
|
image_write_detached(ctx->image, i - 1, ctx->outfilename);
|
||||||
|
} else
|
||||||
image_write(ctx->image, ctx->outfilename);
|
image_write(ctx->image, ctx->outfilename);
|
||||||
|
|
||||||
talloc_free(ctx);
|
talloc_free(ctx);
|
||||||
|
|
|
@ -65,7 +65,7 @@ enum verify_status {
|
||||||
|
|
||||||
static struct option options[] = {
|
static struct option options[] = {
|
||||||
{ "cert", required_argument, NULL, 'c' },
|
{ "cert", required_argument, NULL, 'c' },
|
||||||
{ "no-verify", no_argument, NULL, 'n' },
|
{ "list", no_argument, NULL, 'l' },
|
||||||
{ "detached", required_argument, NULL, 'd' },
|
{ "detached", required_argument, NULL, 'd' },
|
||||||
{ "verbose", no_argument, NULL, 'v' },
|
{ "verbose", no_argument, NULL, 'v' },
|
||||||
{ "help", no_argument, NULL, 'h' },
|
{ "help", no_argument, NULL, 'h' },
|
||||||
|
@ -79,7 +79,7 @@ static void usage(void)
|
||||||
"Verify a UEFI secure boot image.\n\n"
|
"Verify a UEFI secure boot image.\n\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
"\t--cert <certfile> certificate (x509 certificate)\n"
|
"\t--cert <certfile> certificate (x509 certificate)\n"
|
||||||
"\t--no-verify don't perform certificate verification\n"
|
"\t--list list all signatures (but don't verify)\n"
|
||||||
"\t--detached <file> read signature from <file>, instead of\n"
|
"\t--detached <file> read signature from <file>, instead of\n"
|
||||||
"\t looking for an embedded signature\n",
|
"\t looking for an embedded signature\n",
|
||||||
toolname);
|
toolname);
|
||||||
|
@ -157,23 +157,6 @@ static void print_certificate_store_certs(X509_STORE *certs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int load_image_signature_data(struct image *image,
|
|
||||||
uint8_t **buf, size_t *len)
|
|
||||||
{
|
|
||||||
struct cert_table_header *header;
|
|
||||||
|
|
||||||
if (!image->data_dir_sigtable->addr
|
|
||||||
|| !image->data_dir_sigtable->size) {
|
|
||||||
fprintf(stderr, "No signature table present\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
header = (void *)image->buf + image->data_dir_sigtable->addr;
|
|
||||||
*buf = (void *)(header + 1);
|
|
||||||
*len = header->size - sizeof(*header);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int load_detached_signature_data(struct image *image,
|
static int load_detached_signature_data(struct image *image,
|
||||||
const char *filename, uint8_t **buf, size_t *len)
|
const char *filename, uint8_t **buf, size_t *len)
|
||||||
{
|
{
|
||||||
|
@ -217,7 +200,7 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
const char *detached_sig_filename, *image_filename;
|
const char *detached_sig_filename, *image_filename;
|
||||||
enum verify_status status;
|
enum verify_status status;
|
||||||
int rc, c, flags, verify;
|
int rc, c, flags, list;
|
||||||
const uint8_t *tmp_buf;
|
const uint8_t *tmp_buf;
|
||||||
struct image *image;
|
struct image *image;
|
||||||
X509_STORE *certs;
|
X509_STORE *certs;
|
||||||
|
@ -227,10 +210,11 @@ int main(int argc, char **argv)
|
||||||
bool verbose;
|
bool verbose;
|
||||||
BIO *idcbio;
|
BIO *idcbio;
|
||||||
PKCS7 *p7;
|
PKCS7 *p7;
|
||||||
|
int sig_count = 0;
|
||||||
|
|
||||||
status = VERIFY_FAIL;
|
status = VERIFY_FAIL;
|
||||||
certs = X509_STORE_new();
|
certs = X509_STORE_new();
|
||||||
verify = 1;
|
list = 0;
|
||||||
verbose = false;
|
verbose = false;
|
||||||
detached_sig_filename = NULL;
|
detached_sig_filename = NULL;
|
||||||
|
|
||||||
|
@ -244,7 +228,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int idx;
|
int idx;
|
||||||
c = getopt_long(argc, argv, "c:d:nvVh", options, &idx);
|
c = getopt_long(argc, argv, "c:d:lvVh", options, &idx);
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -257,8 +241,8 @@ int main(int argc, char **argv)
|
||||||
case 'd':
|
case 'd':
|
||||||
detached_sig_filename = optarg;
|
detached_sig_filename = optarg;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'l':
|
||||||
verify = 0;
|
list = 1;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
verbose = true;
|
verbose = true;
|
||||||
|
@ -286,56 +270,76 @@ int main(int argc, char **argv)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (detached_sig_filename)
|
for (;;) {
|
||||||
|
if (detached_sig_filename) {
|
||||||
|
if (sig_count++)
|
||||||
|
break;
|
||||||
|
|
||||||
rc = load_detached_signature_data(image, detached_sig_filename,
|
rc = load_detached_signature_data(image, detached_sig_filename,
|
||||||
&sig_buf, &sig_size);
|
&sig_buf, &sig_size);
|
||||||
else
|
} else
|
||||||
rc = load_image_signature_data(image, &sig_buf, &sig_size);
|
rc = image_get_signature(image, sig_count++, &sig_buf, &sig_size);
|
||||||
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
if (sig_count == 0) {
|
||||||
fprintf(stderr, "Unable to read signature data from %s\n",
|
fprintf(stderr, "Unable to read signature data from %s\n",
|
||||||
detached_sig_filename ? : image_filename);
|
detached_sig_filename ? : image_filename);
|
||||||
goto out;
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp_buf = sig_buf;
|
tmp_buf = sig_buf;
|
||||||
|
if (verbose || list)
|
||||||
|
printf("signature %d\n", sig_count);
|
||||||
p7 = d2i_PKCS7(NULL, &tmp_buf, sig_size);
|
p7 = d2i_PKCS7(NULL, &tmp_buf, sig_size);
|
||||||
if (!p7) {
|
if (!p7) {
|
||||||
fprintf(stderr, "Unable to parse signature data\n");
|
fprintf(stderr, "Unable to parse signature data\n");
|
||||||
ERR_print_errors_fp(stderr);
|
ERR_print_errors_fp(stderr);
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose || list) {
|
||||||
print_signature_info(p7);
|
print_signature_info(p7);
|
||||||
print_certificate_store_certs(certs);
|
//print_certificate_store_certs(certs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (list)
|
||||||
|
continue;
|
||||||
|
|
||||||
idcbio = BIO_new(BIO_s_mem());
|
idcbio = BIO_new(BIO_s_mem());
|
||||||
idc = IDC_get(p7, idcbio);
|
idc = IDC_get(p7, idcbio);
|
||||||
if (!idc)
|
if (!idc) {
|
||||||
goto out;
|
fprintf(stderr, "Unable to get IDC from PKCS7\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
rc = IDC_check_hash(idc, image);
|
rc = IDC_check_hash(idc, image);
|
||||||
if (rc)
|
if (rc) {
|
||||||
goto out;
|
fprintf(stderr, "Image fails hash check\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
flags = PKCS7_BINARY;
|
flags = PKCS7_BINARY;
|
||||||
if (!verify)
|
|
||||||
flags |= PKCS7_NOVERIFY;
|
|
||||||
|
|
||||||
X509_STORE_set_verify_cb_func(certs, x509_verify_cb);
|
X509_STORE_set_verify_cb_func(certs, x509_verify_cb);
|
||||||
rc = PKCS7_verify(p7, NULL, certs, idcbio, NULL, flags);
|
rc = PKCS7_verify(p7, NULL, certs, idcbio, NULL, flags);
|
||||||
if (!rc) {
|
if (rc) {
|
||||||
printf("PKCS7 verification failed\n");
|
if (verbose)
|
||||||
ERR_print_errors_fp(stderr);
|
printf("PKCS7 verification passed\n");
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = VERIFY_OK;
|
status = VERIFY_OK;
|
||||||
|
} else if (verbose) {
|
||||||
|
printf("PKCS7 verification failed\n");
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
talloc_free(image);
|
talloc_free(image);
|
||||||
|
|
||||||
|
if (list)
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
|
||||||
if (status == VERIFY_OK)
|
if (status == VERIFY_OK)
|
||||||
printf("Signature verification OK\n");
|
printf("Signature verification OK\n");
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue