From 36e79114d27589e9ccd494b04f79577703d8b0a5 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Thu, 2 Aug 2012 16:43:08 +0800 Subject: [PATCH] sbattach: fix --detach sbattach --detach isn't working, as we're not properly setting sigbuf in image_pecoff parse. This change ensures we populate sigbuf when we find a valid cert table. Also, add a test case for this. Bug report & initial patch from from Steve Langasek. Signed-off-by: Jeremy Kerr --- image.c | 24 ++++++++++++++++++++---- tests/Makefile.am | 1 + tests/sign-detach-verify.sh | 10 ++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) create mode 100755 tests/sign-detach-verify.sh diff --git a/image.c b/image.c index f8ee1d6..2508766 100644 --- a/image.c +++ b/image.c @@ -47,6 +47,9 @@ #define DATA_DIR_CERT_TABLE 4 +#define CERT_TABLE_TYPE_PKCS 0x0002 /* PKCS signedData */ +#define CERT_TABLE_REVISION 0x0200 /* revision 2 */ + /** * The PE/COFF headers export struct fields as arrays of chars. So, define * a couple of accessor functions that allow fields to be deferenced as their @@ -75,6 +78,7 @@ static uint16_t __pehdr_u16(char field[]) static int image_pecoff_parse(struct image *image) { + struct cert_table_header *cert_table; char nt_sig[] = {'P', 'E', 0, 0}; size_t size = image->size; uint32_t addr; @@ -142,9 +146,21 @@ static int image_pecoff_parse(struct image *image) image->cert_table_size = image->data_dir_sigtable->size; if (image->cert_table_size) - image->cert_table = image->buf + image->data_dir_sigtable->addr; + cert_table = image->buf + image->data_dir_sigtable->addr; else - image->cert_table = NULL; + cert_table = NULL; + + image->cert_table = cert_table; + + /* if we have a valid cert table header, populate sigbuf as a shadow + * copy of the cert table */ + if (cert_table && cert_table->revision == CERT_TABLE_REVISION && + cert_table->type == CERT_TABLE_TYPE_PKCS && + cert_table->size < size) { + image->sigsize = cert_table->size; + image->sigbuf = talloc_memdup(image, cert_table + 1, + image->sigsize); + } image->sections = pehdr_u16(image->pehdr->f_nscns); image->scnhdr = (void *)(image->aouthdr+1); @@ -387,8 +403,8 @@ int image_write(struct image *image, const char *filename) if (is_signed) { cert_table_header.size = image->sigsize + sizeof(cert_table_header); - cert_table_header.revision = 0x0200; /* = revision 2 */ - cert_table_header.type = 0x0002; /* PKCS signedData */ + cert_table_header.revision = CERT_TABLE_REVISION; + cert_table_header.type = CERT_TABLE_TYPE_PKCS; len = sizeof(cert_table_header) + image->sigsize; diff --git a/tests/Makefile.am b/tests/Makefile.am index a2e80cc..03af648 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -37,6 +37,7 @@ $(test_cert): $(test_key) Makefile TESTS = sign-verify.sh \ sign-verify-detached.sh \ + sign-detach-verify.sh \ sign-attach-verify.sh \ sign-missing-image.sh \ sign-missing-cert.sh \ diff --git a/tests/sign-detach-verify.sh b/tests/sign-detach-verify.sh new file mode 100755 index 0000000..4356816 --- /dev/null +++ b/tests/sign-detach-verify.sh @@ -0,0 +1,10 @@ +#!/bin/bash -e + +. "$srcdir/common.sh" + +signed="test.signed" +sig="test.sig" + +"$sbsign" --cert "$cert" --key "$key" --output "$signed" "$image" +"$sbattach" --detach "$sig" "$signed" +"$sbverify" --cert "$cert" --detached $sig "$image"