1
2
3
4
5
6
7
8
9
10
11 """Helper class for TLSConnection."""
12 from __future__ import generators
13
14 from .utils.compat import *
15 from .utils.cryptomath import *
16 from .utils.codec import Parser
17 from .errors import *
18 from .messages import *
19 from .mathtls import *
20 from .constants import *
21 from .recordlayer import RecordLayer
22 from .defragmenter import Defragmenter
23 from .handshakehashes import HandshakeHashes
24 from .bufferedsocket import BufferedSocket
25
26 import socket
27 import traceback
30 """
31 This class handles data transmission for a TLS connection.
32
33 Its only subclass is L{tlslite.TLSConnection.TLSConnection}. We've
34 separated the code in this class from TLSConnection to make things
35 more readable.
36
37
38 @type sock: socket.socket
39 @ivar sock: The underlying socket object.
40
41 @type session: L{tlslite.Session.Session}
42 @ivar session: The session corresponding to this connection.
43
44 Due to TLS session resumption, multiple connections can correspond
45 to the same underlying session.
46
47 @type version: tuple
48 @ivar version: The TLS version being used for this connection.
49
50 (3,0) means SSL 3.0, and (3,1) means TLS 1.0.
51
52 @type closed: bool
53 @ivar closed: If this connection is closed.
54
55 @type resumed: bool
56 @ivar resumed: If this connection is based on a resumed session.
57
58 @type allegedSrpUsername: str or None
59 @ivar allegedSrpUsername: This is set to the SRP username
60 asserted by the client, whether the handshake succeeded or not.
61 If the handshake fails, this can be inspected to determine
62 if a guessing attack is in progress against a particular user
63 account.
64
65 @type closeSocket: bool
66 @ivar closeSocket: If the socket should be closed when the
67 connection is closed, defaults to True (writable).
68
69 If you set this to True, TLS Lite will assume the responsibility of
70 closing the socket when the TLS Connection is shutdown (either
71 through an error or through the user calling close()). The default
72 is False.
73
74 @type ignoreAbruptClose: bool
75 @ivar ignoreAbruptClose: If an abrupt close of the socket should
76 raise an error (writable).
77
78 If you set this to True, TLS Lite will not raise a
79 L{tlslite.errors.TLSAbruptCloseError} exception if the underlying
80 socket is unexpectedly closed. Such an unexpected closure could be
81 caused by an attacker. However, it also occurs with some incorrect
82 TLS implementations.
83
84 You should set this to True only if you're not worried about an
85 attacker truncating the connection, and only if necessary to avoid
86 spurious errors. The default is False.
87
88 @type encryptThenMAC: bool
89 @ivar encryptThenMAC: Whether the connection uses the encrypt-then-MAC
90 construct for CBC cipher suites, will be False also if connection uses
91 RC4 or AEAD.
92
93 @type recordSize: int
94 @ivar recordSize: maimum size of data to be sent in a single record layer
95 message. Note that after encryption is established (generally after
96 handshake protocol has finished) the actual amount of data written to
97 network socket will be larger because of the record layer header, padding
98 or encryption overhead. It can be set to low value (so that there is no
99 fragmentation on Ethernet, IP and TCP level) at the beginning of
100 connection to reduce latency and set to protocol max (2**14) to maximise
101 throughput after sending few kiB of data. Setting to values greater than
102 2**14 will cause the connection to be dropped by RFC compliant peers.
103
104 @sort: __init__, read, readAsync, write, writeAsync, close, closeAsync,
105 getCipherImplementation, getCipherName
106 """
107
149
150 @property
152 """Boolean stating if the endpoint acts as a client"""
153 return self._recordLayer.client
154
155 @_client.setter
157 """Set the endpoint to act as a client or not"""
158 self._recordLayer.client = value
159
160 @property
162 """Get the SSL protocol version of connection"""
163 return self._recordLayer.version
164
165 @version.setter
167 """
168 Set the SSL protocol version of connection
169
170 The setter is a public method only for backwards compatibility.
171 Don't use it! See at HandshakeSettings for options to set desired
172 protocol version.
173 """
174 self._recordLayer.version = value
175
176 @property
178 """Whether the connection uses Encrypt Then MAC (RFC 7366)"""
179 return self._recordLayer.encryptThenMAC
180
182 self._readBuffer = b''
183
185 self._send_writer = None
186
187
188
189
190
191
192 - def read(self, max=None, min=1):
193 """Read some data from the TLS connection.
194
195 This function will block until at least 'min' bytes are
196 available (or the connection is closed).
197
198 If an exception is raised, the connection will have been
199 automatically closed.
200
201 @type max: int
202 @param max: The maximum number of bytes to return.
203
204 @type min: int
205 @param min: The minimum number of bytes to return
206
207 @rtype: str
208 @return: A string of no more than 'max' bytes, and no fewer
209 than 'min' (unless the connection has been closed, in which
210 case fewer than 'min' bytes may be returned).
211
212 @raise socket.error: If a socket error occurs.
213 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
214 without a preceding alert.
215 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
216 """
217 for result in self.readAsync(max, min):
218 pass
219 return result
220
222 """Start a read operation on the TLS connection.
223
224 This function returns a generator which behaves similarly to
225 read(). Successive invocations of the generator will return 0
226 if it is waiting to read from the socket, 1 if it is waiting
227 to write to the socket, or a string if the read operation has
228 completed.
229
230 @rtype: iterable
231 @return: A generator; see above for details.
232 """
233 try:
234 while len(self._readBuffer)<min and not self.closed:
235 try:
236 for result in self._getMsg(ContentType.application_data):
237 if result in (0,1):
238 yield result
239 applicationData = result
240 self._readBuffer += applicationData.write()
241 except TLSRemoteAlert as alert:
242 if alert.description != AlertDescription.close_notify:
243 raise
244 except TLSAbruptCloseError:
245 if not self.ignoreAbruptClose:
246 raise
247 else:
248 self._shutdown(True)
249
250 if max == None:
251 max = len(self._readBuffer)
252
253 returnBytes = self._readBuffer[:max]
254 self._readBuffer = self._readBuffer[max:]
255 yield bytes(returnBytes)
256 except GeneratorExit:
257 raise
258 except:
259 self._shutdown(False)
260 raise
261
263 """Add bytes to the front of the socket read buffer for future
264 reading. Be careful using this in the context of select(...): if you
265 unread the last data from a socket, that won't wake up selected waiters,
266 and those waiters may hang forever.
267 """
268 self._readBuffer = b + self._readBuffer
269
271 """Write some data to the TLS connection.
272
273 This function will block until all the data has been sent.
274
275 If an exception is raised, the connection will have been
276 automatically closed.
277
278 @type s: str
279 @param s: The data to transmit to the other party.
280
281 @raise socket.error: If a socket error occurs.
282 """
283 for result in self.writeAsync(s):
284 pass
285
287 """Start a write operation on the TLS connection.
288
289 This function returns a generator which behaves similarly to
290 write(). Successive invocations of the generator will return
291 1 if it is waiting to write to the socket, or will raise
292 StopIteration if the write operation has completed.
293
294 @rtype: iterable
295 @return: A generator; see above for details.
296 """
297 try:
298 if self.closed:
299 raise TLSClosedConnectionError("attempt to write to closed connection")
300
301 applicationData = ApplicationData().create(bytearray(s))
302 for result in self._sendMsg(applicationData, \
303 randomizeFirstBlock=True):
304 yield result
305 except GeneratorExit:
306 raise
307 except Exception:
308
309
310 self._shutdown(self.ignoreAbruptClose)
311 raise
312
314 """Close the TLS connection.
315
316 This function will block until it has exchanged close_notify
317 alerts with the other party. After doing so, it will shut down the
318 TLS connection. Further attempts to read through this connection
319 will return "". Further attempts to write through this connection
320 will raise ValueError.
321
322 If makefile() has been called on this connection, the connection
323 will be not be closed until the connection object and all file
324 objects have been closed.
325
326 Even if an exception is raised, the connection will have been
327 closed.
328
329 @raise socket.error: If a socket error occurs.
330 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
331 without a preceding alert.
332 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
333 """
334 if not self.closed:
335 for result in self._decrefAsync():
336 pass
337
338
339 _decref_socketios = close
340
342 """Start a close operation on the TLS connection.
343
344 This function returns a generator which behaves similarly to
345 close(). Successive invocations of the generator will return 0
346 if it is waiting to read from the socket, 1 if it is waiting
347 to write to the socket, or will raise StopIteration if the
348 close operation has completed.
349
350 @rtype: iterable
351 @return: A generator; see above for details.
352 """
353 if not self.closed:
354 for result in self._decrefAsync():
355 yield result
356
391
393 """Get the name of this TLS version.
394
395 @rtype: str
396 @return: The name of the TLS version used with this connection.
397 Either None, 'SSL 3.0', 'TLS 1.0', 'TLS 1.1', or 'TLS 1.2'.
398 """
399 if self.version == (3,0):
400 return "SSL 3.0"
401 elif self.version == (3,1):
402 return "TLS 1.0"
403 elif self.version == (3,2):
404 return "TLS 1.1"
405 elif self.version == (3,3):
406 return "TLS 1.2"
407 else:
408 return None
409
411 """Get the name of the cipher used with this connection.
412
413 @rtype: str
414 @return: The name of the cipher used with this connection.
415 Either 'aes128', 'aes256', 'rc4', or '3des'.
416 """
417 return self._recordLayer.getCipherName()
418
420 """Get the name of the cipher implementation used with
421 this connection.
422
423 @rtype: str
424 @return: The name of the cipher implementation used with
425 this connection. Either 'python', 'openssl', or 'pycrypto'.
426 """
427 return self._recordLayer.getCipherImplementation()
428
429
431 """Send data to the TLS connection (socket emulation).
432
433 @raise socket.error: If a socket error occurs.
434 """
435 self.write(s)
436 return len(s)
437
439 """Send data to the TLS connection (socket emulation).
440
441 @raise socket.error: If a socket error occurs.
442 """
443 self.write(s)
444
445 - def recv(self, bufsize):
446 """Get some data from the TLS connection (socket emulation).
447
448 @raise socket.error: If a socket error occurs.
449 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
450 without a preceding alert.
451 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
452 """
453 return self.read(bufsize)
454
456
457 data = self.read(len(b))
458 if not data:
459 return None
460 b[:len(data)] = data
461 return len(data)
462
463 - def makefile(self, mode='r', bufsize=-1):
464 """Create a file object for the TLS connection (socket emulation).
465
466 @rtype: L{socket._fileobject}
467 """
468 self._refCount += 1
469
470
471
472
473
474
475
476
477
478
479 if sys.version_info < (3,):
480 return socket._fileobject(self, mode, bufsize, close=True)
481 else:
482
483 return socket.SocketIO(self, mode)
484
486 """Return the socket's own address (socket emulation)."""
487 return self.sock.getsockname()
488
490 """Return the remote address to which the socket is connected
491 (socket emulation)."""
492 return self.sock.getpeername()
493
495 """Set a timeout on blocking socket operations (socket emulation)."""
496 return self.sock.settimeout(value)
497
499 """Return the timeout associated with socket operations (socket
500 emulation)."""
501 return self.sock.gettimeout()
502
504 """Set the value of the given socket option (socket emulation)."""
505 return self.sock.setsockopt(level, optname, value)
506
508 """Shutdown the underlying socket."""
509 return self.sock.shutdown(how)
510
512 """Not implement in TLS Lite."""
513 raise NotImplementedError()
514
515
516
517
518
519
521 self._recordLayer.shutdown()
522 self.version = (0,0)
523 self.closed = True
524 if self.closeSocket:
525 self.sock.close()
526
527
528 if not resumable and self.session:
529 self.session.resumable = False
530
531
532 - def _sendError(self, alertDescription, errorStr=None):
541
543
544 self.sock.buffer_writes = True
545 randomizeFirstBlock = True
546 for msg in msgs:
547 for result in self._sendMsg(msg, randomizeFirstBlock):
548 yield result
549 randomizeFirstBlock = True
550 self.sock.flush()
551 self.sock.buffer_writes = False
552
553 - def _sendMsg(self, msg, randomizeFirstBlock = True):
554 """Fragment and send message through socket"""
555
556
557
558
559 if randomizeFirstBlock and self.version <= (3, 1) \
560 and self._recordLayer.isCBCMode() \
561 and msg.contentType == ContentType.application_data:
562 msgFirstByte = msg.splitFirstByte()
563 for result in self._sendMsgThroughSocket(msgFirstByte):
564 yield result
565 if len(msg.write()) == 0:
566 return
567
568 buf = msg.write()
569 contentType = msg.contentType
570
571 if contentType == ContentType.handshake:
572 self._handshake_hash.update(buf)
573
574
575 while len(buf) > self.recordSize:
576 newB = buf[:self.recordSize]
577 buf = buf[self.recordSize:]
578
579 msgFragment = Message(contentType, newB)
580 for result in self._sendMsgThroughSocket(msgFragment):
581 yield result
582
583 msgFragment = Message(contentType, buf)
584 for result in self._sendMsgThroughSocket(msgFragment):
585 yield result
586
588 """Send message, handle errors"""
589
590 try:
591 for result in self._recordLayer.sendRecord(msg):
592 if result in (0, 1):
593 yield result
594 except socket.error:
595
596
597
598
599
600
601
602
603
604
605 if msg.contentType == ContentType.handshake:
606
607
608
609 for result in self._getNextRecord():
610 if result in (0, 1):
611 yield result
612 else:
613 break
614
615
616 self._shutdown(False)
617
618
619 recordHeader, p = result
620 if recordHeader.type == ContentType.alert:
621 alert = Alert().parse(p)
622 raise TLSRemoteAlert(alert)
623 else:
624
625
626
627 raise
628
629 - def _getMsg(self, expectedType, secondaryType=None, constructorType=None):
630 try:
631 if not isinstance(expectedType, tuple):
632 expectedType = (expectedType,)
633
634
635
636
637
638
639 while 1:
640 for result in self._getNextRecord():
641 if result in (0,1):
642 yield result
643 else:
644 break
645 recordHeader, p = result
646
647
648 if recordHeader.type == ContentType.application_data:
649 if p.index == len(p.bytes):
650 continue
651
652
653 if recordHeader.type not in expectedType:
654
655
656 if recordHeader.type == ContentType.alert:
657 alert = Alert().parse(p)
658
659
660
661
662
663
664 if alert.level == AlertLevel.warning or \
665 alert.description == AlertDescription.close_notify:
666
667
668
669
670
671 try:
672 alertMsg = Alert()
673 alertMsg.create(AlertDescription.close_notify,
674 AlertLevel.warning)
675 for result in self._sendMsg(alertMsg):
676 yield result
677 except socket.error:
678 pass
679
680 if alert.description == \
681 AlertDescription.close_notify:
682 self._shutdown(True)
683 elif alert.level == AlertLevel.warning:
684 self._shutdown(False)
685
686 else:
687 self._shutdown(False)
688
689
690 raise TLSRemoteAlert(alert)
691
692
693 if recordHeader.type == ContentType.handshake:
694 subType = p.get(1)
695 reneg = False
696 if self._client:
697 if subType == HandshakeType.hello_request:
698 reneg = True
699 else:
700 if subType == HandshakeType.client_hello:
701 reneg = True
702
703 if reneg:
704 alertMsg = Alert()
705 alertMsg.create(AlertDescription.no_renegotiation,
706 AlertLevel.warning)
707 for result in self._sendMsg(alertMsg):
708 yield result
709 continue
710
711
712
713 for result in self._sendError(\
714 AlertDescription.unexpected_message,
715 "received type=%d" % recordHeader.type):
716 yield result
717
718 break
719
720
721 if recordHeader.type == ContentType.change_cipher_spec:
722 yield ChangeCipherSpec().parse(p)
723 elif recordHeader.type == ContentType.alert:
724 yield Alert().parse(p)
725 elif recordHeader.type == ContentType.application_data:
726 yield ApplicationData().parse(p)
727 elif recordHeader.type == ContentType.handshake:
728
729 if not isinstance(secondaryType, tuple):
730 secondaryType = (secondaryType,)
731
732
733 if recordHeader.ssl2:
734 subType = p.get(1)
735 if subType != HandshakeType.client_hello:
736 for result in self._sendError(\
737 AlertDescription.unexpected_message,
738 "Can only handle SSLv2 ClientHello messages"):
739 yield result
740 if HandshakeType.client_hello not in secondaryType:
741 for result in self._sendError(\
742 AlertDescription.unexpected_message):
743 yield result
744 subType = HandshakeType.client_hello
745 else:
746 subType = p.get(1)
747 if subType not in secondaryType:
748 for result in self._sendError(\
749 AlertDescription.unexpected_message,
750 "Expecting %s, got %s" % (str(secondaryType), subType)):
751 yield result
752
753
754 self._handshake_hash.update(p.bytes)
755
756
757 if subType == HandshakeType.client_hello:
758 yield ClientHello(recordHeader.ssl2).parse(p)
759 elif subType == HandshakeType.server_hello:
760 yield ServerHello().parse(p)
761 elif subType == HandshakeType.certificate:
762 yield Certificate(constructorType).parse(p)
763 elif subType == HandshakeType.certificate_request:
764 yield CertificateRequest(self.version).parse(p)
765 elif subType == HandshakeType.certificate_verify:
766 yield CertificateVerify(self.version).parse(p)
767 elif subType == HandshakeType.server_key_exchange:
768 yield ServerKeyExchange(constructorType,
769 self.version).parse(p)
770 elif subType == HandshakeType.server_hello_done:
771 yield ServerHelloDone().parse(p)
772 elif subType == HandshakeType.client_key_exchange:
773 yield ClientKeyExchange(constructorType, \
774 self.version).parse(p)
775 elif subType == HandshakeType.finished:
776 yield Finished(self.version).parse(p)
777 elif subType == HandshakeType.next_protocol:
778 yield NextProtocol().parse(p)
779 else:
780 raise AssertionError()
781
782
783 except SyntaxError as e:
784 for result in self._sendError(AlertDescription.decode_error,
785 formatExceptionTrace(e)):
786 yield result
787
788
790 """read next message from socket, defragment message"""
791
792 while True:
793
794
795
796
797
798
799
800
801
802 while True:
803
804 ret = self._defragmenter.getMessage()
805 if ret is None:
806 break
807 header = RecordHeader3().create(self.version, ret[0], 0)
808 yield header, Parser(ret[1])
809
810
811 for result in self._getNextRecordFromSocket():
812 if result in (0, 1):
813 yield result
814 else:
815 break
816
817 header, parser = result
818
819
820 if header.type == ContentType.application_data:
821 yield (header, parser)
822
823
824 elif header.ssl2:
825 yield (header, parser)
826 else:
827
828 self._defragmenter.addData(header.type, parser.bytes)
829
876
878 if not self.closed:
879 raise ValueError("Renegotiation disallowed for security reasons")
880 self._client = client
881 self._handshake_hash = HandshakeHashes()
882 self._defragmenter.clearBuffers()
883 self.allegedSrpUsername = None
884 self._refCount = 1
885
887 self.resumed = resumed
888 self.closed = False
889
890 - def _calcPendingStates(self, cipherSuite, masterSecret,
891 clientRandom, serverRandom, implementations):
892 self._recordLayer.calcPendingStates(cipherSuite, masterSecret,
893 clientRandom, serverRandom,
894 implementations)
895
898
901