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

randombit / botan / 5079590438

25 May 2023 12:28PM UTC coverage: 92.228% (+0.5%) from 91.723%
5079590438

Pull #3502

github

Pull Request #3502: Apply clang-format to the codebase

75589 of 81959 relevant lines covered (92.23%)

12139530.51 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
      case Nonce_Format::AEAD_IMPLICIT_4:
28
         return 4;
29
      case Nonce_Format::AEAD_XOR_12:
3,532✔
30
         return 12;
3,532✔
31
   }
32

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

102
   return std::nullopt;  // some unknown ciphersuite
×
103
}
104

105
namespace {
106

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

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

113
}
114

115
bool Ciphersuite::is_usable() const {
183,300✔
116
   if(!m_cipher_keylen)  // uninitialized object
183,300✔
117
      return false;
118

119
   if(!have_hash(prf_algo()))
183,300✔
120
      return false;
121

122
#if !defined(BOTAN_HAS_TLS_CBC)
123
   if(cbc_ciphersuite())
124
      return false;
125
#endif
126

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

138
         const auto mode = cipher_and_mode[1];
226,200✔
139

140
#if !defined(BOTAN_HAS_AEAD_CCM)
141
         if(mode == "CCM" || mode == "CCM-8")
142
            return false;
143
#endif
144

145
#if !defined(BOTAN_HAS_AEAD_GCM)
146
         if(mode == "GCM")
147
            return false;
148
#endif
149

150
#if !defined(BOTAN_HAS_AEAD_OCB)
151
         if(mode == "OCB(12)" || mode == "OCB")
152
            return false;
153
#endif
154
      }
113,100✔
155
   } else {
156
      // Old non-AEAD schemes
157
      if(!have_cipher(cipher_algo()))
58,500✔
158
         return false;
159
      if(!have_hash(mac_algo()))  // HMAC
58,500✔
160
         return false;
161
   }
162

163
   if(kex_method() == Kex_Algo::ECDH || kex_method() == Kex_Algo::ECDHE_PSK) {
183,300✔
164
#if !defined(BOTAN_HAS_ECDH)
165
      return false;
166
#endif
167
   } else if(kex_method() == Kex_Algo::DH) {
168
#if !defined(BOTAN_HAS_DIFFIE_HELLMAN)
169
      return false;
170
#endif
171
   }
172

173
   if(auth_method() == Auth_Method::ECDSA) {
183,300✔
174
#if !defined(BOTAN_HAS_ECDSA)
175
      return false;
176
#endif
177
   } else if(auth_method() == Auth_Method::RSA) {
178
#if !defined(BOTAN_HAS_RSA)
179
      return false;
180
#endif
181
   }
182

183
   return true;
184
}
185

186
}
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