]> granicus.if.org Git - php/commitdiff
Add support for OpenSSL security level
authorJakub Zelenka <bukka@php.net>
Mon, 17 Jul 2017 16:40:51 +0000 (17:40 +0100)
committerJakub Zelenka <bukka@php.net>
Mon, 17 Jul 2017 16:40:51 +0000 (17:40 +0100)
NEWS
ext/openssl/tests/stream_security_level.phpt [new file with mode: 0644]
ext/openssl/xp_ssl.c

diff --git a/NEWS b/NEWS
index 4b3d6f92d37bf54196fadf76906c639e944c61f3..0c6d5b38478493699c686b72f9d1abb9aef58a95 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -59,6 +59,8 @@ PHP                                                                        NEWS
     (Nikita, Dmitry)
 
 - OpenSSL:
+  . Add ssl security_level stream option to support OpenSSL security levels.
+    (Jakub Zelenka).
   . Allow setting SNI cert and private key in separate files. (Jakub Zelenka)
   . Fixed bug #74651 (negative-size-param (-1) in memcpy in zif_openssl_seal()).
     (Stas)
diff --git a/ext/openssl/tests/stream_security_level.phpt b/ext/openssl/tests/stream_security_level.phpt
new file mode 100644 (file)
index 0000000..fb1d36a
--- /dev/null
@@ -0,0 +1,48 @@
+--TEST--
+security_level setting to prohibit cert
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl")) die("skip openssl not loaded");
+if (OPENSSL_VERSION_NUMBER < 0x10100000) die("skip OpenSSL >= v1.1.0 required");
+if (!function_exists("proc_open")) die("skip no proc_open");
+--FILE--
+<?php
+$serverCode = <<<'CODE'
+       $serverUri = "ssl://127.0.0.1:64322";
+       $serverFlags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN;
+       $serverCtx = stream_context_create(['ssl' => [
+               'local_cert' => __DIR__ . '/bug54992.pem'
+       ]]);
+
+       $server = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx);
+       phpt_notify();
+
+       @stream_socket_accept($server, 1);
+CODE;
+
+$clientCode = <<<'CODE'
+       $serverUri = "ssl://127.0.0.1:64322";
+       $clientFlags = STREAM_CLIENT_CONNECT;
+       $clientCtx = stream_context_create(['ssl' => [
+               'security_level' => 3,
+               'verify_peer' => true,
+               'cafile' => __DIR__ . '/bug54992-ca.pem',
+               'verify_peer_name' => false
+       ]]);
+
+       phpt_wait();
+       $client = stream_socket_client($serverUri, $errno, $errstr, 1, $clientFlags, $clientCtx);
+
+       var_dump($client);
+CODE;
+
+include 'ServerClientTestCase.inc';
+ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
+--EXPECTF--
+Warning: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:
+error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed in %s : eval()'d code on line %d
+
+Warning: stream_socket_client(): Failed to enable crypto in %s : eval()'d code on line %d
+
+Warning: stream_socket_client(): unable to connect to ssl://127.0.0.1:64322 (Unknown error) in %s : eval()'d code on line %d
+bool(false)
index 94420fd0e40ed255339d1a2e34a93231e6535792..5aec089e00c85ce51b8a6137564cd3c8937fe4fc 100644 (file)
@@ -70,6 +70,9 @@
 #endif
 #endif
 
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+#define HAVE_SEC_LEVEL 1
+#endif
 
 /* Flags for determining allowed stream crypto methods */
 #define STREAM_CRYPTO_IS_CLIENT            (1<<0)
@@ -1613,6 +1616,20 @@ int php_openssl_setup_crypto(php_stream *stream,
                }
        }
 
+       if (GET_VER_OPT("security_level")) {
+#ifdef HAVE_SEC_LEVEL
+               convert_to_long(val);
+               if (Z_LVAL_P(val) < 0 || Z_LVAL_P(val) > 5) {
+                       php_error_docref(NULL, E_WARNING, "Security level must be between 0 and 5");
+               }
+               SSL_CTX_set_security_level(sslsock->ctx, Z_LVAL_P(val));
+#else
+               php_error_docref(NULL, E_WARNING,
+                               "security_level is not supported by the linked OpenSSL library "
+                               "- it is supported from version 1.1.0");
+#endif
+       }
+
        GET_VER_OPT_STRING("alpn_protocols", alpn_protocols);
        if (alpn_protocols) {
 #ifdef HAVE_TLS_ALPN