1
2
3
4
5
6
7
8
9 """Helper class for TLSConnection."""
10 from __future__ import generators
11
12 from .utils.compat import *
13 from .utils.cryptomath import *
14 from .utils.cipherfactory import createAES, createRC4, createTripleDES
15 from .utils.codec import *
16 from .errors import *
17 from .messages import *
18 from .mathtls import *
19 from .constants import *
20 from .utils.cryptomath import getRandomBytes
21
22 import socket
23 import errno
24 import traceback
25
28 self.macContext = None
29 self.encContext = None
30 self.seqnum = 0
31
33 w = Writer()
34 w.add(self.seqnum, 8)
35 self.seqnum += 1
36 return w.bytes
37
38
40 """
41 This class handles data transmission for a TLS connection.
42
43 Its only subclass is L{tlslite.TLSConnection.TLSConnection}. We've
44 separated the code in this class from TLSConnection to make things
45 more readable.
46
47
48 @type sock: socket.socket
49 @ivar sock: The underlying socket object.
50
51 @type session: L{tlslite.Session.Session}
52 @ivar session: The session corresponding to this connection.
53
54 Due to TLS session resumption, multiple connections can correspond
55 to the same underlying session.
56
57 @type version: tuple
58 @ivar version: The TLS version being used for this connection.
59
60 (3,0) means SSL 3.0, and (3,1) means TLS 1.0.
61
62 @type closed: bool
63 @ivar closed: If this connection is closed.
64
65 @type resumed: bool
66 @ivar resumed: If this connection is based on a resumed session.
67
68 @type allegedSrpUsername: str or None
69 @ivar allegedSrpUsername: This is set to the SRP username
70 asserted by the client, whether the handshake succeeded or not.
71 If the handshake fails, this can be inspected to determine
72 if a guessing attack is in progress against a particular user
73 account.
74
75 @type closeSocket: bool
76 @ivar closeSocket: If the socket should be closed when the
77 connection is closed, defaults to True (writable).
78
79 If you set this to True, TLS Lite will assume the responsibility of
80 closing the socket when the TLS Connection is shutdown (either
81 through an error or through the user calling close()). The default
82 is False.
83
84 @type ignoreAbruptClose: bool
85 @ivar ignoreAbruptClose: If an abrupt close of the socket should
86 raise an error (writable).
87
88 If you set this to True, TLS Lite will not raise a
89 L{tlslite.errors.TLSAbruptCloseError} exception if the underlying
90 socket is unexpectedly closed. Such an unexpected closure could be
91 caused by an attacker. However, it also occurs with some incorrect
92 TLS implementations.
93
94 You should set this to True only if you're not worried about an
95 attacker truncating the connection, and only if necessary to avoid
96 spurious errors. The default is False.
97
98 @sort: __init__, read, readAsync, write, writeAsync, close, closeAsync,
99 getCipherImplementation, getCipherName
100 """
101
103 self.sock = sock
104
105
106 self.session = None
107
108
109 self._client = None
110
111
112 self._handshakeBuffer = []
113 self.clearReadBuffer()
114 self.clearWriteBuffer()
115
116
117 self._handshake_md5 = hashlib.md5()
118 self._handshake_sha = hashlib.sha1()
119 self._handshake_sha256 = hashlib.sha256()
120
121
122 self.version = (0,0)
123 self._versionCheck = False
124
125
126 self._writeState = _ConnectionState()
127 self._readState = _ConnectionState()
128 self._pendingWriteState = _ConnectionState()
129 self._pendingReadState = _ConnectionState()
130
131
132 self.closed = True
133 self._refCount = 0
134
135
136 self.resumed = False
137
138
139 self.allegedSrpUsername = None
140
141
142 self.closeSocket = True
143
144
145
146 self.ignoreAbruptClose = False
147
148
149 self.fault = None
150
152 self._readBuffer = b''
153
155 self._send_writer = None
156
157
158
159
160
161
162 - def read(self, max=None, min=1):
163 """Read some data from the TLS connection.
164
165 This function will block until at least 'min' bytes are
166 available (or the connection is closed).
167
168 If an exception is raised, the connection will have been
169 automatically closed.
170
171 @type max: int
172 @param max: The maximum number of bytes to return.
173
174 @type min: int
175 @param min: The minimum number of bytes to return
176
177 @rtype: str
178 @return: A string of no more than 'max' bytes, and no fewer
179 than 'min' (unless the connection has been closed, in which
180 case fewer than 'min' bytes may be returned).
181
182 @raise socket.error: If a socket error occurs.
183 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
184 without a preceding alert.
185 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
186 """
187 for result in self.readAsync(max, min):
188 pass
189 return result
190
192 """Start a read operation on the TLS connection.
193
194 This function returns a generator which behaves similarly to
195 read(). Successive invocations of the generator will return 0
196 if it is waiting to read from the socket, 1 if it is waiting
197 to write to the socket, or a string if the read operation has
198 completed.
199
200 @rtype: iterable
201 @return: A generator; see above for details.
202 """
203 try:
204 while len(self._readBuffer)<min and not self.closed:
205 try:
206 for result in self._getMsg(ContentType.application_data):
207 if result in (0,1):
208 yield result
209 applicationData = result
210 self._readBuffer += applicationData.write()
211 except TLSRemoteAlert as alert:
212 if alert.description != AlertDescription.close_notify:
213 raise
214 except TLSAbruptCloseError:
215 if not self.ignoreAbruptClose:
216 raise
217 else:
218 self._shutdown(True)
219
220 if max == None:
221 max = len(self._readBuffer)
222
223 returnBytes = self._readBuffer[:max]
224 self._readBuffer = self._readBuffer[max:]
225 yield bytes(returnBytes)
226 except GeneratorExit:
227 raise
228 except:
229 self._shutdown(False)
230 raise
231
233 """Add bytes to the front of the socket read buffer for future
234 reading. Be careful using this in the context of select(...): if you
235 unread the last data from a socket, that won't wake up selected waiters,
236 and those waiters may hang forever.
237 """
238 self._readBuffer = b + self._readBuffer
239
241 """Write some data to the TLS connection.
242
243 This function will block until all the data has been sent.
244
245 If an exception is raised, the connection will have been
246 automatically closed.
247
248 @type s: str
249 @param s: The data to transmit to the other party.
250
251 @raise socket.error: If a socket error occurs.
252 """
253 for result in self.writeAsync(s):
254 pass
255
257 """Start a write operation on the TLS connection.
258
259 This function returns a generator which behaves similarly to
260 write(). Successive invocations of the generator will return
261 1 if it is waiting to write to the socket, or will raise
262 StopIteration if the write operation has completed.
263
264 @rtype: iterable
265 @return: A generator; see above for details.
266 """
267 try:
268 if self.closed:
269 raise TLSClosedConnectionError("attempt to write to closed connection")
270
271 index = 0
272 blockSize = 16384
273 randomizeFirstBlock = True
274 while 1:
275 startIndex = index * blockSize
276 endIndex = startIndex + blockSize
277 if startIndex >= len(s):
278 break
279 if endIndex > len(s):
280 endIndex = len(s)
281 block = bytearray(s[startIndex : endIndex])
282 applicationData = ApplicationData().create(block)
283 for result in self._sendMsg(applicationData, \
284 randomizeFirstBlock):
285 yield result
286 randomizeFirstBlock = False
287 index += 1
288 except GeneratorExit:
289 raise
290 except Exception:
291 self._shutdown(False)
292 raise
293
295 """Close the TLS connection.
296
297 This function will block until it has exchanged close_notify
298 alerts with the other party. After doing so, it will shut down the
299 TLS connection. Further attempts to read through this connection
300 will return "". Further attempts to write through this connection
301 will raise ValueError.
302
303 If makefile() has been called on this connection, the connection
304 will be not be closed until the connection object and all file
305 objects have been closed.
306
307 Even if an exception is raised, the connection will have been
308 closed.
309
310 @raise socket.error: If a socket error occurs.
311 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
312 without a preceding alert.
313 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
314 """
315 if not self.closed:
316 for result in self._decrefAsync():
317 pass
318
319
320 _decref_socketios = close
321
323 """Start a close operation on the TLS connection.
324
325 This function returns a generator which behaves similarly to
326 close(). Successive invocations of the generator will return 0
327 if it is waiting to read from the socket, 1 if it is waiting
328 to write to the socket, or will raise StopIteration if the
329 close operation has completed.
330
331 @rtype: iterable
332 @return: A generator; see above for details.
333 """
334 if not self.closed:
335 for result in self._decrefAsync():
336 yield result
337
372
374 """Get the name of this TLS version.
375
376 @rtype: str
377 @return: The name of the TLS version used with this connection.
378 Either None, 'SSL 3.0', 'TLS 1.0', 'TLS 1.1', or 'TLS 1.2'.
379 """
380 if self.version == (3,0):
381 return "SSL 3.0"
382 elif self.version == (3,1):
383 return "TLS 1.0"
384 elif self.version == (3,2):
385 return "TLS 1.1"
386 elif self.version == (3,3):
387 return "TLS 1.2"
388 else:
389 return None
390
392 """Get the name of the cipher used with this connection.
393
394 @rtype: str
395 @return: The name of the cipher used with this connection.
396 Either 'aes128', 'aes256', 'rc4', or '3des'.
397 """
398 if not self._writeState.encContext:
399 return None
400 return self._writeState.encContext.name
401
403 """Get the name of the cipher implementation used with
404 this connection.
405
406 @rtype: str
407 @return: The name of the cipher implementation used with
408 this connection. Either 'python', 'openssl', or 'pycrypto'.
409 """
410 if not self._writeState.encContext:
411 return None
412 return self._writeState.encContext.implementation
413
414
415
416
418 """Send data to the TLS connection (socket emulation).
419
420 @raise socket.error: If a socket error occurs.
421 """
422 self.write(s)
423 return len(s)
424
426 """Send data to the TLS connection (socket emulation).
427
428 @raise socket.error: If a socket error occurs.
429 """
430 self.write(s)
431
432 - def recv(self, bufsize):
433 """Get some data from the TLS connection (socket emulation).
434
435 @raise socket.error: If a socket error occurs.
436 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
437 without a preceding alert.
438 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
439 """
440 return self.read(bufsize)
441
443
444 data = self.read(len(b))
445 if not data:
446 return None
447 b[:len(data)] = data
448 return len(data)
449
450 - def makefile(self, mode='r', bufsize=-1):
451 """Create a file object for the TLS connection (socket emulation).
452
453 @rtype: L{socket._fileobject}
454 """
455 self._refCount += 1
456
457
458
459
460
461
462
463
464
465
466 if sys.version_info < (3,):
467 return socket._fileobject(self, mode, bufsize, close=True)
468 else:
469
470 return socket.SocketIO(self, mode)
471
473 """Return the socket's own address (socket emulation)."""
474 return self.sock.getsockname()
475
477 """Return the remote address to which the socket is connected
478 (socket emulation)."""
479 return self.sock.getpeername()
480
482 """Set a timeout on blocking socket operations (socket emulation)."""
483 return self.sock.settimeout(value)
484
486 """Return the timeout associated with socket operations (socket
487 emulation)."""
488 return self.sock.gettimeout()
489
491 """Set the value of the given socket option (socket emulation)."""
492 return self.sock.setsockopt(level, optname, value)
493
495 """Shutdown the underlying socket."""
496 return self.sock.shutdown(how)
497
499 """Not implement in TLS Lite."""
500 raise NotImplementedError()
501
502
503
504
505
506
508 self._writeState = _ConnectionState()
509 self._readState = _ConnectionState()
510 self.version = (0,0)
511 self._versionCheck = False
512 self.closed = True
513 if self.closeSocket:
514 self.sock.close()
515
516
517 if not resumable and self.session:
518 self.session.resumable = False
519
520
521 - def _sendError(self, alertDescription, errorStr=None):
527
529 randomizeFirstBlock = True
530 for msg in msgs:
531 for result in self._sendMsg(msg, randomizeFirstBlock):
532 yield result
533 randomizeFirstBlock = True
534
535 - def _sendMsg(self, msg, randomizeFirstBlock = True):
536
537
538
539
540 if not self.closed and randomizeFirstBlock and self.version <= (3,1) \
541 and self._writeState.encContext \
542 and self._writeState.encContext.isBlockCipher \
543 and isinstance(msg, ApplicationData):
544 msgFirstByte = msg.splitFirstByte()
545 for result in self._sendMsg(msgFirstByte,
546 randomizeFirstBlock = False):
547 yield result
548
549 b = msg.write()
550
551
552
553 if len(b) == 0:
554 return
555
556 contentType = msg.contentType
557
558
559 if contentType == ContentType.handshake:
560 self._handshake_md5.update(compat26Str(b))
561 self._handshake_sha.update(compat26Str(b))
562 self._handshake_sha256.update(compat26Str(b))
563
564
565 if self._writeState.macContext:
566 seqnumBytes = self._writeState.getSeqNumBytes()
567 mac = self._writeState.macContext.copy()
568 mac.update(compatHMAC(seqnumBytes))
569 mac.update(compatHMAC(bytearray([contentType])))
570 if self.version == (3,0):
571 mac.update( compatHMAC( bytearray([len(b)//256] )))
572 mac.update( compatHMAC( bytearray([len(b)%256] )))
573 elif self.version in ((3,1), (3,2), (3,3)):
574 mac.update(compatHMAC( bytearray([self.version[0]] )))
575 mac.update(compatHMAC( bytearray([self.version[1]] )))
576 mac.update( compatHMAC( bytearray([len(b)//256] )))
577 mac.update( compatHMAC( bytearray([len(b)%256] )))
578 else:
579 raise AssertionError()
580 mac.update(compatHMAC(b))
581 macBytes = bytearray(mac.digest())
582 if self.fault == Fault.badMAC:
583 macBytes[0] = (macBytes[0]+1) % 256
584
585
586 if self._writeState.encContext:
587
588 if self._writeState.encContext.isBlockCipher:
589
590
591 if self.version >= (3,2):
592 b = self.fixedIVBlock + b
593
594
595 currentLength = len(b) + len(macBytes) + 1
596 blockLength = self._writeState.encContext.block_size
597 paddingLength = blockLength-(currentLength % blockLength)
598
599 paddingBytes = bytearray([paddingLength] * (paddingLength+1))
600 if self.fault == Fault.badPadding:
601 paddingBytes[0] = (paddingBytes[0]+1) % 256
602 endBytes = macBytes + paddingBytes
603 b += endBytes
604
605 b = self._writeState.encContext.encrypt(b)
606
607
608 else:
609 b += macBytes
610 b = self._writeState.encContext.encrypt(b)
611
612
613 r = RecordHeader3().create(self.version, contentType, len(b))
614 s = r.write() + b
615 while 1:
616 try:
617 bytesSent = self.sock.send(s)
618 except socket.error as why:
619 if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
620 yield 1
621 continue
622 else:
623
624
625
626
627
628
629
630
631
632
633 if contentType == ContentType.handshake:
634
635
636
637 for result in self._getNextRecord():
638 if result in (0,1):
639 yield result
640
641
642 self._shutdown(False)
643
644
645 recordHeader, p = result
646 if recordHeader.type == ContentType.alert:
647 alert = Alert().parse(p)
648 raise TLSRemoteAlert(alert)
649 else:
650
651
652
653 raise
654 if bytesSent == len(s):
655 return
656 s = s[bytesSent:]
657 yield 1
658
659
660 - def _getMsg(self, expectedType, secondaryType=None, constructorType=None):
661 try:
662 if not isinstance(expectedType, tuple):
663 expectedType = (expectedType,)
664
665
666
667
668
669
670 while 1:
671 for result in self._getNextRecord():
672 if result in (0,1):
673 yield result
674 recordHeader, p = result
675
676
677 if recordHeader.type == ContentType.application_data:
678 if p.index == len(p.bytes):
679 continue
680
681
682 if recordHeader.type not in expectedType:
683
684
685 if recordHeader.type == ContentType.alert:
686 alert = Alert().parse(p)
687
688
689
690
691
692
693 if alert.level == AlertLevel.warning or \
694 alert.description == AlertDescription.close_notify:
695
696
697
698
699
700 try:
701 alertMsg = Alert()
702 alertMsg.create(AlertDescription.close_notify,
703 AlertLevel.warning)
704 for result in self._sendMsg(alertMsg):
705 yield result
706 except socket.error:
707 pass
708
709 if alert.description == \
710 AlertDescription.close_notify:
711 self._shutdown(True)
712 elif alert.level == AlertLevel.warning:
713 self._shutdown(False)
714
715 else:
716 self._shutdown(False)
717
718
719 raise TLSRemoteAlert(alert)
720
721
722 if recordHeader.type == ContentType.handshake:
723 subType = p.get(1)
724 reneg = False
725 if self._client:
726 if subType == HandshakeType.hello_request:
727 reneg = True
728 else:
729 if subType == HandshakeType.client_hello:
730 reneg = True
731
732 if reneg:
733 alertMsg = Alert()
734 alertMsg.create(AlertDescription.no_renegotiation,
735 AlertLevel.warning)
736 for result in self._sendMsg(alertMsg):
737 yield result
738 continue
739
740
741
742 for result in self._sendError(\
743 AlertDescription.unexpected_message,
744 "received type=%d" % recordHeader.type):
745 yield result
746
747 break
748
749
750 if recordHeader.type == ContentType.change_cipher_spec:
751 yield ChangeCipherSpec().parse(p)
752 elif recordHeader.type == ContentType.alert:
753 yield Alert().parse(p)
754 elif recordHeader.type == ContentType.application_data:
755 yield ApplicationData().parse(p)
756 elif recordHeader.type == ContentType.handshake:
757
758 if not isinstance(secondaryType, tuple):
759 secondaryType = (secondaryType,)
760
761
762 if recordHeader.ssl2:
763 subType = p.get(1)
764 if subType != HandshakeType.client_hello:
765 for result in self._sendError(\
766 AlertDescription.unexpected_message,
767 "Can only handle SSLv2 ClientHello messages"):
768 yield result
769 if HandshakeType.client_hello not in secondaryType:
770 for result in self._sendError(\
771 AlertDescription.unexpected_message):
772 yield result
773 subType = HandshakeType.client_hello
774 else:
775 subType = p.get(1)
776 if subType not in secondaryType:
777 for result in self._sendError(\
778 AlertDescription.unexpected_message,
779 "Expecting %s, got %s" % (str(secondaryType), subType)):
780 yield result
781
782
783 self._handshake_md5.update(compat26Str(p.bytes))
784 self._handshake_sha.update(compat26Str(p.bytes))
785 self._handshake_sha256.update(compat26Str(p.bytes))
786
787
788 if subType == HandshakeType.client_hello:
789 yield ClientHello(recordHeader.ssl2).parse(p)
790 elif subType == HandshakeType.server_hello:
791 yield ServerHello().parse(p)
792 elif subType == HandshakeType.certificate:
793 yield Certificate(constructorType).parse(p)
794 elif subType == HandshakeType.certificate_request:
795 yield CertificateRequest(self.version).parse(p)
796 elif subType == HandshakeType.certificate_verify:
797 yield CertificateVerify().parse(p)
798 elif subType == HandshakeType.server_key_exchange:
799 yield ServerKeyExchange(constructorType).parse(p)
800 elif subType == HandshakeType.server_hello_done:
801 yield ServerHelloDone().parse(p)
802 elif subType == HandshakeType.client_key_exchange:
803 yield ClientKeyExchange(constructorType, \
804 self.version).parse(p)
805 elif subType == HandshakeType.finished:
806 yield Finished(self.version).parse(p)
807 elif subType == HandshakeType.next_protocol:
808 yield NextProtocol().parse(p)
809 else:
810 raise AssertionError()
811
812
813 except SyntaxError as e:
814 for result in self._sendError(AlertDescription.decode_error,
815 formatExceptionTrace(e)):
816 yield result
817
818
819
821
822
823 if self._handshakeBuffer:
824 recordHeader, b = self._handshakeBuffer[0]
825 self._handshakeBuffer = self._handshakeBuffer[1:]
826 yield (recordHeader, Parser(b))
827 return
828
829
830
831 b = bytearray(0)
832 recordHeaderLength = 1
833 ssl2 = False
834 while 1:
835 try:
836 s = self.sock.recv(recordHeaderLength-len(b))
837 except socket.error as why:
838 if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
839 yield 0
840 continue
841 else:
842 raise
843
844
845 if len(s)==0:
846 raise TLSAbruptCloseError()
847
848 b += bytearray(s)
849 if len(b)==1:
850 if b[0] in ContentType.all:
851 ssl2 = False
852 recordHeaderLength = 5
853 elif b[0] == 128:
854 ssl2 = True
855 recordHeaderLength = 2
856 else:
857 raise SyntaxError()
858 if len(b) == recordHeaderLength:
859 break
860
861
862 if ssl2:
863 r = RecordHeader2().parse(Parser(b))
864 else:
865 r = RecordHeader3().parse(Parser(b))
866
867
868 if r.length > 18432:
869 for result in self._sendError(AlertDescription.record_overflow):
870 yield result
871
872
873 b = bytearray(0)
874 while 1:
875 try:
876 s = self.sock.recv(r.length - len(b))
877 except socket.error as why:
878 if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
879 yield 0
880 continue
881 else:
882 raise
883
884
885 if len(s)==0:
886 raise TLSAbruptCloseError()
887
888 b += bytearray(s)
889 if len(b) == r.length:
890 break
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907 for result in self._decryptRecord(r.type, b):
908 if result in (0,1): yield result
909 else: break
910 b = result
911 p = Parser(b)
912
913
914 if r.type != ContentType.handshake:
915 yield (r, p)
916
917 elif r.ssl2:
918 yield (r, p)
919 else:
920
921
922 while 1:
923 if p.index == len(b):
924 if not self._handshakeBuffer:
925 for result in self._sendError(\
926 AlertDescription.decode_error, \
927 "Received empty handshake record"):
928 yield result
929 break
930
931 if p.index+4 > len(b):
932 for result in self._sendError(\
933 AlertDescription.decode_error,
934 "A record has a partial handshake message (1)"):
935 yield result
936 p.get(1)
937 msgLength = p.get(3)
938 if p.index+msgLength > len(b):
939 for result in self._sendError(\
940 AlertDescription.decode_error,
941 "A record has a partial handshake message (2)"):
942 yield result
943
944 handshakePair = (r, b[p.index-4 : p.index+msgLength])
945 self._handshakeBuffer.append(handshakePair)
946 p.index += msgLength
947
948
949
950 recordHeader, b = self._handshakeBuffer[0]
951 self._handshakeBuffer = self._handshakeBuffer[1:]
952 yield (recordHeader, Parser(b))
953
954
956 if self._readState.encContext:
957
958
959 if self._readState.encContext.isBlockCipher:
960 blockLength = self._readState.encContext.block_size
961 if len(b) % blockLength != 0:
962 for result in self._sendError(\
963 AlertDescription.decryption_failed,
964 "Encrypted data not a multiple of blocksize"):
965 yield result
966 b = self._readState.encContext.decrypt(b)
967 if self.version >= (3,2):
968 b = b[self._readState.encContext.block_size : ]
969
970
971 paddingGood = True
972 paddingLength = b[-1]
973 if (paddingLength+1) > len(b):
974 paddingGood=False
975 totalPaddingLength = 0
976 else:
977 if self.version == (3,0):
978 totalPaddingLength = paddingLength+1
979 elif self.version in ((3,1), (3,2), (3,3)):
980 totalPaddingLength = paddingLength+1
981 paddingBytes = b[-totalPaddingLength:-1]
982 for byte in paddingBytes:
983 if byte != paddingLength:
984 paddingGood = False
985 totalPaddingLength = 0
986 else:
987 raise AssertionError()
988
989
990 else:
991 paddingGood = True
992 b = self._readState.encContext.decrypt(b)
993 totalPaddingLength = 0
994
995
996 macGood = True
997 macLength = self._readState.macContext.digest_size
998 endLength = macLength + totalPaddingLength
999 if endLength > len(b):
1000 macGood = False
1001 else:
1002
1003 startIndex = len(b) - endLength
1004 endIndex = startIndex + macLength
1005 checkBytes = b[startIndex : endIndex]
1006
1007
1008 seqnumBytes = self._readState.getSeqNumBytes()
1009 b = b[:-endLength]
1010 mac = self._readState.macContext.copy()
1011 mac.update(compatHMAC(seqnumBytes))
1012 mac.update(compatHMAC(bytearray([recordType])))
1013 if self.version == (3,0):
1014 mac.update( compatHMAC(bytearray( [len(b)//256] ) ))
1015 mac.update( compatHMAC(bytearray( [len(b)%256] ) ))
1016 elif self.version in ((3,1), (3,2), (3,3)):
1017 mac.update(compatHMAC(bytearray( [self.version[0]] ) ))
1018 mac.update(compatHMAC(bytearray( [self.version[1]] ) ))
1019 mac.update(compatHMAC(bytearray( [len(b)//256] ) ))
1020 mac.update(compatHMAC(bytearray( [len(b)%256] ) ))
1021 else:
1022 raise AssertionError()
1023 mac.update(compatHMAC(b))
1024 macBytes = bytearray(mac.digest())
1025
1026
1027 if macBytes != checkBytes:
1028 macGood = False
1029
1030 if not (paddingGood and macGood):
1031 for result in self._sendError(AlertDescription.bad_record_mac,
1032 "MAC failure (or padding failure)"):
1033 yield result
1034
1035 yield b
1036
1038 if not self.closed:
1039 raise ValueError("Renegotiation disallowed for security reasons")
1040 self._client = client
1041 self._handshake_md5 = hashlib.md5()
1042 self._handshake_sha = hashlib.sha1()
1043 self._handshake_sha256 = hashlib.sha256()
1044 self._handshakeBuffer = []
1045 self.allegedSrpUsername = None
1046 self._refCount = 1
1047
1049 self.resumed = resumed
1050 self.closed = False
1051
1052 - def _calcPendingStates(self, cipherSuite, masterSecret,
1053 clientRandom, serverRandom, implementations):
1054 if cipherSuite in CipherSuite.aes128Suites:
1055 keyLength = 16
1056 ivLength = 16
1057 createCipherFunc = createAES
1058 elif cipherSuite in CipherSuite.aes256Suites:
1059 keyLength = 32
1060 ivLength = 16
1061 createCipherFunc = createAES
1062 elif cipherSuite in CipherSuite.rc4Suites:
1063 keyLength = 16
1064 ivLength = 0
1065 createCipherFunc = createRC4
1066 elif cipherSuite in CipherSuite.tripleDESSuites:
1067 keyLength = 24
1068 ivLength = 8
1069 createCipherFunc = createTripleDES
1070 else:
1071 raise AssertionError()
1072
1073 if cipherSuite in CipherSuite.shaSuites:
1074 macLength = 20
1075 digestmod = hashlib.sha1
1076 elif cipherSuite in CipherSuite.sha256Suites:
1077 macLength = 32
1078 digestmod = hashlib.sha256
1079 elif cipherSuite in CipherSuite.md5Suites:
1080 macLength = 16
1081 digestmod = hashlib.md5
1082
1083 if self.version == (3,0):
1084 createMACFunc = createMAC_SSL
1085 elif self.version in ((3,1), (3,2), (3,3)):
1086 createMACFunc = createHMAC
1087
1088 outputLength = (macLength*2) + (keyLength*2) + (ivLength*2)
1089
1090
1091 if self.version == (3,0):
1092 keyBlock = PRF_SSL(masterSecret,
1093 serverRandom + clientRandom,
1094 outputLength)
1095 elif self.version in ((3,1), (3,2)):
1096 keyBlock = PRF(masterSecret,
1097 b"key expansion",
1098 serverRandom + clientRandom,
1099 outputLength)
1100 elif self.version == (3,3):
1101 keyBlock = PRF_1_2(masterSecret,
1102 b"key expansion",
1103 serverRandom + clientRandom,
1104 outputLength)
1105 else:
1106 raise AssertionError()
1107
1108
1109 clientPendingState = _ConnectionState()
1110 serverPendingState = _ConnectionState()
1111 p = Parser(keyBlock)
1112 clientMACBlock = p.getFixBytes(macLength)
1113 serverMACBlock = p.getFixBytes(macLength)
1114 clientKeyBlock = p.getFixBytes(keyLength)
1115 serverKeyBlock = p.getFixBytes(keyLength)
1116 clientIVBlock = p.getFixBytes(ivLength)
1117 serverIVBlock = p.getFixBytes(ivLength)
1118 clientPendingState.macContext = createMACFunc(
1119 compatHMAC(clientMACBlock), digestmod=digestmod)
1120 serverPendingState.macContext = createMACFunc(
1121 compatHMAC(serverMACBlock), digestmod=digestmod)
1122 clientPendingState.encContext = createCipherFunc(clientKeyBlock,
1123 clientIVBlock,
1124 implementations)
1125 serverPendingState.encContext = createCipherFunc(serverKeyBlock,
1126 serverIVBlock,
1127 implementations)
1128
1129
1130 if self._client:
1131 self._pendingWriteState = clientPendingState
1132 self._pendingReadState = serverPendingState
1133 else:
1134 self._pendingWriteState = serverPendingState
1135 self._pendingReadState = clientPendingState
1136
1137 if self.version >= (3,2) and ivLength:
1138
1139
1140 self.fixedIVBlock = getRandomBytes(ivLength)
1141
1143 self._writeState = self._pendingWriteState
1144 self._pendingWriteState = _ConnectionState()
1145
1147 self._readState = self._pendingReadState
1148 self._pendingReadState = _ConnectionState()
1149
1150
1152 imac_md5 = self._handshake_md5.copy()
1153 imac_sha = self._handshake_sha.copy()
1154
1155 imac_md5.update(compatHMAC(label + masterSecret + bytearray([0x36]*48)))
1156 imac_sha.update(compatHMAC(label + masterSecret + bytearray([0x36]*40)))
1157
1158 md5Bytes = MD5(masterSecret + bytearray([0x5c]*48) + \
1159 bytearray(imac_md5.digest()))
1160 shaBytes = SHA1(masterSecret + bytearray([0x5c]*40) + \
1161 bytearray(imac_sha.digest()))
1162
1163 return md5Bytes + shaBytes
1164