blob: ac8365b8e56712a61ad9f2557e8ae7827f220da9 [file] [log] [blame]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001Subject: [PATCH] PHP 5.6 - LibSSL 1.1 compatibility
2
3This patch does not try to backport the 7.1 openssl module, it is the
4improved version of the 5.6 original openssl module.
5
6https://github.com/oerdnj/deb.sury.org/issues/566
7http://zettasystem.com/PHP-5.6.31-OpenSSL-1.1.0-compatibility-20170801.patch
8
9Upstream-Status: Deny [https://github.com/php/php-src/pull/2667]
10Reason: As PHP 5.6 is no longer actively supported only security fixes
11may land on this branch. As this change does not fall in this category,
12I'm closing this PR. (All higher versions of PHP already have OpenSSL
131.1 support.)
14
15Author: zsalab@github https://github.com/zsalab
16
17Only port source modification, do not include the test case
18Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
19---
20 ext/openssl/openssl.c | 683 +++++++++++++++++++++++++++++++++++++-------------
21 ext/openssl/xp_ssl.c | 18 +-
22 ext/phar/util.c | 13 +-
23 3 files changed, 527 insertions(+), 187 deletions(-)
24
25diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
26index a78a8fb..b53114c 100644
27--- a/ext/openssl/openssl.c
28+++ b/ext/openssl/openssl.c
29@@ -42,6 +42,12 @@
30
31 /* OpenSSL includes */
32 #include <openssl/evp.h>
33+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
34+#include <openssl/bn.h>
35+#include <openssl/rsa.h>
36+#include <openssl/dsa.h>
37+#include <openssl/dh.h>
38+#endif
39 #include <openssl/x509.h>
40 #include <openssl/x509v3.h>
41 #include <openssl/crypto.h>
42@@ -531,6 +537,133 @@ zend_module_entry openssl_module_entry = {
43 ZEND_GET_MODULE(openssl)
44 #endif
45
46+/* {{{ OpenSSL compatibility functions and macros */
47+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined (LIBRESSL_VERSION_NUMBER)
48+#define EVP_PKEY_get0_RSA(_pkey) _pkey->pkey.rsa
49+#define EVP_PKEY_get0_DH(_pkey) _pkey->pkey.dh
50+#define EVP_PKEY_get0_DSA(_pkey) _pkey->pkey.dsa
51+#define EVP_PKEY_get0_EC_KEY(_pkey) _pkey->pkey.ec
52+
53+static int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
54+{
55+ r->n = n;
56+ r->e = e;
57+ r->d = d;
58+
59+ return 1;
60+}
61+
62+static int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
63+{
64+ r->p = p;
65+ r->q = q;
66+
67+ return 1;
68+}
69+
70+static int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
71+{
72+ r->dmp1 = dmp1;
73+ r->dmq1 = dmq1;
74+ r->iqmp = iqmp;
75+
76+ return 1;
77+}
78+
79+static void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
80+{
81+ *n = r->n;
82+ *e = r->e;
83+ *d = r->d;
84+}
85+
86+static void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
87+{
88+ *p = r->p;
89+ *q = r->q;
90+}
91+
92+static void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp)
93+{
94+ *dmp1 = r->dmp1;
95+ *dmq1 = r->dmq1;
96+ *iqmp = r->iqmp;
97+}
98+
99+static void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
100+{
101+ *p = dh->p;
102+ *q = dh->q;
103+ *g = dh->g;
104+}
105+
106+static int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
107+{
108+ dh->p = p;
109+ dh->q = q;
110+ dh->g = g;
111+
112+ return 1;
113+}
114+
115+static void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
116+{
117+ *pub_key = dh->pub_key;
118+ *priv_key = dh->priv_key;
119+}
120+
121+static int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
122+{
123+ dh->pub_key = pub_key;
124+ dh->priv_key = priv_key;
125+
126+ return 1;
127+}
128+
129+static void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
130+{
131+ *p = d->p;
132+ *q = d->q;
133+ *g = d->g;
134+}
135+
136+int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
137+{
138+ d->p = p;
139+ d->q = q;
140+ d->g = g;
141+
142+ return 1;
143+}
144+
145+static void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key)
146+{
147+ *pub_key = d->pub_key;
148+ *priv_key = d->priv_key;
149+}
150+
151+int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
152+{
153+ d->pub_key = pub_key;
154+ d->priv_key = priv_key;
155+
156+ return 1;
157+}
158+
159+#if OPENSSL_VERSION_NUMBER < 0x10002000L || defined (LIBRESSL_VERSION_NUMBER)
160+#define EVP_PKEY_id(_pkey) _pkey->type
161+#define EVP_PKEY_base_id(_key) EVP_PKEY_type(_key->type)
162+
163+static int X509_get_signature_nid(const X509 *x)
164+{
165+ return OBJ_obj2nid(x->sig_alg->algorithm);
166+}
167+
168+#endif
169+
170+#endif
171+/* }}} */
172+
173 static int le_key;
174 static int le_x509;
175 static int le_csr;
176@@ -825,7 +958,7 @@ static int add_oid_section(struct php_x509_request * req TSRMLS_DC) /* {{{ */
177 }
178 for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
179 cnf = sk_CONF_VALUE_value(sktmp, i);
180- if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
181+ if (OBJ_sn2nid(cnf->name) == NID_undef && OBJ_ln2nid(cnf->name) == NID_undef && OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
182 php_error_docref(NULL TSRMLS_CC, E_WARNING, "problem creating object %s=%s", cnf->name, cnf->value);
183 return FAILURE;
184 }
185@@ -967,7 +1100,7 @@ static void php_openssl_dispose_config(struct php_x509_request * req TSRMLS_DC)
186 }
187 /* }}} */
188
189-#ifdef PHP_WIN32
190+#if defined(PHP_WIN32) || (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER))
191 #define PHP_OPENSSL_RAND_ADD_TIME() ((void) 0)
192 #else
193 #define PHP_OPENSSL_RAND_ADD_TIME() php_openssl_rand_add_timeval()
194@@ -1053,9 +1186,11 @@ static EVP_MD * php_openssl_get_evp_md_from_algo(long algo) { /* {{{ */
195 mdtype = (EVP_MD *) EVP_md2();
196 break;
197 #endif
198+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined (LIBRESSL_VERSION_NUMBER)
199 case OPENSSL_ALGO_DSS1:
200 mdtype = (EVP_MD *) EVP_dss1();
201 break;
202+#endif
203 #if OPENSSL_VERSION_NUMBER >= 0x0090708fL
204 case OPENSSL_ALGO_SHA224:
205 mdtype = (EVP_MD *) EVP_sha224();
206@@ -1146,6 +1281,12 @@ PHP_MINIT_FUNCTION(openssl)
207 OpenSSL_add_all_digests();
208 OpenSSL_add_all_algorithms();
209
210+#if !defined(OPENSSL_NO_AES) && defined(EVP_CIPH_CCM_MODE) && OPENSSL_VERSION_NUMBER < 0x100020000
211+ EVP_add_cipher(EVP_aes_128_ccm());
212+ EVP_add_cipher(EVP_aes_192_ccm());
213+ EVP_add_cipher(EVP_aes_256_ccm());
214+#endif
215+
216 SSL_load_error_strings();
217
218 /* register a resource id number with OpenSSL so that we can map SSL -> stream structures in
219@@ -1173,7 +1314,9 @@ PHP_MINIT_FUNCTION(openssl)
220 #ifdef HAVE_OPENSSL_MD2_H
221 REGISTER_LONG_CONSTANT("OPENSSL_ALGO_MD2", OPENSSL_ALGO_MD2, CONST_CS|CONST_PERSISTENT);
222 #endif
223+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined (LIBRESSL_VERSION_NUMBER)
224 REGISTER_LONG_CONSTANT("OPENSSL_ALGO_DSS1", OPENSSL_ALGO_DSS1, CONST_CS|CONST_PERSISTENT);
225+#endif
226 #if OPENSSL_VERSION_NUMBER >= 0x0090708fL
227 REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA224", OPENSSL_ALGO_SHA224, CONST_CS|CONST_PERSISTENT);
228 REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA256", OPENSSL_ALGO_SHA256, CONST_CS|CONST_PERSISTENT);
229@@ -1251,7 +1394,9 @@ PHP_MINIT_FUNCTION(openssl)
230 }
231
232 php_stream_xport_register("ssl", php_openssl_ssl_socket_factory TSRMLS_CC);
233+#ifndef OPENSSL_NO_SSL3
234 php_stream_xport_register("sslv3", php_openssl_ssl_socket_factory TSRMLS_CC);
235+#endif
236 #ifndef OPENSSL_NO_SSL2
237 php_stream_xport_register("sslv2", php_openssl_ssl_socket_factory TSRMLS_CC);
238 #endif
239@@ -1308,7 +1453,9 @@ PHP_MSHUTDOWN_FUNCTION(openssl)
240 #ifndef OPENSSL_NO_SSL2
241 php_stream_xport_unregister("sslv2" TSRMLS_CC);
242 #endif
243+#ifndef OPENSSL_NO_SSL3
244 php_stream_xport_unregister("sslv3" TSRMLS_CC);
245+#endif
246 php_stream_xport_unregister("tls" TSRMLS_CC);
247 php_stream_xport_unregister("tlsv1.0" TSRMLS_CC);
248 #if OPENSSL_VERSION_NUMBER >= 0x10001001L
249@@ -1893,6 +2040,7 @@ static int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension)
250 {
251 GENERAL_NAMES *names;
252 const X509V3_EXT_METHOD *method = NULL;
253+ ASN1_OCTET_STRING *extension_data;
254 long i, length, num;
255 const unsigned char *p;
256
257@@ -1901,8 +2049,9 @@ static int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension)
258 return -1;
259 }
260
261- p = extension->value->data;
262- length = extension->value->length;
263+ extension_data = X509_EXTENSION_get_data(extension);
264+ p = extension_data->data;
265+ length = extension_data->length;
266 if (method->it) {
267 names = (GENERAL_NAMES*)(ASN1_item_d2i(NULL, &p, length,
268 ASN1_ITEM_ptr(method->it)));
269@@ -1965,6 +2114,8 @@ PHP_FUNCTION(openssl_x509_parse)
270 char * tmpstr;
271 zval * subitem;
272 X509_EXTENSION *extension;
273+ X509_NAME *subject_name;
274+ char *cert_name;
275 char *extname;
276 BIO *bio_out;
277 BUF_MEM *bio_buf;
278@@ -1979,10 +2130,10 @@ PHP_FUNCTION(openssl_x509_parse)
279 }
280 array_init(return_value);
281
282- if (cert->name) {
283- add_assoc_string(return_value, "name", cert->name, 1);
284- }
285-/* add_assoc_bool(return_value, "valid", cert->valid); */
286+ subject_name = X509_get_subject_name(cert);
287+ cert_name = X509_NAME_oneline(subject_name, NULL, 0);
288+ add_assoc_string(return_value, "name", cert_name, 1);
289+ OPENSSL_free(cert_name);
290
291 add_assoc_name_entry(return_value, "subject", X509_get_subject_name(cert), useshortnames TSRMLS_CC);
292 /* hash as used in CA directories to lookup cert by subject name */
293@@ -2008,7 +2159,7 @@ PHP_FUNCTION(openssl_x509_parse)
294 add_assoc_string(return_value, "alias", tmpstr, 1);
295 }
296
297- sig_nid = OBJ_obj2nid((cert)->sig_alg->algorithm);
298+ sig_nid = X509_get_signature_nid(cert);
299 add_assoc_string(return_value, "signatureTypeSN", (char*)OBJ_nid2sn(sig_nid), 1);
300 add_assoc_string(return_value, "signatureTypeLN", (char*)OBJ_nid2ln(sig_nid), 1);
301 add_assoc_long(return_value, "signatureTypeNID", sig_nid);
302@@ -3217,7 +3368,21 @@ PHP_FUNCTION(openssl_csr_get_public_key)
303 RETURN_FALSE;
304 }
305
306- tpubkey=X509_REQ_get_pubkey(csr);
307+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
308+ /* Due to changes in OpenSSL 1.1 related to locking when decoding CSR,
309+ * the pub key is not changed after assigning. It means if we pass
310+ * a private key, it will be returned including the private part.
311+ * If we duplicate it, then we get just the public part which is
312+ * the same behavior as for OpenSSL 1.0 */
313+ csr = X509_REQ_dup(csr);
314+#endif
315+ /* Retrieve the public key from the CSR */
316+ tpubkey = X509_REQ_get_pubkey(csr);
317+
318+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
319+ /* We need to free the CSR as it was duplicated */
320+ X509_REQ_free(csr);
321+#endif
322 RETVAL_RESOURCE(zend_list_insert(tpubkey, le_key TSRMLS_CC));
323 return;
324 }
325@@ -3482,13 +3647,20 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC)
326 {
327 assert(pkey != NULL);
328
329- switch (pkey->type) {
330+ switch (EVP_PKEY_id(pkey)) {
331 #ifndef NO_RSA
332 case EVP_PKEY_RSA:
333 case EVP_PKEY_RSA2:
334- assert(pkey->pkey.rsa != NULL);
335- if (pkey->pkey.rsa != NULL && (NULL == pkey->pkey.rsa->p || NULL == pkey->pkey.rsa->q)) {
336- return 0;
337+ {
338+ RSA *rsa = EVP_PKEY_get0_RSA(pkey);
339+ if (rsa != NULL) {
340+ const BIGNUM *p, *q;
341+
342+ RSA_get0_factors(rsa, &p, &q);
343+ if (p == NULL || q == NULL) {
344+ return 0;
345+ }
346+ }
347 }
348 break;
349 #endif
350@@ -3498,28 +3670,51 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC)
351 case EVP_PKEY_DSA2:
352 case EVP_PKEY_DSA3:
353 case EVP_PKEY_DSA4:
354- assert(pkey->pkey.dsa != NULL);
355-
356- if (NULL == pkey->pkey.dsa->p || NULL == pkey->pkey.dsa->q || NULL == pkey->pkey.dsa->priv_key){
357- return 0;
358+ {
359+ DSA *dsa = EVP_PKEY_get0_DSA(pkey);
360+ if (dsa != NULL) {
361+ const BIGNUM *p, *q, *g, *pub_key, *priv_key;
362+
363+ DSA_get0_pqg(dsa, &p, &q, &g);
364+ if (p == NULL || q == NULL) {
365+ return 0;
366+ }
367+
368+ DSA_get0_key(dsa, &pub_key, &priv_key);
369+ if (priv_key == NULL) {
370+ return 0;
371+ }
372+ }
373 }
374 break;
375 #endif
376 #ifndef NO_DH
377 case EVP_PKEY_DH:
378- assert(pkey->pkey.dh != NULL);
379-
380- if (NULL == pkey->pkey.dh->p || NULL == pkey->pkey.dh->priv_key) {
381- return 0;
382+ {
383+ DH *dh = EVP_PKEY_get0_DH(pkey);
384+ if (dh != NULL) {
385+ const BIGNUM *p, *q, *g, *pub_key, *priv_key;
386+
387+ DH_get0_pqg(dh, &p, &q, &g);
388+ if (p == NULL) {
389+ return 0;
390+ }
391+
392+ DH_get0_key(dh, &pub_key, &priv_key);
393+ if (priv_key == NULL) {
394+ return 0;
395+ }
396+ }
397 }
398 break;
399 #endif
400 #ifdef HAVE_EVP_PKEY_EC
401 case EVP_PKEY_EC:
402- assert(pkey->pkey.ec != NULL);
403-
404- if ( NULL == EC_KEY_get0_private_key(pkey->pkey.ec)) {
405- return 0;
406+ {
407+ EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
408+ if (ec != NULL && NULL == EC_KEY_get0_private_key(ec)) {
409+ return 0;
410+ }
411 }
412 break;
413 #endif
414@@ -3531,34 +3726,80 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC)
415 }
416 /* }}} */
417
418-#define OPENSSL_PKEY_GET_BN(_type, _name) do { \
419- if (pkey->pkey._type->_name != NULL) { \
420- int len = BN_num_bytes(pkey->pkey._type->_name); \
421- char *str = emalloc(len + 1); \
422- BN_bn2bin(pkey->pkey._type->_name, (unsigned char*)str); \
423- str[len] = 0; \
424- add_assoc_stringl(_type, #_name, str, len, 0); \
425- } \
426- } while (0)
427-
428-#define OPENSSL_PKEY_SET_BN(_ht, _type, _name) do { \
429- zval **bn; \
430- if (zend_hash_find(_ht, #_name, sizeof(#_name), (void**)&bn) == SUCCESS && \
431- Z_TYPE_PP(bn) == IS_STRING) { \
432- _type->_name = BN_bin2bn( \
433- (unsigned char*)Z_STRVAL_PP(bn), \
434- Z_STRLEN_PP(bn), NULL); \
435- } \
436+#define OPENSSL_GET_BN(_array, _bn, _name) do { \
437+ if (_bn != NULL) { \
438+ int len = BN_num_bytes(_bn); \
439+ char *str = emalloc(len + 1); \
440+ BN_bn2bin(_bn, (unsigned char*)str); \
441+ str[len] = 0; \
442+ add_assoc_stringl(_array, #_name, str, len, 0); \
443+ } \
444 } while (0);
445
446+#define OPENSSL_PKEY_GET_BN(_type, _name) OPENSSL_GET_BN(_type, _name, _name)
447+
448+#define OPENSSL_PKEY_SET_BN(_data, _name) do { \
449+ zval **bn; \
450+ if (zend_hash_find(Z_ARRVAL_P(_data), #_name, sizeof(#_name),(void**)&bn) == SUCCESS && \
451+ Z_TYPE_PP(bn) == IS_STRING) { \
452+ _name = BN_bin2bn( \
453+ (unsigned char*)Z_STRVAL_PP(bn), \
454+ Z_STRLEN_PP(bn), NULL); \
455+ } else { \
456+ _name = NULL; \
457+ } \
458+ } while (0);
459+
460+/* {{{ php_openssl_pkey_init_rsa */
461+zend_bool php_openssl_pkey_init_and_assign_rsa(EVP_PKEY *pkey, RSA *rsa, zval *data)
462+{
463+ BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
464+
465+ OPENSSL_PKEY_SET_BN(data, n);
466+ OPENSSL_PKEY_SET_BN(data, e);
467+ OPENSSL_PKEY_SET_BN(data, d);
468+ if (!n || !d || !RSA_set0_key(rsa, n, e, d)) {
469+ return 0;
470+ }
471+
472+ OPENSSL_PKEY_SET_BN(data, p);
473+ OPENSSL_PKEY_SET_BN(data, q);
474+ if ((p || q) && !RSA_set0_factors(rsa, p, q)) {
475+ return 0;
476+ }
477+
478+ OPENSSL_PKEY_SET_BN(data, dmp1);
479+ OPENSSL_PKEY_SET_BN(data, dmq1);
480+ OPENSSL_PKEY_SET_BN(data, iqmp);
481+ if ((dmp1 || dmq1 || iqmp) && !RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp)) {
482+ return 0;
483+ }
484+
485+ if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
486+ return 0;
487+ }
488+
489+ return 1;
490+}
491+/* }}} */
492+
493 /* {{{ php_openssl_pkey_init_dsa */
494-zend_bool php_openssl_pkey_init_dsa(DSA *dsa)
495+zend_bool php_openssl_pkey_init_dsa(DSA *dsa, zval *data)
496 {
497- if (!dsa->p || !dsa->q || !dsa->g) {
498+ BIGNUM *p, *q, *g, *priv_key, *pub_key;
499+ const BIGNUM *priv_key_const, *pub_key_const;
500+
501+ OPENSSL_PKEY_SET_BN(data, p);
502+ OPENSSL_PKEY_SET_BN(data, q);
503+ OPENSSL_PKEY_SET_BN(data, g);
504+ if (!p || !q || !g || !DSA_set0_pqg(dsa, p, q, g)) {
505 return 0;
506 }
507- if (dsa->priv_key || dsa->pub_key) {
508- return 1;
509+
510+ OPENSSL_PKEY_SET_BN(data, pub_key);
511+ OPENSSL_PKEY_SET_BN(data, priv_key);
512+ if (pub_key) {
513+ return DSA_set0_key(dsa, pub_key, priv_key);
514 }
515 PHP_OPENSSL_RAND_ADD_TIME();
516 if (!DSA_generate_key(dsa)) {
517@@ -3566,7 +3807,8 @@ zend_bool php_openssl_pkey_init_dsa(DSA *dsa)
518 }
519 /* if BN_mod_exp return -1, then DSA_generate_key succeed for failed key
520 * so we need to double check that public key is created */
521- if (!dsa->pub_key || BN_is_zero(dsa->pub_key)) {
522+ DSA_get0_key(dsa, &pub_key_const, &priv_key_const);
523+ if (!pub_key_const || BN_is_zero(pub_key_const)) {
524 return 0;
525 }
526 /* all good */
527@@ -3574,14 +3816,66 @@ zend_bool php_openssl_pkey_init_dsa(DSA *dsa)
528 }
529 /* }}} */
530
531+/* {{{ php_openssl_dh_pub_from_priv */
532+static BIGNUM *php_openssl_dh_pub_from_priv(BIGNUM *priv_key, BIGNUM *g, BIGNUM *p)
533+{
534+ BIGNUM *pub_key, *priv_key_const_time;
535+ BN_CTX *ctx;
536+
537+ pub_key = BN_new();
538+ if (pub_key == NULL) {
539+ return NULL;
540+ }
541+
542+ priv_key_const_time = BN_new();
543+ if (priv_key_const_time == NULL) {
544+ BN_free(pub_key);
545+ return NULL;
546+ }
547+ ctx = BN_CTX_new();
548+ if (ctx == NULL) {
549+ BN_free(pub_key);
550+ BN_free(priv_key_const_time);
551+ return NULL;
552+ }
553+
554+ BN_with_flags(priv_key_const_time, priv_key, BN_FLG_CONSTTIME);
555+
556+ if (!BN_mod_exp_mont(pub_key, g, priv_key_const_time, p, ctx, NULL)) {
557+ BN_free(pub_key);
558+ pub_key = NULL;
559+ }
560+
561+ BN_free(priv_key_const_time);
562+ BN_CTX_free(ctx);
563+
564+ return pub_key;
565+}
566+/* }}} */
567+
568 /* {{{ php_openssl_pkey_init_dh */
569-zend_bool php_openssl_pkey_init_dh(DH *dh)
570+zend_bool php_openssl_pkey_init_dh(DH *dh, zval *data)
571 {
572- if (!dh->p || !dh->g) {
573+ BIGNUM *p, *q, *g, *priv_key, *pub_key;
574+
575+ OPENSSL_PKEY_SET_BN(data, p);
576+ OPENSSL_PKEY_SET_BN(data, q);
577+ OPENSSL_PKEY_SET_BN(data, g);
578+ if (!p || !g || !DH_set0_pqg(dh, p, q, g)) {
579 return 0;
580 }
581- if (dh->pub_key) {
582- return 1;
583+
584+ OPENSSL_PKEY_SET_BN(data, priv_key);
585+ OPENSSL_PKEY_SET_BN(data, pub_key);
586+ if (pub_key) {
587+ return DH_set0_key(dh, pub_key, priv_key);
588+ }
589+ if (priv_key) {
590+ pub_key = php_openssl_dh_pub_from_priv(priv_key, g, p);
591+ if (pub_key == NULL) {
592+ return 0;
593+ }
594+ return DH_set0_key(dh, pub_key, priv_key);
595 }
596 PHP_OPENSSL_RAND_ADD_TIME();
597 if (!DH_generate_key(dh)) {
598@@ -3614,18 +3908,8 @@ PHP_FUNCTION(openssl_pkey_new)
599 if (pkey) {
600 RSA *rsa = RSA_new();
601 if (rsa) {
602- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, n);
603- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, e);
604- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, d);
605- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, p);
606- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, q);
607- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, dmp1);
608- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, dmq1);
609- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, iqmp);
610- if (rsa->n && rsa->d) {
611- if (EVP_PKEY_assign_RSA(pkey, rsa)) {
612- RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
613- }
614+ if (php_openssl_pkey_init_and_assign_rsa(pkey, rsa, *data)) {
615+ RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
616 }
617 RSA_free(rsa);
618 }
619@@ -3638,12 +3922,7 @@ PHP_FUNCTION(openssl_pkey_new)
620 if (pkey) {
621 DSA *dsa = DSA_new();
622 if (dsa) {
623- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, p);
624- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, q);
625- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, g);
626- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, priv_key);
627- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, pub_key);
628- if (php_openssl_pkey_init_dsa(dsa)) {
629+ if (php_openssl_pkey_init_dsa(dsa, *data)) {
630 if (EVP_PKEY_assign_DSA(pkey, dsa)) {
631 RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
632 }
633@@ -3659,11 +3938,7 @@ PHP_FUNCTION(openssl_pkey_new)
634 if (pkey) {
635 DH *dh = DH_new();
636 if (dh) {
637- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, p);
638- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, g);
639- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, priv_key);
640- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, pub_key);
641- if (php_openssl_pkey_init_dh(dh)) {
642+ if (php_openssl_pkey_init_dh(dh, *data)) {
643 if (EVP_PKEY_assign_DH(pkey, dh)) {
644 RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
645 }
646@@ -3738,10 +4013,10 @@ PHP_FUNCTION(openssl_pkey_export_to_file)
647 cipher = NULL;
648 }
649
650- switch (EVP_PKEY_type(key->type)) {
651+ switch (EVP_PKEY_base_id(key)) {
652 #ifdef HAVE_EVP_PKEY_EC
653 case EVP_PKEY_EC:
654- pem_write = PEM_write_bio_ECPrivateKey(bio_out, EVP_PKEY_get1_EC_KEY(key), cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL);
655+ pem_write = PEM_write_bio_ECPrivateKey(bio_out, EVP_PKEY_get0_EC_KEY(key), cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL);
656 break;
657 #endif
658 default:
659@@ -3807,7 +4082,7 @@ PHP_FUNCTION(openssl_pkey_export)
660 cipher = NULL;
661 }
662
663- switch (EVP_PKEY_type(key->type)) {
664+ switch (EVP_PKEY_base_id(key)) {
665 #ifdef HAVE_EVP_PKEY_EC
666 case EVP_PKEY_EC:
667 pem_write = PEM_write_bio_ECPrivateKey(bio_out, EVP_PKEY_get1_EC_KEY(key), cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL);
668@@ -3928,25 +4203,33 @@ PHP_FUNCTION(openssl_pkey_get_details)
669 /*TODO: Use the real values once the openssl constants are used
670 * See the enum at the top of this file
671 */
672- switch (EVP_PKEY_type(pkey->type)) {
673+ switch (EVP_PKEY_base_id(pkey)) {
674 case EVP_PKEY_RSA:
675 case EVP_PKEY_RSA2:
676- ktype = OPENSSL_KEYTYPE_RSA;
677-
678- if (pkey->pkey.rsa != NULL) {
679- zval *rsa;
680-
681- ALLOC_INIT_ZVAL(rsa);
682- array_init(rsa);
683- OPENSSL_PKEY_GET_BN(rsa, n);
684- OPENSSL_PKEY_GET_BN(rsa, e);
685- OPENSSL_PKEY_GET_BN(rsa, d);
686- OPENSSL_PKEY_GET_BN(rsa, p);
687- OPENSSL_PKEY_GET_BN(rsa, q);
688- OPENSSL_PKEY_GET_BN(rsa, dmp1);
689- OPENSSL_PKEY_GET_BN(rsa, dmq1);
690- OPENSSL_PKEY_GET_BN(rsa, iqmp);
691- add_assoc_zval(return_value, "rsa", rsa);
692+ {
693+ RSA *rsa = EVP_PKEY_get0_RSA(pkey);
694+ ktype = OPENSSL_KEYTYPE_RSA;
695+
696+ if (rsa != NULL) {
697+ zval *z_rsa;
698+ const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
699+
700+ RSA_get0_key(rsa, &n, &e, &d);
701+ RSA_get0_factors(rsa, &p, &q);
702+ RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
703+
704+ ALLOC_INIT_ZVAL(z_rsa);
705+ array_init(z_rsa);
706+ OPENSSL_PKEY_GET_BN(z_rsa, n);
707+ OPENSSL_PKEY_GET_BN(z_rsa, e);
708+ OPENSSL_PKEY_GET_BN(z_rsa, d);
709+ OPENSSL_PKEY_GET_BN(z_rsa, p);
710+ OPENSSL_PKEY_GET_BN(z_rsa, q);
711+ OPENSSL_PKEY_GET_BN(z_rsa, dmp1);
712+ OPENSSL_PKEY_GET_BN(z_rsa, dmq1);
713+ OPENSSL_PKEY_GET_BN(z_rsa, iqmp);
714+ add_assoc_zval(return_value, "rsa", z_rsa);
715+ }
716 }
717
718 break;
719@@ -3954,42 +4237,55 @@ PHP_FUNCTION(openssl_pkey_get_details)
720 case EVP_PKEY_DSA2:
721 case EVP_PKEY_DSA3:
722 case EVP_PKEY_DSA4:
723- ktype = OPENSSL_KEYTYPE_DSA;
724-
725- if (pkey->pkey.dsa != NULL) {
726- zval *dsa;
727-
728- ALLOC_INIT_ZVAL(dsa);
729- array_init(dsa);
730- OPENSSL_PKEY_GET_BN(dsa, p);
731- OPENSSL_PKEY_GET_BN(dsa, q);
732- OPENSSL_PKEY_GET_BN(dsa, g);
733- OPENSSL_PKEY_GET_BN(dsa, priv_key);
734- OPENSSL_PKEY_GET_BN(dsa, pub_key);
735- add_assoc_zval(return_value, "dsa", dsa);
736+ {
737+ DSA *dsa = EVP_PKEY_get0_DSA(pkey);
738+ ktype = OPENSSL_KEYTYPE_DSA;
739+
740+ if (dsa != NULL) {
741+ zval *z_dsa;
742+ const BIGNUM *p, *q, *g, *priv_key, *pub_key;
743+
744+ DSA_get0_pqg(dsa, &p, &q, &g);
745+ DSA_get0_key(dsa, &pub_key, &priv_key);
746+
747+ ALLOC_INIT_ZVAL(z_dsa);
748+ array_init(z_dsa);
749+ OPENSSL_PKEY_GET_BN(z_dsa, p);
750+ OPENSSL_PKEY_GET_BN(z_dsa, q);
751+ OPENSSL_PKEY_GET_BN(z_dsa, g);
752+ OPENSSL_PKEY_GET_BN(z_dsa, priv_key);
753+ OPENSSL_PKEY_GET_BN(z_dsa, pub_key);
754+ add_assoc_zval(return_value, "dsa", z_dsa);
755+ }
756 }
757 break;
758 case EVP_PKEY_DH:
759-
760- ktype = OPENSSL_KEYTYPE_DH;
761-
762- if (pkey->pkey.dh != NULL) {
763- zval *dh;
764-
765- ALLOC_INIT_ZVAL(dh);
766- array_init(dh);
767- OPENSSL_PKEY_GET_BN(dh, p);
768- OPENSSL_PKEY_GET_BN(dh, g);
769- OPENSSL_PKEY_GET_BN(dh, priv_key);
770- OPENSSL_PKEY_GET_BN(dh, pub_key);
771- add_assoc_zval(return_value, "dh", dh);
772+ {
773+ DH *dh = EVP_PKEY_get0_DH(pkey);
774+ ktype = OPENSSL_KEYTYPE_DH;
775+
776+ if (dh != NULL) {
777+ zval *z_dh;
778+ const BIGNUM *p, *q, *g, *priv_key, *pub_key;
779+
780+ DH_get0_pqg(dh, &p, &q, &g);
781+ DH_get0_key(dh, &pub_key, &priv_key);
782+
783+ ALLOC_INIT_ZVAL(z_dh);
784+ array_init(z_dh);
785+ OPENSSL_PKEY_GET_BN(z_dh, p);
786+ OPENSSL_PKEY_GET_BN(z_dh, g);
787+ OPENSSL_PKEY_GET_BN(z_dh, priv_key);
788+ OPENSSL_PKEY_GET_BN(z_dh, pub_key);
789+ add_assoc_zval(return_value, "dh", z_dh);
790+ }
791 }
792
793 break;
794 #ifdef HAVE_EVP_PKEY_EC
795 case EVP_PKEY_EC:
796 ktype = OPENSSL_KEYTYPE_EC;
797- if (pkey->pkey.ec != NULL) {
798+ if (EVP_PKEY_get0_EC_KEY(pkey) != NULL) {
799 zval *ec;
800 const EC_GROUP *ec_group;
801 int nid;
802@@ -4546,13 +4842,13 @@ PHP_FUNCTION(openssl_private_encrypt)
803 cryptedlen = EVP_PKEY_size(pkey);
804 cryptedbuf = emalloc(cryptedlen + 1);
805
806- switch (pkey->type) {
807+ switch (EVP_PKEY_id(pkey)) {
808 case EVP_PKEY_RSA:
809 case EVP_PKEY_RSA2:
810 successful = (RSA_private_encrypt(data_len,
811 (unsigned char *)data,
812 cryptedbuf,
813- pkey->pkey.rsa,
814+ EVP_PKEY_get0_RSA(pkey),
815 padding) == cryptedlen);
816 break;
817 default:
818@@ -4604,13 +4900,13 @@ PHP_FUNCTION(openssl_private_decrypt)
819 cryptedlen = EVP_PKEY_size(pkey);
820 crypttemp = emalloc(cryptedlen + 1);
821
822- switch (pkey->type) {
823+ switch (EVP_PKEY_id(pkey)) {
824 case EVP_PKEY_RSA:
825 case EVP_PKEY_RSA2:
826 cryptedlen = RSA_private_decrypt(data_len,
827 (unsigned char *)data,
828 crypttemp,
829- pkey->pkey.rsa,
830+ EVP_PKEY_get0_RSA(pkey),
831 padding);
832 if (cryptedlen != -1) {
833 cryptedbuf = emalloc(cryptedlen + 1);
834@@ -4669,13 +4965,13 @@ PHP_FUNCTION(openssl_public_encrypt)
835 cryptedlen = EVP_PKEY_size(pkey);
836 cryptedbuf = emalloc(cryptedlen + 1);
837
838- switch (pkey->type) {
839+ switch (EVP_PKEY_id(pkey)) {
840 case EVP_PKEY_RSA:
841 case EVP_PKEY_RSA2:
842 successful = (RSA_public_encrypt(data_len,
843 (unsigned char *)data,
844 cryptedbuf,
845- pkey->pkey.rsa,
846+ EVP_PKEY_get0_RSA(pkey),
847 padding) == cryptedlen);
848 break;
849 default:
850@@ -4728,13 +5024,13 @@ PHP_FUNCTION(openssl_public_decrypt)
851 cryptedlen = EVP_PKEY_size(pkey);
852 crypttemp = emalloc(cryptedlen + 1);
853
854- switch (pkey->type) {
855+ switch (EVP_PKEY_id(pkey)) {
856 case EVP_PKEY_RSA:
857 case EVP_PKEY_RSA2:
858 cryptedlen = RSA_public_decrypt(data_len,
859 (unsigned char *)data,
860 crypttemp,
861- pkey->pkey.rsa,
862+ EVP_PKEY_get0_RSA(pkey),
863 padding);
864 if (cryptedlen != -1) {
865 cryptedbuf = emalloc(cryptedlen + 1);
866@@ -4798,7 +5094,7 @@ PHP_FUNCTION(openssl_sign)
867 long keyresource = -1;
868 char * data;
869 int data_len;
870- EVP_MD_CTX md_ctx;
871+ EVP_MD_CTX *md_ctx;
872 zval *method = NULL;
873 long signature_algo = OPENSSL_ALGO_SHA1;
874 const EVP_MD *mdtype;
875@@ -4831,9 +5127,10 @@ PHP_FUNCTION(openssl_sign)
876 siglen = EVP_PKEY_size(pkey);
877 sigbuf = emalloc(siglen + 1);
878
879- EVP_SignInit(&md_ctx, mdtype);
880- EVP_SignUpdate(&md_ctx, data, data_len);
881- if (EVP_SignFinal (&md_ctx, sigbuf,(unsigned int *)&siglen, pkey)) {
882+ md_ctx = EVP_MD_CTX_create();
883+ EVP_SignInit(md_ctx, mdtype);
884+ EVP_SignUpdate(md_ctx, data, data_len);
885+ if (EVP_SignFinal (md_ctx, sigbuf,(unsigned int *)&siglen, pkey)) {
886 zval_dtor(signature);
887 sigbuf[siglen] = '\0';
888 ZVAL_STRINGL(signature, (char *)sigbuf, siglen, 0);
889@@ -4842,7 +5139,7 @@ PHP_FUNCTION(openssl_sign)
890 efree(sigbuf);
891 RETVAL_FALSE;
892 }
893- EVP_MD_CTX_cleanup(&md_ctx);
894+ EVP_MD_CTX_destroy(md_ctx);
895 if (keyresource == -1) {
896 EVP_PKEY_free(pkey);
897 }
898@@ -4856,7 +5153,7 @@ PHP_FUNCTION(openssl_verify)
899 zval **key;
900 EVP_PKEY *pkey;
901 int err;
902- EVP_MD_CTX md_ctx;
903+ EVP_MD_CTX *md_ctx;
904 const EVP_MD *mdtype;
905 long keyresource = -1;
906 char * data; int data_len;
907@@ -4890,10 +5187,11 @@ PHP_FUNCTION(openssl_verify)
908 RETURN_FALSE;
909 }
910
911- EVP_VerifyInit (&md_ctx, mdtype);
912- EVP_VerifyUpdate (&md_ctx, data, data_len);
913- err = EVP_VerifyFinal (&md_ctx, (unsigned char *)signature, signature_len, pkey);
914- EVP_MD_CTX_cleanup(&md_ctx);
915+ md_ctx = EVP_MD_CTX_create();
916+ EVP_VerifyInit (md_ctx, mdtype);
917+ EVP_VerifyUpdate (md_ctx, data, data_len);
918+ err = EVP_VerifyFinal (md_ctx, (unsigned char *)signature, signature_len, pkey);
919+ EVP_MD_CTX_destroy(md_ctx);
920
921 if (keyresource == -1) {
922 EVP_PKEY_free(pkey);
923@@ -4917,7 +5215,7 @@ PHP_FUNCTION(openssl_seal)
924 char *method =NULL;
925 int method_len = 0;
926 const EVP_CIPHER *cipher;
927- EVP_CIPHER_CTX ctx;
928+ EVP_CIPHER_CTX *ctx;
929
930 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szza/|s", &data, &data_len, &sealdata, &ekeys, &pubkeys, &method, &method_len) == FAILURE) {
931 return;
932@@ -4950,6 +5248,7 @@ PHP_FUNCTION(openssl_seal)
933 memset(eks, 0, sizeof(*eks) * nkeys);
934 key_resources = safe_emalloc(nkeys, sizeof(long), 0);
935 memset(key_resources, 0, sizeof(*key_resources) * nkeys);
936+ memset(pkeys, 0, sizeof(*pkeys) * nkeys);
937
938 /* get the public keys we are using to seal this data */
939 zend_hash_internal_pointer_reset_ex(pubkeysht, &pos);
940@@ -4967,27 +5266,28 @@ PHP_FUNCTION(openssl_seal)
941 i++;
942 }
943
944- if (!EVP_EncryptInit(&ctx,cipher,NULL,NULL)) {
945+ ctx = EVP_CIPHER_CTX_new();
946+ if (ctx == NULL || !EVP_EncryptInit(ctx,cipher,NULL,NULL)) {
947 RETVAL_FALSE;
948- EVP_CIPHER_CTX_cleanup(&ctx);
949+ EVP_CIPHER_CTX_free(ctx);
950 goto clean_exit;
951 }
952
953 #if 0
954 /* Need this if allow ciphers that require initialization vector */
955- ivlen = EVP_CIPHER_CTX_iv_length(&ctx);
956+ ivlen = EVP_CIPHER_CTX_iv_length(ctx);
957 iv = ivlen ? emalloc(ivlen + 1) : NULL;
958 #endif
959 /* allocate one byte extra to make room for \0 */
960- buf = emalloc(data_len + EVP_CIPHER_CTX_block_size(&ctx));
961- EVP_CIPHER_CTX_cleanup(&ctx);
962+ buf = emalloc(data_len + EVP_CIPHER_CTX_block_size(ctx));
963+ EVP_CIPHER_CTX_cleanup(ctx);
964
965- if (EVP_SealInit(&ctx, cipher, eks, eksl, NULL, pkeys, nkeys) <= 0 ||
966- !EVP_SealUpdate(&ctx, buf, &len1, (unsigned char *)data, data_len) ||
967- !EVP_SealFinal(&ctx, buf + len1, &len2)) {
968+ if (EVP_SealInit(ctx, cipher, eks, eksl, NULL, pkeys, nkeys) <= 0 ||
969+ !EVP_SealUpdate(ctx, buf, &len1, (unsigned char *)data, data_len) ||
970+ !EVP_SealFinal(ctx, buf + len1, &len2)) {
971 RETVAL_FALSE;
972 efree(buf);
973- EVP_CIPHER_CTX_cleanup(&ctx);
974+ EVP_CIPHER_CTX_free(ctx);
975 goto clean_exit;
976 }
977
978@@ -5018,7 +5318,7 @@ PHP_FUNCTION(openssl_seal)
979 efree(buf);
980 }
981 RETVAL_LONG(len1 + len2);
982- EVP_CIPHER_CTX_cleanup(&ctx);
983+ EVP_CIPHER_CTX_free(ctx);
984
985 clean_exit:
986 for (i=0; i<nkeys; i++) {
987@@ -5045,7 +5345,7 @@ PHP_FUNCTION(openssl_open)
988 int len1, len2;
989 unsigned char *buf;
990 long keyresource = -1;
991- EVP_CIPHER_CTX ctx;
992+ EVP_CIPHER_CTX *ctx;
993 char * data; int data_len;
994 char * ekey; int ekey_len;
995 char *method =NULL;
996@@ -5074,8 +5374,9 @@ PHP_FUNCTION(openssl_open)
997
998 buf = emalloc(data_len + 1);
999
1000- if (EVP_OpenInit(&ctx, cipher, (unsigned char *)ekey, ekey_len, NULL, pkey) && EVP_OpenUpdate(&ctx, buf, &len1, (unsigned char *)data, data_len)) {
1001- if (!EVP_OpenFinal(&ctx, buf + len1, &len2) || (len1 + len2 == 0)) {
1002+ ctx = EVP_CIPHER_CTX_new();
1003+ if (EVP_OpenInit(ctx, cipher, (unsigned char *)ekey, ekey_len, NULL, pkey) && EVP_OpenUpdate(ctx, buf, &len1, (unsigned char *)data, data_len)) {
1004+ if (!EVP_OpenFinal(ctx, buf + len1, &len2) || (len1 + len2 == 0)) {
1005 efree(buf);
1006 RETVAL_FALSE;
1007 } else {
1008@@ -5091,7 +5392,7 @@ PHP_FUNCTION(openssl_open)
1009 if (keyresource == -1) {
1010 EVP_PKEY_free(pkey);
1011 }
1012- EVP_CIPHER_CTX_cleanup(&ctx);
1013+ EVP_CIPHER_CTX_free(ctx);
1014 }
1015 /* }}} */
1016
1017@@ -5151,7 +5452,7 @@ PHP_FUNCTION(openssl_digest)
1018 char *data, *method;
1019 int data_len, method_len;
1020 const EVP_MD *mdtype;
1021- EVP_MD_CTX md_ctx;
1022+ EVP_MD_CTX *md_ctx;
1023 int siglen;
1024 unsigned char *sigbuf;
1025
1026@@ -5167,9 +5468,10 @@ PHP_FUNCTION(openssl_digest)
1027 siglen = EVP_MD_size(mdtype);
1028 sigbuf = emalloc(siglen + 1);
1029
1030- EVP_DigestInit(&md_ctx, mdtype);
1031- EVP_DigestUpdate(&md_ctx, (unsigned char *)data, data_len);
1032- if (EVP_DigestFinal (&md_ctx, (unsigned char *)sigbuf, (unsigned int *)&siglen)) {
1033+ md_ctx = EVP_MD_CTX_create();
1034+ EVP_DigestInit(md_ctx, mdtype);
1035+ EVP_DigestUpdate(md_ctx, (unsigned char *)data, data_len);
1036+ if (EVP_DigestFinal (md_ctx, (unsigned char *)sigbuf, (unsigned int *)&siglen)) {
1037 if (raw_output) {
1038 sigbuf[siglen] = '\0';
1039 RETVAL_STRINGL((char *)sigbuf, siglen, 0);
1040@@ -5185,6 +5487,8 @@ PHP_FUNCTION(openssl_digest)
1041 efree(sigbuf);
1042 RETVAL_FALSE;
1043 }
1044+
1045+ EVP_MD_CTX_destroy(md_ctx);
1046 }
1047 /* }}} */
1048
1049@@ -5230,7 +5534,7 @@ PHP_FUNCTION(openssl_encrypt)
1050 char *data, *method, *password, *iv = "";
1051 int data_len, method_len, password_len, iv_len = 0, max_iv_len;
1052 const EVP_CIPHER *cipher_type;
1053- EVP_CIPHER_CTX cipher_ctx;
1054+ EVP_CIPHER_CTX *cipher_ctx;
1055 int i=0, outlen, keylen;
1056 unsigned char *outbuf, *key;
1057 zend_bool free_iv;
1058@@ -5262,19 +5566,24 @@ PHP_FUNCTION(openssl_encrypt)
1059 outlen = data_len + EVP_CIPHER_block_size(cipher_type);
1060 outbuf = safe_emalloc(outlen, 1, 1);
1061
1062- EVP_EncryptInit(&cipher_ctx, cipher_type, NULL, NULL);
1063+ cipher_ctx = EVP_CIPHER_CTX_new();
1064+ if (!cipher_ctx) {
1065+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to create cipher context");
1066+ RETURN_FALSE;
1067+ }
1068+ EVP_EncryptInit(cipher_ctx, cipher_type, NULL, NULL);
1069 if (password_len > keylen) {
1070- EVP_CIPHER_CTX_set_key_length(&cipher_ctx, password_len);
1071+ EVP_CIPHER_CTX_set_key_length(cipher_ctx, password_len);
1072 }
1073- EVP_EncryptInit_ex(&cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
1074+ EVP_EncryptInit_ex(cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
1075 if (options & OPENSSL_ZERO_PADDING) {
1076- EVP_CIPHER_CTX_set_padding(&cipher_ctx, 0);
1077+ EVP_CIPHER_CTX_set_padding(cipher_ctx, 0);
1078 }
1079 if (data_len > 0) {
1080- EVP_EncryptUpdate(&cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
1081+ EVP_EncryptUpdate(cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
1082 }
1083 outlen = i;
1084- if (EVP_EncryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) {
1085+ if (EVP_EncryptFinal(cipher_ctx, (unsigned char *)outbuf + i, &i)) {
1086 outlen += i;
1087 if (options & OPENSSL_RAW_DATA) {
1088 outbuf[outlen] = '\0';
1089@@ -5301,7 +5610,8 @@ PHP_FUNCTION(openssl_encrypt)
1090 if (free_iv) {
1091 efree(iv);
1092 }
1093- EVP_CIPHER_CTX_cleanup(&cipher_ctx);
1094+ EVP_CIPHER_CTX_cleanup(cipher_ctx);
1095+ EVP_CIPHER_CTX_free(cipher_ctx);
1096 }
1097 /* }}} */
1098
1099@@ -5313,7 +5623,7 @@ PHP_FUNCTION(openssl_decrypt)
1100 char *data, *method, *password, *iv = "";
1101 int data_len, method_len, password_len, iv_len = 0;
1102 const EVP_CIPHER *cipher_type;
1103- EVP_CIPHER_CTX cipher_ctx;
1104+ EVP_CIPHER_CTX *cipher_ctx;
1105 int i, outlen, keylen;
1106 unsigned char *outbuf, *key;
1107 int base64_str_len;
1108@@ -5359,17 +5669,23 @@ PHP_FUNCTION(openssl_decrypt)
1109 outlen = data_len + EVP_CIPHER_block_size(cipher_type);
1110 outbuf = emalloc(outlen + 1);
1111
1112- EVP_DecryptInit(&cipher_ctx, cipher_type, NULL, NULL);
1113+ cipher_ctx = EVP_CIPHER_CTX_new();
1114+ if (!cipher_ctx) {
1115+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to create cipher context");
1116+ RETURN_FALSE;
1117+ }
1118+
1119+ EVP_DecryptInit(cipher_ctx, cipher_type, NULL, NULL);
1120 if (password_len > keylen) {
1121- EVP_CIPHER_CTX_set_key_length(&cipher_ctx, password_len);
1122+ EVP_CIPHER_CTX_set_key_length(cipher_ctx, password_len);
1123 }
1124- EVP_DecryptInit_ex(&cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
1125+ EVP_DecryptInit_ex(cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
1126 if (options & OPENSSL_ZERO_PADDING) {
1127- EVP_CIPHER_CTX_set_padding(&cipher_ctx, 0);
1128+ EVP_CIPHER_CTX_set_padding(cipher_ctx, 0);
1129 }
1130- EVP_DecryptUpdate(&cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
1131+ EVP_DecryptUpdate(cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
1132 outlen = i;
1133- if (EVP_DecryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) {
1134+ if (EVP_DecryptFinal(cipher_ctx, (unsigned char *)outbuf + i, &i)) {
1135 outlen += i;
1136 outbuf[outlen] = '\0';
1137 RETVAL_STRINGL((char *)outbuf, outlen, 0);
1138@@ -5386,7 +5702,8 @@ PHP_FUNCTION(openssl_decrypt)
1139 if (base64_str) {
1140 efree(base64_str);
1141 }
1142- EVP_CIPHER_CTX_cleanup(&cipher_ctx);
1143+ EVP_CIPHER_CTX_cleanup(cipher_ctx);
1144+ EVP_CIPHER_CTX_free(cipher_ctx);
1145 }
1146 /* }}} */
1147
1148@@ -5424,6 +5741,7 @@ PHP_FUNCTION(openssl_dh_compute_key)
1149 zval *key;
1150 char *pub_str;
1151 int pub_len;
1152+ DH *dh;
1153 EVP_PKEY *pkey;
1154 BIGNUM *pub;
1155 char *data;
1156@@ -5433,14 +5751,21 @@ PHP_FUNCTION(openssl_dh_compute_key)
1157 return;
1158 }
1159 ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, &key, -1, "OpenSSL key", le_key);
1160- if (!pkey || EVP_PKEY_type(pkey->type) != EVP_PKEY_DH || !pkey->pkey.dh) {
1161+ if (pkey == NULL) {
1162+ RETURN_FALSE;
1163+ }
1164+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) {
1165+ RETURN_FALSE;
1166+ }
1167+ dh = EVP_PKEY_get0_DH(pkey);
1168+ if (dh == NULL) {
1169 RETURN_FALSE;
1170 }
1171
1172 pub = BN_bin2bn((unsigned char*)pub_str, pub_len, NULL);
1173
1174- data = emalloc(DH_size(pkey->pkey.dh) + 1);
1175- len = DH_compute_key((unsigned char*)data, pub, pkey->pkey.dh);
1176+ data = emalloc(DH_size(dh) + 1);
1177+ len = DH_compute_key((unsigned char*)data, pub, dh);
1178
1179 if (len >= 0) {
1180 data[len] = 0;
1181diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c
1182index d549033..c2d477c 100644
1183--- a/ext/openssl/xp_ssl.c
1184+++ b/ext/openssl/xp_ssl.c
1185@@ -935,7 +935,7 @@ static int set_local_cert(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{ */
1186 static const SSL_METHOD *php_select_crypto_method(long method_value, int is_client TSRMLS_DC) /* {{{ */
1187 {
1188 if (method_value == STREAM_CRYPTO_METHOD_SSLv2) {
1189-#ifndef OPENSSL_NO_SSL2
1190+#if !defined(OPENSSL_NO_SSL2) && OPENSSL_VERSION_NUMBER < 0x10100000L
1191 return is_client ? SSLv2_client_method() : SSLv2_server_method();
1192 #else
1193 php_error_docref(NULL TSRMLS_CC, E_WARNING,
1194@@ -1588,12 +1588,26 @@ int php_openssl_setup_crypto(php_stream *stream,
1195 }
1196 /* }}} */
1197
1198+#define PHP_SSL_MAX_VERSION_LEN 32
1199+
1200+static char *php_ssl_cipher_get_version(const SSL_CIPHER *c, char *buffer, size_t max_len) /* {{{ */
1201+{
1202+ const char *version = SSL_CIPHER_get_version(c);
1203+ strncpy(buffer, version, max_len);
1204+ if (max_len <= strlen(version)) {
1205+ buffer[max_len - 1] = 0;
1206+ }
1207+ return buffer;
1208+}
1209+/* }}} */
1210+
1211 static zval *capture_session_meta(SSL *ssl_handle) /* {{{ */
1212 {
1213 zval *meta_arr;
1214 char *proto_str;
1215 long proto = SSL_version(ssl_handle);
1216 const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl_handle);
1217+ char version_str[PHP_SSL_MAX_VERSION_LEN];
1218
1219 switch (proto) {
1220 #if OPENSSL_VERSION_NUMBER >= 0x10001001L
1221@@ -1611,7 +1625,7 @@ static zval *capture_session_meta(SSL *ssl_handle) /* {{{ */
1222 add_assoc_string(meta_arr, "protocol", proto_str, 1);
1223 add_assoc_string(meta_arr, "cipher_name", (char *) SSL_CIPHER_get_name(cipher), 1);
1224 add_assoc_long(meta_arr, "cipher_bits", SSL_CIPHER_get_bits(cipher, NULL));
1225- add_assoc_string(meta_arr, "cipher_version", SSL_CIPHER_get_version(cipher), 1);
1226+ add_assoc_string(meta_arr, "cipher_version", php_ssl_cipher_get_version(cipher, version_str, PHP_SSL_MAX_VERSION_LEN), 1);
1227
1228 return meta_arr;
1229 }
1230diff --git a/ext/phar/util.c b/ext/phar/util.c
1231index 828be8f..06e4e55 100644
1232--- a/ext/phar/util.c
1233+++ b/ext/phar/util.c
1234@@ -1531,7 +1531,7 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
1235 BIO *in;
1236 EVP_PKEY *key;
1237 EVP_MD *mdtype = (EVP_MD *) EVP_sha1();
1238- EVP_MD_CTX md_ctx;
1239+ EVP_MD_CTX *md_ctx;
1240 #else
1241 int tempsig;
1242 #endif
1243@@ -1608,7 +1608,8 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
1244 return FAILURE;
1245 }
1246
1247- EVP_VerifyInit(&md_ctx, mdtype);
1248+ md_ctx = EVP_MD_CTX_create();
1249+ EVP_VerifyInit(md_ctx, mdtype);
1250 read_len = end_of_phar;
1251
1252 if (read_len > sizeof(buf)) {
1253@@ -1620,7 +1621,7 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
1254 php_stream_seek(fp, 0, SEEK_SET);
1255
1256 while (read_size && (len = php_stream_read(fp, (char*)buf, read_size)) > 0) {
1257- EVP_VerifyUpdate (&md_ctx, buf, len);
1258+ EVP_VerifyUpdate (md_ctx, buf, len);
1259 read_len -= (off_t)len;
1260
1261 if (read_len < read_size) {
1262@@ -1628,9 +1629,9 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
1263 }
1264 }
1265
1266- if (EVP_VerifyFinal(&md_ctx, (unsigned char *)sig, sig_len, key) != 1) {
1267+ if (EVP_VerifyFinal(md_ctx, (unsigned char *)sig, sig_len, key) != 1) {
1268 /* 1: signature verified, 0: signature does not match, -1: failed signature operation */
1269- EVP_MD_CTX_cleanup(&md_ctx);
1270+ EVP_MD_CTX_destroy(md_ctx);
1271
1272 if (error) {
1273 spprintf(error, 0, "broken openssl signature");
1274@@ -1639,7 +1640,7 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
1275 return FAILURE;
1276 }
1277
1278- EVP_MD_CTX_cleanup(&md_ctx);
1279+ EVP_MD_CTX_destroy(md_ctx);
1280 #endif
1281
1282 *signature_len = phar_hex_str((const char*)sig, sig_len, signature TSRMLS_CC);
1283--
12842.7.4
1285