]> granicus.if.org Git - php/commitdiff
couple of resource leaks fixes and use after free's
authorDavid Carlier <devnexen@gmail.com>
Mon, 27 Jun 2016 06:42:49 +0000 (07:42 +0100)
committerDavid Carlier <devnexen@gmail.com>
Mon, 27 Jun 2016 06:44:21 +0000 (07:44 +0100)
16 files changed:
NEWS
ext/curl/interface.c
ext/curl/multi.c
ext/curl/php_curl.h
ext/curl/share.c
ext/curl/tests/curl_multi_errno_strerror_001.phpt [new file with mode: 0644]
ext/curl/tests/curl_share_errno_strerror_001.phpt [new file with mode: 0644]
ext/opcache/zend_file_cache.c
ext/openssl/openssl.c
ext/openssl/tests/029.phpt [new file with mode: 0644]
ext/openssl/tests/ecc.phpt [new file with mode: 0644]
ext/openssl/tests/openssl_pkey_export_basic.phpt
ext/openssl/tests/openssl_pkey_get_details_basic.phpt
main/fastcgi.c
sapi/cli/ps_title.c
sapi/phpdbg/phpdbg.c

diff --git a/NEWS b/NEWS
index 18594c5ff56da3840d21f70deb6004189acda63f..ed47f0bcb042a0a4440fec7c480ec0865942b7cc 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2016, PHP 7.1.0beta1
 
+- CURL:
+  . Add curl_multi_errno(), curl_share_errno() and curl_share_strerror()
+       functions. (Pierrick)
+
 - PCRE:
   . Fixed bug #72476 (Memleak in jit_stack). (Laruence)
   . Fixed bug #72463 (mail fails with invalid argument). (Anatol)
@@ -9,6 +13,10 @@ PHP                                                                        NEWS
 - Standard:
   . array_multisort now uses zend_sort instead zend_qsort. (Laruence)
 
+- OpenSSL:
+  . Implemented FR #61204 (Add elliptic curve support for OpenSSL).
+    (Dominic Luechinger)
+
 23 Jun 2016, PHP 7.1.0alpha2
 
 - Core:
index 82e99864c22c7edbb0650081c1593e4b9553ef34..6ea744d460a94fab6b3b154ba88db95630e6a66b 100644 (file)
@@ -392,6 +392,10 @@ ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_close, 0)
        ZEND_ARG_INFO(0, mh)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_errno, 0)
+       ZEND_ARG_INFO(0, mh)
+ZEND_END_ARG_INFO()
+
 #if LIBCURL_VERSION_NUM >= 0x070c00 /* Available since 7.12.0 */
 ZEND_BEGIN_ARG_INFO(arginfo_curl_strerror, 0)
        ZEND_ARG_INFO(0, errornum)
@@ -400,6 +404,10 @@ ZEND_END_ARG_INFO()
 ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_strerror, 0)
        ZEND_ARG_INFO(0, errornum)
 ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_curl_share_strerror, 0)
+       ZEND_ARG_INFO(0, errornum)
+ZEND_END_ARG_INFO()
 #endif
 
 ZEND_BEGIN_ARG_INFO(arginfo_curl_share_init, 0)
@@ -415,6 +423,10 @@ ZEND_BEGIN_ARG_INFO(arginfo_curl_share_setopt, 0)
        ZEND_ARG_INFO(0, value)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_INFO(arginfo_curl_share_errno, 0)
+       ZEND_ARG_INFO(0, sh)
+ZEND_END_ARG_INFO()
+
 #if LIBCURL_VERSION_NUM >= 0x071200 /* Available since 7.18.0 */
 ZEND_BEGIN_ARG_INFO(arginfo_curl_pause, 0)
        ZEND_ARG_INFO(0, ch)
@@ -445,6 +457,7 @@ const zend_function_entry curl_functions[] = {
 #if LIBCURL_VERSION_NUM >= 0x070c00 /* 7.12.0 */
        PHP_FE(curl_strerror,            arginfo_curl_strerror)
        PHP_FE(curl_multi_strerror,      arginfo_curl_multi_strerror)
+       PHP_FE(curl_share_strerror,      arginfo_curl_share_strerror)
 #endif
 #if LIBCURL_VERSION_NUM >= 0x070c01 /* 7.12.1 */
        PHP_FE(curl_reset,               arginfo_curl_reset)
@@ -464,12 +477,14 @@ const zend_function_entry curl_functions[] = {
        PHP_FE(curl_multi_getcontent,    arginfo_curl_multi_getcontent)
        PHP_FE(curl_multi_info_read,     arginfo_curl_multi_info_read)
        PHP_FE(curl_multi_close,         arginfo_curl_multi_close)
+       PHP_FE(curl_multi_errno,         arginfo_curl_multi_errno)
 #if LIBCURL_VERSION_NUM >= 0x070f04 /* 7.15.4 */
        PHP_FE(curl_multi_setopt,        arginfo_curl_multi_setopt)
 #endif
        PHP_FE(curl_share_init,          arginfo_curl_share_init)
        PHP_FE(curl_share_close,         arginfo_curl_share_close)
        PHP_FE(curl_share_setopt,        arginfo_curl_share_setopt)
+       PHP_FE(curl_share_errno,         arginfo_curl_share_errno)
        PHP_FE(curl_file_create,         arginfo_curlfile_create)
        PHP_FE_END
 };
index ab6d56c4383c9142fce7fdad3ff6a459a81e92dd..da99f8f140c3dbccb8ddd887bc9db2d8cdd4de6c 100644 (file)
@@ -49,6 +49,8 @@
 #include <unistd.h>
 #endif
 
+#define SAVE_CURLM_ERROR(__handle, __err) (__handle)->err.no = (int) __err;
+
 /* {{{ proto resource curl_multi_init(void)
    Returns a new cURL multi handle */
 PHP_FUNCTION(curl_multi_init)
@@ -77,6 +79,7 @@ PHP_FUNCTION(curl_multi_add_handle)
        php_curlm *mh;
        php_curl  *ch;
        zval tmp_val;
+       CURLMcode error = CURLM_OK;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &z_mh, &z_ch) == FAILURE) {
                return;
@@ -97,7 +100,10 @@ PHP_FUNCTION(curl_multi_add_handle)
 
        zend_llist_add_element(&mh->easyh, &tmp_val);
 
-       RETURN_LONG((zend_long)curl_multi_add_handle(mh->multi, ch->cp));
+       error = curl_multi_add_handle(mh->multi, ch->cp);
+       SAVE_CURLM_ERROR(mh, error);
+
+       RETURN_LONG((zend_long) error);
 }
 /* }}} */
 
