3 # Google (adapted by Sam Rushing) - NPN support
4 # Martin von Loewis - python 3 port
6 # See the LICENSE file for legal information regarding use of this file.
8 """Helper class for TLSConnection."""
9 from __future__ import generators
11 from .utils.compat import *
12 from .utils.cryptomath import *
13 from .utils.cipherfactory import createAES, createRC4, createTripleDES
14 from .utils.codec import *
16 from .messages import *
17 from .mathtls import *
18 from .constants import *
19 from .utils.cryptomath import getRandomBytes
25 class _ConnectionState(object):
27 self.macContext = None
28 self.encContext = None
31 def getSeqNumBytes(self):
38 class TLSRecordLayer(object):
40 This class handles data transmission for a TLS connection.
42 Its only subclass is L{tlslite.TLSConnection.TLSConnection}. We've
43 separated the code in this class from TLSConnection to make things
47 @type sock: socket.socket
48 @ivar sock: The underlying socket object.
50 @type session: L{tlslite.Session.Session}
51 @ivar session: The session corresponding to this connection.
53 Due to TLS session resumption, multiple connections can correspond
54 to the same underlying session.
57 @ivar version: The TLS version being used for this connection.
59 (3,0) means SSL 3.0, and (3,1) means TLS 1.0.
62 @ivar closed: If this connection is closed.
65 @ivar resumed: If this connection is based on a resumed session.
67 @type allegedSrpUsername: str or None
68 @ivar allegedSrpUsername: This is set to the SRP username
69 asserted by the client, whether the handshake succeeded or not.
70 If the handshake fails, this can be inspected to determine
71 if a guessing attack is in progress against a particular user
74 @type closeSocket: bool
75 @ivar closeSocket: If the socket should be closed when the
76 connection is closed, defaults to True (writable).
78 If you set this to True, TLS Lite will assume the responsibility of
79 closing the socket when the TLS Connection is shutdown (either
80 through an error or through the user calling close()). The default
83 @type ignoreAbruptClose: bool
84 @ivar ignoreAbruptClose: If an abrupt close of the socket should
85 raise an error (writable).
87 If you set this to True, TLS Lite will not raise a
88 L{tlslite.errors.TLSAbruptCloseError} exception if the underlying
89 socket is unexpectedly closed. Such an unexpected closure could be
90 caused by an attacker. However, it also occurs with some incorrect
93 You should set this to True only if you're not worried about an
94 attacker truncating the connection, and only if necessary to avoid
95 spurious errors. The default is False.
97 @sort: __init__, read, readAsync, write, writeAsync, close, closeAsync,
98 getCipherImplementation, getCipherName
101 def __init__(self, sock):
104 #My session object (Session instance; read-only)
107 #Am I a client or server?
110 #Buffers for processing messages
111 self._handshakeBuffer = []
112 self.clearReadBuffer()
113 self.clearWriteBuffer()
116 self._handshake_md5 = hashlib.md5()
117 self._handshake_sha = hashlib.sha1()
119 #TLS Protocol Version
120 self.version = (0,0) #read-only
121 self._versionCheck = False #Once we choose a version, this is True
123 #Current and Pending connection states
124 self._writeState = _ConnectionState()
125 self._readState = _ConnectionState()
126 self._pendingWriteState = _ConnectionState()
127 self._pendingReadState = _ConnectionState()
129 #Is the connection open?
130 self.closed = True #read-only
131 self._refCount = 0 #Used to trigger closure
133 #Is this a resumed session?
134 self.resumed = False #read-only
136 #What username did the client claim in his handshake?
137 self.allegedSrpUsername = None
139 #On a call to close(), do we close the socket? (writeable)
140 self.closeSocket = True
142 #If the socket is abruptly closed, do we ignore it
143 #and pretend the connection was shut down properly? (writeable)
144 self.ignoreAbruptClose = False
146 #Fault we will induce, for testing purposes
149 def clearReadBuffer(self):
150 self._readBuffer = b''
152 def clearWriteBuffer(self):
153 self._send_writer = None
156 #*********************************************************
157 # Public Functions START
158 #*********************************************************
160 def read(self, max=None, min=1):
161 """Read some data from the TLS connection.
163 This function will block until at least 'min' bytes are
164 available (or the connection is closed).
166 If an exception is raised, the connection will have been
167 automatically closed.
170 @param max: The maximum number of bytes to return.
173 @param min: The minimum number of bytes to return
176 @return: A string of no more than 'max' bytes, and no fewer
177 than 'min' (unless the connection has been closed, in which
178 case fewer than 'min' bytes may be returned).
180 @raise socket.error: If a socket error occurs.
181 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
182 without a preceding alert.
183 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
185 for result in self.readAsync(max, min):
189 def readAsync(self, max=None, min=1):
190 """Start a read operation on the TLS connection.
192 This function returns a generator which behaves similarly to
193 read(). Successive invocations of the generator will return 0
194 if it is waiting to read from the socket, 1 if it is waiting
195 to write to the socket, or a string if the read operation has
199 @return: A generator; see above for details.
202 while len(self._readBuffer)<min and not self.closed:
204 for result in self._getMsg(ContentType.application_data):
207 applicationData = result
208 self._readBuffer += applicationData.write()
209 except TLSRemoteAlert as alert:
210 if alert.description != AlertDescription.close_notify:
212 except TLSAbruptCloseError:
213 if not self.ignoreAbruptClose:
219 max = len(self._readBuffer)
221 returnBytes = self._readBuffer[:max]
222 self._readBuffer = self._readBuffer[max:]
223 yield bytes(returnBytes)
224 except GeneratorExit:
227 self._shutdown(False)
231 """Add bytes to the front of the socket read buffer for future
232 reading. Be careful using this in the context of select(...): if you
233 unread the last data from a socket, that won't wake up selected waiters,
234 and those waiters may hang forever.
236 self._readBuffer = b + self._readBuffer
239 """Write some data to the TLS connection.
241 This function will block until all the data has been sent.
243 If an exception is raised, the connection will have been
244 automatically closed.
247 @param s: The data to transmit to the other party.
249 @raise socket.error: If a socket error occurs.
251 for result in self.writeAsync(s):
254 def writeAsync(self, s):
255 """Start a write operation on the TLS connection.
257 This function returns a generator which behaves similarly to
258 write(). Successive invocations of the generator will return
259 1 if it is waiting to write to the socket, or will raise
260 StopIteration if the write operation has completed.
263 @return: A generator; see above for details.
267 raise TLSClosedConnectionError("attempt to write to closed connection")
271 randomizeFirstBlock = True
273 startIndex = index * blockSize
274 endIndex = startIndex + blockSize
275 if startIndex >= len(s):
277 if endIndex > len(s):
279 block = bytearray(s[startIndex : endIndex])
280 applicationData = ApplicationData().create(block)
281 for result in self._sendMsg(applicationData, \
282 randomizeFirstBlock):
284 randomizeFirstBlock = False #only on 1st message
286 except GeneratorExit:
289 self._shutdown(False)
293 """Close the TLS connection.
295 This function will block until it has exchanged close_notify
296 alerts with the other party. After doing so, it will shut down the
297 TLS connection. Further attempts to read through this connection
298 will return "". Further attempts to write through this connection
299 will raise ValueError.
301 If makefile() has been called on this connection, the connection
302 will be not be closed until the connection object and all file
303 objects have been closed.
305 Even if an exception is raised, the connection will have been
308 @raise socket.error: If a socket error occurs.
309 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
310 without a preceding alert.
311 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
314 for result in self._decrefAsync():
318 _decref_socketios = close
320 def closeAsync(self):
321 """Start a close operation on the TLS connection.
323 This function returns a generator which behaves similarly to
324 close(). Successive invocations of the generator will return 0
325 if it is waiting to read from the socket, 1 if it is waiting
326 to write to the socket, or will raise StopIteration if the
327 close operation has completed.
330 @return: A generator; see above for details.
333 for result in self._decrefAsync():
336 def _decrefAsync(self):
338 if self._refCount == 0 and not self.closed:
340 for result in self._sendMsg(Alert().create(\
341 AlertDescription.close_notify, AlertLevel.warning)):
344 # By default close the socket, since it's been observed
345 # that some other libraries will not respond to the
346 # close_notify alert, thus leaving us hanging if we're
352 for result in self._getMsg((ContentType.alert, \
353 ContentType.application_data)):
356 if result.contentType == ContentType.alert:
358 if alert.description == AlertDescription.close_notify:
361 raise TLSRemoteAlert(alert)
362 except (socket.error, TLSAbruptCloseError):
363 #If the other side closes the socket, that's okay
365 except GeneratorExit:
368 self._shutdown(False)
371 def getVersionName(self):
372 """Get the name of this TLS version.
375 @return: The name of the TLS version used with this connection.
376 Either None, 'SSL 3.0', 'TLS 1.0', or 'TLS 1.1'.
378 if self.version == (3,0):
380 elif self.version == (3,1):
382 elif self.version == (3,2):
387 def getCipherName(self):
388 """Get the name of the cipher used with this connection.
391 @return: The name of the cipher used with this connection.
392 Either 'aes128', 'aes256', 'rc4', or '3des'.
394 if not self._writeState.encContext:
396 return self._writeState.encContext.name
398 def getCipherImplementation(self):
399 """Get the name of the cipher implementation used with
403 @return: The name of the cipher implementation used with
404 this connection. Either 'python', 'openssl', or 'pycrypto'.
406 if not self._writeState.encContext:
408 return self._writeState.encContext.implementation
412 #Emulate a socket, somewhat -
414 """Send data to the TLS connection (socket emulation).
416 @raise socket.error: If a socket error occurs.
421 def sendall(self, s):
422 """Send data to the TLS connection (socket emulation).
424 @raise socket.error: If a socket error occurs.
428 def recv(self, bufsize):
429 """Get some data from the TLS connection (socket emulation).
431 @raise socket.error: If a socket error occurs.
432 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
433 without a preceding alert.
434 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
436 return self.read(bufsize)
438 def recv_into(self, b):
440 data = self.read(len(b))
446 def makefile(self, mode='r', bufsize=-1):
447 """Create a file object for the TLS connection (socket emulation).
449 @rtype: L{socket._fileobject}
452 # So, it is pretty fragile to be using Python internal objects
453 # like this, but it is probably the best/easiest way to provide
454 # matching behavior for socket emulation purposes. The 'close'
455 # argument is nice, its apparently a recent addition to this
456 # class, so that when fileobject.close() gets called, it will
457 # close() us, causing the refcount to be decremented (decrefAsync).
459 # If this is the last close() on the outstanding fileobjects /
460 # TLSConnection, then the "actual" close alerts will be sent,
461 # socket closed, etc.
462 if sys.version_info < (3,):
463 return socket._fileobject(self, mode, bufsize, close=True)
465 # XXX need to wrap this further if buffering is requested
466 return socket.SocketIO(self, mode)
468 def getsockname(self):
469 """Return the socket's own address (socket emulation)."""
470 return self.sock.getsockname()
472 def getpeername(self):
473 """Return the remote address to which the socket is connected
474 (socket emulation)."""
475 return self.sock.getpeername()
477 def settimeout(self, value):
478 """Set a timeout on blocking socket operations (socket emulation)."""
479 return self.sock.settimeout(value)
481 def gettimeout(self):
482 """Return the timeout associated with socket operations (socket
484 return self.sock.gettimeout()
486 def setsockopt(self, level, optname, value):
487 """Set the value of the given socket option (socket emulation)."""
488 return self.sock.setsockopt(level, optname, value)
490 def shutdown(self, how):
491 """Shutdown the underlying socket."""
492 return self.sock.shutdown(how)
495 """Not implement in TLS Lite."""
496 raise NotImplementedError()
499 #*********************************************************
500 # Public Functions END
501 #*********************************************************
503 def _shutdown(self, resumable):
504 self._writeState = _ConnectionState()
505 self._readState = _ConnectionState()
507 self._versionCheck = False
512 #Even if resumable is False, we'll never toggle this on
513 if not resumable and self.session:
514 self.session.resumable = False
517 def _sendError(self, alertDescription, errorStr=None):
518 alert = Alert().create(alertDescription, AlertLevel.fatal)
519 for result in self._sendMsg(alert):
521 self._shutdown(False)
522 raise TLSLocalAlert(alert, errorStr)
524 def _sendMsgs(self, msgs):
525 randomizeFirstBlock = True
527 for result in self._sendMsg(msg, randomizeFirstBlock):
529 randomizeFirstBlock = True
531 def _sendMsg(self, msg, randomizeFirstBlock = True):
532 #Whenever we're connected and asked to send an app data message,
533 #we first send the first byte of the message. This prevents
534 #an attacker from launching a chosen-plaintext attack based on
535 #knowing the next IV (a la BEAST).
536 if not self.closed and randomizeFirstBlock and self.version <= (3,1) \
537 and self._writeState.encContext \
538 and self._writeState.encContext.isBlockCipher \
539 and isinstance(msg, ApplicationData):
540 msgFirstByte = msg.splitFirstByte()
541 for result in self._sendMsg(msgFirstByte,
542 randomizeFirstBlock = False):
547 # If a 1-byte message was passed in, and we "split" the
548 # first(only) byte off above, we may have a 0-length msg:
552 contentType = msg.contentType
554 #Update handshake hashes
555 if contentType == ContentType.handshake:
556 self._handshake_md5.update(compat26Str(b))
557 self._handshake_sha.update(compat26Str(b))
560 if self._writeState.macContext:
561 seqnumBytes = self._writeState.getSeqNumBytes()
562 mac = self._writeState.macContext.copy()
563 mac.update(compatHMAC(seqnumBytes))
564 mac.update(compatHMAC(bytearray([contentType])))
565 if self.version == (3,0):
566 mac.update( compatHMAC( bytearray([len(b)//256] )))
567 mac.update( compatHMAC( bytearray([len(b)%256] )))
568 elif self.version in ((3,1), (3,2)):
569 mac.update(compatHMAC( bytearray([self.version[0]] )))
570 mac.update(compatHMAC( bytearray([self.version[1]] )))
571 mac.update( compatHMAC( bytearray([len(b)//256] )))
572 mac.update( compatHMAC( bytearray([len(b)%256] )))
574 raise AssertionError()
575 mac.update(compatHMAC(b))
576 macBytes = bytearray(mac.digest())
577 if self.fault == Fault.badMAC:
578 macBytes[0] = (macBytes[0]+1) % 256
580 #Encrypt for Block or Stream Cipher
581 if self._writeState.encContext:
582 #Add padding and encrypt (for Block Cipher):
583 if self._writeState.encContext.isBlockCipher:
585 #Add TLS 1.1 fixed block
586 if self.version == (3,2):
587 b = self.fixedIVBlock + b
589 #Add padding: b = b + (macBytes + paddingBytes)
590 currentLength = len(b) + len(macBytes)
591 blockLength = self._writeState.encContext.block_size
592 paddingLength = blockLength - 1 - (currentLength % blockLength)
594 paddingBytes = bytearray([paddingLength] * (paddingLength+1))
595 if self.fault == Fault.badPadding:
596 paddingBytes[0] = (paddingBytes[0]+1) % 256
597 endBytes = macBytes + paddingBytes
600 b = self._writeState.encContext.encrypt(b)
602 #Encrypt (for Stream Cipher)
605 b = self._writeState.encContext.encrypt(b)
607 #Add record header and send
608 r = RecordHeader3().create(self.version, contentType, len(b))
612 bytesSent = self.sock.send(s) #Might raise socket.error
613 except socket.error as why:
614 if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
618 # The socket was unexpectedly closed. The tricky part
619 # is that there may be an alert sent by the other party
620 # sitting in the read buffer. So, if we get here after
621 # handshaking, we will just raise the error and let the
622 # caller read more data if it would like, thus stumbling
625 # However, if we get here DURING handshaking, we take
626 # it upon ourselves to see if the next message is an
628 if contentType == ContentType.handshake:
630 # See if there's an alert record
631 # Could raise socket.error or TLSAbruptCloseError
632 for result in self._getNextRecord():
637 self._shutdown(False)
639 # If we got an alert, raise it
640 recordHeader, p = result
641 if recordHeader.type == ContentType.alert:
642 alert = Alert().parse(p)
643 raise TLSRemoteAlert(alert)
645 # If we got some other message who know what
646 # the remote side is doing, just go ahead and
647 # raise the socket.error
649 if bytesSent == len(s):
655 def _getMsg(self, expectedType, secondaryType=None, constructorType=None):
657 if not isinstance(expectedType, tuple):
658 expectedType = (expectedType,)
660 #Spin in a loop, until we've got a non-empty record of a type we
661 #expect. The loop will be repeated if:
662 # - we receive a renegotiation attempt; we send no_renegotiation,
664 # - we receive an empty application-data fragment; we try again
666 for result in self._getNextRecord():
669 recordHeader, p = result
671 #If this is an empty application-data fragment, try again
672 if recordHeader.type == ContentType.application_data:
673 if p.index == len(p.bytes):
676 #If we received an unexpected record type...
677 if recordHeader.type not in expectedType:
679 #If we received an alert...
680 if recordHeader.type == ContentType.alert:
681 alert = Alert().parse(p)
683 #We either received a fatal error, a warning, or a
684 #close_notify. In any case, we're going to close the
685 #connection. In the latter two cases we respond with
686 #a close_notify, but ignore any socket errors, since
687 #the other side might have already closed the socket.
688 if alert.level == AlertLevel.warning or \
689 alert.description == AlertDescription.close_notify:
691 #If the sendMsg() call fails because the socket has
692 #already been closed, we will be forgiving and not
693 #report the error nor invalidate the "resumability"
697 alertMsg.create(AlertDescription.close_notify,
699 for result in self._sendMsg(alertMsg):
704 if alert.description == \
705 AlertDescription.close_notify:
707 elif alert.level == AlertLevel.warning:
708 self._shutdown(False)
711 self._shutdown(False)
713 #Raise the alert as an exception
714 raise TLSRemoteAlert(alert)
716 #If we received a renegotiation attempt...
717 if recordHeader.type == ContentType.handshake:
721 if subType == HandshakeType.hello_request:
724 if subType == HandshakeType.client_hello:
726 #Send no_renegotiation, then try again
729 alertMsg.create(AlertDescription.no_renegotiation,
731 for result in self._sendMsg(alertMsg):
735 #Otherwise: this is an unexpected record, but neither an
736 #alert nor renegotiation
737 for result in self._sendError(\
738 AlertDescription.unexpected_message,
739 "received type=%d" % recordHeader.type):
744 #Parse based on content_type
745 if recordHeader.type == ContentType.change_cipher_spec:
746 yield ChangeCipherSpec().parse(p)
747 elif recordHeader.type == ContentType.alert:
748 yield Alert().parse(p)
749 elif recordHeader.type == ContentType.application_data:
750 yield ApplicationData().parse(p)
751 elif recordHeader.type == ContentType.handshake:
752 #Convert secondaryType to tuple, if it isn't already
753 if not isinstance(secondaryType, tuple):
754 secondaryType = (secondaryType,)
756 #If it's a handshake message, check handshake header
757 if recordHeader.ssl2:
759 if subType != HandshakeType.client_hello:
760 for result in self._sendError(\
761 AlertDescription.unexpected_message,
762 "Can only handle SSLv2 ClientHello messages"):
764 if HandshakeType.client_hello not in secondaryType:
765 for result in self._sendError(\
766 AlertDescription.unexpected_message):
768 subType = HandshakeType.client_hello
771 if subType not in secondaryType:
772 for result in self._sendError(\
773 AlertDescription.unexpected_message,
774 "Expecting %s, got %s" % (str(secondaryType), subType)):
777 #Update handshake hashes
778 self._handshake_md5.update(compat26Str(p.bytes))
779 self._handshake_sha.update(compat26Str(p.bytes))
781 #Parse based on handshake type
782 if subType == HandshakeType.client_hello:
783 yield ClientHello(recordHeader.ssl2).parse(p)
784 elif subType == HandshakeType.server_hello:
785 yield ServerHello().parse(p)
786 elif subType == HandshakeType.certificate:
787 yield Certificate(constructorType).parse(p)
788 elif subType == HandshakeType.certificate_request:
789 yield CertificateRequest().parse(p)
790 elif subType == HandshakeType.certificate_verify:
791 yield CertificateVerify().parse(p)
792 elif subType == HandshakeType.server_key_exchange:
793 yield ServerKeyExchange(constructorType).parse(p)
794 elif subType == HandshakeType.server_hello_done:
795 yield ServerHelloDone().parse(p)
796 elif subType == HandshakeType.client_key_exchange:
797 yield ClientKeyExchange(constructorType, \
798 self.version).parse(p)
799 elif subType == HandshakeType.finished:
800 yield Finished(self.version).parse(p)
801 elif subType == HandshakeType.next_protocol:
802 yield NextProtocol().parse(p)
803 elif subType == HandshakeType.encrypted_extensions:
804 yield EncryptedExtensions().parse(p)
806 raise AssertionError()
808 #If an exception was raised by a Parser or Message instance:
809 except SyntaxError as e:
810 for result in self._sendError(AlertDescription.decode_error,
811 formatExceptionTrace(e)):
815 #Returns next record or next handshake message
816 def _getNextRecord(self):
818 #If there's a handshake message waiting, return it
819 if self._handshakeBuffer:
820 recordHeader, b = self._handshakeBuffer[0]
821 self._handshakeBuffer = self._handshakeBuffer[1:]
822 yield (recordHeader, Parser(b))
826 #Read the next record header
828 recordHeaderLength = 1
832 s = self.sock.recv(recordHeaderLength-len(b))
833 except socket.error as why:
834 if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
840 #If the connection was abruptly closed, raise an error
842 raise TLSAbruptCloseError()
846 if b[0] in ContentType.all:
848 recordHeaderLength = 5
851 recordHeaderLength = 2
854 if len(b) == recordHeaderLength:
857 #Parse the record header
859 r = RecordHeader2().parse(Parser(b))
861 r = RecordHeader3().parse(Parser(b))
863 #Check the record header fields
865 for result in self._sendError(AlertDescription.record_overflow):
868 #Read the record contents
872 s = self.sock.recv(r.length - len(b))
873 except socket.error as why:
874 if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
880 #If the connection is closed, raise a socket error
882 raise TLSAbruptCloseError()
885 if len(b) == r.length:
888 #Check the record header fields (2)
889 #We do this after reading the contents from the socket, so that
890 #if there's an error, we at least don't leave extra bytes in the
893 # THIS CHECK HAS NO SECURITY RELEVANCE (?), BUT COULD HURT INTEROP.
894 # SO WE LEAVE IT OUT FOR NOW.
896 #if self._versionCheck and r.version != self.version:
897 # for result in self._sendError(AlertDescription.protocol_version,
898 # "Version in header field: %s, should be %s" % (str(r.version),
899 # str(self.version))):
903 for result in self._decryptRecord(r.type, b):
904 if result in (0,1): yield result
909 #If it doesn't contain handshake messages, we can just return it
910 if r.type != ContentType.handshake:
912 #If it's an SSLv2 ClientHello, we can return it as well
916 #Otherwise, we loop through and add the handshake messages to the
919 if p.index == len(b): #If we're at the end
920 if not self._handshakeBuffer:
921 for result in self._sendError(\
922 AlertDescription.decode_error, \
923 "Received empty handshake record"):
926 #There needs to be at least 4 bytes to get a header
927 if p.index+4 > len(b):
928 for result in self._sendError(\
929 AlertDescription.decode_error,
930 "A record has a partial handshake message (1)"):
932 p.get(1) # skip handshake type
934 if p.index+msgLength > len(b):
935 for result in self._sendError(\
936 AlertDescription.decode_error,
937 "A record has a partial handshake message (2)"):
940 handshakePair = (r, b[p.index-4 : p.index+msgLength])
941 self._handshakeBuffer.append(handshakePair)
944 #We've moved at least one handshake message into the
945 #handshakeBuffer, return the first one
946 recordHeader, b = self._handshakeBuffer[0]
947 self._handshakeBuffer = self._handshakeBuffer[1:]
948 yield (recordHeader, Parser(b))
951 def _decryptRecord(self, recordType, b):
952 if self._readState.encContext:
954 #Decrypt if it's a block cipher
955 if self._readState.encContext.isBlockCipher:
956 blockLength = self._readState.encContext.block_size
957 if len(b) % blockLength != 0:
958 for result in self._sendError(\
959 AlertDescription.decryption_failed,
960 "Encrypted data not a multiple of blocksize"):
962 b = self._readState.encContext.decrypt(b)
963 if self.version == (3,2): #For TLS 1.1, remove explicit IV
964 b = b[self._readState.encContext.block_size : ]
968 paddingLength = b[-1]
969 if (paddingLength+1) > len(b):
971 totalPaddingLength = 0
973 if self.version == (3,0):
974 totalPaddingLength = paddingLength+1
975 elif self.version in ((3,1), (3,2)):
976 totalPaddingLength = paddingLength+1
977 paddingBytes = b[-totalPaddingLength:-1]
978 for byte in paddingBytes:
979 if byte != paddingLength:
981 totalPaddingLength = 0
983 raise AssertionError()
985 #Decrypt if it's a stream cipher
988 b = self._readState.encContext.decrypt(b)
989 totalPaddingLength = 0
993 macLength = self._readState.macContext.digest_size
994 endLength = macLength + totalPaddingLength
995 if endLength > len(b):
999 startIndex = len(b) - endLength
1000 endIndex = startIndex + macLength
1001 checkBytes = b[startIndex : endIndex]
1004 seqnumBytes = self._readState.getSeqNumBytes()
1006 mac = self._readState.macContext.copy()
1007 mac.update(compatHMAC(seqnumBytes))
1008 mac.update(compatHMAC(bytearray([recordType])))
1009 if self.version == (3,0):
1010 mac.update( compatHMAC(bytearray( [len(b)//256] ) ))
1011 mac.update( compatHMAC(bytearray( [len(b)%256] ) ))
1012 elif self.version in ((3,1), (3,2)):
1013 mac.update(compatHMAC(bytearray( [self.version[0]] ) ))
1014 mac.update(compatHMAC(bytearray( [self.version[1]] ) ))
1015 mac.update(compatHMAC(bytearray( [len(b)//256] ) ))
1016 mac.update(compatHMAC(bytearray( [len(b)%256] ) ))
1018 raise AssertionError()
1019 mac.update(compatHMAC(b))
1020 macBytes = bytearray(mac.digest())
1023 if macBytes != checkBytes:
1026 if not (paddingGood and macGood):
1027 for result in self._sendError(AlertDescription.bad_record_mac,
1028 "MAC failure (or padding failure)"):
1033 def _handshakeStart(self, client):
1035 raise ValueError("Renegotiation disallowed for security reasons")
1036 self._client = client
1037 self._handshake_md5 = hashlib.md5()
1038 self._handshake_sha = hashlib.sha1()
1039 self._handshakeBuffer = []
1040 self.allegedSrpUsername = None
1043 def _handshakeDone(self, resumed):
1044 self.resumed = resumed
1047 def _calcPendingStates(self, cipherSuite, masterSecret,
1048 clientRandom, serverRandom, implementations):
1049 if cipherSuite in CipherSuite.aes128Suites:
1052 createCipherFunc = createAES
1053 elif cipherSuite in CipherSuite.aes256Suites:
1056 createCipherFunc = createAES
1057 elif cipherSuite in CipherSuite.rc4Suites:
1060 createCipherFunc = createRC4
1061 elif cipherSuite in CipherSuite.tripleDESSuites:
1064 createCipherFunc = createTripleDES
1066 raise AssertionError()
1068 if cipherSuite in CipherSuite.shaSuites:
1070 digestmod = hashlib.sha1
1071 elif cipherSuite in CipherSuite.md5Suites:
1073 digestmod = hashlib.md5
1075 if self.version == (3,0):
1076 createMACFunc = createMAC_SSL
1077 elif self.version in ((3,1), (3,2)):
1078 createMACFunc = createHMAC
1080 outputLength = (macLength*2) + (keyLength*2) + (ivLength*2)
1082 #Calculate Keying Material from Master Secret
1083 if self.version == (3,0):
1084 keyBlock = PRF_SSL(masterSecret,
1085 serverRandom + clientRandom,
1087 elif self.version in ((3,1), (3,2)):
1088 keyBlock = PRF(masterSecret,
1090 serverRandom + clientRandom,
1093 raise AssertionError()
1095 #Slice up Keying Material
1096 clientPendingState = _ConnectionState()
1097 serverPendingState = _ConnectionState()
1098 p = Parser(keyBlock)
1099 clientMACBlock = p.getFixBytes(macLength)
1100 serverMACBlock = p.getFixBytes(macLength)
1101 clientKeyBlock = p.getFixBytes(keyLength)
1102 serverKeyBlock = p.getFixBytes(keyLength)
1103 clientIVBlock = p.getFixBytes(ivLength)
1104 serverIVBlock = p.getFixBytes(ivLength)
1105 clientPendingState.macContext = createMACFunc(
1106 compatHMAC(clientMACBlock), digestmod=digestmod)
1107 serverPendingState.macContext = createMACFunc(
1108 compatHMAC(serverMACBlock), digestmod=digestmod)
1109 clientPendingState.encContext = createCipherFunc(clientKeyBlock,
1112 serverPendingState.encContext = createCipherFunc(serverKeyBlock,
1116 #Assign new connection states to pending states
1118 self._pendingWriteState = clientPendingState
1119 self._pendingReadState = serverPendingState
1121 self._pendingWriteState = serverPendingState
1122 self._pendingReadState = clientPendingState
1124 if self.version == (3,2) and ivLength:
1125 #Choose fixedIVBlock for TLS 1.1 (this is encrypted with the CBC
1126 #residue to create the IV for each sent block)
1127 self.fixedIVBlock = getRandomBytes(ivLength)
1129 def _changeWriteState(self):
1130 self._writeState = self._pendingWriteState
1131 self._pendingWriteState = _ConnectionState()
1133 def _changeReadState(self):
1134 self._readState = self._pendingReadState
1135 self._pendingReadState = _ConnectionState()
1137 #Used for Finished messages and CertificateVerify messages in SSL v3
1138 def _calcSSLHandshakeHash(self, masterSecret, label):
1139 imac_md5 = self._handshake_md5.copy()
1140 imac_sha = self._handshake_sha.copy()
1142 imac_md5.update(compatHMAC(label + masterSecret + bytearray([0x36]*48)))
1143 imac_sha.update(compatHMAC(label + masterSecret + bytearray([0x36]*40)))
1145 md5Bytes = MD5(masterSecret + bytearray([0x5c]*48) + \
1146 bytearray(imac_md5.digest()))
1147 shaBytes = SHA1(masterSecret + bytearray([0x5c]*40) + \
1148 bytearray(imac_sha.digest()))
1150 return md5Bytes + shaBytes