summaryrefslogtreecommitdiff
path: root/ext/openssl/openssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/openssl/openssl.c')
-rwxr-xr-x[-rw-r--r--]ext/openssl/openssl.c1644
1 files changed, 768 insertions, 876 deletions
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index 4aac4e3137..c4b155b478 100644..100755
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -1,8 +1,8 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 5 |
+ | PHP Version 7 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2013 The PHP Group |
+ | Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -27,6 +27,7 @@
#endif
#include "php.h"
+#include "php_ini.h"
#include "php_openssl.h"
/* PHP Includes */
@@ -77,6 +78,10 @@
#endif
#define DEBUG_SMIME 0
+#if !defined(OPENSSL_NO_EC) && defined(EVP_PKEY_EC)
+#define HAVE_EVP_PKEY_EC 1
+#endif
+
/* FIXME: Use the openssl constants instead of
* enum. It is now impossible to match real values
* against php constants. Also sorry to break the
@@ -87,7 +92,7 @@ enum php_openssl_key_type {
OPENSSL_KEYTYPE_DSA,
OPENSSL_KEYTYPE_DH,
OPENSSL_KEYTYPE_DEFAULT = OPENSSL_KEYTYPE_RSA,
-#ifdef EVP_PKEY_EC
+#ifdef HAVE_EVP_PKEY_EC
OPENSSL_KEYTYPE_EC = OPENSSL_KEYTYPE_DH +1
#endif
};
@@ -129,6 +134,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_x509_export, 0, 0, 2)
ZEND_ARG_INFO(0, notext)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_x509_fingerprint, 0, 0, 1)
+ ZEND_ARG_INFO(0, x509)
+ ZEND_ARG_INFO(0, method)
+ ZEND_ARG_INFO(0, raw_output)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO(arginfo_openssl_x509_check_private_key, 0)
ZEND_ARG_INFO(0, cert)
ZEND_ARG_INFO(0, key)
@@ -412,11 +423,16 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_openssl_spki_export_challenge, 0)
ZEND_ARG_INFO(0, spki)
ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_openssl_get_cert_locations, 0)
+ZEND_END_ARG_INFO()
/* }}} */
/* {{{ openssl_functions[]
*/
const zend_function_entry openssl_functions[] = {
+ PHP_FE(openssl_get_cert_locations, arginfo_openssl_get_cert_locations)
+
/* spki functions */
PHP_FE(openssl_spki_new, arginfo_openssl_spki_new)
PHP_FE(openssl_spki_verify, arginfo_openssl_spki_verify)
@@ -443,6 +459,7 @@ const zend_function_entry openssl_functions[] = {
PHP_FE(openssl_x509_checkpurpose, arginfo_openssl_x509_checkpurpose)
PHP_FE(openssl_x509_check_private_key, arginfo_openssl_x509_check_private_key)
PHP_FE(openssl_x509_export, arginfo_openssl_x509_export)
+ PHP_FE(openssl_x509_fingerprint, arginfo_openssl_x509_fingerprint)
PHP_FE(openssl_x509_export_to_file, arginfo_openssl_x509_export_to_file)
/* PKCS12 funcs */
@@ -525,7 +542,7 @@ int php_openssl_get_x509_list_id(void) /* {{{ */
/* }}} */
/* {{{ resource destructors */
-static void php_pkey_free(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+static void php_pkey_free(zend_resource *rsrc TSRMLS_DC)
{
EVP_PKEY *pkey = (EVP_PKEY *)rsrc->ptr;
@@ -534,13 +551,13 @@ static void php_pkey_free(zend_rsrc_list_entry *rsrc TSRMLS_DC)
EVP_PKEY_free(pkey);
}
-static void php_x509_free(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+static void php_x509_free(zend_resource *rsrc TSRMLS_DC)
{
X509 *x509 = (X509 *)rsrc->ptr;
X509_free(x509);
}
-static void php_csr_free(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+static void php_csr_free(zend_resource *rsrc TSRMLS_DC)
{
X509_REQ * csr = (X509_REQ*)rsrc->ptr;
X509_REQ_free(csr);
@@ -558,6 +575,16 @@ inline static int php_openssl_open_base_dir_chk(char *filename TSRMLS_DC)
}
/* }}} */
+php_stream* php_openssl_get_stream_from_ssl_handle(const SSL *ssl)
+{
+ return (php_stream*)SSL_get_ex_data(ssl, ssl_stream_data_index);
+}
+
+int php_openssl_get_ssl_stream_data_index()
+{
+ return ssl_stream_data_index;
+}
+
/* openssl -> PHP "bridging" */
/* true global; readonly after module startup */
static char default_ssl_conf_filename[MAXPATHLEN];
@@ -588,18 +615,18 @@ struct php_x509_request { /* {{{ */
};
/* }}} */
-static X509 * php_openssl_x509_from_zval(zval ** val, int makeresource, long * resourceval TSRMLS_DC);
-static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char * passphrase, int makeresource, long * resourceval TSRMLS_DC);
+static X509 * php_openssl_x509_from_zval(zval * val, int makeresource, zend_resource **resourceval TSRMLS_DC);
+static EVP_PKEY * php_openssl_evp_from_zval(zval * val, int public_key, char * passphrase, int makeresource, zend_resource **resourceval TSRMLS_DC);
static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC);
-static X509_STORE * setup_verify(zval * calist TSRMLS_DC);
+static X509_STORE * setup_verify(zval * calist TSRMLS_DC);
static STACK_OF(X509) * load_all_certs_from_file(char *certfile);
-static X509_REQ * php_openssl_csr_from_zval(zval ** val, int makeresource, long * resourceval TSRMLS_DC);
+static X509_REQ * php_openssl_csr_from_zval(zval * val, int makeresource, zend_resource ** resourceval TSRMLS_DC);
static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req TSRMLS_DC);
static void add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int shortname TSRMLS_DC) /* {{{ */
{
- zval **data;
- zval *subitem, *subentries;
+ zval *data;
+ zval subitem, tmp;
int i;
char *sname;
int nid;
@@ -608,10 +635,9 @@ static void add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int s
ASN1_OBJECT * obj;
if (key != NULL) {
- MAKE_STD_ZVAL(subitem);
- array_init(subitem);
+ array_init(&subitem);
} else {
- subitem = val;
+ ZVAL_COPY_VALUE(&subitem, val);
}
for (i = 0; i < X509_NAME_entry_count(name); i++) {
@@ -638,31 +664,29 @@ static void add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int s
}
if (to_add_len != -1) {
- if (zend_hash_find(Z_ARRVAL_P(subitem), sname, strlen(sname)+1, (void**)&data) == SUCCESS) {
- if (Z_TYPE_PP(data) == IS_ARRAY) {
- subentries = *data;
- add_next_index_stringl(subentries, (char *)to_add, to_add_len, 1);
- } else if (Z_TYPE_PP(data) == IS_STRING) {
- MAKE_STD_ZVAL(subentries);
- array_init(subentries);
- add_next_index_stringl(subentries, Z_STRVAL_PP(data), Z_STRLEN_PP(data), 1);
- add_next_index_stringl(subentries, (char *)to_add, to_add_len, 1);
- zend_hash_update(Z_ARRVAL_P(subitem), sname, strlen(sname)+1, &subentries, sizeof(zval*), NULL);
+ if ((data = zend_hash_str_find(Z_ARRVAL(subitem), sname, strlen(sname))) != NULL) {
+ if (Z_TYPE_P(data) == IS_ARRAY) {
+ add_next_index_stringl(data, (char *)to_add, to_add_len);
+ } else if (Z_TYPE_P(data) == IS_STRING) {
+ array_init(&tmp);
+ add_next_index_str(&tmp, zend_string_copy(Z_STR_P(data)));
+ add_next_index_stringl(&tmp, (char *)to_add, to_add_len);
+ zend_hash_str_update(Z_ARRVAL(subitem), sname, strlen(sname), &tmp);
}
} else {
- add_assoc_stringl(subitem, sname, (char *)to_add, to_add_len, 1);
+ add_assoc_stringl(&subitem, sname, (char *)to_add, to_add_len);
}
}
}
if (key != NULL) {
- zend_hash_update(HASH_OF(val), key, strlen(key) + 1, (void *)&subitem, sizeof(subitem), NULL);
+ zend_hash_str_update(HASH_OF(val), key, strlen(key), &subitem);
}
}
/* }}} */
static void add_assoc_asn1_string(zval * val, char * key, ASN1_STRING * str) /* {{{ */
{
- add_assoc_stringl(val, key, (char *)str->data, str->length, 1);
+ add_assoc_stringl(val, key, (char *)str->data, str->length);
}
/* }}} */
@@ -681,18 +705,33 @@ static time_t asn1_time_to_time_t(ASN1_UTCTIME * timestr TSRMLS_DC) /* {{{ */
char * thestr;
long gmadjust = 0;
- if (timestr->length < 13) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "extension author too lazy to parse %s correctly", timestr->data);
+ if (ASN1_STRING_type(timestr) != V_ASN1_UTCTIME && ASN1_STRING_type(timestr) != V_ASN1_GENERALIZEDTIME) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "illegal ASN1 data type for timestamp");
+ return (time_t)-1;
+ }
+
+ if (ASN1_STRING_length(timestr) != strlen((const char*)ASN1_STRING_data(timestr))) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "illegal length in timestamp");
return (time_t)-1;
}
- strbuf = estrdup((char *)timestr->data);
+ if (ASN1_STRING_length(timestr) < 13) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to parse time string %s correctly", timestr->data);
+ return (time_t)-1;
+ }
+
+ if (ASN1_STRING_type(timestr) == V_ASN1_GENERALIZEDTIME && ASN1_STRING_length(timestr) < 15) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to parse time string %s correctly", timestr->data);
+ return (time_t)-1;
+ }
+
+ strbuf = estrdup((char *)ASN1_STRING_data(timestr));
memset(&thetime, 0, sizeof(thetime));
/* we work backwards so that we can use atoi more easily */
- thestr = strbuf + timestr->length - 3;
+ thestr = strbuf + ASN1_STRING_length(timestr) - 3;
thetime.tm_sec = atoi(thestr);
*thestr = '\0';
@@ -707,14 +746,21 @@ static time_t asn1_time_to_time_t(ASN1_UTCTIME * timestr TSRMLS_DC) /* {{{ */
*thestr = '\0';
thestr -= 2;
thetime.tm_mon = atoi(thestr)-1;
+
*thestr = '\0';
- thestr -= 2;
- thetime.tm_year = atoi(thestr);
+ if( ASN1_STRING_type(timestr) == V_ASN1_UTCTIME ) {
+ thestr -= 2;
+ thetime.tm_year = atoi(thestr);
- if (thetime.tm_year < 68) {
- thetime.tm_year += 100;
+ if (thetime.tm_year < 68) {
+ thetime.tm_year += 100;
+ }
+ } else if( ASN1_STRING_type(timestr) == V_ASN1_GENERALIZEDTIME ) {
+ thestr -= 4;
+ thetime.tm_year = atoi(thestr) - 1900;
}
+
thetime.tm_isdst = -1;
ret = mktime(&thetime);
@@ -792,25 +838,25 @@ static int add_oid_section(struct php_x509_request * req TSRMLS_DC) /* {{{ */
req->config_filename, req->var, req->req_config TSRMLS_CC) == FAILURE) return FAILURE
#define SET_OPTIONAL_STRING_ARG(key, varname, defval) \
- if (optional_args && zend_hash_find(Z_ARRVAL_P(optional_args), key, sizeof(key), (void**)&item) == SUCCESS) \
- varname = Z_STRVAL_PP(item); \
+ if (optional_args && (item = zend_hash_str_find(Z_ARRVAL_P(optional_args), key, sizeof(key)-1)) != NULL && Z_TYPE_P(item) == IS_STRING) \
+ varname = Z_STRVAL_P(item); \
else \
varname = defval
#define SET_OPTIONAL_LONG_ARG(key, varname, defval) \
- if (optional_args && zend_hash_find(Z_ARRVAL_P(optional_args), key, sizeof(key), (void**)&item) == SUCCESS) \
- varname = Z_LVAL_PP(item); \
+ if (optional_args && (item = zend_hash_str_find(Z_ARRVAL_P(optional_args), key, sizeof(key)-1)) != NULL && Z_TYPE_P(item) == IS_LONG) \
+ varname = Z_LVAL_P(item); \
else \
varname = defval
-static const EVP_CIPHER * php_openssl_get_evp_cipher_from_algo(long algo);
+static const EVP_CIPHER * php_openssl_get_evp_cipher_from_algo(zend_long algo);
int openssl_spki_cleanup(const char *src, char *dest);
static int php_openssl_parse_config(struct php_x509_request * req, zval * optional_args TSRMLS_DC) /* {{{ */
{
char * str;
- zval ** item;
+ zval * item;
SET_OPTIONAL_STRING_ARG("config", req->config_filename, default_ssl_conf_filename);
SET_OPTIONAL_STRING_ARG("config_section_name", req->section_name, "req");
@@ -844,8 +890,8 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
SET_OPTIONAL_LONG_ARG("private_key_type", req->priv_key_type, OPENSSL_KEYTYPE_DEFAULT);
- if (optional_args && zend_hash_find(Z_ARRVAL_P(optional_args), "encrypt_key", sizeof("encrypt_key"), (void**)&item) == SUCCESS) {
- req->priv_key_encrypt = Z_BVAL_PP(item);
+ if (optional_args && (item = zend_hash_str_find(Z_ARRVAL_P(optional_args), "encrypt_key", sizeof("encrypt_key")-1)) != NULL) {
+ req->priv_key_encrypt = Z_TYPE_P(item) == IS_TRUE ? 1 : 0;
} else {
str = CONF_get_string(req->req_config, req->section_name, "encrypt_rsa_key");
if (str == NULL) {
@@ -858,8 +904,9 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
}
}
- if (req->priv_key_encrypt && optional_args && zend_hash_find(Z_ARRVAL_P(optional_args), "encrypt_key_cipher", sizeof("encrypt_key_cipher"), (void**)&item) == SUCCESS) {
- long cipher_algo = Z_LVAL_PP(item);
+ if (req->priv_key_encrypt && optional_args && (item = zend_hash_str_find(Z_ARRVAL_P(optional_args), "encrypt_key_cipher", sizeof("encrypt_key_cipher")-1)) != NULL
+ && Z_TYPE_P(item) == IS_LONG) {
+ zend_long cipher_algo = Z_LVAL_P(item);
const EVP_CIPHER* cipher = php_openssl_get_evp_cipher_from_algo(cipher_algo);
if (cipher == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown cipher algorithm for private key.");
@@ -881,7 +928,7 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
req->digest = req->md_alg = EVP_get_digestbyname(req->digest_name);
}
if (req->md_alg == NULL) {
- req->md_alg = req->digest = EVP_md5();
+ req->md_alg = req->digest = EVP_sha1();
}
PHP_SSL_CONFIG_SYNTAX_CHECK(extensions_section);
@@ -965,7 +1012,7 @@ static int php_openssl_write_rand_file(const char * file, int egdsocket, int see
}
/* }}} */
-static EVP_MD * php_openssl_get_evp_md_from_algo(long algo) { /* {{{ */
+static EVP_MD * php_openssl_get_evp_md_from_algo(zend_long algo) { /* {{{ */
EVP_MD *mdtype;
switch (algo) {
@@ -1011,7 +1058,7 @@ static EVP_MD * php_openssl_get_evp_md_from_algo(long algo) { /* {{{ */
}
/* }}} */
-static const EVP_CIPHER * php_openssl_get_evp_cipher_from_algo(long algo) { /* {{{ */
+static const EVP_CIPHER * php_openssl_get_evp_cipher_from_algo(zend_long algo) { /* {{{ */
switch (algo) {
#ifndef OPENSSL_NO_RC2
case PHP_OPENSSL_CIPHER_RC2_40:
@@ -1054,6 +1101,13 @@ static const EVP_CIPHER * php_openssl_get_evp_cipher_from_algo(long algo) { /* {
}
/* }}} */
+/* {{{ INI Settings */
+PHP_INI_BEGIN()
+ PHP_INI_ENTRY("openssl.cafile", NULL, PHP_INI_PERDIR, NULL)
+ PHP_INI_ENTRY("openssl.capath", NULL, PHP_INI_PERDIR, NULL)
+PHP_INI_END()
+/* }}} */
+
/* {{{ PHP_MINIT_FUNCTION
*/
PHP_MINIT_FUNCTION(openssl)
@@ -1121,6 +1175,9 @@ PHP_MINIT_FUNCTION(openssl)
REGISTER_LONG_CONSTANT("OPENSSL_NO_PADDING", RSA_NO_PADDING, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_PKCS1_OAEP_PADDING", RSA_PKCS1_OAEP_PADDING, CONST_CS|CONST_PERSISTENT);
+ /* Informational stream wrapper constants */
+ REGISTER_STRING_CONSTANT("OPENSSL_DEFAULT_STREAM_CIPHERS", OPENSSL_DEFAULT_STREAM_CIPHERS, CONST_CS|CONST_PERSISTENT);
+
/* Ciphers */
#ifndef OPENSSL_NO_RC2
REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_RC2_40", PHP_OPENSSL_CIPHER_RC2_40, CONST_CS|CONST_PERSISTENT);
@@ -1143,7 +1200,7 @@ PHP_MINIT_FUNCTION(openssl)
REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_DSA", OPENSSL_KEYTYPE_DSA, CONST_CS|CONST_PERSISTENT);
#endif
REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_DH", OPENSSL_KEYTYPE_DH, CONST_CS|CONST_PERSISTENT);
-#ifdef EVP_PKEY_EC
+#ifdef HAVE_EVP_PKEY_EC
REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_EC", OPENSSL_KEYTYPE_EC, CONST_CS|CONST_PERSISTENT);
#endif
@@ -1176,13 +1233,20 @@ PHP_MINIT_FUNCTION(openssl)
php_stream_xport_register("sslv2", php_openssl_ssl_socket_factory TSRMLS_CC);
#endif
php_stream_xport_register("tls", php_openssl_ssl_socket_factory TSRMLS_CC);
+ php_stream_xport_register("tlsv1.0", php_openssl_ssl_socket_factory TSRMLS_CC);
+#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+ php_stream_xport_register("tlsv1.1", php_openssl_ssl_socket_factory TSRMLS_CC);
+ php_stream_xport_register("tlsv1.2", php_openssl_ssl_socket_factory TSRMLS_CC);
+#endif
/* override the default tcp socket provider */
php_stream_xport_register("tcp", php_openssl_ssl_socket_factory TSRMLS_CC);
php_register_url_stream_wrapper("https", &php_stream_http_wrapper TSRMLS_CC);
php_register_url_stream_wrapper("ftps", &php_stream_ftp_wrapper TSRMLS_CC);
-
+
+ REGISTER_INI_ENTRIES();
+
return SUCCESS;
}
/* }}} */
@@ -1196,6 +1260,7 @@ PHP_MINFO_FUNCTION(openssl)
php_info_print_table_row(2, "OpenSSL Library Version", SSLeay_version(SSLEAY_VERSION));
php_info_print_table_row(2, "OpenSSL Header Version", OPENSSL_VERSION_TEXT);
php_info_print_table_end();
+ DISPLAY_INI_ENTRIES();
}
/* }}} */
@@ -1214,16 +1279,43 @@ PHP_MSHUTDOWN_FUNCTION(openssl)
#endif
php_stream_xport_unregister("sslv3" TSRMLS_CC);
php_stream_xport_unregister("tls" TSRMLS_CC);
+ php_stream_xport_unregister("tlsv1.0" TSRMLS_CC);
+#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+ php_stream_xport_unregister("tlsv1.1" TSRMLS_CC);
+ php_stream_xport_unregister("tlsv1.2" TSRMLS_CC);
+#endif
/* reinstate the default tcp handler */
php_stream_xport_register("tcp", php_stream_generic_socket_factory TSRMLS_CC);
+ UNREGISTER_INI_ENTRIES();
+
return SUCCESS;
}
/* }}} */
/* {{{ x509 cert functions */
+/* {{{ proto array openssl_get_cert_locations(void)
+ Retrieve an array mapping available certificate locations */
+PHP_FUNCTION(openssl_get_cert_locations)
+{
+ array_init(return_value);
+
+ add_assoc_string(return_value, "default_cert_file", (char *) X509_get_default_cert_file());
+ add_assoc_string(return_value, "default_cert_file_env", (char *) X509_get_default_cert_file_env());
+ add_assoc_string(return_value, "default_cert_dir", (char *) X509_get_default_cert_dir());
+ add_assoc_string(return_value, "default_cert_dir_env", (char *) X509_get_default_cert_dir_env());
+ add_assoc_string(return_value, "default_private_dir", (char *) X509_get_default_private_dir());
+ add_assoc_string(return_value, "default_default_cert_area", (char *) X509_get_default_cert_area());
+ add_assoc_string(return_value, "ini_cafile",
+ zend_ini_string("openssl.cafile", sizeof("openssl.cafile")-1, 0));
+ add_assoc_string(return_value, "ini_capath",
+ zend_ini_string("openssl.capath", sizeof("openssl.capath")-1, 0));
+}
+/* }}} */
+
+
/* {{{ php_openssl_x509_from_zval
Given a zval, coerce it into an X509 object.
The zval can be:
@@ -1233,14 +1325,14 @@ PHP_MSHUTDOWN_FUNCTION(openssl)
If you supply makeresource, the result will be registered as an x509 resource and
it's value returned in makeresource.
*/
-static X509 * php_openssl_x509_from_zval(zval ** val, int makeresource, long * resourceval TSRMLS_DC)
+static X509 * php_openssl_x509_from_zval(zval * val, int makeresource, zend_resource **resourceval TSRMLS_DC)
{
X509 *cert = NULL;
if (resourceval) {
- *resourceval = -1;
+ *resourceval = NULL;
}
- if (Z_TYPE_PP(val) == IS_RESOURCE) {
+ if (Z_TYPE_P(val) == IS_RESOURCE) {
/* is it an x509 resource ? */
void * what;
int type;
@@ -1251,7 +1343,8 @@ static X509 * php_openssl_x509_from_zval(zval ** val, int makeresource, long * r
}
/* this is so callers can decide if they should free the X509 */
if (resourceval) {
- *resourceval = Z_LVAL_PP(val);
+ *resourceval = Z_RES_P(val);
+ Z_ADDREF_P(val);
}
if (type == le_x509) {
return (X509*)what;
@@ -1261,22 +1354,22 @@ static X509 * php_openssl_x509_from_zval(zval ** val, int makeresource, long * r
return NULL;
}
- if (!(Z_TYPE_PP(val) == IS_STRING || Z_TYPE_PP(val) == IS_OBJECT)) {
+ if (!(Z_TYPE_P(val) == IS_STRING || Z_TYPE_P(val) == IS_OBJECT)) {
return NULL;
}
/* force it to be a string and check if it refers to a file */
convert_to_string_ex(val);
- if (Z_STRLEN_PP(val) > 7 && memcmp(Z_STRVAL_PP(val), "file://", sizeof("file://") - 1) == 0) {
+ if (Z_STRLEN_P(val) > 7 && memcmp(Z_STRVAL_P(val), "file://", sizeof("file://") - 1) == 0) {
/* read cert from the named file */
BIO *in;
- if (php_openssl_open_base_dir_chk(Z_STRVAL_PP(val) + (sizeof("file://") - 1) TSRMLS_CC)) {
+ if (php_openssl_open_base_dir_chk(Z_STRVAL_P(val) + (sizeof("file://") - 1) TSRMLS_CC)) {
return NULL;
}
- in = BIO_new_file(Z_STRVAL_PP(val) + (sizeof("file://") - 1), "r");
+ in = BIO_new_file(Z_STRVAL_P(val) + (sizeof("file://") - 1), "r");
if (in == NULL) {
return NULL;
}
@@ -1285,7 +1378,7 @@ static X509 * php_openssl_x509_from_zval(zval ** val, int makeresource, long * r
} else {
BIO *in;
- in = BIO_new_mem_buf(Z_STRVAL_PP(val), Z_STRLEN_PP(val));
+ in = BIO_new_mem_buf(Z_STRVAL_P(val), Z_STRLEN_P(val));
if (in == NULL) {
return NULL;
}
@@ -1298,7 +1391,7 @@ static X509 * php_openssl_x509_from_zval(zval ** val, int makeresource, long * r
}
if (cert && makeresource && resourceval) {
- *resourceval = zend_list_insert(cert, le_x509 TSRMLS_CC);
+ *resourceval = zend_register_resource(NULL, cert, le_x509 TSRMLS_CC);
}
return cert;
}
@@ -1310,14 +1403,14 @@ static X509 * php_openssl_x509_from_zval(zval ** val, int makeresource, long * r
PHP_FUNCTION(openssl_x509_export_to_file)
{
X509 * cert;
- zval ** zcert;
+ zval * zcert;
zend_bool notext = 1;
BIO * bio_out;
- long certresource;
+ zend_resource *certresource;
char * filename;
- int filename_len;
+ size_t filename_len;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zp|b", &zcert, &filename, &filename_len, &notext) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zp|b", &zcert, &filename, &filename_len, &notext) == FAILURE) {
return;
}
RETVAL_FALSE;
@@ -1343,7 +1436,7 @@ PHP_FUNCTION(openssl_x509_export_to_file)
} else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "error opening file %s", filename);
}
- if (certresource == -1 && cert) {
+ if (certresource == NULL && cert) {
X509_free(cert);
}
BIO_free(bio_out);
@@ -1355,11 +1448,12 @@ PHP_FUNCTION(openssl_x509_export_to_file)
outputting results to var */
PHP_FUNCTION(openssl_spki_new)
{
- int challenge_len;
- char * challenge = NULL, * spkstr = NULL, * s = NULL;
- long keyresource = -1;
+ size_t challenge_len;
+ char * challenge = NULL, * spkstr = NULL;
+ zend_string * s = NULL;
+ zend_resource *keyresource = NULL;
const char *spkac = "SPKAC=";
- long algo = OPENSSL_ALGO_MD5;
+ zend_long algo = OPENSSL_ALGO_MD5;
zval *method = NULL;
zval * zpkey = NULL;
@@ -1372,7 +1466,7 @@ PHP_FUNCTION(openssl_spki_new)
}
RETVAL_FALSE;
- pkey = php_openssl_evp_from_zval(&zpkey, 0, challenge, 1, &keyresource TSRMLS_CC);
+ pkey = php_openssl_evp_from_zval(zpkey, 0, challenge, 1, &keyresource TSRMLS_CC);
if (pkey == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to use supplied private key");
@@ -1419,30 +1513,31 @@ PHP_FUNCTION(openssl_spki_new)
goto cleanup;
}
- s = emalloc(strlen(spkac) + strlen(spkstr) + 1);
- sprintf(s, "%s%s", spkac, spkstr);
+ s = zend_string_alloc(strlen(spkac) + strlen(spkstr), 0);
+ sprintf(s->val, "%s%s", spkac, spkstr);
+ s->len = strlen(s->val);
- RETVAL_STRINGL(s, strlen(s), 0);
+ RETVAL_STR(s);
goto cleanup;
cleanup:
- if (keyresource == -1 && spki != NULL) {
+ if (keyresource == NULL && spki != NULL) {
NETSCAPE_SPKI_free(spki);
}
- if (keyresource == -1 && pkey != NULL) {
+ if (keyresource == NULL && pkey != NULL) {
EVP_PKEY_free(pkey);
}
- if (keyresource == -1 && spkstr != NULL) {
+ if (keyresource == NULL && spkstr != NULL) {
efree(spkstr);
}
- if (strlen(s) <= 0) {
+ if (s->len <= 0) {
RETVAL_FALSE;
}
- if (keyresource == -1 && s != NULL) {
- efree(s);
+ if (keyresource == NULL && s != NULL) {
+ zend_string_release(s);
}
}
/* }}} */
@@ -1451,7 +1546,8 @@ cleanup:
Verifies spki returns boolean */
PHP_FUNCTION(openssl_spki_verify)
{
- int spkstr_len, i = 0;
+ size_t spkstr_len;
+ int i = 0;
char *spkstr = NULL, * spkstr_cleaned = NULL;
EVP_PKEY *pkey = NULL;
@@ -1511,7 +1607,7 @@ cleanup:
Exports public key from existing spki to var */
PHP_FUNCTION(openssl_spki_export)
{
- int spkstr_len;
+ size_t spkstr_len;
char *spkstr = NULL, * spkstr_cleaned = NULL, * s = NULL;
EVP_PKEY *pkey = NULL;
@@ -1571,7 +1667,7 @@ cleanup:
Exports spkac challenge from existing spki to var */
PHP_FUNCTION(openssl_spki_export_challenge)
{
- int spkstr_len;
+ size_t spkstr_len;
char *spkstr = NULL, * spkstr_cleaned = NULL;
NETSCAPE_SPKI *spki = NULL;
@@ -1595,7 +1691,7 @@ PHP_FUNCTION(openssl_spki_export_challenge)
goto cleanup;
}
- RETVAL_STRING(ASN1_STRING_data(spki->spkac->challenge), 1);
+ RETVAL_STRING((char *) ASN1_STRING_data(spki->spkac->challenge));
goto cleanup;
cleanup:
@@ -1628,12 +1724,12 @@ int openssl_spki_cleanup(const char *src, char *dest)
PHP_FUNCTION(openssl_x509_export)
{
X509 * cert;
- zval ** zcert, *zout;
+ zval * zcert, *zout;
zend_bool notext = 1;
BIO * bio_out;
- long certresource;
+ zend_resource *certresource;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zz|b", &zcert, &zout, &notext) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz/|b", &zcert, &zout, &notext) == FAILURE) {
return;
}
RETVAL_FALSE;
@@ -1653,30 +1749,88 @@ PHP_FUNCTION(openssl_x509_export)
zval_dtor(zout);
BIO_get_mem_ptr(bio_out, &bio_buf);
- ZVAL_STRINGL(zout, bio_buf->data, bio_buf->length, 1);
+ ZVAL_STRINGL(zout, bio_buf->data, bio_buf->length);
RETVAL_TRUE;
}
- if (certresource == -1 && cert) {
+ if (certresource == NULL && cert) {
X509_free(cert);
}
BIO_free(bio_out);
}
/* }}} */
+zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, zend_bool raw TSRMLS_DC)
+{
+ unsigned char md[EVP_MAX_MD_SIZE];
+ const EVP_MD *mdtype;
+ unsigned int n;
+ zend_string *ret;
+
+ if (!(mdtype = EVP_get_digestbyname(method))) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature algorithm");
+ return NULL;
+ } else if (!X509_digest(peer, mdtype, md, &n)) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not generate signature");
+ return NULL;
+ }
+
+ if (raw) {
+ ret = zend_string_init((char*)md, n, 0);
+ } else {
+ ret = zend_string_alloc(n * 2, 0);
+ make_digest_ex(ret->val, md, n);
+ ret->val[n * 2] = '\0';
+ }
+
+ return ret;
+}
+
+PHP_FUNCTION(openssl_x509_fingerprint)
+{
+ X509 *cert;
+ zval *zcert;
+ zend_resource *certresource;
+ zend_bool raw_output = 0;
+ char *method = "sha1";
+ size_t method_len;
+ zend_string *fingerprint;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|sb", &zcert, &method, &method_len, &raw_output) == FAILURE) {
+ return;
+ }
+
+ cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
+ if (cert == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
+ RETURN_FALSE;
+ }
+
+ fingerprint = php_openssl_x509_fingerprint(cert, method, raw_output TSRMLS_CC);
+ if (fingerprint) {
+ RETVAL_STR(fingerprint);
+ } else {
+ RETVAL_FALSE;
+ }
+
+ if (certresource == NULL && cert) {
+ X509_free(cert);
+ }
+}
+
/* {{{ proto bool openssl_x509_check_private_key(mixed cert, mixed key)
Checks if a private key corresponds to a CERT */
PHP_FUNCTION(openssl_x509_check_private_key)
{
- zval ** zcert, **zkey;
+ zval * zcert, *zkey;
X509 * cert = NULL;
EVP_PKEY * key = NULL;
- long certresource = -1, keyresource = -1;
+ zend_resource *certresource = NULL, *keyresource = NULL;
RETVAL_FALSE;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &zcert, &zkey) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &zcert, &zkey) == FAILURE) {
return;
}
cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
@@ -1688,10 +1842,10 @@ PHP_FUNCTION(openssl_x509_check_private_key)
RETVAL_BOOL(X509_check_private_key(cert, key));
}
- if (keyresource == -1 && key) {
+ if (keyresource == NULL && key) {
EVP_PKEY_free(key);
}
- if (certresource == -1 && cert) {
+ if (certresource == NULL && cert) {
X509_free(cert);
}
}
@@ -1769,20 +1923,20 @@ static int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension)
Returns an array of the fields/values of the CERT */
PHP_FUNCTION(openssl_x509_parse)
{
- zval ** zcert;
+ zval * zcert;
X509 * cert = NULL;
- long certresource = -1;
+ zend_resource *certresource = NULL;
int i;
zend_bool useshortnames = 1;
char * tmpstr;
- zval * subitem;
+ zval subitem;
X509_EXTENSION *extension;
char *extname;
BIO *bio_out;
BUF_MEM *bio_buf;
char buf[256];
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|b", &zcert, &useshortnames) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &zcert, &useshortnames) == FAILURE) {
return;
}
cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
@@ -1792,7 +1946,7 @@ PHP_FUNCTION(openssl_x509_parse)
array_init(return_value);
if (cert->name) {
- add_assoc_string(return_value, "name", cert->name, 1);
+ add_assoc_string(return_value, "name", cert->name);
}
/* add_assoc_bool(return_value, "valid", cert->valid); */
@@ -1801,13 +1955,13 @@ PHP_FUNCTION(openssl_x509_parse)
{
char buf[32];
snprintf(buf, sizeof(buf), "%08lx", X509_subject_name_hash(cert));
- add_assoc_string(return_value, "hash", buf, 1);
+ add_assoc_string(return_value, "hash", buf);
}
add_assoc_name_entry(return_value, "issuer", X509_get_issuer_name(cert), useshortnames TSRMLS_CC);
add_assoc_long(return_value, "version", X509_get_version(cert));
- add_assoc_string(return_value, "serialNumber", i2s_ASN1_INTEGER(NULL, X509_get_serialNumber(cert)), 1);
+ add_assoc_string(return_value, "serialNumber", i2s_ASN1_INTEGER(NULL, X509_get_serialNumber(cert)));
add_assoc_asn1_string(return_value, "validFrom", X509_get_notBefore(cert));
add_assoc_asn1_string(return_value, "validTo", X509_get_notAfter(cert));
@@ -1817,15 +1971,14 @@ PHP_FUNCTION(openssl_x509_parse)
tmpstr = (char *)X509_alias_get0(cert, NULL);
if (tmpstr) {
- add_assoc_string(return_value, "alias", tmpstr, 1);
+ add_assoc_string(return_value, "alias", tmpstr);
}
/*
add_assoc_long(return_value, "signaturetypeLONG", X509_get_signature_type(cert));
- add_assoc_string(return_value, "signaturetype", OBJ_nid2sn(X509_get_signature_type(cert)), 1);
- add_assoc_string(return_value, "signaturetypeLN", OBJ_nid2ln(X509_get_signature_type(cert)), 1);
+ add_assoc_string(return_value, "signaturetype", OBJ_nid2sn(X509_get_signature_type(cert)));
+ add_assoc_string(return_value, "signaturetypeLN", OBJ_nid2ln(X509_get_signature_type(cert)));
*/
- MAKE_STD_ZVAL(subitem);
- array_init(subitem);
+ array_init(&subitem);
/* NOTE: the purposes are added as integer keys - the keys match up to the X509_PURPOSE_SSL_XXX defines
in x509v3.h */
@@ -1833,31 +1986,29 @@ PHP_FUNCTION(openssl_x509_parse)
int id, purpset;
char * pname;
X509_PURPOSE * purp;
- zval * subsub;
+ zval subsub;
- MAKE_STD_ZVAL(subsub);
- array_init(subsub);
+ array_init(&subsub);
purp = X509_PURPOSE_get0(i);
id = X509_PURPOSE_get_id(purp);
purpset = X509_check_purpose(cert, id, 0);
- add_index_bool(subsub, 0, purpset);
+ add_index_bool(&subsub, 0, purpset);
purpset = X509_check_purpose(cert, id, 1);
- add_index_bool(subsub, 1, purpset);
+ add_index_bool(&subsub, 1, purpset);
pname = useshortnames ? X509_PURPOSE_get0_sname(purp) : X509_PURPOSE_get0_name(purp);
- add_index_string(subsub, 2, pname, 1);
+ add_index_string(&subsub, 2, pname);
/* NOTE: if purpset > 1 then it's a warning - we should mention it ? */
- add_index_zval(subitem, id, subsub);
+ add_index_zval(&subitem, id, &subsub);
}
- add_assoc_zval(return_value, "purposes", subitem);
+ add_assoc_zval(return_value, "purposes", &subitem);
- MAKE_STD_ZVAL(subitem);
- array_init(subitem);
+ array_init(&subitem);
for (i = 0; i < X509_get_ext_count(cert); i++) {
@@ -1874,10 +2025,10 @@ PHP_FUNCTION(openssl_x509_parse)
if (nid == NID_subject_alt_name) {
if (openssl_x509v3_subjectAltName(bio_out, extension) == 0) {
BIO_get_mem_ptr(bio_out, &bio_buf);
- add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1);
+ add_assoc_stringl(&subitem, extname, bio_buf->data, bio_buf->length);
} else {
zval_dtor(return_value);
- if (certresource == -1 && cert) {
+ if (certresource == NULL && cert) {
X509_free(cert);
}
BIO_free(bio_out);
@@ -1886,15 +2037,15 @@ PHP_FUNCTION(openssl_x509_parse)
}
else if (X509V3_EXT_print(bio_out, extension, 0, 0)) {
BIO_get_mem_ptr(bio_out, &bio_buf);
- add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1);
+ add_assoc_stringl(&subitem, extname, bio_buf->data, bio_buf->length);
} else {
- add_assoc_asn1_string(subitem, extname, X509_EXTENSION_get_data(extension));
+ add_assoc_asn1_string(&subitem, extname, X509_EXTENSION_get_data(extension));
}
BIO_free(bio_out);
}
- add_assoc_zval(return_value, "extensions", subitem);
+ add_assoc_zval(return_value, "extensions", &subitem);
- if (certresource == -1 && cert) {
+ if (certresource == NULL && cert) {
X509_free(cert);
}
}
@@ -1982,16 +2133,17 @@ static int check_cert(X509_STORE *ctx, X509 *x, STACK_OF(X509) *untrustedchain,
Checks the CERT to see if it can be used for the purpose in purpose. cainfo holds information about trusted CAs */
PHP_FUNCTION(openssl_x509_checkpurpose)
{
- zval ** zcert, * zcainfo = NULL;
+ zval * zcert, * zcainfo = NULL;
X509_STORE * cainfo = NULL;
X509 * cert = NULL;
- long certresource = -1;
+ zend_resource *certresource = NULL;
STACK_OF(X509) * untrustedchain = NULL;
- long purpose;
+ zend_long purpose;
char * untrusted = NULL;
- int untrusted_len = 0, ret;
+ size_t untrusted_len = 0;
+ int ret;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zl|a!s", &zcert, &purpose, &zcainfo, &untrusted, &untrusted_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl|a!s", &zcert, &purpose, &zcainfo, &untrusted, &untrusted_len) == FAILURE) {
return;
}
@@ -2021,7 +2173,7 @@ PHP_FUNCTION(openssl_x509_checkpurpose)
}
clean_exit:
- if (certresource == 1 && cert) {
+ if (certresource == NULL && cert) {
X509_free(cert);
}
if (cainfo) {
@@ -2041,8 +2193,9 @@ static X509_STORE * setup_verify(zval * calist TSRMLS_DC)
{
X509_STORE *store;
X509_LOOKUP * dir_lookup, * file_lookup;
- HashPosition pos;
int ndirs = 0, nfiles = 0;
+ zval * item;
+ zend_stat_t sb;
store = X509_STORE_new();
@@ -2051,39 +2204,32 @@ static X509_STORE * setup_verify(zval * calist TSRMLS_DC)
}
if (calist && (Z_TYPE_P(calist) == IS_ARRAY)) {
- zend_hash_internal_pointer_reset_ex(HASH_OF(calist), &pos);
- for (;; zend_hash_move_forward_ex(HASH_OF(calist), &pos)) {
- zval ** item;
- struct stat sb;
-
- if (zend_hash_get_current_data_ex(HASH_OF(calist), (void**)&item, &pos) == FAILURE) {
- break;
- }
+ ZEND_HASH_FOREACH_VAL(HASH_OF(calist), item) {
convert_to_string_ex(item);
- if (VCWD_STAT(Z_STRVAL_PP(item), &sb) == -1) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to stat %s", Z_STRVAL_PP(item));
+ if (VCWD_STAT(Z_STRVAL_P(item), &sb) == -1) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to stat %s", Z_STRVAL_P(item));
continue;
}
if ((sb.st_mode & S_IFREG) == S_IFREG) {
file_lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
- if (file_lookup == NULL || !X509_LOOKUP_load_file(file_lookup, Z_STRVAL_PP(item), X509_FILETYPE_PEM)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "error loading file %s", Z_STRVAL_PP(item));
+ if (file_lookup == NULL || !X509_LOOKUP_load_file(file_lookup, Z_STRVAL_P(item), X509_FILETYPE_PEM)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "error loading file %s", Z_STRVAL_P(item));
} else {
nfiles++;
}
file_lookup = NULL;
} else {
dir_lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
- if (dir_lookup == NULL || !X509_LOOKUP_add_dir(dir_lookup, Z_STRVAL_PP(item), X509_FILETYPE_PEM)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "error loading directory %s", Z_STRVAL_PP(item));
+ if (dir_lookup == NULL || !X509_LOOKUP_add_dir(dir_lookup, Z_STRVAL_P(item), X509_FILETYPE_PEM)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "error loading directory %s", Z_STRVAL_P(item));
} else {
ndirs++;
}
dir_lookup = NULL;
}
- }
+ } ZEND_HASH_FOREACH_END();
}
if (nfiles == 0) {
file_lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
@@ -2105,14 +2251,15 @@ static X509_STORE * setup_verify(zval * calist TSRMLS_DC)
Reads X.509 certificates */
PHP_FUNCTION(openssl_x509_read)
{
- zval **cert;
+ zval *cert;
X509 *x509;
+ zend_resource *res;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &cert) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &cert) == FAILURE) {
return;
}
- Z_TYPE_P(return_value) = IS_RESOURCE;
- x509 = php_openssl_x509_from_zval(cert, 1, &Z_LVAL_P(return_value) TSRMLS_CC);
+ x509 = php_openssl_x509_from_zval(cert, 1, &res TSRMLS_CC);
+ ZVAL_RES(return_value, res);
if (x509 == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "supplied parameter cannot be coerced into an X509 certificate!");
@@ -2131,8 +2278,8 @@ PHP_FUNCTION(openssl_x509_free)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &x509) == FAILURE) {
return;
}
- ZEND_FETCH_RESOURCE(cert, X509 *, &x509, -1, "OpenSSL X.509", le_x509);
- zend_list_delete(Z_LVAL_P(x509));
+ ZEND_FETCH_RESOURCE(cert, X509 *, x509, -1, "OpenSSL X.509", le_x509);
+ zend_list_close(Z_RES_P(x509));
}
/* }}} */
@@ -2150,27 +2297,24 @@ static void php_sk_X509_free(STACK_OF(X509) * sk) /* {{{ */
}
/* }}} */
-static STACK_OF(X509) * php_array_to_X509_sk(zval ** zcerts TSRMLS_DC) /* {{{ */
+static STACK_OF(X509) * php_array_to_X509_sk(zval * zcerts TSRMLS_DC) /* {{{ */
{
- HashPosition hpos;
- zval ** zcertval;
+ zval * zcertval;
STACK_OF(X509) * sk = NULL;
X509 * cert;
- long certresource;
+ zend_resource *certresource;
sk = sk_X509_new_null();
/* get certs */
- if (Z_TYPE_PP(zcerts) == IS_ARRAY) {
- zend_hash_internal_pointer_reset_ex(HASH_OF(*zcerts), &hpos);
- while(zend_hash_get_current_data_ex(HASH_OF(*zcerts), (void**)&zcertval, &hpos) == SUCCESS) {
-
+ if (Z_TYPE_P(zcerts) == IS_ARRAY) {
+ ZEND_HASH_FOREACH_VAL(HASH_OF(zcerts), zcertval) {
cert = php_openssl_x509_from_zval(zcertval, 0, &certresource TSRMLS_CC);
if (cert == NULL) {
goto clean_exit;
}
- if (certresource != -1) {
+ if (certresource != NULL) {
cert = X509_dup(cert);
if (cert == NULL) {
@@ -2179,9 +2323,7 @@ static STACK_OF(X509) * php_array_to_X509_sk(zval ** zcerts TSRMLS_DC) /* {{{ */
}
sk_X509_push(sk, cert);
-
- zend_hash_move_forward_ex(HASH_OF(*zcerts), &hpos);
- }
+ } ZEND_HASH_FOREACH_END();
} else {
/* a single certificate */
cert = php_openssl_x509_from_zval(zcerts, 0, &certresource TSRMLS_CC);
@@ -2190,7 +2332,7 @@ static STACK_OF(X509) * php_array_to_X509_sk(zval ** zcerts TSRMLS_DC) /* {{{ */
goto clean_exit;
}
- if (certresource != -1) {
+ if (certresource != NULL) {
cert = X509_dup(cert);
if (cert == NULL) {
goto clean_exit;
@@ -2213,16 +2355,16 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file)
PKCS12 * p12 = NULL;
char * filename;
char * friendly_name = NULL;
- int filename_len;
+ size_t filename_len;
char * pass;
- int pass_len;
- zval **zcert = NULL, *zpkey = NULL, *args = NULL;
+ size_t pass_len;
+ zval *zcert = NULL, *zpkey = NULL, *args = NULL;
EVP_PKEY *priv_key = NULL;
- long certresource, keyresource;
- zval ** item;
+ zend_resource *certresource, *keyresource;
+ zval * item;
STACK_OF(X509) *ca = NULL;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zpzs|a", &zcert, &filename, &filename_len, &zpkey, &pass, &pass_len, &args) == FAILURE)
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zpzs|a", &zcert, &filename, &filename_len, &zpkey, &pass, &pass_len, &args) == FAILURE)
return;
RETVAL_FALSE;
@@ -2232,7 +2374,7 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
return;
}
- priv_key = php_openssl_evp_from_zval(&zpkey, 0, "", 1, &keyresource TSRMLS_CC);
+ priv_key = php_openssl_evp_from_zval(zpkey, 0, "", 1, &keyresource TSRMLS_CC);
if (priv_key == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get private key from parameter 3");
goto cleanup;
@@ -2246,14 +2388,14 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file)
}
/* parse extra config from args array, promote this to an extra function */
- if (args && zend_hash_find(Z_ARRVAL_P(args), "friendly_name", sizeof("friendly_name"), (void**)&item) == SUCCESS)
- friendly_name = Z_STRVAL_PP(item);
+ if (args && (item = zend_hash_str_find(Z_ARRVAL_P(args), "friendly_name", sizeof("friendly_name")-1)) != NULL && Z_TYPE_P(item) == IS_STRING)
+ friendly_name = Z_STRVAL_P(item);
/* certpbe (default RC2-40)
keypbe (default 3DES)
friendly_caname
*/
- if (args && zend_hash_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts"), (void**)&item) == SUCCESS)
+ if (args && (item = zend_hash_str_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts")-1)) != NULL)
ca = php_array_to_X509_sk(item TSRMLS_CC);
/* end parse extra config */
@@ -2278,10 +2420,10 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file)
cleanup:
- if (keyresource == -1 && priv_key) {
+ if (keyresource == NULL && priv_key) {
EVP_PKEY_free(priv_key);
}
- if (certresource == -1 && cert) {
+ if (certresource == NULL && cert) {
X509_free(cert);
}
}
@@ -2296,24 +2438,24 @@ PHP_FUNCTION(openssl_pkcs12_export)
PKCS12 * p12 = NULL;
zval * zcert = NULL, *zout = NULL, *zpkey, *args = NULL;
EVP_PKEY *priv_key = NULL;
- long certresource, keyresource;
+ zend_resource *certresource, *keyresource;
char * pass;
- int pass_len;
+ size_t pass_len;
char * friendly_name = NULL;
- zval ** item;
+ zval * item;
STACK_OF(X509) *ca = NULL;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzzs|a", &zcert, &zout, &zpkey, &pass, &pass_len, &args) == FAILURE)
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz/zs|a", &zcert, &zout, &zpkey, &pass, &pass_len, &args) == FAILURE)
return;
RETVAL_FALSE;
- cert = php_openssl_x509_from_zval(&zcert, 0, &certresource TSRMLS_CC);
+ cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
if (cert == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
return;
}
- priv_key = php_openssl_evp_from_zval(&zpkey, 0, "", 1, &keyresource TSRMLS_CC);
+ priv_key = php_openssl_evp_from_zval(zpkey, 0, "", 1, &keyresource TSRMLS_CC);
if (priv_key == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get private key from parameter 3");
goto cleanup;
@@ -2324,10 +2466,10 @@ PHP_FUNCTION(openssl_pkcs12_export)
}
/* parse extra config from args array, promote this to an extra function */
- if (args && zend_hash_find(Z_ARRVAL_P(args), "friendly_name", sizeof("friendly_name"), (void**)&item) == SUCCESS)
- friendly_name = Z_STRVAL_PP(item);
+ if (args && (item = zend_hash_str_find(Z_ARRVAL_P(args), "friendly_name", sizeof("friendly_name")-1)) != NULL && Z_TYPE_P(item) == IS_STRING)
+ friendly_name = Z_STRVAL_P(item);
- if (args && zend_hash_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts"), (void**)&item) == SUCCESS)
+ if (args && (item = zend_hash_str_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts")-1)) != NULL)
ca = php_array_to_X509_sk(item TSRMLS_CC);
/* end parse extra config */
@@ -2339,7 +2481,7 @@ PHP_FUNCTION(openssl_pkcs12_export)
zval_dtor(zout);
BIO_get_mem_ptr(bio_out, &bio_buf);
- ZVAL_STRINGL(zout, bio_buf->data, bio_buf->length, 1);
+ ZVAL_STRINGL(zout, bio_buf->data, bio_buf->length);
RETVAL_TRUE;
}
@@ -2350,10 +2492,10 @@ PHP_FUNCTION(openssl_pkcs12_export)
cleanup:
- if (keyresource == -1 && priv_key) {
+ if (keyresource == NULL && priv_key) {
EVP_PKEY_free(priv_key);
}
- if (certresource == -1 && cert) {
+ if (certresource == NULL && cert) {
X509_free(cert);
}
}
@@ -2363,9 +2505,9 @@ cleanup:
Parses a PKCS12 to an array */
PHP_FUNCTION(openssl_pkcs12_read)
{
- zval *zout = NULL, *zextracerts, *zcert, *zpkey;
+ zval *zout = NULL, zextracerts, zcert, zpkey;
char *pass, *zp12;
- int pass_len, zp12_len;
+ size_t pass_len, zp12_len;
PKCS12 * p12 = NULL;
EVP_PKEY * pkey = NULL;
X509 * cert = NULL;
@@ -2373,7 +2515,7 @@ PHP_FUNCTION(openssl_pkcs12_read)
BIO * bio_in = NULL;
int i;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szs", &zp12, &zp12_len, &zout, &pass, &pass_len) == FAILURE)
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/s", &zp12, &zp12_len, &zout, &pass, &pass_len) == FAILURE)
return;
RETVAL_FALSE;
@@ -2394,9 +2536,8 @@ PHP_FUNCTION(openssl_pkcs12_read)
if (PEM_write_bio_X509(bio_out, cert)) {
BUF_MEM *bio_buf;
BIO_get_mem_ptr(bio_out, &bio_buf);
- MAKE_STD_ZVAL(zcert);
- ZVAL_STRINGL(zcert, bio_buf->data, bio_buf->length, 1);
- add_assoc_zval(zout, "cert", zcert);
+ ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length);
+ add_assoc_zval(zout, "cert", &zcert);
}
BIO_free(bio_out);
@@ -2404,17 +2545,15 @@ PHP_FUNCTION(openssl_pkcs12_read)
if (PEM_write_bio_PrivateKey(bio_out, pkey, NULL, NULL, 0, 0, NULL)) {
BUF_MEM *bio_buf;
BIO_get_mem_ptr(bio_out, &bio_buf);
- MAKE_STD_ZVAL(zpkey);
- ZVAL_STRINGL(zpkey, bio_buf->data, bio_buf->length, 1);
- add_assoc_zval(zout, "pkey", zpkey);
+ ZVAL_STRINGL(&zpkey, bio_buf->data, bio_buf->length);
+ add_assoc_zval(zout, "pkey", &zpkey);
}
BIO_free(bio_out);
- MAKE_STD_ZVAL(zextracerts);
- array_init(zextracerts);
+ array_init(&zextracerts);
for (i=0;;i++) {
- zval * zextracert;
+ zval zextracert;
X509* aCA = sk_X509_pop(ca);
if (!aCA) break;
@@ -2422,9 +2561,8 @@ PHP_FUNCTION(openssl_pkcs12_read)
if (PEM_write_bio_X509(bio_out, aCA)) {
BUF_MEM *bio_buf;
BIO_get_mem_ptr(bio_out, &bio_buf);
- MAKE_STD_ZVAL(zextracert);
- ZVAL_STRINGL(zextracert, bio_buf->data, bio_buf->length, 1);
- add_index_zval(zextracerts, i, zextracert);
+ ZVAL_STRINGL(&zextracert, bio_buf->data, bio_buf->length);
+ add_index_zval(&zextracerts, i, &zextracert);
}
BIO_free(bio_out);
@@ -2433,9 +2571,9 @@ PHP_FUNCTION(openssl_pkcs12_read)
}
if(ca) {
sk_X509_free(ca);
- add_assoc_zval(zout, "extracerts", zextracerts);
+ add_assoc_zval(zout, "extracerts", &zextracerts);
} else {
- zval_dtor(zextracerts);
+ zval_dtor(&zextracerts);
}
RETVAL_TRUE;
@@ -2488,42 +2626,34 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
char * type;
CONF_VALUE * v;
X509_NAME * subj;
- HashPosition hpos;
- zval ** item;
+ zval * item;
+ zend_string * strindex = NULL;
subj = X509_REQ_get_subject_name(csr);
/* apply values from the dn hash */
- zend_hash_internal_pointer_reset_ex(HASH_OF(dn), &hpos);
- while(zend_hash_get_current_data_ex(HASH_OF(dn), (void**)&item, &hpos) == SUCCESS) {
- char * strindex = NULL;
- uint strindexlen = 0;
- ulong intindex;
-
- zend_hash_get_current_key_ex(HASH_OF(dn), &strindex, &strindexlen, &intindex, 0, &hpos);
-
- convert_to_string_ex(item);
-
+ ZEND_HASH_FOREACH_STR_KEY_VAL(HASH_OF(dn), strindex, item) {
if (strindex) {
int nid;
- nid = OBJ_txt2nid(strindex);
+ convert_to_string_ex(item);
+
+ nid = OBJ_txt2nid(strindex->val);
if (nid != NID_undef) {
if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_UTF8,
- (unsigned char*)Z_STRVAL_PP(item), -1, -1, 0))
+ (unsigned char*)Z_STRVAL_P(item), -1, -1, 0))
{
php_error_docref(NULL TSRMLS_CC, E_WARNING,
"dn: add_entry_by_NID %d -> %s (failed; check error"
" queue and value of string_mask OpenSSL option "
"if illegal characters are reported)",
- nid, Z_STRVAL_PP(item));
+ nid, Z_STRVAL_P(item));
return FAILURE;
}
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "dn: %s is not a recognized name", strindex);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "dn: %s is not a recognized name", strindex->val);
}
}
- zend_hash_move_forward_ex(HASH_OF(dn), &hpos);
- }
+ } ZEND_HASH_FOREACH_END();
/* Finally apply defaults from config file */
for(i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
@@ -2574,30 +2704,21 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
}
}
if (attribs) {
- zend_hash_internal_pointer_reset_ex(HASH_OF(attribs), &hpos);
- while(zend_hash_get_current_data_ex(HASH_OF(attribs), (void**)&item, &hpos) == SUCCESS) {
- char *strindex = NULL;
- uint strindexlen;
- ulong intindex;
+ ZEND_HASH_FOREACH_STR_KEY_VAL(HASH_OF(attribs), strindex, item) {
+ int nid;
- zend_hash_get_current_key_ex(HASH_OF(attribs), &strindex, &strindexlen, &intindex, 0, &hpos);
convert_to_string_ex(item);
- if (strindex) {
- int nid;
-
- nid = OBJ_txt2nid(strindex);
- if (nid != NID_undef) {
- if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_UTF8, (unsigned char*)Z_STRVAL_PP(item), -1, -1, 0)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "attribs: add_entry_by_NID %d -> %s (failed)", nid, Z_STRVAL_PP(item));
- return FAILURE;
- }
- } else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "dn: %s is not a recognized name", strindex);
+ nid = OBJ_txt2nid(strindex->val);
+ if (nid != NID_undef) {
+ if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_UTF8, (unsigned char*)Z_STRVAL_P(item), -1, -1, 0)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "attribs: add_entry_by_NID %d -> %s (failed)", nid, Z_STRVAL_P(item));
+ return FAILURE;
}
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "dn: %s is not a recognized name", strindex->val);
}
- zend_hash_move_forward_ex(HASH_OF(attribs), &hpos);
- }
+ } ZEND_HASH_FOREACH_END();
for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) {
v = sk_CONF_VALUE_value(attr_sk, i);
/* if it is already set, skip this */
@@ -2623,33 +2744,34 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
/* }}} */
/* {{{ php_openssl_csr_from_zval */
-static X509_REQ * php_openssl_csr_from_zval(zval ** val, int makeresource, long * resourceval TSRMLS_DC)
+static X509_REQ * php_openssl_csr_from_zval(zval * val, int makeresource, zend_resource **resourceval TSRMLS_DC)
{
X509_REQ * csr = NULL;
char * filename = NULL;
BIO * in;
if (resourceval) {
- *resourceval = -1;
+ *resourceval = NULL;
}
- if (Z_TYPE_PP(val) == IS_RESOURCE) {
+ if (Z_TYPE_P(val) == IS_RESOURCE) {
void * what;
int type;
what = zend_fetch_resource(val TSRMLS_CC, -1, "OpenSSL X.509 CSR", &type, 1, le_csr);
if (what) {
if (resourceval) {
- *resourceval = Z_LVAL_PP(val);
+ *resourceval = Z_RES_P(val);
+ Z_ADDREF_P(val);
}
return (X509_REQ*)what;
}
return NULL;
- } else if (Z_TYPE_PP(val) != IS_STRING) {
+ } else if (Z_TYPE_P(val) != IS_STRING) {
return NULL;
}
- if (Z_STRLEN_PP(val) > 7 && memcmp(Z_STRVAL_PP(val), "file://", sizeof("file://") - 1) == 0) {
- filename = Z_STRVAL_PP(val) + (sizeof("file://") - 1);
+ if (Z_STRLEN_P(val) > 7 && memcmp(Z_STRVAL_P(val), "file://", sizeof("file://") - 1) == 0) {
+ filename = Z_STRVAL_P(val) + (sizeof("file://") - 1);
}
if (filename) {
if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
@@ -2657,7 +2779,7 @@ static X509_REQ * php_openssl_csr_from_zval(zval ** val, int makeresource, long
}
in = BIO_new_file(filename, "r");
} else {
- in = BIO_new_mem_buf(Z_STRVAL_PP(val), Z_STRLEN_PP(val));
+ in = BIO_new_mem_buf(Z_STRVAL_P(val), Z_STRLEN_P(val));
}
csr = PEM_read_bio_X509_REQ(in, NULL,NULL,NULL);
BIO_free(in);
@@ -2673,16 +2795,17 @@ PHP_FUNCTION(openssl_csr_export_to_file)
X509_REQ * csr;
zval * zcsr = NULL;
zend_bool notext = 1;
- char * filename = NULL; int filename_len;
+ char * filename = NULL;
+ size_t filename_len;
BIO * bio_out;
- long csr_resource;
+ zend_resource *csr_resource;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rp|b", &zcsr, &filename, &filename_len, &notext) == FAILURE) {
return;
}
RETVAL_FALSE;
- csr = php_openssl_csr_from_zval(&zcsr, 0, &csr_resource TSRMLS_CC);
+ csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource TSRMLS_CC);
if (csr == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get CSR from parameter 1");
return;
@@ -2703,7 +2826,7 @@ PHP_FUNCTION(openssl_csr_export_to_file)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "error opening file %s", filename);
}
- if (csr_resource == -1 && csr) {
+ if (csr_resource == NULL && csr) {
X509_REQ_free(csr);
}
BIO_free(bio_out);
@@ -2718,15 +2841,15 @@ PHP_FUNCTION(openssl_csr_export)
zval * zcsr = NULL, *zout=NULL;
zend_bool notext = 1;
BIO * bio_out;
+ zend_resource *csr_resource;
- long csr_resource;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|b", &zcsr, &zout, &notext) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz/|b", &zcsr, &zout, &notext) == FAILURE) {
return;
}
+
RETVAL_FALSE;
- csr = php_openssl_csr_from_zval(&zcsr, 0, &csr_resource TSRMLS_CC);
+ csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource TSRMLS_CC);
if (csr == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get CSR from parameter 1");
return;
@@ -2744,12 +2867,12 @@ PHP_FUNCTION(openssl_csr_export)
BIO_get_mem_ptr(bio_out, &bio_buf);
zval_dtor(zout);
- ZVAL_STRINGL(zout, bio_buf->data, bio_buf->length, 1);
+ ZVAL_STRINGL(zout, bio_buf->data, bio_buf->length);
RETVAL_TRUE;
}
- if (csr_resource == -1 && csr) {
+ if (csr_resource == NULL && csr) {
X509_REQ_free(csr);
}
BIO_free(bio_out);
@@ -2760,17 +2883,17 @@ PHP_FUNCTION(openssl_csr_export)
Signs a cert with another CERT */
PHP_FUNCTION(openssl_csr_sign)
{
- zval ** zcert = NULL, **zcsr, **zpkey, *args = NULL;
- long num_days;
- long serial = 0L;
+ zval * zcert = NULL, *zcsr, *zpkey, *args = NULL;
+ zend_long num_days;
+ zend_long serial = Z_L(0);
X509 * cert = NULL, *new_cert = NULL;
X509_REQ * csr;
EVP_PKEY * key = NULL, *priv_key = NULL;
- long csr_resource, certresource = 0, keyresource = -1;
+ zend_resource *csr_resource, *certresource = NULL, *keyresource = NULL;
int i;
struct php_x509_request req;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ!Zl|a!l", &zcsr, &zcert, &zpkey, &num_days, &args, &serial) == FAILURE)
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz!zl|a!l", &zcsr, &zcert, &zpkey, &num_days, &args, &serial) == FAILURE)
return;
RETVAL_FALSE;
@@ -2829,6 +2952,7 @@ PHP_FUNCTION(openssl_csr_sign)
if (!X509_set_version(new_cert, 2))
goto cleanup;
+
ASN1_INTEGER_set(X509_get_serialNumber(new_cert), serial);
X509_set_subject_name(new_cert, X509_REQ_get_subject_name(csr));
@@ -2862,7 +2986,7 @@ PHP_FUNCTION(openssl_csr_sign)
}
/* Succeeded; lets return the cert */
- RETVAL_RESOURCE(zend_list_insert(new_cert, le_x509 TSRMLS_CC));
+ zend_register_resource(return_value, new_cert, le_x509 TSRMLS_CC);
new_cert = NULL;
cleanup:
@@ -2872,16 +2996,16 @@ cleanup:
}
PHP_SSL_REQ_DISPOSE(&req);
- if (keyresource == -1 && priv_key) {
+ if (keyresource == NULL && priv_key) {
EVP_PKEY_free(priv_key);
}
if (key) {
EVP_PKEY_free(key);
}
- if (csr_resource == -1 && csr) {
+ if (csr_resource == NULL && csr) {
X509_REQ_free(csr);
}
- if (certresource == -1 && cert) {
+ if (zcert && certresource == NULL && cert) {
X509_free(cert);
}
if (new_cert) {
@@ -2899,9 +3023,9 @@ PHP_FUNCTION(openssl_csr_new)
zval * out_pkey;
X509_REQ * csr = NULL;
int we_made_the_key = 1;
- long key_resource;
+ zend_resource *key_resource;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az|a!a!", &dn, &out_pkey, &args, &attribs) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az/|a!a!", &dn, &out_pkey, &args, &attribs) == FAILURE) {
return;
}
RETVAL_FALSE;
@@ -2911,7 +3035,7 @@ PHP_FUNCTION(openssl_csr_new)
if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {
/* Generate or use a private key */
if (Z_TYPE_P(out_pkey) != IS_NULL) {
- req.priv_key = php_openssl_evp_from_zval(&out_pkey, 0, NULL, 0, &key_resource TSRMLS_CC);
+ req.priv_key = php_openssl_evp_from_zval(out_pkey, 0, NULL, 0, &key_resource TSRMLS_CC);
if (req.priv_key != NULL) {
we_made_the_key = 0;
}
@@ -2939,7 +3063,7 @@ PHP_FUNCTION(openssl_csr_new)
RETVAL_TRUE;
if (X509_REQ_sign(csr, req.priv_key, req.digest)) {
- RETVAL_RESOURCE(zend_list_insert(csr, le_csr TSRMLS_CC));
+ zend_register_resource(return_value, csr, le_csr TSRMLS_CC);
csr = NULL;
} else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error signing request");
@@ -2948,9 +3072,9 @@ PHP_FUNCTION(openssl_csr_new)
if (we_made_the_key) {
/* and a resource for the private key */
zval_dtor(out_pkey);
- ZVAL_RESOURCE(out_pkey, zend_list_insert(req.priv_key, le_key TSRMLS_CC));
+ zend_register_resource(out_pkey, req.priv_key, le_key TSRMLS_CC);
req.priv_key = NULL; /* make sure the cleanup code doesn't zap it! */
- } else if (key_resource != -1) {
+ } else if (key_resource != NULL) {
req.priv_key = NULL; /* make sure the cleanup code doesn't zap it! */
}
}
@@ -2975,13 +3099,13 @@ PHP_FUNCTION(openssl_csr_new)
Returns the subject of a CERT or FALSE on error */
PHP_FUNCTION(openssl_csr_get_subject)
{
- zval ** zcsr;
+ zval * zcsr;
zend_bool use_shortnames = 1;
- long csr_resource;
+ zend_resource *csr_resource;
X509_NAME * subject;
X509_REQ * csr;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|b", &zcsr, &use_shortnames) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &zcsr, &use_shortnames) == FAILURE) {
return;
}
@@ -3003,14 +3127,14 @@ PHP_FUNCTION(openssl_csr_get_subject)
Returns the subject of a CERT or FALSE on error */
PHP_FUNCTION(openssl_csr_get_public_key)
{
- zval ** zcsr;
+ zval * zcsr;
zend_bool use_shortnames = 1;
- long csr_resource;
+ zend_resource *csr_resource;
X509_REQ * csr;
EVP_PKEY *tpubkey;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|b", &zcsr, &use_shortnames) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &zcsr, &use_shortnames) == FAILURE) {
return;
}
@@ -3021,7 +3145,7 @@ PHP_FUNCTION(openssl_csr_get_public_key)
}
tpubkey=X509_REQ_get_pubkey(csr);
- RETVAL_RESOURCE(zend_list_insert(tpubkey, le_key TSRMLS_CC));
+ zend_register_resource(return_value, tpubkey, le_key TSRMLS_CC);
return;
}
/* }}} */
@@ -3043,16 +3167,16 @@ PHP_FUNCTION(openssl_csr_get_public_key)
empty string rather than NULL for the passphrase - NULL causes a passphrase prompt to be emitted in
the Apache error log!
*/
-static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char * passphrase, int makeresource, long * resourceval TSRMLS_DC)
+static EVP_PKEY * php_openssl_evp_from_zval(zval * val, int public_key, char * passphrase, int makeresource, zend_resource **resourceval TSRMLS_DC)
{
EVP_PKEY * key = NULL;
X509 * cert = NULL;
int free_cert = 0;
- long cert_res = -1;
+ zend_resource *cert_res = NULL;
char * filename = NULL;
zval tmp;
- Z_TYPE(tmp) = IS_NULL;
+ ZVAL_NULL(&tmp);
#define TMP_CLEAN \
if (Z_TYPE(tmp) == IS_STRING) {\
@@ -3061,35 +3185,34 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char *
return NULL;
if (resourceval) {
- *resourceval = -1;
+ *resourceval = NULL;
}
- if (Z_TYPE_PP(val) == IS_ARRAY) {
- zval ** zphrase;
+ if (Z_TYPE_P(val) == IS_ARRAY) {
+ zval * zphrase;
/* get passphrase */
- if (zend_hash_index_find(HASH_OF(*val), 1, (void **)&zphrase) == FAILURE) {
+ if ((zphrase = zend_hash_index_find(HASH_OF(val), 1)) == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "key array must be of the form array(0 => key, 1 => phrase)");
return NULL;
}
- if (Z_TYPE_PP(zphrase) == IS_STRING) {
- passphrase = Z_STRVAL_PP(zphrase);
+ if (Z_TYPE_P(zphrase) == IS_STRING) {
+ passphrase = Z_STRVAL_P(zphrase);
} else {
- tmp = **zphrase;
- zval_copy_ctor(&tmp);
+ ZVAL_DUP(&tmp, zphrase);
convert_to_string(&tmp);
passphrase = Z_STRVAL(tmp);
}
/* now set val to be the key param and continue */
- if (zend_hash_index_find(HASH_OF(*val), 0, (void **)&val) == FAILURE) {
+ if ((val = zend_hash_index_find(HASH_OF(val), 0)) == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "key array must be of the form array(0 => key, 1 => phrase)");
TMP_CLEAN;
}
}
- if (Z_TYPE_PP(val) == IS_RESOURCE) {
+ if (Z_TYPE_P(val) == IS_RESOURCE) {
void * what;
int type;
@@ -3098,7 +3221,8 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char *
TMP_CLEAN;
}
if (resourceval) {
- *resourceval = Z_LVAL_PP(val);
+ *resourceval = Z_RES_P(val);
+ Z_ADDREF_P(val);
}
if (type == le_x509) {
/* extract key from cert, depending on public_key param */
@@ -3134,18 +3258,18 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char *
/* passing non string values leaks, object uses toString, it returns NULL
* See bug38255.phpt
*/
- if (!(Z_TYPE_PP(val) == IS_STRING || Z_TYPE_PP(val) == IS_OBJECT)) {
+ if (!(Z_TYPE_P(val) == IS_STRING || Z_TYPE_P(val) == IS_OBJECT)) {
TMP_CLEAN;
}
convert_to_string_ex(val);
- if (Z_STRLEN_PP(val) > 7 && memcmp(Z_STRVAL_PP(val), "file://", sizeof("file://") - 1) == 0) {
- filename = Z_STRVAL_PP(val) + (sizeof("file://") - 1);
+ if (Z_STRLEN_P(val) > 7 && memcmp(Z_STRVAL_P(val), "file://", sizeof("file://") - 1) == 0) {
+ filename = Z_STRVAL_P(val) + (sizeof("file://") - 1);
}
/* it's an X509 file/cert of some kind, and we need to extract the data from that */
if (public_key) {
cert = php_openssl_x509_from_zval(val, 0, &cert_res TSRMLS_CC);
- free_cert = (cert_res == -1);
+ free_cert = (cert_res == NULL);
/* actual extraction done later */
if (!cert) {
/* not a X509 certificate, try to retrieve public key */
@@ -3153,7 +3277,7 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char *
if (filename) {
in = BIO_new_file(filename, "r");
} else {
- in = BIO_new_mem_buf(Z_STRVAL_PP(val), Z_STRLEN_PP(val));
+ in = BIO_new_mem_buf(Z_STRVAL_P(val), Z_STRLEN_P(val));
}
if (in == NULL) {
TMP_CLEAN;
@@ -3171,7 +3295,7 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char *
}
in = BIO_new_file(filename, "r");
} else {
- in = BIO_new_mem_buf(Z_STRVAL_PP(val), Z_STRLEN_PP(val));
+ in = BIO_new_mem_buf(Z_STRVAL_P(val), Z_STRLEN_P(val));
}
if (in == NULL) {
@@ -3314,6 +3438,15 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC)
}
break;
#endif
+#ifdef HAVE_EVP_PKEY_EC
+ case EVP_PKEY_EC:
+ assert(pkey->pkey.ec != NULL);
+
+ if ( NULL == EC_KEY_get0_private_key(pkey->pkey.ec)) {
+ return 0;
+ }
+ break;
+#endif
default:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "key type not supported in this PHP build!");
break;
@@ -3325,20 +3458,20 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC)
#define OPENSSL_PKEY_GET_BN(_type, _name) do { \
if (pkey->pkey._type->_name != NULL) { \
int len = BN_num_bytes(pkey->pkey._type->_name); \
- char *str = emalloc(len + 1); \
- BN_bn2bin(pkey->pkey._type->_name, (unsigned char*)str); \
- str[len] = 0; \
- add_assoc_stringl(_type, #_name, str, len, 0); \
+ zend_string *str = zend_string_alloc(len, 0); \
+ BN_bn2bin(pkey->pkey._type->_name, (unsigned char*)str->val); \
+ str->val[len] = 0; \
+ add_assoc_str(&_type, #_name, str); \
} \
} while (0)
#define OPENSSL_PKEY_SET_BN(_ht, _type, _name) do { \
- zval **bn; \
- if (zend_hash_find(_ht, #_name, sizeof(#_name), (void**)&bn) == SUCCESS && \
- Z_TYPE_PP(bn) == IS_STRING) { \
+ zval *bn; \
+ if ((bn = zend_hash_str_find(_ht, #_name, sizeof(#_name)-1)) != NULL && \
+ Z_TYPE_P(bn) == IS_STRING) { \
_type->_name = BN_bin2bn( \
- (unsigned char*)Z_STRVAL_PP(bn), \
- Z_STRLEN_PP(bn), NULL); \
+ (unsigned char*)Z_STRVAL_P(bn), \
+ Z_STRLEN_P(bn), NULL); \
} \
} while (0);
@@ -3349,7 +3482,7 @@ PHP_FUNCTION(openssl_pkey_new)
{
struct php_x509_request req;
zval * args = NULL;
- zval **data;
+ zval *data;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!", &args) == FAILURE) {
return;
@@ -3359,23 +3492,24 @@ PHP_FUNCTION(openssl_pkey_new)
if (args && Z_TYPE_P(args) == IS_ARRAY) {
EVP_PKEY *pkey;
- if (zend_hash_find(Z_ARRVAL_P(args), "rsa", sizeof("rsa"), (void**)&data) == SUCCESS &&
- Z_TYPE_PP(data) == IS_ARRAY) {
+ if ((data = zend_hash_str_find(Z_ARRVAL_P(args), "rsa", sizeof("rsa")-1)) != NULL &&
+ Z_TYPE_P(data) == IS_ARRAY) {
pkey = EVP_PKEY_new();
if (pkey) {
RSA *rsa = RSA_new();
if (rsa) {
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, n);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, e);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, d);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, p);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, q);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, dmp1);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, dmq1);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, iqmp);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), rsa, n);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), rsa, e);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), rsa, d);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), rsa, p);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), rsa, q);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), rsa, dmp1);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), rsa, dmq1);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), rsa, iqmp);
if (rsa->n && rsa->d) {
if (EVP_PKEY_assign_RSA(pkey, rsa)) {
- RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
+ zend_register_resource(return_value, pkey, le_key TSRMLS_CC);
+ return;
}
}
RSA_free(rsa);
@@ -3383,23 +3517,24 @@ PHP_FUNCTION(openssl_pkey_new)
EVP_PKEY_free(pkey);
}
RETURN_FALSE;
- } else if (zend_hash_find(Z_ARRVAL_P(args), "dsa", sizeof("dsa"), (void**)&data) == SUCCESS &&
- Z_TYPE_PP(data) == IS_ARRAY) {
+ } else if ((data = zend_hash_str_find(Z_ARRVAL_P(args), "dsa", sizeof("dsa")-1)) != NULL &&
+ Z_TYPE_P(data) == IS_ARRAY) {
pkey = EVP_PKEY_new();
if (pkey) {
DSA *dsa = DSA_new();
if (dsa) {
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, p);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, q);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, g);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, priv_key);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, pub_key);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dsa, p);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dsa, q);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dsa, g);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dsa, priv_key);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dsa, pub_key);
if (dsa->p && dsa->q && dsa->g) {
if (!dsa->priv_key && !dsa->pub_key) {
DSA_generate_key(dsa);
}
if (EVP_PKEY_assign_DSA(pkey, dsa)) {
- RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
+ zend_register_resource(return_value, pkey, le_key TSRMLS_CC);
+ return;
}
}
DSA_free(dsa);
@@ -3407,22 +3542,23 @@ PHP_FUNCTION(openssl_pkey_new)
EVP_PKEY_free(pkey);
}
RETURN_FALSE;
- } else if (zend_hash_find(Z_ARRVAL_P(args), "dh", sizeof("dh"), (void**)&data) == SUCCESS &&
- Z_TYPE_PP(data) == IS_ARRAY) {
+ } else if ((data = zend_hash_str_find(Z_ARRVAL_P(args), "dh", sizeof("dh")-1)) != NULL &&
+ Z_TYPE_P(data) == IS_ARRAY) {
pkey = EVP_PKEY_new();
if (pkey) {
DH *dh = DH_new();
if (dh) {
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, p);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, g);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, priv_key);
- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, pub_key);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dh, p);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dh, g);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dh, priv_key);
+ OPENSSL_PKEY_SET_BN(Z_ARRVAL_P(data), dh, pub_key);
if (dh->p && dh->g) {
if (!dh->pub_key) {
DH_generate_key(dh);
}
if (EVP_PKEY_assign_DH(pkey, dh)) {
- RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
+ ZVAL_COPY_VALUE(return_value, zend_list_insert(pkey, le_key TSRMLS_CC));
+ return;
}
}
DH_free(dh);
@@ -3439,7 +3575,7 @@ PHP_FUNCTION(openssl_pkey_new)
{
if (php_openssl_generate_private_key(&req TSRMLS_CC)) {
/* pass back a key resource */
- RETVAL_RESOURCE(zend_list_insert(req.priv_key, le_key TSRMLS_CC));
+ zend_register_resource(return_value, req.priv_key, le_key TSRMLS_CC);
/* make sure the cleanup code doesn't zap it! */
req.priv_key = NULL;
}
@@ -3453,15 +3589,17 @@ PHP_FUNCTION(openssl_pkey_new)
PHP_FUNCTION(openssl_pkey_export_to_file)
{
struct php_x509_request req;
- zval ** zpkey, * args = NULL;
- char * passphrase = NULL; int passphrase_len = 0;
- char * filename = NULL; int filename_len = 0;
- long key_resource = -1;
+ zval * zpkey, * args = NULL;
+ char * passphrase = NULL;
+ size_t passphrase_len = 0;
+ char * filename = NULL;
+ size_t filename_len = 0;
+ zend_resource *key_resource = NULL;
EVP_PKEY * key;
BIO * bio_out = NULL;
const EVP_CIPHER * cipher;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zp|s!a!", &zpkey, &filename, &filename_len, &passphrase, &passphrase_len, &args) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zp|s!a!", &zpkey, &filename, &filename_len, &passphrase, &passphrase_len, &args) == FAILURE) {
return;
}
RETVAL_FALSE;
@@ -3499,7 +3637,7 @@ PHP_FUNCTION(openssl_pkey_export_to_file)
}
PHP_SSL_REQ_DISPOSE(&req);
- if (key_resource == -1 && key) {
+ if (key_resource == NULL && key) {
EVP_PKEY_free(key);
}
if (bio_out) {
@@ -3513,14 +3651,14 @@ PHP_FUNCTION(openssl_pkey_export_to_file)
PHP_FUNCTION(openssl_pkey_export)
{
struct php_x509_request req;
- zval ** zpkey, * args = NULL, *out;
- char * passphrase = NULL; int passphrase_len = 0;
- long key_resource = -1;
+ zval * zpkey, * args = NULL, *out;
+ char * passphrase = NULL; size_t passphrase_len = 0;
+ zend_resource *key_resource = NULL;
EVP_PKEY * key;
BIO * bio_out = NULL;
const EVP_CIPHER * cipher;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zz|s!a!", &zpkey, &out, &passphrase, &passphrase_len, &args) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz/|s!a!", &zpkey, &out, &passphrase, &passphrase_len, &args) == FAILURE) {
return;
}
RETVAL_FALSE;
@@ -3556,12 +3694,12 @@ PHP_FUNCTION(openssl_pkey_export)
bio_mem_len = BIO_get_mem_data(bio_out, &bio_mem_ptr);
zval_dtor(out);
- ZVAL_STRINGL(out, bio_mem_ptr, bio_mem_len, 1);
+ ZVAL_STRINGL(out, bio_mem_ptr, bio_mem_len);
}
}
PHP_SSL_REQ_DISPOSE(&req);
- if (key_resource == -1 && key) {
+ if (key_resource == NULL && key) {
EVP_PKEY_free(key);
}
if (bio_out) {
@@ -3574,19 +3712,19 @@ PHP_FUNCTION(openssl_pkey_export)
Gets public key from X.509 certificate */
PHP_FUNCTION(openssl_pkey_get_public)
{
- zval **cert;
+ zval *cert;
EVP_PKEY *pkey;
+ zend_resource *res;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &cert) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &cert) == FAILURE) {
return;
}
- Z_TYPE_P(return_value) = IS_RESOURCE;
- pkey = php_openssl_evp_from_zval(cert, 1, NULL, 1, &Z_LVAL_P(return_value) TSRMLS_CC);
-
+ pkey = php_openssl_evp_from_zval(cert, 1, NULL, 1, &res TSRMLS_CC);
if (pkey == NULL) {
RETURN_FALSE;
}
- zend_list_addref(Z_LVAL_P(return_value));
+ ZVAL_RES(return_value, res);
+ Z_ADDREF_P(return_value);
}
/* }}} */
@@ -3600,8 +3738,8 @@ PHP_FUNCTION(openssl_pkey_free)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &key) == FAILURE) {
return;
}
- ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, &key, -1, "OpenSSL key", le_key);
- zend_list_delete(Z_LVAL_P(key));
+ ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, key, -1, "OpenSSL key", le_key);
+ zend_list_close(Z_RES_P(key));
}
/* }}} */
@@ -3609,21 +3747,22 @@ PHP_FUNCTION(openssl_pkey_free)
Gets private keys */
PHP_FUNCTION(openssl_pkey_get_private)
{
- zval **cert;
+ zval *cert;
EVP_PKEY *pkey;
char * passphrase = "";
- int passphrase_len = sizeof("")-1;
+ size_t passphrase_len = sizeof("")-1;
+ zend_resource *res;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|s", &cert, &passphrase, &passphrase_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|s", &cert, &passphrase, &passphrase_len) == FAILURE) {
return;
}
- Z_TYPE_P(return_value) = IS_RESOURCE;
- pkey = php_openssl_evp_from_zval(cert, 0, passphrase, 1, &Z_LVAL_P(return_value) TSRMLS_CC);
+ pkey = php_openssl_evp_from_zval(cert, 0, passphrase, 1, &res TSRMLS_CC);
if (pkey == NULL) {
RETURN_FALSE;
}
- zend_list_addref(Z_LVAL_P(return_value));
+ ZVAL_RES(return_value, res);
+ Z_ADDREF_P(return_value);
}
/* }}} */
@@ -3637,12 +3776,12 @@ PHP_FUNCTION(openssl_pkey_get_details)
BIO *out;
unsigned int pbio_len;
char *pbio;
- long ktype;
+ zend_long ktype;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &key) == FAILURE) {
return;
}
- ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, &key, -1, "OpenSSL key", le_key);
+ ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, key, -1, "OpenSSL key", le_key);
if (!pkey) {
RETURN_FALSE;
}
@@ -3652,7 +3791,7 @@ PHP_FUNCTION(openssl_pkey_get_details)
array_init(return_value);
add_assoc_long(return_value, "bits", EVP_PKEY_bits(pkey));
- add_assoc_stringl(return_value, "key", pbio, pbio_len, 1);
+ add_assoc_stringl(return_value, "key", pbio, pbio_len);
/*TODO: Use the real values once the openssl constants are used
* See the enum at the top of this file
*/
@@ -3662,10 +3801,9 @@ PHP_FUNCTION(openssl_pkey_get_details)
ktype = OPENSSL_KEYTYPE_RSA;
if (pkey->pkey.rsa != NULL) {
- zval *rsa;
+ zval rsa;
- ALLOC_INIT_ZVAL(rsa);
- array_init(rsa);
+ array_init(&rsa);
OPENSSL_PKEY_GET_BN(rsa, n);
OPENSSL_PKEY_GET_BN(rsa, e);
OPENSSL_PKEY_GET_BN(rsa, d);
@@ -3674,7 +3812,7 @@ PHP_FUNCTION(openssl_pkey_get_details)
OPENSSL_PKEY_GET_BN(rsa, dmp1);
OPENSSL_PKEY_GET_BN(rsa, dmq1);
OPENSSL_PKEY_GET_BN(rsa, iqmp);
- add_assoc_zval(return_value, "rsa", rsa);
+ add_assoc_zval(return_value, "rsa", &rsa);
}
break;
@@ -3685,16 +3823,15 @@ PHP_FUNCTION(openssl_pkey_get_details)
ktype = OPENSSL_KEYTYPE_DSA;
if (pkey->pkey.dsa != NULL) {
- zval *dsa;
+ zval dsa;
- ALLOC_INIT_ZVAL(dsa);
- array_init(dsa);
+ array_init(&dsa);
OPENSSL_PKEY_GET_BN(dsa, p);
OPENSSL_PKEY_GET_BN(dsa, q);
OPENSSL_PKEY_GET_BN(dsa, g);
OPENSSL_PKEY_GET_BN(dsa, priv_key);
OPENSSL_PKEY_GET_BN(dsa, pub_key);
- add_assoc_zval(return_value, "dsa", dsa);
+ add_assoc_zval(return_value, "dsa", &dsa);
}
break;
case EVP_PKEY_DH:
@@ -3702,19 +3839,18 @@ PHP_FUNCTION(openssl_pkey_get_details)
ktype = OPENSSL_KEYTYPE_DH;
if (pkey->pkey.dh != NULL) {
- zval *dh;
+ zval dh;
- ALLOC_INIT_ZVAL(dh);
- array_init(dh);
+ array_init(&dh);
OPENSSL_PKEY_GET_BN(dh, p);
OPENSSL_PKEY_GET_BN(dh, g);
OPENSSL_PKEY_GET_BN(dh, priv_key);
OPENSSL_PKEY_GET_BN(dh, pub_key);
- add_assoc_zval(return_value, "dh", dh);
+ add_assoc_zval(return_value, "dh", &dh);
}
break;
-#ifdef EVP_PKEY_EC
+#ifdef HAVE_EVP_PKEY_EC
case EVP_PKEY_EC:
ktype = OPENSSL_KEYTYPE_EC;
break;
@@ -3737,11 +3873,14 @@ PHP_FUNCTION(openssl_pkey_get_details)
Generates a PKCS5 v2 PBKDF2 string, defaults to sha1 */
PHP_FUNCTION(openssl_pbkdf2)
{
- long key_length = 0, iterations = 0;
- char *password; int password_len;
- char *salt; int salt_len;
- char *method; int method_len = 0;
- unsigned char *out_buffer;
+ zend_long key_length = 0, iterations = 0;
+ char *password;
+ size_t password_len;
+ char *salt;
+ size_t salt_len;
+ char *method;
+ size_t method_len = 0;
+ zend_string *out_buffer;
const EVP_MD *digest;
@@ -3768,13 +3907,13 @@ PHP_FUNCTION(openssl_pbkdf2)
RETURN_FALSE;
}
- out_buffer = emalloc(key_length + 1);
- out_buffer[key_length] = '\0';
+ out_buffer = zend_string_alloc(key_length, 0);
- if (PKCS5_PBKDF2_HMAC(password, password_len, (unsigned char *)salt, salt_len, iterations, digest, key_length, out_buffer) == 1) {
- RETVAL_STRINGL((char *)out_buffer, key_length, 0);
+ if (PKCS5_PBKDF2_HMAC(password, password_len, (unsigned char *)salt, salt_len, iterations, digest, key_length, (unsigned char*)out_buffer->val) == 1) {
+ out_buffer->val[key_length] = 0;
+ RETURN_STR(out_buffer);
} else {
- efree(out_buffer);
+ zend_string_release(out_buffer);
RETURN_FALSE;
}
}
@@ -3794,11 +3933,15 @@ PHP_FUNCTION(openssl_pkcs7_verify)
STACK_OF(X509) *others = NULL;
PKCS7 * p7 = NULL;
BIO * in = NULL, * datain = NULL, * dataout = NULL;
- long flags = 0;
- char * filename; int filename_len;
- char * extracerts = NULL; int extracerts_len = 0;
- char * signersfilename = NULL; int signersfilename_len = 0;
- char * datafilename = NULL; int datafilename_len = 0;
+ zend_long flags = 0;
+ char * filename;
+ size_t filename_len;
+ char * extracerts = NULL;
+ size_t extracerts_len = 0;
+ char * signersfilename = NULL;
+ size_t signersfilename_len = 0;
+ char * datafilename = NULL;
+ size_t datafilename_len = 0;
RETVAL_LONG(-1);
@@ -3897,25 +4040,24 @@ clean_exit:
Encrypts the message in the file named infile with the certificates in recipcerts and output the result to the file named outfile */
PHP_FUNCTION(openssl_pkcs7_encrypt)
{
- zval ** zrecipcerts, * zheaders = NULL;
+ zval * zrecipcerts, * zheaders = NULL;
STACK_OF(X509) * recipcerts = NULL;
BIO * infile = NULL, * outfile = NULL;
- long flags = 0;
+ zend_long flags = 0;
PKCS7 * p7 = NULL;
- HashPosition hpos;
- zval ** zcertval;
+ zval * zcertval;
X509 * cert;
const EVP_CIPHER *cipher = NULL;
- long cipherid = PHP_OPENSSL_CIPHER_DEFAULT;
- uint strindexlen;
- ulong intindex;
- char * strindex;
- char * infilename = NULL; int infilename_len;
- char * outfilename = NULL; int outfilename_len;
+ zend_long cipherid = PHP_OPENSSL_CIPHER_DEFAULT;
+ zend_string * strindex;
+ char * infilename = NULL;
+ size_t infilename_len;
+ char * outfilename = NULL;
+ size_t outfilename_len;
RETVAL_FALSE;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ppZa!|ll", &infilename, &infilename_len,
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ppza!|ll", &infilename, &infilename_len,
&outfilename, &outfilename_len, &zrecipcerts, &zheaders, &flags, &cipherid) == FAILURE)
return;
@@ -3937,17 +4079,16 @@ PHP_FUNCTION(openssl_pkcs7_encrypt)
recipcerts = sk_X509_new_null();
/* get certs */
- if (Z_TYPE_PP(zrecipcerts) == IS_ARRAY) {
- zend_hash_internal_pointer_reset_ex(HASH_OF(*zrecipcerts), &hpos);
- while(zend_hash_get_current_data_ex(HASH_OF(*zrecipcerts), (void**)&zcertval, &hpos) == SUCCESS) {
- long certresource;
+ if (Z_TYPE_P(zrecipcerts) == IS_ARRAY) {
+ ZEND_HASH_FOREACH_VAL(HASH_OF(zrecipcerts), zcertval) {
+ zend_resource *certresource;
cert = php_openssl_x509_from_zval(zcertval, 0, &certresource TSRMLS_CC);
if (cert == NULL) {
goto clean_exit;
}
- if (certresource != -1) {
+ if (certresource != NULL) {
/* we shouldn't free this particular cert, as it is a resource.
make a copy and push that on the stack instead */
cert = X509_dup(cert);
@@ -3956,19 +4097,17 @@ PHP_FUNCTION(openssl_pkcs7_encrypt)
}
}
sk_X509_push(recipcerts, cert);
-
- zend_hash_move_forward_ex(HASH_OF(*zrecipcerts), &hpos);
- }
+ } ZEND_HASH_FOREACH_END();
} else {
/* a single certificate */
- long certresource;
+ zend_resource *certresource;
cert = php_openssl_x509_from_zval(zrecipcerts, 0, &certresource TSRMLS_CC);
if (cert == NULL) {
goto clean_exit;
}
- if (certresource != -1) {
+ if (certresource != NULL) {
/* we shouldn't free this particular cert, as it is a resource.
make a copy and push that on the stack instead */
cert = X509_dup(cert);
@@ -3995,21 +4134,15 @@ PHP_FUNCTION(openssl_pkcs7_encrypt)
/* tack on extra headers */
if (zheaders) {
- zend_hash_internal_pointer_reset_ex(HASH_OF(zheaders), &hpos);
- while(zend_hash_get_current_data_ex(HASH_OF(zheaders), (void**)&zcertval, &hpos) == SUCCESS) {
- strindex = NULL;
- zend_hash_get_current_key_ex(HASH_OF(zheaders), &strindex, &strindexlen, &intindex, 0, &hpos);
-
+ ZEND_HASH_FOREACH_STR_KEY_VAL(HASH_OF(zheaders), strindex, zcertval) {
convert_to_string_ex(zcertval);
if (strindex) {
- BIO_printf(outfile, "%s: %s\n", strindex, Z_STRVAL_PP(zcertval));
+ BIO_printf(outfile, "%s: %s\n", strindex->val, Z_STRVAL_P(zcertval));
} else {
- BIO_printf(outfile, "%s\n", Z_STRVAL_PP(zcertval));
+ BIO_printf(outfile, "%s\n", Z_STRVAL_P(zcertval));
}
-
- zend_hash_move_forward_ex(HASH_OF(zheaders), &hpos);
- }
+ } ZEND_HASH_FOREACH_END();
}
(void)BIO_reset(infile);
@@ -4034,24 +4167,24 @@ clean_exit:
PHP_FUNCTION(openssl_pkcs7_sign)
{
- zval ** zcert, ** zprivkey, * zheaders;
- zval ** hval;
+ zval * zcert, * zprivkey, * zheaders;
+ zval * hval;
X509 * cert = NULL;
EVP_PKEY * privkey = NULL;
- long flags = PKCS7_DETACHED;
+ zend_long flags = PKCS7_DETACHED;
PKCS7 * p7 = NULL;
BIO * infile = NULL, * outfile = NULL;
STACK_OF(X509) *others = NULL;
- long certresource = -1, keyresource = -1;
- ulong intindex;
- uint strindexlen;
- HashPosition hpos;
- char * strindex;
- char * infilename; int infilename_len;
- char * outfilename; int outfilename_len;
- char * extracertsfilename = NULL; int extracertsfilename_len;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ppZZa!|lp",
+ zend_resource *certresource = NULL, *keyresource = NULL;
+ zend_string * strindex;
+ char * infilename;
+ size_t infilename_len;
+ char * outfilename;
+ size_t outfilename_len;
+ char * extracertsfilename = NULL;
+ size_t extracertsfilename_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ppzza!|lp",
&infilename, &infilename_len, &outfilename, &outfilename_len,
&zcert, &zprivkey, &zheaders, &flags, &extracertsfilename,
&extracertsfilename_len) == FAILURE) {
@@ -4105,20 +4238,15 @@ PHP_FUNCTION(openssl_pkcs7_sign)
/* tack on extra headers */
if (zheaders) {
- zend_hash_internal_pointer_reset_ex(HASH_OF(zheaders), &hpos);
- while(zend_hash_get_current_data_ex(HASH_OF(zheaders), (void**)&hval, &hpos) == SUCCESS) {
- strindex = NULL;
- zend_hash_get_current_key_ex(HASH_OF(zheaders), &strindex, &strindexlen, &intindex, 0, &hpos);
-
+ ZEND_HASH_FOREACH_STR_KEY_VAL(HASH_OF(zheaders), strindex, hval) {
convert_to_string_ex(hval);
if (strindex) {
- BIO_printf(outfile, "%s: %s\n", strindex, Z_STRVAL_PP(hval));
+ BIO_printf(outfile, "%s: %s\n", strindex->val, Z_STRVAL_P(hval));
} else {
- BIO_printf(outfile, "%s\n", Z_STRVAL_PP(hval));
+ BIO_printf(outfile, "%s\n", Z_STRVAL_P(hval));
}
- zend_hash_move_forward_ex(HASH_OF(zheaders), &hpos);
- }
+ } ZEND_HASH_FOREACH_END();
}
/* write the signed data */
SMIME_write_PKCS7(outfile, p7, infile, flags);
@@ -4132,10 +4260,10 @@ clean_exit:
if (others) {
sk_X509_pop_free(others, X509_free);
}
- if (privkey && keyresource == -1) {
+ if (privkey && keyresource == NULL) {
EVP_PKEY_free(privkey);
}
- if (cert && certresource == -1) {
+ if (cert && certresource == NULL) {
X509_free(cert);
}
}
@@ -4146,16 +4274,18 @@ clean_exit:
PHP_FUNCTION(openssl_pkcs7_decrypt)
{
- zval ** recipcert, ** recipkey = NULL;
+ zval * recipcert, * recipkey = NULL;
X509 * cert = NULL;
EVP_PKEY * key = NULL;
- long certresval, keyresval;
+ zend_resource *certresval, *keyresval;
BIO * in = NULL, * out = NULL, * datain = NULL;
PKCS7 * p7 = NULL;
- char * infilename; int infilename_len;
- char * outfilename; int outfilename_len;
+ char * infilename;
+ size_t infilename_len;
+ char * outfilename;
+ size_t outfilename_len;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ppZ|Z", &infilename, &infilename_len,
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ppz|z", &infilename, &infilename_len,
&outfilename, &outfilename_len, &recipcert, &recipkey) == FAILURE) {
return;
}
@@ -4200,10 +4330,10 @@ clean_exit:
BIO_free(datain);
BIO_free(in);
BIO_free(out);
- if (cert && certresval == -1) {
+ if (cert && certresval == NULL) {
X509_free(cert);
}
- if (key && keyresval == -1) {
+ if (key && keyresval == NULL) {
EVP_PKEY_free(key);
}
}
@@ -4215,17 +4345,17 @@ clean_exit:
Encrypts data with private key */
PHP_FUNCTION(openssl_private_encrypt)
{
- zval **key, *crypted;
+ zval *key, *crypted;
EVP_PKEY *pkey;
int cryptedlen;
- unsigned char *cryptedbuf = NULL;
+ zend_string *cryptedbuf = NULL;
int successful = 0;
- long keyresource = -1;
+ zend_resource *keyresource = NULL;
char * data;
- int data_len;
- long padding = RSA_PKCS1_PADDING;
+ size_t data_len;
+ zend_long padding = RSA_PKCS1_PADDING;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szZ|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/z|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) {
return;
}
RETVAL_FALSE;
@@ -4238,14 +4368,14 @@ PHP_FUNCTION(openssl_private_encrypt)
}
cryptedlen = EVP_PKEY_size(pkey);
- cryptedbuf = emalloc(cryptedlen + 1);
+ cryptedbuf = zend_string_alloc(cryptedlen, 0);
switch (pkey->type) {
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
successful = (RSA_private_encrypt(data_len,
(unsigned char *)data,
- cryptedbuf,
+ (unsigned char *)cryptedbuf->val,
pkey->pkey.rsa,
padding) == cryptedlen);
break;
@@ -4255,15 +4385,15 @@ PHP_FUNCTION(openssl_private_encrypt)
if (successful) {
zval_dtor(crypted);
- cryptedbuf[cryptedlen] = '\0';
- ZVAL_STRINGL(crypted, (char *)cryptedbuf, cryptedlen, 0);
+ cryptedbuf->val[cryptedlen] = '\0';
+ ZVAL_NEW_STR(crypted, cryptedbuf);
cryptedbuf = NULL;
RETVAL_TRUE;
}
if (cryptedbuf) {
- efree(cryptedbuf);
+ zend_string_release(cryptedbuf);
}
- if (keyresource == -1) {
+ if (keyresource == NULL) {
EVP_PKEY_free(pkey);
}
}
@@ -4273,18 +4403,18 @@ PHP_FUNCTION(openssl_private_encrypt)
Decrypts data with private key */
PHP_FUNCTION(openssl_private_decrypt)
{
- zval **key, *crypted;
+ zval *key, *crypted;
EVP_PKEY *pkey;
int cryptedlen;
- unsigned char *cryptedbuf = NULL;
+ zend_string *cryptedbuf = NULL;
unsigned char *crypttemp;
int successful = 0;
- long padding = RSA_PKCS1_PADDING;
- long keyresource = -1;
+ zend_long padding = RSA_PKCS1_PADDING;
+ zend_resource *keyresource = NULL;
char * data;
- int data_len;
+ size_t data_len;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szZ|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/z|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) {
return;
}
RETVAL_FALSE;
@@ -4307,8 +4437,8 @@ PHP_FUNCTION(openssl_private_decrypt)
pkey->pkey.rsa,
padding);
if (cryptedlen != -1) {
- cryptedbuf = emalloc(cryptedlen + 1);
- memcpy(cryptedbuf, crypttemp, cryptedlen);
+ cryptedbuf = zend_string_alloc(cryptedlen, 0);
+ memcpy(cryptedbuf->val, crypttemp, cryptedlen);
successful = 1;
}
break;
@@ -4320,17 +4450,17 @@ PHP_FUNCTION(openssl_private_decrypt)
if (successful) {
zval_dtor(crypted);
- cryptedbuf[cryptedlen] = '\0';
- ZVAL_STRINGL(crypted, (char *)cryptedbuf, cryptedlen, 0);
+ cryptedbuf->val[cryptedlen] = '\0';
+ ZVAL_NEW_STR(crypted, cryptedbuf);
cryptedbuf = NULL;
RETVAL_TRUE;
}
- if (keyresource == -1) {
+ if (keyresource == NULL) {
EVP_PKEY_free(pkey);
}
if (cryptedbuf) {
- efree(cryptedbuf);
+ zend_string_release(cryptedbuf);
}
}
/* }}} */
@@ -4339,19 +4469,18 @@ PHP_FUNCTION(openssl_private_decrypt)
Encrypts data with public key */
PHP_FUNCTION(openssl_public_encrypt)
{
- zval **key, *crypted;
+ zval *key, *crypted;
EVP_PKEY *pkey;
int cryptedlen;
- unsigned char *cryptedbuf;
+ zend_string *cryptedbuf;
int successful = 0;
- long keyresource = -1;
- long padding = RSA_PKCS1_PADDING;
+ zend_resource *keyresource = NULL;
+ zend_long padding = RSA_PKCS1_PADDING;
char * data;
- int data_len;
+ size_t data_len;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szZ|l", &data, &data_len, &crypted, &key, &padding) == FAILURE)
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/z|l", &data, &data_len, &crypted, &key, &padding) == FAILURE)
return;
-
RETVAL_FALSE;
pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource TSRMLS_CC);
@@ -4361,14 +4490,14 @@ PHP_FUNCTION(openssl_public_encrypt)
}
cryptedlen = EVP_PKEY_size(pkey);
- cryptedbuf = emalloc(cryptedlen + 1);
+ cryptedbuf = zend_string_alloc(cryptedlen, 0);
switch (pkey->type) {
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
successful = (RSA_public_encrypt(data_len,
(unsigned char *)data,
- cryptedbuf,
+ (unsigned char *)cryptedbuf->val,
pkey->pkey.rsa,
padding) == cryptedlen);
break;
@@ -4379,16 +4508,16 @@ PHP_FUNCTION(openssl_public_encrypt)
if (successful) {
zval_dtor(crypted);
- cryptedbuf[cryptedlen] = '\0';
- ZVAL_STRINGL(crypted, (char *)cryptedbuf, cryptedlen, 0);
+ cryptedbuf->val[cryptedlen] = '\0';
+ ZVAL_NEW_STR(crypted, cryptedbuf);
cryptedbuf = NULL;
RETVAL_TRUE;
}
- if (keyresource == -1) {
+ if (keyresource == NULL) {
EVP_PKEY_free(pkey);
}
if (cryptedbuf) {
- efree(cryptedbuf);
+ zend_string_release(cryptedbuf);
}
}
/* }}} */
@@ -4397,18 +4526,18 @@ PHP_FUNCTION(openssl_public_encrypt)
Decrypts data with public key */
PHP_FUNCTION(openssl_public_decrypt)
{
- zval **key, *crypted;
+ zval *key, *crypted;
EVP_PKEY *pkey;
int cryptedlen;
- unsigned char *cryptedbuf = NULL;
+ zend_string *cryptedbuf = NULL;
unsigned char *crypttemp;
int successful = 0;
- long keyresource = -1;
- long padding = RSA_PKCS1_PADDING;
+ zend_resource *keyresource = NULL;
+ zend_long padding = RSA_PKCS1_PADDING;
char * data;
- int data_len;
+ size_t data_len;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szZ|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/z|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) {
return;
}
RETVAL_FALSE;
@@ -4431,8 +4560,8 @@ PHP_FUNCTION(openssl_public_decrypt)
pkey->pkey.rsa,
padding);
if (cryptedlen != -1) {
- cryptedbuf = emalloc(cryptedlen + 1);
- memcpy(cryptedbuf, crypttemp, cryptedlen);
+ cryptedbuf = zend_string_alloc(cryptedlen, 0);
+ memcpy(cryptedbuf->val, crypttemp, cryptedlen);
successful = 1;
}
break;
@@ -4446,16 +4575,16 @@ PHP_FUNCTION(openssl_public_decrypt)
if (successful) {
zval_dtor(crypted);
- cryptedbuf[cryptedlen] = '\0';
- ZVAL_STRINGL(crypted, (char *)cryptedbuf, cryptedlen, 0);
+ cryptedbuf->val[cryptedlen] = '\0';
+ ZVAL_NEW_STR(crypted, cryptedbuf);
cryptedbuf = NULL;
RETVAL_TRUE;
}
if (cryptedbuf) {
- efree(cryptedbuf);
+ zend_string_release(cryptedbuf);
}
- if (keyresource == -1) {
+ if (keyresource == NULL) {
EVP_PKEY_free(pkey);
}
}
@@ -4474,7 +4603,7 @@ PHP_FUNCTION(openssl_error_string)
val = ERR_get_error();
if (val) {
- RETURN_STRING(ERR_error_string(val, buf), 1);
+ RETURN_STRING(ERR_error_string(val, buf));
} else {
RETURN_FALSE;
}
@@ -4485,19 +4614,19 @@ PHP_FUNCTION(openssl_error_string)
Signs data */
PHP_FUNCTION(openssl_sign)
{
- zval **key, *signature;
+ zval *key, *signature;
EVP_PKEY *pkey;
- int siglen;
- unsigned char *sigbuf;
- long keyresource = -1;
+ unsigned int siglen;
+ zend_string *sigbuf;
+ zend_resource *keyresource = NULL;
char * data;
- int data_len;
+ size_t data_len;
EVP_MD_CTX md_ctx;
zval *method = NULL;
- long signature_algo = OPENSSL_ALGO_SHA1;
+ zend_long signature_algo = OPENSSL_ALGO_SHA1;
const EVP_MD *mdtype;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szZ|z", &data, &data_len, &signature, &key, &method) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/z|z", &data, &data_len, &signature, &key, &method) == FAILURE) {
return;
}
pkey = php_openssl_evp_from_zval(key, 0, "", 0, &keyresource TSRMLS_CC);
@@ -4523,21 +4652,22 @@ PHP_FUNCTION(openssl_sign)
}
siglen = EVP_PKEY_size(pkey);
- sigbuf = emalloc(siglen + 1);
+ sigbuf = zend_string_alloc(siglen, 0);
EVP_SignInit(&md_ctx, mdtype);
EVP_SignUpdate(&md_ctx, data, data_len);
- if (EVP_SignFinal (&md_ctx, sigbuf,(unsigned int *)&siglen, pkey)) {
+ if (EVP_SignFinal (&md_ctx, (unsigned char*)sigbuf->val, &siglen, pkey)) {
zval_dtor(signature);
- sigbuf[siglen] = '\0';
- ZVAL_STRINGL(signature, (char *)sigbuf, siglen, 0);
+ sigbuf->val[siglen] = '\0';
+ sigbuf->len = siglen;
+ ZVAL_NEW_STR(signature, sigbuf);
RETVAL_TRUE;
} else {
efree(sigbuf);
RETVAL_FALSE;
}
EVP_MD_CTX_cleanup(&md_ctx);
- if (keyresource == -1) {
+ if (keyresource == NULL) {
EVP_PKEY_free(pkey);
}
}
@@ -4547,18 +4677,20 @@ PHP_FUNCTION(openssl_sign)
Verifys data */
PHP_FUNCTION(openssl_verify)
{
- zval **key;
+ zval *key;
EVP_PKEY *pkey;
int err;
EVP_MD_CTX md_ctx;
const EVP_MD *mdtype;
- long keyresource = -1;
- char * data; int data_len;
- char * signature; int signature_len;
+ zend_resource *keyresource = NULL;
+ char * data;
+ size_t data_len;
+ char * signature;
+ size_t signature_len;
zval *method = NULL;
- long signature_algo = OPENSSL_ALGO_SHA1;
+ zend_long signature_algo = OPENSSL_ALGO_SHA1;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssZ|z", &data, &data_len, &signature, &signature_len, &key, &method) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssz|z", &data, &data_len, &signature, &signature_len, &key, &method) == FAILURE) {
return;
}
@@ -4589,7 +4721,7 @@ PHP_FUNCTION(openssl_verify)
err = EVP_VerifyFinal (&md_ctx, (unsigned char *)signature, signature_len, pkey);
EVP_MD_CTX_cleanup(&md_ctx);
- if (keyresource == -1) {
+ if (keyresource == NULL) {
EVP_PKEY_free(pkey);
}
RETURN_LONG(err);
@@ -4600,23 +4732,22 @@ PHP_FUNCTION(openssl_verify)
Seals data */
PHP_FUNCTION(openssl_seal)
{
- zval *pubkeys, **pubkey, *sealdata, *ekeys;
+ zval *pubkeys, *pubkey, *sealdata, *ekeys;
HashTable *pubkeysht;
- HashPosition pos;
EVP_PKEY **pkeys;
- long * key_resources; /* so we know what to cleanup */
+ zend_resource ** key_resources; /* so we know what to cleanup */
int i, len1, len2, *eksl, nkeys;
unsigned char *buf = NULL, **eks;
- char * data; int data_len;
+ char * data;
+ size_t data_len;
char *method =NULL;
- int method_len = 0;
+ size_t method_len = 0;
const EVP_CIPHER *cipher;
EVP_CIPHER_CTX ctx;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szza/|s", &data, &data_len, &sealdata, &ekeys, &pubkeys, &method, &method_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/z/a/|s", &data, &data_len, &sealdata, &ekeys, &pubkeys, &method, &method_len) == FAILURE) {
return;
}
-
pubkeysht = HASH_OF(pubkeys);
nkeys = pubkeysht ? zend_hash_num_elements(pubkeysht) : 0;
if (!nkeys) {
@@ -4638,14 +4769,12 @@ PHP_FUNCTION(openssl_seal)
eksl = safe_emalloc(nkeys, sizeof(*eksl), 0);
eks = safe_emalloc(nkeys, sizeof(*eks), 0);
memset(eks, 0, sizeof(*eks) * nkeys);
- key_resources = safe_emalloc(nkeys, sizeof(long), 0);
- memset(key_resources, 0, sizeof(*key_resources) * nkeys);
+ key_resources = safe_emalloc(nkeys, sizeof(zend_resource), 0);
+ memset(key_resources, 0, sizeof(zend_resource) * nkeys);
/* get the public keys we are using to seal this data */
- zend_hash_internal_pointer_reset_ex(pubkeysht, &pos);
i = 0;
- while (zend_hash_get_current_data_ex(pubkeysht, (void **) &pubkey,
- &pos) == SUCCESS) {
+ ZEND_HASH_FOREACH_VAL(pubkeysht, pubkey) {
pkeys[i] = php_openssl_evp_from_zval(pubkey, 1, NULL, 0, &key_resources[i] TSRMLS_CC);
if (pkeys[i] == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "not a public key (%dth member of pubkeys)", i+1);
@@ -4653,12 +4782,12 @@ PHP_FUNCTION(openssl_seal)
goto clean_exit;
}
eks[i] = emalloc(EVP_PKEY_size(pkeys[i]) + 1);
- zend_hash_move_forward_ex(pubkeysht, &pos);
i++;
- }
+ } ZEND_HASH_FOREACH_END();
if (!EVP_EncryptInit(&ctx,cipher,NULL,NULL)) {
RETVAL_FALSE;
+ EVP_CIPHER_CTX_cleanup(&ctx);
goto clean_exit;
}
@@ -4669,10 +4798,12 @@ PHP_FUNCTION(openssl_seal)
#endif
/* allocate one byte extra to make room for \0 */
buf = emalloc(data_len + EVP_CIPHER_CTX_block_size(&ctx));
+ EVP_CIPHER_CTX_cleanup(&ctx);
if (!EVP_SealInit(&ctx, cipher, eks, eksl, NULL, pkeys, nkeys) || !EVP_SealUpdate(&ctx, buf, &len1, (unsigned char *)data, data_len)) {
RETVAL_FALSE;
efree(buf);
+ EVP_CIPHER_CTX_cleanup(&ctx);
goto clean_exit;
}
@@ -4681,14 +4812,15 @@ PHP_FUNCTION(openssl_seal)
if (len1 + len2 > 0) {
zval_dtor(sealdata);
buf[len1 + len2] = '\0';
- buf = erealloc(buf, len1 + len2 + 1);
- ZVAL_STRINGL(sealdata, (char *)buf, len1 + len2, 0);
+ ZVAL_NEW_STR(sealdata, zend_string_init((char*)buf, len1 + len2, 0));
+ efree(buf);
zval_dtor(ekeys);
array_init(ekeys);
for (i=0; i<nkeys; i++) {
eks[i][eksl[i]] = '\0';
- add_next_index_stringl(ekeys, erealloc(eks[i], eksl[i] + 1), eksl[i], 0);
+ add_next_index_stringl(ekeys, (const char*)eks[i], eksl[i]);
+ efree(eks[i]);
eks[i] = NULL;
}
#if 0
@@ -4696,7 +4828,8 @@ PHP_FUNCTION(openssl_seal)
zval_dtor(*ivec);
if (ivlen) {
iv[ivlen] = '\0';
- ZVAL_STRINGL(*ivec, erealloc(iv, ivlen + 1), ivlen, 0);
+ ZVAL_STRINGL(*ivec, iv, ivlen);
+ efree(iv);
} else {
ZVAL_EMPTY_STRING(*ivec);
}
@@ -4705,10 +4838,11 @@ PHP_FUNCTION(openssl_seal)
efree(buf);
}
RETVAL_LONG(len1 + len2);
+ EVP_CIPHER_CTX_cleanup(&ctx);
clean_exit:
for (i=0; i<nkeys; i++) {
- if (key_resources[i] == -1) {
+ if (key_resources[i] == NULL) {
EVP_PKEY_free(pkeys[i]);
}
if (eks[i]) {
@@ -4726,19 +4860,21 @@ clean_exit:
Opens data */
PHP_FUNCTION(openssl_open)
{
- zval **privkey, *opendata;
+ zval *privkey, *opendata;
EVP_PKEY *pkey;
int len1, len2;
unsigned char *buf;
- long keyresource = -1;
+ zend_resource *keyresource = NULL;
EVP_CIPHER_CTX ctx;
- char * data; int data_len;
- char * ekey; int ekey_len;
+ char * data;
+ size_t data_len;
+ char * ekey;
+ size_t ekey_len;
char *method =NULL;
- int method_len = 0;
+ size_t method_len = 0;
const EVP_CIPHER *cipher;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szsZ|s", &data, &data_len, &opendata, &ekey, &ekey_len, &privkey, &method, &method_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/sz|s", &data, &data_len, &opendata, &ekey, &ekey_len, &privkey, &method, &method_len) == FAILURE) {
return;
}
@@ -4763,285 +4899,35 @@ PHP_FUNCTION(openssl_open)
if (EVP_OpenInit(&ctx, cipher, (unsigned char *)ekey, ekey_len, NULL, pkey) && EVP_OpenUpdate(&ctx, buf, &len1, (unsigned char *)data, data_len)) {
if (!EVP_OpenFinal(&ctx, buf + len1, &len2) || (len1 + len2 == 0)) {
efree(buf);
- if (keyresource == -1) {
- EVP_PKEY_free(pkey);
- }
- RETURN_FALSE;
+ RETVAL_FALSE;
+ } else {
+ zval_dtor(opendata);
+ buf[len1 + len2] = '\0';
+ ZVAL_NEW_STR(opendata, zend_string_init((char*)buf, len1 + len2, 0));
+ efree(buf);
+ RETVAL_TRUE;
}
} else {
efree(buf);
- if (keyresource == -1) {
- EVP_PKEY_free(pkey);
- }
- RETURN_FALSE;
+ RETVAL_FALSE;
}
- if (keyresource == -1) {
+ if (keyresource == NULL) {
EVP_PKEY_free(pkey);
}
- zval_dtor(opendata);
- buf[len1 + len2] = '\0';
- ZVAL_STRINGL(opendata, erealloc(buf, len1 + len2 + 1), len1 + len2, 0);
- RETURN_TRUE;
-}
-/* }}} */
-
-/* SSL verification functions */
-
-#define GET_VER_OPT(name) (stream->context && SUCCESS == php_stream_context_get_option(stream->context, "ssl", name, &val))
-#define GET_VER_OPT_STRING(name, str) if (GET_VER_OPT(name)) { convert_to_string_ex(val); str = Z_STRVAL_PP(val); }
-
-static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) /* {{{ */
-{
- php_stream *stream;
- SSL *ssl;
- X509 *err_cert;
- int err, depth, ret;
- zval **val;
-
- ret = preverify_ok;
-
- /* determine the status for the current cert */
- err_cert = X509_STORE_CTX_get_current_cert(ctx);
- err = X509_STORE_CTX_get_error(ctx);
- depth = X509_STORE_CTX_get_error_depth(ctx);
-
- /* conjure the stream & context to use */
- ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
- stream = (php_stream*)SSL_get_ex_data(ssl, ssl_stream_data_index);
-
- /* if allow_self_signed is set, make sure that verification succeeds */
- if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && GET_VER_OPT("allow_self_signed") && zval_is_true(*val)) {
- ret = 1;
- }
-
- /* check the depth */
- if (GET_VER_OPT("verify_depth")) {
- convert_to_long_ex(val);
-
- if (depth > Z_LVAL_PP(val)) {
- ret = 0;
- X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_CHAIN_TOO_LONG);
- }
- }
-
- return ret;
-
-}
-/* }}} */
-
-int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream *stream TSRMLS_DC) /* {{{ */
-{
- zval **val = NULL;
- char *cnmatch = NULL;
- X509_NAME *name;
- char buf[1024];
- int err;
-
- /* verification is turned off */
- if (!(GET_VER_OPT("verify_peer") && zval_is_true(*val))) {
- return SUCCESS;
- }
-
- if (peer == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not get peer certificate");
- return FAILURE;
- }
-
- err = SSL_get_verify_result(ssl);
- switch (err) {
- case X509_V_OK:
- /* fine */
- break;
- case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
- if (GET_VER_OPT("allow_self_signed") && zval_is_true(*val)) {
- /* allowed */
- break;
- }
- /* not allowed, so fall through */
- default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not verify peer: code:%d %s", err, X509_verify_cert_error_string(err));
- return FAILURE;
- }
-
- /* if the cert passed the usual checks, apply our own local policies now */
-
- name = X509_get_subject_name(peer);
-
- /* Does the common name match ? (used primarily for https://) */
- GET_VER_OPT_STRING("CN_match", cnmatch);
- if (cnmatch) {
- int match = 0;
- int name_len = X509_NAME_get_text_by_NID(name, NID_commonName, buf, sizeof(buf));
-
- if (name_len == -1) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate peer certificate CN");
- return FAILURE;
- } else if (name_len != strlen(buf)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer certificate CN=`%.*s' is malformed", name_len, buf);
- return FAILURE;
- }
-
- match = strcmp(cnmatch, buf) == 0;
- if (!match && strlen(buf) > 3 && buf[0] == '*' && buf[1] == '.') {
- /* Try wildcard */
-
- if (strchr(buf+2, '.')) {
- char *tmp = strstr(cnmatch, buf+1);
-
- match = tmp && strcmp(tmp, buf+2) && tmp == strchr(cnmatch, '.');
- }
- }
-
- if (!match) {
- /* didn't match */
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer certificate CN=`%.*s' did not match expected CN=`%s'", name_len, buf, cnmatch);
- return FAILURE;
- }
- }
-
- return SUCCESS;
-}
-/* }}} */
-
-static int passwd_callback(char *buf, int num, int verify, void *data) /* {{{ */
-{
- php_stream *stream = (php_stream *)data;
- zval **val = NULL;
- char *passphrase = NULL;
- /* TODO: could expand this to make a callback into PHP user-space */
-
- GET_VER_OPT_STRING("passphrase", passphrase);
-
- if (passphrase) {
- if (Z_STRLEN_PP(val) < num - 1) {
- memcpy(buf, Z_STRVAL_PP(val), Z_STRLEN_PP(val)+1);
- return Z_STRLEN_PP(val);
- }
- }
- return 0;
-}
-/* }}} */
-
-SSL *php_SSL_new_from_context(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{ */
-{
- zval **val = NULL;
- char *cafile = NULL;
- char *capath = NULL;
- char *certfile = NULL;
- char *cipherlist = NULL;
- int ok = 1;
-
- ERR_clear_error();
-
- /* look at context options in the stream and set appropriate verification flags */
- if (GET_VER_OPT("verify_peer") && zval_is_true(*val)) {
-
- /* turn on verification callback */
- SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback);
-
- /* CA stuff */
- GET_VER_OPT_STRING("cafile", cafile);
- GET_VER_OPT_STRING("capath", capath);
-
- if (cafile || capath) {
- if (!SSL_CTX_load_verify_locations(ctx, cafile, capath)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set verify locations `%s' `%s'", cafile, capath);
- return NULL;
- }
- }
-
- if (GET_VER_OPT("verify_depth")) {
- convert_to_long_ex(val);
- SSL_CTX_set_verify_depth(ctx, Z_LVAL_PP(val));
- }
- } else {
- SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
- }
-
- /* callback for the passphrase (for localcert) */
- if (GET_VER_OPT("passphrase")) {
- SSL_CTX_set_default_passwd_cb_userdata(ctx, stream);
- SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
- }
-
- GET_VER_OPT_STRING("ciphers", cipherlist);
- if (!cipherlist) {
- cipherlist = "DEFAULT";
- }
- if (SSL_CTX_set_cipher_list(ctx, cipherlist) != 1) {
- return NULL;
- }
-
- GET_VER_OPT_STRING("local_cert", certfile);
- if (certfile) {
- X509 *cert = NULL;
- EVP_PKEY *key = NULL;
- SSL *tmpssl;
- char resolved_path_buff[MAXPATHLEN];
- const char * private_key = NULL;
-
- if (VCWD_REALPATH(certfile, resolved_path_buff)) {
- /* a certificate to use for authentication */
- if (SSL_CTX_use_certificate_chain_file(ctx, resolved_path_buff) != 1) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set local cert chain file `%s'; Check that your cafile/capath settings include details of your certificate and its issuer", certfile);
- return NULL;
- }
- GET_VER_OPT_STRING("local_pk", private_key);
-
- if (private_key) {
- char resolved_path_buff_pk[MAXPATHLEN];
- if (VCWD_REALPATH(private_key, resolved_path_buff_pk)) {
- if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff_pk, SSL_FILETYPE_PEM) != 1) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff_pk);
- return NULL;
- }
- }
- } else {
- if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff, SSL_FILETYPE_PEM) != 1) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff);
- return NULL;
- }
- }
-
- tmpssl = SSL_new(ctx);
- cert = SSL_get_certificate(tmpssl);
-
- if (cert) {
- key = X509_get_pubkey(cert);
- EVP_PKEY_copy_parameters(key, SSL_get_privatekey(tmpssl));
- EVP_PKEY_free(key);
- }
- SSL_free(tmpssl);
-
- if (!SSL_CTX_check_private_key(ctx)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Private key does not match certificate!");
- }
- }
- }
- if (ok) {
- SSL *ssl = SSL_new(ctx);
-
- if (ssl) {
- /* map SSL => stream */
- SSL_set_ex_data(ssl, ssl_stream_data_index, stream);
- }
- return ssl;
- }
-
- return NULL;
+ EVP_CIPHER_CTX_cleanup(&ctx);
}
/* }}} */
static void openssl_add_method_or_alias(const OBJ_NAME *name, void *arg) /* {{{ */
{
- add_next_index_string((zval*)arg, (char*)name->name, 1);
+ add_next_index_string((zval*)arg, (char*)name->name);
}
/* }}} */
static void openssl_add_method(const OBJ_NAME *name, void *arg) /* {{{ */
{
if (name->alias == 0) {
- add_next_index_string((zval*)arg, (char*)name->name, 1);
+ add_next_index_string((zval*)arg, (char*)name->name);
}
}
/* }}} */
@@ -5084,11 +4970,11 @@ PHP_FUNCTION(openssl_digest)
{
zend_bool raw_output = 0;
char *data, *method;
- int data_len, method_len;
+ size_t data_len, method_len;
const EVP_MD *mdtype;
EVP_MD_CTX md_ctx;
- int siglen;
- unsigned char *sigbuf;
+ unsigned int siglen;
+ zend_string *sigbuf;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &data, &data_len, &method, &method_len, &raw_output) == FAILURE) {
return;
@@ -5100,24 +4986,26 @@ PHP_FUNCTION(openssl_digest)
}
siglen = EVP_MD_size(mdtype);
- sigbuf = emalloc(siglen + 1);
+ sigbuf = zend_string_alloc(siglen, 0);
EVP_DigestInit(&md_ctx, mdtype);
EVP_DigestUpdate(&md_ctx, (unsigned char *)data, data_len);
- if (EVP_DigestFinal (&md_ctx, (unsigned char *)sigbuf, (unsigned int *)&siglen)) {
+ if (EVP_DigestFinal (&md_ctx, (unsigned char *)sigbuf->val, &siglen)) {
if (raw_output) {
- sigbuf[siglen] = '\0';
- RETVAL_STRINGL((char *)sigbuf, siglen, 0);
+ sigbuf->val[siglen] = '\0';
+ sigbuf->len = siglen;
+ RETVAL_STR(sigbuf);
} else {
int digest_str_len = siglen * 2;
- char *digest_str = emalloc(digest_str_len + 1);
+ zend_string *digest_str = zend_string_alloc(digest_str_len, 0);
- make_digest_ex(digest_str, sigbuf, siglen);
- efree(sigbuf);
- RETVAL_STRINGL(digest_str, digest_str_len, 0);
+ make_digest_ex(digest_str->val, (unsigned char*)sigbuf->val, siglen);
+ digest_str->val[digest_str_len] = '\0';
+ zend_string_release(sigbuf);
+ RETVAL_STR(digest_str);
}
} else {
- efree(sigbuf);
+ zend_string_release(sigbuf);
RETVAL_FALSE;
}
}
@@ -5161,13 +5049,14 @@ static zend_bool php_openssl_validate_iv(char **piv, int *piv_len, int iv_requir
Encrypts given data with given method and key, returns raw or base64 encoded string */
PHP_FUNCTION(openssl_encrypt)
{
- long options = 0;
+ zend_long options = 0;
char *data, *method, *password, *iv = "";
- int data_len, method_len, password_len, iv_len = 0, max_iv_len;
+ size_t data_len, method_len, password_len, iv_len = 0, max_iv_len;
const EVP_CIPHER *cipher_type;
EVP_CIPHER_CTX cipher_ctx;
int i=0, outlen, keylen;
- unsigned char *outbuf, *key;
+ zend_string *outbuf;
+ unsigned char *key;
zend_bool free_iv;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ls", &data, &data_len, &method, &method_len, &password, &password_len, &options, &iv, &iv_len) == FAILURE) {
@@ -5192,10 +5081,10 @@ PHP_FUNCTION(openssl_encrypt)
if (iv_len <= 0 && max_iv_len > 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Using an empty Initialization Vector (iv) is potentially insecure and not recommended");
}
- free_iv = php_openssl_validate_iv(&iv, &iv_len, max_iv_len TSRMLS_CC);
+ free_iv = php_openssl_validate_iv(&iv, (int *)&iv_len, max_iv_len TSRMLS_CC);
outlen = data_len + EVP_CIPHER_block_size(cipher_type);
- outbuf = emalloc(outlen + 1);
+ outbuf = zend_string_alloc(outlen, 0);
EVP_EncryptInit(&cipher_ctx, cipher_type, NULL, NULL);
if (password_len > keylen) {
@@ -5206,24 +5095,24 @@ PHP_FUNCTION(openssl_encrypt)
EVP_CIPHER_CTX_set_padding(&cipher_ctx, 0);
}
if (data_len > 0) {
- EVP_EncryptUpdate(&cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
+ EVP_EncryptUpdate(&cipher_ctx, (unsigned char*)outbuf->val, &i, (unsigned char *)data, data_len);
}
outlen = i;
- if (EVP_EncryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) {
+ if (EVP_EncryptFinal(&cipher_ctx, (unsigned char *)outbuf->val + i, &i)) {
outlen += i;
if (options & OPENSSL_RAW_DATA) {
- outbuf[outlen] = '\0';
- RETVAL_STRINGL((char *)outbuf, outlen, 0);
+ outbuf->val[outlen] = '\0';
+ outbuf->len = outlen;
+ RETVAL_STR(outbuf);
} else {
- int base64_str_len;
- char *base64_str;
+ zend_string *base64_str;
- base64_str = (char*)php_base64_encode(outbuf, outlen, &base64_str_len);
- efree(outbuf);
- RETVAL_STRINGL(base64_str, base64_str_len, 0);
+ base64_str = php_base64_encode((unsigned char*)outbuf->val, outlen);
+ zend_string_release(outbuf);
+ RETVAL_STR(base64_str);
}
} else {
- efree(outbuf);
+ zend_string_release(outbuf);
RETVAL_FALSE;
}
if (key != (unsigned char*)password) {
@@ -5240,15 +5129,15 @@ PHP_FUNCTION(openssl_encrypt)
Takes raw or base64 encoded string and dectupt it using given method and key */
PHP_FUNCTION(openssl_decrypt)
{
- long options = 0;
+ zend_long options = 0;
char *data, *method, *password, *iv = "";
- int data_len, method_len, password_len, iv_len = 0;
+ size_t data_len, method_len, password_len, iv_len = 0;
const EVP_CIPHER *cipher_type;
EVP_CIPHER_CTX cipher_ctx;
int i, outlen, keylen;
- unsigned char *outbuf, *key;
- int base64_str_len;
- char *base64_str = NULL;
+ zend_string *outbuf;
+ unsigned char *key;
+ zend_string *base64_str = NULL;
zend_bool free_iv;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ls", &data, &data_len, &method, &method_len, &password, &password_len, &options, &iv, &iv_len) == FAILURE) {
@@ -5267,13 +5156,13 @@ PHP_FUNCTION(openssl_decrypt)
}
if (!(options & OPENSSL_RAW_DATA)) {
- base64_str = (char*)php_base64_decode((unsigned char*)data, data_len, &base64_str_len);
+ base64_str = php_base64_decode((unsigned char*)data, data_len);
if (!base64_str) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to base64 decode the input");
RETURN_FALSE;
}
- data_len = base64_str_len;
- data = base64_str;
+ data_len = base64_str->len;
+ data = base64_str->val;
}
keylen = EVP_CIPHER_key_length(cipher_type);
@@ -5285,10 +5174,10 @@ PHP_FUNCTION(openssl_decrypt)
key = (unsigned char*)password;
}
- free_iv = php_openssl_validate_iv(&iv, &iv_len, EVP_CIPHER_iv_length(cipher_type) TSRMLS_CC);
+ free_iv = php_openssl_validate_iv(&iv, (int *)&iv_len, EVP_CIPHER_iv_length(cipher_type) TSRMLS_CC);
outlen = data_len + EVP_CIPHER_block_size(cipher_type);
- outbuf = emalloc(outlen + 1);
+ outbuf = zend_string_alloc(outlen, 0);
EVP_DecryptInit(&cipher_ctx, cipher_type, NULL, NULL);
if (password_len > keylen) {
@@ -5298,14 +5187,15 @@ PHP_FUNCTION(openssl_decrypt)
if (options & OPENSSL_ZERO_PADDING) {
EVP_CIPHER_CTX_set_padding(&cipher_ctx, 0);
}
- EVP_DecryptUpdate(&cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
+ EVP_DecryptUpdate(&cipher_ctx, (unsigned char*)outbuf->val, &i, (unsigned char *)data, data_len);
outlen = i;
- if (EVP_DecryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) {
+ if (EVP_DecryptFinal(&cipher_ctx, (unsigned char *)outbuf->val + i, &i)) {
outlen += i;
- outbuf[outlen] = '\0';
- RETVAL_STRINGL((char *)outbuf, outlen, 0);
+ outbuf->val[outlen] = '\0';
+ outbuf->len = outlen;
+ RETVAL_STR(outbuf);
} else {
- efree(outbuf);
+ zend_string_release(outbuf);
RETVAL_FALSE;
}
if (key != (unsigned char*)password) {
@@ -5315,7 +5205,7 @@ PHP_FUNCTION(openssl_decrypt)
efree(iv);
}
if (base64_str) {
- efree(base64_str);
+ zend_string_release(base64_str);
}
EVP_CIPHER_CTX_cleanup(&cipher_ctx);
}
@@ -5325,7 +5215,7 @@ PHP_FUNCTION(openssl_decrypt)
PHP_FUNCTION(openssl_cipher_iv_length)
{
char *method;
- int method_len;
+ size_t method_len;
const EVP_CIPHER *cipher_type;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &method, &method_len) == FAILURE) {
@@ -5349,35 +5239,36 @@ PHP_FUNCTION(openssl_cipher_iv_length)
/* {{{ proto string openssl_dh_compute_key(string pub_key, resource dh_key)
- Computes shared sicret for public value of remote DH key and local DH key */
+ Computes shared secret for public value of remote DH key and local DH key */
PHP_FUNCTION(openssl_dh_compute_key)
{
zval *key;
char *pub_str;
- int pub_len;
+ size_t pub_len;
EVP_PKEY *pkey;
BIGNUM *pub;
- char *data;
+ zend_string *data;
int len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sr", &pub_str, &pub_len, &key) == FAILURE) {
return;
}
- ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, &key, -1, "OpenSSL key", le_key);
+ ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, key, -1, "OpenSSL key", le_key);
if (!pkey || EVP_PKEY_type(pkey->type) != EVP_PKEY_DH || !pkey->pkey.dh) {
RETURN_FALSE;
}
pub = BN_bin2bn((unsigned char*)pub_str, pub_len, NULL);
- data = emalloc(DH_size(pkey->pkey.dh) + 1);
- len = DH_compute_key((unsigned char*)data, pub, pkey->pkey.dh);
+ data = zend_string_alloc(DH_size(pkey->pkey.dh), 0);
+ len = DH_compute_key((unsigned char*)data->val, pub, pkey->pkey.dh);
if (len >= 0) {
- data[len] = 0;
- RETVAL_STRINGL(data, len, 0);
+ data->len = len;
+ data->val[len] = 0;
+ RETVAL_STR(data);
} else {
- efree(data);
+ zend_string_release(data);
RETVAL_FALSE;
}
@@ -5389,12 +5280,12 @@ PHP_FUNCTION(openssl_dh_compute_key)
Returns a string of the length specified filled with random pseudo bytes */
PHP_FUNCTION(openssl_random_pseudo_bytes)
{
- long buffer_length;
- unsigned char *buffer = NULL;
+ zend_long buffer_length;
+ zend_string *buffer = NULL;
zval *zstrong_result_returned = NULL;
int strong_result = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|z", &buffer_length, &zstrong_result_returned) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|z/", &buffer_length, &zstrong_result_returned) == FAILURE) {
return;
}
@@ -5407,21 +5298,21 @@ PHP_FUNCTION(openssl_random_pseudo_bytes)
ZVAL_BOOL(zstrong_result_returned, 0);
}
- buffer = emalloc(buffer_length + 1);
+ buffer = zend_string_alloc(buffer_length, 0);
#ifdef PHP_WIN32
strong_result = 1;
/* random/urandom equivalent on Windows */
- if (php_win32_get_random_bytes(buffer, (size_t) buffer_length) == FAILURE){
- efree(buffer);
+ if (php_win32_get_random_bytes((unsigned char*)buffer->val, (size_t) buffer_length) == FAILURE){
+ zend_string_release(buffer);
if (zstrong_result_returned) {
ZVAL_BOOL(zstrong_result_returned, 0);
}
RETURN_FALSE;
}
#else
- if ((strong_result = RAND_pseudo_bytes(buffer, buffer_length)) < 0) {
- efree(buffer);
+ if ((strong_result = RAND_pseudo_bytes((unsigned char*)buffer->val, buffer_length)) < 0) {
+ zend_string_release(buffer);
if (zstrong_result_returned) {
ZVAL_BOOL(zstrong_result_returned, 0);
}
@@ -5429,8 +5320,8 @@ PHP_FUNCTION(openssl_random_pseudo_bytes)
}
#endif
- buffer[buffer_length] = 0;
- RETVAL_STRINGL((char *)buffer, buffer_length, 0);
+ buffer->val[buffer_length] = 0;
+ RETVAL_STR(buffer);
if (zstrong_result_returned) {
ZVAL_BOOL(zstrong_result_returned, strong_result);
@@ -5446,3 +5337,4 @@ PHP_FUNCTION(openssl_random_pseudo_bytes)
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
+