@@ -137,6 +143,7 @@ PHP_FUNCTION(curl_multi_remove_handle)
        zval      *z_ch;
        php_curlm *mh;
        php_curl  *ch;
+       CURLMcode error = CURLM_OK;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &z_mh, &z_ch) == FAILURE) {
                return;
@@ -150,7 +157,10 @@ PHP_FUNCTION(curl_multi_remove_handle)
                RETURN_FALSE;
        }
 
-       RETVAL_LONG((zend_long)curl_multi_remove_handle(mh->multi, ch->cp));
+       error = curl_multi_remove_handle(mh->multi, ch->cp);
+       SAVE_CURLM_ERROR(mh, error);
+
+       RETVAL_LONG((zend_long) error);
        zend_llist_del_element(&mh->easyh, z_ch, (int (*)(void *, void *))curl_compare_resources);
 
 }
@@ -178,6 +188,7 @@ PHP_FUNCTION(curl_multi_select)
        int             maxfd;
        double          timeout = 1.0;
        struct timeval  to;
+       CURLMcode error = CURLM_OK;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|d", &z_mh, &timeout) == FAILURE) {
                return;
@@ -193,7 +204,9 @@ PHP_FUNCTION(curl_multi_select)
        FD_ZERO(&writefds);
        FD_ZERO(&exceptfds);
 
-       curl_multi_fdset(mh->multi, &readfds, &writefds, &exceptfds, &maxfd);
+       error = curl_multi_fdset(mh->multi, &readfds, &writefds, &exceptfds, &maxfd);
+       SAVE_CURLM_ERROR(mh, error);
+
        if (maxfd == -1) {
                RETURN_LONG(-1);
        }
@@ -209,7 +222,7 @@ PHP_FUNCTION(curl_multi_exec)
        zval      *z_still_running;
        php_curlm *mh;
        int        still_running;
-       int        result;
+       CURLMcode error = CURLM_OK;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz/", &z_mh, &z_still_running) == FAILURE) {
                return;
@@ -237,10 +250,11 @@ PHP_FUNCTION(curl_multi_exec)
 
        convert_to_long(z_still_running);
        still_running = Z_LVAL_P(z_still_running);
-       result = curl_multi_perform(mh->multi, &still_running);
+       error = curl_multi_perform(mh->multi, &still_running);
        ZVAL_LONG(z_still_running, still_running);
 
-       RETURN_LONG(result);
+       SAVE_CURLM_ERROR(mh, error);
+       RETURN_LONG((zend_long) error);
 }
 /* }}} */
 
@@ -383,6 +397,25 @@ void _php_curl_multi_close(zend_resource *rsrc) /* {{{ */
 }
 /* }}} */
 
+/* {{{ proto int curl_multi_errno(resource mh)
+         Return an integer containing the last multi curl error number */
+PHP_FUNCTION(curl_multi_errno)
+{
+       zval        *z_mh;
+       php_curlm   *mh;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_mh) == FAILURE) {
+               return;
+       }
+
+       if ((mh = (php_curlm *)zend_fetch_resource(Z_RES_P(z_mh), le_curl_multi_handle_name, le_curl_multi_handle)) == NULL) {
+               RETURN_FALSE;
+       }
+
+       RETURN_LONG(mh->err.no);
+}
+/* }}} */
+
 #if LIBCURL_VERSION_NUM >= 0x070c00 /* Available since 7.12.0 */
 /* {{{ proto bool curl_multi_strerror(int code)
          return string describing error code */
@@ -433,6 +466,7 @@ static int _php_curl_multi_setopt(php_curlm *mh, zend_long option, zval *zvalue,
                        break;
        }
 
