PageRenderTime 62ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/gdata/tlslite/TLSConnection.py

http://radioappz.googlecode.com/
Python | 1487 lines | 1233 code | 120 blank | 134 comment | 191 complexity | 488f8801392a6ecc58a9c48c0afcc63c MD5 | raw file
  1. """
  2. MAIN CLASS FOR TLS LITE (START HERE!).
  3. """
  4. from __future__ import generators
  5. import socket
  6. from utils.compat import formatExceptionTrace
  7. from TLSRecordLayer import TLSRecordLayer
  8. from Session import Session
  9. from constants import *
  10. from utils.cryptomath import getRandomBytes
  11. from errors import *
  12. from messages import *
  13. from mathtls import *
  14. from HandshakeSettings import HandshakeSettings
  15. class TLSConnection(TLSRecordLayer):
  16. """
  17. This class wraps a socket and provides TLS handshaking and data
  18. transfer.
  19. To use this class, create a new instance, passing a connected
  20. socket into the constructor. Then call some handshake function.
  21. If the handshake completes without raising an exception, then a TLS
  22. connection has been negotiated. You can transfer data over this
  23. connection as if it were a socket.
  24. This class provides both synchronous and asynchronous versions of
  25. its key functions. The synchronous versions should be used when
  26. writing single-or multi-threaded code using blocking sockets. The
  27. asynchronous versions should be used when performing asynchronous,
  28. event-based I/O with non-blocking sockets.
  29. Asynchronous I/O is a complicated subject; typically, you should
  30. not use the asynchronous functions directly, but should use some
  31. framework like asyncore or Twisted which TLS Lite integrates with
  32. (see
  33. L{tlslite.integration.TLSAsyncDispatcherMixIn.TLSAsyncDispatcherMixIn} or
  34. L{tlslite.integration.TLSTwistedProtocolWrapper.TLSTwistedProtocolWrapper}).
  35. """
  36. def __init__(self, sock):
  37. """Create a new TLSConnection instance.
  38. @param sock: The socket data will be transmitted on. The
  39. socket should already be connected. It may be in blocking or
  40. non-blocking mode.
  41. @type sock: L{socket.socket}
  42. """
  43. TLSRecordLayer.__init__(self, sock)
  44. def handshakeClientSRP(self, username, password, session=None,
  45. settings=None, checker=None, async=False):
  46. """Perform an SRP handshake in the role of client.
  47. This function performs a TLS/SRP handshake. SRP mutually
  48. authenticates both parties to each other using only a
  49. username and password. This function may also perform a
  50. combined SRP and server-certificate handshake, if the server
  51. chooses to authenticate itself with a certificate chain in
  52. addition to doing SRP.
  53. TLS/SRP is non-standard. Most TLS implementations don't
  54. support it. See
  55. U{http://www.ietf.org/html.charters/tls-charter.html} or
  56. U{http://trevp.net/tlssrp/} for the latest information on
  57. TLS/SRP.
  58. Like any handshake function, this can be called on a closed
  59. TLS connection, or on a TLS connection that is already open.
  60. If called on an open connection it performs a re-handshake.
  61. If the function completes without raising an exception, the
  62. TLS connection will be open and available for data transfer.
  63. If an exception is raised, the connection will have been
  64. automatically closed (if it was ever open).
  65. @type username: str
  66. @param username: The SRP username.
  67. @type password: str
  68. @param password: The SRP password.
  69. @type session: L{tlslite.Session.Session}
  70. @param session: A TLS session to attempt to resume. This
  71. session must be an SRP session performed with the same username
  72. and password as were passed in. If the resumption does not
  73. succeed, a full SRP handshake will be performed.
  74. @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
  75. @param settings: Various settings which can be used to control
  76. the ciphersuites, certificate types, and SSL/TLS versions
  77. offered by the client.
  78. @type checker: L{tlslite.Checker.Checker}
  79. @param checker: A Checker instance. This instance will be
  80. invoked to examine the other party's authentication
  81. credentials, if the handshake completes succesfully.
  82. @type async: bool
  83. @param async: If False, this function will block until the
  84. handshake is completed. If True, this function will return a
  85. generator. Successive invocations of the generator will
  86. return 0 if it is waiting to read from the socket, 1 if it is
  87. waiting to write to the socket, or will raise StopIteration if
  88. the handshake operation is completed.
  89. @rtype: None or an iterable
  90. @return: If 'async' is True, a generator object will be
  91. returned.
  92. @raise socket.error: If a socket error occurs.
  93. @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
  94. without a preceding alert.
  95. @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
  96. @raise tlslite.errors.TLSAuthenticationError: If the checker
  97. doesn't like the other party's authentication credentials.
  98. """
  99. handshaker = self._handshakeClientAsync(srpParams=(username, password),
  100. session=session, settings=settings, checker=checker)
  101. if async:
  102. return handshaker
  103. for result in handshaker:
  104. pass
  105. def handshakeClientCert(self, certChain=None, privateKey=None,
  106. session=None, settings=None, checker=None,
  107. async=False):
  108. """Perform a certificate-based handshake in the role of client.
  109. This function performs an SSL or TLS handshake. The server
  110. will authenticate itself using an X.509 or cryptoID certificate
  111. chain. If the handshake succeeds, the server's certificate
  112. chain will be stored in the session's serverCertChain attribute.
  113. Unless a checker object is passed in, this function does no
  114. validation or checking of the server's certificate chain.
  115. If the server requests client authentication, the
  116. client will send the passed-in certificate chain, and use the
  117. passed-in private key to authenticate itself. If no
  118. certificate chain and private key were passed in, the client
  119. will attempt to proceed without client authentication. The
  120. server may or may not allow this.
  121. Like any handshake function, this can be called on a closed
  122. TLS connection, or on a TLS connection that is already open.
  123. If called on an open connection it performs a re-handshake.
  124. If the function completes without raising an exception, the
  125. TLS connection will be open and available for data transfer.
  126. If an exception is raised, the connection will have been
  127. automatically closed (if it was ever open).
  128. @type certChain: L{tlslite.X509CertChain.X509CertChain} or
  129. L{cryptoIDlib.CertChain.CertChain}
  130. @param certChain: The certificate chain to be used if the
  131. server requests client authentication.
  132. @type privateKey: L{tlslite.utils.RSAKey.RSAKey}
  133. @param privateKey: The private key to be used if the server
  134. requests client authentication.
  135. @type session: L{tlslite.Session.Session}
  136. @param session: A TLS session to attempt to resume. If the
  137. resumption does not succeed, a full handshake will be
  138. performed.
  139. @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
  140. @param settings: Various settings which can be used to control
  141. the ciphersuites, certificate types, and SSL/TLS versions
  142. offered by the client.
  143. @type checker: L{tlslite.Checker.Checker}
  144. @param checker: A Checker instance. This instance will be
  145. invoked to examine the other party's authentication
  146. credentials, if the handshake completes succesfully.
  147. @type async: bool
  148. @param async: If False, this function will block until the
  149. handshake is completed. If True, this function will return a
  150. generator. Successive invocations of the generator will
  151. return 0 if it is waiting to read from the socket, 1 if it is
  152. waiting to write to the socket, or will raise StopIteration if
  153. the handshake operation is completed.
  154. @rtype: None or an iterable
  155. @return: If 'async' is True, a generator object will be
  156. returned.
  157. @raise socket.error: If a socket error occurs.
  158. @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
  159. without a preceding alert.
  160. @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
  161. @raise tlslite.errors.TLSAuthenticationError: If the checker
  162. doesn't like the other party's authentication credentials.
  163. """
  164. handshaker = self._handshakeClientAsync(certParams=(certChain,
  165. privateKey), session=session, settings=settings,
  166. checker=checker)
  167. if async:
  168. return handshaker
  169. for result in handshaker:
  170. pass
  171. def handshakeClientUnknown(self, srpCallback=None, certCallback=None,
  172. session=None, settings=None, checker=None,
  173. async=False):
  174. """Perform a to-be-determined type of handshake in the role of client.
  175. This function performs an SSL or TLS handshake. If the server
  176. requests client certificate authentication, the
  177. certCallback will be invoked and should return a (certChain,
  178. privateKey) pair. If the callback returns None, the library
  179. will attempt to proceed without client authentication. The
  180. server may or may not allow this.
  181. If the server requests SRP authentication, the srpCallback
  182. will be invoked and should return a (username, password) pair.
  183. If the callback returns None, the local implementation will
  184. signal a user_canceled error alert.
  185. After the handshake completes, the client can inspect the
  186. connection's session attribute to determine what type of
  187. authentication was performed.
  188. Like any handshake function, this can be called on a closed
  189. TLS connection, or on a TLS connection that is already open.
  190. If called on an open connection it performs a re-handshake.
  191. If the function completes without raising an exception, the
  192. TLS connection will be open and available for data transfer.
  193. If an exception is raised, the connection will have been
  194. automatically closed (if it was ever open).
  195. @type srpCallback: callable
  196. @param srpCallback: The callback to be used if the server
  197. requests SRP authentication. If None, the client will not
  198. offer support for SRP ciphersuites.
  199. @type certCallback: callable
  200. @param certCallback: The callback to be used if the server
  201. requests client certificate authentication.
  202. @type session: L{tlslite.Session.Session}
  203. @param session: A TLS session to attempt to resume. If the
  204. resumption does not succeed, a full handshake will be
  205. performed.
  206. @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
  207. @param settings: Various settings which can be used to control
  208. the ciphersuites, certificate types, and SSL/TLS versions
  209. offered by the client.
  210. @type checker: L{tlslite.Checker.Checker}
  211. @param checker: A Checker instance. This instance will be
  212. invoked to examine the other party's authentication
  213. credentials, if the handshake completes succesfully.
  214. @type async: bool
  215. @param async: If False, this function will block until the
  216. handshake is completed. If True, this function will return a
  217. generator. Successive invocations of the generator will
  218. return 0 if it is waiting to read from the socket, 1 if it is
  219. waiting to write to the socket, or will raise StopIteration if
  220. the handshake operation is completed.
  221. @rtype: None or an iterable
  222. @return: If 'async' is True, a generator object will be
  223. returned.
  224. @raise socket.error: If a socket error occurs.
  225. @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
  226. without a preceding alert.
  227. @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
  228. @raise tlslite.errors.TLSAuthenticationError: If the checker
  229. doesn't like the other party's authentication credentials.
  230. """
  231. handshaker = self._handshakeClientAsync(unknownParams=(srpCallback,
  232. certCallback), session=session, settings=settings,
  233. checker=checker)
  234. if async:
  235. return handshaker
  236. for result in handshaker:
  237. pass
  238. def handshakeClientSharedKey(self, username, sharedKey, settings=None,
  239. checker=None, async=False):
  240. """Perform a shared-key handshake in the role of client.
  241. This function performs a shared-key handshake. Using shared
  242. symmetric keys of high entropy (128 bits or greater) mutually
  243. authenticates both parties to each other.
  244. TLS with shared-keys is non-standard. Most TLS
  245. implementations don't support it. See
  246. U{http://www.ietf.org/html.charters/tls-charter.html} for the
  247. latest information on TLS with shared-keys. If the shared-keys
  248. Internet-Draft changes or is superceded, TLS Lite will track
  249. those changes, so the shared-key support in later versions of
  250. TLS Lite may become incompatible with this version.
  251. Like any handshake function, this can be called on a closed
  252. TLS connection, or on a TLS connection that is already open.
  253. If called on an open connection it performs a re-handshake.
  254. If the function completes without raising an exception, the
  255. TLS connection will be open and available for data transfer.
  256. If an exception is raised, the connection will have been
  257. automatically closed (if it was ever open).
  258. @type username: str
  259. @param username: The shared-key username.
  260. @type sharedKey: str
  261. @param sharedKey: The shared key.
  262. @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
  263. @param settings: Various settings which can be used to control
  264. the ciphersuites, certificate types, and SSL/TLS versions
  265. offered by the client.
  266. @type checker: L{tlslite.Checker.Checker}
  267. @param checker: A Checker instance. This instance will be
  268. invoked to examine the other party's authentication
  269. credentials, if the handshake completes succesfully.
  270. @type async: bool
  271. @param async: If False, this function will block until the
  272. handshake is completed. If True, this function will return a
  273. generator. Successive invocations of the generator will
  274. return 0 if it is waiting to read from the socket, 1 if it is
  275. waiting to write to the socket, or will raise StopIteration if
  276. the handshake operation is completed.
  277. @rtype: None or an iterable
  278. @return: If 'async' is True, a generator object will be
  279. returned.
  280. @raise socket.error: If a socket error occurs.
  281. @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
  282. without a preceding alert.
  283. @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
  284. @raise tlslite.errors.TLSAuthenticationError: If the checker
  285. doesn't like the other party's authentication credentials.
  286. """
  287. handshaker = self._handshakeClientAsync(sharedKeyParams=(username,
  288. sharedKey), settings=settings, checker=checker)
  289. if async:
  290. return handshaker
  291. for result in handshaker:
  292. pass
  293. def _handshakeClientAsync(self, srpParams=(), certParams=(),
  294. unknownParams=(), sharedKeyParams=(),
  295. session=None, settings=None, checker=None,
  296. recursive=False):
  297. handshaker = self._handshakeClientAsyncHelper(srpParams=srpParams,
  298. certParams=certParams, unknownParams=unknownParams,
  299. sharedKeyParams=sharedKeyParams, session=session,
  300. settings=settings, recursive=recursive)
  301. for result in self._handshakeWrapperAsync(handshaker, checker):
  302. yield result
  303. def _handshakeClientAsyncHelper(self, srpParams, certParams, unknownParams,
  304. sharedKeyParams, session, settings, recursive):
  305. if not recursive:
  306. self._handshakeStart(client=True)
  307. #Unpack parameters
  308. srpUsername = None # srpParams
  309. password = None # srpParams
  310. clientCertChain = None # certParams
  311. privateKey = None # certParams
  312. srpCallback = None # unknownParams
  313. certCallback = None # unknownParams
  314. #session # sharedKeyParams (or session)
  315. #settings # settings
  316. if srpParams:
  317. srpUsername, password = srpParams
  318. elif certParams:
  319. clientCertChain, privateKey = certParams
  320. elif unknownParams:
  321. srpCallback, certCallback = unknownParams
  322. elif sharedKeyParams:
  323. session = Session()._createSharedKey(*sharedKeyParams)
  324. if not settings:
  325. settings = HandshakeSettings()
  326. settings = settings._filter()
  327. #Validate parameters
  328. if srpUsername and not password:
  329. raise ValueError("Caller passed a username but no password")
  330. if password and not srpUsername:
  331. raise ValueError("Caller passed a password but no username")
  332. if clientCertChain and not privateKey:
  333. raise ValueError("Caller passed a certChain but no privateKey")
  334. if privateKey and not clientCertChain:
  335. raise ValueError("Caller passed a privateKey but no certChain")
  336. if clientCertChain:
  337. foundType = False
  338. try:
  339. import cryptoIDlib.CertChain
  340. if isinstance(clientCertChain, cryptoIDlib.CertChain.CertChain):
  341. if "cryptoID" not in settings.certificateTypes:
  342. raise ValueError("Client certificate doesn't "\
  343. "match Handshake Settings")
  344. settings.certificateTypes = ["cryptoID"]
  345. foundType = True
  346. except ImportError:
  347. pass
  348. if not foundType and isinstance(clientCertChain,
  349. X509CertChain):
  350. if "x509" not in settings.certificateTypes:
  351. raise ValueError("Client certificate doesn't match "\
  352. "Handshake Settings")
  353. settings.certificateTypes = ["x509"]
  354. foundType = True
  355. if not foundType:
  356. raise ValueError("Unrecognized certificate type")
  357. if session:
  358. if not session.valid():
  359. session = None #ignore non-resumable sessions...
  360. elif session.resumable and \
  361. (session.srpUsername != srpUsername):
  362. raise ValueError("Session username doesn't match")
  363. #Add Faults to parameters
  364. if srpUsername and self.fault == Fault.badUsername:
  365. srpUsername += "GARBAGE"
  366. if password and self.fault == Fault.badPassword:
  367. password += "GARBAGE"
  368. if sharedKeyParams:
  369. identifier = sharedKeyParams[0]
  370. sharedKey = sharedKeyParams[1]
  371. if self.fault == Fault.badIdentifier:
  372. identifier += "GARBAGE"
  373. session = Session()._createSharedKey(identifier, sharedKey)
  374. elif self.fault == Fault.badSharedKey:
  375. sharedKey += "GARBAGE"
  376. session = Session()._createSharedKey(identifier, sharedKey)
  377. #Initialize locals
  378. serverCertChain = None
  379. cipherSuite = 0
  380. certificateType = CertificateType.x509
  381. premasterSecret = None
  382. #Get client nonce
  383. clientRandom = getRandomBytes(32)
  384. #Initialize acceptable ciphersuites
  385. cipherSuites = []
  386. if srpParams:
  387. cipherSuites += CipherSuite.getSrpRsaSuites(settings.cipherNames)
  388. cipherSuites += CipherSuite.getSrpSuites(settings.cipherNames)
  389. elif certParams:
  390. cipherSuites += CipherSuite.getRsaSuites(settings.cipherNames)
  391. elif unknownParams:
  392. if srpCallback:
  393. cipherSuites += \
  394. CipherSuite.getSrpRsaSuites(settings.cipherNames)
  395. cipherSuites += \
  396. CipherSuite.getSrpSuites(settings.cipherNames)
  397. cipherSuites += CipherSuite.getRsaSuites(settings.cipherNames)
  398. elif sharedKeyParams:
  399. cipherSuites += CipherSuite.getRsaSuites(settings.cipherNames)
  400. else:
  401. cipherSuites += CipherSuite.getRsaSuites(settings.cipherNames)
  402. #Initialize acceptable certificate types
  403. certificateTypes = settings._getCertificateTypes()
  404. #Tentatively set the version to the client's minimum version.
  405. #We'll use this for the ClientHello, and if an error occurs
  406. #parsing the Server Hello, we'll use this version for the response
  407. self.version = settings.maxVersion
  408. #Either send ClientHello (with a resumable session)...
  409. if session:
  410. #If it's a resumable (i.e. not a shared-key session), then its
  411. #ciphersuite must be one of the acceptable ciphersuites
  412. if (not sharedKeyParams) and \
  413. session.cipherSuite not in cipherSuites:
  414. raise ValueError("Session's cipher suite not consistent "\
  415. "with parameters")
  416. else:
  417. clientHello = ClientHello()
  418. clientHello.create(settings.maxVersion, clientRandom,
  419. session.sessionID, cipherSuites,
  420. certificateTypes, session.srpUsername)
  421. #Or send ClientHello (without)
  422. else:
  423. clientHello = ClientHello()
  424. clientHello.create(settings.maxVersion, clientRandom,
  425. createByteArraySequence([]), cipherSuites,
  426. certificateTypes, srpUsername)
  427. for result in self._sendMsg(clientHello):
  428. yield result
  429. #Get ServerHello (or missing_srp_username)
  430. for result in self._getMsg((ContentType.handshake,
  431. ContentType.alert),
  432. HandshakeType.server_hello):
  433. if result in (0,1):
  434. yield result
  435. else:
  436. break
  437. msg = result
  438. if isinstance(msg, ServerHello):
  439. serverHello = msg
  440. elif isinstance(msg, Alert):
  441. alert = msg
  442. #If it's not a missing_srp_username, re-raise
  443. if alert.description != AlertDescription.missing_srp_username:
  444. self._shutdown(False)
  445. raise TLSRemoteAlert(alert)
  446. #If we're not in SRP callback mode, we won't have offered SRP
  447. #without a username, so we shouldn't get this alert
  448. if not srpCallback:
  449. for result in self._sendError(\
  450. AlertDescription.unexpected_message):
  451. yield result
  452. srpParams = srpCallback()
  453. #If the callback returns None, cancel the handshake
  454. if srpParams == None:
  455. for result in self._sendError(AlertDescription.user_canceled):
  456. yield result
  457. #Recursively perform handshake
  458. for result in self._handshakeClientAsyncHelper(srpParams,
  459. None, None, None, None, settings, True):
  460. yield result
  461. return
  462. #Get the server version. Do this before anything else, so any
  463. #error alerts will use the server's version
  464. self.version = serverHello.server_version
  465. #Future responses from server must use this version
  466. self._versionCheck = True
  467. #Check ServerHello
  468. if serverHello.server_version < settings.minVersion:
  469. for result in self._sendError(\
  470. AlertDescription.protocol_version,
  471. "Too old version: %s" % str(serverHello.server_version)):
  472. yield result
  473. if serverHello.server_version > settings.maxVersion:
  474. for result in self._sendError(\
  475. AlertDescription.protocol_version,
  476. "Too new version: %s" % str(serverHello.server_version)):
  477. yield result
  478. if serverHello.cipher_suite not in cipherSuites:
  479. for result in self._sendError(\
  480. AlertDescription.illegal_parameter,
  481. "Server responded with incorrect ciphersuite"):
  482. yield result
  483. if serverHello.certificate_type not in certificateTypes:
  484. for result in self._sendError(\
  485. AlertDescription.illegal_parameter,
  486. "Server responded with incorrect certificate type"):
  487. yield result
  488. if serverHello.compression_method != 0:
  489. for result in self._sendError(\
  490. AlertDescription.illegal_parameter,
  491. "Server responded with incorrect compression method"):
  492. yield result
  493. #Get the server nonce
  494. serverRandom = serverHello.random
  495. #If the server agrees to resume
  496. if session and session.sessionID and \
  497. serverHello.session_id == session.sessionID:
  498. #If a shared-key, we're flexible about suites; otherwise the
  499. #server-chosen suite has to match the session's suite
  500. if sharedKeyParams:
  501. session.cipherSuite = serverHello.cipher_suite
  502. elif serverHello.cipher_suite != session.cipherSuite:
  503. for result in self._sendError(\
  504. AlertDescription.illegal_parameter,\
  505. "Server's ciphersuite doesn't match session"):
  506. yield result
  507. #Set the session for this connection
  508. self.session = session
  509. #Calculate pending connection states
  510. self._calcPendingStates(clientRandom, serverRandom,
  511. settings.cipherImplementations)
  512. #Exchange ChangeCipherSpec and Finished messages
  513. for result in self._getFinished():
  514. yield result
  515. for result in self._sendFinished():
  516. yield result
  517. #Mark the connection as open
  518. self._handshakeDone(resumed=True)
  519. #If server DOES NOT agree to resume
  520. else:
  521. if sharedKeyParams:
  522. for result in self._sendError(\
  523. AlertDescription.user_canceled,
  524. "Was expecting a shared-key resumption"):
  525. yield result
  526. #We've already validated these
  527. cipherSuite = serverHello.cipher_suite
  528. certificateType = serverHello.certificate_type
  529. #If the server chose an SRP suite...
  530. if cipherSuite in CipherSuite.srpSuites:
  531. #Get ServerKeyExchange, ServerHelloDone
  532. for result in self._getMsg(ContentType.handshake,
  533. HandshakeType.server_key_exchange, cipherSuite):
  534. if result in (0,1):
  535. yield result
  536. else:
  537. break
  538. serverKeyExchange = result
  539. for result in self._getMsg(ContentType.handshake,
  540. HandshakeType.server_hello_done):
  541. if result in (0,1):
  542. yield result
  543. else:
  544. break
  545. serverHelloDone = result
  546. #If the server chose an SRP+RSA suite...
  547. elif cipherSuite in CipherSuite.srpRsaSuites:
  548. #Get Certificate, ServerKeyExchange, ServerHelloDone
  549. for result in self._getMsg(ContentType.handshake,
  550. HandshakeType.certificate, certificateType):
  551. if result in (0,1):
  552. yield result
  553. else:
  554. break
  555. serverCertificate = result
  556. for result in self._getMsg(ContentType.handshake,
  557. HandshakeType.server_key_exchange, cipherSuite):
  558. if result in (0,1):
  559. yield result
  560. else:
  561. break
  562. serverKeyExchange = result
  563. for result in self._getMsg(ContentType.handshake,
  564. HandshakeType.server_hello_done):
  565. if result in (0,1):
  566. yield result
  567. else:
  568. break
  569. serverHelloDone = result
  570. #If the server chose an RSA suite...
  571. elif cipherSuite in CipherSuite.rsaSuites:
  572. #Get Certificate[, CertificateRequest], ServerHelloDone
  573. for result in self._getMsg(ContentType.handshake,
  574. HandshakeType.certificate, certificateType):
  575. if result in (0,1):
  576. yield result
  577. else:
  578. break
  579. serverCertificate = result
  580. for result in self._getMsg(ContentType.handshake,
  581. (HandshakeType.server_hello_done,
  582. HandshakeType.certificate_request)):
  583. if result in (0,1):
  584. yield result
  585. else:
  586. break
  587. msg = result
  588. certificateRequest = None
  589. if isinstance(msg, CertificateRequest):
  590. certificateRequest = msg
  591. for result in self._getMsg(ContentType.handshake,
  592. HandshakeType.server_hello_done):
  593. if result in (0,1):
  594. yield result
  595. else:
  596. break
  597. serverHelloDone = result
  598. elif isinstance(msg, ServerHelloDone):
  599. serverHelloDone = msg
  600. else:
  601. raise AssertionError()
  602. #Calculate SRP premaster secret, if server chose an SRP or
  603. #SRP+RSA suite
  604. if cipherSuite in CipherSuite.srpSuites + \
  605. CipherSuite.srpRsaSuites:
  606. #Get and check the server's group parameters and B value
  607. N = serverKeyExchange.srp_N
  608. g = serverKeyExchange.srp_g
  609. s = serverKeyExchange.srp_s
  610. B = serverKeyExchange.srp_B
  611. if (g,N) not in goodGroupParameters:
  612. for result in self._sendError(\
  613. AlertDescription.untrusted_srp_parameters,
  614. "Unknown group parameters"):
  615. yield result
  616. if numBits(N) < settings.minKeySize:
  617. for result in self._sendError(\
  618. AlertDescription.untrusted_srp_parameters,
  619. "N value is too small: %d" % numBits(N)):
  620. yield result
  621. if numBits(N) > settings.maxKeySize:
  622. for result in self._sendError(\
  623. AlertDescription.untrusted_srp_parameters,
  624. "N value is too large: %d" % numBits(N)):
  625. yield result
  626. if B % N == 0:
  627. for result in self._sendError(\
  628. AlertDescription.illegal_parameter,
  629. "Suspicious B value"):
  630. yield result
  631. #Check the server's signature, if server chose an
  632. #SRP+RSA suite
  633. if cipherSuite in CipherSuite.srpRsaSuites:
  634. #Hash ServerKeyExchange/ServerSRPParams
  635. hashBytes = serverKeyExchange.hash(clientRandom,
  636. serverRandom)
  637. #Extract signature bytes from ServerKeyExchange
  638. sigBytes = serverKeyExchange.signature
  639. if len(sigBytes) == 0:
  640. for result in self._sendError(\
  641. AlertDescription.illegal_parameter,
  642. "Server sent an SRP ServerKeyExchange "\
  643. "message without a signature"):
  644. yield result
  645. #Get server's public key from the Certificate message
  646. for result in self._getKeyFromChain(serverCertificate,
  647. settings):
  648. if result in (0,1):
  649. yield result
  650. else:
  651. break
  652. publicKey, serverCertChain = result
  653. #Verify signature
  654. if not publicKey.verify(sigBytes, hashBytes):
  655. for result in self._sendError(\
  656. AlertDescription.decrypt_error,
  657. "Signature failed to verify"):
  658. yield result
  659. #Calculate client's ephemeral DH values (a, A)
  660. a = bytesToNumber(getRandomBytes(32))
  661. A = powMod(g, a, N)
  662. #Calculate client's static DH values (x, v)
  663. x = makeX(bytesToString(s), srpUsername, password)
  664. v = powMod(g, x, N)
  665. #Calculate u
  666. u = makeU(N, A, B)
  667. #Calculate premaster secret
  668. k = makeK(N, g)
  669. S = powMod((B - (k*v)) % N, a+(u*x), N)
  670. if self.fault == Fault.badA:
  671. A = N
  672. S = 0
  673. premasterSecret = numberToBytes(S)
  674. #Send ClientKeyExchange
  675. for result in self._sendMsg(\
  676. ClientKeyExchange(cipherSuite).createSRP(A)):
  677. yield result
  678. #Calculate RSA premaster secret, if server chose an RSA suite
  679. elif cipherSuite in CipherSuite.rsaSuites:
  680. #Handle the presence of a CertificateRequest
  681. if certificateRequest:
  682. if unknownParams and certCallback:
  683. certParamsNew = certCallback()
  684. if certParamsNew:
  685. clientCertChain, privateKey = certParamsNew
  686. #Get server's public key from the Certificate message
  687. for result in self._getKeyFromChain(serverCertificate,
  688. settings):
  689. if result in (0,1):
  690. yield result
  691. else:
  692. break
  693. publicKey, serverCertChain = result
  694. #Calculate premaster secret
  695. premasterSecret = getRandomBytes(48)
  696. premasterSecret[0] = settings.maxVersion[0]
  697. premasterSecret[1] = settings.maxVersion[1]
  698. if self.fault == Fault.badPremasterPadding:
  699. premasterSecret[0] = 5
  700. if self.fault == Fault.shortPremasterSecret:
  701. premasterSecret = premasterSecret[:-1]
  702. #Encrypt premaster secret to server's public key
  703. encryptedPreMasterSecret = publicKey.encrypt(premasterSecret)
  704. #If client authentication was requested, send Certificate
  705. #message, either with certificates or empty
  706. if certificateRequest:
  707. clientCertificate = Certificate(certificateType)
  708. if clientCertChain:
  709. #Check to make sure we have the same type of
  710. #certificates the server requested
  711. wrongType = False
  712. if certificateType == CertificateType.x509:
  713. if not isinstance(clientCertChain, X509CertChain):
  714. wrongType = True
  715. elif certificateType == CertificateType.cryptoID:
  716. if not isinstance(clientCertChain,
  717. cryptoIDlib.CertChain.CertChain):
  718. wrongType = True
  719. if wrongType:
  720. for result in self._sendError(\
  721. AlertDescription.handshake_failure,
  722. "Client certificate is of wrong type"):
  723. yield result
  724. clientCertificate.create(clientCertChain)
  725. for result in self._sendMsg(clientCertificate):
  726. yield result
  727. else:
  728. #The server didn't request client auth, so we
  729. #zeroize these so the clientCertChain won't be
  730. #stored in the session.
  731. privateKey = None
  732. clientCertChain = None
  733. #Send ClientKeyExchange
  734. clientKeyExchange = ClientKeyExchange(cipherSuite,
  735. self.version)
  736. clientKeyExchange.createRSA(encryptedPreMasterSecret)
  737. for result in self._sendMsg(clientKeyExchange):
  738. yield result
  739. #If client authentication was requested and we have a
  740. #private key, send CertificateVerify
  741. if certificateRequest and privateKey:
  742. if self.version == (3,0):
  743. #Create a temporary session object, just for the
  744. #purpose of creating the CertificateVerify
  745. session = Session()
  746. session._calcMasterSecret(self.version,
  747. premasterSecret,
  748. clientRandom,
  749. serverRandom)
  750. verifyBytes = self._calcSSLHandshakeHash(\
  751. session.masterSecret, "")
  752. elif self.version in ((3,1), (3,2)):
  753. verifyBytes = stringToBytes(\
  754. self._handshake_md5.digest() + \
  755. self._handshake_sha.digest())
  756. if self.fault == Fault.badVerifyMessage:
  757. verifyBytes[0] = ((verifyBytes[0]+1) % 256)
  758. signedBytes = privateKey.sign(verifyBytes)
  759. certificateVerify = CertificateVerify()
  760. certificateVerify.create(signedBytes)
  761. for result in self._sendMsg(certificateVerify):
  762. yield result
  763. #Create the session object
  764. self.session = Session()
  765. self.session._calcMasterSecret(self.version, premasterSecret,
  766. clientRandom, serverRandom)
  767. self.session.sessionID = serverHello.session_id
  768. self.session.cipherSuite = cipherSuite
  769. self.session.srpUsername = srpUsername
  770. self.session.clientCertChain = clientCertChain
  771. self.session.serverCertChain = serverCertChain
  772. #Calculate pending connection states
  773. self._calcPendingStates(clientRandom, serverRandom,
  774. settings.cipherImplementations)
  775. #Exchange ChangeCipherSpec and Finished messages
  776. for result in self._sendFinished():
  777. yield result
  778. for result in self._getFinished():
  779. yield result
  780. #Mark the connection as open
  781. self.session._setResumable(True)
  782. self._handshakeDone(resumed=False)
  783. def handshakeServer(self, sharedKeyDB=None, verifierDB=None,
  784. certChain=None, privateKey=None, reqCert=False,
  785. sessionCache=None, settings=None, checker=None):
  786. """Perform a handshake in the role of server.
  787. This function performs an SSL or TLS handshake. Depending on
  788. the arguments and the behavior of the client, this function can
  789. perform a shared-key, SRP, or certificate-based handshake. It
  790. can also perform a combined SRP and server-certificate
  791. handshake.
  792. Like any handshake function, this can be called on a closed
  793. TLS connection, or on a TLS connection that is already open.
  794. If called on an open connection it performs a re-handshake.
  795. This function does not send a Hello Request message before
  796. performing the handshake, so if re-handshaking is required,
  797. the server must signal the client to begin the re-handshake
  798. through some other means.
  799. If the function completes without raising an exception, the
  800. TLS connection will be open and available for data transfer.
  801. If an exception is raised, the connection will have been
  802. automatically closed (if it was ever open).
  803. @type sharedKeyDB: L{tlslite.SharedKeyDB.SharedKeyDB}
  804. @param sharedKeyDB: A database of shared symmetric keys
  805. associated with usernames. If the client performs a
  806. shared-key handshake, the session's sharedKeyUsername
  807. attribute will be set.
  808. @type verifierDB: L{tlslite.VerifierDB.VerifierDB}
  809. @param verifierDB: A database of SRP password verifiers
  810. associated with usernames. If the client performs an SRP
  811. handshake, the session's srpUsername attribute will be set.
  812. @type certChain: L{tlslite.X509CertChain.X509CertChain} or
  813. L{cryptoIDlib.CertChain.CertChain}
  814. @param certChain: The certificate chain to be used if the
  815. client requests server certificate authentication.
  816. @type privateKey: L{tlslite.utils.RSAKey.RSAKey}
  817. @param privateKey: The private key to be used if the client
  818. requests server certificate authentication.
  819. @type reqCert: bool
  820. @param reqCert: Whether to request client certificate
  821. authentication. This only applies if the client chooses server
  822. certificate authentication; if the client chooses SRP or
  823. shared-key authentication, this will be ignored. If the client
  824. performs a client certificate authentication, the sessions's
  825. clientCertChain attribute will be set.
  826. @type sessionCache: L{tlslite.SessionCache.SessionCache}
  827. @param sessionCache: An in-memory cache of resumable sessions.
  828. The client can resume sessions from this cache. Alternatively,
  829. if the client performs a full handshake, a new session will be
  830. added to the cache.
  831. @type settings: L{tlslite.HandshakeSettings.HandshakeSettings}
  832. @param settings: Various settings which can be used to control
  833. the ciphersuites and SSL/TLS version chosen by the server.
  834. @type checker: L{tlslite.Checker.Checker}
  835. @param checker: A Checker instance. This instance will be
  836. invoked to examine the other party's authentication
  837. credentials, if the handshake completes succesfully.
  838. @raise socket.error: If a socket error occurs.
  839. @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
  840. without a preceding alert.
  841. @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
  842. @raise tlslite.errors.TLSAuthenticationError: If the checker
  843. doesn't like the other party's authentication credentials.
  844. """
  845. for result in self.handshakeServerAsync(sharedKeyDB, verifierDB,
  846. certChain, privateKey, reqCert, sessionCache, settings,
  847. checker):
  848. pass
  849. def handshakeServerAsync(self, sharedKeyDB=None, verifierDB=None,
  850. certChain=None, privateKey=None, reqCert=False,
  851. sessionCache=None, settings=None, checker=None):
  852. """Start a server handshake operation on the TLS connection.
  853. This function returns a generator which behaves similarly to
  854. handshakeServer(). Successive invocations of the generator
  855. will return 0 if it is waiting to read from the socket, 1 if it is
  856. waiting to write to the socket, or it will raise StopIteration
  857. if the handshake operation is complete.
  858. @rtype: iterable
  859. @return: A generator; see above for details.
  860. """
  861. handshaker = self._handshakeServerAsyncHelper(\
  862. sharedKeyDB=sharedKeyDB,
  863. verifierDB=verifierDB, certChain=certChain,
  864. privateKey=privateKey, reqCert=reqCert,
  865. sessionCache=sessionCache, settings=settings)
  866. for result in self._handshakeWrapperAsync(handshaker, checker):
  867. yield result
  868. def _handshakeServerAsyncHelper(self, sharedKeyDB, verifierDB,
  869. certChain, privateKey, reqCert, sessionCache,
  870. settings):
  871. self._handshakeStart(client=False)
  872. if (not sharedKeyDB) and (not verifierDB) and (not certChain):
  873. raise ValueError("Caller passed no authentication credentials")
  874. if certChain and not privateKey:
  875. raise ValueError("Caller passed a certChain but no privateKey")
  876. if privateKey and not certChain:
  877. raise ValueError("Caller passed a privateKey but no certChain")
  878. if not settings:
  879. settings = HandshakeSettings()
  880. settings = settings._filter()
  881. #Initialize acceptable cipher suites
  882. cipherSuites = []
  883. if verifierDB:
  884. if certChain:
  885. cipherSuites += \
  886. CipherSuite.getSrpRsaSuites(settings.cipherNames)
  887. cipherSuites += CipherSuite.getSrpSuites(settings.cipherNames)
  888. if sharedKeyDB or certChain:
  889. cipherSuites += CipherSuite.getRsaSuites(settings.cipherNames)
  890. #Initialize acceptable certificate type
  891. certificateType = None
  892. if certChain:
  893. try:
  894. import cryptoIDlib.CertChain
  895. if isinstance(certChain, cryptoIDlib.CertChain.CertChain):
  896. certificateType = CertificateType.cryptoID
  897. except ImportError:
  898. pass
  899. if isinstance(certChain, X509CertChain):
  900. certificateType = CertificateType.x509
  901. if certificateType == None:
  902. raise ValueError("Unrecognized certificate type")
  903. #Initialize locals
  904. clientCertChain = None
  905. serverCertChain = None #We may set certChain to this later
  906. postFinishedError = None
  907. #Tentatively set version to most-desirable version, so if an error
  908. #occurs parsing the ClientHello, this is what we'll use for the
  909. #error alert
  910. self.version = settings.maxVersion
  911. #Get ClientHello
  912. for result in self._getMsg(ContentType.handshake,
  913. HandshakeType.client_hello):
  914. if result in (0,1):
  915. yield result
  916. else:
  917. break
  918. clientHello = result
  919. #If client's version is too low, reject it
  920. if clientHello.client_version < settings.minVersion:
  921. self.version = settings.minVersion
  922. for result in self._sendError(\
  923. AlertDescription.protocol_version,
  924. "Too old version: %s" % str(clientHello.client_version)):
  925. yield result
  926. #If client's version is too high, propose my highest version
  927. elif clientHello.client_version > settings.maxVersion:
  928. self.version = settings.maxVersion
  929. else:
  930. #Set the version to the client's version
  931. self.version = clientHello.client_version
  932. #Get the client nonce; create server nonce
  933. clientRandom = clientHello.random
  934. serverRandom = getRandomBytes(32)
  935. #Calculate the first cipher suite intersection.
  936. #This is the 'privileged' ciphersuite. We'll use it if we're
  937. #doing a shared-key resumption or a new negotiation. In fact,
  938. #the only time we won't use it is if we're resuming a non-sharedkey
  939. #session, in which case we use the ciphersuite from the session.
  940. #
  941. #Given the current ciphersuite ordering, this means we prefer SRP
  942. #over non-SRP.
  943. for cipherSuite in cipherSuites:
  944. if cipherSuite in clientHello.cipher_suites:
  945. break
  946. else:
  947. for result in self._sendError(\
  948. AlertDescription.handshake_failure):
  949. yield result
  950. #If resumption was requested...
  951. if clientHello.session_id and (sharedKeyDB or sessionCache):
  952. session = None
  953. #Check in the sharedKeys container
  954. if sharedKeyDB and len(clientHello.session_id)==16:
  955. try:
  956. #Trim off zero padding, if any
  957. for x in range(16):
  958. if clientHello.session_id[x]==0:
  959. break
  960. self.allegedSharedKeyUsername = bytesToString(\
  961. clientHello.session_id[:x])
  962. session = sharedKeyDB[self.allegedSharedKeyUsername]
  963. if not session.sharedKey:
  964. raise AssertionError()
  965. #use privileged ciphersuite
  966. session.cipherSuite = cipherSuite
  967. except KeyError:
  968. pass
  969. #Then check in the session cache
  970. if sessionCache and not session:
  971. try:
  972. session = sessionCache[bytesToString(\
  973. clientHello.session_id)]
  974. if session.sharedKey:
  975. raise AssertionError()
  976. if not session.resumable:
  977. raise AssertionError()
  978. #Check for consistency with ClientHello
  979. if session.cipherSuite not in cipherSuites:
  980. for result in self._sendError(\
  981. AlertDescription.handshake_failure):
  982. yield result
  983. if session.cipherSuite not in clientHello.cipher_suites:
  984. for result in self._sendError(\
  985. AlertDescription.handshake_failure):
  986. yield result
  987. if clientHello.srp_username:
  988. if clientHello.srp_username != session.srpUsername:
  989. for result in self._sendError(\
  990. AlertDescription.handshake_failure):
  991. yield result
  992. except KeyError:
  993. pass
  994. #If a session is found..
  995. if session:
  996. #Set the session
  997. self.session = session
  998. #Send ServerHello
  999. serverHello = ServerHello()
  1000. serverHello.create(self.version, serverRandom,
  1001. session.sessionID, session.cipherSuite,
  1002. certificateType)
  1003. for result in self._sendMsg(serverHello):
  1004. yield result
  1005. #From here on, the client's messages must have the right version
  1006. self._versionCheck = True
  1007. #Calculate pending connection states
  1008. self._calcPendingStates(clientRandom, serverRandom,
  1009. settings.cipherImplementations)
  1010. #Exchange ChangeCipherSpec and Finished messages
  1011. for result in self._sendFinished():
  1012. yield result
  1013. for result in self._getFinished():
  1014. yield result
  1015. #Mark the connection as open
  1016. self._handshakeDone(resumed=True)
  1017. return
  1018. #If not a resumption...
  1019. #TRICKY: we might have chosen an RSA suite that was only deemed
  1020. #acceptable because of the shared-key resumption. If the shared-
  1021. #key resumption failed, because the identifier wasn't recognized,
  1022. #we might fall through to here, where we have an RSA suite
  1023. #chosen, but no certificate.
  1024. if cipherSuite in CipherSuite.rsaSuites and not certChain:
  1025. for result in self._sendError(\
  1026. AlertDescription.handshake_failure):
  1027. yield result
  1028. #If an RSA suite is chosen, check for certificate type intersection
  1029. #(We do this check down here because if the mismatch occurs but the
  1030. # client is using a shared-key session, it's okay)
  1031. if cipherSuite in CipherSuite.rsaSuites + \
  1032. CipherSuite.srpRsaSuites:
  1033. if certificateType not in clientHello.certificate_types:
  1034. for result in self._sendError(\
  1035. AlertDescription.handshake_failure,
  1036. "the client doesn't support my certificate type"):
  1037. yield result
  1038. #Move certChain -> serverCertChain, now that we're using it
  1039. serverCertChain = certChain
  1040. #Create sessionID
  1041. if sessionCache:
  1042. sessionID = getRandomBytes(32)
  1043. else:
  1044. sessionID = createByteArraySequence([])
  1045. #If we've selected an SRP suite, exchange keys and calculate
  1046. #premaster secret:
  1047. if cipherSuite in CipherSuite.srpSuites + CipherSuite.srpRsaSuites:
  1048. #If there's no SRP username...
  1049. if not clientHello.srp_username:
  1050. #Ask the client to re-send ClientHello with one
  1051. for result in self._sendMsg(Alert().create(\
  1052. AlertDescription.missing_srp_username,
  1053. AlertLevel.warning)):
  1054. yield result
  1055. #Get ClientHello
  1056. for result in self._getMsg(ContentType.handshake,
  1057. HandshakeType.client_hello):
  1058. if result in (0,1):
  1059. yield result
  1060. else:
  1061. break
  1062. clientHello = result
  1063. #Check ClientHello
  1064. #If client's version is too low, reject it (COPIED CODE; BAD!)
  1065. if clientHello.client_version < settings.minVersion:
  1066. self.version = settings.minVersion
  1067. for result in self._sendError(\
  1068. AlertDescription.protocol_version,
  1069. "Too old version: %s" % str(clientHello.client_version)):
  1070. yield result
  1071. #If client's version is too high, propose my highest version
  1072. elif clientHello.client_version > settings.maxVersion:
  1073. self.version = settings.maxVersion
  1074. else:
  1075. #Set the version to the client's version
  1076. self.version = clientHello.client_version
  1077. #Recalculate the privileged cipher suite, making sure to
  1078. #pick an SRP suite
  1079. cipherSuites = [c for c in cipherSuites if c in \
  1080. CipherSuite.srpSuites + \
  1081. CipherSuite.srpRsaSuites]
  1082. for cipherSuite in cipherSuites:
  1083. if cipherSuite in clientHello.cipher_suites:
  1084. break
  1085. else:
  1086. for result in self._sendError(\
  1087. AlertDescription.handshake_failure):
  1088. yield result
  1089. #Get the client nonce; create server nonce
  1090. clientRandom = clientHello.random
  1091. serverRandom = getRandomBytes(32)
  1092. #The username better be there, this time
  1093. if not clientHello.srp_username:
  1094. for result in self._sendError(\
  1095. AlertDescription.illegal_parameter,
  1096. "Client resent a hello, but without the SRP"\
  1097. " username"):
  1098. yield result
  1099. #Get username
  1100. self.allegedSrpUsername = clientHello.srp_username
  1101. #Get parameters from username
  1102. try:
  1103. entry = verifierDB[self.allegedSrpUsername]
  1104. except KeyError:
  1105. for result in self._sendError(\
  1106. AlertDescription.unknown_srp_username):
  1107. yield result
  1108. (N, g, s, v) = entry
  1109. #Calculate server's ephemeral DH values (b, B)
  1110. b = bytesToNumber(getRandomBytes(32))
  1111. k = makeK(N, g)
  1112. B = (powMod(g, b, N) + (k*v)) % N
  1113. #Create ServerKeyExchange, signing it if necessary
  1114. serverKeyExchange = ServerKeyExchange(cipherSuite)
  1115. serverKeyExchange.createSRP(N, g, stringToBytes(s), B)
  1116. if cipherSuite in CipherSuite.srpRsaSuites:
  1117. hashBytes = serverKeyExchange.hash(clientRandom,
  1118. serverRandom)
  1119. serverKeyExchange.signature = privateKey.sign(hashBytes)
  1120. #Send ServerHello[, Certificate], ServerKeyExchange,
  1121. #ServerHelloDone
  1122. msgs = []
  1123. serverHello = ServerHello()
  1124. serverHello.create(self.version, serverRandom, sessionID,
  1125. cipherSuite, certificateType)
  1126. msgs.append(serverHello)
  1127. if cipherSuite in CipherSuite.srpRsaSuites:
  1128. certificateMsg = Certificate(certificateType)
  1129. certificateMsg.create(serverCertChain)
  1130. msgs.append(certificateMsg)
  1131. msgs.append(serverKeyExchange)
  1132. msgs.append(ServerHelloDone())
  1133. for result in self._sendMsgs(msgs):
  1134. yield result
  1135. #From here on, the client's messages must have the right version
  1136. self._versionCheck = True
  1137. #Get and check ClientKeyExchange
  1138. for result in self._getMsg(ContentType.handshake,
  1139. HandshakeType.client_key_exchange,
  1140. cipherSuite):
  1141. if result in (0,1):
  1142. yield result
  1143. else:
  1144. break
  1145. clientKeyExchange = result
  1146. A = clientKeyExchange.srp_A
  1147. if A % N == 0:
  1148. postFinishedError = (AlertDescription.illegal_parameter,
  1149. "Suspicious A value")
  1150. #Calculate u
  1151. u = makeU(N, A, B)
  1152. #Calculate premaster secret
  1153. S = powMod((A * powMod(v,u,N)) % N, b, N)
  1154. premasterSecret = numberToBytes(S)
  1155. #If we've selected an RSA suite, exchange keys and calculate
  1156. #premaster secret:
  1157. elif cipherSuite in CipherSuite.rsaSuites:
  1158. #Send ServerHello, Certificate[, CertificateRequest],
  1159. #ServerHelloDone
  1160. msgs = []
  1161. msgs.append(ServerHello().create(self.version, serverRandom,
  1162. sessionID, cipherSuite, certificateType))
  1163. msgs.append(Certificate(certificateType).create(serverCertChain))
  1164. if reqCert:
  1165. msgs.append(CertificateRequest())
  1166. msgs.append(ServerHelloDone())
  1167. for result in self._sendMsgs(msgs):
  1168. yield result
  1169. #From here on, the client's messages must have the right version
  1170. self._versionCheck = True
  1171. #Get [Certificate,] (if was requested)
  1172. if reqCert:
  1173. if self.version == (3,0):
  1174. for result in self._getMsg((ContentType.handshake,
  1175. ContentType.alert),
  1176. HandshakeType.certificate,
  1177. certificateType):
  1178. if result in (0,1):
  1179. yield result
  1180. else:
  1181. break
  1182. msg = result
  1183. if isinstance(msg, Alert):
  1184. #If it's not a no_certificate alert, re-raise
  1185. alert = msg
  1186. if alert.description != \
  1187. AlertDescription.no_certificate:
  1188. self._shutdown(False)
  1189. raise TLSRemoteAlert(alert)
  1190. elif isinstance(msg, Certificate):
  1191. clientCertificate = msg
  1192. if clientCertificate.certChain and \
  1193. clientCertificate.certChain.getNumCerts()!=0:
  1194. clientCertChain = clientCertificate.certChain
  1195. else:
  1196. raise AssertionError()
  1197. elif self.version in ((3,1), (3,2)):
  1198. for result in self._getMsg(ContentType.handshake,
  1199. HandshakeType.certificate,
  1200. certificateType):
  1201. if result in (0,1):
  1202. yield result
  1203. else:
  1204. break
  1205. clientCertificate = result
  1206. if clientCertificate.certChain and \
  1207. clientCertificate.certChain.getNumCerts()!=0:
  1208. clientCertChain = clientCertificate.certChain
  1209. else:
  1210. raise AssertionError()
  1211. #Get ClientKeyExchange
  1212. for result in self._getMsg(ContentType.handshake,
  1213. HandshakeType.client_key_exchange,
  1214. cipherSuite):
  1215. if result in (0,1):
  1216. yield result
  1217. else:
  1218. break
  1219. clientKeyExchange = result
  1220. #Decrypt ClientKeyExchange
  1221. premasterSecret = privateKey.decrypt(\
  1222. clientKeyExchange.encryptedPreMasterSecret)
  1223. randomPreMasterSecret = getRandomBytes(48)
  1224. versionCheck = (premasterSecret[0], premasterSecret[1])
  1225. if not premasterSecret:
  1226. premasterSecret = randomPreMasterSecret
  1227. elif len(premasterSecret)!=48:
  1228. premasterSecret = randomPreMasterSecret
  1229. elif versionCheck != clientHello.client_version:
  1230. if versionCheck != self.version: #Tolerate buggy IE clients
  1231. premasterSecret = randomPreMasterSecret
  1232. #Get and check CertificateVerify, if relevant
  1233. if clientCertChain:
  1234. if self.version == (3,0):
  1235. #Create a temporary session object, just for the purpose
  1236. #of checking the CertificateVerify
  1237. session = Session()
  1238. session._calcMasterSecret(self.version, premasterSecret,
  1239. clientRandom, serverRandom)
  1240. verifyBytes = self._calcSSLHandshakeHash(\
  1241. session.masterSecret, "")
  1242. elif self.version in ((3,1), (3,2)):
  1243. verifyBytes = stringToBytes(self._handshake_md5.digest() +\
  1244. self._handshake_sha.digest())
  1245. for result in self._getMsg(ContentType.handshake,
  1246. HandshakeType.certificate_verify):
  1247. if result in (0,1):
  1248. yield result
  1249. else:
  1250. break
  1251. certificateVerify = result
  1252. publicKey = clientCertChain.getEndEntityPublicKey()
  1253. if len(publicKey) < settings.minKeySize:
  1254. postFinishedError = (AlertDescription.handshake_failure,
  1255. "Client's public key too small: %d" % len(publicKey))
  1256. if len(publicKey) > settings.maxKeySize:
  1257. postFinishedError = (AlertDescription.handshake_failure,
  1258. "Client's public key too large: %d" % len(publicKey))
  1259. if not publicKey.verify(certificateVerify.signature,