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