+       SAVE_CURLM_ERROR(mh, error);
        if (error != CURLM_OK) {
                return 1;
        } else {
index d3a22c7c3022b9061642101d05a1e207568b7a67..02077aaf2702a79e755ad3550a511fb6c86d868d 100644 (file)
@@ -90,14 +90,17 @@ PHP_FUNCTION(curl_multi_info_read);
 PHP_FUNCTION(curl_multi_init);
 PHP_FUNCTION(curl_multi_remove_handle);
 PHP_FUNCTION(curl_multi_select);
+PHP_FUNCTION(curl_multi_errno);
 
 PHP_FUNCTION(curl_share_close);
 PHP_FUNCTION(curl_share_init);
 PHP_FUNCTION(curl_share_setopt);
+PHP_FUNCTION(curl_share_errno);
 
 #if LIBCURL_VERSION_NUM >= 0x070c00 /* 7.12.0 */
 PHP_FUNCTION(curl_strerror);
 PHP_FUNCTION(curl_multi_strerror);
+PHP_FUNCTION(curl_share_strerror);
 #endif
 
 #if LIBCURL_VERSION_NUM >= 0x070c01 /* 7.12.1 */
@@ -114,6 +117,7 @@ PHP_FUNCTION(curl_multi_setopt);
 #if LIBCURL_VERSION_NUM >= 0x071200 /* 7.18.0 */
 PHP_FUNCTION(curl_pause);
 #endif
+
 PHP_FUNCTION(curl_file_create);
 
 
@@ -190,10 +194,16 @@ typedef struct {
        int         still_running;
        CURLM      *multi;
        zend_llist  easyh;
+       struct {
+               int no;
+       } err;
 } php_curlm;
 
 typedef struct {
        CURLSH                   *share;
+       struct {
+               int no;
+       } err;
 } php_curlsh;
 
 void _php_curl_cleanup_handle(php_curl *);
index 3806e2778bf302da2867c0c4a4b7f7e3e774bec2..983cc2750e23feb4bf046eb4698772a5612bbe6a 100644 (file)
@@ -32,6 +32,8 @@
 
 #include <curl/curl.h>
 
+#define SAVE_CURLSH_ERROR(__handle, __err) (__handle)->err.no = (int) __err;
+
 /* {{{ proto void curl_share_init()
    Initialize a share curl handle */
 PHP_FUNCTION(curl_share_init)
@@ -85,6 +87,7 @@ static int _php_curl_share_setopt(php_curlsh *sh, zend_long option, zval *zvalue
                        break;
        }
 
+       SAVE_CURLSH_ERROR(sh, error);
        if (error != CURLSHE_OK) {
                return 1;
        } else {
@@ -128,6 +131,48 @@ void _php_curl_share_close(zend_resource *rsrc) /* {{{ */
 }
 /* }}} */
 
+/* {{{ proto int curl_share_errno(resource mh)
+         Return an integer containing the last share curl error number */
+PHP_FUNCTION(curl_share_errno)
+{
+       zval        *z_sh;
+       php_curlsh  *sh;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_sh) == FAILURE) {
+               return;
+       }
+
+       if ((sh = (php_curlsh *)zend_fetch_resource(Z_RES_P(z_sh), le_curl_share_handle_name, le_curl_share_handle)) == NULL) {
+               RETURN_FALSE;
+       }
+
+       RETURN_LONG(sh->err.no);
+}
+/* }}} */
+
+
+#if LIBCURL_VERSION_NUM >= 0x070c00 /* Available since 7.12.0 */
+/* {{{ proto bool curl_share_strerror(int code)
+         return string describing error code */
+PHP_FUNCTION(curl_share_strerror)
+{
+       zend_long code;
+       const char *str;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &code) == FAILURE) {
+               return;
+       }
+
+       str = curl_share_strerror(code);
+       if (str) {
+               RETURN_STRING(str);
+       } else {
+               RETURN_NULL();
+       }
+}
+/* }}} */
+#endif
+
 #endif
 
 /*
diff --git a/ext/curl/tests/curl_multi_errno_strerror_001.phpt b/ext/curl/tests/curl_multi_errno_strerror_001.phpt
new file mode 100644 (file)
index 0000000..1fcdfe9
--- /dev/null
@@ -0,0 +1,30 @@
+--TEST--
+curl_multi_errno and curl_multi_strerror basic test
+--SKIPIF--
+<?php
+if (!extension_loaded("curl")) {
+           exit("skip curl extension not loaded");
+}
+$curl_version = curl_version();
+if ($curl_version['version_number'] < 0x070f04) {
+       exit("skip: test works only with curl >= 7.15.4");
+}
+?>
+--FILE--
+<?php
+
+$mh = curl_multi_init();
+$errno = curl_multi_errno($mh);
+echo $errno . PHP_EOL;
+echo curl_multi_strerror($errno) . PHP_EOL;
+
+@curl_multi_setopt($mh, -1, -1);
+$errno = curl_multi_errno($mh);
+echo $errno . PHP_EOL;
+echo curl_multi_strerror($errno) . PHP_EOL;
+?>
+--EXPECTF--
+0
+No error
+6
+Unknown option
diff --git a/ext/curl/tests/curl_share_errno_strerror_001.phpt b/ext/curl/tests/curl_share_errno_strerror_001.phpt
new file mode 100644 (file)
index 0000000..91476cd
--- /dev/null
@@ -0,0 +1,30 @@
+--TEST--
+curl_share_errno and curl_share_strerror basic test
+--SKIPIF--
+<?php
+if (!extension_loaded("curl")) {
+           exit("skip curl extension not loaded");
+}
+$curl_version = curl_version();
+if ($curl_version['version_number'] < 0x070c00) {
+       exit("skip: test works only with curl >= 7.12.0");
+}
+?>
+--FILE--
+<?php
+
+$sh = curl_share_init();
+$errno = curl_share_errno($sh);
+echo $errno . PHP_EOL;
+echo curl_share_strerror($errno) . PHP_EOL;
+
+@curl_share_setopt($sh, -1, -1);
+$errno = curl_share_errno($sh);
+echo $errno . PHP_EOL;
+echo curl_share_strerror($errno) . PHP_EOL;
+?>
+--EXPECTF--
+0
+No error
+1
+Unknown share option
index 6ac4f0e35f6452c52e0c7a9b2960c8f3edf3fc56..6d34851352a4284f1b6dfc6afc01a1eab375ae06 100644 (file)
@@ -791,6 +791,7 @@ int zend_file_cache_script_store(zend_persistent_script *script, int in_shm)
        if (writev(fd, vec, 3) != (ssize_t)(sizeof(info) + script->size + info.str_size)) {
                zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot write to file '%s'\n", filename);
                zend_string_release((zend_string*)ZCG(mem));
+               close(fd);
                efree(mem);
                unlink(filename);
                efree(filename);
@@ -804,6 +805,7 @@ int zend_file_cache_script_store(zend_persistent_script *script, int in_shm)
                ) {
                zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot write to file '%s'\n", filename);
                zend_string_release((zend_string*)ZCG(mem));
+               close(fd);
                efree(mem);
                unlink(filename);
                efree(filename);
index 32c27c326f9d889e3c6a5bfb729de78004e97679..95e5b54f1e9ef43d9bb5e9b79d199d5281234241 100644 (file)
@@ -118,6 +118,9 @@ enum php_openssl_cipher_type {
 
 PHP_FUNCTION(openssl_get_md_methods);
 PHP_FUNCTION(openssl_get_cipher_methods);
+#ifdef HAVE_EVP_PKEY_EC
+PHP_FUNCTION(openssl_get_curve_names);
+#endif
 
 PHP_FUNCTION(openssl_digest);
 PHP_FUNCTION(openssl_encrypt);
@@ -379,6 +382,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_get_cipher_methods, 0, 0, 0)
        ZEND_ARG_INFO(0, aliases)
 ZEND_END_ARG_INFO()
 
+#ifdef HAVE_EVP_PKEY_EC
+ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_get_curve_names, 0, 0, 0)
+ZEND_END_ARG_INFO()
+#endif
+
 ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_digest, 0, 0, 2)
        ZEND_ARG_INFO(0, data)
        ZEND_ARG_INFO(0, method)
@@ -515,6 +523,9 @@ const zend_function_entry openssl_functions[] = {
 
        PHP_FE(openssl_get_md_methods,          arginfo_openssl_get_md_methods)
        PHP_FE(openssl_get_cipher_methods,      arginfo_openssl_get_cipher_methods)
+#ifdef HAVE_EVP_PKEY_EC
+       PHP_FE(openssl_get_curve_names,         arginfo_openssl_get_curve_names)
+#endif
 
        PHP_FE(openssl_dh_compute_key,          arginfo_openssl_dh_compute_key)
 
@@ -672,6 +683,10 @@ struct php_x509_request { /* {{{ */
 
        int priv_key_encrypt;
 
