Skip to content

Commit bf209e0

Browse files
olszomalmtrojnar
authored andcommitted
Refactor SpcIndirectDataContent parsing helpers
1 parent 68a6826 commit bf209e0

8 files changed

Lines changed: 160 additions & 107 deletions

File tree

appx.c

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -470,33 +470,33 @@ static int appx_hash_length_get(FILE_FORMAT_CTX *ctx)
470470
*/
471471
static int appx_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
472472
{
473-
if (is_content_type(p7, SPC_INDIRECT_DATA_OBJID)) {
474-
ASN1_STRING *content_val = p7->d.sign->contents->d.other->value.sequence;
475-
const u_char *p = ASN1_STRING_get0_data(content_val);
476-
int len = ASN1_STRING_length(content_val);
477-
SpcIndirectDataContent *idc = d2i_SpcIndirectDataContent(NULL, &p, len);
478-
479-
if (idc) {
480-
BIO *hashes;
481-
if (!appx_extract_hashes(ctx, idc)) {
482-
fprintf(stderr, "Failed to extract hashes from the signature\n");
483-
SpcIndirectDataContent_free(idc);
484-
return 0; /* FAILED */
485-
}
486-
hashes = appx_calculate_hashes(ctx);
487-
if (!hashes) {
488-
SpcIndirectDataContent_free(idc);
489-
return 0; /* FAILED */
490-
}
491-
BIO_free_all(hashes);
492-
if (!appx_compare_hashes(ctx)) {
493-
fprintf(stderr, "Signature hash verification failed\n");
494-
SpcIndirectDataContent_free(idc);
495-
return 0; /* FAILED */
496-
}
497-
SpcIndirectDataContent_free(idc);
498-
}
473+
SpcIndirectDataContent *idc;
474+
BIO *hashes;
475+
476+
idc = pkcs7_get_indirect_data_content(p7);
477+
if (!idc)
478+
return 1; /* OK - no SpcIndirectDataContent */
479+
480+
if (!appx_extract_hashes(ctx, idc)) {
481+
fprintf(stderr, "Failed to extract hashes from the signature\n");
482+
SpcIndirectDataContent_free(idc);
483+
return 0; /* FAILED */
499484
}
485+
486+
hashes = appx_calculate_hashes(ctx);
487+
if (!hashes) {
488+
SpcIndirectDataContent_free(idc);
489+
return 0; /* FAILED */
490+
}
491+
BIO_free_all(hashes);
492+
493+
if (!appx_compare_hashes(ctx)) {
494+
fprintf(stderr, "Signature hash verification failed\n");
495+
SpcIndirectDataContent_free(idc);
496+
return 0; /* FAILED */
497+
}
498+
499+
SpcIndirectDataContent_free(idc);
500500
return 1; /* OK */
501501
}
502502

cab.c

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -337,22 +337,7 @@ static int cab_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
337337
u_char mdbuf[EVP_MAX_MD_SIZE];
338338
u_char *cmdbuf;
339339

340-
if (is_content_type(p7, SPC_INDIRECT_DATA_OBJID)) {
341-
ASN1_STRING *content_val = p7->d.sign->contents->d.other->value.sequence;
342-
const u_char *data = ASN1_STRING_get0_data(content_val);
343-
int len = ASN1_STRING_length(content_val);
344-
345-
SpcIndirectDataContent *idc = d2i_SpcIndirectDataContent(NULL, &data, len);
346-
if (idc) {
347-
if (spc_indirect_data_content_get_digest(idc, mdbuf, &mdtype) < 0) {
348-
fprintf(stderr, "Failed to extract message digest from signature\n\n");
349-
SpcIndirectDataContent_free(idc);
350-
return 0; /* FAILED */
351-
}
352-
SpcIndirectDataContent_free(idc);
353-
}
354-
}
355-
if (mdtype == -1) {
340+
if (!pkcs7_get_content_digest(p7, mdbuf, &mdtype)) {
356341
fprintf(stderr, "Failed to extract current message digest\n\n");
357342
return 0; /* FAILED */
358343
}

cat.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -393,23 +393,22 @@ static int cat_print_content_member_digest(ASN1_TYPE *content)
393393
{
394394
SpcIndirectDataContent *idc;
395395
u_char mdbuf[EVP_MAX_MD_SIZE];
396-
const u_char *data ;
397396
int mdtype = -1;
398-
ASN1_STRING *value;
399397

400-
value = content->value.sequence;
401-
data = ASN1_STRING_get0_data(value);
402-
idc = d2i_SpcIndirectDataContent(NULL, &data, ASN1_STRING_length(value));
398+
idc = asn1_type_get_indirect_data_content(content);
403399
if (!idc)
404400
return 0; /* FAILED */
401+
405402
if (spc_indirect_data_content_get_digest(idc, mdbuf, &mdtype) < 0) {
406403
fprintf(stderr, "Failed to extract message digest from signature\n\n");
407404
SpcIndirectDataContent_free(idc);
408405
return 0; /* FAILED */
409406
}
410407
SpcIndirectDataContent_free(idc);
408+
411409
printf("\tHash algorithm: %s\n", OBJ_nid2sn(mdtype));
412410
print_hash("\tMessage digest", "", mdbuf, EVP_MD_size(EVP_get_digestbynid(mdtype)));
411+
413412
return 1; /* OK */
414413
}
415414

helpers.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,91 @@ PKCS7 *pkcs7_set_content(ASN1_OCTET_STRING *content)
341341
return p7;
342342
}
343343

344+
/*
345+
* Retrieve the message digest and digest algorithm from PKCS7
346+
* SpcIndirectDataContent.
347+
*
348+
* [in] p7: PKCS7 structure containing SPC_INDIRECT_DATA_OBJID content
349+
* [out] mdbuf: message digest buffer, at least EVP_MAX_MD_SIZE bytes
350+
* [out] mdtype: OpenSSL NID of the digest algorithm
351+
* [returns] 0 on error or 1 on success
352+
*/
353+
int pkcs7_get_content_digest(PKCS7 *p7, u_char *mdbuf, int *mdtype)
354+
{
355+
SpcIndirectDataContent *idc;
356+
357+
if (!mdbuf || !mdtype)
358+
return 0; /* FAILED */
359+
360+
*mdtype = -1;
361+
362+
idc = pkcs7_get_indirect_data_content(p7);
363+
if (!idc) {
364+
fprintf(stderr, "Failed to decode SpcIndirectDataContent\n\n");
365+
return 0; /* FAILED */
366+
}
367+
if (spc_indirect_data_content_get_digest(idc, mdbuf, mdtype) < 0) {
368+
fprintf(stderr, "Failed to extract message digest from signature\n\n");
369+
SpcIndirectDataContent_free(idc);
370+
return 0; /* FAILED */
371+
}
372+
SpcIndirectDataContent_free(idc);
373+
if (*mdtype == -1) {
374+
fprintf(stderr, "Failed to extract current message digest\n\n");
375+
return 0; /* FAILED */
376+
}
377+
return 1; /* OK */
378+
}
379+
380+
/*
381+
* Decode SpcIndirectDataContent from a PKCS7 signedData content.
382+
*
383+
* [in] p7: PKCS7 structure containing SPC_INDIRECT_DATA_OBJID content
384+
* [returns] newly allocated SpcIndirectDataContent, or NULL on error
385+
*
386+
* The caller is responsible for freeing the returned object with
387+
* SpcIndirectDataContent_free().
388+
*/
389+
SpcIndirectDataContent *pkcs7_get_indirect_data_content(PKCS7 *p7)
390+
{
391+
if (!is_content_type(p7, SPC_INDIRECT_DATA_OBJID))
392+
return NULL;
393+
394+
if (!p7->d.sign || !p7->d.sign->contents || !p7->d.sign->contents->d.other)
395+
return NULL;
396+
397+
return asn1_type_get_indirect_data_content(p7->d.sign->contents->d.other);
398+
}
399+
400+
/*
401+
* Decode SpcIndirectDataContent from an ASN1_TYPE object.
402+
* The ASN1_TYPE is expected to contain a V_ASN1_SEQUENCE value.
403+
*
404+
* [in] content: ASN1_TYPE containing DER-encoded SpcIndirectDataContent
405+
* [returns] newly allocated SpcIndirectDataContent, or NULL on error
406+
*
407+
* The caller is responsible for freeing the returned object with
408+
* SpcIndirectDataContent_free().
409+
*/
410+
SpcIndirectDataContent *asn1_type_get_indirect_data_content(ASN1_TYPE *content)
411+
{
412+
ASN1_STRING *value;
413+
const unsigned char *data;
414+
int len;
415+
416+
if (!content || content->type != V_ASN1_SEQUENCE)
417+
return NULL;
418+
419+
value = content->value.sequence;
420+
if (!value)
421+
return NULL;
422+
423+
data = ASN1_STRING_get0_data(value);
424+
len = ASN1_STRING_length(value);
425+
426+
return d2i_SpcIndirectDataContent(NULL, &data, len);
427+
}
428+
344429
/*
345430
* Return spcIndirectDataContent.
346431
* [in] hash: message digest BIO

helpers.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ PKCS7 *pkcs7_create(FILE_FORMAT_CTX *ctx);
1515
int add_indirect_data_object(PKCS7 *p7);
1616
int sign_spc_indirect_data_content(PKCS7 *p7, ASN1_OCTET_STRING *content);
1717
PKCS7 *pkcs7_set_content(ASN1_OCTET_STRING *content);
18+
int pkcs7_get_content_digest(PKCS7 *p7, u_char *mdbuf, int *mdtype);
19+
SpcIndirectDataContent *pkcs7_get_indirect_data_content(PKCS7 *p7);
20+
SpcIndirectDataContent *asn1_type_get_indirect_data_content(ASN1_TYPE *content);
1821
ASN1_OCTET_STRING *spc_indirect_data_content_get(BIO *hash, FILE_FORMAT_CTX *ctx);
1922
int pkcs7_sign_content(PKCS7 *p7, const u_char *data, int len);
2023
int asn1_simple_hdr_len(const u_char *p, int len);

msi.c

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -414,22 +414,7 @@ static int msi_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
414414
const EVP_MD *md;
415415
BIO *hash;
416416

417-
if (is_content_type(p7, SPC_INDIRECT_DATA_OBJID)) {
418-
ASN1_STRING *content_val = p7->d.sign->contents->d.other->value.sequence;
419-
const u_char *p = ASN1_STRING_get0_data(content_val);
420-
int len = ASN1_STRING_length(content_val);
421-
SpcIndirectDataContent *idc = d2i_SpcIndirectDataContent(NULL, &p, len);
422-
423-
if (idc) {
424-
if (spc_indirect_data_content_get_digest(idc, mdbuf, &mdtype) < 0) {
425-
fprintf(stderr, "Failed to extract message digest from signature\n\n");
426-
SpcIndirectDataContent_free(idc);
427-
return 0; /* FAILED */
428-
}
429-
SpcIndirectDataContent_free(idc);
430-
}
431-
}
432-
if (mdtype == -1) {
417+
if (!pkcs7_get_content_digest(p7, mdbuf, &mdtype)) {
433418
fprintf(stderr, "Failed to extract current message digest\n\n");
434419
return 0; /* FAILED */
435420
}

pe.c

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ static uint32_t pe_calc_checksum(BIO *bio, uint32_t header_size);
8787
static uint32_t pe_calc_realchecksum(FILE_FORMAT_CTX *ctx);
8888
static int pe_modify_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata);
8989
static BIO *pe_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md);
90+
static int pkcs7_get_page_hash(PKCS7 *p7, u_char **ph, int *phlen, int *phtype);
9091
static int pe_page_hash_get(u_char **ph, int *phlen, int *phtype, SpcAttributeTypeAndOptionalValue *obj);
9192
static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype);
9293
static int pe_verify_page_hash(FILE_FORMAT_CTX *ctx, u_char *ph, int phlen, int phtype);
@@ -247,53 +248,34 @@ static int pe_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
247248
u_char *cmdbuf = NULL;
248249
u_char *ph = NULL;
249250

