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

randombit / botan / 5134090420

31 May 2023 03:12PM UTC coverage: 91.721% (-0.3%) from 91.995%
5134090420

push

github

randombit
Merge GH #3565 Disable noisy/pointless pylint warnings

76048 of 82912 relevant lines covered (91.72%)

11755290.1 hits per line

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

86.58
/src/lib/tls/tls_text_policy.cpp
1
/*
2
* Text-Based TLS Policy
3
* (C) 2016,2017 Jack Lloyd
4
*     2017 Harry Reimann, Rohde & Schwarz Cybersecurity
5
*
6
* Botan is released under the Simplified BSD License (see license.txt)
7
*/
8

9
#include <botan/tls_policy.h>
10

11
#include <botan/exceptn.h>
12
#include <botan/internal/parsing.h>
13
#include <optional>
14
#include <sstream>
15

16
namespace Botan::TLS {
17

18
std::vector<std::string> Text_Policy::allowed_ciphers() const { return get_list("ciphers", Policy::allowed_ciphers()); }
52,210✔
19

20
std::vector<std::string> Text_Policy::allowed_signature_hashes() const {
4,561✔
21
   return get_list("signature_hashes", Policy::allowed_signature_hashes());
9,122✔
22
}
23

24
std::vector<std::string> Text_Policy::allowed_macs() const { return get_list("macs", Policy::allowed_macs()); }
6,576✔
25

26
std::vector<std::string> Text_Policy::allowed_key_exchange_methods() const {
334✔
27
   return get_list("key_exchange_methods", Policy::allowed_key_exchange_methods());
668✔
28
}
29

30
std::vector<std::string> Text_Policy::allowed_signature_methods() const {
4,504✔
31
   return get_list("signature_methods", Policy::allowed_signature_methods());
9,008✔
32
}
33

34
bool Text_Policy::use_ecc_point_compression() const {
252✔
35
   return get_bool("use_ecc_point_compression", Policy::use_ecc_point_compression());
504✔
36
}
37

38
bool Text_Policy::allow_tls12() const { return get_bool("allow_tls12", Policy::allow_tls12()); }
904✔
39

40
bool Text_Policy::allow_tls13() const { return get_bool("allow_tls13", Policy::allow_tls13()); }
290✔
41

42
bool Text_Policy::allow_dtls12() const { return get_bool("allow_dtls12", Policy::allow_dtls12()); }
219✔
43

44
bool Text_Policy::allow_insecure_renegotiation() const {
221✔
45
   return get_bool("allow_insecure_renegotiation", Policy::allow_insecure_renegotiation());
442✔
46
}
47

48
bool Text_Policy::include_time_in_hello_random() const {
522✔
49
   return get_bool("include_time_in_hello_random", Policy::include_time_in_hello_random());
1,044✔
50
}
51

52
bool Text_Policy::require_client_certificate_authentication() const {
113✔
53
   return get_bool("require_client_certificate_authentication", Policy::require_client_certificate_authentication());
226✔
54
}
55

56
bool Text_Policy::allow_client_initiated_renegotiation() const {
×
57
   return get_bool("allow_client_initiated_renegotiation", Policy::allow_client_initiated_renegotiation());
×
58
}
59

60
bool Text_Policy::allow_server_initiated_renegotiation() const {
6✔
61
   return get_bool("allow_server_initiated_renegotiation", Policy::allow_server_initiated_renegotiation());
12✔
62
}
63

64
bool Text_Policy::server_uses_own_ciphersuite_preferences() const {
156✔
65
   return get_bool("server_uses_own_ciphersuite_preferences", Policy::server_uses_own_ciphersuite_preferences());
312✔
66
}
67

68
bool Text_Policy::negotiate_encrypt_then_mac() const {
151✔
69
   return get_bool("negotiate_encrypt_then_mac", Policy::negotiate_encrypt_then_mac());
302✔
70
}
71

72
std::optional<uint16_t> Text_Policy::record_size_limit() const {
53✔
73
   const auto limit = get_len("record_size_limit", 0);
53✔
74
   // RFC 8449 4.
75
   //    TLS 1.3 uses a limit of 2^14+1 octets.
76
   BOTAN_ARG_CHECK(limit <= 16385, "record size limit too large");
53✔
77
   return (limit > 0) ? std::make_optional(static_cast<uint16_t>(limit)) : std::nullopt;
53✔
78
}
79

80
bool Text_Policy::support_cert_status_message() const {
306✔
81
   return get_bool("support_cert_status_message", Policy::support_cert_status_message());
612✔
82
}
83

84
std::vector<Group_Params> Text_Policy::key_exchange_groups() const {
620✔
85
   std::string group_str = get_str("key_exchange_groups");
1,240✔
86

87
   if(group_str.empty()) {
620✔
88
      // fall back to previously used name
89
      group_str = get_str("groups");
572✔
90
   }
91

92
   if(group_str.empty()) {
620✔
93
      return Policy::key_exchange_groups();
502✔
94
   }
95

96
   return read_group_list(group_str);
118✔
97
}
620✔
98

99
std::vector<Group_Params> Text_Policy::key_exchange_groups_to_offer() const {
48✔
100
   std::string group_str = get_str("key_exchange_groups_to_offer", "notset");
96✔
101

102
   if(group_str.empty() || group_str == "notset") {
48✔
103
      // policy was not set, fall back to default behaviour
104
      return Policy::key_exchange_groups_to_offer();
28✔
105
   }
106

107
   if(group_str == "none") {
20✔
108
      return {};
48✔
109
   }
110

111
   return read_group_list(group_str);
18✔
112
}
48✔
113

114
size_t Text_Policy::minimum_ecdh_group_size() const {
225✔
115
   return get_len("minimum_ecdh_group_size", Policy::minimum_ecdh_group_size());
450✔
116
}
117

118
size_t Text_Policy::minimum_ecdsa_group_size() const {
69✔
119
   return get_len("minimum_ecdsa_group_size", Policy::minimum_ecdsa_group_size());
138✔
120
}
121

122
size_t Text_Policy::minimum_dh_group_size() const {
16✔
123
   return get_len("minimum_dh_group_size", Policy::minimum_dh_group_size());
32✔
124
}
125

126
size_t Text_Policy::minimum_rsa_bits() const { return get_len("minimum_rsa_bits", Policy::minimum_rsa_bits()); }
94✔
127

128
size_t Text_Policy::minimum_signature_strength() const {
9✔
129
   return get_len("minimum_signature_strength", Policy::minimum_signature_strength());
18✔
130
}
131

132
size_t Text_Policy::dtls_default_mtu() const { return get_len("dtls_default_mtu", Policy::dtls_default_mtu()); }
248✔
133

134
size_t Text_Policy::dtls_initial_timeout() const {
×
135
   return get_len("dtls_initial_timeout", Policy::dtls_initial_timeout());
×
136
}
137

138
size_t Text_Policy::dtls_maximum_timeout() const {
×
139
   return get_len("dtls_maximum_timeout", Policy::dtls_maximum_timeout());
×
140
}
141

142
bool Text_Policy::require_cert_revocation_info() const {
96✔
143
   return get_bool("require_cert_revocation_info", Policy::require_cert_revocation_info());
192✔
144
}
145

146
bool Text_Policy::hide_unknown_users() const { return get_bool("hide_unknown_users", Policy::hide_unknown_users()); }
12✔
147

148
size_t Text_Policy::maximum_session_tickets_per_client_hello() const {
308✔
149
   return get_len("maximum_session_tickets_per_client_hello", Policy::maximum_session_tickets_per_client_hello());
616✔
150
}
151

152
std::chrono::seconds Text_Policy::session_ticket_lifetime() const {
362✔
153
   return get_duration("session_ticket_lifetime", Policy::session_ticket_lifetime());
724✔
154
}
155

156
bool Text_Policy::reuse_session_tickets() const {
157✔
157
   return get_bool("reuse_session_tickets", Policy::reuse_session_tickets());
314✔
158
}
159

160
size_t Text_Policy::new_session_tickets_upon_handshake_success() const {
21✔
161
   return get_len("new_session_tickets_upon_handshake_success", Policy::new_session_tickets_upon_handshake_success());
42✔
162
}
163

164
std::vector<uint16_t> Text_Policy::srtp_profiles() const {
116✔
165
   std::vector<uint16_t> r;
116✔
166
   for(const auto& p : get_list("srtp_profiles", std::vector<std::string>())) {
116✔
167
      r.push_back(to_uint16(p));
×
168
   }
116✔
169
   return r;
116✔
170
}
×
171

172
bool Text_Policy::tls_13_middlebox_compatibility_mode() const {
81✔
173
   return get_bool("tls_13_middlebox_compatibility_mode", Policy::tls_13_middlebox_compatibility_mode());
162✔
174
}
175

176
bool Text_Policy::hash_hello_random() const { return get_bool("hash_hello_random", Policy::hash_hello_random()); }
1,044✔
177

178
void Text_Policy::set(const std::string& key, const std::string& value) { m_kv[key] = value; }
162✔
179

180
Text_Policy::Text_Policy(std::string_view s) {
57✔
181
   std::istringstream iss{std::string(s)};  // FIXME C++23 avoid copy
114✔
182
   m_kv = read_cfg(iss);
57✔
183
}
57✔
184

185
Text_Policy::Text_Policy(std::istream& in) : m_kv(read_cfg(in)) {}
21✔
186

187
std::vector<std::string> Text_Policy::get_list(const std::string& key, const std::vector<std::string>& def) const {
38,908✔
188
   const std::string v = get_str(key);
38,908✔
189

190
   if(v.empty()) {
38,908✔
191
      return def;
18,122✔
192
   }
193

194
   return split_on(v, ' ');
20,786✔
195
}
38,908✔
196

197
std::vector<Group_Params> Text_Policy::read_group_list(std::string_view group_str) const {
136✔
198
   std::vector<Group_Params> groups;
136✔
199
   for(const auto& group_name : split_on(group_str, ' ')) {
534✔
200
      Group_Params group_id = group_param_from_string(group_name);
398✔
201

202
#if !defined(BOTAN_HAS_CURVE_25519)
203
      if(group_id == Group_Params::X25519)
204
         continue;
205
#endif
206

207
      if(group_id == Group_Params::NONE) {
398✔
208
         try {
16✔
209
            size_t consumed = 0;
16✔
210
            unsigned long ll_id = std::stoul(group_name, &consumed, 0);
16✔
211
            if(consumed != group_name.size()) {
16✔
212
               continue;  // some other cruft
×
213
            }
214

215
            const uint16_t id = static_cast<uint16_t>(ll_id);
16✔
216

217
            if(id != ll_id) {
16✔
218
               continue;  // integer too large
×
219
            }
220

221
            group_id = static_cast<Group_Params>(id);
16✔
222
         } catch(...) {
×
223
            continue;
×
224
         }
×
225
      }
226

227
      if(group_id != Group_Params::NONE) {
398✔
228
         groups.push_back(group_id);
398✔
229
      }
230
   }
136✔
231

232
   return groups;
136✔
233
}
×
234

235
size_t Text_Policy::get_len(const std::string& key, size_t def) const {
1,234✔
236
   const std::string v = get_str(key);
1,234✔
237

238
   if(v.empty()) {
1,234✔
239
      return def;
240
   }
241

242
   return to_u32bit(v);
76✔
243
}
1,234✔
244

245
std::chrono::seconds Text_Policy::get_duration(const std::string& key, std::chrono::seconds def) const {
362✔
246
   using rep_t = std::chrono::seconds::rep;
362✔
247
   constexpr rep_t max_seconds = std::chrono::seconds::max().count();
362✔
248
   constexpr auto max_sizet = std::numeric_limits<size_t>::max();
362✔
249
   using ull = unsigned long long;
362✔
250

251
   // The concrete type of `rep` is not specified exactly. Let's play it extra safe...
252
   // e.g. on 32-bit platforms size_t is 32 bits but rep_t is "at least 35 bits"
253

254
   // at least zero and certainly fitting into rep_t
255
   const rep_t positive_default = std::max(def.count(), rep_t(0));
362✔
256
   // at least zero but capped to whatever size_t can handle
257
   const size_t positive_capped_default = static_cast<size_t>(std::min<ull>(positive_default, max_sizet));
362✔
258
   // at least zero but capped to whatever rep_t can handle
259
   const rep_t result = static_cast<rep_t>(std::min<ull>(get_len(key, positive_capped_default), max_seconds));
362✔
260

261
   return std::chrono::seconds(result);
362✔
262
}
263

264
bool Text_Policy::get_bool(const std::string& key, bool def) const {
4,002✔
265
   const std::string v = get_str(key);
4,002✔
266

267
   if(v.empty()) {
4,002✔
268
      return def;
269
   }
270

271
   if(v == "true" || v == "True") {
1,323✔
272
      return true;
273
   } else if(v == "false" || v == "False") {
252✔
274
      return false;
275
   } else {
276
      throw Decoding_Error("Invalid boolean '" + v + "'");
×
277
   }
278
}
4,002✔
279

280
std::string Text_Policy::get_str(const std::string& key, const std::string& def) const {
45,384✔
281
   auto i = m_kv.find(key);
45,384✔
282
   if(i == m_kv.end()) {
45,384✔
283
      return def;
23,061✔
284
   }
285

286
   return i->second;
22,323✔
287
}
288

289
bool Text_Policy::set_value(const std::string& key, std::string_view val, bool overwrite) {
×
290
   auto i = m_kv.find(key);
×
291

292
   if(overwrite == false && i != m_kv.end()) {
×
293
      return false;
294
   }
295

296
   m_kv.insert(i, std::make_pair(key, val));
×
297
   return true;
×
298
}
299

300
}  // namespace Botan::TLS
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

© 2026 Coveralls, Inc