+#ifdef HAVE_EVP_PKEY_EC
+       int curve_name;
+#endif
+
        EVP_PKEY * priv_key;
 
        const EVP_CIPHER * priv_key_encrypt_cipher;
@@ -761,7 +776,7 @@ static time_t asn1_time_to_time_t(ASN1_UTCTIME * timestr) /* {{{ */
        This is how the time string is formatted:
 
    snprintf(p, sizeof(p), "%02d%02d%02d%02d%02d%02dZ",ts->tm_year%100,
-      ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
+         ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
 */
 
        time_t ret;
@@ -1035,6 +1050,18 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
        }
 
        PHP_SSL_CONFIG_SYNTAX_CHECK(extensions_section);
+#ifdef HAVE_EVP_PKEY_EC
+       /* set the ec group curve name */
+       req->curve_name = NID_undef;
+       if (optional_args && (item = zend_hash_str_find(Z_ARRVAL_P(optional_args), "curve_name", sizeof("curve_name")-1)) != NULL
+               && Z_TYPE_P(item) == IS_STRING) {
+               req->curve_name = OBJ_sn2nid(Z_STRVAL_P(item));
+               if (req->curve_name == NID_undef) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown elliptic curve (short) name %s", Z_STRVAL_P(item));
+                       return FAILURE;
+               }
+       }
+#endif
 
        /* set the string mask */
        str = CONF_get_string(req->req_config, req->section_name, "string_mask");
@@ -3730,6 +3757,26 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
                                        }
                                }
                                break;
+#endif
+#ifdef HAVE_EVP_PKEY_EC
+                       case OPENSSL_KEYTYPE_EC:
+                               {
+                                       if (req->curve_name == NID_undef) {
+                                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing configuration value: 'curve_name' not set");
+                                               return NULL;
+                                       }
+                                       EC_KEY *eckey = EC_KEY_new_by_curve_name(req->curve_name);
+                                       if (eckey) {
+                                               EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
+                                               if (EC_KEY_generate_key(eckey) &&
+                                                       EVP_PKEY_assign_EC_KEY(req->priv_key, eckey)) {
+                                                       return_val = req->priv_key;
+                                               } else {
+                                                       EC_KEY_free(eckey);
+                                               }
+                                       }
+                               }
+                               break;
 #endif
                        default:
                                php_error_docref(NULL, E_WARNING, "Unsupported private key type");
@@ -3805,24 +3852,30 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey)
 }
 /* }}} */
 
-#define OPENSSL_PKEY_GET_BN(_type, _name) do {                                                 \
-               if (pkey->pkey._type->_name != NULL) {                                                  \
-                       int len = BN_num_bytes(pkey->pkey._type->_name);                        \
-                       zend_string *str = zend_string_alloc(len, 0);                           \
-                       BN_bn2bin(pkey->pkey._type->_name, (unsigned char*)ZSTR_VAL(str));      \
-                       ZSTR_VAL(str)[len] = 0;                                                                         \
-                       add_assoc_str(&_type, #_name, str);                                                     \
-               }                                                                                                                               \
-       } while (0)
-
-#define OPENSSL_PKEY_SET_BN(_ht, _type, _name) do {                                            \
-               zval *bn;                                                                                                               \
+#define OPENSSL_GET_BN(_array, _bn, _name) do {                                                \
+               if (_bn != NULL) {                                                      \
+                       int len = BN_num_bytes(_bn);                                    \
+                       zend_string *str = zend_string_alloc(len, 0);                   \
+                       BN_bn2bin(_bn, (unsigned char*)ZSTR_VAL(str));                  \
+                       ZSTR_VAL(str)[len] = 0;                                         \
+                       add_assoc_str(&_array, #_name, str);                            \
+               }                                                                       \
+       } while (0);
+
+#define OPENSSL_PKEY_GET_BN(_type, _name) do {                                         \
+               if (pkey->pkey._type->_name != NULL) {                                  \
+                       OPENSSL_GET_BN(_type, pkey->pkey._type->_name, _name);          \
+               }                                                                       \
+       } while (0);
+
+#define OPENSSL_PKEY_SET_BN(_ht, _type, _name) do {                                    \
+               zval *bn;                                                               \
                if ((bn = zend_hash_str_find(_ht, #_name, sizeof(#_name)-1)) != NULL && \
-                               Z_TYPE_P(bn) == IS_STRING) {                                                    \
-                       _type->_name = BN_bin2bn(                                                                       \
-                               (unsigned char*)Z_STRVAL_P(bn),                                                 \
-                               (int)Z_STRLEN_P(bn), NULL);                                                                     \
-           }                                                               \
+                               Z_TYPE_P(bn) == IS_STRING) {                            \
+                       _type->_name = BN_bin2bn(                                       \
+                               (unsigned char*)Z_STRVAL_P(bn),                         \
+                               (int)Z_STRLEN_P(bn), NULL);                             \
+               }                                                                               \
        } while (0);
 
 /* {{{ php_openssl_pkey_init_dsa */
@@ -3968,6 +4021,118 @@ PHP_FUNCTION(openssl_pkey_new)
                                php_openssl_store_errors();
                        }
                        RETURN_FALSE;
