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:
Jeremy Kerr 2012-05-12 23:11:46 -07:00
parent d5f1a61b99
commit e404a4d412
3 changed files with 47 additions and 28 deletions

42
idc.c
View file

@ -217,20 +217,48 @@ int IDC_set(PKCS7 *p7, PKCS7_SIGNER_INFO *si, struct image *image)
return 0; 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]; unsigned char sha[SHA256_DIGEST_LENGTH];
const unsigned char *buf; const unsigned char *buf;
ASN1_STRING *str; ASN1_STRING *str;
IDC *idc;
image_hash_sha256(image, sha); 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 */ /* check hash algorithm sanity */
if (OBJ_cmp(idc->digest->alg->algorithm, OBJ_nid2obj(NID_sha256))) { if (OBJ_cmp(idc->digest->alg->algorithm, OBJ_nid2obj(NID_sha256))) {
fprintf(stderr, "Invalid algorithm type\n"); fprintf(stderr, "Invalid algorithm type\n");

5
idc.h
View file

@ -23,8 +23,11 @@
#include <openssl/pkcs7.h> #include <openssl/pkcs7.h>
struct idc;
int IDC_set(PKCS7 *p7, PKCS7_SIGNER_INFO *si, struct image *image); 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 */ #endif /* IDC_H */

View file

@ -40,9 +40,9 @@ int main(int argc, char **argv)
struct cert_table_header *header; struct cert_table_header *header;
enum verify_status status; enum verify_status status;
struct image *image; struct image *image;
uint8_t *idcbuf, tmp;
const uint8_t *buf; const uint8_t *buf;
int idclen, rc; struct idc *idc;
int rc;
BIO *idcbio; BIO *idcbio;
PKCS7 *p7; PKCS7 *p7;
@ -70,29 +70,17 @@ int main(int argc, char **argv)
buf = (void *)(header + 1); buf = (void *)(header + 1);
p7 = d2i_PKCS7(NULL, &buf, header->size); 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) if (rc)
goto out; 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, rc = PKCS7_verify(p7, NULL, NULL, idcbio, NULL,
PKCS7_BINARY | PKCS7_NOVERIFY); PKCS7_BINARY | PKCS7_NOVERIFY);
if (!rc) { if (!rc) {
printf("PKCS7 verification failed\n"); printf("PKCS7 verification failed\n");
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);