[PATCH v4] sslutil-add tls 1.3 support - done during IETF101 Hackathon
Codarren Velvindron
codarren at hackers.mu
Sun Apr 8 04:46:00 EDT 2018
# HG changeset patch
# User Codarren Velvindron <codarren at hackers.mu>
# Date 1523166519 -14400
# Sun Apr 08 09:48:39 2018 +0400
# Node ID 5df15ef67ce1674a8f408058cd953de5ab9601cf
# Parent 632b928992039afe96df8f99a8dec6127ff983f1
slutil: add tls 1.3 support
Done during the IETF101 Hackathon.
diff -r 632b92899203 -r 5df15ef67ce1 mercurial/help/config.txt
--- a/mercurial/help/config.txt Sat Apr 07 21:26:37 2018 +0900
+++ b/mercurial/help/config.txt Sun Apr 08 09:48:39 2018 +0400
@@ -1163,7 +1163,7 @@
By default, the highest version of TLS supported by both client and server
is used.
- Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
+ Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``, ``tls1.3``.
When running on an old Python version, only ``tls1.0`` is allowed since
old versions of Python only support up to TLS 1.0.
diff -r 632b92899203 -r 5df15ef67ce1 mercurial/sslutil.py
--- a/mercurial/sslutil.py Sat Apr 07 21:26:37 2018 +0900
+++ b/mercurial/sslutil.py Sun Apr 08 09:48:39 2018 +0400
@@ -38,17 +38,20 @@
'tls1.0',
'tls1.1',
'tls1.2',
+ 'tls1.3',
}
hassni = getattr(ssl, 'HAS_SNI', False)
-# TLS 1.1 and 1.2 may not be supported if the OpenSSL Python is compiled
+# TLS 1.1,1.2 and 1.3 may not be supported if the OpenSSL Python is compiled
# against doesn't support them.
supportedprotocols = {'tls1.0'}
if util.safehasattr(ssl, 'PROTOCOL_TLSv1_1'):
supportedprotocols.add('tls1.1')
if util.safehasattr(ssl, 'PROTOCOL_TLSv1_2'):
supportedprotocols.add('tls1.2')
+if util.safehasattr(ssl, 'PROTOCOL_TLS'):
+ supportedprotocols.add('tls1.3')
try:
# ssl.SSLContext was added in 2.7.9 and presence indicates modern
@@ -293,7 +296,7 @@
# Despite its name, PROTOCOL_SSLv23 selects the highest protocol
# that both ends support, including TLS protocols. On legacy stacks,
# the highest it likely goes is TLS 1.0. On modern stacks, it can
- # support TLS 1.2.
+ # support TLS 1.2 or TLS 1.3.
#
# The PROTOCOL_TLSv* constants select a specific TLS version
# only (as opposed to multiple versions). So the method for
@@ -323,6 +326,8 @@
options |= ssl.OP_NO_TLSv1
elif protocol == 'tls1.2':
options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1
+ elif protocol == 'tls1.3':
+ options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_TLSv1_2
else:
raise error.Abort(_('this should not happen'))
@@ -542,6 +547,10 @@
if 'tls1.2' not in supportedprotocols:
raise error.Abort(_('TLS 1.2 not supported by this Python'))
protocol = ssl.PROTOCOL_TLSv1_2
+ elif exactprotocol == 'tls1.3':
+ if 'tls1.3' not in supportedprotocols:
+ raise error.Abort(_('TLS 1.3 not supported by this Python'))
+ protocol = ssl.PROTOCOL_TLSv1_3
elif exactprotocol:
raise error.Abort(_('invalid value for serverexactprotocol: %s') %
exactprotocol)
diff -r 632b92899203 -r 5df15ef67ce1 tests/hghave.py
--- a/tests/hghave.py Sat Apr 07 21:26:37 2018 +0900
+++ b/tests/hghave.py Sun Apr 08 09:48:39 2018 +0400
@@ -523,6 +523,11 @@
from mercurial import sslutil
return 'tls1.2' in sslutil.supportedprotocols
+ at check("tls1.3", "TLS 1.3 protocol support")
+def has_tls1_3():
+ from mercurial import sslutil
+ return 'tls1.3' in sslutil.supportedprotocols
+
@check("windows", "Windows")
def has_windows():
return os.name == 'nt'
diff -r 632b92899203 -r 5df15ef67ce1 tests/test-https.t
--- a/tests/test-https.t Sat Apr 07 21:26:37 2018 +0900
+++ b/tests/test-https.t Sun Apr 08 09:48:39 2018 +0400
@@ -536,6 +536,61 @@
$ killdaemons.py hg2.pid
#endif
+#if sslcontext tls1.3
+Start servers running supported TLS versions
+
+ $ cd test
+ $ hg serve -p $HGPORT -d --pid-file=../hg0.pid --certificate=$PRIV \
+ > --config devel.serverexactprotocol=tls1.0
+ $ cat ../hg0.pid >> $DAEMON_PIDS
+ $ hg serve -p $HGPORT1 -d --pid-file=../hg1.pid --certificate=$PRIV \
+ > --config devel.serverexactprotocol=tls1.3
+ $ cat ../hg1.pid >> $DAEMON_PIDS
+ $ cd ..
+
+Clients talking same TLS versions work
+
+ $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.0 id https://localhost:$HGPORT/
+ 5fed3813f7f5
+ $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.3 id https://localhost:$HGPORT1/
+ 5fed3813f7f5
+
+Clients requiring newer TLS version than what server supports fail
+
+ $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.3 id https://localhost:$HGPORT/
+ (could not negotiate a common security protocol (tls1.3+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
+ (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
+ (see https://mercurial-scm.org/wiki/SecureConnections for more info)
+ abort: error: *unsupported protocol* (glob)
+ [255]
+
+--insecure will allow TLS 1.0 connections and override configs
+
+ $ hg --config hostsecurity.minimumprotocol=tls1.3 id --insecure https://localhost:$HGPORT/
+ warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
+ 5fed3813f7f5
+
+The per-host config option overrides the default
+
+ $ P="$CERTSDIR" hg id https://localhost:$HGPORT/ \
+ > --config hostsecurity.minimumprotocol=tls1.3 \
+ > --config hostsecurity.localhost:minimumprotocol=tls1.0
+ 5fed3813f7f5
+
+The per-host config option by itself works
+
+ $ P="$CERTSDIR" hg id https://localhost:$HGPORT/ \
+ > --config hostsecurity.localhost:minimumprotocol=tls1.3
+ (could not negotiate a common security protocol (tls1.3+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
+ (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
+ (see https://mercurial-scm.org/wiki/SecureConnections for more info)
+ abort: error: *unsupported protocol* (glob)
+ [255]
+
+ $ killdaemons.py hg0.pid
+ $ killdaemons.py hg1.pid
+#endif
+
Prepare for connecting through proxy
$ hg serve -R test -p $HGPORT -d --pid-file=hg0.pid --certificate=$PRIV
More information about the Mercurial-devel
mailing list