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() |