aboutsummaryrefslogtreecommitdiffstats
path: root/src/cmd/fuzzer.cpp
blob: 09c1fba4264d03bbabe8f6e4c5ada0d590237057 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
* (C) 2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "apps.h"
#include <botan/x509cert.h>
#include <botan/x509_crl.h>
#include <botan/pkcs8.h>
#include <botan/tls_client.h>
#include <botan/system_rng.h>
#include <fstream>

namespace {

class Fuzzer_Creds : public Credentials_Manager
   {
   public:
      void verify_certificate_chain(const std::string& type,
                                    const std::string& purported_hostname,
                                    const std::vector<X509_Certificate>& cert_chain) override
         {
         try
            {
            Credentials_Manager::verify_certificate_chain(type,
                                                          purported_hostname,
                                                          cert_chain);
            }
         catch(std::exception& e) {}
         }

      std::string psk_identity_hint(const std::string&, const std::string&) { return "psk_hint"; }
      std::string psk_identity(const std::string&, const std::string&) { return "psk_id"; }
      SymmetricKey psk(const std::string&, const std::string&, const std::string&)
         {
         return SymmetricKey("AABBCCDDEEFF00112233445566778899");
         }
   };

int fuzzer(int argc, char* argv[])
   {
   if(argc != 3)
      {
      std::cout << "Usage: " << argv[0] << " [type] [input_file]\n";
      std::cout << "Hook for fuzzers such as afl (produces no output)\n";
      std::cout << "Types: cert crl privkey tls_client\n";
      return 1;
      }

   const std::string type = argv[1];
   const std::string input = argv[2];

   auto& rng = system_rng();

   if(type == "cert")
      {
      X509_Certificate cert(input);
      }
   else if(type == "crl")
      {
      X509_CRL crl(input);
      }
   else if(type == "privkey")
      {
      std::unique_ptr<Private_Key>(PKCS8::load_key(input, rng));
      }
   else if(type == "tls_client")
      {
      auto dev_null = [](const byte[], size_t) {};

      auto ignore_alerts = [](TLS::Alert, const byte[], size_t) {};
      auto ignore_hs = [](const TLS::Session&) { return true; };

      TLS::Session_Manager_In_Memory session_manager(rng);
      TLS::Policy policy;
      TLS::Protocol_Version client_offer = TLS::Protocol_Version::TLS_V12;
      TLS::Server_Information info("server.name", 443);
      const std::vector<std::string> protocols_to_offer = { "fuzz/1.0", "http/1.1", "bunny/1.21.3" };
      Fuzzer_Creds creds;

      TLS::Client client(dev_null,
                         dev_null,
                         ignore_alerts,
                         ignore_hs,
                         session_manager,
                         creds,
                         policy,
                         rng,
                         info,
                         client_offer,
                         protocols_to_offer);

      std::ifstream in(input.c_str());

      std::vector<byte> buf(1024);

      try
         {
         while(in.good())
            {
            in.read((char*)&buf[0], buf.size());
            size_t got = in.gcount();
            client.received_data(&buf[0], got);
            }
         }
      catch(std::exception& e)
         {
         }
      }
   else
      {
      std::cout << "Unhandled type " << type << "\n";
      return 1;
      }

   return 0;
   }

REGISTER_APP(fuzzer);

}