diff -Naur php-5.3.29_orig/ext/openssl/openssl.c php-5.4.16/ext/openssl/openssl.c
--- php-5.3.29_orig/ext/openssl/openssl.c	2014-08-14 01:22:50.000000000 +0600
+++ php-5.4.16/ext/openssl/openssl.c	2013-06-05 11:03:57.000000000 +0600
@@ -16,7 +16,7 @@
    |          Wez Furlong <wez@thebrainroom.com>                          |
    |          Sascha Kettler <kettler@gmx.net>                            |
    |          Pierre-Alain Joye <pierre@php.net>                          |
-   |          Marc Delling <delling@silpion.de> (PKCS12 functions)        |		
+   |          Marc Delling <delling@silpion.de> (PKCS12 functions)        |
    +----------------------------------------------------------------------+
  */
 
@@ -36,6 +36,10 @@
 #include "ext/standard/md5.h"
 #include "ext/standard/base64.h"
 
+#if PHP_WIN32
+# include "win32/winutil.h"
+#endif
+
 /* OpenSSL includes */
 #include <openssl/evp.h>
 #include <openssl/x509.h>
@@ -65,7 +69,13 @@
 #define OPENSSL_ALGO_MD2	4
 #endif
 #define OPENSSL_ALGO_DSS1	5
-
+#if OPENSSL_VERSION_NUMBER >= 0x0090708fL
+#define OPENSSL_ALGO_SHA224 6
+#define OPENSSL_ALGO_SHA256 7
+#define OPENSSL_ALGO_SHA384 8
+#define OPENSSL_ALGO_SHA512 9
+#define OPENSSL_ALGO_RMD160 10
+#endif
 #define DEBUG_SMIME	0
 
 /* FIXME: Use the openssl constants instead of
@@ -89,6 +99,9 @@
 	PHP_OPENSSL_CIPHER_RC2_64,
 	PHP_OPENSSL_CIPHER_DES,
 	PHP_OPENSSL_CIPHER_3DES,
+	PHP_OPENSSL_CIPHER_AES_128_CBC,
+	PHP_OPENSSL_CIPHER_AES_192_CBC,
+	PHP_OPENSSL_CIPHER_AES_256_CBC,
 
 	PHP_OPENSSL_CIPHER_DEFAULT = PHP_OPENSSL_CIPHER_RC2_40
 };
@@ -347,7 +360,7 @@
     ZEND_ARG_INFO(0, data)
     ZEND_ARG_INFO(0, method)
     ZEND_ARG_INFO(0, password)
-    ZEND_ARG_INFO(0, raw_output)
+    ZEND_ARG_INFO(0, options)
     ZEND_ARG_INFO(0, iv)
 ZEND_END_ARG_INFO()
 
@@ -355,7 +368,7 @@
     ZEND_ARG_INFO(0, data)
     ZEND_ARG_INFO(0, method)
     ZEND_ARG_INFO(0, password)
-    ZEND_ARG_INFO(0, raw_input)
+    ZEND_ARG_INFO(0, options)
     ZEND_ARG_INFO(0, iv)
 ZEND_END_ARG_INFO()
 
@@ -497,16 +510,13 @@
 }
 /* }}} */
 
-/* {{{ openssl safe_mode & open_basedir checks */
-inline static int php_openssl_safe_mode_chk(char *filename TSRMLS_DC)
+/* {{{ openssl open_basedir check */
+inline static int php_openssl_open_base_dir_chk(char *filename TSRMLS_DC)
 {
-	if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
-		return -1;
-	}
 	if (php_check_open_basedir(filename TSRMLS_CC)) {
 		return -1;
 	}
-	
+
 	return 0;
 }
 /* }}} */
@@ -536,6 +546,8 @@
 	int priv_key_encrypt;
 
 	EVP_PKEY * priv_key;
+
+    const EVP_CIPHER * priv_key_encrypt_cipher;
 };
 /* }}} */
 
@@ -563,7 +575,7 @@
 	} else {
 		subitem = val;
 	}
-	
+
 	for (i = 0; i < X509_NAME_entry_count(name); i++) {
 		unsigned char *to_add;
 		int to_add_len;
@@ -606,7 +618,7 @@
 			last = j;
 		}
 		i = last;
-		
+
 		if (obj_cnt > 1) {
 			add_assoc_zval_ex(subitem, sname, strlen(sname) + 1, subentries);
 		} else {
@@ -644,28 +656,18 @@
 	char * thestr;
 	long gmadjust = 0;
 
-	if (ASN1_STRING_type(timestr) != V_ASN1_UTCTIME) {
-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "illegal ASN1 data type for timestamp");
+	if (timestr->length < 13) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "extension author too lazy to parse %s correctly", timestr->data);
 		return (time_t)-1;
 	}
 
-	if (ASN1_STRING_length(timestr) != strlen((char*)ASN1_STRING_data(timestr))) {
-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "illegal length in timestamp");
-		return (time_t)-1;
-	}
-
-	if (ASN1_STRING_length(timestr) < 13) {
-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to parse time string %s correctly", timestr->data);
-		return (time_t)-1;
-	}
-
-	strbuf = estrdup((char *)ASN1_STRING_data(timestr));
+	strbuf = estrdup((char *)timestr->data);
 
 	memset(&thetime, 0, sizeof(thetime));
 
 	/* we work backwards so that we can use atoi more easily */
 
-	thestr = strbuf + ASN1_STRING_length(timestr) - 3;
+	thestr = strbuf + timestr->length - 3;
 
 	thetime.tm_sec = atoi(thestr);
 	*thestr = '\0';
@@ -716,7 +718,7 @@
 #endif
 {
 	X509V3_CTX ctx;
-	
+
 	X509V3_set_ctx_test(&ctx);
 	X509V3_set_conf_lhash(&ctx, config);
 	if (!X509V3_EXT_add_conf(config, &ctx, (char *)section, NULL)) {
@@ -765,17 +767,20 @@
 			req->config_filename, req->var, req->req_config TSRMLS_CC) == FAILURE) return FAILURE
 
 #define SET_OPTIONAL_STRING_ARG(key, varname, defval)	\
-	if (optional_args && zend_hash_find(Z_ARRVAL_P(optional_args), key, sizeof(key), (void**)&item) == SUCCESS && Z_TYPE_PP(item) == IS_STRING) \
+	if (optional_args && zend_hash_find(Z_ARRVAL_P(optional_args), key, sizeof(key), (void**)&item) == SUCCESS) \
 		varname = Z_STRVAL_PP(item); \
 	else \
 		varname = defval
 
 #define SET_OPTIONAL_LONG_ARG(key, varname, defval)	\
-	if (optional_args && zend_hash_find(Z_ARRVAL_P(optional_args), key, sizeof(key), (void**)&item) == SUCCESS && Z_TYPE_PP(item) == IS_LONG) \
+	if (optional_args && zend_hash_find(Z_ARRVAL_P(optional_args), key, sizeof(key), (void**)&item) == SUCCESS) \
 		varname = Z_LVAL_PP(item); \
 	else \
 		varname = defval
 
+static const EVP_CIPHER * php_openssl_get_evp_cipher_from_algo(long algo);
+
+
 static int php_openssl_parse_config(struct php_x509_request * req, zval * optional_args TSRMLS_DC) /* {{{ */
 {
 	char * str;
@@ -792,7 +797,7 @@
 
 	/* read in the oids */
 	str = CONF_get_string(req->req_config, NULL, "oid_file");
-	if (str && !php_openssl_safe_mode_chk(str TSRMLS_CC)) {
+	if (str && !php_openssl_open_base_dir_chk(str TSRMLS_CC)) {
 		BIO *oid_bio = BIO_new_file(str, "r");
 		if (oid_bio) {
 			OBJ_create_objects(oid_bio);
@@ -813,7 +818,7 @@
 
 	SET_OPTIONAL_LONG_ARG("private_key_type", req->priv_key_type, OPENSSL_KEYTYPE_DEFAULT);
 
-	if (optional_args && zend_hash_find(Z_ARRVAL_P(optional_args), "encrypt_key", sizeof("encrypt_key"), (void**)&item) == SUCCESS && Z_TYPE_PP(item) == IS_BOOL) {
+	if (optional_args && zend_hash_find(Z_ARRVAL_P(optional_args), "encrypt_key", sizeof("encrypt_key"), (void**)&item) == SUCCESS) {
 		req->priv_key_encrypt = Z_BVAL_PP(item);
 	} else {
 		str = CONF_get_string(req->req_config, req->section_name, "encrypt_rsa_key");
@@ -826,7 +831,22 @@
 			req->priv_key_encrypt = 1;
 		}
 	}
-	
+
+	if (req->priv_key_encrypt && optional_args && zend_hash_find(Z_ARRVAL_P(optional_args), "encrypt_key_cipher", sizeof("encrypt_key_cipher"), (void**)&item) == SUCCESS) {
+		long cipher_algo = Z_LVAL_PP(item);
+		const EVP_CIPHER* cipher = php_openssl_get_evp_cipher_from_algo(cipher_algo);
+		if (cipher == NULL) {
+			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown cipher algorithm for private key.");
+			return FAILURE;
+		} else  {
+			req->priv_key_encrypt_cipher = cipher;
+		}
+	} else {
+		req->priv_key_encrypt_cipher = NULL;
+	}
+
+
+
 	/* digest alg */
 	if (req->digest_name == NULL) {
 		req->digest_name = CONF_get_string(req->req_config, req->section_name, "default_md");
@@ -848,7 +868,7 @@
 	}
 
 	PHP_SSL_CONFIG_SYNTAX_CHECK(request_extensions_section);
-	
+
 	return SUCCESS;
 }
 /* }}} */
@@ -870,12 +890,10 @@
 }
 /* }}} */
 
-static int php_openssl_load_rand_file(const char * file, int *egdsocket, int *seeded) /* {{{ */
+static int php_openssl_load_rand_file(const char * file, int *egdsocket, int *seeded TSRMLS_DC) /* {{{ */
 {
 	char buffer[MAXPATHLEN];
 
-	TSRMLS_FETCH();
-
 	*egdsocket = 0;
 	*seeded = 0;
 
@@ -942,6 +960,23 @@
 		case OPENSSL_ALGO_DSS1:
 			mdtype = (EVP_MD *) EVP_dss1();
 			break;
+#if OPENSSL_VERSION_NUMBER >= 0x0090708fL
+		case OPENSSL_ALGO_SHA224:
+			mdtype = (EVP_MD *) EVP_sha224();
+			break;
+		case OPENSSL_ALGO_SHA256:
+			mdtype = (EVP_MD *) EVP_sha256();
+			break;
+		case OPENSSL_ALGO_SHA384:
+			mdtype = (EVP_MD *) EVP_sha384();
+			break;
+		case OPENSSL_ALGO_SHA512:
+			mdtype = (EVP_MD *) EVP_sha512();
+			break;
+		case OPENSSL_ALGO_RMD160:
+			mdtype = (EVP_MD *) EVP_ripemd160();
+			break;
+#endif
 		default:
 			return NULL;
 			break;
@@ -972,6 +1007,20 @@
 			return EVP_des_ede3_cbc();
 			break;
 #endif
+
+#ifndef OPENSSL_NO_AES
+		case PHP_OPENSSL_CIPHER_AES_128_CBC:
+			return EVP_aes_128_cbc();
+			break;
+		case PHP_OPENSSL_CIPHER_AES_192_CBC:
+			return EVP_aes_192_cbc();
+			break;
+		case PHP_OPENSSL_CIPHER_AES_256_CBC:
+			return EVP_aes_256_cbc();
+			break;
+#endif
+
+
 		default:
 			return NULL;
 			break;
@@ -994,17 +1043,15 @@
 	OpenSSL_add_all_digests();
 	OpenSSL_add_all_algorithms();
 
-	ERR_load_ERR_strings();
-	ERR_load_crypto_strings();
-	ERR_load_EVP_strings();
+	SSL_load_error_strings();
 
 	/* register a resource id number with OpenSSL so that we can map SSL -> stream structures in
 	 * OpenSSL callbacks */
 	ssl_stream_data_index = SSL_get_ex_new_index(0, "PHP stream index", NULL, NULL, NULL);
-	
+
 	REGISTER_STRING_CONSTANT("OPENSSL_VERSION_TEXT", OPENSSL_VERSION_TEXT, CONST_CS|CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("OPENSSL_VERSION_NUMBER", OPENSSL_VERSION_NUMBER, CONST_CS|CONST_PERSISTENT);
-	
+
 	/* purposes for cert purpose checking */
 	REGISTER_LONG_CONSTANT("X509_PURPOSE_SSL_CLIENT", X509_PURPOSE_SSL_CLIENT, CONST_CS|CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("X509_PURPOSE_SSL_SERVER", X509_PURPOSE_SSL_SERVER, CONST_CS|CONST_PERSISTENT);
@@ -1024,6 +1071,13 @@
 	REGISTER_LONG_CONSTANT("OPENSSL_ALGO_MD2", OPENSSL_ALGO_MD2, CONST_CS|CONST_PERSISTENT);
 #endif
 	REGISTER_LONG_CONSTANT("OPENSSL_ALGO_DSS1", OPENSSL_ALGO_DSS1, CONST_CS|CONST_PERSISTENT);
+#if OPENSSL_VERSION_NUMBER >= 0x0090708fL
+	REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA224", OPENSSL_ALGO_SHA224, CONST_CS|CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA256", OPENSSL_ALGO_SHA256, CONST_CS|CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA384", OPENSSL_ALGO_SHA384, CONST_CS|CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA512", OPENSSL_ALGO_SHA512, CONST_CS|CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("OPENSSL_ALGO_RMD160", OPENSSL_ALGO_RMD160, CONST_CS|CONST_PERSISTENT);
+#endif
 
 	/* flags for S/MIME */
 	REGISTER_LONG_CONSTANT("PKCS7_DETACHED", PKCS7_DETACHED, CONST_CS|CONST_PERSISTENT);
@@ -1051,6 +1105,11 @@
 	REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_DES", PHP_OPENSSL_CIPHER_DES, CONST_CS|CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_3DES", PHP_OPENSSL_CIPHER_3DES, CONST_CS|CONST_PERSISTENT);
 #endif
+#ifndef OPENSSL_NO_AES
+	REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_AES_128_CBC", PHP_OPENSSL_CIPHER_AES_128_CBC, CONST_CS|CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_AES_192_CBC", PHP_OPENSSL_CIPHER_AES_192_CBC, CONST_CS|CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_AES_256_CBC", PHP_OPENSSL_CIPHER_AES_256_CBC, CONST_CS|CONST_PERSISTENT);
+#endif
 
 	/* Values for key types */
 	REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_RSA", OPENSSL_KEYTYPE_RSA, CONST_CS|CONST_PERSISTENT);
@@ -1062,6 +1121,9 @@
 	REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_EC", OPENSSL_KEYTYPE_EC, CONST_CS|CONST_PERSISTENT);
 #endif
 
+	REGISTER_LONG_CONSTANT("OPENSSL_RAW_DATA", OPENSSL_RAW_DATA, CONST_CS|CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("OPENSSL_ZERO_PADDING", OPENSSL_ZERO_PADDING, CONST_CS|CONST_PERSISTENT);
+
 #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
 	/* SNI support included in OpenSSL >= 0.9.8j */
 	REGISTER_LONG_CONSTANT("OPENSSL_TLSEXT_SERVER_NAME", 1, CONST_CS|CONST_PERSISTENT);
@@ -1094,7 +1156,7 @@
 
 	php_register_url_stream_wrapper("https", &php_stream_http_wrapper TSRMLS_CC);
 	php_register_url_stream_wrapper("ftps", &php_stream_ftp_wrapper TSRMLS_CC);
-	
+
 	return SUCCESS;
 }
 /* }}} */
@@ -1184,7 +1246,7 @@
 		/* read cert from the named file */
 		BIO *in;
 
-		if (php_openssl_safe_mode_chk(Z_STRVAL_PP(val) + (sizeof("file://") - 1) TSRMLS_CC)) {
+		if (php_openssl_open_base_dir_chk(Z_STRVAL_PP(val) + (sizeof("file://") - 1) TSRMLS_CC)) {
 			return NULL;
 		}
 
@@ -1210,7 +1272,7 @@
 	}
 
 	if (cert && makeresource && resourceval) {
-		*resourceval = zend_list_insert(cert, le_x509);
+		*resourceval = zend_list_insert(cert, le_x509 TSRMLS_CC);
 	}
 	return cert;
 }
@@ -1229,7 +1291,7 @@
 	char * filename;
 	int filename_len;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zs|b", &zcert, &filename, &filename_len, &notext) == FAILURE) {
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zp|b", &zcert, &filename, &filename_len, &notext) == FAILURE) {
 		return;
 	}
 	RETVAL_FALSE;
@@ -1240,7 +1302,7 @@
 		return;
 	}
 
-	if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) {
+	if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
 		return;
 	}
 
@@ -1314,14 +1376,14 @@
 	long certresource = -1, keyresource = -1;
 
 	RETVAL_FALSE;
-	
+
 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &zcert, &zkey) == FAILURE) {
 		return;
 	}
 	cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
 	if (cert == NULL) {
 		RETURN_FALSE;
-	}	
+	}
 	key = php_openssl_evp_from_zval(zkey, 0, "", 1, &keyresource TSRMLS_CC);
 	if (key) {
 		RETVAL_BOOL(X509_check_private_key(cert, key));
@@ -1336,74 +1398,6 @@
 }
 /* }}} */
 
-/* Special handling of subjectAltName, see CVE-2013-4073
- * Christian Heimes
- */
-
-static int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension)
-{
-	GENERAL_NAMES *names;
-	const X509V3_EXT_METHOD *method = NULL;
-	long i, length, num;
-	const unsigned char *p;
-
-	method = X509V3_EXT_get(extension);
-	if (method == NULL) {
-		return -1;
-	}
-
-	p = extension->value->data;
-	length = extension->value->length;
-	if (method->it) {
-		names = (GENERAL_NAMES*)(ASN1_item_d2i(NULL, &p, length,
-						       ASN1_ITEM_ptr(method->it)));
-	} else {
-		names = (GENERAL_NAMES*)(method->d2i(NULL, &p, length));
-	}
-	if (names == NULL) {
-		return -1;
-	}
-
-	num = sk_GENERAL_NAME_num(names);
-	for (i = 0; i < num; i++) {
-			GENERAL_NAME *name;
-			ASN1_STRING *as;
-			name = sk_GENERAL_NAME_value(names, i);
-			switch (name->type) {
-				case GEN_EMAIL:
-					BIO_puts(bio, "email:");
-					as = name->d.rfc822Name;
-					BIO_write(bio, ASN1_STRING_data(as),
-						  ASN1_STRING_length(as));
-					break;
-				case GEN_DNS:
-					BIO_puts(bio, "DNS:");
-					as = name->d.dNSName;
-					BIO_write(bio, ASN1_STRING_data(as),
-						  ASN1_STRING_length(as));
-					break;
-				case GEN_URI:
-					BIO_puts(bio, "URI:");
-					as = name->d.uniformResourceIdentifier;
-					BIO_write(bio, ASN1_STRING_data(as),
-						  ASN1_STRING_length(as));
-					break;
-				default:
-					/* use builtin print for GEN_OTHERNAME, GEN_X400,
-					 * GEN_EDIPARTY, GEN_DIRNAME, GEN_IPADD and GEN_RID
-					 */
-					GENERAL_NAME_print(bio, name);
-			}
-			/* trailing ', ' except for last element */
-			if (i < (num - 1)) {
-				BIO_puts(bio, ", ");
-			}
-	}
-	sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
-
-	return 0;
-}
-
 /* {{{ proto array openssl_x509_parse(mixed x509 [, bool shortnames=true])
    Returns an array of the fields/values of the CERT */
 PHP_FUNCTION(openssl_x509_parse)
@@ -1442,11 +1436,11 @@
 		snprintf(buf, sizeof(buf), "%08lx", X509_subject_name_hash(cert));
 		add_assoc_string(return_value, "hash", buf, 1);
 	}
-	
+
 	add_assoc_name_entry(return_value, "issuer", 		X509_get_issuer_name(cert), useshortnames TSRMLS_CC);
 	add_assoc_long(return_value, "version", 			X509_get_version(cert));
 
-	add_assoc_string(return_value, "serialNumber", i2s_ASN1_INTEGER(NULL, X509_get_serialNumber(cert)), 1); 
+	add_assoc_string(return_value, "serialNumber", i2s_ASN1_INTEGER(NULL, X509_get_serialNumber(cert)), 1);
 
 	add_assoc_asn1_string(return_value, "validFrom", 	X509_get_notBefore(cert));
 	add_assoc_asn1_string(return_value, "validTo", 		X509_get_notAfter(cert));
@@ -1500,30 +1494,15 @@
 
 
 	for (i = 0; i < X509_get_ext_count(cert); i++) {
-		int nid;
 		extension = X509_get_ext(cert, i);
-		nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension));
-		if (nid != NID_undef) {
+		if (OBJ_obj2nid(X509_EXTENSION_get_object(extension)) != NID_undef) {
 			extname = (char *)OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(extension)));
 		} else {
 			OBJ_obj2txt(buf, sizeof(buf)-1, X509_EXTENSION_get_object(extension), 1);
 			extname = buf;
 		}
 		bio_out = BIO_new(BIO_s_mem());
-		if (nid == NID_subject_alt_name) {
-			if (openssl_x509v3_subjectAltName(bio_out, extension) == 0) {
-				BIO_get_mem_ptr(bio_out, &bio_buf);
-				add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1);
-			} else {
-				zval_dtor(return_value);
-				if (certresource == -1 && cert) {
-					X509_free(cert);
-				}
-				BIO_free(bio_out);
-				RETURN_FALSE;
-			}
-		}
-		else if (X509V3_EXT_print(bio_out, extension, 0, 0)) {
+		if (X509V3_EXT_print(bio_out, extension, 0, 0)) {
 			BIO_get_mem_ptr(bio_out, &bio_buf);
 			add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1);
 		} else {
@@ -1553,7 +1532,7 @@
 		goto end;
 	}
 
-	if (php_openssl_safe_mode_chk(certfile TSRMLS_CC)) {
+	if (php_openssl_open_base_dir_chk(certfile TSRMLS_CC)) {
 		sk_X509_free(stack);
 		goto end;
 	}
@@ -1663,8 +1642,8 @@
 	if (certresource == 1 && cert) {
 		X509_free(cert);
 	}
-	if (cainfo) { 
-		X509_STORE_free(cainfo); 
+	if (cainfo) {
+		X509_STORE_free(cainfo);
 	}
 	if (untrustedchain) {
 		sk_X509_pop_free(untrustedchain, X509_free);
@@ -1717,7 +1696,7 @@
 				dir_lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
 				if (dir_lookup == NULL || !X509_LOOKUP_add_dir(dir_lookup, Z_STRVAL_PP(item), X509_FILETYPE_PEM)) {
 					php_error_docref(NULL TSRMLS_CC, E_WARNING, "error loading directory %s", Z_STRVAL_PP(item));
-				} else { 
+				} else {
 					ndirs++;
 				}
 				dir_lookup = NULL;
@@ -1811,11 +1790,11 @@
 
 			if (certresource != -1) {
 				cert = X509_dup(cert);
-				
+
 				if (cert == NULL) {
 					goto clean_exit;
 				}
-				
+
 			}
 			sk_X509_push(sk, cert);
 
@@ -1824,7 +1803,7 @@
 	} else {
 		/* a single certificate */
 		cert = php_openssl_x509_from_zval(zcerts, 0, &certresource TSRMLS_CC);
-		
+
 		if (cert == NULL) {
 			goto clean_exit;
 		}
@@ -1861,15 +1840,11 @@
 	zval ** item;
 	STACK_OF(X509) *ca = NULL;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zszs|a", &zcert, &filename, &filename_len, &zpkey, &pass, &pass_len, &args) == FAILURE)
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zpzs|a", &zcert, &filename, &filename_len, &zpkey, &pass, &pass_len, &args) == FAILURE)
 		return;
 
 	RETVAL_FALSE;
 
-	if (strlen(filename) != filename_len) {
-		return;
-	}
-	
 	cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
 	if (cert == NULL) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
@@ -1884,12 +1859,12 @@
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key does not correspond to cert");
 		goto cleanup;
 	}
-	if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) {
+	if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
 		goto cleanup;
 	}
 
 	/* parse extra config from args array, promote this to an extra function */
-	if (args && zend_hash_find(Z_ARRVAL_P(args), "friendly_name", sizeof("friendly_name"), (void**)&item) == SUCCESS && Z_TYPE_PP(item) == IS_STRING)
+	if (args && zend_hash_find(Z_ARRVAL_P(args), "friendly_name", sizeof("friendly_name"), (void**)&item) == SUCCESS)
 		friendly_name = Z_STRVAL_PP(item);
 	/* certpbe (default RC2-40)
 	   keypbe (default 3DES)
@@ -1905,9 +1880,9 @@
 
 	p12 = PKCS12_create(pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0);
 
-	bio_out = BIO_new_file(filename, "w"); 
+	bio_out = BIO_new_file(filename, "w");
 	if (bio_out) {
-		
+
 		i2d_PKCS12_bio(bio_out, p12);
 
 		RETVAL_TRUE;
@@ -1918,13 +1893,13 @@
 	BIO_free(bio_out);
 	PKCS12_free(p12);
 	php_sk_X509_free(ca);
-	
+
 cleanup:
 
 	if (keyresource == -1 && priv_key) {
 		EVP_PKEY_free(priv_key);
 	}
-	if (certresource == -1 && cert) { 
+	if (certresource == -1 && cert) {
 		X509_free(cert);
 	}
 }
@@ -1950,7 +1925,7 @@
 		return;
 
 	RETVAL_FALSE;
-	
+
 	cert = php_openssl_x509_from_zval(&zcert, 0, &certresource TSRMLS_CC);
 	if (cert == NULL) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
@@ -1967,13 +1942,13 @@
 	}
 
 	/* parse extra config from args array, promote this to an extra function */
-	if (args && zend_hash_find(Z_ARRVAL_P(args), "friendly_name", sizeof("friendly_name"), (void**)&item) == SUCCESS && Z_TYPE_PP(item) == IS_STRING)
+	if (args && zend_hash_find(Z_ARRVAL_P(args), "friendly_name", sizeof("friendly_name"), (void**)&item) == SUCCESS)
 		friendly_name = Z_STRVAL_PP(item);
 
 	if (args && zend_hash_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts"), (void**)&item) == SUCCESS)
 		ca = php_array_to_X509_sk(item TSRMLS_CC);
 	/* end parse extra config */
-	
+
 	p12 = PKCS12_create(pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0);
 
 	bio_out = BIO_new(BIO_s_mem());
@@ -1990,13 +1965,13 @@
 	BIO_free(bio_out);
 	PKCS12_free(p12);
 	php_sk_X509_free(ca);
-	
+
 cleanup:
 
 	if (keyresource == -1 && priv_key) {
 		EVP_PKEY_free(priv_key);
 	}
-	if (certresource == -1 && cert) { 
+	if (certresource == -1 && cert) {
 		X509_free(cert);
 	}
 }
@@ -2020,12 +1995,12 @@
 		return;
 
 	RETVAL_FALSE;
-	
+
 	bio_in = BIO_new(BIO_s_mem());
-	
+
 	if(!BIO_write(bio_in, zp12, zp12_len))
 		goto cleanup;
-	
+
 	if(d2i_PKCS12_bio(bio_in, &p12)) {
 		if(PKCS12_parse(p12, pass, &pkey, &cert, &ca)) {
 			BIO * bio_out;
@@ -2055,12 +2030,12 @@
 
 			MAKE_STD_ZVAL(zextracerts);
 			array_init(zextracerts);
-			
+
 			for (i=0;;i++) {
 				zval * zextracert;
 				X509* aCA = sk_X509_pop(ca);
 				if (!aCA) break;
-				
+
 				bio_out = BIO_new(BIO_s_mem());
 				if (PEM_write_bio_X509(bio_out, aCA)) {
 					BUF_MEM *bio_buf;
@@ -2068,7 +2043,7 @@
 					MAKE_STD_ZVAL(zextracert);
 					ZVAL_STRINGL(zextracert, bio_buf->data, bio_buf->length, 1);
 					add_index_zval(zextracerts, i, zextracert);
-					
+
 				}
 				BIO_free(bio_out);
 
@@ -2080,13 +2055,13 @@
 			} else {
 				zval_dtor(zextracerts);
 			}
-			
+
 			RETVAL_TRUE;
-			
+
 			PKCS12_free(p12);
 		}
 	}
-	
+
   cleanup:
 	if (bio_in) {
 		BIO_free(bio_in);
@@ -2094,7 +2069,7 @@
 	if (pkey) {
 		EVP_PKEY_free(pkey);
 	}
-	if (cert) { 
+	if (cert) {
 		X509_free(cert);
 	}
 }
@@ -2113,7 +2088,7 @@
 		return FAILURE;
 	}
 	dn_sk = CONF_get_section(req->req_config, dn_sect);
-	if (dn_sk == NULL) { 
+	if (dn_sk == NULL) {
 		return FAILURE;
 	}
 	attr_sect = CONF_get_string(req->req_config, req->section_name, "attributes");
@@ -2133,15 +2108,15 @@
 		X509_NAME * subj;
 		HashPosition hpos;
 		zval ** item;
-		
+
 		subj = X509_REQ_get_subject_name(csr);
 		/* apply values from the dn hash */
 		zend_hash_internal_pointer_reset_ex(HASH_OF(dn), &hpos);
 		while(zend_hash_get_current_data_ex(HASH_OF(dn), (void**)&item, &hpos) == SUCCESS) {
-			char * strindex = NULL; 
+			char * strindex = NULL;
 			uint strindexlen = 0;
 			ulong intindex;
-			
+
 			zend_hash_get_current_key_ex(HASH_OF(dn), &strindex, &strindexlen, &intindex, 0, &hpos);
 
 			convert_to_string_ex(item);
@@ -2151,10 +2126,14 @@
 
 				nid = OBJ_txt2nid(strindex);
 				if (nid != NID_undef) {
-					if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_ASC, 
+					if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_UTF8,
 								(unsigned char*)Z_STRVAL_PP(item), -1, -1, 0))
 					{
-						php_error_docref(NULL TSRMLS_CC, E_WARNING, "dn: add_entry_by_NID %d -> %s (failed)", nid, Z_STRVAL_PP(item));
+						php_error_docref(NULL TSRMLS_CC, E_WARNING,
+							"dn: add_entry_by_NID %d -> %s (failed; check error"
+							" queue and value of string_mask OpenSSL option "
+							"if illegal characters are reported)",
+							nid, Z_STRVAL_PP(item));
 						return FAILURE;
 					}
 				} else {
@@ -2168,10 +2147,10 @@
 		for(i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
 			int len;
 			char buffer[200 + 1]; /*200 + \0 !*/
-			
+
 			v = sk_CONF_VALUE_value(dn_sk, i);
 			type = v->name;
-			
+
 			len = strlen(type);
 			if (len < sizeof("_default")) {
 				continue;
@@ -2186,7 +2165,7 @@
 			memcpy(buffer, type, len);
 			buffer[len] = '\0';
 			type = buffer;
-		
+
 			/* Skip past any leading X. X: X, etc to allow for multiple
 			 * instances */
 			for (str = type; *str; str++) {
@@ -2203,7 +2182,7 @@
 			if (X509_NAME_get_index_by_NID(subj, nid, -1) >= 0) {
 				continue;
 			}
-			if (!X509_NAME_add_entry_by_txt(subj, type, MBSTRING_ASC, (unsigned char*)v->value, -1, -1, 0)) {
+			if (!X509_NAME_add_entry_by_txt(subj, type, MBSTRING_UTF8, (unsigned char*)v->value, -1, -1, 0)) {
 				php_error_docref(NULL TSRMLS_CC, E_WARNING, "add_entry_by_txt %s -> %s (failed)", type, v->value);
 				return FAILURE;
 			}
@@ -2227,7 +2206,7 @@
 
 					nid = OBJ_txt2nid(strindex);
 					if (nid != NID_undef) {
-						if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_ASC, (unsigned char*)Z_STRVAL_PP(item), -1, -1, 0)) {
+						if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_UTF8, (unsigned char*)Z_STRVAL_PP(item), -1, -1, 0)) {
 							php_error_docref(NULL TSRMLS_CC, E_WARNING, "attribs: add_entry_by_NID %d -> %s (failed)", nid, Z_STRVAL_PP(item));
 							return FAILURE;
 						}
@@ -2244,8 +2223,12 @@
 				if (X509_REQ_get_attr_by_NID(csr, nid, -1) >= 0) {
 					continue;
 				}
-				if (!X509_REQ_add1_attr_by_txt(csr, v->name, MBSTRING_ASC, (unsigned char*)v->value, -1)) {
-					php_error_docref(NULL TSRMLS_CC, E_WARNING, "add1_attr_by_txt %s -> %s (failed)", v->name, v->value);
+				if (!X509_REQ_add1_attr_by_txt(csr, v->name, MBSTRING_UTF8, (unsigned char*)v->value, -1)) {
+					php_error_docref(NULL TSRMLS_CC, E_WARNING,
+						"add1_attr_by_txt %s -> %s (failed; check error queue "
+						"and value of string_mask OpenSSL option if illegal "
+						"characters are reported)",
+						v->name, v->value);
 					return FAILURE;
 				}
 			}
@@ -2263,7 +2246,7 @@
 	X509_REQ * csr = NULL;
 	char * filename = NULL;
 	BIO * in;
-	
+
 	if (resourceval) {
 		*resourceval = -1;
 	}
@@ -2287,7 +2270,7 @@
 		filename = Z_STRVAL_PP(val) + (sizeof("file://") - 1);
 	}
 	if (filename) {
-		if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) {
+		if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
 			return NULL;
 		}
 		in = BIO_new_file(filename, "r");
@@ -2312,22 +2295,18 @@
 	BIO * bio_out;
 	long csr_resource;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|b", &zcsr, &filename, &filename_len, &notext) == FAILURE) {
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rp|b", &zcsr, &filename, &filename_len, &notext) == FAILURE) {
 		return;
 	}
 	RETVAL_FALSE;
 
-	if (strlen(filename) != filename_len) {
-		return;
-	}
-
 	csr = php_openssl_csr_from_zval(&zcsr, 0, &csr_resource TSRMLS_CC);
 	if (csr == NULL) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get CSR from parameter 1");
 		return;
 	}
 
-	if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) {
+	if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
 		return;
 	}
 
@@ -2408,13 +2387,13 @@
 	long csr_resource, certresource = 0, keyresource = -1;
 	int i;
 	struct php_x509_request req;
-	
+
 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ!Zl|a!l", &zcsr, &zcert, &zpkey, &num_days, &args, &serial) == FAILURE)
 		return;
 
 	RETVAL_FALSE;
 	PHP_SSL_REQ_INIT(&req);
-	
+
 	csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource TSRMLS_CC);
 	if (csr == NULL) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get CSR from parameter 1");
