1 /*
2 * (C) 2014,2015,2018 Jack Lloyd
3 *     2016 Matthias Gierlings
4 *     2017 René Korthaus, Rohde & Schwarz Cybersecurity
5 *     2017 Harry Reimann, Rohde & Schwarz Cybersecurity
6 *
7 * Botan is released under the Simplified BSD License (see license.txt)
8 */
9 
10 #include "tests.h"
11 #include <vector>
12 #include <memory>
13 
14 #if defined(BOTAN_HAS_TLS)
15 
16    #include <botan/tls_client.h>
17    #include <botan/tls_server.h>
18    #include <botan/tls_policy.h>
19    #include <botan/tls_extensions.h>
20    #include <botan/internal/tls_reader.h>
21 
22    #include <botan/ec_group.h>
23    #include <botan/hex.h>
24    #include <botan/oids.h>
25    #include <botan/pkcs10.h>
26    #include <botan/rsa.h>
27    #include <botan/ecdsa.h>
28    #include <botan/x509_ca.h>
29    #include <botan/x509self.h>
30 
31    #if defined(BOTAN_HAS_DSA)
32       #include <botan/dsa.h>
33    #endif
34 
35    #if defined(BOTAN_HAS_SRP6)
36       #include <botan/srp6.h>
37    #endif
38 
39    #if defined(BOTAN_HAS_TLS_SQLITE3_SESSION_MANAGER)
40       #include <botan/tls_session_manager_sqlite.h>
41    #endif
42 
43 #endif
44 
45 namespace Botan_Tests {
46 
47 namespace {
48 
49 #if defined(BOTAN_HAS_TLS)
50 class Credentials_Manager_Test final : public Botan::Credentials_Manager
51    {
52    public:
Credentials_Manager_Test(bool with_client_certs,const Botan::X509_Certificate & rsa_cert,Botan::Private_Key * rsa_key,const Botan::X509_Certificate & rsa_ca,const Botan::X509_CRL & rsa_crl,const Botan::X509_Certificate & ecdsa_cert,Botan::Private_Key * ecdsa_key,const Botan::X509_Certificate & ecdsa_ca,const Botan::X509_CRL & ecdsa_crl,const Botan::X509_Certificate * dsa_cert,Botan::Private_Key * dsa_key,const Botan::X509_Certificate * dsa_ca,Botan::X509_CRL * dsa_crl)53       Credentials_Manager_Test(bool with_client_certs,
54                                const Botan::X509_Certificate& rsa_cert,
55                                Botan::Private_Key* rsa_key,
56                                const Botan::X509_Certificate& rsa_ca,
57                                const Botan::X509_CRL& rsa_crl,
58                                const Botan::X509_Certificate& ecdsa_cert,
59                                Botan::Private_Key* ecdsa_key,
60                                const Botan::X509_Certificate& ecdsa_ca,
61                                const Botan::X509_CRL& ecdsa_crl,
62                                const Botan::X509_Certificate* dsa_cert,
63                                Botan::Private_Key* dsa_key,
64                                const Botan::X509_Certificate* dsa_ca,
65                                Botan::X509_CRL* dsa_crl) :
66          m_rsa_cert(rsa_cert),
67          m_rsa_ca(rsa_ca),
68          m_rsa_key(rsa_key),
69          m_ecdsa_cert(ecdsa_cert),
70          m_ecdsa_ca(ecdsa_ca),
71          m_ecdsa_key(ecdsa_key),
72          m_dsa_cert(dsa_cert),
73          m_dsa_ca(dsa_ca),
74          m_dsa_key(dsa_key),
75          m_dsa_crl(dsa_crl)
76          {
77          std::unique_ptr<Botan::Certificate_Store_In_Memory> store(new Botan::Certificate_Store_In_Memory);
78          store->add_certificate(m_rsa_ca);
79          store->add_certificate(m_ecdsa_ca);
80          store->add_crl(rsa_crl);
81          store->add_crl(ecdsa_crl);
82 
83          if(m_dsa_ca != nullptr)
84             {
85             store->add_certificate(*m_dsa_ca);
86             }
87          if(m_dsa_crl != nullptr)
88             {
89             store->add_crl(*m_dsa_crl);
90             }
91 
92          m_stores.push_back(std::move(store));
93          m_provides_client_certs = with_client_certs;
94          }
95 
96       std::vector<Botan::Certificate_Store*>
trusted_certificate_authorities(const std::string &,const std::string &)97       trusted_certificate_authorities(const std::string&,
98                                       const std::string&) override
99          {
100          std::vector<Botan::Certificate_Store*> v;
101          for(auto const& store : m_stores)
102             {
103             v.push_back(store.get());
104             }
105          return v;
106          }
107 
find_cert_chain(const std::vector<std::string> & cert_key_types,const std::vector<Botan::X509_DN> & acceptable_CAs,const std::string & type,const std::string & context)108       std::vector<Botan::X509_Certificate> find_cert_chain(
109          const std::vector<std::string>& cert_key_types,
110          const std::vector<Botan::X509_DN>& acceptable_CAs,
111          const std::string& type,
112          const std::string& context) override
113          {
114          std::vector<Botan::X509_Certificate> chain;
115 
116          if(m_acceptable_cas.empty())
117             m_acceptable_cas = acceptable_CAs;
118 
119          if(type == "tls-server" || (type == "tls-client" && m_provides_client_certs))
120             {
121             for(auto const& key_type : cert_key_types)
122                {
123                if(key_type == "RSA")
124                   {
125                   chain.push_back(m_rsa_cert);
126                   chain.push_back(m_rsa_ca);
127                   break;
128                   }
129                else if(key_type == "ECDSA")
130                   {
131                   chain.push_back(m_ecdsa_cert);
132                   chain.push_back(m_ecdsa_ca);
133                   break;
134                   }
135 #if defined(BOTAN_HAS_DSA)
136                else if(key_type == "DSA")
137                   {
138                   if(m_dsa_cert == nullptr || m_dsa_ca == nullptr)
139                      {
140                      throw Test_Error("No DSA certificates set for " + type + "/" + context);
141                      }
142                   chain.push_back(*m_dsa_cert);
143                   chain.push_back(*m_dsa_ca);
144                   break;
145                   }
146 #else
147                BOTAN_UNUSED(context);
148 #endif
149                }
150             }
151 
152          return chain;
153          }
154 
private_key_for(const Botan::X509_Certificate & crt,const std::string &,const std::string &)155       Botan::Private_Key* private_key_for(const Botan::X509_Certificate& crt,
156                                           const std::string&,
157                                           const std::string&) override
158          {
159          if(crt == m_rsa_cert)
160             {
161             return m_rsa_key.get();
162             }
163          if(crt == m_ecdsa_cert)
164             {
165             return m_ecdsa_key.get();
166             }
167          if(crt == *m_dsa_cert)
168             {
169             return m_dsa_key.get();
170             }
171          return nullptr;
172          }
173 
psk(const std::string & type,const std::string & context,const std::string &)174       Botan::SymmetricKey psk(const std::string& type,
175                               const std::string& context,
176                               const std::string&) override
177          {
178          if(type == "tls-server" && context == "session-ticket")
179             {
180             return Botan::SymmetricKey("AABBCCDDEEFF012345678012345678");
181             }
182 
183          if(type == "tls-server" && context == "dtls-cookie-secret")
184             {
185             return Botan::SymmetricKey("4AEA5EAD279CADEB537A594DA0E9DE3A");
186             }
187 
188          if(context == "server.example.com" && type == "tls-client")
189             {
190             return Botan::SymmetricKey("20B602D1475F2DF888FCB60D2AE03AFD");
191             }
192 
193          if(context == "server.example.com" && type == "tls-server")
194             {
195             return Botan::SymmetricKey("20B602D1475F2DF888FCB60D2AE03AFD");
196             }
197 
198          throw Test_Error("No PSK set for " + type + "/" + context);
199          }
200 
get_acceptable_cas() const201       const std::vector<Botan::X509_DN>& get_acceptable_cas() const { return m_acceptable_cas; }
202 
203    private:
204       Botan::X509_Certificate m_rsa_cert, m_rsa_ca;
205       std::unique_ptr<Botan::Private_Key> m_rsa_key;
206 
207       Botan::X509_Certificate m_ecdsa_cert, m_ecdsa_ca;
208       std::unique_ptr<Botan::Private_Key> m_ecdsa_key;
209 
210       std::unique_ptr<const Botan::X509_Certificate> m_dsa_cert, m_dsa_ca;
211       std::unique_ptr<Botan::Private_Key> m_dsa_key;
212       std::unique_ptr<Botan::X509_CRL> m_dsa_crl;
213       std::vector<std::unique_ptr<Botan::Certificate_Store>> m_stores;
214       bool m_provides_client_certs;
215       std::vector<Botan::X509_DN> m_acceptable_cas;
216    };
217 
218 Botan::Credentials_Manager*
create_creds(Botan::RandomNumberGenerator & rng,bool with_client_certs=false)219 create_creds(Botan::RandomNumberGenerator& rng,
220              bool with_client_certs = false)
221    {
222    // rsa and ecdsa are required for the tls module
223    const Botan::EC_Group ecdsa_params("secp256r1");
224    const size_t rsa_params = 1024;
225 
226    std::unique_ptr<Botan::Private_Key> rsa_ca_key(new Botan::RSA_PrivateKey(rng, rsa_params));
227    std::unique_ptr<Botan::Private_Key> rsa_srv_key(new Botan::RSA_PrivateKey(rng, rsa_params));
228 
229    std::unique_ptr<Botan::Private_Key> ecdsa_ca_key(new Botan::ECDSA_PrivateKey(rng, ecdsa_params));
230    std::unique_ptr<Botan::Private_Key> ecdsa_srv_key(new Botan::ECDSA_PrivateKey(rng, ecdsa_params));
231 
232    Botan::X509_Cert_Options rsa_ca_opts("RSA Test CA/VT");
233    Botan::X509_Cert_Options ecdsa_ca_opts("ECDSA Test CA/VT");
234    rsa_ca_opts.CA_key(1);
235    ecdsa_ca_opts.CA_key(1);
236 
237    const Botan::X509_Certificate rsa_ca_cert =
238       Botan::X509::create_self_signed_cert(rsa_ca_opts, *rsa_ca_key, "SHA-256", rng);
239    const Botan::X509_Certificate ecdsa_ca_cert =
240       Botan::X509::create_self_signed_cert(ecdsa_ca_opts, *ecdsa_ca_key, "SHA-256", rng);
241 
242    const Botan::X509_Cert_Options server_opts("server.example.com");
243 
244    const Botan::PKCS10_Request rsa_req =
245       Botan::X509::create_cert_req(server_opts, *rsa_srv_key, "SHA-256", rng);
246    const Botan::PKCS10_Request ecdsa_req =
247       Botan::X509::create_cert_req(server_opts, *ecdsa_srv_key, "SHA-256", rng);
248 
249    Botan::X509_CA rsa_ca(rsa_ca_cert, *rsa_ca_key, "SHA-256", rng);
250    Botan::X509_CA ecdsa_ca(ecdsa_ca_cert, *ecdsa_ca_key, "SHA-256", rng);
251 
252    typedef std::chrono::duration<int, std::ratio<31556926>> years;
253    auto now = std::chrono::system_clock::now();
254 
255    const Botan::X509_Time start_time(now);
256    const Botan::X509_Time end_time(now + years(1));
257 
258    const Botan::X509_Certificate rsa_srv_cert =
259       rsa_ca.sign_request(rsa_req, rng, start_time, end_time);
260    const Botan::X509_Certificate ecdsa_srv_cert =
261       ecdsa_ca.sign_request(ecdsa_req, rng, start_time, end_time);
262 
263    Botan::X509_CRL rsa_crl = rsa_ca.new_crl(rng);
264    Botan::X509_CRL ecdsa_crl = ecdsa_ca.new_crl(rng);
265 
266    // dsa support is optional
267    std::unique_ptr<Botan::Private_Key> dsa_ca_key;
268    std::unique_ptr<Botan::Private_Key> dsa_srv_key;
269    std::unique_ptr<Botan::X509_CRL> dsa_crl;
270    std::unique_ptr<Botan::X509_Certificate> dsa_srv_cert;
271    std::unique_ptr<Botan::X509_Certificate> dsa_ca_cert;
272 
273 #if defined(BOTAN_HAS_DSA)
274    const Botan::DL_Group dsa_params("dsa/jce/1024");
275 
276    dsa_ca_key.reset(new Botan::DSA_PrivateKey(rng, dsa_params));
277    dsa_srv_key.reset(new Botan::DSA_PrivateKey(rng, dsa_params));
278 
279    Botan::X509_Cert_Options dsa_ca_opts("DSA Test CA/VT");
280    dsa_ca_opts.CA_key(1);
281 
282    dsa_ca_cert.reset(new Botan::X509_Certificate(
283                         Botan::X509::create_self_signed_cert(dsa_ca_opts, *dsa_ca_key, "SHA-256", rng)));
284 
285    const Botan::PKCS10_Request dsa_req =
286       Botan::X509::create_cert_req(server_opts, *dsa_srv_key, "SHA-256", rng);
287 
288    Botan::X509_CA dsa_ca(*dsa_ca_cert, *dsa_ca_key, "SHA-256", rng);
289    dsa_srv_cert.reset(new Botan::X509_Certificate(
290                          dsa_ca.sign_request(dsa_req, rng, start_time, end_time)));
291 
292    dsa_crl.reset(new Botan::X509_CRL(dsa_ca.new_crl(rng)));
293 #endif
294 
295    Credentials_Manager_Test* cmt = new Credentials_Manager_Test(
296       with_client_certs,
297       rsa_srv_cert, rsa_srv_key.release(), rsa_ca_cert, rsa_crl,
298       ecdsa_srv_cert, ecdsa_srv_key.release(), ecdsa_ca_cert, ecdsa_crl,
299       dsa_srv_cert.release(), dsa_srv_key.release(), dsa_ca_cert.release(), dsa_crl.release());
300 
301    return cmt;
302    }
303 
304 #if defined(BOTAN_HAS_SRP6)
305 Botan::Credentials_Manager*
create_srp6_creds(Botan::RandomNumberGenerator & rng)306 create_srp6_creds(Botan::RandomNumberGenerator& rng)
307    {
308    class Credentials_Manager_SRP6 : public Botan::Credentials_Manager
309       {
310       public:
311          Credentials_Manager_SRP6(Botan::RandomNumberGenerator& rng)
312             {
313             m_group_id = "modp/srp/1024";
314             m_username = "srp6_username";
315             m_password = "srp6_password";
316             m_salt.resize(16);
317             rng.randomize(m_salt.data(), m_salt.size());
318 
319             m_verifier = Botan::generate_srp6_verifier(m_username,
320                                                        m_password,
321                                                        m_salt,
322                                                        m_group_id,
323                                                        "SHA-1");
324             }
325 
326          bool attempt_srp(const std::string& /*type*/,
327                           const std::string& /*context*/) override
328             {
329             return true;
330             }
331 
332          std::string srp_identifier(const std::string& /*type*/,
333                                     const std::string& /*context*/) override
334             {
335             return m_username;
336             }
337 
338          std::string srp_password(const std::string& /*type*/,
339                                   const std::string& /*context*/,
340                                   const std::string& identifier) override
341             {
342             if(identifier == m_username)
343                return m_password;
344             return "";
345             }
346 
347          bool srp_verifier(const std::string& /*type*/,
348                            const std::string& /*context*/,
349                            const std::string& identifier,
350                            std::string& group_name,
351                            Botan::BigInt& verifier,
352                            std::vector<uint8_t>& salt,
353                            bool generate_fake_on_unknown) override
354             {
355             // FIXME test generate_fake_on_unknown behavior
356             if(identifier == m_username)
357                {
358                group_name = m_group_id;
359                verifier = m_verifier;
360                salt = m_salt;
361                return true;
362                }
363             else if(generate_fake_on_unknown)
364                {
365                group_name = m_group_id;
366                verifier = m_verifier + 1;
367                salt = m_salt;
368                return true;
369                }
370             else
371                return false;
372             }
373 
374          std::string m_username;
375          std::string m_password;
376          std::vector<uint8_t> m_salt;
377          std::string m_group_id;
378          Botan::BigInt m_verifier;
379       };
380 
381    return new Credentials_Manager_SRP6(rng);
382    }
383 #endif
384 
385 
386 class TLS_Handshake_Test final
387    {
388    public:
TLS_Handshake_Test(const std::string & test_descr,Botan::TLS::Protocol_Version offer_version,Botan::Credentials_Manager & creds,const Botan::TLS::Policy & client_policy,const Botan::TLS::Policy & server_policy,Botan::RandomNumberGenerator & rng,Botan::TLS::Session_Manager & client_sessions,Botan::TLS::Session_Manager & server_sessions,bool expect_client_auth)389       TLS_Handshake_Test(const std::string& test_descr,
390                          Botan::TLS::Protocol_Version offer_version,
391                          Botan::Credentials_Manager& creds,
392                          const Botan::TLS::Policy& client_policy,
393                          const Botan::TLS::Policy& server_policy,
394                          Botan::RandomNumberGenerator& rng,
395                          Botan::TLS::Session_Manager& client_sessions,
396                          Botan::TLS::Session_Manager& server_sessions,
397                          bool expect_client_auth) :
398          m_offer_version(offer_version),
399          m_results(test_descr),
400          m_creds(creds),
401          m_client_policy(client_policy),
402          m_client_sessions(client_sessions),
403          m_rng(rng),
404          m_client_auth(expect_client_auth)
405          {
406          m_server_cb.reset(new Test_Callbacks(m_results, offer_version, m_s2c, m_server_recv));
407          m_client_cb.reset(new Test_Callbacks(m_results, offer_version, m_c2s, m_client_recv));
408 
409          m_server.reset(
410             new Botan::TLS::Server(*m_server_cb, server_sessions, m_creds, server_policy, m_rng,
411                                    offer_version.is_datagram_protocol())
412             );
413 
414          }
415 
416       void go();
417 
results() const418       const Test::Result& results() const { return m_results; }
419    private:
420 
421       class Test_Extension : public Botan::TLS::Extension
422          {
423          public:
static_type()424             static Botan::TLS::Handshake_Extension_Type static_type()
425                { return static_cast<Botan::TLS::Handshake_Extension_Type>(666); }
426 
type() const427             Botan::TLS::Handshake_Extension_Type type() const override { return static_type(); }
428 
serialize(Botan::TLS::Connection_Side) const429             std::vector<uint8_t> serialize(Botan::TLS::Connection_Side) const override { return m_buf; }
430 
value() const431             const std::vector<uint8_t>& value() const { return m_buf; }
432 
empty() const433             bool empty() const override { return false; }
434 
Test_Extension(Botan::TLS::Connection_Side side)435             Test_Extension(Botan::TLS::Connection_Side side)
436                {
437                const uint8_t client_extn[6] = { 'c', 'l', 'i', 'e', 'n', 't' };
438                const uint8_t server_extn[6] = { 's', 'e', 'r', 'v', 'e', 'r' };
439 
440                Botan::TLS::append_tls_length_value(m_buf,
441                                                    (side == Botan::TLS::CLIENT) ? client_extn : server_extn,
442                                                    6, 1);
443                }
444          private:
445             std::vector<uint8_t> m_buf;
446          };
447 
448       class Test_Callbacks : public Botan::TLS::Callbacks
449          {
450          public:
Test_Callbacks(Test::Result & results,Botan::TLS::Protocol_Version expected_version,std::vector<uint8_t> & outbound,std::vector<uint8_t> & recv_buf)451             Test_Callbacks(Test::Result& results,
452                            Botan::TLS::Protocol_Version expected_version,
453                            std::vector<uint8_t>& outbound,
454                            std::vector<uint8_t>& recv_buf) :
455                m_results(results),
456                m_expected_version(expected_version),
457                m_outbound(outbound),
458                m_recv(recv_buf)
459                {}
460 
tls_emit_data(const uint8_t bits[],size_t len)461             void tls_emit_data(const uint8_t bits[], size_t len) override
462                {
463                m_outbound.insert(m_outbound.end(), bits, bits + len);
464                }
465 
tls_record_received(uint64_t,const uint8_t bits[],size_t len)466             void tls_record_received(uint64_t /*seq*/, const uint8_t bits[], size_t len) override
467                {
468                m_recv.insert(m_recv.end(), bits, bits + len);
469                }
470 
tls_alert(Botan::TLS::Alert)471             void tls_alert(Botan::TLS::Alert /*alert*/) override
472                {
473                // TODO test that it is a no_renegotiation alert
474                // ignore
475                }
476 
tls_modify_extensions(Botan::TLS::Extensions & extn,Botan::TLS::Connection_Side which_side)477             void tls_modify_extensions(Botan::TLS::Extensions& extn, Botan::TLS::Connection_Side which_side) override
478                {
479                extn.add(new Test_Extension(which_side));
480 
481                // Insert an unsupported signature scheme as highest prio, to ensure we are tolerant of this
482                if(auto sig_algs = extn.get<Botan::TLS::Signature_Algorithms>())
483                   {
484                   std::vector<Botan::TLS::Signature_Scheme> schemes = sig_algs->supported_schemes();
485                   // 0x0301 is RSA PKCS1/SHA-224, which is not supported anymore
486                   schemes.insert(schemes.begin(), static_cast<Botan::TLS::Signature_Scheme>(0x0301));
487                   // This replaces the previous extension value
488                   extn.add(new Botan::TLS::Signature_Algorithms(schemes));
489                   }
490                }
491 
tls_examine_extensions(const Botan::TLS::Extensions & extn,Botan::TLS::Connection_Side which_side)492             void tls_examine_extensions(const Botan::TLS::Extensions& extn, Botan::TLS::Connection_Side which_side) override
493                {
494                Botan::TLS::Extension* test_extn = extn.get(static_cast<Botan::TLS::Handshake_Extension_Type>(666));
495 
496                if(test_extn == nullptr)
497                   {
498                   m_results.test_failure("Did not receive test extension from peer");
499                   }
500                else
501                   {
502                   Botan::TLS::Unknown_Extension* unknown_ext = dynamic_cast<Botan::TLS::Unknown_Extension*>(test_extn);
503 
504                   if(unknown_ext)
505                      {
506                      const std::vector<uint8_t> val = unknown_ext->value();
507 
508                      if(m_results.test_eq("Expected size for test extn", val.size(), 7))
509                         {
510                         if(which_side == Botan::TLS::CLIENT)
511                            m_results.test_eq("Expected extension value", val, "06636C69656E74");
512                         else
513                            m_results.test_eq("Expected extension value", val, "06736572766572");
514                         }
515                      }
516                   else
517                      {
518                      m_results.test_failure("Unknown extension type had unexpected type at runtime");
519                      }
520                   }
521                }
522 
tls_session_established(const Botan::TLS::Session & session)523             bool tls_session_established(const Botan::TLS::Session& session) override
524                {
525                const std::string session_report =
526                   "Session established " + session.version().to_string() + " " +
527                   session.ciphersuite().to_string() + " " +
528                   Botan::hex_encode(session.session_id());
529 
530                m_results.test_note(session_report);
531 
532                if(session.version() != m_expected_version)
533                   {
534                   m_results.test_failure("Expected " + m_expected_version.to_string() +
535                                          " negotiated " + session.version().to_string());
536                   }
537 
538                return true;
539                }
540 
tls_server_choose_app_protocol(const std::vector<std::string> & protos)541             std::string tls_server_choose_app_protocol(const std::vector<std::string>& protos) override
542                {
543                m_results.test_eq("ALPN protocol count", protos.size(), 2);
544                m_results.test_eq("ALPN protocol 1", protos[0], "test/1");
545                m_results.test_eq("ALPN protocol 2", protos[1], "test/2");
546                return "test/3";
547                }
548 
tls_decode_group_param(Botan::TLS::Group_Params group_param)549             virtual std::string tls_decode_group_param(Botan::TLS::Group_Params group_param) override
550                {
551                if(static_cast<uint16_t>(group_param) == 0xFEE1)
552                   return "secp112r1";
553 
554                return Botan::TLS::Callbacks::tls_decode_group_param(group_param);
555                }
556 
557          private:
558             Test::Result& m_results;
559             const Botan::TLS::Protocol_Version m_expected_version;
560             std::vector<uint8_t>& m_outbound;
561             std::vector<uint8_t>& m_recv;
562          };
563 
564       const Botan::TLS::Protocol_Version m_offer_version;
565       Test::Result m_results;
566 
567       Botan::Credentials_Manager& m_creds;
568       const Botan::TLS::Policy& m_client_policy;
569       Botan::TLS::Session_Manager& m_client_sessions;
570       Botan::RandomNumberGenerator& m_rng;
571 
572       std::unique_ptr<Test_Callbacks> m_client_cb;
573 
574       std::unique_ptr<Test_Callbacks> m_server_cb;
575       std::unique_ptr<Botan::TLS::Server> m_server;
576 
577       const bool m_client_auth;
578 
579       std::vector<uint8_t> m_c2s, m_s2c, m_client_recv, m_server_recv;
580    };
581 
go()582 void TLS_Handshake_Test::go()
583    {
584    m_results.start_timer();
585 
586    Botan::RandomNumberGenerator& rng = Test::rng();
587 
588    const std::vector<std::string> protocols_offered = { "test/1", "test/2" };
589 
590    // Choose random application data to send
591    const size_t c_len = 1 + ((static_cast<size_t>(rng.next_byte()) << 4) ^ rng.next_byte());
592    std::vector<uint8_t> client_msg(c_len);
593    Test::rng().randomize(client_msg.data(), client_msg.size());
594    bool client_has_written = false;
595 
596    const size_t s_len = 1 + ((static_cast<size_t>(rng.next_byte()) << 4) ^ rng.next_byte());
597    std::vector<uint8_t> server_msg(s_len);
598    Test::rng().randomize(server_msg.data(), server_msg.size());
599    bool server_has_written = false;
600 
601    std::unique_ptr<Botan::TLS::Client> client;
602    client.reset(
603       new Botan::TLS::Client(*m_client_cb, m_client_sessions, m_creds,
604                              m_client_policy, m_rng,
605                              Botan::TLS::Server_Information("server.example.com"),
606                              m_offer_version,
607                              protocols_offered));
608 
609    size_t rounds = 0;
610 
611    bool client_handshake_completed = false;
612    bool server_handshake_completed = false;
613 
614    while(true)
615       {
616       ++rounds;
617 
618       if(rounds > 25)
619          {
620          m_results.test_failure("Still here after many rounds, deadlock?");
621          break;
622          }
623 
624       if(client_handshake_completed == false && client->is_active())
625          client_handshake_completed = true;
626 
627       if(server_handshake_completed == false && m_server->is_active())
628          server_handshake_completed = true;
629 
630       if(client->is_closed() || m_server->is_closed())
631          {
632          break;
633          }
634 
635       if(client->is_active() && client_has_written == false)
636          {
637          m_results.test_eq("client ALPN protocol", client->application_protocol(), "test/3");
638 
639          size_t sent_so_far = 0;
640          while(sent_so_far != client_msg.size())
641             {
642             const size_t left = client_msg.size() - sent_so_far;
643             const size_t rnd12 = (rng.next_byte() << 4) ^ rng.next_byte();
644             const size_t sending = std::min(left, rnd12);
645 
646             client->send(&client_msg[sent_so_far], sending);
647             sent_so_far += sending;
648             }
649          client->send_warning_alert(Botan::TLS::Alert::NO_RENEGOTIATION);
650          client_has_written = true;
651          }
652 
653       if(m_server->is_active() && server_has_written == false)
654          {
655          m_results.test_eq("server ALPN protocol", m_server->application_protocol(), "test/3");
656 
657          size_t sent_so_far = 0;
658          while(sent_so_far != server_msg.size())
659             {
660             const size_t left = server_msg.size() - sent_so_far;
661             const size_t rnd12 = (rng.next_byte() << 4) ^ rng.next_byte();
662             const size_t sending = std::min(left, rnd12);
663 
664             m_server->send(&server_msg[sent_so_far], sending);
665             sent_so_far += sending;
666             }
667 
668          m_server->send_warning_alert(Botan::TLS::Alert::NO_RENEGOTIATION);
669          server_has_written = true;
670          }
671 
672       if(m_c2s.size() > 0)
673          {
674          /*
675          * Use this as a temp value to hold the queues as otherwise they
676          * might end up appending more in response to messages during the
677          * handshake.
678          */
679          std::vector<uint8_t> input;
680          std::swap(m_c2s, input);
681 
682          size_t needed = m_server->received_data(input.data(), input.size());
683          m_results.test_eq("full packet received", needed, 0);
684 
685          continue;
686          }
687 
688       if(m_s2c.size() > 0)
689          {
690          std::vector<uint8_t> input;
691          std::swap(m_s2c, input);
692 
693          size_t needed = client->received_data(input.data(), input.size());
694          m_results.test_eq("full packet received", needed, 0);
695 
696          continue;
697          }
698 
699       if(m_client_recv.size())
700          {
701          m_results.test_eq("client recv", m_client_recv, server_msg);
702          }
703 
704       if(m_server_recv.size())
705          {
706          m_results.test_eq("server recv", m_server_recv, client_msg);
707          }
708 
709       if(client->is_closed() && m_server->is_closed())
710          {
711          break;
712          }
713 
714       if(m_server->is_active())
715          {
716          std::vector<Botan::X509_Certificate> certs = m_server->peer_cert_chain();
717          if(m_client_auth)
718             {
719             m_results.test_eq("got client certs", certs.size(), 2);
720 
721             Credentials_Manager_Test& test_creds = dynamic_cast<Credentials_Manager_Test&>(m_creds);
722 
723             std::vector<Botan::X509_DN> acceptable_CAs = test_creds.get_acceptable_cas();
724 
725             m_results.test_gte("client got CA list", acceptable_CAs.size(), 2); // DSA is optional
726 
727             for(const Botan::X509_DN& dn : acceptable_CAs)
728                {
729                m_results.test_eq("Expected CA country field",
730                                  dn.get_first_attribute("C"), "VT");
731                }
732             }
733          else
734             {
735             m_results.test_eq("no client certs", certs.size(), 0);
736             }
737          }
738 
739       if(m_server_recv.size() && m_client_recv.size())
740          {
741          Botan::SymmetricKey client_key = client->key_material_export("label", "context", 32);
742          Botan::SymmetricKey server_key = m_server->key_material_export("label", "context", 32);
743 
744          m_results.test_eq("TLS key material export", client_key.bits_of(), server_key.bits_of());
745 
746          m_results.confirm("Client is active", client->is_active());
747          m_results.confirm("Client is not closed", !client->is_closed());
748          client->close();
749          m_results.confirm("Client is no longer active", !client->is_active());
750          m_results.confirm("Client is closed", client->is_closed());
751          }
752       }
753 
754    m_results.end_timer();
755    }
756 
757 class Test_Policy final : public Botan::TLS::Text_Policy
758    {
759    public:
Test_Policy()760       Test_Policy() : Text_Policy("") {}
acceptable_protocol_version(Botan::TLS::Protocol_Version) const761       bool acceptable_protocol_version(Botan::TLS::Protocol_Version) const override
762          {
763          return true;
764          }
send_fallback_scsv(Botan::TLS::Protocol_Version) const765       bool send_fallback_scsv(Botan::TLS::Protocol_Version) const override
766          {
767          return false;
768          }
769 
dtls_initial_timeout() const770       size_t dtls_initial_timeout() const override
771          {
772          return 1;
773          }
dtls_maximum_timeout() const774       size_t dtls_maximum_timeout() const override
775          {
776          return 8;
777          }
778 
minimum_rsa_bits() const779       size_t minimum_rsa_bits() const override
780          {
781          return 1024;
782          }
783 
minimum_dsa_group_size() const784       size_t minimum_dsa_group_size() const override
785          {
786          return 1024;
787          }
788 
minimum_signature_strength() const789       size_t minimum_signature_strength() const override
790          {
791          return 80;
792          }
793    };
794 
795 class TLS_Unit_Tests final : public Test
796    {
797    private:
test_with_policy(const std::string & test_descr,std::vector<Test::Result> & results,Botan::TLS::Session_Manager & client_ses,Botan::TLS::Session_Manager & server_ses,Botan::Credentials_Manager & creds,const std::vector<Botan::TLS::Protocol_Version> & versions,const Botan::TLS::Policy & policy,bool client_auth=false)798       void test_with_policy(const std::string& test_descr,
799                             std::vector<Test::Result>& results,
800                             Botan::TLS::Session_Manager& client_ses,
801                             Botan::TLS::Session_Manager& server_ses,
802                             Botan::Credentials_Manager& creds,
803                             const std::vector<Botan::TLS::Protocol_Version>& versions,
804                             const Botan::TLS::Policy& policy,
805                             bool client_auth = false)
806          {
807          Botan::RandomNumberGenerator& rng = Test::rng();
808 
809          try
810             {
811             for(auto const& version : versions)
812                {
813                TLS_Handshake_Test test(
814                   version.to_string() + " " + test_descr,
815                   version, creds, policy, policy, rng, client_ses, server_ses, client_auth);
816                test.go();
817                results.push_back(test.results());
818 
819                TLS_Handshake_Test test_resumption(
820                   version.to_string() + " " + test_descr,
821                   version, creds, policy, policy, rng, client_ses, server_ses, client_auth);
822                test_resumption.go();
823                results.push_back(test_resumption.results());
824                }
825             }
826          catch(std::exception& e)
827             {
828             results.push_back(Test::Result::Failure(test_descr, e.what()));
829             }
830          }
831 
test_all_versions(const std::string & test_descr,std::vector<Test::Result> & results,Botan::TLS::Session_Manager & client_ses,Botan::TLS::Session_Manager & server_ses,Botan::Credentials_Manager & creds,const std::string & kex_policy,const std::string & cipher_policy,const std::string & mac_policy,const std::string & etm_policy,bool client_auth=false)832       void test_all_versions(const std::string& test_descr,
833                              std::vector<Test::Result>& results,
834                              Botan::TLS::Session_Manager& client_ses,
835                              Botan::TLS::Session_Manager& server_ses,
836                              Botan::Credentials_Manager& creds,
837                              const std::string& kex_policy,
838                              const std::string& cipher_policy,
839                              const std::string& mac_policy,
840                              const std::string& etm_policy,
841                              bool client_auth = false)
842          {
843          Test_Policy policy;
844          policy.set("ciphers", cipher_policy);
845          policy.set("macs", mac_policy);
846          policy.set("key_exchange_methods", kex_policy);
847          policy.set("negotiate_encrypt_then_mac", etm_policy);
848 
849          policy.set("allow_tls10", "true");
850          policy.set("allow_tls11", "true");
851          policy.set("allow_tls12", "true");
852          policy.set("allow_dtls10", "true");
853          policy.set("allow_dtls12", "true");
854 
855          if(kex_policy.find("RSA") != std::string::npos || kex_policy.find("SRP") != std::string::npos)
856             {
857             policy.set("signature_methods", "IMPLICIT");
858             }
859 
860          std::vector<Botan::TLS::Protocol_Version> versions =
861             {
862 #if defined(BOTAN_HAS_TLS_V10)
863             Botan::TLS::Protocol_Version::TLS_V10,
864             Botan::TLS::Protocol_Version::TLS_V11,
865             Botan::TLS::Protocol_Version::DTLS_V10,
866 #endif
867             Botan::TLS::Protocol_Version::TLS_V12,
868             Botan::TLS::Protocol_Version::DTLS_V12
869             };
870 
871          return test_with_policy(test_descr, results, client_ses, server_ses, creds, versions, policy, client_auth);
872          }
873 
test_modern_versions(const std::string & test_descr,std::vector<Test::Result> & results,Botan::TLS::Session_Manager & client_ses,Botan::TLS::Session_Manager & server_ses,Botan::Credentials_Manager & creds,const std::string & kex_policy,const std::string & cipher_policy,const std::string & mac_policy="AEAD",bool client_auth=false)874       void test_modern_versions(const std::string& test_descr,
875                                 std::vector<Test::Result>& results,
876                                 Botan::TLS::Session_Manager& client_ses,
877                                 Botan::TLS::Session_Manager& server_ses,
878                                 Botan::Credentials_Manager& creds,
879                                 const std::string& kex_policy,
880                                 const std::string& cipher_policy,
881                                 const std::string& mac_policy = "AEAD",
882                                 bool client_auth = false)
883          {
884          std::map<std::string, std::string> no_extra_policies;
885          return test_modern_versions(test_descr, results, client_ses, server_ses, creds,
886                                      kex_policy, cipher_policy, mac_policy, no_extra_policies, client_auth);
887          }
888 
test_modern_versions(const std::string & test_descr,std::vector<Test::Result> & results,Botan::TLS::Session_Manager & client_ses,Botan::TLS::Session_Manager & server_ses,Botan::Credentials_Manager & creds,const std::string & kex_policy,const std::string & cipher_policy,const std::string & mac_policy,const std::map<std::string,std::string> & extra_policies,bool client_auth=false)889       void test_modern_versions(const std::string& test_descr,
890                                 std::vector<Test::Result>& results,
891                                 Botan::TLS::Session_Manager& client_ses,
892                                 Botan::TLS::Session_Manager& server_ses,
893                                 Botan::Credentials_Manager& creds,
894                                 const std::string& kex_policy,
895                                 const std::string& cipher_policy,
896                                 const std::string& mac_policy,
897                                 const std::map<std::string, std::string>& extra_policies,
898                                 bool client_auth = false)
899          {
900          Test_Policy policy;
901          policy.set("ciphers", cipher_policy);
902          policy.set("macs", mac_policy);
903          policy.set("key_exchange_methods", kex_policy);
904          policy.set("allow_tls10", "false");
905          policy.set("allow_tls11", "false");
906          policy.set("allow_tls12", "true");
907          policy.set("allow_dtls10", "false");
908          policy.set("allow_dtls12", "true");
909 
910          if(kex_policy.find("RSA") != std::string::npos)
911             {
912             policy.set("signature_methods", "IMPLICIT");
913             }
914 
915          for(auto const& kv : extra_policies)
916             {
917             policy.set(kv.first, kv.second);
918             }
919 
920          std::vector<Botan::TLS::Protocol_Version> versions =
921             {
922             Botan::TLS::Protocol_Version::TLS_V12,
923             Botan::TLS::Protocol_Version::DTLS_V12
924             };
925 
926          return test_with_policy(test_descr, results, client_ses, server_ses, creds, versions, policy, client_auth);
927          }
928 
929    public:
run()930       std::vector<Test::Result> run() override
931          {
932          std::vector<Test::Result> results;
933 
934          Botan::RandomNumberGenerator& rng = Test::rng();
935 
936          std::unique_ptr<Botan::TLS::Session_Manager> client_ses;
937          std::unique_ptr<Botan::TLS::Session_Manager> server_ses;
938 
939 #if defined(BOTAN_HAS_TLS_SQLITE3_SESSION_MANAGER)
940          client_ses.reset(
941             new Botan::TLS::Session_Manager_SQLite("client pass", rng, ":memory:", 5, std::chrono::seconds(2)));
942          server_ses.reset(
943             new Botan::TLS::Session_Manager_SQLite("server pass", rng, ":memory:", 10, std::chrono::seconds(4)));
944 
945 #else
946          client_ses.reset(new Botan::TLS::Session_Manager_In_Memory(rng));
947          server_ses.reset(new Botan::TLS::Session_Manager_In_Memory(rng));
948 #endif
949 
950          std::unique_ptr<Botan::Credentials_Manager> creds(create_creds(rng));
951 
952 #if defined(BOTAN_HAS_TLS_CBC)
953          for(std::string etm_setting : { "false", "true" })
954             {
955             test_all_versions("AES-128 RSA", results, *client_ses, *server_ses, *creds, "RSA", "AES-128", "SHA-256 SHA-1", etm_setting);
956             test_all_versions("AES-128 ECDH", results, *client_ses, *server_ses, *creds, "ECDH", "AES-128", "SHA-256 SHA-1", etm_setting);
957 
958 #if defined(BOTAN_HAS_CAMELLIA) && defined(BOTAN_HAS_TLS_CBC)
959             test_all_versions("Camellia-128 RSA", results, *client_ses, *server_ses,
960                               *creds, "RSA", "Camellia-128", "SHA-256 SHA-1", etm_setting);
961             test_all_versions("Camellia-256 RSA SHA-2", results, *client_ses, *server_ses,
962                               *creds, "RSA", "Camellia-256", "SHA-256 SHA-384 SHA-1", etm_setting);
963 #endif
964 
965 #if defined(BOTAN_HAS_DES)
966             test_all_versions("3DES RSA", results, *client_ses, *server_ses, *creds, "RSA", "3DES", "SHA-1", etm_setting);
967             test_all_versions("3DES ECDH", results, *client_ses, *server_ses, *creds, "ECDH", "3DES", "SHA-1", etm_setting);
968 #endif
969 
970 #if defined(BOTAN_HAS_SEED)
971             test_all_versions("SEED RSA", results, *client_ses, *server_ses, *creds, "RSA", "SEED", "SHA-1", etm_setting);
972 #endif
973 
974             server_ses->remove_all();
975             }
976          client_ses->remove_all();
977 
978          test_modern_versions("AES-128 DH", results, *client_ses, *server_ses, *creds, "DH", "AES-128", "SHA-256");
979 
980 #if defined(BOTAN_HAS_DSA)
981          if(Test::run_long_tests())
982             {
983             test_modern_versions("AES-128 DSA", results, *client_ses, *server_ses, *creds, "DH", "AES-128", "SHA-256",
984                                  { { "signature_methods", "DSA" } });
985 
986             test_modern_versions("AES-128/GCM DSA", results, *client_ses, *server_ses, *creds, "DH", "AES-128/GCM", "AEAD",
987                                  { { "signature_methods", "DSA" } });
988             }
989 #endif
990 
991 #if defined(BOTAN_HAS_SRP6)
992          std::unique_ptr<Botan::Credentials_Manager> srp6_creds(create_srp6_creds(rng));
993          test_all_versions("SRP6 AES", results, *client_ses, *server_ses, *srp6_creds, "SRP_SHA", "AES-128", "SHA-1", "false");
994 #endif
995 
996 #endif
997 
998          Botan::TLS::Strict_Policy strict_policy;
999          test_with_policy("Strict policy", results, *client_ses, *server_ses, *creds,
1000             {Botan::TLS::Protocol_Version::TLS_V12}, strict_policy);
1001 
1002          Botan::TLS::NSA_Suite_B_128 suiteb_128;
1003          test_with_policy("Suite B", results, *client_ses, *server_ses, *creds,
1004             {Botan::TLS::Protocol_Version::TLS_V12}, suiteb_128);
1005 
1006          // Remove server sessions before client, so clients retry with session server doesn't know
1007          server_ses->remove_all();
1008 
1009          test_modern_versions("AES-128/GCM RSA", results, *client_ses, *server_ses, *creds, "RSA", "AES-128/GCM");
1010          test_modern_versions("AES-128/GCM ECDH", results, *client_ses, *server_ses, *creds, "ECDH", "AES-128/GCM");
1011 
1012          test_modern_versions("AES-128/GCM ECDH RSA",
1013                               results, *client_ses, *server_ses, *creds, "ECDH", "AES-128/GCM", "AEAD",
1014                               { { "signature_methods", "RSA" } });
1015 
1016          test_modern_versions("AES-128/GCM ECDH no OCSP",
1017                               results, *client_ses, *server_ses, *creds, "ECDH", "AES-128/GCM", "AEAD",
1018                               { { "support_cert_status_message", "false" } });
1019 
1020          client_ses->remove_all();
1021 
1022 #if defined(BOTAN_HAS_CAMELLIA) && defined(BOTAN_HAS_TLS_CBC)
1023          test_modern_versions("Camellia-256 SHA-2", results, *client_ses, *server_ses, *creds, "RSA", "Camellia-256", "SHA-384 SHA-256");
1024 #endif
1025 #if defined(BOTAN_HAS_CAMELLIA) && defined(BOTAN_HAS_AEAD_GCM)
1026          test_modern_versions("Camellia-128/GCM ECDH", results, *client_ses, *server_ses, *creds, "ECDH", "Camellia-128/GCM", "AEAD");
1027 #endif
1028 
1029 #if defined(BOTAN_HAS_ARIA)
1030          test_modern_versions("ARIA ECDH", results, *client_ses, *server_ses, *creds, "ECDH", "ARIA-128/GCM", "AEAD");
1031 #endif
1032 
1033 #if defined(BOTAN_HAS_CECPQ1)
1034 
1035 #if defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_AEAD_GCM)
1036          test_modern_versions("AES-256/GCM CECPQ1", results, *client_ses, *server_ses, *creds, "CECPQ1", "AES-256/GCM", "AEAD");
1037 #endif
1038 
1039 #if defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_AEAD_OCB)
1040          test_modern_versions("AES-256/OCB CECPQ1", results, *client_ses, *server_ses, *creds,
1041                               "CECPQ1", "AES-256/OCB(12)", "AEAD");
1042          test_modern_versions("AES-256/OCB CECPQ1 RSA", results, *client_ses, *server_ses, *creds,
1043                               "CECPQ1", "AES-256/OCB(12)", "AEAD",
1044                               {{ "signature_methods", "RSA" }});
1045 #endif
1046 
1047 #if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305)
1048          test_modern_versions("ChaCha20Poly1305 CECPQ1", results, *client_ses, *server_ses, *creds,
1049                               "CECPQ1", "ChaCha20Poly1305", "AEAD",
1050                               { { "signature_methods", "RSA" }});
1051 #endif
1052 
1053 #endif
1054 
1055          test_modern_versions("AES-128/GCM point compression", results, *client_ses, *server_ses, *creds, "ECDH", "AES-128/GCM", "AEAD",
1056                               { { "use_ecc_point_compression", "true" } });
1057          test_modern_versions("AES-256/GCM p521", results, *client_ses, *server_ses, *creds, "ECDH", "AES-256/GCM", "AEAD",
1058                               { { "groups", "secp521r1" } });
1059          test_modern_versions("AES-128/GCM bp256r1", results, *client_ses, *server_ses, *creds, "ECDH", "AES-128/GCM", "AEAD",
1060                               { { "groups", "brainpool256r1" } });
1061 
1062 #if defined(BOTAN_HAS_CURVE_25519)
1063          test_modern_versions("AES-128/GCM x25519", results, *client_ses, *server_ses, *creds, "ECDH", "AES-128/GCM", "AEAD",
1064                               { { "groups", "x25519" } });
1065 #endif
1066 
1067          test_modern_versions("AES-128/GCM FFDHE-2048",
1068                               results, *client_ses, *server_ses, *creds, "DH", "AES-128/GCM", "AEAD",
1069                               { { "groups", "ffdhe/ietf/2048" } });
1070 
1071          std::unique_ptr<Botan::Credentials_Manager> creds_with_client_cert(create_creds(rng, true));
1072 
1073          client_ses->remove_all();
1074          test_modern_versions("AES-256/GCM client certs",
1075                               results, *client_ses, *server_ses, *creds_with_client_cert, "ECDH", "AES-256/GCM", "AEAD", true);
1076 
1077 #if defined(BOTAN_HAS_TLS_SQLITE3_SESSION_MANAGER)
1078          client_ses.reset(new Botan::TLS::Session_Manager_In_Memory(rng));
1079          server_ses.reset(new Botan::TLS::Session_Manager_In_Memory(rng));
1080 #endif
1081 
1082 #if defined(BOTAN_HAS_AEAD_OCB)
1083          test_modern_versions("AES-128/OCB ECDH", results, *client_ses, *server_ses, *creds, "ECDH", "AES-128/OCB(12)");
1084 #endif
1085 
1086          server_ses->remove_all();
1087 
1088 #if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305)
1089          test_modern_versions("ChaCha20Poly1305 ECDH", results, *client_ses, *server_ses, *creds, "ECDH", "ChaCha20Poly1305");
1090 #endif
1091 
1092          test_modern_versions("AES-128/GCM PSK", results, *client_ses, *server_ses, *creds, "PSK", "AES-128/GCM");
1093 
1094 #if defined(BOTAN_HAS_AEAD_CCM)
1095          test_modern_versions("AES-128/CCM PSK", results, *client_ses, *server_ses, *creds, "PSK", "AES-128/CCM");
1096          test_modern_versions("AES-128/CCM-8 PSK", results, *client_ses, *server_ses, *creds, "PSK", "AES-128/CCM(8)");
1097 #endif
1098 
1099 #if defined(BOTAN_HAS_TLS_CBC)
1100          // For whatever reason no (EC)DHE_PSK GCM ciphersuites are defined
1101          test_modern_versions("AES-128 ECDHE_PSK", results, *client_ses, *server_ses, *creds, "ECDHE_PSK", "AES-128", "SHA-256");
1102          test_modern_versions("AES-128 DHE_PSK", results, *client_ses, *server_ses, *creds, "DHE_PSK", "AES-128", "SHA-1");
1103 #endif
1104 
1105          // Test with a custom curve
1106 
1107          /*
1108          * First register a curve, in this case secp112r1
1109          */
1110          const Botan::BigInt p("0xDB7C2ABF62E35E668076BEAD208B");
1111          const Botan::BigInt a("0xDB7C2ABF62E35E668076BEAD2088");
1112          const Botan::BigInt b("0x659EF8BA043916EEDE8911702B22");
1113 
1114          const Botan::BigInt g_x("0x09487239995A5EE76B55F9C2F098");
1115          const Botan::BigInt g_y("0xA89CE5AF8724C0A23E0E0FF77500");
1116          const Botan::BigInt order("0xDB7C2ABF62E35E7628DFAC6561C5");
1117 
1118          const Botan::OID oid("1.3.132.0.6");
1119 
1120          // Creating this object implicitly registers the curve for future use ...
1121          Botan::EC_Group reg_secp112r1(p, a, b, g_x, g_y, order, 1, oid);
1122 
1123          Botan::OIDS::add_oid(oid, "secp112r1");
1124 
1125          test_modern_versions("AES-256/GCM secp112r1", results, *client_ses, *server_ses, *creds, "ECDH", "AES-256/GCM", "AEAD",
1126                               { { "groups", "0xFEE1" }, { "minimum_ecdh_group_size", "112" } });
1127 
1128          return results;
1129          }
1130 
1131    };
1132 
1133 BOTAN_REGISTER_TEST("tls", "tls", TLS_Unit_Tests);
1134 
1135 class DTLS_Reconnection_Test : public Test
1136    {
1137    public:
run()1138       std::vector<Test::Result> run() override
1139          {
1140          class Test_Callbacks : public Botan::TLS::Callbacks
1141             {
1142             public:
1143                Test_Callbacks(Test::Result& results,
1144                               std::vector<uint8_t>& outbound,
1145                               std::vector<uint8_t>& recv_buf) :
1146                   m_results(results),
1147                   m_outbound(outbound),
1148                   m_recv(recv_buf)
1149                   {}
1150 
1151                void tls_emit_data(const uint8_t bits[], size_t len) override
1152                   {
1153                   m_outbound.insert(m_outbound.end(), bits, bits + len);
1154                   }
1155 
1156                void tls_record_received(uint64_t /*seq*/, const uint8_t bits[], size_t len) override
1157                   {
1158                   m_recv.insert(m_recv.end(), bits, bits + len);
1159                   }
1160 
1161                void tls_alert(Botan::TLS::Alert /*alert*/) override
1162                   {
1163                   // ignore
1164                   }
1165 
1166                bool tls_session_established(const Botan::TLS::Session& /*session*/) override
1167                   {
1168                   m_results.test_success("Established a session");
1169                   return true;
1170                   }
1171 
1172             private:
1173                Test::Result& m_results;
1174                std::vector<uint8_t>& m_outbound;
1175                std::vector<uint8_t>& m_recv;
1176             };
1177 
1178          class Credentials_PSK : public Botan::Credentials_Manager
1179             {
1180             public:
1181                Botan::SymmetricKey psk(const std::string& type,
1182                                        const std::string& context,
1183                                        const std::string&) override
1184                   {
1185                   if(type == "tls-server" && context == "session-ticket")
1186                      {
1187                      return Botan::SymmetricKey("AABBCCDDEEFF012345678012345678");
1188                      }
1189 
1190                   if(type == "tls-server" && context == "dtls-cookie-secret")
1191                      {
1192                      return Botan::SymmetricKey("4AEA5EAD279CADEB537A594DA0E9DE3A");
1193                      }
1194 
1195                   if(context == "localhost" && type == "tls-client")
1196                      {
1197                      return Botan::SymmetricKey("20B602D1475F2DF888FCB60D2AE03AFD");
1198                      }
1199 
1200                   if(context == "localhost" && type == "tls-server")
1201                      {
1202                      return Botan::SymmetricKey("20B602D1475F2DF888FCB60D2AE03AFD");
1203                      }
1204 
1205                   throw Test_Error("No PSK set for " + type + "/" + context);
1206                   }
1207             };
1208 
1209          class Datagram_PSK_Policy : public Botan::TLS::Policy
1210             {
1211             public:
1212                std::vector<std::string> allowed_macs() const override
1213                   { return std::vector<std::string>({"AEAD"}); }
1214 
1215                std::vector<std::string> allowed_key_exchange_methods() const override
1216                   { return {"PSK"}; }
1217 
1218                bool allow_tls10()  const override { return false; }
1219                bool allow_tls11()  const override { return false; }
1220                bool allow_tls12()  const override { return false; }
1221                bool allow_dtls10() const override { return false; }
1222                bool allow_dtls12() const override { return true;  }
1223 
1224                bool allow_dtls_epoch0_restart() const override { return true; }
1225             };
1226 
1227          Test::Result result("DTLS reconnection");
1228 
1229          Datagram_PSK_Policy server_policy;
1230          Datagram_PSK_Policy client_policy;
1231          Credentials_PSK creds;
1232          Botan::TLS::Session_Manager_In_Memory server_sessions(rng());
1233          //Botan::TLS::Session_Manager_In_Memory client_sessions(rng());
1234          Botan::TLS::Session_Manager_Noop client_sessions;
1235 
1236          std::vector<uint8_t> s2c, server_recv;
1237          Test_Callbacks server_callbacks(result, s2c, server_recv);
1238          Botan::TLS::Server server(server_callbacks, server_sessions, creds, server_policy, rng(), true);
1239 
1240          std::vector<uint8_t> c1_c2s, client1_recv;
1241          Test_Callbacks client1_callbacks(result, c1_c2s, client1_recv);
1242          Botan::TLS::Client client1(client1_callbacks, client_sessions, creds, client_policy, rng(),
1243                                     Botan::TLS::Server_Information("localhost"),
1244                                     Botan::TLS::Protocol_Version::latest_dtls_version());
1245 
1246          bool c1_to_server_sent = false;
1247          bool server_to_c1_sent = false;
1248 
1249          const std::vector<uint8_t> c1_to_server_magic(16, 0xC1);
1250          const std::vector<uint8_t> server_to_c1_magic(16, 0x42);
1251 
1252          size_t c1_rounds = 0;
1253          for(;;)
1254             {
1255             c1_rounds++;
1256 
1257             if(c1_rounds > 64)
1258                {
1259                result.test_failure("Still spinning in client1 loop after 64 rounds");
1260                return {result};
1261                }
1262 
1263             if(c1_c2s.size() > 0)
1264                {
1265                std::vector<uint8_t> input;
1266                std::swap(c1_c2s, input);
1267                server.received_data(input.data(), input.size());
1268                continue;
1269                }
1270 
1271             if(s2c.size() > 0)
1272                {
1273                std::vector<uint8_t> input;
1274                std::swap(s2c, input);
1275                client1.received_data(input.data(), input.size());
1276                continue;
1277                }
1278 
1279             if(!c1_to_server_sent && client1.is_active())
1280                {
1281                client1.send(c1_to_server_magic);
1282                c1_to_server_sent = true;
1283                }
1284 
1285             if(!server_to_c1_sent && server.is_active())
1286                {
1287                server.send(server_to_c1_magic);
1288                }
1289 
1290             if(server_recv.size() > 0 && client1_recv.size() > 0)
1291                {
1292                result.test_eq("Expected message from client1", server_recv, c1_to_server_magic);
1293                result.test_eq("Expected message to client1", client1_recv, server_to_c1_magic);
1294                break;
1295                }
1296             }
1297 
1298          // Now client1 "goes away" (goes silent) and new client
1299          // connects to same server context (ie due to reuse of client source port)
1300          // See RFC 6347 section 4.2.8
1301 
1302          server_recv.clear();
1303          s2c.clear();
1304 
1305          std::vector<uint8_t> c2_c2s, client2_recv;
1306          Test_Callbacks client2_callbacks(result, c2_c2s, client2_recv);
1307          Botan::TLS::Client client2(client2_callbacks, client_sessions, creds, client_policy, rng(),
1308                                     Botan::TLS::Server_Information("localhost"),
1309                                     Botan::TLS::Protocol_Version::latest_dtls_version());
1310 
1311          bool c2_to_server_sent = false;
1312          bool server_to_c2_sent = false;
1313 
1314          const std::vector<uint8_t> c2_to_server_magic(16, 0xC2);
1315          const std::vector<uint8_t> server_to_c2_magic(16, 0x66);
1316 
1317          size_t c2_rounds = 0;
1318 
1319          for(;;)
1320             {
1321             c2_rounds++;
1322 
1323             if(c2_rounds > 64)
1324                {
1325                result.test_failure("Still spinning in client2 loop after 64 rounds");
1326                return {result};
1327                }
1328 
1329             if(c2_c2s.size() > 0)
1330                {
1331                std::vector<uint8_t> input;
1332                std::swap(c2_c2s, input);
1333                server.received_data(input.data(), input.size());
1334                continue;
1335                }
1336 
1337             if(s2c.size() > 0)
1338                {
1339                std::vector<uint8_t> input;
1340                std::swap(s2c, input);
1341                client2.received_data(input.data(), input.size());
1342                continue;
1343                }
1344 
1345             if(!c2_to_server_sent && client2.is_active())
1346                {
1347                client2.send(c2_to_server_magic);
1348                c2_to_server_sent = true;
1349                }
1350 
1351             if(!server_to_c2_sent && server.is_active())
1352                {
1353                server.send(server_to_c2_magic);
1354                }
1355 
1356             if(server_recv.size() > 0 && client2_recv.size() > 0)
1357                {
1358                result.test_eq("Expected message from client2", server_recv, c2_to_server_magic);
1359                result.test_eq("Expected message to client2", client2_recv, server_to_c2_magic);
1360                break;
1361                }
1362             }
1363 
1364          return {result};
1365          }
1366    };
1367 
1368 BOTAN_REGISTER_TEST("tls", "tls_dtls_reconnect", DTLS_Reconnection_Test);
1369 
1370 #endif
1371 
1372 }
1373 
1374 }
1375