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;
|
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
5
idc.h
|
@ -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 */
|
||||||
|
|
||||||
|
|
28
sbverify.c
28
sbverify.c
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue