@@ -87,6 +87,7 @@ static uint32_t pe_calc_checksum(BIO *bio, uint32_t header_size);
8787static uint32_t pe_calc_realchecksum (FILE_FORMAT_CTX * ctx );
8888static int pe_modify_header (FILE_FORMAT_CTX * ctx , BIO * hash , BIO * outdata );
8989static 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 );
9091static int pe_page_hash_get (u_char * * ph , int * phlen , int * phtype , SpcAttributeTypeAndOptionalValue * obj );
9192static u_char * pe_page_hash_calc (int * rphlen , FILE_FORMAT_CTX * ctx , int phtype );
9293static 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
0 commit comments