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)