Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(696)

Side by Side Diff: third_party/tlslite/tlslite/tlsrecordlayer.py

Issue 210323002: Update tlslite to 0.4.6. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rietveld, please behave Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 # Authors:
2 # Trevor Perrin
3 # Google (adapted by Sam Rushing) - NPN support
4 # Martin von Loewis - python 3 port
5 #
6 # See the LICENSE file for legal information regarding use of this file.
7
1 """Helper class for TLSConnection.""" 8 """Helper class for TLSConnection."""
2 from __future__ import generators 9 from __future__ import generators
3 10
4 from utils.compat import * 11 from .utils.compat import *
5 from utils.cryptomath import * 12 from .utils.cryptomath import *
6 from utils.cipherfactory import createAES, createRC4, createTripleDES 13 from .utils.cipherfactory import createAES, createRC4, createTripleDES
7 from utils.codec import * 14 from .utils.codec import *
8 from errors import * 15 from .errors import *
9 from messages import * 16 from .messages import *
10 from mathtls import * 17 from .mathtls import *
11 from constants import * 18 from .constants import *
12 from utils.cryptomath import getRandomBytes 19 from .utils.cryptomath import getRandomBytes
13 from utils import hmac
14 from fileobject import FileObject
15
16 # The sha module is deprecated in Python 2.6
17 try:
18 import sha
19 except ImportError:
20 from hashlib import sha1 as sha
21
22 # The md5 module is deprecated in Python 2.6
23 try:
24 import md5
25 except ImportError:
26 from hashlib import md5
27 20
28 import socket 21 import socket
29 import errno 22 import errno
30 import traceback 23 import traceback
31 24
32 class _ConnectionState: 25 class _ConnectionState(object):
33 def __init__(self): 26 def __init__(self):
34 self.macContext = None 27 self.macContext = None
35 self.encContext = None 28 self.encContext = None
36 self.seqnum = 0 29 self.seqnum = 0
37 30
38 def getSeqNumStr(self): 31 def getSeqNumBytes(self):
39 w = Writer(8) 32 w = Writer()
40 w.add(self.seqnum, 8) 33 w.add(self.seqnum, 8)
41 seqnumStr = bytesToString(w.bytes)
42 self.seqnum += 1 34 self.seqnum += 1
43 return seqnumStr 35 return w.bytes
44 36
45 37
46 class TLSRecordLayer: 38 class TLSRecordLayer(object):
47 """ 39 """
48 This class handles data transmission for a TLS connection. 40 This class handles data transmission for a TLS connection.
49 41
50 Its only subclass is L{tlslite.TLSConnection.TLSConnection}. We've 42 Its only subclass is L{tlslite.TLSConnection.TLSConnection}. We've
51 separated the code in this class from TLSConnection to make things 43 separated the code in this class from TLSConnection to make things
52 more readable. 44 more readable.
53 45
54 46
55 @type sock: socket.socket 47 @type sock: socket.socket
56 @ivar sock: The underlying socket object. 48 @ivar sock: The underlying socket object.
57 49
58 @type session: L{tlslite.Session.Session} 50 @type session: L{tlslite.Session.Session}
59 @ivar session: The session corresponding to this connection. 51 @ivar session: The session corresponding to this connection.
60 52
61 Due to TLS session resumption, multiple connections can correspond 53 Due to TLS session resumption, multiple connections can correspond
62 to the same underlying session. 54 to the same underlying session.
63 55
64 @type version: tuple 56 @type version: tuple
65 @ivar version: The TLS version being used for this connection. 57 @ivar version: The TLS version being used for this connection.
66 58
67 (3,0) means SSL 3.0, and (3,1) means TLS 1.0. 59 (3,0) means SSL 3.0, and (3,1) means TLS 1.0.
68 60
69 @type closed: bool 61 @type closed: bool
70 @ivar closed: If this connection is closed. 62 @ivar closed: If this connection is closed.
71 63
72 @type resumed: bool 64 @type resumed: bool
73 @ivar resumed: If this connection is based on a resumed session. 65 @ivar resumed: If this connection is based on a resumed session.
74 66
75 @type allegedSharedKeyUsername: str or None
76 @ivar allegedSharedKeyUsername: This is set to the shared-key
77 username asserted by the client, whether the handshake succeeded or
78 not. If the handshake fails, this can be inspected to
79 determine if a guessing attack is in progress against a particular
80 user account.
81
82 @type allegedSrpUsername: str or None 67 @type allegedSrpUsername: str or None
83 @ivar allegedSrpUsername: This is set to the SRP username 68 @ivar allegedSrpUsername: This is set to the SRP username
84 asserted by the client, whether the handshake succeeded or not. 69 asserted by the client, whether the handshake succeeded or not.
85 If the handshake fails, this can be inspected to determine 70 If the handshake fails, this can be inspected to determine
86 if a guessing attack is in progress against a particular user 71 if a guessing attack is in progress against a particular user
87 account. 72 account.
88 73
89 @type closeSocket: bool 74 @type closeSocket: bool
90 @ivar closeSocket: If the socket should be closed when the 75 @ivar closeSocket: If the socket should be closed when the
91 connection is closed (writable). 76 connection is closed, defaults to True (writable).
92 77
93 If you set this to True, TLS Lite will assume the responsibility of 78 If you set this to True, TLS Lite will assume the responsibility of
94 closing the socket when the TLS Connection is shutdown (either 79 closing the socket when the TLS Connection is shutdown (either
95 through an error or through the user calling close()). The default 80 through an error or through the user calling close()). The default
96 is False. 81 is False.
97 82
98 @type ignoreAbruptClose: bool 83 @type ignoreAbruptClose: bool
99 @ivar ignoreAbruptClose: If an abrupt close of the socket should 84 @ivar ignoreAbruptClose: If an abrupt close of the socket should
100 raise an error (writable). 85 raise an error (writable).
101 86
(...skipping 15 matching lines...) Expand all
117 self.sock = sock 102 self.sock = sock
118 103
119 #My session object (Session instance; read-only) 104 #My session object (Session instance; read-only)
120 self.session = None 105 self.session = None
121 106
122 #Am I a client or server? 107 #Am I a client or server?
123 self._client = None 108 self._client = None
124 109
125 #Buffers for processing messages 110 #Buffers for processing messages
126 self._handshakeBuffer = [] 111 self._handshakeBuffer = []
127 self._readBuffer = "" 112 self.clearReadBuffer()
113 self.clearWriteBuffer()
128 114
129 #Handshake digests 115 #Handshake digests
130 self._handshake_md5 = md5.md5() 116 self._handshake_md5 = hashlib.md5()
131 self._handshake_sha = sha.sha() 117 self._handshake_sha = hashlib.sha1()
132 118
133 #TLS Protocol Version 119 #TLS Protocol Version
134 self.version = (0,0) #read-only 120 self.version = (0,0) #read-only
135 self._versionCheck = False #Once we choose a version, this is True 121 self._versionCheck = False #Once we choose a version, this is True
136 122
137 #Current and Pending connection states 123 #Current and Pending connection states
138 self._writeState = _ConnectionState() 124 self._writeState = _ConnectionState()
139 self._readState = _ConnectionState() 125 self._readState = _ConnectionState()
140 self._pendingWriteState = _ConnectionState() 126 self._pendingWriteState = _ConnectionState()
141 self._pendingReadState = _ConnectionState() 127 self._pendingReadState = _ConnectionState()
142 128
143 #Is the connection open? 129 #Is the connection open?
144 self.closed = True #read-only 130 self.closed = True #read-only
145 self._refCount = 0 #Used to trigger closure 131 self._refCount = 0 #Used to trigger closure
146 132
147 #Is this a resumed (or shared-key) session? 133 #Is this a resumed session?
148 self.resumed = False #read-only 134 self.resumed = False #read-only
149 135
150 #What username did the client claim in his handshake? 136 #What username did the client claim in his handshake?
151 self.allegedSharedKeyUsername = None
152 self.allegedSrpUsername = None 137 self.allegedSrpUsername = None
153 138
154 #On a call to close(), do we close the socket? (writeable) 139 #On a call to close(), do we close the socket? (writeable)
155 self.closeSocket = False 140 self.closeSocket = True
156 141
157 #If the socket is abruptly closed, do we ignore it 142 #If the socket is abruptly closed, do we ignore it
158 #and pretend the connection was shut down properly? (writeable) 143 #and pretend the connection was shut down properly? (writeable)
159 self.ignoreAbruptClose = False 144 self.ignoreAbruptClose = False
160 145
161 #Fault we will induce, for testing purposes 146 #Fault we will induce, for testing purposes
162 self.fault = None 147 self.fault = None
163 148
149 def clearReadBuffer(self):
150 self._readBuffer = b''
151
152 def clearWriteBuffer(self):
153 self._send_writer = None
154
155
164 #********************************************************* 156 #*********************************************************
165 # Public Functions START 157 # Public Functions START
166 #********************************************************* 158 #*********************************************************
167 159
168 def read(self, max=None, min=1): 160 def read(self, max=None, min=1):
169 """Read some data from the TLS connection. 161 """Read some data from the TLS connection.
170 162
171 This function will block until at least 'min' bytes are 163 This function will block until at least 'min' bytes are
172 available (or the connection is closed). 164 available (or the connection is closed).
173 165
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 @rtype: iterable 198 @rtype: iterable
207 @return: A generator; see above for details. 199 @return: A generator; see above for details.
208 """ 200 """
209 try: 201 try:
210 while len(self._readBuffer)<min and not self.closed: 202 while len(self._readBuffer)<min and not self.closed:
211 try: 203 try:
212 for result in self._getMsg(ContentType.application_data): 204 for result in self._getMsg(ContentType.application_data):
213 if result in (0,1): 205 if result in (0,1):
214 yield result 206 yield result
215 applicationData = result 207 applicationData = result
216 self._readBuffer += bytesToString(applicationData.write()) 208 self._readBuffer += applicationData.write()
217 except TLSRemoteAlert, alert: 209 except TLSRemoteAlert as alert:
218 if alert.description != AlertDescription.close_notify: 210 if alert.description != AlertDescription.close_notify:
219 raise 211 raise
220 except TLSAbruptCloseError: 212 except TLSAbruptCloseError:
221 if not self.ignoreAbruptClose: 213 if not self.ignoreAbruptClose:
222 raise 214 raise
223 else: 215 else:
224 self._shutdown(True) 216 self._shutdown(True)
225 217
226 if max == None: 218 if max == None:
227 max = len(self._readBuffer) 219 max = len(self._readBuffer)
228 220
229 returnStr = self._readBuffer[:max] 221 returnBytes = self._readBuffer[:max]
230 self._readBuffer = self._readBuffer[max:] 222 self._readBuffer = self._readBuffer[max:]
231 yield returnStr 223 yield bytes(returnBytes)
224 except GeneratorExit:
225 raise
232 except: 226 except:
233 self._shutdown(False) 227 self._shutdown(False)
234 raise 228 raise
235 229
230 def unread(self, b):
231 """Add bytes to the front of the socket read buffer for future
232 reading. Be careful using this in the context of select(...): if you
233 unread the last data from a socket, that won't wake up selected waiters,
234 and those waiters may hang forever.
235 """
236 self._readBuffer = b + self._readBuffer
237
236 def write(self, s): 238 def write(self, s):
237 """Write some data to the TLS connection. 239 """Write some data to the TLS connection.
238 240
239 This function will block until all the data has been sent. 241 This function will block until all the data has been sent.
240 242
241 If an exception is raised, the connection will have been 243 If an exception is raised, the connection will have been
242 automatically closed. 244 automatically closed.
243 245
244 @type s: str 246 @type s: str
245 @param s: The data to transmit to the other party. 247 @param s: The data to transmit to the other party.
246 248
247 @raise socket.error: If a socket error occurs. 249 @raise socket.error: If a socket error occurs.
248 """ 250 """
249 for result in self.writeAsync(s): 251 for result in self.writeAsync(s):
250 pass 252 pass
251 253
252 def writeAsync(self, s): 254 def writeAsync(self, s):
253 """Start a write operation on the TLS connection. 255 """Start a write operation on the TLS connection.
254 256
255 This function returns a generator which behaves similarly to 257 This function returns a generator which behaves similarly to
256 write(). Successive invocations of the generator will return 258 write(). Successive invocations of the generator will return
257 1 if it is waiting to write to the socket, or will raise 259 1 if it is waiting to write to the socket, or will raise
258 StopIteration if the write operation has completed. 260 StopIteration if the write operation has completed.
259 261
260 @rtype: iterable 262 @rtype: iterable
261 @return: A generator; see above for details. 263 @return: A generator; see above for details.
262 """ 264 """
263 try: 265 try:
264 if self.closed: 266 if self.closed:
265 raise ValueError() 267 raise TLSClosedConnectionError("attempt to write to closed conne ction")
266 268
267 index = 0 269 index = 0
268 blockSize = 16384 270 blockSize = 16384
269 skipEmptyFrag = False 271 randomizeFirstBlock = True
270 while 1: 272 while 1:
271 startIndex = index * blockSize 273 startIndex = index * blockSize
272 endIndex = startIndex + blockSize 274 endIndex = startIndex + blockSize
273 if startIndex >= len(s): 275 if startIndex >= len(s):
274 break 276 break
275 if endIndex > len(s): 277 if endIndex > len(s):
276 endIndex = len(s) 278 endIndex = len(s)
277 block = stringToBytes(s[startIndex : endIndex]) 279 block = bytearray(s[startIndex : endIndex])
278 applicationData = ApplicationData().create(block) 280 applicationData = ApplicationData().create(block)
279 for result in self._sendMsg(applicationData, skipEmptyFrag): 281 for result in self._sendMsg(applicationData, \
282 randomizeFirstBlock):
280 yield result 283 yield result
281 skipEmptyFrag = True #only send an empy fragment on 1st message 284 randomizeFirstBlock = False #only on 1st message
282 index += 1 285 index += 1
283 except: 286 except GeneratorExit:
287 raise
288 except Exception:
284 self._shutdown(False) 289 self._shutdown(False)
285 raise 290 raise
286 291
287 def close(self): 292 def close(self):
288 """Close the TLS connection. 293 """Close the TLS connection.
289 294
290 This function will block until it has exchanged close_notify 295 This function will block until it has exchanged close_notify
291 alerts with the other party. After doing so, it will shut down the 296 alerts with the other party. After doing so, it will shut down the
292 TLS connection. Further attempts to read through this connection 297 TLS connection. Further attempts to read through this connection
293 will return "". Further attempts to write through this connection 298 will return "". Further attempts to write through this connection
294 will raise ValueError. 299 will raise ValueError.
295 300
296 If makefile() has been called on this connection, the connection 301 If makefile() has been called on this connection, the connection
297 will be not be closed until the connection object and all file 302 will be not be closed until the connection object and all file
298 objects have been closed. 303 objects have been closed.
299 304
300 Even if an exception is raised, the connection will have been 305 Even if an exception is raised, the connection will have been
301 closed. 306 closed.
302 307
303 @raise socket.error: If a socket error occurs. 308 @raise socket.error: If a socket error occurs.
304 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed 309 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
305 without a preceding alert. 310 without a preceding alert.
306 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. 311 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
307 """ 312 """
308 if not self.closed: 313 if not self.closed:
309 for result in self._decrefAsync(): 314 for result in self._decrefAsync():
310 pass 315 pass
311 316
317 # Python 3 callback
318 _decref_socketios = close
319
312 def closeAsync(self): 320 def closeAsync(self):
313 """Start a close operation on the TLS connection. 321 """Start a close operation on the TLS connection.
314 322
315 This function returns a generator which behaves similarly to 323 This function returns a generator which behaves similarly to
316 close(). Successive invocations of the generator will return 0 324 close(). Successive invocations of the generator will return 0
317 if it is waiting to read from the socket, 1 if it is waiting 325 if it is waiting to read from the socket, 1 if it is waiting
318 to write to the socket, or will raise StopIteration if the 326 to write to the socket, or will raise StopIteration if the
319 close operation has completed. 327 close operation has completed.
320 328
321 @rtype: iterable 329 @rtype: iterable
322 @return: A generator; see above for details. 330 @return: A generator; see above for details.
323 """ 331 """
324 if not self.closed: 332 if not self.closed:
325 for result in self._decrefAsync(): 333 for result in self._decrefAsync():
326 yield result 334 yield result
327 335
328 def _decrefAsync(self): 336 def _decrefAsync(self):
329 self._refCount -= 1 337 self._refCount -= 1
330 if self._refCount == 0 and not self.closed: 338 if self._refCount == 0 and not self.closed:
331 try: 339 try:
332 for result in self._sendMsg(Alert().create(\ 340 for result in self._sendMsg(Alert().create(\
333 AlertDescription.close_notify, AlertLevel.warning)): 341 AlertDescription.close_notify, AlertLevel.warning)):
334 yield result 342 yield result
335 alert = None 343 alert = None
336 # Forcing a shutdown as WinHTTP does not seem to be 344 # By default close the socket, since it's been observed
337 # responsive to the close notify. 345 # that some other libraries will not respond to the
338 prevCloseSocket = self.closeSocket 346 # close_notify alert, thus leaving us hanging if we're
339 self.closeSocket = True 347 # expecting it
340 self._shutdown(True) 348 if self.closeSocket:
341 self.closeSocket = prevCloseSocket
342 while not alert:
343 for result in self._getMsg((ContentType.alert, \
344 ContentType.application_data)):
345 if result in (0,1):
346 yield result
347 if result.contentType == ContentType.alert:
348 alert = result
349 if alert.description == AlertDescription.close_notify:
350 self._shutdown(True) 349 self._shutdown(True)
351 else: 350 else:
352 raise TLSRemoteAlert(alert) 351 while not alert:
352 for result in self._getMsg((ContentType.alert, \
353 ContentType.application_data)) :
354 if result in (0,1):
355 yield result
356 if result.contentType == ContentType.alert:
357 alert = result
358 if alert.description == AlertDescription.close_notify:
359 self._shutdown(True)
360 else:
361 raise TLSRemoteAlert(alert)
353 except (socket.error, TLSAbruptCloseError): 362 except (socket.error, TLSAbruptCloseError):
354 #If the other side closes the socket, that's okay 363 #If the other side closes the socket, that's okay
355 self._shutdown(True) 364 self._shutdown(True)
365 except GeneratorExit:
366 raise
356 except: 367 except:
357 self._shutdown(False) 368 self._shutdown(False)
358 raise 369 raise
359 370
371 def getVersionName(self):
372 """Get the name of this TLS version.
373
374 @rtype: str
375 @return: The name of the TLS version used with this connection.
376 Either None, 'SSL 3.0', 'TLS 1.0', or 'TLS 1.1'.
377 """
378 if self.version == (3,0):
379 return "SSL 3.0"
380 elif self.version == (3,1):
381 return "TLS 1.0"
382 elif self.version == (3,2):
383 return "TLS 1.1"
384 else:
385 return None
386
360 def getCipherName(self): 387 def getCipherName(self):
361 """Get the name of the cipher used with this connection. 388 """Get the name of the cipher used with this connection.
362 389
363 @rtype: str 390 @rtype: str
364 @return: The name of the cipher used with this connection. 391 @return: The name of the cipher used with this connection.
365 Either 'aes128', 'aes256', 'rc4', or '3des'. 392 Either 'aes128', 'aes256', 'rc4', or '3des'.
366 """ 393 """
367 if not self._writeState.encContext: 394 if not self._writeState.encContext:
368 return None 395 return None
369 return self._writeState.encContext.name 396 return self._writeState.encContext.name
370 397
371 def getCipherImplementation(self): 398 def getCipherImplementation(self):
372 """Get the name of the cipher implementation used with 399 """Get the name of the cipher implementation used with
373 this connection. 400 this connection.
374 401
375 @rtype: str 402 @rtype: str
376 @return: The name of the cipher implementation used with 403 @return: The name of the cipher implementation used with
377 this connection. Either 'python', 'cryptlib', 'openssl', 404 this connection. Either 'python', 'openssl', or 'pycrypto'.
378 or 'pycrypto'.
379 """ 405 """
380 if not self._writeState.encContext: 406 if not self._writeState.encContext:
381 return None 407 return None
382 return self._writeState.encContext.implementation 408 return self._writeState.encContext.implementation
383 409
384 410
385 411
386 #Emulate a socket, somewhat - 412 #Emulate a socket, somewhat -
387 def send(self, s): 413 def send(self, s):
388 """Send data to the TLS connection (socket emulation). 414 """Send data to the TLS connection (socket emulation).
(...skipping 13 matching lines...) Expand all
402 def recv(self, bufsize): 428 def recv(self, bufsize):
403 """Get some data from the TLS connection (socket emulation). 429 """Get some data from the TLS connection (socket emulation).
404 430
405 @raise socket.error: If a socket error occurs. 431 @raise socket.error: If a socket error occurs.
406 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed 432 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
407 without a preceding alert. 433 without a preceding alert.
408 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. 434 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
409 """ 435 """
410 return self.read(bufsize) 436 return self.read(bufsize)
411 437
438 def recv_into(self, b):
439 # XXX doc string
440 data = self.read(len(b))
441 if not data:
442 return None
443 b[:len(data)] = data
444 return len(data)
445
412 def makefile(self, mode='r', bufsize=-1): 446 def makefile(self, mode='r', bufsize=-1):
413 """Create a file object for the TLS connection (socket emulation). 447 """Create a file object for the TLS connection (socket emulation).
414 448
415 @rtype: L{tlslite.FileObject.FileObject} 449 @rtype: L{socket._fileobject}
416 """ 450 """
417 self._refCount += 1 451 self._refCount += 1
418 return FileObject(self, mode, bufsize) 452 # So, it is pretty fragile to be using Python internal objects
453 # like this, but it is probably the best/easiest way to provide
454 # matching behavior for socket emulation purposes. The 'close'
455 # argument is nice, its apparently a recent addition to this
456 # class, so that when fileobject.close() gets called, it will
457 # close() us, causing the refcount to be decremented (decrefAsync).
458 #
459 # If this is the last close() on the outstanding fileobjects /
460 # TLSConnection, then the "actual" close alerts will be sent,
461 # socket closed, etc.
462 if sys.version_info < (3,):
463 return socket._fileobject(self, mode, bufsize, close=True)
464 else:
465 # XXX need to wrap this further if buffering is requested
466 return socket.SocketIO(self, mode)
419 467
420 def getsockname(self): 468 def getsockname(self):
421 """Return the socket's own address (socket emulation).""" 469 """Return the socket's own address (socket emulation)."""
422 return self.sock.getsockname() 470 return self.sock.getsockname()
423 471
424 def getpeername(self): 472 def getpeername(self):
425 """Return the remote address to which the socket is connected 473 """Return the remote address to which the socket is connected
426 (socket emulation).""" 474 (socket emulation)."""
427 return self.sock.getpeername() 475 return self.sock.getpeername()
428 476
429 def settimeout(self, value): 477 def settimeout(self, value):
430 """Set a timeout on blocking socket operations (socket emulation).""" 478 """Set a timeout on blocking socket operations (socket emulation)."""
431 return self.sock.settimeout(value) 479 return self.sock.settimeout(value)
432 480
433 def gettimeout(self): 481 def gettimeout(self):
434 """Return the timeout associated with socket operations (socket 482 """Return the timeout associated with socket operations (socket
435 emulation).""" 483 emulation)."""
436 return self.sock.gettimeout() 484 return self.sock.gettimeout()
437 485
438 def setsockopt(self, level, optname, value): 486 def setsockopt(self, level, optname, value):
439 """Set the value of the given socket option (socket emulation).""" 487 """Set the value of the given socket option (socket emulation)."""
440 return self.sock.setsockopt(level, optname, value) 488 return self.sock.setsockopt(level, optname, value)
441 489
490 def shutdown(self, how):
491 """Shutdown the underlying socket."""
492 return self.sock.shutdown(how)
493
494 def fileno(self):
495 """Not implement in TLS Lite."""
496 raise NotImplementedError()
497
442 498
443 #********************************************************* 499 #*********************************************************
444 # Public Functions END 500 # Public Functions END
445 #********************************************************* 501 #*********************************************************
446 502
447 def _shutdown(self, resumable): 503 def _shutdown(self, resumable):
448 self._writeState = _ConnectionState() 504 self._writeState = _ConnectionState()
449 self._readState = _ConnectionState() 505 self._readState = _ConnectionState()
450 #Don't do this: self._readBuffer = ""
451 self.version = (0,0) 506 self.version = (0,0)
452 self._versionCheck = False 507 self._versionCheck = False
453 self.closed = True 508 self.closed = True
454 if self.closeSocket: 509 if self.closeSocket:
455 self.sock.close() 510 self.sock.close()
456 511
457 #Even if resumable is False, we'll never toggle this on 512 #Even if resumable is False, we'll never toggle this on
458 if not resumable and self.session: 513 if not resumable and self.session:
459 self.session.resumable = False 514 self.session.resumable = False
460 515
461 516
462 def _sendError(self, alertDescription, errorStr=None): 517 def _sendError(self, alertDescription, errorStr=None):
463 alert = Alert().create(alertDescription, AlertLevel.fatal) 518 alert = Alert().create(alertDescription, AlertLevel.fatal)
464 for result in self._sendMsg(alert): 519 for result in self._sendMsg(alert):
465 yield result 520 yield result
466 self._shutdown(False) 521 self._shutdown(False)
467 raise TLSLocalAlert(alert, errorStr) 522 raise TLSLocalAlert(alert, errorStr)
468 523
469 def _sendMsgs(self, msgs): 524 def _sendMsgs(self, msgs):
470 skipEmptyFrag = False 525 randomizeFirstBlock = True
471 for msg in msgs: 526 for msg in msgs:
472 for result in self._sendMsg(msg, skipEmptyFrag): 527 for result in self._sendMsg(msg, randomizeFirstBlock):
473 yield result 528 yield result
474 skipEmptyFrag = True 529 randomizeFirstBlock = True
475 530
476 def _sendMsg(self, msg, skipEmptyFrag=False): 531 def _sendMsg(self, msg, randomizeFirstBlock = True):
477 bytes = msg.write() 532 #Whenever we're connected and asked to send an app data message,
533 #we first send the first byte of the message. This prevents
534 #an attacker from launching a chosen-plaintext attack based on
535 #knowing the next IV (a la BEAST).
536 if not self.closed and randomizeFirstBlock and self.version <= (3,1) \
537 and self._writeState.encContext \
538 and self._writeState.encContext.isBlockCipher \
539 and isinstance(msg, ApplicationData):
540 msgFirstByte = msg.splitFirstByte()
541 for result in self._sendMsg(msgFirstByte,
542 randomizeFirstBlock = False):
543 yield result
544
545 b = msg.write()
546
547 # If a 1-byte message was passed in, and we "split" the
548 # first(only) byte off above, we may have a 0-length msg:
549 if len(b) == 0:
550 return
551
478 contentType = msg.contentType 552 contentType = msg.contentType
479 553
480 #Whenever we're connected and asked to send a message,
481 #we first send an empty Application Data message. This prevents
482 #an attacker from launching a chosen-plaintext attack based on
483 #knowing the next IV.
484 if not self.closed and not skipEmptyFrag and self.version == (3,1):
485 if self._writeState.encContext:
486 if self._writeState.encContext.isBlockCipher:
487 for result in self._sendMsg(ApplicationData(),
488 skipEmptyFrag=True):
489 yield result
490
491 #Update handshake hashes 554 #Update handshake hashes
492 if contentType == ContentType.handshake: 555 if contentType == ContentType.handshake:
493 bytesStr = bytesToString(bytes) 556 self._handshake_md5.update(compat26Str(b))
494 self._handshake_md5.update(bytesStr) 557 self._handshake_sha.update(compat26Str(b))
495 self._handshake_sha.update(bytesStr)
496 558
497 #Calculate MAC 559 #Calculate MAC
498 if self._writeState.macContext: 560 if self._writeState.macContext:
499 seqnumStr = self._writeState.getSeqNumStr() 561 seqnumBytes = self._writeState.getSeqNumBytes()
500 bytesStr = bytesToString(bytes)
501 mac = self._writeState.macContext.copy() 562 mac = self._writeState.macContext.copy()
502 mac.update(seqnumStr) 563 mac.update(compatHMAC(seqnumBytes))
503 mac.update(chr(contentType)) 564 mac.update(compatHMAC(bytearray([contentType])))
504 if self.version == (3,0): 565 if self.version == (3,0):
505 mac.update( chr( int(len(bytes)/256) ) ) 566 mac.update( compatHMAC( bytearray([len(b)//256] )))
506 mac.update( chr( int(len(bytes)%256) ) ) 567 mac.update( compatHMAC( bytearray([len(b)%256] )))
507 elif self.version in ((3,1), (3,2)): 568 elif self.version in ((3,1), (3,2)):
508 mac.update(chr(self.version[0])) 569 mac.update(compatHMAC( bytearray([self.version[0]] )))
509 mac.update(chr(self.version[1])) 570 mac.update(compatHMAC( bytearray([self.version[1]] )))
510 mac.update( chr( int(len(bytes)/256) ) ) 571 mac.update( compatHMAC( bytearray([len(b)//256] )))
511 mac.update( chr( int(len(bytes)%256) ) ) 572 mac.update( compatHMAC( bytearray([len(b)%256] )))
512 else: 573 else:
513 raise AssertionError() 574 raise AssertionError()
514 mac.update(bytesStr) 575 mac.update(compatHMAC(b))
515 macString = mac.digest() 576 macBytes = bytearray(mac.digest())
516 macBytes = stringToBytes(macString)
517 if self.fault == Fault.badMAC: 577 if self.fault == Fault.badMAC:
518 macBytes[0] = (macBytes[0]+1) % 256 578 macBytes[0] = (macBytes[0]+1) % 256
519 579
520 #Encrypt for Block or Stream Cipher 580 #Encrypt for Block or Stream Cipher
521 if self._writeState.encContext: 581 if self._writeState.encContext:
522 #Add padding and encrypt (for Block Cipher): 582 #Add padding and encrypt (for Block Cipher):
523 if self._writeState.encContext.isBlockCipher: 583 if self._writeState.encContext.isBlockCipher:
524 584
525 #Add TLS 1.1 fixed block 585 #Add TLS 1.1 fixed block
526 if self.version == (3,2): 586 if self.version == (3,2):
527 bytes = self.fixedIVBlock + bytes 587 b = self.fixedIVBlock + b
528 588
529 #Add padding: bytes = bytes + (macBytes + paddingBytes) 589 #Add padding: b = b+ (macBytes + paddingBytes)
530 currentLength = len(bytes) + len(macBytes) + 1 590 currentLength = len(b) + len(macBytes) + 1
531 blockLength = self._writeState.encContext.block_size 591 blockLength = self._writeState.encContext.block_size
532 paddingLength = blockLength-(currentLength % blockLength) 592 paddingLength = blockLength-(currentLength % blockLength)
593 #SSL3 requires minimal padding. (TLS doesn't care.)
594 if paddingLength == blockLength:
595 paddingLength = 0
533 596
534 paddingBytes = createByteArraySequence([paddingLength] * \ 597 paddingBytes = bytearray([paddingLength] * (paddingLength+1))
535 (paddingLength+1))
536 if self.fault == Fault.badPadding: 598 if self.fault == Fault.badPadding:
537 paddingBytes[0] = (paddingBytes[0]+1) % 256 599 paddingBytes[0] = (paddingBytes[0]+1) % 256
538 endBytes = concatArrays(macBytes, paddingBytes) 600 endBytes = macBytes + paddingBytes
539 bytes = concatArrays(bytes, endBytes) 601 b += endBytes
540 #Encrypt 602 #Encrypt
541 plaintext = stringToBytes(bytes) 603 b = self._writeState.encContext.encrypt(b)
542 ciphertext = self._writeState.encContext.encrypt(plaintext)
543 bytes = stringToBytes(ciphertext)
544 604
545 #Encrypt (for Stream Cipher) 605 #Encrypt (for Stream Cipher)
546 else: 606 else:
547 bytes = concatArrays(bytes, macBytes) 607 b += macBytes
548 plaintext = bytesToString(bytes) 608 b = self._writeState.encContext.encrypt(b)
549 ciphertext = self._writeState.encContext.encrypt(plaintext)
550 bytes = stringToBytes(ciphertext)
551 609
552 #Add record header and send 610 #Add record header and send
553 r = RecordHeader3().create(self.version, contentType, len(bytes)) 611 r = RecordHeader3().create(self.version, contentType, len(b))
554 s = bytesToString(concatArrays(r.write(), bytes)) 612 s = r.write() + b
555 while 1: 613 while 1:
556 try: 614 try:
557 bytesSent = self.sock.send(s) #Might raise socket.error 615 bytesSent = self.sock.send(s) #Might raise socket.error
558 except socket.error, why: 616 except socket.error as why:
559 if why[0] == errno.EWOULDBLOCK: 617 if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
560 yield 1 618 yield 1
561 continue 619 continue
562 else: 620 else:
563 raise 621 # The socket was unexpectedly closed. The tricky part
622 # is that there may be an alert sent by the other party
623 # sitting in the read buffer. So, if we get here after
624 # handshaking, we will just raise the error and let the
625 # caller read more data if it would like, thus stumbling
626 # upon the error.
627 #
628 # However, if we get here DURING handshaking, we take
629 # it upon ourselves to see if the next message is an
630 # Alert.
631 if contentType == ContentType.handshake:
632
633 # See if there's an alert record
634 # Could raise socket.error or TLSAbruptCloseError
635 for result in self._getNextRecord():
636 if result in (0,1):
637 yield result
638
639 # Closes the socket
640 self._shutdown(False)
641
642 # If we got an alert, raise it
643 recordHeader, p = result
644 if recordHeader.type == ContentType.alert:
645 alert = Alert().parse(p)
646 raise TLSRemoteAlert(alert)
647 else:
648 # If we got some other message who know what
649 # the remote side is doing, just go ahead and
650 # raise the socket.error
651 raise
564 if bytesSent == len(s): 652 if bytesSent == len(s):
565 return 653 return
566 s = s[bytesSent:] 654 s = s[bytesSent:]
567 yield 1 655 yield 1
568 656
569 657
570 def _getMsg(self, expectedType, secondaryType=None, constructorType=None): 658 def _getMsg(self, expectedType, secondaryType=None, constructorType=None):
571 try: 659 try:
572 if not isinstance(expectedType, tuple): 660 if not isinstance(expectedType, tuple):
573 expectedType = (expectedType,) 661 expectedType = (expectedType,)
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 subType = HandshakeType.client_hello 771 subType = HandshakeType.client_hello
684 else: 772 else:
685 subType = p.get(1) 773 subType = p.get(1)
686 if subType not in secondaryType: 774 if subType not in secondaryType:
687 for result in self._sendError(\ 775 for result in self._sendError(\
688 AlertDescription.unexpected_message, 776 AlertDescription.unexpected_message,
689 "Expecting %s, got %s" % (str(secondaryType), su bType)): 777 "Expecting %s, got %s" % (str(secondaryType), su bType)):
690 yield result 778 yield result
691 779
692 #Update handshake hashes 780 #Update handshake hashes
693 sToHash = bytesToString(p.bytes) 781 self._handshake_md5.update(compat26Str(p.bytes))
694 self._handshake_md5.update(sToHash) 782 self._handshake_sha.update(compat26Str(p.bytes))
695 self._handshake_sha.update(sToHash)
696 783
697 #Parse based on handshake type 784 #Parse based on handshake type
698 if subType == HandshakeType.client_hello: 785 if subType == HandshakeType.client_hello:
699 yield ClientHello(recordHeader.ssl2).parse(p) 786 yield ClientHello(recordHeader.ssl2).parse(p)
700 elif subType == HandshakeType.server_hello: 787 elif subType == HandshakeType.server_hello:
701 yield ServerHello().parse(p) 788 yield ServerHello().parse(p)
702 elif subType == HandshakeType.certificate: 789 elif subType == HandshakeType.certificate:
703 yield Certificate(constructorType).parse(p) 790 yield Certificate(constructorType).parse(p)
704 elif subType == HandshakeType.certificate_request: 791 elif subType == HandshakeType.certificate_request:
705 yield CertificateRequest().parse(p) 792 yield CertificateRequest().parse(p)
706 elif subType == HandshakeType.certificate_verify: 793 elif subType == HandshakeType.certificate_verify:
707 yield CertificateVerify().parse(p) 794 yield CertificateVerify().parse(p)
708 elif subType == HandshakeType.server_key_exchange: 795 elif subType == HandshakeType.server_key_exchange:
709 yield ServerKeyExchange(constructorType).parse(p) 796 yield ServerKeyExchange(constructorType).parse(p)
710 elif subType == HandshakeType.server_hello_done: 797 elif subType == HandshakeType.server_hello_done:
711 yield ServerHelloDone().parse(p) 798 yield ServerHelloDone().parse(p)
712 elif subType == HandshakeType.client_key_exchange: 799 elif subType == HandshakeType.client_key_exchange:
713 yield ClientKeyExchange(constructorType, \ 800 yield ClientKeyExchange(constructorType, \
714 self.version).parse(p) 801 self.version).parse(p)
715 elif subType == HandshakeType.finished: 802 elif subType == HandshakeType.finished:
716 yield Finished(self.version).parse(p) 803 yield Finished(self.version).parse(p)
804 elif subType == HandshakeType.next_protocol:
805 yield NextProtocol().parse(p)
717 elif subType == HandshakeType.encrypted_extensions: 806 elif subType == HandshakeType.encrypted_extensions:
718 yield EncryptedExtensions().parse(p) 807 yield EncryptedExtensions().parse(p)
719 else: 808 else:
720 raise AssertionError() 809 raise AssertionError()
721 810
722 #If an exception was raised by a Parser or Message instance: 811 #If an exception was raised by a Parser or Message instance:
723 except SyntaxError, e: 812 except SyntaxError as e:
724 for result in self._sendError(AlertDescription.decode_error, 813 for result in self._sendError(AlertDescription.decode_error,
725 formatExceptionTrace(e)): 814 formatExceptionTrace(e)):
726 yield result 815 yield result
727 816
728 817
729 #Returns next record or next handshake message 818 #Returns next record or next handshake message
730 def _getNextRecord(self): 819 def _getNextRecord(self):
731 820
732 #If there's a handshake message waiting, return it 821 #If there's a handshake message waiting, return it
733 if self._handshakeBuffer: 822 if self._handshakeBuffer:
734 recordHeader, bytes = self._handshakeBuffer[0] 823 recordHeader, b = self._handshakeBuffer[0]
735 self._handshakeBuffer = self._handshakeBuffer[1:] 824 self._handshakeBuffer = self._handshakeBuffer[1:]
736 yield (recordHeader, Parser(bytes)) 825 yield (recordHeader, Parser(b))
737 return 826 return
738 827
739 #Otherwise... 828 #Otherwise...
740 #Read the next record header 829 #Read the next record header
741 bytes = createByteArraySequence([]) 830 b = bytearray(0)
742 recordHeaderLength = 1 831 recordHeaderLength = 1
743 ssl2 = False 832 ssl2 = False
744 while 1: 833 while 1:
745 try: 834 try:
746 s = self.sock.recv(recordHeaderLength-len(bytes)) 835 s = self.sock.recv(recordHeaderLength-len(b))
747 except socket.error, why: 836 except socket.error as why:
748 if why[0] == errno.EWOULDBLOCK: 837 if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
749 yield 0 838 yield 0
750 continue 839 continue
751 else: 840 else:
752 raise 841 raise
753 842
754 #If the connection was abruptly closed, raise an error 843 #If the connection was abruptly closed, raise an error
755 if len(s)==0: 844 if len(s)==0:
756 raise TLSAbruptCloseError() 845 raise TLSAbruptCloseError()
757 846
758 bytes += stringToBytes(s) 847 b += bytearray(s)
759 if len(bytes)==1: 848 if len(b)==1:
760 if bytes[0] in ContentType.all: 849 if b[0] in ContentType.all:
761 ssl2 = False 850 ssl2 = False
762 recordHeaderLength = 5 851 recordHeaderLength = 5
763 elif bytes[0] == 128: 852 elif b[0] == 128:
764 ssl2 = True 853 ssl2 = True
765 recordHeaderLength = 2 854 recordHeaderLength = 2
766 else: 855 else:
767 raise SyntaxError() 856 raise SyntaxError()
768 if len(bytes) == recordHeaderLength: 857 if len(b) == recordHeaderLength:
769 break 858 break
770 859
771 #Parse the record header 860 #Parse the record header
772 if ssl2: 861 if ssl2:
773 r = RecordHeader2().parse(Parser(bytes)) 862 r = RecordHeader2().parse(Parser(b))
774 else: 863 else:
775 r = RecordHeader3().parse(Parser(bytes)) 864 r = RecordHeader3().parse(Parser(b))
776 865
777 #Check the record header fields 866 #Check the record header fields
778 if r.length > 18432: 867 if r.length > 18432:
779 for result in self._sendError(AlertDescription.record_overflow): 868 for result in self._sendError(AlertDescription.record_overflow):
780 yield result 869 yield result
781 870
782 #Read the record contents 871 #Read the record contents
783 bytes = createByteArraySequence([]) 872 b = bytearray(0)
784 while 1: 873 while 1:
785 try: 874 try:
786 s = self.sock.recv(r.length - len(bytes)) 875 s = self.sock.recv(r.length - len(b))
787 except socket.error, why: 876 except socket.error as why:
788 if why[0] == errno.EWOULDBLOCK: 877 if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
789 yield 0 878 yield 0
790 continue 879 continue
791 else: 880 else:
792 raise 881 raise
793 882
794 #If the connection is closed, raise a socket error 883 #If the connection is closed, raise a socket error
795 if len(s)==0: 884 if len(s)==0:
796 raise TLSAbruptCloseError() 885 raise TLSAbruptCloseError()
797 886
798 bytes += stringToBytes(s) 887 b += bytearray(s)
799 if len(bytes) == r.length: 888 if len(b) == r.length:
800 break 889 break
801 890
802 #Check the record header fields (2) 891 #Check the record header fields (2)
803 #We do this after reading the contents from the socket, so that 892 #We do this after reading the contents from the socket, so that
804 #if there's an error, we at least don't leave extra bytes in the 893 #if there's an error, we at least don't leave extra bytes in the
805 #socket.. 894 #socket..
806 # 895 #
807 # THIS CHECK HAS NO SECURITY RELEVANCE (?), BUT COULD HURT INTEROP. 896 # THIS CHECK HAS NO SECURITY RELEVANCE (?), BUT COULD HURT INTEROP.
808 # SO WE LEAVE IT OUT FOR NOW. 897 # SO WE LEAVE IT OUT FOR NOW.
809 # 898 #
810 #if self._versionCheck and r.version != self.version: 899 #if self._versionCheck and r.version != self.version:
811 # for result in self._sendError(AlertDescription.protocol_version, 900 # for result in self._sendError(AlertDescription.protocol_version,
812 # "Version in header field: %s, should be %s" % (str(r.versio n), 901 # "Version in header field: %s, should be %s" % (str(r.versio n),
813 # str(self.version ))): 902 # str(self.version ))):
814 # yield result 903 # yield result
815 904
816 #Decrypt the record 905 #Decrypt the record
817 for result in self._decryptRecord(r.type, bytes): 906 for result in self._decryptRecord(r.type, b):
818 if result in (0,1): 907 if result in (0,1): yield result
819 yield result 908 else: break
820 else: 909 b = result
821 break 910 p = Parser(b)
822 bytes = result
823 p = Parser(bytes)
824 911
825 #If it doesn't contain handshake messages, we can just return it 912 #If it doesn't contain handshake messages, we can just return it
826 if r.type != ContentType.handshake: 913 if r.type != ContentType.handshake:
827 yield (r, p) 914 yield (r, p)
828 #If it's an SSLv2 ClientHello, we can return it as well 915 #If it's an SSLv2 ClientHello, we can return it as well
829 elif r.ssl2: 916 elif r.ssl2:
830 yield (r, p) 917 yield (r, p)
831 else: 918 else:
832 #Otherwise, we loop through and add the handshake messages to the 919 #Otherwise, we loop through and add the handshake messages to the
833 #handshake buffer 920 #handshake buffer
834 while 1: 921 while 1:
835 if p.index == len(bytes): #If we're at the end 922 if p.index == len(b): #If we're at the end
836 if not self._handshakeBuffer: 923 if not self._handshakeBuffer:
837 for result in self._sendError(\ 924 for result in self._sendError(\
838 AlertDescription.decode_error, \ 925 AlertDescription.decode_error, \
839 "Received empty handshake record"): 926 "Received empty handshake record"):
840 yield result 927 yield result
841 break 928 break
842 #There needs to be at least 4 bytes to get a header 929 #There needs to be at least 4 bytes to get a header
843 if p.index+4 > len(bytes): 930 if p.index+4 > len(b):
844 for result in self._sendError(\ 931 for result in self._sendError(\
845 AlertDescription.decode_error, 932 AlertDescription.decode_error,
846 "A record has a partial handshake message (1)"): 933 "A record has a partial handshake message (1)"):
847 yield result 934 yield result
848 p.get(1) # skip handshake type 935 p.get(1) # skip handshake type
849 msgLength = p.get(3) 936 msgLength = p.get(3)
850 if p.index+msgLength > len(bytes): 937 if p.index+msgLength > len(b):
851 for result in self._sendError(\ 938 for result in self._sendError(\
852 AlertDescription.decode_error, 939 AlertDescription.decode_error,
853 "A record has a partial handshake message (2)"): 940 "A record has a partial handshake message (2)"):
854 yield result 941 yield result
855 942
856 handshakePair = (r, bytes[p.index-4 : p.index+msgLength]) 943 handshakePair = (r, b[p.index-4 : p.index+msgLength])
857 self._handshakeBuffer.append(handshakePair) 944 self._handshakeBuffer.append(handshakePair)
858 p.index += msgLength 945 p.index += msgLength
859 946
860 #We've moved at least one handshake message into the 947 #We've moved at least one handshake message into the
861 #handshakeBuffer, return the first one 948 #handshakeBuffer, return the first one
862 recordHeader, bytes = self._handshakeBuffer[0] 949 recordHeader, b = self._handshakeBuffer[0]
863 self._handshakeBuffer = self._handshakeBuffer[1:] 950 self._handshakeBuffer = self._handshakeBuffer[1:]
864 yield (recordHeader, Parser(bytes)) 951 yield (recordHeader, Parser(b))
865 952
866 953
867 def _decryptRecord(self, recordType, bytes): 954 def _decryptRecord(self, recordType, b):
868 if self._readState.encContext: 955 if self._readState.encContext:
869 956
870 #Decrypt if it's a block cipher 957 #Decrypt if it's a block cipher
871 if self._readState.encContext.isBlockCipher: 958 if self._readState.encContext.isBlockCipher:
872 blockLength = self._readState.encContext.block_size 959 blockLength = self._readState.encContext.block_size
873 if len(bytes) % blockLength != 0: 960 if len(b) % blockLength != 0:
874 for result in self._sendError(\ 961 for result in self._sendError(\
875 AlertDescription.decryption_failed, 962 AlertDescription.decryption_failed,
876 "Encrypted data not a multiple of blocksize"): 963 "Encrypted data not a multiple of blocksize"):
877 yield result 964 yield result
878 ciphertext = bytesToString(bytes) 965 b = self._readState.encContext.decrypt(b)
879 plaintext = self._readState.encContext.decrypt(ciphertext)
880 if self.version == (3,2): #For TLS 1.1, remove explicit IV 966 if self.version == (3,2): #For TLS 1.1, remove explicit IV
881 plaintext = plaintext[self._readState.encContext.block_size : ] 967 b = b[self._readState.encContext.block_size : ]
882 bytes = stringToBytes(plaintext)
883 968
884 #Check padding 969 #Check padding
885 paddingGood = True 970 paddingGood = True
886 paddingLength = bytes[-1] 971 paddingLength = b[-1]
887 if (paddingLength+1) > len(bytes): 972 if (paddingLength+1) > len(b):
888 paddingGood=False 973 paddingGood=False
889 totalPaddingLength = 0 974 totalPaddingLength = 0
890 else: 975 else:
891 if self.version == (3,0): 976 if self.version == (3,0):
892 totalPaddingLength = paddingLength+1 977 totalPaddingLength = paddingLength+1
893 elif self.version in ((3,1), (3,2)): 978 elif self.version in ((3,1), (3,2)):
894 totalPaddingLength = paddingLength+1 979 totalPaddingLength = paddingLength+1
895 paddingBytes = bytes[-totalPaddingLength:-1] 980 paddingBytes = b[-totalPaddingLength:-1]
896 for byte in paddingBytes: 981 for byte in paddingBytes:
897 if byte != paddingLength: 982 if byte != paddingLength:
898 paddingGood = False 983 paddingGood = False
899 totalPaddingLength = 0 984 totalPaddingLength = 0
900 else: 985 else:
901 raise AssertionError() 986 raise AssertionError()
902 987
903 #Decrypt if it's a stream cipher 988 #Decrypt if it's a stream cipher
904 else: 989 else:
905 paddingGood = True 990 paddingGood = True
906 ciphertext = bytesToString(bytes) 991 b = self._readState.encContext.decrypt(b)
907 plaintext = self._readState.encContext.decrypt(ciphertext)
908 bytes = stringToBytes(plaintext)
909 totalPaddingLength = 0 992 totalPaddingLength = 0
910 993
911 #Check MAC 994 #Check MAC
912 macGood = True 995 macGood = True
913 macLength = self._readState.macContext.digest_size 996 macLength = self._readState.macContext.digest_size
914 endLength = macLength + totalPaddingLength 997 endLength = macLength + totalPaddingLength
915 if endLength > len(bytes): 998 if endLength > len(b):
916 macGood = False 999 macGood = False
917 else: 1000 else:
918 #Read MAC 1001 #Read MAC
919 startIndex = len(bytes) - endLength 1002 startIndex = len(b) - endLength
920 endIndex = startIndex + macLength 1003 endIndex = startIndex + macLength
921 checkBytes = bytes[startIndex : endIndex] 1004 checkBytes = b[startIndex : endIndex]
922 1005
923 #Calculate MAC 1006 #Calculate MAC
924 seqnumStr = self._readState.getSeqNumStr() 1007 seqnumBytes = self._readState.getSeqNumBytes()
925 bytes = bytes[:-endLength] 1008 b = b[:-endLength]
926 bytesStr = bytesToString(bytes)
927 mac = self._readState.macContext.copy() 1009 mac = self._readState.macContext.copy()
928 mac.update(seqnumStr) 1010 mac.update(compatHMAC(seqnumBytes))
929 mac.update(chr(recordType)) 1011 mac.update(compatHMAC(bytearray([recordType])))
930 if self.version == (3,0): 1012 if self.version == (3,0):
931 mac.update( chr( int(len(bytes)/256) ) ) 1013 mac.update( compatHMAC(bytearray( [len(b)//256] ) ))
932 mac.update( chr( int(len(bytes)%256) ) ) 1014 mac.update( compatHMAC(bytearray( [len(b)%256] ) ))
933 elif self.version in ((3,1), (3,2)): 1015 elif self.version in ((3,1), (3,2)):
934 mac.update(chr(self.version[0])) 1016 mac.update(compatHMAC(bytearray( [self.version[0]] ) ))
935 mac.update(chr(self.version[1])) 1017 mac.update(compatHMAC(bytearray( [self.version[1]] ) ))
936 mac.update( chr( int(len(bytes)/256) ) ) 1018 mac.update(compatHMAC(bytearray( [len(b)//256] ) ))
937 mac.update( chr( int(len(bytes)%256) ) ) 1019 mac.update(compatHMAC(bytearray( [len(b)%256] ) ))
938 else: 1020 else:
939 raise AssertionError() 1021 raise AssertionError()
940 mac.update(bytesStr) 1022 mac.update(compatHMAC(b))
941 macString = mac.digest() 1023 macBytes = bytearray(mac.digest())
942 macBytes = stringToBytes(macString)
943 1024
944 #Compare MACs 1025 #Compare MACs
945 if macBytes != checkBytes: 1026 if macBytes != checkBytes:
946 macGood = False 1027 macGood = False
947 1028
948 if not (paddingGood and macGood): 1029 if not (paddingGood and macGood):
949 for result in self._sendError(AlertDescription.bad_record_mac, 1030 for result in self._sendError(AlertDescription.bad_record_mac,
950 "MAC failure (or padding failure)"): 1031 "MAC failure (or padding failure)"):
951 yield result 1032 yield result
952 1033
953 yield bytes 1034 yield b
954 1035
955 def _handshakeStart(self, client): 1036 def _handshakeStart(self, client):
1037 if not self.closed:
1038 raise ValueError("Renegotiation disallowed for security reasons")
956 self._client = client 1039 self._client = client
957 self._handshake_md5 = md5.md5() 1040 self._handshake_md5 = hashlib.md5()
958 self._handshake_sha = sha.sha() 1041 self._handshake_sha = hashlib.sha1()
959 self._handshakeBuffer = [] 1042 self._handshakeBuffer = []
960 self.allegedSharedKeyUsername = None
961 self.allegedSrpUsername = None 1043 self.allegedSrpUsername = None
962 self._refCount = 1 1044 self._refCount = 1
963 1045
964 def _handshakeDone(self, resumed): 1046 def _handshakeDone(self, resumed):
965 self.resumed = resumed 1047 self.resumed = resumed
966 self.closed = False 1048 self.closed = False
967 1049
968 def _calcPendingStates(self, clientRandom, serverRandom, implementations): 1050 def _calcPendingStates(self, cipherSuite, masterSecret,
969 if self.session.cipherSuite in CipherSuite.aes128Suites: 1051 clientRandom, serverRandom, implementations):
970 macLength = 20 1052 if cipherSuite in CipherSuite.aes128Suites:
971 keyLength = 16 1053 keyLength = 16
972 ivLength = 16 1054 ivLength = 16
973 createCipherFunc = createAES 1055 createCipherFunc = createAES
974 elif self.session.cipherSuite in CipherSuite.aes256Suites: 1056 elif cipherSuite in CipherSuite.aes256Suites:
975 macLength = 20
976 keyLength = 32 1057 keyLength = 32
977 ivLength = 16 1058 ivLength = 16
978 createCipherFunc = createAES 1059 createCipherFunc = createAES
979 elif self.session.cipherSuite in CipherSuite.rc4Suites: 1060 elif cipherSuite in CipherSuite.rc4Suites:
980 macLength = 20
981 keyLength = 16 1061 keyLength = 16
982 ivLength = 0 1062 ivLength = 0
983 createCipherFunc = createRC4 1063 createCipherFunc = createRC4
984 elif self.session.cipherSuite in CipherSuite.tripleDESSuites: 1064 elif cipherSuite in CipherSuite.tripleDESSuites:
985 macLength = 20
986 keyLength = 24 1065 keyLength = 24
987 ivLength = 8 1066 ivLength = 8
988 createCipherFunc = createTripleDES 1067 createCipherFunc = createTripleDES
989 else: 1068 else:
990 raise AssertionError() 1069 raise AssertionError()
1070
1071 if cipherSuite in CipherSuite.shaSuites:
1072 macLength = 20
1073 digestmod = hashlib.sha1
1074 elif cipherSuite in CipherSuite.md5Suites:
1075 macLength = 16
1076 digestmod = hashlib.md5
991 1077
992 if self.version == (3,0): 1078 if self.version == (3,0):
993 createMACFunc = MAC_SSL 1079 createMACFunc = createMAC_SSL
994 elif self.version in ((3,1), (3,2)): 1080 elif self.version in ((3,1), (3,2)):
995 createMACFunc = hmac.HMAC 1081 createMACFunc = createHMAC
996 1082
997 outputLength = (macLength*2) + (keyLength*2) + (ivLength*2) 1083 outputLength = (macLength*2) + (keyLength*2) + (ivLength*2)
998 1084
999 #Calculate Keying Material from Master Secret 1085 #Calculate Keying Material from Master Secret
1000 if self.version == (3,0): 1086 if self.version == (3,0):
1001 keyBlock = PRF_SSL(self.session.masterSecret, 1087 keyBlock = PRF_SSL(masterSecret,
1002 concatArrays(serverRandom, clientRandom), 1088 serverRandom + clientRandom,
1003 outputLength) 1089 outputLength)
1004 elif self.version in ((3,1), (3,2)): 1090 elif self.version in ((3,1), (3,2)):
1005 keyBlock = PRF(self.session.masterSecret, 1091 keyBlock = PRF(masterSecret,
1006 "key expansion", 1092 b"key expansion",
1007 concatArrays(serverRandom,clientRandom), 1093 serverRandom + clientRandom,
1008 outputLength) 1094 outputLength)
1009 else: 1095 else:
1010 raise AssertionError() 1096 raise AssertionError()
1011 1097
1012 #Slice up Keying Material 1098 #Slice up Keying Material
1013 clientPendingState = _ConnectionState() 1099 clientPendingState = _ConnectionState()
1014 serverPendingState = _ConnectionState() 1100 serverPendingState = _ConnectionState()
1015 p = Parser(keyBlock) 1101 p = Parser(keyBlock)
1016 clientMACBlock = bytesToString(p.getFixBytes(macLength)) 1102 clientMACBlock = p.getFixBytes(macLength)
1017 serverMACBlock = bytesToString(p.getFixBytes(macLength)) 1103 serverMACBlock = p.getFixBytes(macLength)
1018 clientKeyBlock = bytesToString(p.getFixBytes(keyLength)) 1104 clientKeyBlock = p.getFixBytes(keyLength)
1019 serverKeyBlock = bytesToString(p.getFixBytes(keyLength)) 1105 serverKeyBlock = p.getFixBytes(keyLength)
1020 clientIVBlock = bytesToString(p.getFixBytes(ivLength)) 1106 clientIVBlock = p.getFixBytes(ivLength)
1021 serverIVBlock = bytesToString(p.getFixBytes(ivLength)) 1107 serverIVBlock = p.getFixBytes(ivLength)
1022 clientPendingState.macContext = createMACFunc(clientMACBlock, 1108 clientPendingState.macContext = createMACFunc(
1023 digestmod=sha) 1109 compatHMAC(clientMACBlock), digestmod=digestmod)
1024 serverPendingState.macContext = createMACFunc(serverMACBlock, 1110 serverPendingState.macContext = createMACFunc(
1025 digestmod=sha) 1111 compatHMAC(serverMACBlock), digestmod=digestmod)
1026 clientPendingState.encContext = createCipherFunc(clientKeyBlock, 1112 clientPendingState.encContext = createCipherFunc(clientKeyBlock,
1027 clientIVBlock, 1113 clientIVBlock,
1028 implementations) 1114 implementations)
1029 serverPendingState.encContext = createCipherFunc(serverKeyBlock, 1115 serverPendingState.encContext = createCipherFunc(serverKeyBlock,
1030 serverIVBlock, 1116 serverIVBlock,
1031 implementations) 1117 implementations)
1032 1118
1033 #Assign new connection states to pending states 1119 #Assign new connection states to pending states
1034 if self._client: 1120 if self._client:
1035 self._pendingWriteState = clientPendingState 1121 self._pendingWriteState = clientPendingState
1036 self._pendingReadState = serverPendingState 1122 self._pendingReadState = serverPendingState
1037 else: 1123 else:
1038 self._pendingWriteState = serverPendingState 1124 self._pendingWriteState = serverPendingState
1039 self._pendingReadState = clientPendingState 1125 self._pendingReadState = clientPendingState
1040 1126
1041 if self.version == (3,2) and ivLength: 1127 if self.version == (3,2) and ivLength:
1042 #Choose fixedIVBlock for TLS 1.1 (this is encrypted with the CBC 1128 #Choose fixedIVBlock for TLS 1.1 (this is encrypted with the CBC
1043 #residue to create the IV for each sent block) 1129 #residue to create the IV for each sent block)
1044 self.fixedIVBlock = getRandomBytes(ivLength) 1130 self.fixedIVBlock = getRandomBytes(ivLength)
1045 1131
1046 def _changeWriteState(self): 1132 def _changeWriteState(self):
1047 self._writeState = self._pendingWriteState 1133 self._writeState = self._pendingWriteState
1048 self._pendingWriteState = _ConnectionState() 1134 self._pendingWriteState = _ConnectionState()
1049 1135
1050 def _changeReadState(self): 1136 def _changeReadState(self):
1051 self._readState = self._pendingReadState 1137 self._readState = self._pendingReadState
1052 self._pendingReadState = _ConnectionState() 1138 self._pendingReadState = _ConnectionState()
1053 1139
1054 def _sendFinished(self):
1055 #Send ChangeCipherSpec
1056 for result in self._sendMsg(ChangeCipherSpec()):
1057 yield result
1058
1059 #Switch to pending write state
1060 self._changeWriteState()
1061
1062 #Calculate verification data
1063 verifyData = self._calcFinished(True)
1064 if self.fault == Fault.badFinished:
1065 verifyData[0] = (verifyData[0]+1)%256
1066
1067 #Send Finished message under new state
1068 finished = Finished(self.version).create(verifyData)
1069 for result in self._sendMsg(finished):
1070 yield result
1071
1072 def _getChangeCipherSpec(self):
1073 #Get and check ChangeCipherSpec
1074 for result in self._getMsg(ContentType.change_cipher_spec):
1075 if result in (0,1):
1076 yield result
1077 changeCipherSpec = result
1078
1079 if changeCipherSpec.type != 1:
1080 for result in self._sendError(AlertDescription.illegal_parameter,
1081 "ChangeCipherSpec type incorrect"):
1082 yield result
1083
1084 #Switch to pending read state
1085 self._changeReadState()
1086
1087 def _getEncryptedExtensions(self):
1088 for result in self._getMsg(ContentType.handshake,
1089 HandshakeType.encrypted_extensions):
1090 if result in (0,1):
1091 yield result
1092 encrypted_extensions = result
1093 self.channel_id = encrypted_extensions.channel_id_key
1094
1095 def _getFinished(self):
1096 #Calculate verification data
1097 verifyData = self._calcFinished(False)
1098
1099 #Get and check Finished message under new state
1100 for result in self._getMsg(ContentType.handshake,
1101 HandshakeType.finished):
1102 if result in (0,1):
1103 yield result
1104 finished = result
1105 if finished.verify_data != verifyData:
1106 for result in self._sendError(AlertDescription.decrypt_error,
1107 "Finished message is incorrect"):
1108 yield result
1109
1110 def _calcFinished(self, send=True):
1111 if self.version == (3,0):
1112 if (self._client and send) or (not self._client and not send):
1113 senderStr = "\x43\x4C\x4E\x54"
1114 else:
1115 senderStr = "\x53\x52\x56\x52"
1116
1117 verifyData = self._calcSSLHandshakeHash(self.session.masterSecret,
1118 senderStr)
1119 return verifyData
1120
1121 elif self.version in ((3,1), (3,2)):
1122 if (self._client and send) or (not self._client and not send):
1123 label = "client finished"
1124 else:
1125 label = "server finished"
1126
1127 handshakeHashes = stringToBytes(self._handshake_md5.digest() + \
1128 self._handshake_sha.digest())
1129 verifyData = PRF(self.session.masterSecret, label, handshakeHashes,
1130 12)
1131 return verifyData
1132 else:
1133 raise AssertionError()
1134
1135 #Used for Finished messages and CertificateVerify messages in SSL v3 1140 #Used for Finished messages and CertificateVerify messages in SSL v3
1136 def _calcSSLHandshakeHash(self, masterSecret, label): 1141 def _calcSSLHandshakeHash(self, masterSecret, label):
1137 masterSecretStr = bytesToString(masterSecret)
1138
1139 imac_md5 = self._handshake_md5.copy() 1142 imac_md5 = self._handshake_md5.copy()
1140 imac_sha = self._handshake_sha.copy() 1143 imac_sha = self._handshake_sha.copy()
1141 1144
1142 imac_md5.update(label + masterSecretStr + '\x36'*48) 1145 imac_md5.update(compatHMAC(label + masterSecret + bytearray([0x36]*48)))
1143 imac_sha.update(label + masterSecretStr + '\x36'*40) 1146 imac_sha.update(compatHMAC(label + masterSecret + bytearray([0x36]*40)))
1144 1147
1145 md5Str = md5.md5(masterSecretStr + ('\x5c'*48) + \ 1148 md5Bytes = MD5(masterSecret + bytearray([0x5c]*48) + \
1146 imac_md5.digest()).digest() 1149 bytearray(imac_md5.digest()))
1147 shaStr = sha.sha(masterSecretStr + ('\x5c'*40) + \ 1150 shaBytes = SHA1(masterSecret + bytearray([0x5c]*40) + \
1148 imac_sha.digest()).digest() 1151 bytearray(imac_sha.digest()))
1149 1152
1150 return stringToBytes(md5Str + shaStr) 1153 return md5Bytes + shaBytes
1154
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698