+#ifdef HAVE_EVP_PKEY_EC
+               } else if ((data = zend_hash_str_find(Z_ARRVAL_P(args), "ec", sizeof("ec") - 1)) != NULL &&
+                       Z_TYPE_P(data) == IS_ARRAY) {
+                       EC_KEY *eckey = NULL;
+                       EC_GROUP *group = NULL;
+                       EC_POINT *pnt = NULL;
+                       const BIGNUM *d;
+                       pkey = EVP_PKEY_new();
+                       if (pkey) {
+                               eckey = EC_KEY_new();
+                               if (eckey) {
+                                       EC_GROUP *group = NULL;
+                                       zval *bn;
+                                       zval *x;
+                                       zval *y;
+
+                                       if ((bn = zend_hash_str_find(Z_ARRVAL_P(data), "curve_name", sizeof("curve_name") - 1)) != NULL &&
+                                                       Z_TYPE_P(bn) == IS_STRING) {
+                                               int nid = OBJ_sn2nid(Z_STRVAL_P(bn));
+                                               if (nid != NID_undef) {
+                                                       group = EC_GROUP_new_by_curve_name(nid);
+                                                       if (!group) {
+                                                               php_openssl_store_errors();
+                                                               goto clean_exit;
+                                                       }
+                                                       EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
+                                                       EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED);
+                                                       if (!EC_KEY_set_group(eckey, group)) {
+                                                               php_openssl_store_errors();
+                                                               goto clean_exit;
+                                                       }
+                                               }
+                                       }
+
+                                       if (group == NULL) {
+                                               php_error_docref(NULL, E_WARNING, "Unknown curve_name");
+                                               goto clean_exit;
+                                       }
+
+                                       // The public key 'pnt' can be calculated from 'd' or is defined by 'x' and 'y'
+                                       if ((bn = zend_hash_str_find(Z_ARRVAL_P(data), "d", sizeof("d") - 1)) != NULL &&
+                                                       Z_TYPE_P(bn) == IS_STRING) {
+                                               d = BN_bin2bn((unsigned char*) Z_STRVAL_P(bn), Z_STRLEN_P(bn), NULL);
+                                               if (!EC_KEY_set_private_key(eckey, d)) {
+                                                       php_openssl_store_errors();
+                                                       goto clean_exit;
+                                               }
+                                               // Calculate the public key by multiplying the Point Q with the public key
+                                               // P = d * Q
+                                               pnt = EC_POINT_new(group);
+                                               if (!pnt || !EC_POINT_mul(group, pnt, d, NULL, NULL, NULL)) {
+                                                       php_openssl_store_errors();
+                                                       goto clean_exit;
+                                               }
+                                       } else if ((x = zend_hash_str_find(Z_ARRVAL_P(data), "x", sizeof("x") - 1)) != NULL &&
+                                                       Z_TYPE_P(x) == IS_STRING &&
+                                                       (y = zend_hash_str_find(Z_ARRVAL_P(data), "y", sizeof("y") - 1)) != NULL &&
+                                                       Z_TYPE_P(y) == IS_STRING) {
+                                               pnt = EC_POINT_new(group);
+                                               if (pnt == NULL) {
+                                                       php_openssl_store_errors();
+                                                       goto clean_exit;
+                                               }
+                                               if (!EC_POINT_set_affine_coordinates_GFp(
+                                                               group, pnt, BN_bin2bn((unsigned char*) Z_STRVAL_P(x), Z_STRLEN_P(x), NULL),
+                                                               BN_bin2bn((unsigned char*) Z_STRVAL_P(y), Z_STRLEN_P(y), NULL), NULL)) {
+                                                       php_openssl_store_errors();
+                                                       goto clean_exit;
+                                               }
+                                       }
+
+                                       if (pnt != NULL) {
+                                               if (!EC_KEY_set_public_key(eckey, pnt)) {
+                                                       php_openssl_store_errors();
+                                                       goto clean_exit;
+                                               }
+                                               EC_POINT_free(pnt);
+                                               pnt = NULL;
+                                       }
+
+                                       if (!EC_KEY_check_key(eckey)) {
+                                               PHP_OPENSSL_RAND_ADD_TIME();
+                                               EC_KEY_generate_key(eckey);
+                                               php_openssl_store_errors();
+                                       }
+                                       if (EC_KEY_check_key(eckey) && EVP_PKEY_assign_EC_KEY(pkey, eckey)) {
+                                               EC_GROUP_free(group);
+                                               RETURN_RES(zend_register_resource(pkey, le_key));
+                                       } else {
+                                               php_openssl_store_errors();
+                                       }
+                               } else {
+                                       php_openssl_store_errors();
+                               }
+                       } else {
+                               php_openssl_store_errors();
+                       }
+clean_exit:
+                       if (pnt != NULL) {
+                               EC_POINT_free(pnt);
+                       }
+                       if (group != NULL) {
+                               EC_GROUP_free(group);
+                       }
+                       if (eckey != NULL) {
+                               EC_KEY_free(eckey);
+                       }
+                       if (pkey != NULL) {
+                               EVP_PKEY_free(pkey);
+                       }
+                       RETURN_FALSE;
+#endif
                }
        }
 
@@ -4303,13 +4468,18 @@ PHP_FUNCTION(openssl_pkey_get_details)
                        if (pkey->pkey.ec != NULL) {
                                zval ec;
                                const EC_GROUP *ec_group;
+                               const EC_POINT *pub;
                                int nid;
                                char *crv_sn;
                                ASN1_OBJECT *obj;
                                // openssl recommends a buffer length of 80
                                char oir_buf[80];
+                               const EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(pkey);
+                               BIGNUM *x = BN_new();
+                               BIGNUM *y = BN_new();
+                               const BIGNUM *d;
 
-                               ec_group = EC_KEY_get0_group(EVP_PKEY_get1_EC_KEY(pkey));
+                               ec_group = EC_KEY_get0_group(ec_key);
 
                                // Curve nid (numerical identifier) used for ASN1 mapping
                                nid = EC_GROUP_get_curve_name(ec_group);
@@ -4327,11 +4497,27 @@ PHP_FUNCTION(openssl_pkey_get_details)
                                obj = OBJ_nid2obj(nid);
                                if (obj != NULL) {
                                        int oir_len = OBJ_obj2txt(oir_buf, sizeof(oir_buf), obj, 1);
-                                       add_assoc_stringl(&ec, "curve_oid", (char*)oir_buf, oir_len);
+                                       add_assoc_stringl(&ec, "curve_oid", (char*) oir_buf, oir_len);
                                        ASN1_OBJECT_free(obj);
                                }
 
+                               pub = EC_KEY_get0_public_key(ec_key);
+
+                               if (EC_POINT_get_affine_coordinates_GFp(ec_group, pub, x, y, NULL)) {
+                                       OPENSSL_GET_BN(ec, x, x);
+                                       OPENSSL_GET_BN(ec, y, y);
+                               } else {
+                                       php_openssl_store_errors();
+                               }
+
+                               if ((d = EC_KEY_get0_private_key(pkey->pkey.ec)) != NULL) {
+                                       OPENSSL_GET_BN(ec, d, d);
+                               }
+
                                add_assoc_zval(return_value, "ec", &ec);
+
+                               BN_free(x);
+                               BN_free(y);
                        }
                        break;
 #endif
