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