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