diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-02 18:40:41 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-02 18:40:41 +0000 |
commit | ec015f42c958334d7b27246412b6b705779aed3b (patch) | |
tree | 36c6c2c5ae9f76a9aadbe163b442155431844542 /third_party/tlslite | |
parent | 230e980d95cd743a7019fa8e1e79f08dbaff2b85 (diff) | |
download | chromium_src-ec015f42c958334d7b27246412b6b705779aed3b.zip chromium_src-ec015f42c958334d7b27246412b6b705779aed3b.tar.gz chromium_src-ec015f42c958334d7b27246412b6b705779aed3b.tar.bz2 |
net: add basic ChannelID support to TLSLite.
In order to test some ChannelID functions, this change adds basic ChannelID
support to testserver and TLSLite. With this change, testserver can receive a
ChannelID and echo its hash on /channel-id.
This code doesn't check the ChannelID signature.
BUG=none
TBR=darin
Review URL: https://chromiumcodereview.appspot.com/12313068
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@185744 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/tlslite')
-rw-r--r-- | third_party/tlslite/README.chromium | 2 | ||||
-rw-r--r-- | third_party/tlslite/patches/channel_id.patch | 217 | ||||
-rw-r--r-- | third_party/tlslite/tlslite/TLSConnection.py | 25 | ||||
-rw-r--r-- | third_party/tlslite/tlslite/TLSRecordLayer.py | 13 | ||||
-rw-r--r-- | third_party/tlslite/tlslite/constants.py | 4 | ||||
-rw-r--r-- | third_party/tlslite/tlslite/messages.py | 33 |
6 files changed, 291 insertions, 3 deletions
diff --git a/third_party/tlslite/README.chromium b/third_party/tlslite/README.chromium index 02d1d29..de941c0 100644 --- a/third_party/tlslite/README.chromium +++ b/third_party/tlslite/README.chromium @@ -32,3 +32,5 @@ Local Modifications: updated to add a parseChain method, that can parse multiple certificates from a PEM string. - patches/tls_intolerant.patch: allow TLSLite to simulate a TLS-intolerant server. +- patches/channel_id.patch: add basic ChannelID support. (Signatures are not + checked.) diff --git a/third_party/tlslite/patches/channel_id.patch b/third_party/tlslite/patches/channel_id.patch new file mode 100644 index 0000000..472406e --- /dev/null +++ b/third_party/tlslite/patches/channel_id.patch @@ -0,0 +1,217 @@ +diff --git a/third_party/tlslite/tlslite/TLSConnection.py b/third_party/tlslite/tlslite/TLSConnection.py +index f8811a9..e882e2c 100644 +--- a/third_party/tlslite/tlslite/TLSConnection.py ++++ b/third_party/tlslite/tlslite/TLSConnection.py +@@ -611,6 +611,8 @@ class TLSConnection(TLSRecordLayer): + settings.cipherImplementations) + + #Exchange ChangeCipherSpec and Finished messages ++ for result in self._getChangeCipherSpec(): ++ yield result + for result in self._getFinished(): + yield result + for result in self._sendFinished(): +@@ -920,6 +922,8 @@ class TLSConnection(TLSRecordLayer): + #Exchange ChangeCipherSpec and Finished messages + for result in self._sendFinished(): + yield result ++ for result in self._getChangeCipherSpec(): ++ yield result + for result in self._getFinished(): + yield result + +@@ -1089,6 +1093,7 @@ class TLSConnection(TLSRecordLayer): + clientCertChain = None + serverCertChain = None #We may set certChain to this later + postFinishedError = None ++ doingChannelID = False + + #Tentatively set version to most-desirable version, so if an error + #occurs parsing the ClientHello, this is what we'll use for the +@@ -1208,6 +1213,8 @@ class TLSConnection(TLSRecordLayer): + serverHello.create(self.version, serverRandom, + session.sessionID, session.cipherSuite, + certificateType) ++ serverHello.channel_id = clientHello.channel_id ++ doingChannelID = clientHello.channel_id + for result in self._sendMsg(serverHello): + yield result + +@@ -1221,6 +1228,11 @@ class TLSConnection(TLSRecordLayer): + #Exchange ChangeCipherSpec and Finished messages + for result in self._sendFinished(): + yield result ++ for result in self._getChangeCipherSpec(): ++ yield result ++ if doingChannelID: ++ for result in self._getEncryptedExtensions(): ++ yield result + for result in self._getFinished(): + yield result + +@@ -1399,8 +1411,12 @@ class TLSConnection(TLSRecordLayer): + #Send ServerHello, Certificate[, CertificateRequest], + #ServerHelloDone + msgs = [] +- msgs.append(ServerHello().create(self.version, serverRandom, +- sessionID, cipherSuite, certificateType)) ++ serverHello = ServerHello().create( ++ self.version, serverRandom, ++ sessionID, cipherSuite, certificateType) ++ serverHello.channel_id = clientHello.channel_id ++ doingChannelID = clientHello.channel_id ++ msgs.append(serverHello) + msgs.append(Certificate(certificateType).create(serverCertChain)) + if reqCert and reqCAs: + msgs.append(CertificateRequest().create([], reqCAs)) +@@ -1528,6 +1544,11 @@ class TLSConnection(TLSRecordLayer): + settings.cipherImplementations) + + #Exchange ChangeCipherSpec and Finished messages ++ for result in self._getChangeCipherSpec(): ++ yield result ++ if doingChannelID: ++ for result in self._getEncryptedExtensions(): ++ yield result + for result in self._getFinished(): + yield result + +diff --git a/third_party/tlslite/tlslite/TLSRecordLayer.py b/third_party/tlslite/tlslite/TLSRecordLayer.py +index 1bbd09d..933b95a 100644 +--- a/third_party/tlslite/tlslite/TLSRecordLayer.py ++++ b/third_party/tlslite/tlslite/TLSRecordLayer.py +@@ -714,6 +714,8 @@ class TLSRecordLayer: + self.version).parse(p) + elif subType == HandshakeType.finished: + yield Finished(self.version).parse(p) ++ elif subType == HandshakeType.encrypted_extensions: ++ yield EncryptedExtensions().parse(p) + else: + raise AssertionError() + +@@ -1067,7 +1069,7 @@ class TLSRecordLayer: + for result in self._sendMsg(finished): + yield result + +- def _getFinished(self): ++ def _getChangeCipherSpec(self): + #Get and check ChangeCipherSpec + for result in self._getMsg(ContentType.change_cipher_spec): + if result in (0,1): +@@ -1082,6 +1084,15 @@ class TLSRecordLayer: + #Switch to pending read state + self._changeReadState() + ++ def _getEncryptedExtensions(self): ++ for result in self._getMsg(ContentType.handshake, ++ HandshakeType.encrypted_extensions): ++ if result in (0,1): ++ yield result ++ encrypted_extensions = result ++ self.channel_id = encrypted_extensions.channel_id_key ++ ++ def _getFinished(self): + #Calculate verification data + verifyData = self._calcFinished(False) + +diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py +index 04302c0..e357dd0 100644 +--- a/third_party/tlslite/tlslite/constants.py ++++ b/third_party/tlslite/tlslite/constants.py +@@ -22,6 +22,7 @@ class HandshakeType: + certificate_verify = 15 + client_key_exchange = 16 + finished = 20 ++ encrypted_extensions = 203 + + class ContentType: + change_cipher_spec = 20 +@@ -30,6 +31,9 @@ class ContentType: + application_data = 23 + all = (20,21,22,23) + ++class ExtensionType: ++ channel_id = 30031 ++ + class AlertLevel: + warning = 1 + fatal = 2 +diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py +index dc6ed32..fa4d817 100644 +--- a/third_party/tlslite/tlslite/messages.py ++++ b/third_party/tlslite/tlslite/messages.py +@@ -130,6 +130,7 @@ class ClientHello(HandshakeMsg): + self.certificate_types = [CertificateType.x509] + self.compression_methods = [] # a list of 8-bit values + self.srp_username = None # a string ++ self.channel_id = False + + def create(self, version, random, session_id, cipher_suites, + certificate_types=None, srp_username=None): +@@ -174,6 +175,8 @@ class ClientHello(HandshakeMsg): + self.srp_username = bytesToString(p.getVarBytes(1)) + elif extType == 7: + self.certificate_types = p.getVarList(1, 1) ++ elif extType == ExtensionType.channel_id: ++ self.channel_id = True + else: + p.getFixBytes(extLength) + soFar += 4 + extLength +@@ -220,6 +223,7 @@ class ServerHello(HandshakeMsg): + self.cipher_suite = 0 + self.certificate_type = CertificateType.x509 + self.compression_method = 0 ++ self.channel_id = False + + def create(self, version, random, session_id, cipher_suite, + certificate_type): +@@ -266,6 +270,9 @@ class ServerHello(HandshakeMsg): + CertificateType.x509: + extLength += 5 + ++ if self.channel_id: ++ extLength += 4 ++ + if extLength != 0: + w.add(extLength, 2) + +@@ -275,6 +282,10 @@ class ServerHello(HandshakeMsg): + w.add(1, 2) + w.add(self.certificate_type, 1) + ++ if self.channel_id: ++ w.add(ExtensionType.channel_id, 2) ++ w.add(0, 2) ++ + return HandshakeMsg.postWrite(self, w, trial) + + class Certificate(HandshakeMsg): +@@ -567,6 +578,28 @@ class Finished(HandshakeMsg): + w.addFixSeq(self.verify_data, 1) + return HandshakeMsg.postWrite(self, w, trial) + ++class EncryptedExtensions(HandshakeMsg): ++ def __init__(self): ++ self.channel_id_key = None ++ self.channel_id_proof = None ++ ++ def parse(self, p): ++ p.startLengthCheck(3) ++ soFar = 0 ++ while soFar != p.lengthCheck: ++ extType = p.get(2) ++ extLength = p.get(2) ++ if extType == ExtensionType.channel_id: ++ if extLength != 32*4: ++ raise SyntaxError() ++ self.channel_id_key = p.getFixBytes(64) ++ self.channel_id_proof = p.getFixBytes(64) ++ else: ++ p.getFixBytes(extLength) ++ soFar += 4 + extLength ++ p.stopLengthCheck() ++ return self ++ + class ApplicationData(Msg): + def __init__(self): + self.contentType = ContentType.application_data diff --git a/third_party/tlslite/tlslite/TLSConnection.py b/third_party/tlslite/tlslite/TLSConnection.py index f8811a9..e882e2c8 100644 --- a/third_party/tlslite/tlslite/TLSConnection.py +++ b/third_party/tlslite/tlslite/TLSConnection.py @@ -611,6 +611,8 @@ class TLSConnection(TLSRecordLayer): settings.cipherImplementations) #Exchange ChangeCipherSpec and Finished messages + for result in self._getChangeCipherSpec(): + yield result for result in self._getFinished(): yield result for result in self._sendFinished(): @@ -920,6 +922,8 @@ class TLSConnection(TLSRecordLayer): #Exchange ChangeCipherSpec and Finished messages for result in self._sendFinished(): yield result + for result in self._getChangeCipherSpec(): + yield result for result in self._getFinished(): yield result @@ -1089,6 +1093,7 @@ class TLSConnection(TLSRecordLayer): clientCertChain = None serverCertChain = None #We may set certChain to this later postFinishedError = None + doingChannelID = False #Tentatively set version to most-desirable version, so if an error #occurs parsing the ClientHello, this is what we'll use for the @@ -1208,6 +1213,8 @@ class TLSConnection(TLSRecordLayer): serverHello.create(self.version, serverRandom, session.sessionID, session.cipherSuite, certificateType) + serverHello.channel_id = clientHello.channel_id + doingChannelID = clientHello.channel_id for result in self._sendMsg(serverHello): yield result @@ -1221,6 +1228,11 @@ class TLSConnection(TLSRecordLayer): #Exchange ChangeCipherSpec and Finished messages for result in self._sendFinished(): yield result + for result in self._getChangeCipherSpec(): + yield result + if doingChannelID: + for result in self._getEncryptedExtensions(): + yield result for result in self._getFinished(): yield result @@ -1399,8 +1411,12 @@ class TLSConnection(TLSRecordLayer): #Send ServerHello, Certificate[, CertificateRequest], #ServerHelloDone msgs = [] - msgs.append(ServerHello().create(self.version, serverRandom, - sessionID, cipherSuite, certificateType)) + serverHello = ServerHello().create( + self.version, serverRandom, + sessionID, cipherSuite, certificateType) + serverHello.channel_id = clientHello.channel_id + doingChannelID = clientHello.channel_id + msgs.append(serverHello) msgs.append(Certificate(certificateType).create(serverCertChain)) if reqCert and reqCAs: msgs.append(CertificateRequest().create([], reqCAs)) @@ -1528,6 +1544,11 @@ class TLSConnection(TLSRecordLayer): settings.cipherImplementations) #Exchange ChangeCipherSpec and Finished messages + for result in self._getChangeCipherSpec(): + yield result + if doingChannelID: + for result in self._getEncryptedExtensions(): + yield result for result in self._getFinished(): yield result diff --git a/third_party/tlslite/tlslite/TLSRecordLayer.py b/third_party/tlslite/tlslite/TLSRecordLayer.py index 1bbd09d..933b95a 100644 --- a/third_party/tlslite/tlslite/TLSRecordLayer.py +++ b/third_party/tlslite/tlslite/TLSRecordLayer.py @@ -714,6 +714,8 @@ class TLSRecordLayer: self.version).parse(p) elif subType == HandshakeType.finished: yield Finished(self.version).parse(p) + elif subType == HandshakeType.encrypted_extensions: + yield EncryptedExtensions().parse(p) else: raise AssertionError() @@ -1067,7 +1069,7 @@ class TLSRecordLayer: for result in self._sendMsg(finished): yield result - def _getFinished(self): + def _getChangeCipherSpec(self): #Get and check ChangeCipherSpec for result in self._getMsg(ContentType.change_cipher_spec): if result in (0,1): @@ -1082,6 +1084,15 @@ class TLSRecordLayer: #Switch to pending read state self._changeReadState() + def _getEncryptedExtensions(self): + for result in self._getMsg(ContentType.handshake, + HandshakeType.encrypted_extensions): + if result in (0,1): + yield result + encrypted_extensions = result + self.channel_id = encrypted_extensions.channel_id_key + + def _getFinished(self): #Calculate verification data verifyData = self._calcFinished(False) diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py index 04302c0..e357dd0 100644 --- a/third_party/tlslite/tlslite/constants.py +++ b/third_party/tlslite/tlslite/constants.py @@ -22,6 +22,7 @@ class HandshakeType: certificate_verify = 15 client_key_exchange = 16 finished = 20 + encrypted_extensions = 203 class ContentType: change_cipher_spec = 20 @@ -30,6 +31,9 @@ class ContentType: application_data = 23 all = (20,21,22,23) +class ExtensionType: + channel_id = 30031 + class AlertLevel: warning = 1 fatal = 2 diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py index dc6ed32..fa4d817 100644 --- a/third_party/tlslite/tlslite/messages.py +++ b/third_party/tlslite/tlslite/messages.py @@ -130,6 +130,7 @@ class ClientHello(HandshakeMsg): self.certificate_types = [CertificateType.x509] self.compression_methods = [] # a list of 8-bit values self.srp_username = None # a string + self.channel_id = False def create(self, version, random, session_id, cipher_suites, certificate_types=None, srp_username=None): @@ -174,6 +175,8 @@ class ClientHello(HandshakeMsg): self.srp_username = bytesToString(p.getVarBytes(1)) elif extType == 7: self.certificate_types = p.getVarList(1, 1) + elif extType == ExtensionType.channel_id: + self.channel_id = True else: p.getFixBytes(extLength) soFar += 4 + extLength @@ -220,6 +223,7 @@ class ServerHello(HandshakeMsg): self.cipher_suite = 0 self.certificate_type = CertificateType.x509 self.compression_method = 0 + self.channel_id = False def create(self, version, random, session_id, cipher_suite, certificate_type): @@ -266,6 +270,9 @@ class ServerHello(HandshakeMsg): CertificateType.x509: extLength += 5 + if self.channel_id: + extLength += 4 + if extLength != 0: w.add(extLength, 2) @@ -275,6 +282,10 @@ class ServerHello(HandshakeMsg): w.add(1, 2) w.add(self.certificate_type, 1) + if self.channel_id: + w.add(ExtensionType.channel_id, 2) + w.add(0, 2) + return HandshakeMsg.postWrite(self, w, trial) class Certificate(HandshakeMsg): @@ -567,6 +578,28 @@ class Finished(HandshakeMsg): w.addFixSeq(self.verify_data, 1) return HandshakeMsg.postWrite(self, w, trial) +class EncryptedExtensions(HandshakeMsg): + def __init__(self): + self.channel_id_key = None + self.channel_id_proof = None + + def parse(self, p): + p.startLengthCheck(3) + soFar = 0 + while soFar != p.lengthCheck: + extType = p.get(2) + extLength = p.get(2) + if extType == ExtensionType.channel_id: + if extLength != 32*4: + raise SyntaxError() + self.channel_id_key = p.getFixBytes(64) + self.channel_id_proof = p.getFixBytes(64) + else: + p.getFixBytes(extLength) + soFar += 4 + extLength + p.stopLengthCheck() + return self + class ApplicationData(Msg): def __init__(self): self.contentType = ContentType.application_data |