@@ -5540,6 +5726,33 @@ PHP_FUNCTION(openssl_get_cipher_methods)
 }
 /* }}} */
 
+/* {{{ proto array openssl_get_curve_names()
+   Return array of available elliptic curves */
+#ifdef HAVE_EVP_PKEY_EC
+PHP_FUNCTION(openssl_get_curve_names)
+{
+       EC_builtin_curve *curves = NULL;
+       const char *sname;
+       int i;
+       size_t len = EC_get_builtin_curves(NULL, 0);
+
+       curves = emalloc(sizeof(EC_builtin_curve) * len);
+       if (!EC_get_builtin_curves(curves, len)) {
+               RETURN_FALSE;
+       }
+
+       array_init(return_value);
+       for (i = 0; i < len; i++) {
+               sname = OBJ_nid2sn(curves[i].nid);
+               if (sname != NULL) {
+                       add_next_index_string(return_value, sname);
+               }
+       }
+       efree(curves);
+}
+#endif
+/* }}} */
+
 /* {{{ proto string openssl_digest(string data, string method [, bool raw_output=false])
    Computes digest hash value for given data using given method, returns raw or binhex encoded string */
 PHP_FUNCTION(openssl_digest)
diff --git a/ext/openssl/tests/029.phpt b/ext/openssl/tests/029.phpt
new file mode 100644 (file)
index 0000000..cf43e0e
--- /dev/null
@@ -0,0 +1,254 @@
+--TEST--
+openssl_pkey_new() with EC key
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl")) die("skip");
+if (!defined("OPENSSL_KEYTYPE_EC")) die("skip no EC available");
+?>
+--FILE--
+<?php
+$key = openssl_pkey_get_private("file://" . dirname(__FILE__) . "/private_ec.key");
+
+$details = openssl_pkey_get_details($key);
+print_r($details);
+
+echo "Use details an create the same key pair\n";
+$key2 = openssl_pkey_new($details);
+$details2 = openssl_pkey_get_details($key2);
+print_r($details2);
+var_dump(array_diff($details["ec"], $details2["ec"]));
+
+echo "Missing 'd' parameter (private key part) => no private key informations\n";
+$detailsCopy3 = $details;
+unset($detailsCopy3["ec"]["d"]);
+$key3 = openssl_pkey_new($detailsCopy3);
+$details3 = openssl_pkey_get_details($key3);
+print_r($details3);
+var_dump(array_diff($details["ec"], $details3["ec"]));
+$privateKey3 = openssl_pkey_get_private($key3);
+var_dump($privateKey3);
+$publicKey3 = openssl_pkey_get_public($key3);
+var_dump($publicKey3);
+var_dump($details["key"] === $details3["key"]);
+
+echo "Missing 'x' parameter will not change the details. The public key is calculated from the private key 'd'\n";
+$detailsCopy4 = $details;
+unset($detailsCopy4["ec"]["x"]);
+$key4 = openssl_pkey_new($detailsCopy4);
+$details4 = openssl_pkey_get_details($key4);
+print_r($details4);
+var_dump(array_diff($details["ec"], $details4["ec"]));
+
+echo "Missing 'y' parameter will not change the details. The public key is calculated from the private key 'd'\n";
+$detailsCopy5 = $details;
+unset($detailsCopy5["ec"]["y"]);
+$key5 = openssl_pkey_new($detailsCopy5);
+$details5 = openssl_pkey_get_details($key5);
+print_r($details5);
+var_dump(array_diff($details["ec"], $details5["ec"]));
+
+echo "Missing 'd' and 'x' parameters will generate a new public key pair\n";
+$detailsCopy6 = $details;
+unset($detailsCopy6["ec"]["d"]);
+unset($detailsCopy6["ec"]["x"]);
+$key6 = openssl_pkey_new($detailsCopy6);
+$details6 = openssl_pkey_get_details($key6);
+print_r($details6);
+var_dump(array_diff($details["ec"], $details6["ec"]));
+
+echo "Missing 'd' and 'y' parameters will generate a new public key pair\n";
+$detailsCopy7 = $details;
+unset($detailsCopy7["ec"]["d"]);
+unset($detailsCopy7["ec"]["y"]);
+$key7 = openssl_pkey_new($detailsCopy7);
+$details7 = openssl_pkey_get_details($key7);
+print_r($details7);
+var_dump(array_diff($details["ec"], $details7["ec"]));
+
+// Tests vectors from http://point-at-infinity.org/ecc/nisttv
+echo "Create a private key from scratch 1\n";
+$detailsFromScratch8 = array(
+       "ec" => array(
+               "curve_name" => "prime256v1",
+               "d" => "\1",
+       ),
+);
+$key8 = openssl_pkey_new($detailsFromScratch8);
+$details8 = openssl_pkey_get_details($key8);
+var_dump(strtoupper(bin2hex($details8["ec"]["x"])) === "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296");
+var_dump(strtoupper(bin2hex($details8["ec"]["y"])) === "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5");
+
+echo "Create a private key from scratch 2\n";
+$detailsFromScratch9 = array(
+       "ec" => array(
+               "curve_name" => "prime192v1",
+               "d" => hex2bin("7FFFFFFFFE0000007FFFFE003FFFFFE0007FFF1FFFFE0800"),
+       ),
+);
+$key9 = openssl_pkey_new($detailsFromScratch9);
+$details9 = openssl_pkey_get_details($key9);
+var_dump(strtoupper(bin2hex($details9["ec"]["x"])) === "45DAF0A306121BDB3B82E734CB44FDF65C9930F0E4FD2068");
+var_dump(strtoupper(bin2hex($details9["ec"]["y"])) === "F039FACE58EB7DE34E3374ADB28DF81F019C4548BAA75B64");
+?>
+--EXPECTF--
+Array
+(
+    [bits] => 256
+    [key] => -----BEGIN PUBLIC KEY-----%a
+-----END PUBLIC KEY-----
+
+    [ec] => Array
+        (
+            [curve_name] => prime256v1
+            [curve_oid] => 1.2.840.10045.3.1.7
+            [x] => %a
+            [y] => %a
+            [d] => %a
+        )
+
+    [type] => 3
+)
+Use details an create the same key pair
+Array
+(
+    [bits] => 256
+    [key] => -----BEGIN PUBLIC KEY-----%a
+-----END PUBLIC KEY-----
+
+    [ec] => Array
+        (
+            [curve_name] => prime256v1
+            [curve_oid] => 1.2.840.10045.3.1.7
+            [x] => %a
+            [y] => %a
+            [d] => %a
+        )
+
+    [type] => 3
+)
+array(0) {
+}
+Missing 'd' parameter (private key part) => no private key informations
+Array
+(
+    [bits] => 256
+    [key] => -----BEGIN PUBLIC KEY-----%a
+-----END PUBLIC KEY-----
+
+    [ec] => Array
+        (
+            [curve_name] => prime256v1
+            [curve_oid] => 1.2.840.10045.3.1.7
+            [x] => %a
+            [y] => %a
+        )
+
+    [type] => 3
+)
+array(1) {
+  ["d"]=>
+  string(32) "%a"
+}
+
+Warning: openssl_pkey_get_private(): supplied key param is a public key in %s on line %d
+bool(false)
+resource(%d) of type (OpenSSL key)
+bool(true)
+Missing 'x' parameter will not change the details. The public key is calculated from the private key 'd'
+Array
+(
+    [bits] => 256
+    [key] => -----BEGIN PUBLIC KEY-----%a
+-----END PUBLIC KEY-----
+
+    [ec] => Array
+        (
+            [curve_name] => prime256v1
+            [curve_oid] => 1.2.840.10045.3.1.7
+            [x] => %a
+            [y] => %a
+            [d] => %a
+        )
+
+    [type] => 3
+)
+array(0) {
+}
+Missing 'y' parameter will not change the details. The public key is calculated from the private key 'd'
+Array
+(
+    [bits] => 256
+    [key] => -----BEGIN PUBLIC KEY-----%a
+-----END PUBLIC KEY-----
+
+    [ec] => Array
+        (
+            [curve_name] => prime256v1
+            [curve_oid] => 1.2.840.10045.3.1.7
+            [x] => %a
+            [y] => %a
+            [d] => %a
+        )
+
+    [type] => 3
+)
+array(0) {
+}
+Missing 'd' and 'x' parameters will generate a new public key pair
+Array
+(
+    [bits] => 256
+    [key] => -----BEGIN PUBLIC KEY-----%a
+-----END PUBLIC KEY-----
+
+    [ec] => Array
+        (
+            [curve_name] => prime256v1
+            [curve_oid] => 1.2.840.10045.3.1.7
+            [x] => %a
+            [y] => %a
+            [d] => %a
+        )
+
+    [type] => 3
+)
+array(3) {
+  ["x"]=>
+  string(32) "%a"
+  ["y"]=>
+  string(32) "%a"
+  ["d"]=>
+  string(32) "%a"
+}
+Missing 'd' and 'y' parameters will generate a new public key pair
+Array
+(
+    [bits] => 256
+    [key] => -----BEGIN PUBLIC KEY-----%a
+-----END PUBLIC KEY-----
+
+    [ec] => Array
+        (
+            [curve_name] => prime256v1
+            [curve_oid] => 1.2.840.10045.3.1.7
+            [x] => %a
+            [y] => %a
+            [d] => %a
+        )
+
+    [type] => 3
+)
+array(3) {
+  ["x"]=>
+  string(32) "%a"
+  ["y"]=>
+  string(32) "%a"
+  ["d"]=>
+  string(32) "%a"
+}
+Create a private key from scratch 1
+bool(true)
+bool(true)
+Create a private key from scratch 2
+bool(true)
+bool(true)
diff --git a/ext/openssl/tests/ecc.phpt b/ext/openssl/tests/ecc.phpt
new file mode 100644 (file)
index 0000000..5df0130
--- /dev/null
@@ -0,0 +1,110 @@
+--TEST--
+openssl_*() with OPENSSL_KEYTYPE_EC
+--SKIPIF--
+<?php if (!extension_loaded("openssl") && !defined("OPENSSL_KEYTYPE_EC")) print "skip"; ?>
+--FILE--
+<?php
+$args = array(
+       "curve_name" => "secp384r1",
+       "private_key_type" => OPENSSL_KEYTYPE_EC,
+);
+echo "Testing openssl_pkey_new\n";
+$key1 = openssl_pkey_new($args);
+var_dump($key1);
+
+$argsFailed = array(
+       "curve_name" => "invalid_cuve_name",
+       "private_key_type" => OPENSSL_KEYTYPE_EC,
+);
+
+$keyFailed = openssl_pkey_new($argsFailed);
+var_dump($keyFailed);
+
+$d1 = openssl_pkey_get_details($key1);
+var_dump($d1["bits"]);
+var_dump(strlen($d1["key"]));
+var_dump($d1["ec"]["curve_name"]);
+var_dump($d1["type"] == OPENSSL_KEYTYPE_EC);
+
+$key2 = openssl_pkey_new($d1);
+var_dump($key2);
+
+$d2 = openssl_pkey_get_details($key2);
+// Compare array
+var_dump($d1 === $d2);
+
+$dn = array(
+       "countryName" => "BR",
+       "stateOrProvinceName" => "Rio Grande do Sul",
+       "localityName" => "Porto Alegre",
+       "commonName" => "Henrique do N. Angelo",
+       "emailAddress" => "hnangelo@php.net"
+);
+
+// openssl_csr_new creates a new public key pair if the key argument is null
+echo "Testing openssl_csr_new with key generation\n";
+$keyGenerate = null;
+var_dump($keyGenerate);
+$csr = openssl_csr_new($dn, $keyGenerate, $args);
+
+var_dump($keyGenerate);
+
+$args["digest_alg"] = "sha1";
+echo "Testing openssl_csr_new with existing ecc key\n";
+$csr = openssl_csr_new($dn, $key1, $args);
+var_dump($csr);
+
+$pubkey1 = openssl_pkey_get_details(openssl_csr_get_public_key($csr));
+var_dump(isset($pubkey1["ec"]["priv_key"]));
+unset($d1["ec"]["priv_key"]);
+var_dump(array_diff($d1["ec"], $pubkey1["ec"]));
+
+$x509 = openssl_csr_sign($csr, null, $key1, 365, $args);
+var_dump($x509);
+
+echo "Testing openssl_x509_check_private_key\n";
+var_dump(openssl_x509_check_private_key($x509, $key1));
+
+$key3 = openssl_pkey_new($args);
+var_dump(openssl_x509_check_private_key($x509, $key3));
+
+echo "Testing openssl_get_curve_names\n";
+$curve_names = openssl_get_curve_names();
+
+var_dump(is_array($curve_names));
+
+foreach ($curve_names as $curve_name) {
+       if ("secp384r1" === $curve_name) {
+               echo "Found secp384r1 in curve names\n";
+       }
+}
+?>
+--EXPECTF--
+Testing openssl_pkey_new
+resource(%d) of type (OpenSSL key)
+
+Warning: openssl_pkey_new(): Unknown elliptic curve (short) name invalid_cuve_name in %s on line %d
+bool(false)
+int(384)
+int(215)
+string(9) "secp384r1"
+bool(true)
+resource(%d) of type (OpenSSL key)
+bool(true)
+Testing openssl_csr_new with key generation
+NULL
+resource(%d) of type (OpenSSL key)
+Testing openssl_csr_new with existing ecc key
+resource(%d) of type (OpenSSL X.509 CSR)
+bool(false)
+array(1) {
+  ["d"]=>
+  string(48) "%a"
+}
+resource(%d) of type (OpenSSL X.509)
+Testing openssl_x509_check_private_key
+bool(true)
+bool(false)
+Testing openssl_get_curve_names
+bool(true)
+Found secp384r1 in curve names
index d229d6b13529bd4c9308452bf035a68f8e285997..530158d7d94f0106f865c7d32227b2c4a2a743ab 100644 (file)
@@ -2,8 +2,10 @@
 openssl_pkey_export() with EC key
 --SKIPIF--
 <?php
