ZEND_ARG_INFO(0, cainfo) /* array */
ZEND_ARG_INFO(0, extracerts)
ZEND_ARG_INFO(0, content)
+ ZEND_ARG_INFO(0, pk7)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_pkcs7_encrypt, 0, 0, 4)
ZEND_ARG_INFO(0, recipkey)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_pkcs7_read, 0, 0, 2)
+ ZEND_ARG_INFO(0, infilename)
+ ZEND_ARG_INFO(1, certs)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_private_encrypt, 0, 0, 3)
ZEND_ARG_INFO(0, data)
ZEND_ARG_INFO(1, crypted)
PHP_FE(openssl_pkcs7_decrypt, arginfo_openssl_pkcs7_decrypt)
PHP_FE(openssl_pkcs7_sign, arginfo_openssl_pkcs7_sign)
PHP_FE(openssl_pkcs7_encrypt, arginfo_openssl_pkcs7_encrypt)
+ PHP_FE(openssl_pkcs7_read, arginfo_openssl_pkcs7_read)
PHP_FE(openssl_private_encrypt, arginfo_openssl_private_encrypt)
PHP_FE(openssl_private_decrypt, arginfo_openssl_private_decrypt)
/* {{{ PKCS7 S/MIME functions */
-/* {{{ proto bool openssl_pkcs7_verify(string filename, long flags [, string signerscerts [, array cainfo [, string extracerts [, string content]]]])
+/* {{{ proto bool openssl_pkcs7_verify(string filename, long flags [, string signerscerts [, array cainfo [, string extracerts [, string content [, string pk7]]]]])
Verifys that the data block is intact, the signer is who they say they are, and returns the CERTs of the signers */
PHP_FUNCTION(openssl_pkcs7_verify)
{
STACK_OF(X509) *signers= NULL;
STACK_OF(X509) *others = NULL;
PKCS7 * p7 = NULL;
- BIO * in = NULL, * datain = NULL, * dataout = NULL;
+ BIO * in = NULL, * datain = NULL, * dataout = NULL, * p7bout = NULL;
zend_long flags = 0;
char * filename;
size_t filename_len;
size_t signersfilename_len = 0;
char * datafilename = NULL;
size_t datafilename_len = 0;
+ char * p7bfilename = NULL;
+ size_t p7bfilename_len = 0;
RETVAL_LONG(-1);
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "pl|papp", &filename, &filename_len,
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "pl|pappp", &filename, &filename_len,
&flags, &signersfilename, &signersfilename_len, &cainfo,
- &extracerts, &extracerts_len, &datafilename, &datafilename_len) == FAILURE) {
+ &extracerts, &extracerts_len, &datafilename, &datafilename_len, &p7bfilename, &p7bfilename_len) == FAILURE) {
return;
}
goto clean_exit;
}
}
+
+ if (p7bfilename) {
+
+ if (php_openssl_open_base_dir_chk(p7bfilename)) {
+ goto clean_exit;
+ }
+
+ p7bout = BIO_new_file(p7bfilename, "w");
+ if (p7bout == NULL) {
+ php_openssl_store_errors();
+ goto clean_exit;
+ }
+ }
#if DEBUG_SMIME
zend_printf("Calling PKCS7 verify\n");
#endif
php_error_docref(NULL, E_WARNING, "signature OK, but cannot open %s for writing", signersfilename);
RETVAL_LONG(-1);
}
+
+ if (p7bout) {
+ PEM_write_bio_PKCS7(p7bout, p7);
+ }
}
} else {
php_openssl_store_errors();
RETVAL_FALSE;
}
clean_exit:
+ if (p7bout) {
+ BIO_free(p7bout);
+ }
X509_STORE_free(store);
BIO_free(datain);
BIO_free(in);
}
/* }}} */
+/* {{{ proto bool openssl_pkcs7_read(string P7B, array &certs)
+ Exports the PKCS7 file to an array of PEM certificates */
+PHP_FUNCTION(openssl_pkcs7_read)
+{
+ zval * zout = NULL, zcert;
+ char *p7b;
+ size_t p7b_len;
+ STACK_OF(X509) *certs = NULL;
+ STACK_OF(X509_CRL) *crls = NULL;
+ BIO * bio_in = NULL, * bio_out = NULL;
+ PKCS7 * p7 = NULL;
+ int i;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz/", &p7b, &p7b_len,
+ &zout) == FAILURE) {
+ return;
+ }
+
+ RETVAL_FALSE;
+
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT(p7b_len, p7b);
+
+ bio_in = BIO_new(BIO_s_mem());
+ if (bio_in == NULL) {
+ goto clean_exit;
+ }
+
+ if (0 >= BIO_write(bio_in, p7b, (int)p7b_len)) {
+ php_openssl_store_errors();
+ goto clean_exit;
+ }
+
+ p7 = PEM_read_bio_PKCS7(bio_in, NULL, NULL, NULL);
+ if (p7 == NULL) {
+ php_openssl_store_errors();
+ goto clean_exit;
+ }
+
+ switch (OBJ_obj2nid(p7->type)) {
+ case NID_pkcs7_signed:
+ if (p7->d.sign != NULL) {
+ certs = p7->d.sign->cert;
+ crls = p7->d.sign->crl;
+ }
+ break;
+ case NID_pkcs7_signedAndEnveloped:
+ if (p7->d.signed_and_enveloped != NULL) {
+ certs = p7->d.signed_and_enveloped->cert;
+ crls = p7->d.signed_and_enveloped->crl;
+ }
+ break;
+ default:
+ break;
+ }
+
+ zval_dtor(zout);
+ array_init(zout);
+
+ if (certs != NULL) {
+ for (i = 0; i < sk_X509_num(certs); i++) {
+ X509* ca = sk_X509_value(certs, i);
+
+ bio_out = BIO_new(BIO_s_mem());
+ if (bio_out && PEM_write_bio_X509(bio_out, ca)) {
+ BUF_MEM *bio_buf;
+ BIO_get_mem_ptr(bio_out, &bio_buf);
+ ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length);
+ add_index_zval(zout, i, &zcert);
+ BIO_free(bio_out);
+ }
+ }
+ }
+
+ if (crls != NULL) {
+ for (i = 0; i < sk_X509_CRL_num(crls); i++) {
+ X509_CRL* crl = sk_X509_CRL_value(crls, i);
+
+ bio_out = BIO_new(BIO_s_mem());
+ if (bio_out && PEM_write_bio_X509_CRL(bio_out, crl)) {
+ BUF_MEM *bio_buf;
+ BIO_get_mem_ptr(bio_out, &bio_buf);
+ ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length);
+ add_index_zval(zout, i, &zcert);
+ BIO_free(bio_out);
+ }
+ }
+ }
+
+ RETVAL_TRUE;
+
+clean_exit:
+ if (bio_in != NULL) {
+ BIO_free(bio_in);
+ }
+
+ if (p7 != NULL) {
+ PKCS7_free(p7);
+ }
+}
+/* }}} */
+
/* {{{ proto bool openssl_pkcs7_sign(string infile, string outfile, mixed signcert, mixed signkey, array headers [, long flags [, string extracertsfilename]])
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 */
--- /dev/null
+--TEST--
+openssl_pkcs7_read() tests
+--SKIPIF--
+<?php if (!extension_loaded("openssl")) print "skip"; ?>
+--FILE--
+<?php
+$infile = file_get_contents(dirname(__FILE__) . "/cert.p7b");
+$certfile = file_get_contents(dirname(__FILE__) . "/cert.crt");
+$result = [];
+
+var_dump(openssl_pkcs7_read());
+var_dump(openssl_pkcs7_read(""));
+var_dump(openssl_pkcs7_read("", $result));
+var_dump(openssl_pkcs7_read($certfile, $result));
+var_dump(openssl_pkcs7_read($infile, $result));
+var_dump($result);
+?>
+--EXPECTF--
+
+Warning: openssl_pkcs7_read() expects exactly 2 parameters, 0 given in %s on line %d
+NULL
+
+Warning: openssl_pkcs7_read() expects exactly 2 parameters, 1 given in %s on line %d
+NULL
+bool(false)
+bool(false)
+bool(true)
+array(1) {
+ [0]=>
+ string(1249) "-----BEGIN CERTIFICATE-----
+MIIDbDCCAtWgAwIBAgIJAK7FVsxyN1CiMA0GCSqGSIb3DQEBBQUAMIGBMQswCQYD
+VQQGEwJCUjEaMBgGA1UECBMRUmlvIEdyYW5kZSBkbyBTdWwxFTATBgNVBAcTDFBv
+cnRvIEFsZWdyZTEeMBwGA1UEAxMVSGVucmlxdWUgZG8gTi4gQW5nZWxvMR8wHQYJ
+KoZIhvcNAQkBFhBobmFuZ2Vsb0BwaHAubmV0MB4XDTA4MDYzMDEwMjg0M1oXDTA4
+MDczMDEwMjg0M1owgYExCzAJBgNVBAYTAkJSMRowGAYDVQQIExFSaW8gR3JhbmRl
+IGRvIFN1bDEVMBMGA1UEBxMMUG9ydG8gQWxlZ3JlMR4wHAYDVQQDExVIZW5yaXF1
+ZSBkbyBOLiBBbmdlbG8xHzAdBgkqhkiG9w0BCQEWEGhuYW5nZWxvQHBocC5uZXQw
+gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMteno+QK1ulX4/WDAVBYfoTPRTz
+e4SZLwgael4jwWTytj+8c5nNllrFELD6WjJzfjaoIMhCF4w4I2bkWR6/PTqrvnv+
+iiiItHfKvJgYqIobUhkiKmWa2wL3mgqvNRIqTrTC4jWZuCkxQ/ksqL9O/F6zk+aR
+S1d+KbPaqCR5Rw+lAgMBAAGjgekwgeYwHQYDVR0OBBYEFNt+QHK9XDWF7CkpgRLo
+Ymhqtz99MIG2BgNVHSMEga4wgauAFNt+QHK9XDWF7CkpgRLoYmhqtz99oYGHpIGE
+MIGBMQswCQYDVQQGEwJCUjEaMBgGA1UECBMRUmlvIEdyYW5kZSBkbyBTdWwxFTAT
+BgNVBAcTDFBvcnRvIEFsZWdyZTEeMBwGA1UEAxMVSGVucmlxdWUgZG8gTi4gQW5n
+ZWxvMR8wHQYJKoZIhvcNAQkBFhBobmFuZ2Vsb0BwaHAubmV0ggkArsVWzHI3UKIw
+DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCP1GUnStC0TBqngr3Kx+zS
+UW8KutKO0ORc5R8aV/x9LlaJrzPyQJgiPpu5hXogLSKRIHxQS3X2+Y0VvIpW72LW
+PVKPhYlNtO3oKnfoJGKin0eEhXRZMjfEW/kznY+ZZmNifV2r8s+KhNAqI4PbClvn
+4vh8xF/9+eVEj+hM+0OflA==
+-----END CERTIFICATE-----
+"
+}
die("failed to get a temporary filename!");
}
+$pkcsfile = dirname(__FILE__) . "/openssl_pkcs7_verify__pkcsfile.tmp";
+
$infile = dirname(__FILE__) . "/cert.crt";
$eml = dirname(__FILE__) . "/signed.eml";
$wrong = "wrong";
var_dump(openssl_pkcs7_verify($eml, 0, $empty));
var_dump(openssl_pkcs7_verify($eml, PKCS7_NOVERIFY, $outfile));
var_dump(openssl_pkcs7_verify($eml, PKCS7_NOVERIFY, $outfile, $cainfo, $outfile, $contentfile));
+var_dump(openssl_pkcs7_verify($eml, PKCS7_NOVERIFY, $outfile, $cainfo, $outfile, $contentfile, $pkcsfile));
+var_dump(file_get_contents($pkcsfile));
if (file_exists($outfile)) {
echo "true\n";
unlink($contentfile);
}
?>
+--CLEAN--
+<?php
+if (file_exists($pkcsfile)) {
+ unlink($pkcsfile);
+}
+?>
--EXPECTF--
int(-1)
int(-1)
bool(false)
bool(true)
bool(true)
+bool(true)
+string(2062) "-----BEGIN PKCS7-----
+MIIFzQYJKoZIhvcNAQcCoIIFvjCCBboCAQExDzANBglghkgBZQMEAgEFADALBgkq
+hkiG9w0BBwGgggNwMIIDbDCCAtWgAwIBAgIJAK7FVsxyN1CiMA0GCSqGSIb3DQEB
+BQUAMIGBMQswCQYDVQQGEwJCUjEaMBgGA1UECBMRUmlvIEdyYW5kZSBkbyBTdWwx
+FTATBgNVBAcTDFBvcnRvIEFsZWdyZTEeMBwGA1UEAxMVSGVucmlxdWUgZG8gTi4g
+QW5nZWxvMR8wHQYJKoZIhvcNAQkBFhBobmFuZ2Vsb0BwaHAubmV0MB4XDTA4MDYz
+MDEwMjg0M1oXDTA4MDczMDEwMjg0M1owgYExCzAJBgNVBAYTAkJSMRowGAYDVQQI
+ExFSaW8gR3JhbmRlIGRvIFN1bDEVMBMGA1UEBxMMUG9ydG8gQWxlZ3JlMR4wHAYD
+VQQDExVIZW5yaXF1ZSBkbyBOLiBBbmdlbG8xHzAdBgkqhkiG9w0BCQEWEGhuYW5n
+ZWxvQHBocC5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMteno+QK1ul
+X4/WDAVBYfoTPRTze4SZLwgael4jwWTytj+8c5nNllrFELD6WjJzfjaoIMhCF4w4
+I2bkWR6/PTqrvnv+iiiItHfKvJgYqIobUhkiKmWa2wL3mgqvNRIqTrTC4jWZuCkx
+Q/ksqL9O/F6zk+aRS1d+KbPaqCR5Rw+lAgMBAAGjgekwgeYwHQYDVR0OBBYEFNt+
+QHK9XDWF7CkpgRLoYmhqtz99MIG2BgNVHSMEga4wgauAFNt+QHK9XDWF7CkpgRLo
+Ymhqtz99oYGHpIGEMIGBMQswCQYDVQQGEwJCUjEaMBgGA1UECBMRUmlvIEdyYW5k
+ZSBkbyBTdWwxFTATBgNVBAcTDFBvcnRvIEFsZWdyZTEeMBwGA1UEAxMVSGVucmlx
+dWUgZG8gTi4gQW5nZWxvMR8wHQYJKoZIhvcNAQkBFhBobmFuZ2Vsb0BwaHAubmV0
+ggkArsVWzHI3UKIwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCP1GUn
+StC0TBqngr3Kx+zSUW8KutKO0ORc5R8aV/x9LlaJrzPyQJgiPpu5hXogLSKRIHxQ
+S3X2+Y0VvIpW72LWPVKPhYlNtO3oKnfoJGKin0eEhXRZMjfEW/kznY+ZZmNifV2r
+8s+KhNAqI4PbClvn4vh8xF/9+eVEj+hM+0OflDGCAiEwggIdAgEBMIGPMIGBMQsw
+CQYDVQQGEwJCUjEaMBgGA1UECBMRUmlvIEdyYW5kZSBkbyBTdWwxFTATBgNVBAcT
+DFBvcnRvIEFsZWdyZTEeMBwGA1UEAxMVSGVucmlxdWUgZG8gTi4gQW5nZWxvMR8w
+HQYJKoZIhvcNAQkBFhBobmFuZ2Vsb0BwaHAubmV0AgkArsVWzHI3UKIwDQYJYIZI
+AWUDBAIBBQCggeQwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0B
+CQUxDxcNMTcwNTIyMTAxMDU1WjAvBgkqhkiG9w0BCQQxIgQg37MSoxw91phVhwUO
+MeurwtXAXK1ADEeYYl/7Bfmz4CsweQYJKoZIhvcNAQkPMWwwajALBglghkgBZQME
+ASowCwYJYIZIAWUDBAEWMAsGCWCGSAFlAwQBAjAKBggqhkiG9w0DBzAOBggqhkiG
+9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgw
+DQYJKoZIhvcNAQEBBQAEgYAw4XcsQ4BIhEuRNspG8RqPE9ODCrTWwXPSQ4B9fzks
+KUAsqcefO8AfifY+uuq3/k6Prhl23U5ILth/0fUAIGFLTcIZziaGTwbpgcmRSmNi
+jBxatHyKVaGJNGqij5KRk8vhEpy5mwOzmkUzYa0r4teXjyfnKhI/h1vUrO3kKybC
+5Q==
+-----END PKCS7-----
+"
true
true