e4ebf9516c11fefd9e5ad16dde59170e0129c44c
[BoarSSL] / SSLTLS / SSLEngine.cs
1 /*
2 * Copyright (c) 2017 Thomas Pornin <pornin@bolet.org>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25 using System;
26 using System.Collections.Generic;
27 using System.IO;
28 using System.Text;
29
30 using Crypto;
31
32 namespace SSLTLS {
33
34 /*
35 * This is the base class common to SSLClient and SSLServer.
36 */
37
38 public abstract class SSLEngine : Stream {
39
40 Stream sub;
41 InputRecord inRec;
42 OutputRecord outRec;
43 int deferredAlert;
44 int state;
45 int versionMin;
46 int actualVersion;
47 bool receivedNoReneg;
48
49 /*
50 * Functions used to hash handshake messages.
51 */
52 MD5 md5;
53 SHA1 sha1;
54 SHA256 sha256;
55 SHA384 sha384;
56
57 /*
58 * State:
59 * STATE_HANDSHAKE expecting handshake message only
60 * STATE_CCS expecting Change Cipher Spec message only
61 * STATE_APPDATA expecting application data or handshake
62 * STATE_CLOSING expecting only alert (close_notify)
63 * STATE_CLOSED closed
64 */
65 internal const int STATE_CLOSED = 0;
66 internal const int STATE_HANDSHAKE = 1;
67 internal const int STATE_CCS = 2;
68 internal const int STATE_APPDATA = 3;
69 internal const int STATE_CLOSING = 4;
70
71 /*
72 * Default cipher suites.
73 */
74 static int[] DEFAULT_CIPHER_SUITES = {
75 SSL.ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
76 SSL.ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
77
78 SSL.ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
79 SSL.ECDHE_RSA_WITH_AES_128_GCM_SHA256,
80 SSL.ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
81 SSL.ECDHE_RSA_WITH_AES_256_GCM_SHA384,
82 SSL.ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
83 SSL.ECDHE_RSA_WITH_AES_128_CBC_SHA256,
84 SSL.ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
85 SSL.ECDHE_RSA_WITH_AES_256_CBC_SHA384,
86 SSL.ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
87 SSL.ECDHE_RSA_WITH_AES_128_CBC_SHA,
88 SSL.ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
89 SSL.ECDHE_RSA_WITH_AES_256_CBC_SHA,
90
91 SSL.ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
92 SSL.ECDH_RSA_WITH_AES_128_GCM_SHA256,
93 SSL.ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
94 SSL.ECDH_RSA_WITH_AES_256_GCM_SHA384,
95 SSL.ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
96 SSL.ECDH_RSA_WITH_AES_128_CBC_SHA256,
97 SSL.ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
98 SSL.ECDH_RSA_WITH_AES_256_CBC_SHA384,
99 SSL.ECDH_ECDSA_WITH_AES_128_CBC_SHA,
100 SSL.ECDH_RSA_WITH_AES_128_CBC_SHA,
101 SSL.ECDH_ECDSA_WITH_AES_256_CBC_SHA,
102 SSL.ECDH_RSA_WITH_AES_256_CBC_SHA,
103
104 SSL.RSA_WITH_AES_128_GCM_SHA256,
105 SSL.RSA_WITH_AES_256_GCM_SHA384,
106 SSL.RSA_WITH_AES_128_CBC_SHA256,
107 SSL.RSA_WITH_AES_256_CBC_SHA256,
108 SSL.RSA_WITH_AES_128_CBC_SHA,
109 SSL.RSA_WITH_AES_256_CBC_SHA,
110
111 SSL.ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
112 SSL.ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
113 SSL.ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
114 SSL.ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
115 SSL.RSA_WITH_3DES_EDE_CBC_SHA
116 };
117
118 /*
119 * Default curves.
120 */
121 static int[] DEFAULT_CURVES = {
122 SSL.Curve25519,
123 SSL.NIST_P256,
124 SSL.NIST_P384,
125 SSL.NIST_P521
126 };
127
128 /*
129 * Default hash and sign algorithms.
130 */
131 static int[] DEFAULT_HASHANDSIGN = {
132 SSL.ECDSA_SHA256,
133 SSL.RSA_SHA256,
134 SSL.ECDSA_SHA224,
135 SSL.RSA_SHA224,
136 SSL.ECDSA_SHA384,
137 SSL.RSA_SHA384,
138 SSL.ECDSA_SHA512,
139 SSL.RSA_SHA512,
140 SSL.ECDSA_SHA1,
141 SSL.RSA_SHA1
142 };
143
144 internal byte[] clientRandom;
145 internal byte[] serverRandom;
146 internal byte[] sessionID;
147
148 /*
149 * 'renegSupport' is one of:
150 * 0 initial handshake not done yet
151 * 1 peer supports secure renegotiation
152 * -1 peer does not support secure renegotiation
153 */
154 internal int renegSupport;
155 internal byte[] savedClientFinished;
156 internal byte[] savedServerFinished;
157
158 byte[] masterSecret;
159
160 /*
161 * Create a new engine over the provided transport stream.
162 */
163 public SSLEngine(Stream sub)
164 {
165 this.sub = sub;
166 inRec = new InputRecord(sub);
167 outRec = new OutputRecord(sub);
168 md5 = new MD5();
169 sha1 = new SHA1();
170 sha256 = new SHA256();
171 sha384 = new SHA384();
172 state = STATE_HANDSHAKE;
173 deferredAlert = -1;
174 AutoFlush = true;
175 CloseSub = true;
176 OnClose = null;
177 NoCloseNotify = false;
178 ClosedWithoutNotify = false;
179 MaximumHandshakeMessageLength = 65536;
180 SupportedCipherSuites = DEFAULT_CIPHER_SUITES;
181 SupportedCurves = DEFAULT_CURVES;
182 SupportedHashAndSign = DEFAULT_HASHANDSIGN;
183 VersionMin = SSL.TLS10;
184 VersionMax = SSL.TLS12;
185 AllowRenegotiation = true;
186 receivedNoReneg = false;
187 clientRandom = new byte[32];
188 serverRandom = new byte[32];
189 masterSecret = new byte[48];
190 HandshakeCount = 0;
191 }
192
193 /*
194 * If 'NormalizeIOError' is true, then I/O errors while writing
195 * on the underlying stream will be reported as a generic
196 * SSLException with message "Unexpected transport closure".
197 * This helps test code that expects an asynchronous abort that
198 * may be detected during a read of a write operation, depending
199 * on the exact timing. Default is false.
200 */
201 public bool NormalizeIOError {
202 get {
203 return outRec.NormalizeIOError;
204 }
205 set {
206 outRec.NormalizeIOError = value;
207 }
208 }
209
210 /*
211 * If 'AutoFlush' is true, then after every Write() or WriteByte()
212 * call, the current record is assembled and sent, leaving no
213 * buffered data yet to be sent. Default value is true.
214 */
215 public bool AutoFlush {
216 get; set;
217 }
218
219 /*
220 * If 'CloseSub' is true, then the underlying transport stream
221 * will be closed on normal closure or protocol failure. Default
222 * value is true. If a closure callback is set in 'OnClose',
223 * then this flag is ignored.
224 */
225 public bool CloseSub {
226 get; set;
227 }
228
229 /*
230 * A generic callback to be invoked when the SSL connection is
231 * closed. If a callback is specified here, then the 'CloseSub'
232 * flag is ignored; the callback is supposed to handle the
233 * closing of the transport stream, if necessary.
234 */
235 public delegate void CloseGen(Stream sub);
236 public CloseGen OnClose {
237 get; set;
238 }
239
240 /*
241 * If 'NoCloseNotify' is true, then lack of a close_notify from
242 * the peer before closing the transport stream will NOT be
243 * considered erroneous; i.e. it won't trigger an exception.
244 * If that situation arises, the ClosedWithoutNotify flag will
245 * return true, so the caller may still test for it.
246 *
247 * Not sending close_notify alerts before closing is a widespread
248 * practice, since it simplifies timeout management. It is unsafe,
249 * in that it allows truncation attacks, unless the application
250 * protocol is self-terminated (e.g. HTTP/1.1 is self-terminated,
251 * HTTP/0.9 is not).
252 *
253 * Default value is false: lack of close_notify triggers an
254 * exception.
255 */
256 public bool NoCloseNotify {
257 get; set;
258 }
259
260 /*
261 * The 'ClosedWithoutNotify' flag is set to true if the connection
262 * was closed abruptly (no close_notify alert), but this engine
263 * was configured to tolerate that situation ('NoCloseNotify' was
264 * set to true).
265 */
266 public bool ClosedWithoutNotify {
267 get; private set;
268 }
269
270 /*
271 * Maximum allowed size for a handshake message. The protocol
272 * allows for messages up to 16 megabytes, but these hardly
273 * make sense in practice. In the interest of avoiding
274 * memory-based denials of service, a lower limit can be set.
275 * If an incoming handshake message exceeds that size, then
276 * an exception is thrown. Default value is 65536.
277 */
278 public int MaximumHandshakeMessageLength {
279 get; set;
280 }
281
282 /*
283 * Set the cipher suites supported by this engine, in preference
284 * order (most preferred comes first). Default value should ensure
285 * maximum interoperability and good security and performance.
286 */
287 public int[] SupportedCipherSuites {
288 get; set;
289 }
290
291 /*
292 * Set the elliptic curves supported by this engine, for ECDH
293 * and ECDHE. The list is in preference order (most preferred
294 * comes first). Default list is Curve25519 followed by the
295 * usual NIST curves (P-256, P-384 and P-521, in that order).
296 */
297 public int[] SupportedCurves {
298 get; set;
299 }
300
301 /*
302 * Set the supported hash and sign algorithm combinations. Each
303 * value is a 16-bit integer: high byte is the hash algorithm
304 * identifier, while low byte is the signature algorithm identifier.
305 * List is ordered by preference order. Default list applies the
306 * following rules:
307 *
308 * - Hash function order is:
309 * SHA-256, SHA-224, SHA-384, SHA-512, SHA-1
310 *
311 * - For the same hash function, ECDSA is preferred over RSA.
312 *
313 * Note that the special RSA with MD5+SHA-1 shall not be part of
314 * this list. Its use is implicit when using TLS 1.0 or 1.1 with
315 * a cipher suite or client authentication that uses RSA signatures.
316 */
317 public int[] SupportedHashAndSign {
318 get; set;
319 }
320
321 /*
322 * Set the minimum supported protocol version. Default is TLS 1.0.
323 */
324 public int VersionMin {
325 get {
326 return versionMin;
327 }
328 set {
329 SetOutputRecordVersion(value);
330 versionMin = value;
331 }
332 }
333
334 /*
335 * Set the maximum supported protocol version. Default is TLS 1.2.
336 */
337 public int VersionMax {
338 get; set;
339 }
340
341 /*
342 * Get the actual protocol version. This is set only when the
343 * version is chosen, within the handshake.
344 */
345 public int Version {
346 get {
347 return actualVersion;
348 }
349 internal set {
350 actualVersion = value;
351 SetOutputRecordVersion(value);
352 }
353 }
354
355 /*
356 * Get the actual cipher suite. This is set only when it is chosen,
357 * within the handshake.
358 */
359 public int CipherSuite {
360 get; internal set;
361 }
362
363 /*
364 * Get or set the server name associated with this connection.
365 *
366 * On a client, the caller shall set that name; if non-null and
367 * non-empty, then it will be sent to the server as a SNI
368 * extension; it will moreover be matched against the names
369 * found in the server's certificate.
370 *
371 * On a server, this value is set to the host name received from
372 * the client as a SNI extension (if any).
373 */
374 public string ServerName {
375 get; set;
376 }
377
378 /*
379 * Get the current session parameters. If the initial handshake
380 * was not performed yet, then the handshake is performed now
381 * (thus, this call may trigger an exception in case of I/O or
382 * protocol error).
383 *
384 * The returned object is a freshly allocated copy, which is not
385 * impacted by further activity on this engine.
386 */
387 public SSLSessionParameters SessionParameters {
388 get {
389 if (state == STATE_HANDSHAKE) {
390 DoHandshakeWrapper();
391 }
392 return new SSLSessionParameters(sessionID, Version,
393 CipherSuite, ServerName, masterSecret);
394 }
395 }
396
397 /*
398 * Renegotiation support: if true, then renegotiations will be
399 * accepted (both explicit calls to Renegotiate(), and requests
400 * from the peer); if false, then all renegotiation attempts will
401 * be rejected.
402 *
403 * Default value is true. Regardless of the value of this flag,
404 * renegotiation attempts will be denied if the peer does not
405 * support the "Secure Renegotiation" extension (RFC 5746).
406 */
407 public bool AllowRenegotiation {
408 get; set;
409 }
410
411 /*
412 * Set "quirks" to alter engine behaviour. When null (which is the
413 * default), normal behaviour occurs.
414 */
415 public SSLQuirks Quirks {
416 get; set;
417 }
418
419 /*
420 * Get the current handshake count. This starts at 0 (before
421 * the initial handshake) and is incremented for each handshake.
422 * The increment occurs at the start of the handshake (after
423 * confirmation that a handshake will be indeed attempted, when
424 * doing a renegotiation).
425 */
426 public long HandshakeCount {
427 get; internal set;
428 }
429
430 /*
431 * Tell whether the last handshake was a session resumption or not.
432 * This flag is set at the end of the handshake.
433 */
434 public bool IsResume {
435 get; internal set;
436 }
437
438 /*
439 * Trigger a new handshake. If the initial handshake was not done
440 * yet, then it is performed at that point. Otherwise, this is
441 * a renegotiation attempt.
442 *
443 * Returned value is true if a new handshake happened, false
444 * otherwise. For the initial handshake, true is always returned
445 * (handshake failures trigger exceptions). For a renegotiation,
446 * a 'false' value may be returned if one of the following holds:
447 * - This engine was configured not to use renegotiations.
448 * - The peer does not support secure renegotiation.
449 * - A renegotiation was attempted, but denied by the peer.
450 */
451 public bool Renegotiate()
452 {
453 if (!FirstHandshakeDone) {
454 DoHandshakeWrapper();
455 return true;
456 }
457
458 if (!AllowRenegotiation) {
459 return false;
460 }
461 if (!GetQuirkBool("noSecureReneg") && renegSupport < 0) {
462 return false;
463 }
464 int rt = outRec.RecordType;
465 try {
466 PrepareRenegotiate();
467 } catch {
468 MarkFailed();
469 throw;
470 }
471 if (!DoHandshakeWrapper()) {
472 outRec.RecordType = rt;
473 return false;
474 }
475 return true;
476 }
477
478 /* ============================================================ */
479 /*
480 * Stream standard API.
481 */
482
483 public override int ReadByte()
484 {
485 if (state == STATE_CLOSED) {
486 return -1;
487 }
488 CheckAppData();
489 try {
490 return ZRead();
491 } catch {
492 MarkFailed();
493 throw;
494 }
495 }
496
497 public override int Read(byte[] buf, int off, int len)
498 {
499 if (state == STATE_CLOSED) {
500 return -1;
501 }
502 CheckAppData();
503 try {
504 return ZRead(buf, off, len);
505 } catch {
506 MarkFailed();
507 throw;
508 }
509 }
510
511 public override void WriteByte(byte x)
512 {
513 CheckAppData();
514 try {
515 outRec.Write(x);
516 if (AutoFlush) {
517 outRec.Flush();
518 }
519 } catch {
520 MarkFailed();
521 throw;
522 }
523 }
524
525 public override void Write(byte[] buf, int off, int len)
526 {
527 CheckAppData();
528 try {
529 outRec.Write(buf, off, len);
530 if (AutoFlush) {
531 outRec.Flush();
532 }
533 } catch {
534 MarkFailed();
535 throw;
536 }
537 }
538
539 public override void Flush()
540 {
541 CheckAppData();
542 try {
543 outRec.Flush();
544 } catch {
545 MarkFailed();
546 throw;
547 }
548 }
549
550 public override void Close()
551 {
552 Close(true);
553 }
554
555 void Close(bool expectCloseNotify)
556 {
557 if (state == STATE_CLOSED) {
558 return;
559 }
560 try {
561 if (state == STATE_APPDATA) {
562 SendWarning(SSL.CLOSE_NOTIFY);
563 state = STATE_CLOSING;
564 if (expectCloseNotify) {
565 if (!NextRecord()) {
566 return;
567 }
568 throw new SSLException(
569 "Peer does not want to close");
570 }
571 }
572 } catch {
573 // ignored
574 } finally {
575 MarkFailed();
576 }
577 }
578
579 public override long Seek(long off, SeekOrigin origin)
580 {
581 throw new NotSupportedException();
582 }
583
584 public override void SetLength(long len)
585 {
586 throw new NotSupportedException();
587 }
588
589 public override bool CanRead {
590 get {
591 return state != STATE_CLOSED;
592 }
593 }
594
595 public override bool CanWrite {
596 get {
597 return state != STATE_CLOSED;
598 }
599 }
600
601 public override bool CanSeek {
602 get {
603 return false;
604 }
605 }
606
607 public override long Length {
608 get {
609 throw new NotSupportedException();
610 }
611 }
612
613 public override long Position {
614 get {
615 throw new NotSupportedException();
616 }
617 set {
618 throw new NotSupportedException();
619 }
620 }
621
622 /* ============================================================ */
623
624 /*
625 * Test whether this engine is a client or a server.
626 */
627 internal abstract bool IsClient {
628 get;
629 }
630
631 /*
632 * Test the configuration of hash-and-sign with regards to
633 * cipher suites: if the list of cipher suites includes an
634 * ECDHE suite, then there must be at least one supported
635 * hash-and-sign with the corresponding signature type.
636 */
637 internal void CheckConfigHashAndSign()
638 {
639 /*
640 * The hash-and-sign are only for TLS 1.2.
641 */
642 if (VersionMax < SSL.TLS12) {
643 return;
644 }
645
646 /*
647 * If the list is empty then we will work over the default
648 * list inferred by the peer (no extension sent).
649 */
650 if (SupportedHashAndSign == null
651 || SupportedHashAndSign.Length == 0)
652 {
653 return;
654 }
655
656 bool needRSA = false;
657 bool needECDSA = false;
658 foreach (int cs in SupportedCipherSuites) {
659 if (SSL.IsECDHE_RSA(cs)) {
660 needRSA = true;
661 }
662 if (SSL.IsECDHE_ECDSA(cs)) {
663 needECDSA = true;
664 }
665 }
666 foreach (int hs in SupportedHashAndSign) {
667 int sa = hs & 0xFF;
668 if (needRSA && sa == SSL.RSA) {
669 needRSA = false;
670 }
671 if (needECDSA && sa == SSL.ECDSA) {
672 needECDSA = false;
673 }
674 }
675 if (needRSA) {
676 throw new SSLException("Incoherent configuration:"
677 + " supports ECDHE_RSA but no RSA signature"
678 + " (for TLS 1.2)");
679 }
680 if (needECDSA) {
681 throw new SSLException("Incoherent configuration:"
682 + " supports ECDHE_ECDSA but no ECDSA signature"
683 + " (for TLS 1.2)");
684 }
685 }
686
687 internal bool HasQuirk(string name)
688 {
689 return Quirks != null && Quirks.GetString(name, null) != null;
690 }
691
692 internal bool GetQuirkBool(string name)
693 {
694 return GetQuirkBool(name, false);
695 }
696
697 internal bool GetQuirkBool(string name, bool defaultValue)
698 {
699 if (Quirks == null) {
700 return false;
701 }
702 return Quirks.GetBoolean(name, defaultValue);
703 }
704
705 internal int GetQuirkInt(string name)
706 {
707 return GetQuirkInt(name, 0);
708 }
709
710 internal int GetQuirkInt(string name, int defaultValue)
711 {
712 if (Quirks == null) {
713 return defaultValue;
714 }
715 return Quirks.GetInteger(name, defaultValue);
716 }
717
718 internal string GetQuirkString(string name)
719 {
720 return GetQuirkString(name, null);
721 }
722
723 internal string GetQuirkString(string name, string defaultValue)
724 {
725 if (Quirks == null) {
726 return defaultValue;
727 }
728 return Quirks.GetString(name, defaultValue);
729 }
730
731 /*
732 * Test whether the first handshake has been done or not.
733 */
734 internal bool FirstHandshakeDone {
735 get {
736 return savedClientFinished != null;
737 }
738 }
739
740 /*
741 * Close the engine. No I/O may happen beyond this call.
742 */
743 internal void MarkFailed()
744 {
745 if (sub != null) {
746 try {
747 if (OnClose != null) {
748 OnClose(sub);
749 } else if (CloseSub) {
750 sub.Close();
751 }
752 } catch {
753 // ignored
754 }
755 sub = null;
756 }
757 state = STATE_CLOSED;
758 }
759
760 /*
761 * Check that the current state is not closed.
762 */
763 void CheckNotClosed()
764 {
765 if (state == STATE_CLOSED) {
766 throw new SSLException("Connection is closed");
767 }
768 }
769
770 /*
771 * Check that we are ready to exchange application data. A
772 * handshake is performed if necessary.
773 */
774 void CheckAppData()
775 {
776 CheckNotClosed();
777 if (!FirstHandshakeDone) {
778 DoHandshakeWrapper();
779 } else if (state != STATE_APPDATA) {
780 throw new SSLException(
781 "Connection not ready for application data");
782 }
783 }
784
785 /*
786 * Set the version for outgoing records.
787 */
788 internal void SetOutputRecordVersion(int version)
789 {
790 outRec.SetVersion(version);
791 }
792
793 /*
794 * Set the expected version for incoming records. This should be
795 * used by the server code just after parsing the ClientHello,
796 * because the client is supposed to send records matching the
797 * protocol version decided by the server and sent in the
798 * ServerHello.
799 *
800 * For a SSL client, this call in unnecessary because default
801 * behaviour is to look at the version of the first incoming
802 * record (containing the ServerHello for the server) and expect
803 * all subsequent records to have the same version.
804 */
805 internal void SetInputRecordVersion(int version)
806 {
807 inRec.SetExpectedVersion(version);
808 }
809
810 /*
811 * Flush the underlying record engine.
812 */
813 internal void FlushSub()
814 {
815 outRec.Flush();
816 }
817
818 /*
819 * Get next record. This returns false only if the connection
820 * turned out to be ended "properly".
821 *
822 * In all other cases, a record is obtained, and true is
823 * returned. It is possible that the record contains no unread
824 * data (it could be an empty record, or it could be an alert
825 * record whose contents are automatically processed).
826 */
827 internal bool NextRecord()
828 {
829 if (!inRec.NextRecord()) {
830 if (NoCloseNotify && (state == STATE_APPDATA
831 || state == STATE_CLOSING))
832 {
833 /*
834 * No close_notify, but we have been set
835 * to tolerate it.
836 */
837 ClosedWithoutNotify = true;
838 MarkFailed();
839 return false;
840 }
841 throw new SSLException("Unexpected transport closure");
842 }
843
844 /*
845 * We basically ignore empty records, regardless of state.
846 */
847 if (inRec.BufferedLength == 0) {
848 return true;
849 }
850
851 int rt = inRec.RecordType;
852 switch (rt) {
853
854 case SSL.ALERT:
855 /*
856 * Fatal alerts trigger an exception. Warnings are
857 * ignored, except close_notify and no_renegotiation.
858 */
859 while (inRec.BufferedLength > 0) {
860 int level = deferredAlert;
861 deferredAlert = -1;
862 if (level < 0) {
863 level = inRec.Read();
864 if (inRec.BufferedLength == 0) {
865 deferredAlert = level;
866 break;
867 }
868 }
869 int desc = inRec.Read();
870 if (level == SSL.FATAL) {
871 throw new SSLException(desc);
872 }
873 if (level != SSL.WARNING) {
874 throw new SSLException("Unknown"
875 + " alert level: " + level);
876 }
877 if (desc == SSL.CLOSE_NOTIFY) {
878 if (state == STATE_CLOSING) {
879 MarkFailed();
880 return false;
881 }
882 if (state != STATE_APPDATA) {
883 throw new SSLException(
884 "Unexpected closure");
885 }
886 Close(false);
887 return false;
888 } else if (desc == SSL.NO_RENEGOTIATION) {
889 receivedNoReneg = true;
890 }
891 }
892 return true;
893
894 case SSL.HANDSHAKE:
895 switch (state) {
896 case STATE_HANDSHAKE:
897 return true;
898 case STATE_APPDATA:
899 ProcessExtraHandshakeWrapper();
900 return true;
901 }
902 throw new SSLException("Unexpected handshake message");
903
904 case SSL.CHANGE_CIPHER_SPEC:
905 if (state == STATE_CCS) {
906 return true;
907 }
908 throw new SSLException("Unexpected Change Cipher Spec");
909
910 case SSL.APPLICATION_DATA:
911 if (state == STATE_APPDATA) {
912 return true;
913 }
914 throw new SSLException("Unexpected application data");
915
916 default:
917 throw new SSLException("Invalid record type: " + rt);
918
919 }
920 }
921
922 /*
923 * ZRead() reads the next byte, possibly obtaining further records
924 * to do so. It may return -1 only if the end-of-stream was reached,
925 * which can happen only in "application data" state (after a
926 * successful handshake).
927 */
928 int ZRead()
929 {
930 int x = ZReadNoHash();
931 if (x >= 0 && inRec.RecordType == SSL.HANDSHAKE) {
932 HashExtra((byte)x);
933 }
934 return x;
935 }
936
937 /*
938 * ZReadNoHash() is similar to ZRead() except that it skips
939 * the automatic hashing of handshake messages.
940 */
941 int ZReadNoHash()
942 {
943 while (inRec.BufferedLength == 0) {
944 if (!NextRecord()) {
945 return -1;
946 }
947 }
948 return inRec.Read();
949 }
950
951 /*
952 * ZReadNoHashNoReneg() is similar to ZReadNoHash() except
953 * that it may return -1 while being in state STATE_HANDSHAKE
954 * in case a no_renegotiation alert is received.
955 */
956 int ZReadNoHashNoReneg()
957 {
958 while (inRec.BufferedLength == 0) {
959 receivedNoReneg = false;
960 if (!NextRecord() || receivedNoReneg) {
961 return -1;
962 }
963 }
964 return inRec.Read();
965 }
966
967 /*
968 * Read some bytes. At least one byte will be obtained, unless
969 * EOF is reached. Extra records are obtained if necessary.
970 */
971 int ZRead(byte[] buf)
972 {
973 return ZRead(buf, 0, buf.Length);
974 }
975
976 /*
977 * Read some bytes. At least one byte will be obtained, unless
978 * EOF is reached. Extra records are obtained if necessary.
979 */
980 int ZRead(byte[] buf, int off, int len)
981 {
982 while (inRec.BufferedLength == 0) {
983 if (!NextRecord()) {
984 return 0;
985 }
986 }
987 int rlen = inRec.Read(buf, off, len);
988 if (rlen > 0 && inRec.RecordType == SSL.HANDSHAKE) {
989 md5.Update(buf, off, rlen);
990 sha1.Update(buf, off, rlen);
991 sha256.Update(buf, off, rlen);
992 sha384.Update(buf, off, rlen);
993 }
994 return rlen;
995 }
996
997 bool DoHandshakeWrapper()
998 {
999 /*
1000 * Record split mode syntax: name:[types]
1001 *
1002 * 'name' is a symbolic name.
1003 *
1004 * 'types' is a comma-separated list of record types on
1005 * which the splitting mode applies. Record types are
1006 * numeric values (in decimal).
1007 */
1008 string splitMode = GetQuirkString("recordSplitMode");
1009 if (splitMode != null) {
1010 splitMode = splitMode.Trim();
1011 int j = splitMode.IndexOf(':');
1012 int m = 0;
1013 if (j >= 0) {
1014 string w = splitMode.Substring(j + 1);
1015 foreach (string s in w.Split(',')) {
1016 m |= 1 << Int32.Parse(s.Trim());
1017 }
1018 splitMode = splitMode.Substring(0, j).Trim();
1019 }
1020 switch (splitMode.ToLowerInvariant()) {
1021 case "half":
1022 m |= OutputRecord.MODE_SPLIT_HALF;
1023 break;
1024 case "zero_before":
1025 m |= OutputRecord.MODE_SPLIT_ZERO_BEFORE;
1026 break;
1027 case "zero_half":
1028 m |= OutputRecord.MODE_SPLIT_ZERO_HALF;
1029 break;
1030 case "one_start":
1031 m |= OutputRecord.MODE_SPLIT_ONE_START;
1032 break;
1033 case "one_end":
1034 m |= OutputRecord.MODE_SPLIT_ONE_END;
1035 break;
1036 case "multi_one":
1037 m |= OutputRecord.MODE_SPLIT_MULTI_ONE;
1038 break;
1039 default:
1040 throw new SSLException(string.Format(
1041 "Bad recordSplitMode name: '{0}'",
1042 splitMode));
1043 }
1044 outRec.SetSplitMode(m);
1045 }
1046
1047 /*
1048 * Triggers for extra empty records.
1049 */
1050 outRec.SetThresholdZeroHandshake(
1051 GetQuirkInt("thresholdZeroHandshake"));
1052 outRec.SetThresholdZeroAppData(
1053 GetQuirkInt("thresholdZeroAppData"));
1054
1055 try {
1056 for (;;) {
1057 bool ret = DoHandshake();
1058 if (!ret) {
1059 return false;
1060 }
1061 /*
1062 * There could be some extra handshake
1063 * data lingering in the input buffer, in
1064 * which case we must process it right away.
1065 */
1066 if (HasBufferedHandshake) {
1067 ProcessExtraHandshakeWrapper();
1068 }
1069 return true;
1070 }
1071 } catch {
1072 MarkFailed();
1073 throw;
1074 }
1075 }
1076
1077 void ProcessExtraHandshakeWrapper()
1078 {
1079 try {
1080 while (HasBufferedHandshake) {
1081 ProcessExtraHandshake();
1082 }
1083 } catch {
1084 MarkFailed();
1085 throw;
1086 }
1087 }
1088
1089 /*
1090 * Set the state to the provided value.
1091 */
1092 internal void SetState(int state)
1093 {
1094 this.state = state;
1095 }
1096
1097 /*
1098 * Reset running hashes for handshake messages.
1099 */
1100 internal void ResetHashes()
1101 {
1102 md5.Reset();
1103 sha1.Reset();
1104 sha256.Reset();
1105 sha384.Reset();
1106 }
1107
1108 /*
1109 * Inject a specific byte value in the hash functions for handshake
1110 * messages.
1111 */
1112 void HashExtra(byte b)
1113 {
1114 md5.Update(b);
1115 sha1.Update(b);
1116 sha256.Update(b);
1117 sha384.Update(b);
1118 }
1119
1120 /*
1121 * Run a handshake. This function normally returns true; it returns
1122 * false only if the call was a renegotiation attempt AND it was
1123 * denied by the peer.
1124 */
1125 internal abstract bool DoHandshake();
1126
1127 /*
1128 * A non-empty handshake record has been received while we
1129 * were in post-handshake "application data" state. This
1130 * method should handle that message with the necessary
1131 * actions; if it returns false then the caller will fail
1132 * the connection with an exception.
1133 */
1134 internal abstract void ProcessExtraHandshake();
1135
1136 /*
1137 * Perform the preparatory steps for a renegotiation. For a client,
1138 * there are no such steps, so this call is a no-op. For a server,
1139 * an HelloRequest should be sent.
1140 */
1141 internal abstract void PrepareRenegotiate();
1142
1143 /*
1144 * Read the next handshake message. This also sets the state
1145 * to STATE_HANDSHAKE.
1146 */
1147 internal byte[] ReadHandshakeMessage(out int msgType)
1148 {
1149 return ReadHandshakeMessage(out msgType, false);
1150 }
1151
1152 /*
1153 * Read the next handshake message. This also sets the state
1154 * to STATE_HANDSHAKE. If tolerateNoReneg is true, then a
1155 * received no_renegotiation alert interrupts the reading, in
1156 * which case this function sets the state back to its previous
1157 * value and returns null.
1158 */
1159 internal byte[] ReadHandshakeMessage(
1160 out int msgType, bool tolerateNoReneg)
1161 {
1162 int oldState = state;
1163 state = STATE_HANDSHAKE;
1164
1165 /*
1166 * In STATE_HANDSHAKE, an unexpected closure is never
1167 * tolerated, so ZRead() won't return -1.
1168 */
1169 for (;;) {
1170 msgType = ZReadNoHashNoReneg();
1171 if (msgType < 0) {
1172 if (tolerateNoReneg) {
1173 state = oldState;
1174 return null;
1175 }
1176 continue;
1177 }
1178 if (msgType == SSL.HELLO_REQUEST && IsClient) {
1179 /*
1180 * Extra HelloRequest messages are ignored
1181 * (as long as they are properly empty), and
1182 * they don't contribute to the running hashes.
1183 */
1184 if (ZReadNoHash() != 0
1185 || ZReadNoHash() != 0
1186 || ZReadNoHash() != 0)
1187 {
1188 throw new SSLException(
1189 "Non-empty HelloRequest");
1190 }
1191 continue;
1192 }
1193 HashExtra((byte)msgType);
1194 int len = ZRead();
1195 len = (len << 8) + ZRead();
1196 len = (len << 8) + ZRead();
1197 if (len > MaximumHandshakeMessageLength) {
1198 throw new SSLException(
1199 "Oversized handshake message: len="
1200 + len);
1201 }
1202 byte[] buf = new byte[len];
1203 int off = 0;
1204 while (off < len) {
1205 off += ZRead(buf, off, len - off);
1206 }
1207 return buf;
1208 }
1209 }
1210
1211 /*
1212 * Read the next handshake message; fail (with an exception) if
1213 * it does not have the specified type. This also sets the state
1214 * to STATE_HANDSHAKE.
1215 */
1216 internal byte[] ReadHandshakeMessageExpected(int msgType)
1217 {
1218 int rmt;
1219 byte[] msg = ReadHandshakeMessage(out rmt);
1220 if (rmt != msgType) {
1221 throw new SSLException(string.Format("Unexpected"
1222 + " handshake message {0} (expected: {1})",
1223 rmt, msgType));
1224 }
1225 return msg;
1226 }
1227
1228 /*
1229 * Read an HelloRequest message. If, after reading an HelloRequest,
1230 * the record is not empty, then other HelloRequest messages are
1231 * read.
1232 *
1233 * This method shall be called only when a non-empty record of type
1234 * handshake is buffered. It switches the state to STATE_HANDSHAKE.
1235 */
1236 internal void ReadHelloRequests()
1237 {
1238 state = STATE_HANDSHAKE;
1239 while (inRec.BufferedLength > 0) {
1240 int x = ZReadNoHash();
1241 if (x != SSL.HELLO_REQUEST) {
1242 throw new SSLException(
1243 "Unexpected handshake message");
1244 }
1245 if (ZReadNoHash() != 0x00
1246 || ZReadNoHash() != 0x00
1247 || ZReadNoHash() != 0x00)
1248 {
1249 throw new SSLException(
1250 "Non-empty HelloRequest");
1251 }
1252 }
1253 }
1254
1255 /*
1256 * Test whether there is some buffered handshake data.
1257 */
1258 internal bool HasBufferedHandshake {
1259 get {
1260 return inRec.RecordType == SSL.HANDSHAKE
1261 && inRec.BufferedLength > 0;
1262 }
1263 }
1264
1265 static DateTime EPOCH =
1266 new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
1267
1268 /*
1269 * Create a new client or server random.
1270 */
1271 internal void MakeRandom(byte[] dst)
1272 {
1273 uint utc = (uint)((DateTime.UtcNow - EPOCH).Ticks / 10000000);
1274 IO.Enc32be(utc, dst, 0);
1275 RNG.GetBytes(dst, 4, dst.Length - 4);
1276 }
1277
1278 /*
1279 * Create a MemoryStream with preloaded 4-byte handshake message
1280 * header.
1281 */
1282 internal MemoryStream StartHandshakeMessage(int type)
1283 {
1284 MemoryStream ms = new MemoryStream();
1285 ms.WriteByte((byte)type);
1286 IO.Write24(ms, 0);
1287 return ms;
1288 }
1289
1290 /*
1291 * Finalise a handshake message, and send it.
1292 */
1293 internal void EndHandshakeMessage(MemoryStream ms)
1294 {
1295 byte[] buf = ms.ToArray();
1296 IO.Enc24be(buf.Length - 4, buf, 1);
1297 outRec.RecordType = SSL.HANDSHAKE;
1298 outRec.Write(buf);
1299 md5.Update(buf);
1300 sha1.Update(buf);
1301 sha256.Update(buf);
1302 sha384.Update(buf);
1303 }
1304
1305 /*
1306 * Get the PRF corresponding to the negotiated protocol version
1307 * and cipher suite.
1308 */
1309 internal PRF GetPRF()
1310 {
1311 if (Version <= SSL.TLS11) {
1312 return new PRF();
1313 } else {
1314 return SSL.GetPRFForTLS12(CipherSuite);
1315 }
1316 }
1317
1318 /*
1319 * Compute the master secret from the provided premaster secret.
1320 */
1321 internal void ComputeMaster(byte[] pms)
1322 {
1323 PRF prf = GetPRF();
1324 byte[] seed = new byte[64];
1325 Array.Copy(clientRandom, 0, seed, 0, 32);
1326 Array.Copy(serverRandom, 0, seed, 32, 32);
1327 prf.GetBytes(pms, PRF.LABEL_MASTER_SECRET, seed, masterSecret);
1328 }
1329
1330 /*
1331 * Set the master secret to the provided value. This is used when
1332 * resuming a session.
1333 */
1334 internal void SetMasterSecret(byte[] rms)
1335 {
1336 Array.Copy(rms, 0, masterSecret, 0, rms.Length);
1337 }
1338
1339 /*
1340 * Switch to new security parameters.
1341 * 'write' is true if we switch encryption for our sending channel,
1342 * false for our receiving channel.
1343 */
1344 internal void SwitchEncryption(bool write)
1345 {
1346 int macLen, encLen, ivLen;
1347 IBlockCipher block = null;
1348 IDigest hash = null;
1349 Poly1305 pp = null;
1350 switch (CipherSuite) {
1351 case SSL.RSA_WITH_3DES_EDE_CBC_SHA:
1352 case SSL.DH_DSS_WITH_3DES_EDE_CBC_SHA:
1353 case SSL.DH_RSA_WITH_3DES_EDE_CBC_SHA:
1354 case SSL.DHE_DSS_WITH_3DES_EDE_CBC_SHA:
1355 case SSL.DHE_RSA_WITH_3DES_EDE_CBC_SHA:
1356 case SSL.DH_anon_WITH_3DES_EDE_CBC_SHA:
1357 case SSL.ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
1358 case SSL.ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
1359 case SSL.ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
1360 case SSL.ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
1361 case SSL.ECDH_anon_WITH_3DES_EDE_CBC_SHA:
1362 macLen = 20;
1363 encLen = 24;
1364 ivLen = 8;
1365 block = new DES();
1366 hash = new SHA1();
1367 break;
1368
1369 case SSL.RSA_WITH_AES_128_CBC_SHA:
1370 case SSL.DH_DSS_WITH_AES_128_CBC_SHA:
1371 case SSL.DH_RSA_WITH_AES_128_CBC_SHA:
1372 case SSL.DHE_DSS_WITH_AES_128_CBC_SHA:
1373 case SSL.DHE_RSA_WITH_AES_128_CBC_SHA:
1374 case SSL.DH_anon_WITH_AES_128_CBC_SHA:
1375 case SSL.ECDH_ECDSA_WITH_AES_128_CBC_SHA:
1376 case SSL.ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
1377 case SSL.ECDH_RSA_WITH_AES_128_CBC_SHA:
1378 case SSL.ECDHE_RSA_WITH_AES_128_CBC_SHA:
1379 case SSL.ECDH_anon_WITH_AES_128_CBC_SHA:
1380 macLen = 20;
1381 encLen = 16;
1382 ivLen = 16;
1383 block = new AES();
1384 hash = new SHA1();
1385 break;
1386
1387 case SSL.RSA_WITH_AES_256_CBC_SHA:
1388 case SSL.DH_DSS_WITH_AES_256_CBC_SHA:
1389 case SSL.DH_RSA_WITH_AES_256_CBC_SHA:
1390 case SSL.DHE_DSS_WITH_AES_256_CBC_SHA:
1391 case SSL.DHE_RSA_WITH_AES_256_CBC_SHA:
1392 case SSL.DH_anon_WITH_AES_256_CBC_SHA:
1393 case SSL.ECDH_ECDSA_WITH_AES_256_CBC_SHA:
1394 case SSL.ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
1395 case SSL.ECDH_RSA_WITH_AES_256_CBC_SHA:
1396 case SSL.ECDHE_RSA_WITH_AES_256_CBC_SHA:
1397 case SSL.ECDH_anon_WITH_AES_256_CBC_SHA:
1398 macLen = 20;
1399 encLen = 32;
1400 ivLen = 16;
1401 block = new AES();
1402 hash = new SHA1();
1403 break;
1404
1405 case SSL.RSA_WITH_AES_128_CBC_SHA256:
1406 case SSL.DH_DSS_WITH_AES_128_CBC_SHA256:
1407 case SSL.DH_RSA_WITH_AES_128_CBC_SHA256:
1408 case SSL.DHE_DSS_WITH_AES_128_CBC_SHA256:
1409 case SSL.DHE_RSA_WITH_AES_128_CBC_SHA256:
1410 case SSL.DH_anon_WITH_AES_128_CBC_SHA256:
1411 case SSL.ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
1412 case SSL.ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
1413 case SSL.ECDHE_RSA_WITH_AES_128_CBC_SHA256:
1414 case SSL.ECDH_RSA_WITH_AES_128_CBC_SHA256:
1415 macLen = 32;
1416 encLen = 16;
1417 ivLen = 16;
1418 block = new AES();
1419 hash = new SHA256();
1420 break;
1421
1422 case SSL.RSA_WITH_AES_256_CBC_SHA256:
1423 case SSL.DH_DSS_WITH_AES_256_CBC_SHA256:
1424 case SSL.DH_RSA_WITH_AES_256_CBC_SHA256:
1425 case SSL.DHE_DSS_WITH_AES_256_CBC_SHA256:
1426 case SSL.DHE_RSA_WITH_AES_256_CBC_SHA256:
1427 case SSL.DH_anon_WITH_AES_256_CBC_SHA256:
1428 macLen = 32;
1429 encLen = 32;
1430 ivLen = 16;
1431 block = new AES();
1432 hash = new SHA256();
1433 break;
1434
1435 case SSL.ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
1436 case SSL.ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
1437 case SSL.ECDHE_RSA_WITH_AES_256_CBC_SHA384:
1438 case SSL.ECDH_RSA_WITH_AES_256_CBC_SHA384:
1439 macLen = 48;
1440 encLen = 32;
1441 ivLen = 16;
1442 block = new AES();
1443 hash = new SHA384();
1444 break;
1445
1446 case SSL.RSA_WITH_AES_128_GCM_SHA256:
1447 case SSL.DHE_RSA_WITH_AES_128_GCM_SHA256:
1448 case SSL.DH_RSA_WITH_AES_128_GCM_SHA256:
1449 case SSL.DHE_DSS_WITH_AES_128_GCM_SHA256:
1450 case SSL.DH_DSS_WITH_AES_128_GCM_SHA256:
1451 case SSL.DH_anon_WITH_AES_128_GCM_SHA256:
1452 case SSL.ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
1453 case SSL.ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
1454 case SSL.ECDHE_RSA_WITH_AES_128_GCM_SHA256:
1455 case SSL.ECDH_RSA_WITH_AES_128_GCM_SHA256:
1456 macLen = 0;
1457 encLen = 16;
1458 ivLen = 4;
1459 block = new AES();
1460 break;
1461
1462 case SSL.RSA_WITH_AES_256_GCM_SHA384:
1463 case SSL.DHE_RSA_WITH_AES_256_GCM_SHA384:
1464 case SSL.DH_RSA_WITH_AES_256_GCM_SHA384:
1465 case SSL.DHE_DSS_WITH_AES_256_GCM_SHA384:
1466 case SSL.DH_DSS_WITH_AES_256_GCM_SHA384:
1467 case SSL.DH_anon_WITH_AES_256_GCM_SHA384:
1468 case SSL.ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
1469 case SSL.ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
1470 case SSL.ECDHE_RSA_WITH_AES_256_GCM_SHA384:
1471 case SSL.ECDH_RSA_WITH_AES_256_GCM_SHA384:
1472 macLen = 0;
1473 encLen = 32;
1474 ivLen = 4;
1475 block = new AES();
1476 break;
1477
1478 case SSL.ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
1479 case SSL.ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
1480 case SSL.DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
1481 macLen = 0;
1482 encLen = 32;
1483 ivLen = 12;
1484 pp = new Poly1305();
1485 pp.ChaCha = new ChaCha20();
1486 break;
1487
1488 default:
1489 throw new SSLException("Unsupported cipher suite");
1490 }
1491
1492 /*
1493 * Normally we don't need IV when using CBC+HMAC with
1494 * TLS 1.1+.
1495 */
1496 if (Version >= SSL.TLS11 && hash != null) {
1497 ivLen = 0;
1498 }
1499
1500 byte[] seed = new byte[64];
1501 Array.Copy(serverRandom, 0, seed, 0, 32);
1502 Array.Copy(clientRandom, 0, seed, 32, 32);
1503 byte[] kb = GetPRF().GetBytes(masterSecret,
1504 PRF.LABEL_KEY_EXPANSION, seed,
1505 (macLen + encLen + ivLen) << 1);
1506
1507 /*
1508 * Test whether we need the client write keys, or the
1509 * server write keys.
1510 */
1511 bool clientWrite = (IsClient == write);
1512 HMAC hm = null;
1513 if (macLen > 0) {
1514 hm = new HMAC(hash);
1515 hm.SetKey(kb, clientWrite ? 0 : macLen, macLen);
1516 }
1517 if (block != null) {
1518 block.SetKey(kb, (macLen << 1)
1519 + (clientWrite ? 0 : encLen), encLen);
1520 } else if (pp != null) {
1521 pp.ChaCha.SetKey(kb, (macLen << 1)
1522 + (clientWrite ? 0 : encLen), encLen);
1523 }
1524 byte[] iv = null;
1525 if (ivLen > 0) {
1526 iv = new byte[ivLen];
1527 Array.Copy(kb, ((macLen + encLen) << 1)
1528 + (clientWrite ? 0 : ivLen), iv, 0, ivLen);
1529 }
1530
1531 if (hm != null) {
1532 /*
1533 * CBC+HMAC cipher suite.
1534 */
1535 if (write) {
1536 outRec.SetEncryption(
1537 new RecordEncryptCBC(block, hm, iv));
1538 } else {
1539 inRec.SetDecryption(
1540 new RecordDecryptCBC(block, hm, iv));
1541 }
1542 } else if (block != null) {
1543 /*
1544 * GCM cipher suite.
1545 */
1546 if (write) {
1547 outRec.SetEncryption(
1548 new RecordEncryptGCM(block, iv));
1549 } else {
1550 inRec.SetDecryption(
1551 new RecordDecryptGCM(block, iv));
1552 }
1553 } else if (pp != null) {
1554 /*
1555 * ChaCha20 + Poly1305 cipher suite.
1556 */
1557 if (write) {
1558 outRec.SetEncryption(
1559 new RecordEncryptChaPol(pp, iv));
1560 } else {
1561 inRec.SetDecryption(
1562 new RecordDecryptChaPol(pp, iv));
1563 }
1564 } else {
1565 throw new Exception("NYI");
1566 }
1567 }
1568
1569 /*
1570 * Compute Finished message. The 'client' flag is set to true
1571 * for the Finished message sent by the client, false for the
1572 * Finished message sent by the server.
1573 */
1574 internal byte[] ComputeFinished(bool client)
1575 {
1576 PRF prf;
1577 byte[] seed;
1578 if (Version <= SSL.TLS11) {
1579 seed = new byte[36];
1580 md5.DoPartial(seed, 0);
1581 sha1.DoPartial(seed, 16);
1582 prf = new PRF();
1583 } else if (SSL.IsSHA384(CipherSuite)) {
1584 seed = sha384.DoPartial();
1585 prf = new PRF(new SHA384());
1586 } else {
1587 seed = sha256.DoPartial();
1588 prf = new PRF(new SHA256());
1589 }
1590 byte[] label = client
1591 ? PRF.LABEL_CLIENT_FINISHED
1592 : PRF.LABEL_SERVER_FINISHED;
1593 return prf.GetBytes(masterSecret, label, seed, 12);
1594 }
1595
1596 /*
1597 * Send a ChangeCipherSpec, then a Finished message. This
1598 * call implies switching to the new encryption parameters for
1599 * the sending channel.
1600 */
1601 internal void SendCCSAndFinished()
1602 {
1603 outRec.RecordType = SSL.CHANGE_CIPHER_SPEC;
1604 outRec.Write(0x01);
1605 outRec.RecordType = SSL.HANDSHAKE;
1606 SwitchEncryption(true);
1607 byte[] fin = ComputeFinished(IsClient);
1608 if (IsClient) {
1609 savedClientFinished = fin;
1610 } else {
1611 savedServerFinished = fin;
1612 }
1613 MemoryStream ms = StartHandshakeMessage(SSL.FINISHED);
1614 ms.Write(fin, 0, fin.Length);
1615 EndHandshakeMessage(ms);
1616 }
1617
1618 /*
1619 * Receive a ChangeCipherSpec, then a Finished message. This
1620 * call implies switching to the new encryption parameters for
1621 * the receiving channel.
1622 */
1623 internal void ParseCCSAndFinished()
1624 {
1625 if (inRec.BufferedLength > 0) {
1626 throw new SSLException(
1627 "Buffered data while expecting CCS");
1628 }
1629 state = STATE_CCS;
1630 int x = ZRead();
1631 if (x != 0x01 || inRec.BufferedLength > 0) {
1632 throw new SSLException("Invalid CCS contents");
1633 }
1634 SwitchEncryption(false);
1635 state = STATE_HANDSHAKE;
1636 byte[] fin = ComputeFinished(!IsClient);
1637 byte[] msg = ReadHandshakeMessageExpected(SSL.FINISHED);
1638 if (!Eq(fin, msg)) {
1639 throw new SSLException("Wrong Finished value");
1640 }
1641 if (inRec.BufferedLength > 0) {
1642 throw new SSLException(
1643 "Extra handshake data after Finished message");
1644 }
1645 if (IsClient) {
1646 savedServerFinished = fin;
1647 } else {
1648 savedClientFinished = fin;
1649 }
1650 }
1651
1652 /*
1653 * Switch to "application data" state just after the handshake.
1654 */
1655 internal void SetAppData()
1656 {
1657 SetState(STATE_APPDATA);
1658 outRec.RecordType = SSL.APPLICATION_DATA;
1659 }
1660
1661 /*
1662 * Send an alert of level "warning".
1663 */
1664 internal void SendWarning(int type)
1665 {
1666 int rt = outRec.RecordType;
1667 outRec.RecordType = SSL.ALERT;
1668 outRec.Write(SSL.WARNING);
1669 outRec.Write((byte)type);
1670 outRec.Flush();
1671 outRec.RecordType = rt;
1672 }
1673
1674 static bool Eq(byte[] a, byte[] b)
1675 {
1676 int n = a.Length;
1677 if (n != b.Length) {
1678 return false;
1679 }
1680 int z = 0;
1681 for (int i = 0; i < n; i ++) {
1682 z |= a[i] ^ b[i];
1683 }
1684 return z == 0;
1685 }
1686 }
1687
1688 }