1 /**
2 * TLS Server
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.server;
12 
13 import botan.constants;
14 static if (BOTAN_HAS_TLS):
15 
16 public import botan.tls.channel;
17 import botan.tls.credentials_manager;
18 import botan.tls.handshake_state;
19 import botan.tls.messages;
20 import botan.tls.alert;
21 import botan.rng.rng;
22 import memutils.dictionarylist;
23 import memutils.hashmap;
24 import botan.utils.types;
25 import std.datetime;
26 
27 alias NextProtocolHandler = string delegate(in Vector!string);
28 alias SNIHandler = SNIContextSwitchInfo delegate(string);
29 
30 struct SNIContextSwitchInfo
31 {
32 	TLSSessionManager session_manager;
33 	TLSCredentialsManager credentials;
34 	TLSPolicy policy;
35 	NextProtocolHandler next_proto;
36 	void* user_data;
37 }
38 
39 
40 /**
41 * TLS Server
42 */
43 final class TLSServer : TLSChannel
44 {
45 public:
46 
47     /**
48     * TLSServer initialization
49     */
50     this(DataWriter output_fn,
51          OnClearData data_cb,
52          OnAlert alert_cb,
53          OnHandshakeComplete handshake_cb,
54          TLSSessionManager session_manager,
55          TLSCredentialsManager creds,
56          TLSPolicy policy,
57          RandomNumberGenerator rng,
58          NextProtocolHandler next_proto = null,
59 		 SNIHandler sni_handler = null,
60          bool is_datagram = false,
61          size_t io_buf_sz = 16*1024) 
62     {
63         super(output_fn, data_cb, alert_cb, handshake_cb, session_manager, rng, is_datagram, io_buf_sz);
64 		m_policy = policy;
65         m_creds = creds;
66         m_choose_next_protocol = next_proto;
67 		m_sni_handler = sni_handler;
68     }
69 
70 	void* getUserData() { return m_user_data; }
71 
72 protected:
73     override Vector!X509Certificate getPeerCertChain(in HandshakeState state) const
74     {
75         if (state.clientCerts())
76             return state.clientCerts().certChain().dup();
77         return Vector!X509Certificate();
78     }
79 
80     /*
81     * Send a hello request to the client
82     */
83     override void initiateHandshake(HandshakeState state, bool force_full_renegotiation)
84     {
85         (cast(ServerHandshakeState)state).allow_session_resumption = !force_full_renegotiation;
86         
87         auto hello_req = scoped!HelloRequest(state.handshakeIo());
88     }
89 
90     /*
91     * Process a handshake message
92     */
93     override void processHandshakeMsg(in HandshakeState active_state,
94                                       HandshakeState state_base,
95                                       HandshakeType type,
96                                       const ref Vector!ubyte contents)
97     {
98         ServerHandshakeState state = cast(ServerHandshakeState)(state_base);
99         
100         state.confirmTransitionTo(type);
101         
102         /*
103         * The change cipher spec message isn't technically a handshake
104         * message so it's not included in the hash. The finished and
105         * certificate verify messages are verified based on the current
106         * state of the hash *before* this message so we delay adding them
107         * to the hash computation until we've processed them below.
108         */
109         if (type != HANDSHAKE_CCS && type != FINISHED && type != CERTIFICATE_VERIFY)
110         {
111             if (type == CLIENT_HELLO_SSLV2)
112                 state.hash().update(contents);
113             else
114                 state.hash().update(state.handshakeIo().format(contents, type));
115         }
116         
117         if (type == CLIENT_HELLO || type == CLIENT_HELLO_SSLV2)
118         {
119             const bool initial_handshake = !active_state;
120             
121             if (!m_policy.allowInsecureRenegotiation() &&
122                 !(initial_handshake || secureRenegotiationSupported()))
123             {
124                 sendWarningAlert(TLSAlert.NO_RENEGOTIATION);
125                 return;
126             }
127             state.clientHello(new ClientHello(contents, type));
128 
129 			// choose a proper context depending on hostname and register the userdata
130 			if (m_sni_handler) {
131 				const string sni_hostname = state.clientHello().sniHostname();
132 				SNIContextSwitchInfo ctx = m_sni_handler(sni_hostname);
133 				if (ctx !is SNIContextSwitchInfo.init)
134 					switchContext(ctx);
135 			}
136 
137             const TLSProtocolVersion client_version = state.clientHello().Version();
138             
139             TLSProtocolVersion negotiated_version;
140 
141             const TLSProtocolVersion latest_supported = m_policy.latestSupportedVersion(client_version.isDatagramProtocol());
142 
143             if ((initial_handshake && client_version.knownVersion()) ||
144                 (!initial_handshake && client_version == active_state.Version()))
145             {
146                 /*
147                 Common cases: new client hello with some known version, or a
148                 renegotiation using the same version as previously
149                 negotiated.
150                 */
151                 
152                 negotiated_version = client_version;
153             }
154             else if (!initial_handshake && (client_version != active_state.Version()))
155             {
156                 /*
157                 * If this is a renegotiation, and the client has offered a
158                 * later version than what it initially negotiated, negotiate
159                 * the old version. This matches OpenSSL's behavior. If the
160                 * client is offering a version earlier than what it initially
161                 * negotiated, reject as a probable attack.
162                 */
163                 if (active_state.Version() > client_version)
164                 {
165                     throw new TLSException(TLSAlert.PROTOCOL_VERSION,
166                                             "TLSClient negotiated " ~
167                                             active_state.Version().toString() ~
168                                             " then renegotiated with " ~
169                                             client_version.toString());
170                 }
171                 else
172                     negotiated_version = active_state.Version();
173             }
174             else
175             {
176                 /*
177                 New negotiation using a version we don't know. Offer
178                 them the best we currently know and support.
179                 */
180                 negotiated_version = latest_supported;
181             }
182             
183             if (!m_policy.acceptableProtocolVersion(negotiated_version))
184             {
185                 throw new TLSException(TLSAlert.PROTOCOL_VERSION, "Client version " ~ negotiated_version.toString() ~ " is unacceptable by policy");
186             }
187 
188             if (state.clientHello().sentFallbackSCSV())
189             {
190                 if (latest_supported > client_version)
191                     throw new TLSException(TLSAlert.INAPPROPRIATE_FALLBACK, "Client signalled fallback SCSV, possible attack");
192             }
193 
194             secureRenegotiationCheck(state.clientHello());
195             
196             state.setVersion(negotiated_version);
197 
198             TLSSession session_info;
199 			scope(exit) destroy(session_info);
200             const bool resuming = state.allow_session_resumption &&
201                                     checkForResume(session_info,
202                                                    sessionManager(),
203                                                    m_creds,
204                                                    state.clientHello(),
205                                                    m_policy.sessionTicketLifetime());
206             
207             bool have_session_ticket_key = false;
208             
209             try
210             {
211                 have_session_ticket_key = m_creds.psk("tls-server", "session-ticket", "").length > 0;
212             }
213             catch (Exception) {}
214 
215             m_application_protocol = "";
216 
217             if (m_choose_next_protocol && state.clientHello().supportsAlpn())
218                 m_application_protocol = m_choose_next_protocol(state.clientHello().nextProtocols());
219 
220             if (resuming)
221             {
222                 // resume session
223                 
224                 const bool offer_new_session_ticket = (state.clientHello().supportsSessionTicket() &&
225                                                         state.clientHello().sessionTicket().empty &&
226                                                         have_session_ticket_key);
227                 
228                 state.serverHello(new ServerHello(state.handshakeIo(),
229                                                   state.hash(),
230                                                   m_policy,
231                                                   state.clientHello().sessionId().dup,
232                                                   session_info.Version(),
233                                                   session_info.ciphersuiteCode(),
234                                                   session_info.compressionMethod(),
235                                                   session_info.fragmentSize(),
236                                                   state.clientHello().secureRenegotiation(),
237                                                   secureRenegotiationDataForServerHello(),
238                                                   offer_new_session_ticket,
239                                                   state.clientHello().supportsAlpn(),
240                                                   m_application_protocol,
241                                                   state.clientHello().supportsHeartbeats(),
242                                                   rng()));
243                 
244                 secureRenegotiationCheck(state.serverHello());
245                 
246                 state.computeSessionKeys(session_info.masterSecret().dup);
247                 
248                 if (!saveSession(session_info))
249                 {
250                     auto entry = &session_info.sessionId();
251                     sessionManager().removeEntry(*entry);
252                     
253                     if (state.serverHello().supportsSessionTicket()) // send an empty ticket
254                     {
255                         state.newSessionTicket(new NewSessionTicket(state.handshakeIo(), state.hash()));
256                     }
257                 }
258                 
259                 if (state.serverHello().supportsSessionTicket() && !state.newSessionTicket())
260                 {
261                     try
262                     {
263                         const SymmetricKey ticket_key = m_creds.psk("tls-server", "session-ticket", "");
264                         
265                         state.newSessionTicket(new NewSessionTicket(state.handshakeIo(),
266                                                                         state.hash(),
267                                                                         session_info.encrypt(ticket_key, rng()),
268                                                                         m_policy.sessionTicketLifetime()));
269                     }
270                     catch (Exception) {}
271                     
272                     if (!state.newSessionTicket())
273                     {
274                         state.newSessionTicket(new NewSessionTicket(state.handshakeIo(), state.hash()));
275                     }
276                 }
277                 
278                 state.handshakeIo().send(scoped!ChangeCipherSpec());
279                 
280                 changeCipherSpecWriter(SERVER);
281                 
282                 state.serverFinished(new Finished(state.handshakeIo(), state, SERVER));
283                 
284                 state.setExpectedNext(HANDSHAKE_CCS);
285             }
286             else // new session
287             {
288                 HashMapRef!(string, Array!X509Certificate) cert_chains;
289                 
290                 const string sni_hostname = state.clientHello().sniHostname();
291                 
292                 cert_chains = getServerCerts(sni_hostname, m_creds);
293                 
294                 if (sni_hostname != "" && cert_chains.length == 0)
295                 {
296                     cert_chains = getServerCerts("", m_creds);
297                         
298                     /*
299                     * Only send the unrecognized_name alert if we couldn't
300                     * find any certs for the requested name but did find at
301                     * least one cert to use in general. That avoids sending an
302                     * unrecognized_name when a server is configured for purely
303                     * anonymous operation.
304                     */
305                     if (cert_chains.length != 0)
306                         sendAlert(TLSAlert(TLSAlert.UNRECOGNIZED_NAME));
307                 }
308                 state.serverHello(
309                     new ServerHello(    state.handshakeIo(),
310                                         state.hash(),
311                                         m_policy,
312                                         makeHelloRandom(rng(), m_policy), // new session ID
313                                         state.Version(),
314                                         chooseCiphersuite(m_policy, state.Version(), m_creds, cert_chains, state.clientHello()),
315                                         chooseCompression(m_policy, state.clientHello().compressionMethods()),
316                                         state.clientHello().fragmentSize(),
317                                         state.clientHello().secureRenegotiation(),
318                                         secureRenegotiationDataForServerHello(),
319                                         state.clientHello().supportsSessionTicket() && have_session_ticket_key,
320                                         state.clientHello().supportsAlpn(),
321                                         m_application_protocol,
322                                         state.clientHello().supportsHeartbeats(),
323                                         rng()
324                     )
325                 );
326                 
327                 secureRenegotiationCheck(state.serverHello());
328                 
329                 const string sig_algo = state.ciphersuite().sigAlgo();
330                 const string kex_algo = state.ciphersuite().kexAlgo();
331                 
332                 if (sig_algo != "")
333                 {
334                     assert(!cert_chains[sig_algo].empty,
335                     "Attempting to send empty certificate chain");
336                     
337                     state.serverCerts(new Certificate(state.handshakeIo(), state.hash(), cert_chains[sig_algo])
338                     );
339                 }
340                 
341                 PrivateKey priv_key = null;
342                 
343                 if (kex_algo == "RSA" || sig_algo != "")
344                 {
345                     priv_key = m_creds.privateKeyFor(state.serverCerts().certChain()[0],
346                                                      "tls-server",
347                                                      sni_hostname );
348                     
349                     if (!priv_key)
350                         throw new InternalError("No private key located for associated server cert");
351                 }
352                 
353                 if (kex_algo == "RSA")
354                 {
355                     state.server_rsa_kex_key = priv_key;
356                 }
357                 else
358                 {
359                     state.serverKex(
360                         new ServerKeyExchange(state.handshakeIo(),
361                                                 state,
362                                                 m_policy,
363                                                 m_creds,
364                                                 rng(),
365                                                 priv_key)
366                         );
367                 }
368                 
369                 auto trusted_CAs = m_creds.trustedCertificateAuthorities("tls-server", sni_hostname);
370                 
371                 Vector!X509DN client_auth_CAs;
372                 
373                 foreach (store; trusted_CAs[])
374                 {
375                     auto subjects = store.allSubjects();
376                     client_auth_CAs ~= subjects[];
377                 }
378                 
379                 if (!client_auth_CAs.empty && state.ciphersuite().sigAlgo() != "")
380                 {
381                     state.certReq(new CertificateReq(state.handshakeIo(), state.hash(), m_policy,
382                                                      client_auth_CAs.move(), state.Version()));
383                     
384                     state.setExpectedNext(CERTIFICATE);
385                 }
386                 
387                 /*
388                 * If the client doesn't have a cert they want to use they are
389                 * allowed to send either an empty cert message or proceed
390                 * directly to the client key exchange, so allow either case.
391                 */
392                 state.setExpectedNext(CLIENT_KEX);
393                 
394                 state.serverHelloDone(new ServerHelloDone(state.handshakeIo(), state.hash()));
395             }
396         }
397         else if (type == CERTIFICATE)
398         {
399             state.clientCerts(new Certificate(contents));
400             
401             state.setExpectedNext(CLIENT_KEX);
402         }
403         else if (type == CLIENT_KEX)
404         {
405             if (state.receivedHandshakeMsg(CERTIFICATE) && !state.clientCerts().empty)
406                 state.setExpectedNext(CERTIFICATE_VERIFY);
407             else
408                 state.setExpectedNext(HANDSHAKE_CCS);
409             
410             state.clientKex(
411                 new ClientKeyExchange(contents, state, state.server_rsa_kex_key, m_creds, m_policy, rng())
412             );
413             
414             state.computeSessionKeys();
415         }
416         else if (type == CERTIFICATE_VERIFY)
417         {
418             state.clientVerify(new CertificateVerify(contents, state.Version()));
419             
420             const(Vector!X509Certificate)* client_certs = &state.clientCerts().certChain();
421             
422             const bool sig_valid = state.clientVerify().verify((*client_certs)[0], state);
423             
424             state.hash().update(state.handshakeIo().format(contents, type));
425             
426             /*
427             * Using DECRYPT_ERROR looks weird here, but per RFC 4346 is for
428             * "A handshake cryptographic operation failed, including being
429             * unable to correctly verify a signature, ..."
430             */
431             if (!sig_valid)
432                 throw new TLSException(TLSAlert.DECRYPT_ERROR, "TLSClient cert verify failed");
433             
434             try
435             {
436                 m_creds.verifyCertificateChain("tls-server", "", *client_certs);
437             }
438             catch(Exception e)
439             {
440                 throw new TLSException(TLSAlert.BAD_CERTIFICATE, e.msg);
441             }
442             
443             state.setExpectedNext(HANDSHAKE_CCS);
444         }
445         else if (type == HANDSHAKE_CCS)
446         {
447             state.setExpectedNext(FINISHED);
448             changeCipherSpecReader(SERVER);
449             
450         }
451         else if (type == FINISHED)
452         {
453             state.setExpectedNext(HANDSHAKE_NONE);
454             
455             state.clientFinished(new Finished(contents.dup));
456             
457             if (!state.clientFinished().verify(state, CLIENT))
458                 throw new TLSException(TLSAlert.DECRYPT_ERROR, "Finished message didn't verify");
459             
460             if (!state.serverFinished())
461             {
462                 // already sent finished if resuming, so this is a new session
463                 
464                 state.hash().update(state.handshakeIo().format(contents, type));
465                 
466                 auto session_info =   new TLSSession(state.serverHello().sessionId().dup,
467                                                      state.sessionKeys().masterSecret().dup,
468                                                      state.serverHello().Version(),
469                                                      state.serverHello().ciphersuite(),
470                                                      state.serverHello().compressionMethod(),
471                                                      SERVER,
472                                                      state.serverHello().fragmentSize(),
473                                                      getPeerCertChain(state),
474                                                      Vector!ubyte(),
475                                                      TLSServerInformation(state.clientHello().sniHostname()),
476                                                      state.srpIdentifier()
477                     );
478                 
479                 if (saveSession(session_info))
480                 {
481                     if (state.serverHello().supportsSessionTicket())
482                     {
483                         try
484                         {
485                             const SymmetricKey ticket_key = m_creds.psk("tls-server", "session-ticket", "");
486                             
487                             state.newSessionTicket(
488                                 new NewSessionTicket(state.handshakeIo(),
489                                                      state.hash(),
490                                                      session_info.encrypt(ticket_key, rng()),
491                                                      m_policy.sessionTicketLifetime())
492                                 );
493                         }
494                         catch (Exception) {}
495                     }
496                     else
497                         sessionManager().save(session_info);
498                 }
499                 
500                 if (!state.newSessionTicket() && state.serverHello().supportsSessionTicket())
501                 {
502                     state.newSessionTicket(new NewSessionTicket(state.handshakeIo(), state.hash()));
503                 }
504                 
505                 state.handshakeIo().send(scoped!ChangeCipherSpec());
506                 
507                 changeCipherSpecWriter(SERVER);
508                 
509                 state.serverFinished(new Finished(state.handshakeIo(), state, SERVER));
510             }
511             activateSession();
512         }
513         else
514             throw new TLSUnexpectedMessage("Unknown handshake message received");
515     }
516 
517     override HandshakeState newHandshakeState(HandshakeIO io)
518     {
519         HandshakeState state = new ServerHandshakeState(io);
520         state.setExpectedNext(CLIENT_HELLO);
521         return state;
522     }
523 
524 	void switchContext(SNIContextSwitchInfo info)
525 	{
526 		m_creds = info.credentials;
527 		m_session_manager = info.session_manager;
528 		m_policy = info.policy;
529 		m_choose_next_protocol = info.next_proto;
530 		m_user_data = info.user_data;
531 	}
532 
533 private:
534     TLSPolicy m_policy;
535     TLSCredentialsManager m_creds;
536 
537     NextProtocolHandler m_choose_next_protocol;
538 	SNIHandler m_sni_handler;
539 	void* m_user_data;
540 }
541 
542 private:
543 
544 bool checkForResume(ref TLSSession session_info,
545                     TLSSessionManager session_manager,
546                     TLSCredentialsManager credentials,
547                     in ClientHello clientHello,
548                     Duration session_ticket_lifetime)
549 {
550     const(Vector!ubyte)* client_session_id = &clientHello.sessionId();
551     const Vector!ubyte session_ticket = clientHello.sessionTicket();
552     
553     if (session_ticket.empty)
554     {
555         if (client_session_id.empty) // not resuming
556             return false;
557         
558         // not found
559         if (!session_manager.loadFromSessionId(*client_session_id, session_info))
560             return false;
561     }
562     else
563     {
564         // If a session ticket was sent, ignore client session ID
565         try
566         {
567             session_info = TLSSession.decrypt(session_ticket,
568             credentials.psk("tls-server", "session-ticket", ""));
569             
570             if (session_ticket_lifetime != Duration.init &&
571                 session_info.sessionAge() > session_ticket_lifetime)
572                 return false; // ticket has expired
573         }
574         catch (Exception)
575         {
576             return false;
577         }
578     }
579     
580 	if (!session_info) 
581 		return false;
582 
583     // wrong version
584     if (clientHello.Version() != session_info.Version())
585         return false;
586     
587     // client didn't send original ciphersuite
588     if (!valueExists(clientHello.ciphersuites(),
589                       session_info.ciphersuiteCode()))
590         return false;
591     
592     // client didn't send original compression method
593     if (!valueExists(clientHello.compressionMethods(),
594                       session_info.compressionMethod()))
595         return false;
596     
597     // client sent a different SRP identity
598     if (clientHello.srpIdentifier() != "")
599     {
600         if (clientHello.srpIdentifier() != session_info.srpIdentifier())
601             return false;
602     }
603     
604     // client sent a different SNI hostname
605     if (clientHello.sniHostname() != "")
606     {
607         if (clientHello.sniHostname() != session_info.serverInfo().hostname())
608             return false;
609     }
610 
611     return true;
612 }
613 
614 /*
615 * Choose which ciphersuite to use
616 */
617 ushort chooseCiphersuite(in TLSPolicy policy,
618                          TLSProtocolVersion _version,
619                          TLSCredentialsManager creds,
620                          in HashMapRef!(string, Array!X509Certificate) cert_chains,
621                          in ClientHello client_hello)
622 {
623     const bool our_choice = policy.serverUsesOwnCiphersuitePreferences();
624     
625     const bool have_srp = creds.attemptSrp("tls-server", client_hello.sniHostname());
626     
627     const(Vector!ushort)* client_suites = &client_hello.ciphersuites();
628     
629     const Vector!ushort server_suites = policy.ciphersuiteList(_version, have_srp);
630     
631     if (server_suites.empty)
632         throw new TLSException(TLSAlert.HANDSHAKE_FAILURE, "TLSPolicy forbids us from negotiating any ciphersuite");
633     
634     const bool have_shared_ecc_curve = (policy.chooseCurve(client_hello.supportedEccCurves()) != "");
635     
636     Vector!ushort pref_list = server_suites.dup;
637        
638     if (!our_choice)
639         pref_list[] = *client_suites;
640 	debug {
641 		string dbg_msg;
642 		string dbg_sig;
643 	}
644     foreach (suite_id; pref_list[])
645     {
646         if (!valueExists(*client_suites, suite_id))
647             continue;
648         
649         TLSCiphersuite suite = TLSCiphersuite.byId(suite_id);
650         
651         if (!have_shared_ecc_curve && suite.eccCiphersuite())
652             continue;
653         
654         if (suite.sigAlgo() != "" && cert_chains.get(suite.sigAlgo(), Array!X509Certificate(0)) == Array!X509Certificate(0))
655 		{
656 			debug  {
657 				dbg_msg = "Server Certificate type did not match a type that was accepted from policy: ";
658 				dbg_sig = suite.sigAlgo;
659 			}
660             continue;
661 		}
662         /*
663         The client may offer SRP cipher suites in the hello message but
664         omit the SRP extension.  If the server would like to select an
665         SRP cipher suite in this case, the server SHOULD return a fatal
666         "unknown_psk_identity" alert immediately after processing the
667         client hello message.
668          - RFC 5054 section 2.5.1.2
669         */
670         if (suite.kexAlgo() == "SRP_SHA" && client_hello.srpIdentifier() == "")
671             throw new TLSException(TLSAlert.UNKNOWN_PSK_IDENTITY,
672                                     "TLSClient wanted SRP but did not send username");
673         
674         return suite_id;
675     }
676 	debug logDebug(dbg_msg, dbg_sig);
677     throw new TLSException(TLSAlert.HANDSHAKE_FAILURE, "Can't agree on a ciphersuite with client");
678 }
679 
680 /*
681 * Choose which compression algorithm to use
682 */
683 ubyte chooseCompression(in TLSPolicy policy, const ref Vector!ubyte c_comp)
684 {
685     Vector!ubyte s_comp = policy.compression();
686     
687     for (size_t i = 0; i != s_comp.length; ++i)
688         for (size_t j = 0; j != c_comp.length; ++j)
689             if (s_comp[i] == c_comp[j])
690                 return s_comp[i];
691     
692     return NO_COMPRESSION;
693 }
694 
695 HashMapRef!(string, Array!X509Certificate) 
696     getServerCerts(in string hostname, TLSCredentialsManager creds)
697 {
698     string[] cert_types = [ "RSA", "DSA", "ECDSA", null ];
699     
700     HashMapRef!(string, Array!X509Certificate) cert_chains;
701     
702     for (size_t i = 0; cert_types[i]; ++i)
703     {
704         Vector!X509Certificate certs = creds.certChainSingleType(cert_types[i], "tls-server", hostname);
705         
706         if (!certs.empty)
707             cert_chains[cert_types[i]] = certs.dupr;
708     }
709     
710     return cert_chains;
711 }
712 
713 private final class ServerHandshakeState : HandshakeState
714 {
715 public:    
716     this(HandshakeIO io)
717     {
718         super(io);
719     }
720     
721     // Used by the server only, in case of RSA key exchange. Not owned
722     PrivateKey server_rsa_kex_key = null;
723     
724     /*
725     * Used by the server to know if resumption should be allowed on
726     * a server-initiated renegotiation
727     */
728     bool allow_session_resumption = true;
729 }