summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Lowrey <rdlowrey@gmail.com>2013-10-08 13:54:22 -0400
committerMichael Wallner <mike@php.net>2013-10-17 14:49:44 +0200
commit2aaa3d538a7b93d92c52aec95707d8230f21be65 (patch)
treeca54e477c4ed32d999e7969ea348c1d130bda0e5
parent51b809e3ad244df1102ca2f44a03ea1fee063579 (diff)
downloadphp-git-2aaa3d538a7b93d92c52aec95707d8230f21be65.tar.gz
Added support for TLSv1.1 and TLSv1.2
Conflicts: ext/openssl/xp_ssl.c
-rw-r--r--ext/openssl/openssl.c8
-rw-r--r--ext/openssl/tests/streams_crypto_method.pem33
-rw-r--r--ext/openssl/tests/tlsv1.1_wrapper_001.phpt46
-rw-r--r--ext/openssl/tests/tlsv1.2_wrapper_002.phpt46
-rw-r--r--ext/openssl/xp_ssl.c86
-rw-r--r--ext/standard/file.c4
-rw-r--r--main/streams/php_stream_transport.h6
7 files changed, 226 insertions, 3 deletions
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index 59a58b1c00..5d0cf4384d 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -1151,6 +1151,10 @@ PHP_MINIT_FUNCTION(openssl)
php_stream_xport_register("sslv2", php_openssl_ssl_socket_factory TSRMLS_CC);
#endif
php_stream_xport_register("tls", php_openssl_ssl_socket_factory TSRMLS_CC);
+#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+ php_stream_xport_register("tlsv1.1", php_openssl_ssl_socket_factory TSRMLS_CC);
+ php_stream_xport_register("tlsv1.2", php_openssl_ssl_socket_factory TSRMLS_CC);
+#endif
/* override the default tcp socket provider */
php_stream_xport_register("tcp", php_openssl_ssl_socket_factory TSRMLS_CC);
@@ -1189,6 +1193,10 @@ PHP_MSHUTDOWN_FUNCTION(openssl)
#endif
php_stream_xport_unregister("sslv3" TSRMLS_CC);
php_stream_xport_unregister("tls" TSRMLS_CC);
+#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+ php_stream_xport_unregister("tlsv1.1" TSRMLS_CC);
+ php_stream_xport_unregister("tlsv1.2" TSRMLS_CC);
+#endif
/* reinstate the default tcp handler */
php_stream_xport_register("tcp", php_stream_generic_socket_factory TSRMLS_CC);
diff --git a/ext/openssl/tests/streams_crypto_method.pem b/ext/openssl/tests/streams_crypto_method.pem
new file mode 100644
index 0000000000..9d754d460d
--- /dev/null
+++ b/ext/openssl/tests/streams_crypto_method.pem
@@ -0,0 +1,33 @@
+-----BEGIN CERTIFICATE-----
+MIIC5jCCAk+gAwIBAgIBADANBgkqhkiG9w0BAQQFADBcMQswCQYDVQQGEwJBVTET
+MBEGA1UECBMKUXVlZW5zbGFuZDEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQx
+HDAaBgNVBAMTE1Rlc3QgUENBICgxMDI0IGJpdCkwHhcNOTkxMjAyMjEzNTQ4WhcN
+MDUwNzExMjEzNTQ4WjBcMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFu
+ZDEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxHDAaBgNVBAMTE1Rlc3QgUENB
+ICgxMDI0IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ2haT/f5Zwy
+V+MiuSDjSR62adBoSiBB7Usty44lXqsp9RICw+DCCxpsn/CfxPEDXLLd4olsWXc6
+JRcxGynbYmnzk+Z6aIPPJQhK3CTvaqGnWKZsA1m+WaUIUqJCuNTK4N+7hMAGaf6S
+S3e9HVgEQ4a34gXJ7VQFVIBNV1EnZRWHAgMBAAGjgbcwgbQwHQYDVR0OBBYEFE0R
+aEcrj18q1dw+G6nJbsTWR213MIGEBgNVHSMEfTB7gBRNEWhHK49fKtXcPhupyW7E
+1kdtd6FgpF4wXDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxGjAY
+BgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYDVQQDExNUZXN0IFBDQSAoMTAy
+NCBiaXQpggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAUa8B3pho
++Mvxeq9HsEzJxHIFQla05S5J/e/V+DQTYoKiRFchKPrDAdrzYSEvP3h4QJEtsNqQ
+JfOxg5M42uLFq7aPGWkF6ZZqZsYS+zA9IVT14g7gNA6Ne+5QtJqQtH9HA24st0T0
+Tga/lZ9M2ovImovaxSL/kRHbpCWcqWVxpOw=
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQCdoWk/3+WcMlfjIrkg40ketmnQaEogQe1LLcuOJV6rKfUSAsPg
+wgsabJ/wn8TxA1yy3eKJbFl3OiUXMRsp22Jp85PmemiDzyUIStwk72qhp1imbANZ
+vlmlCFKiQrjUyuDfu4TABmn+kkt3vR1YBEOGt+IFye1UBVSATVdRJ2UVhwIDAQAB
+AoGAba4fTtuap5l7/8ZsbE7Z1O32KJY4ZcOZukLOLUUhXxXduT+FTgGWujc0/rgc
+z9qYCLlNZHOouMYTgtSfYvuMuLZ11VIt0GYH+nRioLShE59Yy+zCRyC+gPigS1kz
+xvo14AsOIPYV14Tk/SsHyq6E0eTk7VzaIE197giiINUERPECQQDSKmtPTh/lRKw7
+HSZSM0I1mFWn/1zqrAbontRQY5w98QWIOe5qmzYyFbPXYT3d9BzlsMyhgiRNoBbD
+yvohSHXJAkEAwAHx6ezAZeWWzD5yXD36nyjpkVCw7Tk7TSmOceLJMWt1QcrCfqlS
+xA5jjpQ6Z8suU5DdtWAryM2sAir1WisYzwJAd6Zcx56jvAQ3xcPXsE6scBTVFzrj
+7FqZ6E+cclPzfLQ+QQsyOBE7bpI6e/FJppY26XGZXo3YGzV8IGXrt40oOQJALETG
+h86EFXo3qGOFbmsDy4pdP5nBERCu8X1xUCSfintiD4c2DInxgS5oGclnJeMcjTvL
+QjQoJCX3UJCi/OUO1QJBAKgcDHWjMvt+l1pjJBsSEZ0HX9AAIIVx0RQmbFGS+F2Q
+hhu5l77WnnZOQ9vvhV5u7NPCUF9nhU3jh60qWWO8mkc=
+-----END RSA PRIVATE KEY-----
diff --git a/ext/openssl/tests/tlsv1.1_wrapper_001.phpt b/ext/openssl/tests/tlsv1.1_wrapper_001.phpt
new file mode 100644
index 0000000000..56211f0b96
--- /dev/null
+++ b/ext/openssl/tests/tlsv1.1_wrapper_001.phpt
@@ -0,0 +1,46 @@
+--TEST--
+tlsv1.1 stream wrapper
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl")) die("skip");
+if (OPENSSL_VERSION_NUMBER < 0x10001001) die("skip OpenSSL 1.0.1 required");
+if (!function_exists('pcntl_fork')) die("skip no fork");
+--FILE--
+<?php
+$flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN;
+$ctx = stream_context_create(array('ssl' => array(
+ 'local_cert' => __DIR__ . '/streams_crypto_method.pem',
+)));
+
+$server = stream_socket_server('tlsv1.1://127.0.0.1:64321', $errno, $errstr, $flags, $ctx);
+var_dump($server);
+
+$pid = pcntl_fork();
+if ($pid == -1) {
+ die('could not fork');
+} elseif ($pid) {
+ $flags = STREAM_CLIENT_CONNECT;
+ $ctx = stream_context_create(array('ssl' => array(
+ 'verify_peer' => false
+ )));
+
+ $client = stream_socket_client("tlsv1.1://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx);
+ var_dump($client);
+
+ $client = @stream_socket_client("sslv3://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx);
+ var_dump($client);
+
+ $client = @stream_socket_client("tlsv1.2://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx);
+ var_dump($client);
+
+} else {
+ @pcntl_wait($status);
+ for ($i=0; $i < 3; $i++) {
+ @stream_socket_accept($server, 1);
+ }
+}
+--EXPECTF--
+resource(%d) of type (stream)
+resource(%d) of type (stream)
+bool(false)
+bool(false)
diff --git a/ext/openssl/tests/tlsv1.2_wrapper_002.phpt b/ext/openssl/tests/tlsv1.2_wrapper_002.phpt
new file mode 100644
index 0000000000..cb3f4106c7
--- /dev/null
+++ b/ext/openssl/tests/tlsv1.2_wrapper_002.phpt
@@ -0,0 +1,46 @@
+--TEST--
+tlsv1.2 stream wrapper
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl")) die("skip");
+if (OPENSSL_VERSION_NUMBER < 0x10001001) die("skip OpenSSL 1.0.1 required");
+if (!function_exists('pcntl_fork')) die("skip no fork");
+--FILE--
+<?php
+$flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN;
+$ctx = stream_context_create(array('ssl' => array(
+ 'local_cert' => __DIR__ . '/streams_crypto_method.pem',
+)));
+
+$server = stream_socket_server('tlsv1.2://127.0.0.1:64321', $errno, $errstr, $flags, $ctx);
+var_dump($server);
+
+$pid = pcntl_fork();
+if ($pid == -1) {
+ die('could not fork');
+} elseif ($pid) {
+ $flags = STREAM_CLIENT_CONNECT;
+ $ctx = stream_context_create(array('ssl' => array(
+ 'verify_peer' => false
+ )));
+
+ $client = stream_socket_client("tlsv1.2://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx);
+ var_dump($client);
+
+ $client = @stream_socket_client("sslv3://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx);
+ var_dump($client);
+
+ $client = @stream_socket_client("tlsv1.1://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx);
+ var_dump($client);
+
+} else {
+ @pcntl_wait($status);
+ for ($i=0; $i < 3; $i++) {
+ @stream_socket_accept($server, 1);
+ }
+}
+--EXPECTF--
+resource(%d) of type (stream)
+resource(%d) of type (stream)
+bool(false)
+bool(false)
diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c
index a1a7ffc3f4..d62ab89fcf 100644
--- a/ext/openssl/xp_ssl.c
+++ b/ext/openssl/xp_ssl.c
@@ -346,6 +346,24 @@ static inline int php_openssl_setup_crypto(php_stream *stream,
sslsock->is_client = 1;
method = TLSv1_client_method();
break;
+ case STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT:
+#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+ sslsock->is_client = 1;
+ method = TLSv1_1_client_method();
+ break;
+#else
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.1 support is not compiled into the OpenSSL library PHP is linked against");
+ return -1;
+#endif
+ case STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT:
+#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+ sslsock->is_client = 1;
+ method = TLSv1_2_client_method();
+ break;
+#else
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.2 support is not compiled into the OpenSSL library PHP is linked against");
+ return -1;
+#endif
case STREAM_CRYPTO_METHOD_SSLv23_SERVER:
sslsock->is_client = 0;
method = SSLv23_server_method();
@@ -367,6 +385,24 @@ static inline int php_openssl_setup_crypto(php_stream *stream,
sslsock->is_client = 0;
method = TLSv1_server_method();
break;
+ case STREAM_CRYPTO_METHOD_TLSv1_1_SERVER:
+#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+ sslsock->is_client = 0;
+ method = TLSv1_1_server_method();
+ break;
+#else
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.1 support is not compiled into the OpenSSL library PHP is linked against");
+ return -1;
+#endif
+ case STREAM_CRYPTO_METHOD_TLSv1_2_SERVER:
+#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+ sslsock->is_client = 0;
+ method = TLSv1_2_server_method();
+ break;
+#else
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.2 support is not compiled into the OpenSSL library PHP is linked against");
+ return -1;
+#endif
default:
return -1;
@@ -667,6 +703,12 @@ static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_
case STREAM_CRYPTO_METHOD_TLS_CLIENT:
sock->method = STREAM_CRYPTO_METHOD_TLS_SERVER;
break;
+ case STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT:
+ sock->method = STREAM_CRYPTO_METHOD_TLSv1_1_SERVER;
+ break;
+ case STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT:
+ sock->method = STREAM_CRYPTO_METHOD_TLSv1_2_SERVER;
+ break;
default:
break;
}
@@ -853,8 +895,32 @@ php_stream_ops php_openssl_socket_ops = {
php_openssl_sockop_set_option,
};
-static char * get_sni(php_stream_context *ctx, char *resourcename, long resourcenamelen, int is_persistent TSRMLS_DC) {
+static int get_crypto_method(php_stream_context *ctx) {
+ if (ctx) {
+ zval **val = NULL;
+ long crypto_method;
+
+ if (php_stream_context_get_option(ctx, "ssl", "crypto_method", &val) == SUCCESS) {
+ convert_to_long_ex(val);
+ crypto_method = (long)Z_LVAL_PP(val);
+
+ switch (crypto_method) {
+ case STREAM_CRYPTO_METHOD_SSLv2_CLIENT:
+ case STREAM_CRYPTO_METHOD_SSLv3_CLIENT:
+ case STREAM_CRYPTO_METHOD_SSLv23_CLIENT:
+ case STREAM_CRYPTO_METHOD_TLS_CLIENT:
+ case STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT:
+ case STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT:
+ return crypto_method;
+ }
+
+ }
+ }
+
+ return STREAM_CRYPTO_METHOD_SSLv23_CLIENT;
+}
+static char * get_sni(php_stream_context *ctx, const char *resourcename, size_t resourcenamelen, int is_persistent TSRMLS_DC) {
php_url *url;
if (ctx) {
@@ -954,8 +1020,24 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, long protolen,
} else if (strncmp(proto, "tls", protolen) == 0) {
sslsock->enable_on_connect = 1;
sslsock->method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
+ } else if (strncmp(proto, "tlsv1.1", protolen) == 0) {
+#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+ sslsock->enable_on_connect = 1;
+ sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
+#else
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.1 support is not compiled into the OpenSSL library PHP is linked against");
+ return NULL;
+#endif
+ } else if (strncmp(proto, "tlsv1.2", protolen) == 0) {
+#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+ sslsock->enable_on_connect = 1;
+ sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
+#else
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.2 support is not compiled into the OpenSSL library PHP is linked against");
+ return NULL;
+#endif
}
-
+
return stream;
}
diff --git a/ext/standard/file.c b/ext/standard/file.c
index ad6bdad34f..13561aa3a9 100644
--- a/ext/standard/file.c
+++ b/ext/standard/file.c
@@ -223,10 +223,14 @@ PHP_MINIT_FUNCTION(file)
REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv3_CLIENT", STREAM_CRYPTO_METHOD_SSLv3_CLIENT, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv23_CLIENT", STREAM_CRYPTO_METHOD_SSLv23_CLIENT, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLS_CLIENT", STREAM_CRYPTO_METHOD_TLS_CLIENT, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT", STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT", STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv2_SERVER", STREAM_CRYPTO_METHOD_SSLv2_SERVER, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv3_SERVER", STREAM_CRYPTO_METHOD_SSLv3_SERVER, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv23_SERVER", STREAM_CRYPTO_METHOD_SSLv23_SERVER, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLS_SERVER", STREAM_CRYPTO_METHOD_TLS_SERVER, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_1_SERVER", STREAM_CRYPTO_METHOD_TLSv1_1_SERVER, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_2_SERVER", STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("STREAM_SHUT_RD", STREAM_SHUT_RD, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("STREAM_SHUT_WR", STREAM_SHUT_WR, CONST_CS|CONST_PERSISTENT);
diff --git a/main/streams/php_stream_transport.h b/main/streams/php_stream_transport.h
index c2d911032e..3c276ad6d3 100644
--- a/main/streams/php_stream_transport.h
+++ b/main/streams/php_stream_transport.h
@@ -170,10 +170,14 @@ typedef enum {
STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
STREAM_CRYPTO_METHOD_TLS_CLIENT,
+ STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT,
+ STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT,
STREAM_CRYPTO_METHOD_SSLv2_SERVER,
STREAM_CRYPTO_METHOD_SSLv3_SERVER,
STREAM_CRYPTO_METHOD_SSLv23_SERVER,
- STREAM_CRYPTO_METHOD_TLS_SERVER
+ STREAM_CRYPTO_METHOD_TLS_SERVER,
+ STREAM_CRYPTO_METHOD_TLSv1_1_SERVER,
+ STREAM_CRYPTO_METHOD_TLSv1_2_SERVER
} php_stream_xport_crypt_method_t;
BEGIN_EXTERN_C()