@@ -290,6 +290,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_pkcs7_verify, 0, 0, 2)
290
290
ZEND_ARG_INFO (0 , cainfo ) /* array */
291
291
ZEND_ARG_INFO (0 , extracerts )
292
292
ZEND_ARG_INFO (0 , content )
293
+ ZEND_ARG_INFO (0 , pk7 )
293
294
ZEND_END_ARG_INFO ()
294
295
295
296
ZEND_BEGIN_ARG_INFO_EX (arginfo_openssl_pkcs7_encrypt , 0 , 0 , 4 )
@@ -318,6 +319,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_pkcs7_decrypt, 0, 0, 3)
318
319
ZEND_ARG_INFO (0 , recipkey )
319
320
ZEND_END_ARG_INFO ()
320
321
322
+ ZEND_BEGIN_ARG_INFO_EX (arginfo_openssl_pkcs7_read , 0 , 0 , 2 )
323
+ ZEND_ARG_INFO (0 , infilename )
324
+ ZEND_ARG_INFO (1 , certs )
325
+ ZEND_END_ARG_INFO ()
326
+
321
327
ZEND_BEGIN_ARG_INFO_EX (arginfo_openssl_private_encrypt , 0 , 0 , 3 )
322
328
ZEND_ARG_INFO (0 , data )
323
329
ZEND_ARG_INFO (1 , crypted )
@@ -519,6 +525,7 @@ const zend_function_entry openssl_functions[] = {
519
525
PHP_FE (openssl_pkcs7_decrypt , arginfo_openssl_pkcs7_decrypt )
520
526
PHP_FE (openssl_pkcs7_sign , arginfo_openssl_pkcs7_sign )
521
527
PHP_FE (openssl_pkcs7_encrypt , arginfo_openssl_pkcs7_encrypt )
528
+ PHP_FE (openssl_pkcs7_read , arginfo_openssl_pkcs7_read )
522
529
523
530
PHP_FE (openssl_private_encrypt , arginfo_openssl_private_encrypt )
524
531
PHP_FE (openssl_private_decrypt , arginfo_openssl_private_decrypt )
@@ -4968,7 +4975,7 @@ PHP_FUNCTION(openssl_pbkdf2)
4968
4975
4969
4976
/* {{{ PKCS7 S/MIME functions */
4970
4977
4971
- /* {{{ proto bool openssl_pkcs7_verify(string filename, long flags [, string signerscerts [, array cainfo [, string extracerts [, string content]]]])
4978
+ /* {{{ proto bool openssl_pkcs7_verify(string filename, long flags [, string signerscerts [, array cainfo [, string extracerts [, string content [, string pk7] ]]]])
4972
4979
Verifys that the data block is intact, the signer is who they say they are, and returns the CERTs of the signers */
4973
4980
PHP_FUNCTION (openssl_pkcs7_verify )
4974
4981
{
@@ -4977,7 +4984,7 @@ PHP_FUNCTION(openssl_pkcs7_verify)
4977
4984
STACK_OF (X509 ) * signers = NULL ;
4978
4985
STACK_OF (X509 ) * others = NULL ;
4979
4986
PKCS7 * p7 = NULL ;
4980
- BIO * in = NULL , * datain = NULL , * dataout = NULL ;
4987
+ BIO * in = NULL , * datain = NULL , * dataout = NULL , * p7bout = NULL ;
4981
4988
zend_long flags = 0 ;
4982
4989
char * filename ;
4983
4990
size_t filename_len ;
@@ -4987,12 +4994,14 @@ PHP_FUNCTION(openssl_pkcs7_verify)
4987
4994
size_t signersfilename_len = 0 ;
4988
4995
char * datafilename = NULL ;
4989
4996
size_t datafilename_len = 0 ;
4997
+ char * p7bfilename = NULL ;
4998
+ size_t p7bfilename_len = 0 ;
4990
4999
4991
5000
RETVAL_LONG (-1 );
4992
5001
4993
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "pl|papp " , & filename , & filename_len ,
5002
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "pl|pappp " , & filename , & filename_len ,
4994
5003
& flags , & signersfilename , & signersfilename_len , & cainfo ,
4995
- & extracerts , & extracerts_len , & datafilename , & datafilename_len ) == FAILURE ) {
5004
+ & extracerts , & extracerts_len , & datafilename , & datafilename_len , & p7bfilename , & p7bfilename_len ) == FAILURE ) {
4996
5005
return ;
4997
5006
}
4998
5007
@@ -5040,6 +5049,19 @@ PHP_FUNCTION(openssl_pkcs7_verify)
5040
5049
goto clean_exit ;
5041
5050
}
5042
5051
}
5052
+
5053
+ if (p7bfilename ) {
5054
+
5055
+ if (php_openssl_open_base_dir_chk (p7bfilename )) {
5056
+ goto clean_exit ;
5057
+ }
5058
+
5059
+ p7bout = BIO_new_file (p7bfilename , "w" );
5060
+ if (p7bout == NULL ) {
5061
+ php_openssl_store_errors ();
5062
+ goto clean_exit ;
5063
+ }
5064
+ }
5043
5065
#if DEBUG_SMIME
5044
5066
zend_printf ("Calling PKCS7 verify\n" );
5045
5067
#endif
@@ -5081,12 +5103,19 @@ PHP_FUNCTION(openssl_pkcs7_verify)
5081
5103
php_error_docref (NULL , E_WARNING , "signature OK, but cannot open %s for writing" , signersfilename );
5082
5104
RETVAL_LONG (-1 );
5083
5105
}
5106
+
5107
+ if (p7bout ) {
5108
+ PEM_write_bio_PKCS7 (p7bout , p7 );
5109
+ }
5084
5110
}
5085
5111
} else {
5086
5112
php_openssl_store_errors ();
5087
5113
RETVAL_FALSE ;
5088
5114
}
5089
5115
clean_exit :
5116
+ if (p7bout ) {
5117
+ BIO_free (p7bout );
5118
+ }
5090
5119
X509_STORE_free (store );
5091
5120
BIO_free (datain );
5092
5121
BIO_free (in );
@@ -5230,6 +5259,107 @@ PHP_FUNCTION(openssl_pkcs7_encrypt)
5230
5259
}
5231
5260
/* }}} */
5232
5261
5262
+ /* {{{ proto bool openssl_pkcs7_read(string P7B, array &certs)
5263
+ Exports the PKCS7 file to an array of PEM certificates */
5264
+ PHP_FUNCTION (openssl_pkcs7_read )
5265
+ {
5266
+ zval * zout = NULL , zcert ;
5267
+ char * p7b ;
5268
+ size_t p7b_len ;
5269
+ STACK_OF (X509 ) * certs = NULL ;
5270
+ STACK_OF (X509_CRL ) * crls = NULL ;
5271
+ BIO * bio_in = NULL , * bio_out = NULL ;
5272
+ PKCS7 * p7 = NULL ;
5273
+ int i ;
5274
+
5275
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "sz/" , & p7b , & p7b_len ,
5276
+ & zout ) == FAILURE ) {
5277
+ return ;
5278
+ }
5279
+
5280
+ RETVAL_FALSE ;
5281
+
5282
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT (p7b_len , p7b );
5283
+
5284
+ bio_in = BIO_new (BIO_s_mem ());
5285
+ if (bio_in == NULL ) {
5286
+ goto clean_exit ;
5287
+ }
5288
+
5289
+ if (0 >= BIO_write (bio_in , p7b , (int )p7b_len )) {
5290
+ php_openssl_store_errors ();
5291
+ goto clean_exit ;
5292
+ }
5293
+
5294
+ p7 = PEM_read_bio_PKCS7 (bio_in , NULL , NULL , NULL );
5295
+ if (p7 == NULL ) {
5296
+ php_openssl_store_errors ();
5297
+ goto clean_exit ;
5298
+ }
5299
+
5300
+ switch (OBJ_obj2nid (p7 -> type )) {
5301
+ case NID_pkcs7_signed :
5302
+ if (p7 -> d .sign != NULL ) {
5303
+ certs = p7 -> d .sign -> cert ;
5304
+ crls = p7 -> d .sign -> crl ;
5305
+ }
5306
+ break ;
5307
+ case NID_pkcs7_signedAndEnveloped :
5308
+ if (p7 -> d .signed_and_enveloped != NULL ) {
5309
+ certs = p7 -> d .signed_and_enveloped -> cert ;
5310
+ crls = p7 -> d .signed_and_enveloped -> crl ;
5311
+ }
5312
+ break ;
5313
+ default :
5314
+ break ;
5315
+ }
5316
+
5317
+ zval_dtor (zout );
5318
+ array_init (zout );
5319
+
5320
+ if (certs != NULL ) {
5321
+ for (i = 0 ; i < sk_X509_num (certs ); i ++ ) {
5322
+ X509 * ca = sk_X509_value (certs , i );
5323
+
5324
+ bio_out = BIO_new (BIO_s_mem ());
5325
+ if (bio_out && PEM_write_bio_X509 (bio_out , ca )) {
5326
+ BUF_MEM * bio_buf ;
5327
+ BIO_get_mem_ptr (bio_out , & bio_buf );
5328
+ ZVAL_STRINGL (& zcert , bio_buf -> data , bio_buf -> length );
5329
+ add_index_zval (zout , i , & zcert );
5330
+ BIO_free (bio_out );
5331
+ }
5332
+ }
5333
+ }
5334
+
5335
+ if (crls != NULL ) {
5336
+ for (i = 0 ; i < sk_X509_CRL_num (crls ); i ++ ) {
5337
+ X509_CRL * crl = sk_X509_CRL_value (crls , i );
5338
+
5339
+ bio_out = BIO_new (BIO_s_mem ());
5340
+ if (bio_out && PEM_write_bio_X509_CRL (bio_out , crl )) {
5341
+ BUF_MEM * bio_buf ;
5342
+ BIO_get_mem_ptr (bio_out , & bio_buf );
5343
+ ZVAL_STRINGL (& zcert , bio_buf -> data , bio_buf -> length );
5344
+ add_index_zval (zout , i , & zcert );
5345
+ BIO_free (bio_out );
5346
+ }
5347
+ }
5348
+ }
5349
+
5350
+ RETVAL_TRUE ;
5351
+
5352
+ clean_exit :
5353
+ if (bio_in != NULL ) {
5354
+ BIO_free (bio_in );
5355
+ }
5356
+
5357
+ if (p7 != NULL ) {
5358
+ PKCS7_free (p7 );
5359
+ }
5360
+ }
5361
+ /* }}} */
5362
+
5233
5363
/* {{{ proto bool openssl_pkcs7_sign(string infile, string outfile, mixed signcert, mixed signkey, array headers [, long flags [, string extracertsfilename]])
5234
5364
Signs the MIME message in the file named infile with signcert/signkey and output the result to file name outfile. headers lists plain text headers to exclude from the signed portion of the message, and should include to, from and subject as a minimum */
5235
5365
0 commit comments