blob: 9e8beb9f763f3082c5df8bfb46aeb3387004f45a [file] [log] [blame]
diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py
index bac05c2f70cf..3f994e7e6f60 100644
--- a/third_party/tlslite/tlslite/constants.py
+++ b/third_party/tlslite/tlslite/constants.py
@@ -52,8 +52,9 @@ class CertificateStatusType:
class ExtensionType: # RFC 6066 / 4366
server_name = 0 # RFC 6066 / 4366
status_request = 5 # RFC 6066 / 4366
- srp = 12 # RFC 5054
+ srp = 12 # RFC 5054
cert_type = 9 # RFC 6091
+ signature_algorithms = 13 # RFC 5246
alpn = 16 # RFC 7301
signed_cert_timestamps = 18 # RFC 6962
extended_master_secret = 23 # RFC 7627
diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py
index 90a3cec9f54e..ce4f1a6e15eb 100644
--- a/third_party/tlslite/tlslite/messages.py
+++ b/third_party/tlslite/tlslite/messages.py
@@ -142,6 +142,7 @@ class ClientHello(HandshakeMsg):
self.status_request = False
self.has_supported_versions = False
self.ri = False
+ self.signature_algorithms = []
def create(self, version, random, session_id, cipher_suites,
certificate_types=None, srpUsername=None,
@@ -257,6 +258,14 @@ class ClientHello(HandshakeMsg):
# intolerance simulation.
self.has_supported_versions = True
_ = p.getFixBytes(extLength)
+ elif extType == ExtensionType.signature_algorithms:
+ numBytes = p.get(2)
+ if numBytes + 2 != extLength or numBytes % 2 != 0:
+ raise SyntaxError()
+ for _ in range(numBytes / 2):
+ hashAlg = p.get(1)
+ sigAlg = p.get(1)
+ self.signature_algorithms.append((hashAlg, sigAlg))
else:
_ = p.getFixBytes(extLength)
index2 = p.index
@@ -605,6 +614,7 @@ class ServerKeyExchange(HandshakeMsg):
self.ecdhCurve = 0
self.ecdhPublic = bytearray(0)
self.signature = bytearray(0)
+ self.signature_algorithm = None
def createSRP(self, srp_N, srp_g, srp_s, srp_B):
self.srp_N = srp_N
@@ -664,18 +674,13 @@ class ServerKeyExchange(HandshakeMsg):
w.bytes += self.write_params()
if self.cipherSuite in CipherSuite.certAllSuites:
if self.version >= (3,3):
- # TODO: Signature algorithm negotiation not supported.
- w.add(HashAlgorithm.sha1, 1)
- w.add(SignatureAlgorithm.rsa, 1)
+ w.add(self.signature_algorithm[0], 1)
+ w.add(self.signature_algorithm[1], 1)
w.addVarSeq(self.signature, 1, 2)
return self.postWrite(w)
- def hash(self, clientRandom, serverRandom):
- bytes = clientRandom + serverRandom + self.write_params()
- if self.version >= (3,3):
- # TODO: Signature algorithm negotiation not supported.
- return SHA1(bytes)
- return MD5(bytes) + SHA1(bytes)
+ def signingPayload(self, clientRandom, serverRandom):
+ return clientRandom + serverRandom + self.write_params()
class ServerHelloDone(HandshakeMsg):
def __init__(self):
diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py
index efe2b9fefaa0..6d7c859884a4 100644
--- a/third_party/tlslite/tlslite/tlsconnection.py
+++ b/third_party/tlslite/tlslite/tlsconnection.py
@@ -17,7 +17,7 @@ from .utils.compat import formatExceptionTrace
from .tlsrecordlayer import TLSRecordLayer
from .session import Session
from .constants import *
-from .utils.cryptomath import getRandomBytes
+from .utils.cryptomath import getRandomBytes, MD5, SHA1, SHA256
from .errors import *
from .messages import *
from .mathtls import *
@@ -51,6 +51,24 @@ class KeyExchange(object):
"""
raise NotImplementedError()
+ def sign(self, inpBytes):
+ algorithm = None
+ if self.serverHello.server_version >= (3, 3):
+ # Negotiate a signature algorithm.
+ peerPrefs = self.clientHello.signature_algorithms
+ if (HashAlgorithm.sha256, SignatureAlgorithm.rsa) in peerPrefs:
+ algorithm = (HashAlgorithm.sha256, SignatureAlgorithm.rsa)
+ inpBytes = RSAKey.addPKCS1SHA256Prefix(SHA256(inpBytes))
+ elif (HashAlgorithm.sha1, SignatureAlgorithm.rsa) in peerPrefs:
+ algorithm = (HashAlgorithm.sha1, SignatureAlgorithm.rsa)
+ inpBytes = RSAKey.addPKCS1SHA1Prefix(SHA1(inpBytes))
+ else:
+ raise TLSLocalAlert(AlertDescription.handshake_failure,
+ "no common signature algorithms")
+ else:
+ inpBytes = MD5(inpBytes) + SHA1(inpBytes)
+ return algorithm, self.privateKey.sign(inpBytes)
+
class RSAKeyExchange(KeyExchange):
def makeServerKeyExchange(self):
return None
@@ -108,12 +126,9 @@ DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510
version = self.serverHello.server_version
serverKeyExchange = ServerKeyExchange(self.cipherSuite, version)
serverKeyExchange.createDH(self.dh_p, self.dh_g, dh_Ys)
- 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)
+ serverKeyExchange.signature_algorithm, serverKeyExchange.signature = \
+ self.sign(serverKeyExchange.signingPayload(self.clientHello.random,
+ self.serverHello.random))
return serverKeyExchange
def processClientKeyExchange(self, clientKeyExchange):
@@ -135,12 +150,9 @@ class ECDHE_RSAKeyExchange(KeyExchange):
version = self.serverHello.server_version
serverKeyExchange = ServerKeyExchange(self.cipherSuite, version)
serverKeyExchange.createECDH(NamedCurve.secp256r1, bytearray(public))
- 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)
+ serverKeyExchange.signature_algorithm, serverKeyExchange.signature = \
+ self.sign(serverKeyExchange.signingPayload(self.clientHello.random,
+ self.serverHello.random))
return serverKeyExchange
def processClientKeyExchange(self, clientKeyExchange):
diff --git a/third_party/tlslite/tlslite/utils/cryptomath.py b/third_party/tlslite/tlslite/utils/cryptomath.py
index 61fd1432d566..f7142c06ba23 100644
--- a/third_party/tlslite/tlslite/utils/cryptomath.py
+++ b/third_party/tlslite/tlslite/utils/cryptomath.py
@@ -73,6 +73,9 @@ def MD5(b):
def SHA1(b):
return bytearray(hashlib.sha1(compat26Str(b)).digest())
+def SHA256(b):
+ return bytearray(hashlib.sha256(compat26Str(b)).digest())
+
def HMAC_MD5(k, b):
k = compatHMAC(k)
b = compatHMAC(b)
diff --git a/third_party/tlslite/tlslite/utils/rsakey.py b/third_party/tlslite/tlslite/utils/rsakey.py
index fb022cc6445d..7e3f97881a10 100644
--- a/third_party/tlslite/tlslite/utils/rsakey.py
+++ b/third_party/tlslite/tlslite/utils/rsakey.py
@@ -240,6 +240,13 @@ class RSAKey(object):
prefixedBytes = prefixBytes + bytes
return prefixedBytes
+ @staticmethod
+ def addPKCS1SHA256Prefix(bytes):
+ prefixBytes = bytearray([
+ 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
+ 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20])
+ return prefixBytes + bytes
+
def _addPKCS1Padding(self, bytes, blockType):
padLength = (numBytes(self.n) - (len(bytes)+3))
if blockType == 1: #Signature padding