@@ -2436,7 +2415,7 @@
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key does not correspond to signing cert");
 		goto cleanup;
 	}
-	
+
 	if (PHP_SSL_REQ_PARSE(&req, args) == FAILURE) {
 		goto cleanup;
 	}
@@ -2456,9 +2435,9 @@
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Signature did not match the certificate request");
 		goto cleanup;
 	}
-	
+
 	/* Now we can get on with it */
-	
+
 	new_cert = X509_new();
 	if (new_cert == NULL) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "No memory");
@@ -2469,7 +2448,7 @@
 		goto cleanup;
 
 	ASN1_INTEGER_set(X509_get_serialNumber(new_cert), serial);
-	
+
 	X509_set_subject_name(new_cert, X509_REQ_get_subject_name(csr));
 
 	if (cert == NULL) {
@@ -2486,7 +2465,7 @@
 	}
 	if (req.extensions_section) {
 		X509V3_CTX ctx;
-		
+
 		X509V3_set_ctx(&ctx, cert, new_cert, csr, NULL, 0);
 		X509V3_set_conf_lhash(&ctx, req.req_config);
 		if (!X509V3_EXT_add_conf(req.req_config, &ctx, req.extensions_section, new_cert)) {
@@ -2499,11 +2478,11 @@
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to sign it");
 		goto cleanup;
 	}
-	
+
 	/* Succeeded; lets return the cert */
-	RETVAL_RESOURCE(zend_list_insert(new_cert, le_x509));
+	RETVAL_RESOURCE(zend_list_insert(new_cert, le_x509 TSRMLS_CC));
 	new_cert = NULL;
-	
+
 cleanup:
 
 	if (cert == new_cert) {
@@ -2520,7 +2499,7 @@
 	if (csr_resource == -1 && csr) {
 		X509_REQ_free(csr);
 	}
-	if (certresource == -1 && cert) { 
+	if (certresource == -1 && cert) {
 		X509_free(cert);
 	}
 	if (new_cert) {
@@ -2539,12 +2518,12 @@
 	X509_REQ * csr = NULL;
 	int we_made_the_key = 1;
 	long key_resource;
-	
+
 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az|a!a!", &dn, &out_pkey, &args, &attribs) == FAILURE) {
 		return;
 	}
 	RETVAL_FALSE;
-	
+
 	PHP_SSL_REQ_INIT(&req);
 
 	if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {
@@ -2576,10 +2555,10 @@
 						php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error loading extension section %s", req.request_extensions_section);
 					} else {
 						RETVAL_TRUE;
-						
+
 						if (X509_REQ_sign(csr, req.priv_key, req.digest)) {
-							RETVAL_RESOURCE(zend_list_insert(csr, le_csr));
-							csr = NULL;			
+							RETVAL_RESOURCE(zend_list_insert(csr, le_csr TSRMLS_CC));
+							csr = NULL;
 						} else {
 							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error signing request");
 						}
@@ -2587,7 +2566,7 @@
 						if (we_made_the_key) {
 							/* and a resource for the private key */
 							zval_dtor(out_pkey);
-							ZVAL_RESOURCE(out_pkey, zend_list_insert(req.priv_key, le_key));
+							ZVAL_RESOURCE(out_pkey, zend_list_insert(req.priv_key, le_key TSRMLS_CC));
 							req.priv_key = NULL; /* make sure the cleanup code doesn't zap it! */
 						} else if (key_resource != -1) {
 							req.priv_key = NULL; /* make sure the cleanup code doesn't zap it! */
@@ -2660,7 +2639,7 @@
 	}
 
 	tpubkey=X509_REQ_get_pubkey(csr);
-	RETVAL_RESOURCE(zend_list_insert(tpubkey, le_key));
+	RETVAL_RESOURCE(zend_list_insert(tpubkey, le_key TSRMLS_CC));
 	return;
 }
 /* }}} */
@@ -2704,14 +2683,14 @@
 	}
 	if (Z_TYPE_PP(val) == IS_ARRAY) {
 		zval ** zphrase;
-		
+
 		/* get passphrase */
 
 		if (zend_hash_index_find(HASH_OF(*val), 1, (void **)&zphrase) == FAILURE) {
 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "key array must be of the form array(0 => key, 1 => phrase)");
 			return NULL;
 		}
-		
+
 		if (Z_TYPE_PP(zphrase) == IS_STRING) {
 			passphrase = Z_STRVAL_PP(zphrase);
 		} else {
@@ -2736,7 +2715,7 @@
 		if (!what) {
 			TMP_CLEAN;
 		}
-		if (resourceval) { 
+		if (resourceval) {
 			*resourceval = Z_LVAL_PP(val);
 		}
 		if (type == le_x509) {
@@ -2770,8 +2749,8 @@
 		}
 	} else {
 		/* force it to be a string and check if it refers to a file */
-		/* passing non string values leaks, object uses toString, it returns NULL 
-		 * See bug38255.phpt 
+		/* passing non string values leaks, object uses toString, it returns NULL
+		 * See bug38255.phpt
 		 */
 		if (!(Z_TYPE_PP(val) == IS_STRING || Z_TYPE_PP(val) == IS_OBJECT)) {
 			TMP_CLEAN;
@@ -2805,7 +2784,7 @@
 			BIO *in;
 
 			if (filename) {
-				if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) {
+				if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
 					TMP_CLEAN;
 				}
 				in = BIO_new_file(filename, "r");
@@ -2845,7 +2824,7 @@
 	char * randfile = NULL;
 	int egdsocket, seeded;
 	EVP_PKEY * return_val = NULL;
-	
+
 	if (req->priv_key_bits < MIN_KEY_LENGTH) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key length is too short; it needs to be at least %d bits, not %d",
 				MIN_KEY_LENGTH, req->priv_key_bits);
@@ -2853,8 +2832,8 @@
 	}
 
 	randfile = CONF_get_string(req->req_config, req->section_name, "RANDFILE");
-	php_openssl_load_rand_file(randfile, &egdsocket, &seeded);
-	
+	php_openssl_load_rand_file(randfile, &egdsocket, &seeded TSRMLS_CC);
+
 	if ((req->priv_key = EVP_PKEY_new()) != NULL) {
 		switch(req->priv_key_type) {
 			case OPENSSL_KEYTYPE_RSA:
@@ -2904,13 +2883,13 @@
 	}
 
 	php_openssl_write_rand_file(randfile, egdsocket, seeded);
-	
+
 	if (return_val == NULL) {
 		EVP_PKEY_free(req->priv_key);
 		req->priv_key = NULL;
 		return NULL;
 	}
-	
+
 	return return_val;
 }
 /* }}} */
@@ -2939,7 +2918,7 @@
 		case EVP_PKEY_DSA4:
 			assert(pkey->pkey.dsa != NULL);
 
-			if (NULL == pkey->pkey.dsa->p || NULL == pkey->pkey.dsa->q || NULL == pkey->pkey.dsa->priv_key){ 
+			if (NULL == pkey->pkey.dsa->p || NULL == pkey->pkey.dsa->q || NULL == pkey->pkey.dsa->priv_key){
 				return 0;
 			}
 			break;
@@ -3014,7 +2993,7 @@
 					OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, iqmp);
 					if (rsa->n && rsa->d) {
 						if (EVP_PKEY_assign_RSA(pkey, rsa)) {
-							RETURN_RESOURCE(zend_list_insert(pkey, le_key));
+							RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
 						}
 					}
 					RSA_free(rsa);
@@ -3038,7 +3017,7 @@
 							DSA_generate_key(dsa);
 						}
 						if (EVP_PKEY_assign_DSA(pkey, dsa)) {
-							RETURN_RESOURCE(zend_list_insert(pkey, le_key));
+							RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
 						}
 					}
 					DSA_free(dsa);
@@ -3061,7 +3040,7 @@
 							DH_generate_key(dh);
 						}
 						if (EVP_PKEY_assign_DH(pkey, dh)) {
-							RETURN_RESOURCE(zend_list_insert(pkey, le_key));
+							RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
 						}
 					}
 					DH_free(dh);
@@ -3070,7 +3049,7 @@
 			}
 			RETURN_FALSE;
 		}
-	} 
+	}
 
 	PHP_SSL_REQ_INIT(&req);
 
@@ -3078,7 +3057,7 @@
 	{
 		if (php_openssl_generate_private_key(&req TSRMLS_CC)) {
 			/* pass back a key resource */
-			RETVAL_RESOURCE(zend_list_insert(req.priv_key, le_key));
+			RETVAL_RESOURCE(zend_list_insert(req.priv_key, le_key TSRMLS_CC));
 			/* make sure the cleanup code doesn't zap it! */
 			req.priv_key = NULL;
 		}
@@ -3099,15 +3078,11 @@
 	EVP_PKEY * key;
 	BIO * bio_out = NULL;
 	const EVP_CIPHER * cipher;
-	
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zs|s!a!", &zpkey, &filename, &filename_len, &passphrase, &passphrase_len, &args) == FAILURE) {
-		return;
-	}
-	RETVAL_FALSE;
 
