blob: b6ad58ddfd5e17cc98ed4c75786fc4128d41946a [file] [log] [blame]
diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py
index 6d78a20..f9c8676 100644
--- a/third_party/tlslite/tlslite/constants.py
+++ b/third_party/tlslite/tlslite/constants.py
@@ -55,6 +55,7 @@ class ExtensionType: # RFC 6066 / 4366
srp = 12 # RFC 5054
cert_type = 9 # RFC 6091
signed_cert_timestamps = 18 # RFC 6962
+ extended_master_secret = 23 # draft-ietf-tls-session-hash-06
tack = 0xF300
supports_npn = 13172
channel_id = 30032
diff --git a/third_party/tlslite/tlslite/handshakesettings.py b/third_party/tlslite/tlslite/handshakesettings.py
index 605ed42..a7b6ab9 100644
--- a/third_party/tlslite/tlslite/handshakesettings.py
+++ b/third_party/tlslite/tlslite/handshakesettings.py
@@ -111,6 +111,10 @@ class HandshakeSettings(object):
@type alertAfterHandshake: bool
@ivar alertAfterHandshake: If true, the server will send a fatal
alert immediately after the handshake completes.
+
+ @type enableExtendedMasterSecret: bool
+ @ivar enableExtendedMasterSecret: If true, the server supports the extended
+ master secret TLS extension and will negotiated it with supporting clients.
Note that TACK support is not standardized by IETF and uses a temporary
TLS Extension number, so should NOT be used in production software.
@@ -129,6 +133,7 @@ class HandshakeSettings(object):
self.tlsIntoleranceType = 'alert'
self.useExperimentalTackExtension = False
self.alertAfterHandshake = False
+ self.enableExtendedMasterSecret = True
# Validates the min/max fields, and certificateTypes
# Filters out unsupported cipherNames and cipherImplementations
@@ -146,6 +151,7 @@ class HandshakeSettings(object):
other.tlsIntolerant = self.tlsIntolerant
other.tlsIntoleranceType = self.tlsIntoleranceType
other.alertAfterHandshake = self.alertAfterHandshake
+ other.enableExtendedMasterSecret = self.enableExtendedMasterSecret
if not cipherfactory.tripleDESPresent:
other.cipherNames = [e for e in self.cipherNames if e != "3des"]
diff --git a/third_party/tlslite/tlslite/mathtls.py b/third_party/tlslite/tlslite/mathtls.py
index 60a331a..0a23fe1 100644
--- a/third_party/tlslite/tlslite/mathtls.py
+++ b/third_party/tlslite/tlslite/mathtls.py
@@ -67,16 +67,20 @@ def PRF_SSL(secret, seed, length):
index += 1
return bytes
-def calcMasterSecret(version, premasterSecret, clientRandom, serverRandom):
+def calcMasterSecret(version, premasterSecret, clientRandom, serverRandom,
+ handshakeHash, useExtendedMasterSecret):
+ label = b"master secret"
+ seed = clientRandom + serverRandom
+ if useExtendedMasterSecret:
+ label = b"extended master secret"
+ seed = handshakeHash
+
if version == (3,0):
- masterSecret = PRF_SSL(premasterSecret,
- clientRandom + serverRandom, 48)
+ masterSecret = PRF_SSL(premasterSecret, seed, 48)
elif version in ((3,1), (3,2)):
- masterSecret = PRF(premasterSecret, b"master secret",
- clientRandom + serverRandom, 48)
+ masterSecret = PRF(premasterSecret, label, seed, 48)
elif version == (3,3):
- masterSecret = PRF_1_2(premasterSecret, b"master secret",
- clientRandom + serverRandom, 48)
+ masterSecret = PRF_1_2(premasterSecret, label, seed, 48)
else:
raise AssertionError()
return masterSecret
diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py
index 9aeff6d..9b553ce 100644
--- a/third_party/tlslite/tlslite/messages.py
+++ b/third_party/tlslite/tlslite/messages.py
@@ -114,6 +114,7 @@ class ClientHello(HandshakeMsg):
self.supports_npn = False
self.server_name = bytearray(0)
self.channel_id = False
+ self.extended_master_secret = False
self.support_signed_cert_timestamps = False
self.status_request = False
@@ -185,6 +186,8 @@ class ClientHello(HandshakeMsg):
break
elif extType == ExtensionType.channel_id:
self.channel_id = True
+ elif extType == ExtensionType.extended_master_secret:
+ self.extended_master_secret = True
elif extType == ExtensionType.signed_cert_timestamps:
if extLength:
raise SyntaxError()
@@ -267,6 +270,7 @@ class ServerHello(HandshakeMsg):
self.next_protos_advertised = None
self.next_protos = None
self.channel_id = False
+ self.extended_master_secret = False
self.signed_cert_timestamps = None
self.status_request = False
@@ -358,6 +362,9 @@ class ServerHello(HandshakeMsg):
if self.channel_id:
w2.add(ExtensionType.channel_id, 2)
w2.add(0, 2)
+ if self.extended_master_secret:
+ w2.add(ExtensionType.extended_master_secret, 2)
+ w2.add(0, 2)
if self.signed_cert_timestamps:
w2.add(ExtensionType.signed_cert_timestamps, 2)
w2.addVarSeq(bytearray(self.signed_cert_timestamps), 1, 2)
diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py
index dfac274..04161513 100644
--- a/third_party/tlslite/tlslite/tlsconnection.py
+++ b/third_party/tlslite/tlslite/tlsconnection.py
@@ -981,7 +981,8 @@ class TLSConnection(TLSRecordLayer):
masterSecret = calcMasterSecret(self.version,
premasterSecret,
clientRandom,
- serverRandom)
+ serverRandom,
+ b"", False)
verifyBytes = self._calcSSLHandshakeHash(masterSecret, b"")
elif self.version in ((3,1), (3,2)):
verifyBytes = self._handshake_md5.digest() + \
@@ -1036,7 +1037,7 @@ class TLSConnection(TLSRecordLayer):
cipherSuite, cipherImplementations, nextProto):
masterSecret = calcMasterSecret(self.version, premasterSecret,
- clientRandom, serverRandom)
+ clientRandom, serverRandom, b"", False)
self._calcPendingStates(cipherSuite, masterSecret,
clientRandom, serverRandom,
cipherImplementations)
@@ -1326,6 +1327,9 @@ class TLSConnection(TLSRecordLayer):
cipherSuite, CertificateType.x509, tackExt,
nextProtos)
serverHello.channel_id = clientHello.channel_id
+ serverHello.extended_master_secret = \
+ clientHello.extended_master_secret and \
+ settings.enableExtendedMasterSecret
if clientHello.support_signed_cert_timestamps:
serverHello.signed_cert_timestamps = signedCertTimestamps
if clientHello.status_request:
@@ -1383,7 +1387,8 @@ class TLSConnection(TLSRecordLayer):
for result in self._serverFinished(premasterSecret,
clientHello.random, serverHello.random,
cipherSuite, settings.cipherImplementations,
- nextProtos, clientHello.channel_id):
+ nextProtos, clientHello.channel_id,
+ serverHello.extended_master_secret):
if result in (0,1): yield result
else: break
masterSecret = result
@@ -1523,6 +1528,9 @@ class TLSConnection(TLSRecordLayer):
serverHello.create(self.version, getRandomBytes(32),
session.sessionID, session.cipherSuite,
CertificateType.x509, None, None)
+ serverHello.extended_master_secret = \
+ clientHello.extended_master_secret and \
+ settings.enableExtendedMasterSecret
for result in self._sendMsg(serverHello):
yield result
@@ -1743,7 +1751,8 @@ class TLSConnection(TLSRecordLayer):
if clientCertChain:
if self.version == (3,0):
masterSecret = calcMasterSecret(self.version, premasterSecret,
- clientHello.random, serverHello.random)
+ clientHello.random, serverHello.random,
+ b"", False)
verifyBytes = self._calcSSLHandshakeHash(masterSecret, b"")
elif self.version in ((3,1), (3,2)):
verifyBytes = self._handshake_md5.digest() + \
@@ -1827,9 +1836,11 @@ class TLSConnection(TLSRecordLayer):
def _serverFinished(self, premasterSecret, clientRandom, serverRandom,
cipherSuite, cipherImplementations, nextProtos,
- doingChannelID):
+ doingChannelID, useExtendedMasterSecret):
masterSecret = calcMasterSecret(self.version, premasterSecret,
- clientRandom, serverRandom)
+ clientRandom, serverRandom,
+ self._ems_handshake_hash,
+ useExtendedMasterSecret)
#Calculate pending connection states
self._calcPendingStates(cipherSuite, masterSecret,
diff --git a/third_party/tlslite/tlslite/tlsrecordlayer.py b/third_party/tlslite/tlslite/tlsrecordlayer.py
index c3bcd8c..d2320b8 100644
--- a/third_party/tlslite/tlslite/tlsrecordlayer.py
+++ b/third_party/tlslite/tlslite/tlsrecordlayer.py
@@ -119,6 +119,7 @@ class TLSRecordLayer(object):
self._handshake_md5 = hashlib.md5()
self._handshake_sha = hashlib.sha1()
self._handshake_sha256 = hashlib.sha256()
+ self._ems_handshake_hash = b""
#TLS Protocol Version
self.version = (0,0) #read-only
@@ -814,6 +815,8 @@ class TLSRecordLayer(object):
self._handshake_md5.update(compat26Str(p.bytes))
self._handshake_sha.update(compat26Str(p.bytes))
self._handshake_sha256.update(compat26Str(p.bytes))
+ if subType == HandshakeType.client_key_exchange:
+ self._ems_handshake_hash = self._getHandshakeHash()
#Parse based on handshake type
if subType == HandshakeType.client_hello:
@@ -1112,6 +1115,7 @@ class TLSRecordLayer(object):
self._handshake_md5 = hashlib.md5()
self._handshake_sha = hashlib.sha1()
self._handshake_sha256 = hashlib.sha256()
+ self._ems_handshake_hash = b""
self._handshakeBuffer = []
self.allegedSrpUsername = None
self._refCount = 1
@@ -1256,3 +1260,9 @@ class TLSRecordLayer(object):
return md5Bytes + shaBytes
+ def _getHandshakeHash(self):
+ if self.version in ((3,1), (3,2)):
+ return self._handshake_md5.digest() + \
+ self._handshake_sha.digest()
+ elif self.version == (3,3):
+ return self._handshake_sha256.digest()