-if (!extension_loaded("openssl")) die("skip");
-if (!defined('OPENSSL_KEYTYPE_EC')) die("skip no EC available");
+if (!extension_loaded("openssl"))
+    die("skip");
+if (!defined('OPENSSL_KEYTYPE_EC'))
+    die("skip no EC available");
 ?>
 --FILE--
 <?php
@@ -28,9 +30,9 @@ var_dump(OPENSSL_KEYTYPE_EC === $details['type']);
 // Read public key
 $pKey = openssl_pkey_get_public('file://' . dirname(__FILE__) . '/public_ec.key');
 var_dump($pKey);
-// The details are the same for a public or private key
-var_dump($details === openssl_pkey_get_details($pKey));
-
+// The details are the same for a public or private key, expect the private key parameter 'd
+$detailsPKey = openssl_pkey_get_details($pKey);
+var_dump(array_diff_assoc($details['ec'], $detailsPKey['ec']));
 
 // Export to file
 $tempname = tempnam(sys_get_temp_dir(), 'openssl_ec');
@@ -40,7 +42,6 @@ var_dump(OPENSSL_KEYTYPE_EC === $details['type']);
 
 // Clean the temporary file
 @unlink($tempname);
-
 ?>
 --EXPECTF--
 resource(%d) of type (OpenSSL key)
