| diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py |
| index e1be195..f2e2cfc 100644 |
| --- a/third_party/tlslite/tlslite/messages.py |
| +++ b/third_party/tlslite/tlslite/messages.py |
| @@ -460,7 +460,7 @@ class CertificateRequest(HandshakeMsg): |
| self.version = version |
| self.supported_signature_algs = [] |
| |
| - def create(self, certificate_types, certificate_authorities, sig_algs=()): |
| + def create(self, certificate_types, certificate_authorities, sig_algs): |
| self.certificate_types = certificate_types |
| self.certificate_authorities = certificate_authorities |
| self.supported_signature_algs = sig_algs |
| @@ -470,7 +470,8 @@ class CertificateRequest(HandshakeMsg): |
| p.startLengthCheck(3) |
| self.certificate_types = p.getVarList(1, 1) |
| if self.version >= (3,3): |
| - self.supported_signature_algs = p.getVarList(2, 2) |
| + self.supported_signature_algs = \ |
| + [(b >> 8, b & 0xff) for b in p.getVarList(2, 2)] |
| ca_list_length = p.get(2) |
| index = 0 |
| self.certificate_authorities = [] |
| @@ -485,7 +486,10 @@ class CertificateRequest(HandshakeMsg): |
| w = Writer() |
| w.addVarSeq(self.certificate_types, 1, 1) |
| if self.version >= (3,3): |
| - w.addVarSeq(self.supported_signature_algs, 2, 2) |
| + w.add(2 * len(self.supported_signature_algs), 2) |
| + for (hash, signature) in self.supported_signature_algs: |
| + w.add(hash, 1) |
| + w.add(signature, 1) |
| caLength = 0 |
| #determine length |
| for ca_dn in self.certificate_authorities: |
| @@ -646,22 +650,30 @@ class ClientKeyExchange(HandshakeMsg): |
| return self.postWrite(w) |
| |
| class CertificateVerify(HandshakeMsg): |
| - def __init__(self): |
| + def __init__(self, version): |
| HandshakeMsg.__init__(self, HandshakeType.certificate_verify) |
| + self.version = version |
| + self.signature_algorithm = None |
| self.signature = bytearray(0) |
| |
| - def create(self, signature): |
| + def create(self, signature_algorithm, signature): |
| + self.signature_algorithm = signature_algorithm |
| self.signature = signature |
| return self |
| |
| def parse(self, p): |
| p.startLengthCheck(3) |
| + if self.version >= (3,3): |
| + self.signature_algorithm = (p.get(1), p.get(1)) |
| self.signature = p.getVarBytes(2) |
| p.stopLengthCheck() |
| return self |
| |
| def write(self): |
| w = Writer() |
| + if self.version >= (3,3): |
| + w.add(self.signature_algorithm[0], 1) |
| + w.add(self.signature_algorithm[1], 1) |
| w.addVarSeq(self.signature, 1, 2) |
| return self.postWrite(w) |
| |
| diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py |
| index cb743fe..3d97e97 100644 |
| --- a/third_party/tlslite/tlslite/tlsconnection.py |
| +++ b/third_party/tlslite/tlslite/tlsconnection.py |
| @@ -956,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, |
| @@ -966,12 +967,15 @@ class TLSConnection(TLSRecordLayer): |
| verifyBytes = self._handshake_md5.digest() + \ |
| self._handshake_sha.digest() |
| elif self.version == (3,3): |
| - verifyBytes = self._handshake_sha256.digest() |
| + # 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) |
| @@ -1640,8 +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] |
| + #Only SHA-1 + RSA is supported. |
| + sigAlgs = [(HashAlgorithm.sha1, SignatureAlgorithm.rsa)] |
| msgs.append(CertificateRequest(self.version).create(reqCertTypes, |
| - reqCAs)) |
| + reqCAs, |
| + sigAlgs)) |
| msgs.append(ServerHelloDone()) |
| for result in self._sendMsgs(msgs): |
| yield result |
| @@ -1713,7 +1720,8 @@ class TLSConnection(TLSRecordLayer): |
| verifyBytes = self._handshake_md5.digest() + \ |
| self._handshake_sha.digest() |
| elif self.version == (3,3): |
| - verifyBytes = self._handshake_sha256.digest() |
| + 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 |
| diff --git a/third_party/tlslite/tlslite/tlsrecordlayer.py b/third_party/tlslite/tlslite/tlsrecordlayer.py |
| index eda11e6..a09499d 100644 |
| --- a/third_party/tlslite/tlslite/tlsrecordlayer.py |
| +++ b/third_party/tlslite/tlslite/tlsrecordlayer.py |
| @@ -804,7 +804,7 @@ class TLSRecordLayer(object): |
| elif subType == HandshakeType.certificate_request: |
| yield CertificateRequest(self.version).parse(p) |
| elif subType == HandshakeType.certificate_verify: |
| - yield CertificateVerify().parse(p) |
| + yield CertificateVerify(self.version).parse(p) |
| elif subType == HandshakeType.server_key_exchange: |
| yield ServerKeyExchange(constructorType, |
| self.version).parse(p) |