| Index: third_party/tlslite/tlslite/tlsconnection.py
|
| diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py
|
| index 06aa0c9022d5fb51ee38cb1b2ab0c41ce8a767a0..3d97e979a339cb29060574f260e44c78ecfcf35b 100644
|
| --- a/third_party/tlslite/tlslite/tlsconnection.py
|
| +++ b/third_party/tlslite/tlslite/tlsconnection.py
|
| @@ -4,6 +4,7 @@
|
| # Google (adapted by Sam Rushing and Marcelo Fernandez) - NPN support
|
| # Dimitris Moraitis - Anon ciphersuites
|
| # Martin von Loewis - python 3 port
|
| +# Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2
|
| #
|
| # See the LICENSE file for legal information regarding use of this file.
|
|
|
| @@ -22,6 +23,7 @@ from .messages import *
|
| from .mathtls import *
|
| from .handshakesettings import HandshakeSettings
|
| from .utils.tackwrapper import *
|
| +from .utils.rsakey import RSAKey
|
|
|
| class KeyExchange(object):
|
| def __init__(self, cipherSuite, clientHello, serverHello, privateKey):
|
| @@ -102,11 +104,15 @@ DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510
|
| self.dh_Xs = bytesToNumber(getRandomBytes(self.strength * 2 / 8))
|
| dh_Ys = powMod(self.dh_g, self.dh_Xs, self.dh_p)
|
|
|
| - serverKeyExchange = ServerKeyExchange(self.cipherSuite)
|
| + version = self.serverHello.server_version
|
| + serverKeyExchange = ServerKeyExchange(self.cipherSuite, version)
|
| serverKeyExchange.createDH(self.dh_p, self.dh_g, dh_Ys)
|
| - serverKeyExchange.signature = self.privateKey.sign(
|
| - serverKeyExchange.hash(self.clientHello.random,
|
| - self.serverHello.random))
|
| + hashBytes = serverKeyExchange.hash(self.clientHello.random,
|
| + self.serverHello.random)
|
| + if version >= (3,3):
|
| + # TODO: Signature algorithm negotiation not supported.
|
| + hashBytes = RSAKey.addPKCS1SHA1Prefix(hashBytes)
|
| + serverKeyExchange.signature = self.privateKey.sign(hashBytes)
|
| return serverKeyExchange
|
|
|
| def processClientKeyExchange(self, clientKeyExchange):
|
| @@ -596,9 +602,9 @@ class TLSConnection(TLSRecordLayer):
|
| if srpParams:
|
| cipherSuites += CipherSuite.getSrpAllSuites(settings)
|
| elif certParams:
|
| - cipherSuites += CipherSuite.getCertSuites(settings)
|
| # TODO: Client DHE_RSA not supported.
|
| # cipherSuites += CipherSuite.getDheCertSuites(settings)
|
| + cipherSuites += CipherSuite.getCertSuites(settings)
|
| elif anonParams:
|
| cipherSuites += CipherSuite.getAnonSuites(settings)
|
| else:
|
| @@ -950,6 +956,7 @@ class TLSConnection(TLSRecordLayer):
|
| #If client authentication was requested and we have a
|
| #private key, send CertificateVerify
|
| if certificateRequest and privateKey:
|
| + signatureAlgorithm = None
|
| if self.version == (3,0):
|
| masterSecret = calcMasterSecret(self.version,
|
| premasterSecret,
|
| @@ -959,11 +966,16 @@ class TLSConnection(TLSRecordLayer):
|
| elif self.version in ((3,1), (3,2)):
|
| verifyBytes = self._handshake_md5.digest() + \
|
| self._handshake_sha.digest()
|
| + elif self.version == (3,3):
|
| + # TODO: Signature algorithm negotiation not supported.
|
| + signatureAlgorithm = (HashAlgorithm.sha1, SignatureAlgorithm.rsa)
|
| + verifyBytes = self._handshake_sha.digest()
|
| + verifyBytes = RSAKey.addPKCS1SHA1Prefix(verifyBytes)
|
| if self.fault == Fault.badVerifyMessage:
|
| verifyBytes[0] = ((verifyBytes[0]+1) % 256)
|
| signedBytes = privateKey.sign(verifyBytes)
|
| - certificateVerify = CertificateVerify()
|
| - certificateVerify.create(signedBytes)
|
| + certificateVerify = CertificateVerify(self.version)
|
| + certificateVerify.create(signatureAlgorithm, signedBytes)
|
| for result in self._sendMsg(certificateVerify):
|
| yield result
|
| yield (premasterSecret, serverCertChain, clientCertChain, tackExt)
|
| @@ -1381,8 +1393,8 @@ class TLSConnection(TLSRecordLayer):
|
| CipherSuite.getSrpCertSuites(settings)
|
| cipherSuites += CipherSuite.getSrpSuites(settings)
|
| elif certChain:
|
| - cipherSuites += CipherSuite.getCertSuites(settings)
|
| cipherSuites += CipherSuite.getDheCertSuites(settings)
|
| + cipherSuites += CipherSuite.getCertSuites(settings)
|
| elif anon:
|
| cipherSuites += CipherSuite.getAnonSuites(settings)
|
| else:
|
| @@ -1512,9 +1524,10 @@ class TLSConnection(TLSRecordLayer):
|
| #the only time we won't use it is if we're resuming a
|
| #session, in which case we use the ciphersuite from the session.
|
| #
|
| - #Use the client's preferences for now.
|
| - for cipherSuite in clientHello.cipher_suites:
|
| - if cipherSuite in cipherSuites:
|
| + #Given the current ciphersuite ordering, this means we prefer SRP
|
| + #over non-SRP.
|
| + for cipherSuite in cipherSuites:
|
| + if cipherSuite in clientHello.cipher_suites:
|
| break
|
| else:
|
| for result in self._sendError(\
|
| @@ -1561,7 +1574,7 @@ class TLSConnection(TLSRecordLayer):
|
| B = (powMod(g, b, N) + (k*v)) % N
|
|
|
| #Create ServerKeyExchange, signing it if necessary
|
| - serverKeyExchange = ServerKeyExchange(cipherSuite)
|
| + serverKeyExchange = ServerKeyExchange(cipherSuite, self.version)
|
| serverKeyExchange.createSRP(N, g, s, B)
|
| if cipherSuite in CipherSuite.srpCertSuites:
|
| hashBytes = serverKeyExchange.hash(clientHello.random,
|
| @@ -1631,7 +1644,11 @@ class TLSConnection(TLSRecordLayer):
|
| #Apple's Secure Transport library rejects empty certificate_types,
|
| #so default to rsa_sign.
|
| reqCertTypes = reqCertTypes or [ClientCertificateType.rsa_sign]
|
| - msgs.append(CertificateRequest().create(reqCertTypes, reqCAs))
|
| + #Only SHA-1 + RSA is supported.
|
| + sigAlgs = [(HashAlgorithm.sha1, SignatureAlgorithm.rsa)]
|
| + msgs.append(CertificateRequest(self.version).create(reqCertTypes,
|
| + reqCAs,
|
| + sigAlgs))
|
| msgs.append(ServerHelloDone())
|
| for result in self._sendMsgs(msgs):
|
| yield result
|
| @@ -1664,7 +1681,7 @@ class TLSConnection(TLSRecordLayer):
|
| clientCertChain = clientCertificate.certChain
|
| else:
|
| raise AssertionError()
|
| - elif self.version in ((3,1), (3,2)):
|
| + elif self.version in ((3,1), (3,2), (3,3)):
|
| for result in self._getMsg(ContentType.handshake,
|
| HandshakeType.certificate,
|
| CertificateType.x509):
|
| @@ -1702,6 +1719,9 @@ class TLSConnection(TLSRecordLayer):
|
| elif self.version in ((3,1), (3,2)):
|
| verifyBytes = self._handshake_md5.digest() + \
|
| self._handshake_sha.digest()
|
| + elif self.version == (3,3):
|
| + verifyBytes = self._handshake_sha.digest()
|
| + verifyBytes = RSAKey.addPKCS1SHA1Prefix(verifyBytes)
|
| for result in self._getMsg(ContentType.handshake,
|
| HandshakeType.certificate_verify):
|
| if result in (0,1): yield result
|
| @@ -1737,7 +1757,7 @@ class TLSConnection(TLSRecordLayer):
|
| dh_Ys = powMod(dh_g, dh_Xs, dh_p)
|
|
|
| #Create ServerKeyExchange
|
| - serverKeyExchange = ServerKeyExchange(cipherSuite)
|
| + serverKeyExchange = ServerKeyExchange(cipherSuite, self.version)
|
| serverKeyExchange.createDH(dh_p, dh_g, dh_Ys)
|
|
|
| #Send ServerHello[, Certificate], ServerKeyExchange,
|
| @@ -1909,6 +1929,15 @@ class TLSConnection(TLSRecordLayer):
|
| self._handshake_sha.digest()
|
| verifyData = PRF(masterSecret, label, handshakeHashes, 12)
|
| return verifyData
|
| + elif self.version == (3,3):
|
| + if (self._client and send) or (not self._client and not send):
|
| + label = b"client finished"
|
| + else:
|
| + label = b"server finished"
|
| +
|
| + handshakeHashes = self._handshake_sha256.digest()
|
| + verifyData = PRF_1_2(masterSecret, label, handshakeHashes, 12)
|
| + return verifyData
|
| else:
|
| raise AssertionError()
|
|
|
|
|