@@ -49,6 +50,9 @@ bool(true)
 bool(true)
 bool(true)
 resource(%d) of type (OpenSSL key)
-bool(true)
+array(1) {
+  ["d"]=>
+  string(32) "%a"
+}
 bool(true)
 bool(true)
index 8e0cef46c07cf7ce2f5208a7b642ae5e9762b005..3c239af2a2b5b10d1c3c2199c83df1b901484e2b 100644 (file)
@@ -3,11 +3,11 @@ openssl_pkey_get_details() with EC key
 --SKIPIF--
 <?php
 if (!extension_loaded("openssl")) die("skip");
-if (!defined('OPENSSL_KEYTYPE_EC')) die("skip no EC available");
+if (!defined("OPENSSL_KEYTYPE_EC")) die("skip no EC available");
 ?>
 --FILE--
 <?php
-$key = openssl_pkey_get_private('file://' . dirname(__FILE__) . '/private_ec.key');
+$key = openssl_pkey_get_private("file://" . dirname(__FILE__) . "/private_ec.key");
 
 print_r(openssl_pkey_get_details($key));
 ?>
@@ -22,6 +22,9 @@ Array
         (
             [curve_name] => prime256v1
             [curve_oid] => 1.2.840.10045.3.1.7
+            [x] => %a
+            [y] => %a
+            [d] => %a
         )
 
     [type] => 3
index 3f2efc86f1c912dfea49714a404e23a43c39394b..d77e8a0ae308e5ce052ca6799922f8a1726387f9 100644 (file)
@@ -758,6 +758,7 @@ int fcgi_listen(const char *path, int backlog)
            bind(listen_socket, (struct sockaddr *) &sa, sock_len) < 0 ||
            listen(listen_socket, backlog) < 0) {
 
+               close(listen_socket);
                fcgi_log(FCGI_ERROR, "Cannot bind/listen socket - [%d] %s.\n",errno, strerror(errno));
                return -1;
        }
index 2d95e494aa8473e81ebf4abc23a6f7a7716a9b87..8f5ce2480088e59e606db774da7298bea7db0cd3 100644 (file)
@@ -224,8 +224,10 @@ char** save_ps_args(int argc, char** argv)
         for (i = 0; i < argc; i++)
         {
             new_argv[i] = strdup(argv[i]);
-            if (!new_argv[i])
+            if (!new_argv[i]) {
+                free(new_argv);
                 goto clobber_error;
+            }
         }
         new_argv[argc] = NULL;
 
index 0a45882251d4ea9561b9e128d6988e6b50cb57ab..ecd3f3974e0c419019bec895d9a4450dc79e9be1 100644 (file)
@@ -1433,6 +1433,7 @@ phpdbg_main:
                        case 'i': { /* set init file */
                                if (init_file) {
                                        free(init_file);
+                                       init_file = NULL;
                                }
 
                                init_file_len = strlen(php_optarg);
@@ -1786,7 +1787,9 @@ phpdbg_main:
                /* initialize from file */
                PHPDBG_G(flags) |= PHPDBG_IS_INITIALIZING;
                zend_try {
-                       phpdbg_init(init_file, init_file_len, init_file_default);
+                       if (init_file) {
+                               phpdbg_init(init_file, init_file_len, init_file_default);
+                       }
                        if (bp_tmp) {
                                PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT;
                                phpdbg_string_init(bp_tmp);