250-
if (is_content_type(p7, SPC_INDIRECT_DATA_OBJID)) {
251-
ASN1_STRING *content_val = p7->d.sign->contents->d.other->value.sequence;
252-
const u_char *p = ASN1_STRING_get0_data(content_val);
253-
int len = ASN1_STRING_length(content_val);
254-
SpcIndirectDataContent *idc = d2i_SpcIndirectDataContent(NULL, &p, len);
255-
256-
if (idc) {
257-
if (!pe_page_hash_get(&ph, &phlen, &phtype, idc->data)) {
258-
fprintf(stderr, "Failed to extract a page hash\n\n");
259-
SpcIndirectDataContent_free(idc);
260-
return 0; /* FAILED */
261-
}
262-
if (spc_indirect_data_content_get_digest(idc, mdbuf, &mdtype) < 0) {
263-
fprintf(stderr, "Failed to extract message digest from signature\n\n");
264-
OPENSSL_free(ph);
265-
SpcIndirectDataContent_free(idc);
266-
return 0; /* FAILED */
267-
}
268-
SpcIndirectDataContent_free(idc);
269-
}
270-
}
271-
if (mdtype == -1) {
251+
if (!pkcs7_get_content_digest(p7, mdbuf, &mdtype)) {
272252
fprintf(stderr, "Failed to extract current message digest\n\n");
273-
OPENSSL_free(ph);
274253
return 0; /* FAILED */
275254
}
276255
md = EVP_get_digestbynid(mdtype);
277256
cmdbuf = pe_digest_calc(ctx, md);
278257
if (!cmdbuf) {
279258
fprintf(stderr, "Failed to calculate message digest\n\n");
280-
OPENSSL_free(ph);
281259
return 0; /* FAILED */
282260
}
283261
if (!compare_digests(mdbuf, cmdbuf, mdtype)) {
284262
fprintf(stderr, "Signature verification: failed\n\n");
285-
OPENSSL_free(ph);
286263
OPENSSL_free(cmdbuf);
287264
return 0; /* FAILED */
288265
}
266+
OPENSSL_free(cmdbuf);
267+
268+
if (!pkcs7_get_page_hash(p7, &ph, &phlen, &phtype)) {
269+
fprintf(stderr, "Failed to extract page hash\n\n");
270+
return 0; /* FAILED */
271+
}
289272
if (!pe_verify_page_hash(ctx, ph, phlen, phtype)) {
290273
fprintf(stderr, "Signature verification: failed\n\n");
291274
OPENSSL_free(ph);
292-
OPENSSL_free(cmdbuf);
293275
return 0; /* FAILED */
294276
}
295277
OPENSSL_free(ph);
296-
OPENSSL_free(cmdbuf);
278+
297279
return 1; /* OK */
298280
}
299281

