1 /**
2 * TLS Messages
3 * 
4 * Copyright:
5 * (C) 2004-2011,2015 Jack Lloyd
6 * (C) 2014-2015 Etienne Cimon
7 *
8 * License:
9 * Botan is released under the Simplified BSD License (see LICENSE.md)
10 */
11 module botan.tls.messages;
12 
13 import botan.constants;
14 static if (BOTAN_HAS_TLS):
15 package:
16 
17 import botan.tls.handshake_state;
18 import botan.tls.session_key;
19 import std.algorithm : canFind;
20 import botan.tls.alert : TLSAlert;
21 import memutils.dictionarylist;
22 
23 public import botan.algo_base.sym_algo;
24 public import botan.tls.session;
25 public import botan.tls.policy;
26 public import botan.tls.ciphersuite;
27 public import botan.tls.reader;
28 public import botan.tls.extensions;
29 public import botan.tls.handshake_io;
30 public import botan.tls.version_;
31 public import botan.tls.handshake_hash;
32 public import botan.tls.magic;
33 public import botan.tls.credentials_manager;
34 import botan.constructs.srp6;
35 import botan.utils.loadstor;
36 import botan.constructs.srp6;
37 import botan.math.bigint.bigint;
38 import botan.pubkey.algo.ec_group;
39 import botan.math.ec_gfp.point_gfp;
40 import botan.pubkey.pkcs8;
41 import botan.pubkey.pubkey;
42 import botan.pubkey.algo.dh;
43 import botan.pubkey.algo.ecdh;
44 import botan.pubkey.algo.rsa;
45 import botan.cert.x509.x509cert;
46 import botan.asn1.oids;
47 import botan.asn1.der_enc;
48 import botan.asn1.ber_dec;
49 import botan.utils.loadstor;
50 import botan.utils.types;
51 import botan.libstate.lookup;
52 import botan.rng.rng;
53 import botan.utils.types : Unique;
54 import std.datetime;
55 import botan.utils.types;
56 
57 // import string;
58 
59 enum {
60     TLS_EMPTY_RENEGOTIATION_INFO_SCSV  = 0x00FF,
61     TLS_FALLBACK_SCSV                  = 0x5600
62 }
63 
64 /**
65 * TLS Handshake Message Base Class
66 */
67 interface HandshakeMessage
68 {
69 public:
70     abstract HandshakeType type() const;
71     
72     abstract Vector!ubyte serialize() const;
73 }
74 
75 /**
76 * DTLS Hello Verify Request
77 */
78 final class HelloVerifyRequest : HandshakeMessage
79 {
80 public:
81     override Vector!ubyte serialize() const
82     {
83         /* DTLS 1.2 server implementations SHOULD use DTLS version 1.0
84             regardless of the version of TLS that is expected to be
85             negotiated (RFC 6347, section 4.2.1)
86         */
87             
88         TLSProtocolVersion format_version = TLSProtocolVersion(TLSProtocolVersion.DTLS_V10);
89         
90         Vector!ubyte bits;
91         bits.pushBack(format_version.majorVersion());
92         bits.pushBack(format_version.minorVersion());
93         bits.pushBack(cast(ubyte) m_cookie.length);
94         bits ~= m_cookie[];
95         return bits.move();
96     }
97 
98     override HandshakeType type() const { return HELLO_VERIFY_REQUEST; }
99 
100     ref const(Vector!ubyte) cookie() const { return m_cookie; }
101 
102     this(const ref Vector!ubyte buf)
103     {
104         if (buf.length < 3)
105             throw new DecodingError("Hello verify request too small");
106         
107         TLSProtocolVersion version_ = TLSProtocolVersion(buf[0], buf[1]);
108         
109         if (version_ != TLSProtocolVersion.DTLS_V10 &&
110             version_ != TLSProtocolVersion.DTLS_V12)
111         {
112             throw new DecodingError("Unknown version from server in hello verify request");
113         }
114 
115         if ((cast(size_t) buf[2]) + 3 != buf.length)
116             throw new DecodingError("Bad length in hello verify request");
117         
118         m_cookie[] = buf.ptr[3 .. buf.length];
119     }
120 
121     this(const ref Vector!ubyte client_hello_bits, in string client_identity, in SymmetricKey secret_key)
122     {
123         Unique!MessageAuthenticationCode hmac = retrieveMac("HMAC(SHA-256)").clone();
124         hmac.setKey(secret_key);
125         
126         hmac.updateBigEndian(client_hello_bits.length);
127         hmac.update(client_hello_bits);
128         hmac.updateBigEndian(client_identity.length);
129         hmac.update(client_identity);
130         
131         m_cookie = unlock(hmac.finished());
132     }
133 private:
134     Vector!ubyte m_cookie;
135 }
136 
137 /**
138 * TLSClient Hello Message
139 */
140 final class ClientHello : HandshakeMessage
141 {
142 public:
143     override HandshakeType type() const { return CLIENT_HELLO; }
144 
145     const(TLSProtocolVersion) Version() const { return m_version; }
146 
147     ref const(Vector!ubyte) random() const { return m_random; }
148 
149 	const(ubyte[]) randomBytes() const { return m_random[]; }
150 	
151 	ref const(Vector!ubyte) sessionId() const { return m_session_id; }
152 	
153 	const(ubyte[]) sessionIdBytes() const { return m_session_id[]; }
154 
155 	ref const(Vector!ushort) ciphersuites() const { return m_suites; }
156 
157 	const(ushort[]) ciphersuitesData() const { return m_suites[]; }
158 
159     ref const(Vector!ubyte) compressionMethods() const { return m_comp_methods; }
160 
161     /*
162     * Check if we offered this ciphersuite
163     */
164     bool offeredSuite(ushort ciphersuite) const
165     {
166         for (size_t i = 0; i != m_suites.length; ++i)
167             if (m_suites[i] == ciphersuite)
168                 return true;
169         return false;
170     }
171 
172     Vector!( Pair!(string, string) ) supportedAlgos() const
173     {
174         if (SignatureAlgorithms sigs = m_extensions.get!SignatureAlgorithms())
175             return sigs.supportedSignatureAlgorthms().dup();
176         return Vector!( Pair!(string, string) )();
177     }
178 
179     Vector!string supportedEccCurves() const
180     {
181         if (SupportedEllipticCurves ecc = m_extensions.get!SupportedEllipticCurves())
182             return ecc.curves().dup();
183         return Vector!string();
184     }
185 
186     string sniHostname() const
187     {
188         if (ServerNameIndicator sni = m_extensions.get!ServerNameIndicator())
189             return sni.hostName();
190         return "";
191     }
192 
193     string srpIdentifier() const
194     {
195         if (SRPIdentifier srp = m_extensions.get!SRPIdentifier())
196             return srp.identifier();
197         return "";
198     }
199 
200     bool sentFallbackSCSV() const
201     {
202         return offeredSuite(cast(ushort) TLS_FALLBACK_SCSV);
203     }
204 
205     bool secureRenegotiation() const
206     {
207         return m_extensions.get!RenegotiationExtension() !is null;
208     }
209 
210     Vector!ubyte renegotiationInfo() const
211     {
212         if (RenegotiationExtension reneg = m_extensions.get!RenegotiationExtension())
213             return reneg.renegotiationInfo().dup();
214         return Vector!ubyte();
215     }
216 
217     size_t fragmentSize() const
218     {
219         if (MaximumFragmentLength frag = m_extensions.get!MaximumFragmentLength())
220             return frag.fragmentSize();
221         return 0;
222     }
223 
224     bool supportsSessionTicket() const
225     {
226         return m_extensions.get!SessionTicket() !is null;
227     }
228 
229     Vector!ubyte sessionTicket() const
230     {
231         if (SessionTicket ticket = m_extensions.get!SessionTicket())
232             return ticket.contents().dup();
233         return Vector!ubyte();
234     }
235 
236 	bool supportsAlpn() const
237 	{
238 		return m_extensions.get!ApplicationLayerProtocolNotification() !is null;
239 	}
240 
241 	bool supportsExtendedMasterSecret() const
242 	{
243 		return m_extensions.get!ExtendedMasterSecret() !is null;
244 	}
245 
246     const(Vector!string) nextProtocols() const
247     {
248         if (auto alpn = m_extensions.get!ApplicationLayerProtocolNotification())
249             return alpn.protocols().dup;
250         return Vector!string();
251     }
252 
253     bool supportsHeartbeats() const
254     {
255         return m_extensions.get!HeartbeatSupportIndicator() !is null;
256     }
257 
258     bool peerCanSendHeartbeats() const
259     {
260         if (HeartbeatSupportIndicator hb = m_extensions.get!HeartbeatSupportIndicator())
261             return hb.peerAllowedToSend();
262         return false;
263     }
264 
265     bool supportsChannelID() const
266     {
267         return m_extensions.get!ChannelIDSupport() !is null;
268     }
269 
270     void updateHelloCookie(in HelloVerifyRequest hello_verify)
271     {
272         if (!m_version.isDatagramProtocol())
273             throw new Exception("Cannot use hello cookie with stream protocol");
274         
275         m_hello_cookie = hello_verify.cookie().dup;
276     }
277 
278     const(Vector!HandshakeExtensionType) extensionTypes() const
279     { return m_extensions.extensionTypes(); }
280 
281     /*
282     * Create a new TLSClient Hello message
283     */
284     this(HandshakeIO io,
285          ref HandshakeHash hash,
286          TLSProtocolVersion _version,
287          in TLSPolicy policy,
288          RandomNumberGenerator rng,
289          Vector!ubyte reneg_info,
290          Vector!string next_protocols,
291          in string hostname,
292          in string srp_identifier) 
293     {
294 		//logDebug("ClientHello with hostname: ", hostname);
295 
296         bool reneg_empty = reneg_info.empty;
297         m_version = _version;
298 
299 		assert(policy.acceptableProtocolVersion(_version), "Our policy accepts the version we are offering");
300 
301         m_random = makeHelloRandom(rng, policy);
302         m_suites = policy.ciphersuiteList(m_version, (srp_identifier != ""));
303         m_comp_methods = policy.compression();
304 
305 		foreach (extension_; policy.enabledExtensions()) {
306 			switch (extension_) {
307 				case TLSEXT_SAFE_RENEGOTIATION:
308 					m_extensions.add(new RenegotiationExtension(reneg_info.move()));
309 					break;
310 				case TLSEXT_SERVER_NAME_INDICATION:
311 					m_extensions.add(new ServerNameIndicator(hostname));
312 					break;
313 				case TLSEXT_EC_POINT_FORMATS:
314 					m_extensions.add(new SupportedPointFormats);
315 					break;
316 				case TLSEXT_USABLE_ELLIPTIC_CURVES:
317 					m_extensions.add(new SupportedEllipticCurves(policy.allowedEccCurves()));
318 					break;
319 				case TLSEXT_EXTENDED_MASTER_SECRET:
320 					m_extensions.add(new ExtendedMasterSecret);
321 					break;
322 				case TLSEXT_SESSION_TICKET:
323 					m_extensions.add(new SessionTicket());
324 					break;
325 				case TLSEXT_SIGNATURE_ALGORITHMS:
326 					if (m_version.supportsNegotiableSignatureAlgorithms())
327 						m_extensions.add(new SignatureAlgorithms(policy.allowedSignatureHashes(),
328 							policy.allowedSignatureMethods()));
329 					break;
330 				case TLSEXT_STATUS_REQUEST: //todo: Complete support
331 					m_extensions.add(new StatusRequest);
332 					break;
333 				case TLSEXT_NPN:
334 					m_extensions.add(new NPN);
335 					break;
336 				case TLSEXT_SIGNED_CERT_TIMESTAMP:
337 					m_extensions.add(new SignedCertificateTimestamp);
338 					break;
339 				case TLSEXT_ALPN:
340 					if (reneg_empty && !next_protocols.empty)
341 						m_extensions.add(new ApplicationLayerProtocolNotification(next_protocols.move));
342 					break;
343 				case TLSEXT_CHANNEL_ID:
344                     m_extensions.add(new ChannelIDSupport);
345 					break;
346 				case TLSEXT_SRP_IDENTIFIER:
347 					m_extensions.add(new SRPIdentifier(srp_identifier));
348 					break;
349 				case TLSEXT_HEARTBEAT_SUPPORT:
350 					if (policy.negotiateHeartbeatSupport())
351 	            		m_extensions.add(new HeartbeatSupportIndicator(true));
352 					break;
353                 default:
354                     break;
355 			}
356 
357 		}
358 
359         if (policy.sendFallbackSCSV(_version))
360             m_suites.pushBack(TLS_FALLBACK_SCSV);
361         else m_suites.pushBack(TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
362 
363         hash.update(io.send(this));
364     }
365 
366 
367     /*
368     * Create a new TLSClient Hello message (session resumption case)
369     */
370     this(HandshakeIO io,
371          ref HandshakeHash hash,
372          in TLSPolicy policy,
373          RandomNumberGenerator rng,
374          Vector!ubyte reneg_info,
375          in TLSSession session,
376          Vector!string next_protocols)
377     { 
378         bool reneg_empty = reneg_info.empty;
379 
380         m_version = session.Version();
381         m_session_id = session.sessionId().dup;
382         m_random = makeHelloRandom(rng, policy);
383         m_suites = policy.ciphersuiteList(m_version, (session.srpIdentifier() != ""));
384         m_comp_methods = policy.compression();
385         if (!valueExists(m_suites, session.ciphersuiteCode()))
386             m_suites.pushBack(session.ciphersuiteCode());
387         
388         if (!valueExists(m_comp_methods, session.compressionMethod()))
389             m_comp_methods.pushBack(session.compressionMethod());
390 
391 		foreach (extension_; policy.enabledExtensions()) {
392 			switch (extension_) {
393 				case TLSEXT_SAFE_RENEGOTIATION:
394 					m_extensions.add(new RenegotiationExtension(reneg_info.move()));
395 					break;
396 				case TLSEXT_SERVER_NAME_INDICATION:
397 					m_extensions.add(new ServerNameIndicator(session.serverInfo().hostname()));
398 					break;
399 				case TLSEXT_EC_POINT_FORMATS:
400 					m_extensions.add(new SupportedPointFormats);
401 					break;
402 				case TLSEXT_USABLE_ELLIPTIC_CURVES:
403 					m_extensions.add(new SupportedEllipticCurves(policy.allowedEccCurves()));
404 					break;
405 				case TLSEXT_EXTENDED_MASTER_SECRET:
406 					m_extensions.add(new ExtendedMasterSecret);
407 					break;
408 				case TLSEXT_SESSION_TICKET:
409 					m_extensions.add(new SessionTicket(session.sessionTicket().dup));
410 					break;
411 				case TLSEXT_SIGNATURE_ALGORITHMS:
412 					if (m_version.supportsNegotiableSignatureAlgorithms())
413 						m_extensions.add(new SignatureAlgorithms(policy.allowedSignatureHashes(),
414 								policy.allowedSignatureMethods()));
415 					break;
416 				case TLSEXT_STATUS_REQUEST: //todo: Complete support
417 					m_extensions.add(new StatusRequest);
418 					break;
419 				case TLSEXT_NPN:
420 					m_extensions.add(new NPN);
421 					break;
422 				case TLSEXT_SIGNED_CERT_TIMESTAMP:
423 					m_extensions.add(new SignedCertificateTimestamp);
424 					break;
425 				case TLSEXT_ALPN:
426 					if (reneg_empty && !next_protocols.empty)
427 						m_extensions.add(new ApplicationLayerProtocolNotification(next_protocols.move));
428 					break;
429 				case TLSEXT_CHANNEL_ID:
430                     m_extensions.add(new ChannelIDSupport);
431 					break;
432 				case TLSEXT_SRP_IDENTIFIER:
433 					m_extensions.add(new SRPIdentifier(session.srpIdentifier()));
434 					break;
435 				case TLSEXT_HEARTBEAT_SUPPORT:
436 					if (policy.negotiateHeartbeatSupport())
437 						m_extensions.add(new HeartbeatSupportIndicator(true));
438 					break;
439 				case TLSEXT_MAX_FRAGMENT_LENGTH:
440 					if (session.fragmentSize() != 0)
441 						m_extensions.add(new MaximumFragmentLength(session.fragmentSize()));
442 					break;
443                 default:
444                     break;
445 			}
446 		}
447 
448         
449         if (policy.sendFallbackSCSV(m_version))
450             m_suites.pushBack(TLS_FALLBACK_SCSV);
451         else
452             m_suites.pushBack(TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
453 
454         hash.update(io.send(this));
455     }
456 	bool deserialized;
457     /*
458     * Read a counterparty client hello
459     */
460     this(const ref Vector!ubyte buf, HandshakeType type)
461     {
462 		deserialized = true;
463         if (type == CLIENT_HELLO)
464             deserialize(buf);
465     }
466 
467 protected:
468     /*
469     * Serialize a TLSClient Hello message
470     */
471     override Vector!ubyte serialize() const
472     {
473 
474 		/*logDebug("Ciphersuites: ", ciphersuites()[]);
475 		logDebug("Supported ECC curves: ", supportedEccCurves()[]);
476 		logDebug("SupportedAlgos: ", supportedAlgos()[]);
477 		logDebug("Session ID: ", sessionId[]);
478 		logDebug("Random: ", random()[]);
479 		logDebug("sni Hostname: ", sniHostname);
480 		logDebug("sentFallback SCSV: ", sentFallbackSCSV());
481 		logDebug("Secure renegotiation: ", secureRenegotiation());
482 		logDebug("NextProtocol: ", nextProtocols[]);
483 		*/
484         Vector!ubyte buf;
485 		buf.reserve(512);
486 
487         buf.pushBack(m_version.majorVersion());
488         buf.pushBack(m_version.minorVersion());
489         buf ~= m_random[];
490         
491         appendTlsLengthValue(buf, m_session_id, 1);
492         
493         if (m_version.isDatagramProtocol())
494             appendTlsLengthValue(buf, m_hello_cookie, 1);
495         
496         appendTlsLengthValue(buf, m_suites, 2);
497         appendTlsLengthValue(buf, m_comp_methods, 1);
498         
499         /*
500         * May not want to send extensions at all in some cases. If so,
501         * should include SCSV value (if reneg info is empty, if not we are
502         * renegotiating with a modern server)
503         */
504         
505         auto vec = m_extensions.serialize();
506         // pad when between 256 and 511 (inclusive) bytes long
507         if ((buf.length+4) + vec.length <= 511 &&  (buf.length+4) + vec.length >= 256)
508         {
509             long pad = 512L - cast(long)vec.length - (cast(long)buf.length+4L) - 4L;
510             if (pad <= 0)
511                 pad = 1;
512             ushort extn_size = cast(ushort)(vec.length+pad+4-2);
513             vec[0] = get_byte(0, extn_size);
514             vec[1] = get_byte(1, extn_size);
515             vec.pushBack(get_byte(0, cast(ushort) 21));
516             vec.pushBack(get_byte(1, cast(ushort) 21)); // padding extension identifier
517             vec.pushBack(get_byte(0, cast(ushort) pad));
518             vec.pushBack(get_byte(1, cast(ushort) pad));
519             foreach (i; 0 .. pad)
520                 vec ~= cast(ubyte)0x00;
521         }
522         buf ~= vec[];
523 
524         return buf.move();
525     }
526 
527     /*
528     * Deserialize a TLSClient Hello message
529     */
530     void deserialize(const ref Vector!ubyte buf)
531     {
532 		if (buf.length == 0)
533             throw new DecodingError("ClientHello: Packet corrupted");
534         
535         if (buf.length < 41)
536             throw new DecodingError("ClientHello: Packet corrupted");
537         
538         TLSDataReader reader = TLSDataReader("ClientHello", buf);
539         
540         const ubyte major_version = reader.get_byte();
541         const ubyte minor_version = reader.get_byte();
542         
543         m_version = TLSProtocolVersion(major_version, minor_version);
544         m_random = reader.getFixed!ubyte(32);
545         
546         if (m_version.isDatagramProtocol())
547             m_hello_cookie = reader.getRange!ubyte(1, 0, 255);
548         
549         m_session_id = reader.getRange!ubyte(1, 0, 32);
550         
551         m_suites = reader.getRangeVector!ushort(2, 1, 32767);
552         
553         m_comp_methods = reader.getRangeVector!ubyte(1, 1, 255);
554         
555 		m_extensions.reserve(8);
556         m_extensions.deserialize(reader);
557         
558         if (offeredSuite(cast(ushort)(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)))
559         {
560             if (RenegotiationExtension reneg = m_extensions.get!RenegotiationExtension())
561             {
562                 if (!reneg.renegotiationInfo().empty)
563                     throw new TLSException(TLSAlert.HANDSHAKE_FAILURE,
564                                             "Client sent renegotiation SCSV and non-empty extension");
565             }
566             else
567             {
568                 // add fake extension
569                 m_extensions.add(new RenegotiationExtension());
570             }
571         }
572 		/*logDebug("Ciphersuites: ", ciphersuites()[]);
573 		logDebug("Session ID: ", sessionId[]);
574 		logDebug("Random: ", random()[]);
575 		logDebug("sni Hostname: ", sniHostname);
576 		logDebug("sentFallback SCSV: ", sentFallbackSCSV());
577 		logDebug("Secure renegotiation: ", secureRenegotiation());*/
578 		//logDebug("NextProtocol: ", nextProtocols[]);
579     }
580 
581 private:
582     TLSProtocolVersion m_version;
583     Vector!ubyte m_session_id;
584     Vector!ubyte m_random;
585     Vector!ushort m_suites;
586     Vector!ubyte m_comp_methods;
587     Vector!ubyte m_hello_cookie; // DTLS only
588 
589     TLSExtensions m_extensions;
590 }
591 
592 /**
593 * TLSServer Hello Message
594 */
595 final class ServerHello : HandshakeMessage
596 {
597 public:
598     override const(HandshakeType) type() const { return SERVER_HELLO; }
599 
600     TLSProtocolVersion Version() const { return m_version; }
601 
602     ref const(Vector!ubyte) random() const { return m_random; }
603 
604 	const(ubyte[]) randomBytes() const { return m_random[]; }
605 
606 	ref const(Vector!ubyte) sessionId() const { return m_session_id; }
607 
608 	const(ubyte[]) sessionIdBytes() const { return m_session_id[]; }
609 
610     ushort ciphersuite() const { return m_ciphersuite; }
611 
612     ubyte compressionMethod() const { return m_comp_method; }
613 
614     bool secureRenegotiation() const
615     {
616         return m_extensions.get!RenegotiationExtension() !is null;
617     }
618 
619     Vector!ubyte renegotiationInfo() const
620     {
621         if (RenegotiationExtension reneg = m_extensions.get!RenegotiationExtension())
622             return reneg.renegotiationInfo().dup;
623         return Vector!ubyte();
624     }
625 
626     size_t fragmentSize() const
627     {
628         if (MaximumFragmentLength frag = m_extensions.get!MaximumFragmentLength())
629             return frag.fragmentSize();
630         return 0;
631     }
632 
633 	bool supportsExtendedMasterSecret() const
634 	{
635 		return m_extensions.get!ExtendedMasterSecret() !is null;
636 	}
637 
638     bool supportsSessionTicket() const
639     {
640         return m_extensions.get!SessionTicket() !is null;
641     }
642 
643     bool supportsHeartbeats() const
644     {
645         return m_extensions.get!HeartbeatSupportIndicator() !is null;
646     }
647 
648     bool supportsChannelID() const
649     {
650         return m_extensions.get!ChannelIDSupport() !is null;
651     }
652 
653     bool peerCanSendHeartbeats() const
654     {
655         if (auto hb = m_extensions.get!HeartbeatSupportIndicator())
656             return hb.peerAllowedToSend();
657         return false;
658     }
659 
660     string nextProtocol() const
661     {
662         if (auto alpn = m_extensions.get!ApplicationLayerProtocolNotification())
663             return alpn.singleProtocol();
664         return "";
665     }
666 
667     const(Vector!HandshakeExtensionType) extensionTypes() const
668     { return m_extensions.extensionTypes(); }
669 
670     /*
671     * Create a new TLSServer Hello message
672     */
673     this(HandshakeIO io,
674          ref HandshakeHash hash,
675          in TLSPolicy policy,
676          Vector!ubyte session_id,
677          TLSProtocolVersion ver,
678          ushort ciphersuite,
679          ubyte compression,
680          size_t max_fragment_size,
681          bool client_has_secure_renegotiation,
682          bool client_has_extended_master_secret,
683          Vector!ubyte reneg_info,
684          bool offer_session_ticket,
685          bool client_has_alpn,
686          in string next_protocol,
687          bool client_has_heartbeat,
688          RandomNumberGenerator rng) 
689     {
690         m_version = ver;
691         m_session_id = session_id.move();
692         m_random = makeHelloRandom(rng, policy);
693         m_ciphersuite = ciphersuite;
694         m_comp_method = compression;
695 		m_extensions.reserve(8);
696 
697 		if (client_has_extended_master_secret)
698 			m_extensions.add(new ExtendedMasterSecret);
699 
700         if (client_has_heartbeat && policy.negotiateHeartbeatSupport())
701             m_extensions.add(new HeartbeatSupportIndicator(true));
702         
703         if (client_has_secure_renegotiation)
704             m_extensions.add(new RenegotiationExtension(reneg_info.move()));
705         
706         if (max_fragment_size)
707             m_extensions.add(new MaximumFragmentLength(max_fragment_size));
708         
709         if (next_protocol != "" && client_has_alpn)
710             m_extensions.add(new ApplicationLayerProtocolNotification(next_protocol));
711         
712         if (offer_session_ticket)
713             m_extensions.add(new SessionTicket());
714         
715         hash.update(io.send(this));
716     }
717 
718     /*
719     * Deserialize a TLSServer Hello message
720     */
721     this(const ref Vector!ubyte buf)
722     {
723         if (buf.length < 38)
724             throw new DecodingError("ServerHello: Packet corrupted");
725 
726         TLSDataReader reader = TLSDataReader("ServerHello", buf);
727         
728         const ubyte major_version = reader.get_byte();
729         const ubyte minor_version = reader.get_byte();
730         
731         m_version = TLSProtocolVersion(major_version, minor_version);
732         
733         m_random = reader.getFixed!ubyte(32);
734 
735         m_session_id = reader.getRange!ubyte(1, 0, 32);
736 
737         m_ciphersuite = reader.get_ushort();
738         
739         m_comp_method = reader.get_byte();
740         
741 		m_extensions.reserve(8);
742         m_extensions.deserialize(reader);
743     }
744 
745 protected:
746     /*
747     * Serialize a TLSServer Hello message
748     */
749     override Vector!ubyte serialize() const
750     {
751         Vector!ubyte buf;
752 		buf.reserve(512);
753 
754         buf.pushBack(m_version.majorVersion());
755         buf.pushBack(m_version.minorVersion());
756         buf ~= m_random[];
757         
758         appendTlsLengthValue(buf, m_session_id, 1);
759         
760         buf.pushBack(get_byte(0, m_ciphersuite));
761         buf.pushBack(get_byte(1, m_ciphersuite));
762         
763         buf.pushBack(m_comp_method);
764                 
765 		auto vec = m_extensions.serialize();
766 		buf ~= vec[];
767 		return buf.move();
768     }
769 
770 private:
771     TLSProtocolVersion m_version;
772     Vector!ubyte m_session_id, m_random;
773     ushort m_ciphersuite;
774     ubyte m_comp_method;
775 
776     TLSExtensions m_extensions;
777 }
778 
779 /**
780 * TLSClient Key Exchange Message
781 */
782 final class ClientKeyExchange : HandshakeMessage
783 {
784 public:
785     override HandshakeType type() const { return CLIENT_KEX; }
786 
787     ref const(SecureVector!ubyte) preMasterSecret() const
788     { return m_pre_master; }
789 
790     /*
791     * Read a TLSClient Key Exchange message
792     */
793     this(const ref Vector!ubyte contents,
794          in HandshakeState state,
795          in PrivateKey server_rsa_kex_key,
796          TLSCredentialsManager creds,
797          in TLSPolicy policy,
798          RandomNumberGenerator rng)
799     {
800         const string kex_algo = state.ciphersuite().kexAlgo();
801         
802         if (kex_algo == "RSA")
803         {
804             assert(state.serverCerts() && !state.serverCerts().certChain().empty,
805                          "RSA key exchange negotiated so server sent a certificate");
806             
807             if (!server_rsa_kex_key)
808                 throw new InternalError("Expected RSA kex but no server kex key set");
809             
810             if (server_rsa_kex_key.algoName != "RSA")
811                 throw new InternalError("Expected RSA key but got " ~ server_rsa_kex_key.algoName);
812             
813             auto decryptor = scoped!PKDecryptorEME(server_rsa_kex_key, "PKCS1v15");
814             
815             TLSProtocolVersion client_version = state.clientHello().Version();
816             
817             /*
818             * This is used as the pre-master if RSA decryption fails.
819             * Otherwise we can be used as an oracle. See Bleichenbacher
820             * "Chosen Ciphertext Attacks against Protocols Based on RSA
821             * Encryption Standard PKCS #1", Crypto 98
822             *
823             * Create it here instead if in the catch clause as otherwise we
824             * expose a timing channel WRT the generation of the fake value.
825             * Some timing channel likely remains due to exception handling
826             * and the like.
827             */
828             SecureVector!ubyte fake_pre_master = rng.randomVec(48);
829             fake_pre_master[0] = client_version.majorVersion();
830             fake_pre_master[1] = client_version.minorVersion();
831             
832             try
833             {
834                 TLSDataReader reader = TLSDataReader("ClientKeyExchange", contents);
835                 m_pre_master = decryptor.decrypt(reader.getRange!ubyte(2, 0, 65535));
836 
837                 if (m_pre_master.length != 48 ||
838                     client_version.majorVersion() != m_pre_master[0] ||
839                     client_version.minorVersion() != m_pre_master[1])
840                 {
841                     throw new DecodingError("ClientKeyExchange: Secret corrupted");
842                 }
843             }
844             catch (Exception)
845             {
846                 m_pre_master = fake_pre_master;
847             }
848         }
849         else
850         {
851             TLSDataReader reader = TLSDataReader("ClientKeyExchange", contents);
852             
853             auto psk = SymmetricKey();
854             
855             if (kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
856             {
857                 const string psk_identity = reader.getString(2, 0, 65535);
858                 
859                 psk = creds.psk("tls-server",
860                                 state.clientHello().sniHostname(),
861                                 psk_identity);
862                 
863                 if (psk.length == 0)
864                 {
865                     if (policy.hideUnknownUsers())
866                         psk = SymmetricKey(rng, 16);
867                     else
868                         throw new TLSException(TLSAlert.UNKNOWN_PSK_IDENTITY,
869                                                 "No PSK for identifier " ~ psk_identity);
870                 }
871             }
872             
873             if (kex_algo == "PSK")
874             {
875                 Vector!ubyte zeros = Vector!ubyte(psk.length);
876                 appendTlsLengthValue(m_pre_master, zeros, 2);
877                 appendTlsLengthValue(m_pre_master, psk.bitsOf(), 2);
878             }
879             else if (kex_algo == "SRP_SHA")
880             {
881 				static if (BOTAN_HAS_SRP6) {
882 	                SRP6ServerSession srp = cast(SRP6ServerSession) state.serverKex().serverSrpParams();
883 	                
884 	                m_pre_master = srp.step2(BigInt.decode(reader.getRange!ubyte(2, 0, 65535))).bitsOf();
885 				}
886 				else {
887 					throw new InternalError("ClientKeyExchange: Unknown kex type " ~ kex_algo);
888 				}
889             }
890             else if (kex_algo == "DH" || kex_algo == "DHE_PSK" ||
891                      kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
892             {
893                 const PrivateKey private_key = state.serverKex().serverKexKey();
894                 
895                 const PKKeyAgreementKey ka_key = cast(const PKKeyAgreementKey)(private_key);
896                 
897                 if (!ka_key)
898                     throw new InternalError("Expected key agreement key type but got " ~
899                                              private_key.algoName);
900                 
901                 try
902                 {
903                     auto ka = scoped!PKKeyAgreement(ka_key, "Raw");
904                     
905                     Vector!ubyte client_pubkey;
906                     
907                     if (ka_key.algoName == "DH")
908                         client_pubkey = reader.getRange!ubyte(2, 0, 65535);
909                     else
910                         client_pubkey = reader.getRange!ubyte(1, 0, 255);
911 					auto derived_key = ka.deriveKey(0, client_pubkey);
912 					SecureVector!ubyte shared_secret = derived_key.bitsOf();
913                     
914                     if (ka_key.algoName == "DH")
915                         shared_secret = stripLeadingZeros(shared_secret);
916                     
917                     if (kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
918                     {
919                         appendTlsLengthValue(m_pre_master, shared_secret, 2);
920                         appendTlsLengthValue(m_pre_master, psk.bitsOf(), 2);
921                     }
922                     else
923                         m_pre_master = shared_secret.move();
924                 }
925                 catch(Exception e)
926                 {
927                     /*
928                     * Something failed in the DH computation. To avoid possible
929                     * timing attacks, randomize the pre-master output and carry
930                     * on, allowing the protocol to fail later in the finished
931                     * checks.
932                     */
933                     m_pre_master = rng.randomVec(ka_key.publicValue().length);
934                 }
935             }
936             else
937                 throw new InternalError("ClientKeyExchange: Unknown kex type " ~ kex_algo);
938         }
939     }
940 
941     /*
942     * Create a new TLSClient Key Exchange message
943     */
944     this(HandshakeIO io,
945          HandshakeState state,
946          in TLSPolicy policy,
947          TLSCredentialsManager creds,
948          const PublicKey server_public_key,
949          in string hostname,
950          RandomNumberGenerator rng)
951     {
952         const string kex_algo = state.ciphersuite().kexAlgo();
953         
954         if (kex_algo == "PSK")
955         {
956             string identity_hint = "";
957             
958             if (state.serverKex())
959             {
960                 TLSDataReader reader = TLSDataReader("ClientKeyExchange", state.serverKex().params());
961                 identity_hint = reader.getString(2, 0, 65535);
962             }
963             
964             const string hostname_ = state.clientHello().sniHostname();
965             
966             const string psk_identity = creds.pskIdentity("tls-client",
967                                                            hostname_,
968                                                            identity_hint);
969             
970             appendTlsLengthValue(m_key_material, psk_identity, 2);
971             
972             SymmetricKey psk = creds.psk("tls-client", hostname_, psk_identity);
973             
974             Vector!ubyte zeros = Vector!ubyte(psk.length);
975             
976             appendTlsLengthValue(m_pre_master, zeros, 2);
977             appendTlsLengthValue(m_pre_master, psk.bitsOf(), 2);
978         }
979         else if (state.serverKex())
980         {
981             TLSDataReader reader = TLSDataReader("ClientKeyExchange", state.serverKex().params());
982             
983             auto psk = SymmetricKey();
984             
985             if (kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
986             {
987                 string identity_hint = reader.getString(2, 0, 65535);
988                 
989                 const string hostname_ = state.clientHello().sniHostname();
990                 
991                 const string psk_identity = creds.pskIdentity("tls-client",
992                                                                hostname_,
993                                                                identity_hint);
994                 
995                 appendTlsLengthValue(m_key_material, psk_identity, 2);
996                 
997                 psk = creds.psk("tls-client", hostname_, psk_identity);
998             }
999             
1000             if (kex_algo == "DH" || kex_algo == "DHE_PSK")
1001             {
1002                 BigInt p = BigInt.decode(reader.getRange!ubyte(2, 1, 65535));
1003                 BigInt g = BigInt.decode(reader.getRange!ubyte(2, 1, 65535));
1004                 BigInt Y = BigInt.decode(reader.getRange!ubyte(2, 1, 65535));
1005                 
1006                 if (reader.remainingBytes())
1007                     throw new DecodingError("Bad params size for DH key exchange");
1008                 
1009                 if (p.bits() < policy.minimumDhGroupSize())
1010                     throw new TLSException(TLSAlert.INSUFFICIENT_SECURITY,
1011                                             "TLSServer sent DH group of " ~
1012                                             to!string(p.bits()) ~
1013                                             " bits, policy requires at least " ~
1014                                             to!string(policy.minimumDhGroupSize()));
1015                 
1016                 /*
1017                 * A basic check for key validity. As we do not know q here we
1018                 * cannot check that Y is in the right subgroup. However since
1019                 * our key is ephemeral there does not seem to be any
1020                 * advantage to bogus keys anyway.
1021                 */
1022                 if (Y <= 1 || Y >= p - 1)
1023                     throw new TLSException(TLSAlert.INSUFFICIENT_SECURITY,
1024                                             "TLSServer sent bad DH key for DHE exchange");
1025                 
1026                 DLGroup group = DLGroup(p, g);
1027                 
1028                 if (!group.verifyGroup(rng, false))
1029                     throw new TLSException(TLSAlert.INSUFFICIENT_SECURITY, "DH group failed validation, possible attack");
1030                 auto counterparty_key = DHPublicKey(group.dup, Y.move);
1031                 
1032                 auto priv_key = DHPrivateKey(rng, group.move);
1033                 
1034                 auto ka = scoped!PKKeyAgreement(priv_key, "Raw");
1035                 
1036 				auto octet_string = ka.deriveKey(0, counterparty_key.publicValue());
1037                 SecureVector!ubyte dh_secret = stripLeadingZeros(octet_string.bitsOf());
1038                 
1039                 if (kex_algo == "DH")
1040                     m_pre_master = dh_secret.move();
1041                 else
1042                 {
1043                     appendTlsLengthValue(m_pre_master, dh_secret, 2);
1044                     appendTlsLengthValue(m_pre_master, psk.bitsOf(), 2);
1045                 }
1046                 
1047                 appendTlsLengthValue(m_key_material, priv_key.publicValue(), 2);
1048             }
1049             else if (kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
1050             {
1051                 const ubyte curve_type = reader.get_byte();
1052                 
1053                 if (curve_type != 3)
1054                     throw new DecodingError("TLSServer sent non-named ECC curve");
1055                 
1056                 const ushort curve_id = reader.get_ushort();
1057                 
1058                 const string curve_name = SupportedEllipticCurves.curveIdToName(curve_id);
1059                 
1060 				if (curve_name == "")
1061                     throw new DecodingError("TLSServer sent unknown named curve " ~ to!string(curve_id));
1062 				{
1063 					Vector!string allowed_curves = policy.allowedEccCurves();
1064 					if(!(allowed_curves[]).canFind(curve_name))
1065 						throw new TLSException(TLSAlert.HANDSHAKE_FAILURE, "Server sent ECC curve prohibited by policy");
1066 				}
1067 				Vector!ubyte ecdh_key = reader.getRange!ubyte(1, 1, 255);
1068 
1069 				Vector!ubyte our_ecdh_public;
1070 				SecureVector!ubyte ecdh_secret;
1071 
1072 				if (curve_name == "x25519") {
1073 					import botan.pubkey.algo.curve25519;
1074 					if (ecdh_key.length != 32)
1075 						throw new TLSException(TLSAlert.HANDSHAKE_FAILURE, "Invalid X25519 key size");
1076 					Curve25519PublicKey counterparty_key = Curve25519PublicKey(ecdh_key);
1077 					Curve25519PrivateKey priv_key = Curve25519PrivateKey(rng);
1078 
1079 					auto ka = scoped!PKKeyAgreement(priv_key, "Raw");
1080 					auto public_value = counterparty_key.publicValue();
1081 					auto derived_key = ka.deriveKey(0, public_value);
1082 
1083 					ecdh_secret = derived_key.bitsOf();
1084 					our_ecdh_public = priv_key.publicValue();
1085 
1086 				} else {
1087 					ECGroup group = ECGroup(curve_name);
1088 	                
1089 	                
1090 	                auto counterparty_key = ECDHPublicKey(group, OS2ECP(ecdh_key, group.getCurve()));	                
1091 	                auto priv_key = ECDHPrivateKey(rng, group);
1092 					
1093 					auto ka = scoped!PKKeyAgreement(priv_key, "Raw");
1094 					auto public_value = counterparty_key.publicValue();
1095 					auto derived_key = ka.deriveKey(0, public_value);
1096 
1097 					ecdh_secret = derived_key.bitsOf();
1098 					our_ecdh_public = priv_key.publicValue();
1099 				}
1100                 if (kex_algo == "ECDH")
1101                     m_pre_master = ecdh_secret.move();
1102                 else
1103                 {
1104                     appendTlsLengthValue(m_pre_master, ecdh_secret, 2);
1105                     appendTlsLengthValue(m_pre_master, psk.bitsOf(), 2);
1106                 }
1107                 
1108 				appendTlsLengthValue(m_key_material, our_ecdh_public, 1);
1109             }
1110             else if (kex_algo == "SRP_SHA")
1111             {
1112 				static if (BOTAN_HAS_SRP6) {
1113 	                const BigInt N = BigInt.decode(reader.getRange!ubyte(2, 1, 65535));
1114 	                const BigInt g = BigInt.decode(reader.getRange!ubyte(2, 1, 65535));
1115 	                Vector!ubyte salt = reader.getRange!ubyte(1, 1, 255);
1116 	                const BigInt B = BigInt.decode(reader.getRange!ubyte(2, 1, 65535));
1117 	                
1118 	                const string srp_group = srp6GroupIdentifier(N, g);
1119 	                
1120 	                const string srp_identifier = creds.srpIdentifier("tls-client", hostname);
1121 	                
1122 	                const string srp_password = creds.srpPassword("tls-client", hostname, srp_identifier);
1123 	                
1124 	                SRP6KeyPair srp_vals = srp6ClientAgree(srp_identifier,
1125 	                                                                       srp_password,
1126 	                                                                       srp_group,
1127 	                                                                       "SHA-1",
1128 	                                                                       salt,
1129 	                                                                       B,
1130 	                                                                       rng);
1131 	                
1132 	                appendTlsLengthValue(m_key_material, BigInt.encode(srp_vals.privkey), 2);
1133 	                m_pre_master = srp_vals.pubkey.bitsOf();
1134 				} else {
1135 					throw new InternalError("ClientKeyExchange: Unknown kex " ~ kex_algo);
1136 				}
1137             }
1138             else
1139             {
1140                 throw new InternalError("ClientKeyExchange: Unknown kex " ~
1141                                          kex_algo);
1142             }
1143             
1144             reader.assertDone();
1145         }
1146         else
1147         {
1148             // No server key exchange msg better mean RSA kex + RSA key in cert
1149             
1150             if (kex_algo != "RSA")
1151                 throw new TLSUnexpectedMessage("No server kex but negotiated kex " ~ kex_algo);
1152             
1153             if (!server_public_key)
1154                 throw new InternalError("No server public key for RSA exchange");
1155             
1156             if (server_public_key.algoName == "RSA")
1157             {
1158                 auto rsa_pub = RSAPublicKey(cast(PublicKey)server_public_key);
1159                 const TLSProtocolVersion offered_version = state.clientHello().Version();
1160                 
1161                 m_pre_master = rng.randomVec(48);
1162                 m_pre_master[0] = offered_version.majorVersion();
1163                 m_pre_master[1] = offered_version.minorVersion();
1164                 
1165                 auto encryptor = scoped!PKEncryptorEME(rsa_pub, "PKCS1v15");
1166                 
1167                 Vector!ubyte encrypted_key = encryptor.encrypt(m_pre_master, rng);
1168                 
1169                 appendTlsLengthValue(m_key_material, encrypted_key, 2);
1170             }
1171             else
1172                 throw new TLSException(TLSAlert.HANDSHAKE_FAILURE,
1173                                         "Expected a RSA key in server cert but got " ~
1174                                         server_public_key.algoName);
1175         }
1176         
1177         state.hash().update(io.send(this));
1178     }
1179 
1180 
1181 protected:
1182     override Vector!ubyte serialize() const { return m_key_material.dup; }
1183 
1184 private:
1185     Vector!ubyte m_key_material;
1186     SecureVector!ubyte m_pre_master;
1187 }
1188 
1189 /**
1190 * Certificate Message
1191 */
1192 final class Certificate : HandshakeMessage
1193 {
1194 public:
1195     override const(HandshakeType) type() const { return CERTIFICATE; }
1196     ref const(Vector!X509Certificate) certChain() const { return *m_certs; }
1197 
1198     size_t count() const { return m_certs.length; }
1199     @property bool empty() const { return m_certs.empty; }
1200 
1201     /**
1202     * Create a new Certificate message
1203     */
1204     this()(HandshakeIO io,
1205            ref HandshakeHash hash,
1206            auto ref Array!X509Certificate cert_list)
1207     {
1208         m_certs = cert_list;
1209         hash.update(io.send(this));
1210     }
1211 
1212     /**
1213     * Create a new Certificate message
1214     */
1215     this()(HandshakeIO io,
1216         ref HandshakeHash hash,
1217         auto ref Vector!X509Certificate cert_list)
1218     {
1219         m_certs = cert_list.dupr;
1220         hash.update(io.send(this));
1221     }
1222 
1223     /**
1224     * Deserialize a Certificate message
1225     */
1226     this()(auto const ref Vector!ubyte buf)
1227     {
1228         if (buf.length < 3)
1229             throw new DecodingError("Certificate: Message malformed");
1230         
1231         const size_t total_size = make_uint(0, buf[0], buf[1], buf[2]);
1232 
1233         if (total_size != buf.length - 3)
1234             throw new DecodingError("Certificate: Message malformed");
1235         
1236         const(ubyte)* certs = buf.ptr + 3;
1237         
1238         while (true)
1239         {
1240             size_t remaining_bytes = buf.ptr + buf.length - certs;
1241             if (remaining_bytes <= 0)
1242                 break;
1243             if (remaining_bytes < 3)
1244                 throw new DecodingError("Certificate: Message malformed");
1245             
1246             const size_t cert_size = make_uint(0, certs[0], certs[1], certs[2]);
1247             
1248             if (remaining_bytes < (3 + cert_size))
1249                 throw new DecodingError("Certificate: Message malformed");
1250             
1251             auto cert_buf = DataSourceMemory(&certs[3], cert_size);
1252             m_certs.pushBack(X509Certificate(cast(DataSource)cert_buf));
1253             
1254             certs += cert_size + 3;
1255         }
1256     }
1257 
1258 protected:
1259     /**
1260     * Serialize a Certificate message
1261     */
1262     override Vector!ubyte serialize() const
1263     {
1264 		Vector!ubyte buf;
1265 		buf.reserve(2048);
1266 		buf.length = 3;
1267         for (size_t i = 0; i != m_certs.length; ++i)
1268         {
1269             Vector!ubyte raw_cert = m_certs[i].BER_encode();
1270             const size_t cert_size = raw_cert.length;
1271             foreach (size_t j; 0 .. 3)
1272                 buf.pushBack(get_byte!uint(j+1, cast(uint) cert_size));
1273             buf ~= raw_cert;
1274         }
1275         
1276         const size_t buf_size = buf.length - 3;
1277         foreach (size_t i; 0 .. 3)
1278             buf[i] = get_byte!uint(i+1, cast(uint) buf_size);
1279         
1280         return buf.move();
1281     }
1282 
1283 private:
1284     Array!X509Certificate m_certs;
1285 }
1286 
1287 /**
1288 * Certificate Request Message
1289 */
1290 final class CertificateReq : HandshakeMessage
1291 {
1292 public:
1293     override const(HandshakeType) type() const { return CERTIFICATE_REQUEST; }
1294 
1295     ref const(Vector!string) acceptableCertTypes() const
1296     { return m_cert_key_types; }
1297 
1298     ref const(Vector!X509DN) acceptableCAs() const { return m_names; }
1299 
1300     Vector!( Pair!(string, string) ) supportedAlgos() const
1301     { return m_supported_algos.dup; }
1302 
1303     /**
1304     * Create a new Certificate Request message
1305     */
1306     this(HandshakeIO io,
1307          ref HandshakeHash hash,
1308          in TLSPolicy policy,
1309          Vector!X509DN ca_certs,
1310          TLSProtocolVersion _version) 
1311     {
1312         m_names = ca_certs.move();
1313         m_cert_key_types = [ "RSA", "DSA", "ECDSA" ];
1314 		static Vector!( Pair!(string, string)  ) last_supported_algos;
1315 		static TLSPolicy last_tls_policy;
1316         static TLSProtocolVersion last_version;
1317 		if (policy is last_tls_policy && _version == last_version)
1318 			m_supported_algos = last_supported_algos.dup;
1319 		else {
1320 			m_supported_algos.reserve(16);
1321 	        if (_version.supportsNegotiableSignatureAlgorithms())
1322 	        {
1323 	            Vector!string hashes = policy.allowedSignatureHashes();
1324 	            Vector!string sigs = policy.allowedSignatureMethods();
1325 	            
1326 	            for (size_t i = 0; i != hashes.length; ++i)
1327 	                for (size_t j = 0; j != sigs.length; ++j)
1328 	                    m_supported_algos.pushBack(makePair(hashes[i], sigs[j]));
1329 	        }
1330 			last_tls_policy = cast() policy;
1331             last_version = _version;
1332 			last_supported_algos = m_supported_algos.dup;
1333 		}
1334         
1335         hash.update(io.send(this));
1336     }
1337 
1338     /**
1339     * Deserialize a Certificate Request message
1340     */
1341     this(const ref Vector!ubyte buf, TLSProtocolVersion _version)
1342     {
1343         if (buf.length < 4)
1344             throw new DecodingError("Certificate_Req: Bad certificate request");
1345         
1346         TLSDataReader reader = TLSDataReader("CertificateRequest", buf);
1347 
1348         Vector!ubyte cert_type_codes = reader.getRangeVector!ubyte(1, 1, 255);
1349         
1350         for (size_t i = 0; i != cert_type_codes.length; ++i)
1351         {
1352             const string cert_type_name = certTypeCodeToName(cert_type_codes[i]);
1353             
1354             if (cert_type_name == "") // something we don't know
1355                 continue;
1356             
1357             m_cert_key_types.pushBack(cert_type_name);
1358         }
1359         
1360         if (_version.supportsNegotiableSignatureAlgorithms())
1361         {
1362             Vector!ubyte sig_hash_algs = reader.getRangeVector!ubyte(2, 2, 65534);
1363             
1364             if (sig_hash_algs.length % 2 != 0)
1365                 throw new DecodingError("Bad length for signature IDs in certificate request");
1366             
1367             for (size_t i = 0; i != sig_hash_algs.length; i += 2)
1368             {
1369                 string hash = SignatureAlgorithms.hashAlgoName(sig_hash_algs[i]);
1370                 string sig = SignatureAlgorithms.sigAlgoName(sig_hash_algs[i+1]);
1371                 m_supported_algos.pushBack(makePair(hash, sig));
1372             }
1373         }
1374         
1375         const ushort purported_size = reader.get_ushort();
1376         
1377         if (reader.remainingBytes() != purported_size)
1378             throw new DecodingError("Inconsistent length in certificate request");
1379         
1380         while (reader.hasRemaining())
1381         {
1382             Vector!ubyte name_bits = reader.getRangeVector!ubyte(2, 0, 65535);
1383             
1384             BERDecoder decoder = BERDecoder(name_bits.ptr, name_bits.length);
1385             X509DN name = X509DN();
1386             decoder.decode(name);
1387             m_names.pushBack(name);
1388         }
1389     }
1390 
1391 protected:
1392 
1393     /**
1394     * Serialize a Certificate Request message
1395     */
1396     override Vector!ubyte serialize() const
1397     {
1398         Vector!ubyte buf;
1399 		buf.reserve(256);
1400         Vector!ubyte cert_types;
1401 		cert_types.reserve(64);
1402         for (size_t i = 0; i != m_cert_key_types.length; ++i)
1403             cert_types.pushBack(certTypeNameToCode(m_cert_key_types[i]));
1404 
1405         appendTlsLengthValue(buf, cert_types, 1);
1406         
1407         if (!m_supported_algos.empty) {
1408 			Unique!SignatureAlgorithms sig_algos = new SignatureAlgorithms(m_supported_algos.dup);
1409             buf ~= sig_algos.serialize();
1410 		}
1411         
1412         Vector!ubyte encoded_names;
1413         
1414         for (size_t i = 0; i != m_names.length; ++i)
1415         {
1416             DEREncoder encoder = DEREncoder();
1417             encoder.encode(m_names[i]);
1418             
1419             appendTlsLengthValue(encoded_names, encoder.getContents(), 2);
1420         }
1421         
1422         appendTlsLengthValue(buf, encoded_names, 2);
1423         
1424         return buf.move();
1425     }
1426 
1427 private:
1428     Vector!X509DN m_names;
1429     Vector!string m_cert_key_types;
1430 
1431     Vector!( Pair!(string, string)  ) m_supported_algos;
1432 }
1433 
1434 /**
1435 * Certificate Verify Message
1436 */
1437 final class CertificateVerify : HandshakeMessage
1438 {
1439 public:
1440     override const(HandshakeType) type() const { return CERTIFICATE_VERIFY; }
1441 
1442     /**
1443     * Check the signature on a certificate verify message
1444     * Params:
1445     *  cert = the purported certificate
1446     *  state = the handshake state
1447     */
1448     bool verify(const X509Certificate cert,
1449                 const HandshakeState state) const
1450     {
1451         Unique!PublicKey key = cert.subjectPublicKey();
1452         
1453         Pair!(string, SignatureFormat) format = state.understandSigFormat(*key, m_hash_algo, m_sig_algo, true);
1454         
1455         PKVerifier verifier = PKVerifier(*key, format.first, format.second);
1456         
1457         return verifier.verifyMessage(state.hash().getContents(), m_signature);
1458     }
1459 
1460     /*
1461     * Create a new Certificate Verify message
1462     */
1463     this(HandshakeIO io,
1464          HandshakeState state,
1465          in TLSPolicy policy,
1466          RandomNumberGenerator rng,
1467          const PrivateKey priv_key)
1468     {
1469         assert(priv_key, "No private key defined");
1470         
1471         Pair!(string, SignatureFormat) format = state.chooseSigFormat(priv_key, m_hash_algo, m_sig_algo, true, policy);
1472         
1473         PKSigner signer = PKSigner(priv_key, format.first, format.second);
1474         
1475 		m_signature = signer.signMessage(state.hash().getContents(), rng);
1476                 
1477         state.hash().update(io.send(this));
1478     }
1479 
1480     /*
1481     * Deserialize a Certificate Verify message
1482     */
1483     this(const ref Vector!ubyte buf,
1484          TLSProtocolVersion _version)
1485     {
1486         TLSDataReader reader = TLSDataReader("CertificateVerify", buf);
1487         
1488         if (_version.supportsNegotiableSignatureAlgorithms())
1489         {
1490             m_hash_algo = SignatureAlgorithms.hashAlgoName(reader.get_byte());
1491             m_sig_algo = SignatureAlgorithms.sigAlgoName(reader.get_byte());
1492         }
1493         
1494         m_signature = reader.getRange!ubyte(2, 0, 65535);
1495     }
1496 
1497 protected:
1498     /*
1499     * Serialize a Certificate Verify message
1500     */
1501     override Vector!ubyte serialize() const
1502     {
1503         Vector!ubyte buf;
1504         
1505         if (m_hash_algo != "" && m_sig_algo != "")
1506         {
1507             buf.pushBack(SignatureAlgorithms.hashAlgoCode(m_hash_algo));
1508             buf.pushBack(SignatureAlgorithms.sigAlgoCode(m_sig_algo));
1509         }
1510         
1511         const ushort sig_len = cast(ushort) m_signature.length;
1512         buf.pushBack(get_byte(0, sig_len));
1513         buf.pushBack(get_byte(1, sig_len));
1514         buf ~= m_signature[];
1515         
1516         return buf.move();
1517     }
1518 
1519 private:
1520     string m_sig_algo; // sig algo used to create signature
1521     string m_hash_algo; // hash used to create signature
1522     Vector!ubyte m_signature;
1523 }
1524 
1525 /**
1526 * Finished Message
1527 */
1528 final class Finished : HandshakeMessage
1529 {
1530 public:
1531     override const(HandshakeType) type() const { return FINISHED; }
1532 
1533     ref const(Vector!ubyte) verifyData() const
1534     { return m_verification_data; }
1535 
1536 	const(ubyte[]) verifyDataBytes() const { return m_verification_data[]; }
1537 
1538     /*
1539     * Verify a Finished message
1540     */
1541     bool verify(in HandshakeState state, ConnectionSide side) const
1542     {
1543         return (m_verification_data == finishedComputeVerify(state, side));
1544     }
1545 
1546     /*
1547     * Create a new Finished message
1548     */
1549     this(HandshakeIO io,
1550          HandshakeState state,
1551          ConnectionSide side)
1552     {
1553         m_verification_data = finishedComputeVerify(state, side);
1554         state.hash().update(io.send(this));
1555     }
1556 
1557     /*
1558     * Deserialize a Finished message
1559     */
1560     this(Vector!ubyte buf)
1561     {
1562         m_verification_data = buf.move();
1563     }
1564 
1565 protected:
1566     /*
1567     * Serialize a Finished message
1568     */
1569     override Vector!ubyte serialize() const
1570     {
1571         return m_verification_data.dup;
1572     }
1573    
1574 private:
1575     Vector!ubyte m_verification_data;
1576 }
1577 
1578 /**
1579 * Hello Request Message
1580 */
1581 final class HelloRequest : HandshakeMessage
1582 {
1583 public:
1584     override const(HandshakeType) type() const { return HELLO_REQUEST; }
1585 
1586     /*
1587     * Create a new Hello Request message
1588     */
1589     this(HandshakeIO io)
1590     {
1591         io.send(this);
1592     }
1593 
1594     /*
1595     * Deserialize a Hello Request message
1596     */
1597     this(const ref Vector!ubyte buf)
1598     {
1599         if (buf.length)
1600             throw new DecodingError("Bad HelloRequest, has non-zero size");
1601     }
1602 
1603 protected:
1604     /*
1605     * Serialize a Hello Request message
1606     */
1607     override Vector!ubyte serialize() const
1608     {
1609         return Vector!ubyte();
1610     }
1611 }
1612 
1613 /**
1614 * TLSServer Key Exchange Message
1615 */
1616 final class ServerKeyExchange : HandshakeMessage
1617 {
1618 public:
1619     override const(HandshakeType) type() const { return SERVER_KEX; }
1620 
1621     ref const(Vector!ubyte) params() const { return m_params; }
1622 
1623     /**
1624     * Verify a TLSServer Key Exchange message
1625     */
1626     bool verify(in PublicKey server_key,
1627                 const HandshakeState state) const
1628     {
1629         Pair!(string, SignatureFormat) format = state.understandSigFormat(server_key, m_hash_algo, m_sig_algo, false);
1630 
1631         PKVerifier verifier = PKVerifier(server_key, format.first, format.second);
1632         verifier.update(state.clientHello().random());
1633         verifier.update(state.serverHello().random());
1634         verifier.update(params());
1635         return verifier.checkSignature(m_signature);
1636     }
1637 
1638     // Only valid for certain kex types
1639     const(PrivateKey) serverKexKey() const
1640     {
1641         assert(m_kex_key, "PrivateKey cannot be null");
1642         return *m_kex_key;
1643     }
1644 
1645 	static if (BOTAN_HAS_SRP6) {
1646 	    // Only valid for SRP negotiation
1647 	    const(SRP6ServerSession) serverSrpParams() const
1648 	    {
1649 	        assert(m_srp_params, "SRP6ServerSession cannot be null");
1650 	        return *m_srp_params;
1651 	    }
1652 	}
1653 
1654     /**
1655     * Deserialize a TLSServer Key Exchange message
1656     */
1657     this(const ref Vector!ubyte buf,
1658          in string kex_algo,
1659          in string sig_algo,
1660          TLSProtocolVersion _version) 
1661     {
1662         m_kex_key.free();
1663 		static if (BOTAN_HAS_SRP6)
1664 	        m_srp_params.free();
1665         if (buf.length < 6)
1666             throw new DecodingError("ServerKeyExchange: Packet corrupted");
1667         
1668         TLSDataReader reader = TLSDataReader("ServerKeyExchange", buf);
1669         
1670         /*
1671         * We really are just serializing things back to what they were
1672         * before, but unfortunately to know where the signature is we need
1673         * to be able to parse the whole thing anyway.
1674         */
1675         
1676         if (kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
1677         {
1678             const string identity_hint = reader.getString(2, 0, 65535);
1679             appendTlsLengthValue(m_params, identity_hint, 2);
1680         }
1681         
1682         if (kex_algo == "DH" || kex_algo == "DHE_PSK")
1683         {
1684             // 3 bigints, DH p, g, Y
1685             
1686             foreach (size_t i; 0 .. 3)
1687             {
1688                 BigInt v = BigInt.decode(reader.getRange!ubyte(2, 1, 65535));
1689                 appendTlsLengthValue(m_params, BigInt.encode(v), 2);
1690             }
1691         }
1692         else if (kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
1693         {
1694             const ubyte curve_type = reader.get_byte();
1695             
1696             if (curve_type != 3)
1697                 throw new DecodingError("ServerKeyExchange: TLSServer sent non-named ECC curve");
1698             
1699             const ushort curve_id = reader.get_ushort();
1700             
1701             const string name = SupportedEllipticCurves.curveIdToName(curve_id);
1702             
1703             Vector!ubyte ecdh_key = reader.getRange!ubyte(1, 1, 255);
1704             
1705             if (name == "")
1706                 throw new DecodingError("ServerKeyExchange: TLSServer sent unknown named curve " ~
1707                                          to!string(curve_id));
1708             
1709             m_params.pushBack(curve_type);
1710             m_params.pushBack(get_byte(0, curve_id));
1711             m_params.pushBack(get_byte(1, curve_id));
1712             appendTlsLengthValue(m_params, ecdh_key, 1);
1713         }
1714         else if (kex_algo == "SRP_SHA")
1715         {
1716             // 2 bigints (N,g) then salt, then server B
1717             
1718             const BigInt N = BigInt.decode(reader.getRange!ubyte(2, 1, 65535));
1719             const BigInt g = BigInt.decode(reader.getRange!ubyte(2, 1, 65535));
1720             Vector!ubyte salt = reader.getRange!ubyte(1, 1, 255);
1721             const BigInt B = BigInt.decode(reader.getRange!ubyte(2, 1, 65535));
1722             
1723             appendTlsLengthValue(m_params, BigInt.encode(N), 2);
1724             appendTlsLengthValue(m_params, BigInt.encode(g), 2);
1725             appendTlsLengthValue(m_params, salt, 1);
1726             appendTlsLengthValue(m_params, BigInt.encode(B), 2);
1727         }
1728         else if (kex_algo != "PSK")
1729                 throw new DecodingError("ServerKeyExchange: Unsupported kex type " ~ kex_algo);
1730         
1731         if (sig_algo != "")
1732         {
1733             if (_version.supportsNegotiableSignatureAlgorithms())
1734             {
1735                 m_hash_algo = SignatureAlgorithms.hashAlgoName(reader.get_byte());
1736                 m_sig_algo = SignatureAlgorithms.sigAlgoName(reader.get_byte());
1737             }
1738             
1739             m_signature = reader.getRange!ubyte(2, 0, 65535);
1740         }
1741         
1742         reader.assertDone();
1743     }
1744 
1745     /**
1746     * Create a new TLSServer Key Exchange message
1747     */
1748     this(HandshakeIO io,
1749          HandshakeState state,
1750          in TLSPolicy policy,
1751          TLSCredentialsManager creds,
1752          RandomNumberGenerator rng,
1753          in PrivateKey signing_key = null)
1754     {
1755         const string hostname = state.clientHello().sniHostname();
1756         const string kex_algo = state.ciphersuite().kexAlgo();
1757         
1758         if (kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
1759         {
1760             string identity_hint = creds.pskIdentityHint("tls-server", hostname);
1761             
1762             appendTlsLengthValue(m_params, identity_hint, 2);
1763         }
1764         
1765         if (kex_algo == "DH" || kex_algo == "DHE_PSK")
1766         {
1767             auto dh = DHPrivateKey(rng, policy.dhGroup());
1768 
1769             appendTlsLengthValue(m_params, BigInt.encode(dh.getDomain().getP()), 2);
1770             appendTlsLengthValue(m_params, BigInt.encode(dh.getDomain().getG()), 2);
1771             appendTlsLengthValue(m_params, dh.publicValue(), 2);
1772             m_kex_key = dh.release();
1773         }
1774         else if (kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
1775         {
1776             Vector!string curves = state.clientHello().supportedEccCurves();
1777             
1778             if (curves.empty)
1779                 throw new InternalError("TLSClient sent no ECC extension but we negotiated ECDH");
1780             
1781             const string curve_name = policy.chooseCurve(curves.move());
1782             
1783             if (curve_name == "")
1784                 throw new TLSException(TLSAlert.HANDSHAKE_FAILURE, "Could not agree on an ECC curve with the client");
1785 			const ushort named_curve_id = SupportedEllipticCurves.nameToCurveId(curve_name);
1786 			if (named_curve_id == 0)
1787 				throw new InternalError("TLS does not support ECC with " ~ curve_name);
1788 			Vector!ubyte ecdh_public_val;
1789 
1790 			if (curve_name == "x25519") {
1791 				import botan.pubkey.algo.curve25519;
1792 				Curve25519PrivateKey x25519 = Curve25519PrivateKey(rng);
1793 				ecdh_public_val = x25519.publicValue();
1794 				m_kex_key = x25519.release();
1795 			} else {
1796 	            ECGroup ec_group = ECGroup(curve_name);	            
1797 	            auto ecdh = ECDHPrivateKey(rng, ec_group);
1798 				ecdh_public_val = ecdh.publicValue();
1799 	            
1800 				m_kex_key = ecdh.release();
1801 			}
1802             m_params.pushBack(3); // named curve
1803             m_params.pushBack(get_byte(0, named_curve_id));
1804             m_params.pushBack(get_byte(1, named_curve_id));
1805             
1806             appendTlsLengthValue(m_params, ecdh_public_val, 1);
1807             
1808         }
1809         else if (kex_algo == "SRP_SHA")
1810         {
1811 			static if (BOTAN_HAS_SRP6) {
1812 	            const string srp_identifier = state.clientHello().srpIdentifier();
1813 	            
1814 	            string group_id;
1815 	            BigInt v;
1816 	            Vector!ubyte salt;
1817 	            
1818 	            const bool found = creds.srpVerifier("tls-server", hostname,
1819 	                                                  srp_identifier,
1820 	                                                  group_id, v, salt,
1821 	                                                  policy.hideUnknownUsers());
1822 	            
1823 	            if (!found)
1824 	                throw new TLSException(TLSAlert.UNKNOWN_PSK_IDENTITY, "Unknown SRP user " ~ srp_identifier);
1825 	            
1826 	            m_srp_params = new SRP6ServerSession;
1827 	            
1828 	            const BigInt* B = &m_srp_params.step1(v, group_id, "SHA-1", rng);
1829 	            
1830 	            DLGroup group = DLGroup(group_id);
1831 
1832 	            appendTlsLengthValue(m_params, BigInt.encode(group.getP()), 2);
1833 	            appendTlsLengthValue(m_params, BigInt.encode(group.getG()), 2);
1834 	            appendTlsLengthValue(m_params, salt, 1);
1835 	            appendTlsLengthValue(m_params, BigInt.encode(*B), 2);
1836 			} else {
1837 				throw new InternalError("ServerKeyExchange: Unknown kex type " ~ kex_algo);
1838 			}
1839         }
1840         else if (kex_algo != "PSK")
1841             throw new InternalError("ServerKeyExchange: Unknown kex type " ~ kex_algo);
1842         
1843         if (state.ciphersuite().sigAlgo() != "")
1844         {
1845             assert(signing_key, "Signing key was set");
1846             
1847             Pair!(string, SignatureFormat) format = state.chooseSigFormat(signing_key, m_hash_algo, m_sig_algo, false, policy);
1848             
1849             PKSigner signer = PKSigner(signing_key, format.first, format.second);
1850             
1851             signer.update(state.clientHello().random());
1852             signer.update(state.serverHello().random());
1853             signer.update(params());
1854             m_signature = signer.signature(rng);
1855         }
1856         
1857         state.hash().update(io.send(this));
1858     }
1859 
1860 protected:
1861     /**
1862     * Serialize a TLSServer Key Exchange message
1863     */
1864     override Vector!ubyte serialize() const
1865     {
1866         Vector!ubyte buf = params().dup;
1867         
1868         if (m_signature.length)
1869         {
1870             // This should be an explicit version check
1871             if (m_hash_algo != "" && m_sig_algo != "")
1872             {
1873                 buf.pushBack(SignatureAlgorithms.hashAlgoCode(m_hash_algo));
1874                 buf.pushBack(SignatureAlgorithms.sigAlgoCode(m_sig_algo));
1875             }
1876             
1877             appendTlsLengthValue(buf, m_signature, 2);
1878         }
1879         
1880         return buf.move();
1881     }
1882 
1883 private:
1884     Unique!PrivateKey m_kex_key;
1885 	static if (BOTAN_HAS_SRP6)
1886 	    Unique!SRP6ServerSession m_srp_params;
1887 
1888     Vector!ubyte m_params;
1889 
1890     string m_sig_algo; // sig algo used to create signature
1891     string m_hash_algo; // hash used to create signature
1892     Vector!ubyte m_signature;
1893 }
1894 
1895 /**
1896 * TLSServer Hello Done Message
1897 */
1898 final class ServerHelloDone : HandshakeMessage
1899 {
1900 public:
1901     override const(HandshakeType) type() const { return SERVER_HELLO_DONE; }
1902 
1903     /*
1904     * Create a new TLSServer Hello Done message
1905     */
1906     this(HandshakeIO io, ref HandshakeHash hash)
1907     {
1908         hash.update(io.send(this));
1909     }
1910 
1911     /*
1912     * Deserialize a TLSServer Hello Done message
1913     */
1914     this(const ref Vector!ubyte buf)
1915     {
1916         if (buf.length)
1917             throw new DecodingError("ServerHello_Done: Must be empty, and is not");
1918     }
1919 protected:
1920     /*
1921     * Serialize a TLSServer Hello Done message
1922     */
1923     override Vector!ubyte serialize() const
1924     {
1925         return Vector!ubyte();
1926     }
1927 }
1928 
1929 /**
1930  * New EncryptedExtensions Message used mainly for ChannelIDExtension
1931  */
1932 final class ChannelID : HandshakeMessage
1933 {
1934     override const(HandshakeType) type() const { return CHANNEL_ID; }
1935 
1936     this(HandshakeIO io, 
1937          ref HandshakeHash hash,
1938          TLSCredentialsManager creds, 
1939          string hostname, 
1940          SecureVector!ubyte hs_hash,
1941          SecureVector!ubyte orig_hs_hash = SecureVector!ubyte())
1942     {
1943         m_channel_id = new EncryptedChannelID(creds.channelPrivateKey(hostname), hs_hash.move(), orig_hs_hash.move());
1944         hash.update(io.send(this));
1945     }
1946 
1947     override Vector!ubyte serialize() const
1948     {
1949         Vector!ubyte buf;
1950         buf.reserve(130);
1951 
1952         const ushort extn_code = m_channel_id.type();
1953         const Vector!ubyte extn_val = m_channel_id.serialize();
1954         
1955         buf.pushBack(get_byte(0, extn_code));
1956         buf.pushBack(get_byte(1, extn_code));
1957         
1958         buf.pushBack(get_byte(0, cast(ushort) extn_val.length));
1959         buf.pushBack(get_byte(1, cast(ushort) extn_val.length));
1960         
1961         buf ~= extn_val[];
1962         return buf.move();
1963     }
1964 
1965 private:
1966     Unique!EncryptedChannelID m_channel_id;
1967 }
1968 
1969 /**
1970 * New TLS Session Ticket Message
1971 */
1972 final class NewSessionTicket : HandshakeMessage
1973 {
1974 public:
1975     override const(HandshakeType) type() const { return NEW_SESSION_TICKET; }
1976 
1977     const(Duration) ticketLifetimeHint() const { return m_ticket_lifetime_hint; }
1978     ref const(Vector!ubyte) ticket() const { return m_ticket; }
1979 
1980     this(HandshakeIO io,
1981          ref HandshakeHash hash,
1982          Vector!ubyte ticket,
1983          Duration lifetime) 
1984         
1985     {   
1986         m_ticket_lifetime_hint = lifetime;
1987         m_ticket = ticket.move();
1988         hash.update = io.send(this);
1989     }
1990 
1991     this(const ref Vector!ubyte buf)
1992     {
1993         if (buf.length < 6)
1994             throw new DecodingError("TLSSession ticket message too short to be valid");
1995         
1996         TLSDataReader reader = TLSDataReader("SessionTicket", buf);
1997         
1998         m_ticket_lifetime_hint = reader.get_uint().seconds;
1999         m_ticket = reader.getRange!ubyte(2, 0, 65535);
2000     }
2001 
2002     this(HandshakeIO io, ref HandshakeHash hash)
2003     {
2004         hash.update(io.send(this));
2005     }
2006 
2007 protected:
2008     override Vector!ubyte serialize() const
2009     {
2010         Vector!ubyte buf = Vector!ubyte(4);
2011         storeBigEndian(m_ticket_lifetime_hint.total!"seconds", buf.ptr);
2012         appendTlsLengthValue(buf, m_ticket, 2);
2013         return buf.move();
2014     }
2015 
2016 private:
2017     Duration m_ticket_lifetime_hint;
2018     Vector!ubyte m_ticket;
2019 }
2020 
2021 /**
2022 * Change Cipher Spec
2023 */
2024 final class ChangeCipherSpec : HandshakeMessage
2025 {
2026 public:
2027     override const(HandshakeType) type() const { return HANDSHAKE_CCS; }
2028 
2029     override Vector!ubyte serialize() const
2030     { return Vector!ubyte(cast(ubyte[])[1]); }
2031 }
2032 
2033 
2034 package:
2035 
2036 string certTypeCodeToName(ubyte code)
2037 {
2038     switch(code)
2039     {
2040         case 1:
2041             return "RSA";
2042         case 2:
2043             return "DSA";
2044         case 64:
2045             return "ECDSA";
2046         default:
2047             return ""; // DH or something else
2048     }
2049 }
2050 
2051 ubyte certTypeNameToCode(in string name)
2052 {
2053     if (name == "RSA")
2054         return 1;
2055     if (name == "DSA")
2056         return 2;
2057     if (name == "ECDSA")
2058         return 64;
2059     
2060     throw new InvalidArgument("Unknown cert type " ~ name);
2061 }
2062 
2063 
2064 SecureVector!ubyte stripLeadingZeros()(auto const ref SecureVector!ubyte input)
2065 {
2066     size_t leading_zeros = 0;
2067     
2068     for (size_t i = 0; i != input.length; ++i)
2069     {
2070         if (input[i] != 0)
2071             break;
2072         ++leading_zeros;
2073     }
2074     
2075     SecureVector!ubyte output = SecureVector!ubyte(input.ptr[leading_zeros .. input.length]);
2076     return output;
2077 }
2078 
2079 
2080 /*
2081 * Compute the verifyData
2082 */
2083 Vector!ubyte finishedComputeVerify(in HandshakeState state, ConnectionSide side)
2084 {
2085     __gshared immutable const(ubyte)[] TLS_CLIENT_LABEL = [
2086         0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x69,
2087         0x73, 0x68, 0x65, 0x64 ];
2088     
2089     __gshared immutable const(ubyte)[] TLS_SERVER_LABEL = [
2090         0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x66, 0x69, 0x6E, 0x69,
2091         0x73, 0x68, 0x65, 0x64 ];
2092     
2093     Unique!KDF prf = state.protocolSpecificPrf();
2094     
2095     Vector!ubyte input;
2096 	input.reserve(64);
2097     if (side == CLIENT)
2098         input ~= cast(ubyte[])TLS_CLIENT_LABEL;
2099     else
2100         input ~= cast(ubyte[])TLS_SERVER_LABEL;
2101     
2102     auto vec = state.hash().flushInto(state.Version(), state.ciphersuite().prfAlgo());
2103 	input ~= vec[];
2104 	return unlock(prf.deriveKey(12, state.sessionKeys().masterSecret(), input));
2105 
2106 }
2107 
2108 Vector!ubyte makeHelloRandom(RandomNumberGenerator rng, in TLSPolicy policy)
2109 {
2110     Vector!ubyte buf = Vector!ubyte(32);
2111     rng.randomize(&buf[0], buf.length);
2112 
2113     if (policy.includeTimeInHelloRandom())
2114     {
2115         const uint time32 = cast(uint)(Clock.currTime(UTC()).toUnixTime);
2116         storeBigEndian(time32, buf.ptr);
2117     }
2118 
2119     return buf;
2120 }