DtlsServerProtocol.cs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  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.Asn1.X509;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
  9. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  10. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Tls
  11. {
  12. public class DtlsServerProtocol
  13. : DtlsProtocol
  14. {
  15. protected bool mVerifyRequests = true;
  16. public DtlsServerProtocol(SecureRandom secureRandom)
  17. : base(secureRandom)
  18. {
  19. }
  20. public virtual bool VerifyRequests
  21. {
  22. get { return mVerifyRequests; }
  23. set { this.mVerifyRequests = value; }
  24. }
  25. public virtual DtlsTransport Accept(TlsServer server, DatagramTransport transport)
  26. {
  27. if (server == null)
  28. throw new ArgumentNullException("server");
  29. if (transport == null)
  30. throw new ArgumentNullException("transport");
  31. SecurityParameters securityParameters = new SecurityParameters();
  32. securityParameters.entity = ConnectionEnd.server;
  33. ServerHandshakeState state = new ServerHandshakeState();
  34. state.server = server;
  35. state.serverContext = new TlsServerContextImpl(mSecureRandom, securityParameters);
  36. securityParameters.serverRandom = TlsProtocol.CreateRandomBlock(server.ShouldUseGmtUnixTime(),
  37. state.serverContext.NonceRandomGenerator);
  38. server.Init(state.serverContext);
  39. DtlsRecordLayer recordLayer = new DtlsRecordLayer(transport, state.serverContext, server, ContentType.handshake);
  40. // TODO Need to handle sending of HelloVerifyRequest without entering a full connection
  41. try
  42. {
  43. return ServerHandshake(state, recordLayer);
  44. }
  45. catch (TlsFatalAlert fatalAlert)
  46. {
  47. AbortServerHandshake(state, recordLayer, fatalAlert.AlertDescription);
  48. throw fatalAlert;
  49. }
  50. catch (IOException e)
  51. {
  52. AbortServerHandshake(state, recordLayer, AlertDescription.internal_error);
  53. throw e;
  54. }
  55. catch (Exception e)
  56. {
  57. AbortServerHandshake(state, recordLayer, AlertDescription.internal_error);
  58. throw new TlsFatalAlert(AlertDescription.internal_error, e);
  59. }
  60. finally
  61. {
  62. securityParameters.Clear();
  63. }
  64. }
  65. internal virtual void AbortServerHandshake(ServerHandshakeState state, DtlsRecordLayer recordLayer, byte alertDescription)
  66. {
  67. recordLayer.Fail(alertDescription);
  68. InvalidateSession(state);
  69. }
  70. internal virtual DtlsTransport ServerHandshake(ServerHandshakeState state, DtlsRecordLayer recordLayer)
  71. {
  72. SecurityParameters securityParameters = state.serverContext.SecurityParameters;
  73. DtlsReliableHandshake handshake = new DtlsReliableHandshake(state.serverContext, recordLayer);
  74. DtlsReliableHandshake.Message clientMessage = handshake.ReceiveMessage();
  75. // NOTE: DTLSRecordLayer requires any DTLS version, we don't otherwise constrain this
  76. //ProtocolVersion recordLayerVersion = recordLayer.ReadVersion;
  77. if (clientMessage.Type == HandshakeType.client_hello)
  78. {
  79. ProcessClientHello(state, clientMessage.Body);
  80. }
  81. else
  82. {
  83. throw new TlsFatalAlert(AlertDescription.unexpected_message);
  84. }
  85. {
  86. byte[] serverHelloBody = GenerateServerHello(state);
  87. ApplyMaxFragmentLengthExtension(recordLayer, securityParameters.maxFragmentLength);
  88. ProtocolVersion recordLayerVersion = state.serverContext.ServerVersion;
  89. recordLayer.ReadVersion = recordLayerVersion;
  90. recordLayer.SetWriteVersion(recordLayerVersion);
  91. handshake.SendMessage(HandshakeType.server_hello, serverHelloBody);
  92. }
  93. handshake.NotifyHelloComplete();
  94. IList serverSupplementalData = state.server.GetServerSupplementalData();
  95. if (serverSupplementalData != null)
  96. {
  97. byte[] supplementalDataBody = GenerateSupplementalData(serverSupplementalData);
  98. handshake.SendMessage(HandshakeType.supplemental_data, supplementalDataBody);
  99. }
  100. state.keyExchange = state.server.GetKeyExchange();
  101. state.keyExchange.Init(state.serverContext);
  102. state.serverCredentials = state.server.GetCredentials();
  103. Certificate serverCertificate = null;
  104. if (state.serverCredentials == null)
  105. {
  106. state.keyExchange.SkipServerCredentials();
  107. }
  108. else
  109. {
  110. state.keyExchange.ProcessServerCredentials(state.serverCredentials);
  111. serverCertificate = state.serverCredentials.Certificate;
  112. byte[] certificateBody = GenerateCertificate(serverCertificate);
  113. handshake.SendMessage(HandshakeType.certificate, certificateBody);
  114. }
  115. // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus
  116. if (serverCertificate == null || serverCertificate.IsEmpty)
  117. {
  118. state.allowCertificateStatus = false;
  119. }
  120. if (state.allowCertificateStatus)
  121. {
  122. CertificateStatus certificateStatus = state.server.GetCertificateStatus();
  123. if (certificateStatus != null)
  124. {
  125. byte[] certificateStatusBody = GenerateCertificateStatus(state, certificateStatus);
  126. handshake.SendMessage(HandshakeType.certificate_status, certificateStatusBody);
  127. }
  128. }
  129. byte[] serverKeyExchange = state.keyExchange.GenerateServerKeyExchange();
  130. if (serverKeyExchange != null)
  131. {
  132. handshake.SendMessage(HandshakeType.server_key_exchange, serverKeyExchange);
  133. }
  134. if (state.serverCredentials != null)
  135. {
  136. state.certificateRequest = state.server.GetCertificateRequest();
  137. if (state.certificateRequest != null)
  138. {
  139. if (TlsUtilities.IsTlsV12(state.serverContext) != (state.certificateRequest.SupportedSignatureAlgorithms != null))
  140. throw new TlsFatalAlert(AlertDescription.internal_error);
  141. state.keyExchange.ValidateCertificateRequest(state.certificateRequest);
  142. byte[] certificateRequestBody = GenerateCertificateRequest(state, state.certificateRequest);
  143. handshake.SendMessage(HandshakeType.certificate_request, certificateRequestBody);
  144. TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash,
  145. state.certificateRequest.SupportedSignatureAlgorithms);
  146. }
  147. }
  148. handshake.SendMessage(HandshakeType.server_hello_done, TlsUtilities.EmptyBytes);
  149. handshake.HandshakeHash.SealHashAlgorithms();
  150. clientMessage = handshake.ReceiveMessage();
  151. if (clientMessage.Type == HandshakeType.supplemental_data)
  152. {
  153. ProcessClientSupplementalData(state, clientMessage.Body);
  154. clientMessage = handshake.ReceiveMessage();
  155. }
  156. else
  157. {
  158. state.server.ProcessClientSupplementalData(null);
  159. }
  160. if (state.certificateRequest == null)
  161. {
  162. state.keyExchange.SkipClientCredentials();
  163. }
  164. else
  165. {
  166. if (clientMessage.Type == HandshakeType.certificate)
  167. {
  168. ProcessClientCertificate(state, clientMessage.Body);
  169. clientMessage = handshake.ReceiveMessage();
  170. }
  171. else
  172. {
  173. if (TlsUtilities.IsTlsV12(state.serverContext))
  174. {
  175. /*
  176. * RFC 5246 If no suitable certificate is available, the client MUST send a
  177. * certificate message containing no certificates.
  178. *
  179. * NOTE: In previous RFCs, this was SHOULD instead of MUST.
  180. */
  181. throw new TlsFatalAlert(AlertDescription.unexpected_message);
  182. }
  183. NotifyClientCertificate(state, Certificate.EmptyChain);
  184. }
  185. }
  186. if (clientMessage.Type == HandshakeType.client_key_exchange)
  187. {
  188. ProcessClientKeyExchange(state, clientMessage.Body);
  189. }
  190. else
  191. {
  192. throw new TlsFatalAlert(AlertDescription.unexpected_message);
  193. }
  194. TlsHandshakeHash prepareFinishHash = handshake.PrepareToFinish();
  195. securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.serverContext, prepareFinishHash, null);
  196. TlsProtocol.EstablishMasterSecret(state.serverContext, state.keyExchange);
  197. recordLayer.InitPendingEpoch(state.server.GetCipher());
  198. /*
  199. * RFC 5246 7.4.8 This message is only sent following a client certificate that has signing
  200. * capability (i.e., all certificates except those containing fixed Diffie-Hellman
  201. * parameters).
  202. */
  203. if (ExpectCertificateVerifyMessage(state))
  204. {
  205. byte[] certificateVerifyBody = handshake.ReceiveMessageBody(HandshakeType.certificate_verify);
  206. ProcessCertificateVerify(state, certificateVerifyBody, prepareFinishHash);
  207. }
  208. // NOTE: Calculated exclusive of the actual Finished message from the client
  209. byte[] expectedClientVerifyData = TlsUtilities.CalculateVerifyData(state.serverContext, ExporterLabel.client_finished,
  210. TlsProtocol.GetCurrentPrfHash(state.serverContext, handshake.HandshakeHash, null));
  211. ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), expectedClientVerifyData);
  212. if (state.expectSessionTicket)
  213. {
  214. NewSessionTicket newSessionTicket = state.server.GetNewSessionTicket();
  215. byte[] newSessionTicketBody = GenerateNewSessionTicket(state, newSessionTicket);
  216. handshake.SendMessage(HandshakeType.session_ticket, newSessionTicketBody);
  217. }
  218. // NOTE: Calculated exclusive of the Finished message itself
  219. byte[] serverVerifyData = TlsUtilities.CalculateVerifyData(state.serverContext, ExporterLabel.server_finished,
  220. TlsProtocol.GetCurrentPrfHash(state.serverContext, handshake.HandshakeHash, null));
  221. handshake.SendMessage(HandshakeType.finished, serverVerifyData);
  222. handshake.Finish();
  223. //{
  224. // state.sessionParameters = new SessionParameters.Builder()
  225. // .SetCipherSuite(securityParameters.CipherSuite)
  226. // .SetCompressionAlgorithm(securityParameters.CompressionAlgorithm)
  227. // .SetExtendedMasterSecret(securityParameters.IsExtendedMasterSecret)
  228. // .SetMasterSecret(securityParameters.MasterSecret)
  229. // .SetPeerCertificate(state.clientCertificate)
  230. // .SetPskIdentity(securityParameters.PskIdentity)
  231. // .SetSrpIdentity(securityParameters.SrpIdentity)
  232. // // TODO Consider filtering extensions that aren't relevant to resumed sessions
  233. // .SetServerExtensions(state.serverExtensions)
  234. // .Build();
  235. // state.tlsSession = TlsUtilities.ImportSession(state.tlsSession.SessionID, state.sessionParameters);
  236. // state.serverContext.SetResumableSession(state.tlsSession);
  237. //}
  238. state.server.NotifyHandshakeComplete();
  239. return new DtlsTransport(recordLayer);
  240. }
  241. protected virtual void InvalidateSession(ServerHandshakeState state)
  242. {
  243. if (state.sessionParameters != null)
  244. {
  245. state.sessionParameters.Clear();
  246. state.sessionParameters = null;
  247. }
  248. if (state.tlsSession != null)
  249. {
  250. state.tlsSession.Invalidate();
  251. state.tlsSession = null;
  252. }
  253. }
  254. protected virtual byte[] GenerateCertificateRequest(ServerHandshakeState state, CertificateRequest certificateRequest)
  255. {
  256. MemoryStream buf = new MemoryStream();
  257. certificateRequest.Encode(buf);
  258. return buf.ToArray();
  259. }
  260. protected virtual byte[] GenerateCertificateStatus(ServerHandshakeState state, CertificateStatus certificateStatus)
  261. {
  262. MemoryStream buf = new MemoryStream();
  263. certificateStatus.Encode(buf);
  264. return buf.ToArray();
  265. }
  266. protected virtual byte[] GenerateNewSessionTicket(ServerHandshakeState state, NewSessionTicket newSessionTicket)
  267. {
  268. MemoryStream buf = new MemoryStream();
  269. newSessionTicket.Encode(buf);
  270. return buf.ToArray();
  271. }
  272. protected virtual byte[] GenerateServerHello(ServerHandshakeState state)
  273. {
  274. SecurityParameters securityParameters = state.serverContext.SecurityParameters;
  275. MemoryStream buf = new MemoryStream();
  276. {
  277. ProtocolVersion server_version = state.server.GetServerVersion();
  278. if (!server_version.IsEqualOrEarlierVersionOf(state.serverContext.ClientVersion))
  279. throw new TlsFatalAlert(AlertDescription.internal_error);
  280. // TODO Read RFCs for guidance on the expected record layer version number
  281. // recordStream.setReadVersion(server_version);
  282. // recordStream.setWriteVersion(server_version);
  283. // recordStream.setRestrictReadVersion(true);
  284. state.serverContext.SetServerVersion(server_version);
  285. TlsUtilities.WriteVersion(state.serverContext.ServerVersion, buf);
  286. }
  287. buf.Write(securityParameters.ServerRandom, 0, securityParameters.ServerRandom.Length);
  288. /*
  289. * The server may return an empty session_id to indicate that the session will not be cached
  290. * and therefore cannot be resumed.
  291. */
  292. TlsUtilities.WriteOpaque8(TlsUtilities.EmptyBytes, buf);
  293. int selectedCipherSuite = state.server.GetSelectedCipherSuite();
  294. if (!Arrays.Contains(state.offeredCipherSuites, selectedCipherSuite)
  295. || selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL
  296. || CipherSuite.IsScsv(selectedCipherSuite)
  297. || !TlsUtilities.IsValidCipherSuiteForVersion(selectedCipherSuite, state.serverContext.ServerVersion))
  298. {
  299. throw new TlsFatalAlert(AlertDescription.internal_error);
  300. }
  301. ValidateSelectedCipherSuite(selectedCipherSuite, AlertDescription.internal_error);
  302. securityParameters.cipherSuite = selectedCipherSuite;
  303. byte selectedCompressionMethod = state.server.GetSelectedCompressionMethod();
  304. if (!Arrays.Contains(state.offeredCompressionMethods, selectedCompressionMethod))
  305. throw new TlsFatalAlert(AlertDescription.internal_error);
  306. securityParameters.compressionAlgorithm = selectedCompressionMethod;
  307. TlsUtilities.WriteUint16(selectedCipherSuite, buf);
  308. TlsUtilities.WriteUint8(selectedCompressionMethod, buf);
  309. state.serverExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(state.server.GetServerExtensions());
  310. /*
  311. * RFC 5746 3.6. Server Behavior: Initial Handshake
  312. */
  313. if (state.secure_renegotiation)
  314. {
  315. byte[] renegExtData = TlsUtilities.GetExtensionData(state.serverExtensions, ExtensionType.renegotiation_info);
  316. bool noRenegExt = (null == renegExtData);
  317. if (noRenegExt)
  318. {
  319. /*
  320. * Note that sending a "renegotiation_info" extension in response to a ClientHello
  321. * containing only the SCSV is an explicit exception to the prohibition in RFC 5246,
  322. * Section 7.4.1.4, on the server sending unsolicited extensions and is only allowed
  323. * because the client is signaling its willingness to receive the extension via the
  324. * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV.
  325. */
  326. /*
  327. * If the secure_renegotiation flag is set to TRUE, the server MUST include an empty
  328. * "renegotiation_info" extension in the ServerHello message.
  329. */
  330. state.serverExtensions[ExtensionType.renegotiation_info] = TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes);
  331. }
  332. }
  333. if (securityParameters.IsExtendedMasterSecret)
  334. {
  335. TlsExtensionsUtilities.AddExtendedMasterSecretExtension(state.serverExtensions);
  336. }
  337. /*
  338. * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore
  339. * extensions appearing in the client hello, and send a server hello containing no
  340. * extensions.
  341. */
  342. if (state.serverExtensions.Count > 0)
  343. {
  344. securityParameters.encryptThenMac = TlsExtensionsUtilities.HasEncryptThenMacExtension(state.serverExtensions);
  345. securityParameters.maxFragmentLength = EvaluateMaxFragmentLengthExtension(state.resumedSession,
  346. state.clientExtensions, state.serverExtensions, AlertDescription.internal_error);
  347. securityParameters.truncatedHMac = TlsExtensionsUtilities.HasTruncatedHMacExtension(state.serverExtensions);
  348. /*
  349. * TODO It's surprising that there's no provision to allow a 'fresh' CertificateStatus to be sent in
  350. * a session resumption handshake.
  351. */
  352. state.allowCertificateStatus = !state.resumedSession
  353. && TlsUtilities.HasExpectedEmptyExtensionData(state.serverExtensions, ExtensionType.status_request,
  354. AlertDescription.internal_error);
  355. state.expectSessionTicket = !state.resumedSession
  356. && TlsUtilities.HasExpectedEmptyExtensionData(state.serverExtensions, ExtensionType.session_ticket,
  357. AlertDescription.internal_error);
  358. TlsProtocol.WriteExtensions(buf, state.serverExtensions);
  359. }
  360. securityParameters.prfAlgorithm = TlsProtocol.GetPrfAlgorithm(state.serverContext,
  361. securityParameters.CipherSuite);
  362. /*
  363. * RFC 5246 7.4.9. Any cipher suite which does not explicitly specify verify_data_length
  364. * has a verify_data_length equal to 12. This includes all existing cipher suites.
  365. */
  366. securityParameters.verifyDataLength = 12;
  367. return buf.ToArray();
  368. }
  369. protected virtual void NotifyClientCertificate(ServerHandshakeState state, Certificate clientCertificate)
  370. {
  371. if (state.certificateRequest == null)
  372. throw new InvalidOperationException();
  373. if (state.clientCertificate != null)
  374. throw new TlsFatalAlert(AlertDescription.unexpected_message);
  375. state.clientCertificate = clientCertificate;
  376. if (clientCertificate.IsEmpty)
  377. {
  378. state.keyExchange.SkipClientCredentials();
  379. }
  380. else
  381. {
  382. /*
  383. * TODO RFC 5246 7.4.6. If the certificate_authorities list in the certificate request
  384. * message was non-empty, one of the certificates in the certificate chain SHOULD be
  385. * issued by one of the listed CAs.
  386. */
  387. state.clientCertificateType = TlsUtilities.GetClientCertificateType(clientCertificate,
  388. state.serverCredentials.Certificate);
  389. state.keyExchange.ProcessClientCertificate(clientCertificate);
  390. }
  391. /*
  392. * RFC 5246 7.4.6. If the client does not send any certificates, the server MAY at its
  393. * discretion either continue the handshake without client authentication, or respond with a
  394. * fatal handshake_failure alert. Also, if some aspect of the certificate chain was
  395. * unacceptable (e.g., it was not signed by a known, trusted CA), the server MAY at its
  396. * discretion either continue the handshake (considering the client unauthenticated) or send
  397. * a fatal alert.
  398. */
  399. state.server.NotifyClientCertificate(clientCertificate);
  400. }
  401. protected virtual void ProcessClientCertificate(ServerHandshakeState state, byte[] body)
  402. {
  403. MemoryStream buf = new MemoryStream(body, false);
  404. Certificate clientCertificate = Certificate.Parse(buf);
  405. TlsProtocol.AssertEmpty(buf);
  406. NotifyClientCertificate(state, clientCertificate);
  407. }
  408. protected virtual void ProcessCertificateVerify(ServerHandshakeState state, byte[] body, TlsHandshakeHash prepareFinishHash)
  409. {
  410. if (state.certificateRequest == null)
  411. throw new InvalidOperationException();
  412. MemoryStream buf = new MemoryStream(body, false);
  413. TlsServerContextImpl context = state.serverContext;
  414. DigitallySigned clientCertificateVerify = DigitallySigned.Parse(context, buf);
  415. TlsProtocol.AssertEmpty(buf);
  416. // Verify the CertificateVerify message contains a correct signature.
  417. try
  418. {
  419. SignatureAndHashAlgorithm signatureAlgorithm = clientCertificateVerify.Algorithm;
  420. byte[] hash;
  421. if (TlsUtilities.IsTlsV12(context))
  422. {
  423. TlsUtilities.VerifySupportedSignatureAlgorithm(state.certificateRequest.SupportedSignatureAlgorithms, signatureAlgorithm);
  424. hash = prepareFinishHash.GetFinalHash(signatureAlgorithm.Hash);
  425. }
  426. else
  427. {
  428. hash = context.SecurityParameters.SessionHash;
  429. }
  430. X509CertificateStructure x509Cert = state.clientCertificate.GetCertificateAt(0);
  431. SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo;
  432. AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(keyInfo);
  433. TlsSigner tlsSigner = TlsUtilities.CreateTlsSigner((byte)state.clientCertificateType);
  434. tlsSigner.Init(context);
  435. if (!tlsSigner.VerifyRawSignature(signatureAlgorithm, clientCertificateVerify.Signature, publicKey, hash))
  436. throw new TlsFatalAlert(AlertDescription.decrypt_error);
  437. }
  438. catch (TlsFatalAlert e)
  439. {
  440. throw e;
  441. }
  442. catch (Exception e)
  443. {
  444. throw new TlsFatalAlert(AlertDescription.decrypt_error, e);
  445. }
  446. }
  447. protected virtual void ProcessClientHello(ServerHandshakeState state, byte[] body)
  448. {
  449. MemoryStream buf = new MemoryStream(body, false);
  450. // TODO Read RFCs for guidance on the expected record layer version number
  451. ProtocolVersion client_version = TlsUtilities.ReadVersion(buf);
  452. if (!client_version.IsDtls)
  453. throw new TlsFatalAlert(AlertDescription.illegal_parameter);
  454. /*
  455. * Read the client random
  456. */
  457. byte[] client_random = TlsUtilities.ReadFully(32, buf);
  458. byte[] sessionID = TlsUtilities.ReadOpaque8(buf);
  459. if (sessionID.Length > 32)
  460. throw new TlsFatalAlert(AlertDescription.illegal_parameter);
  461. // TODO RFC 4347 has the cookie length restricted to 32, but not in RFC 6347
  462. byte[] cookie = TlsUtilities.ReadOpaque8(buf);
  463. int cipher_suites_length = TlsUtilities.ReadUint16(buf);
  464. if (cipher_suites_length < 2 || (cipher_suites_length & 1) != 0)
  465. {
  466. throw new TlsFatalAlert(AlertDescription.decode_error);
  467. }
  468. /*
  469. * NOTE: "If the session_id field is not empty (implying a session resumption request) this
  470. * vector must include at least the cipher_suite from that session."
  471. */
  472. state.offeredCipherSuites = TlsUtilities.ReadUint16Array(cipher_suites_length / 2, buf);
  473. int compression_methods_length = TlsUtilities.ReadUint8(buf);
  474. if (compression_methods_length < 1)
  475. {
  476. throw new TlsFatalAlert(AlertDescription.illegal_parameter);
  477. }
  478. state.offeredCompressionMethods = TlsUtilities.ReadUint8Array(compression_methods_length, buf);
  479. /*
  480. * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore
  481. * extensions appearing in the client hello, and send a server hello containing no
  482. * extensions.
  483. */
  484. state.clientExtensions = TlsProtocol.ReadExtensions(buf);
  485. TlsServerContextImpl context = state.serverContext;
  486. SecurityParameters securityParameters = context.SecurityParameters;
  487. /*
  488. * TODO[resumption] Check RFC 7627 5.4. for required behaviour
  489. */
  490. /*
  491. * RFC 7627 4. Clients and servers SHOULD NOT accept handshakes that do not use the extended
  492. * master secret [..]. (and see 5.2, 5.3)
  493. */
  494. securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(state.clientExtensions);
  495. if (!securityParameters.IsExtendedMasterSecret && state.server.RequiresExtendedMasterSecret())
  496. {
  497. throw new TlsFatalAlert(AlertDescription.handshake_failure);
  498. }
  499. context.SetClientVersion(client_version);
  500. state.server.NotifyClientVersion(client_version);
  501. state.server.NotifyFallback(Arrays.Contains(state.offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV));
  502. securityParameters.clientRandom = client_random;
  503. state.server.NotifyOfferedCipherSuites(state.offeredCipherSuites);
  504. state.server.NotifyOfferedCompressionMethods(state.offeredCompressionMethods);
  505. /*
  506. * RFC 5746 3.6. Server Behavior: Initial Handshake
  507. */
  508. {
  509. /*
  510. * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension,
  511. * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the
  512. * ClientHello. Including both is NOT RECOMMENDED.
  513. */
  514. /*
  515. * When a ClientHello is received, the server MUST check if it includes the
  516. * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If it does, set the secure_renegotiation flag
  517. * to TRUE.
  518. */
  519. if (Arrays.Contains(state.offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV))
  520. {
  521. state.secure_renegotiation = true;
  522. }
  523. /*
  524. * The server MUST check if the "renegotiation_info" extension is included in the
  525. * ClientHello.
  526. */
  527. byte[] renegExtData = TlsUtilities.GetExtensionData(state.clientExtensions, ExtensionType.renegotiation_info);
  528. if (renegExtData != null)
  529. {
  530. /*
  531. * If the extension is present, set secure_renegotiation flag to TRUE. The
  532. * server MUST then verify that the length of the "renegotiated_connection"
  533. * field is zero, and if it is not, MUST abort the handshake.
  534. */
  535. state.secure_renegotiation = true;
  536. if (!Arrays.ConstantTimeAreEqual(renegExtData, TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes)))
  537. throw new TlsFatalAlert(AlertDescription.handshake_failure);
  538. }
  539. }
  540. state.server.NotifySecureRenegotiation(state.secure_renegotiation);
  541. if (state.clientExtensions != null)
  542. {
  543. // NOTE: Validates the padding extension data, if present
  544. TlsExtensionsUtilities.GetPaddingExtension(state.clientExtensions);
  545. state.server.ProcessClientExtensions(state.clientExtensions);
  546. }
  547. }
  548. protected virtual void ProcessClientKeyExchange(ServerHandshakeState state, byte[] body)
  549. {
  550. MemoryStream buf = new MemoryStream(body, false);
  551. state.keyExchange.ProcessClientKeyExchange(buf);
  552. TlsProtocol.AssertEmpty(buf);
  553. }
  554. protected virtual void ProcessClientSupplementalData(ServerHandshakeState state, byte[] body)
  555. {
  556. MemoryStream buf = new MemoryStream(body, false);
  557. IList clientSupplementalData = TlsProtocol.ReadSupplementalDataMessage(buf);
  558. state.server.ProcessClientSupplementalData(clientSupplementalData);
  559. }
  560. protected virtual bool ExpectCertificateVerifyMessage(ServerHandshakeState state)
  561. {
  562. return state.clientCertificateType >= 0 && TlsUtilities.HasSigningCapability((byte)state.clientCertificateType);
  563. }
  564. protected internal class ServerHandshakeState
  565. {
  566. internal TlsServer server = null;
  567. internal TlsServerContextImpl serverContext = null;
  568. internal TlsSession tlsSession = null;
  569. internal SessionParameters sessionParameters = null;
  570. internal SessionParameters.Builder sessionParametersBuilder = null;
  571. internal int[] offeredCipherSuites = null;
  572. internal byte[] offeredCompressionMethods = null;
  573. internal IDictionary clientExtensions = null;
  574. internal IDictionary serverExtensions = null;
  575. internal bool resumedSession = false;
  576. internal bool secure_renegotiation = false;
  577. internal bool allowCertificateStatus = false;
  578. internal bool expectSessionTicket = false;
  579. internal TlsKeyExchange keyExchange = null;
  580. internal TlsCredentials serverCredentials = null;
  581. internal CertificateRequest certificateRequest = null;
  582. internal short clientCertificateType = -1;
  583. internal Certificate clientCertificate = null;
  584. }
  585. }
  586. }
  587. #pragma warning restore
  588. #endif