TlsProtocol.cs 55 KB

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