From 9f44eca6b60f8073dc9e2aa31154f9d70b42938d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Sat, 1 Aug 2020 22:42:26 +0200 Subject: Convert resources to objects in ext/openssl Closes GH-5860 Co-authored-by: Nikita Popov --- UPGRADING | 17 + ext/openssl/openssl.c | 1195 ++++++++++++-------- ext/openssl/openssl.stub.php | 212 ++-- ext/openssl/openssl_arginfo.h | 105 +- ext/openssl/php_openssl.h | 15 + ext/openssl/tests/001.phpt | 20 +- ext/openssl/tests/CertificateGenerator.inc | 2 +- ext/openssl/tests/bug38261.phpt | 24 +- ext/openssl/tests/bug61930.phpt | 3 +- ext/openssl/tests/bug68912.phpt | 2 +- ext/openssl/tests/bug73711.phpt | 6 +- ext/openssl/tests/bug74651.phpt | 3 +- ext/openssl/tests/bug79145.phpt | 2 +- ext/openssl/tests/ecc.phpt | 15 +- ext/openssl/tests/openssl_cms_decrypt_basic.phpt | 6 +- ext/openssl/tests/openssl_cms_decrypt_error.phpt | 8 +- ext/openssl/tests/openssl_cms_sign_basic.phpt | 4 +- ext/openssl/tests/openssl_csr_export_bacis.phpt | 46 - ext/openssl/tests/openssl_csr_export_basic.phpt | 48 + .../tests/openssl_csr_export_to_file_basic.phpt | 18 +- .../tests/openssl_csr_get_public_key_basic.phpt | 6 +- ext/openssl/tests/openssl_csr_new_basic.phpt | 6 +- ext/openssl/tests/openssl_csr_sign_basic.phpt | 43 +- ext/openssl/tests/openssl_free_key.phpt | 8 +- ext/openssl/tests/openssl_pkcs12_export_basic.phpt | 8 +- .../tests/openssl_pkcs12_export_to_file_basic.phpt | 8 +- ext/openssl/tests/openssl_pkcs7_decrypt_basic.phpt | 6 +- ext/openssl/tests/openssl_pkcs7_decrypt_error.phpt | 8 +- ext/openssl/tests/openssl_pkcs7_sign_basic.phpt | 4 +- ext/openssl/tests/openssl_pkey_export_basic.phpt | 8 +- ext/openssl/tests/openssl_pkey_new_error.phpt | 6 +- ext/openssl/tests/openssl_x509_export_basic.phpt | 13 +- .../tests/openssl_x509_export_to_file_basic.phpt | 12 +- .../tests/openssl_x509_fingerprint_basic.phpt | 2 +- ext/openssl/tests/openssl_x509_free_basic.phpt | 8 +- ext/openssl/tests/openssl_x509_read_basic.phpt | 34 +- ext/openssl/xp_ssl.c | 12 +- 37 files changed, 1131 insertions(+), 812 deletions(-) delete mode 100644 ext/openssl/tests/openssl_csr_export_bacis.phpt create mode 100644 ext/openssl/tests/openssl_csr_export_basic.phpt diff --git a/UPGRADING b/UPGRADING index f38f149236..cee09177be 100644 --- a/UPGRADING +++ b/UPGRADING @@ -366,6 +366,23 @@ PHP 8.0 UPGRADE NOTES . Several alias functions have been marked as deprecated. . oci_internal_debug() and its alias ociinternaldebug() have been removed. +- OpenSSL: + . openssl_x509_read() and openssl_csr_sign() will now return an + OpenSSLCertificate object rather than a resource. Return value checks using + is_resource() should be replaced with checks for `false`. + . The openssl_x509_free() function is deprecated and no longer has an effect, + instead the OpenSSLCertificate instance is automatically destroyed if it is no + longer referenced. + . openssl_csr_new() will now return an OpenSSLCertificateSigningRequest object + rather than a resource. Return value checks using is_resource() should be + replaced with checks for `false`. + . openssl_pkey_new() will now return an OpenSSLAsymmetricKey object rather than a + resource. Return value checks using is_resource() should be replaced with + checks for `false`. + . The openssl_pkey_free() function is deprecated and no longer has an effect, + instead the OpenSSLAsymmetricKey instance is automatically destroyed if it is no + longer referenced. + - PCRE: . When passing invalid escape sequences they are no longer interpreted as literals. This behavior previously required the X modifier - which is diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 7539dda14d..3537a5be42 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -28,6 +28,7 @@ #include "php_ini.h" #include "php_openssl.h" #include "zend_exceptions.h" +#include "Zend/zend_interfaces.h" /* PHP Includes */ #include "ext/standard/file.h" @@ -127,6 +128,118 @@ enum php_openssl_encoding { ENCODING_PEM, }; +/* OpenSSLCertificate class */ + +zend_class_entry *php_openssl_certificate_ce; + +static zend_object_handlers php_openssl_certificate_object_handlers; + +static zend_object *php_openssl_certificate_create_object(zend_class_entry *class_type) { + php_openssl_certificate_object *intern = zend_object_alloc(sizeof(php_openssl_certificate_object), class_type); + + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &php_openssl_certificate_object_handlers; + + return &intern->std; +} + +static zend_function *php_openssl_certificate_get_constructor(zend_object *object) { + zend_throw_error(NULL, "Cannot directly construct OpenSSLCertificate, use openssl_x509_read() instead"); + return NULL; +} + +static void php_openssl_certificate_free_obj(zend_object *object) +{ + php_openssl_certificate_object *x509_object = php_openssl_certificate_from_obj(object); + + X509_free(x509_object->x509); + zend_object_std_dtor(&x509_object->std); +} + +/* OpenSSLCertificateSigningRequest class */ + +typedef struct _php_openssl_x509_request_object { + X509_REQ *csr; + zend_object std; +} php_openssl_request_object; + +zend_class_entry *php_openssl_request_ce; + +static inline php_openssl_request_object *php_openssl_request_from_obj(zend_object *obj) { + return (php_openssl_request_object *)((char *)(obj) - XtOffsetOf(php_openssl_request_object, std)); +} + +#define Z_OPENSSL_REQUEST_P(zv) php_openssl_request_from_obj(Z_OBJ_P(zv)) + +static zend_object_handlers php_openssl_request_object_handlers; + +static zend_object *php_openssl_request_create_object(zend_class_entry *class_type) { + php_openssl_request_object *intern = zend_object_alloc(sizeof(php_openssl_request_object), class_type); + + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &php_openssl_request_object_handlers; + + return &intern->std; +} + +static zend_function *php_openssl_request_get_constructor(zend_object *object) { + zend_throw_error(NULL, "Cannot directly construct OpenSSLCertificateSigningRequest, use openssl_csr_new() instead"); + return NULL; +} + +static void php_openssl_request_free_obj(zend_object *object) +{ + php_openssl_request_object *x509_request = php_openssl_request_from_obj(object); + + X509_REQ_free(x509_request->csr); + zend_object_std_dtor(&x509_request->std); +} + +/* OpenSSLAsymmetricKey class */ + +typedef struct _php_openssl_pkey_object { + EVP_PKEY *pkey; + zend_object std; +} php_openssl_pkey_object; + +zend_class_entry *php_openssl_pkey_ce; + +static inline php_openssl_pkey_object *php_openssl_pkey_from_obj(zend_object *obj) { + return (php_openssl_pkey_object *)((char *)(obj) - XtOffsetOf(php_openssl_pkey_object, std)); +} + +#define Z_OPENSSL_PKEY_P(zv) php_openssl_pkey_from_obj(Z_OBJ_P(zv)) + +static zend_object_handlers php_openssl_pkey_object_handlers; + +static zend_object *php_openssl_pkey_create_object(zend_class_entry *class_type) { + php_openssl_pkey_object *intern = zend_object_alloc(sizeof(php_openssl_pkey_object), class_type); + + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &php_openssl_pkey_object_handlers; + + return &intern->std; +} + +static zend_function *php_openssl_pkey_get_constructor(zend_object *object) { + zend_throw_error(NULL, "Cannot directly construct OpenSSLAsymmetricKey, use openssl_pkey_new() instead"); + return NULL; +} + +static void php_openssl_pkey_free_obj(zend_object *object) +{ + php_openssl_pkey_object *key_object = php_openssl_pkey_from_obj(object); + + EVP_PKEY *pkey = key_object->pkey; + assert(pkey != NULL); + EVP_PKEY_free(pkey); + + zend_object_std_dtor(&key_object->std); +} + /* {{{ openssl_module_entry */ zend_module_entry openssl_module_entry = { STANDARD_MODULE_HEADER, @@ -152,6 +265,7 @@ ZEND_GET_MODULE(openssl) /* {{{ OpenSSL compatibility functions and macros */ #if PHP_OPENSSL_API_VERSION < 0x10100 + #define EVP_PKEY_get0_RSA(_pkey) _pkey->pkey.rsa #define EVP_PKEY_get0_DH(_pkey) _pkey->pkey.dh #define EVP_PKEY_get0_DSA(_pkey) _pkey->pkey.dsa @@ -268,6 +382,11 @@ static const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *asn1) return M_ASN1_STRING_data(asn1); } +static int EVP_PKEY_up_ref(EVP_PKEY *pkey) +{ + return CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); +} + #if PHP_OPENSSL_API_VERSION < 0x10002 static int X509_get_signature_nid(const X509 *x) @@ -345,38 +464,8 @@ void php_openssl_store_errors() } /* }}} */ -static int le_key; -static int le_x509; -static int le_csr; static int ssl_stream_data_index; -int php_openssl_get_x509_list_id(void) /* {{{ */ -{ - return le_x509; -} -/* }}} */ - -/* {{{ resource destructors */ -static void php_openssl_pkey_free(zend_resource *rsrc) -{ - EVP_PKEY *pkey = (EVP_PKEY *)rsrc->ptr; - - assert(pkey != NULL); - - EVP_PKEY_free(pkey); -} - -static void php_openssl_x509_free(zend_resource *rsrc) -{ - X509 *x509 = (X509 *)rsrc->ptr; - X509_free(x509); -} - -static void php_openssl_csr_free(zend_resource *rsrc) -{ - X509_REQ * csr = (X509_REQ*)rsrc->ptr; - X509_REQ_free(csr); -} /* }}} */ /* {{{ openssl open_basedir check */ @@ -429,14 +518,14 @@ struct php_x509_request { /* {{{ */ }; /* }}} */ -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, size_t passphrase_len, - int makeresource, zend_resource **resourceval); +static X509 *php_openssl_x509_from_param(zend_object *cert_obj, zend_string *cert_str); +static X509 *php_openssl_x509_from_zval(zval *val, bool *free_cert); +static X509_REQ *php_openssl_csr_from_param(zend_object *csr_obj, zend_string *csr_str); +static EVP_PKEY *php_openssl_pkey_from_zval(zval *val, int public_key, char *passphrase, size_t passphrase_len, bool *free_pkey); + static int php_openssl_is_private_key(EVP_PKEY* pkey); static X509_STORE * php_openssl_setup_verify(zval * calist); static STACK_OF(X509) * php_openssl_load_all_certs_from_file(char *certfile); -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 php_openssl_add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int shortname) /* {{{ */ @@ -1018,9 +1107,47 @@ PHP_MINIT_FUNCTION(openssl) { char * config_filename; - le_key = zend_register_list_destructors_ex(php_openssl_pkey_free, NULL, "OpenSSL key", module_number); - le_x509 = zend_register_list_destructors_ex(php_openssl_x509_free, NULL, "OpenSSL X.509", module_number); - le_csr = zend_register_list_destructors_ex(php_openssl_csr_free, NULL, "OpenSSL X.509 CSR", module_number); + zend_class_entry ce; + INIT_CLASS_ENTRY(ce, "OpenSSLCertificate", class_OpenSSLCertificate_methods); + php_openssl_certificate_ce = zend_register_internal_class(&ce); + php_openssl_certificate_ce->ce_flags |= ZEND_ACC_FINAL | ZEND_ACC_NO_DYNAMIC_PROPERTIES; + php_openssl_certificate_ce->create_object = php_openssl_certificate_create_object; + php_openssl_certificate_ce->serialize = zend_class_serialize_deny; + php_openssl_certificate_ce->unserialize = zend_class_unserialize_deny; + + memcpy(&php_openssl_certificate_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + php_openssl_certificate_object_handlers.offset = XtOffsetOf(php_openssl_certificate_object, std); + php_openssl_certificate_object_handlers.free_obj = php_openssl_certificate_free_obj; + php_openssl_certificate_object_handlers.get_constructor = php_openssl_certificate_get_constructor; + php_openssl_certificate_object_handlers.clone_obj = NULL; + + zend_class_entry csr_ce; + INIT_CLASS_ENTRY(csr_ce, "OpenSSLCertificateSigningRequest", class_OpenSSLCertificateSigningRequest_methods); + php_openssl_request_ce = zend_register_internal_class(&csr_ce); + php_openssl_request_ce->ce_flags |= ZEND_ACC_FINAL | ZEND_ACC_NO_DYNAMIC_PROPERTIES; + php_openssl_request_ce->create_object = php_openssl_request_create_object; + php_openssl_request_ce->serialize = zend_class_serialize_deny; + php_openssl_request_ce->unserialize = zend_class_unserialize_deny; + + memcpy(&php_openssl_request_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + php_openssl_request_object_handlers.offset = XtOffsetOf(php_openssl_request_object, std); + php_openssl_request_object_handlers.free_obj = php_openssl_request_free_obj; + php_openssl_request_object_handlers.get_constructor = php_openssl_request_get_constructor; + php_openssl_request_object_handlers.clone_obj = NULL; + + zend_class_entry key_ce; + INIT_CLASS_ENTRY(key_ce, "OpenSSLAsymmetricKey", class_OpenSSLAsymmetricKey_methods); + php_openssl_pkey_ce = zend_register_internal_class(&key_ce); + php_openssl_pkey_ce->ce_flags |= ZEND_ACC_FINAL | ZEND_ACC_NO_DYNAMIC_PROPERTIES; + php_openssl_pkey_ce->create_object = php_openssl_pkey_create_object; + php_openssl_pkey_ce->serialize = zend_class_serialize_deny; + php_openssl_pkey_ce->unserialize = zend_class_unserialize_deny; + + memcpy(&php_openssl_pkey_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + php_openssl_pkey_object_handlers.offset = XtOffsetOf(php_openssl_pkey_object, std); + php_openssl_pkey_object_handlers.free_obj = php_openssl_pkey_free_obj; + php_openssl_pkey_object_handlers.get_constructor = php_openssl_pkey_get_constructor; + php_openssl_pkey_object_handlers.clone_obj = NULL; #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined (LIBRESSL_VERSION_NUMBER) OPENSSL_config(NULL); @@ -1274,67 +1401,23 @@ PHP_FUNCTION(openssl_get_cert_locations) } /* }}} */ - -/* {{{ php_openssl_x509_from_zval - Given a zval, coerce it into an X509 object. - The zval can be: - . X509 resource created using openssl_read_x509() - . if it starts with file:// then it will be interpreted as the path to that cert - . it will be interpreted as the cert data - 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, zend_resource **resourceval) -{ +static X509 *php_openssl_x509_from_str(zend_string *cert_str) { X509 *cert = NULL; BIO *in; - if (resourceval) { - *resourceval = NULL; - } - if (Z_TYPE_P(val) == IS_RESOURCE) { - /* is it an x509 resource ? */ - void * what; - zend_resource *res = Z_RES_P(val); - - what = zend_fetch_resource(res, "OpenSSL X.509", le_x509); - if (!what) { - return NULL; - } - if (resourceval) { - *resourceval = res; - if (makeresource) { - Z_ADDREF_P(val); - } - } - return (X509*)what; - } - - 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 */ - if (!try_convert_to_string(val)) { - return NULL; - } - - if (Z_STRLEN_P(val) > 7 && memcmp(Z_STRVAL_P(val), "file://", sizeof("file://") - 1) == 0) { - - if (php_openssl_open_base_dir_chk(Z_STRVAL_P(val) + (sizeof("file://") - 1))) { + if (ZSTR_LEN(cert_str) > 7 && memcmp(ZSTR_VAL(cert_str), "file://", sizeof("file://") - 1) == 0) { + if (php_openssl_open_base_dir_chk(ZSTR_VAL(cert_str) + (sizeof("file://") - 1))) { return NULL; } - in = BIO_new_file(Z_STRVAL_P(val) + (sizeof("file://") - 1), PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)); + in = BIO_new_file(ZSTR_VAL(cert_str) + (sizeof("file://") - 1), PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)); if (in == NULL) { php_openssl_store_errors(); return NULL; } cert = PEM_read_bio_X509(in, NULL, NULL, NULL); - } else { - - in = BIO_new_mem_buf(Z_STRVAL_P(val), (int)Z_STRLEN_P(val)); + in = BIO_new_mem_buf(ZSTR_VAL(cert_str), (int) ZSTR_LEN(cert_str)); if (in == NULL) { php_openssl_store_errors(); return NULL; @@ -1355,32 +1438,69 @@ static X509 * php_openssl_x509_from_zval(zval * val, int makeresource, zend_reso return NULL; } - if (makeresource && resourceval) { - *resourceval = zend_register_resource(cert, le_x509); - } return cert; } +/* {{{ php_openssl_x509_from_param + Given a parameter, extract it into an X509 object. + The parameter can be: + . X509 object created using openssl_read_x509() + . a path to that cert if it starts with file:// + . the cert data otherwise +*/ +static X509 *php_openssl_x509_from_param(zend_object *cert_obj, zend_string *cert_str) { + if (cert_obj) { + return php_openssl_certificate_from_obj(cert_obj)->x509; + } + + ZEND_ASSERT(cert_str); + + return php_openssl_x509_from_str(cert_str); +} +/* }}} */ + +static X509 *php_openssl_x509_from_zval(zval *val, bool *free_cert) +{ + if (Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val) == php_openssl_certificate_ce) { + *free_cert = 0; + + return php_openssl_certificate_from_obj(Z_OBJ_P(val))->x509; + } + + *free_cert = 1; + + if (!try_convert_to_string(val)) { + return NULL; + } + + return php_openssl_x509_from_str(Z_STR_P(val)); +} /* }}} */ /* {{{ Exports a CERT to file or a var */ PHP_FUNCTION(openssl_x509_export_to_file) { - X509 * cert; - zval * zcert; + X509 *cert; + zend_object *cert_obj; + zend_string *cert_str; + zend_bool notext = 1; BIO * bio_out; char * filename; size_t filename_len; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "zp|b", &zcert, &filename, &filename_len, ¬ext) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR_OR_OBJ_OF_CLASS(cert_str, cert_obj, php_openssl_certificate_ce) + Z_PARAM_PATH(filename, filename_len) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(notext) + ZEND_PARSE_PARAMETERS_END(); + RETVAL_FALSE; - cert = php_openssl_x509_from_zval(zcert, 0, NULL); + cert = php_openssl_x509_from_param(cert_obj, cert_str); if (cert == NULL) { - php_error_docref(NULL, E_WARNING, "Cannot get cert from parameter 1"); + php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); return; } @@ -1402,7 +1522,8 @@ PHP_FUNCTION(openssl_x509_export_to_file) php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Error opening file %s", filename); } - if (Z_TYPE_P(zcert) != IS_RESOURCE) { + + if (cert_str) { X509_free(cert); } @@ -1417,25 +1538,25 @@ PHP_FUNCTION(openssl_x509_export_to_file) PHP_FUNCTION(openssl_spki_new) { size_t challenge_len; - char * challenge = NULL, * spkstr = NULL; + char * challenge = NULL, *spkstr = NULL; zend_string * s = NULL; - zend_resource *keyresource = NULL; + bool free_pkey = 0; const char *spkac = "SPKAC="; zend_long algo = OPENSSL_ALGO_MD5; - zval * zpkey = NULL; - EVP_PKEY * pkey = NULL; + zval *zpkey = NULL; + EVP_PKEY *pkey = NULL; NETSCAPE_SPKI *spki=NULL; const EVP_MD *mdtype; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|l", &zpkey, &challenge, &challenge_len, &algo) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os|l", &zpkey, php_openssl_pkey_ce, &challenge, &challenge_len, &algo) == FAILURE) { RETURN_THROWS(); } RETVAL_FALSE; PHP_OPENSSL_CHECK_SIZE_T_TO_INT(challenge_len, challenge); - pkey = php_openssl_evp_from_zval(zpkey, 0, challenge, challenge_len, 1, &keyresource); + pkey = php_openssl_pkey_from_zval(zpkey, 0, challenge, challenge_len, &free_pkey); if (pkey == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Unable to use supplied private key"); @@ -1496,17 +1617,10 @@ cleanup: if (spki != NULL) { NETSCAPE_SPKI_free(spki); } - if (keyresource == NULL && pkey != NULL) { - EVP_PKEY_free(pkey); - } if (s && ZSTR_LEN(s) <= 0) { RETVAL_FALSE; } - - if (keyresource == NULL && s != NULL) { - zend_string_release_ex(s, 0); - } } /* }}} */ @@ -1683,19 +1797,25 @@ cleanup: /* {{{ Exports a CERT to file or a var */ PHP_FUNCTION(openssl_x509_export) { - X509 * cert; - zval * zcert, *zout; + X509 *cert; + zend_object *cert_obj; + zend_string *cert_str; + zval *zout; zend_bool notext = 1; BIO * bio_out; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz|b", &zcert, &zout, ¬ext) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR_OR_OBJ_OF_CLASS(cert_str, cert_obj, php_openssl_certificate_ce) + Z_PARAM_ZVAL(zout) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(notext) + ZEND_PARSE_PARAMETERS_END(); + RETVAL_FALSE; - cert = php_openssl_x509_from_zval(zcert, 0, NULL); + cert = php_openssl_x509_from_param(cert_obj, cert_str); if (cert == NULL) { - php_error_docref(NULL, E_WARNING, "Cannot get cert from parameter 1"); + php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); return; } @@ -1721,7 +1841,7 @@ PHP_FUNCTION(openssl_x509_export) BIO_free(bio_out); cleanup: - if (Z_TYPE_P(zcert) != IS_RESOURCE) { + if (cert_str) { X509_free(cert); } } @@ -1757,19 +1877,23 @@ zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, zend_b PHP_FUNCTION(openssl_x509_fingerprint) { X509 *cert; - zval *zcert; + zend_object *cert_obj; + zend_string *cert_str; zend_bool raw_output = 0; char *method = "sha1"; size_t method_len; zend_string *fingerprint; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|sb", &zcert, &method, &method_len, &raw_output) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 3) + Z_PARAM_STR_OR_OBJ_OF_CLASS(cert_str, cert_obj, php_openssl_certificate_ce) + Z_PARAM_OPTIONAL + Z_PARAM_STRING(method, method_len) + Z_PARAM_BOOL(raw_output) + ZEND_PARSE_PARAMETERS_END(); - cert = php_openssl_x509_from_zval(zcert, 0, NULL); + cert = php_openssl_x509_from_param(cert_obj, cert_str); if (cert == NULL) { - php_error_docref(NULL, E_WARNING, "Cannot get cert from parameter 1"); + php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); RETURN_FALSE; } @@ -1780,7 +1904,7 @@ PHP_FUNCTION(openssl_x509_fingerprint) RETVAL_FALSE; } - if (Z_TYPE_P(zcert) != IS_RESOURCE) { + if (cert_str) { X509_free(cert); } } @@ -1788,29 +1912,35 @@ PHP_FUNCTION(openssl_x509_fingerprint) /* {{{ Checks if a private key corresponds to a CERT */ PHP_FUNCTION(openssl_x509_check_private_key) { - zval * zcert, *zkey; - X509 * cert = NULL; + X509 *cert; + zend_object *cert_obj; + zend_string *cert_str; + zval *zkey; EVP_PKEY * key = NULL; - zend_resource *keyresource = NULL; + bool free_pkey = 0; - RETVAL_FALSE; + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_STR_OR_OBJ_OF_CLASS(cert_str, cert_obj, php_openssl_certificate_ce) + Z_PARAM_ZVAL(zkey) + ZEND_PARSE_PARAMETERS_END(); - if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &zcert, &zkey) == FAILURE) { - RETURN_THROWS(); - } - cert = php_openssl_x509_from_zval(zcert, 0, NULL); + cert = php_openssl_x509_from_param(cert_obj, cert_str); if (cert == NULL) { RETURN_FALSE; } - key = php_openssl_evp_from_zval(zkey, 0, "", 0, 1, &keyresource); + + RETVAL_FALSE; + + key = php_openssl_pkey_from_zval(zkey, 0, "", 0, &free_pkey); if (key) { RETVAL_BOOL(X509_check_private_key(cert, key)); } - if (keyresource == NULL && key) { + if (free_pkey && key) { EVP_PKEY_free(key); } - if (Z_TYPE_P(zcert) != IS_RESOURCE) { + + if (cert_str) { X509_free(cert); } } @@ -1819,20 +1949,25 @@ PHP_FUNCTION(openssl_x509_check_private_key) /* {{{ Verifies the signature of certificate cert using public key key */ PHP_FUNCTION(openssl_x509_verify) { - zval * zcert, *zkey; - X509 * cert = NULL; + X509 *cert; + zend_object *cert_obj; + zend_string *cert_str; + zval *zkey; EVP_PKEY * key = NULL; - zend_resource *keyresource = NULL; + bool free_pkey = 0; int err = -1; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &zcert, &zkey) == FAILURE) { - RETURN_THROWS(); - } - cert = php_openssl_x509_from_zval(zcert, 0, NULL); + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_STR_OR_OBJ_OF_CLASS(cert_str, cert_obj, php_openssl_certificate_ce) + Z_PARAM_ZVAL(zkey) + ZEND_PARSE_PARAMETERS_END(); + + cert = php_openssl_x509_from_param(cert_obj, cert_str); if (cert == NULL) { RETURN_LONG(err); } - key = php_openssl_evp_from_zval(zkey, 1, NULL, 0, 0, &keyresource); + + key = php_openssl_pkey_from_zval(zkey, 1, NULL, 0, &free_pkey); if (key == NULL) { X509_free(cert); RETURN_LONG(err); @@ -1844,10 +1979,10 @@ PHP_FUNCTION(openssl_x509_verify) php_openssl_store_errors(); } - if (keyresource == NULL && key) { + if (free_pkey && key) { EVP_PKEY_free(key); } - if (Z_TYPE_P(zcert) != IS_RESOURCE) { + if (cert_str) { X509_free(cert); } @@ -1929,8 +2064,9 @@ 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; - X509 * cert = NULL; + X509 *cert; + zend_object *cert_obj; + zend_string *cert_str; int i, sig_nid; zend_bool useshortnames = 1; char * tmpstr; @@ -1947,10 +2083,13 @@ PHP_FUNCTION(openssl_x509_parse) char *hex_serial; char buf[256]; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|b", &zcert, &useshortnames) == FAILURE) { - RETURN_THROWS(); - } - cert = php_openssl_x509_from_zval(zcert, 0, NULL); + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR_OR_OBJ_OF_CLASS(cert_str, cert_obj, php_openssl_certificate_ce) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(useshortnames) + ZEND_PARSE_PARAMETERS_END(); + + cert = php_openssl_x509_from_param(cert_obj, cert_str); if (cert == NULL) { RETURN_FALSE; } @@ -2067,7 +2206,7 @@ PHP_FUNCTION(openssl_x509_parse) } else { zend_array_destroy(Z_ARR_P(return_value)); BIO_free(bio_out); - if (Z_TYPE_P(zcert) != IS_RESOURCE) { + if (cert_str) { X509_free(cert); } RETURN_FALSE; @@ -2082,7 +2221,7 @@ PHP_FUNCTION(openssl_x509_parse) BIO_free(bio_out); } add_assoc_zval(return_value, "extensions", &subitem); - if (Z_TYPE_P(zcert) != IS_RESOURCE) { + if (cert_str) { X509_free(cert); } } @@ -2178,18 +2317,24 @@ 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; - X509_STORE * cainfo = NULL; - X509 * cert = NULL; - STACK_OF(X509) * untrustedchain = NULL; + X509 *cert; + zend_object *cert_obj; + zend_string *cert_str; + zval *zcainfo = NULL; + X509_STORE *cainfo = NULL; + STACK_OF(X509) *untrustedchain = NULL; zend_long purpose; char * untrusted = NULL; size_t untrusted_len = 0; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "zl|a!s", &zcert, &purpose, &zcainfo, &untrusted, &untrusted_len) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_STR_OR_OBJ_OF_CLASS(cert_str, cert_obj, php_openssl_certificate_ce) + Z_PARAM_LONG(purpose) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(zcainfo) + Z_PARAM_STRING_OR_NULL(untrusted, untrusted_len) + ZEND_PARSE_PARAMETERS_END(); RETVAL_LONG(-1); @@ -2204,7 +2349,7 @@ PHP_FUNCTION(openssl_x509_checkpurpose) if (cainfo == NULL) { goto clean_exit; } - cert = php_openssl_x509_from_zval(zcert, 0, NULL); + cert = php_openssl_x509_from_param(cert_obj, cert_str); if (cert == NULL) { goto clean_exit; } @@ -2215,7 +2360,7 @@ PHP_FUNCTION(openssl_x509_checkpurpose) } else { RETVAL_BOOL(ret); } - if (Z_TYPE_P(zcert) != IS_RESOURCE) { + if (cert_str) { X509_free(cert); } clean_exit: @@ -2301,20 +2446,24 @@ static X509_STORE *php_openssl_setup_verify(zval *calist) /* {{{ Reads X.509 certificates */ PHP_FUNCTION(openssl_x509_read) { - zval *cert; - X509 *x509; - zend_resource *res; + X509 *cert; + php_openssl_certificate_object *x509_cert_obj; + zend_object *cert_obj; + zend_string *cert_str; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &cert) == FAILURE) { - RETURN_THROWS(); - } - x509 = php_openssl_x509_from_zval(cert, 1, &res); - ZVAL_RES(return_value, res); + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR_OR_OBJ_OF_CLASS(cert_str, cert_obj, php_openssl_certificate_ce) + ZEND_PARSE_PARAMETERS_END(); - if (x509 == NULL) { - php_error_docref(NULL, E_WARNING, "Supplied parameter cannot be coerced into an X509 certificate!"); + cert = php_openssl_x509_from_param(cert_obj, cert_str); + if (cert == NULL) { + php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); RETURN_FALSE; } + + object_init_ex(return_value, php_openssl_certificate_ce); + x509_cert_obj = Z_OPENSSL_CERTIFICATE_P(return_value); + x509_cert_obj->x509 = cert_obj ? X509_dup(cert) : cert; } /* }}} */ @@ -2322,15 +2471,10 @@ PHP_FUNCTION(openssl_x509_read) PHP_FUNCTION(openssl_x509_free) { zval *x509; - X509 *cert; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &x509) == FAILURE) { - RETURN_THROWS(); - } - if ((cert = (X509 *)zend_fetch_resource(Z_RES_P(x509), "OpenSSL X.509", le_x509)) == NULL) { - RETURN_THROWS(); - } - zend_list_close(Z_RES_P(x509)); + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJECT_OF_CLASS(x509, php_openssl_certificate_ce) + ZEND_PARSE_PARAMETERS_END(); } /* }}} */ @@ -2353,19 +2497,19 @@ static STACK_OF(X509) * php_array_to_X509_sk(zval * zcerts) /* {{{ */ zval * zcertval; STACK_OF(X509) * sk = NULL; X509 * cert; - zend_resource *certresource; + bool free_cert; sk = sk_X509_new_null(); /* get certs */ 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); + cert = php_openssl_x509_from_zval(zcertval, &free_cert); if (cert == NULL) { goto clean_exit; } - if (certresource != NULL) { + if (!free_cert) { cert = X509_dup(cert); if (cert == NULL) { @@ -2378,13 +2522,13 @@ static STACK_OF(X509) * php_array_to_X509_sk(zval * zcerts) /* {{{ */ } ZEND_HASH_FOREACH_END(); } else { /* a single certificate */ - cert = php_openssl_x509_from_zval(zcerts, 0, &certresource); + cert = php_openssl_x509_from_zval(zcerts, &free_cert); if (cert == NULL) { goto clean_exit; } - if (certresource != NULL) { + if (!free_cert) { cert = X509_dup(cert); if (cert == NULL) { php_openssl_store_errors(); @@ -2402,7 +2546,9 @@ clean_exit: /* {{{ Creates and exports a PKCS to file */ PHP_FUNCTION(openssl_pkcs12_export_to_file) { - X509 * cert = NULL; + X509 *cert; + zend_object *cert_obj; + zend_string *cert_str; BIO * bio_out = NULL; PKCS12 * p12 = NULL; char * filename; @@ -2410,23 +2556,30 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file) size_t filename_len; char * pass; size_t pass_len; - zval *zcert = NULL, *zpkey = NULL, *args = NULL; + zval *zpkey = NULL, *args = NULL; EVP_PKEY *priv_key = NULL; - zend_resource *keyresource; + bool free_pkey; zval * item; STACK_OF(X509) *ca = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "zpzs|a", &zcert, &filename, &filename_len, &zpkey, &pass, &pass_len, &args) == FAILURE) - RETURN_THROWS(); + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_STR_OR_OBJ_OF_CLASS(cert_str, cert_obj, php_openssl_certificate_ce) + Z_PARAM_PATH(filename, filename_len) + Z_PARAM_ZVAL(zpkey) + Z_PARAM_STRING(pass, pass_len) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY(args) + ZEND_PARSE_PARAMETERS_END(); RETVAL_FALSE; - cert = php_openssl_x509_from_zval(zcert, 0, NULL); + cert = php_openssl_x509_from_param(cert_obj, cert_str); if (cert == NULL) { - php_error_docref(NULL, E_WARNING, "Cannot get cert from parameter 1"); + php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); return; } - priv_key = php_openssl_evp_from_zval(zpkey, 0, "", 0, 1, &keyresource); + + priv_key = php_openssl_pkey_from_zval(zpkey, 0, "", 0, &free_pkey); if (priv_key == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Cannot get private key from parameter 3"); @@ -2485,11 +2638,11 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file) cleanup: - if (keyresource == NULL && priv_key) { + if (free_pkey && priv_key) { EVP_PKEY_free(priv_key); } - if (Z_TYPE_P(zcert) != IS_RESOURCE) { + if (cert_str) { X509_free(cert); } } @@ -2498,30 +2651,38 @@ cleanup: /* {{{ Creates and exports a PKCS12 to a var */ PHP_FUNCTION(openssl_pkcs12_export) { - X509 * cert = NULL; + X509 *cert; + zend_object *cert_obj; + zend_string *cert_str; BIO * bio_out; PKCS12 * p12 = NULL; - zval * zcert = NULL, *zout = NULL, *zpkey, *args = NULL; + zval *zout = NULL, *zpkey, *args = NULL; EVP_PKEY *priv_key = NULL; - zend_resource *keyresource; + bool free_pkey; char * pass; size_t pass_len; char * friendly_name = NULL; zval * item; STACK_OF(X509) *ca = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "zzzs|a", &zcert, &zout, &zpkey, &pass, &pass_len, &args) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_STR_OR_OBJ_OF_CLASS(cert_str, cert_obj, php_openssl_certificate_ce) + Z_PARAM_ZVAL(zout) + Z_PARAM_ZVAL(zpkey) + Z_PARAM_STRING(pass, pass_len) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY(args) + ZEND_PARSE_PARAMETERS_END(); RETVAL_FALSE; - cert = php_openssl_x509_from_zval(zcert, 0, NULL); + cert = php_openssl_x509_from_param(cert_obj, cert_str); if (cert == NULL) { - php_error_docref(NULL, E_WARNING, "Cannot get cert from parameter 1"); + php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); return; } - priv_key = php_openssl_evp_from_zval(zpkey, 0, "", 0, 1, &keyresource); + + priv_key = php_openssl_pkey_from_zval(zpkey, 0, "", 0, &free_pkey); if (priv_key == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Cannot get private key from parameter 3"); @@ -2570,10 +2731,10 @@ PHP_FUNCTION(openssl_pkcs12_export) cleanup: - if (keyresource == NULL && priv_key) { + if (free_pkey && priv_key) { EVP_PKEY_free(priv_key); } - if (Z_TYPE_P(zcert) != IS_RESOURCE) { + if (cert_str) { X509_free(cert); } } @@ -2859,45 +3020,24 @@ 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, zend_resource **resourceval) + +static X509_REQ *php_openssl_csr_from_str(zend_string *csr_str) { X509_REQ * csr = NULL; char * filename = NULL; BIO * in; - if (resourceval) { - *resourceval = NULL; - } - if (Z_TYPE_P(val) == IS_RESOURCE) { - void * what; - zend_resource *res = Z_RES_P(val); - - what = zend_fetch_resource(res, "OpenSSL X.509 CSR", le_csr); - if (what) { - if (resourceval) { - *resourceval = res; - if (makeresource) { - Z_ADDREF_P(val); - } - } - return (X509_REQ*)what; - } - return NULL; - } else if (Z_TYPE_P(val) != IS_STRING) { - return NULL; + if (ZSTR_LEN(csr_str) > 7 && memcmp(ZSTR_VAL(csr_str), "file://", sizeof("file://") - 1) == 0) { + filename = ZSTR_VAL(csr_str) + (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)) { return NULL; } in = BIO_new_file(filename, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)); } else { - in = BIO_new_mem_buf(Z_STRVAL_P(val), (int)Z_STRLEN_P(val)); + in = BIO_new_mem_buf(ZSTR_VAL(csr_str), (int) ZSTR_LEN(csr_str)); } if (in == NULL) { @@ -2914,29 +3054,41 @@ static X509_REQ * php_openssl_csr_from_zval(zval * val, int makeresource, zend_r return csr; } -/* }}} */ + +static X509_REQ *php_openssl_csr_from_param(zend_object *csr_obj, zend_string *csr_str) +{ + if (csr_obj) { + return php_openssl_request_from_obj(csr_obj)->csr; + } + + ZEND_ASSERT(csr_str); + + return php_openssl_csr_from_str(csr_str); +} /* {{{ Exports a CSR to file */ PHP_FUNCTION(openssl_csr_export_to_file) { - X509_REQ * csr; - zval * zcsr = NULL; + X509_REQ *csr; + zend_object *csr_obj; + zend_string *csr_str; zend_bool notext = 1; char * filename = NULL; size_t filename_len; BIO * bio_out; - zend_resource *csr_resource; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rp|b", &zcsr, &filename, &filename_len, ¬ext) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR_OR_OBJ_OF_CLASS(csr_str, csr_obj, php_openssl_request_ce) + Z_PARAM_PATH(filename, filename_len) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(notext) + ZEND_PARSE_PARAMETERS_END(); + RETVAL_FALSE; - csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource); + csr = php_openssl_csr_from_param(csr_obj, csr_str); if (csr == NULL) { - if (!EG(exception)) { - php_error_docref(NULL, E_WARNING, "Cannot get CSR from parameter 1"); - } + php_error_docref(NULL, E_WARNING, "X.509 Certificate Signing Request cannot be retrieved"); return; } @@ -2961,7 +3113,7 @@ PHP_FUNCTION(openssl_csr_export_to_file) php_error_docref(NULL, E_WARNING, "Error opening file %s", filename); } - if (csr_resource == NULL && csr != NULL) { + if (csr_str) { X509_REQ_free(csr); } } @@ -2970,23 +3122,25 @@ PHP_FUNCTION(openssl_csr_export_to_file) /* {{{ Exports a CSR to file or a var */ PHP_FUNCTION(openssl_csr_export) { - X509_REQ * csr; - zval * zcsr = NULL, *zout=NULL; + X509_REQ *csr; + zend_object *csr_obj; + zend_string *csr_str; + zval *zout; zend_bool notext = 1; BIO * bio_out; - zend_resource *csr_resource; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz|b", &zcsr, &zout, ¬ext) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR_OR_OBJ_OF_CLASS(csr_str, csr_obj, php_openssl_request_ce) + Z_PARAM_ZVAL(zout) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(notext) + ZEND_PARSE_PARAMETERS_END(); RETVAL_FALSE; - csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource); + csr = php_openssl_csr_from_param(csr_obj, csr_str); if (csr == NULL) { - if (!EG(exception)) { - php_error_docref(NULL, E_WARNING, "Cannot get CSR from parameter 1"); - } + php_error_docref(NULL, E_WARNING, "X.509 Certificate Signing Request cannot be retrieved"); return; } @@ -3008,7 +3162,7 @@ PHP_FUNCTION(openssl_csr_export) php_openssl_store_errors(); } - if (csr_resource == NULL && csr) { + if (csr_str) { X509_REQ_free(csr); } BIO_free(bio_out); @@ -3018,38 +3172,51 @@ PHP_FUNCTION(openssl_csr_export) /* {{{ Signs a cert with another CERT */ PHP_FUNCTION(openssl_csr_sign) { - zval * zcert = NULL, *zcsr, *zpkey, *args = NULL; + X509_REQ *csr; + zend_object *csr_obj; + zend_string *csr_str; + + php_openssl_certificate_object *cert_object; + zend_object *cert_obj; + zend_string *cert_str; + zval *zpkey, *args = NULL; zend_long num_days; zend_long serial = Z_L(0); - X509 * cert = NULL, *new_cert = NULL; - X509_REQ * csr; + X509 *cert = NULL, *new_cert = NULL; EVP_PKEY * key = NULL, *priv_key = NULL; - zend_resource *csr_resource, *certresource = NULL, *keyresource = NULL; + bool free_pkey = 0; int i; struct php_x509_request req; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz!zl|a!l", &zcsr, &zcert, &zpkey, &num_days, &args, &serial) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(4, 6) + Z_PARAM_STR_OR_OBJ_OF_CLASS(csr_str, csr_obj, php_openssl_request_ce) + Z_PARAM_STR_OR_OBJ_OF_CLASS_OR_NULL(cert_str, cert_obj, php_openssl_certificate_ce) + Z_PARAM_ZVAL(zpkey) + Z_PARAM_LONG(num_days) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(args) + Z_PARAM_LONG(serial) + ZEND_PARSE_PARAMETERS_END(); RETVAL_FALSE; - PHP_SSL_REQ_INIT(&req); - csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource); + csr = php_openssl_csr_from_param(csr_obj, csr_str); if (csr == NULL) { - if (!EG(exception)) { - php_error_docref(NULL, E_WARNING, "Cannot get CSR from parameter 1"); - } + php_error_docref(NULL, E_WARNING, "X.509 Certificate Signing Request cannot be retrieved"); return; } - if (zcert) { - cert = php_openssl_x509_from_zval(zcert, 0, &certresource); + + PHP_SSL_REQ_INIT(&req); + + if (cert_str || cert_obj) { + cert = php_openssl_x509_from_param(cert_obj, cert_str); if (cert == NULL) { - php_error_docref(NULL, E_WARNING, "Cannot get cert from parameter 2"); + php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); goto cleanup; } } - priv_key = php_openssl_evp_from_zval(zpkey, 0, "", 0, 1, &keyresource); + + priv_key = php_openssl_pkey_from_zval(zpkey, 0, "", 0, &free_pkey); if (priv_key == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Cannot get private key from parameter 3"); @@ -3134,32 +3301,30 @@ PHP_FUNCTION(openssl_csr_sign) goto cleanup; } - /* Succeeded; lets return the cert */ - ZVAL_RES(return_value, zend_register_resource(new_cert, le_x509)); - new_cert = NULL; + object_init_ex(return_value, php_openssl_certificate_ce); + cert_object = Z_OPENSSL_CERTIFICATE_P(return_value); + cert_object->x509 = new_cert; cleanup: if (cert == new_cert) { cert = NULL; } + PHP_SSL_REQ_DISPOSE(&req); - if (keyresource == NULL && priv_key) { + if (free_pkey && priv_key) { EVP_PKEY_free(priv_key); } if (key) { EVP_PKEY_free(key); } - if (csr_resource == NULL && csr) { + if (csr_str) { X509_REQ_free(csr); } - if (zcert && certresource == NULL && cert) { + if (cert_str && cert) { X509_free(cert); } - if (new_cert) { - X509_free(new_cert); - } } /* }}} */ @@ -3167,11 +3332,12 @@ cleanup: PHP_FUNCTION(openssl_csr_new) { struct php_x509_request req; - zval * args = NULL, * dn, *attribs = NULL; - zval * out_pkey; - X509_REQ * csr = NULL; + php_openssl_request_object *x509_request_obj; + zval *args = NULL, *dn, *attribs = NULL; + zval *out_pkey; + X509_REQ *csr = NULL; int we_made_the_key = 1; - zend_resource *key_resource; + bool free_pkey; if (zend_parse_parameters(ZEND_NUM_ARGS(), "az|a!a!", &dn, &out_pkey, &args, &attribs) == FAILURE) { RETURN_THROWS(); @@ -3186,7 +3352,7 @@ PHP_FUNCTION(openssl_csr_new) /* Generate or use a private key */ if (Z_TYPE_P(out_pkey_val) != IS_NULL) { - req.priv_key = php_openssl_evp_from_zval(out_pkey_val, 0, NULL, 0, 0, &key_resource); + req.priv_key = php_openssl_pkey_from_zval(out_pkey_val, 0, NULL, 0, &free_pkey); if (req.priv_key != NULL) { we_made_the_key = 0; } @@ -3215,7 +3381,9 @@ PHP_FUNCTION(openssl_csr_new) RETVAL_TRUE; if (X509_REQ_sign(csr, req.priv_key, req.digest)) { - ZVAL_RES(return_value, zend_register_resource(csr, le_csr)); + object_init_ex(return_value, php_openssl_request_ce); + x509_request_obj = Z_OPENSSL_REQUEST_P(return_value); + x509_request_obj->csr = csr; csr = NULL; } else { php_openssl_store_errors(); @@ -3223,10 +3391,16 @@ PHP_FUNCTION(openssl_csr_new) } if (we_made_the_key) { - /* and a resource for the private key */ - ZEND_TRY_ASSIGN_REF_RES(out_pkey, zend_register_resource(req.priv_key, le_key)); + /* and an object for the private key */ + zval zkey_object; + php_openssl_pkey_object *key_object; + object_init_ex(&zkey_object, php_openssl_pkey_ce); + key_object = Z_OPENSSL_PKEY_P(&zkey_object); + key_object->pkey = req.priv_key; + + ZEND_TRY_ASSIGN_REF_TMP(out_pkey, &zkey_object); req.priv_key = NULL; /* make sure the cleanup code doesn't zap it! */ - } else if (key_resource != NULL) { + } else if (!free_pkey) { req.priv_key = NULL; /* make sure the cleanup code doesn't zap it! */ } } @@ -3253,18 +3427,19 @@ PHP_FUNCTION(openssl_csr_new) /* {{{ Returns the subject of a CERT or FALSE on error */ PHP_FUNCTION(openssl_csr_get_subject) { - zval * zcsr; + X509_REQ *csr; + zend_object *csr_obj; + zend_string *csr_str; zend_bool use_shortnames = 1; - zend_resource *csr_resource; - X509_NAME * subject; - X509_REQ * csr; + X509_NAME *subject; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|b", &zcsr, &use_shortnames) == FAILURE) { - RETURN_THROWS(); - } - - csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource); + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR_OR_OBJ_OF_CLASS(csr_str, csr_obj, php_openssl_request_ce) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(use_shortnames) + ZEND_PARSE_PARAMETERS_END(); + csr = php_openssl_csr_from_param(csr_obj, csr_str); if (csr == NULL) { RETURN_FALSE; } @@ -3274,7 +3449,7 @@ PHP_FUNCTION(openssl_csr_get_subject) array_init(return_value); php_openssl_add_assoc_name_entry(return_value, NULL, subject, use_shortnames); - if (!csr_resource) { + if (csr_str) { X509_REQ_free(csr); } } @@ -3283,19 +3458,21 @@ 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; + X509_REQ *orig_csr, *csr; + zend_object *csr_obj; + zend_string *csr_str; zend_bool use_shortnames = 1; - zend_resource *csr_resource; - X509_REQ *orig_csr, *csr; + php_openssl_pkey_object *key_object; EVP_PKEY *tpubkey; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|b", &zcsr, &use_shortnames) == FAILURE) { - RETURN_THROWS(); - } - - orig_csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource); + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR_OR_OBJ_OF_CLASS(csr_str, csr_obj, php_openssl_request_ce) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(use_shortnames) + ZEND_PARSE_PARAMETERS_END(); + orig_csr = php_openssl_csr_from_param(csr_obj, csr_str); if (orig_csr == NULL) { RETURN_FALSE; } @@ -3319,7 +3496,7 @@ PHP_FUNCTION(openssl_csr_get_public_key) X509_REQ_free(csr); } - if (!csr_resource) { + if (csr_str) { /* We also need to free the original CSR if it was freshly created */ X509_REQ_free(orig_csr); } @@ -3329,7 +3506,9 @@ PHP_FUNCTION(openssl_csr_get_public_key) RETURN_FALSE; } - RETURN_RES(zend_register_resource(tpubkey, le_key)); + object_init_ex(return_value, php_openssl_pkey_ce); + key_object = Z_OPENSSL_PKEY_P(return_value); + key_object->pkey = tpubkey; } /* }}} */ @@ -3358,27 +3537,11 @@ static int php_openssl_pem_password_cb(char *buf, int size, int rwflag, void *us } /* }}} */ -/* {{{ php_openssl_evp_from_zval - Given a zval, coerce it into a EVP_PKEY object. - It can be: - 1. private key resource from openssl_get_privatekey() - 2. X509 resource -> public key will be extracted from it - 3. if it starts with file:// interpreted as path to key file - 4. interpreted as the data from the cert/key file and interpreted in same way as openssl_get_privatekey() - 5. an array(0 => [items 2..4], 1 => passphrase) - 6. if val is a string (possibly starting with file:///) and it is not an X509 certificate, then interpret as public key - NOTE: If you are requesting a private key but have not specified a passphrase, you should use an - 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, size_t passphrase_len, - int makeresource, zend_resource **resourceval) +static EVP_PKEY *php_openssl_pkey_from_zval(zval *val, int public_key, char *passphrase, size_t passphrase_len, bool *free_pkey) { - EVP_PKEY * key = NULL; - X509 * cert = NULL; - int free_cert = 0; - zend_resource *cert_res = NULL; + EVP_PKEY *key = NULL; + X509 *cert = NULL; + bool free_cert = 0; char * filename = NULL; zval tmp; @@ -3390,9 +3553,10 @@ static EVP_PKEY * php_openssl_evp_from_zval( } \ return NULL; - if (resourceval) { - *resourceval = NULL; + if (free_pkey) { + *free_pkey = 1; } + if (Z_TYPE_P(val) == IS_ARRAY) { zval * zphrase; @@ -3423,47 +3587,33 @@ static EVP_PKEY * php_openssl_evp_from_zval( } } - if (Z_TYPE_P(val) == IS_RESOURCE) { - void * what; - zend_resource * res = Z_RES_P(val); + if (Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val) == php_openssl_pkey_ce) { + int is_priv; + + key = php_openssl_pkey_from_obj(Z_OBJ_P(val))->pkey; + is_priv = php_openssl_is_private_key(key); - what = zend_fetch_resource2(res, "OpenSSL X.509/key", le_x509, le_key); - if (!what) { + /* check whether it is actually a private key if requested */ + if (!public_key && !is_priv) { + php_error_docref(NULL, E_WARNING, "Supplied key param is a public key"); TMP_CLEAN; } - if (res->type == le_x509) { - /* extract key from cert, depending on public_key param */ - cert = (X509*)what; - free_cert = 0; - } else if (res->type == le_key) { - int is_priv; - 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, E_WARNING, "Supplied key param is a public key"); - TMP_CLEAN; + if (public_key && is_priv) { + 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) { + zval_ptr_dtor_str(&tmp); } - - if (public_key && is_priv) { - 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) { - zval_ptr_dtor_str(&tmp); - } - /* got the key - return it */ - if (resourceval) { - *resourceval = res; - Z_ADDREF_P(val); - } - return (EVP_PKEY*)what; + /* got the key - return it */ + if (free_pkey) { + *free_pkey = 0; } - } else { - /* other types could be used here - eg: file pointers and read in the data from them */ - TMP_CLEAN; + return key; } + } else if (Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val) == php_openssl_certificate_ce) { + cert = php_openssl_certificate_from_obj(Z_OBJ_P(val))->x509; } 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 @@ -3484,10 +3634,11 @@ static EVP_PKEY * php_openssl_evp_from_zval( } /* 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); - free_cert = (cert_res == NULL); - /* actual extraction done later */ - if (!cert) { + cert = php_openssl_x509_from_str(Z_STR_P(val)); + + if (cert) { + free_cert = 1; + } else { /* not a X509 certificate, try to retrieve public key */ BIO* in; if (filename) { @@ -3539,18 +3690,16 @@ static EVP_PKEY * php_openssl_evp_from_zval( } } - if (free_cert && cert) { + if (free_cert) { X509_free(cert); } - if (key && makeresource && resourceval) { - *resourceval = zend_register_resource(key, le_key); - } + if (Z_TYPE(tmp) == IS_STRING) { zval_ptr_dtor_str(&tmp); } + return key; } -/* }}} */ /* {{{ php_openssl_generate_private_key */ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req) @@ -3946,6 +4095,7 @@ PHP_FUNCTION(openssl_pkey_new) struct php_x509_request req; zval * args = NULL; zval *data; + php_openssl_pkey_object *key_object; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a!", &args) == FAILURE) { RETURN_THROWS(); @@ -3962,7 +4112,10 @@ PHP_FUNCTION(openssl_pkey_new) RSA *rsa = RSA_new(); if (rsa) { if (php_openssl_pkey_init_and_assign_rsa(pkey, rsa, data)) { - RETURN_RES(zend_register_resource(pkey, le_key)); + object_init_ex(return_value, php_openssl_pkey_ce); + key_object = Z_OPENSSL_PKEY_P(return_value); + key_object->pkey = pkey; + return; } RSA_free(rsa); } else { @@ -3981,7 +4134,10 @@ PHP_FUNCTION(openssl_pkey_new) if (dsa) { if (php_openssl_pkey_init_dsa(dsa, data)) { if (EVP_PKEY_assign_DSA(pkey, dsa)) { - RETURN_RES(zend_register_resource(pkey, le_key)); + object_init_ex(return_value, php_openssl_pkey_ce); + key_object = Z_OPENSSL_PKEY_P(return_value); + key_object->pkey = pkey; + return; } else { php_openssl_store_errors(); } @@ -4003,7 +4159,11 @@ PHP_FUNCTION(openssl_pkey_new) if (dh) { if (php_openssl_pkey_init_dh(dh, data)) { if (EVP_PKEY_assign_DH(pkey, dh)) { - ZVAL_COPY_VALUE(return_value, zend_list_insert(pkey, le_key)); + php_openssl_pkey_object *key_object; + + object_init_ex(return_value, php_openssl_pkey_ce); + key_object = Z_OPENSSL_PKEY_P(return_value); + key_object->pkey = pkey; return; } else { php_openssl_store_errors(); @@ -4107,7 +4267,11 @@ PHP_FUNCTION(openssl_pkey_new) } if (EC_KEY_check_key(eckey) && EVP_PKEY_assign_EC_KEY(pkey, eckey)) { EC_GROUP_free(group); - RETURN_RES(zend_register_resource(pkey, le_key)); + + object_init_ex(return_value, php_openssl_pkey_ce); + key_object = Z_OPENSSL_PKEY_P(return_value); + key_object->pkey = pkey; + return; } else { php_openssl_store_errors(); } @@ -4143,7 +4307,9 @@ clean_exit: if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) { if (php_openssl_generate_private_key(&req)) { /* pass back a key resource */ - RETVAL_RES(zend_register_resource(req.priv_key, le_key)); + object_init_ex(return_value, php_openssl_pkey_ce); + key_object = Z_OPENSSL_PKEY_P(return_value); + key_object->pkey = req.priv_key; /* make sure the cleanup code doesn't zap it! */ req.priv_key = NULL; } @@ -4161,7 +4327,7 @@ PHP_FUNCTION(openssl_pkey_export_to_file) size_t passphrase_len = 0; char * filename = NULL; size_t filename_len = 0; - zend_resource *key_resource = NULL; + bool free_pkey = 0; int pem_write = 0; EVP_PKEY * key; BIO * bio_out = NULL; @@ -4173,8 +4339,8 @@ PHP_FUNCTION(openssl_pkey_export_to_file) RETVAL_FALSE; PHP_OPENSSL_CHECK_SIZE_T_TO_INT(passphrase_len, passphrase); - key = php_openssl_evp_from_zval(zpkey, 0, passphrase, passphrase_len, 0, &key_resource); + key = php_openssl_pkey_from_zval(zpkey, 0, passphrase, passphrase_len, &free_pkey); if (key == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Cannot get key from parameter 1"); @@ -4232,7 +4398,7 @@ PHP_FUNCTION(openssl_pkey_export_to_file) clean_exit: PHP_SSL_REQ_DISPOSE(&req); - if (key_resource == NULL && key) { + if (free_pkey && key) { EVP_PKEY_free(key); } if (bio_out) { @@ -4248,7 +4414,7 @@ PHP_FUNCTION(openssl_pkey_export) zval * zpkey, * args = NULL, *out; char * passphrase = NULL; size_t passphrase_len = 0; int pem_write = 0; - zend_resource *key_resource = NULL; + bool free_pkey = 0; EVP_PKEY * key; BIO * bio_out = NULL; const EVP_CIPHER * cipher; @@ -4259,8 +4425,8 @@ PHP_FUNCTION(openssl_pkey_export) RETVAL_FALSE; PHP_OPENSSL_CHECK_SIZE_T_TO_INT(passphrase_len, passphrase); - key = php_openssl_evp_from_zval(zpkey, 0, passphrase, passphrase_len, 0, &key_resource); + key = php_openssl_pkey_from_zval(zpkey, 0, passphrase, passphrase_len, &free_pkey); if (key == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Cannot get key from parameter 1"); @@ -4314,7 +4480,7 @@ PHP_FUNCTION(openssl_pkey_export) } PHP_SSL_REQ_DISPOSE(&req); - if (key_resource == NULL && key) { + if (free_pkey && key) { EVP_PKEY_free(key); } if (bio_out) { @@ -4328,16 +4494,23 @@ PHP_FUNCTION(openssl_pkey_get_public) { zval *cert; EVP_PKEY *pkey; - zend_resource *res; + php_openssl_pkey_object *key_object; + bool free_pkey; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &cert) == FAILURE) { RETURN_THROWS(); } - pkey = php_openssl_evp_from_zval(cert, 1, NULL, 0, 1, &res); + pkey = php_openssl_pkey_from_zval(cert, 1, NULL, 0, &free_pkey); if (pkey == NULL) { RETURN_FALSE; } - ZVAL_RES(return_value, res); + + object_init_ex(return_value, php_openssl_pkey_ce); + key_object = Z_OPENSSL_PKEY_P(return_value); + key_object->pkey = pkey; + if (!free_pkey) { + EVP_PKEY_up_ref(pkey); + } } /* }}} */ @@ -4345,15 +4518,10 @@ PHP_FUNCTION(openssl_pkey_get_public) PHP_FUNCTION(openssl_pkey_free) { zval *key; - EVP_PKEY *pkey; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &key) == FAILURE) { - RETURN_THROWS(); - } - if ((pkey = (EVP_PKEY *)zend_fetch_resource(Z_RES_P(key), "OpenSSL key", le_key)) == NULL) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &key, php_openssl_pkey_ce) == FAILURE) { RETURN_THROWS(); } - zend_list_close(Z_RES_P(key)); } /* }}} */ @@ -4364,19 +4532,22 @@ PHP_FUNCTION(openssl_pkey_get_private) EVP_PKEY *pkey; char * passphrase = ""; size_t passphrase_len = sizeof("")-1; - zend_resource *res; + php_openssl_pkey_object *key_object; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|s", &cert, &passphrase, &passphrase_len) == FAILURE) { RETURN_THROWS(); } PHP_OPENSSL_CHECK_SIZE_T_TO_INT(passphrase_len, passphrase); - pkey = php_openssl_evp_from_zval(cert, 0, passphrase, passphrase_len, 1, &res); + pkey = php_openssl_pkey_from_zval(cert, 0, passphrase, passphrase_len, NULL); if (pkey == NULL) { RETURN_FALSE; } - ZVAL_RES(return_value, res); + + object_init_ex(return_value, php_openssl_pkey_ce); + key_object = Z_OPENSSL_PKEY_P(return_value); + key_object->pkey = pkey; } /* }}} */ @@ -4391,12 +4562,12 @@ PHP_FUNCTION(openssl_pkey_get_details) char *pbio; zend_long ktype; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &key) == FAILURE) { - RETURN_THROWS(); - } - if ((pkey = (EVP_PKEY *)zend_fetch_resource(Z_RES_P(key), "OpenSSL key", le_key)) == NULL) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &key, php_openssl_pkey_ce) == FAILURE) { RETURN_THROWS(); } + + pkey = Z_OPENSSL_PKEY_P(key)->pkey; + out = BIO_new(BIO_s_mem()); if (!PEM_write_bio_PUBKEY(out, pkey)) { BIO_free(out); @@ -4566,12 +4737,12 @@ PHP_FUNCTION(openssl_dh_compute_key) zend_string *data; int len; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "sr", &pub_str, &pub_len, &key) == FAILURE) { - RETURN_THROWS(); - } - if ((pkey = (EVP_PKEY *)zend_fetch_resource(Z_RES_P(key), "OpenSSL key", le_key)) == NULL) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sO", &pub_str, &pub_len, &key, php_openssl_pkey_ce) == FAILURE) { RETURN_THROWS(); } + + pkey = Z_OPENSSL_PKEY_P(key)->pkey; + if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) { RETURN_FALSE; } @@ -4618,8 +4789,8 @@ PHP_FUNCTION(openssl_pkey_derive) php_error_docref(NULL, E_WARNING, "keylen < 0, assuming NULL"); } key_size = key_len; - if ((pkey = php_openssl_evp_from_zval(priv_key, 0, "", 0, 0, NULL)) == NULL - || (peer_key = php_openssl_evp_from_zval(peer_pub_key, 1, NULL, 0, 0, NULL)) == NULL) { + if ((pkey = php_openssl_pkey_from_zval(priv_key, 0, "", 0, NULL)) == NULL + || (peer_key = php_openssl_pkey_from_zval(peer_pub_key, 1, NULL, 0, NULL)) == NULL) { RETURN_FALSE; } EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL); @@ -4873,7 +5044,6 @@ PHP_FUNCTION(openssl_pkcs7_encrypt) RETURN_THROWS(); } - if (php_openssl_open_base_dir_chk(infilename) || php_openssl_open_base_dir_chk(outfilename)) { return; } @@ -4895,14 +5065,14 @@ PHP_FUNCTION(openssl_pkcs7_encrypt) /* get certs */ if (Z_TYPE_P(zrecipcerts) == IS_ARRAY) { ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(zrecipcerts), zcertval) { - zend_resource *certresource; + bool free_cert; - cert = php_openssl_x509_from_zval(zcertval, 0, &certresource); + cert = php_openssl_x509_from_zval(zcertval, &free_cert); if (cert == NULL) { goto clean_exit; } - if (certresource != NULL) { + if (!free_cert) { /* 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); @@ -4915,14 +5085,14 @@ PHP_FUNCTION(openssl_pkcs7_encrypt) } ZEND_HASH_FOREACH_END(); } else { /* a single certificate */ - zend_resource *certresource; + bool free_cert; - cert = php_openssl_x509_from_zval(zrecipcerts, 0, &certresource); + cert = php_openssl_x509_from_zval(zrecipcerts, &free_cert); if (cert == NULL) { goto clean_exit; } - if (certresource != NULL) { + if (!free_cert) { /* 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); @@ -5091,15 +5261,17 @@ clean_exit: PHP_FUNCTION(openssl_pkcs7_sign) { - zval * zcert, * zprivkey, * zheaders; + X509 *cert = NULL; + zend_object *cert_obj; + zend_string *cert_str; + zval *zprivkey, * zheaders; zval * hval; - X509 * cert = NULL; EVP_PKEY * privkey = NULL; zend_long flags = PKCS7_DETACHED; PKCS7 * p7 = NULL; BIO * infile = NULL, * outfile = NULL; STACK_OF(X509) *others = NULL; - zend_resource *certresource = NULL, *keyresource = NULL; + bool free_pkey = 0; zend_string * strindex; char * infilename; size_t infilename_len; @@ -5108,12 +5280,16 @@ PHP_FUNCTION(openssl_pkcs7_sign) 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_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(5, 7) + Z_PARAM_PATH(infilename, infilename_len) + Z_PARAM_PATH(outfilename, outfilename_len) + Z_PARAM_STR_OR_OBJ_OF_CLASS(cert_str, cert_obj, php_openssl_certificate_ce) + Z_PARAM_ZVAL(zprivkey) + Z_PARAM_ARRAY_OR_NULL(zheaders) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(flags) + Z_PARAM_PATH_OR_NULL(extracertsfilename, extracertsfilename_len) + ZEND_PARSE_PARAMETERS_END(); RETVAL_FALSE; @@ -5124,7 +5300,7 @@ PHP_FUNCTION(openssl_pkcs7_sign) } } - privkey = php_openssl_evp_from_zval(zprivkey, 0, "", 0, 0, &keyresource); + privkey = php_openssl_pkey_from_zval(zprivkey, 0, "", 0, &free_pkey); if (privkey == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Error getting private key"); @@ -5132,9 +5308,9 @@ PHP_FUNCTION(openssl_pkcs7_sign) goto clean_exit; } - cert = php_openssl_x509_from_zval(zcert, 0, &certresource); + cert = php_openssl_x509_from_param(cert_obj, cert_str); if (cert == NULL) { - php_error_docref(NULL, E_WARNING, "Error getting cert"); + php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); goto clean_exit; } @@ -5200,10 +5376,10 @@ clean_exit: if (others) { sk_X509_pop_free(others, X509_free); } - if (privkey && keyresource == NULL) { + if (privkey && free_pkey) { EVP_PKEY_free(privkey); } - if (cert && certresource == NULL) { + if (cert && cert_str) { X509_free(cert); } } @@ -5213,31 +5389,35 @@ clean_exit: PHP_FUNCTION(openssl_pkcs7_decrypt) { - zval * recipcert, * recipkey = NULL; - X509 * cert = NULL; + X509 *cert; + zval *recipcert, *recipkey = NULL; + bool free_recipcert; EVP_PKEY * key = NULL; - zend_resource *certresval, *keyresval; - BIO * in = NULL, * out = NULL, * datain = NULL; + bool free_pkey; + BIO * in = NULL, *out = NULL, *datain = NULL; PKCS7 * p7 = NULL; char * infilename; size_t infilename_len; char * outfilename; size_t outfilename_len; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ppz|z", &infilename, &infilename_len, - &outfilename, &outfilename_len, &recipcert, &recipkey) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(3, 4) + Z_PARAM_PATH(infilename, infilename_len) + Z_PARAM_PATH(outfilename, outfilename_len) + Z_PARAM_ZVAL(recipcert) + Z_PARAM_OPTIONAL + Z_PARAM_ZVAL_OR_NULL(recipkey) + ZEND_PARSE_PARAMETERS_END(); RETVAL_FALSE; - cert = php_openssl_x509_from_zval(recipcert, 0, &certresval); + cert = php_openssl_x509_from_zval(recipcert, &free_recipcert); if (cert == NULL) { - php_error_docref(NULL, E_WARNING, "Unable to coerce parameter 3 to x509 cert"); + php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); goto clean_exit; } - key = php_openssl_evp_from_zval(recipkey ? recipkey : recipcert, 0, "", 0, 0, &keyresval); + key = php_openssl_pkey_from_zval(recipkey ? recipkey : recipcert, 0, "", 0, &free_pkey); if (key == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Unable to get private key"); @@ -5276,10 +5456,10 @@ clean_exit: BIO_free(datain); BIO_free(in); BIO_free(out); - if (cert && certresval == NULL) { + if (cert && free_recipcert) { X509_free(cert); } - if (key && keyresval == NULL) { + if (key && free_pkey) { EVP_PKEY_free(key); } } @@ -5521,14 +5701,14 @@ PHP_FUNCTION(openssl_cms_encrypt) /* get certs */ if (Z_TYPE_P(zrecipcerts) == IS_ARRAY) { ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(zrecipcerts), zcertval) { - zend_resource *certresource; + bool free_cert; - cert = php_openssl_x509_from_zval(zcertval, 0, &certresource); + cert = php_openssl_x509_from_zval(zcertval, &free_cert); if (cert == NULL) { goto clean_exit; } - if (certresource != NULL) { + if (!free_cert) { /* 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); @@ -5541,14 +5721,14 @@ PHP_FUNCTION(openssl_cms_encrypt) } ZEND_HASH_FOREACH_END(); } else { /* a single certificate */ - zend_resource *certresource; + bool free_cert; - cert = php_openssl_x509_from_zval(zrecipcerts, 0, &certresource); + cert = php_openssl_x509_from_zval(zrecipcerts, &free_cert); if (cert == NULL) { goto clean_exit; } - if (certresource != NULL) { + if (!free_cert) { /* 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); @@ -5756,16 +5936,18 @@ clean_exit: PHP_FUNCTION(openssl_cms_sign) { - zval * zcert, * zprivkey, * zheaders; + X509 *cert = NULL; + zend_object *cert_obj; + zend_string *cert_str; + zval *zprivkey, *zheaders; zval * hval; - X509 * cert = NULL; EVP_PKEY * privkey = NULL; zend_long flags = 0; zend_long encoding = ENCODING_SMIME; CMS_ContentInfo * cms = NULL; BIO * infile = NULL, * outfile = NULL; STACK_OF(X509) *others = NULL; - zend_resource *certresource = NULL, *keyresource = NULL; + bool free_pkey = 0; zend_string * strindex; char * infilename; size_t infilename_len; @@ -5775,12 +5957,17 @@ PHP_FUNCTION(openssl_cms_sign) size_t extracertsfilename_len; int need_final = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ppzza!|llp!", - &infilename, &infilename_len, &outfilename, &outfilename_len, - &zcert, &zprivkey, &zheaders, &flags, &encoding, &extracertsfilename, - &extracertsfilename_len) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(5, 8) + Z_PARAM_PATH(infilename, infilename_len) + Z_PARAM_PATH(outfilename, outfilename_len) + Z_PARAM_STR_OR_OBJ_OF_CLASS(cert_str, cert_obj, php_openssl_certificate_ce) + Z_PARAM_ZVAL(zprivkey) + Z_PARAM_ARRAY_OR_NULL(zheaders) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(flags) + Z_PARAM_LONG(encoding) + Z_PARAM_PATH(extracertsfilename, extracertsfilename_len) + ZEND_PARSE_PARAMETERS_END(); RETVAL_FALSE; @@ -5791,7 +5978,7 @@ PHP_FUNCTION(openssl_cms_sign) } } - privkey = php_openssl_evp_from_zval(zprivkey, 0, "", 0, 0, &keyresource); + privkey = php_openssl_pkey_from_zval(zprivkey, 0, "", 0, &free_pkey); if (privkey == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Error getting private key"); @@ -5799,9 +5986,9 @@ PHP_FUNCTION(openssl_cms_sign) goto clean_exit; } - cert = php_openssl_x509_from_zval(zcert, 0, &certresource); + cert = php_openssl_x509_from_param(cert_obj, cert_str); if (cert == NULL) { - php_error_docref(NULL, E_WARNING, "Error getting cert"); + php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); goto clean_exit; } @@ -5926,7 +6113,7 @@ clean_exit: sk_X509_pop_free(others, X509_free); } EVP_PKEY_free(privkey); - if (cert && certresource == NULL) { + if (cert && cert_str) { X509_free(cert); } } @@ -5936,10 +6123,11 @@ clean_exit: PHP_FUNCTION(openssl_cms_decrypt) { - zval * recipcert, * recipkey = NULL; - X509 * cert = NULL; + X509 *cert; + zval *recipcert, *recipkey = NULL; + bool free_recipcert; EVP_PKEY * key = NULL; - zend_resource *certresval, *keyresval; + bool free_pkey; zend_long encoding = ENCODING_SMIME; BIO * in = NULL, * out = NULL, * datain = NULL; CMS_ContentInfo * cms = NULL; @@ -5948,21 +6136,24 @@ PHP_FUNCTION(openssl_cms_decrypt) char * outfilename; size_t outfilename_len; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ppz|zl", &infilename, &infilename_len, - &outfilename, &outfilename_len, &recipcert, - &recipkey, &encoding) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(3, 5) + Z_PARAM_PATH(infilename, infilename_len) + Z_PARAM_PATH(outfilename, outfilename_len) + Z_PARAM_ZVAL(recipcert) + Z_PARAM_OPTIONAL + Z_PARAM_ZVAL(recipkey) + Z_PARAM_LONG(encoding) + ZEND_PARSE_PARAMETERS_END(); RETVAL_FALSE; - cert = php_openssl_x509_from_zval(recipcert, 0, &certresval); + cert = php_openssl_x509_from_zval(recipcert, &free_recipcert); if (cert == NULL) { - php_error_docref(NULL, E_WARNING, "Unable to coerce parameter 3 to x509 cert"); + php_error_docref(NULL, E_WARNING, "X.509 Certificate cannot be retrieved"); goto clean_exit; } - key = php_openssl_evp_from_zval(recipkey ? recipkey : recipcert, 0, "", 0, 0, &keyresval); + key = php_openssl_pkey_from_zval(recipkey ? recipkey : recipcert, 0, "", 0, &free_pkey); if (key == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Unable to get private key"); @@ -6017,10 +6208,10 @@ clean_exit: BIO_free(datain); BIO_free(in); BIO_free(out); - if (cert && certresval == NULL) { + if (cert && free_recipcert) { X509_free(cert); } - if (key && keyresval == NULL) { + if (key && free_pkey) { EVP_PKEY_free(key); } } @@ -6038,7 +6229,7 @@ PHP_FUNCTION(openssl_private_encrypt) int cryptedlen; zend_string *cryptedbuf = NULL; int successful = 0; - zend_resource *keyresource = NULL; + bool free_pkey = 0; char * data; size_t data_len; zend_long padding = RSA_PKCS1_PADDING; @@ -6048,7 +6239,7 @@ PHP_FUNCTION(openssl_private_encrypt) } RETVAL_FALSE; - pkey = php_openssl_evp_from_zval(key, 0, "", 0, 0, &keyresource); + pkey = php_openssl_pkey_from_zval(key, 0, "", 0, &free_pkey); if (pkey == NULL) { if (!EG(exception)) { @@ -6086,7 +6277,7 @@ PHP_FUNCTION(openssl_private_encrypt) if (cryptedbuf) { zend_string_release_ex(cryptedbuf, 0); } - if (keyresource == NULL) { + if (free_pkey) { EVP_PKEY_free(pkey); } } @@ -6102,7 +6293,7 @@ PHP_FUNCTION(openssl_private_decrypt) unsigned char *crypttemp; int successful = 0; zend_long padding = RSA_PKCS1_PADDING; - zend_resource *keyresource = NULL; + bool free_pkey = 0; char * data; size_t data_len; @@ -6111,7 +6302,7 @@ PHP_FUNCTION(openssl_private_decrypt) } RETVAL_FALSE; - pkey = php_openssl_evp_from_zval(key, 0, "", 0, 0, &keyresource); + pkey = php_openssl_pkey_from_zval(key, 0, "", 0, &free_pkey); if (pkey == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "key parameter is not a valid private key"); @@ -6153,7 +6344,7 @@ PHP_FUNCTION(openssl_private_decrypt) php_openssl_store_errors(); } - if (keyresource == NULL) { + if (free_pkey) { EVP_PKEY_free(pkey); } if (cryptedbuf) { @@ -6170,7 +6361,7 @@ PHP_FUNCTION(openssl_public_encrypt) int cryptedlen; zend_string *cryptedbuf; int successful = 0; - zend_resource *keyresource = NULL; + bool free_pkey = 0; zend_long padding = RSA_PKCS1_PADDING; char * data; size_t data_len; @@ -6180,7 +6371,7 @@ PHP_FUNCTION(openssl_public_encrypt) } RETVAL_FALSE; - pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, 0, &keyresource); + pkey = php_openssl_pkey_from_zval(key, 1, NULL, 0, &free_pkey); if (pkey == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "key parameter is not a valid public key"); @@ -6215,7 +6406,7 @@ PHP_FUNCTION(openssl_public_encrypt) } else { php_openssl_store_errors(); } - if (keyresource == NULL) { + if (free_pkey) { EVP_PKEY_free(pkey); } if (cryptedbuf) { @@ -6233,7 +6424,7 @@ PHP_FUNCTION(openssl_public_decrypt) zend_string *cryptedbuf = NULL; unsigned char *crypttemp; int successful = 0; - zend_resource *keyresource = NULL; + bool free_pkey = 0; zend_long padding = RSA_PKCS1_PADDING; char * data; size_t data_len; @@ -6243,7 +6434,7 @@ PHP_FUNCTION(openssl_public_decrypt) } RETVAL_FALSE; - pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, 0, &keyresource); + pkey = php_openssl_pkey_from_zval(key, 1, NULL, 0, &free_pkey); if (pkey == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "key parameter is not a valid public key"); @@ -6290,7 +6481,7 @@ PHP_FUNCTION(openssl_public_decrypt) if (cryptedbuf) { zend_string_release_ex(cryptedbuf, 0); } - if (keyresource == NULL) { + if (free_pkey) { EVP_PKEY_free(pkey); } } @@ -6331,7 +6522,7 @@ PHP_FUNCTION(openssl_sign) EVP_PKEY *pkey; unsigned int siglen; zend_string *sigbuf; - zend_resource *keyresource = NULL; + bool free_pkey = 0; char * data; size_t data_len; EVP_MD_CTX *md_ctx; @@ -6342,7 +6533,7 @@ PHP_FUNCTION(openssl_sign) if (zend_parse_parameters(ZEND_NUM_ARGS(), "szz|z", &data, &data_len, &signature, &key, &method) == FAILURE) { RETURN_THROWS(); } - pkey = php_openssl_evp_from_zval(key, 0, "", 0, 0, &keyresource); + pkey = php_openssl_pkey_from_zval(key, 0, "", 0, &free_pkey); if (pkey == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Supplied key param cannot be coerced into a private key"); @@ -6384,7 +6575,7 @@ PHP_FUNCTION(openssl_sign) RETVAL_FALSE; } EVP_MD_CTX_destroy(md_ctx); - if (keyresource == NULL) { + if (free_pkey) { EVP_PKEY_free(pkey); } } @@ -6398,7 +6589,7 @@ PHP_FUNCTION(openssl_verify) int err = 0; EVP_MD_CTX *md_ctx; const EVP_MD *mdtype; - zend_resource *keyresource = NULL; + bool free_pkey = 0; char * data; size_t data_len; char * signature; @@ -6428,7 +6619,7 @@ PHP_FUNCTION(openssl_verify) RETURN_FALSE; } - pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, 0, &keyresource); + pkey = php_openssl_pkey_from_zval(key, 1, NULL, 0, &free_pkey); if (pkey == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Supplied key param cannot be coerced into a public key"); @@ -6445,7 +6636,7 @@ PHP_FUNCTION(openssl_verify) } EVP_MD_CTX_destroy(md_ctx); - if (keyresource == NULL) { + if (free_pkey) { EVP_PKEY_free(pkey); } RETURN_LONG(err); @@ -6458,7 +6649,7 @@ PHP_FUNCTION(openssl_seal) zval *pubkeys, *pubkey, *sealdata, *ekeys, *iv = NULL; HashTable *pubkeysht; EVP_PKEY **pkeys; - zend_resource ** key_resources; /* so we know what to cleanup */ + bool *free_pkeys; /* 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; @@ -6502,14 +6693,14 @@ PHP_FUNCTION(openssl_seal) eksl = safe_emalloc(nkeys, sizeof(*eksl), 0); eks = safe_emalloc(nkeys, sizeof(*eks), 0); memset(eks, 0, sizeof(*eks) * nkeys); - key_resources = safe_emalloc(nkeys, sizeof(zend_resource*), 0); - memset(key_resources, 0, sizeof(zend_resource*) * nkeys); + free_pkeys = safe_emalloc(nkeys, sizeof(int *), 0); + memset(free_pkeys, 0, sizeof(int *) * nkeys); memset(pkeys, 0, sizeof(*pkeys) * nkeys); /* get the public keys we are using to seal this data */ i = 0; ZEND_HASH_FOREACH_VAL(pubkeysht, pubkey) { - pkeys[i] = php_openssl_evp_from_zval(pubkey, 1, NULL, 0, 0, &key_resources[i]); + pkeys[i] = php_openssl_pkey_from_zval(pubkey, 1, NULL, 0, &free_pkeys[i]); if (pkeys[i] == NULL) { if (!EG(exception)) { php_error_docref(NULL, E_WARNING, "Not a public key (%dth member of pubkeys)", i+1); @@ -6572,7 +6763,7 @@ PHP_FUNCTION(openssl_seal) clean_exit: for (i=0; i ---EXPECT-- +--CLEAN-- + +--EXPECTF-- Creating private key Export key to file bool(true) Load key from file - array syntax + +Deprecated: Function openssl_pkey_free() is deprecated in %s on line %d Load key using direct syntax + +Deprecated: Function openssl_pkey_free() is deprecated in %s on line %d Load key manually and use string syntax + +Deprecated: Function openssl_pkey_free() is deprecated in %s on line %d OK! ---CLEAN-- - diff --git a/ext/openssl/tests/CertificateGenerator.inc b/ext/openssl/tests/CertificateGenerator.inc index b409376058..1dc378e706 100644 --- a/ext/openssl/tests/CertificateGenerator.inc +++ b/ext/openssl/tests/CertificateGenerator.inc @@ -4,7 +4,7 @@ class CertificateGenerator { const CONFIG = __DIR__. DIRECTORY_SEPARATOR . 'openssl.cnf'; - /** @var resource */ + /** @var OpenSSLCertificate */ private $ca; /** @var resource */ diff --git a/ext/openssl/tests/bug38261.phpt b/ext/openssl/tests/bug38261.phpt index 971fba71c2..827f3aca75 100644 --- a/ext/openssl/tests/bug38261.phpt +++ b/ext/openssl/tests/bug38261.phpt @@ -15,12 +15,24 @@ class test { $t = new test; var_dump(openssl_x509_parse("foo")); -var_dump(openssl_x509_parse($t)); -var_dump(openssl_x509_parse(array())); + +try { + var_dump(openssl_x509_parse($t)); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +try { + openssl_x509_parse([]); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + var_dump(openssl_x509_parse($cert)); + try { - var_dump(openssl_x509_parse(new stdClass)); -} catch (Error $e) { + openssl_x509_parse(new stdClass); +} catch (TypeError $e) { echo $e->getMessage(), "\n"; } @@ -28,6 +40,6 @@ try { --EXPECT-- bool(false) bool(false) +openssl_x509_parse(): Argument #1 ($x509) must be of type OpenSSLCertificate|string, array given bool(false) -bool(false) -Object of class stdClass could not be converted to string +openssl_x509_parse(): Argument #1 ($x509) must be of type OpenSSLCertificate|string, stdClass given diff --git a/ext/openssl/tests/bug61930.phpt b/ext/openssl/tests/bug61930.phpt index c79f51eeef..f63dd93ec3 100644 --- a/ext/openssl/tests/bug61930.phpt +++ b/ext/openssl/tests/bug61930.phpt @@ -21,5 +21,6 @@ var_dump(openssl_get_publickey($key)); var_dump(openssl_verify($data, base64_decode($sig), $key)); ?> --EXPECTF-- -resource(%d) of type (OpenSSL key) +object(OpenSSLAsymmetricKey)#%d (0) { +} int(1) diff --git a/ext/openssl/tests/bug68912.phpt b/ext/openssl/tests/bug68912.phpt index 0b796b7683..64d1a9b60a 100644 --- a/ext/openssl/tests/bug68912.phpt +++ b/ext/openssl/tests/bug68912.phpt @@ -19,4 +19,4 @@ try { } ?> --EXPECT-- -openssl_spki_new(): supplied resource is not a valid OpenSSL X.509/key resource +openssl_spki_new(): Argument #1 ($privkey) must be of type OpenSSLAsymmetricKey, resource given diff --git a/ext/openssl/tests/bug73711.phpt b/ext/openssl/tests/bug73711.phpt index c5f5575e2c..0b3f91b8fe 100644 --- a/ext/openssl/tests/bug73711.phpt +++ b/ext/openssl/tests/bug73711.phpt @@ -12,6 +12,8 @@ var_dump(openssl_pkey_new(["private_key_type" => OPENSSL_KEYTYPE_DH, 'config' => echo "DONE"; ?> --EXPECTF-- -resource(%d) of type (OpenSSL key) -resource(%d) of type (OpenSSL key) +object(OpenSSLAsymmetricKey)#%d (0) { +} +object(OpenSSLAsymmetricKey)#%d (0) { +} DONE diff --git a/ext/openssl/tests/bug74651.phpt b/ext/openssl/tests/bug74651.phpt index b4e50a0421..96c06231b2 100644 --- a/ext/openssl/tests/bug74651.phpt +++ b/ext/openssl/tests/bug74651.phpt @@ -13,5 +13,6 @@ var_dump($pub_key_id); var_dump(openssl_seal($inputstr, $sealed, $ekeys, array($pub_key_id, $pub_key_id), 'AES-128-ECB')); ?> --EXPECTF-- -resource(%d) of type (OpenSSL key) +object(OpenSSLAsymmetricKey)#%d (0) { +} bool(false) diff --git a/ext/openssl/tests/bug79145.phpt b/ext/openssl/tests/bug79145.phpt index 348831189b..4f3dc9e766 100644 --- a/ext/openssl/tests/bug79145.phpt +++ b/ext/openssl/tests/bug79145.phpt @@ -17,7 +17,7 @@ C9C4JmhTOjBVAK8SewIDAQAC $start = memory_get_usage(true); for ($i = 0; $i < 100000; $i++) { $a = openssl_get_publickey($b); - openssl_free_key($a); + @openssl_free_key($a); } $end = memory_get_usage(true); var_dump($end <= 1.1 * $start); diff --git a/ext/openssl/tests/ecc.phpt b/ext/openssl/tests/ecc.phpt index 41567e9b32..0a71393ae3 100644 --- a/ext/openssl/tests/ecc.phpt +++ b/ext/openssl/tests/ecc.phpt @@ -81,7 +81,8 @@ foreach ($curve_names as $curve_name) { ?> --EXPECTF-- Testing openssl_pkey_new -resource(%d) of type (OpenSSL key) +object(OpenSSLAsymmetricKey)#1 (0) { +} Warning: openssl_pkey_new(): Unknown elliptic curve (short) name invalid_cuve_name in %s on line %d bool(false) @@ -89,19 +90,23 @@ int(384) int(215) string(9) "secp384r1" bool(true) -resource(%d) of type (OpenSSL key) +object(OpenSSLAsymmetricKey)#%d (0) { +} bool(true) Testing openssl_csr_new with key generation NULL -resource(%d) of type (OpenSSL key) +object(OpenSSLAsymmetricKey)#%d (0) { +} Testing openssl_csr_new with existing ecc key -resource(%d) of type (OpenSSL X.509 CSR) +object(OpenSSLCertificateSigningRequest)#%d (0) { +} bool(false) array(1) { ["d"]=> string(%d) "%a" } -resource(%d) of type (OpenSSL X.509) +object(OpenSSLCertificate)#%d (0) { +} Testing openssl_x509_check_private_key bool(true) bool(false) diff --git a/ext/openssl/tests/openssl_cms_decrypt_basic.phpt b/ext/openssl/tests/openssl_cms_decrypt_basic.phpt index ec295be1b7..86c70f4fde 100644 --- a/ext/openssl/tests/openssl_cms_decrypt_basic.phpt +++ b/ext/openssl/tests/openssl_cms_decrypt_basic.phpt @@ -50,16 +50,16 @@ bool(true) Warning: openssl_cms_decrypt(): Unable to get private key in %s on line %d bool(false) -Warning: openssl_cms_decrypt(): Unable to coerce parameter 3 to x509 cert in %s on line %d +Warning: openssl_cms_decrypt(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) -Warning: openssl_cms_decrypt(): Unable to coerce parameter 3 to x509 cert in %s on line %d +Warning: openssl_cms_decrypt(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) bool(false) bool(false) bool(false) -Warning: openssl_cms_decrypt(): Unable to coerce parameter 3 to x509 cert in %s on line %d +Warning: openssl_cms_decrypt(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) Warning: openssl_cms_decrypt(): Unable to get private key in %s on line %d diff --git a/ext/openssl/tests/openssl_cms_decrypt_error.phpt b/ext/openssl/tests/openssl_cms_decrypt_error.phpt index 28812c3200..66b8f71df7 100644 --- a/ext/openssl/tests/openssl_cms_decrypt_error.phpt +++ b/ext/openssl/tests/openssl_cms_decrypt_error.phpt @@ -33,12 +33,12 @@ echo "Done\n"; Object of class stdClass could not be converted to string object(stdClass)#1 (0) { } -string(64) "openssl_cms_decrypt(): Unable to coerce parameter 3 to x509 cert" +string(60) "openssl_cms_decrypt(): X.509 Certificate cannot be retrieved" bool(false) -string(64) "openssl_cms_decrypt(): Unable to coerce parameter 3 to x509 cert" +string(60) "openssl_cms_decrypt(): X.509 Certificate cannot be retrieved" bool(false) -string(64) "openssl_cms_decrypt(): Unable to coerce parameter 3 to x509 cert" +string(60) "openssl_cms_decrypt(): X.509 Certificate cannot be retrieved" bool(false) -string(64) "openssl_cms_decrypt(): Unable to coerce parameter 3 to x509 cert" +string(60) "openssl_cms_decrypt(): X.509 Certificate cannot be retrieved" bool(false) Done diff --git a/ext/openssl/tests/openssl_cms_sign_basic.phpt b/ext/openssl/tests/openssl_cms_sign_basic.phpt index cbeaaf3ab2..8099272ee8 100644 --- a/ext/openssl/tests/openssl_cms_sign_basic.phpt +++ b/ext/openssl/tests/openssl_cms_sign_basic.phpt @@ -53,10 +53,10 @@ bool(false) Warning: openssl_cms_sign(): Error opening output file %s in %s on line %d bool(false) -Warning: openssl_cms_sign(): Error getting cert in %s on line %d +Warning: openssl_cms_sign(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) -Warning: openssl_cms_sign(): Error getting cert in %s on line %d +Warning: openssl_cms_sign(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) Warning: openssl_cms_sign(): Error getting private key in %s on line %d diff --git a/ext/openssl/tests/openssl_csr_export_bacis.phpt b/ext/openssl/tests/openssl_csr_export_bacis.phpt deleted file mode 100644 index f0a258dd15..0000000000 --- a/ext/openssl/tests/openssl_csr_export_bacis.phpt +++ /dev/null @@ -1,46 +0,0 @@ ---TEST-- -openssl_csr_export() tests ---SKIPIF-- - ---FILE-- - $config); - -$dn = array( - "countryName" => "BR", - "stateOrProvinceName" => "Rio Grande do Sul", - "localityName" => "Porto Alegre", - "commonName" => "Henrique do N. Angelo", - "emailAddress" => "hnangelo@php.net" -); - -$args = array( - "digest_alg" => "sha1", - "private_key_bits" => 2048, - "private_key_type" => OPENSSL_KEYTYPE_DSA, - "encrypt_key" => true, - "config" => $config, -); - -$privkey = openssl_pkey_new($config_arg); -$csr = openssl_csr_new($dn, $privkey, $args); -var_dump(openssl_csr_export($csr, $output)); -try { - var_dump(openssl_csr_export($wrong, $output)); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; -} -try { - var_dump(openssl_csr_export($privkey, $output)); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; -} -var_dump(openssl_csr_export($csr, $output, false)); -?> ---EXPECT-- -bool(true) -openssl_csr_export(): Argument #1 ($csr) must be of type resource, string given -openssl_csr_export(): supplied resource is not a valid OpenSSL X.509 CSR resource -bool(true) diff --git a/ext/openssl/tests/openssl_csr_export_basic.phpt b/ext/openssl/tests/openssl_csr_export_basic.phpt new file mode 100644 index 0000000000..5f8c9f2c6d --- /dev/null +++ b/ext/openssl/tests/openssl_csr_export_basic.phpt @@ -0,0 +1,48 @@ +--TEST-- +openssl_csr_export() tests +--SKIPIF-- + +--FILE-- + $config); + +$dn = array( + "countryName" => "BR", + "stateOrProvinceName" => "Rio Grande do Sul", + "localityName" => "Porto Alegre", + "commonName" => "Henrique do N. Angelo", + "emailAddress" => "hnangelo@php.net" +); + +$args = array( + "digest_alg" => "sha1", + "private_key_bits" => 2048, + "private_key_type" => OPENSSL_KEYTYPE_DSA, + "encrypt_key" => true, + "config" => $config, +); + +$privkey = openssl_pkey_new($config_arg); +$csr = openssl_csr_new($dn, $privkey, $args); +var_dump(openssl_csr_export($csr, $output)); +try { + var_dump(openssl_csr_export($wrong, $output)); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump(openssl_csr_export($privkey, $output)); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +var_dump(openssl_csr_export($csr, $output, false)); +?> +--EXPECTF-- +bool(true) + +Warning: openssl_csr_export(): X.509 Certificate Signing Request cannot be retrieved in %s on line %d +bool(false) +openssl_csr_export(): Argument #1 ($csr) must be of type OpenSSLCertificateSigningRequest|string, OpenSSLAsymmetricKey given +bool(true) diff --git a/ext/openssl/tests/openssl_csr_export_to_file_basic.phpt b/ext/openssl/tests/openssl_csr_export_to_file_basic.phpt index 7f6347840d..4efa6f35d5 100644 --- a/ext/openssl/tests/openssl_csr_export_to_file_basic.phpt +++ b/ext/openssl/tests/openssl_csr_export_to_file_basic.phpt @@ -36,13 +36,11 @@ $privkey_file = 'file://' . __DIR__ . '/private_rsa_2048.key'; $csr = openssl_csr_new($dn, $privkey_file, $args); var_dump(openssl_csr_export_to_file($csr, $csrfile)); var_dump(file_get_contents($csrfile)); + +var_dump(openssl_csr_export_to_file($wrong, $csrfile)); + try { - var_dump(openssl_csr_export_to_file($wrong, $csrfile)); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; -} -try { - var_dump(openssl_csr_export_to_file($dh, $csrfile)); + openssl_csr_export_to_file($dh, $csrfile); } catch (TypeError $e) { echo $e->getMessage(), "\n"; } @@ -55,7 +53,7 @@ if (file_exists($csrfile)) { unlink($csrfile); } ?> ---EXPECT-- +--EXPECTF-- bool(true) string(1086) "-----BEGIN CERTIFICATE REQUEST----- MIIC6jCCAdICAQAwgaQxCzAJBgNVBAYTAkJSMRowGAYDVQQIExFSaW8gR3JhbmRl @@ -76,6 +74,8 @@ sfBgVeqg0P4SWez5fHXqBNcjMdMI5f0bikcDZSIfTHS8FX+PMurLBC8UPB0YNIOl JViHkCA9x6m8RJXAFvqmgLlWlUzbDv/cRrDfjWjR -----END CERTIFICATE REQUEST----- " -openssl_csr_export_to_file(): Argument #1 ($csr) must be of type resource, string given -openssl_csr_export_to_file(): supplied resource is not a valid OpenSSL X.509 CSR resource + +Warning: openssl_csr_export_to_file(): X.509 Certificate Signing Request cannot be retrieved in %s on line %d +bool(false) +openssl_csr_export_to_file(): Argument #1 ($csr) must be of type OpenSSLCertificateSigningRequest|string, OpenSSLAsymmetricKey given bool(true) diff --git a/ext/openssl/tests/openssl_csr_get_public_key_basic.phpt b/ext/openssl/tests/openssl_csr_get_public_key_basic.phpt index 185e46539e..20cbbb83d6 100644 --- a/ext/openssl/tests/openssl_csr_get_public_key_basic.phpt +++ b/ext/openssl/tests/openssl_csr_get_public_key_basic.phpt @@ -40,5 +40,7 @@ var_dump(openssl_csr_get_public_key($csr)); var_dump(openssl_csr_get_public_key($csr_file)); ?> --EXPECTF-- -resource(%d) of type (OpenSSL key) -resource(%d) of type (OpenSSL key) +object(OpenSSLAsymmetricKey)#%d (0) { +} +object(OpenSSLAsymmetricKey)#%d (0) { +} diff --git a/ext/openssl/tests/openssl_csr_new_basic.phpt b/ext/openssl/tests/openssl_csr_new_basic.phpt index c18ac2a22e..793cf03ed0 100644 --- a/ext/openssl/tests/openssl_csr_new_basic.phpt +++ b/ext/openssl/tests/openssl_csr_new_basic.phpt @@ -27,6 +27,8 @@ Warning: openssl_csr_new(): Key array must be of the form array(0 => key, 1 => p 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 %s on line %d bool(false) -resource(%d) of type (OpenSSL X.509 CSR) -resource(%d) of type (OpenSSL X.509 CSR) +object(OpenSSLCertificateSigningRequest)#%d (0) { +} +object(OpenSSLCertificateSigningRequest)#%d (0) { +} Done diff --git a/ext/openssl/tests/openssl_csr_sign_basic.phpt b/ext/openssl/tests/openssl_csr_sign_basic.phpt index 03e070e52b..ea720248d0 100644 --- a/ext/openssl/tests/openssl_csr_sign_basic.phpt +++ b/ext/openssl/tests/openssl_csr_sign_basic.phpt @@ -29,6 +29,7 @@ $args = array( $privkey = openssl_pkey_new($config_arg); $csr = openssl_csr_new($dn, $privkey, $args); + var_dump(openssl_csr_sign($csr, null, $privkey, 365, $args)); var_dump(openssl_csr_sign($csr, null, $privkey, 365, $config_arg)); var_dump(openssl_csr_sign($csr, $cert, $priv, 365, $config_arg)); @@ -36,34 +37,46 @@ var_dump(openssl_csr_sign($csr, openssl_x509_read($cert), $priv, 365, $config_ar var_dump(openssl_csr_sign($csr, $wrong, $privkey, 365)); var_dump(openssl_csr_sign($csr, null, $wrong, 365)); var_dump(openssl_csr_sign($wrong, null, $privkey, 365)); -var_dump(openssl_csr_sign(array(), null, $privkey, 365)); -var_dump(openssl_csr_sign($csr, array(), $privkey, 365)); + +try { + openssl_csr_sign(array(), null, $privkey, 365); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + var_dump(openssl_csr_sign($csr, array(), $privkey, 365)); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} + var_dump(openssl_csr_sign($csr, null, array(), 365)); var_dump(openssl_csr_sign($csr, null, $privkey, 365, $config_arg)); ?> --EXPECTF-- -resource(%d) of type (OpenSSL X.509) -resource(%d) of type (OpenSSL X.509) -resource(%d) of type (OpenSSL X.509) -resource(%d) of type (OpenSSL X.509) +object(OpenSSLCertificate)#%d (0) { +} +object(OpenSSLCertificate)#%d (0) { +} +object(OpenSSLCertificate)#%d (0) { +} +object(OpenSSLCertificate)#%d (0) { +} -Warning: openssl_csr_sign(): Cannot get cert from parameter 2 in %s on line %d +Warning: openssl_csr_sign(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) Warning: openssl_csr_sign(): Cannot get private key from parameter 3 in %s on line %d bool(false) -Warning: openssl_csr_sign(): Cannot get CSR from parameter 1 in %s on line %d -bool(false) - -Warning: openssl_csr_sign(): Cannot get CSR from parameter 1 in %s on line %d -bool(false) - -Warning: openssl_csr_sign(): Cannot get cert from parameter 2 in %s on line %d +Warning: openssl_csr_sign(): X.509 Certificate Signing Request cannot be retrieved in %s on line %d bool(false) +openssl_csr_sign(): Argument #1 ($csr) must be of type OpenSSLCertificateSigningRequest|string, array given +openssl_csr_sign(): Argument #2 ($cacert) must be of type OpenSSLCertificate|string|null, array given Warning: openssl_csr_sign(): Key array must be of the form array(0 => key, 1 => phrase) in %s on line %d Warning: openssl_csr_sign(): Cannot get private key from parameter 3 in %s on line %d bool(false) -resource(%d) of type (OpenSSL X.509) +object(OpenSSLCertificate)#%d (0) { +} diff --git a/ext/openssl/tests/openssl_free_key.phpt b/ext/openssl/tests/openssl_free_key.phpt index 0c8bdd92de..328394cc8e 100644 --- a/ext/openssl/tests/openssl_free_key.phpt +++ b/ext/openssl/tests/openssl_free_key.phpt @@ -68,10 +68,16 @@ echo "OK!\n"; @unlink($key_file_name); ?> ---EXPECT-- +--EXPECTF-- Creating private key Export key to file Load key from file - array syntax + +Deprecated: Function openssl_free_key() is deprecated in %s on line %d Load key using direct syntax + +Deprecated: Function openssl_free_key() is deprecated in %s on line %d Load key manually and use string syntax + +Deprecated: Function openssl_free_key() is deprecated in %s on line %d OK! diff --git a/ext/openssl/tests/openssl_pkcs12_export_basic.phpt b/ext/openssl/tests/openssl_pkcs12_export_basic.phpt index 41d2fbdedd..fc8a146c0c 100644 --- a/ext/openssl/tests/openssl_pkcs12_export_basic.phpt +++ b/ext/openssl/tests/openssl_pkcs12_export_basic.phpt @@ -48,11 +48,9 @@ bool(true) bool(true) int(3) -Warning: openssl_pkcs12_export(): Cannot get cert from parameter 1 in %s on line %d +Warning: openssl_pkcs12_export(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) -Warning: openssl_pkcs12_export(): Cannot get cert from parameter 1 in %s on line %d +Warning: openssl_pkcs12_export(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) - -Warning: openssl_pkcs12_export(): Cannot get cert from parameter 1 in %s on line %d -openssl_pkcs12_export(): supplied resource is not a valid OpenSSL X.509 resource +openssl_pkcs12_export(): Argument #1 ($x509) must be of type OpenSSLCertificate|string, OpenSSLAsymmetricKey given diff --git a/ext/openssl/tests/openssl_pkcs12_export_to_file_basic.phpt b/ext/openssl/tests/openssl_pkcs12_export_to_file_basic.phpt index 73dc070f3f..69363fe34f 100644 --- a/ext/openssl/tests/openssl_pkcs12_export_to_file_basic.phpt +++ b/ext/openssl/tests/openssl_pkcs12_export_to_file_basic.phpt @@ -53,11 +53,9 @@ bool(true) bool(true) bool(true) -Warning: openssl_pkcs12_export_to_file(): Cannot get cert from parameter 1 in %s on line %d +Warning: openssl_pkcs12_export_to_file(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) -Warning: openssl_pkcs12_export_to_file(): Cannot get cert from parameter 1 in %s on line %d +Warning: openssl_pkcs12_export_to_file(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) - -Warning: openssl_pkcs12_export_to_file(): Cannot get cert from parameter 1 in %s on line %d -openssl_pkcs12_export_to_file(): supplied resource is not a valid OpenSSL X.509 resource +openssl_pkcs12_export_to_file(): Argument #1 ($x509cert) must be of type OpenSSLCertificate|string, OpenSSLAsymmetricKey given diff --git a/ext/openssl/tests/openssl_pkcs7_decrypt_basic.phpt b/ext/openssl/tests/openssl_pkcs7_decrypt_basic.phpt index f96fd401cd..eb0698da9f 100644 --- a/ext/openssl/tests/openssl_pkcs7_decrypt_basic.phpt +++ b/ext/openssl/tests/openssl_pkcs7_decrypt_basic.phpt @@ -48,16 +48,16 @@ bool(true) Warning: openssl_pkcs7_decrypt(): Unable to get private key in %s on line %d bool(false) -Warning: openssl_pkcs7_decrypt(): Unable to coerce parameter 3 to x509 cert in %s on line %d +Warning: openssl_pkcs7_decrypt(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) -Warning: openssl_pkcs7_decrypt(): Unable to coerce parameter 3 to x509 cert in %s on line %d +Warning: openssl_pkcs7_decrypt(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) bool(false) bool(false) bool(false) -Warning: openssl_pkcs7_decrypt(): Unable to coerce parameter 3 to x509 cert in %s on line %d +Warning: openssl_pkcs7_decrypt(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) Warning: openssl_pkcs7_decrypt(): Unable to get private key in %s on line %d diff --git a/ext/openssl/tests/openssl_pkcs7_decrypt_error.phpt b/ext/openssl/tests/openssl_pkcs7_decrypt_error.phpt index d7ae715efb..39e45399fd 100644 --- a/ext/openssl/tests/openssl_pkcs7_decrypt_error.phpt +++ b/ext/openssl/tests/openssl_pkcs7_decrypt_error.phpt @@ -33,12 +33,12 @@ echo "Done\n"; Object of class stdClass could not be converted to string object(stdClass)#1 (0) { } -string(66) "openssl_pkcs7_decrypt(): Unable to coerce parameter 3 to x509 cert" +string(62) "openssl_pkcs7_decrypt(): X.509 Certificate cannot be retrieved" bool(false) -string(66) "openssl_pkcs7_decrypt(): Unable to coerce parameter 3 to x509 cert" +string(62) "openssl_pkcs7_decrypt(): X.509 Certificate cannot be retrieved" bool(false) -string(66) "openssl_pkcs7_decrypt(): Unable to coerce parameter 3 to x509 cert" +string(62) "openssl_pkcs7_decrypt(): X.509 Certificate cannot be retrieved" bool(false) -string(66) "openssl_pkcs7_decrypt(): Unable to coerce parameter 3 to x509 cert" +string(62) "openssl_pkcs7_decrypt(): X.509 Certificate cannot be retrieved" bool(false) Done diff --git a/ext/openssl/tests/openssl_pkcs7_sign_basic.phpt b/ext/openssl/tests/openssl_pkcs7_sign_basic.phpt index 9b9ff91ddd..13eac36a79 100644 --- a/ext/openssl/tests/openssl_pkcs7_sign_basic.phpt +++ b/ext/openssl/tests/openssl_pkcs7_sign_basic.phpt @@ -49,10 +49,10 @@ bool(false) Warning: openssl_pkcs7_sign(): Error opening output file %s in %s on line %d bool(false) -Warning: openssl_pkcs7_sign(): Error getting cert in %s on line %d +Warning: openssl_pkcs7_sign(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) -Warning: openssl_pkcs7_sign(): Error getting cert in %s on line %d +Warning: openssl_pkcs7_sign(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) Warning: openssl_pkcs7_sign(): Error getting private key in %s on line %d diff --git a/ext/openssl/tests/openssl_pkey_export_basic.phpt b/ext/openssl/tests/openssl_pkey_export_basic.phpt index d71f8da9a3..678b7e7299 100644 --- a/ext/openssl/tests/openssl_pkey_export_basic.phpt +++ b/ext/openssl/tests/openssl_pkey_export_basic.phpt @@ -39,17 +39,19 @@ $tempname = tempnam(sys_get_temp_dir(), 'openssl_ec'); var_dump(openssl_pkey_export_to_file($key, $tempname, NULL, $config_arg)); $details = openssl_pkey_get_details(openssl_pkey_get_private('file://' . $tempname)); var_dump(OPENSSL_KEYTYPE_EC === $details['type']); -var_dump(is_resource($key)); +var_dump($key instanceof OpenSSLAsymmetricKey); // Clean the temporary file @unlink($tempname); ?> --EXPECTF-- -resource(%d) of type (OpenSSL key) +object(OpenSSLAsymmetricKey)#%d (0) { +} bool(true) -----BEGIN EC PRIVATE KEY-----%a-----END EC PRIVATE KEY----- bool(true) bool(true) -resource(%d) of type (OpenSSL key) +object(OpenSSLAsymmetricKey)#%d (0) { +} array(1) { ["d"]=> string(32) "%a" diff --git a/ext/openssl/tests/openssl_pkey_new_error.phpt b/ext/openssl/tests/openssl_pkey_new_error.phpt index 4bed65278c..f863f0637a 100644 --- a/ext/openssl/tests/openssl_pkey_new_error.phpt +++ b/ext/openssl/tests/openssl_pkey_new_error.phpt @@ -28,6 +28,6 @@ try { } ?> --EXPECT-- -openssl_pkey_get_details(): Argument #1 ($key) must be of type resource, bool given -openssl_pkey_get_details(): Argument #1 ($key) must be of type resource, bool given -openssl_pkey_get_details(): Argument #1 ($key) must be of type resource, bool given +openssl_pkey_get_details(): Argument #1 ($key) must be of type OpenSSLAsymmetricKey, bool given +openssl_pkey_get_details(): Argument #1 ($key) must be of type OpenSSLAsymmetricKey, bool given +openssl_pkey_get_details(): Argument #1 ($key) must be of type OpenSSLAsymmetricKey, bool given diff --git a/ext/openssl/tests/openssl_x509_export_basic.phpt b/ext/openssl/tests/openssl_x509_export_basic.phpt index 03baae9266..43dc843b70 100644 --- a/ext/openssl/tests/openssl_x509_export_basic.phpt +++ b/ext/openssl/tests/openssl_x509_export_basic.phpt @@ -16,7 +16,12 @@ var_dump(openssl_x509_export($a, $output)); // read cert as a binary string var_dump(openssl_x509_export($b, $output2)); // read cert from a filename string 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 + +try { + openssl_x509_export($e, $output5); // read an array, fails +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} if (PHP_EOL !== "\n") { $a = str_replace(PHP_EOL, "\n", $a); @@ -32,12 +37,10 @@ var_dump(strcmp($output, $output5)); // different bool(true) bool(true) -Warning: openssl_x509_export(): Cannot get cert from parameter 1 in %s on line %d +Warning: openssl_x509_export(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) bool(true) - -Warning: openssl_x509_export(): Cannot get cert from parameter 1 in %s on line %d -bool(false) +openssl_x509_export(): Argument #1 ($x509) must be of type OpenSSLCertificate|string, array given int(0) int(0) int(%d) diff --git a/ext/openssl/tests/openssl_x509_export_to_file_basic.phpt b/ext/openssl/tests/openssl_x509_export_to_file_basic.phpt index 45037449a9..71a494f401 100644 --- a/ext/openssl/tests/openssl_x509_export_to_file_basic.phpt +++ b/ext/openssl/tests/openssl_x509_export_to_file_basic.phpt @@ -17,7 +17,11 @@ var_dump(openssl_x509_export_to_file($a, $outfilename)); // read cert as a binar var_dump(openssl_x509_export_to_file($b, $outfilename)); // read cert from a filename string var_dump(openssl_x509_export_to_file($c, $outfilename)); // read an invalid cert, fails var_dump(openssl_x509_export_to_file($d, $outfilename)); // read cert from a resource -var_dump(openssl_x509_export_to_file($e, $outfilename)); // read an array, fails +try { + openssl_x509_export_to_file($e, $outfilename); // read an array, fails +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} echo "---\n"; var_dump($exists = file_exists($outfilename)); ?> @@ -32,11 +36,9 @@ if (file_exists($outfilename)) { bool(true) bool(true) -Warning: openssl_x509_export_to_file(): Cannot get cert from parameter 1 in %s on line %d +Warning: openssl_x509_export_to_file(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) bool(true) - -Warning: openssl_x509_export_to_file(): Cannot get cert from parameter 1 in %s on line %d -bool(false) +openssl_x509_export_to_file(): Argument #1 ($x509) must be of type OpenSSLCertificate|string, array given --- bool(true) diff --git a/ext/openssl/tests/openssl_x509_fingerprint_basic.phpt b/ext/openssl/tests/openssl_x509_fingerprint_basic.phpt index 14f8c0c1ce..c4524ada0b 100644 --- a/ext/openssl/tests/openssl_x509_fingerprint_basic.phpt +++ b/ext/openssl/tests/openssl_x509_fingerprint_basic.phpt @@ -36,7 +36,7 @@ string(32) "ac77008e172897e06c0b065294487a67" string(40) "6e6fd1ea10a5a23071d61c728ee9b40df6dbc33c" ** Testing bad certification ** -Warning: openssl_x509_fingerprint(): Cannot get cert from parameter 1 in %s on line %d +Warning: openssl_x509_fingerprint(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) ** Testing bad hash method ** diff --git a/ext/openssl/tests/openssl_x509_free_basic.phpt b/ext/openssl/tests/openssl_x509_free_basic.phpt index 6fc28f1e75..77d42fda42 100644 --- a/ext/openssl/tests/openssl_x509_free_basic.phpt +++ b/ext/openssl/tests/openssl_x509_free_basic.phpt @@ -9,5 +9,9 @@ openssl_x509_free($res); var_dump($res); ?> --EXPECTF-- -resource(%d) of type (OpenSSL X.509) -resource(%d) of type (Unknown) +object(OpenSSLCertificate)#1 (0) { +} + +Deprecated: Function openssl_x509_free() is deprecated in %s on line %d +object(OpenSSLCertificate)#1 (0) { +} diff --git a/ext/openssl/tests/openssl_x509_read_basic.phpt b/ext/openssl/tests/openssl_x509_read_basic.phpt index d3aeadd29b..e4d956b120 100644 --- a/ext/openssl/tests/openssl_x509_read_basic.phpt +++ b/ext/openssl/tests/openssl_x509_read_basic.phpt @@ -18,19 +18,29 @@ var_dump(openssl_x509_read($a)); // read cert as a string var_dump(openssl_x509_read($b)); // read cert as a filename string var_dump(openssl_x509_read($c)); // read an invalid cert, fails var_dump(openssl_x509_read($d)); // read cert from a resource -var_dump(openssl_x509_read($e)); // read an array -var_dump(openssl_x509_read($f)); // read an array with the filename -?> ---EXPECTF-- -resource(%d) of type (OpenSSL X.509) -resource(%d) of type (OpenSSL X.509) -Warning: openssl_x509_read(): Supplied parameter cannot be coerced into an X509 certificate! in %s on line %d -bool(false) -resource(%d) of type (OpenSSL X.509) +try { + openssl_x509_read($e); // read an array +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} -Warning: openssl_x509_read(): Supplied parameter cannot be coerced into an X509 certificate! in %s on line %d -bool(false) +try { + openssl_x509_read($f); // read an array with the filename +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} + +?> +--EXPECTF-- +object(OpenSSLCertificate)#%d (0) { +} +object(OpenSSLCertificate)#%d (0) { +} -Warning: openssl_x509_read(): Supplied parameter cannot be coerced into an X509 certificate! in %s on line %d +Warning: openssl_x509_read(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) +object(OpenSSLCertificate)#%d (0) { +} +openssl_x509_read(): Argument #1 ($x509) must be of type OpenSSLCertificate|string, array given +openssl_x509_read(): Argument #1 ($x509) must be of type OpenSSLCertificate|string, array given diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index 3e2b72d9db..feb9ee52c1 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -122,7 +122,6 @@ static RSA *php_openssl_tmp_rsa_cb(SSL *s, int is_export, int keylength); extern php_stream* php_openssl_get_stream_from_ssl_handle(const SSL *ssl); 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 php_openssl_subtract_timeval(struct timeval a, struct timeval b); static int php_openssl_compare_timeval(struct timeval a, struct timeval b); static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, size_t count); @@ -1820,13 +1819,17 @@ static int php_openssl_capture_peer_certs(php_stream *stream, php_openssl_netstream_data_t *sslsock, X509 *peer_cert) /* {{{ */ { zval *val, zcert; + php_openssl_certificate_object *cert_object; int cert_captured = 0; if (NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "capture_peer_cert")) && zend_is_true(val) ) { - ZVAL_RES(&zcert, zend_register_resource(peer_cert, php_openssl_get_x509_list_id())); + object_init_ex(&zcert, php_openssl_certificate_ce); + cert_object = Z_OPENSSL_CERTIFICATE_P(&zcert); + cert_object->x509 = peer_cert; + php_stream_context_set_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_certificate", &zcert); zval_ptr_dtor(&zcert); cert_captured = 1; @@ -1847,7 +1850,10 @@ static int php_openssl_capture_peer_certs(php_stream *stream, for (i = 0; i < sk_X509_num(chain); i++) { X509 *mycert = X509_dup(sk_X509_value(chain, i)); - ZVAL_RES(&zcert, zend_register_resource(mycert, php_openssl_get_x509_list_id())); + + object_init_ex(&zcert, php_openssl_certificate_ce); + cert_object = Z_OPENSSL_CERTIFICATE_P(&zcert); + cert_object->x509 = mycert; add_next_index_zval(&arr, &zcert); } -- cgit v1.2.1