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

randombit / botan / 5123321399

30 May 2023 04:06PM UTC coverage: 92.213% (+0.004%) from 92.209%
5123321399

Pull #3558

github

web-flow
Merge dd72f7389 into 057bcbc35
Pull Request #3558: Add braces around all if/else statements

75602 of 81986 relevant lines covered (92.21%)

11859779.3 hits per line

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

93.1
/src/lib/tls/tls_ciphersuite.cpp
1
/*
2
* TLS Cipher Suite
3
* (C) 2004-2010,2012,2013 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include <botan/tls_ciphersuite.h>
9

10
#include <botan/block_cipher.h>
11
#include <botan/exceptn.h>
12
#include <botan/hash.h>
13
#include <botan/stream_cipher.h>
14
#include <botan/internal/parsing.h>
15
#include <algorithm>
16

17
namespace Botan::TLS {
18

19
size_t Ciphersuite::nonce_bytes_from_handshake() const {
5,338✔
20
   switch(m_nonce_format) {
5,338✔
21
      case Nonce_Format::CBC_MODE: {
753✔
22
         if(cipher_algo() == "3DES") {
753✔
23
            return 8;
24
         } else {
25
            return 16;
599✔
26
         }
27
      }
28
      case Nonce_Format::AEAD_IMPLICIT_4:
29
         return 4;
30
      case Nonce_Format::AEAD_XOR_12:
3,532✔
31
         return 12;
3,532✔
32
   }
33

34
   throw Invalid_State("In Ciphersuite::nonce_bytes_from_handshake invalid enum value");
×
35
}
36

37
size_t Ciphersuite::nonce_bytes_from_record(Protocol_Version version) const {
3,507✔
38
   BOTAN_UNUSED(version);
3,507✔
39
   switch(m_nonce_format) {
3,507✔
40
      case Nonce_Format::CBC_MODE:
499✔
41
         return cipher_algo() == "3DES" ? 8 : 16;
898✔
42
      case Nonce_Format::AEAD_IMPLICIT_4:
43
         return 8;
44
      case Nonce_Format::AEAD_XOR_12:
2,306✔
45
         return 0;
2,306✔
46
   }
47

48
   throw Invalid_State("In Ciphersuite::nonce_bytes_from_handshake invalid enum value");
×
49
}
50

51
bool Ciphersuite::is_scsv(uint16_t suite) {
1,200✔
52
   // TODO: derive from IANA file in script
53
   return (suite == 0x00FF || suite == 0x5600);
1,200✔
54
}
55

56
bool Ciphersuite::psk_ciphersuite() const {
2,527✔
57
   return kex_method() == Kex_Algo::PSK || kex_method() == Kex_Algo::ECDHE_PSK;
2,527✔
58
}
59

60
bool Ciphersuite::ecc_ciphersuite() const {
945✔
61
   return kex_method() == Kex_Algo::ECDH || kex_method() == Kex_Algo::ECDHE_PSK || auth_method() == Auth_Method::ECDSA;
945✔
62
}
63

64
bool Ciphersuite::usable_in_version(Protocol_Version version) const {
346,023✔
65
   // RFC 8446 B.4.:
66
   //   Although TLS 1.3 uses the same cipher suite space as previous
67
   //   versions of TLS, TLS 1.3 cipher suites are defined differently, only
68
   //   specifying the symmetric ciphers, and cannot be used for TLS 1.2.
69
   //   Similarly, cipher suites for TLS 1.2 and lower cannot be used with
70
   //   TLS 1.3.
71
   //
72
   // Currently cipher suite codes {0x13,0x01} through {0x13,0x05} are
73
   // allowed for TLS 1.3. This may change in the future.
74
   const auto is_legacy_suite = (ciphersuite_code() & 0xFF00) != 0x1300;
346,023✔
75
   return version.is_pre_tls_13() == is_legacy_suite;
346,023✔
76
}
77

78
bool Ciphersuite::cbc_ciphersuite() const { return (mac_algo() != "AEAD"); }
776✔
79

80
bool Ciphersuite::aead_ciphersuite() const { return (mac_algo() == "AEAD"); }
1,200✔
81

82
bool Ciphersuite::signature_used() const { return auth_method() != Auth_Method::IMPLICIT; }
5,709✔
83

84
std::optional<Ciphersuite> Ciphersuite::by_id(uint16_t suite) {
78,075✔
85
   const std::vector<Ciphersuite>& all_suites = all_known_ciphersuites();
78,075✔
86
   auto s = std::lower_bound(all_suites.begin(), all_suites.end(), suite);
78,075✔
87

88
   if(s != all_suites.end() && s->ciphersuite_code() == suite) {
78,075✔
89
      return *s;
12,587✔
90
   }
91

92
   return std::nullopt;  // some unknown ciphersuite
65,488✔
93
}
94

95
std::optional<Ciphersuite> Ciphersuite::from_name(std::string_view name) {
89✔
96
   const std::vector<Ciphersuite>& all_suites = all_known_ciphersuites();
89✔
97

98
   for(auto suite : all_suites) {
2,378✔
99
      if(suite.to_string() == name) {
7,326✔
100
         return suite;
89✔
101
      }
102
   }
103

104
   return std::nullopt;  // some unknown ciphersuite
×
105
}
106

107
namespace {
108

109
bool have_hash(std::string_view prf) { return (!HashFunction::providers(prf).empty()); }
241,800✔
110

111
bool have_cipher(std::string_view cipher) {
171,600✔
112
   return (!BlockCipher::providers(cipher).empty()) || (!StreamCipher::providers(cipher).empty());
171,600✔
113
}
114

115
}  // namespace
116

117
bool Ciphersuite::is_usable() const {
183,300✔
118
   if(!m_cipher_keylen) {  // uninitialized object
183,300✔
119
      return false;
120
   }
121

122
   if(!have_hash(prf_algo())) {
183,300✔
123
      return false;
124
   }
125

126
#if !defined(BOTAN_HAS_TLS_CBC)
127
   if(cbc_ciphersuite())
128
      return false;
129
#endif
130

131
   if(mac_algo() == "AEAD") {
183,300✔
132
      if(cipher_algo() == "ChaCha20Poly1305") {
156,000✔
133
#if !defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305)
134
         return false;
135
#endif
136
      } else {
137
         auto cipher_and_mode = split_on(cipher_algo(), '/');
113,100✔
138
         BOTAN_ASSERT(cipher_and_mode.size() == 2, "Expected format for AEAD algo");
113,100✔
139
         if(!have_cipher(cipher_and_mode[0])) {
113,100✔
140
            return false;
×
141
         }
142

143
         const auto mode = cipher_and_mode[1];
226,200✔
144

145
#if !defined(BOTAN_HAS_AEAD_CCM)
146
         if(mode == "CCM" || mode == "CCM-8")
147
            return false;
148
#endif
149

150
#if !defined(BOTAN_HAS_AEAD_GCM)
151
         if(mode == "GCM")
152
            return false;
153
#endif
154

155
#if !defined(BOTAN_HAS_AEAD_OCB)
156
         if(mode == "OCB(12)" || mode == "OCB")
157
            return false;
158
#endif
159
      }
113,100✔
160
   } else {
161
      // Old non-AEAD schemes
162
      if(!have_cipher(cipher_algo())) {
58,500✔
163
         return false;
164
      }
165
      if(!have_hash(mac_algo())) {  // HMAC
58,500✔
166
         return false;
167
      }
168
   }
169

170
   if(kex_method() == Kex_Algo::ECDH || kex_method() == Kex_Algo::ECDHE_PSK) {
183,300✔
171
#if !defined(BOTAN_HAS_ECDH)
172
      return false;
173
#endif
174
   } else if(kex_method() == Kex_Algo::DH) {
175
#if !defined(BOTAN_HAS_DIFFIE_HELLMAN)
176
      return false;
177
#endif
178
   }
179

180
   if(auth_method() == Auth_Method::ECDSA) {
183,300✔
181
#if !defined(BOTAN_HAS_ECDSA)
182
      return false;
183
#endif
184
   } else if(auth_method() == Auth_Method::RSA) {
185
#if !defined(BOTAN_HAS_RSA)
186
      return false;
187
#endif
188
   }
189

190
   return true;
191
}
192

193
}  // 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