1
2
3
4
5
6
7
8
9
10
11 """Helper class for TLSConnection."""
12 from __future__ import generators
13
14 import io
15 import socket
16
17 from .utils.compat import *
18 from .utils.cryptomath import *
19 from .utils.codec import Parser
20 from .errors import *
21 from .messages import *
22 from .mathtls import *
23 from .constants import *
24 from .recordlayer import RecordLayer
25 from .defragmenter import Defragmenter
26 from .handshakehashes import HandshakeHashes
27 from .bufferedsocket import BufferedSocket
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
153
154 @property
156 """Boolean stating if the endpoint acts as a client"""
157 return self._recordLayer.client
158
159 @_client.setter
161 """Set the endpoint to act as a client or not"""
162 self._recordLayer.client = value
163
164 @property
166 """Get the SSL protocol version of connection"""
167 return self._recordLayer.version
168
169 @version.setter
171 """
172 Set the SSL protocol version of connection
173
174 The setter is a public method only for backwards compatibility.
175 Don't use it! See at HandshakeSettings for options to set desired
176 protocol version.
177 """
178 self._recordLayer.version = value
179
180 @property
182 """Whether the connection uses Encrypt Then MAC (RFC 7366)"""
183 return self._recordLayer.encryptThenMAC
184
186 self._readBuffer = b''
187
189 self._send_writer = None
190
191
192
193
194
195
196 - def read(self, max=None, min=1):
197 """Read some data from the TLS connection.
198
199 This function will block until at least 'min' bytes are
200 available (or the connection is closed).
201
202 If an exception is raised, the connection will have been
203 automatically closed.
204
205 @type max: int
206 @param max: The maximum number of bytes to return.
207
208 @type min: int
209 @param min: The minimum number of bytes to return
210
211 @rtype: str
212 @return: A string of no more than 'max' bytes, and no fewer
213 than 'min' (unless the connection has been closed, in which
214 case fewer than 'min' bytes may be returned).
215
216 @raise socket.error: If a socket error occurs.
217 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
218 without a preceding alert.
219 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
220 """
221 for result in self.readAsync(max, min):
222 pass
223 return result
224
226 """Start a read operation on the TLS connection.
227
228 This function returns a generator which behaves similarly to
229 read(). Successive invocations of the generator will return 0
230 if it is waiting to read from the socket, 1 if it is waiting
231 to write to the socket, or a string if the read operation has
232 completed.
233
234 @rtype: iterable
235 @return: A generator; see above for details.
236 """
237 try:
238 while len(self._readBuffer)<min and not self.closed:
239 try:
240 for result in self._getMsg(ContentType.application_data):
241 if result in (0,1):
242 yield result
243 applicationData = result
244 self._readBuffer += applicationData.write()
245 except TLSRemoteAlert as alert:
246 if alert.description != AlertDescription.close_notify:
247 raise
248 except TLSAbruptCloseError:
249 if not self.ignoreAbruptClose:
250 raise
251 else:
252 self._shutdown(True)
253
254 if max == None:
255 max = len(self._readBuffer)
256
257 returnBytes = self._readBuffer[:max]
258 self._readBuffer = self._readBuffer[max:]
259 yield bytes(returnBytes)
260 except GeneratorExit:
261 raise
262 except:
263 self._shutdown(False)
264 raise
265
267 """Add bytes to the front of the socket read buffer for future
268 reading. Be careful using this in the context of select(...): if you
269 unread the last data from a socket, that won't wake up selected waiters,
270 and those waiters may hang forever.
271 """
272 self._readBuffer = b + self._readBuffer
273
275 """Write some data to the TLS connection.
276
277 This function will block until all the data has been sent.
278
279 If an exception is raised, the connection will have been
280 automatically closed.
281
282 @type s: str
283 @param s: The data to transmit to the other party.
284
285 @raise socket.error: If a socket error occurs.
286 """
287 for result in self.writeAsync(s):
288 pass
289
291 """Start a write operation on the TLS connection.
292
293 This function returns a generator which behaves similarly to
294 write(). Successive invocations of the generator will return
295 1 if it is waiting to write to the socket, or will raise
296 StopIteration if the write operation has completed.
297
298 @rtype: iterable
299 @return: A generator; see above for details.
300 """
301 try:
302 if self.closed:
303 raise TLSClosedConnectionError("attempt to write to closed connection")
304
305 applicationData = ApplicationData().create(bytearray(s))
306 for result in self._sendMsg(applicationData, \
307 randomizeFirstBlock=True):
308 yield result
309 except GeneratorExit:
310 raise
311 except Exception:
312
313
314 self._shutdown(self.ignoreAbruptClose)
315 raise
316
318 """Close the TLS connection.
319
320 This function will block until it has exchanged close_notify
321 alerts with the other party. After doing so, it will shut down the
322 TLS connection. Further attempts to read through this connection
323 will return "". Further attempts to write through this connection
324 will raise ValueError.
325
326 If makefile() has been called on this connection, the connection
327 will be not be closed until the connection object and all file
328 objects have been closed.
329
330 Even if an exception is raised, the connection will have been
331 closed.
332
333 @raise socket.error: If a socket error occurs.
334 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
335 without a preceding alert.
336 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
337 """
338 if not self.closed:
339 for result in self._decrefAsync():
340 pass
341
342
343 _decref_socketios = close
344
346 """Start a close operation on the TLS connection.
347
348 This function returns a generator which behaves similarly to
349 close(). Successive invocations of the generator will return 0
350 if it is waiting to read from the socket, 1 if it is waiting
351 to write to the socket, or will raise StopIteration if the
352 close operation has completed.
353
354 @rtype: iterable
355 @return: A generator; see above for details.
356 """
357 if not self.closed:
358 for result in self._decrefAsync():
359 yield result
360
395
397 """Get the name of this TLS version.
398
399 @rtype: str
400 @return: The name of the TLS version used with this connection.
401 Either None, 'SSL 3.0', 'TLS 1.0', 'TLS 1.1', or 'TLS 1.2'.
402 """
403 if self.version == (3,0):
404 return "SSL 3.0"
405 elif self.version == (3,1):
406 return "TLS 1.0"
407 elif self.version == (3,2):
408 return "TLS 1.1"
409 elif self.version == (3,3):
410 return "TLS 1.2"
411 else:
412 return None
413
415 """Get the name of the cipher used with this connection.
416
417 @rtype: str
418 @return: The name of the cipher used with this connection.
419 Either 'aes128', 'aes256', 'rc4', or '3des'.
420 """
421 return self._recordLayer.getCipherName()
422
424 """Get the name of the cipher implementation used with
425 this connection.
426
427 @rtype: str
428 @return: The name of the cipher implementation used with
429 this connection. Either 'python', 'openssl', or 'pycrypto'.
430 """
431 return self._recordLayer.getCipherImplementation()
432
433
435 """Send data to the TLS connection (socket emulation).
436
437 @raise socket.error: If a socket error occurs.
438 """
439 self.write(s)
440 return len(s)
441
443 """Send data to the TLS connection (socket emulation).
444
445 @raise socket.error: If a socket error occurs.
446 """
447 self.write(s)
448
449 - def recv(self, bufsize):
450 """Get some data from the TLS connection (socket emulation).
451
452 @raise socket.error: If a socket error occurs.
453 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
454 without a preceding alert.
455 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
456 """
457 return self.read(bufsize)
458
460
461 data = self.read(len(b))
462 if not data:
463 return None
464 b[:len(data)] = data
465 return len(data)
466
467
468
469
470
471 - def makefile(self, mode='r', bufsize=-1):
472 """Create a file object for the TLS connection (socket emulation).
473
474 @rtype: L{socket._fileobject}
475 """
476 self._refCount += 1
477
478
479
480
481
482
483
484
485
486
487
488
489
490 if 'w' in mode and bufsize <= 0:
491 bufsize = 2**14
492
493 if sys.version_info < (3,):
494 return socket._fileobject(self, mode, bufsize, close=True)
495 else:
496 if 'w' in mode:
497 return io.BufferedWriter(socket.SocketIO(self, mode), bufsize)
498 else:
499 return socket.SocketIO(self, mode)
500
501
503 """Return the socket's own address (socket emulation)."""
504 return self.sock.getsockname()
505
507 """Return the remote address to which the socket is connected
508 (socket emulation)."""
509 return self.sock.getpeername()
510
512 """Set a timeout on blocking socket operations (socket emulation)."""
513 return self.sock.settimeout(value)
514
516 """Return the timeout associated with socket operations (socket
517 emulation)."""
518 return self.sock.gettimeout()
519
521 """Set the value of the given socket option (socket emulation)."""
522 return self.sock.setsockopt(level, optname, value)
523
525 """Shutdown the underlying socket."""
526 return self.sock.shutdown(how)
527
529 """Not implement in TLS Lite."""
530 raise NotImplementedError()
531
532
533
534
535
536
538 self._recordLayer.shutdown()
539 self.version = (0,0)
540 self.closed = True
541 if self.closeSocket:
542 self.sock.close()
543
544
545 if not resumable and self.session:
546 self.session.resumable = False
547
548
549 - def _sendError(self, alertDescription, errorStr=None):
558
560
561 self.sock.buffer_writes = True
562 randomizeFirstBlock = True
563 for msg in msgs:
564 for result in self._sendMsg(msg, randomizeFirstBlock):
565 yield result
566 randomizeFirstBlock = True
567 self.sock.flush()
568 self.sock.buffer_writes = False
569
570 - def _sendMsg(self, msg, randomizeFirstBlock = True):
571 """Fragment and send message through socket"""
572
573
574
575
576 if randomizeFirstBlock and self.version <= (3, 1) \
577 and self._recordLayer.isCBCMode() \
578 and msg.contentType == ContentType.application_data:
579 msgFirstByte = msg.splitFirstByte()
580 for result in self._sendMsgThroughSocket(msgFirstByte):
581 yield result
582 if len(msg.write()) == 0:
583 return
584
585 buf = msg.write()
586 contentType = msg.contentType
587
588 if contentType == ContentType.handshake:
589 self._handshake_hash.update(buf)
590
591
592 while len(buf) > self.recordSize:
593 newB = buf[:self.recordSize]
594 buf = buf[self.recordSize:]
595
596 msgFragment = Message(contentType, newB)
597 for result in self._sendMsgThroughSocket(msgFragment):
598 yield result
599
600 msgFragment = Message(contentType, buf)
601 for result in self._sendMsgThroughSocket(msgFragment):
602 yield result
603
605 """Send message, handle errors"""
606
607 try:
608 for result in self._recordLayer.sendRecord(msg):
609 if result in (0, 1):
610 yield result
611 except socket.error:
612
613
614
615
616
617
618
619
620
621
622 if msg.contentType == ContentType.handshake:
623
624
625
626 for result in self._getNextRecord():
627 if result in (0, 1):
628 yield result
629 else:
630 break
631
632
633 self._shutdown(False)
634
635
636 recordHeader, p = result
637 if recordHeader.type == ContentType.alert:
638 alert = Alert().parse(p)
639 raise TLSRemoteAlert(alert)
640 else:
641
642
643
644 raise
645
646 - def _getMsg(self, expectedType, secondaryType=None, constructorType=None):
647 try:
648 if not isinstance(expectedType, tuple):
649 expectedType = (expectedType,)
650
651
652
653
654
655
656 while 1:
657 for result in self._getNextRecord():
658 if result in (0,1):
659 yield result
660 else:
661 break
662 recordHeader, p = result
663
664
665 if recordHeader.type == ContentType.application_data:
666 if p.index == len(p.bytes):
667 continue
668
669
670 if recordHeader.type not in expectedType:
671
672
673 if recordHeader.type == ContentType.alert:
674 alert = Alert().parse(p)
675
676
677
678
679
680
681 if alert.level == AlertLevel.warning or \
682 alert.description == AlertDescription.close_notify:
683
684
685
686
687
688 try:
689 alertMsg = Alert()
690 alertMsg.create(AlertDescription.close_notify,
691 AlertLevel.warning)
692 for result in self._sendMsg(alertMsg):
693 yield result
694 except socket.error:
695 pass
696
697 if alert.description == \
698 AlertDescription.close_notify:
699 self._shutdown(True)
700 elif alert.level == AlertLevel.warning:
701 self._shutdown(False)
702
703 else:
704 self._shutdown(False)
705
706
707 raise TLSRemoteAlert(alert)
708
709
710 if recordHeader.type == ContentType.handshake:
711 subType = p.get(1)
712 reneg = False
713 if self._client:
714 if subType == HandshakeType.hello_request:
715 reneg = True
716 else:
717 if subType == HandshakeType.client_hello:
718 reneg = True
719
720
721 if reneg and self.session:
722 alertMsg = Alert()
723 alertMsg.create(AlertDescription.no_renegotiation,
724 AlertLevel.warning)
725 for result in self._sendMsg(alertMsg):
726 yield result
727 continue
728
729
730
731 for result in self._sendError(\
732 AlertDescription.unexpected_message,
733 "received type=%d" % recordHeader.type):
734 yield result
735
736 break
737
738
739 if recordHeader.type == ContentType.change_cipher_spec:
740 yield ChangeCipherSpec().parse(p)
741 elif recordHeader.type == ContentType.alert:
742 yield Alert().parse(p)
743 elif recordHeader.type == ContentType.application_data:
744 yield ApplicationData().parse(p)
745 elif recordHeader.type == ContentType.handshake:
746
747 if not isinstance(secondaryType, tuple):
748 secondaryType = (secondaryType,)
749
750
751 if recordHeader.ssl2:
752 subType = p.get(1)
753 if subType != HandshakeType.client_hello:
754 for result in self._sendError(\
755 AlertDescription.unexpected_message,
756 "Can only handle SSLv2 ClientHello messages"):
757 yield result
758 if HandshakeType.client_hello not in secondaryType:
759 for result in self._sendError(\
760 AlertDescription.unexpected_message):
761 yield result
762 subType = HandshakeType.client_hello
763 else:
764 subType = p.get(1)
765 if subType not in secondaryType:
766 for result in self._sendError(\
767 AlertDescription.unexpected_message,
768 "Expecting %s, got %s" % (str(secondaryType), subType)):
769 yield result
770
771
772 self._handshake_hash.update(p.bytes)
773
774
775 if subType == HandshakeType.client_hello:
776 yield ClientHello(recordHeader.ssl2).parse(p)
777 elif subType == HandshakeType.server_hello:
778 yield ServerHello().parse(p)
779 elif subType == HandshakeType.certificate:
780 yield Certificate(constructorType).parse(p)
781 elif subType == HandshakeType.certificate_request:
782 yield CertificateRequest(self.version).parse(p)
783 elif subType == HandshakeType.certificate_verify:
784 yield CertificateVerify(self.version).parse(p)
785 elif subType == HandshakeType.server_key_exchange:
786 yield ServerKeyExchange(constructorType,
787 self.version).parse(p)
788 elif subType == HandshakeType.server_hello_done:
789 yield ServerHelloDone().parse(p)
790 elif subType == HandshakeType.client_key_exchange:
791 yield ClientKeyExchange(constructorType, \
792 self.version).parse(p)
793 elif subType == HandshakeType.finished:
794 yield Finished(self.version).parse(p)
795 elif subType == HandshakeType.next_protocol:
796 yield NextProtocol().parse(p)
797 else:
798 raise AssertionError()
799
800
801 except SyntaxError as e:
802 for result in self._sendError(AlertDescription.decode_error,
803 formatExceptionTrace(e)):
804 yield result
805
806
808 """read next message from socket, defragment message"""
809
810 while True:
811
812
813
814
815
816
817
818
819
820 while True:
821
822 ret = self._defragmenter.getMessage()
823 if ret is None:
824 break
825 header = RecordHeader3().create(self.version, ret[0], 0)
826 yield header, Parser(ret[1])
827
828
829 for result in self._getNextRecordFromSocket():
830 if result in (0, 1):
831 yield result
832 else:
833 break
834
835 header, parser = result
836
837
838 if header.type == ContentType.application_data:
839 yield (header, parser)
840
841
842 elif header.ssl2:
843 yield (header, parser)
844 else:
845
846 self._defragmenter.addData(header.type, parser.bytes)
847
894
896 if not self.closed:
897 raise ValueError("Renegotiation disallowed for security reasons")
898 self._client = client
899 self._handshake_hash = HandshakeHashes()
900 self._certificate_verify_handshake_hash = None
901 self._defragmenter.clearBuffers()
902 self.allegedSrpUsername = None
903 self._refCount = 1
904
906 self.resumed = resumed
907 self.closed = False
908
909 - def _calcPendingStates(self, cipherSuite, masterSecret,
910 clientRandom, serverRandom, implementations):
911 self._recordLayer.calcPendingStates(cipherSuite, masterSecret,
912 clientRandom, serverRandom,
913 implementations)
914
917
920