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

randombit / botan / 5133556677

31 May 2023 02:11PM UTC coverage: 91.735% (-0.3%) from 92.012%
5133556677

Pull #3568

github

web-flow
Merge de48a2eb6 into 1cbeffafb
Pull Request #3568: Change clang-format AllowShortBlocksOnASingleLine from true to Empty

76059 of 82912 relevant lines covered (91.73%)

12004312.75 hits per line

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

80.0
/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) {
1✔
114
            error_output() << "Parsing client hello failed: " << e.what() << "\n";
×
115
         }
×
116
      }
1✔
117

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

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

138
         oss << "Supported signature schemes: ";
1✔
139

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

154
         std::map<std::string, bool> hello_flags;
1✔
155
         hello_flags["ALPN"] = hello.supports_alpn();
1✔
156
         hello_flags["Encrypt Then Mac"] = hello.supports_encrypt_then_mac();
1✔
157
         hello_flags["Extended Master Secret"] = hello.supports_extended_master_secret();
1✔
158
         hello_flags["Session Ticket"] = hello.supports_session_ticket();
1✔
159

160
         for(auto&& i : hello_flags) {
5✔
161
            oss << "Supports " << i.first << "? " << (i.second ? "yes" : "no") << "\n";
5✔
162
         }
163

164
         return oss.str();
2✔
165
      }
1✔
166
};
167

168
BOTAN_REGISTER_COMMAND("tls_client_hello", TLS_Client_Hello_Reader);
2✔
169

170
}  // namespace Botan_CLI
171

172
#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