rfc:improved-tls-defaults
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionLast revisionBoth sides next revision | ||
rfc:improved-tls-defaults [2014/02/07 14:33] – rdlowrey | rfc:improved-tls-defaults [2014/06/20 12:12] – Correct server_forward_secrecy anchor target daverandom | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Improved TLS Defaults ====== | ====== Improved TLS Defaults ====== | ||
- | * Version: 0.9 | + | * Version: 0.11 |
* Date: 2014-01-28 | * Date: 2014-01-28 | ||
- | * Author: Daniel Lowrey, rdlowrey@gmail.com | + | * Author: Daniel Lowrey, rdlowrey@php.net |
- | * Status: | + | * Status: |
* First Published at: http:// | * First Published at: http:// | ||
- | * Minor Revision (v0.1 → v0.2): 2014-01-28 | ||
- | * Major Revision (v0.2 → v0.3): 2014-01-29 | ||
- | * Minor Revision (v0.3 → v0.4): 2014-01-30 | ||
- | * Minor Revision (v0.4 → v0.5): 2014-01-30 | ||
- | * Major Revision (v0.5 → v0.6): 2014-02-01 | ||
- | * Minor Revision (v0.6 → v0.7): 2014-02-02 | ||
- | * Minor Revision (v0.7 → v0.8): 2014-02-03 | ||
- | * Minor Revision (v0.8 → v0.9): 2014-02-06 | ||
===== Introduction ===== | ===== Introduction ===== | ||
Line 43: | Line 35: | ||
* [[https:// | * [[https:// | ||
* [[https:// | * [[https:// | ||
- | * [[https:// | ||
* [[https:// | * [[https:// | ||
- | * [[https:// | + | * [[https:// |
* [[https:// | * [[https:// | ||
- | * [[https:// | + | * [[https:// |
===== Default Ciphers ===== | ===== Default Ciphers ===== | ||
- | Currently all encrypted stream transports use the openssl '' | + | Currently all encrypted stream transports use the openssl '' |
specified by the user via a ''" | specified by the user via a ''" | ||
to the possibility that very weak ciphers will be negotiated for SSL/TLS sessions. The use of such | to the possibility that very weak ciphers will be negotiated for SSL/TLS sessions. The use of such | ||
Line 75: | Line 66: | ||
'' | '' | ||
- | * Anonymous Diffie-Hellman ciphers disallowed as per [[http://www.ietf.org/rfc/rfc2246.txt|RFC2246 Section A.5]] | + | * Anonymous Diffie-Hellman ciphers disallowed as per [[http://tools.ietf.org/html/rfc2246#appendix-A.5|RFC2246 Section A.5]] |
'' | '' | ||
Line 171: | Line 162: | ||
$context = stream_context_create([' | $context = stream_context_create([' | ||
- | | + | |
+ | " | ||
+ | " | ||
+ | "honor_cipher_order" | ||
]]); | ]]); | ||
- | + | ||
- | $uri = 'https://www.bankofamerica.com/'; | + | $socketFlags |
- | $html = file_get_contents($uri, FALSE, $context); | + | $server = stream_socket_server('tls://127.0.0.1:443', $errno, |
?> | ?> | ||
</ | </ | ||
- | |||
- | |||
- | ===== Verify Depth ===== | ||
- | |||
- | **Proposal** | ||
- | |||
- | * Use a default ''" | ||
- | |||
- | **Logic** | ||
- | |||
- | Users can control how deeply PHP should verify certificates before concluding that the peer's | ||
- | certificate is invalid via the existing ''" | ||
- | " | ||
- | ''" | ||
- | valid. By default PHP sets no limit on how deeply certificate chains can be verified. | ||
- | |||
- | This proposal specifies a default ''" | ||
- | |||
- | **Example** | ||
- | |||
- | <code php> | ||
- | <?php | ||
- | |||
- | // New informational constant exposed to userland | ||
- | var_dump(OPENSSL_DEFAULT_STREAM_VERIFY_DEPTH); | ||
- | |||
- | $context = stream_context_create([' | ||
- | ' | ||
- | ]]); | ||
- | |||
- | $html = file_get_contents(' | ||
- | |||
- | ?> | ||
- | </ | ||
- | |||
===== Expose Negotiated Values ===== | ===== Expose Negotiated Values ===== | ||
Line 225: | Line 184: | ||
Users may wish to access information regarding the negotiated protocol and/or cipher for a given | Users may wish to access information regarding the negotiated protocol and/or cipher for a given | ||
encrypted session. The '' | encrypted session. The '' | ||
- | conflicts with other wrappers | + | conflicts with other wrappers. The context option approach also remains consistent with the existing |
- | also remains consistent with the existing '' | + | '' |
- | context abstractions. When the new context option is truthy the '' | + | context option is truthy the '' |
- | option is populated with an informational array as shown here: | + | informational array as shown here: |
**Example** | **Example** | ||
Line 256: | Line 215: | ||
</ | </ | ||
- | ===== Forward Secrecy | + | ===== Server |
**Proposal** | **Proposal** | ||
- | Encrypted client streams already support [[http:// | + | Encrypted client streams already |
- | as this functionality is largely implemented server-side. | + | (PFS) as this functionality is largely implemented server-side. |
- | encrypted PHP stream //servers// to also achieve (perfect) forward secrecy when negotiating cipher | + | support for PFS, however, the proposed |
- | suites that utilize ephemeral key agreements. | + | in servers negotiating cipher suites that utilize ephemeral key agreements. |
+ | |||
+ | //NOTE:// Servers deploying certificates capable of PFS aren't required to take any additional action | ||
+ | to achieve forward secrecy. The proposed context options simply allow fine-grained configuration and | ||
+ | broader potential FS support/ | ||
**New Context Options** | **New Context Options** | ||
Line 306: | Line 269: | ||
$context = stream_context_create([' | $context = stream_context_create([' | ||
- | " | ||
" | " | ||
" | " | ||
Line 321: | Line 283: | ||
stream_set_blocking($server, | stream_set_blocking($server, | ||
- | // stream_socket_enable_crypto() is used when client sockets are accepted | + | // stream_socket_enable_crypto() is used after client sockets are accepted |
// to enable crypto in a non-blocking way ... | // to enable crypto in a non-blocking way ... | ||
+ | |||
+ | stream_socket_enable_crypto($client, | ||
?> | ?> | ||
Line 373: | Line 337: | ||
Meanwhile, 5.6 has added the following new wrappers: | Meanwhile, 5.6 has added the following new wrappers: | ||
- | * '' | ||
* '' | * '' | ||
* '' | * '' | ||
Line 408: | Line 371: | ||
* Allow only one narrow protocol | * Allow only one narrow protocol | ||
- | * Allow *ALL* of the protocols, even if some do not provide the requisite level of security | + | * Allow //ALL// of the protocols, even if some do not provide the requisite level of security |
While this paradigm negatively impacts client-side applications, | While this paradigm negatively impacts client-side applications, | ||
Line 418: | Line 381: | ||
* Internally re-value the existing '' | * Internally re-value the existing '' | ||
- | * Remove the new stream wrappers previously merged for inclusion in 5.6: | + | * New '' |
- | * '' | + | * Repurpose |
- | * '' | + | |
- | * '' | + | |
- | * Deprecate the following stream wrappers in PHP 5.6 with removal | + | |
- | * '' | + | |
- | * '' | + | |
- | * '' | + | |
- | + | ||
- | **Logic** | + | |
- | + | ||
- | The main reason for reshuffling the stream wrappers is simplicity. Most users are unlikely to know | + | |
- | the difference between the various protocols much less which they should use. It's not difficult to | + | |
- | imagine a scenario in which a user reasons, //"If SSL is safe, SSLv2 and SSLv3 must be REALLY safe. | + | |
- | I should use those."// | + | |
- | despite its standing as the most secure option. | + | |
- | + | ||
- | So the overarching goal in this change is two-fold: | + | |
- | + | ||
- | * Keep users safe by default without preventing them from doing insecure things if they need to do so; | + | |
- | * Eliminate | + | |
- | + | ||
- | The decision was made to retain | + | |
- | population is more familiar with what " | + | |
- | specified using the ''" | + | |
- | Note again that these stream wrappers //are not// removed. Their use will trigger an | + | |
- | '' | + | |
- | + | ||
- | Note also that though the '' | + | |
- | best available of the TLS1, TLSv1.1 and TLSv1.2 protocols. Because '' | + | |
- | TLSv1.1 and TLSv1.2 prior to PHP 5.6 this wrapper was previously | + | |
- | + | ||
- | **BC Implications of Proposed Stream Wrapper Changes** | + | |
- | + | ||
- | //None.// | + | |
- | + | ||
- | The only implications for existing code are the '' | + | |
- | '' | + | |
- | notices. This notice triggering has nothing to do with the underlying protocols; it only occurs when | + | |
- | using the wrappers made unnecessary by the introduction of protocol flags. Users are encouraged to | + | |
- | specify protocol flags in their stream contexts to avoid these deprecation notices. | + | |
**Existing Constant Re-Valuing** | **Existing Constant Re-Valuing** | ||
Line 475: | Line 399: | ||
STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT = (1 << 5 | 1), /* New in 5.6 */ | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT = (1 << 5 | 1), /* New in 5.6 */ | ||
STREAM_CRYPTO_METHOD_TLS_CLIENT = ((1 << 3) | (1 << 4) | (1 << 5) | 1), /* Any TLS protocol */ | STREAM_CRYPTO_METHOD_TLS_CLIENT = ((1 << 3) | (1 << 4) | (1 << 5) | 1), /* Any TLS protocol */ | ||
+ | STREAM_CRYPTO_METHOD_ANY_CLIENT = ((1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | 1), /* Any protocol */ | ||
STREAM_CRYPTO_METHOD_SSLv2_SERVER = (1 << 1), | STREAM_CRYPTO_METHOD_SSLv2_SERVER = (1 << 1), | ||
STREAM_CRYPTO_METHOD_SSLv3_SERVER = (1 << 2), | STREAM_CRYPTO_METHOD_SSLv3_SERVER = (1 << 2), | ||
Line 482: | Line 407: | ||
STREAM_CRYPTO_METHOD_TLSv1_2_SERVER = (1 << 5), /* New in 5.6 */ | STREAM_CRYPTO_METHOD_TLSv1_2_SERVER = (1 << 5), /* New in 5.6 */ | ||
STREAM_CRYPTO_METHOD_TLS_SERVER = ((1 << 3) | (1 << 4) | (1 << 5)) /* Any TLS protocol */ | STREAM_CRYPTO_METHOD_TLS_SERVER = ((1 << 3) | (1 << 4) | (1 << 5)) /* Any TLS protocol */ | ||
+ | STREAM_CRYPTO_METHOD_ANY_SERVER = ((1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5)), /* Any protocol */ | ||
} php_stream_xport_crypt_method_t; | } php_stream_xport_crypt_method_t; | ||
</ | </ | ||
Line 491: | Line 417: | ||
legacy naming convention is a source of constant confusion for users not versed in the inner-workings | legacy naming convention is a source of constant confusion for users not versed in the inner-workings | ||
of OpenSSL. Here we use the more natural connotation and translate '' | of OpenSSL. Here we use the more natural connotation and translate '' | ||
- | mean " | + | mean " |
+ | represent //"any protocol we can support."// | ||
**Examples** | **Examples** | ||
Line 513: | Line 440: | ||
' | ' | ||
]]); | ]]); | ||
- | $html = file_get_contents(' | + | $html = file_get_contents(' |
?> | ?> | ||
Line 523: | Line 450: | ||
<?php | <?php | ||
- | $allowedProtocols = STREAM_CRYPTO_METHOD_SSLv3_CLIENT | + | $allowedProtocols = STREAM_CRYPTO_METHOD_SSLv3_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; |
$context = stream_context_create([' | $context = stream_context_create([' | ||
' | ' | ||
Line 550: | Line 477: | ||
</ | </ | ||
- | Connect using the (deprecated) | + | Connect using the '' |
- | available protocol of TLSv1, TLSv1.1, TLSv1.2. The stream is created successfully and an | + | available protocol of TLSv1, TLSv1.1, TLSv1.2: |
- | E_DEPRECATED error is triggered to encourage users to use the catch-all '' | + | |
<code php> | <code php> | ||
<?php | <?php | ||
- | // Triggers E_DEPRECATED, | + | $timeout = 42; |
- | $sock = stream_socket_client(' | + | $connFlags |
- | ?> | + | // Works as before |
- | </code> | + | $sock = stream_socket_client(' |
- | + | ||
- | The //only// wrapper for which the " | + | |
- | context | + | |
- | + | ||
- | <code php> | + | |
- | <?php | + | |
+ | // Negotiates SSLv3, TLSv1.1 or TLSv1.2 because tls:// default is overridden by the context | ||
$context = stream_context_create([' | $context = stream_context_create([' | ||
- | ' | + | ' |
]]); | ]]); | ||
- | + | $sock = stream_socket_client(' | |
- | // Triggers E_DEPRECATED, | + | |
- | $sock = stream_socket_client(' | + | |
?> | ?> | ||
</ | </ | ||
- | There is no need to use the deprecated wrappers as the '' | + | Enable crypto on an existing stream. Previously only a single value constant could be used at |
- | the best available protocol. However, for the sake of completeness, | + | parameter 3. Flags are now accepted as shown here: |
- | works: | + | |
<code php> | <code php> | ||
<?php | <?php | ||
- | $sock = stream_socket_client(' | + | $cryptoMethod |
+ | stream_socket_enable_crypto($stream , $enable = TRUE, $cryptoMethod); | ||
?> | ?> | ||
</ | </ | ||
- | Enable crypto on an existing stream. Previously only a single value constant | + | Encrypt |
- | parameter 3. Flags are now accepted as shown here: | + | '' |
<code php> | <code php> | ||
<?php | <?php | ||
- | $cryptoMethod | + | $sock = stream_socket_client(' |
- | stream_socket_enable_crypto($stream | + | var_dump($sock); // resource(%d) of type (stream) |
+ | var_dump(stream_socket_enable_crypto($sock, TRUE, STREAM_CRYPTO_METHOD_ANY_CLIENT)); | ||
?> | ?> | ||
Line 606: | Line 526: | ||
===== TL;DR Definitive Progress ===== | ===== TL;DR Definitive Progress ===== | ||
- | **Requirements for a secure transfer prior to PHP 5.6:** | + | **Forward Secrecy** |
+ | |||
+ | Encrypted stream servers support improved forward secrecy using ephemeral key exchange via RSA, DH | ||
+ | and elliptic curve DH. No additional action is required for servers deploying certificates capable | ||
+ | of ephemeral key exchange; new context options for fine-grained configuration are available. | ||
+ | |||
+ | **Requirements for a secure | ||
Note that this is still insufficient as SAN x509 extension matching is unavailable prior to 5.6. | Note that this is still insufficient as SAN x509 extension matching is unavailable prior to 5.6. | ||
Line 618: | Line 544: | ||
' | ' | ||
' | ' | ||
- | ' | ||
' | ' | ||
' | ' | ||
Line 629: | Line 554: | ||
</ | </ | ||
- | **Requirements for a secure transfer in 5.6 without this proposal:** | + | **Requirements for a secure |
<code php> | <code php> | ||
Line 636: | Line 561: | ||
' | ' | ||
' | ' | ||
- | ' | ||
' | ' | ||
) | ) | ||
Line 646: | Line 570: | ||
- | **Requirements for a secure transfer in 5.6 if this RFC passes:** | + | **Requirements for a secure |
Users are encouraged to merge the provided patch and view the HTML returned in the following code | Users are encouraged to merge the provided patch and view the HTML returned in the following code | ||
Line 657: | Line 581: | ||
</ | </ | ||
+ | |||
+ | ===== Removed Features Originally Planned for 5.6 ===== | ||
+ | |||
+ | Originally this RFC proposed the deprecation and future remove of the protocol-specific wrappers. | ||
+ | This recommendation was removed to retain the ability for streams without access to a stream context | ||
+ | to interface with protocol-specific clients and servers. In particular, the '' | ||
+ | cannot accept a stream context. As a result, removing protocol-specific stream wrappers would render | ||
+ | '' | ||
+ | hello methods. | ||
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== | ||
- | Most existing code is expected work without any BC implications. The only source of potential breakage | + | Most existing code is expected |
- | involves the scenario where users connect to servers employing outdated/ | + | involves the scenario where users connect to servers employing |
- | For these users the option always exists to manually override secure defaults with insecure settings | + | technologies. For these users the option always exists to manually override secure defaults with |
- | in the stream context. | + | insecure settings in the stream context. |
===== Proposed PHP Version ===== | ===== Proposed PHP Version ===== | ||
Line 673: | Line 606: | ||
'' | '' | ||
- | Provides userland access to the default cipher list used for stream encryption | + | Provides userland access to the default cipher list used for stream encryption. |
- | '' | + | '' |
- | Provides userland access to the default verify depth used for stream encryption | + | Crypto method interpreted as "any client crypto method we can possibly support." |
+ | use this method | ||
+ | |||
+ | '' | ||
+ | |||
+ | Crypto method interpreted as "any server crypto method we can possibly support." | ||
+ | use this method for maximum compatibility with SSLv2, SSLv3, TLSv1, TLSv1.1 and TLSv1.2 clients. | ||
'' | '' | ||
- | Flag allowing specific TLSv1 usage in encrypted client streams | + | Crypto method flag allowing specific TLSv1 usage in encrypted client streams. |
'' | '' | ||
- | Flag allowing specific TLSv1 usage in encrypted server streams | + | Crypto method flag allowing specific TLSv1 usage in encrypted server streams. |
- | + | ||
- | ===== Open Issues ===== | + | |
- | + | ||
- | * Feedback? | + | |
===== Proposed Voting Choices ===== | ===== Proposed Voting Choices ===== | ||
Line 695: | Line 630: | ||
* Should PHP implement the recommendations in this proposal as part of 5.6? | * Should PHP implement the recommendations in this proposal as part of 5.6? | ||
- | ===== Patches and Tests ===== | + | https:// |
- | The linked patch is ready to merge against PHP-5.6 and includes several .phpt tests: | + | ===== Vote ===== |
- | https://gist.github.com/rdlowrey/2b3895db9329582d37f6 | + | Voting period: //2014/02/11 - 2014/02/19// |
- | ===== Implementation ===== | + | Note that the minor revisions in v0.10 of this RFC were introduced soon after the initial vote |
+ | announcement (in response to feedback). The changes are cosmetic in relation to the main elements | ||
+ | of the RFC. They are noted here to avoid confusion. | ||
- | TBD | + | <doodle title=" |
+ | * Yes | ||
+ | * No | ||
+ | </ | ||
- | ===== Vote ===== | + | Thanks for your time :) |
- | //Voting will begin on Feb. 11// | ||
- | ===== Rejected Features ===== | ||
- | TBD | + | == Revisions == |
+ | v0.11 Updated constant names, protocol-specific stream wrappers no longer deprecated | ||
- | + | v0.10 Removed default verify depth setting; tls wrapper no longer deprecated | |
- | == Revisions == | + | |
v0.9 Added server forward secrecy, updated default cipher list | v0.9 Added server forward secrecy, updated default cipher list |
rfc/improved-tls-defaults.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1