TlsProtocol.cs 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Collections;
  5. using System.IO;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Prng;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  9. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Tls
  10. {
  11. public abstract class TlsProtocol
  12. {
  13. /*
  14. * Our Connection states
  15. */
  16. protected const short CS_START = 0;
  17. protected const short CS_CLIENT_HELLO = 1;
  18. protected const short CS_SERVER_HELLO = 2;
  19. protected const short CS_SERVER_SUPPLEMENTAL_DATA = 3;
  20. protected const short CS_SERVER_CERTIFICATE = 4;
  21. protected const short CS_CERTIFICATE_STATUS = 5;
  22. protected const short CS_SERVER_KEY_EXCHANGE = 6;
  23. protected const short CS_CERTIFICATE_REQUEST = 7;
  24. protected const short CS_SERVER_HELLO_DONE = 8;
  25. protected const short CS_CLIENT_SUPPLEMENTAL_DATA = 9;
  26. protected const short CS_CLIENT_CERTIFICATE = 10;
  27. protected const short CS_CLIENT_KEY_EXCHANGE = 11;
  28. protected const short CS_CERTIFICATE_VERIFY = 12;
  29. protected const short CS_CLIENT_FINISHED = 13;
  30. protected const short CS_SERVER_SESSION_TICKET = 14;
  31. protected const short CS_SERVER_FINISHED = 15;
  32. protected const short CS_END = 16;
  33. /*
  34. * Different modes to handle the known IV weakness
  35. */
  36. protected const short ADS_MODE_1_Nsub1 = 0; // 1/n-1 record splitting
  37. protected const short ADS_MODE_0_N = 1; // 0/n record splitting
  38. protected const short ADS_MODE_0_N_FIRSTONLY = 2; // 0/n record splitting on first data fragment only
  39. /*
  40. * Queues for data from some protocols.
  41. */
  42. private ByteQueue mApplicationDataQueue = new ByteQueue(0);
  43. private ByteQueue mAlertQueue = new ByteQueue(2);
  44. private ByteQueue mHandshakeQueue = new ByteQueue(0);
  45. // private ByteQueue mHeartbeatQueue = new ByteQueue();
  46. /*
  47. * The Record Stream we use
  48. */
  49. internal RecordStream mRecordStream;
  50. protected SecureRandom mSecureRandom;
  51. private TlsStream mTlsStream = null;
  52. private volatile bool mClosed = false;
  53. private volatile bool mFailedWithError = false;
  54. private volatile bool mAppDataReady = false;
  55. private volatile bool mAppDataSplitEnabled = true;
  56. private volatile int mAppDataSplitMode = ADS_MODE_1_Nsub1;
  57. private byte[] mExpectedVerifyData = null;
  58. protected TlsSession mTlsSession = null;
  59. protected SessionParameters mSessionParameters = null;
  60. protected SecurityParameters mSecurityParameters = null;
  61. protected Certificate mPeerCertificate = null;
  62. protected int[] mOfferedCipherSuites = null;
  63. protected byte[] mOfferedCompressionMethods = null;
  64. protected IDictionary mClientExtensions = null;
  65. protected IDictionary mServerExtensions = null;
  66. protected short mConnectionState = CS_START;
  67. protected bool mResumedSession = false;
  68. protected bool mReceivedChangeCipherSpec = false;
  69. protected bool mSecureRenegotiation = false;
  70. protected bool mAllowCertificateStatus = false;
  71. protected bool mExpectSessionTicket = false;
  72. protected bool mBlocking = true;
  73. protected ByteQueueStream mInputBuffers = null;
  74. protected ByteQueueStream mOutputBuffer = null;
  75. public TlsProtocol(Stream stream, SecureRandom secureRandom)
  76. : this(stream, stream, secureRandom)
  77. {
  78. }
  79. public TlsProtocol(Stream input, Stream output, SecureRandom secureRandom)
  80. {
  81. this.mRecordStream = new RecordStream(this, input, output);
  82. this.mSecureRandom = secureRandom;
  83. }
  84. public TlsProtocol(SecureRandom secureRandom)
  85. {
  86. this.mBlocking = false;
  87. this.mInputBuffers = new ByteQueueStream();
  88. this.mOutputBuffer = new ByteQueueStream();
  89. this.mRecordStream = new RecordStream(this, mInputBuffers, mOutputBuffer);
  90. this.mSecureRandom = secureRandom;
  91. }
  92. protected abstract TlsContext Context { get; }
  93. internal abstract AbstractTlsContext ContextAdmin { get; }
  94. protected abstract TlsPeer Peer { get; }
  95. protected virtual void HandleAlertMessage(byte alertLevel, byte alertDescription)
  96. {
  97. Peer.NotifyAlertReceived(alertLevel, alertDescription);
  98. if (alertLevel == AlertLevel.warning)
  99. {
  100. HandleAlertWarningMessage(alertDescription);
  101. }
  102. else
  103. {
  104. HandleFailure();
  105. throw new TlsFatalAlertReceived(alertDescription);
  106. }
  107. }
  108. protected virtual void HandleAlertWarningMessage(byte alertDescription)
  109. {
  110. /*
  111. * RFC 5246 7.2.1. The other party MUST respond with a close_notify alert of its own
  112. * and close down the connection immediately, discarding any pending writes.
  113. */
  114. if (alertDescription == AlertDescription.close_notify)
  115. {
  116. if (!mAppDataReady)
  117. throw new TlsFatalAlert(AlertDescription.handshake_failure);
  118. HandleClose(false);
  119. }
  120. }
  121. protected virtual void HandleChangeCipherSpecMessage()
  122. {
  123. }
  124. protected virtual void HandleClose(bool user_canceled)
  125. {
  126. if (!mClosed)
  127. {
  128. this.mClosed = true;
  129. if (user_canceled && !mAppDataReady)
  130. {
  131. RaiseAlertWarning(AlertDescription.user_canceled, "User canceled handshake");
  132. }
  133. RaiseAlertWarning(AlertDescription.close_notify, "Connection closed");
  134. mRecordStream.SafeClose();
  135. if (!mAppDataReady)
  136. {
  137. CleanupHandshake();
  138. }
  139. }
  140. }
  141. protected virtual void HandleException(byte alertDescription, string message, Exception cause)
  142. {
  143. if (!mClosed)
  144. {
  145. RaiseAlertFatal(alertDescription, message, cause);
  146. HandleFailure();
  147. }
  148. }
  149. protected virtual void HandleFailure()
  150. {
  151. this.mClosed = true;
  152. this.mFailedWithError = true;
  153. /*
  154. * RFC 2246 7.2.1. The session becomes unresumable if any connection is terminated
  155. * without proper close_notify messages with level equal to warning.
  156. */
  157. // TODO This isn't quite in the right place. Also, as of TLS 1.1 the above is obsolete.
  158. InvalidateSession();
  159. mRecordStream.SafeClose();
  160. if (!mAppDataReady)
  161. {
  162. CleanupHandshake();
  163. }
  164. }
  165. protected abstract void HandleHandshakeMessage(byte type, MemoryStream buf);
  166. protected virtual void ApplyMaxFragmentLengthExtension()
  167. {
  168. if (mSecurityParameters.maxFragmentLength >= 0)
  169. {
  170. if (!MaxFragmentLength.IsValid((byte)mSecurityParameters.maxFragmentLength))
  171. throw new TlsFatalAlert(AlertDescription.internal_error);
  172. int plainTextLimit = 1 << (8 + mSecurityParameters.maxFragmentLength);
  173. mRecordStream.SetPlaintextLimit(plainTextLimit);
  174. }
  175. }
  176. protected virtual void CheckReceivedChangeCipherSpec(bool expected)
  177. {
  178. if (expected != mReceivedChangeCipherSpec)
  179. throw new TlsFatalAlert(AlertDescription.unexpected_message);
  180. }
  181. protected virtual void CleanupHandshake()
  182. {
  183. if (this.mExpectedVerifyData != null)
  184. {
  185. Arrays.Fill(this.mExpectedVerifyData, (byte)0);
  186. this.mExpectedVerifyData = null;
  187. }
  188. this.mSecurityParameters.Clear();
  189. this.mPeerCertificate = null;
  190. this.mOfferedCipherSuites = null;
  191. this.mOfferedCompressionMethods = null;
  192. this.mClientExtensions = null;
  193. this.mServerExtensions = null;
  194. this.mResumedSession = false;
  195. this.mReceivedChangeCipherSpec = false;
  196. this.mSecureRenegotiation = false;
  197. this.mAllowCertificateStatus = false;
  198. this.mExpectSessionTicket = false;
  199. }
  200. protected virtual void BlockForHandshake()
  201. {
  202. if (mBlocking)
  203. {
  204. while (this.mConnectionState != CS_END)
  205. {
  206. if (this.mClosed)
  207. {
  208. // NOTE: Any close during the handshake should have raised an exception.
  209. throw new TlsFatalAlert(AlertDescription.internal_error);
  210. }
  211. SafeReadRecord();
  212. }
  213. }
  214. }
  215. protected virtual void CompleteHandshake()
  216. {
  217. try
  218. {
  219. this.mConnectionState = CS_END;
  220. this.mAlertQueue.Shrink();
  221. this.mHandshakeQueue.Shrink();
  222. this.mRecordStream.FinaliseHandshake();
  223. this.mAppDataSplitEnabled = !TlsUtilities.IsTlsV11(Context);
  224. /*
  225. * If this was an initial handshake, we are now ready to send and receive application data.
  226. */
  227. if (!mAppDataReady)
  228. {
  229. this.mAppDataReady = true;
  230. if (mBlocking)
  231. {
  232. this.mTlsStream = new TlsStream(this);
  233. }
  234. }
  235. if (this.mTlsSession != null)
  236. {
  237. if (this.mSessionParameters == null)
  238. {
  239. this.mSessionParameters = new SessionParameters.Builder()
  240. .SetCipherSuite(this.mSecurityParameters.CipherSuite)
  241. .SetCompressionAlgorithm(this.mSecurityParameters.CompressionAlgorithm)
  242. .SetExtendedMasterSecret(this.mSecurityParameters.IsExtendedMasterSecret)
  243. .SetMasterSecret(this.mSecurityParameters.MasterSecret)
  244. .SetPeerCertificate(this.mPeerCertificate)
  245. .SetPskIdentity(this.mSecurityParameters.PskIdentity)
  246. .SetSrpIdentity(this.mSecurityParameters.SrpIdentity)
  247. // TODO Consider filtering extensions that aren't relevant to resumed sessions
  248. .SetServerExtensions(this.mServerExtensions)
  249. .Build();
  250. this.mTlsSession = new TlsSessionImpl(this.mTlsSession.SessionID, this.mSessionParameters);
  251. }
  252. ContextAdmin.SetResumableSession(this.mTlsSession);
  253. }
  254. Peer.NotifyHandshakeComplete();
  255. }
  256. finally
  257. {
  258. CleanupHandshake();
  259. }
  260. }
  261. protected internal void ProcessRecord(byte protocol, byte[] buf, int off, int len)
  262. {
  263. /*
  264. * Have a look at the protocol type, and add it to the correct queue.
  265. */
  266. switch (protocol)
  267. {
  268. case ContentType.alert:
  269. {
  270. mAlertQueue.AddData(buf, off, len);
  271. ProcessAlertQueue();
  272. break;
  273. }
  274. case ContentType.application_data:
  275. {
  276. if (!mAppDataReady)
  277. throw new TlsFatalAlert(AlertDescription.unexpected_message);
  278. mApplicationDataQueue.AddData(buf, off, len);
  279. ProcessApplicationDataQueue();
  280. break;
  281. }
  282. case ContentType.change_cipher_spec:
  283. {
  284. ProcessChangeCipherSpec(buf, off, len);
  285. break;
  286. }
  287. case ContentType.handshake:
  288. {
  289. if (mHandshakeQueue.Available > 0)
  290. {
  291. mHandshakeQueue.AddData(buf, off, len);
  292. ProcessHandshakeQueue(mHandshakeQueue);
  293. }
  294. else
  295. {
  296. ByteQueue tmpQueue = new ByteQueue(buf, off, len);
  297. ProcessHandshakeQueue(tmpQueue);
  298. int remaining = tmpQueue.Available;
  299. if (remaining > 0)
  300. {
  301. mHandshakeQueue.AddData(buf, off + len - remaining, remaining);
  302. }
  303. }
  304. break;
  305. }
  306. //case ContentType.heartbeat:
  307. //{
  308. // if (!mAppDataReady)
  309. // throw new TlsFatalAlert(AlertDescription.unexpected_message);
  310. // // TODO[RFC 6520]
  311. // //mHeartbeatQueue.AddData(buf, offset, len);
  312. // //ProcessHeartbeat();
  313. // break;
  314. //}
  315. default:
  316. // Record type should already have been checked
  317. throw new TlsFatalAlert(AlertDescription.internal_error);
  318. }
  319. }
  320. private void ProcessHandshakeQueue(ByteQueue queue)
  321. {
  322. while (queue.Available >= 4)
  323. {
  324. /*
  325. * We need the first 4 bytes, they contain type and length of the message.
  326. */
  327. byte[] beginning = new byte[4];
  328. queue.Read(beginning, 0, 4, 0);
  329. byte type = TlsUtilities.ReadUint8(beginning, 0);
  330. int length = TlsUtilities.ReadUint24(beginning, 1);
  331. int totalLength = 4 + length;
  332. /*
  333. * Check if we have enough bytes in the buffer to read the full message.
  334. */
  335. if (queue.Available < totalLength)
  336. break;
  337. /*
  338. * RFC 2246 7.4.9. The value handshake_messages includes all handshake messages
  339. * starting at client hello up to, but not including, this finished message.
  340. * [..] Note: [Also,] Hello Request messages are omitted from handshake hashes.
  341. */
  342. if (HandshakeType.hello_request != type)
  343. {
  344. if (HandshakeType.finished == type)
  345. {
  346. CheckReceivedChangeCipherSpec(true);
  347. TlsContext ctx = Context;
  348. if (this.mExpectedVerifyData == null
  349. && ctx.SecurityParameters.MasterSecret != null)
  350. {
  351. this.mExpectedVerifyData = CreateVerifyData(!ctx.IsServer);
  352. }
  353. }
  354. else
  355. {
  356. CheckReceivedChangeCipherSpec(mConnectionState == CS_END);
  357. }
  358. queue.CopyTo(mRecordStream.HandshakeHashUpdater, totalLength);
  359. }
  360. queue.RemoveData(4);
  361. MemoryStream buf = queue.ReadFrom(length);
  362. /*
  363. * Now, parse the message.
  364. */
  365. HandleHandshakeMessage(type, buf);
  366. }
  367. }
  368. private void ProcessApplicationDataQueue()
  369. {
  370. /*
  371. * There is nothing we need to do here.
  372. *
  373. * This function could be used for callbacks when application data arrives in the future.
  374. */
  375. }
  376. private void ProcessAlertQueue()
  377. {
  378. while (mAlertQueue.Available >= 2)
  379. {
  380. /*
  381. * An alert is always 2 bytes. Read the alert.
  382. */
  383. byte[] alert = mAlertQueue.RemoveData(2, 0);
  384. byte alertLevel = alert[0];
  385. byte alertDescription = alert[1];
  386. HandleAlertMessage(alertLevel, alertDescription);
  387. }
  388. }
  389. /**
  390. * This method is called, when a change cipher spec message is received.
  391. *
  392. * @throws IOException If the message has an invalid content or the handshake is not in the correct
  393. * state.
  394. */
  395. private void ProcessChangeCipherSpec(byte[] buf, int off, int len)
  396. {
  397. for (int i = 0; i < len; ++i)
  398. {
  399. byte message = TlsUtilities.ReadUint8(buf, off + i);
  400. if (message != ChangeCipherSpec.change_cipher_spec)
  401. throw new TlsFatalAlert(AlertDescription.decode_error);
  402. if (this.mReceivedChangeCipherSpec
  403. || mAlertQueue.Available > 0
  404. || mHandshakeQueue.Available > 0)
  405. {
  406. throw new TlsFatalAlert(AlertDescription.unexpected_message);
  407. }
  408. mRecordStream.ReceivedReadCipherSpec();
  409. this.mReceivedChangeCipherSpec = true;
  410. HandleChangeCipherSpecMessage();
  411. }
  412. }
  413. protected internal virtual int ApplicationDataAvailable()
  414. {
  415. return mApplicationDataQueue.Available;
  416. }
  417. /**
  418. * Read data from the network. The method will return immediately, if there is still some data
  419. * left in the buffer, or block until some application data has been read from the network.
  420. *
  421. * @param buf The buffer where the data will be copied to.
  422. * @param offset The position where the data will be placed in the buffer.
  423. * @param len The maximum number of bytes to read.
  424. * @return The number of bytes read.
  425. * @throws IOException If something goes wrong during reading data.
  426. */
  427. protected internal virtual int ReadApplicationData(byte[] buf, int offset, int len)
  428. {
  429. if (len < 1)
  430. return 0;
  431. while (mApplicationDataQueue.Available == 0)
  432. {
  433. if (this.mClosed)
  434. {
  435. if (this.mFailedWithError)
  436. throw new IOException("Cannot read application data on failed TLS connection");
  437. if (!mAppDataReady)
  438. throw new InvalidOperationException("Cannot read application data until initial handshake completed.");
  439. return 0;
  440. }
  441. SafeReadRecord();
  442. }
  443. len = System.Math.Min(len, mApplicationDataQueue.Available);
  444. mApplicationDataQueue.RemoveData(buf, offset, len, 0);
  445. return len;
  446. }
  447. protected virtual void SafeCheckRecordHeader(byte[] recordHeader)
  448. {
  449. try
  450. {
  451. mRecordStream.CheckRecordHeader(recordHeader);
  452. }
  453. catch (TlsFatalAlert e)
  454. {
  455. HandleException(e.AlertDescription, "Failed to read record", e);
  456. throw e;
  457. }
  458. catch (IOException e)
  459. {
  460. HandleException(AlertDescription.internal_error, "Failed to read record", e);
  461. throw e;
  462. }
  463. catch (Exception e)
  464. {
  465. HandleException(AlertDescription.internal_error, "Failed to read record", e);
  466. throw new TlsFatalAlert(AlertDescription.internal_error, e);
  467. }
  468. }
  469. protected virtual void SafeReadRecord()
  470. {
  471. try
  472. {
  473. if (mRecordStream.ReadRecord())
  474. return;
  475. if (!mAppDataReady)
  476. throw new TlsFatalAlert(AlertDescription.handshake_failure);
  477. }
  478. catch (TlsFatalAlertReceived e)
  479. {
  480. // Connection failure already handled at source
  481. throw e;
  482. }
  483. catch (TlsFatalAlert e)
  484. {
  485. HandleException(e.AlertDescription, "Failed to read record", e);
  486. throw e;
  487. }
  488. catch (IOException e)
  489. {
  490. HandleException(AlertDescription.internal_error, "Failed to read record", e);
  491. throw e;
  492. }
  493. catch (Exception e)
  494. {
  495. HandleException(AlertDescription.internal_error, "Failed to read record", e);
  496. throw new TlsFatalAlert(AlertDescription.internal_error, e);
  497. }
  498. HandleFailure();
  499. throw new TlsNoCloseNotifyException();
  500. }
  501. protected virtual void SafeWriteRecord(byte type, byte[] buf, int offset, int len)
  502. {
  503. try
  504. {
  505. mRecordStream.WriteRecord(type, buf, offset, len);
  506. }
  507. catch (TlsFatalAlert e)
  508. {
  509. HandleException(e.AlertDescription, "Failed to write record", e);
  510. throw e;
  511. }
  512. catch (IOException e)
  513. {
  514. HandleException(AlertDescription.internal_error, "Failed to write record", e);
  515. throw e;
  516. }
  517. catch (Exception e)
  518. {
  519. HandleException(AlertDescription.internal_error, "Failed to write record", e);
  520. throw new TlsFatalAlert(AlertDescription.internal_error, e);
  521. }
  522. }
  523. /**
  524. * Send some application data to the remote system.
  525. * <p/>
  526. * The method will handle fragmentation internally.
  527. *
  528. * @param buf The buffer with the data.
  529. * @param offset The position in the buffer where the data is placed.
  530. * @param len The length of the data.
  531. * @throws IOException If something goes wrong during sending.
  532. */
  533. protected internal virtual void WriteData(byte[] buf, int offset, int len)
  534. {
  535. if (this.mClosed)
  536. throw new IOException("Cannot write application data on closed/failed TLS connection");
  537. while (len > 0)
  538. {
  539. /*
  540. * RFC 5246 6.2.1. Zero-length fragments of Application data MAY be sent as they are
  541. * potentially useful as a traffic analysis countermeasure.
  542. *
  543. * NOTE: Actually, implementations appear to have settled on 1/n-1 record splitting.
  544. */
  545. if (this.mAppDataSplitEnabled)
  546. {
  547. /*
  548. * Protect against known IV attack!
  549. *
  550. * DO NOT REMOVE THIS CODE, EXCEPT YOU KNOW EXACTLY WHAT YOU ARE DOING HERE.
  551. */
  552. switch (mAppDataSplitMode)
  553. {
  554. case ADS_MODE_0_N:
  555. SafeWriteRecord(ContentType.application_data, TlsUtilities.EmptyBytes, 0, 0);
  556. break;
  557. case ADS_MODE_0_N_FIRSTONLY:
  558. this.mAppDataSplitEnabled = false;
  559. SafeWriteRecord(ContentType.application_data, TlsUtilities.EmptyBytes, 0, 0);
  560. break;
  561. case ADS_MODE_1_Nsub1:
  562. default:
  563. SafeWriteRecord(ContentType.application_data, buf, offset, 1);
  564. ++offset;
  565. --len;
  566. break;
  567. }
  568. }
  569. if (len > 0)
  570. {
  571. // Fragment data according to the current fragment limit.
  572. int toWrite = System.Math.Min(len, mRecordStream.GetPlaintextLimit());
  573. SafeWriteRecord(ContentType.application_data, buf, offset, toWrite);
  574. offset += toWrite;
  575. len -= toWrite;
  576. }
  577. }
  578. }
  579. protected virtual void SetAppDataSplitMode(int appDataSplitMode)
  580. {
  581. if (appDataSplitMode < ADS_MODE_1_Nsub1 || appDataSplitMode > ADS_MODE_0_N_FIRSTONLY)
  582. throw new ArgumentException("Illegal appDataSplitMode mode: " + appDataSplitMode, "appDataSplitMode");
  583. this.mAppDataSplitMode = appDataSplitMode;
  584. }
  585. protected virtual void WriteHandshakeMessage(byte[] buf, int off, int len)
  586. {
  587. if (len < 4)
  588. throw new TlsFatalAlert(AlertDescription.internal_error);
  589. byte type = TlsUtilities.ReadUint8(buf, off);
  590. if (type != HandshakeType.hello_request)
  591. {
  592. mRecordStream.HandshakeHashUpdater.Write(buf, off, len);
  593. }
  594. int total = 0;
  595. do
  596. {
  597. // Fragment data according to the current fragment limit.
  598. int toWrite = System.Math.Min(len - total, mRecordStream.GetPlaintextLimit());
  599. SafeWriteRecord(ContentType.handshake, buf, off + total, toWrite);
  600. total += toWrite;
  601. }
  602. while (total < len);
  603. }
  604. /// <summary>The secure bidirectional stream for this connection</summary>
  605. /// <remarks>Only allowed in blocking mode.</remarks>
  606. public virtual Stream Stream
  607. {
  608. get
  609. {
  610. if (!mBlocking)
  611. throw new InvalidOperationException("Cannot use Stream in non-blocking mode! Use OfferInput()/OfferOutput() instead.");
  612. return this.mTlsStream;
  613. }
  614. }
  615. /**
  616. * Should be called in non-blocking mode when the input data reaches EOF.
  617. */
  618. public virtual void CloseInput()
  619. {
  620. if (mBlocking)
  621. throw new InvalidOperationException("Cannot use CloseInput() in blocking mode!");
  622. if (mClosed)
  623. return;
  624. if (mInputBuffers.Available > 0)
  625. throw new EndOfStreamException();
  626. if (!mAppDataReady)
  627. throw new TlsFatalAlert(AlertDescription.handshake_failure);
  628. throw new TlsNoCloseNotifyException();
  629. }
  630. /**
  631. * Offer input from an arbitrary source. Only allowed in non-blocking mode.<br/>
  632. * <br/>
  633. * After this method returns, the input buffer is "owned" by this object. Other code
  634. * must not attempt to do anything with it.<br/>
  635. * <br/>
  636. * This method will decrypt and process all records that are fully available.
  637. * If only part of a record is available, the buffer will be retained until the
  638. * remainder of the record is offered.<br/>
  639. * <br/>
  640. * If any records containing application data were processed, the decrypted data
  641. * can be obtained using {@link #readInput(byte[], int, int)}. If any records
  642. * containing protocol data were processed, a response may have been generated.
  643. * You should always check to see if there is any available output after calling
  644. * this method by calling {@link #getAvailableOutputBytes()}.
  645. * @param input The input buffer to offer
  646. * @throws IOException If an error occurs while decrypting or processing a record
  647. */
  648. public virtual void OfferInput(byte[] input)
  649. {
  650. if (mBlocking)
  651. throw new InvalidOperationException("Cannot use OfferInput() in blocking mode! Use Stream instead.");
  652. if (mClosed)
  653. throw new IOException("Connection is closed, cannot accept any more input");
  654. mInputBuffers.Write(input);
  655. // loop while there are enough bytes to read the length of the next record
  656. while (mInputBuffers.Available >= RecordStream.TLS_HEADER_SIZE)
  657. {
  658. byte[] recordHeader = new byte[RecordStream.TLS_HEADER_SIZE];
  659. mInputBuffers.Peek(recordHeader);
  660. int totalLength = TlsUtilities.ReadUint16(recordHeader, RecordStream.TLS_HEADER_LENGTH_OFFSET) + RecordStream.TLS_HEADER_SIZE;
  661. if (mInputBuffers.Available < totalLength)
  662. {
  663. // not enough bytes to read a whole record
  664. SafeCheckRecordHeader(recordHeader);
  665. break;
  666. }
  667. SafeReadRecord();
  668. if (mClosed)
  669. {
  670. if (mConnectionState != CS_END)
  671. {
  672. // NOTE: Any close during the handshake should have raised an exception.
  673. throw new TlsFatalAlert(AlertDescription.internal_error);
  674. }
  675. break;
  676. }
  677. }
  678. }
  679. /**
  680. * Gets the amount of received application data. A call to {@link #readInput(byte[], int, int)}
  681. * is guaranteed to be able to return at least this much data.<br/>
  682. * <br/>
  683. * Only allowed in non-blocking mode.
  684. * @return The number of bytes of available application data
  685. */
  686. public virtual int GetAvailableInputBytes()
  687. {
  688. if (mBlocking)
  689. throw new InvalidOperationException("Cannot use GetAvailableInputBytes() in blocking mode! Use ApplicationDataAvailable() instead.");
  690. return ApplicationDataAvailable();
  691. }
  692. /**
  693. * Retrieves received application data. Use {@link #getAvailableInputBytes()} to check
  694. * how much application data is currently available. This method functions similarly to
  695. * {@link InputStream#read(byte[], int, int)}, except that it never blocks. If no data
  696. * is available, nothing will be copied and zero will be returned.<br/>
  697. * <br/>
  698. * Only allowed in non-blocking mode.
  699. * @param buffer The buffer to hold the application data
  700. * @param offset The start offset in the buffer at which the data is written
  701. * @param length The maximum number of bytes to read
  702. * @return The total number of bytes copied to the buffer. May be less than the
  703. * length specified if the length was greater than the amount of available data.
  704. */
  705. public virtual int ReadInput(byte[] buffer, int offset, int length)
  706. {
  707. if (mBlocking)
  708. throw new InvalidOperationException("Cannot use ReadInput() in blocking mode! Use Stream instead.");
  709. return ReadApplicationData(buffer, offset, System.Math.Min(length, ApplicationDataAvailable()));
  710. }
  711. /**
  712. * Offer output from an arbitrary source. Only allowed in non-blocking mode.<br/>
  713. * <br/>
  714. * After this method returns, the specified section of the buffer will have been
  715. * processed. Use {@link #readOutput(byte[], int, int)} to get the bytes to
  716. * transmit to the other peer.<br/>
  717. * <br/>
  718. * This method must not be called until after the handshake is complete! Attempting
  719. * to call it before the handshake is complete will result in an exception.
  720. * @param buffer The buffer containing application data to encrypt
  721. * @param offset The offset at which to begin reading data
  722. * @param length The number of bytes of data to read
  723. * @throws IOException If an error occurs encrypting the data, or the handshake is not complete
  724. */
  725. public virtual void OfferOutput(byte[] buffer, int offset, int length)
  726. {
  727. if (mBlocking)
  728. throw new InvalidOperationException("Cannot use OfferOutput() in blocking mode! Use Stream instead.");
  729. if (!mAppDataReady)
  730. throw new IOException("Application data cannot be sent until the handshake is complete!");
  731. WriteData(buffer, offset, length);
  732. }
  733. /**
  734. * Gets the amount of encrypted data available to be sent. A call to
  735. * {@link #readOutput(byte[], int, int)} is guaranteed to be able to return at
  736. * least this much data.<br/>
  737. * <br/>
  738. * Only allowed in non-blocking mode.
  739. * @return The number of bytes of available encrypted data
  740. */
  741. public virtual int GetAvailableOutputBytes()
  742. {
  743. if (mBlocking)
  744. throw new InvalidOperationException("Cannot use GetAvailableOutputBytes() in blocking mode! Use Stream instead.");
  745. return mOutputBuffer.Available;
  746. }
  747. /**
  748. * Retrieves encrypted data to be sent. Use {@link #getAvailableOutputBytes()} to check
  749. * how much encrypted data is currently available. This method functions similarly to
  750. * {@link InputStream#read(byte[], int, int)}, except that it never blocks. If no data
  751. * is available, nothing will be copied and zero will be returned.<br/>
  752. * <br/>
  753. * Only allowed in non-blocking mode.
  754. * @param buffer The buffer to hold the encrypted data
  755. * @param offset The start offset in the buffer at which the data is written
  756. * @param length The maximum number of bytes to read
  757. * @return The total number of bytes copied to the buffer. May be less than the
  758. * length specified if the length was greater than the amount of available data.
  759. */
  760. public virtual int ReadOutput(byte[] buffer, int offset, int length)
  761. {
  762. if (mBlocking)
  763. throw new InvalidOperationException("Cannot use ReadOutput() in blocking mode! Use Stream instead.");
  764. return mOutputBuffer.Read(buffer, offset, length);
  765. }
  766. protected virtual void InvalidateSession()
  767. {
  768. if (this.mSessionParameters != null)
  769. {
  770. this.mSessionParameters.Clear();
  771. this.mSessionParameters = null;
  772. }
  773. if (this.mTlsSession != null)
  774. {
  775. this.mTlsSession.Invalidate();
  776. this.mTlsSession = null;
  777. }
  778. }
  779. protected virtual void ProcessFinishedMessage(MemoryStream buf)
  780. {
  781. if (mExpectedVerifyData == null)
  782. throw new TlsFatalAlert(AlertDescription.internal_error);
  783. byte[] verify_data = TlsUtilities.ReadFully(mExpectedVerifyData.Length, buf);
  784. AssertEmpty(buf);
  785. /*
  786. * Compare both checksums.
  787. */
  788. if (!Arrays.ConstantTimeAreEqual(mExpectedVerifyData, verify_data))
  789. {
  790. /*
  791. * Wrong checksum in the finished message.
  792. */
  793. throw new TlsFatalAlert(AlertDescription.decrypt_error);
  794. }
  795. }
  796. protected virtual void RaiseAlertFatal(byte alertDescription, string message, Exception cause)
  797. {
  798. Peer.NotifyAlertRaised(AlertLevel.fatal, alertDescription, message, cause);
  799. byte[] alert = new byte[]{ AlertLevel.fatal, alertDescription };
  800. try
  801. {
  802. mRecordStream.WriteRecord(ContentType.alert, alert, 0, 2);
  803. }
  804. catch (Exception)
  805. {
  806. // We are already processing an exception, so just ignore this
  807. }
  808. }
  809. protected virtual void RaiseAlertWarning(byte alertDescription, string message)
  810. {
  811. Peer.NotifyAlertRaised(AlertLevel.warning, alertDescription, message, null);
  812. byte[] alert = new byte[]{ AlertLevel.warning, alertDescription };
  813. SafeWriteRecord(ContentType.alert, alert, 0, 2);
  814. }
  815. protected virtual void SendCertificateMessage(Certificate certificate)
  816. {
  817. if (certificate == null)
  818. {
  819. certificate = Certificate.EmptyChain;
  820. }
  821. if (certificate.IsEmpty)
  822. {
  823. TlsContext context = Context;
  824. if (!context.IsServer)
  825. {
  826. ProtocolVersion serverVersion = Context.ServerVersion;
  827. if (serverVersion.IsSsl)
  828. {
  829. string errorMessage = serverVersion.ToString() + " client didn't provide credentials";
  830. RaiseAlertWarning(AlertDescription.no_certificate, errorMessage);
  831. return;
  832. }
  833. }
  834. }
  835. HandshakeMessage message = new HandshakeMessage(HandshakeType.certificate);
  836. certificate.Encode(message);
  837. message.WriteToRecordStream(this);
  838. }
  839. protected virtual void SendChangeCipherSpecMessage()
  840. {
  841. byte[] message = new byte[]{ 1 };
  842. SafeWriteRecord(ContentType.change_cipher_spec, message, 0, message.Length);
  843. mRecordStream.SentWriteCipherSpec();
  844. }
  845. protected virtual void SendFinishedMessage()
  846. {
  847. byte[] verify_data = CreateVerifyData(Context.IsServer);
  848. HandshakeMessage message = new HandshakeMessage(HandshakeType.finished, verify_data.Length);
  849. message.Write(verify_data, 0, verify_data.Length);
  850. message.WriteToRecordStream(this);
  851. }
  852. protected virtual void SendSupplementalDataMessage(IList supplementalData)
  853. {
  854. HandshakeMessage message = new HandshakeMessage(HandshakeType.supplemental_data);
  855. WriteSupplementalData(message, supplementalData);
  856. message.WriteToRecordStream(this);
  857. }
  858. protected virtual byte[] CreateVerifyData(bool isServer)
  859. {
  860. TlsContext context = Context;
  861. string asciiLabel = isServer ? ExporterLabel.server_finished : ExporterLabel.client_finished;
  862. byte[] sslSender = isServer ? TlsUtilities.SSL_SERVER : TlsUtilities.SSL_CLIENT;
  863. byte[] hash = GetCurrentPrfHash(context, mRecordStream.HandshakeHash, sslSender);
  864. return TlsUtilities.CalculateVerifyData(context, asciiLabel, hash);
  865. }
  866. /**
  867. * Closes this connection.
  868. *
  869. * @throws IOException If something goes wrong during closing.
  870. */
  871. public virtual void Close()
  872. {
  873. HandleClose(true);
  874. }
  875. protected internal virtual void Flush()
  876. {
  877. mRecordStream.Flush();
  878. }
  879. public virtual bool IsClosed
  880. {
  881. get { return mClosed; }
  882. }
  883. protected virtual short ProcessMaxFragmentLengthExtension(IDictionary clientExtensions, IDictionary serverExtensions,
  884. byte alertDescription)
  885. {
  886. short maxFragmentLength = TlsExtensionsUtilities.GetMaxFragmentLengthExtension(serverExtensions);
  887. if (maxFragmentLength >= 0)
  888. {
  889. if (!MaxFragmentLength.IsValid((byte)maxFragmentLength)
  890. || (!this.mResumedSession && maxFragmentLength != TlsExtensionsUtilities
  891. .GetMaxFragmentLengthExtension(clientExtensions)))
  892. {
  893. throw new TlsFatalAlert(alertDescription);
  894. }
  895. }
  896. return maxFragmentLength;
  897. }
  898. protected virtual void RefuseRenegotiation()
  899. {
  900. /*
  901. * RFC 5746 4.5 SSLv3 clients that refuse renegotiation SHOULD use a fatal
  902. * handshake_failure alert.
  903. */
  904. if (TlsUtilities.IsSsl(Context))
  905. throw new TlsFatalAlert(AlertDescription.handshake_failure);
  906. RaiseAlertWarning(AlertDescription.no_renegotiation, "Renegotiation not supported");
  907. }
  908. /**
  909. * Make sure the InputStream 'buf' now empty. Fail otherwise.
  910. *
  911. * @param buf The InputStream to check.
  912. * @throws IOException If 'buf' is not empty.
  913. */
  914. protected internal static void AssertEmpty(MemoryStream buf)
  915. {
  916. if (buf.Position < buf.Length)
  917. throw new TlsFatalAlert(AlertDescription.decode_error);
  918. }
  919. protected internal static byte[] CreateRandomBlock(bool useGmtUnixTime, IRandomGenerator randomGenerator)
  920. {
  921. byte[] result = new byte[32];
  922. randomGenerator.NextBytes(result);
  923. if (useGmtUnixTime)
  924. {
  925. TlsUtilities.WriteGmtUnixTime(result, 0);
  926. }
  927. return result;
  928. }
  929. protected internal static byte[] CreateRenegotiationInfo(byte[] renegotiated_connection)
  930. {
  931. return TlsUtilities.EncodeOpaque8(renegotiated_connection);
  932. }
  933. protected internal static void EstablishMasterSecret(TlsContext context, TlsKeyExchange keyExchange)
  934. {
  935. byte[] pre_master_secret = keyExchange.GeneratePremasterSecret();
  936. try
  937. {
  938. context.SecurityParameters.masterSecret = TlsUtilities.CalculateMasterSecret(context, pre_master_secret);
  939. }
  940. finally
  941. {
  942. // TODO Is there a way to ensure the data is really overwritten?
  943. /*
  944. * RFC 2246 8.1. The pre_master_secret should be deleted from memory once the
  945. * master_secret has been computed.
  946. */
  947. if (pre_master_secret != null)
  948. {
  949. Arrays.Fill(pre_master_secret, (byte)0);
  950. }
  951. }
  952. }
  953. /**
  954. * 'sender' only relevant to SSLv3
  955. */
  956. protected internal static byte[] GetCurrentPrfHash(TlsContext context, TlsHandshakeHash handshakeHash, byte[] sslSender)
  957. {
  958. IDigest d = handshakeHash.ForkPrfHash();
  959. if (sslSender != null && TlsUtilities.IsSsl(context))
  960. {
  961. d.BlockUpdate(sslSender, 0, sslSender.Length);
  962. }
  963. return DigestUtilities.DoFinal(d);
  964. }
  965. protected internal static IDictionary ReadExtensions(MemoryStream input)
  966. {
  967. if (input.Position >= input.Length)
  968. return null;
  969. byte[] extBytes = TlsUtilities.ReadOpaque16(input);
  970. AssertEmpty(input);
  971. MemoryStream buf = new MemoryStream(extBytes, false);
  972. // Integer -> byte[]
  973. IDictionary extensions = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateHashtable();
  974. while (buf.Position < buf.Length)
  975. {
  976. int extension_type = TlsUtilities.ReadUint16(buf);
  977. byte[] extension_data = TlsUtilities.ReadOpaque16(buf);
  978. /*
  979. * RFC 3546 2.3 There MUST NOT be more than one extension of the same type.
  980. */
  981. if (extensions.Contains(extension_type))
  982. throw new TlsFatalAlert(AlertDescription.illegal_parameter);
  983. extensions.Add(extension_type, extension_data);
  984. }
  985. return extensions;
  986. }
  987. protected internal static IList ReadSupplementalDataMessage(MemoryStream input)
  988. {
  989. byte[] supp_data = TlsUtilities.ReadOpaque24(input);
  990. AssertEmpty(input);
  991. MemoryStream buf = new MemoryStream(supp_data, false);
  992. IList supplementalData = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList();
  993. while (buf.Position < buf.Length)
  994. {
  995. int supp_data_type = TlsUtilities.ReadUint16(buf);
  996. byte[] data = TlsUtilities.ReadOpaque16(buf);
  997. supplementalData.Add(new SupplementalDataEntry(supp_data_type, data));
  998. }
  999. return supplementalData;
  1000. }
  1001. protected internal static void WriteExtensions(Stream output, IDictionary extensions)
  1002. {
  1003. MemoryStream buf = new MemoryStream();
  1004. /*
  1005. * NOTE: There are reports of servers that don't accept a zero-length extension as the last
  1006. * one, so we write out any zero-length ones first as a best-effort workaround.
  1007. */
  1008. WriteSelectedExtensions(buf, extensions, true);
  1009. WriteSelectedExtensions(buf, extensions, false);
  1010. byte[] extBytes = buf.ToArray();
  1011. TlsUtilities.WriteOpaque16(extBytes, output);
  1012. }
  1013. protected internal static void WriteSelectedExtensions(Stream output, IDictionary extensions, bool selectEmpty)
  1014. {
  1015. foreach (int extension_type in extensions.Keys)
  1016. {
  1017. byte[] extension_data = (byte[])extensions[extension_type];
  1018. if (selectEmpty == (extension_data.Length == 0))
  1019. {
  1020. TlsUtilities.CheckUint16(extension_type);
  1021. TlsUtilities.WriteUint16(extension_type, output);
  1022. TlsUtilities.WriteOpaque16(extension_data, output);
  1023. }
  1024. }
  1025. }
  1026. protected internal static void WriteSupplementalData(Stream output, IList supplementalData)
  1027. {
  1028. MemoryStream buf = new MemoryStream();
  1029. foreach (SupplementalDataEntry entry in supplementalData)
  1030. {
  1031. int supp_data_type = entry.DataType;
  1032. TlsUtilities.CheckUint16(supp_data_type);
  1033. TlsUtilities.WriteUint16(supp_data_type, buf);
  1034. TlsUtilities.WriteOpaque16(entry.Data, buf);
  1035. }
  1036. byte[] supp_data = buf.ToArray();
  1037. TlsUtilities.WriteOpaque24(supp_data, output);
  1038. }
  1039. protected internal static int GetPrfAlgorithm(TlsContext context, int ciphersuite)
  1040. {
  1041. bool isTLSv12 = TlsUtilities.IsTlsV12(context);
  1042. switch (ciphersuite)
  1043. {
  1044. case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA256:
  1045. case CipherSuite.TLS_DH_anon_WITH_AES_128_GCM_SHA256:
  1046. case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA256:
  1047. case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256:
  1048. case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256:
  1049. case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256:
  1050. case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
  1051. case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
  1052. case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
  1053. case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256:
  1054. case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256:
  1055. case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256:
  1056. case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
  1057. case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
  1058. case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
  1059. case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
  1060. case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
  1061. case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256:
  1062. case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
  1063. case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
  1064. case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
  1065. case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256:
  1066. case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256:
  1067. case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256:
  1068. case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM:
  1069. case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
  1070. case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_AES_128_OCB:
  1071. case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM:
  1072. case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_AES_256_OCB:
  1073. case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256:
  1074. case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
  1075. case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
  1076. case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM:
  1077. case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8:
  1078. case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
  1079. case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_AES_128_OCB:
  1080. case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
  1081. case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM:
  1082. case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8:
  1083. case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_AES_256_OCB:
  1084. case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
  1085. case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
  1086. case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256:
  1087. case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
  1088. case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
  1089. case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
  1090. case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
  1091. case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
  1092. case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
  1093. case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
  1094. case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256:
  1095. case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256:
  1096. case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
  1097. case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
  1098. case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
  1099. case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
  1100. case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_AES_128_OCB:
  1101. case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM:
  1102. case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
  1103. case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_AES_256_OCB:
  1104. case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256:
  1105. case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256:
  1106. case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
  1107. case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_128_OCB:
  1108. case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_256_OCB:
  1109. case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
  1110. case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
  1111. case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
  1112. case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_AES_128_OCB:
  1113. case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_AES_256_OCB:
  1114. case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
  1115. case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256:
  1116. case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
  1117. case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8:
  1118. case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8:
  1119. case CipherSuite.TLS_PSK_WITH_AES_128_CCM:
  1120. case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8:
  1121. case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256:
  1122. case CipherSuite.DRAFT_TLS_PSK_WITH_AES_128_OCB:
  1123. case CipherSuite.TLS_PSK_WITH_AES_256_CCM:
  1124. case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8:
  1125. case CipherSuite.DRAFT_TLS_PSK_WITH_AES_256_OCB:
  1126. case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256:
  1127. case CipherSuite.DRAFT_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256:
  1128. case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
  1129. case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256:
  1130. case CipherSuite.DRAFT_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256:
  1131. case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256:
  1132. case CipherSuite.TLS_RSA_WITH_AES_128_CCM:
  1133. case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8:
  1134. case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256:
  1135. case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256:
  1136. case CipherSuite.TLS_RSA_WITH_AES_256_CCM:
  1137. case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8:
  1138. case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256:
  1139. case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256:
  1140. case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256:
  1141. case CipherSuite.TLS_RSA_WITH_NULL_SHA256:
  1142. {
  1143. if (isTLSv12)
  1144. {
  1145. return PrfAlgorithm.tls_prf_sha256;
  1146. }
  1147. throw new TlsFatalAlert(AlertDescription.illegal_parameter);
  1148. }
  1149. case CipherSuite.TLS_DH_anon_WITH_AES_256_GCM_SHA384:
  1150. case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384:
  1151. case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
  1152. case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384:
  1153. case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
  1154. case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
  1155. case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
  1156. case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384:
  1157. case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
  1158. case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384:
  1159. case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
  1160. case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
  1161. case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
  1162. case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
  1163. case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
  1164. case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
  1165. case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
  1166. case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
  1167. case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384:
  1168. case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384:
  1169. case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
  1170. case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
  1171. case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384:
  1172. case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384:
  1173. case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
  1174. case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
  1175. case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384:
  1176. case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384:
  1177. case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384:
  1178. case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384:
  1179. case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
  1180. case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384:
  1181. case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384:
  1182. case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384:
  1183. {
  1184. if (isTLSv12)
  1185. {
  1186. return PrfAlgorithm.tls_prf_sha384;
  1187. }
  1188. throw new TlsFatalAlert(AlertDescription.illegal_parameter);
  1189. }
  1190. case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
  1191. case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
  1192. case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384:
  1193. case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384:
  1194. case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384:
  1195. case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384:
  1196. case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384:
  1197. case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384:
  1198. case CipherSuite.TLS_PSK_WITH_NULL_SHA384:
  1199. case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
  1200. case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384:
  1201. case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384:
  1202. {
  1203. if (isTLSv12)
  1204. {
  1205. return PrfAlgorithm.tls_prf_sha384;
  1206. }
  1207. return PrfAlgorithm.tls_prf_legacy;
  1208. }
  1209. default:
  1210. {
  1211. if (isTLSv12)
  1212. {
  1213. return PrfAlgorithm.tls_prf_sha256;
  1214. }
  1215. return PrfAlgorithm.tls_prf_legacy;
  1216. }
  1217. }
  1218. }
  1219. internal class HandshakeMessage
  1220. : MemoryStream
  1221. {
  1222. internal HandshakeMessage(byte handshakeType)
  1223. : this(handshakeType, 60)
  1224. {
  1225. }
  1226. internal HandshakeMessage(byte handshakeType, int length)
  1227. : base(length + 4)
  1228. {
  1229. TlsUtilities.WriteUint8(handshakeType, this);
  1230. // Reserve space for length
  1231. TlsUtilities.WriteUint24(0, this);
  1232. }
  1233. internal void Write(byte[] data)
  1234. {
  1235. Write(data, 0, data.Length);
  1236. }
  1237. internal void WriteToRecordStream(TlsProtocol protocol)
  1238. {
  1239. // Patch actual length back in
  1240. long length = Length - 4;
  1241. TlsUtilities.CheckUint24(length);
  1242. this.Position = 1;
  1243. TlsUtilities.WriteUint24((int)length, this);
  1244. #if PORTABLE || NETFX_CORE
  1245. byte[] buf = ToArray();
  1246. int bufLen = buf.Length;
  1247. #else
  1248. byte[] buf = GetBuffer();
  1249. int bufLen = (int)Length;
  1250. #endif
  1251. protocol.WriteHandshakeMessage(buf, 0, bufLen);
  1252. BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.Dispose(this);
  1253. }
  1254. }
  1255. }
  1256. }
  1257. #pragma warning restore
  1258. #endif