@@ -841,6 +823,36 @@ static BIO *pe_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
841823
* Page hash support
842824
*/
843825

826+
/*
827+
* Retrieve a page hash from PKCS7 SPC_INDIRECT_DATA structure.
828+
* [in] p7: PKCS7 signature
829+
* [out] ph: page hash
830+
* [out] phlen: page hash length
831+
* [out] phtype: NID_sha1 or NID_sha256
832+
* [returns] 0 on error or 1 on success
833+
*/
834+
static int pkcs7_get_page_hash(PKCS7 *p7, u_char **ph, int *phlen, int *phtype)
835+
{
836+
SpcIndirectDataContent *idc = pkcs7_get_indirect_data_content(p7);
837+
838+
if (!idc) {
839+
fprintf(stderr, "Failed to decode SpcIndirectDataContent\n\n");
840+
return 0; /* FAILED */
841+
}
842+
if (!idc->data) {
843+
fprintf(stderr, "Missing SpcIndirectDataContent data\n\n");
844+
SpcIndirectDataContent_free(idc);
845+
return 0; /* FAILED */
846+
}
847+
if (!pe_page_hash_get(ph, phlen, phtype, idc->data)) {
848+
fprintf(stderr, "Failed to extract a page hash\n\n");
849+
SpcIndirectDataContent_free(idc);
850+
return 0; /* FAILED */
851+
}
852+
SpcIndirectDataContent_free(idc);
853+
return 1; /* OK */
854+
}
855+
844856
/*
845857
* Retrieve a page hash from SPC_INDIRECT_DATA structure.
846858
* [out] ph: page hash

script.c

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -288,23 +288,7 @@ static int script_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
288288
const EVP_MD *md;
289289
BIO *bhash;
290290

291-
/* FIXME: this shared code most likely belongs in osslsigncode.c */
292-
if (is_content_type(p7, SPC_INDIRECT_DATA_OBJID)) {
293-
ASN1_STRING *content_val = p7->d.sign->contents->d.other->value.sequence;
294-
const u_char *p = ASN1_STRING_get0_data(content_val);
295-
int len = ASN1_STRING_length(content_val);
296-
SpcIndirectDataContent *idc = d2i_SpcIndirectDataContent(NULL, &p, len);
297-
298-
if (idc) {
299-
if (spc_indirect_data_content_get_digest(idc, mdbuf, &mdtype) < 0) {
300-
fprintf(stderr, "Failed to extract message digest from signature\n\n");
301-
SpcIndirectDataContent_free(idc);
302-
return 0; /* FAILED */
303-
}
304-
SpcIndirectDataContent_free(idc);
305-
}
306-
}
307-
if (mdtype == -1) {
291+
if (!pkcs7_get_content_digest(p7, mdbuf, &mdtype)) {
308292
fprintf(stderr, "Failed to extract current message digest\n\n");
309293
return 0; /* FAILED */
310294
}

0 commit comments

Comments
 (0)