summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Lowrey <rdlowrey@php.net>2015-03-04 12:50:35 -0700
committerDaniel Lowrey <rdlowrey@php.net>2015-03-04 12:50:35 -0700
commit5de64a29e6104b2d3e1fcf9e3d8ea3ba6a87f22d (patch)
treed211bdda126e16fd1807b79e0631a4f8f59b31aa
parent01ccfb7cc91e652a6c93ec8c62817d4ed95bbc19 (diff)
parent241f3c34b89ab55432d5af3fd1e4217540e161a3 (diff)
downloadphp-git-5de64a29e6104b2d3e1fcf9e3d8ea3ba6a87f22d.tar.gz
Merge branch 'PHP-5.6'
* PHP-5.6: Fixed bug #68920 (use strict peer_fingerprint input checks) Conflicts: ext/openssl/xp_ssl.c
-rw-r--r--NEWS2
-rw-r--r--ext/openssl/tests/bug68920.phpt57
-rw-r--r--ext/openssl/tests/openssl_peer_fingerprint.phpt2
-rw-r--r--ext/openssl/xp_ssl.c22
4 files changed, 77 insertions, 6 deletions
diff --git a/NEWS b/NEWS
index 4f0518f303..9831ff8fa7 100644
--- a/NEWS
+++ b/NEWS
@@ -38,6 +38,8 @@
. Fixed bug #68912 (Segmentation fault at openssl_spki_new). (Laruence)
. Fixed bug #61285, #68329, #68046, #41631 (encrypted streams don't observe
socket timeouts). (Brad Broerman)
+ . Fixed bug #68920 (use strict peer_fingerprint input checks)
+ (Daniel Lowrey)
- pgsql:
. Fixed bug #68638 (pg_update() fails to store infinite values).
diff --git a/ext/openssl/tests/bug68920.phpt b/ext/openssl/tests/bug68920.phpt
new file mode 100644
index 0000000000..72e3f6c8f9
--- /dev/null
+++ b/ext/openssl/tests/bug68920.phpt
@@ -0,0 +1,57 @@
+--TEST--
+Bug #68920: peer_fingerprint input checks should be strict
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl")) die("skip openssl not loaded");
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+$ctx = stream_context_create(['ssl' => ['verify_peer'=> false, 'peer_fingerprint' => true]]);
+$sock = stream_socket_client("ssl://php.net:443", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $ctx);
+var_dump($sock);
+
+$ctx = stream_context_create(['ssl' => ['verify_peer'=> false, 'peer_fingerprint' => null]]);
+$sock = stream_socket_client("ssl://php.net:443", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $ctx);
+var_dump($sock);
+
+$ctx = stream_context_create(['ssl' => ['verify_peer'=> false, 'peer_fingerprint' => []]]);
+$sock = stream_socket_client("ssl://php.net:443", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $ctx);
+var_dump($sock);
+
+$ctx = stream_context_create(['ssl' => ['verify_peer'=> false, 'peer_fingerprint' => ['foo']]]);
+$sock = stream_socket_client("ssl://php.net:443", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $ctx);
+var_dump($sock);
+--EXPECTF--
+
+Warning: stream_socket_client(): Expected peer fingerprint must be a string or an array in %s on line %d
+
+Warning: stream_socket_client(): Failed to enable crypto in %s on line %d
+
+Warning: stream_socket_client(): unable to connect to %s (Unknown error) in %s on line %d
+bool(false)
+
+Warning: stream_socket_client(): Expected peer fingerprint must be a string or an array in %s on line %d
+
+Warning: stream_socket_client(): Failed to enable crypto in %s on line %d
+
+Warning: stream_socket_client(): unable to connect to %s (Unknown error) in %s on line %d
+bool(false)
+
+Warning: stream_socket_client(): Invalid peer_fingerprint array; [algo => fingerprint] form required in %s on line %d
+
+Warning: stream_socket_client(): peer_fingerprint match failure in %s on line %d
+
+Warning: stream_socket_client(): Failed to enable crypto in %s on line %d
+
+Warning: stream_socket_client(): unable to connect to %s (Unknown error) in %s on line %d
+bool(false)
+
+Warning: stream_socket_client(): Invalid peer_fingerprint array; [algo => fingerprint] form required in %s on line %d
+
+Warning: stream_socket_client(): peer_fingerprint match failure in %s on line %d
+
+Warning: stream_socket_client(): Failed to enable crypto in %s on line %d
+
+Warning: stream_socket_client(): unable to connect to %s (Unknown error) in %s on line %d
+bool(false)
diff --git a/ext/openssl/tests/openssl_peer_fingerprint.phpt b/ext/openssl/tests/openssl_peer_fingerprint.phpt
index 7f48cb4546..743233579a 100644
--- a/ext/openssl/tests/openssl_peer_fingerprint.phpt
+++ b/ext/openssl/tests/openssl_peer_fingerprint.phpt
@@ -45,7 +45,7 @@ CODE;
include 'ServerClientTestCase.inc';
ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
--EXPECTF--
-Warning: stream_socket_client(): Peer fingerprint doesn't match in %s on line %d
+Warning: stream_socket_client(): peer_fingerprint match failure in %s on line %d
Warning: stream_socket_client(): Failed to enable crypto in %s on line %d
diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c
index 2165091695..aac84b4426 100644
--- a/ext/openssl/xp_ssl.c
+++ b/ext/openssl/xp_ssl.c
@@ -299,15 +299,26 @@ static zend_bool php_x509_fingerprint_match(X509 *peer, zval *val)
zval *current;
zend_string *key;
+ if (!zend_hash_num_elements(Z_ARRVAL_P(val))) {
+ php_error_docref(NULL, E_WARNING, "Invalid peer_fingerprint array; [algo => fingerprint] form required");
+ return 0;
+ }
+
ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(val), key, current) {
- if (key && Z_TYPE_P(current) == IS_STRING
- && php_x509_fingerprint_cmp(peer, key->val, Z_STRVAL_P(current)) != 0
- ) {
+ if (key == NULL || Z_TYPE_P(current) != IS_STRING) {
+ php_error_docref(NULL, E_WARNING, "Invalid peer_fingerprint array; [algo => fingerprint] form required");
+ return 0;
+ }
+ if (php_x509_fingerprint_cmp(peer, key->val, Z_STRVAL_P(current)) != 0) {
return 0;
}
} ZEND_HASH_FOREACH_END();
+
return 1;
+ } else {
+ php_error_docref(NULL, E_WARNING, "Invalid peer_fingerprint value; fingerprint string or array of the form [algo => fingerprint] required");
}
+
return 0;
}
@@ -428,7 +439,7 @@ static int apply_peer_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
? zend_is_true(val)
: sslsock->is_client;
- must_verify_fingerprint = (GET_VER_OPT("peer_fingerprint") && zend_is_true(val));
+ must_verify_fingerprint = GET_VER_OPT("peer_fingerprint");
if ((must_verify_peer || must_verify_peer_name || must_verify_fingerprint) && peer == NULL) {
php_error_docref(NULL, E_WARNING, "Could not get peer certificate");
@@ -463,7 +474,7 @@ static int apply_peer_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
if (Z_TYPE_P(val) == IS_STRING || Z_TYPE_P(val) == IS_ARRAY) {
if (!php_x509_fingerprint_match(peer, val)) {
php_error_docref(NULL, E_WARNING,
- "Peer fingerprint doesn't match"
+ "peer_fingerprint match failure"
);
return FAILURE;
}
@@ -471,6 +482,7 @@ static int apply_peer_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
php_error_docref(NULL, E_WARNING,
"Expected peer fingerprint must be a string or an array"
);
+ return FAILURE;
}
}