From 741ff7ae5d4adbbf3e2a909a402fb29d46be35d0 Mon Sep 17 00:00:00 2001 From: codarrenvelvindron Date: Wed, 5 Dec 2018 08:23:34 +0400 Subject: [PATCH] Added tls 1.3 support for PHP --- ext/openssl/openssl.c | 6 +++ .../tests/session_meta_capture_tlsv13.phpt | 50 +++++++++++++++++++ ext/openssl/tests/tlsv1.3_wrapper.phpt | 50 +++++++++++++++++++ ext/openssl/xp_ssl.c | 41 +++++++++++++-- ext/standard/file.c | 3 ++ main/streams/php_stream_transport.h | 2 + 6 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 ext/openssl/tests/session_meta_capture_tlsv13.phpt create mode 100644 ext/openssl/tests/tlsv1.3_wrapper.phpt diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 7fcab17ed66b5..a654fb97d2a77 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -1559,6 +1559,9 @@ PHP_MINIT_FUNCTION(openssl) php_stream_xport_register("tlsv1.0", php_openssl_ssl_socket_factory); php_stream_xport_register("tlsv1.1", php_openssl_ssl_socket_factory); php_stream_xport_register("tlsv1.2", php_openssl_ssl_socket_factory); +#if OPENSSL_VERSION_NUMBER >= 0x10101000 + php_stream_xport_register("tlsv1.3", php_openssl_ssl_socket_factory); +#endif /* override the default tcp socket provider */ php_stream_xport_register("tcp", php_openssl_ssl_socket_factory); @@ -1632,6 +1635,9 @@ PHP_MSHUTDOWN_FUNCTION(openssl) php_stream_xport_unregister("tlsv1.0"); php_stream_xport_unregister("tlsv1.1"); php_stream_xport_unregister("tlsv1.2"); +#if OPENSSL_VERSION_NUMBER >= 0x10101000 + php_stream_xport_unregister("tlsv1.3"); +#endif /* reinstate the default tcp handler */ php_stream_xport_register("tcp", php_stream_generic_socket_factory); diff --git a/ext/openssl/tests/session_meta_capture_tlsv13.phpt b/ext/openssl/tests/session_meta_capture_tlsv13.phpt new file mode 100644 index 0000000000000..bb3ac3f71bacd --- /dev/null +++ b/ext/openssl/tests/session_meta_capture_tlsv13.phpt @@ -0,0 +1,50 @@ +--TEST-- +Capture SSL session meta array in stream context for TLSv1.3 +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => __DIR__ . '/bug54992.pem', + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_SERVER, + ]]); + + $server = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx); + phpt_notify(); + + @stream_socket_accept($server, 1); + @stream_socket_accept($server, 1); + @stream_socket_accept($server, 1); + @stream_socket_accept($server, 1); +CODE; + +$clientCode = <<<'CODE' + $serverUri = "ssl://127.0.0.1:64321"; + $clientFlags = STREAM_CLIENT_CONNECT; + $clientCtx = stream_context_create(['ssl' => [ + 'verify_peer' => true, + 'cafile' => __DIR__ . '/bug54992-ca.pem', + 'peer_name' => 'bug54992.local', + 'capture_session_meta' => true, + ]]); + + phpt_wait(); + + stream_context_set_option($clientCtx, 'ssl', 'crypto_method', STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT); + @stream_socket_client($serverUri, $errno, $errstr, 1, $clientFlags, $clientCtx); + $meta = stream_context_get_options($clientCtx)['ssl']['session_meta']; + var_dump($meta['protocol']); +CODE; + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +string(7) "TLSv1.3" diff --git a/ext/openssl/tests/tlsv1.3_wrapper.phpt b/ext/openssl/tests/tlsv1.3_wrapper.phpt new file mode 100644 index 0000000000000..cc73f7d22d39f --- /dev/null +++ b/ext/openssl/tests/tlsv1.3_wrapper.phpt @@ -0,0 +1,50 @@ +--TEST-- +tlsv1.3 stream wrapper +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => __DIR__ . '/streams_crypto_method.pem', + ]]); + + $server = stream_socket_server('tlsv1.3://127.0.0.1:64321', $errno, $errstr, $flags, $ctx); + phpt_notify(); + + for ($i=0; $i < 3; $i++) { + @stream_socket_accept($server, 3); + } +CODE; + +$clientCode = <<<'CODE' + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + ]]); + + phpt_wait(); + + $client = stream_socket_client("tlsv1.3://127.0.0.1:64321", $errno, $errstr, 3, $flags, $ctx); + var_dump($client); + + $client = @stream_socket_client("sslv3://127.0.0.1:64321", $errno, $errstr, 3, $flags, $ctx); + var_dump($client); + + $client = @stream_socket_client("tlsv1.2://127.0.0.1:64321", $errno, $errstr, 3, $flags, $ctx); + var_dump($client); +CODE; + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECTF-- +resource(%d) of type (stream) +bool(false) +bool(false) diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index 4c4bfaddd3ef9..2a6b693c04769 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -58,6 +58,7 @@ #define STREAM_CRYPTO_METHOD_TLSv1_0 (1<<3) #define STREAM_CRYPTO_METHOD_TLSv1_1 (1<<4) #define STREAM_CRYPTO_METHOD_TLSv1_2 (1<<5) +#define STREAM_CRYPTO_METHOD_TLSv1_3 (1<<6) #ifndef OPENSSL_NO_SSL3 #define HAVE_SSL3 1 @@ -65,11 +66,14 @@ #else #define PHP_OPENSSL_MIN_PROTO_VERSION STREAM_CRYPTO_METHOD_TLSv1_0 #endif -#define PHP_OPENSSL_MAX_PROTO_VERSION STREAM_CRYPTO_METHOD_TLSv1_2 +#define PHP_OPENSSL_MAX_PROTO_VERSION STREAM_CRYPTO_METHOD_TLSv1_3 #define HAVE_TLS11 1 #define HAVE_TLS12 1 +#if OPENSSL_VERSION_NUMBER >= 0x10101000 +#define HAVE_TLS13 1 +#endif #ifndef OPENSSL_NO_ECDH #define HAVE_ECDH 1 @@ -998,6 +1002,11 @@ static int php_openssl_get_crypto_method_ctx_flags(int method_flags) /* {{{ */ ssl_ctx_options |= SSL_OP_NO_TLSv1_2; } #endif +#ifdef HAVE_TLS13 + if (!(method_flags & STREAM_CRYPTO_METHOD_TLSv1_3)) { + ssl_ctx_options |= SSL_OP_NO_TLSv1_3; + } +#endif return ssl_ctx_options; } @@ -1012,7 +1021,7 @@ static inline int php_openssl_get_min_proto_version_flag(int flags) /* {{{ */ return ver; } } - return STREAM_CRYPTO_METHOD_TLSv1_2; + return STREAM_CRYPTO_METHOD_TLSv1_3; } /* }}} */ @@ -1024,7 +1033,7 @@ static inline int php_openssl_get_max_proto_version_flag(int flags) /* {{{ */ return ver; } } - return STREAM_CRYPTO_METHOD_TLSv1_2; + return STREAM_CRYPTO_METHOD_TLSv1_3; } /* }}} */ @@ -1040,9 +1049,13 @@ static inline int php_openssl_map_proto_version(int flag) /* {{{ */ return TLS1_VERSION; case STREAM_CRYPTO_METHOD_TLSv1_1: return TLS1_1_VERSION; - /* case STREAM_CRYPTO_METHOD_TLSv1_2: */ + case STREAM_CRYPTO_METHOD_TLSv1_2: + return TLS1_2_VERSION; + /* case STREAM_CRYPTO_METHOD_TLSv1_3: */ +#ifdef HAVE_TLS13 default: - return TLS1_2_VERSION; + return TLS1_3_VERSION; +#endif } } @@ -1788,6 +1801,11 @@ static zend_array *php_openssl_capture_session_meta(SSL *ssl_handle) /* {{{ */ char version_str[PHP_SSL_MAX_VERSION_LEN]; switch (proto) { +#ifdef HAVE_TLS13 + case TLS1_3_VERSION: + proto_str = "TLSv1.3"; + break; +#endif #ifdef HAVE_TLS12 case TLS1_2_VERSION: proto_str = "TLSv1.2"; @@ -2392,6 +2410,9 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val array_init(&tmp); switch (SSL_version(sslsock->ssl_handle)) { +#ifdef HAVE_TLS13 + case TLS1_3_VERSION: proto_str = "TLSv1.3"; break; +#endif #ifdef HAVE_TLS12 case TLS1_2_VERSION: proto_str = "TLSv1.2"; break; #endif @@ -2739,6 +2760,16 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen, "TLSv1.2 support is not compiled into the OpenSSL library against which PHP is linked"); php_stream_close(stream); return NULL; +#endif + } else if (strncmp(proto, "tlsv1.3", protolen) == 0) { +#ifdef HAVE_TLS13 + sslsock->enable_on_connect = 1; + sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT; +#else + php_error_docref(NULL, E_WARNING, + "TLSv1.3 support is not compiled into the OpenSSL library against which PHP is linked"); + php_stream_close(stream); + return NULL; #endif } diff --git a/ext/standard/file.c b/ext/standard/file.c index 2eed1562b9323..fc1b55ab4e877 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -217,6 +217,7 @@ PHP_MINIT_FUNCTION(file) REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT", STREAM_CRYPTO_METHOD_TLSv1_0_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_TLSv1_3_CLIENT", STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_ANY_SERVER", STREAM_CRYPTO_METHOD_ANY_SERVER, 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); @@ -225,11 +226,13 @@ PHP_MINIT_FUNCTION(file) REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_0_SERVER", STREAM_CRYPTO_METHOD_TLSv1_0_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_CRYPTO_METHOD_TLSv1_3_SERVER", STREAM_CRYPTO_METHOD_TLSv1_3_SERVER, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_PROTO_SSLv3", STREAM_CRYPTO_METHOD_SSLv3_SERVER, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_PROTO_TLSv1_0", STREAM_CRYPTO_METHOD_TLSv1_0_SERVER, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_PROTO_TLSv1_1", STREAM_CRYPTO_METHOD_TLSv1_1_SERVER, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_PROTO_TLSv1_2", STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_PROTO_TLSv1_3", STREAM_CRYPTO_METHOD_TLSv1_3_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 a4a851b399967..9ae5d13d422e2 100644 --- a/main/streams/php_stream_transport.h +++ b/main/streams/php_stream_transport.h @@ -171,6 +171,7 @@ typedef enum { STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT = (1 << 3 | 1), STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT = (1 << 4 | 1), STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT = (1 << 5 | 1), + STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT = (1 << 6 | 1), /* TLS equates to TLS_ANY as of PHP 7.2 */ STREAM_CRYPTO_METHOD_TLS_CLIENT = ((1 << 3) | (1 << 4) | (1 << 5) | 1), STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT = ((1 << 3) | (1 << 4) | (1 << 5) | 1), @@ -182,6 +183,7 @@ typedef enum { STREAM_CRYPTO_METHOD_TLSv1_0_SERVER = (1 << 3), STREAM_CRYPTO_METHOD_TLSv1_1_SERVER = (1 << 4), STREAM_CRYPTO_METHOD_TLSv1_2_SERVER = (1 << 5), + STREAM_CRYPTO_METHOD_TLSv1_3_SERVER = (1 << 6), /* TLS equates to TLS_ANY as of PHP 7.2 */ STREAM_CRYPTO_METHOD_TLS_SERVER = ((1 << 3) | (1 << 4) | (1 << 5)), STREAM_CRYPTO_METHOD_TLS_ANY_SERVER = ((1 << 3) | (1 << 4) | (1 << 5)), pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy