• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5111374265

29 May 2023 11:19AM UTC coverage: 92.227% (+0.5%) from 91.723%
5111374265

push

github

randombit
Next release will be 3.1.0. Update release notes

75588 of 81959 relevant lines covered (92.23%)

11886470.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.95
/src/cli/tls_utils.cpp
1
/*
2
* (C) 2016 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#include "cli.h"
8

9
#if defined(BOTAN_HAS_TLS) && defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
10

11
   #include <botan/hex.h>
12
   #include <botan/tls_messages.h>
13
   #include <botan/tls_policy.h>
14
   #include <botan/tls_version.h>
15
   #include <botan/internal/loadstor.h>
16
   #include <sstream>
17

18
   #include "tls_helpers.h"
19

20
namespace Botan_CLI {
21

22
class TLS_Ciphersuites final : public Command {
23
   public:
24
      TLS_Ciphersuites() : Command("tls_ciphers --policy=default --version=tls1.2") {}
12✔
25

26
      static Botan::TLS::Protocol_Version tls_version_from_str(const std::string& str) {
5✔
27
         if(str == "tls1.2" || str == "TLS1.2" || str == "TLS-1.2") {
5✔
28
            return Botan::TLS::Protocol_Version::TLS_V12;
5✔
29
         }
30
         if(str == "dtls1.2" || str == "DTLS1.2" || str == "DTLS-1.2") {
×
31
            return Botan::TLS::Protocol_Version::DTLS_V12;
×
32
         } else {
33
            throw CLI_Error("Unknown TLS version '" + str + "'");
×
34
         }
35
      }
36

37
      std::string group() const override { return "tls"; }
1✔
38

39
      std::string description() const override { return "Lists all ciphersuites for a policy and TLS version"; }
1✔
40

41
      void go() override {
5✔
42
         const std::string policy_type = get_arg("policy");
5✔
43
         const Botan::TLS::Protocol_Version version = tls_version_from_str(get_arg("version"));
10✔
44

45
         auto policy = load_tls_policy(policy_type);
10✔
46

47
         if(policy->acceptable_protocol_version(version) == false) {
5✔
48
            error_output() << "Error: the policy specified does not allow the given TLS version\n";
×
49
            return;
×
50
         }
51

52
         for(uint16_t suite_id : policy->ciphersuite_list(version)) {
111✔
53
            const auto s = Botan::TLS::Ciphersuite::by_id(suite_id);
106✔
54
            output() << ((s) ? s->to_string() : "unknown cipher suite") << "\n";
318✔
55
         }
5✔
56
      }
5✔
57
};
58

59
BOTAN_REGISTER_COMMAND("tls_ciphers", TLS_Ciphersuites);
6✔
60

61
class TLS_Client_Hello_Reader final : public Command {
62
   public:
63
      TLS_Client_Hello_Reader() : Command("tls_client_hello --hex input") {}
4✔
64

65
      std::string group() const override { return "tls"; }
1✔
66

67
      std::string description() const override { return "Parse a TLS client hello message"; }
1✔
68

69
      void go() override {
1✔
70
         const std::string input_file = get_arg("input");
1✔
71
         std::vector<uint8_t> input;
1✔
72

73
         if(flag_set("hex")) {
1✔
74
            input = Botan::hex_decode(slurp_file_as_str(input_file));
3✔
75
         } else {
76
            input = slurp_file(input_file);
×
77
         }
78

79
         if(input.size() < 45) {
1✔
80
            error_output() << "Input too short to be valid\n";
×
81
            return;
82
         }
83

84
         // Input also contains the record layer header, strip it
85
         if(input[0] == 22) {
1✔
86
            const size_t len = Botan::make_uint16(input[3], input[4]);
1✔
87

88
            if(input.size() != len + 5) {
1✔
89
               error_output() << "Record layer length invalid\n";
×
90
               return;
91
            }
92

93
            input = std::vector<uint8_t>(input.begin() + 5, input.end());
2✔
94
         }
95

96
         // Assume the handshake header is there, strip it
97
         if(input[0] == 1) {
1✔
98
            const size_t hs_len = Botan::make_uint32(0, input[1], input[2], input[3]);
1✔
99

100
            if(input.size() != hs_len + 4) {
1✔
101
               error_output() << "Handshake layer length invalid\n";
×
102
               return;
103
            }
104

105
            input = std::vector<uint8_t>(input.begin() + 4, input.end());
2✔
106
         }
107

108
         try {
1✔
109
            // TODO: deal with Client_Hello_13
110
            Botan::TLS::Client_Hello_12 hello(input);
1✔
111

112
            output() << format_hello(hello);
3✔
113
         } catch(std::exception& e) { error_output() << "Parsing client hello failed: " << e.what() << "\n"; }
1✔
114
      }
1✔
115

116
   private:
117
      static std::string format_hello(const Botan::TLS::Client_Hello_12& hello) {
1✔
118
         std::ostringstream oss;
1✔
119
         oss << "Version: " << hello.legacy_version().to_string() << "\n"
2✔
120
             << "Random: " << Botan::hex_encode(hello.random()) << "\n";
3✔
121

122
         if(!hello.session_id().empty())
1✔
123
            oss << "SessionID: " << Botan::hex_encode(hello.session_id().get()) << "\n";
×
124
         for(uint16_t csuite_id : hello.ciphersuites()) {
30✔
125
            const auto csuite = Botan::TLS::Ciphersuite::by_id(csuite_id);
29✔
126
            if(csuite && csuite->valid())
29✔
127
               oss << "Cipher: " << csuite->to_string() << "\n";
75✔
128
            else if(csuite_id == 0x00FF)
4✔
129
               oss << "Cipher: EMPTY_RENEGOTIATION_INFO_SCSV\n";
×
130
            else
131
               oss << "Cipher: Unknown (" << std::hex << csuite_id << ")\n";
4✔
132
         }
133

134
         oss << "Supported signature schemes: ";
1✔
135

136
         if(hello.signature_schemes().empty()) {
2✔
137
            oss << "Did not send signature_algorithms extension\n";
×
138
         } else {
139
            for(Botan::TLS::Signature_Scheme scheme : hello.signature_schemes()) {
10✔
140
               try {
9✔
141
                  auto s = scheme.to_string();
9✔
142
                  oss << s << " ";
9✔
143
               } catch(...) { oss << "(" << std::hex << static_cast<unsigned int>(scheme.wire_code()) << ") "; }
9✔
144
            }
×
145
            oss << "\n";
1✔
146
         }
147

148
         std::map<std::string, bool> hello_flags;
1✔
149
         hello_flags["ALPN"] = hello.supports_alpn();
1✔
150
         hello_flags["Encrypt Then Mac"] = hello.supports_encrypt_then_mac();
1✔
151
         hello_flags["Extended Master Secret"] = hello.supports_extended_master_secret();
1✔
152
         hello_flags["Session Ticket"] = hello.supports_session_ticket();
1✔
153

154
         for(auto&& i : hello_flags)
5✔
155
            oss << "Supports " << i.first << "? " << (i.second ? "yes" : "no") << "\n";
5✔
156

157
         return oss.str();
2✔
158
      }
1✔
159
};
160

161
BOTAN_REGISTER_COMMAND("tls_client_hello", TLS_Client_Hello_Reader);
2✔
162

163
}  // namespace Botan_CLI
164

165
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc