1a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch# Author: Trevor Perrin 2a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch# See the LICENSE file for legal information regarding use of this file. 3a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""Classes for reading/writing binary data (such as TLS records).""" 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochfrom .compat import * 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass Writer(object): 9a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch def __init__(self): 10a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch self.bytes = bytearray(0) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def add(self, x, length): 13a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch self.bytes += bytearray(length) 14a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch newIndex = len(self.bytes) - 1 15a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch for count in range(length): 16a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch self.bytes[newIndex] = x & 0xFF 17a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch x >>= 8 18a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch newIndex -= 1 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def addFixSeq(self, seq, length): 21a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch for e in seq: 22a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch self.add(e, length) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def addVarSeq(self, seq, length, lengthLength): 25a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch self.add(len(seq)*length, lengthLength) 26a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch for e in seq: 27a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch self.add(e, length) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass Parser(object): 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, bytes): 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.bytes = bytes 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.index = 0 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get(self, length): 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.index + length > len(self.bytes): 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise SyntaxError() 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = 0 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for count in range(length): 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x <<= 8 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x |= self.bytes[self.index] 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.index += 1 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return x 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def getFixBytes(self, lengthBytes): 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes = self.bytes[self.index : self.index+lengthBytes] 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.index += lengthBytes 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bytes 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def getVarBytes(self, lengthLength): 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lengthBytes = self.get(lengthLength) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.getFixBytes(lengthBytes) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def getFixList(self, length, lengthList): 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l = [0] * lengthList 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for x in range(lengthList): 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l[x] = self.get(length) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return l 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def getVarList(self, length, lengthLength): 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lengthList = self.get(lengthLength) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if lengthList % length != 0: 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise SyntaxError() 63a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch lengthList = lengthList // length 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l = [0] * lengthList 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for x in range(lengthList): 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l[x] = self.get(length) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return l 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def startLengthCheck(self, lengthLength): 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.lengthCheck = self.get(lengthLength) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.indexCheck = self.index 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def setLengthCheck(self, length): 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.lengthCheck = length 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.indexCheck = self.index 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def stopLengthCheck(self): 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (self.index - self.indexCheck) != self.lengthCheck: 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise SyntaxError() 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def atLengthCheck(self): 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (self.index - self.indexCheck) < self.lengthCheck: 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif (self.index - self.indexCheck) == self.lengthCheck: 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 87a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch raise SyntaxError() 88