verify: move idc-related parsing to idc.c
Extract the IDC-parsing code from IDC_check_hash, and use it to initialise a BIO. This BIO can then be used to perform the PKCS7 verification. Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
This commit is contained in:
parent
d5f1a61b99
commit
e404a4d412
3 changed files with 47 additions and 28 deletions
42
idc.c
42
idc.c
|
@ -217,20 +217,48 @@ int IDC_set(PKCS7 *p7, PKCS7_SIGNER_INFO *si, struct image *image)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int IDC_check_hash(struct image *image, PKCS7 *p7)
|
||||
struct idc *IDC_get(PKCS7 *p7, BIO *bio)
|
||||
{
|
||||
const unsigned char *buf, *idcbuf;
|
||||
ASN1_STRING *str;
|
||||
IDC *idc;
|
||||
|
||||
/* extract the idc from the signed PKCS7 'other' data */
|
||||
str = p7->d.sign->contents->d.other->value.asn1_string;
|
||||
idcbuf = buf = ASN1_STRING_data(str);
|
||||
idc = d2i_IDC(NULL, &buf, ASN1_STRING_length(str));
|
||||
|
||||
/* If we were passed a BIO, write the idc data, minus type and length,
|
||||
* to the BIO. This can be used to PKCS7_verify the idc */
|
||||
if (bio) {
|
||||
uint32_t idclen;
|
||||
uint8_t tmp;
|
||||
|
||||
tmp = idcbuf[1];
|
||||
|
||||
if (!(tmp & 0x80)) {
|
||||
idclen = tmp & 0x7f;
|
||||
idcbuf += 2;
|
||||
} else if ((tmp & 0x82) == 0x82) {
|
||||
idclen = (idcbuf[2] << 8) +
|
||||
idcbuf[3];
|
||||
idcbuf += 4;
|
||||
}
|
||||
|
||||
BIO_write(bio, idcbuf, idclen);
|
||||
}
|
||||
|
||||
return idc;
|
||||
}
|
||||
|
||||
int IDC_check_hash(struct idc *idc, struct image *image)
|
||||
{
|
||||
unsigned char sha[SHA256_DIGEST_LENGTH];
|
||||
const unsigned char *buf;
|
||||
ASN1_STRING *str;
|
||||
IDC *idc;
|
||||
|
||||
image_hash_sha256(image, sha);
|
||||
|
||||
/* extract the idc from the signed PKCS7 'other' data */
|
||||
str = p7->d.sign->contents->d.other->value.asn1_string;
|
||||
buf = ASN1_STRING_data(str);
|
||||
idc = d2i_IDC(NULL, &buf, ASN1_STRING_length(str));
|
||||
|
||||
/* check hash algorithm sanity */
|
||||
if (OBJ_cmp(idc->digest->alg->algorithm, OBJ_nid2obj(NID_sha256))) {
|
||||
fprintf(stderr, "Invalid algorithm type\n");
|
||||
|
|
5
idc.h
5
idc.h
|
@ -23,8 +23,11 @@
|
|||
|
||||
#include <openssl/pkcs7.h>
|
||||
|
||||
struct idc;
|
||||
|
||||
int IDC_set(PKCS7 *p7, PKCS7_SIGNER_INFO *si, struct image *image);
|
||||
int IDC_check_hash(struct image *image, PKCS7 *p7);
|
||||
struct idc *IDC_get(PKCS7 *p7, BIO *bio);
|
||||
int IDC_check_hash(struct idc *idc, struct image *image);
|
||||
|
||||
#endif /* IDC_H */
|
||||
|
||||
|
|
28
sbverify.c
28
sbverify.c
|
@ -40,9 +40,9 @@ int main(int argc, char **argv)
|
|||
struct cert_table_header *header;
|
||||
enum verify_status status;
|
||||
struct image *image;
|
||||
uint8_t *idcbuf, tmp;
|
||||
const uint8_t *buf;
|
||||
int idclen, rc;
|
||||
struct idc *idc;
|
||||
int rc;
|
||||
BIO *idcbio;
|
||||
PKCS7 *p7;
|
||||
|
||||
|
@ -70,29 +70,17 @@ int main(int argc, char **argv)
|
|||
buf = (void *)(header + 1);
|
||||
p7 = d2i_PKCS7(NULL, &buf, header->size);
|
||||
|
||||
rc = IDC_check_hash(image, p7);
|
||||
idcbio = BIO_new(BIO_s_mem());
|
||||
idc = IDC_get(p7, idcbio);
|
||||
if (!idc)
|
||||
goto out;
|
||||
|
||||
rc = IDC_check_hash(idc, image);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
idcbuf = p7->d.sign->contents->d.other->value.asn1_string->data;
|
||||
|
||||
/* we don't include the type and length data in the hash */
|
||||
tmp = idcbuf[1];
|
||||
if (!(tmp & 0x80)) {
|
||||
idclen = tmp & 0x7f;
|
||||
idcbuf += 2;
|
||||
} else if ((tmp & 0x82) == 0x82) {
|
||||
idclen = (idcbuf[2] << 8) +
|
||||
idcbuf[3];
|
||||
idcbuf += 4;
|
||||
}
|
||||
|
||||
idcbio = BIO_new(BIO_s_mem());
|
||||
BIO_write(idcbio, idcbuf, idclen);
|
||||
|
||||
rc = PKCS7_verify(p7, NULL, NULL, idcbio, NULL,
|
||||
PKCS7_BINARY | PKCS7_NOVERIFY);
|
||||
|
||||
if (!rc) {
|
||||
printf("PKCS7 verification failed\n");
|
||||
ERR_print_errors_fp(stderr);
|
||||
|
|
Loading…
Reference in a new issue