summaryrefslogtreecommitdiff
path: root/ext/openssl
diff options
context:
space:
mode:
Diffstat (limited to 'ext/openssl')
-rw-r--r--ext/openssl/config0.m44
-rw-r--r--ext/openssl/openssl.c2440
-rw-r--r--ext/openssl/openssl.dsp111
-rw-r--r--ext/openssl/openssl.mak2
-rw-r--r--ext/openssl/php_openssl.h5
-rw-r--r--ext/openssl/tests/bug60632.phpt3
-rw-r--r--ext/openssl/tests/bug70438.phpt29
-rw-r--r--ext/openssl/tests/bug71475.phpt16
-rw-r--r--ext/openssl/tests/bug72165.phpt17
-rw-r--r--ext/openssl/tests/openssl_csr_sign_basic.phpt4
-rw-r--r--ext/openssl/tests/openssl_free_key.phpt77
-rw-r--r--ext/openssl/tests/openssl_pkcs7_decrypt_error.phpt1
-rw-r--r--ext/openssl/tests/openssl_x509_checkpurpose.phpt149
-rw-r--r--ext/openssl/tests/openssl_x509_export_basic.phpt4
-rw-r--r--ext/openssl/tests/session_meta_capture.phpt6
-rw-r--r--ext/openssl/xp_ssl.c1089
16 files changed, 2199 insertions, 1758 deletions
diff --git a/ext/openssl/config0.m4 b/ext/openssl/config0.m4
index a9484b4acc..01fc89b28d 100644
--- a/ext/openssl/config0.m4
+++ b/ext/openssl/config0.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(openssl, for OpenSSL support,
-[ --with-openssl[=DIR] Include OpenSSL support (requires OpenSSL >= 0.9.6)])
+[ --with-openssl[=DIR] Include OpenSSL support (requires OpenSSL >= 0.9.8)])
PHP_ARG_WITH(kerberos, for Kerberos support,
[ --with-kerberos[=DIR] OPENSSL: Include Kerberos support], no, no)
@@ -19,8 +19,6 @@ if test "$PHP_OPENSSL" != "no"; then
PHP_SETUP_KERBEROS(OPENSSL_SHARED_LIBADD)
fi
- AC_CHECK_LIB(ssl, DSA_get_default_method, AC_DEFINE(HAVE_DSA_DEFAULT_METHOD, 1, [OpenSSL 0.9.7 or later]))
- AC_CHECK_LIB(crypto, X509_free, AC_DEFINE(HAVE_DSA_DEFAULT_METHOD, 1, [OpenSSL 0.9.7 or later]))
AC_CHECK_FUNCS([RAND_egd])
PHP_SETUP_OPENSSL(OPENSSL_SHARED_LIBADD,
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index f8641c62fc..6bf1d6b25f 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 5 |
+ | PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2016 The PHP Group |
+----------------------------------------------------------------------+
@@ -16,7 +16,7 @@
| Wez Furlong <wez@thebrainroom.com> |
| Sascha Kettler <kettler@gmx.net> |
| Pierre-Alain Joye <pierre@php.net> |
- | Marc Delling <delling@silpion.de> (PKCS12 functions) |
+ | Marc Delling <delling@silpion.de> (PKCS12 functions) |
+----------------------------------------------------------------------+
*/
@@ -42,6 +42,10 @@
/* OpenSSL includes */
#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/dh.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/crypto.h>
@@ -55,7 +59,7 @@
/* Common */
#include <time.h>
-#ifdef NETWARE
+#if defined(NETWARE) || (defined(PHP_WIN32) && defined(_MSC_VER) && _MSC_VER >= 1900)
#define timezone _timezone /* timezone is called _timezone in LibC */
#endif
@@ -354,6 +358,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_seal, 0, 0, 4)
ZEND_ARG_INFO(1, ekeys) /* arary */
ZEND_ARG_INFO(0, pubkeys) /* array */
ZEND_ARG_INFO(0, method)
+ ZEND_ARG_INFO(1, iv)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_openssl_open, 0)
@@ -361,6 +366,7 @@ ZEND_BEGIN_ARG_INFO(arginfo_openssl_open, 0)
ZEND_ARG_INFO(1, opendata)
ZEND_ARG_INFO(0, ekey)
ZEND_ARG_INFO(0, privkey)
+ ZEND_ARG_INFO(0, iv)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_get_md_methods, 0, 0, 0)
@@ -455,7 +461,7 @@ const zend_function_entry openssl_functions[] = {
/* x.509 cert funcs */
PHP_FE(openssl_x509_read, arginfo_openssl_x509_read)
- PHP_FE(openssl_x509_free, arginfo_openssl_x509_free)
+ PHP_FE(openssl_x509_free, arginfo_openssl_x509_free)
PHP_FE(openssl_x509_parse, arginfo_openssl_x509_parse)
PHP_FE(openssl_x509_checkpurpose, arginfo_openssl_x509_checkpurpose)
PHP_FE(openssl_x509_check_private_key, arginfo_openssl_x509_check_private_key)
@@ -503,9 +509,9 @@ const zend_function_entry openssl_functions[] = {
PHP_FE(openssl_get_md_methods, arginfo_openssl_get_md_methods)
PHP_FE(openssl_get_cipher_methods, arginfo_openssl_get_cipher_methods)
- PHP_FE(openssl_dh_compute_key, arginfo_openssl_dh_compute_key)
+ PHP_FE(openssl_dh_compute_key, arginfo_openssl_dh_compute_key)
- PHP_FE(openssl_random_pseudo_bytes, arginfo_openssl_random_pseudo_bytes)
+ PHP_FE(openssl_random_pseudo_bytes, arginfo_openssl_random_pseudo_bytes)
PHP_FE(openssl_error_string, arginfo_openssl_error_string)
PHP_FE_END
};
@@ -522,7 +528,7 @@ zend_module_entry openssl_module_entry = {
NULL,
NULL,
PHP_MINFO(openssl),
- NO_VERSION_YET,
+ PHP_OPENSSL_VERSION,
STANDARD_MODULE_PROPERTIES
};
/* }}} */
@@ -531,6 +537,25 @@ zend_module_entry openssl_module_entry = {
ZEND_GET_MODULE(openssl)
#endif
+/* number conversion flags checks */
+#define PHP_OPENSSL_CHECK_NUMBER_CONVERSION(_cond, _name) \
+ do { \
+ if (_cond) { \
+ php_error_docref(NULL, E_WARNING, #_name" is too long"); \
+ RETURN_FALSE; \
+ } \
+ } while(0)
+/* check if size_t can be safely casted to int */
+#define PHP_OPENSSL_CHECK_SIZE_T_TO_INT(_var, _name) \
+ PHP_OPENSSL_CHECK_NUMBER_CONVERSION(ZEND_SIZE_T_INT_OVFL(_var), _name)
+/* check if size_t can be safely casted to unsigned int */
+#define PHP_OPENSSL_CHECK_SIZE_T_TO_UINT(_var, _name) \
+ PHP_OPENSSL_CHECK_NUMBER_CONVERSION(ZEND_SIZE_T_UINT_OVFL(_var), _name)
+/* check if long can be safely casted to int */
+#define PHP_OPENSSL_CHECK_LONG_TO_INT(_var, _name) \
+ PHP_OPENSSL_CHECK_NUMBER_CONVERSION(ZEND_LONG_EXCEEDS_INT(_var), _name)
+
+
static int le_key;
static int le_x509;
static int le_csr;
@@ -543,7 +568,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)
{
EVP_PKEY *pkey = (EVP_PKEY *)rsrc->ptr;
@@ -552,13 +577,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)
{
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)
{
X509_REQ * csr = (X509_REQ*)rsrc->ptr;
X509_REQ_free(csr);
@@ -566,12 +591,12 @@ static void php_csr_free(zend_rsrc_list_entry *rsrc TSRMLS_DC)
/* }}} */
/* {{{ openssl open_basedir check */
-inline static int php_openssl_open_base_dir_chk(char *filename TSRMLS_DC)
+inline static int php_openssl_open_base_dir_chk(char *filename)
{
- if (php_check_open_basedir(filename TSRMLS_CC)) {
+ if (php_check_open_basedir(filename)) {
return -1;
}
-
+
return 0;
}
/* }}} */
@@ -595,8 +620,8 @@ struct php_x509_request { /* {{{ */
LHASH_OF(CONF_VALUE) * global_config; /* Global SSL config */
LHASH_OF(CONF_VALUE) * req_config; /* SSL config for this request */
#else
- LHASH * global_config; /* Global SSL config */
- LHASH * req_config; /* SSL config for this request */
+ LHASH * global_config; /* Global SSL config */
+ LHASH * req_config; /* SSL config for this request */
#endif
const EVP_MD * md_alg;
const EVP_MD * digest;
@@ -612,22 +637,22 @@ struct php_x509_request { /* {{{ */
EVP_PKEY * priv_key;
- const EVP_CIPHER * priv_key_encrypt_cipher;
+ const EVP_CIPHER * priv_key_encrypt_cipher;
};
/* }}} */
-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 int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC);
-static X509_STORE * setup_verify(zval * calist TSRMLS_DC);
+static X509 * php_openssl_x509_from_zval(zval * val, int makeresource, zend_resource **resourceval);
+static EVP_PKEY * php_openssl_evp_from_zval(zval * val, int public_key, char * passphrase, int makeresource, zend_resource **resourceval);
+static int php_openssl_is_private_key(EVP_PKEY* pkey);
+static X509_STORE * setup_verify(zval * calist);
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 EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req TSRMLS_DC);
+static X509_REQ * php_openssl_csr_from_zval(zval * val, int makeresource, zend_resource ** resourceval);
+static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req);
-static void add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int shortname TSRMLS_DC) /* {{{ */
+static void add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int shortname) /* {{{ */
{
- zval **data;
- zval *subitem, *subentries;
+ zval *data;
+ zval subitem, tmp;
int i;
char *sname;
int nid;
@@ -636,18 +661,17 @@ 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++) {
unsigned char *to_add;
int to_add_len = 0;
- ne = X509_NAME_get_entry(name, i);
+ ne = X509_NAME_get_entry(name, i);
obj = X509_NAME_ENTRY_get_object(ne);
nid = OBJ_obj2nid(obj);
@@ -666,35 +690,33 @@ 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(Z_ARRVAL_P(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);
}
/* }}} */
-static time_t asn1_time_to_time_t(ASN1_UTCTIME * timestr TSRMLS_DC) /* {{{ */
+static time_t asn1_time_to_time_t(ASN1_UTCTIME * timestr) /* {{{ */
{
/*
This is how the time string is formatted:
@@ -710,22 +732,22 @@ static time_t asn1_time_to_time_t(ASN1_UTCTIME * timestr TSRMLS_DC) /* {{{ */
long gmadjust = 0;
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");
+ php_error_docref(NULL, 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");
+ php_error_docref(NULL, E_WARNING, "illegal length in timestamp");
return (time_t)-1;
}
if (ASN1_STRING_length(timestr) < 13) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to parse time string %s correctly", timestr->data);
+ php_error_docref(NULL, 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);
+ php_error_docref(NULL, E_WARNING, "unable to parse time string %s correctly", timestr->data);
return (time_t)-1;
}
@@ -787,17 +809,17 @@ static time_t asn1_time_to_time_t(ASN1_UTCTIME * timestr TSRMLS_DC) /* {{{ */
/* }}} */
#if OPENSSL_VERSION_NUMBER >= 0x10000002L
-static inline int php_openssl_config_check_syntax(const char * section_label, const char * config_filename, const char * section, LHASH_OF(CONF_VALUE) * config TSRMLS_DC) /* {{{ */
+static inline int php_openssl_config_check_syntax(const char * section_label, const char * config_filename, const char * section, LHASH_OF(CONF_VALUE) * config) /* {{{ */
#else
-static inline int php_openssl_config_check_syntax(const char * section_label, const char * config_filename, const char * section, LHASH * config TSRMLS_DC)
+static inline int php_openssl_config_check_syntax(const char * section_label, const char * config_filename, const char * section, LHASH * config)
#endif
{
X509V3_CTX ctx;
-
+
X509V3_set_ctx_test(&ctx);
X509V3_set_conf_lhash(&ctx, config);
if (!X509V3_EXT_add_conf(config, &ctx, (char *)section, NULL)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error loading %s section %s of %s",
+ php_error_docref(NULL, E_WARNING, "Error loading %s section %s of %s",
section_label,
section,
config_filename);
@@ -807,7 +829,7 @@ static inline int php_openssl_config_check_syntax(const char * section_label, co
}
/* }}} */
-static int add_oid_section(struct php_x509_request * req TSRMLS_DC) /* {{{ */
+static int add_oid_section(struct php_x509_request * req) /* {{{ */
{
char * str;
STACK_OF(CONF_VALUE) * sktmp;
@@ -820,13 +842,13 @@ static int add_oid_section(struct php_x509_request * req TSRMLS_DC) /* {{{ */
}
sktmp = CONF_get_section(req->req_config, str);
if (sktmp == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "problem loading oid section %s", str);
+ php_error_docref(NULL, E_WARNING, "problem loading oid section %s", str);
return FAILURE;
}
for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
cnf = sk_CONF_VALUE_value(sktmp, i);
if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "problem creating object %s=%s", cnf->name, cnf->value);
+ php_error_docref(NULL, E_WARNING, "problem creating object %s=%s", cnf->name, cnf->value);
return FAILURE;
}
}
@@ -835,32 +857,49 @@ static int add_oid_section(struct php_x509_request * req TSRMLS_DC) /* {{{ */
/* }}} */
#define PHP_SSL_REQ_INIT(req) memset(req, 0, sizeof(*req))
-#define PHP_SSL_REQ_DISPOSE(req) php_openssl_dispose_config(req TSRMLS_CC)
-#define PHP_SSL_REQ_PARSE(req, zval) php_openssl_parse_config(req, zval TSRMLS_CC)
+#define PHP_SSL_REQ_DISPOSE(req) php_openssl_dispose_config(req)
+#define PHP_SSL_REQ_PARSE(req, zval) php_openssl_parse_config(req, zval)
#define PHP_SSL_CONFIG_SYNTAX_CHECK(var) if (req->var && php_openssl_config_check_syntax(#var, \
- req->config_filename, req->var, req->req_config TSRMLS_CC) == FAILURE) return FAILURE
+ req->config_filename, req->var, req->req_config) == 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 && Z_TYPE_PP(item) == IS_STRING) \
- 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 && Z_TYPE_PP(item) == IS_LONG) \
- 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 = (int)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);
+
+/* {{{ strip line endings from spkac */
+static int openssl_spki_cleanup(const char *src, char *dest)
+{
+ int removed = 0;
+
+ while (*src) {
+ if (*src != '\n' && *src != '\r') {
+ *dest++ = *src;
+ } else {
+ ++removed;
+ }
+ ++src;
+ }
+ *dest = 0;
+ return removed;
+}
+/* }}} */
-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) /* {{{ */
+static int php_openssl_parse_config(struct php_x509_request * req, zval * optional_args) /* {{{ */
{
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");
@@ -873,14 +912,14 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
/* read in the oids */
str = CONF_get_string(req->req_config, NULL, "oid_file");
- if (str && !php_openssl_open_base_dir_chk(str TSRMLS_CC)) {
+ if (str && !php_openssl_open_base_dir_chk(str)) {
BIO *oid_bio = BIO_new_file(str, "r");
if (oid_bio) {
OBJ_create_objects(oid_bio);
BIO_free(oid_bio);
}
}
- if (add_oid_section(req TSRMLS_CC) == FAILURE) {
+ if (add_oid_section(req) == FAILURE) {
return FAILURE;
}
SET_OPTIONAL_STRING_ARG("digest_alg", req->digest_name,
@@ -894,8 +933,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) {
@@ -908,14 +947,14 @@ 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
- && Z_TYPE_PP(item) == IS_LONG) {
- 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.");
+ php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm for private key.");
return FAILURE;
- } else {
+ } else {
req->priv_key_encrypt_cipher = cipher;
}
} else {
@@ -923,7 +962,7 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
}
-
+
/* digest alg */
if (req->digest_name == NULL) {
req->digest_name = CONF_get_string(req->req_config, req->section_name, "default_md");
@@ -940,17 +979,17 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
/* set the string mask */
str = CONF_get_string(req->req_config, req->section_name, "string_mask");
if (str && !ASN1_STRING_set_default_mask_asc(str)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid global string mask setting %s", str);
+ php_error_docref(NULL, E_WARNING, "Invalid global string mask setting %s", str);
return FAILURE;
}
PHP_SSL_CONFIG_SYNTAX_CHECK(request_extensions_section);
-
+
return SUCCESS;
}
/* }}} */
-static void php_openssl_dispose_config(struct php_x509_request * req TSRMLS_DC) /* {{{ */
+static void php_openssl_dispose_config(struct php_x509_request * req) /* {{{ */
{
if (req->priv_key) {
EVP_PKEY_free(req->priv_key);
@@ -983,7 +1022,7 @@ static inline void php_openssl_rand_add_timeval() /* {{{ */
#endif
-static int php_openssl_load_rand_file(const char * file, int *egdsocket, int *seeded TSRMLS_DC) /* {{{ */
+static int php_openssl_load_rand_file(const char * file, int *egdsocket, int *seeded) /* {{{ */
{
char buffer[MAXPATHLEN];
@@ -1002,7 +1041,7 @@ static int php_openssl_load_rand_file(const char * file, int *egdsocket, int *se
}
if (file == NULL || !RAND_load_file(file, -1)) {
if (RAND_status() == 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to load random state; not enough random data!");
+ php_error_docref(NULL, E_WARNING, "unable to load random state; not enough random data!");
return FAILURE;
}
return FAILURE;
@@ -1016,7 +1055,6 @@ static int php_openssl_write_rand_file(const char * file, int egdsocket, int see
{
char buffer[MAXPATHLEN];
- TSRMLS_FETCH();
if (egdsocket || !seeded) {
/* if we did not manage to read the seed file, we should not write
@@ -1028,14 +1066,14 @@ static int php_openssl_write_rand_file(const char * file, int egdsocket, int see
}
PHP_OPENSSL_RAND_ADD_TIME();
if (file == NULL || !RAND_write_file(file)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to write random state");
+ php_error_docref(NULL, E_WARNING, "unable to write random state");
return FAILURE;
}
return SUCCESS;
}
/* }}} */
-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) {
@@ -1081,7 +1119,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:
@@ -1130,7 +1168,7 @@ PHP_INI_BEGIN()
PHP_INI_ENTRY("openssl.capath", NULL, PHP_INI_PERDIR, NULL)
PHP_INI_END()
/* }}} */
-
+
/* {{{ PHP_MINIT_FUNCTION
*/
PHP_MINIT_FUNCTION(openssl)
@@ -1151,10 +1189,10 @@ PHP_MINIT_FUNCTION(openssl)
/* register a resource id number with OpenSSL so that we can map SSL -> stream structures in
* OpenSSL callbacks */
ssl_stream_data_index = SSL_get_ex_new_index(0, "PHP stream index", NULL, NULL, NULL);
-
+
REGISTER_STRING_CONSTANT("OPENSSL_VERSION_TEXT", OPENSSL_VERSION_TEXT, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_VERSION_NUMBER", OPENSSL_VERSION_NUMBER, CONST_CS|CONST_PERSISTENT);
-
+
/* purposes for cert purpose checking */
REGISTER_LONG_CONSTANT("X509_PURPOSE_SSL_CLIENT", X509_PURPOSE_SSL_CLIENT, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("X509_PURPOSE_SSL_SERVER", X509_PURPOSE_SSL_SERVER, CONST_CS|CONST_PERSISTENT);
@@ -1216,7 +1254,7 @@ PHP_MINIT_FUNCTION(openssl)
REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_AES_192_CBC", PHP_OPENSSL_CIPHER_AES_192_CBC, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_AES_256_CBC", PHP_OPENSSL_CIPHER_AES_256_CBC, CONST_CS|CONST_PERSISTENT);
#endif
-
+
/* Values for key types */
REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_RSA", OPENSSL_KEYTYPE_RSA, CONST_CS|CONST_PERSISTENT);
#ifndef NO_DSA
@@ -1250,23 +1288,25 @@ PHP_MINIT_FUNCTION(openssl)
strlcpy(default_ssl_conf_filename, config_filename, sizeof(default_ssl_conf_filename));
}
- php_stream_xport_register("ssl", php_openssl_ssl_socket_factory TSRMLS_CC);
- php_stream_xport_register("sslv3", php_openssl_ssl_socket_factory TSRMLS_CC);
+ php_stream_xport_register("ssl", php_openssl_ssl_socket_factory);
+#ifndef OPENSSL_NO_SSL3
+ php_stream_xport_register("sslv3", php_openssl_ssl_socket_factory);
+#endif
#ifndef OPENSSL_NO_SSL2
- php_stream_xport_register("sslv2", php_openssl_ssl_socket_factory TSRMLS_CC);
+ php_stream_xport_register("sslv2", php_openssl_ssl_socket_factory);
#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);
+ php_stream_xport_register("tls", php_openssl_ssl_socket_factory);
+ php_stream_xport_register("tlsv1.0", php_openssl_ssl_socket_factory);
#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);
+ php_stream_xport_register("tlsv1.1", php_openssl_ssl_socket_factory);
+ php_stream_xport_register("tlsv1.2", php_openssl_ssl_socket_factory);
#endif
/* override the default tcp socket provider */
- php_stream_xport_register("tcp", php_openssl_ssl_socket_factory TSRMLS_CC);
+ php_stream_xport_register("tcp", php_openssl_ssl_socket_factory);
- php_register_url_stream_wrapper("https", &php_stream_http_wrapper TSRMLS_CC);
- php_register_url_stream_wrapper("ftps", &php_stream_ftp_wrapper TSRMLS_CC);
+ php_register_url_stream_wrapper("https", &php_stream_http_wrapper);
+ php_register_url_stream_wrapper("ftps", &php_stream_ftp_wrapper);
REGISTER_INI_ENTRIES();
@@ -1301,23 +1341,25 @@ PHP_MSHUTDOWN_FUNCTION(openssl)
ERR_free_strings();
#endif
- php_unregister_url_stream_wrapper("https" TSRMLS_CC);
- php_unregister_url_stream_wrapper("ftps" TSRMLS_CC);
+ php_unregister_url_stream_wrapper("https");
+ php_unregister_url_stream_wrapper("ftps");
- php_stream_xport_unregister("ssl" TSRMLS_CC);
+ php_stream_xport_unregister("ssl");
#ifndef OPENSSL_NO_SSL2
- php_stream_xport_unregister("sslv2" TSRMLS_CC);
+ php_stream_xport_unregister("sslv2");
#endif
- php_stream_xport_unregister("sslv3" TSRMLS_CC);
- php_stream_xport_unregister("tls" TSRMLS_CC);
- php_stream_xport_unregister("tlsv1.0" TSRMLS_CC);
+#ifndef OPENSSL_NO_SSL3
+ php_stream_xport_unregister("sslv3");
+#endif
+ php_stream_xport_unregister("tls");
+ php_stream_xport_unregister("tlsv1.0");
#if OPENSSL_VERSION_NUMBER >= 0x10001001L
- php_stream_xport_unregister("tlsv1.1" TSRMLS_CC);
- php_stream_xport_unregister("tlsv1.2" TSRMLS_CC);
+ php_stream_xport_unregister("tlsv1.1");
+ php_stream_xport_unregister("tlsv1.2");
#endif
/* reinstate the default tcp handler */
- php_stream_xport_register("tcp", php_stream_generic_socket_factory TSRMLS_CC);
+ php_stream_xport_register("tcp", php_stream_generic_socket_factory);
UNREGISTER_INI_ENTRIES();
@@ -1333,16 +1375,16 @@ PHP_FUNCTION(openssl_get_cert_locations)
{
array_init(return_value);
- add_assoc_string(return_value, "default_cert_file", (char *) X509_get_default_cert_file(), 1);
- add_assoc_string(return_value, "default_cert_file_env", (char *) X509_get_default_cert_file_env(), 1);
- add_assoc_string(return_value, "default_cert_dir", (char *) X509_get_default_cert_dir(), 1);
- add_assoc_string(return_value, "default_cert_dir_env", (char *) X509_get_default_cert_dir_env(), 1);
- add_assoc_string(return_value, "default_private_dir", (char *) X509_get_default_private_dir(), 1);
- add_assoc_string(return_value, "default_default_cert_area", (char *) X509_get_default_cert_area(), 1);
+ 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"), 0), 1);
+ 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"), 0), 1);
+ zend_ini_string("openssl.capath", sizeof("openssl.capath")-1, 0));
}
/* }}} */
@@ -1356,50 +1398,46 @@ PHP_FUNCTION(openssl_get_cert_locations)
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)
{
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;
+ zend_resource *res = Z_RES_P(val);
- what = zend_fetch_resource(val TSRMLS_CC, -1, "OpenSSL X.509", &type, 1, le_x509);
+ what = zend_fetch_resource(res, "OpenSSL X.509", le_x509);
if (!what) {
return NULL;
}
/* this is so callers can decide if they should free the X509 */
if (resourceval) {
- *resourceval = Z_LVAL_PP(val);
- }
- if (type == le_x509) {
- return (X509*)what;
+ *resourceval = res;
+ Z_ADDREF_P(val);
}
- /* other types could be used here - eg: file pointers and read in the data from them */
-
- return NULL;
+ return (X509*)what;
}
- 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))) {
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;
}
@@ -1408,7 +1446,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), (int)Z_STRLEN_P(val));
if (in == NULL) {
return NULL;
}
@@ -1421,7 +1459,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(cert, le_x509);
}
return cert;
}
@@ -1433,25 +1471,25 @@ 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(), "zp|b", &zcert, &filename, &filename_len, &notext) == FAILURE) {
return;
}
RETVAL_FALSE;
- cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
+ cert = php_openssl_x509_from_zval(zcert, 0, &certresource);
if (cert == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
+ php_error_docref(NULL, E_WARNING, "cannot get cert from parameter 1");
return;
}
- if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
+ if (php_openssl_open_base_dir_chk(filename)) {
return;
}
@@ -1464,9 +1502,9 @@ PHP_FUNCTION(openssl_x509_export_to_file)
RETVAL_TRUE;
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "error opening file %s", filename);
+ php_error_docref(NULL, E_WARNING, "error opening file %s", filename);
}
- if (certresource == -1 && cert) {
+ if (certresource == NULL && cert) {
X509_free(cert);
}
BIO_free(bio_out);
@@ -1478,11 +1516,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;
@@ -1490,15 +1529,15 @@ PHP_FUNCTION(openssl_spki_new)
NETSCAPE_SPKI *spki=NULL;
const EVP_MD *mdtype;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|z", &zpkey, &challenge, &challenge_len, &method) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|z", &zpkey, &challenge, &challenge_len, &method) == FAILURE) {
return;
}
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);
if (pkey == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to use supplied private key");
+ php_error_docref(NULL, E_WARNING, "Unable to use supplied private key");
goto cleanup;
}
@@ -1506,66 +1545,70 @@ PHP_FUNCTION(openssl_spki_new)
if (Z_TYPE_P(method) == IS_LONG) {
algo = Z_LVAL_P(method);
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Algorithm must be of supported type");
+ php_error_docref(NULL, E_WARNING, "Algorithm must be of supported type");
goto cleanup;
}
}
mdtype = php_openssl_get_evp_md_from_algo(algo);
if (!mdtype) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature algorithm");
+ php_error_docref(NULL, E_WARNING, "Unknown signature algorithm");
goto cleanup;
}
if ((spki = NETSCAPE_SPKI_new()) == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create new SPKAC");
+ php_error_docref(NULL, E_WARNING, "Unable to create new SPKAC");
goto cleanup;
}
if (challenge) {
- ASN1_STRING_set(spki->spkac->challenge, challenge, challenge_len);
+ if (!ASN1_STRING_set(spki->spkac->challenge, challenge, (int)challenge_len)) {
+ php_error_docref(NULL, E_WARNING, "Unable to set challenge data");
+ goto cleanup;
+ }
}
if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to embed public key");
+ php_error_docref(NULL, E_WARNING, "Unable to embed public key");
goto cleanup;
}
if (!NETSCAPE_SPKI_sign(spki, pkey, mdtype)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to sign with specified algorithm");
+ php_error_docref(NULL, E_WARNING, "Unable to sign with specified algorithm");
goto cleanup;
}
spkstr = NETSCAPE_SPKI_b64_encode(spki);
if (!spkstr){
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to encode SPKAC");
+ php_error_docref(NULL, E_WARNING, "Unable to encode SPKAC");
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(ZSTR_VAL(s), "%s%s", spkac, spkstr);
+ ZSTR_LEN(s) = strlen(ZSTR_VAL(s));
- 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 (s && strlen(s) <= 0) {
+ if (s && ZSTR_LEN(s) <= 0) {
RETVAL_FALSE;
}
- if (keyresource == -1 && s != NULL) {
- efree(s);
+ if (keyresource == NULL && s != NULL) {
+ zend_string_release(s);
}
}
/* }}} */
@@ -1574,39 +1617,40 @@ cleanup:
Verifies spki returns boolean */
PHP_FUNCTION(openssl_spki_verify)
{
- int spkstr_len, i = 0;
+ size_t spkstr_len;
+ int i = 0, spkstr_cleaned_len = 0;
char *spkstr = NULL, * spkstr_cleaned = NULL;
EVP_PKEY *pkey = NULL;
NETSCAPE_SPKI *spki = NULL;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &spkstr, &spkstr_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &spkstr, &spkstr_len) == FAILURE) {
return;
}
RETVAL_FALSE;
if (spkstr == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to use supplied SPKAC");
+ php_error_docref(NULL, E_WARNING, "Unable to use supplied SPKAC");
goto cleanup;
}
spkstr_cleaned = emalloc(spkstr_len + 1);
- openssl_spki_cleanup(spkstr, spkstr_cleaned);
+ spkstr_cleaned_len = (int)(spkstr_len - openssl_spki_cleanup(spkstr, spkstr_cleaned));
- if (strlen(spkstr_cleaned)<=0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid SPKAC");
+ if (spkstr_cleaned_len == 0) {
+ php_error_docref(NULL, E_WARNING, "Invalid SPKAC");
goto cleanup;
}
- spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned));
+ spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, spkstr_cleaned_len);
if (spki == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to decode supplied SPKAC");
+ php_error_docref(NULL, E_WARNING, "Unable to decode supplied SPKAC");
goto cleanup;
}
pkey = X509_PUBKEY_get(spki->spkac->pubkey);
if (pkey == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to acquire signed public key");
+ php_error_docref(NULL, E_WARNING, "Unable to acquire signed public key");
goto cleanup;
}
@@ -1634,44 +1678,50 @@ 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;
+ int spkstr_cleaned_len;
EVP_PKEY *pkey = NULL;
NETSCAPE_SPKI *spki = NULL;
BIO *out = NULL;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &spkstr, &spkstr_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &spkstr, &spkstr_len) == FAILURE) {
return;
}
RETVAL_FALSE;
if (spkstr == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to use supplied SPKAC");
+ php_error_docref(NULL, E_WARNING, "Unable to use supplied SPKAC");
goto cleanup;
}
spkstr_cleaned = emalloc(spkstr_len + 1);
- openssl_spki_cleanup(spkstr, spkstr_cleaned);
+ spkstr_cleaned_len = (int)(spkstr_len - openssl_spki_cleanup(spkstr, spkstr_cleaned));
- spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned));
+ if (spkstr_cleaned_len == 0) {
+ php_error_docref(NULL, E_WARNING, "Invalid SPKAC");
+ goto cleanup;
+ }
+
+ spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, spkstr_cleaned_len);
if (spki == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to decode supplied SPKAC");
+ php_error_docref(NULL, E_WARNING, "Unable to decode supplied SPKAC");
goto cleanup;
}
pkey = X509_PUBKEY_get(spki->spkac->pubkey);
if (pkey == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to acquire signed public key");
+ php_error_docref(NULL, E_WARNING, "Unable to acquire signed public key");
goto cleanup;
}
out = BIO_new(BIO_s_mem());
- if (out && PEM_write_bio_PUBKEY(out, pkey)) {
+ if (out && PEM_write_bio_PUBKEY(out, pkey)) {
BUF_MEM *bio_buf;
BIO_get_mem_ptr(out, &bio_buf);
- RETVAL_STRINGL((char *)bio_buf->data, bio_buf->length, 1);
+ RETVAL_STRINGL((char *)bio_buf->data, bio_buf->length);
}
goto cleanup;
@@ -1699,31 +1749,37 @@ 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;
+ int spkstr_cleaned_len;
NETSCAPE_SPKI *spki = NULL;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &spkstr, &spkstr_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &spkstr, &spkstr_len) == FAILURE) {
return;
}
RETVAL_FALSE;
if (spkstr == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to use supplied SPKAC");
+ php_error_docref(NULL, E_WARNING, "Unable to use supplied SPKAC");
goto cleanup;
}
spkstr_cleaned = emalloc(spkstr_len + 1);
- openssl_spki_cleanup(spkstr, spkstr_cleaned);
+ spkstr_cleaned_len = (int)(spkstr_len - openssl_spki_cleanup(spkstr, spkstr_cleaned));
+
+ if (spkstr_cleaned_len == 0) {
+ php_error_docref(NULL, E_WARNING, "Invalid SPKAC");
+ goto cleanup;
+ }
- spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned));
+ spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, spkstr_cleaned_len);
if (spki == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to decode SPKAC");
+ php_error_docref(NULL, E_WARNING, "Unable to decode SPKAC");
goto cleanup;
}
- RETVAL_STRING((char *) ASN1_STRING_data(spki->spkac->challenge), 1);
+ RETVAL_STRING((char *) ASN1_STRING_data(spki->spkac->challenge));
goto cleanup;
cleanup:
@@ -1733,42 +1789,24 @@ cleanup:
}
/* }}} */
-/* {{{ strip line endings from spkac */
-int openssl_spki_cleanup(const char *src, char *dest)
-{
- int removed=0;
-
- while (*src) {
- if (*src!='\n'&&*src!='\r') {
- *dest++=*src;
- } else {
- ++removed;
- }
- ++src;
- }
- *dest=0;
- return removed;
-}
-/* }}} */
-
/* {{{ proto bool openssl_x509_export(mixed x509, string &out [, bool notext = true])
Exports a CERT to file or a var */
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(), "zz/|b", &zcert, &zout, &notext) == FAILURE) {
return;
}
RETVAL_FALSE;
- cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
+ cert = php_openssl_x509_from_zval(zcert, 0, &certresource);
if (cert == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
+ php_error_docref(NULL, E_WARNING, "cannot get cert from parameter 1");
return;
}
@@ -1776,79 +1814,77 @@ PHP_FUNCTION(openssl_x509_export)
if (!notext) {
X509_print(bio_out, cert);
}
- if (PEM_write_bio_X509(bio_out, cert)) {
+ if (PEM_write_bio_X509(bio_out, cert)) {
BUF_MEM *bio_buf;
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);
}
/* }}} */
-int php_openssl_x509_fingerprint(X509 *peer, const char *method, zend_bool raw, char **out, int *out_len TSRMLS_DC)
+zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, zend_bool raw)
{
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 FAILURE;
+ php_error_docref(NULL, 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 FAILURE;
+ php_error_docref(NULL, E_ERROR, "Could not generate signature");
+ return NULL;
}
if (raw) {
- *out_len = n;
- *out = estrndup((char *) md, n);
+ ret = zend_string_init((char*)md, n, 0);
} else {
- *out_len = n * 2;
- *out = emalloc(*out_len + 1);
-
- make_digest_ex(*out, md, n);
+ ret = zend_string_alloc(n * 2, 0);
+ make_digest_ex(ZSTR_VAL(ret), md, n);
+ ZSTR_VAL(ret)[n * 2] = '\0';
}
- return SUCCESS;
+ return ret;
}
PHP_FUNCTION(openssl_x509_fingerprint)
{
X509 *cert;
- zval **zcert;
- long certresource;
+ zval *zcert;
+ zend_resource *certresource;
zend_bool raw_output = 0;
char *method = "sha1";
- int method_len;
-
- char *fingerprint;
- int fingerprint_len;
+ 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) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|sb", &zcert, &method, &method_len, &raw_output) == FAILURE) {
return;
}
- cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
+ cert = php_openssl_x509_from_zval(zcert, 0, &certresource);
if (cert == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
+ php_error_docref(NULL, E_WARNING, "cannot get cert from parameter 1");
RETURN_FALSE;
}
- if (php_openssl_x509_fingerprint(cert, method, raw_output, &fingerprint, &fingerprint_len TSRMLS_CC) == SUCCESS) {
- RETVAL_STRINGL(fingerprint, fingerprint_len, 0);
+ fingerprint = php_openssl_x509_fingerprint(cert, method, raw_output);
+ if (fingerprint) {
+ RETVAL_STR(fingerprint);
} else {
RETVAL_FALSE;
}
- if (certresource == -1 && cert) {
+ if (certresource == NULL && cert) {
X509_free(cert);
}
}
@@ -1857,29 +1893,29 @@ PHP_FUNCTION(openssl_x509_fingerprint)
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(), "zz", &zcert, &zkey) == FAILURE) {
return;
}
- cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
+ cert = php_openssl_x509_from_zval(zcert, 0, &certresource);
if (cert == NULL) {
RETURN_FALSE;
- }
- key = php_openssl_evp_from_zval(zkey, 0, "", 1, &keyresource TSRMLS_CC);
+ }
+ key = php_openssl_evp_from_zval(zkey, 0, "", 1, &keyresource);
if (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);
}
}
@@ -1904,10 +1940,10 @@ static int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension)
p = extension->value->data;
length = extension->value->length;
if (method->it) {
- names = (GENERAL_NAMES*)(ASN1_item_d2i(NULL, &p, length,
- ASN1_ITEM_ptr(method->it)));
+ names = (GENERAL_NAMES*) (ASN1_item_d2i(NULL, &p, length,
+ ASN1_ITEM_ptr(method->it)));
} else {
- names = (GENERAL_NAMES*)(method->d2i(NULL, &p, length));
+ names = (GENERAL_NAMES*) (method->d2i(NULL, &p, length));
}
if (names == NULL) {
return -1;
@@ -1915,33 +1951,33 @@ static int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension)
num = sk_GENERAL_NAME_num(names);
for (i = 0; i < num; i++) {
- GENERAL_NAME *name;
- ASN1_STRING *as;
- name = sk_GENERAL_NAME_value(names, i);
- switch (name->type) {
- case GEN_EMAIL:
- BIO_puts(bio, "email:");
- as = name->d.rfc822Name;
- BIO_write(bio, ASN1_STRING_data(as),
- ASN1_STRING_length(as));
- break;
- case GEN_DNS:
- BIO_puts(bio, "DNS:");
- as = name->d.dNSName;
- BIO_write(bio, ASN1_STRING_data(as),
- ASN1_STRING_length(as));
- break;
- case GEN_URI:
- BIO_puts(bio, "URI:");
- as = name->d.uniformResourceIdentifier;
- BIO_write(bio, ASN1_STRING_data(as),
- ASN1_STRING_length(as));
- break;
- default:
- /* use builtin print for GEN_OTHERNAME, GEN_X400,
- * GEN_EDIPARTY, GEN_DIRNAME, GEN_IPADD and GEN_RID
- */
- GENERAL_NAME_print(bio, name);
+ GENERAL_NAME *name;
+ ASN1_STRING *as;
+ name = sk_GENERAL_NAME_value(names, i);
+ switch (name->type) {
+ case GEN_EMAIL:
+ BIO_puts(bio, "email:");
+ as = name->d.rfc822Name;
+ BIO_write(bio, ASN1_STRING_data(as),
+ ASN1_STRING_length(as));
+ break;
+ case GEN_DNS:
+ BIO_puts(bio, "DNS:");
+ as = name->d.dNSName;
+ BIO_write(bio, ASN1_STRING_data(as),
+ ASN1_STRING_length(as));
+ break;
+ case GEN_URI:
+ BIO_puts(bio, "URI:");
+ as = name->d.uniformResourceIdentifier;
+ BIO_write(bio, ASN1_STRING_data(as),
+ ASN1_STRING_length(as));
+ break;
+ default:
+ /* use builtin print for GEN_OTHERNAME, GEN_X400,
+ * GEN_EDIPARTY, GEN_DIRNAME, GEN_IPADD and GEN_RID
+ */
+ GENERAL_NAME_print(bio, name);
}
/* trailing ', ' except for last element */
if (i < (num - 1)) {
@@ -1957,64 +1993,62 @@ 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, sig_nid;
zend_bool useshortnames = 1;
char * tmpstr;
- zval * subitem;
+ zval subitem;
X509_EXTENSION *extension;
char *extname;
- BIO *bio_out;
+ 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(), "z|b", &zcert, &useshortnames) == FAILURE) {
return;
}
- cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
+ cert = php_openssl_x509_from_zval(zcert, 0, &certresource);
if (cert == NULL) {
RETURN_FALSE;
}
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); */
- add_assoc_name_entry(return_value, "subject", X509_get_subject_name(cert), useshortnames TSRMLS_CC);
+ add_assoc_name_entry(return_value, "subject", X509_get_subject_name(cert), useshortnames);
/* hash as used in CA directories to lookup cert by subject name */
{
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_name_entry(return_value, "issuer", X509_get_issuer_name(cert), useshortnames);
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));
- add_assoc_long(return_value, "validFrom_time_t", asn1_time_to_time_t(X509_get_notBefore(cert) TSRMLS_CC));
- add_assoc_long(return_value, "validTo_time_t", asn1_time_to_time_t(X509_get_notAfter(cert) TSRMLS_CC));
+ add_assoc_long(return_value, "validFrom_time_t", asn1_time_to_time_t(X509_get_notBefore(cert)));
+ add_assoc_long(return_value, "validTo_time_t", asn1_time_to_time_t(X509_get_notAfter(cert)));
tmpstr = (char *)X509_alias_get0(cert, NULL);
if (tmpstr) {
- add_assoc_string(return_value, "alias", tmpstr, 1);
+ add_assoc_string(return_value, "alias", tmpstr);
}
sig_nid = OBJ_obj2nid((cert)->sig_alg->algorithm);
- add_assoc_string(return_value, "signatureTypeSN", (char*)OBJ_nid2sn(sig_nid), 1);
- add_assoc_string(return_value, "signatureTypeLN", (char*)OBJ_nid2ln(sig_nid), 1);
+ add_assoc_string(return_value, "signatureTypeSN", (char*)OBJ_nid2sn(sig_nid));
+ add_assoc_string(return_value, "signatureTypeLN", (char*)OBJ_nid2ln(sig_nid));
add_assoc_long(return_value, "signatureTypeNID", sig_nid);
-
- 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 */
@@ -2022,31 +2056,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++) {
@@ -2063,10 +2095,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);
@@ -2075,15 +2107,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);
}
}
@@ -2096,27 +2128,26 @@ static STACK_OF(X509) * load_all_certs_from_file(char *certfile)
STACK_OF(X509) *stack=NULL, *ret=NULL;
BIO *in=NULL;
X509_INFO *xi;
- TSRMLS_FETCH();
if(!(stack = sk_X509_new_null())) {
- php_error_docref(NULL TSRMLS_CC, E_ERROR, "memory allocation failure");
+ php_error_docref(NULL, E_ERROR, "memory allocation failure");
goto end;
}
- if (php_openssl_open_base_dir_chk(certfile TSRMLS_CC)) {
+ if (php_openssl_open_base_dir_chk(certfile)) {
sk_X509_free(stack);
goto end;
}
if(!(in=BIO_new_file(certfile, "r"))) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "error opening the file, %s", certfile);
+ php_error_docref(NULL, E_WARNING, "error opening the file, %s", certfile);
sk_X509_free(stack);
goto end;
}
/* This loads from a file, a stack of x509/crl/pkey sets */
if(!(sk=PEM_X509_INFO_read_bio(in, NULL, NULL, NULL))) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "error reading the file, %s", certfile);
+ php_error_docref(NULL, E_WARNING, "error reading the file, %s", certfile);
sk_X509_free(stack);
goto end;
}
@@ -2131,7 +2162,7 @@ static STACK_OF(X509) * load_all_certs_from_file(char *certfile)
X509_INFO_free(xi);
}
if(!sk_X509_num(stack)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "no certificates in file, %s", certfile);
+ php_error_docref(NULL, E_WARNING, "no certificates in file, %s", certfile);
sk_X509_free(stack);
goto end;
}
@@ -2149,11 +2180,10 @@ static int check_cert(X509_STORE *ctx, X509 *x, STACK_OF(X509) *untrustedchain,
{
int ret=0;
X509_STORE_CTX *csc;
- TSRMLS_FETCH();
csc = X509_STORE_CTX_new();
if (csc == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_ERROR, "memory allocation failure");
+ php_error_docref(NULL, E_ERROR, "memory allocation failure");
return 0;
}
X509_STORE_CTX_init(csc, ctx, x, untrustedchain);
@@ -2171,16 +2201,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(), "zl|a!s", &zcert, &purpose, &zcainfo, &untrusted, &untrusted_len) == FAILURE) {
return;
}
@@ -2193,16 +2224,16 @@ PHP_FUNCTION(openssl_x509_checkpurpose)
}
}
- cainfo = setup_verify(zcainfo TSRMLS_CC);
+ cainfo = setup_verify(zcainfo);
if (cainfo == NULL) {
goto clean_exit;
}
- cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
+ cert = php_openssl_x509_from_zval(zcert, 0, &certresource);
if (cert == NULL) {
goto clean_exit;
}
- ret = check_cert(cainfo, cert, untrustedchain, purpose);
+ ret = check_cert(cainfo, cert, untrustedchain, (int)purpose);
if (ret != 0 && ret != 1) {
RETVAL_LONG(ret);
} else {
@@ -2210,11 +2241,11 @@ PHP_FUNCTION(openssl_x509_checkpurpose)
}
clean_exit:
- if (certresource == 1 && cert) {
+ if (certresource == NULL && cert) {
X509_free(cert);
}
- if (cainfo) {
- X509_STORE_free(cainfo);
+ if (cainfo) {
+ X509_STORE_free(cainfo);
}
if (untrustedchain) {
sk_X509_pop_free(untrustedchain, X509_free);
@@ -2226,12 +2257,13 @@ clean_exit:
* calist is an array containing file and directory names. create a
* certificate store and add those certs to it for use in verification.
*/
-static X509_STORE * setup_verify(zval * calist TSRMLS_DC)
+static X509_STORE * setup_verify(zval * calist)
{
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();
@@ -2240,39 +2272,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(Z_ARRVAL_P(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, 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, 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));
- } else {
+ if (dir_lookup == NULL || !X509_LOOKUP_add_dir(dir_lookup, Z_STRVAL_P(item), X509_FILETYPE_PEM)) {
+ php_error_docref(NULL, 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());
@@ -2294,17 +2319,18 @@ 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(), "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);
+ 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!");
+ php_error_docref(NULL, E_WARNING, "supplied parameter cannot be coerced into an X509 certificate!");
RETURN_FALSE;
}
}
@@ -2317,11 +2343,13 @@ PHP_FUNCTION(openssl_x509_free)
zval *x509;
X509 *cert;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &x509) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &x509) == FAILURE) {
return;
}
- ZEND_FETCH_RESOURCE(cert, X509 *, &x509, -1, "OpenSSL X.509", le_x509);
- zend_list_delete(Z_LVAL_P(x509));
+ if ((cert = (X509 *)zend_fetch_resource(Z_RES_P(x509), "OpenSSL X.509", le_x509)) == NULL) {
+ RETURN_FALSE;
+ }
+ zend_list_close(Z_RES_P(x509));
}
/* }}} */
@@ -2339,47 +2367,42 @@ 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) /* {{{ */
{
- HashPosition hpos;
- zval ** zcertval;
+ zval * zcertval;
STACK_OF(X509) * sk = NULL;
- X509 * cert;
- long certresource;
+ X509 * cert;
+ 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) {
-
- cert = php_openssl_x509_from_zval(zcertval, 0, &certresource TSRMLS_CC);
+ if (Z_TYPE_P(zcerts) == IS_ARRAY) {
+ ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(zcerts), zcertval) {
+ cert = php_openssl_x509_from_zval(zcertval, 0, &certresource);
if (cert == NULL) {
goto clean_exit;
}
- if (certresource != -1) {
+ if (certresource != NULL) {
cert = X509_dup(cert);
-
+
if (cert == NULL) {
goto clean_exit;
}
-
+
}
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);
-
+ cert = php_openssl_x509_from_zval(zcerts, 0, &certresource);
+
if (cert == NULL) {
goto clean_exit;
}
- if (certresource != -1) {
+ if (certresource != NULL) {
cert = X509_dup(cert);
if (cert == NULL) {
goto clean_exit;
@@ -2388,8 +2411,8 @@ static STACK_OF(X509) * php_array_to_X509_sk(zval ** zcerts TSRMLS_DC) /* {{{ */
sk_X509_push(sk, cert);
}
- clean_exit:
- return sk;
+clean_exit:
+ return sk;
}
/* }}} */
@@ -2402,75 +2425,75 @@ 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(), "zpzs|a", &zcert, &filename, &filename_len, &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);
if (cert == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
+ php_error_docref(NULL, 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);
if (priv_key == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get private key from parameter 3");
+ php_error_docref(NULL, E_WARNING, "cannot get private key from parameter 3");
goto cleanup;
}
if (cert && !X509_check_private_key(cert, priv_key)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key does not correspond to cert");
+ php_error_docref(NULL, E_WARNING, "private key does not correspond to cert");
goto cleanup;
}
- if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
+ if (php_openssl_open_base_dir_chk(filename)) {
goto cleanup;
}
/* 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 && Z_TYPE_PP(item) == IS_STRING)
- 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)
- ca = php_array_to_X509_sk(item TSRMLS_CC);
+ if (args && (item = zend_hash_str_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts")-1)) != NULL)
+ ca = php_array_to_X509_sk(item);
/* end parse extra config */
/*PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, STACK_OF(X509) *ca,
- int nid_key, int nid_cert, int iter, int mac_iter, int keytype);*/
+ int nid_key, int nid_cert, int iter, int mac_iter, int keytype);*/
p12 = PKCS12_create(pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0);
- bio_out = BIO_new_file(filename, "w");
+ bio_out = BIO_new_file(filename, "w");
if (bio_out) {
-
+
i2d_PKCS12_bio(bio_out, p12);
RETVAL_TRUE;
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "error opening file %s", filename);
+ php_error_docref(NULL, E_WARNING, "error opening file %s", filename);
}
BIO_free(bio_out);
PKCS12_free(p12);
php_sk_X509_free(ca);
-
+
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);
}
}
@@ -2485,50 +2508,50 @@ 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(), "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);
if (cert == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
+ php_error_docref(NULL, 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);
if (priv_key == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get private key from parameter 3");
+ php_error_docref(NULL, E_WARNING, "cannot get private key from parameter 3");
goto cleanup;
}
if (cert && !X509_check_private_key(cert, priv_key)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key does not correspond to cert");
+ php_error_docref(NULL, E_WARNING, "private key does not correspond to cert");
goto cleanup;
}
/* 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 && Z_TYPE_PP(item) == IS_STRING)
- 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)
- ca = php_array_to_X509_sk(item TSRMLS_CC);
+ if (args && (item = zend_hash_str_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts")-1)) != NULL)
+ ca = php_array_to_X509_sk(item);
/* end parse extra config */
-
+
p12 = PKCS12_create(pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0);
bio_out = BIO_new(BIO_s_mem());
- if (i2d_PKCS12_bio(bio_out, p12)) {
+ if (i2d_PKCS12_bio(bio_out, p12)) {
BUF_MEM *bio_buf;
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;
}
@@ -2536,13 +2559,13 @@ PHP_FUNCTION(openssl_pkcs12_export)
BIO_free(bio_out);
PKCS12_free(p12);
php_sk_X509_free(ca);
-
+
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);
}
}
@@ -2552,9 +2575,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;
@@ -2562,16 +2585,18 @@ 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(), "sz/s", &zp12, &zp12_len, &zout, &pass, &pass_len) == FAILURE)
return;
RETVAL_FALSE;
-
+
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT(zp12_len, pkcs12);
+
bio_in = BIO_new(BIO_s_mem());
-
- if(!BIO_write(bio_in, zp12, zp12_len))
+
+ if(0 >= BIO_write(bio_in, zp12, (int)zp12_len))
goto cleanup;
-
+
if(d2i_PKCS12_bio(bio_in, &p12)) {
if(PKCS12_parse(p12, pass, &pkey, &cert, &ca)) {
BIO * bio_out;
@@ -2583,9 +2608,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);
@@ -2593,17 +2617,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;
@@ -2619,10 +2641,9 @@ 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);
@@ -2630,25 +2651,25 @@ 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;
-
+
PKCS12_free(p12);
}
}
-
- cleanup:
+
+ cleanup:
if (bio_in) {
BIO_free(bio_in);
}
if (pkey) {
EVP_PKEY_free(pkey);
}
- if (cert) {
+ if (cert) {
X509_free(cert);
}
}
@@ -2657,7 +2678,7 @@ PHP_FUNCTION(openssl_pkcs12_read)
/* {{{ x509 CSR functions */
/* {{{ php_openssl_make_REQ */
-static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, zval * dn, zval * attribs TSRMLS_DC)
+static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, zval * dn, zval * attribs)
{
STACK_OF(CONF_VALUE) * dn_sk, *attr_sk = NULL;
char * str, *dn_sect, *attr_sect;
@@ -2667,7 +2688,7 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
return FAILURE;
}
dn_sk = CONF_get_section(req->req_config, dn_sect);
- if (dn_sk == NULL) {
+ if (dn_sk == NULL) {
return FAILURE;
}
attr_sect = CONF_get_string(req->req_config, req->section_name, "attributes");
@@ -2685,52 +2706,44 @@ 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(Z_ARRVAL_P(dn), strindex, item) {
if (strindex) {
int nid;
- nid = OBJ_txt2nid(strindex);
+ convert_to_string_ex(item);
+
+ nid = OBJ_txt2nid(ZSTR_VAL(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))
+ 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,
+ php_error_docref(NULL, 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, E_WARNING, "dn: %s is not a recognized name", ZSTR_VAL(strindex));
}
}
- 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++) {
int len;
char buffer[200 + 1]; /*200 + \0 !*/
-
+
v = sk_CONF_VALUE_value(dn_sk, i);
type = v->name;
-
- len = strlen(type);
+
+ len = (int)strlen(type);
if (len < sizeof("_default")) {
continue;
}
@@ -2744,7 +2757,7 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
memcpy(buffer, type, len);
buffer[len] = '\0';
type = buffer;
-
+
/* Skip past any leading X. X: X, etc to allow for multiple
* instances */
for (str = type; *str; str++) {
@@ -2762,39 +2775,35 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
continue;
}
if (!X509_NAME_add_entry_by_txt(subj, type, MBSTRING_UTF8, (unsigned char*)v->value, -1, -1, 0)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "add_entry_by_txt %s -> %s (failed)", type, v->value);
+ php_error_docref(NULL, E_WARNING, "add_entry_by_txt %s -> %s (failed)", type, v->value);
return FAILURE;
}
if (!X509_NAME_entry_count(subj)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "no objects specified in config file");
+ php_error_docref(NULL, E_WARNING, "no objects specified in config file");
return FAILURE;
}
}
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(Z_ARRVAL_P(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 (NULL == strindex) {
+ php_error_docref(NULL, E_WARNING, "dn: numeric fild names are not supported");
+ continue;
+ }
- if (strindex) {
- int nid;
+ convert_to_string_ex(item);
- 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(ZSTR_VAL(strindex));
+ 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, E_WARNING, "attribs: add_entry_by_NID %d -> %s (failed)", nid, Z_STRVAL_P(item));
+ return FAILURE;
}
+ } else {
+ php_error_docref(NULL, E_WARNING, "dn: %s is not a recognized name", ZSTR_VAL(strindex));
}
- 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 */
@@ -2803,7 +2812,7 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
continue;
}
if (!X509_REQ_add1_attr_by_txt(csr, v->name, MBSTRING_UTF8, (unsigned char*)v->value, -1)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ php_error_docref(NULL, E_WARNING,
"add1_attr_by_txt %s -> %s (failed; check error queue "
"and value of string_mask OpenSSL option if illegal "
"characters are reported)",
@@ -2820,41 +2829,42 @@ 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)
{
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;
+ zend_resource *res = Z_RES_P(val);
- what = zend_fetch_resource(val TSRMLS_CC, -1, "OpenSSL X.509 CSR", &type, 1, le_csr);
+ what = zend_fetch_resource(res, "OpenSSL X.509 CSR", le_csr);
if (what) {
if (resourceval) {
- *resourceval = Z_LVAL_PP(val);
+ *resourceval = res;
+ 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)) {
+ if (php_openssl_open_base_dir_chk(filename)) {
return NULL;
}
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), (int)Z_STRLEN_P(val));
}
csr = PEM_read_bio_X509_REQ(in, NULL,NULL,NULL);
BIO_free(in);
@@ -2870,22 +2880,23 @@ 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) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "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);
if (csr == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get CSR from parameter 1");
+ php_error_docref(NULL, E_WARNING, "cannot get CSR from parameter 1");
return;
}
- if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
+ if (php_openssl_open_base_dir_chk(filename)) {
return;
}
@@ -2897,10 +2908,10 @@ PHP_FUNCTION(openssl_csr_export_to_file)
PEM_write_bio_X509_REQ(bio_out, csr);
RETVAL_TRUE;
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "error opening file %s", filename);
+ php_error_docref(NULL, 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);
@@ -2915,17 +2926,17 @@ 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(), "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);
if (csr == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get CSR from parameter 1");
+ php_error_docref(NULL, E_WARNING, "cannot get CSR from parameter 1");
return;
}
@@ -2941,12 +2952,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);
@@ -2957,77 +2968,78 @@ 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(), "zz!zl|a!l", &zcsr, &zcert, &zpkey, &num_days, &args, &serial) == FAILURE)
return;
RETVAL_FALSE;
PHP_SSL_REQ_INIT(&req);
-
- csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource TSRMLS_CC);
+
+ csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource);
if (csr == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get CSR from parameter 1");
+ php_error_docref(NULL, E_WARNING, "cannot get CSR from parameter 1");
return;
}
if (zcert) {
- cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
+ cert = php_openssl_x509_from_zval(zcert, 0, &certresource);
if (cert == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 2");
+ php_error_docref(NULL, E_WARNING, "cannot get cert from parameter 2");
goto cleanup;
}
}
- priv_key = php_openssl_evp_from_zval(zpkey, 0, "", 1, &keyresource TSRMLS_CC);
+ priv_key = php_openssl_evp_from_zval(zpkey, 0, "", 1, &keyresource);
if (priv_key == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get private key from parameter 3");
+ php_error_docref(NULL, E_WARNING, "cannot get private key from parameter 3");
goto cleanup;
}
if (cert && !X509_check_private_key(cert, priv_key)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key does not correspond to signing cert");
+ php_error_docref(NULL, E_WARNING, "private key does not correspond to signing cert");
goto cleanup;
}
-
+
if (PHP_SSL_REQ_PARSE(&req, args) == FAILURE) {
goto cleanup;
}
/* Check that the request matches the signature */
key = X509_REQ_get_pubkey(csr);
if (key == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "error unpacking public key");
+ php_error_docref(NULL, E_WARNING, "error unpacking public key");
goto cleanup;
}
i = X509_REQ_verify(csr, key);
if (i < 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Signature verification problems");
+ php_error_docref(NULL, E_WARNING, "Signature verification problems");
goto cleanup;
}
else if (i == 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Signature did not match the certificate request");
+ php_error_docref(NULL, E_WARNING, "Signature did not match the certificate request");
goto cleanup;
}
-
+
/* Now we can get on with it */
-
+
new_cert = X509_new();
if (new_cert == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "No memory");
+ php_error_docref(NULL, E_WARNING, "No memory");
goto cleanup;
}
/* Version 3 cert */
if (!X509_set_version(new_cert, 2))
goto cleanup;
- ASN1_INTEGER_set(X509_get_serialNumber(new_cert), serial);
-
+
+ ASN1_INTEGER_set(X509_get_serialNumber(new_cert), (long)serial);
+
X509_set_subject_name(new_cert, X509_REQ_get_subject_name(csr));
if (cert == NULL) {
@@ -3037,14 +3049,14 @@ PHP_FUNCTION(openssl_csr_sign)
goto cleanup;
}
X509_gmtime_adj(X509_get_notBefore(new_cert), 0);
- X509_gmtime_adj(X509_get_notAfter(new_cert), (long)60*60*24*num_days);
+ X509_gmtime_adj(X509_get_notAfter(new_cert), 60*60*24*(long)num_days);
i = X509_set_pubkey(new_cert, key);
if (!i) {
goto cleanup;
}
if (req.extensions_section) {
X509V3_CTX ctx;
-
+
X509V3_set_ctx(&ctx, cert, new_cert, csr, NULL, 0);
X509V3_set_conf_lhash(&ctx, req.req_config);
if (!X509V3_EXT_add_conf(req.req_config, &ctx, req.extensions_section, new_cert)) {
@@ -3054,14 +3066,14 @@ PHP_FUNCTION(openssl_csr_sign)
/* Now sign it */
if (!X509_sign(new_cert, priv_key, req.digest)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to sign it");
+ php_error_docref(NULL, E_WARNING, "failed to sign it");
goto cleanup;
}
-
+
/* Succeeded; lets return the cert */
- RETVAL_RESOURCE(zend_list_insert(new_cert, le_x509 TSRMLS_CC));
+ ZVAL_RES(return_value, zend_register_resource(new_cert, le_x509));
new_cert = NULL;
-
+
cleanup:
if (cert == new_cert) {
@@ -3069,16 +3081,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) {
@@ -3096,32 +3108,32 @@ PHP_FUNCTION(openssl_csr_new)
zval * out_pkey;
X509_REQ * csr = NULL;
int we_made_the_key = 1;
- long key_resource;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az|a!a!", &dn, &out_pkey, &args, &attribs) == FAILURE) {
+ zend_resource *key_resource;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "az/|a!a!", &dn, &out_pkey, &args, &attribs) == FAILURE) {
return;
}
RETVAL_FALSE;
-
+
PHP_SSL_REQ_INIT(&req);
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);
if (req.priv_key != NULL) {
we_made_the_key = 0;
}
}
if (req.priv_key == NULL) {
- php_openssl_generate_private_key(&req TSRMLS_CC);
+ php_openssl_generate_private_key(&req);
}
if (req.priv_key == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to generate a private key");
+ php_error_docref(NULL, E_WARNING, "Unable to generate a private key");
} else {
csr = X509_REQ_new();
if (csr) {
- if (php_openssl_make_REQ(&req, csr, dn, attribs TSRMLS_CC) == SUCCESS) {
+ if (php_openssl_make_REQ(&req, csr, dn, attribs) == SUCCESS) {
X509V3_CTX ext_ctx;
X509V3_set_ctx(&ext_ctx, NULL, NULL, csr, NULL, 0);
@@ -3131,23 +3143,23 @@ PHP_FUNCTION(openssl_csr_new)
if (req.request_extensions_section && !X509V3_EXT_REQ_add_conf(req.req_config,
&ext_ctx, req.request_extensions_section, csr))
{
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error loading extension section %s", req.request_extensions_section);
+ php_error_docref(NULL, E_WARNING, "Error loading extension section %s", req.request_extensions_section);
} else {
RETVAL_TRUE;
-
+
if (X509_REQ_sign(csr, req.priv_key, req.digest)) {
- RETVAL_RESOURCE(zend_list_insert(csr, le_csr TSRMLS_CC));
- csr = NULL;
+ ZVAL_RES(return_value, zend_register_resource(csr, le_csr));
+ csr = NULL;
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error signing request");
+ php_error_docref(NULL, E_WARNING, "Error signing request");
}
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));
+ ZVAL_RES(out_pkey, zend_register_resource(req.priv_key, le_key));
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! */
}
}
@@ -3172,17 +3184,17 @@ 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(), "z|b", &zcsr, &use_shortnames) == FAILURE) {
return;
}
- csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource TSRMLS_CC);
+ csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource);
if (csr == NULL) {
RETURN_FALSE;
@@ -3191,7 +3203,7 @@ PHP_FUNCTION(openssl_csr_get_subject)
subject = X509_REQ_get_subject_name(csr);
array_init(return_value);
- add_assoc_name_entry(return_value, NULL, subject, use_shortnames TSRMLS_CC);
+ add_assoc_name_entry(return_value, NULL, subject, use_shortnames);
return;
}
/* }}} */
@@ -3200,26 +3212,25 @@ 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(), "z|b", &zcsr, &use_shortnames) == FAILURE) {
return;
}
- csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource TSRMLS_CC);
+ csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource);
if (csr == NULL) {
RETURN_FALSE;
}
tpubkey=X509_REQ_get_pubkey(csr);
- RETVAL_RESOURCE(zend_list_insert(tpubkey, le_key TSRMLS_CC));
- return;
+ RETURN_RES(zend_register_resource(tpubkey, le_key));
}
/* }}} */
@@ -3240,16 +3251,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)
{
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) {\
@@ -3258,62 +3269,62 @@ 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) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "key array must be of the form array(0 => key, 1 => phrase)");
+ if ((zphrase = zend_hash_index_find(Z_ARRVAL_P(val), 1)) == NULL) {
+ php_error_docref(NULL, 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_COPY(&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) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "key array must be of the form array(0 => key, 1 => phrase)");
+ if ((val = zend_hash_index_find(Z_ARRVAL_P(val), 0)) == NULL) {
+ php_error_docref(NULL, 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;
+ zend_resource * res = Z_RES_P(val);
- what = zend_fetch_resource(val TSRMLS_CC, -1, "OpenSSL X.509/key", &type, 2, le_x509, le_key);
+ what = zend_fetch_resource2(res, "OpenSSL X.509/key", le_x509, le_key);
if (!what) {
TMP_CLEAN;
}
- if (resourceval) {
- *resourceval = Z_LVAL_PP(val);
+ if (resourceval) {
+ *resourceval = res;
+ Z_ADDREF_P(val);
}
- if (type == le_x509) {
+ if (res->type == le_x509) {
/* extract key from cert, depending on public_key param */
cert = (X509*)what;
free_cert = 0;
- } else if (type == le_key) {
+ } else if (res->type == le_key) {
int is_priv;
- is_priv = php_openssl_is_private_key((EVP_PKEY*)what TSRMLS_CC);
+ is_priv = php_openssl_is_private_key((EVP_PKEY*)what);
/* check whether it is actually a private key if requested */
if (!public_key && !is_priv) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "supplied key param is a public key");
+ php_error_docref(NULL, E_WARNING, "supplied key param is a public key");
TMP_CLEAN;
}
if (public_key && is_priv) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Don't know how to get public key from this private key");
+ php_error_docref(NULL, E_WARNING, "Don't know how to get public key from this private key");
TMP_CLEAN;
} else {
if (Z_TYPE(tmp) == IS_STRING) {
@@ -3328,21 +3339,21 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char *
}
} else {
/* force it to be a string and check if it refers to a file */
- /* passing non string values leaks, object uses toString, it returns NULL
- * See bug38255.phpt
+ /* 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);
+ cert = php_openssl_x509_from_zval(val, 0, &cert_res);
+ free_cert = (cert_res == NULL);
/* actual extraction done later */
if (!cert) {
/* not a X509 certificate, try to retrieve public key */
@@ -3350,7 +3361,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), (int)Z_STRLEN_P(val));
}
if (in == NULL) {
TMP_CLEAN;
@@ -3363,12 +3374,12 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char *
BIO *in;
if (filename) {
- if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
+ if (php_openssl_open_base_dir_chk(filename)) {
TMP_CLEAN;
}
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), (int)Z_STRLEN_P(val));
}
if (in == NULL) {
@@ -3388,7 +3399,7 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char *
X509_free(cert);
}
if (key && makeresource && resourceval) {
- *resourceval = ZEND_REGISTER_RESOURCE(NULL, key, le_key);
+ *resourceval = zend_register_resource(key, le_key);
}
if (Z_TYPE(tmp) == IS_STRING) {
zval_dtor(&tmp);
@@ -3398,42 +3409,67 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char *
/* }}} */
/* {{{ php_openssl_generate_private_key */
-static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req TSRMLS_DC)
+static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req)
{
char * randfile = NULL;
int egdsocket, seeded;
EVP_PKEY * return_val = NULL;
-
+
if (req->priv_key_bits < MIN_KEY_LENGTH) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key length is too short; it needs to be at least %d bits, not %d",
+ php_error_docref(NULL, E_WARNING, "private key length is too short; it needs to be at least %d bits, not %d",
MIN_KEY_LENGTH, req->priv_key_bits);
return NULL;
}
randfile = CONF_get_string(req->req_config, req->section_name, "RANDFILE");
- php_openssl_load_rand_file(randfile, &egdsocket, &seeded TSRMLS_CC);
-
+ php_openssl_load_rand_file(randfile, &egdsocket, &seeded);
+
if ((req->priv_key = EVP_PKEY_new()) != NULL) {
switch(req->priv_key_type) {
case OPENSSL_KEYTYPE_RSA:
- PHP_OPENSSL_RAND_ADD_TIME();
- if (EVP_PKEY_assign_RSA(req->priv_key, RSA_generate_key(req->priv_key_bits, 0x10001, NULL, NULL))) {
- return_val = req->priv_key;
+ {
+ RSA* rsaparam;
+#if OPENSSL_VERSION_NUMBER < 0x10002000L
+ /* OpenSSL 1.0.2 deprecates RSA_generate_key */
+ PHP_OPENSSL_RAND_ADD_TIME();
+ rsaparam = (RSA*)RSA_generate_key(req->priv_key_bits, RSA_F4, NULL, NULL);
+#else
+ {
+ BIGNUM *bne = (BIGNUM *)BN_new();
+ if (BN_set_word(bne, RSA_F4) != 1) {
+ BN_free(bne);
+ php_error_docref(NULL, E_WARNING, "failed setting exponent");
+ return NULL;
+ }
+ rsaparam = RSA_new();
+ PHP_OPENSSL_RAND_ADD_TIME();
+ RSA_generate_key_ex(rsaparam, req->priv_key_bits, bne, NULL);
+ BN_free(bne);
+ }
+#endif
+ if (rsaparam && EVP_PKEY_assign_RSA(req->priv_key, rsaparam)) {
+ return_val = req->priv_key;
+ }
}
break;
-#if !defined(NO_DSA) && defined(HAVE_DSA_DEFAULT_METHOD)
+#if !defined(NO_DSA)
case OPENSSL_KEYTYPE_DSA:
PHP_OPENSSL_RAND_ADD_TIME();
{
- DSA *dsapar = DSA_generate_parameters(req->priv_key_bits, NULL, 0, NULL, NULL, NULL, NULL);
- if (dsapar) {
- DSA_set_method(dsapar, DSA_get_default_method());
- if (DSA_generate_key(dsapar)) {
- if (EVP_PKEY_assign_DSA(req->priv_key, dsapar)) {
+ DSA *dsaparam = NULL;
+#if OPENSSL_VERSION_NUMBER < 0x10002000L
+ dsaparam = DSA_generate_parameters(req->priv_key_bits, NULL, 0, NULL, NULL, NULL, NULL);
+#else
+ DSA_generate_parameters_ex(dsaparam, req->priv_key_bits, NULL, 0, NULL, NULL, NULL);
+#endif
+ if (dsaparam) {
+ DSA_set_method(dsaparam, DSA_get_default_method());
+ if (DSA_generate_key(dsaparam)) {
+ if (EVP_PKEY_assign_DSA(req->priv_key, dsaparam)) {
return_val = req->priv_key;
}
} else {
- DSA_free(dsapar);
+ DSA_free(dsaparam);
}
}
}
@@ -3443,42 +3479,46 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
case OPENSSL_KEYTYPE_DH:
PHP_OPENSSL_RAND_ADD_TIME();
{
- DH *dhpar = DH_generate_parameters(req->priv_key_bits, 2, NULL, NULL);
int codes = 0;
-
- if (dhpar) {
- DH_set_method(dhpar, DH_get_default_method());
- if (DH_check(dhpar, &codes) && codes == 0 && DH_generate_key(dhpar)) {
- if (EVP_PKEY_assign_DH(req->priv_key, dhpar)) {
+ DH *dhparam = NULL;
+#if OPENSSL_VERSION_NUMBER < 0x10002000L
+ dhparam = DH_generate_parameters(req->priv_key_bits, 2, NULL, NULL);
+#else
+ DH_generate_parameters_ex(dhparam, req->priv_key_bits, 2, NULL);
+#endif
+ if (dhparam) {
+ DH_set_method(dhparam, DH_get_default_method());
+ if (DH_check(dhparam, &codes) && codes == 0 && DH_generate_key(dhparam)) {
+ if (EVP_PKEY_assign_DH(req->priv_key, dhparam)) {
return_val = req->priv_key;
}
} else {
- DH_free(dhpar);
+ DH_free(dhparam);
}
}
}
break;
#endif
default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported private key type");
+ php_error_docref(NULL, E_WARNING, "Unsupported private key type");
}
}
php_openssl_write_rand_file(randfile, egdsocket, seeded);
-
+
if (return_val == NULL) {
EVP_PKEY_free(req->priv_key);
req->priv_key = NULL;
return NULL;
}
-
+
return return_val;
}
/* }}} */
/* {{{ php_openssl_is_private_key
Check whether the supplied key is a private key by checking if the secret prime factors are set */
-static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC)
+static int php_openssl_is_private_key(EVP_PKEY* pkey)
{
assert(pkey != NULL);
@@ -3500,7 +3540,7 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC)
case EVP_PKEY_DSA4:
assert(pkey->pkey.dsa != NULL);
- if (NULL == pkey->pkey.dsa->p || NULL == pkey->pkey.dsa->q || NULL == pkey->pkey.dsa->priv_key){
+ if (NULL == pkey->pkey.dsa->p || NULL == pkey->pkey.dsa->q || NULL == pkey->pkey.dsa->priv_key){
return 0;
}
break;
@@ -3524,7 +3564,7 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC)
break;
#endif
default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "key type not supported in this PHP build!");
+ php_error_docref(NULL, E_WARNING, "key type not supported in this PHP build!");
break;
}
return 1;
@@ -3534,20 +3574,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*)ZSTR_VAL(str)); \
+ ZSTR_VAL(str)[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), \
+ (int)Z_STRLEN_P(bn), NULL); \
} \
} while (0);
@@ -3598,9 +3638,9 @@ 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) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a!", &args) == FAILURE) {
return;
}
RETVAL_FALSE;
@@ -3608,23 +3648,23 @@ 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) {
- pkey = EVP_PKEY_new();
- if (pkey) {
+ 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));
+ RETURN_RES(zend_register_resource(pkey, le_key));
}
}
RSA_free(rsa);
@@ -3632,20 +3672,20 @@ 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) {
- pkey = EVP_PKEY_new();
- if (pkey) {
+ } 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 (php_openssl_pkey_init_dsa(dsa)) {
if (EVP_PKEY_assign_DSA(pkey, dsa)) {
- RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
+ RETURN_RES(zend_register_resource(pkey, le_key));
}
}
DSA_free(dsa);
@@ -3653,19 +3693,20 @@ 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) {
- pkey = EVP_PKEY_new();
- if (pkey) {
+ } 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 (php_openssl_pkey_init_dh(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));
+ return;
}
}
DH_free(dh);
@@ -3674,15 +3715,15 @@ PHP_FUNCTION(openssl_pkey_new)
}
RETURN_FALSE;
}
- }
+ }
PHP_SSL_REQ_INIT(&req);
if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS)
{
- if (php_openssl_generate_private_key(&req TSRMLS_CC)) {
+ if (php_openssl_generate_private_key(&req)) {
/* pass back a key resource */
- RETVAL_RESOURCE(zend_list_insert(req.priv_key, le_key TSRMLS_CC));
+ RETVAL_RES(zend_register_resource(req.priv_key, le_key));
/* make sure the cleanup code doesn't zap it! */
req.priv_key = NULL;
}
@@ -3696,33 +3737,35 @@ 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;
int pem_write = 0;
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(), "zp|s!a!", &zpkey, &filename, &filename_len, &passphrase, &passphrase_len, &args) == FAILURE) {
return;
}
RETVAL_FALSE;
- key = php_openssl_evp_from_zval(zpkey, 0, passphrase, 0, &key_resource TSRMLS_CC);
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT(passphrase_len, passphrase);
+
+ key = php_openssl_evp_from_zval(zpkey, 0, passphrase, 0, &key_resource);
if (key == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get key from parameter 1");
+ php_error_docref(NULL, E_WARNING, "cannot get key from parameter 1");
RETURN_FALSE;
}
-
- if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
+
+ if (php_openssl_open_base_dir_chk(filename)) {
RETURN_FALSE;
}
-
+
PHP_SSL_REQ_INIT(&req);
if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {
@@ -3741,11 +3784,11 @@ PHP_FUNCTION(openssl_pkey_export_to_file)
switch (EVP_PKEY_type(key->type)) {
#ifdef HAVE_EVP_PKEY_EC
case EVP_PKEY_EC:
- pem_write = PEM_write_bio_ECPrivateKey(bio_out, EVP_PKEY_get1_EC_KEY(key), cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL);
+ pem_write = PEM_write_bio_ECPrivateKey(bio_out, EVP_PKEY_get1_EC_KEY(key), cipher, (unsigned char *)passphrase, (int)passphrase_len, NULL, NULL);
break;
#endif
default:
- pem_write = PEM_write_bio_PrivateKey(bio_out, key, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL);
+ pem_write = PEM_write_bio_PrivateKey(bio_out, key, cipher, (unsigned char *)passphrase, (int)passphrase_len, NULL, NULL);
break;
}
@@ -3757,7 +3800,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) {
@@ -3771,27 +3814,28 @@ 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;
int pem_write = 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(), "zz/|s!a!", &zpkey, &out, &passphrase, &passphrase_len, &args) == FAILURE) {
return;
}
RETVAL_FALSE;
- key = php_openssl_evp_from_zval(zpkey, 0, passphrase, 0, &key_resource TSRMLS_CC);
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT(passphrase_len, passphrase);
+
+ key = php_openssl_evp_from_zval(zpkey, 0, passphrase, 0, &key_resource);
if (key == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get key from parameter 1");
+ php_error_docref(NULL, E_WARNING, "cannot get key from parameter 1");
RETURN_FALSE;
}
-
+
PHP_SSL_REQ_INIT(&req);
if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {
@@ -3810,11 +3854,11 @@ PHP_FUNCTION(openssl_pkey_export)
switch (EVP_PKEY_type(key->type)) {
#ifdef HAVE_EVP_PKEY_EC
case EVP_PKEY_EC:
- pem_write = PEM_write_bio_ECPrivateKey(bio_out, EVP_PKEY_get1_EC_KEY(key), cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL);
+ pem_write = PEM_write_bio_ECPrivateKey(bio_out, EVP_PKEY_get1_EC_KEY(key), cipher, (unsigned char *)passphrase, (int)passphrase_len, NULL, NULL);
break;
#endif
default:
- pem_write = PEM_write_bio_PrivateKey(bio_out, key, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL);
+ pem_write = PEM_write_bio_PrivateKey(bio_out, key, cipher, (unsigned char *)passphrase, (int)passphrase_len, NULL, NULL);
break;
}
@@ -3828,12 +3872,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) {
@@ -3846,19 +3890,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(), "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);
if (pkey == NULL) {
RETURN_FALSE;
}
- zend_list_addref(Z_LVAL_P(return_value));
+ ZVAL_RES(return_value, res);
+ Z_ADDREF_P(return_value);
}
/* }}} */
@@ -3869,11 +3913,13 @@ PHP_FUNCTION(openssl_pkey_free)
zval *key;
EVP_PKEY *pkey;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &key) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &key) == FAILURE) {
return;
}
- ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, &key, -1, "OpenSSL key", le_key);
- zend_list_delete(Z_LVAL_P(key));
+ if ((pkey = (EVP_PKEY *)zend_fetch_resource(Z_RES_P(key), "OpenSSL key", le_key)) == NULL) {
+ RETURN_FALSE;
+ }
+ zend_list_close(Z_RES_P(key));
}
/* }}} */
@@ -3881,21 +3927,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(), "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);
if (pkey == NULL) {
RETURN_FALSE;
}
- zend_list_addref(Z_LVAL_P(return_value));
+ ZVAL_RES(return_value, res);
+ Z_ADDREF_P(return_value);
}
/* }}} */
@@ -3909,13 +3956,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) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &key) == FAILURE) {
return;
}
- ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, &key, -1, "OpenSSL key", le_key);
- if (!pkey) {
+ if ((pkey = (EVP_PKEY *)zend_fetch_resource(Z_RES_P(key), "OpenSSL key", le_key)) == NULL) {
RETURN_FALSE;
}
out = BIO_new(BIO_s_mem());
@@ -3924,8 +3970,8 @@ 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);
- /*TODO: Use the real values once the openssl constants are used
+ 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
*/
switch (EVP_PKEY_type(pkey->type)) {
@@ -3934,10 +3980,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);
@@ -3946,10 +3991,10 @@ 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;
+ break;
case EVP_PKEY_DSA:
case EVP_PKEY_DSA2:
case EVP_PKEY_DSA3:
@@ -3957,32 +4002,30 @@ 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:
-
+
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;
@@ -3990,7 +4033,7 @@ PHP_FUNCTION(openssl_pkey_get_details)
case EVP_PKEY_EC:
ktype = OPENSSL_KEYTYPE_EC;
if (pkey->pkey.ec != NULL) {
- zval *ec;
+ zval ec;
const EC_GROUP *ec_group;
int nid;
char *crv_sn;
@@ -4005,23 +4048,22 @@ PHP_FUNCTION(openssl_pkey_get_details)
if (nid == NID_undef) {
break;
}
- ALLOC_INIT_ZVAL(ec);
- array_init(ec);
+ array_init(&ec);
// Short object name
crv_sn = (char*) OBJ_nid2sn(nid);
if (crv_sn != NULL) {
- add_assoc_string(ec, "curve_name", crv_sn, 1);
+ add_assoc_string(&ec, "curve_name", crv_sn);
}
obj = OBJ_nid2obj(nid);
if (obj != NULL) {
int oir_len = OBJ_obj2txt(oir_buf, sizeof(oir_buf), obj, 1);
- add_assoc_stringl(ec, "curve_oid", (char*)oir_buf, oir_len, 1);
+ add_assoc_stringl(&ec, "curve_oid", (char*)oir_buf, oir_len);
ASN1_OBJECT_free(obj);
}
- add_assoc_zval(return_value, "ec", ec);
+ add_assoc_zval(return_value, "ec", &ec);
}
break;
#endif
@@ -4043,15 +4085,18 @@ 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;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssll|s",
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssll|s",
&password, &password_len,
&salt, &salt_len,
&key_length, &iterations,
@@ -4059,7 +4104,7 @@ PHP_FUNCTION(openssl_pbkdf2)
return;
}
- if (key_length <= 0 || key_length > INT_MAX) {
+ if (key_length <= 0) {
RETURN_FALSE;
}
@@ -4070,17 +4115,22 @@ PHP_FUNCTION(openssl_pbkdf2)
}
if (!digest) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature algorithm");
+ php_error_docref(NULL, E_WARNING, "Unknown signature algorithm");
RETURN_FALSE;
}
- out_buffer = emalloc(key_length + 1);
- out_buffer[key_length] = '\0';
+ PHP_OPENSSL_CHECK_LONG_TO_INT(key_length, key);
+ PHP_OPENSSL_CHECK_LONG_TO_INT(iterations, iterations);
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT(password_len, password);
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT(salt_len, salt);
+
+ 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, (int)password_len, (unsigned char *)salt, (int)salt_len, (int)iterations, digest, (int)key_length, (unsigned char*)ZSTR_VAL(out_buffer)) == 1) {
+ ZSTR_VAL(out_buffer)[key_length] = 0;
+ RETURN_NEW_STR(out_buffer);
} else {
- efree(out_buffer);
+ zend_string_release(out_buffer);
RETURN_FALSE;
}
}
@@ -4100,20 +4150,24 @@ 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);
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pl|papp", &filename, &filename_len,
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "pl|papp", &filename, &filename_len,
&flags, &signersfilename, &signersfilename_len, &cainfo,
&extracerts, &extracerts_len, &datafilename, &datafilename_len) == FAILURE) {
return;
}
-
+
if (extracerts) {
others = load_all_certs_from_file(extracerts);
if (others == NULL) {
@@ -4123,12 +4177,12 @@ PHP_FUNCTION(openssl_pkcs7_verify)
flags = flags & ~PKCS7_DETACHED;
- store = setup_verify(cainfo TSRMLS_CC);
+ store = setup_verify(cainfo);
if (!store) {
goto clean_exit;
}
- if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
+ if (php_openssl_open_base_dir_chk(filename)) {
goto clean_exit;
}
@@ -4146,7 +4200,7 @@ PHP_FUNCTION(openssl_pkcs7_verify)
if (datafilename) {
- if (php_openssl_open_base_dir_chk(datafilename TSRMLS_CC)) {
+ if (php_openssl_open_base_dir_chk(datafilename)) {
goto clean_exit;
}
@@ -4159,21 +4213,21 @@ PHP_FUNCTION(openssl_pkcs7_verify)
zend_printf("Calling PKCS7 verify\n");
#endif
- if (PKCS7_verify(p7, others, store, datain, dataout, flags)) {
+ if (PKCS7_verify(p7, others, store, datain, dataout, (int)flags)) {
RETVAL_TRUE;
if (signersfilename) {
BIO *certout;
-
- if (php_openssl_open_base_dir_chk(signersfilename TSRMLS_CC)) {
+
+ if (php_openssl_open_base_dir_chk(signersfilename)) {
goto clean_exit;
}
-
+
certout = BIO_new_file(signersfilename, "w");
if (certout) {
int i;
- signers = PKCS7_get0_signers(p7, NULL, flags);
+ signers = PKCS7_get0_signers(p7, NULL, (int)flags);
for(i = 0; i < sk_X509_num(signers); i++) {
PEM_write_bio_X509(certout, sk_X509_value(signers, i));
@@ -4181,7 +4235,7 @@ PHP_FUNCTION(openssl_pkcs7_verify)
BIO_free(certout);
sk_X509_free(signers);
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "signature OK, but cannot open %s for writing", signersfilename);
+ php_error_docref(NULL, E_WARNING, "signature OK, but cannot open %s for writing", signersfilename);
RETVAL_LONG(-1);
}
}
@@ -4203,30 +4257,29 @@ 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(), "ppza!|ll", &infilename, &infilename_len,
&outfilename, &outfilename_len, &zrecipcerts, &zheaders, &flags, &cipherid) == FAILURE)
return;
-
- if (php_openssl_open_base_dir_chk(infilename TSRMLS_CC) || php_openssl_open_base_dir_chk(outfilename TSRMLS_CC)) {
+
+ if (php_openssl_open_base_dir_chk(infilename) || php_openssl_open_base_dir_chk(outfilename)) {
return;
}
@@ -4236,24 +4289,23 @@ PHP_FUNCTION(openssl_pkcs7_encrypt)
}
outfile = BIO_new_file(outfilename, "w");
- if (outfile == NULL) {
+ if (outfile == NULL) {
goto clean_exit;
}
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(Z_ARRVAL_P(zrecipcerts), zcertval) {
+ zend_resource *certresource;
- cert = php_openssl_x509_from_zval(zcertval, 0, &certresource TSRMLS_CC);
+ cert = php_openssl_x509_from_zval(zcertval, 0, &certresource);
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);
@@ -4262,19 +4314,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);
+ cert = php_openssl_x509_from_zval(zrecipcerts, 0, &certresource);
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);
@@ -4289,11 +4339,11 @@ PHP_FUNCTION(openssl_pkcs7_encrypt)
cipher = php_openssl_get_evp_cipher_from_algo(cipherid);
if (cipher == NULL) {
/* shouldn't happen */
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to get cipher");
+ php_error_docref(NULL, E_WARNING, "Failed to get cipher");
goto clean_exit;
}
- p7 = PKCS7_encrypt(recipcerts, infile, (EVP_CIPHER*)cipher, flags);
+ p7 = PKCS7_encrypt(recipcerts, infile, (EVP_CIPHER*)cipher, (int)flags);
if (p7 == NULL) {
goto clean_exit;
@@ -4301,27 +4351,21 @@ 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(Z_ARRVAL_P(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", ZSTR_VAL(strindex), 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);
/* write the encrypted data */
- SMIME_write_PKCS7(outfile, p7, infile, flags);
+ SMIME_write_PKCS7(outfile, p7, infile, (int)flags);
RETVAL_TRUE;
@@ -4340,70 +4384,70 @@ 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(), "ppzza!|lp!",
&infilename, &infilename_len, &outfilename, &outfilename_len,
&zcert, &zprivkey, &zheaders, &flags, &extracertsfilename,
&extracertsfilename_len) == FAILURE) {
return;
}
-
+
RETVAL_FALSE;
if (extracertsfilename) {
others = load_all_certs_from_file(extracertsfilename);
- if (others == NULL) {
+ if (others == NULL) {
goto clean_exit;
}
}
- privkey = php_openssl_evp_from_zval(zprivkey, 0, "", 0, &keyresource TSRMLS_CC);
+ privkey = php_openssl_evp_from_zval(zprivkey, 0, "", 0, &keyresource);
if (privkey == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "error getting private key");
+ php_error_docref(NULL, E_WARNING, "error getting private key");
goto clean_exit;
}
- cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
+ cert = php_openssl_x509_from_zval(zcert, 0, &certresource);
if (cert == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "error getting cert");
+ php_error_docref(NULL, E_WARNING, "error getting cert");
goto clean_exit;
}
- if (php_openssl_open_base_dir_chk(infilename TSRMLS_CC) || php_openssl_open_base_dir_chk(outfilename TSRMLS_CC)) {
+ if (php_openssl_open_base_dir_chk(infilename) || php_openssl_open_base_dir_chk(outfilename)) {
goto clean_exit;
}
infile = BIO_new_file(infilename, "r");
if (infile == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "error opening input file %s!", infilename);
+ php_error_docref(NULL, E_WARNING, "error opening input file %s!", infilename);
goto clean_exit;
}
outfile = BIO_new_file(outfilename, "w");
if (outfile == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "error opening output file %s!", outfilename);
+ php_error_docref(NULL, E_WARNING, "error opening output file %s!", outfilename);
goto clean_exit;
}
- p7 = PKCS7_sign(cert, privkey, others, infile, flags);
+ p7 = PKCS7_sign(cert, privkey, others, infile, (int)flags);
if (p7 == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "error creating PKCS7 structure!");
+ php_error_docref(NULL, E_WARNING, "error creating PKCS7 structure!");
goto clean_exit;
}
@@ -4411,23 +4455,18 @@ 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(Z_ARRVAL_P(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", ZSTR_VAL(strindex), 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);
+ SMIME_write_PKCS7(outfile, p7, infile, (int)flags);
RETVAL_TRUE;
@@ -4438,10 +4477,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);
}
}
@@ -4452,35 +4491,37 @@ 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(), "ppz|z", &infilename, &infilename_len,
&outfilename, &outfilename_len, &recipcert, &recipkey) == FAILURE) {
return;
}
RETVAL_FALSE;
- cert = php_openssl_x509_from_zval(recipcert, 0, &certresval TSRMLS_CC);
+ cert = php_openssl_x509_from_zval(recipcert, 0, &certresval);
if (cert == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to coerce parameter 3 to x509 cert");
+ php_error_docref(NULL, E_WARNING, "unable to coerce parameter 3 to x509 cert");
goto clean_exit;
}
- key = php_openssl_evp_from_zval(recipkey ? recipkey : recipcert, 0, "", 0, &keyresval TSRMLS_CC);
+ key = php_openssl_evp_from_zval(recipkey ? recipkey : recipcert, 0, "", 0, &keyresval);
if (key == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to get private key");
+ php_error_docref(NULL, E_WARNING, "unable to get private key");
goto clean_exit;
}
-
- if (php_openssl_open_base_dir_chk(infilename TSRMLS_CC) || php_openssl_open_base_dir_chk(outfilename TSRMLS_CC)) {
+
+ if (php_openssl_open_base_dir_chk(infilename) || php_openssl_open_base_dir_chk(outfilename)) {
goto clean_exit;
}
@@ -4498,7 +4539,7 @@ PHP_FUNCTION(openssl_pkcs7_decrypt)
if (p7 == NULL) {
goto clean_exit;
}
- if (PKCS7_decrypt(p7, key, cert, out, PKCS7_DETACHED)) {
+ if (PKCS7_decrypt(p7, key, cert, out, PKCS7_DETACHED)) {
RETVAL_TRUE;
}
clean_exit:
@@ -4506,10 +4547,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);
}
}
@@ -4521,55 +4562,57 @@ 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(), "sz/z|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) {
return;
}
RETVAL_FALSE;
- pkey = php_openssl_evp_from_zval(key, 0, "", 0, &keyresource TSRMLS_CC);
+ pkey = php_openssl_evp_from_zval(key, 0, "", 0, &keyresource);
if (pkey == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "key param is not a valid private key");
+ php_error_docref(NULL, E_WARNING, "key param is not a valid private key");
RETURN_FALSE;
}
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT(data_len, data);
+
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,
- pkey->pkey.rsa,
- padding) == cryptedlen);
+ successful = (RSA_private_encrypt((int)data_len,
+ (unsigned char *)data,
+ (unsigned char *)ZSTR_VAL(cryptedbuf),
+ pkey->pkey.rsa,
+ (int)padding) == cryptedlen);
break;
default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "key type not supported in this PHP build!");
+ php_error_docref(NULL, E_WARNING, "key type not supported in this PHP build!");
}
if (successful) {
zval_dtor(crypted);
- cryptedbuf[cryptedlen] = '\0';
- ZVAL_STRINGL(crypted, (char *)cryptedbuf, cryptedlen, 0);
+ ZSTR_VAL(cryptedbuf)[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);
}
}
@@ -4579,64 +4622,66 @@ 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(), "sz/z|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) {
return;
}
RETVAL_FALSE;
- pkey = php_openssl_evp_from_zval(key, 0, "", 0, &keyresource TSRMLS_CC);
+ pkey = php_openssl_evp_from_zval(key, 0, "", 0, &keyresource);
if (pkey == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "key parameter is not a valid private key");
+ php_error_docref(NULL, E_WARNING, "key parameter is not a valid private key");
RETURN_FALSE;
}
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT(data_len, data);
+
cryptedlen = EVP_PKEY_size(pkey);
crypttemp = emalloc(cryptedlen + 1);
switch (pkey->type) {
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
- cryptedlen = RSA_private_decrypt(data_len,
- (unsigned char *)data,
- crypttemp,
- pkey->pkey.rsa,
- padding);
+ cryptedlen = RSA_private_decrypt((int)data_len,
+ (unsigned char *)data,
+ crypttemp,
+ pkey->pkey.rsa,
+ (int)padding);
if (cryptedlen != -1) {
- cryptedbuf = emalloc(cryptedlen + 1);
- memcpy(cryptedbuf, crypttemp, cryptedlen);
+ cryptedbuf = zend_string_alloc(cryptedlen, 0);
+ memcpy(ZSTR_VAL(cryptedbuf), crypttemp, cryptedlen);
successful = 1;
}
break;
default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "key type not supported in this PHP build!");
+ php_error_docref(NULL, E_WARNING, "key type not supported in this PHP build!");
}
efree(crypttemp);
if (successful) {
zval_dtor(crypted);
- cryptedbuf[cryptedlen] = '\0';
- ZVAL_STRINGL(crypted, (char *)cryptedbuf, cryptedlen, 0);
+ ZSTR_VAL(cryptedbuf)[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);
+ if (cryptedbuf) {
+ zend_string_release(cryptedbuf);
}
}
/* }}} */
@@ -4645,56 +4690,57 @@ 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(), "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);
+
+ pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource);
if (pkey == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "key parameter is not a valid public key");
+ php_error_docref(NULL, E_WARNING, "key parameter is not a valid public key");
RETURN_FALSE;
}
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT(data_len, data);
+
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,
- pkey->pkey.rsa,
- padding) == cryptedlen);
+ successful = (RSA_public_encrypt((int)data_len,
+ (unsigned char *)data,
+ (unsigned char *)ZSTR_VAL(cryptedbuf),
+ pkey->pkey.rsa,
+ (int)padding) == cryptedlen);
break;
default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "key type not supported in this PHP build!");
+ php_error_docref(NULL, E_WARNING, "key type not supported in this PHP build!");
}
if (successful) {
zval_dtor(crypted);
- cryptedbuf[cryptedlen] = '\0';
- ZVAL_STRINGL(crypted, (char *)cryptedbuf, cryptedlen, 0);
+ ZSTR_VAL(cryptedbuf)[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);
}
}
/* }}} */
@@ -4703,65 +4749,67 @@ 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(), "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);
+
+ pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource);
if (pkey == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "key parameter is not a valid public key");
+ php_error_docref(NULL, E_WARNING, "key parameter is not a valid public key");
RETURN_FALSE;
}
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT(data_len, data);
+
cryptedlen = EVP_PKEY_size(pkey);
crypttemp = emalloc(cryptedlen + 1);
switch (pkey->type) {
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
- cryptedlen = RSA_public_decrypt(data_len,
- (unsigned char *)data,
- crypttemp,
- pkey->pkey.rsa,
- padding);
+ cryptedlen = RSA_public_decrypt((int)data_len,
+ (unsigned char *)data,
+ crypttemp,
+ pkey->pkey.rsa,
+ (int)padding);
if (cryptedlen != -1) {
- cryptedbuf = emalloc(cryptedlen + 1);
- memcpy(cryptedbuf, crypttemp, cryptedlen);
+ cryptedbuf = zend_string_alloc(cryptedlen, 0);
+ memcpy(ZSTR_VAL(cryptedbuf), crypttemp, cryptedlen);
successful = 1;
}
break;
-
+
default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "key type not supported in this PHP build!");
-
+ php_error_docref(NULL, E_WARNING, "key type not supported in this PHP build!");
+
}
efree(crypttemp);
if (successful) {
zval_dtor(crypted);
- cryptedbuf[cryptedlen] = '\0';
- ZVAL_STRINGL(crypted, (char *)cryptedbuf, cryptedlen, 0);
+ ZSTR_VAL(cryptedbuf)[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);
}
}
@@ -4780,7 +4828,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;
}
@@ -4791,24 +4839,24 @@ 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(), "sz/z|z", &data, &data_len, &signature, &key, &method) == FAILURE) {
return;
}
- pkey = php_openssl_evp_from_zval(key, 0, "", 0, &keyresource TSRMLS_CC);
+ pkey = php_openssl_evp_from_zval(key, 0, "", 0, &keyresource);
if (pkey == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "supplied key param cannot be coerced into a private key");
+ php_error_docref(NULL, E_WARNING, "supplied key param cannot be coerced into a private key");
RETURN_FALSE;
}
@@ -4820,30 +4868,31 @@ PHP_FUNCTION(openssl_sign)
} else if (Z_TYPE_P(method) == IS_STRING) {
mdtype = EVP_get_digestbyname(Z_STRVAL_P(method));
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature algorithm.");
+ php_error_docref(NULL, E_WARNING, "Unknown signature algorithm.");
RETURN_FALSE;
}
if (!mdtype) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature algorithm.");
+ php_error_docref(NULL, E_WARNING, "Unknown signature algorithm.");
RETURN_FALSE;
}
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*)ZSTR_VAL(sigbuf), &siglen, pkey)) {
zval_dtor(signature);
- sigbuf[siglen] = '\0';
- ZVAL_STRINGL(signature, (char *)sigbuf, siglen, 0);
+ ZSTR_VAL(sigbuf)[siglen] = '\0';
+ ZSTR_LEN(sigbuf) = 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);
}
}
@@ -4853,21 +4902,25 @@ PHP_FUNCTION(openssl_sign)
Verifys data */
PHP_FUNCTION(openssl_verify)
{
- zval **key;
+ zval *key;
EVP_PKEY *pkey;
int err;
- EVP_MD_CTX md_ctx;
+ 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;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssZ|z", &data, &data_len, &signature, &signature_len, &key, &method) == FAILURE) {
+ zend_long signature_algo = OPENSSL_ALGO_SHA1;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssz|z", &data, &data_len, &signature, &signature_len, &key, &method) == FAILURE) {
return;
}
+ PHP_OPENSSL_CHECK_SIZE_T_TO_UINT(signature_len, signature);
+
if (method == NULL || Z_TYPE_P(method) == IS_LONG) {
if (method != NULL) {
signature_algo = Z_LVAL_P(method);
@@ -4876,26 +4929,26 @@ PHP_FUNCTION(openssl_verify)
} else if (Z_TYPE_P(method) == IS_STRING) {
mdtype = EVP_get_digestbyname(Z_STRVAL_P(method));
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature algorithm.");
+ php_error_docref(NULL, E_WARNING, "Unknown signature algorithm.");
RETURN_FALSE;
}
if (!mdtype) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature algorithm.");
+ php_error_docref(NULL, E_WARNING, "Unknown signature algorithm.");
RETURN_FALSE;
}
- pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource TSRMLS_CC);
+ pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource);
if (pkey == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "supplied key param cannot be coerced into a public key");
+ php_error_docref(NULL, E_WARNING, "supplied key param cannot be coerced into a public key");
RETURN_FALSE;
}
- EVP_VerifyInit (&md_ctx, mdtype);
+ EVP_VerifyInit (&md_ctx, mdtype);
EVP_VerifyUpdate (&md_ctx, data, data_len);
- err = EVP_VerifyFinal (&md_ctx, (unsigned char *)signature, signature_len, pkey);
+ err = EVP_VerifyFinal(&md_ctx, (unsigned char *)signature, (unsigned int)signature_len, pkey);
EVP_MD_CTX_cleanup(&md_ctx);
- if (keyresource == -1) {
+ if (keyresource == NULL) {
EVP_PKEY_free(pkey);
}
RETURN_LONG(err);
@@ -4906,66 +4959,69 @@ PHP_FUNCTION(openssl_verify)
Seals data */
PHP_FUNCTION(openssl_seal)
{
- zval *pubkeys, **pubkey, *sealdata, *ekeys;
+ zval *pubkeys, *pubkey, *sealdata, *ekeys, *iv = NULL;
HashTable *pubkeysht;
- HashPosition pos;
EVP_PKEY **pkeys;
- long * key_resources; /* so we know what to cleanup */
- int i, len1, len2, *eksl, nkeys;
- unsigned char *buf = NULL, **eks;
- char * data; int data_len;
+ zend_resource ** key_resources; /* so we know what to cleanup */
+ int i, len1, len2, *eksl, nkeys, iv_len;
+ unsigned char iv_buf[EVP_MAX_IV_LENGTH + 1], *buf = NULL, **eks;
+ 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(), "sz/z/a/|sz/", &data, &data_len,
+ &sealdata, &ekeys, &pubkeys, &method, &method_len, &iv) == FAILURE) {
return;
}
-
- pubkeysht = HASH_OF(pubkeys);
+ pubkeysht = Z_ARRVAL_P(pubkeys);
nkeys = pubkeysht ? zend_hash_num_elements(pubkeysht) : 0;
if (!nkeys) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Fourth argument to openssl_seal() must be a non-empty array");
+ php_error_docref(NULL, E_WARNING, "Fourth argument to openssl_seal() must be a non-empty array");
RETURN_FALSE;
}
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT(data_len, data);
+
if (method) {
cipher = EVP_get_cipherbyname(method);
if (!cipher) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature algorithm.");
- RETURN_FALSE;
- }
- if (EVP_CIPHER_iv_length(cipher) > 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Ciphers with modes requiring IV are not supported");
+ php_error_docref(NULL, E_WARNING, "Unknown signature algorithm.");
RETURN_FALSE;
}
} else {
cipher = EVP_rc4();
}
+ iv_len = EVP_CIPHER_iv_length(cipher);
+ if (!iv && iv_len > 0) {
+ php_error_docref(NULL, E_WARNING,
+ "Cipher algorithm requires an IV to be supplied as a sixth parameter");
+ RETURN_FALSE;
+ }
+
pkeys = safe_emalloc(nkeys, sizeof(*pkeys), 0);
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);
+ memset(pkeys, 0, sizeof(*pkeys) * 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) {
- pkeys[i] = php_openssl_evp_from_zval(pubkey, 1, NULL, 0, &key_resources[i] TSRMLS_CC);
+ ZEND_HASH_FOREACH_VAL(pubkeysht, pubkey) {
+ pkeys[i] = php_openssl_evp_from_zval(pubkey, 1, NULL, 0, &key_resources[i]);
if (pkeys[i] == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "not a public key (%dth member of pubkeys)", i+1);
+ php_error_docref(NULL, E_WARNING, "not a public key (%dth member of pubkeys)", i+1);
RETVAL_FALSE;
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;
@@ -4973,47 +5029,39 @@ PHP_FUNCTION(openssl_seal)
goto clean_exit;
}
-#if 0
- /* Need this if allow ciphers that require initialization vector */
- ivlen = EVP_CIPHER_CTX_iv_length(&ctx);
- iv = ivlen ? emalloc(ivlen + 1) : NULL;
-#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)) {
+ if (!EVP_SealInit(&ctx, cipher, eks, eksl, &iv_buf[0], pkeys, nkeys) ||
+ !EVP_SealUpdate(&ctx, buf, &len1, (unsigned char *)data, (int)data_len) ||
+ !EVP_SealFinal(&ctx, buf + len1, &len2)) {
RETVAL_FALSE;
efree(buf);
EVP_CIPHER_CTX_cleanup(&ctx);
goto clean_exit;
}
- EVP_SealFinal(&ctx, buf + len1, &len2);
-
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
- /* If allow ciphers that need IV, we need this */
- zval_dtor(*ivec);
- if (ivlen) {
- iv[ivlen] = '\0';
- ZVAL_STRINGL(*ivec, erealloc(iv, ivlen + 1), ivlen, 0);
- } else {
- ZVAL_EMPTY_STRING(*ivec);
+
+ if (iv) {
+ zval_dtor(iv);
+ iv_buf[iv_len] = '\0';
+ ZVAL_NEW_STR(iv, zend_string_init((char*)iv_buf, iv_len, 0));
}
-#endif
} else {
efree(buf);
}
@@ -5022,10 +5070,10 @@ PHP_FUNCTION(openssl_seal)
clean_exit:
for (i=0; i<nkeys; i++) {
- if (key_resources[i] == -1) {
+ if (key_resources[i] == NULL && pkeys[i] != NULL) {
EVP_PKEY_free(pkeys[i]);
}
- if (eks[i]) {
+ if (eks[i]) {
efree(eks[i]);
}
}
@@ -5040,73 +5088,95 @@ 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;
+ int len1, len2, cipher_iv_len;
+ unsigned char *buf, *iv_buf;
+ zend_resource *keyresource = NULL;
EVP_CIPHER_CTX ctx;
- char * data; int data_len;
- char * ekey; int ekey_len;
- char *method =NULL;
- int method_len = 0;
+ char * data;
+ size_t data_len;
+ char * ekey;
+ size_t ekey_len;
+ char *method = NULL, *iv = NULL;
+ size_t method_len = 0, iv_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(), "sz/sz|ss", &data, &data_len, &opendata,
+ &ekey, &ekey_len, &privkey, &method, &method_len, &iv, &iv_len) == FAILURE) {
return;
}
- pkey = php_openssl_evp_from_zval(privkey, 0, "", 0, &keyresource TSRMLS_CC);
+ pkey = php_openssl_evp_from_zval(privkey, 0, "", 0, &keyresource);
if (pkey == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to coerce parameter 4 into a private key");
+ php_error_docref(NULL, E_WARNING, "unable to coerce parameter 4 into a private key");
RETURN_FALSE;
}
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT(ekey_len, ekey);
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT(data_len, data);
+
if (method) {
cipher = EVP_get_cipherbyname(method);
if (!cipher) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature algorithm.");
+ php_error_docref(NULL, E_WARNING, "Unknown signature algorithm.");
RETURN_FALSE;
}
} else {
cipher = EVP_rc4();
}
-
+
+ cipher_iv_len = EVP_CIPHER_iv_length(cipher);
+ if (cipher_iv_len > 0) {
+ if (!iv) {
+ php_error_docref(NULL, E_WARNING,
+ "Cipher algorithm requires an IV to be supplied as a sixth parameter");
+ RETURN_FALSE;
+ }
+ if (cipher_iv_len != iv_len) {
+ php_error_docref(NULL, E_WARNING, "IV length is invalid");
+ RETURN_FALSE;
+ }
+ iv_buf = (unsigned char *)iv;
+ } else {
+ iv_buf = NULL;
+ }
+
buf = emalloc(data_len + 1);
- if (EVP_OpenInit(&ctx, cipher, (unsigned char *)ekey, ekey_len, NULL, pkey) && EVP_OpenUpdate(&ctx, buf, &len1, (unsigned char *)data, data_len)) {
+ if (EVP_OpenInit(&ctx, cipher, (unsigned char *)ekey, (int)ekey_len, iv_buf, pkey) &&
+ EVP_OpenUpdate(&ctx, buf, &len1, (unsigned char *)data, (int)data_len)) {
if (!EVP_OpenFinal(&ctx, buf + len1, &len2) || (len1 + len2 == 0)) {
efree(buf);
RETVAL_FALSE;
} else {
zval_dtor(opendata);
buf[len1 + len2] = '\0';
- ZVAL_STRINGL(opendata, erealloc(buf, len1 + len2 + 1), len1 + len2, 0);
+ ZVAL_NEW_STR(opendata, zend_string_init((char*)buf, len1 + len2, 0));
+ efree(buf);
RETVAL_TRUE;
}
} else {
efree(buf);
RETVAL_FALSE;
}
- if (keyresource == -1) {
+ if (keyresource == NULL) {
EVP_PKEY_free(pkey);
}
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);
}
}
/* }}} */
@@ -5117,12 +5187,12 @@ PHP_FUNCTION(openssl_get_md_methods)
{
zend_bool aliases = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &aliases) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &aliases) == FAILURE) {
return;
}
array_init(return_value);
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH,
- aliases ? openssl_add_method_or_alias: openssl_add_method,
+ aliases ? openssl_add_method_or_alias: openssl_add_method,
return_value);
}
/* }}} */
@@ -5133,12 +5203,12 @@ PHP_FUNCTION(openssl_get_cipher_methods)
{
zend_bool aliases = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &aliases) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &aliases) == FAILURE) {
return;
}
array_init(return_value);
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
- aliases ? openssl_add_method_or_alias: openssl_add_method,
+ aliases ? openssl_add_method_or_alias: openssl_add_method,
return_value);
}
/* }}} */
@@ -5149,46 +5219,48 @@ 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) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|b", &data, &data_len, &method, &method_len, &raw_output) == FAILURE) {
return;
}
mdtype = EVP_get_digestbyname(method);
if (!mdtype) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature algorithm");
+ php_error_docref(NULL, E_WARNING, "Unknown signature algorithm");
RETURN_FALSE;
}
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 *)ZSTR_VAL(sigbuf), &siglen)) {
if (raw_output) {
- sigbuf[siglen] = '\0';
- RETVAL_STRINGL((char *)sigbuf, siglen, 0);
+ ZSTR_VAL(sigbuf)[siglen] = '\0';
+ ZSTR_LEN(sigbuf) = 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(ZSTR_VAL(digest_str), (unsigned char*)ZSTR_VAL(sigbuf), siglen);
+ ZSTR_VAL(digest_str)[digest_str_len] = '\0';
+ zend_string_release(sigbuf);
+ RETVAL_STR(digest_str);
}
} else {
- efree(sigbuf);
+ zend_string_release(sigbuf);
RETVAL_FALSE;
}
}
/* }}} */
-static zend_bool php_openssl_validate_iv(char **piv, int *piv_len, int iv_required_len TSRMLS_DC)
+static zend_bool php_openssl_validate_iv(char **piv, size_t *piv_len, size_t iv_required_len)
{
char *iv_new;
@@ -5199,25 +5271,25 @@ static zend_bool php_openssl_validate_iv(char **piv, int *piv_len, int iv_requir
iv_new = ecalloc(1, iv_required_len + 1);
- if (*piv_len <= 0) {
+ if (*piv_len == 0) {
/* BC behavior */
*piv_len = iv_required_len;
- *piv = iv_new;
+ *piv = iv_new;
return 1;
}
if (*piv_len < iv_required_len) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "IV passed is only %d bytes long, cipher expects an IV of precisely %d bytes, padding with \\0", *piv_len, iv_required_len);
+ php_error_docref(NULL, E_WARNING, "IV passed is only %zd bytes long, cipher expects an IV of precisely %zd bytes, padding with \\0", *piv_len, iv_required_len);
memcpy(iv_new, *piv, *piv_len);
*piv_len = iv_required_len;
- *piv = iv_new;
+ *piv = iv_new;
return 1;
}
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "IV passed is %d bytes long which is longer than the %d expected by selected cipher, truncating", *piv_len, iv_required_len);
+ php_error_docref(NULL, E_WARNING, "IV passed is %zd bytes long which is longer than the %zd expected by selected cipher, truncating", *piv_len, iv_required_len);
memcpy(iv_new, *piv, iv_required_len);
*piv_len = iv_required_len;
- *piv = iv_new;
+ *piv = iv_new;
return 1;
}
@@ -5226,24 +5298,28 @@ 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;
+ int i=0, keylen;
+ size_t outlen;
+ 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) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|ls", &data, &data_len, &method, &method_len, &password, &password_len, &options, &iv, &iv_len) == FAILURE) {
return;
}
cipher_type = EVP_get_cipherbyname(method);
if (!cipher_type) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown cipher algorithm");
+ php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
RETURN_FALSE;
}
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT(data_len, data);
+
keylen = EVP_CIPHER_key_length(cipher_type);
if (keylen > password_len) {
key = emalloc(keylen);
@@ -5254,45 +5330,42 @@ PHP_FUNCTION(openssl_encrypt)
}
max_iv_len = EVP_CIPHER_iv_length(cipher_type);
- 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");
+ if (iv_len == 0 && max_iv_len > 0) {
+ php_error_docref(NULL, 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, &iv_len, max_iv_len);
outlen = data_len + EVP_CIPHER_block_size(cipher_type);
- outbuf = safe_emalloc(outlen, 1, 1);
+ outbuf = zend_string_alloc(outlen, 0);
EVP_EncryptInit(&cipher_ctx, cipher_type, NULL, NULL);
if (password_len > keylen) {
- EVP_CIPHER_CTX_set_key_length(&cipher_ctx, password_len);
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT(password_len, password);
+ EVP_CIPHER_CTX_set_key_length(&cipher_ctx, (int)password_len);
}
EVP_EncryptInit_ex(&cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
if (options & OPENSSL_ZERO_PADDING) {
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*)ZSTR_VAL(outbuf), &i, (unsigned char *)data, (int)data_len);
}
outlen = i;
- if (EVP_EncryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) {
+ if (EVP_EncryptFinal(&cipher_ctx, (unsigned char *)ZSTR_VAL(outbuf) + i, &i)) {
outlen += i;
if (options & OPENSSL_RAW_DATA) {
- outbuf[outlen] = '\0';
- RETVAL_STRINGL_CHECK((char *)outbuf, outlen, 0);
+ ZSTR_VAL(outbuf)[outlen] = '\0';
+ ZSTR_LEN(outbuf) = 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);
- if (!base64_str) {
- RETVAL_FALSE;
- } else {
- RETVAL_STRINGL(base64_str, base64_str_len, 0);
- }
+ base64_str = php_base64_encode((unsigned char*)ZSTR_VAL(outbuf), outlen);
+ zend_string_release(outbuf);
+ RETVAL_STR(base64_str);
}
} else {
- efree(outbuf);
+ zend_string_release(outbuf);
RETVAL_FALSE;
}
if (key != (unsigned char*)password) {
@@ -5306,43 +5379,46 @@ PHP_FUNCTION(openssl_encrypt)
/* }}} */
/* {{{ proto string openssl_decrypt(string data, string method, string password [, long options=0 [, string $iv = '']])
- Takes raw or base64 encoded string and dectupt it using given method and key */
+ Takes raw or base64 encoded string and decrypts 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;
+ int i, keylen;
+ size_t outlen;
+ 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) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|ls", &data, &data_len, &method, &method_len, &password, &password_len, &options, &iv, &iv_len) == FAILURE) {
return;
}
if (!method_len) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown cipher algorithm");
+ php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
RETURN_FALSE;
}
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT(data_len, data);
+
cipher_type = EVP_get_cipherbyname(method);
if (!cipher_type) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown cipher algorithm");
+ php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
RETURN_FALSE;
}
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");
+ php_error_docref(NULL, E_WARNING, "Failed to base64 decode the input");
RETURN_FALSE;
}
- data_len = base64_str_len;
- data = base64_str;
+ data_len = ZSTR_LEN(base64_str);
+ data = ZSTR_VAL(base64_str);
}
keylen = EVP_CIPHER_key_length(cipher_type);
@@ -5354,27 +5430,29 @@ 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, &iv_len, EVP_CIPHER_iv_length(cipher_type));
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) {
- EVP_CIPHER_CTX_set_key_length(&cipher_ctx, password_len);
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT(password_len, password);
+ EVP_CIPHER_CTX_set_key_length(&cipher_ctx, (int)password_len);
}
EVP_DecryptInit_ex(&cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
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*)ZSTR_VAL(outbuf), &i, (unsigned char *)data, (int)data_len);
outlen = i;
- if (EVP_DecryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) {
+ if (EVP_DecryptFinal(&cipher_ctx, (unsigned char *)ZSTR_VAL(outbuf) + i, &i)) {
outlen += i;
- outbuf[outlen] = '\0';
- RETVAL_STRINGL((char *)outbuf, outlen, 0);
+ ZSTR_VAL(outbuf)[outlen] = '\0';
+ ZSTR_LEN(outbuf) = outlen;
+ RETVAL_STR(outbuf);
} else {
- efree(outbuf);
+ zend_string_release(outbuf);
RETVAL_FALSE;
}
if (key != (unsigned char*)password) {
@@ -5384,7 +5462,7 @@ PHP_FUNCTION(openssl_decrypt)
efree(iv);
}
if (base64_str) {
- efree(base64_str);
+ zend_string_release(base64_str);
}
EVP_CIPHER_CTX_cleanup(&cipher_ctx);
}
@@ -5394,21 +5472,21 @@ 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) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &method, &method_len) == FAILURE) {
return;
}
if (!method_len) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown cipher algorithm");
+ php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
RETURN_FALSE;
}
cipher_type = EVP_get_cipherbyname(method);
if (!cipher_type) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown cipher algorithm");
+ php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
RETURN_FALSE;
}
@@ -5423,30 +5501,34 @@ 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) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sr", &pub_str, &pub_len, &key) == FAILURE) {
return;
}
- 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) {
+ if ((pkey = (EVP_PKEY *)zend_fetch_resource(Z_RES_P(key), "OpenSSL key", le_key)) == NULL) {
+ RETURN_FALSE;
+ }
+ if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DH || !pkey->pkey.dh) {
RETURN_FALSE;
}
- pub = BN_bin2bn((unsigned char*)pub_str, pub_len, NULL);
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT(pub_len, pub_key);
+ pub = BN_bin2bn((unsigned char*)pub_str, (int)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*)ZSTR_VAL(data), pub, pkey->pkey.dh);
if (len >= 0) {
- data[len] = 0;
- RETVAL_STRINGL(data, len, 0);
+ ZSTR_LEN(data) = len;
+ ZSTR_VAL(data)[len] = 0;
+ RETVAL_STR(data);
} else {
- efree(data);
+ zend_string_release(data);
RETVAL_FALSE;
}
@@ -5458,47 +5540,53 @@ 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;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|z", &buffer_length, &zstrong_result_returned) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|z/", &buffer_length, &zstrong_result_returned) == FAILURE) {
return;
}
if (zstrong_result_returned) {
zval_dtor(zstrong_result_returned);
- ZVAL_BOOL(zstrong_result_returned, 0);
+ ZVAL_FALSE(zstrong_result_returned);
}
- if (buffer_length <= 0 || buffer_length > INT_MAX) {
+ if (buffer_length <= 0
+#ifndef PHP_WIN32
+ || ZEND_LONG_INT_OVFL(buffer_length)
+#endif
+ ) {
RETURN_FALSE;
}
-
- buffer = safe_emalloc(buffer_length, 1, 1);
+ buffer = zend_string_alloc(buffer_length, 0);
#ifdef PHP_WIN32
/* 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);
+ ZVAL_FALSE(zstrong_result_returned);
}
RETURN_FALSE;
}
#else
+
+ PHP_OPENSSL_CHECK_LONG_TO_INT(buffer_length, length);
PHP_OPENSSL_RAND_ADD_TIME();
- if (RAND_bytes(buffer, buffer_length) <= 0) {
- efree(buffer);
+ /* FIXME loop if requested size > INT_MAX */
+ if (RAND_bytes((unsigned char*)ZSTR_VAL(buffer), (int)buffer_length) <= 0) {
+ zend_string_release(buffer);
if (zstrong_result_returned) {
- ZVAL_BOOL(zstrong_result_returned, 0);
+ ZVAL_FALSE(zstrong_result_returned);
}
RETURN_FALSE;
}
#endif
- buffer[buffer_length] = 0;
- RETVAL_STRINGL((char *)buffer, buffer_length, 0);
+ ZSTR_VAL(buffer)[buffer_length] = 0;
+ RETVAL_STR(buffer);
if (zstrong_result_returned) {
ZVAL_BOOL(zstrong_result_returned, 1);
diff --git a/ext/openssl/openssl.dsp b/ext/openssl/openssl.dsp
deleted file mode 100644
index 857666a6a3..0000000000
--- a/ext/openssl/openssl.dsp
+++ /dev/null
@@ -1,111 +0,0 @@
-# Microsoft Developer Studio Project File - Name="openssl" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-
-CFG=openssl - Win32 Debug_TS
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "openssl.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "openssl.mak" CFG="openssl - Win32 Debug_TS"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "openssl - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "openssl - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "openssl - Win32 Release_TS"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release_TS"
-# PROP BASE Intermediate_Dir "Release_TS"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release_TS"
-# PROP Intermediate_Dir "Release_TS"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OPENSSL_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\TSRM" /D ZEND_DEBUG=0 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "COMPILE_DL_OPENSSL" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_OPENSSL_EXT=1 /YX /FD /c
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x407 /d "NDEBUG"
-# ADD RSC /l 0x407 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 php5ts.lib ssleay32.lib libeay32.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_openssl.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline"
-
-!ELSEIF "$(CFG)" == "openssl - Win32 Debug_TS"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug_TS"
-# PROP BASE Intermediate_Dir "Debug_TS"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug_TS"
-# PROP Intermediate_Dir "Debug_TS"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OPENSSL_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\TSRM" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "COMPILE_DL_OPENSSL" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_OPENSSL_EXT=1 /YX /FD /GZ /c
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x407 /d "_DEBUG"
-# ADD RSC /l 0x407 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 php5ts_debug.lib ssleay32.lib libeay32.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS/php_openssl.dll" /pdbtype:sept /libpath:"..\..\Debug_TS"
-
-!ENDIF
-
-# Begin Target
-
-# Name "openssl - Win32 Release_TS"
-# Name "openssl - Win32 Debug_TS"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\openssl.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\xp_ssl.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\php_openssl.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/ext/openssl/openssl.mak b/ext/openssl/openssl.mak
index a0c6fa483e..9bc053b662 100644
--- a/ext/openssl/openssl.mak
+++ b/ext/openssl/openssl.mak
@@ -4,7 +4,7 @@ PROJECT_ROOT = ..\..
# Module details
MODULE_NAME = php_ossl
-MODULE_DESC = "PHP 5 - OpenSSL Extension"
+MODULE_DESC = "PHP 7 - OpenSSL Extension"
VMAJ = 1
VMIN = 0
VREV = 0
diff --git a/ext/openssl/php_openssl.h b/ext/openssl/php_openssl.h
index 36b8bbbeb9..92e01241f4 100644
--- a/ext/openssl/php_openssl.h
+++ b/ext/openssl/php_openssl.h
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 5 |
+ | PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2016 The PHP Group |
+----------------------------------------------------------------------+
@@ -26,6 +26,9 @@
extern zend_module_entry openssl_module_entry;
#define phpext_openssl_ptr &openssl_module_entry
+#include "php_version.h"
+#define PHP_OPENSSL_VERSION PHP_VERSION
+
#define OPENSSL_RAW_DATA 1
#define OPENSSL_ZERO_PADDING 2
diff --git a/ext/openssl/tests/bug60632.phpt b/ext/openssl/tests/bug60632.phpt
index a4b473112b..eb51276fa5 100644
--- a/ext/openssl/tests/bug60632.phpt
+++ b/ext/openssl/tests/bug60632.phpt
@@ -6,6 +6,7 @@ if (!extension_loaded("openssl")) die("skip openssl not loaded");
?>
--FILE--
<?php
+
$pkey = openssl_pkey_new(array(
'digest_alg' => 'sha256',
'private_key_bits' => 1024,
@@ -22,5 +23,5 @@ $result = openssl_seal('test phrase', $encrypted, $ekeys, array($pubkey), 'AES-2
echo "Done";
?>
--EXPECTF--
-Warning: openssl_seal(): Ciphers with modes requiring IV are not supported in %s on line %d
+Warning: openssl_seal(): Cipher algorithm requires an IV to be supplied as a sixth parameter in %s on line %d
Done
diff --git a/ext/openssl/tests/bug70438.phpt b/ext/openssl/tests/bug70438.phpt
new file mode 100644
index 0000000000..937e9f3bd9
--- /dev/null
+++ b/ext/openssl/tests/bug70438.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Request #70438: Add IV parameter for openssl_seal and openssl_open
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl")) {
+ print "skip";
+}
+if (!in_array('AES-128-CBC', openssl_get_cipher_methods(true))) {
+ print "skip";
+}
+?>
+--FILE--
+<?php
+$data = "openssl_seal() test";
+$cipher = 'AES-128-CBC';
+$pub_key = "file://" . dirname(__FILE__) . "/public.key";
+$priv_key = "file://" . dirname(__FILE__) . "/private_rsa_1024.key";
+
+openssl_seal($data, $sealed, $ekeys, array($pub_key, $pub_key), $cipher);
+openssl_seal($data, $sealed, $ekeys, array($pub_key, $pub_key), 'sparkles', $iv);
+openssl_seal($data, $sealed, $ekeys, array($pub_key, $pub_key), $cipher, $iv);
+openssl_open($sealed, $decrypted, $ekeys[0], $priv_key, $cipher, $iv);
+echo $decrypted;
+?>
+--EXPECTF--
+Warning: openssl_seal(): Cipher algorithm requires an IV to be supplied as a sixth parameter in %s on line %d
+
+Warning: openssl_seal(): Unknown signature algorithm. in %s on line %d
+openssl_seal() test
diff --git a/ext/openssl/tests/bug71475.phpt b/ext/openssl/tests/bug71475.phpt
new file mode 100644
index 0000000000..e959371c4c
--- /dev/null
+++ b/ext/openssl/tests/bug71475.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Bug #71475: openssl_seal() uninitialized memory usage
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl")) die("skip openssl not loaded");
+?>
+--FILE--
+<?php
+$_ = str_repeat("A", 512);
+openssl_seal($_, $_, $_, array_fill(0,64,0));
+?>
+DONE
+--EXPECTF--
+
+Warning: openssl_seal(): not a public key (1th member of pubkeys) in %s%ebug71475.php on line %d
+DONE
diff --git a/ext/openssl/tests/bug72165.phpt b/ext/openssl/tests/bug72165.phpt
new file mode 100644
index 0000000000..93b3c3d4a8
--- /dev/null
+++ b/ext/openssl/tests/bug72165.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #72165 Null pointer dereference - openssl_csr_new
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl")) die("skip");
+?>
+--FILE--
+<?php
+$var0 = array(0 => "hello", 1 => "world");
+$var2 = openssl_csr_new(array(0),$var0,null,array(0));
+?>
+==DONE==
+--EXPECTF--
+Warning: openssl_csr_new(): dn: numeric fild names are not supported in %sbug72165.php on line %d
+
+Warning: openssl_csr_new(): add1_attr_by_txt challengePassword_min -> 4 (failed; check error queue and value of string_mask OpenSSL option if illegal characters are reported) in %sbug72165.php on line %d
+==DONE==
diff --git a/ext/openssl/tests/openssl_csr_sign_basic.phpt b/ext/openssl/tests/openssl_csr_sign_basic.phpt
index ae948e3d25..34cf50a997 100644
--- a/ext/openssl/tests/openssl_csr_sign_basic.phpt
+++ b/ext/openssl/tests/openssl_csr_sign_basic.phpt
@@ -54,7 +54,7 @@ bool(false)
Warning: openssl_csr_sign(): cannot get private key from parameter 3 in %s on line %d
bool(false)
-Warning: openssl_csr_sign() expects parameter 4 to be long, string given in %s on line %d
+Warning: openssl_csr_sign() expects parameter 4 to be integer, string given in %s on line %d
NULL
Warning: openssl_csr_sign() expects parameter 5 to be array, string given in %s on line %d
@@ -74,7 +74,7 @@ Warning: openssl_csr_sign(): key array must be of the form array(0 => key, 1 =>
Warning: openssl_csr_sign(): cannot get private key from parameter 3 in %s on line %d
bool(false)
-Warning: openssl_csr_sign() expects parameter 4 to be long, array given in %s on line %d
+Warning: openssl_csr_sign() expects parameter 4 to be integer, array given in %s on line %d
NULL
resource(%d) of type (OpenSSL X.509)
diff --git a/ext/openssl/tests/openssl_free_key.phpt b/ext/openssl/tests/openssl_free_key.phpt
new file mode 100644
index 0000000000..816f7cf5eb
--- /dev/null
+++ b/ext/openssl/tests/openssl_free_key.phpt
@@ -0,0 +1,77 @@
+--TEST--
+void openssl_free_key ( resource $key_identifier );
+--CREDITS--
+marcosptf - <marcosptf@yahoo.com.br> - @phpsp - sao paulo - br
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl"))
+ die("skip");
+if (!@openssl_pkey_new())
+ die("skip cannot create private key");
+?>
+--FILE--
+<?php
+echo "Creating private key\n";
+
+/* stack up some entropy; performance is not critical,
+ * and being slow will most likely even help the test.
+ */
+for ($z = "", $i = 0; $i < 1024; $i++) {
+ $z .= $i * $i;
+ if (function_exists("usleep"))
+ usleep($i);
+}
+
+$privkey = openssl_pkey_new();
+
+if ($privkey === false)
+ die("failed to create private key");
+
+$passphrase = "banana";
+$key_file_name = tempnam(sys_get_temp_dir(), "ssl");
+if ($key_file_name === false)
+ die("failed to get a temporary filename!");
+
+echo "Export key to file\n";
+
+openssl_pkey_export_to_file($privkey, $key_file_name, $passphrase) or die("failed to export to file $key_file_name");
+
+echo "Load key from file - array syntax\n";
+
+$loaded_key = openssl_pkey_get_private(array("file://$key_file_name", $passphrase));
+
+if ($loaded_key === false)
+ die("failed to load key using array syntax");
+
+openssl_free_key($loaded_key);
+
+echo "Load key using direct syntax\n";
+
+$loaded_key = openssl_pkey_get_private("file://$key_file_name", $passphrase);
+
+if ($loaded_key === false)
+ die("failed to load key using direct syntax");
+
+openssl_free_key($loaded_key);
+
+echo "Load key manually and use string syntax\n";
+
+$key_content = file_get_contents($key_file_name);
+$loaded_key = openssl_pkey_get_private($key_content, $passphrase);
+
+if ($loaded_key === false)
+ die("failed to load key using string syntax");
+
+openssl_free_key($loaded_key);
+
+echo "OK!\n";
+
+@unlink($key_file_name);
+?>
+--EXPECT--
+Creating private key
+Export key to file
+Load key from file - array syntax
+Load key using direct syntax
+Load key manually and use string syntax
+OK!
diff --git a/ext/openssl/tests/openssl_pkcs7_decrypt_error.phpt b/ext/openssl/tests/openssl_pkcs7_decrypt_error.phpt
index 0fdb9856eb..e8ba264550 100644
--- a/ext/openssl/tests/openssl_pkcs7_decrypt_error.phpt
+++ b/ext/openssl/tests/openssl_pkcs7_decrypt_error.phpt
@@ -27,7 +27,6 @@ echo "Done\n";
?>
--EXPECTF--
string(57) "Object of class stdClass could not be converted to string"
-string(45) "Object of class stdClass to string conversion"
string(66) "openssl_pkcs7_decrypt(): unable to coerce parameter 3 to x509 cert"
bool(false)
object(stdClass)#1 (0) {
diff --git a/ext/openssl/tests/openssl_x509_checkpurpose.phpt b/ext/openssl/tests/openssl_x509_checkpurpose.phpt
new file mode 100644
index 0000000000..2126330a02
--- /dev/null
+++ b/ext/openssl/tests/openssl_x509_checkpurpose.phpt
@@ -0,0 +1,149 @@
+--TEST--
+int openssl_x509_checkpurpose ( mixed $x509cert , int $purpose [, array $cainfo = array() [, string $untrustedfile ]] ) function
+--CREDITS--
+marcosptf - <marcosptf@yahoo.com.br>
+--SKIPIF--
+<?php if (!extension_loaded("openssl")) print "skip";
+if (OPENSSL_VERSION_NUMBER < 0x10000000) die("skip Output requires OpenSSL 1.0");
+?>
+--FILE--
+<?php
+$cert = "file://" . dirname(__FILE__) . "/cert.crt";
+$bert = "file://" . dirname(__FILE__) . "/bug41033.pem";
+$sert = "file://" . dirname(__FILE__) . "/san-cert.pem";
+$cpca = dirname(__FILE__) . "/san-ca.pem";
+$utfl = dirname(__FILE__) . "/sni_server_domain1.pem";
+
+/* int openssl_x509_checkpurpose ( mixed $x509cert , int $purpose); */
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_SSL_CLIENT));
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_SSL_SERVER));
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_NS_SSL_SERVER));
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_SMIME_SIGN));
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_SMIME_ENCRYPT));
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_CRL_SIGN));
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_ANY));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_SSL_CLIENT));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_SSL_SERVER));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_NS_SSL_SERVER));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_SMIME_SIGN));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_SMIME_ENCRYPT));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_CRL_SIGN));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_ANY));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_SSL_CLIENT));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_SSL_SERVER));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_NS_SSL_SERVER));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_SMIME_SIGN));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_SMIME_ENCRYPT));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_CRL_SIGN));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_ANY));
+
+/* int openssl_x509_checkpurpose ( mixed $x509cert , int $purpose [, array $cainfo = array() ] ); */
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_SSL_CLIENT, array($cpca)));
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_SSL_SERVER, array($cpca)));
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_NS_SSL_SERVER, array($cpca)));
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_SMIME_SIGN, array($cpca)));
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_SMIME_ENCRYPT, array($cpca)));
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_CRL_SIGN, array($cpca)));
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_ANY, array($cpca)));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_SSL_CLIENT, array($cpca)));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_SSL_SERVER, array($cpca)));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_NS_SSL_SERVER, array($cpca)));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_SMIME_SIGN, array($cpca)));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_SMIME_ENCRYPT, array($cpca)));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_CRL_SIGN, array($cpca)));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_ANY, array($cpca)));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_SSL_CLIENT, array($cpca)));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_SSL_SERVER, array($cpca)));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_NS_SSL_SERVER, array($cpca)));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_SMIME_SIGN, array($cpca)));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_SMIME_ENCRYPT, array($cpca)));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_CRL_SIGN, array($cpca)));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_ANY, array($cpca)));
+
+/* int openssl_x509_checkpurpose ( mixed $x509cert , int $purpose [, array $cainfo = array() [, string $untrustedfile ]] ); function */
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_SSL_CLIENT, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_SSL_SERVER, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_NS_SSL_SERVER, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_SMIME_SIGN, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_SMIME_ENCRYPT, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_CRL_SIGN, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($cert, X509_PURPOSE_ANY, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_SSL_CLIENT, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_SSL_SERVER, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_NS_SSL_SERVER, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_SMIME_SIGN, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_SMIME_ENCRYPT, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_CRL_SIGN, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($bert, X509_PURPOSE_ANY, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_SSL_CLIENT, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_SSL_SERVER, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_NS_SSL_SERVER, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_SMIME_SIGN, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_SMIME_ENCRYPT, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_CRL_SIGN, array($cpca), $utfl));
+var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_ANY, array($cpca), $utfl));
+?>
+--EXPECT--
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+int(-1)
+int(-1)
+int(-1)
+int(-1)
+int(-1)
+int(-1)
+int(-1)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+int(-1)
+int(-1)
+int(-1)
+int(-1)
+int(-1)
+int(-1)
+int(-1)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+int(-1)
+int(-1)
+int(-1)
+int(-1)
+int(-1)
+int(-1)
+int(-1)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
diff --git a/ext/openssl/tests/openssl_x509_export_basic.phpt b/ext/openssl/tests/openssl_x509_export_basic.phpt
index cfe1cad524..4177bd7798 100644
--- a/ext/openssl/tests/openssl_x509_export_basic.phpt
+++ b/ext/openssl/tests/openssl_x509_export_basic.phpt
@@ -18,6 +18,10 @@ var_dump(openssl_x509_export($c, $output3)); // read an invalid cert, fails
var_dump(openssl_x509_export($d, $output4)); // read cert from a resource
var_dump(openssl_x509_export($e, $output5)); // read an array, fails
+if (PHP_EOL !== "\n") {
+ $a = str_replace(PHP_EOL, "\n", $a);
+}
+
var_dump(strcmp($output, $a));
var_dump(strcmp($output, $output2));
var_dump(strcmp($output, $output3));
diff --git a/ext/openssl/tests/session_meta_capture.phpt b/ext/openssl/tests/session_meta_capture.phpt
index 650d5c6959..a09d7e8780 100644
--- a/ext/openssl/tests/session_meta_capture.phpt
+++ b/ext/openssl/tests/session_meta_capture.phpt
@@ -36,17 +36,17 @@ $clientCode = <<<'CODE'
phpt_wait();
stream_context_set_option($clientCtx, 'ssl', 'crypto_method', STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT);
- stream_socket_client($serverUri, $errno, $errstr, 1, $clientFlags, $clientCtx);
+ @stream_socket_client($serverUri, $errno, $errstr, 1, $clientFlags, $clientCtx);
$meta = stream_context_get_options($clientCtx)['ssl']['session_meta'];
var_dump($meta['protocol']);
stream_context_set_option($clientCtx, 'ssl', 'crypto_method', STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT);
- stream_socket_client($serverUri, $errno, $errstr, 1, $clientFlags, $clientCtx);
+ @stream_socket_client($serverUri, $errno, $errstr, 1, $clientFlags, $clientCtx);
$meta = stream_context_get_options($clientCtx)['ssl']['session_meta'];
var_dump($meta['protocol']);
stream_context_set_option($clientCtx, 'ssl', 'crypto_method', STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT);
- stream_socket_client($serverUri, $errno, $errstr, 2, $clientFlags, $clientCtx);
+ @stream_socket_client($serverUri, $errno, $errstr, 2, $clientFlags, $clientCtx);
$meta = stream_context_get_options($clientCtx)['ssl']['session_meta'];
var_dump($meta['protocol']);
CODE;
diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c
index d5490331d6..208aafcd7b 100644
--- a/ext/openssl/xp_ssl.c
+++ b/ext/openssl/xp_ssl.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 5 |
+ | PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2016 The PHP Group |
+----------------------------------------------------------------------+
@@ -28,14 +28,20 @@
#include "ext/standard/file.h"
#include "ext/standard/url.h"
#include "streams/php_streams_int.h"
-#include "ext/standard/php_smart_str.h"
+#include "zend_smart_str.h"
#include "php_openssl.h"
#include "php_network.h"
#include <openssl/ssl.h>
+#include <openssl/rsa.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#endif
+
#ifdef PHP_WIN32
#include "win32/winutil.h"
#include "win32/time.h"
@@ -50,13 +56,33 @@
#include <sys/select.h>
#endif
+/* OpenSSL 1.0.2 removes SSLv2 support entirely*/
+#if OPENSSL_VERSION_NUMBER < 0x10002000L && !defined(OPENSSL_NO_SSL2)
+#define HAVE_SSL2 1
+#endif
+
+#ifndef OPENSSL_NO_SSL3
+#define HAVE_SSL3 1
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+#define HAVE_TLS11 1
+#define HAVE_TLS12 1
+#endif
+
#if !defined(OPENSSL_NO_ECDH) && OPENSSL_VERSION_NUMBER >= 0x0090800fL
#define HAVE_ECDH 1
#endif
-#if OPENSSL_VERSION_NUMBER >= 0x00908070L && !defined(OPENSSL_NO_TLSEXT)
-#define HAVE_SNI 1
+#if !defined(OPENSSL_NO_TLSEXT)
+#if OPENSSL_VERSION_NUMBER >= 0x00908070L
+#define HAVE_TLS_SNI 1
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+#define HAVE_TLS_ALPN 1
+#endif
+#endif
+
/* Flags for determining allowed stream crypto methods */
#define STREAM_CRYPTO_IS_CLIENT (1<<0)
@@ -67,20 +93,24 @@
#define STREAM_CRYPTO_METHOD_TLSv1_2 (1<<5)
/* Simplify ssl context option retrieval */
-#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); }
-#define GET_VER_OPT_LONG(name, num) if (GET_VER_OPT(name)) { convert_to_long_ex(val); num = Z_LVAL_PP(val); }
+#define GET_VER_OPT(name) (PHP_STREAM_CONTEXT(stream) && (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", name)) != NULL)
+#define GET_VER_OPT_STRING(name, str) if (GET_VER_OPT(name)) { convert_to_string_ex(val); str = Z_STRVAL_P(val); }
+#define GET_VER_OPT_LONG(name, num) if (GET_VER_OPT(name)) { convert_to_long_ex(val); num = Z_LVAL_P(val); }
/* Used for peer verification in windows */
#define PHP_X509_NAME_ENTRY_TO_UTF8(ne, i, out) ASN1_STRING_to_UTF8(&out, X509_NAME_ENTRY_get_data(X509_NAME_get_entry(ne, i)))
+#ifndef OPENSSL_NO_RSA
+static RSA *tmp_rsa_cb(SSL *s, int is_export, int keylength);
+#endif
+
extern php_stream* php_openssl_get_stream_from_ssl_handle(const SSL *ssl);
-extern int php_openssl_x509_fingerprint(X509 *peer, const char *method, zend_bool raw, char **out, int *out_len TSRMLS_DC);
+extern zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, zend_bool raw);
extern int php_openssl_get_ssl_stream_data_index();
extern int php_openssl_get_x509_list_id(void);
static struct timeval subtract_timeval( struct timeval a, struct timeval b );
static int compare_timeval( struct timeval a, struct timeval b );
-static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, size_t count TSRMLS_DC);
+static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, size_t count);
php_stream_ops php_openssl_socket_ops;
@@ -92,13 +122,21 @@ typedef struct _php_openssl_sni_cert_t {
/* Provides leaky bucket handhsake renegotiation rate-limiting */
typedef struct _php_openssl_handshake_bucket_t {
- long prev_handshake;
- long limit;
- long window;
+ zend_long prev_handshake;
+ zend_long limit;
+ zend_long window;
float tokens;
unsigned should_close;
} php_openssl_handshake_bucket_t;
+#ifdef HAVE_TLS_ALPN
+/* Holds the available server ALPN protocols for negotiation */
+typedef struct _php_openssl_alpn_ctx_t {
+ unsigned char *data;
+ unsigned short len;
+} php_openssl_alpn_ctx;
+#endif
+
/* This implementation is very closely tied to the that of the native
* sockets implemented in the core.
* Don't try this technique in other extensions!
@@ -115,6 +153,9 @@ typedef struct _php_openssl_netstream_data_t {
php_openssl_handshake_bucket_t *reneg;
php_openssl_sni_cert_t *sni_certs;
unsigned sni_cert_count;
+#ifdef HAVE_TLS_ALPN
+ php_openssl_alpn_ctx *alpn_ctx;
+#endif
char *url_name;
unsigned state_set:1;
unsigned _spare:31;
@@ -122,32 +163,28 @@ typedef struct _php_openssl_netstream_data_t {
/* it doesn't matter that we do some hash traversal here, since it is done only
* in an error condition arising from a network connection problem */
-static int is_http_stream_talking_to_iis(php_stream *stream TSRMLS_DC) /* {{{ */
+static int is_http_stream_talking_to_iis(php_stream *stream) /* {{{ */
{
- if (stream->wrapperdata && stream->wrapper && strcasecmp(stream->wrapper->wops->label, "HTTP") == 0) {
+ if (Z_TYPE(stream->wrapperdata) == IS_ARRAY && stream->wrapper && strcasecmp(stream->wrapper->wops->label, "HTTP") == 0) {
/* the wrapperdata is an array zval containing the headers */
- zval **tmp;
+ zval *tmp;
#define SERVER_MICROSOFT_IIS "Server: Microsoft-IIS"
#define SERVER_GOOGLE "Server: GFE/"
-
- zend_hash_internal_pointer_reset(Z_ARRVAL_P(stream->wrapperdata));
- while (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(stream->wrapperdata), (void**)&tmp)) {
- if (strncasecmp(Z_STRVAL_PP(tmp), SERVER_MICROSOFT_IIS, sizeof(SERVER_MICROSOFT_IIS)-1) == 0) {
+ ZEND_HASH_FOREACH_VAL(Z_ARRVAL(stream->wrapperdata), tmp) {
+ if (strncasecmp(Z_STRVAL_P(tmp), SERVER_MICROSOFT_IIS, sizeof(SERVER_MICROSOFT_IIS)-1) == 0) {
return 1;
- } else if (strncasecmp(Z_STRVAL_PP(tmp), SERVER_GOOGLE, sizeof(SERVER_GOOGLE)-1) == 0) {
+ } else if (strncasecmp(Z_STRVAL_P(tmp), SERVER_GOOGLE, sizeof(SERVER_GOOGLE)-1) == 0) {
return 1;
}
-
- zend_hash_move_forward(Z_ARRVAL_P(stream->wrapperdata));
- }
+ } ZEND_HASH_FOREACH_END();
}
return 0;
}
/* }}} */
-static int handle_ssl_error(php_stream *stream, int nr_bytes, zend_bool is_init TSRMLS_DC) /* {{{ */
+static int handle_ssl_error(php_stream *stream, int nr_bytes, zend_bool is_init) /* {{{ */
{
php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
int err = SSL_get_error(sslsock->ssl_handle, nr_bytes);
@@ -171,8 +208,8 @@ static int handle_ssl_error(php_stream *stream, int nr_bytes, zend_bool is_init
case SSL_ERROR_SYSCALL:
if (ERR_peek_error() == 0) {
if (nr_bytes == 0) {
- if (!is_http_stream_talking_to_iis(stream TSRMLS_CC) && ERR_get_error() != 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ if (!is_http_stream_talking_to_iis(stream) && ERR_get_error() != 0) {
+ php_error_docref(NULL, E_WARNING,
"SSL: fatal protocol error");
}
SSL_set_shutdown(sslsock->ssl_handle, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
@@ -181,7 +218,7 @@ static int handle_ssl_error(php_stream *stream, int nr_bytes, zend_bool is_init
} else {
char *estr = php_socket_strerror(php_socket_errno(), NULL, 0);
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ php_error_docref(NULL, E_WARNING,
"SSL: %s", estr);
efree(estr);
@@ -190,7 +227,7 @@ static int handle_ssl_error(php_stream *stream, int nr_bytes, zend_bool is_init
break;
}
-
+
/* fall through */
default:
/* some other error */
@@ -198,7 +235,7 @@ static int handle_ssl_error(php_stream *stream, int nr_bytes, zend_bool is_init
switch (ERR_GET_REASON(ecode)) {
case SSL_R_NO_SHARED_CIPHER:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL_R_NO_SHARED_CIPHER: no suitable shared cipher could be used. This could be because the server is missing an SSL certificate (local_cert context option)");
+ php_error_docref(NULL, E_WARNING, "SSL_R_NO_SHARED_CIPHER: no suitable shared cipher could be used. This could be because the server is missing an SSL certificate (local_cert context option)");
retry = 0;
break;
@@ -206,7 +243,7 @@ static int handle_ssl_error(php_stream *stream, int nr_bytes, zend_bool is_init
do {
/* NULL is automatically added */
ERR_error_string_n(ecode, esbuf, sizeof(esbuf));
- if (ebuf.c) {
+ if (ebuf.s) {
smart_str_appendc(&ebuf, '\n');
}
smart_str_appends(&ebuf, esbuf);
@@ -214,16 +251,16 @@ static int handle_ssl_error(php_stream *stream, int nr_bytes, zend_bool is_init
smart_str_0(&ebuf);
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ php_error_docref(NULL, E_WARNING,
"SSL operation failed with code %d. %s%s",
err,
- ebuf.c ? "OpenSSL Error messages:\n" : "",
- ebuf.c ? ebuf.c : "");
- if (ebuf.c) {
+ ebuf.s ? "OpenSSL Error messages:\n" : "",
+ ebuf.s ? ZSTR_VAL(ebuf.s) : "");
+ if (ebuf.s) {
smart_str_free(&ebuf);
}
}
-
+
retry = 0;
errno = 0;
}
@@ -236,8 +273,9 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) /* {{{ */
php_stream *stream;
SSL *ssl;
int err, depth, ret;
- zval **val;
- unsigned long allowed_depth = OPENSSL_DEFAULT_STREAM_VERIFY_DEPTH;
+ zval *val;
+ zend_ulong allowed_depth = OPENSSL_DEFAULT_STREAM_VERIFY_DEPTH;
+
ret = preverify_ok;
@@ -252,14 +290,14 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) /* {{{ */
/* 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") &&
- zend_is_true(*val)
+ zend_is_true(val)
) {
ret = 1;
}
/* check the depth */
GET_VER_OPT_LONG("verify_depth", allowed_depth);
- if ((unsigned long)depth > allowed_depth) {
+ if ((zend_ulong)depth > allowed_depth) {
ret = 0;
X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_CHAIN_TOO_LONG);
}
@@ -268,21 +306,21 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) /* {{{ */
}
/* }}} */
-static int php_x509_fingerprint_cmp(X509 *peer, const char *method, const char *expected TSRMLS_DC)
+static int php_x509_fingerprint_cmp(X509 *peer, const char *method, const char *expected)
{
- char *fingerprint;
- int fingerprint_len;
+ zend_string *fingerprint;
int result = -1;
- if (php_openssl_x509_fingerprint(peer, method, 0, &fingerprint, &fingerprint_len TSRMLS_CC) == SUCCESS) {
- result = strcasecmp(expected, fingerprint);
- efree(fingerprint);
+ fingerprint = php_openssl_x509_fingerprint(peer, method, 0);
+ if (fingerprint) {
+ result = strcasecmp(expected, ZSTR_VAL(fingerprint));
+ zend_string_release(fingerprint);
}
return result;
}
-static zend_bool php_x509_fingerprint_match(X509 *peer, zval *val TSRMLS_DC)
+static zend_bool php_x509_fingerprint_match(X509 *peer, zval *val)
{
if (Z_TYPE_P(val) == IS_STRING) {
const char *method = NULL;
@@ -297,39 +335,29 @@ static zend_bool php_x509_fingerprint_match(X509 *peer, zval *val TSRMLS_DC)
break;
}
- return method && php_x509_fingerprint_cmp(peer, method, Z_STRVAL_P(val) TSRMLS_CC) == 0;
-
+ return method && php_x509_fingerprint_cmp(peer, method, Z_STRVAL_P(val)) == 0;
} else if (Z_TYPE_P(val) == IS_ARRAY) {
- HashPosition pos;
- zval **current;
- char *key;
- uint key_len;
- ulong key_index;
+ zval *current;
+ zend_string *key;
if (!zend_hash_num_elements(Z_ARRVAL_P(val))) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid peer_fingerprint array; [algo => fingerprint] form required");
+ php_error_docref(NULL, E_WARNING, "Invalid peer_fingerprint array; [algo => fingerprint] form required");
return 0;
}
- for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(val), &pos);
- zend_hash_get_current_data_ex(Z_ARRVAL_P(val), (void **)&current, &pos) == SUCCESS;
- zend_hash_move_forward_ex(Z_ARRVAL_P(val), &pos)
- ) {
- int key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(val), &key, &key_len, &key_index, 0, &pos);
-
- if (!(key_type == HASH_KEY_IS_STRING && Z_TYPE_PP(current) == IS_STRING)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid peer_fingerprint array; [algo => fingerprint] form required");
+ ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(val), key, current) {
+ if (key == NULL || Z_TYPE_P(current) != IS_STRING) {
+ php_error_docref(NULL, E_WARNING, "Invalid peer_fingerprint array; [algo => fingerprint] form required");
return 0;
}
- if (php_x509_fingerprint_cmp(peer, key, Z_STRVAL_PP(current) TSRMLS_CC) != 0) {
+ if (php_x509_fingerprint_cmp(peer, ZSTR_VAL(key), Z_STRVAL_P(current)) != 0) {
return 0;
}
- }
+ } ZEND_HASH_FOREACH_END();
return 1;
-
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ php_error_docref(NULL, E_WARNING,
"Invalid peer_fingerprint value; fingerprint string or array of the form [algo => fingerprint] required");
}
@@ -339,7 +367,8 @@ static zend_bool php_x509_fingerprint_match(X509 *peer, zval *val TSRMLS_DC)
static zend_bool matches_wildcard_name(const char *subjectname, const char *certname) /* {{{ */
{
char *wildcard = NULL;
- int prefix_len, suffix_len, subject_len;
+ ptrdiff_t prefix_len;
+ size_t suffix_len, subject_len;
if (strcasecmp(subjectname, certname) == 0) {
return 1;
@@ -414,9 +443,9 @@ static zend_bool matches_san_list(X509 *peer, const char *subject_name) /* {{{ *
}
}
/* No, we aren't bothering to check IPv6 addresses. Why?
- * Because IP SAN names are officially deprecated and are
- * not allowed by CAs starting in 2015. Deal with it.
- */
+ * * Because IP SAN names are officially deprecated and are
+ * * not allowed by CAs starting in 2015. Deal with it.
+ * */
}
}
@@ -424,7 +453,7 @@ static zend_bool matches_san_list(X509 *peer, const char *subject_name) /* {{{ *
}
/* }}} */
-static zend_bool matches_common_name(X509 *peer, const char *subject_name TSRMLS_DC) /* {{{ */
+static zend_bool matches_common_name(X509 *peer, const char *subject_name) /* {{{ */
{
char buf[1024];
X509_NAME *cert_name;
@@ -435,44 +464,42 @@ static zend_bool matches_common_name(X509 *peer, const char *subject_name TSRMLS
cert_name_len = X509_NAME_get_text_by_NID(cert_name, NID_commonName, buf, sizeof(buf));
if (cert_name_len == -1) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate peer certificate CN");
+ php_error_docref(NULL, E_WARNING, "Unable to locate peer certificate CN");
} else if (cert_name_len != strlen(buf)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer certificate CN=`%.*s' is malformed", cert_name_len, buf);
+ php_error_docref(NULL, E_WARNING, "Peer certificate CN=`%.*s' is malformed", cert_name_len, buf);
} else if (matches_wildcard_name(subject_name, buf)) {
is_match = 1;
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer certificate CN=`%.*s' did not match expected CN=`%s'", cert_name_len, buf, subject_name);
+ php_error_docref(NULL, E_WARNING, "Peer certificate CN=`%.*s' did not match expected CN=`%s'", cert_name_len, buf, subject_name);
}
return is_match;
}
/* }}} */
-static int apply_peer_verification_policy(SSL *ssl, X509 *peer, php_stream *stream TSRMLS_DC) /* {{{ */
+static int apply_peer_verification_policy(SSL *ssl, X509 *peer, php_stream *stream) /* {{{ */
{
- zval **val = NULL;
+ zval *val = NULL;
char *peer_name = NULL;
int err,
must_verify_peer,
must_verify_peer_name,
- must_verify_fingerprint,
- has_cnmatch_ctx_opt;
+ must_verify_fingerprint;
php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
must_verify_peer = GET_VER_OPT("verify_peer")
- ? zend_is_true(*val)
+ ? zend_is_true(val)
: sslsock->is_client;
- has_cnmatch_ctx_opt = GET_VER_OPT("CN_match");
- must_verify_peer_name = (has_cnmatch_ctx_opt || GET_VER_OPT("verify_peer_name"))
- ? zend_is_true(*val)
+ must_verify_peer_name = GET_VER_OPT("verify_peer_name")
+ ? zend_is_true(val)
: sslsock->is_client;
must_verify_fingerprint = GET_VER_OPT("peer_fingerprint");
if ((must_verify_peer || must_verify_peer_name || must_verify_fingerprint) && peer == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not get peer certificate");
+ php_error_docref(NULL, E_WARNING, "Could not get peer certificate");
return FAILURE;
}
@@ -484,13 +511,13 @@ static int apply_peer_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
/* fine */
break;
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
- if (GET_VER_OPT("allow_self_signed") && zend_is_true(*val)) {
+ if (GET_VER_OPT("allow_self_signed") && zend_is_true(val)) {
/* allowed */
break;
}
/* not allowed, so fall through */
default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ php_error_docref(NULL, E_WARNING,
"Could not verify peer: code:%d %s",
err,
X509_verify_cert_error_string(err)
@@ -501,15 +528,15 @@ static int apply_peer_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
/* If a peer_fingerprint match is required this trumps peer and peer_name verification */
if (must_verify_fingerprint) {
- if (Z_TYPE_PP(val) == IS_STRING || Z_TYPE_PP(val) == IS_ARRAY) {
- if (!php_x509_fingerprint_match(peer, *val TSRMLS_CC)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ if (Z_TYPE_P(val) == IS_STRING || Z_TYPE_P(val) == IS_ARRAY) {
+ if (!php_x509_fingerprint_match(peer, val)) {
+ php_error_docref(NULL, E_WARNING,
"peer_fingerprint match failure"
);
return FAILURE;
}
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ php_error_docref(NULL, E_WARNING,
"Expected peer fingerprint must be a string or an array"
);
return FAILURE;
@@ -520,12 +547,6 @@ static int apply_peer_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
if (must_verify_peer_name) {
GET_VER_OPT_STRING("peer_name", peer_name);
- if (has_cnmatch_ctx_opt) {
- GET_VER_OPT_STRING("CN_match", peer_name);
- php_error(E_DEPRECATED,
- "the 'CN_match' SSL context option is deprecated in favor of 'peer_name'"
- );
- }
/* If no peer name was specified we use the autodetected url name in client environments */
if (peer_name == NULL && sslsock->is_client) {
peer_name = sslsock->url_name;
@@ -534,7 +555,7 @@ static int apply_peer_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
if (peer_name) {
if (matches_san_list(peer, peer_name)) {
return SUCCESS;
- } else if (matches_common_name(peer, peer_name TSRMLS_CC)) {
+ } else if (matches_common_name(peer, peer_name)) {
return SUCCESS;
} else {
return FAILURE;
@@ -551,16 +572,16 @@ static int apply_peer_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
static int passwd_callback(char *buf, int num, int verify, void *data) /* {{{ */
{
php_stream *stream = (php_stream *)data;
- zval **val = NULL;
+ 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);
+ if (Z_STRLEN_P(val) < num - 1) {
+ memcpy(buf, Z_STRVAL_P(val), Z_STRLEN_P(val)+1);
+ return (int)Z_STRLEN_P(val);
}
}
return 0;
@@ -576,10 +597,9 @@ static int win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, void *arg) /
php_stream *stream;
php_openssl_netstream_data_t *sslsock;
- zval **val;
+ zval *val;
zend_bool is_self_signed = 0;
- TSRMLS_FETCH();
stream = (php_stream*)arg;
sslsock = (php_openssl_netstream_data_t*)stream->abstract;
@@ -597,7 +617,7 @@ static int win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, void *arg) /
err_code = e;
}
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error encoding X509 certificate: %d: %s", err_code, ERR_error_string(err_code, err_buf));
+ php_error_docref(NULL, E_WARNING, "Error encoding X509 certificate: %d: %s", err_code, ERR_error_string(err_code, err_buf));
RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED);
}
@@ -605,7 +625,7 @@ static int win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, void *arg) /
OPENSSL_free(der_buf);
if (cert_ctx == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error creating certificate context: %s", php_win_err());
+ php_error_docref(NULL, E_WARNING, "Error creating certificate context: %s", php_win_err());
RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED);
}
}
@@ -627,7 +647,7 @@ static int win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, void *arg) /
chain_flags = CERT_CHAIN_CACHE_END_CERT | CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT;
if (!CertGetCertificateChain(NULL, cert_ctx, NULL, NULL, &chain_params, chain_flags, NULL, &cert_chain_ctx)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error getting certificate chain: %s", php_win_err());
+ php_error_docref(NULL, E_WARNING, "Error getting certificate chain: %s", php_win_err());
CertFreeCertificateContext(cert_ctx);
RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED);
}
@@ -668,7 +688,7 @@ static int win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, void *arg) /
cert_name = X509_get_subject_name(x509_store_ctx->cert);
index = X509_NAME_get_index_by_NID(cert_name, NID_commonName, -1);
if (index < 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate certificate CN");
+ php_error_docref(NULL, E_WARNING, "Unable to locate certificate CN");
CertFreeCertificateChain(cert_chain_ctx);
CertFreeCertificateContext(cert_ctx);
RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED);
@@ -678,7 +698,7 @@ static int win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, void *arg) /
num_wchars = MultiByteToWideChar(CP_UTF8, 0, (char*)cert_name_utf8, -1, NULL, 0);
if (num_wchars == 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to convert %s to wide character string", cert_name_utf8);
+ php_error_docref(NULL, E_WARNING, "Unable to convert %s to wide character string", cert_name_utf8);
OPENSSL_free(cert_name_utf8);
CertFreeCertificateChain(cert_chain_ctx);
CertFreeCertificateContext(cert_ctx);
@@ -689,7 +709,7 @@ static int win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, void *arg) /
num_wchars = MultiByteToWideChar(CP_UTF8, 0, (char*)cert_name_utf8, -1, server_name, num_wchars);
if (num_wchars == 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to convert %s to wide character string", cert_name_utf8);
+ php_error_docref(NULL, E_WARNING, "Unable to convert %s to wide character string", cert_name_utf8);
efree(server_name);
OPENSSL_free(cert_name_utf8);
CertFreeCertificateChain(cert_chain_ctx);
@@ -711,14 +731,14 @@ static int win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, void *arg) /
CertFreeCertificateContext(cert_ctx);
if (!verify_result) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error verifying certificate chain policy: %s", php_win_err());
+ php_error_docref(NULL, E_WARNING, "Error verifying certificate chain policy: %s", php_win_err());
RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED);
}
if (chain_policy_status.dwError != 0) {
/* The chain does not match the policy */
if (is_self_signed && chain_policy_status.dwError == CERT_E_UNTRUSTEDROOT
- && GET_VER_OPT("allow_self_signed") && zend_is_true(*val)) {
+ && GET_VER_OPT("allow_self_signed") && zend_is_true(val)) {
/* allow self-signed certs */
X509_STORE_CTX_set_error(x509_store_ctx, X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT);
} else {
@@ -732,7 +752,7 @@ static int win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, void *arg) /
/* }}} */
#endif
-static long load_stream_cafile(X509_STORE *cert_store, const char *cafile TSRMLS_DC) /* {{{ */
+static long load_stream_cafile(X509_STORE *cert_store, const char *cafile) /* {{{ */
{
php_stream *stream;
X509 *cert;
@@ -812,9 +832,9 @@ static long load_stream_cafile(X509_STORE *cert_store, const char *cafile TSRMLS
}
/* }}} */
-static int enable_peer_verification(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{ */
+static int enable_peer_verification(SSL_CTX *ctx, php_stream *stream) /* {{{ */
{
- zval **val = NULL;
+ zval *val = NULL;
char *cafile = NULL;
char *capath = NULL;
php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
@@ -823,7 +843,7 @@ static int enable_peer_verification(SSL_CTX *ctx, php_stream *stream TSRMLS_DC)
GET_VER_OPT_STRING("capath", capath);
if (cafile == NULL) {
- cafile = zend_ini_string("openssl.cafile", sizeof("openssl.cafile"), 0);
+ cafile = zend_ini_string("openssl.cafile", sizeof("openssl.cafile")-1, 0);
cafile = strlen(cafile) ? cafile : NULL;
} else if (!sslsock->is_client) {
/* Servers need to load and assign CA names from the cafile */
@@ -837,13 +857,13 @@ static int enable_peer_verification(SSL_CTX *ctx, php_stream *stream TSRMLS_DC)
}
if (capath == NULL) {
- capath = zend_ini_string("openssl.capath", sizeof("openssl.capath"), 0);
+ capath = zend_ini_string("openssl.capath", sizeof("openssl.capath")-1, 0);
capath = strlen(capath) ? capath : NULL;
}
if (cafile || capath) {
if (!SSL_CTX_load_verify_locations(ctx, cafile, capath)) {
- if (cafile && !load_stream_cafile(SSL_CTX_get_cert_store(ctx), cafile TSRMLS_CC)) {
+ if (cafile && !load_stream_cafile(SSL_CTX_get_cert_store(ctx), cafile)) {
return FAILURE;
}
}
@@ -853,7 +873,7 @@ static int enable_peer_verification(SSL_CTX *ctx, php_stream *stream TSRMLS_DC)
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
#else
if (sslsock->is_client && !SSL_CTX_set_default_verify_paths(ctx)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ php_error_docref(NULL, E_WARNING,
"Unable to set default verify locations and no CA settings specified");
return FAILURE;
}
@@ -866,15 +886,15 @@ static int enable_peer_verification(SSL_CTX *ctx, php_stream *stream TSRMLS_DC)
}
/* }}} */
-static void disable_peer_verification(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{ */
+static void disable_peer_verification(SSL_CTX *ctx, php_stream *stream) /* {{{ */
{
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
}
/* }}} */
-static int set_local_cert(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{ */
+static int set_local_cert(SSL_CTX *ctx, php_stream *stream) /* {{{ */
{
- zval **val = NULL;
+ zval *val = NULL;
char *certfile = NULL;
GET_VER_OPT_STRING("local_cert", certfile);
@@ -886,7 +906,7 @@ static int set_local_cert(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{ */
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);
+ php_error_docref(NULL, 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 FAILURE;
}
GET_VER_OPT_STRING("local_pk", private_key);
@@ -895,15 +915,15 @@ static int set_local_cert(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{ */
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);
+ php_error_docref(NULL, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff_pk);
return FAILURE;
}
}
} 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);
+ php_error_docref(NULL, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff);
return FAILURE;
- }
+ }
}
#if OPENSSL_VERSION_NUMBER < 0x10001001L
@@ -923,7 +943,7 @@ static int set_local_cert(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{ */
} while (0);
#endif
if (!SSL_CTX_check_private_key(ctx)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Private key does not match certificate!");
+ php_error_docref(NULL, E_WARNING, "Private key does not match certificate!");
}
}
}
@@ -932,74 +952,73 @@ static int set_local_cert(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{ */
}
/* }}} */
-static const SSL_METHOD *php_select_crypto_method(long method_value, int is_client TSRMLS_DC) /* {{{ */
+static const SSL_METHOD *php_select_crypto_method(zend_long method_value, int is_client) /* {{{ */
{
if (method_value == STREAM_CRYPTO_METHOD_SSLv2) {
-#ifndef OPENSSL_NO_SSL2
- return is_client ? SSLv2_client_method() : SSLv2_server_method();
+#ifdef HAVE_SSL2
+ return is_client ? (SSL_METHOD *)SSLv2_client_method() : (SSL_METHOD *)SSLv2_server_method();
#else
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "SSLv2 support is not compiled into the OpenSSL library PHP is linked against");
+ php_error_docref(NULL, E_WARNING,
+ "SSLv2 unavailable in the OpenSSL library against which PHP is linked");
return NULL;
#endif
} else if (method_value == STREAM_CRYPTO_METHOD_SSLv3) {
-#ifndef OPENSSL_NO_SSL3
+#ifdef HAVE_SSL3
return is_client ? SSLv3_client_method() : SSLv3_server_method();
#else
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "SSLv3 support is not compiled into the OpenSSL library PHP is linked against");
+ php_error_docref(NULL, E_WARNING,
+ "SSLv3 unavailable in the OpenSSL library against which PHP is linked");
return NULL;
#endif
} else if (method_value == STREAM_CRYPTO_METHOD_TLSv1_0) {
return is_client ? TLSv1_client_method() : TLSv1_server_method();
} else if (method_value == STREAM_CRYPTO_METHOD_TLSv1_1) {
-#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+#ifdef HAVE_TLS11
return is_client ? TLSv1_1_client_method() : TLSv1_1_server_method();
#else
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "TLSv1.1 support is not compiled into the OpenSSL library PHP is linked against");
+ php_error_docref(NULL, E_WARNING,
+ "TLSv1.1 unavailable in the OpenSSL library against which PHP is linked");
return NULL;
#endif
} else if (method_value == STREAM_CRYPTO_METHOD_TLSv1_2) {
-#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+#ifdef HAVE_TLS12
return is_client ? TLSv1_2_client_method() : TLSv1_2_server_method();
#else
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "TLSv1.2 support is not compiled into the OpenSSL library PHP is linked against");
+ php_error_docref(NULL, E_WARNING,
+ "TLSv1.2 unavailable in the OpenSSL library against which PHP is linked");
return NULL;
#endif
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ php_error_docref(NULL, E_WARNING,
"Invalid crypto method");
return NULL;
}
}
/* }}} */
-static long php_get_crypto_method_ctx_flags(long method_flags TSRMLS_DC) /* {{{ */
+static int php_get_crypto_method_ctx_flags(int method_flags) /* {{{ */
{
- long ssl_ctx_options = SSL_OP_ALL;
+ int ssl_ctx_options = SSL_OP_ALL;
-#ifndef OPENSSL_NO_SSL2
+#ifdef HAVE_SSL2
if (!(method_flags & STREAM_CRYPTO_METHOD_SSLv2)) {
ssl_ctx_options |= SSL_OP_NO_SSLv2;
}
#endif
-#ifndef OPENSSL_NO_SSL3
+#ifdef HAVE_SSL3
if (!(method_flags & STREAM_CRYPTO_METHOD_SSLv3)) {
ssl_ctx_options |= SSL_OP_NO_SSLv3;
}
#endif
-#ifndef OPENSSL_NO_TLS1
if (!(method_flags & STREAM_CRYPTO_METHOD_TLSv1_0)) {
ssl_ctx_options |= SSL_OP_NO_TLSv1;
}
-#endif
-#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+#ifdef HAVE_TLS11
if (!(method_flags & STREAM_CRYPTO_METHOD_TLSv1_1)) {
ssl_ctx_options |= SSL_OP_NO_TLSv1_1;
}
-
+#endif
+#ifdef HAVE_TLS12
if (!(method_flags & STREAM_CRYPTO_METHOD_TLSv1_2)) {
ssl_ctx_options |= SSL_OP_NO_TLSv1_2;
}
@@ -1014,7 +1033,7 @@ static void limit_handshake_reneg(const SSL *ssl) /* {{{ */
php_stream *stream;
php_openssl_netstream_data_t *sslsock;
struct timeval now;
- long elapsed_time;
+ zend_long elapsed_time;
stream = php_openssl_get_stream_from_ssl_handle(ssl);
sslsock = (php_openssl_netstream_data_t*)stream->abstract;
@@ -1037,39 +1056,33 @@ static void limit_handshake_reneg(const SSL *ssl) /* {{{ */
/* The token level exceeds our allowed limit */
if (sslsock->reneg->tokens > sslsock->reneg->limit) {
- zval **val;
+ zval *val;
- TSRMLS_FETCH();
sslsock->reneg->should_close = 1;
- if (stream->context && SUCCESS == php_stream_context_get_option(stream->context,
- "ssl", "reneg_limit_callback", &val)
+ if (PHP_STREAM_CONTEXT(stream) && (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream),
+ "ssl", "reneg_limit_callback")) != NULL
) {
- zval *param, **params[1], *retval;
+ zval param, retval;
- MAKE_STD_ZVAL(param);
- php_stream_to_zval(stream, param);
- params[0] = &param;
+ php_stream_to_zval(stream, &param);
/* Closing the stream inside this callback would segfault! */
stream->flags |= PHP_STREAM_FLAG_NO_FCLOSE;
- if (FAILURE == call_user_function_ex(EG(function_table), NULL, *val, &retval, 1, params, 0, NULL TSRMLS_CC)) {
+ if (FAILURE == call_user_function_ex(EG(function_table), NULL, val, &retval, 1, &param, 0, NULL)) {
php_error(E_WARNING, "SSL: failed invoking reneg limit notification callback");
}
stream->flags ^= PHP_STREAM_FLAG_NO_FCLOSE;
/* If the reneg_limit_callback returned true don't auto-close */
- if (retval != NULL && Z_TYPE_P(retval) == IS_BOOL && Z_BVAL_P(retval) == 1) {
+ if (Z_TYPE(retval) == IS_TRUE) {
sslsock->reneg->should_close = 0;
}
- FREE_ZVAL(param);
- if (retval != NULL) {
- zval_ptr_dtor(&retval);
- }
+ zval_ptr_dtor(&retval);
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ php_error_docref(NULL, E_WARNING,
"SSL: client-initiated handshake rate limit exceeded by peer");
}
}
@@ -1087,16 +1100,16 @@ static void info_callback(const SSL *ssl, int where, int ret) /* {{{ */
static void init_server_reneg_limit(php_stream *stream, php_openssl_netstream_data_t *sslsock) /* {{{ */
{
- zval **val;
- long limit = OPENSSL_DEFAULT_RENEG_LIMIT;
- long window = OPENSSL_DEFAULT_RENEG_WINDOW;
+ zval *val;
+ zend_long limit = OPENSSL_DEFAULT_RENEG_LIMIT;
+ zend_long window = OPENSSL_DEFAULT_RENEG_WINDOW;
- if (stream->context &&
- SUCCESS == php_stream_context_get_option(stream->context,
- "ssl", "reneg_limit", &val)
+ if (PHP_STREAM_CONTEXT(stream) &&
+ NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream),
+ "ssl", "reneg_limit"))
) {
- convert_to_long(*val);
- limit = Z_LVAL_PP(val);
+ convert_to_long(val);
+ limit = Z_LVAL_P(val);
}
/* No renegotiation rate-limiting */
@@ -1104,12 +1117,12 @@ static void init_server_reneg_limit(php_stream *stream, php_openssl_netstream_da
return;
}
- if (stream->context &&
- SUCCESS == php_stream_context_get_option(stream->context,
- "ssl", "reneg_window", &val)
+ if (PHP_STREAM_CONTEXT(stream) &&
+ NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream),
+ "ssl", "reneg_window"))
) {
- convert_to_long(*val);
- window = Z_LVAL_PP(val);
+ convert_to_long(val);
+ window = Z_LVAL_P(val);
}
sslsock->reneg = (void*)pemalloc(sizeof(php_openssl_handshake_bucket_t),
@@ -1126,45 +1139,53 @@ static void init_server_reneg_limit(php_stream *stream, php_openssl_netstream_da
}
/* }}} */
-static int set_server_rsa_key(php_stream *stream, SSL_CTX *ctx TSRMLS_DC) /* {{{ */
+#ifndef OPENSSL_NO_RSA
+static RSA *tmp_rsa_cb(SSL *s, int is_export, int keylength)
{
- zval ** val;
- int rsa_key_size;
- RSA* rsa;
-
- if (php_stream_context_get_option(stream->context, "ssl", "rsa_key_size", &val) == SUCCESS) {
- rsa_key_size = (int) Z_LVAL_PP(val);
- if ((rsa_key_size != 1) && (rsa_key_size & (rsa_key_size - 1))) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "RSA key size requires a power of 2: %d", rsa_key_size);
- rsa_key_size = 2048;
- }
- } else {
- rsa_key_size = 2048;
- }
-
- rsa = RSA_generate_key(rsa_key_size, RSA_F4, NULL, NULL);
+ BIGNUM *bn = NULL;
+ static RSA *rsa_tmp = NULL;
- if (!SSL_CTX_set_tmp_rsa(ctx, rsa)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed setting RSA key");
- RSA_free(rsa);
- return FAILURE;
+ if (!rsa_tmp && ((bn = BN_new()) == NULL)) {
+ php_error_docref(NULL, E_WARNING, "allocation error generating RSA key");
+ }
+ if (!rsa_tmp && bn) {
+ if (!BN_set_word(bn, RSA_F4) || ((rsa_tmp = RSA_new()) == NULL) ||
+ !RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL)) {
+ if (rsa_tmp) {
+ RSA_free(rsa_tmp);
+ }
+ rsa_tmp = NULL;
+ }
+ BN_free(bn);
}
- RSA_free(rsa);
-
- return SUCCESS;
+ return (rsa_tmp);
}
-/* }}} */
+#endif
-static int set_server_dh_param(SSL_CTX *ctx, char *dh_path TSRMLS_DC) /* {{{ */
+#ifndef OPENSSL_NO_DH
+static int set_server_dh_param(php_stream * stream, SSL_CTX *ctx) /* {{{ */
{
DH *dh;
BIO* bio;
+ zval *zdhpath;
+
+ zdhpath = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "dh_param");
+ if (zdhpath == NULL) {
+#if 0
+ /* Coming in OpenSSL 1.1 ... eventually we'll want to enable this
+ * in the absence of an explicit dh_param.
+ */
+ SSL_CTX_set_dh_auto(ctx, 1);
+#endif
+ return SUCCESS;
+ }
- bio = BIO_new_file(dh_path, "r");
+ convert_to_string_ex(zdhpath);
+ bio = BIO_new_file(Z_STRVAL_P(zdhpath), "r");
if (bio == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid dh_param file: %s", dh_path);
+ php_error_docref(NULL, E_WARNING, "invalid dh_param");
return FAILURE;
}
@@ -1172,12 +1193,12 @@ static int set_server_dh_param(SSL_CTX *ctx, char *dh_path TSRMLS_DC) /* {{{ */
BIO_free(bio);
if (dh == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed reading DH params from file: %s", dh_path);
+ php_error_docref(NULL, E_WARNING, "failed reading DH params");
return FAILURE;
}
if (SSL_CTX_set_tmp_dh(ctx, dh) < 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "DH param assignment failed");
+ php_error_docref(NULL, E_WARNING, "failed assigning DH params");
DH_free(dh);
return FAILURE;
}
@@ -1187,32 +1208,35 @@ static int set_server_dh_param(SSL_CTX *ctx, char *dh_path TSRMLS_DC) /* {{{ */
return SUCCESS;
}
/* }}} */
+#endif
#ifdef HAVE_ECDH
-static int set_server_ecdh_curve(php_stream *stream, SSL_CTX *ctx TSRMLS_DC) /* {{{ */
+static int set_server_ecdh_curve(php_stream *stream, SSL_CTX *ctx) /* {{{ */
{
- zval **val;
+ zval *zvcurve;
int curve_nid;
- char *curve_str;
EC_KEY *ecdh;
- if (php_stream_context_get_option(stream->context, "ssl", "ecdh_curve", &val) == SUCCESS) {
- convert_to_string_ex(val);
- curve_str = Z_STRVAL_PP(val);
- curve_nid = OBJ_sn2nid(curve_str);
+ zvcurve = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "ecdh_curve");
+ if (zvcurve == NULL) {
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+ SSL_CTX_set_ecdh_auto(ctx, 1);
+ return SUCCESS;
+#else
+ curve_nid = NID_X9_62_prime256v1;
+#endif
+ } else {
+ convert_to_string_ex(zvcurve);
+ curve_nid = OBJ_sn2nid(Z_STRVAL_P(zvcurve));
if (curve_nid == NID_undef) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid ECDH curve: %s", curve_str);
+ php_error_docref(NULL, E_WARNING, "invalid ecdh_curve specified");
return FAILURE;
}
- } else {
- curve_nid = NID_X9_62_prime256v1;
}
ecdh = EC_KEY_new_by_curve_name(curve_nid);
if (ecdh == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "Failed generating ECDH curve");
-
+ php_error_docref(NULL, E_WARNING, "failed generating ECDH curve");
return FAILURE;
}
@@ -1224,57 +1248,37 @@ static int set_server_ecdh_curve(php_stream *stream, SSL_CTX *ctx TSRMLS_DC) /*
/* }}} */
#endif
-static int set_server_specific_opts(php_stream *stream, SSL_CTX *ctx TSRMLS_DC) /* {{{ */
+static int set_server_specific_opts(php_stream *stream, SSL_CTX *ctx) /* {{{ */
{
- zval **val;
+ zval *zv;
long ssl_ctx_options = SSL_CTX_get_options(ctx);
#ifdef HAVE_ECDH
- if (FAILURE == set_server_ecdh_curve(stream, ctx TSRMLS_CC)) {
- return FAILURE;
- }
-#else
- if (SUCCESS == php_stream_context_get_option(stream->context, "ssl", "ecdh_curve", &val)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "ECDH curve support not compiled into the OpenSSL lib against which PHP is linked");
-
+ if (set_server_ecdh_curve(stream, ctx) == FAILURE) {
return FAILURE;
}
#endif
- if (php_stream_context_get_option(stream->context, "ssl", "dh_param", &val) == SUCCESS) {
- convert_to_string_ex(val);
- if (FAILURE == set_server_dh_param(ctx, Z_STRVAL_PP(val) TSRMLS_CC)) {
- return FAILURE;
- }
- }
-
- if (FAILURE == set_server_rsa_key(stream, ctx TSRMLS_CC)) {
- return FAILURE;
- }
-
- if (SUCCESS == php_stream_context_get_option(
- stream->context, "ssl", "honor_cipher_order", &val) &&
- zend_is_true(*val)
- ) {
- ssl_ctx_options |= SSL_OP_CIPHER_SERVER_PREFERENCE;
+#ifndef OPENSSL_NO_RSA
+ SSL_CTX_set_tmp_rsa_callback(ctx, tmp_rsa_cb);
+#endif
+ /* We now use tmp_rsa_cb to generate a key of appropriate size whenever necessary */
+ if (php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "rsa_key_size") != NULL) {
+ php_error_docref(NULL, E_WARNING, "rsa_key_size context option has been removed");
}
- if (SUCCESS == php_stream_context_get_option(
- stream->context, "ssl", "single_dh_use", &val) &&
- zend_is_true(*val)
- ) {
+#ifndef OPENSSL_NO_DH
+ set_server_dh_param(stream, ctx);
+ zv = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "single_dh_use");
+ if (zv != NULL && zend_is_true(zv)) {
ssl_ctx_options |= SSL_OP_SINGLE_DH_USE;
}
+#endif
-#ifdef HAVE_ECDH
- if (SUCCESS == php_stream_context_get_option(
- stream->context, "ssl", "single_ecdh_use", &val) &&
- zend_is_true(*val)
- ) {
- ssl_ctx_options |= SSL_OP_SINGLE_ECDH_USE;
+ zv = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "honor_cipher_order");
+ if (zv != NULL && zend_is_true(zv)) {
+ ssl_ctx_options |= SSL_OP_CIPHER_SERVER_PREFERENCE;
}
-#endif
SSL_CTX_set_options(ctx, ssl_ctx_options);
@@ -1282,7 +1286,7 @@ static int set_server_specific_opts(php_stream *stream, SSL_CTX *ctx TSRMLS_DC)
}
/* }}} */
-#ifdef HAVE_SNI
+#ifdef HAVE_TLS_SNI
static int server_sni_callback(SSL *ssl_handle, int *al, void *arg) /* {{{ */
{
php_stream *stream;
@@ -1314,21 +1318,18 @@ static int server_sni_callback(SSL *ssl_handle, int *al, void *arg) /* {{{ */
}
/* }}} */
-static int enable_server_sni(php_stream *stream, php_openssl_netstream_data_t *sslsock TSRMLS_DC)
+static int enable_server_sni(php_stream *stream, php_openssl_netstream_data_t *sslsock)
{
- zval **val;
- zval **current;
- char *key;
- uint key_len;
- ulong key_index;
- int key_type;
- HashPosition pos;
+ zval *val;
+ zval *current;
+ zend_string *key;
+ zend_ulong key_index;
int i = 0;
char resolved_path_buff[MAXPATHLEN];
SSL_CTX *ctx;
/* If the stream ctx disables SNI we're finished here */
- if (GET_VER_OPT("SNI_enabled") && !zend_is_true(*val)) {
+ if (GET_VER_OPT("SNI_enabled") && !zend_is_true(val)) {
return SUCCESS;
}
@@ -1337,16 +1338,16 @@ static int enable_server_sni(php_stream *stream, php_openssl_netstream_data_t *s
return SUCCESS;
}
- if (Z_TYPE_PP(val) != IS_ARRAY) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ if (Z_TYPE_P(val) != IS_ARRAY) {
+ php_error_docref(NULL, E_WARNING,
"SNI_server_certs requires an array mapping host names to cert paths"
);
return FAILURE;
}
- sslsock->sni_cert_count = zend_hash_num_elements(Z_ARRVAL_PP(val));
+ sslsock->sni_cert_count = zend_hash_num_elements(Z_ARRVAL_P(val));
if (sslsock->sni_cert_count == 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ php_error_docref(NULL, E_WARNING,
"SNI_server_certs host cert array must not be empty"
);
return FAILURE;
@@ -1357,25 +1358,23 @@ static int enable_server_sni(php_stream *stream, php_openssl_netstream_data_t *s
);
memset(sslsock->sni_certs, 0, sslsock->sni_cert_count * sizeof(php_openssl_sni_cert_t));
- for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(val), &pos);
- zend_hash_get_current_data_ex(Z_ARRVAL_PP(val), (void **)&current, &pos) == SUCCESS;
- zend_hash_move_forward_ex(Z_ARRVAL_PP(val), &pos)
- ) {
- key_type = zend_hash_get_current_key_ex(Z_ARRVAL_PP(val), &key, &key_len, &key_index, 0, &pos);
- if (key_type != HASH_KEY_IS_STRING) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(val), key_index, key, current) {
+ (void) key_index;
+
+ if (!key) {
+ php_error_docref(NULL, E_WARNING,
"SNI_server_certs array requires string host name keys"
);
return FAILURE;
}
- if (VCWD_REALPATH(Z_STRVAL_PP(current), resolved_path_buff)) {
+ if (VCWD_REALPATH(Z_STRVAL_P(current), resolved_path_buff)) {
/* The hello method is not inherited by SSL structs when assigning a new context
* inside the SNI callback, so the just use SSLv23 */
ctx = SSL_CTX_new(SSLv23_server_method());
if (SSL_CTX_use_certificate_chain_file(ctx, resolved_path_buff) != 1) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ php_error_docref(NULL, E_WARNING,
"failed setting local cert chain file `%s'; " \
"check that your cafile/capath settings include " \
"details of your certificate and its issuer",
@@ -1384,25 +1383,25 @@ static int enable_server_sni(php_stream *stream, php_openssl_netstream_data_t *s
SSL_CTX_free(ctx);
return FAILURE;
} else if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff, SSL_FILETYPE_PEM) != 1) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ php_error_docref(NULL, E_WARNING,
"failed setting private key from file `%s'",
resolved_path_buff
);
SSL_CTX_free(ctx);
return FAILURE;
} else {
- sslsock->sni_certs[i].name = pestrdup(key, php_stream_is_persistent(stream));
+ sslsock->sni_certs[i].name = pestrdup(ZSTR_VAL(key), php_stream_is_persistent(stream));
sslsock->sni_certs[i].ctx = ctx;
++i;
}
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ php_error_docref(NULL, E_WARNING,
"failed setting local cert chain file `%s'; file not found",
- Z_STRVAL_PP(current)
+ Z_STRVAL_P(current)
);
return FAILURE;
}
- }
+ } ZEND_HASH_FOREACH_END();
SSL_CTX_set_tlsext_servername_callback(sslsock->ctx, server_sni_callback);
@@ -1411,11 +1410,11 @@ static int enable_server_sni(php_stream *stream, php_openssl_netstream_data_t *s
static void enable_client_sni(php_stream *stream, php_openssl_netstream_data_t *sslsock) /* {{{ */
{
- zval **val;
+ zval *val;
char *sni_server_name;
/* If SNI is explicitly disabled we're finished here */
- if (GET_VER_OPT("SNI_enabled") && !zend_is_true(*val)) {
+ if (GET_VER_OPT("SNI_enabled") && !zend_is_true(val)) {
return;
}
@@ -1423,11 +1422,6 @@ static void enable_client_sni(php_stream *stream, php_openssl_netstream_data_t *
GET_VER_OPT_STRING("peer_name", sni_server_name);
- if (GET_VER_OPT("SNI_server_name")) {
- GET_VER_OPT_STRING("SNI_server_name", sni_server_name);
- php_error(E_DEPRECATED, "SNI_server_name is deprecated in favor of peer_name");
- }
-
if (sni_server_name) {
SSL_set_tlsext_host_name(sslsock->ssl_handle, sni_server_name);
}
@@ -1435,20 +1429,80 @@ static void enable_client_sni(php_stream *stream, php_openssl_netstream_data_t *
/* }}} */
#endif
+#ifdef HAVE_TLS_ALPN
+/*-
+ * parses a comma-separated list of strings into a string suitable for SSL_CTX_set_next_protos_advertised
+ * outlen: (output) set to the length of the resulting buffer on success.
+ * err: (maybe NULL) on failure, an error message line is written to this BIO.
+ * in: a NULL terminated string like "abc,def,ghi"
+ *
+ * returns: an emalloced buffer or NULL on failure.
+ */
+static unsigned char *alpn_protos_parse(unsigned short *outlen, const char *in)
+{
+ size_t len;
+ unsigned char *out;
+ size_t i, start = 0;
+
+ len = strlen(in);
+ if (len >= 65535) {
+ return NULL;
+ }
+
+ out = emalloc(strlen(in) + 1);
+ if (!out) {
+ return NULL;
+ }
+
+ for (i = 0; i <= len; ++i) {
+ if (i == len || in[i] == ',') {
+ if (i - start > 255) {
+ efree(out);
+ return NULL;
+ }
+ out[start] = i - start;
+ start = i + 1;
+ } else {
+ out[i + 1] = in[i];
+ }
+ }
+
+ *outlen = len + 1;
+
+ return out;
+}
+
+static int server_alpn_callback(SSL *ssl_handle, const unsigned char **out, unsigned char *outlen,
+ const unsigned char *in, unsigned int inlen, void *arg)
+{
+ php_openssl_netstream_data_t *sslsock = arg;
+
+ if (SSL_select_next_proto
+ ((unsigned char **)out, outlen, sslsock->alpn_ctx->data, sslsock->alpn_ctx->len, in,
+ inlen) != OPENSSL_NPN_NEGOTIATED) {
+ return SSL_TLSEXT_ERR_NOACK;
+ }
+
+ return SSL_TLSEXT_ERR_OK;
+}
+
+#endif
+
int php_openssl_setup_crypto(php_stream *stream,
php_openssl_netstream_data_t *sslsock,
php_stream_xport_crypto_param *cparam
- TSRMLS_DC) /* {{{ */
+ ) /* {{{ */
{
const SSL_METHOD *method;
- long ssl_ctx_options;
- long method_flags;
+ int ssl_ctx_options;
+ int method_flags;
char *cipherlist = NULL;
- zval **val;
+ char *alpn_protocols = NULL;
+ zval *val;
if (sslsock->ssl_handle) {
if (sslsock->s.is_blocked) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL/TLS already set-up for this stream");
+ php_error_docref(NULL, E_WARNING, "SSL/TLS already set-up for this stream");
return FAILURE;
} else {
return SUCCESS;
@@ -1465,13 +1519,13 @@ int php_openssl_setup_crypto(php_stream *stream,
/* Should we use a specific crypto method or is generic SSLv23 okay? */
if ((method_flags & (method_flags-1)) == 0) {
ssl_ctx_options = SSL_OP_ALL;
- method = php_select_crypto_method(method_flags, sslsock->is_client TSRMLS_CC);
+ method = php_select_crypto_method(method_flags, sslsock->is_client);
if (method == NULL) {
return FAILURE;
}
} else {
method = sslsock->is_client ? SSLv23_client_method() : SSLv23_server_method();
- ssl_ctx_options = php_get_crypto_method_ctx_flags(method_flags TSRMLS_CC);
+ ssl_ctx_options = php_get_crypto_method_ctx_flags(method_flags);
if (ssl_ctx_options == -1) {
return FAILURE;
}
@@ -1485,12 +1539,12 @@ int php_openssl_setup_crypto(php_stream *stream,
#endif
if (sslsock->ctx == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL context creation failure");
+ php_error_docref(NULL, E_WARNING, "SSL context creation failure");
return FAILURE;
}
#if OPENSSL_VERSION_NUMBER >= 0x0090806fL
- if (GET_VER_OPT("no_ticket") && zend_is_true(*val)) {
+ if (GET_VER_OPT("no_ticket") && zend_is_true(val)) {
ssl_ctx_options |= SSL_OP_NO_TICKET;
}
#endif
@@ -1500,14 +1554,14 @@ int php_openssl_setup_crypto(php_stream *stream,
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
- if (!GET_VER_OPT("disable_compression") || zend_is_true(*val)) {
+ if (!GET_VER_OPT("disable_compression") || zend_is_true(val)) {
ssl_ctx_options |= SSL_OP_NO_COMPRESSION;
}
#endif
- if (GET_VER_OPT("verify_peer") && !zend_is_true(*val)) {
- disable_peer_verification(sslsock->ctx, stream TSRMLS_CC);
- } else if (FAILURE == enable_peer_verification(sslsock->ctx, stream TSRMLS_CC)) {
+ if (GET_VER_OPT("verify_peer") && !zend_is_true(val)) {
+ disable_peer_verification(sslsock->ctx, stream);
+ } else if (FAILURE == enable_peer_verification(sslsock->ctx, stream)) {
return FAILURE;
}
@@ -1528,22 +1582,54 @@ int php_openssl_setup_crypto(php_stream *stream,
return FAILURE;
}
}
- if (FAILURE == set_local_cert(sslsock->ctx, stream TSRMLS_CC)) {
+
+ GET_VER_OPT_STRING("alpn_protocols", alpn_protocols);
+ if (alpn_protocols) {
+#ifdef HAVE_TLS_ALPN
+ {
+ unsigned short alpn_len;
+ unsigned char *alpn = alpn_protos_parse(&alpn_len, alpn_protocols);
+
+ if (alpn == NULL) {
+ php_error_docref(NULL, E_WARNING, "Failed parsing comma-separated TLS ALPN protocol string");
+ SSL_CTX_free(sslsock->ctx);
+ sslsock->ctx = NULL;
+ return FAILURE;
+ }
+ if (sslsock->is_client) {
+ SSL_CTX_set_alpn_protos(sslsock->ctx, alpn, alpn_len);
+ } else {
+ sslsock->alpn_ctx = (php_openssl_alpn_ctx *) emalloc(sizeof(php_openssl_alpn_ctx));
+ sslsock->alpn_ctx->data = (unsigned char*)estrndup((const char*)alpn, alpn_len);
+ sslsock->alpn_ctx->len = alpn_len;
+ SSL_CTX_set_alpn_select_cb(sslsock->ctx, server_alpn_callback, sslsock);
+ }
+
+ efree(alpn);
+ }
+#else
+ php_error_docref(NULL, E_WARNING,
+ "alpn_protocols support is not compiled into the OpenSSL library against which PHP is linked");
+#endif
+ }
+
+ if (FAILURE == set_local_cert(sslsock->ctx, stream)) {
return FAILURE;
}
SSL_CTX_set_options(sslsock->ctx, ssl_ctx_options);
if (sslsock->is_client == 0 &&
- stream->context &&
- FAILURE == set_server_specific_opts(stream, sslsock->ctx TSRMLS_CC)
+ PHP_STREAM_CONTEXT(stream) &&
+ FAILURE == set_server_specific_opts(stream, sslsock->ctx)
) {
return FAILURE;
}
sslsock->ssl_handle = SSL_new(sslsock->ctx);
+
if (sslsock->ssl_handle == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL handle creation failure");
+ php_error_docref(NULL, E_WARNING, "SSL handle creation failure");
SSL_CTX_free(sslsock->ctx);
sslsock->ctx = NULL;
return FAILURE;
@@ -1552,18 +1638,18 @@ int php_openssl_setup_crypto(php_stream *stream,
}
if (!SSL_set_fd(sslsock->ssl_handle, sslsock->s.socket)) {
- handle_ssl_error(stream, 0, 1 TSRMLS_CC);
+ handle_ssl_error(stream, 0, 1);
}
-#ifdef HAVE_SNI
+#ifdef HAVE_TLS_SNI
/* Enable server-side SNI */
- if (sslsock->is_client == 0 && enable_server_sni(stream, sslsock TSRMLS_CC) == FAILURE) {
+ if (!sslsock->is_client && enable_server_sni(stream, sslsock) == FAILURE) {
return FAILURE;
}
#endif
/* Enable server-side handshake renegotiation rate-limiting */
- if (sslsock->is_client == 0) {
+ if (!sslsock->is_client) {
init_server_reneg_limit(stream, sslsock);
}
@@ -1576,9 +1662,9 @@ int php_openssl_setup_crypto(php_stream *stream,
if (cparam->inputs.session) {
if (cparam->inputs.session->ops != &php_openssl_socket_ops) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "supplied session stream must be an SSL enabled stream");
+ php_error_docref(NULL, E_WARNING, "supplied session stream must be an SSL enabled stream");
} else if (((php_openssl_netstream_data_t*)cparam->inputs.session->abstract)->ssl_handle == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "supplied SSL session stream is not initialized");
+ php_error_docref(NULL, E_WARNING, "supplied SSL session stream is not initialized");
} else {
SSL_copy_session_id(sslsock->ssl_handle, ((php_openssl_netstream_data_t*)cparam->inputs.session->abstract)->ssl_handle);
}
@@ -1588,79 +1674,90 @@ int php_openssl_setup_crypto(php_stream *stream,
}
/* }}} */
-static zval *capture_session_meta(SSL *ssl_handle) /* {{{ */
+static zend_array *capture_session_meta(SSL *ssl_handle) /* {{{ */
{
- zval *meta_arr;
+ zval meta_arr;
char *proto_str;
long proto = SSL_version(ssl_handle);
const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl_handle);
switch (proto) {
-#if OPENSSL_VERSION_NUMBER >= 0x10001001L
- case TLS1_2_VERSION: proto_str = "TLSv1.2"; break;
- case TLS1_1_VERSION: proto_str = "TLSv1.1"; break;
+#ifdef HAVE_TLS12
+ case TLS1_2_VERSION:
+ proto_str = "TLSv1.2";
+ break;
+#endif
+#ifdef HAVE_TLS11
+ case TLS1_1_VERSION:
+ proto_str = "TLSv1.1";
+ break;
+#endif
+ case TLS1_VERSION:
+ proto_str = "TLSv1";
+ break;
+#ifdef HAVE_SSL3
+ case SSL3_VERSION:
+ proto_str = "SSLv3";
+ break;
+#endif
+#ifdef HAVE_SSL2
+ case SSL2_VERSION:
+ proto_str = "SSLv2";
+ break;
#endif
- case TLS1_VERSION: proto_str = "TLSv1"; break;
- case SSL3_VERSION: proto_str = "SSLv3"; break;
- case SSL2_VERSION: proto_str = "SSLv2"; break;
default: proto_str = "UNKNOWN";
}
- MAKE_STD_ZVAL(meta_arr);
- array_init(meta_arr);
- add_assoc_string(meta_arr, "protocol", proto_str, 1);
- add_assoc_string(meta_arr, "cipher_name", (char *) SSL_CIPHER_get_name(cipher), 1);
- add_assoc_long(meta_arr, "cipher_bits", SSL_CIPHER_get_bits(cipher, NULL));
- add_assoc_string(meta_arr, "cipher_version", SSL_CIPHER_get_version(cipher), 1);
+ array_init(&meta_arr);
+ add_assoc_string(&meta_arr, "protocol", proto_str);
+ add_assoc_string(&meta_arr, "cipher_name", (char *) SSL_CIPHER_get_name(cipher));
+ add_assoc_long(&meta_arr, "cipher_bits", SSL_CIPHER_get_bits(cipher, NULL));
+ add_assoc_string(&meta_arr, "cipher_version", SSL_CIPHER_get_version(cipher));
- return meta_arr;
+ return Z_ARR(meta_arr);
}
/* }}} */
-static int capture_peer_certs(php_stream *stream, php_openssl_netstream_data_t *sslsock, X509 *peer_cert TSRMLS_DC) /* {{{ */
+static int capture_peer_certs(php_stream *stream, php_openssl_netstream_data_t *sslsock, X509 *peer_cert) /* {{{ */
{
- zval **val, *zcert;
+ zval *val, zcert;
int cert_captured = 0;
- if (SUCCESS == php_stream_context_get_option(stream->context,
- "ssl", "capture_peer_cert", &val) &&
- zend_is_true(*val)
+ if (NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream),
+ "ssl", "capture_peer_cert")) &&
+ zend_is_true(val)
) {
- MAKE_STD_ZVAL(zcert);
- ZVAL_RESOURCE(zcert, zend_list_insert(peer_cert, php_openssl_get_x509_list_id() TSRMLS_CC));
- php_stream_context_set_option(stream->context, "ssl", "peer_certificate", zcert);
+ ZVAL_RES(&zcert, zend_register_resource(peer_cert, php_openssl_get_x509_list_id()));
+ php_stream_context_set_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_certificate", &zcert);
+ zval_ptr_dtor(&zcert);
cert_captured = 1;
- FREE_ZVAL(zcert);
}
- if (SUCCESS == php_stream_context_get_option(stream->context,
- "ssl", "capture_peer_cert_chain", &val) &&
- zend_is_true(*val)
+ if (NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream),
+ "ssl", "capture_peer_cert_chain")) &&
+ zend_is_true(val)
) {
- zval *arr;
+ zval arr;
STACK_OF(X509) *chain;
- MAKE_STD_ZVAL(arr);
chain = SSL_get_peer_cert_chain(sslsock->ssl_handle);
if (chain && sk_X509_num(chain) > 0) {
int i;
- array_init(arr);
+ array_init(&arr);
for (i = 0; i < sk_X509_num(chain); i++) {
X509 *mycert = X509_dup(sk_X509_value(chain, i));
- MAKE_STD_ZVAL(zcert);
- ZVAL_RESOURCE(zcert, zend_list_insert(mycert, php_openssl_get_x509_list_id() TSRMLS_CC));
- add_next_index_zval(arr, zcert);
+ ZVAL_RES(&zcert, zend_register_resource(mycert, php_openssl_get_x509_list_id()));
+ add_next_index_zval(&arr, &zcert);
}
} else {
- ZVAL_NULL(arr);
+ ZVAL_NULL(&arr);
}
- php_stream_context_set_option(stream->context, "ssl", "peer_certificate_chain", arr);
- zval_dtor(arr);
- efree(arr);
+ php_stream_context_set_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_certificate_chain", &arr);
+ zval_ptr_dtor(&arr);
}
return cert_captured;
@@ -1670,7 +1767,7 @@ static int capture_peer_certs(php_stream *stream, php_openssl_netstream_data_t *
static int php_openssl_enable_crypto(php_stream *stream,
php_openssl_netstream_data_t *sslsock,
php_stream_xport_crypto_param *cparam
- TSRMLS_DC)
+ )
{
int n;
int retry = 1;
@@ -1683,7 +1780,7 @@ static int php_openssl_enable_crypto(php_stream *stream,
int blocked = sslsock->s.is_blocked,
has_timeout = 0;
-#ifdef HAVE_SNI
+#ifdef HAVE_TLS_SNI
if (sslsock->is_client) {
enable_client_sni(stream, sslsock);
}
@@ -1698,20 +1795,20 @@ static int php_openssl_enable_crypto(php_stream *stream,
sslsock->state_set = 1;
}
- if (SUCCESS == php_set_sock_blocking(sslsock->s.socket, 0 TSRMLS_CC)) {
+ if (SUCCESS == php_set_sock_blocking(sslsock->s.socket, 0)) {
sslsock->s.is_blocked = 0;
}
-
+
timeout = sslsock->is_client ? &sslsock->connect_timeout : &sslsock->s.timeout;
has_timeout = !sslsock->s.is_blocked && (timeout->tv_sec || timeout->tv_usec);
/* gettimeofday is not monotonic; using it here is not strictly correct */
if (has_timeout) {
gettimeofday(&start_time, NULL);
}
-
+
do {
struct timeval cur_time,
- elapsed_time = {0};
+ elapsed_time;
if (sslsock->is_client) {
n = SSL_connect(sslsock->ssl_handle);
@@ -1724,20 +1821,20 @@ static int php_openssl_enable_crypto(php_stream *stream,
elapsed_time = subtract_timeval( cur_time, start_time );
if (compare_timeval( elapsed_time, *timeout) > 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL: Handshake timed out");
+ php_error_docref(NULL, E_WARNING, "SSL: Handshake timed out");
return -1;
}
}
if (n <= 0) {
/* in case of SSL_ERROR_WANT_READ/WRITE, do not retry in non-blocking mode */
- retry = handle_ssl_error(stream, n, blocked TSRMLS_CC);
+ retry = handle_ssl_error(stream, n, blocked);
if (retry) {
/* wait until something interesting happens in the socket. It may be a
* timeout. Also consider the unlikely of possibility of a write block */
int err = SSL_get_error(sslsock->ssl_handle, n);
struct timeval left_time;
-
+
if (has_timeout) {
left_time = subtract_timeval( *timeout, elapsed_time );
}
@@ -1749,33 +1846,37 @@ static int php_openssl_enable_crypto(php_stream *stream,
}
} while (retry);
- if (sslsock->s.is_blocked != blocked && SUCCESS == php_set_sock_blocking(sslsock->s.socket, blocked TSRMLS_CC)) {
+ if (sslsock->s.is_blocked != blocked && SUCCESS == php_set_sock_blocking(sslsock->s.socket, blocked)) {
sslsock->s.is_blocked = blocked;
}
if (n == 1) {
peer_cert = SSL_get_peer_certificate(sslsock->ssl_handle);
- if (peer_cert && stream->context) {
- cert_captured = capture_peer_certs(stream, sslsock, peer_cert TSRMLS_CC);
+ if (peer_cert && PHP_STREAM_CONTEXT(stream)) {
+ cert_captured = capture_peer_certs(stream, sslsock, peer_cert);
}
- if (FAILURE == apply_peer_verification_policy(sslsock->ssl_handle, peer_cert, stream TSRMLS_CC)) {
+ if (FAILURE == apply_peer_verification_policy(sslsock->ssl_handle, peer_cert, stream)) {
SSL_shutdown(sslsock->ssl_handle);
n = -1;
- } else {
+ } else {
sslsock->ssl_active = 1;
- if (stream->context) {
- zval **val;
-
- if (SUCCESS == php_stream_context_get_option(stream->context,
- "ssl", "capture_session_meta", &val) &&
- zend_is_true(*val)
+ if (PHP_STREAM_CONTEXT(stream)) {
+ zval *val;
+ if (NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream),
+ "ssl", "capture_session_meta"))
) {
- zval *meta_arr = capture_session_meta(sslsock->ssl_handle);
- php_stream_context_set_option(stream->context, "ssl", "session_meta", meta_arr);
- zval_dtor(meta_arr);
- efree(meta_arr);
+ php_error(E_DEPRECATED,
+ "capture_session_meta is deprecated; its information is now available via stream_get_meta_data()"
+ );
+ }
+
+ if (val && zend_is_true(val)) {
+ zval meta_arr;
+ ZVAL_ARR(&meta_arr, capture_session_meta(sslsock->ssl_handle));
+ php_stream_context_set_option(PHP_STREAM_CONTEXT(stream), "ssl", "session_meta", &meta_arr);
+ zval_ptr_dtor(&meta_arr);
}
}
}
@@ -1783,9 +1884,10 @@ static int php_openssl_enable_crypto(php_stream *stream,
n = 0;
} else {
n = -1;
+ /* We want to capture the peer cert even if verification fails*/
peer_cert = SSL_get_peer_certificate(sslsock->ssl_handle);
- if (peer_cert && stream->context) {
- cert_captured = capture_peer_certs(stream, sslsock, peer_cert TSRMLS_CC);
+ if (peer_cert && PHP_STREAM_CONTEXT(stream)) {
+ cert_captured = capture_peer_certs(stream, sslsock, peer_cert);
}
}
@@ -1804,15 +1906,15 @@ static int php_openssl_enable_crypto(php_stream *stream,
return -1;
}
-static size_t php_openssl_sockop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)/* {{{ */
+static size_t php_openssl_sockop_read(php_stream *stream, char *buf, size_t count) /* {{{ */
{
- return php_openssl_sockop_io(1, stream, buf, count TSRMLS_CC);
+ return php_openssl_sockop_io( 1, stream, buf, count );
}
/* }}} */
-static size_t php_openssl_sockop_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) /* {{{ */
+static size_t php_openssl_sockop_write(php_stream *stream, const char *buf, size_t count) /* {{{ */
{
- return php_openssl_sockop_io(0, stream, (char*)buf, count TSRMLS_CC);
+ return php_openssl_sockop_io( 0, stream, (char*)buf, count );
}
/* }}} */
@@ -1823,10 +1925,9 @@ static size_t php_openssl_sockop_write(php_stream *stream, const char *buf, size
* report that back to PHP
*
*/
-static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, size_t count TSRMLS_DC)
+static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, size_t count) /* {{{ */
{
php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
- int nr_bytes = 0;
/* Only do this if SSL is active. */
if (sslsock->ssl_active) {
@@ -1835,13 +1936,19 @@ static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, siz
struct timeval *timeout = NULL;
int began_blocked = sslsock->s.is_blocked;
int has_timeout = 0;
+ int nr_bytes = 0;
+
+ /* prevent overflow in openssl */
+ if (count > INT_MAX) {
+ count = INT_MAX;
+ }
/* never use a timeout with non-blocking sockets */
if (began_blocked && &sslsock->s.timeout) {
timeout = &sslsock->s.timeout;
}
- if (timeout && php_set_sock_blocking(sslsock->s.socket, 0 TSRMLS_CC) == SUCCESS) {
+ if (timeout && php_set_sock_blocking(sslsock->s.socket, 0) == SUCCESS) {
sslsock->s.is_blocked = 0;
}
@@ -1854,7 +1961,7 @@ static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, siz
/* Main IO loop. */
do {
struct timeval cur_time, elapsed_time, left_time;
-
+
/* If we have a timeout to check, figure out how much time has elapsed since we started. */
if (has_timeout) {
gettimeofday(&cur_time, NULL);
@@ -1866,7 +1973,7 @@ static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, siz
if (compare_timeval(elapsed_time, *timeout) > 0 ) {
/* If the socket was originally blocking, set it back. */
if (began_blocked) {
- php_set_sock_blocking(sslsock->s.socket, 1 TSRMLS_CC);
+ php_set_sock_blocking(sslsock->s.socket, 1);
sslsock->s.is_blocked = 1;
}
sslsock->s.timeout_event = 1;
@@ -1876,17 +1983,17 @@ static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, siz
/* Now, do the IO operation. Don't block if we can't complete... */
if (read) {
- nr_bytes = SSL_read(sslsock->ssl_handle, buf, count);
+ nr_bytes = SSL_read(sslsock->ssl_handle, buf, (int)count);
if (sslsock->reneg && sslsock->reneg->should_close) {
/* renegotiation rate limiting triggered */
- php_stream_xport_shutdown(stream, (stream_shutdown_t)SHUT_RDWR TSRMLS_CC);
+ php_stream_xport_shutdown(stream, (stream_shutdown_t)SHUT_RDWR);
nr_bytes = 0;
stream->eof = 1;
- break;
+ break;
}
} else {
- nr_bytes = SSL_write(sslsock->ssl_handle, buf, count);
+ nr_bytes = SSL_write(sslsock->ssl_handle, buf, (int)count);
}
/* Now, how much time until we time out? */
@@ -1899,7 +2006,7 @@ static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, siz
/* Get the error code from SSL, and check to see if it's an error or not. */
int err = SSL_get_error(sslsock->ssl_handle, nr_bytes );
- retry = handle_ssl_error(stream, nr_bytes, 0 TSRMLS_CC);
+ retry = handle_ssl_error(stream, nr_bytes, 0);
/* If we get this (the above doesn't check) then we'll retry as well. */
if (errno == EAGAIN && err == SSL_ERROR_WANT_READ && read) {
@@ -1908,7 +2015,7 @@ static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, siz
if (errno == EAGAIN && err == SSL_ERROR_WANT_WRITE && read == 0) {
retry = 1;
}
-
+
/* Also, on reads, we may get this condition on an EOF. We should check properly. */
if (read) {
stream->eof = (retry == 0 && errno != EAGAIN && !SSL_pending(sslsock->ssl_handle));
@@ -1936,8 +2043,9 @@ static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, siz
int err = SSL_get_error(sslsock->ssl_handle, nr_bytes);
/* If we didn't get any error, then let's return it to PHP. */
- if (err == SSL_ERROR_NONE)
- break;
+ if (err == SSL_ERROR_NONE) {
+ break;
+ }
/* Otherwise, we need to wait again (up to time_left or we get an error) */
if (began_blocked) {
@@ -1950,39 +2058,39 @@ static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, siz
}
}
}
- /* Finally, we keep going until we got data, and an SSL_ERROR_NONE, unless we had an error. */
+
+ /* Finally, we keep going until we got data, and an SSL_ERROR_NONE, unless we had an error. */
} while (retry);
/* Tell PHP if we read / wrote bytes. */
if (nr_bytes > 0) {
- php_stream_notify_progress_increment(stream->context, nr_bytes, 0);
+ php_stream_notify_progress_increment(PHP_STREAM_CONTEXT(stream), nr_bytes, 0);
}
/* And if we were originally supposed to be blocking, let's reset the socket to that. */
- if (began_blocked && php_set_sock_blocking(sslsock->s.socket, 1 TSRMLS_CC) == SUCCESS) {
+ if (began_blocked && php_set_sock_blocking(sslsock->s.socket, 1) == SUCCESS) {
sslsock->s.is_blocked = 1;
}
+
+ return 0 > nr_bytes ? 0 : nr_bytes;
} else {
+ size_t nr_bytes = 0;
+
/*
- * This block is if we had no timeout... We will just sit and wait forever on the IO operation.
+ * This block is if we had no timeout... We will just sit and wait forever on the IO operation.
*/
if (read) {
- nr_bytes = php_stream_socket_ops.read(stream, buf, count TSRMLS_CC);
+ nr_bytes = php_stream_socket_ops.read(stream, buf, count);
} else {
- nr_bytes = php_stream_socket_ops.write(stream, buf, count TSRMLS_CC);
+ nr_bytes = php_stream_socket_ops.write(stream, buf, count);
}
- }
- /* PHP doesn't expect a negative return. */
- if (nr_bytes < 0) {
- nr_bytes = 0;
+ return nr_bytes;
}
-
- return nr_bytes;
}
/* }}} */
-struct timeval subtract_timeval( struct timeval a, struct timeval b )
+static struct timeval subtract_timeval( struct timeval a, struct timeval b )
{
struct timeval difference;
@@ -1997,7 +2105,7 @@ struct timeval subtract_timeval( struct timeval a, struct timeval b )
return difference;
}
-int compare_timeval( struct timeval a, struct timeval b )
+static int compare_timeval( struct timeval a, struct timeval b )
{
if (a.tv_sec > b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_usec > b.tv_usec) ) {
return 1;
@@ -2008,7 +2116,7 @@ int compare_timeval( struct timeval a, struct timeval b )
}
}
-static int php_openssl_sockop_close(php_stream *stream, int close_handle TSRMLS_DC) /* {{{ */
+static int php_openssl_sockop_close(php_stream *stream, int close_handle) /* {{{ */
{
php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
#ifdef PHP_WIN32
@@ -2078,20 +2186,20 @@ static int php_openssl_sockop_close(php_stream *stream, int close_handle TSRMLS_
}
/* }}} */
-static int php_openssl_sockop_flush(php_stream *stream TSRMLS_DC) /* {{{ */
+static int php_openssl_sockop_flush(php_stream *stream) /* {{{ */
{
- return php_stream_socket_ops.flush(stream TSRMLS_CC);
+ return php_stream_socket_ops.flush(stream);
}
/* }}} */
-static int php_openssl_sockop_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) /* {{{ */
+static int php_openssl_sockop_stat(php_stream *stream, php_stream_statbuf *ssb) /* {{{ */
{
- return php_stream_socket_ops.stat(stream, ssb TSRMLS_CC);
+ return php_stream_socket_ops.stat(stream, ssb);
}
/* }}} */
static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_netstream_data_t *sock,
- php_stream_xport_param *xparam STREAMS_DC TSRMLS_DC)
+ php_stream_xport_param *xparam STREAMS_DC)
{
int clisock;
@@ -2099,13 +2207,12 @@ static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_
clisock = php_network_accept_incoming(sock->s.socket,
xparam->want_textaddr ? &xparam->outputs.textaddr : NULL,
- xparam->want_textaddr ? &xparam->outputs.textaddrlen : NULL,
xparam->want_addr ? &xparam->outputs.addr : NULL,
xparam->want_addr ? &xparam->outputs.addrlen : NULL,
xparam->inputs.timeout,
xparam->want_errortext ? &xparam->outputs.error_text : NULL,
&xparam->outputs.error_code
- TSRMLS_CC);
+ );
if (clisock >= 0) {
php_openssl_netstream_data_t *clisockdata;
@@ -2121,12 +2228,12 @@ static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_
memcpy(clisockdata, sock, sizeof(clisockdata->s));
clisockdata->s.socket = clisock;
-
+
xparam->outputs.client = php_stream_alloc_rel(stream->ops, clisockdata, NULL, "r+");
if (xparam->outputs.client) {
- xparam->outputs.client->context = stream->context;
- if (stream->context) {
- zend_list_addref(stream->context->rsrc_id);
+ xparam->outputs.client->ctx = stream->ctx;
+ if (stream->ctx) {
+ GC_REFCOUNT(stream->ctx)++;
}
}
}
@@ -2140,9 +2247,9 @@ static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_
clisockdata->method = sock->method;
if (php_stream_xport_crypto_setup(xparam->outputs.client, clisockdata->method,
- NULL TSRMLS_CC) < 0 || php_stream_xport_crypto_enable(
- xparam->outputs.client, 1 TSRMLS_CC) < 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to enable crypto");
+ NULL) < 0 || php_stream_xport_crypto_enable(
+ xparam->outputs.client, 1) < 0) {
+ php_error_docref(NULL, E_WARNING, "Failed to enable crypto");
php_stream_close(xparam->outputs.client);
xparam->outputs.client = NULL;
@@ -2150,17 +2257,69 @@ static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_
}
}
}
-
+
return xparam->outputs.client == NULL ? -1 : 0;
}
-static int php_openssl_sockop_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC)
+static int php_openssl_sockop_set_option(php_stream *stream, int option, int value, void *ptrparam)
{
php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
php_stream_xport_crypto_param *cparam = (php_stream_xport_crypto_param *)ptrparam;
php_stream_xport_param *xparam = (php_stream_xport_param *)ptrparam;
switch (option) {
+ case PHP_STREAM_OPTION_META_DATA_API:
+ if (sslsock->ssl_active) {
+ zval tmp;
+ char *proto_str;
+ const SSL_CIPHER *cipher;
+
+ array_init(&tmp);
+
+ switch (SSL_version(sslsock->ssl_handle)) {
+#ifdef HAVE_TLS12
+ case TLS1_2_VERSION: proto_str = "TLSv1.2"; break;
+#endif
+#ifdef HAVE_TLS11
+ case TLS1_1_VERSION: proto_str = "TLSv1.1"; break;
+#endif
+ case TLS1_VERSION: proto_str = "TLSv1"; break;
+#ifdef HAVE_SSL3
+ case SSL3_VERSION: proto_str = "SSLv3"; break;
+#endif
+#ifdef HAVE_SSL2
+ case SSL2_VERSION: proto_str = "SSLv2"; break;
+#endif
+ default: proto_str = "UNKNOWN";
+ }
+
+ cipher = SSL_get_current_cipher(sslsock->ssl_handle);
+
+ add_assoc_string(&tmp, "protocol", proto_str);
+ add_assoc_string(&tmp, "cipher_name", (char *) SSL_CIPHER_get_name(cipher));
+ add_assoc_long(&tmp, "cipher_bits", SSL_CIPHER_get_bits(cipher, NULL));
+ add_assoc_string(&tmp, "cipher_version", SSL_CIPHER_get_version(cipher));
+
+#ifdef HAVE_TLS_ALPN
+ {
+ const unsigned char *alpn_proto = NULL;
+ unsigned int alpn_proto_len = 0;
+
+ SSL_get0_alpn_selected(sslsock->ssl_handle, &alpn_proto, &alpn_proto_len);
+ if (alpn_proto) {
+ add_assoc_stringl(&tmp, "alpn_protocol", (char *)alpn_proto, alpn_proto_len);
+ }
+ }
+#endif
+ add_assoc_zval((zval *)ptrparam, "crypto", &tmp);
+ }
+
+ add_assoc_bool((zval *)ptrparam, "timed_out", sslsock->s.timeout_event);
+ add_assoc_bool((zval *)ptrparam, "blocked", sslsock->s.is_blocked);
+ add_assoc_bool((zval *)ptrparam, "eof", stream->eof);
+
+ return PHP_STREAM_OPTION_RETURN_OK;
+
case PHP_STREAM_OPTION_CHECK_LIVENESS:
{
struct timeval tv;
@@ -2169,7 +2328,11 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val
if (value == -1) {
if (sslsock->s.timeout.tv_sec == -1) {
- tv.tv_sec = FG(default_socket_timeout);
+#ifdef _WIN32
+ tv.tv_sec = (long)FG(default_socket_timeout);
+#else
+ tv.tv_sec = (time_t)FG(default_socket_timeout);
+#endif
tv.tv_usec = 0;
} else {
tv = sslsock->connect_timeout;
@@ -2213,17 +2376,17 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val
}
return alive ? PHP_STREAM_OPTION_RETURN_OK : PHP_STREAM_OPTION_RETURN_ERR;
}
-
+
case PHP_STREAM_OPTION_CRYPTO_API:
switch(cparam->op) {
case STREAM_XPORT_CRYPTO_OP_SETUP:
- cparam->outputs.returncode = php_openssl_setup_crypto(stream, sslsock, cparam TSRMLS_CC);
+ cparam->outputs.returncode = php_openssl_setup_crypto(stream, sslsock, cparam);
return PHP_STREAM_OPTION_RETURN_OK;
break;
case STREAM_XPORT_CRYPTO_OP_ENABLE:
- cparam->outputs.returncode = php_openssl_enable_crypto(stream, sslsock, cparam TSRMLS_CC);
+ cparam->outputs.returncode = php_openssl_enable_crypto(stream, sslsock, cparam);
return PHP_STREAM_OPTION_RETURN_OK;
break;
default:
@@ -2240,16 +2403,16 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val
case STREAM_XPORT_OP_CONNECT_ASYNC:
/* TODO: Async connects need to check the enable_on_connect option when
* we notice that the connect has actually been established */
- php_stream_socket_ops.set_option(stream, option, value, ptrparam TSRMLS_CC);
+ php_stream_socket_ops.set_option(stream, option, value, ptrparam);
if ((sslsock->enable_on_connect) &&
((xparam->outputs.returncode == 0) ||
- (xparam->op == STREAM_XPORT_OP_CONNECT_ASYNC &&
+ (xparam->op == STREAM_XPORT_OP_CONNECT_ASYNC &&
xparam->outputs.returncode == 1 && xparam->outputs.error_code == EINPROGRESS)))
{
- if (php_stream_xport_crypto_setup(stream, sslsock->method, NULL TSRMLS_CC) < 0 ||
- php_stream_xport_crypto_enable(stream, 1 TSRMLS_CC) < 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to enable crypto");
+ if (php_stream_xport_crypto_setup(stream, sslsock->method, NULL) < 0 ||
+ php_stream_xport_crypto_enable(stream, 1) < 0) {
+ php_error_docref(NULL, E_WARNING, "Failed to enable crypto");
xparam->outputs.returncode = -1;
}
}
@@ -2258,9 +2421,9 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val
case STREAM_XPORT_OP_ACCEPT:
/* we need to copy the additional fields that the underlying tcp transport
* doesn't know about */
- xparam->outputs.returncode = php_openssl_tcp_sockop_accept(stream, sslsock, xparam STREAMS_CC TSRMLS_CC);
+ xparam->outputs.returncode = php_openssl_tcp_sockop_accept(stream, sslsock, xparam STREAMS_CC);
+
-
return PHP_STREAM_OPTION_RETURN_OK;
default:
@@ -2269,10 +2432,10 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val
}
}
- return php_stream_socket_ops.set_option(stream, option, value, ptrparam TSRMLS_CC);
+ return php_stream_socket_ops.set_option(stream, option, value, ptrparam);
}
-static int php_openssl_sockop_cast(php_stream *stream, int castas, void **ret TSRMLS_DC)
+static int php_openssl_sockop_cast(php_stream *stream, int castas, void **ret)
{
php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
@@ -2329,20 +2492,20 @@ php_stream_ops php_openssl_socket_ops = {
php_openssl_sockop_set_option,
};
-static long get_crypto_method(php_stream_context *ctx, long crypto_method)
+static zend_long get_crypto_method(php_stream_context *ctx, zend_long crypto_method)
{
- zval **val;
+ zval *val;
- if (ctx && php_stream_context_get_option(ctx, "ssl", "crypto_method", &val) == SUCCESS) {
+ if (ctx && (val = php_stream_context_get_option(ctx, "ssl", "crypto_method")) != NULL) {
convert_to_long_ex(val);
- crypto_method = (long)Z_LVAL_PP(val);
+ crypto_method = (zend_long)Z_LVAL_P(val);
crypto_method |= STREAM_CRYPTO_IS_CLIENT;
}
return crypto_method;
}
-static char *get_url_name(const char *resourcename, size_t resourcenamelen, int is_persistent TSRMLS_DC)
+static char *get_url_name(const char *resourcename, size_t resourcenamelen, int is_persistent)
{
php_url *url;
@@ -2381,7 +2544,7 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen,
const char *resourcename, size_t resourcenamelen,
const char *persistent_id, int options, int flags,
struct timeval *timeout,
- php_stream_context *context STREAMS_DC TSRMLS_DC)
+ php_stream_context *context STREAMS_DC)
{
php_stream *stream = NULL;
php_openssl_netstream_data_t *sslsock = NULL;
@@ -2391,7 +2554,11 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen,
sslsock->s.is_blocked = 1;
/* this timeout is used by standard stream funcs, therefor it should use the default value */
- sslsock->s.timeout.tv_sec = FG(default_socket_timeout);
+#ifdef _WIN32
+ sslsock->s.timeout.tv_sec = (long)FG(default_socket_timeout);
+#else
+ sslsock->s.timeout.tv_sec = (time_t)FG(default_socket_timeout);
+#endif
sslsock->s.timeout.tv_usec = 0;
/* use separate timeout for our private funcs */
@@ -2403,7 +2570,7 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen,
sslsock->s.socket = -1;
/* Initialize context as NULL */
- sslsock->ctx = NULL;
+ sslsock->ctx = NULL;
stream = php_stream_alloc_rel(&php_openssl_socket_ops, sslsock, persistent_id, "r+");
@@ -2416,20 +2583,22 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen,
sslsock->enable_on_connect = 1;
sslsock->method = get_crypto_method(context, STREAM_CRYPTO_METHOD_ANY_CLIENT);
} else if (strncmp(proto, "sslv2", protolen) == 0) {
-#ifdef OPENSSL_NO_SSL2
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSLv2 support is not compiled into the OpenSSL library PHP is linked against");
- return NULL;
-#else
+#ifdef HAVE_SSL2
sslsock->enable_on_connect = 1;
sslsock->method = STREAM_CRYPTO_METHOD_SSLv2_CLIENT;
+#else
+ php_error_docref(NULL, E_WARNING, "SSLv2 support is not compiled into the OpenSSL library against which PHP is linked");
+ php_stream_close(stream);
+ return NULL;
#endif
} else if (strncmp(proto, "sslv3", protolen) == 0) {
-#ifdef OPENSSL_NO_SSL3
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSLv3 support is not compiled into the OpenSSL library PHP is linked against");
- return NULL;
-#else
+#ifdef HAVE_SSL3
sslsock->enable_on_connect = 1;
sslsock->method = STREAM_CRYPTO_METHOD_SSLv3_CLIENT;
+#else
+ php_error_docref(NULL, E_WARNING, "SSLv3 support is not compiled into the OpenSSL library against which PHP is linked");
+ php_stream_close(stream);
+ return NULL;
#endif
} else if (strncmp(proto, "tls", protolen) == 0) {
sslsock->enable_on_connect = 1;
@@ -2438,24 +2607,26 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen,
sslsock->enable_on_connect = 1;
sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT;
} else if (strncmp(proto, "tlsv1.1", protolen) == 0) {
-#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+#ifdef HAVE_TLS11
sslsock->enable_on_connect = 1;
sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
#else
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.1 support is not compiled into the OpenSSL library PHP is linked against");
+ php_error_docref(NULL, E_WARNING, "TLSv1.1 support is not compiled into the OpenSSL library against which PHP is linked");
+ php_stream_close(stream);
return NULL;
#endif
} else if (strncmp(proto, "tlsv1.2", protolen) == 0) {
-#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+#ifdef HAVE_TLS12
sslsock->enable_on_connect = 1;
sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
#else
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.2 support is not compiled into the OpenSSL library PHP is linked against");
+ php_error_docref(NULL, E_WARNING, "TLSv1.2 support is not compiled into the OpenSSL library against which PHP is linked");
+ php_stream_close(stream);
return NULL;
#endif
}
- sslsock->url_name = get_url_name(resourcename, resourcenamelen, !!persistent_id TSRMLS_CC);
+ sslsock->url_name = get_url_name(resourcename, resourcenamelen, !!persistent_id);
return stream;
}