@@ -2216,16 +2216,15 @@ static int verify_timestamp_token(PKCS7 *p7, CMS_ContentInfo *timestamp)
22162216 */
22172217static int verify_timestamp (FILE_FORMAT_CTX * ctx , PKCS7 * p7 , CMS_ContentInfo * timestamp , time_t time )
22182218{
2219- X509_STORE * store ;
22202219 STACK_OF (CMS_SignerInfo ) * sinfos ;
22212220 CMS_SignerInfo * cmssi ;
22222221 X509 * signer ;
22232222 X509_CRL * crl = NULL ;
22242223 STACK_OF (X509_CRL ) * crls = NULL ;
22252224 char * url = NULL ;
22262225 int verok = 0 ;
2226+ X509_STORE * store = X509_STORE_new ();
22272227
2228- store = X509_STORE_new ();
22292228 if (!store )
22302229 goto out ;
22312230 if (x509_store_load_file (store , ctx -> options -> tsa_cafile )) {
@@ -2240,12 +2239,10 @@ static int verify_timestamp(FILE_FORMAT_CTX *ctx, PKCS7 *p7, CMS_ContentInfo *ti
22402239 */
22412240 if (!x509_store_set_time (store , time )) {
22422241 fprintf (stderr , "Failed to set store time\n" );
2243- X509_STORE_free (store );
22442242 goto out ;
22452243 }
22462244 } else {
22472245 printf ("Use the \"-TSA-CAfile\" option to add the Time-Stamp Authority certificates bundle to verify the Timestamp Server.\n" );
2248- X509_STORE_free (store );
22492246 goto out ;
22502247 }
22512248
@@ -2255,14 +2252,12 @@ static int verify_timestamp(FILE_FORMAT_CTX *ctx, PKCS7 *p7, CMS_ContentInfo *ti
22552252 STACK_OF (X509 ) * cms_certs ;
22562253
22572254 printf ("CMS_verify error\n" );
2258- X509_STORE_free (store );
22592255 printf ("\nFailed timestamp certificate chain retrieved from the signature:\n" );
22602256 cms_certs = CMS_get1_certs (timestamp );
22612257 print_certs_chain (cms_certs );
22622258 sk_X509_pop_free (cms_certs , X509_free );
22632259 goto out ;
22642260 }
2265- X509_STORE_free (store );
22662261
22672262 sinfos = CMS_get0_SignerInfos (timestamp );
22682263 cmssi = sk_CMS_SignerInfo_value (sinfos , 0 );
@@ -2299,7 +2294,6 @@ static int verify_timestamp(FILE_FORMAT_CTX *ctx, PKCS7 *p7, CMS_ContentInfo *ti
22992294 int crlok = verify_crl (ctx -> options -> tsa_cafile , ctx -> options -> tsa_crlfile ,
23002295 crls , signer , chain );
23012296 sk_X509_pop_free (chain , X509_free );
2302- sk_X509_CRL_pop_free (crls , X509_CRL_free );
23032297 printf ("Timestamp Server Signature CRL verification: %s\n" , crlok ? "ok" : "failed" );
23042298 if (!crlok )
23052299 goto out ;
@@ -2317,6 +2311,8 @@ static int verify_timestamp(FILE_FORMAT_CTX *ctx, PKCS7 *p7, CMS_ContentInfo *ti
23172311 }
23182312 verok = 1 ; /* OK */
23192313out :
2314+ X509_STORE_free (store );
2315+ sk_X509_CRL_pop_free (crls , X509_CRL_free );
23202316 if (!verok )
23212317 ERR_print_errors_fp (stderr );
23222318 return verok ;
@@ -2344,6 +2340,60 @@ static int PKCS7_type_is_other(PKCS7 *p7)
23442340}
23452341#endif /* OPENSSL_VERSION_NUMBER<0x30000000L */
23462342
2343+ /*
2344+ * [in] p7: PKCS#7 signature
2345+ * [in] store: X509_STORE
2346+ * [returns] 1 on error or 0 on success
2347+ */
2348+ static int verify_pkcs7_data (PKCS7 * p7 , X509_STORE * store )
2349+ {
2350+ int verok = 0 ;
2351+ #if OPENSSL_VERSION_NUMBER < 0x30500000L
2352+ BIO * bio = NULL ;
2353+ PKCS7 * contents = p7 -> d .sign -> contents ;
2354+
2355+ /*
2356+ * In the PKCS7_verify() function, the BIO *indata parameter refers to
2357+ * the signed data if the content is detached from p7.
2358+ * Otherwise, indata should be NULL, and then the signed data must be in p7.
2359+ * The OpenSSL error workaround is to put the inner content into BIO *indata parameter
2360+ * https://github.com/openssl/openssl/pull/22575
2361+ */
2362+ if (PKCS7_type_is_other (contents ) && (contents -> d .other != NULL )
2363+ && (contents -> d .other -> value .sequence != NULL )
2364+ && (contents -> d .other -> value .sequence -> length > 0 )) {
2365+ if (contents -> d .other -> type == V_ASN1_SEQUENCE ) {
2366+ /* only verify the content of the sequence */
2367+ const unsigned char * data = contents -> d .other -> value .sequence -> data ;
2368+ long len ;
2369+ int inf , tag , class ;
2370+
2371+ inf = ASN1_get_object (& data , & len , & tag , & class ,
2372+ contents -> d .other -> value .sequence -> length );
2373+ if (inf != V_ASN1_CONSTRUCTED || tag != V_ASN1_SEQUENCE ) {
2374+ fprintf (stderr , "Corrupted data content\n" );
2375+ X509_STORE_free (store );
2376+ return 0 ; /* FAILED */
2377+ }
2378+ bio = BIO_new_mem_buf (data , (int )len );
2379+ } else {
2380+ /* verify the entire value */
2381+ bio = BIO_new_mem_buf (contents -> d .other -> value .sequence -> data ,
2382+ contents -> d .other -> value .sequence -> length );
2383+ }
2384+ } else {
2385+ fprintf (stderr , "Corrupted data content\n" );
2386+ X509_STORE_free (store );
2387+ return 0 ; /* FAILED */
2388+ }
2389+ verok = PKCS7_verify (p7 , NULL , store , bio , NULL , 0 );
2390+ BIO_free (bio );
2391+ #else /* OPENSSL_VERSION_NUMBER<0x30500000L */
2392+ verok = PKCS7_verify (p7 , NULL , store , NULL , NULL , 0 );
2393+ #endif /* OPENSSL_VERSION_NUMBER<0x30500000L */
2394+ return verok ;
2395+ }
2396+
23472397/*
23482398 * [in] ctx: structure holds input and output data
23492399 * [in] p7: PKCS#7 signature
@@ -2353,86 +2403,42 @@ static int PKCS7_type_is_other(PKCS7 *p7)
23532403 */
23542404static int verify_authenticode (FILE_FORMAT_CTX * ctx , PKCS7 * p7 , time_t time , X509 * signer )
23552405{
2356- X509_STORE * store ;
23572406 X509_CRL * crl = NULL ;
23582407 STACK_OF (X509_CRL ) * crls = NULL ;
2359- BIO * bio = NULL ;
23602408 int verok = 0 ;
23612409 char * url = NULL ;
2362- PKCS7 * contents = p7 -> d . sign -> contents ;
2410+ X509_STORE * store = X509_STORE_new () ;
23632411
2364- store = X509_STORE_new ();
23652412 if (!store )
23662413 goto out ;
23672414
23682415 if (!x509_store_load_file (store , ctx -> options -> cafile )) {
23692416 fprintf (stderr , "Failed to add store lookup file\n" );
2370- X509_STORE_free (store );
23712417 goto out ;
23722418 }
23732419 if (time != INVALID_TIME ) {
23742420 printf ("Signature verification time: " );
23752421 print_time_t (time );
23762422 if (!x509_store_set_time (store , time )) {
23772423 fprintf (stderr , "Failed to set signature time\n" );
2378- X509_STORE_free (store );
23792424 goto out ;
23802425 }
23812426 } else if (ctx -> options -> time != INVALID_TIME ) {
23822427 printf ("Signature verification time: " );
23832428 print_time_t (ctx -> options -> time );
23842429 if (!x509_store_set_time (store , ctx -> options -> time )) {
23852430 fprintf (stderr , "Failed to set verifying time\n" );
2386- X509_STORE_free (store );
23872431 goto out ;
23882432 }
23892433 }
23902434 /* verify a PKCS#7 signedData structure */
2391- if (PKCS7_type_is_other (contents ) && (contents -> d .other != NULL )
2392- && (contents -> d .other -> value .sequence != NULL )
2393- && (contents -> d .other -> value .sequence -> length > 0 )) {
2394- if (contents -> d .other -> type == V_ASN1_SEQUENCE ) {
2395- /* only verify the content of the sequence */
2396- const unsigned char * data = contents -> d .other -> value .sequence -> data ;
2397- long len ;
2398- int inf , tag , class ;
2399-
2400- inf = ASN1_get_object (& data , & len , & tag , & class ,
2401- contents -> d .other -> value .sequence -> length );
2402- if (inf != V_ASN1_CONSTRUCTED || tag != V_ASN1_SEQUENCE ) {
2403- fprintf (stderr , "Corrupted data content\n" );
2404- X509_STORE_free (store );
2405- goto out ;
2406- }
2407- bio = BIO_new_mem_buf (data , (int )len );
2408- } else {
2409- /* verify the entire value */
2410- bio = BIO_new_mem_buf (contents -> d .other -> value .sequence -> data ,
2411- contents -> d .other -> value .sequence -> length );
2412- }
2413- } else {
2414- fprintf (stderr , "Corrupted data content\n" );
2415- X509_STORE_free (store );
2416- goto out ;
2417- }
24182435 printf ("Signing certificate chain verified using:\n" );
2419- /*
2420- * In the PKCS7_verify() function, the BIO *indata parameter refers to
2421- * the signed data if the content is detached from p7.
2422- * Otherwise, indata should be NULL, and then the signed data must be in p7.
2423- * The OpenSSL error workaround is to put the inner content into BIO *indata parameter
2424- * https://github.com/openssl/openssl/pull/22575
2425- */
2426- if (!PKCS7_verify (p7 , NULL , store , bio , NULL , 0 )) {
2436+ if (!verify_pkcs7_data (p7 , store )) {
24272437 printf ("PKCS7_verify error\n" );
2428- X509_STORE_free (store );
2429- BIO_free (bio );
24302438 printf ("Failed signing certificate chain retrieved from the signature:\n" );
24312439 print_certs_chain (p7 -> d .sign -> cert );
24322440 goto out ;
24332441 }
2434- X509_STORE_free (store );
2435- BIO_free (bio );
24362442
24372443 /* verify a Certificate Revocation List */
24382444 if (!ctx -> options -> ignore_crl ) {
@@ -2464,7 +2470,7 @@ static int verify_authenticode(FILE_FORMAT_CTX *ctx, PKCS7 *p7, time_t time, X50
24642470 STACK_OF (X509 ) * chain = p7 -> d .sign -> cert ;
24652471 int crlok = verify_crl (ctx -> options -> cafile , ctx -> options -> crlfile ,
24662472 crls , signer , chain );
2467- sk_X509_CRL_pop_free ( crls , X509_CRL_free );
2473+
24682474 printf ("Signature CRL verification: %s\n" , crlok ? "ok" : "failed" );
24692475 if (!crlok )
24702476 goto out ;
@@ -2477,6 +2483,8 @@ static int verify_authenticode(FILE_FORMAT_CTX *ctx, PKCS7 *p7, time_t time, X50
24772483
24782484 verok = 1 ; /* OK */
24792485out :
2486+ X509_STORE_free (store );
2487+ sk_X509_CRL_pop_free (crls , X509_CRL_free );
24802488 if (!verok )
24812489 ERR_print_errors_fp (stderr );
24822490 return verok ;
0 commit comments