-	if (strlen(filename) != filename_len) {
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zp|s!a!", &zpkey, &filename, &filename_len, &passphrase, &passphrase_len, &args) == FAILURE) {
 		return;
 	}
+	RETVAL_FALSE;
 
 	key = php_openssl_evp_from_zval(zpkey, 0, passphrase, 0, &key_resource TSRMLS_CC);
 
@@ -3115,18 +3090,22 @@
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get key from parameter 1");
 		RETURN_FALSE;
 	}
-	
-	if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) {
+
+	if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
 		RETURN_FALSE;
 	}
-	
+
 	PHP_SSL_REQ_INIT(&req);
 
 	if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {
 		bio_out = BIO_new_file(filename, "w");
 
 		if (passphrase && req.priv_key_encrypt) {
-			cipher = (EVP_CIPHER *) EVP_des_ede3_cbc();
+			if (req.priv_key_encrypt_cipher) {
+				cipher = req.priv_key_encrypt_cipher;
+			} else {
+				cipher = (EVP_CIPHER *) EVP_des_ede3_cbc();
+			}
 		} else {
 			cipher = NULL;
 		}
@@ -3158,7 +3137,7 @@
 	EVP_PKEY * key;
 	BIO * bio_out = NULL;
 	const EVP_CIPHER * cipher;
-	
+
 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zz|s!a!", &zpkey, &out, &passphrase, &passphrase_len, &args) == FAILURE) {
 		return;
 	}
@@ -3170,14 +3149,18 @@
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get key from parameter 1");
 		RETURN_FALSE;
 	}
-	
+
 	PHP_SSL_REQ_INIT(&req);
 
 	if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {
 		bio_out = BIO_new(BIO_s_mem());
 
 		if (passphrase && req.priv_key_encrypt) {
-			cipher = (EVP_CIPHER *) EVP_des_ede3_cbc();
+			if (req.priv_key_encrypt_cipher) {
+				cipher = req.priv_key_encrypt_cipher;
+			} else {
+				cipher = (EVP_CIPHER *) EVP_des_ede3_cbc();
+			}
 		} else {
 			cipher = NULL;
 		}
@@ -3221,6 +3204,7 @@
 	if (pkey == NULL) {
 		RETURN_FALSE;
 	}
+	zend_list_addref(Z_LVAL_P(return_value));
 }
 /* }}} */
 
@@ -3257,6 +3241,7 @@
 	if (pkey == NULL) {
 		RETURN_FALSE;
 	}
+	zend_list_addref(Z_LVAL_P(return_value));
 }
 
 /* }}} */
@@ -3286,7 +3271,7 @@
 	array_init(return_value);
 	add_assoc_long(return_value, "bits", EVP_PKEY_bits(pkey));
 	add_assoc_stringl(return_value, "key", pbio, pbio_len, 1);
-	/*TODO: Use the real values once the openssl constants are used 
+	/*TODO: Use the real values once the openssl constants are used
 	 * See the enum at the top of this file
 	 */
 	switch (EVP_PKEY_type(pkey->type)) {
@@ -3310,7 +3295,7 @@
 				add_assoc_zval(return_value, "rsa", rsa);
 			}
 
-			break;	
+			break;
 		case EVP_PKEY_DSA:
 		case EVP_PKEY_DSA2:
 		case EVP_PKEY_DSA3:
@@ -3331,7 +3316,7 @@
 			}
 			break;
 		case EVP_PKEY_DH:
-			
+
 			ktype = OPENSSL_KEYTYPE_DH;
 
 			if (pkey->pkey.dh != NULL) {
@@ -3347,7 +3332,7 @@
 			}
 
 			break;
-#ifdef EVP_PKEY_EC 
+#ifdef EVP_PKEY_EC
 		case EVP_PKEY_EC:
 			ktype = OPENSSL_KEYTYPE_EC;
 			break;
@@ -3381,15 +3366,15 @@
 	char * extracerts = NULL; int extracerts_len = 0;
 	char * signersfilename = NULL; int signersfilename_len = 0;
 	char * datafilename = NULL; int datafilename_len = 0;
-	
+
 	RETVAL_LONG(-1);
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|sass", &filename, &filename_len,
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pl|papp", &filename, &filename_len,
 				&flags, &signersfilename, &signersfilename_len, &cainfo,
 				&extracerts, &extracerts_len, &datafilename, &datafilename_len) == FAILURE) {
 		return;
 	}
-	
+
 	if (extracerts) {
 		others = load_all_certs_from_file(extracerts);
 		if (others == NULL) {
@@ -3404,7 +3389,7 @@
 	if (!store) {
 		goto clean_exit;
 	}
-	if (php_openssl_safe_mode_chk(filename TSRMLS_CC)) {
+	if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
 		goto clean_exit;
 	}
 
@@ -3422,7 +3407,7 @@
 
 	if (datafilename) {
 
-		if (php_openssl_safe_mode_chk(datafilename TSRMLS_CC)) {
+		if (php_openssl_open_base_dir_chk(datafilename TSRMLS_CC)) {
 			goto clean_exit;
 		}
 
@@ -3441,11 +3426,11 @@
 
 		if (signersfilename) {
 			BIO *certout;
-		
-			if (php_openssl_safe_mode_chk(signersfilename TSRMLS_CC)) {
+
+			if (php_openssl_open_base_dir_chk(signersfilename TSRMLS_CC)) {
 				goto clean_exit;
 			}
-		
+
 			certout = BIO_new_file(signersfilename, "w");
 			if (certout) {
 				int i;
@@ -3494,22 +3479,15 @@
 	char * strindex;
 	char * infilename = NULL;	int infilename_len;
 	char * outfilename = NULL;	int outfilename_len;
-	
+
 	RETVAL_FALSE;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssZa!|ll", &infilename, &infilename_len,
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ppZa!|ll", &infilename, &infilename_len,
 				&outfilename, &outfilename_len, &zrecipcerts, &zheaders, &flags, &cipherid) == FAILURE)
 		return;
 
-	if (strlen(infilename) != infilename_len) {
-		return;
-	}
 
-	if (strlen(outfilename) != outfilename_len) {
-		return;
-	}
-
-	if (php_openssl_safe_mode_chk(infilename TSRMLS_CC) || php_openssl_safe_mode_chk(outfilename TSRMLS_CC)) {
+	if (php_openssl_open_base_dir_chk(infilename TSRMLS_CC) || php_openssl_open_base_dir_chk(outfilename TSRMLS_CC)) {
 		return;
 	}
 
@@ -3519,7 +3497,7 @@
 	}
 
 	outfile = BIO_new_file(outfilename, "w");
-	if (outfile == NULL) { 
+	if (outfile == NULL) {
 		goto clean_exit;
 	}
 
@@ -3640,25 +3618,18 @@
 	char * outfilename;	int outfilename_len;
 	char * extracertsfilename = NULL; int extracertsfilename_len;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssZZa!|ls",
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ppZZa!|lp",
 				&infilename, &infilename_len, &outfilename, &outfilename_len,
 				&zcert, &zprivkey, &zheaders, &flags, &extracertsfilename,
 				&extracertsfilename_len) == FAILURE) {
 		return;
 	}
-	RETVAL_FALSE;
 
-	if (strlen(infilename) != infilename_len) {
-		return;
-	}
-
-	if (strlen(outfilename) != outfilename_len) {
-		return;
-	}
+	RETVAL_FALSE;
 
 	if (extracertsfilename) {
 		others = load_all_certs_from_file(extracertsfilename);
-		if (others == NULL) { 
+		if (others == NULL) {
 			goto clean_exit;
 		}
 	}
@@ -3675,7 +3646,7 @@
 		goto clean_exit;
 	}
 
-	if (php_openssl_safe_mode_chk(infilename TSRMLS_CC) || php_openssl_safe_mode_chk(outfilename TSRMLS_CC)) {
+	if (php_openssl_open_base_dir_chk(infilename TSRMLS_CC) || php_openssl_open_base_dir_chk(outfilename TSRMLS_CC)) {
 		goto clean_exit;
 	}
 
@@ -3751,20 +3722,12 @@
 	char * infilename;	int infilename_len;
 	char * outfilename;	int outfilename_len;
 
-	RETVAL_FALSE;
-
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssZ|Z", &infilename, &infilename_len,
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ppZ|Z", &infilename, &infilename_len,
 				&outfilename, &outfilename_len, &recipcert, &recipkey) == FAILURE) {
 		return;
 	}
 
-	if (strlen(infilename) != infilename_len) {
-		return;
-	}
-
-	if (strlen(outfilename) != outfilename_len) {
-		return;
-	}
+	RETVAL_FALSE;
 
 	cert = php_openssl_x509_from_zval(recipcert, 0, &certresval TSRMLS_CC);
 	if (cert == NULL) {
@@ -3777,8 +3740,8 @@
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to get private key");
 		goto clean_exit;
 	}
-	
-	if (php_openssl_safe_mode_chk(infilename TSRMLS_CC) || php_openssl_safe_mode_chk(outfilename TSRMLS_CC)) {
+
+	if (php_openssl_open_base_dir_chk(infilename TSRMLS_CC) || php_openssl_open_base_dir_chk(outfilename TSRMLS_CC)) {
 		goto clean_exit;
 	}
 
@@ -3796,7 +3759,7 @@
 	if (p7 == NULL) {
 		goto clean_exit;
 	}
-	if (PKCS7_decrypt(p7, key, cert, out, PKCS7_DETACHED)) { 
+	if (PKCS7_decrypt(p7, key, cert, out, PKCS7_DETACHED)) {
 		RETVAL_TRUE;
 	}
 clean_exit:
@@ -3829,7 +3792,7 @@
 	int data_len;
 	long padding = RSA_PKCS1_PADDING;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szZ|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) { 
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szZ|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) {
 		return;
 	}
 	RETVAL_FALSE;
@@ -3847,10 +3810,10 @@
 	switch (pkey->type) {
 		case EVP_PKEY_RSA:
 		case EVP_PKEY_RSA2:
-			successful =  (RSA_private_encrypt(data_len, 
-						(unsigned char *)data, 
-						cryptedbuf, 
-						pkey->pkey.rsa, 
+			successful =  (RSA_private_encrypt(data_len,
+						(unsigned char *)data,
+						cryptedbuf,
+						pkey->pkey.rsa,
 						padding) == cryptedlen);
 			break;
 		default:
@@ -3867,7 +3830,7 @@
 	if (cryptedbuf) {
 		efree(cryptedbuf);
 	}
-	if (keyresource == -1) { 
+	if (keyresource == -1) {
 		EVP_PKEY_free(pkey);
 	}
 }
@@ -3905,10 +3868,10 @@
 	switch (pkey->type) {
 		case EVP_PKEY_RSA:
 		case EVP_PKEY_RSA2:
-			cryptedlen = RSA_private_decrypt(data_len, 
-					(unsigned char *)data, 
-					crypttemp, 
-					pkey->pkey.rsa, 
+			cryptedlen = RSA_private_decrypt(data_len,
+					(unsigned char *)data,
+					crypttemp,
+					pkey->pkey.rsa,
 					padding);
 			if (cryptedlen != -1) {
 				cryptedbuf = emalloc(cryptedlen + 1);
@@ -3933,7 +3896,7 @@
 	if (keyresource == -1) {
 		EVP_PKEY_free(pkey);
 	}
-	if (cryptedbuf) { 
+	if (cryptedbuf) {
 		efree(cryptedbuf);
 	}
 }
@@ -3957,7 +3920,7 @@
 		return;
 
 	RETVAL_FALSE;
-	
+
 	pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource TSRMLS_CC);
 	if (pkey == NULL) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "key parameter is not a valid public key");
@@ -3970,10 +3933,10 @@
 	switch (pkey->type) {
 		case EVP_PKEY_RSA:
 		case EVP_PKEY_RSA2:
-			successful = (RSA_public_encrypt(data_len, 
-						(unsigned char *)data, 
-						cryptedbuf, 
-						pkey->pkey.rsa, 
+			successful = (RSA_public_encrypt(data_len,
+						(unsigned char *)data,
+						cryptedbuf,
+						pkey->pkey.rsa,
 						padding) == cryptedlen);
 			break;
 		default:
@@ -4016,7 +3979,7 @@
 		return;
 	}
 	RETVAL_FALSE;
-	
+
 	pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource TSRMLS_CC);
 	if (pkey == NULL) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "key parameter is not a valid public key");
@@ -4029,10 +3992,10 @@
 	switch (pkey->type) {
 		case EVP_PKEY_RSA:
 		case EVP_PKEY_RSA2:
-			cryptedlen = RSA_public_decrypt(data_len, 
-					(unsigned char *)data, 
-					crypttemp, 
-					pkey->pkey.rsa, 
+			cryptedlen = RSA_public_decrypt(data_len,
+					(unsigned char *)data,
+					crypttemp,
+					pkey->pkey.rsa,
 					padding);
 			if (cryptedlen != -1) {
 				cryptedbuf = emalloc(cryptedlen + 1);
@@ -4040,10 +4003,10 @@
 				successful = 1;
 			}
 			break;
-			
+
 		default:
 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "key type not supported in this PHP build!");
-		 
+
 	}
 
 	efree(crypttemp);
@@ -4161,7 +4124,7 @@
 	char * signature;	int signature_len;
 	zval *method = NULL;
 	long signature_algo = OPENSSL_ALGO_SHA1;
-	
+
 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssZ|z", &data, &data_len, &signature, &signature_len, &key, &method) == FAILURE) {
 		return;
 	}
@@ -4220,7 +4183,7 @@
 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szza/|s", &data, &data_len, &sealdata, &ekeys, &pubkeys, &method, &method_len) == FAILURE) {
 		return;
 	}
-	
+
 	pubkeysht = HASH_OF(pubkeys);
 	nkeys = pubkeysht ? zend_hash_num_elements(pubkeysht) : 0;
 	if (!nkeys) {
@@ -4315,7 +4278,7 @@
 		if (key_resources[i] == -1) {
 			EVP_PKEY_free(pkeys[i]);
 		}
-		if (eks[i]) { 
+		if (eks[i]) {
 			efree(eks[i]);
 		}
 	}
@@ -4361,13 +4324,13 @@
 	} else {
 		cipher = EVP_rc4();
 	}
-	
+
 	buf = emalloc(data_len + 1);
 
 	if (EVP_OpenInit(&ctx, cipher, (unsigned char *)ekey, ekey_len, NULL, pkey) && EVP_OpenUpdate(&ctx, buf, &len1, (unsigned char *)data, data_len)) {
 		if (!EVP_OpenFinal(&ctx, buf + len1, &len2) || (len1 + len2 == 0)) {
 			efree(buf);
-			if (keyresource == -1) { 
+			if (keyresource == -1) {
 				EVP_PKEY_free(pkey);
 			}
 			RETURN_FALSE;
@@ -4604,7 +4567,7 @@
 				if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff, SSL_FILETYPE_PEM) != 1) {
 					php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff);
 					return NULL;
-				}		
+				}
 			}
 
 			tmpssl = SSL_new(ctx);
@@ -4661,7 +4624,7 @@
 	}
 	array_init(return_value);
 	OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH,
-		aliases ? openssl_add_method_or_alias: openssl_add_method, 
+		aliases ? openssl_add_method_or_alias: openssl_add_method,
 		return_value);
 }
 /* }}} */
@@ -4677,7 +4640,7 @@
 	}
 	array_init(return_value);
 	OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
