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 name = SupportedEllipticCurves.curveIdToName(curve_id);
1059                 
1060                 if (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(name))
1065 						throw new TLSException(TLSAlert.HANDSHAKE_FAILURE, "Server sent ECC curve prohibited by policy");
1066 				}
1067 
1068                 ECGroup group = ECGroup(name);
1069                 
1070                 Vector!ubyte ecdh_key = reader.getRange!ubyte(1, 1, 255);
1071                 
1072                 auto counterparty_key = ECDHPublicKey(group, OS2ECP(ecdh_key, group.getCurve()));
1073                 
1074                 auto priv_key = ECDHPrivateKey(rng, group);
1075 				SecureVector!ubyte ecdh_secret;
1076 				{
1077 					auto ka = scoped!PKKeyAgreement(priv_key, "Raw");
1078 					auto public_value = counterparty_key.publicValue();
1079 					auto derived_key = ka.deriveKey(0, public_value);
1080 					ecdh_secret = derived_key.bitsOf();
1081 				}
1082 
1083                 if (kex_algo == "ECDH")
1084                     m_pre_master = ecdh_secret.move();
1085                 else
1086                 {
1087                     appendTlsLengthValue(m_pre_master, ecdh_secret, 2);
1088                     appendTlsLengthValue(m_pre_master, psk.bitsOf(), 2);
1089                 }
1090                 
1091                 appendTlsLengthValue(m_key_material, priv_key.publicValue(), 1);
1092             }
1093             else if (kex_algo == "SRP_SHA")
1094             {
1095 				static if (BOTAN_HAS_SRP6) {
1096 	                const BigInt N = BigInt.decode(reader.getRange!ubyte(2, 1, 65535));
1097 	                const BigInt g = BigInt.decode(reader.getRange!ubyte(2, 1, 65535));
1098 	                Vector!ubyte salt = reader.getRange!ubyte(1, 1, 255);
1099 	                const BigInt B = BigInt.decode(reader.getRange!ubyte(2, 1, 65535));
1100 	                
1101 	                const string srp_group = srp6GroupIdentifier(N, g);
1102 	                
1103 	                const string srp_identifier = creds.srpIdentifier("tls-client", hostname);
1104 	                
1105 	                const string srp_password = creds.srpPassword("tls-client", hostname, srp_identifier);
1106 	                
1107 	                SRP6KeyPair srp_vals = srp6ClientAgree(srp_identifier,
1108 	                                                                       srp_password,
1109 	                                                                       srp_group,
1110 	                                                                       "SHA-1",
1111 	                                                                       salt,
1112 	                                                                       B,
1113 	                                                                       rng);
1114 	                
1115 	                appendTlsLengthValue(m_key_material, BigInt.encode(srp_vals.privkey), 2);
1116 	                m_pre_master = srp_vals.pubkey.bitsOf();
1117 				} else {
1118 					throw new InternalError("ClientKeyExchange: Unknown kex " ~ kex_algo);
1119 				}
1120             }
1121             else
1122             {
1123                 throw new InternalError("ClientKeyExchange: Unknown kex " ~
1124                                          kex_algo);
1125             }
1126             
1127             reader.assertDone();
1128         }
1129         else
1130         {
1131             // No server key exchange msg better mean RSA kex + RSA key in cert
1132             
1133             if (kex_algo != "RSA")
1134                 throw new TLSUnexpectedMessage("No server kex but negotiated kex " ~ kex_algo);
1135             
1136             if (!server_public_key)
1137                 throw new InternalError("No server public key for RSA exchange");
1138             
1139             if (server_public_key.algoName == "RSA")
1140             {
1141                 auto rsa_pub = RSAPublicKey(cast(PublicKey)server_public_key);
1142                 const TLSProtocolVersion offered_version = state.clientHello().Version();
1143                 
1144                 m_pre_master = rng.randomVec(48);
1145                 m_pre_master[0] = offered_version.majorVersion();
1146                 m_pre_master[1] = offered_version.minorVersion();
1147                 
1148                 auto encryptor = scoped!PKEncryptorEME(rsa_pub, "PKCS1v15");
1149                 
1150                 Vector!ubyte encrypted_key = encryptor.encrypt(m_pre_master, rng);
1151                 
1152                 appendTlsLengthValue(m_key_material, encrypted_key, 2);
1153             }
1154             else
1155                 throw new TLSException(TLSAlert.HANDSHAKE_FAILURE,
1156                                         "Expected a RSA key in server cert but got " ~
1157                                         server_public_key.algoName);
1158         }
1159         
1160         state.hash().update(io.send(this));
1161     }
1162 
1163 
1164 protected:
1165     override Vector!ubyte serialize() const { return m_key_material.dup; }
1166 
1167 private:
1168     Vector!ubyte m_key_material;
1169     SecureVector!ubyte m_pre_master;
1170 }
1171 
1172 /**
1173 * Certificate Message
1174 */
1175 final class Certificate : HandshakeMessage
1176 {
1177 public:
1178     override const(HandshakeType) type() const { return CERTIFICATE; }
1179     ref const(Vector!X509Certificate) certChain() const { return *m_certs; }
1180 
1181     size_t count() const { return m_certs.length; }
1182     @property bool empty() const { return m_certs.empty; }
1183 
1184     /**
1185     * Create a new Certificate message
1186     */
1187     this()(HandshakeIO io,
1188            ref HandshakeHash hash,
1189            auto ref Array!X509Certificate cert_list)
1190     {
1191         m_certs = cert_list;
1192         hash.update(io.send(this));
1193     }
1194 
1195     /**
1196     * Create a new Certificate message
1197     */
1198     this()(HandshakeIO io,
1199         ref HandshakeHash hash,
1200         auto ref Vector!X509Certificate cert_list)
1201     {
1202         m_certs = cert_list.dupr;
1203         hash.update(io.send(this));
1204     }
1205 
1206     /**
1207     * Deserialize a Certificate message
1208     */
1209     this()(auto const ref Vector!ubyte buf)
1210     {
1211         if (buf.length < 3)
1212             throw new DecodingError("Certificate: Message malformed");
1213         
1214         const size_t total_size = make_uint(0, buf[0], buf[1], buf[2]);
1215 
1216         if (total_size != buf.length - 3)
1217             throw new DecodingError("Certificate: Message malformed");
1218         
1219         const(ubyte)* certs = buf.ptr + 3;
1220         
1221         while (true)
1222         {
1223             size_t remaining_bytes = buf.ptr + buf.length - certs;
1224             if (remaining_bytes <= 0)
1225                 break;
1226             if (remaining_bytes < 3)
1227                 throw new DecodingError("Certificate: Message malformed");
1228             
1229             const size_t cert_size = make_uint(0, certs[0], certs[1], certs[2]);
1230             
1231             if (remaining_bytes < (3 + cert_size))
1232                 throw new DecodingError("Certificate: Message malformed");
1233             
1234             auto cert_buf = DataSourceMemory(&certs[3], cert_size);
1235             m_certs.pushBack(X509Certificate(cast(DataSource)cert_buf));
1236             
1237             certs += cert_size + 3;
1238         }
1239     }
1240 
1241 protected:
1242     /**
1243     * Serialize a Certificate message
1244     */
1245     override Vector!ubyte serialize() const
1246     {
1247 		Vector!ubyte buf;
1248 		buf.reserve(2048);
1249 		buf.length = 3;
1250         for (size_t i = 0; i != m_certs.length; ++i)
1251         {
1252             Vector!ubyte raw_cert = m_certs[i].BER_encode();
1253             const size_t cert_size = raw_cert.length;
1254             foreach (size_t j; 0 .. 3)
1255                 buf.pushBack(get_byte!uint(j+1, cast(uint) cert_size));
1256             buf ~= raw_cert;
1257         }
1258         
1259         const size_t buf_size = buf.length - 3;
1260         foreach (size_t i; 0 .. 3)
1261             buf[i] = get_byte!uint(i+1, cast(uint) buf_size);
1262         
1263         return buf.move();
1264     }
1265 
1266 private:
1267     Array!X509Certificate m_certs;
1268 }
1269 
1270 /**
1271 * Certificate Request Message
1272 */
1273 final class CertificateReq : HandshakeMessage
1274 {
1275 public:
1276     override const(HandshakeType) type() const { return CERTIFICATE_REQUEST; }
1277 
1278     ref const(Vector!string) acceptableCertTypes() const
1279     { return m_cert_key_types; }
1280 
1281     ref const(Vector!X509DN) acceptableCAs() const { return m_names; }
1282 
1283     Vector!( Pair!(string, string) ) supportedAlgos() const
1284     { return m_supported_algos.dup; }
1285 
1286     /**
1287     * Create a new Certificate Request message
1288     */
1289     this(HandshakeIO io,
1290          ref HandshakeHash hash,
1291          in TLSPolicy policy,
1292          Vector!X509DN ca_certs,
1293          TLSProtocolVersion _version) 
1294     {
1295         m_names = ca_certs.move();
1296         m_cert_key_types = [ "RSA", "DSA", "ECDSA" ];
1297 		static Vector!( Pair!(string, string)  ) last_supported_algos;
1298 		static TLSPolicy last_tls_policy;
1299         static TLSProtocolVersion last_version;
1300 		if (policy is last_tls_policy && _version == last_version)
1301 			m_supported_algos = last_supported_algos.dup;
1302 		else {
1303 			m_supported_algos.reserve(16);
1304 	        if (_version.supportsNegotiableSignatureAlgorithms())
1305 	        {
1306 	            Vector!string hashes = policy.allowedSignatureHashes();
1307 	            Vector!string sigs = policy.allowedSignatureMethods();
1308 	            
1309 	            for (size_t i = 0; i != hashes.length; ++i)
1310 	                for (size_t j = 0; j != sigs.length; ++j)
1311 	                    m_supported_algos.pushBack(makePair(hashes[i], sigs[j]));
1312 	        }
1313 			last_tls_policy = cast() policy;
1314             last_version = _version;
1315 			last_supported_algos = m_supported_algos.dup;
1316 		}
1317         
1318         hash.update(io.send(this));
1319     }
1320 
1321     /**
1322     * Deserialize a Certificate Request message
1323     */
1324     this(const ref Vector!ubyte buf, TLSProtocolVersion _version)
1325     {
1326         if (buf.length < 4)
1327             throw new DecodingError("Certificate_Req: Bad certificate request");
1328         
1329         TLSDataReader reader = TLSDataReader("CertificateRequest", buf);
1330 
1331         Vector!ubyte cert_type_codes = reader.getRangeVector!ubyte(1, 1, 255);
1332         
1333         for (size_t i = 0; i != cert_type_codes.length; ++i)
1334         {
1335             const string cert_type_name = certTypeCodeToName(cert_type_codes[i]);
1336             
1337             if (cert_type_name == "") // something we don't know
1338                 continue;
1339             
1340             m_cert_key_types.pushBack(cert_type_name);
1341         }
1342         
1343         if (_version.supportsNegotiableSignatureAlgorithms())
1344         {
1345             Vector!ubyte sig_hash_algs = reader.getRangeVector!ubyte(2, 2, 65534);
1346             
1347             if (sig_hash_algs.length % 2 != 0)
1348                 throw new DecodingError("Bad length for signature IDs in certificate request");
1349             
1350             for (size_t i = 0; i != sig_hash_algs.length; i += 2)
1351             {
1352                 string hash = SignatureAlgorithms.hashAlgoName(sig_hash_algs[i]);
1353                 string sig = SignatureAlgorithms.sigAlgoName(sig_hash_algs[i+1]);
1354                 m_supported_algos.pushBack(makePair(hash, sig));
1355             }
1356         }
1357         
1358         const ushort purported_size = reader.get_ushort();
1359         
1360         if (reader.remainingBytes() != purported_size)
1361             throw new DecodingError("Inconsistent length in certificate request");
1362         
1363         while (reader.hasRemaining())
1364         {
1365             Vector!ubyte name_bits = reader.getRangeVector!ubyte(2, 0, 65535);
1366             
1367             BERDecoder decoder = BERDecoder(name_bits.ptr, name_bits.length);
1368             X509DN name = X509DN();
1369             decoder.decode(name);
1370             m_names.pushBack(name);
1371         }
1372     }
1373 
1374 protected:
1375 
1376     /**
1377     * Serialize a Certificate Request message
1378     */
1379     override Vector!ubyte serialize() const
1380     {
1381         Vector!ubyte buf;
1382 		buf.reserve(256);
1383         Vector!ubyte cert_types;
1384 		cert_types.reserve(64);
1385         for (size_t i = 0; i != m_cert_key_types.length; ++i)
1386             cert_types.pushBack(certTypeNameToCode(m_cert_key_types[i]));
1387 
1388         appendTlsLengthValue(buf, cert_types, 1);
1389         
1390         if (!m_supported_algos.empty) {
1391 			Unique!SignatureAlgorithms sig_algos = new SignatureAlgorithms(m_supported_algos.dup);
1392             buf ~= sig_algos.serialize();
1393 		}
1394         
1395         Vector!ubyte encoded_names;
1396         
1397         for (size_t i = 0; i != m_names.length; ++i)
1398         {
1399             DEREncoder encoder = DEREncoder();
1400             encoder.encode(m_names[i]);
1401             
1402             appendTlsLengthValue(encoded_names, encoder.getContents(), 2);
1403         }
1404         
1405         appendTlsLengthValue(buf, encoded_names, 2);
1406         
1407         return buf.move();
1408     }
1409 
1410 private:
1411     Vector!X509DN m_names;
1412     Vector!string m_cert_key_types;
1413 
1414     Vector!( Pair!(string, string)  ) m_supported_algos;
1415 }
1416 
1417 /**
1418 * Certificate Verify Message
1419 */
1420 final class CertificateVerify : HandshakeMessage
1421 {
1422 public:
1423     override const(HandshakeType) type() const { return CERTIFICATE_VERIFY; }
1424 
1425     /**
1426     * Check the signature on a certificate verify message
1427     * Params:
1428     *  cert = the purported certificate
1429     *  state = the handshake state
1430     */
1431     bool verify(const X509Certificate cert,
1432                 const HandshakeState state) const
1433     {
1434         Unique!PublicKey key = cert.subjectPublicKey();
1435         
1436         Pair!(string, SignatureFormat) format = state.understandSigFormat(*key, m_hash_algo, m_sig_algo, true);
1437         
1438         PKVerifier verifier = PKVerifier(*key, format.first, format.second);
1439         
1440         return verifier.verifyMessage(state.hash().getContents(), m_signature);
1441     }
1442 
1443     /*
1444     * Create a new Certificate Verify message
1445     */
1446     this(HandshakeIO io,
1447          HandshakeState state,
1448          in TLSPolicy policy,
1449          RandomNumberGenerator rng,
1450          const PrivateKey priv_key)
1451     {
1452         assert(priv_key, "No private key defined");
1453         
1454         Pair!(string, SignatureFormat) format = state.chooseSigFormat(priv_key, m_hash_algo, m_sig_algo, true, policy);
1455         
1456         PKSigner signer = PKSigner(priv_key, format.first, format.second);
1457         
1458 		m_signature = signer.signMessage(state.hash().getContents(), rng);
1459                 
1460         state.hash().update(io.send(this));
1461     }
1462 
1463     /*
1464     * Deserialize a Certificate Verify message
1465     */
1466     this(const ref Vector!ubyte buf,
1467          TLSProtocolVersion _version)
1468     {
1469         TLSDataReader reader = TLSDataReader("CertificateVerify", buf);
1470         
1471         if (_version.supportsNegotiableSignatureAlgorithms())
1472         {
1473             m_hash_algo = SignatureAlgorithms.hashAlgoName(reader.get_byte());
1474             m_sig_algo = SignatureAlgorithms.sigAlgoName(reader.get_byte());
1475         }
1476         
1477         m_signature = reader.getRange!ubyte(2, 0, 65535);
1478     }
1479 
1480 protected:
1481     /*
1482     * Serialize a Certificate Verify message
1483     */
1484     override Vector!ubyte serialize() const
1485     {
1486         Vector!ubyte buf;
1487         
1488         if (m_hash_algo != "" && m_sig_algo != "")
1489         {
1490             buf.pushBack(SignatureAlgorithms.hashAlgoCode(m_hash_algo));
1491             buf.pushBack(SignatureAlgorithms.sigAlgoCode(m_sig_algo));
1492         }
1493         
1494         const ushort sig_len = cast(ushort) m_signature.length;
1495         buf.pushBack(get_byte(0, sig_len));
1496         buf.pushBack(get_byte(1, sig_len));
1497         buf ~= m_signature[];
1498         
1499         return buf.move();
1500     }
1501 
1502 private:
1503     string m_sig_algo; // sig algo used to create signature
1504     string m_hash_algo; // hash used to create signature
1505     Vector!ubyte m_signature;
1506 }
1507 
1508 /**
1509 * Finished Message
1510 */
1511 final class Finished : HandshakeMessage
1512 {
1513 public:
1514     override const(HandshakeType) type() const { return FINISHED; }
1515 
1516     ref const(Vector!ubyte) verifyData() const
1517     { return m_verification_data; }
1518 
1519 	const(ubyte[]) verifyDataBytes() const { return m_verification_data[]; }
1520 
1521     /*
1522     * Verify a Finished message
1523     */
1524     bool verify(in HandshakeState state, ConnectionSide side) const
1525     {
1526         return (m_verification_data == finishedComputeVerify(state, side));
1527     }
1528 
1529     /*
1530     * Create a new Finished message
1531     */
1532     this(HandshakeIO io,
1533          HandshakeState state,
1534          ConnectionSide side)
1535     {
1536         m_verification_data = finishedComputeVerify(state, side);
1537         state.hash().update(io.send(this));
1538     }
1539 
1540     /*
1541     * Deserialize a Finished message
1542     */
1543     this(Vector!ubyte buf)
1544     {
1545         m_verification_data = buf.move();
1546     }
1547 
1548 protected:
1549     /*
1550     * Serialize a Finished message
1551     */
1552     override Vector!ubyte serialize() const
1553     {
1554         return m_verification_data.dup;
1555     }
1556    
1557 private:
1558     Vector!ubyte m_verification_data;
1559 }
1560 
1561 /**
1562 * Hello Request Message
1563 */
1564 final class HelloRequest : HandshakeMessage
1565 {
1566 public:
1567     override const(HandshakeType) type() const { return HELLO_REQUEST; }
1568 
1569     /*
1570     * Create a new Hello Request message
1571     */
1572     this(HandshakeIO io)
1573     {
1574         io.send(this);
1575     }
1576 
1577     /*
1578     * Deserialize a Hello Request message
1579     */
1580     this(const ref Vector!ubyte buf)
1581     {
1582         if (buf.length)
1583             throw new DecodingError("Bad HelloRequest, has non-zero size");
1584     }
1585 
1586 protected:
1587     /*
1588     * Serialize a Hello Request message
1589     */
1590     override Vector!ubyte serialize() const
1591     {
1592         return Vector!ubyte();
1593     }
1594 }
1595 
1596 /**
1597 * TLSServer Key Exchange Message
1598 */
1599 final class ServerKeyExchange : HandshakeMessage
1600 {
1601 public:
1602     override const(HandshakeType) type() const { return SERVER_KEX; }
1603 
1604     ref const(Vector!ubyte) params() const { return m_params; }
1605 
1606     /**
1607     * Verify a TLSServer Key Exchange message
1608     */
1609     bool verify(in PublicKey server_key,
1610                 const HandshakeState state) const
1611     {
1612         Pair!(string, SignatureFormat) format = state.understandSigFormat(server_key, m_hash_algo, m_sig_algo, false);
1613 
1614         PKVerifier verifier = PKVerifier(server_key, format.first, format.second);
1615         verifier.update(state.clientHello().random());
1616         verifier.update(state.serverHello().random());
1617         verifier.update(params());
1618         return verifier.checkSignature(m_signature);
1619     }
1620 
1621     // Only valid for certain kex types
1622     const(PrivateKey) serverKexKey() const
1623     {
1624         assert(m_kex_key, "PrivateKey cannot be null");
1625         return *m_kex_key;
1626     }
1627 
1628 	static if (BOTAN_HAS_SRP6) {
1629 	    // Only valid for SRP negotiation
1630 	    const(SRP6ServerSession) serverSrpParams() const
1631 	    {
1632 	        assert(m_srp_params, "SRP6ServerSession cannot be null");
1633 	        return *m_srp_params;
1634 	    }
1635 	}
1636 
1637     /**
1638     * Deserialize a TLSServer Key Exchange message
1639     */
1640     this(const ref Vector!ubyte buf,
1641          in string kex_algo,
1642          in string sig_algo,
1643          TLSProtocolVersion _version) 
1644     {
1645         m_kex_key.free();
1646 		static if (BOTAN_HAS_SRP6)
1647 	        m_srp_params.free();
1648         if (buf.length < 6)
1649             throw new DecodingError("ServerKeyExchange: Packet corrupted");
1650         
1651         TLSDataReader reader = TLSDataReader("ServerKeyExchange", buf);
1652         
1653         /*
1654         * We really are just serializing things back to what they were
1655         * before, but unfortunately to know where the signature is we need
1656         * to be able to parse the whole thing anyway.
1657         */
1658         
1659         if (kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
1660         {
1661             const string identity_hint = reader.getString(2, 0, 65535);
1662             appendTlsLengthValue(m_params, identity_hint, 2);
1663         }
1664         
1665         if (kex_algo == "DH" || kex_algo == "DHE_PSK")
1666         {
1667             // 3 bigints, DH p, g, Y
1668             
1669             foreach (size_t i; 0 .. 3)
1670             {
1671                 BigInt v = BigInt.decode(reader.getRange!ubyte(2, 1, 65535));
1672                 appendTlsLengthValue(m_params, BigInt.encode(v), 2);
1673             }
1674         }
1675         else if (kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
1676         {
1677             const ubyte curve_type = reader.get_byte();
1678             
1679             if (curve_type != 3)
1680                 throw new DecodingError("ServerKeyExchange: TLSServer sent non-named ECC curve");
1681             
1682             const ushort curve_id = reader.get_ushort();
1683             
1684             const string name = SupportedEllipticCurves.curveIdToName(curve_id);
1685             
1686             Vector!ubyte ecdh_key = reader.getRange!ubyte(1, 1, 255);
1687             
1688             if (name == "")
1689                 throw new DecodingError("ServerKeyExchange: TLSServer sent unknown named curve " ~
1690                                          to!string(curve_id));
1691             
1692             m_params.pushBack(curve_type);
1693             m_params.pushBack(get_byte(0, curve_id));
1694             m_params.pushBack(get_byte(1, curve_id));
1695             appendTlsLengthValue(m_params, ecdh_key, 1);
1696         }
1697         else if (kex_algo == "SRP_SHA")
1698         {
1699             // 2 bigints (N,g) then salt, then server B
1700             
1701             const BigInt N = BigInt.decode(reader.getRange!ubyte(2, 1, 65535));
1702             const BigInt g = BigInt.decode(reader.getRange!ubyte(2, 1, 65535));
1703             Vector!ubyte salt = reader.getRange!ubyte(1, 1, 255);
1704             const BigInt B = BigInt.decode(reader.getRange!ubyte(2, 1, 65535));
1705             
1706             appendTlsLengthValue(m_params, BigInt.encode(N), 2);
1707             appendTlsLengthValue(m_params, BigInt.encode(g), 2);
1708             appendTlsLengthValue(m_params, salt, 1);
1709             appendTlsLengthValue(m_params, BigInt.encode(B), 2);
1710         }
1711         else if (kex_algo != "PSK")
1712                 throw new DecodingError("ServerKeyExchange: Unsupported kex type " ~ kex_algo);
1713         
1714         if (sig_algo != "")
1715         {
1716             if (_version.supportsNegotiableSignatureAlgorithms())
1717             {
1718                 m_hash_algo = SignatureAlgorithms.hashAlgoName(reader.get_byte());
1719                 m_sig_algo = SignatureAlgorithms.sigAlgoName(reader.get_byte());
1720             }
1721             
1722             m_signature = reader.getRange!ubyte(2, 0, 65535);
1723         }
1724         
1725         reader.assertDone();
1726     }
1727 
1728     /**
1729     * Create a new TLSServer Key Exchange message
1730     */
1731     this(HandshakeIO io,
1732          HandshakeState state,
1733          in TLSPolicy policy,
1734          TLSCredentialsManager creds,
1735          RandomNumberGenerator rng,
1736          in PrivateKey signing_key = null)
1737     {
1738         const string hostname = state.clientHello().sniHostname();
1739         const string kex_algo = state.ciphersuite().kexAlgo();
1740         
1741         if (kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
1742         {
1743             string identity_hint = creds.pskIdentityHint("tls-server", hostname);
1744             
1745             appendTlsLengthValue(m_params, identity_hint, 2);
1746         }
1747         
1748         if (kex_algo == "DH" || kex_algo == "DHE_PSK")
1749         {
1750             auto dh = DHPrivateKey(rng, policy.dhGroup());
1751 
1752             appendTlsLengthValue(m_params, BigInt.encode(dh.getDomain().getP()), 2);
1753             appendTlsLengthValue(m_params, BigInt.encode(dh.getDomain().getG()), 2);
1754             appendTlsLengthValue(m_params, dh.publicValue(), 2);
1755             m_kex_key = dh.release();
1756         }
1757         else if (kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
1758         {
1759             Vector!string curves = state.clientHello().supportedEccCurves();
1760             
1761             if (curves.empty)
1762                 throw new InternalError("TLSClient sent no ECC extension but we negotiated ECDH");
1763             
1764             const string curve_name = policy.chooseCurve(curves.move());
1765             
1766             if (curve_name == "")
1767                 throw new TLSException(TLSAlert.HANDSHAKE_FAILURE, "Could not agree on an ECC curve with the client");
1768 
1769             ECGroup ec_group = ECGroup(curve_name);
1770             
1771             auto ecdh = ECDHPrivateKey(rng, ec_group);
1772             
1773             const string ecdh_domain_oid = ecdh.domain().getOid();
1774             const string domain = OIDS.lookup(OID(ecdh_domain_oid));
1775             
1776             if (domain == "")
1777                 throw new InternalError("Could not find name of ECDH domain " ~ ecdh_domain_oid);
1778             
1779             const ushort named_curve_id = SupportedEllipticCurves.nameToCurveId(domain);
1780             
1781             m_params.pushBack(3); // named curve
1782             m_params.pushBack(get_byte(0, named_curve_id));
1783             m_params.pushBack(get_byte(1, named_curve_id));
1784             
1785             appendTlsLengthValue(m_params, ecdh.publicValue(), 1);
1786             
1787             m_kex_key = ecdh.release();
1788         }
1789         else if (kex_algo == "SRP_SHA")
1790         {
1791 			static if (BOTAN_HAS_SRP6) {
1792 	            const string srp_identifier = state.clientHello().srpIdentifier();
1793 	            
1794 	            string group_id;
1795 	            BigInt v;
1796 	            Vector!ubyte salt;
1797 	            
1798 	            const bool found = creds.srpVerifier("tls-server", hostname,
1799 	                                                  srp_identifier,
1800 	                                                  group_id, v, salt,
1801 	                                                  policy.hideUnknownUsers());
1802 	            
1803 	            if (!found)
1804 	                throw new TLSException(TLSAlert.UNKNOWN_PSK_IDENTITY, "Unknown SRP user " ~ srp_identifier);
1805 	            
1806 	            m_srp_params = new SRP6ServerSession;
1807 	            
1808 	            const BigInt* B = &m_srp_params.step1(v, group_id, "SHA-1", rng);
1809 	            
1810 	            DLGroup group = DLGroup(group_id);
1811 
1812 	            appendTlsLengthValue(m_params, BigInt.encode(group.getP()), 2);
1813 	            appendTlsLengthValue(m_params, BigInt.encode(group.getG()), 2);
1814 	            appendTlsLengthValue(m_params, salt, 1);
1815 	            appendTlsLengthValue(m_params, BigInt.encode(*B), 2);
1816 			} else {
1817 				throw new InternalError("ServerKeyExchange: Unknown kex type " ~ kex_algo);
1818 			}
1819         }
1820         else if (kex_algo != "PSK")
1821             throw new InternalError("ServerKeyExchange: Unknown kex type " ~ kex_algo);
1822         
1823         if (state.ciphersuite().sigAlgo() != "")
1824         {
1825             assert(signing_key, "Signing key was set");
1826             
1827             Pair!(string, SignatureFormat) format = state.chooseSigFormat(signing_key, m_hash_algo, m_sig_algo, false, policy);
1828             
1829             PKSigner signer = PKSigner(signing_key, format.first, format.second);
1830             
1831             signer.update(state.clientHello().random());
1832             signer.update(state.serverHello().random());
1833             signer.update(params());
1834             m_signature = signer.signature(rng);
1835         }
1836         
1837         state.hash().update(io.send(this));
1838     }
1839 
1840 protected:
1841     /**
1842     * Serialize a TLSServer Key Exchange message
1843     */
1844     override Vector!ubyte serialize() const
1845     {
1846         Vector!ubyte buf = params().dup;
1847         
1848         if (m_signature.length)
1849         {
1850             // This should be an explicit version check
1851             if (m_hash_algo != "" && m_sig_algo != "")
1852             {
1853                 buf.pushBack(SignatureAlgorithms.hashAlgoCode(m_hash_algo));
1854                 buf.pushBack(SignatureAlgorithms.sigAlgoCode(m_sig_algo));
1855             }
1856             
1857             appendTlsLengthValue(buf, m_signature, 2);
1858         }
1859         
1860         return buf.move();
1861     }
1862 
1863 private:
1864     Unique!PrivateKey m_kex_key;
1865 	static if (BOTAN_HAS_SRP6)
1866 	    Unique!SRP6ServerSession m_srp_params;
1867 
1868     Vector!ubyte m_params;
1869 
1870     string m_sig_algo; // sig algo used to create signature
1871     string m_hash_algo; // hash used to create signature
1872     Vector!ubyte m_signature;
1873 }
1874 
1875 /**
1876 * TLSServer Hello Done Message
1877 */
1878 final class ServerHelloDone : HandshakeMessage
1879 {
1880 public:
1881     override const(HandshakeType) type() const { return SERVER_HELLO_DONE; }
1882 
1883     /*
1884     * Create a new TLSServer Hello Done message
1885     */
1886     this(HandshakeIO io, ref HandshakeHash hash)
1887     {
1888         hash.update(io.send(this));
1889     }
1890 
1891     /*
1892     * Deserialize a TLSServer Hello Done message
1893     */
1894     this(const ref Vector!ubyte buf)
1895     {
1896         if (buf.length)
1897             throw new DecodingError("ServerHello_Done: Must be empty, and is not");
1898     }
1899 protected:
1900     /*
1901     * Serialize a TLSServer Hello Done message
1902     */
1903     override Vector!ubyte serialize() const
1904     {
1905         return Vector!ubyte();
1906     }
1907 }
1908 
1909 /**
1910  * New EncryptedExtensions Message used mainly for ChannelIDExtension
1911  */
1912 final class ChannelID : HandshakeMessage
1913 {
1914     override const(HandshakeType) type() const { return CHANNEL_ID; }
1915 
1916     this(HandshakeIO io, 
1917          ref HandshakeHash hash,
1918          TLSCredentialsManager creds, 
1919          string hostname, 
1920          SecureVector!ubyte hs_hash,
1921          SecureVector!ubyte orig_hs_hash = SecureVector!ubyte())
1922     {
1923         m_channel_id = new EncryptedChannelID(creds.channelPrivateKey(hostname), hs_hash.move(), orig_hs_hash.move());
1924         hash.update(io.send(this));
1925     }
1926 
1927     override Vector!ubyte serialize() const
1928     {
1929         Vector!ubyte buf;
1930         buf.reserve(130);
1931 
1932         const ushort extn_code = m_channel_id.type();
1933         const Vector!ubyte extn_val = m_channel_id.serialize();
1934         
1935         buf.pushBack(get_byte(0, extn_code));
1936         buf.pushBack(get_byte(1, extn_code));
1937         
1938         buf.pushBack(get_byte(0, cast(ushort) extn_val.length));
1939         buf.pushBack(get_byte(1, cast(ushort) extn_val.length));
1940         
1941         buf ~= extn_val[];
1942         return buf.move();
1943     }
1944 
1945 private:
1946     Unique!EncryptedChannelID m_channel_id;
1947 }
1948 
1949 /**
1950 * New TLS Session Ticket Message
1951 */
1952 final class NewSessionTicket : HandshakeMessage
1953 {
1954 public:
1955     override const(HandshakeType) type() const { return NEW_SESSION_TICKET; }
1956 
1957     const(Duration) ticketLifetimeHint() const { return m_ticket_lifetime_hint; }
1958     ref const(Vector!ubyte) ticket() const { return m_ticket; }
1959 
1960     this(HandshakeIO io,
1961          ref HandshakeHash hash,
1962          Vector!ubyte ticket,
1963          Duration lifetime) 
1964         
1965     {   
1966         m_ticket_lifetime_hint = lifetime;
1967         m_ticket = ticket.move();
1968         hash.update = io.send(this);
1969     }
1970 
1971     this(const ref Vector!ubyte buf)
1972     {
1973         if (buf.length < 6)
1974             throw new DecodingError("TLSSession ticket message too short to be valid");
1975         
1976         TLSDataReader reader = TLSDataReader("SessionTicket", buf);
1977         
1978         m_ticket_lifetime_hint = reader.get_uint().seconds;
1979         m_ticket = reader.getRange!ubyte(2, 0, 65535);
1980     }
1981 
1982     this(HandshakeIO io, ref HandshakeHash hash)
1983     {
1984         hash.update(io.send(this));
1985     }
1986 
1987 protected:
1988     override Vector!ubyte serialize() const
1989     {
1990         Vector!ubyte buf = Vector!ubyte(4);
1991         storeBigEndian(m_ticket_lifetime_hint.total!"seconds", buf.ptr);
1992         appendTlsLengthValue(buf, m_ticket, 2);
1993         return buf.move();
1994     }
1995 
1996 private:
1997     Duration m_ticket_lifetime_hint;
1998     Vector!ubyte m_ticket;
1999 }
2000 
2001 /**
2002 * Change Cipher Spec
2003 */
2004 final class ChangeCipherSpec : HandshakeMessage
2005 {
2006 public:
2007     override const(HandshakeType) type() const { return HANDSHAKE_CCS; }
2008 
2009     override Vector!ubyte serialize() const
2010     { return Vector!ubyte(cast(ubyte[])[1]); }
2011 }
2012 
2013 
2014 package:
2015 
2016 string certTypeCodeToName(ubyte code)
2017 {
2018     switch(code)
2019     {
2020         case 1:
2021             return "RSA";
2022         case 2:
2023             return "DSA";
2024         case 64:
2025             return "ECDSA";
2026         default:
2027             return ""; // DH or something else
2028     }
2029 }
2030 
2031 ubyte certTypeNameToCode(in string name)
2032 {
2033     if (name == "RSA")
2034         return 1;
2035     if (name == "DSA")
2036         return 2;
2037     if (name == "ECDSA")
2038         return 64;
2039     
2040     throw new InvalidArgument("Unknown cert type " ~ name);
2041 }
2042 
2043 
2044 SecureVector!ubyte stripLeadingZeros()(auto const ref SecureVector!ubyte input)
2045 {
2046     size_t leading_zeros = 0;
2047     
2048     for (size_t i = 0; i != input.length; ++i)
2049     {
2050         if (input[i] != 0)
2051             break;
2052         ++leading_zeros;
2053     }
2054     
2055     SecureVector!ubyte output = SecureVector!ubyte(input.ptr[leading_zeros .. input.length]);
2056     return output;
2057 }
2058 
2059 
2060 /*
2061 * Compute the verifyData
2062 */
2063 Vector!ubyte finishedComputeVerify(in HandshakeState state, ConnectionSide side)
2064 {
2065     __gshared immutable const(ubyte)[] TLS_CLIENT_LABEL = [
2066         0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x69,
2067         0x73, 0x68, 0x65, 0x64 ];
2068     
2069     __gshared immutable const(ubyte)[] TLS_SERVER_LABEL = [
2070         0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x66, 0x69, 0x6E, 0x69,
2071         0x73, 0x68, 0x65, 0x64 ];
2072     
2073     Unique!KDF prf = state.protocolSpecificPrf();
2074     
2075     Vector!ubyte input;
2076 	input.reserve(64);
2077     if (side == CLIENT)
2078         input ~= cast(ubyte[])TLS_CLIENT_LABEL;
2079     else
2080         input ~= cast(ubyte[])TLS_SERVER_LABEL;
2081     
2082     auto vec = state.hash().flushInto(state.Version(), state.ciphersuite().prfAlgo());
2083 	input ~= vec[];
2084 	return unlock(prf.deriveKey(12, state.sessionKeys().masterSecret(), input));
2085 
2086 }
2087 
2088 Vector!ubyte makeHelloRandom(RandomNumberGenerator rng, in TLSPolicy policy)
2089 {
2090     Vector!ubyte buf = Vector!ubyte(32);
2091     rng.randomize(&buf[0], buf.length);
2092 
2093     if (policy.includeTimeInHelloRandom())
2094     {
2095         const uint time32 = cast(uint)(Clock.currTime(UTC()).toUnixTime);
2096         storeBigEndian(time32, buf.ptr);
2097     }
2098 
2099     return buf;
2100 }