From: Daniel Lowrey Date: Wed, 26 Feb 2014 20:06:08 +0000 (-0700) Subject: Deprecate CN_match in favor of peer_name in SSL contexts X-Git-Tag: php-5.6.0alpha3~1^2~8 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d0a6f8c68ec1044e936735f28bdc1bbd35f81362;p=php Deprecate CN_match in favor of peer_name in SSL contexts --- diff --git a/NEWS b/NEWS index b79f0006a9..0c28d48c4a 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,9 @@ PHP NEWS . Implemented unified default encoding (RFC: https://wiki.php.net/rfc/default_encoding). (Yasuo Ohgaki) +- Curl + . Check for openssl.cafile ini directive when loading CA certs. (Daniel Lowrey) + - Fileinfo . Upgraded to libmagic-5.17 (Anatol) @@ -25,12 +28,17 @@ PHP NEWS . Fallback to Windows CA cert store for peer verification if no openssl.cafile ini directive or "cafile" SSL context option specified in Windows. (Chris Wright) + . The openssl.cafile and openssl.capath ini directives introduced in alpha2 + now have PHP_INI_PERDIR accessibility (was PHP_INI_ALL). (Daniel Lowrey) + . New "peer_name" SSL context option replaces "CN_match" (which still works + as before but triggers E_DEPRECATED). (Daniel Lowrey) . Fixed segfault when accessing non-existent context for client SNI use (Daniel Lowrey) . Fixed bug #66501 (Add EC key support to php_openssl_is_private_key). (Mark Zedwood) - . Fixed Bug #47030 (add new boolean "verify_host" SSL context option - allowing clients to verify names separately from peer certs). + . Fixed Bug #47030 (add new boolean "verify_peer_name" SSL context option + allowing clients to verify cert names separately from the cert itself). + "verify_peer_name" is enabled by default for client streams. (Daniel Lowrey) . Fixed Bug #65538 ("cafile" SSL context option now supports stream wrappers). (Daniel Lowrey) diff --git a/UPGRADING b/UPGRADING index 4ef3085672..6ae672e4f5 100755 --- a/UPGRADING +++ b/UPGRADING @@ -69,8 +69,8 @@ PHP X.Y UPGRADE NOTES - Added gost-crypto (CryptoPro S-box) hash algo. -- Stream wrappers verify peers and host names by default in encrypted client - streams. +- Stream wrappers verify peer certificates and host names by default in + encrypted client streams. - Added openssl certificate fingerprint support (inclusive stream context option). @@ -104,10 +104,14 @@ PHP X.Y UPGRADE NOTES - Added "crypto_method" SSL context option for use in encrypted streams. +- Added "peer_name" SSL context option to better reflect peer certificate + name matching using SAN extension (replaces deprecated "CN_match"). + - Added stream wrapper support when specifying "cafile" SSL context paths. -- Independent peer cert and host names validation is now available via a new - "verify_host" SSL context option. +- Independent peer cert and peer name validation is now available via a new + boolean "verify_peer_name" SSL context option. This option is enabled by + default in encrypted client streams. - Added protocol-specific tlsv1.0://, tlsv1.1:// and tlsv1.2:// encryption stream wrappers. tls:// wrapper now supports TLSv1.1 and TLSv1.2 (previously @@ -131,6 +135,13 @@ PHP X.Y UPGRADE NOTES Instance calls from an incompatible context are now deprecated and issue E_DEPRECATED instead of E_STRICT. See https://wiki.php.net/rfc/incompat_ctx +- The "CN_match" SSL context option is deprecated in favor of the new + "peer_name" option. Name verification now checks certificate SAN names as + well as the CN field and "CN_match" is deprecated to avoid confusion. Its + use triggers E_DEPRECATED but continues to work as before. If both values + are specified "CN_match" takes precedence. Otherwise, the two options are + interchangeable. + ======================================== 4. Changed Functions ======================================== diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index d2b453807d..88ae9a1000 100755 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -5145,24 +5145,26 @@ static zend_bool matches_common_name(X509 *peer, const char *subject_name TSRMLS int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream *stream TSRMLS_DC) /* {{{ */ { zval **val = NULL; - char *cnmatch = NULL; + char *peer_name = NULL; int err; zend_bool must_verify_peer; - zend_bool must_verify_host; + zend_bool must_verify_peer_name; zend_bool must_verify_fingerprint; + zend_bool has_cnmatch_ctx_opt; php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract; must_verify_peer = GET_VER_OPT("verify_peer") ? zend_is_true(*val) : sslsock->is_client; - must_verify_host = GET_VER_OPT("verify_host") + has_cnmatch_ctx_opt = GET_VER_OPT("CN_match"); + must_verify_peer_name = (has_cnmatch_ctx_opt || GET_VER_OPT("verify_peer_name")) ? zend_is_true(*val) : sslsock->is_client; must_verify_fingerprint = (GET_VER_OPT("peer_fingerprint") && zend_is_true(*val)); - if ((must_verify_peer || must_verify_host || must_verify_fingerprint) && peer == NULL) { + if ((must_verify_peer || must_verify_peer_name || must_verify_fingerprint) && peer == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not get peer certificate"); return FAILURE; } @@ -5190,7 +5192,7 @@ int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream *stre } } - /* If a peer_fingerprint match is required this trumps host verification */ + /* If a peer_fingerprint match is required this trumps peer and peer_name verification */ if (must_verify_fingerprint) { if (Z_TYPE_PP(val) == IS_STRING || Z_TYPE_PP(val) == IS_ARRAY) { if (!php_x509_fingerprint_match(peer, *val TSRMLS_CC)) { @@ -5207,18 +5209,24 @@ int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream *stre } /* verify the host name presented in the peer certificate */ + if (must_verify_peer_name) { + GET_VER_OPT_STRING("peer_name", peer_name); - if (must_verify_host) { - GET_VER_OPT_STRING("CN_match", cnmatch); - /* If no CN_match was specified assign the autodetected url name in client environments */ - if (cnmatch == NULL && sslsock->is_client) { - cnmatch = sslsock->url_name; + if (has_cnmatch_ctx_opt) { + GET_VER_OPT_STRING("CN_match", peer_name); + php_error(E_DEPRECATED, + "the 'CN_match' SSL context option is deprecated in favor of 'peer_name'" + ); + } + /* If no peer name was specified we use the autodetected url name in client environments */ + if (peer_name == NULL && sslsock->is_client) { + peer_name = sslsock->url_name; } - if (cnmatch) { - if (matches_san_list(peer, cnmatch TSRMLS_CC)) { + if (peer_name) { + if (matches_san_list(peer, peer_name TSRMLS_CC)) { return SUCCESS; - } else if (matches_common_name(peer, cnmatch TSRMLS_CC)) { + } else if (matches_common_name(peer, peer_name TSRMLS_CC)) { return SUCCESS; } else { return FAILURE; @@ -5342,7 +5350,7 @@ static int win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, void *arg) / LPWSTR server_name = NULL; BOOL verify_result; - { /* This looks ridiculous and it is - but we validate the name ourselves using the CN_match + { /* This looks ridiculous and it is - but we validate the name ourselves using the peer_name ctx option, so just use the CN from the cert here */ X509_NAME *cert_name; diff --git a/ext/openssl/tests/bug46127.phpt b/ext/openssl/tests/bug46127.phpt index 6a3d1a0d6c..80bd61c287 100644 --- a/ext/openssl/tests/bug46127.phpt +++ b/ext/openssl/tests/bug46127.phpt @@ -27,7 +27,7 @@ $clientCode = <<<'CODE' $clientCtx = stream_context_create(['ssl' => [ 'verify_peer' => false, - 'verify_host' => false + 'verify_peer_name' => false ]]); phpt_wait(); diff --git a/ext/openssl/tests/bug48182.phpt b/ext/openssl/tests/bug48182.phpt index 8d3f9eef43..5211c23d20 100644 --- a/ext/openssl/tests/bug48182.phpt +++ b/ext/openssl/tests/bug48182.phpt @@ -28,7 +28,7 @@ $clientCode = <<<'CODE' $clientFlags = STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT; $clientCtx = stream_context_create(['ssl' => [ 'cafile' => __DIR__ . '/bug54992-ca.pem', - 'CN_match' => 'bug54992.local' + 'peer_name' => 'bug54992.local' ]]); phpt_wait(); diff --git a/ext/openssl/tests/bug54992.phpt b/ext/openssl/tests/bug54992.phpt index 2937faa169..bcb33fdd8a 100644 --- a/ext/openssl/tests/bug54992.phpt +++ b/ext/openssl/tests/bug54992.phpt @@ -25,7 +25,7 @@ $clientCode = <<<'CODE' $clientCtx = stream_context_create(['ssl' => [ 'verify_peer' => true, 'cafile' => __DIR__ . '/bug54992-ca.pem', - 'CN_match' => 'buga_buga', + 'peer_name' => 'buga_buga', ]]); phpt_wait(); diff --git a/ext/openssl/tests/bug65538_001.phpt b/ext/openssl/tests/bug65538_001.phpt index ea7d6f4d8d..e666859d0d 100644 --- a/ext/openssl/tests/bug65538_001.phpt +++ b/ext/openssl/tests/bug65538_001.phpt @@ -37,7 +37,7 @@ $clientCode = <<<'CODE' $serverUri = "https://127.0.0.1:64321/"; $clientCtx = stream_context_create(['ssl' => [ 'cafile' => 'file://' . __DIR__ . '/bug54992-ca.pem', - 'CN_match' => 'bug54992.local', + 'peer_name' => 'bug54992.local', ]]); phpt_wait(); diff --git a/ext/openssl/tests/bug65538_003.phpt b/ext/openssl/tests/bug65538_003.phpt index b927e4ed85..da99779143 100644 --- a/ext/openssl/tests/bug65538_003.phpt +++ b/ext/openssl/tests/bug65538_003.phpt @@ -38,7 +38,7 @@ $clientCode = <<<'CODE' $serverUri = "https://127.0.0.1:64321/"; $clientCtx = stream_context_create(['ssl' => [ 'cafile' => 'phar://' . __DIR__ . '/bug65538.phar/bug54992-ca.pem', - 'CN_match' => 'bug54992.local', + 'peer_name' => 'bug54992.local', ]]); phpt_wait(); diff --git a/ext/openssl/tests/bug65729.phpt b/ext/openssl/tests/bug65729.phpt index e27dbb9c93..b405b7213d 100644 --- a/ext/openssl/tests/bug65729.phpt +++ b/ext/openssl/tests/bug65729.phpt @@ -33,7 +33,7 @@ $clientCode = <<<'CODE' $clientCtx = stream_context_create(['ssl' => [ 'verify_peer' => true, 'allow_self_signed' => true, - 'CN_match' => $expected_name, + 'peer_name' => $expected_name, ]]); var_dump(stream_socket_client($serverUri, $errno, $errstr, 1, $clientFlags, $clientCtx)); diff --git a/ext/openssl/tests/openssl_peer_fingerprint.phpt b/ext/openssl/tests/openssl_peer_fingerprint.phpt index 5390c492ee..0bd91d543a 100644 --- a/ext/openssl/tests/openssl_peer_fingerprint.phpt +++ b/ext/openssl/tests/openssl_peer_fingerprint.phpt @@ -27,7 +27,7 @@ $clientCode = <<<'CODE' 'verify_peer' => true, 'cafile' => __DIR__ . '/bug54992-ca.pem', 'capture_peer_cert' => true, - 'CN_match' => 'bug54992.local', + 'peer_name' => 'bug54992.local', ]]); phpt_wait(); diff --git a/ext/openssl/tests/peer_verification.phpt b/ext/openssl/tests/peer_verification.phpt index 607b61797f..6aff34ddd8 100644 --- a/ext/openssl/tests/peer_verification.phpt +++ b/ext/openssl/tests/peer_verification.phpt @@ -40,14 +40,14 @@ $clientCode = <<<'CODE' // Should succeed with peer verification disabled in context $clientCtx = stream_context_create(['ssl' => [ 'verify_peer' => false, - 'verify_host' => false, + 'verify_peer_name' => false, ]]); var_dump(stream_socket_client($serverUri, $errno, $errstr, 1, $clientFlags, $clientCtx)); // Should succeed with CA file specified in context $clientCtx = stream_context_create(['ssl' => [ 'cafile' => $caFile, - 'CN_match' => 'bug54992.local', + 'peer_name' => 'bug54992.local', ]]); var_dump(stream_socket_client($serverUri, $errno, $errstr, 1, $clientFlags, $clientCtx)); CODE; diff --git a/ext/openssl/tests/san_peer_matching.phpt b/ext/openssl/tests/san_peer_matching.phpt index 3fa479ea13..0e1f30cb64 100644 --- a/ext/openssl/tests/san_peer_matching.phpt +++ b/ext/openssl/tests/san_peer_matching.phpt @@ -30,10 +30,10 @@ $clientCode = <<<'CODE' phpt_wait(); - stream_context_set_option($clientCtx, 'ssl', 'CN_match', 'example.org'); + stream_context_set_option($clientCtx, 'ssl', 'peer_name', 'example.org'); var_dump(stream_socket_client($serverUri, $errno, $errstr, 1, $clientFlags, $clientCtx)); - stream_context_set_option($clientCtx, 'ssl', 'CN_match', 'moar.example.org'); + stream_context_set_option($clientCtx, 'ssl', 'peer_name', 'moar.example.org'); var_dump(stream_socket_client($serverUri, $errno, $errstr, 1, $clientFlags, $clientCtx)); CODE; diff --git a/ext/openssl/tests/session_meta_capture.phpt b/ext/openssl/tests/session_meta_capture.phpt index 3b2a80446f..62cdffe686 100644 --- a/ext/openssl/tests/session_meta_capture.phpt +++ b/ext/openssl/tests/session_meta_capture.phpt @@ -29,7 +29,7 @@ $clientCode = <<<'CODE' $clientCtx = stream_context_create(['ssl' => [ 'verify_peer' => true, 'cafile' => __DIR__ . '/bug54992-ca.pem', - 'CN_match' => 'bug54992.local', + 'peer_name' => 'bug54992.local', 'capture_session_meta' => true, ]]); diff --git a/ext/openssl/tests/sni_001.phpt b/ext/openssl/tests/sni_001.phpt index 0dbd18d381..e6c05f7ec2 100644 --- a/ext/openssl/tests/sni_001.phpt +++ b/ext/openssl/tests/sni_001.phpt @@ -26,9 +26,9 @@ function context($host = NULL) { stream_context_set_option($ctx, 'ssl', 'capture_peer_cert', true); stream_context_set_option($ctx, 'ssl', 'verify_peer', false); if ($host) { - stream_context_set_option($ctx, 'ssl', 'CN_match', $host); + stream_context_set_option($ctx, 'ssl', 'peer_name', $host); } else { - stream_context_set_option($ctx, 'ssl', 'verify_host', false); + stream_context_set_option($ctx, 'ssl', 'verify_peer_name', false); } return $ctx; diff --git a/ext/openssl/tests/stream_crypto_flags_001.phpt b/ext/openssl/tests/stream_crypto_flags_001.phpt index b9a49f9ac2..f988886db2 100644 --- a/ext/openssl/tests/stream_crypto_flags_001.phpt +++ b/ext/openssl/tests/stream_crypto_flags_001.phpt @@ -27,7 +27,7 @@ $clientCode = <<<'CODE' $clientCtx = stream_context_create(['ssl' => [ 'verify_peer' => true, 'cafile' => __DIR__ . '/bug54992-ca.pem', - 'CN_match' => 'bug54992.local', + 'peer_name' => 'bug54992.local', ]]); phpt_wait(); diff --git a/ext/openssl/tests/stream_crypto_flags_002.phpt b/ext/openssl/tests/stream_crypto_flags_002.phpt index 15b3fb9416..b72b4d62f2 100644 --- a/ext/openssl/tests/stream_crypto_flags_002.phpt +++ b/ext/openssl/tests/stream_crypto_flags_002.phpt @@ -29,7 +29,7 @@ $clientCode = <<<'CODE' $clientCtx = stream_context_create(['ssl' => [ 'verify_peer' => true, 'cafile' => __DIR__ . '/bug54992-ca.pem', - 'CN_match' => 'bug54992.local', + 'peer_name' => 'bug54992.local', ]]); phpt_wait(); diff --git a/ext/openssl/tests/stream_crypto_flags_003.phpt b/ext/openssl/tests/stream_crypto_flags_003.phpt index c5aebd891f..30ca7a76e9 100644 --- a/ext/openssl/tests/stream_crypto_flags_003.phpt +++ b/ext/openssl/tests/stream_crypto_flags_003.phpt @@ -32,7 +32,7 @@ $clientCode = <<<'CODE' $clientCtx = stream_context_create(['ssl' => [ 'verify_peer' => true, 'cafile' => __DIR__ . '/bug54992-ca.pem', - 'CN_match' => 'bug54992.local', + 'peer_name' => 'bug54992.local', ]]); phpt_wait(); diff --git a/ext/openssl/tests/stream_crypto_flags_004.phpt b/ext/openssl/tests/stream_crypto_flags_004.phpt index 38f406caa3..e51a2bab3e 100644 --- a/ext/openssl/tests/stream_crypto_flags_004.phpt +++ b/ext/openssl/tests/stream_crypto_flags_004.phpt @@ -29,7 +29,7 @@ $clientCode = <<<'CODE' $clientCtx = stream_context_create(['ssl' => [ 'verify_peer' => true, 'cafile' => __DIR__ . '/bug54992-ca.pem', - 'CN_match' => 'bug54992.local', + 'peer_name' => 'bug54992.local', ]]); phpt_wait(); diff --git a/ext/openssl/tests/stream_verify_host_001.phpt b/ext/openssl/tests/stream_verify_peer_name_001.phpt similarity index 96% rename from ext/openssl/tests/stream_verify_host_001.phpt rename to ext/openssl/tests/stream_verify_peer_name_001.phpt index c4d87b82db..4aecf8c744 100644 --- a/ext/openssl/tests/stream_verify_host_001.phpt +++ b/ext/openssl/tests/stream_verify_peer_name_001.phpt @@ -24,7 +24,7 @@ $clientCode = <<<'CODE' $clientFlags = STREAM_CLIENT_CONNECT; $clientCtx = stream_context_create(['ssl' => [ 'verify_peer' => false, - 'CN_match' => 'bug54992.local' + 'peer_name' => 'bug54992.local' ]]); phpt_wait(); diff --git a/ext/openssl/tests/stream_verify_host_002.phpt b/ext/openssl/tests/stream_verify_peer_name_002.phpt similarity index 96% rename from ext/openssl/tests/stream_verify_host_002.phpt rename to ext/openssl/tests/stream_verify_peer_name_002.phpt index c0db4f2d90..ae97ea1269 100644 --- a/ext/openssl/tests/stream_verify_host_002.phpt +++ b/ext/openssl/tests/stream_verify_peer_name_002.phpt @@ -25,7 +25,7 @@ $clientCode = <<<'CODE' $clientCtx = stream_context_create(['ssl' => [ 'verify_peer' => true, 'cafile' => __DIR__ . '/bug54992-ca.pem', - 'verify_host' => false + 'verify_peer_name' => false ]]); phpt_wait(); diff --git a/ext/openssl/tests/stream_verify_host_003.phpt b/ext/openssl/tests/stream_verify_peer_name_003.phpt similarity index 100% rename from ext/openssl/tests/stream_verify_host_003.phpt rename to ext/openssl/tests/stream_verify_peer_name_003.phpt diff --git a/ext/openssl/tests/streams_crypto_method.phpt b/ext/openssl/tests/streams_crypto_method.phpt index 1bf9048151..84f7934308 100644 --- a/ext/openssl/tests/streams_crypto_method.phpt +++ b/ext/openssl/tests/streams_crypto_method.phpt @@ -39,7 +39,7 @@ $clientCode = <<<'CODE' $clientCtx = stream_context_create(['ssl' => [ 'crypto_method' => STREAM_CRYPTO_METHOD_SSLv3_CLIENT, 'verify_peer' => false, - 'verify_host' => false + 'verify_peer_name' => false ]]); phpt_wait(); diff --git a/ext/openssl/tests/tlsv1.0_wrapper.phpt b/ext/openssl/tests/tlsv1.0_wrapper.phpt index d24ab455de..7479259426 100644 --- a/ext/openssl/tests/tlsv1.0_wrapper.phpt +++ b/ext/openssl/tests/tlsv1.0_wrapper.phpt @@ -24,7 +24,7 @@ $clientCode = <<<'CODE' $flags = STREAM_CLIENT_CONNECT; $ctx = stream_context_create(['ssl' => [ 'verify_peer' => false, - 'verify_host' => false, + 'verify_peer_name' => false, ]]); phpt_wait(); diff --git a/ext/openssl/tests/tlsv1.1_wrapper.phpt b/ext/openssl/tests/tlsv1.1_wrapper.phpt index cd881782c4..3e067a14b7 100644 --- a/ext/openssl/tests/tlsv1.1_wrapper.phpt +++ b/ext/openssl/tests/tlsv1.1_wrapper.phpt @@ -25,7 +25,7 @@ $clientCode = <<<'CODE' $flags = STREAM_CLIENT_CONNECT; $ctx = stream_context_create(['ssl' => [ 'verify_peer' => false, - 'verify_host' => false, + 'verify_peer_name' => false, ]]); phpt_wait(); diff --git a/ext/openssl/tests/tlsv1.2_wrapper.phpt b/ext/openssl/tests/tlsv1.2_wrapper.phpt index 124fdf202c..ca967d18b4 100644 --- a/ext/openssl/tests/tlsv1.2_wrapper.phpt +++ b/ext/openssl/tests/tlsv1.2_wrapper.phpt @@ -25,7 +25,7 @@ $clientCode = <<<'CODE' $flags = STREAM_CLIENT_CONNECT; $ctx = stream_context_create(['ssl' => [ 'verify_peer' => false, - 'verify_host' => false, + 'verify_peer_name' => false, ]]); phpt_wait();