-		aliases ? openssl_add_method_or_alias: openssl_add_method, 
+		aliases ? openssl_add_method_or_alias: openssl_add_method,
 		return_value);
 }
 /* }}} */
@@ -4761,20 +4724,20 @@
 
 }
 
-/* {{{ proto string openssl_encrypt(string data, string method, string password [, bool raw_output=false [, string $iv='']])
+/* {{{ proto string openssl_encrypt(string data, string method, string password [, long options=0 [, string $iv='']])
    Encrypts given data with given method and key, returns raw or base64 encoded string */
 PHP_FUNCTION(openssl_encrypt)
 {
-	zend_bool raw_output = 0;
+	long options = 0;
 	char *data, *method, *password, *iv = "";
 	int data_len, method_len, password_len, iv_len = 0, max_iv_len;
 	const EVP_CIPHER *cipher_type;
 	EVP_CIPHER_CTX cipher_ctx;
-	int i = 0, outlen, keylen;
+	int i=0, outlen, keylen;
 	unsigned char *outbuf, *key;
 	zend_bool free_iv;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|bs", &data, &data_len, &method, &method_len, &password, &password_len, &raw_output, &iv, &iv_len) == FAILURE) {
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ls", &data, &data_len, &method, &method_len, &password, &password_len, &options, &iv, &iv_len) == FAILURE) {
 		return;
 	}
 	cipher_type = EVP_get_cipherbyname(method);
@@ -4806,13 +4769,16 @@
 		EVP_CIPHER_CTX_set_key_length(&cipher_ctx, password_len);
 	}
 	EVP_EncryptInit_ex(&cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
+	if (options & OPENSSL_ZERO_PADDING) {
+		EVP_CIPHER_CTX_set_padding(&cipher_ctx, 0);
+	}
 	if (data_len > 0) {
 		EVP_EncryptUpdate(&cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
 	}
 	outlen = i;
 	if (EVP_EncryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) {
 		outlen += i;
-		if (raw_output) {
+		if (options & OPENSSL_RAW_DATA) {
 			outbuf[outlen] = '\0';
 			RETVAL_STRINGL((char *)outbuf, outlen, 0);
 		} else {
@@ -4837,11 +4803,11 @@
 }
 /* }}} */
 
-/* {{{ proto string openssl_decrypt(string data, string method, string password [, bool raw_input=false [, string $iv = '']])
+/* {{{ proto string openssl_decrypt(string data, string method, string password [, long options=0 [, string $iv = '']])
    Takes raw or base64 encoded string and dectupt it using given method and key */
 PHP_FUNCTION(openssl_decrypt)
 {
-	zend_bool raw_input = 0;
+	long options = 0;
 	char *data, *method, *password, *iv = "";
 	int data_len, method_len, password_len, iv_len = 0;
 	const EVP_CIPHER *cipher_type;
@@ -4852,7 +4818,7 @@
 	char *base64_str = NULL;
 	zend_bool free_iv;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|bs", &data, &data_len, &method, &method_len, &password, &password_len, &raw_input, &iv, &iv_len) == FAILURE) {
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ls", &data, &data_len, &method, &method_len, &password, &password_len, &options, &iv, &iv_len) == FAILURE) {
 		return;
 	}
 
@@ -4867,7 +4833,7 @@
 		RETURN_FALSE;
 	}
 
-	if (!raw_input) {
+	if (!(options & OPENSSL_RAW_DATA)) {
 		base64_str = (char*)php_base64_decode((unsigned char*)data, data_len, &base64_str_len);
 		if (!base64_str) {
 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to base64 decode the input");
@@ -4896,6 +4862,9 @@
 		EVP_CIPHER_CTX_set_key_length(&cipher_ctx, password_len);
 	}
 	EVP_DecryptInit_ex(&cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
+	if (options & OPENSSL_ZERO_PADDING) {
+		EVP_CIPHER_CTX_set_padding(&cipher_ctx, 0);
+	}
 	EVP_DecryptUpdate(&cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
 	outlen = i;
 	if (EVP_DecryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) {
@@ -5007,10 +4976,25 @@
 
 	buffer = emalloc(buffer_length + 1);
 
+#ifdef PHP_WIN32
+	strong_result = 1;
+	/* random/urandom equivalent on Windows */
+	if (php_win32_get_random_bytes(buffer, (size_t) buffer_length) == FAILURE) {
+		efree(buffer);
+		if (zstrong_result_returned) {
+			ZVAL_BOOL(zstrong_result_returned, 0);
+		}
+		RETURN_FALSE;
+	}
+#else
 	if ((strong_result = RAND_pseudo_bytes(buffer, buffer_length)) < 0) {
 		efree(buffer);
+		if (zstrong_result_returned) {
+			ZVAL_BOOL(zstrong_result_returned, 0);
+		}
 		RETURN_FALSE;
 	}
+#endif
 
 	buffer[buffer_length] = 0;
 	RETVAL_STRINGL((char *)buffer, buffer_length, 0);
diff -Naur php-5.3.29_orig/ext/openssl/php_openssl.h php-5.4.16/ext/openssl/php_openssl.h
--- php-5.3.29_orig/ext/openssl/php_openssl.h	2014-08-14 01:22:50.000000000 +0600
+++ php-5.4.16/ext/openssl/php_openssl.h	2013-06-05 11:03:57.000000000 +0600
@@ -26,6 +26,9 @@
 extern zend_module_entry openssl_module_entry;
 #define phpext_openssl_ptr &openssl_module_entry
 
+#define OPENSSL_RAW_DATA 1
+#define OPENSSL_ZERO_PADDING 2
+
 php_stream_transport_factory_func php_openssl_ssl_socket_factory;
 
 PHP_MINIT_FUNCTION(openssl);
diff -Naur php-5.3.29_orig/ext/openssl/tests/004.phpt php-5.4.16/ext/openssl/tests/004.phpt
--- php-5.3.29_orig/ext/openssl/tests/004.phpt	2014-08-14 01:22:50.000000000 +0600
+++ php-5.4.16/ext/openssl/tests/004.phpt	2013-06-05 11:03:57.000000000 +0600
@@ -28,7 +28,7 @@
 
 Warning: openssl_csr_new(): key array must be of the form array(0 => key, 1 => phrase) in %s on line %d
 
-Warning: openssl_csr_new(): add1_attr_by_txt challengePassword_min -> 4 (failed) in %s on line %d
+Warning: openssl_csr_new(): add1_attr_by_txt challengePassword_min -> 4 (failed; check error queue and value of string_mask OpenSSL option if illegal characters are reported) in %s on line %d
 bool(false)
 resource(%d) of type (OpenSSL X.509 CSR)
 Done
diff -Naur php-5.3.29_orig/ext/openssl/tests/011.phpt php-5.4.16/ext/openssl/tests/011.phpt
--- php-5.3.29_orig/ext/openssl/tests/011.phpt	2014-08-14 01:22:50.000000000 +0600
+++ php-5.4.16/ext/openssl/tests/011.phpt	2013-06-05 11:03:57.000000000 +0600
@@ -13,14 +13,19 @@
 srand(time() + ((microtime(true) * 1000000) % 1000000));
 while(strlen($iv) < $ivlen) $iv .= chr(rand(0,255));
 
-$encrypted = openssl_encrypt($data, $method, $password, false, $iv);
-$output = openssl_decrypt($encrypted, $method, $password, false, $iv);
+$encrypted = openssl_encrypt($data, $method, $password, 0, $iv);
+$output = openssl_decrypt($encrypted, $method, $password, 0, $iv);
 var_dump($output);
-$encrypted = openssl_encrypt($data, $method, $password, true, $iv);
-$output = openssl_decrypt($encrypted, $method, $password, true, $iv);
+$encrypted = openssl_encrypt($data, $method, $password, OPENSSL_RAW_DATA, $iv);
+$output = openssl_decrypt($encrypted, $method, $password, OPENSSL_RAW_DATA, $iv);
 var_dump($output);
+// if we want to manage our own padding
+$padded_data = $data . str_repeat(' ', 16 - (strlen($data) % 16));
+$encrypted = openssl_encrypt($padded_data, $method, $password, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
+$output = openssl_decrypt($encrypted, $method, $password, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
+var_dump(rtrim($output));
 ?>
 --EXPECT--
 string(45) "openssl_encrypt() and openssl_decrypt() tests"
 string(45) "openssl_encrypt() and openssl_decrypt() tests"
-
+string(45) "openssl_encrypt() and openssl_decrypt() tests"
diff -Naur php-5.3.29_orig/ext/openssl/tests/026.phpt php-5.4.16/ext/openssl/tests/026.phpt
--- php-5.3.29_orig/ext/openssl/tests/026.phpt	2014-08-14 01:22:50.000000000 +0600
+++ php-5.4.16/ext/openssl/tests/026.phpt	1970-01-01 06:00:00.000000000 +0600
@@ -1,12 +0,0 @@
---TEST--
-Options type checks
---SKIPIF--
-<?php if (!extension_loaded("openssl")) print "skip"; ?>
---FILE--
-<?php
-$x = openssl_pkey_new();
-$csr = openssl_csr_new(["countryName" => "DE"], $x, ["x509_extensions" => 0xDEADBEEF]);
-?>
-DONE
---EXPECT--
-DONE
diff -Naur php-5.3.29_orig/ext/openssl/tests/bug54060.phpt php-5.4.16/ext/openssl/tests/bug54060.phpt
--- php-5.3.29_orig/ext/openssl/tests/bug54060.phpt	2014-08-14 01:22:50.000000000 +0600
+++ php-5.4.16/ext/openssl/tests/bug54060.phpt	2013-06-05 11:03:57.000000000 +0600
@@ -10,7 +10,7 @@
 972439 8478942 yrhfjkdhls";
 $pass = "r23498rui324hjbnkj";
 
-openssl_encrypt($data, 'des3', $pass, false, '1qazxsw2');
+openssl_encrypt($data, 'des3', $pass, 0, '1qazxsw2');
 echo "Done";
 ?>
 --EXPECT--
diff -Naur php-5.3.29_orig/ext/openssl/tests/bug54061.phpt php-5.4.16/ext/openssl/tests/bug54061.phpt
--- php-5.3.29_orig/ext/openssl/tests/bug54061.phpt	2014-08-14 01:22:50.000000000 +0600
+++ php-5.4.16/ext/openssl/tests/bug54061.phpt	2013-06-05 11:03:57.000000000 +0600
@@ -9,8 +9,8 @@
 972439 8478942 yrhfjkdhls";
 $pass = "r23498rui324hjbnkj";
 
-$cr = openssl_encrypt($data, 'des3', $pass, false, '1qazxsw2');
-$dcr = openssl_decrypt($cr, 'des3', $pass, false, '1qazxsw2');
+$cr = openssl_encrypt($data, 'des3', $pass, 0, '1qazxsw2');
+$dcr = openssl_decrypt($cr, 'des3', $pass, 0, '1qazxsw2');
 echo "Done";
 ?>
 --EXPECT--
diff -Naur php-5.3.29_orig/ext/openssl/tests/bug55646.phpt php-5.4.16/ext/openssl/tests/bug55646.phpt
--- php-5.3.29_orig/ext/openssl/tests/bug55646.phpt	1970-01-01 06:00:00.000000000 +0600
+++ php-5.4.16/ext/openssl/tests/bug55646.phpt	2013-06-05 11:03:57.000000000 +0600
@@ -0,0 +1,38 @@
+--TEST--
+Bug #55646: textual input in openssl_csr_new() is not expected in UTF-8
+--SKIPIF--
+<?php
+if (!function_exists('openssl_csr_new'))
+	die('skip no openssl extension');
+--FILE--
+<?php
+function stringAsHex($string){$unpacked = unpack("H*", $string);return implode(" ", str_split($unpacked[1],2));}
+
+$config = array("digest_alg" => "sha1","x509_extensions" => "v3_ca","req_extensions" => "v3_req","private_key_bits" => 2048,"private_key_type" => OPENSSL_KEYTYPE_RSA,"encrypt_key" => false,);
+$csr_info = array(
+  "countryName" => "US",
+  "stateOrProvinceName" => "Utah",
+  "localityName" => "Lindon",
+  "organizationName" => "Chinese",
+  "organizationalUnitName" => "IT \xe4\xba\x92",
+  "commonName" => "www.example.com",);
+$private = openssl_pkey_new($config);
+while (openssl_error_string()) {}
+$csr_res = openssl_csr_new($csr_info, $private,
+	['config' => __DIR__."/openssl.cnf"]);
+if (!$csr_res) {
+	while ($e = openssl_error_string()) { $err = $e; }
+	die("Failed; last error: $err");
+}
+openssl_csr_export($csr_res, $csr);
+$output = openssl_csr_get_subject($csr);
+
+echo "A: ".$csr_info["organizationalUnitName"]."\n";
+echo "B: ".stringAsHex($csr_info["organizationalUnitName"])."\n";
+echo "C: ".$output['OU']."\n";
+echo "D: ".stringAsHex($output['OU'])."\n";
+--EXPECT--
+A: IT 互
+B: 49 54 20 e4 ba 92
+C: IT 互
+D: 49 54 20 e4 ba 92
diff -Naur php-5.3.29_orig/ext/openssl/tests/bug61930.phpt php-5.4.16/ext/openssl/tests/bug61930.phpt
--- php-5.3.29_orig/ext/openssl/tests/bug61930.phpt	1970-01-01 06:00:00.000000000 +0600
+++ php-5.4.16/ext/openssl/tests/bug61930.phpt	2013-06-05 11:03:57.000000000 +0600
@@ -0,0 +1,24 @@
+--TEST--
+Bug #61930: openssl corrupts ssl key resource when using openssl_get_publickey()
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl")) die("skip");
+?>
+--FILE--
+<?php
+$cert = file_get_contents(__DIR__.'/cert.crt');
+
+$data = <<<DATA
+Please verify me
+DATA;
+
+$sig = 'f9Gyb6NV/ENn7GUa37ygTLcF93XHf5fbFTnoYF/O+fXbq3iChGUbET0RuhOsptlAODi6JsDLnJO4ikcVZo0tC1fFTj3LyCuPy3ZdgJbbVxQ/rviROCmuMFTqUW/Xa2LQYiapeCCgLQeWTLg7TM/BoHEkKbKLG/XT5jHvep1758A=';
+
+$key = openssl_get_publickey($cert);
+var_dump(openssl_get_publickey($key));
+var_dump(openssl_verify($data, base64_decode($sig), $key));
+?>
+--EXPECTF--
+resource(%d) of type (OpenSSL key)
+int(1)
+
diff -Naur php-5.3.29_orig/ext/openssl/tests/cve-2013-6420.crt php-5.4.16/ext/openssl/tests/cve-2013-6420.crt
--- php-5.3.29_orig/ext/openssl/tests/cve-2013-6420.crt	2014-08-14 01:22:50.000000000 +0600
+++ php-5.4.16/ext/openssl/tests/cve-2013-6420.crt	1970-01-01 06:00:00.000000000 +0600
@@ -1,29 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEpDCCA4ygAwIBAgIJAJzu8r6u6eBcMA0GCSqGSIb3DQEBBQUAMIHDMQswCQYD
-VQQGEwJERTEcMBoGA1UECAwTTm9yZHJoZWluLVdlc3RmYWxlbjEQMA4GA1UEBwwH
-S8ODwrZsbjEUMBIGA1UECgwLU2VrdGlvbkVpbnMxHzAdBgNVBAsMFk1hbGljaW91
-cyBDZXJ0IFNlY3Rpb24xITAfBgNVBAMMGG1hbGljaW91cy5zZWt0aW9uZWlucy5k
-ZTEqMCgGCSqGSIb3DQEJARYbc3RlZmFuLmVzc2VyQHNla3Rpb25laW5zLmRlMHUY
-ZDE5NzAwMTAxMDAwMDAwWgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAXDTE0MTEyODExMzkzNVowgcMxCzAJBgNVBAYTAkRFMRwwGgYDVQQIDBNO
-b3JkcmhlaW4tV2VzdGZhbGVuMRAwDgYDVQQHDAdLw4PCtmxuMRQwEgYDVQQKDAtT
-ZWt0aW9uRWluczEfMB0GA1UECwwWTWFsaWNpb3VzIENlcnQgU2VjdGlvbjEhMB8G
-A1UEAwwYbWFsaWNpb3VzLnNla3Rpb25laW5zLmRlMSowKAYJKoZIhvcNAQkBFhtz
-dGVmYW4uZXNzZXJAc2VrdGlvbmVpbnMuZGUwggEiMA0GCSqGSIb3DQEBAQUAA4IB
-DwAwggEKAoIBAQDDAf3hl7JY0XcFniyEJpSSDqn0OqBr6QP65usJPRt/8PaDoqBu
-wEYT/Na+6fsgPjC0uK9DZgWg2tHWWoanSblAMoz5PH6Z+S4SHRZ7e2dDIjPjdhjh
-0mLg2UMO5yp0V797Ggs9lNt6JRfH81MN2obXWs4NtztLMuD6egqpr8dDbr34aOs8
-pkdui5UawTZksy5pLPHq5cMhFGm06v65CLo0V2Pd9+KAokPrPcN5KLKebz7mLpk6
-SMeEXOKP4idEqxyQ7O7fBuHMedsQhu+prY3si3BUyKfQtP5CZnX2bp0wKHxX12DX
-1nfFIt9DbGvHTcyOuN+nZLPBm3vWxntyIIvVAgMBAAGjQjBAMAkGA1UdEwQCMAAw
-EQYJYIZIAYb4QgEBBAQDAgeAMAsGA1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEF
-BQcDAjANBgkqhkiG9w0BAQUFAAOCAQEAG0fZYYCTbdj1XYc+1SnoaPR+vI8C8CaD
-8+0UYhdnyU4gga0BAcDrY9e94eEAu6ZqycF6FjLqXXdAboppWocr6T6GD1x33Ckl
-VArzG/KxQohGD2JeqkhIMlDomxHO7ka39+Oa8i2vWLVyjU8AZvWMAruHa4EENyG7
-lW2AagaFKFCr9TnXTfrdxGVEbv7KVQ6bdhg5p5SjpWH1+Mq03uR3ZXPBYdyV8319
-o0lVj1KFI2DCL/liWisJRoof+1cR35Ctd0wYBcpB6TZslMcOPl76dwKwJgeJo2Qg
-Zsfmc2vC1/qOlNuNq/0TzzkVGv8ETT3CgaU+UXe4XOVvkccebJn2dg==
------END CERTIFICATE-----
-
-
diff -Naur php-5.3.29_orig/ext/openssl/tests/cve-2013-6420.phpt php-5.4.16/ext/openssl/tests/cve-2013-6420.phpt
--- php-5.3.29_orig/ext/openssl/tests/cve-2013-6420.phpt	2014-08-14 01:22:50.000000000 +0600
+++ php-5.4.16/ext/openssl/tests/cve-2013-6420.phpt	1970-01-01 06:00:00.000000000 +0600
@@ -1,18 +0,0 @@
---TEST--
-CVE-2013-6420
---SKIPIF--
-<?php 
-if (!extension_loaded("openssl")) die("skip"); 
-?>
---FILE--
-<?php
-$crt = substr(__FILE__, 0, -4).'.crt';
-$info = openssl_x509_parse("file://$crt");
-var_dump($info['issuer']['emailAddress'], $info["validFrom_time_t"]);
-?>
-Done
---EXPECTF--
-%s openssl_x509_parse(): illegal ASN1 data type for timestamp in %s%ecve-2013-6420.php on line 3
-string(27) "stefan.esser@sektioneins.de"
-int(-1)
-Done
diff -Naur php-5.3.29_orig/ext/openssl/tests/cve2013_4073.pem php-5.4.16/ext/openssl/tests/cve2013_4073.pem
--- php-5.3.29_orig/ext/openssl/tests/cve2013_4073.pem	2014-08-14 01:22:50.000000000 +0600
+++ php-5.4.16/ext/openssl/tests/cve2013_4073.pem	1970-01-01 06:00:00.000000000 +0600
@@ -1,28 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIE2DCCA8CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBxTELMAkGA1UEBhMCVVMx
-DzANBgNVBAgMBk9yZWdvbjESMBAGA1UEBwwJQmVhdmVydG9uMSMwIQYDVQQKDBpQ
-eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEgMB4GA1UECwwXUHl0aG9uIENvcmUg
-RGV2ZWxvcG1lbnQxJDAiBgNVBAMMG251bGwucHl0aG9uLm9yZwBleGFtcGxlLm9y
-ZzEkMCIGCSqGSIb3DQEJARYVcHl0aG9uLWRldkBweXRob24ub3JnMB4XDTEzMDgw
-NzEzMTE1MloXDTEzMDgwNzEzMTI1MlowgcUxCzAJBgNVBAYTAlVTMQ8wDQYDVQQI
-DAZPcmVnb24xEjAQBgNVBAcMCUJlYXZlcnRvbjEjMCEGA1UECgwaUHl0aG9uIFNv
-ZnR3YXJlIEZvdW5kYXRpb24xIDAeBgNVBAsMF1B5dGhvbiBDb3JlIERldmVsb3Bt
-ZW50MSQwIgYDVQQDDBtudWxsLnB5dGhvbi5vcmcAZXhhbXBsZS5vcmcxJDAiBgkq
-hkiG9w0BCQEWFXB5dGhvbi1kZXZAcHl0aG9uLm9yZzCCASIwDQYJKoZIhvcNAQEB
-BQADggEPADCCAQoCggEBALXq7cn7Rn1vO3aA3TrzA5QLp6bb7B3f/yN0CJ2XFj+j
-pHs+Gw6WWSUDpybiiKnPec33BFawq3kyblnBMjBU61ioy5HwQqVkJ8vUVjGIUq3P
-vX/wBmQfzCe4o4uM89gpHyUL9UYGG8oCRa17dgqcv7u5rg0Wq2B1rgY+nHwx3JIv
-KRrgSwyRkGzpN8WQ1yrXlxWjgI9de0mPVDDUlywcWze1q2kwaEPTM3hLAmD1PESA
-oY/n8A/RXoeeRs9i/Pm/DGUS8ZPINXk/yOzsR/XvvkTVroIeLZqfmFpnZeF0cHzL
-08LODkVJJ9zjLdT7SA4vnne4FEbAxDbKAq5qkYzaL4UCAwEAAaOB0DCBzTAMBgNV
-HRMBAf8EAjAAMB0GA1UdDgQWBBSIWlXAUv9hzVKjNQ/qWpwkOCL3XDALBgNVHQ8E
-BAMCBeAwgZAGA1UdEQSBiDCBhYIeYWx0bnVsbC5weXRob24ub3JnAGV4YW1wbGUu
-Y29tgSBudWxsQHB5dGhvbi5vcmcAdXNlckBleGFtcGxlLm9yZ4YpaHR0cDovL251
-bGwucHl0aG9uLm9yZwBodHRwOi8vZXhhbXBsZS5vcmeHBMAAAgGHECABDbgAAAAA
-AAAAAAAAAAEwDQYJKoZIhvcNAQEFBQADggEBAKxPRe99SaghcI6IWT7UNkJw9aO9
-i9eo0Fj2MUqxpKbdb9noRDy2CnHWf7EIYZ1gznXPdwzSN4YCjV5d+Q9xtBaowT0j
-HPERs1ZuytCNNJTmhyqZ8q6uzMLoht4IqH/FBfpvgaeC5tBTnTT0rD5A/olXeimk
-kX4LxlEx5RAvpGB2zZVRGr6LobD9rVK91xuHYNIxxxfEGE8tCCWjp0+3ksri9SXx
-VHWBnbM9YaL32u3hxm8sYB/Yb8WSBavJCWJJqRStVRHM1koZlJmXNx2BX4vPo6iW
-RFEIPQsFZRLrtnCAiEhyT8bC2s/Njlu6ly9gtJZWSV46Q3ZjBL4q9sHKqZQ=
------END CERTIFICATE-----
diff -Naur php-5.3.29_orig/ext/openssl/tests/cve2013_4073.phpt php-5.4.16/ext/openssl/tests/cve2013_4073.phpt
--- php-5.3.29_orig/ext/openssl/tests/cve2013_4073.phpt	2014-08-14 01:22:50.000000000 +0600
+++ php-5.4.16/ext/openssl/tests/cve2013_4073.phpt	1970-01-01 06:00:00.000000000 +0600
@@ -1,19 +0,0 @@
---TEST--
-CVE 2013-4073: Null-byte certificate handling
---SKIPIF--
-<?php 
-if (!extension_loaded("openssl")) die("skip");
---FILE--
-<?php
-$cert = file_get_contents(__DIR__ . '/cve2013_4073.pem');
-$info = openssl_x509_parse($cert);
-var_export($info['extensions']);
-
---EXPECTF--
-array (
-  'basicConstraints' => 'CA:FALSE',
-  'subjectKeyIdentifier' => '88:5A:55:C0:52:FF:61:CD:52:A3:35:0F:EA:5A:9C:24:38:22:F7:5C',
-  'keyUsage' => 'Digital Signature, Non Repudiation, Key Encipherment',
-  'subjectAltName' => 'DNS:altnull.python.org' . "\0" . 'example.com, email:null@python.org' . "\0" . 'user@example.org, URI:http://null.python.org' . "\0" . 'http://example.org, IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1
-',
-)
diff -Naur php-5.3.29_orig/ext/openssl/tests/openssl_decrypt_error.phpt php-5.4.16/ext/openssl/tests/openssl_decrypt_error.phpt
--- php-5.3.29_orig/ext/openssl/tests/openssl_decrypt_error.phpt	2014-08-14 01:22:50.000000000 +0600
+++ php-5.4.16/ext/openssl/tests/openssl_decrypt_error.phpt	2013-06-05 11:03:57.000000000 +0600
@@ -12,7 +12,7 @@
 
 $encrypted = openssl_encrypt($data, $method, $password);
 var_dump($encrypted); /* Not passing $iv should be the same as all-NULL iv, but with a warning */
-var_dump(openssl_encrypt($data, $method, $password, false, $iv)); 
+var_dump(openssl_encrypt($data, $method, $password, 0, $iv)); 
 var_dump(openssl_decrypt($encrypted, $method, $wrong));
 var_dump(openssl_decrypt($encrypted, $wrong, $password));
 var_dump(openssl_decrypt($wrong, $method, $password));
diff -Naur php-5.3.29_orig/ext/openssl/xp_ssl.c php-5.4.16/ext/openssl/xp_ssl.c
--- php-5.3.29_orig/ext/openssl/xp_ssl.c	2014-08-14 01:22:50.000000000 +0600
+++ php-5.4.16/ext/openssl/xp_ssl.c	2013-06-05 11:03:57.000000000 +0600
@@ -310,6 +310,7 @@
 		TSRMLS_DC)
 {
 	SSL_METHOD *method;
+	long ssl_ctx_options = SSL_OP_ALL;
 	
 	if (sslsock->ssl_handle) {
 		if (sslsock->s.is_blocked) {
@@ -377,7 +378,10 @@
 		return -1;
 	}
 
-	SSL_CTX_set_options(sslsock->ctx, SSL_OP_ALL);
+#if OPENSSL_VERSION_NUMBER >= 0x0090605fL
+	ssl_ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
+#endif
+	SSL_CTX_set_options(sslsock->ctx, ssl_ctx_options);
 
 #if OPENSSL_VERSION_NUMBER >= 0x0090806fL
 	{
@@ -391,6 +395,18 @@
 	}
 #endif
 
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+	{
+		zval **val;
+
+		if (stream->context && SUCCESS == php_stream_context_get_option(
+					stream->context, "ssl", "disable_compression", &val) &&
+				zval_is_true(*val)) {
+			SSL_CTX_set_options(sslsock->ctx, SSL_OP_NO_COMPRESSION);
+		}
+	}
+#endif
+
 	sslsock->ssl_handle = php_SSL_new_from_context(sslsock->ctx, stream TSRMLS_CC);
 	if (sslsock->ssl_handle == NULL) {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to create an SSL handle");
@@ -532,7 +548,7 @@
 							zval_is_true(*val)) {
 						MAKE_STD_ZVAL(zcert);
 						ZVAL_RESOURCE(zcert, zend_list_insert(peer_cert, 
-									php_openssl_get_x509_list_id()));
+									php_openssl_get_x509_list_id() TSRMLS_CC));
 						php_stream_context_set_option(stream->context,
 								"ssl", "peer_certificate",
 								zcert);
@@ -561,7 +577,7 @@
 								MAKE_STD_ZVAL(zcert);
 								ZVAL_RESOURCE(zcert,
 										zend_list_insert(mycert,
-											php_openssl_get_x509_list_id()));
+											php_openssl_get_x509_list_id() TSRMLS_CC));
 								add_next_index_zval(arr, zcert);
 							}