@@ -4200,21 +4200,30 @@ static int add_opus_attribute(PKCS7_SIGNER_INFO *si, char *desc, char *url)
42004200static PKCS7 * create_new_signature (file_type_t type ,
42014201 GLOBAL_OPTIONS * options , CRYPTO_PARAMS * cparams )
42024202{
4203- int i ;
4203+ int i , signer = -1 ;
42044204 PKCS7 * sig ;
42054205 PKCS7_SIGNER_INFO * si = NULL ;
4206- X509 * signcert ;
42074206
42084207 sig = PKCS7_new ();
42094208 PKCS7_set_type (sig , NID_pkcs7_signed );
42104209
4211- if (cparams -> cert != NULL )
4210+ if (cparams -> cert != NULL ) {
4211+ /*
4212+ * the private key and corresponding certificate are parsed from the PKCS12
4213+ * structure or loaded from the security token, so we may omit to check
4214+ * the consistency of a private key with the public key in an X509 certificate
4215+ */
42124216 si = PKCS7_add_signature (sig , cparams -> cert , cparams -> pkey , options -> md );
4213-
4214- for (i = 0 ; si == NULL && i < sk_X509_num (cparams -> certs ); i ++ ) {
4215- signcert = sk_X509_value (cparams -> certs , i );
4216- /* X509_print_fp(stdout, signcert); */
4217- si = PKCS7_add_signature (sig , signcert , cparams -> pkey , options -> md );
4217+ } else {
4218+ /* find the signer's certificate located somewhere in the whole certificate chain */
4219+ for (i = 0 ; i < sk_X509_num (cparams -> certs ); i ++ ) {
4220+ X509 * signcert = sk_X509_value (cparams -> certs , i );
4221+ if (X509_check_private_key (signcert , cparams -> pkey )) {
4222+ si = PKCS7_add_signature (sig , signcert , cparams -> pkey , options -> md );
4223+ signer = i ;
4224+ break ;
4225+ }
4226+ }
42184227 }
42194228 if (si == NULL ) {
42204229 printf ("PKCS7_add_signature failed\n" );
@@ -4236,21 +4245,28 @@ static PKCS7 *create_new_signature(file_type_t type,
42364245 }
42374246 PKCS7_content_new (sig , NID_pkcs7_data );
42384247
4248+ /* add the signer's certificate */
42394249 if (cparams -> cert != NULL )
42404250 PKCS7_add_certificate (sig , cparams -> cert );
4251+ if (signer != -1 )
4252+ PKCS7_add_certificate (sig , sk_X509_value (cparams -> certs , signer ));
4253+
4254+ /* add the certificate chain */
4255+ for (i = 0 ; i < sk_X509_num (cparams -> certs ); i ++ ) {
4256+ if (i == signer )
4257+ continue ;
4258+ PKCS7_add_certificate (sig , sk_X509_value (cparams -> certs , i ));
4259+ }
4260+ /* add all cross certificates */
42414261 if (cparams -> xcerts ) {
4242- for ( i = sk_X509_num (cparams -> xcerts )- 1 ; i >= 0 ; i -- )
4262+ for ( i = 0 ; i < sk_X509_num (cparams -> xcerts ); i ++ )
42434263 PKCS7_add_certificate (sig , sk_X509_value (cparams -> xcerts , i ));
42444264 }
4245- for (i = sk_X509_num (cparams -> certs )- 1 ; i >=0 ; i -- )
4246- PKCS7_add_certificate (sig , sk_X509_value (cparams -> certs , i ));
4247-
42484265 /* add crls */
42494266 if (cparams -> crls ) {
42504267 for (i = 0 ; i < sk_X509_CRL_num (cparams -> crls ); i ++ )
42514268 PKCS7_add_crl (sig , sk_X509_CRL_value (cparams -> crls , i ));
42524269 }
4253-
42544270 return sig ; /* OK */
42554271}
42564272
0 commit comments