Botan  2.4.0
Crypto and TLS for C++11
tls_ciphersuite.cpp
Go to the documentation of this file.
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 #include <botan/parsing.h>
10 #include <botan/block_cipher.h>
11 #include <botan/stream_cipher.h>
12 #include <botan/hash.h>
13 #include <algorithm>
14 
15 namespace Botan {
16 
17 namespace TLS {
18 
19 bool Ciphersuite::is_scsv(uint16_t suite)
20  {
21  // TODO: derive from IANA file in script
22  return (suite == 0x00FF || suite == 0x5600);
23  }
24 
26  {
27  return (kex_algo() == "PSK" ||
28  kex_algo() == "DHE_PSK" ||
29  kex_algo() == "ECDHE_PSK");
30  }
31 
33  {
34  return (sig_algo() == "ECDSA" || kex_algo() == "ECDH" || kex_algo() == "ECDHE_PSK");
35  }
36 
38  {
39  return (mac_algo() != "AEAD");
40  }
41 
43  {
44  const std::vector<Ciphersuite>& all_suites = all_known_ciphersuites();
45  auto s = std::lower_bound(all_suites.begin(), all_suites.end(), suite);
46 
47  if(s != all_suites.end() && s->ciphersuite_code() == suite)
48  {
49  return *s;
50  }
51 
52  return Ciphersuite(); // some unknown ciphersuite
53  }
54 
55 namespace {
56 
57 bool have_hash(const std::string& prf)
58  {
59  return (HashFunction::providers(prf).size() > 0);
60  }
61 
62 bool have_cipher(const std::string& cipher)
63  {
64  return (BlockCipher::providers(cipher).size() > 0) ||
65  (StreamCipher::providers(cipher).size() > 0);
66  }
67 
68 }
69 
70 bool Ciphersuite::is_usable() const
71  {
72  if(!m_cipher_keylen) // uninitialized object
73  return false;
74 
75  if(!have_hash(prf_algo()))
76  return false;
77 
78 #if !defined(BOTAN_HAS_TLS_CBC)
79  if(cbc_ciphersuite())
80  return false;
81 #endif
82 
83  if(mac_algo() == "AEAD")
84  {
85  if(cipher_algo() == "ChaCha20Poly1305")
86  {
87 #if !defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305)
88  return false;
89 #endif
90  }
91  else
92  {
93  auto cipher_and_mode = split_on(cipher_algo(), '/');
94  BOTAN_ASSERT(cipher_and_mode.size() == 2, "Expected format for AEAD algo");
95  if(!have_cipher(cipher_and_mode[0]))
96  return false;
97 
98  const auto mode = cipher_and_mode[1];
99 
100 #if !defined(BOTAN_HAS_AEAD_CCM)
101  if(mode == "CCM" || mode == "CCM-8")
102  return false;
103 #endif
104 
105 #if !defined(BOTAN_HAS_AEAD_GCM)
106  if(mode == "GCM")
107  return false;
108 #endif
109 
110 #if !defined(BOTAN_HAS_AEAD_OCB)
111  if(mode == "OCB(12)" || mode == "OCB")
112  return false;
113 #endif
114  }
115  }
116  else
117  {
118  // Old non-AEAD schemes
119  if(!have_cipher(cipher_algo()))
120  return false;
121  if(!have_hash(mac_algo())) // HMAC
122  return false;
123  }
124 
125  if(kex_algo() == "SRP_SHA")
126  {
127 #if !defined(BOTAN_HAS_SRP6)
128  return false;
129 #endif
130  }
131  else if(kex_algo() == "ECDH" || kex_algo() == "ECDHE_PSK")
132  {
133 #if !defined(BOTAN_HAS_ECDH)
134  return false;
135 #endif
136  }
137  else if(kex_algo() == "DH" || kex_algo() == "DHE_PSK")
138  {
139 #if !defined(BOTAN_HAS_DIFFIE_HELLMAN)
140  return false;
141 #endif
142  }
143  else if(kex_algo() == "CECPQ1")
144  {
145 #if !defined(BOTAN_HAS_CECPQ1)
146  return false;
147 #endif
148  }
149 
150  if(sig_algo() == "DSA")
151  {
152 #if !defined(BOTAN_HAS_DSA)
153  return false;
154 #endif
155  }
156  else if(sig_algo() == "ECDSA")
157  {
158 #if !defined(BOTAN_HAS_ECDSA)
159  return false;
160 #endif
161  }
162  else if(sig_algo() == "RSA")
163  {
164 #if !defined(BOTAN_HAS_RSA)
165  return false;
166 #endif
167  }
168 
169  return true;
170  }
171 
172 }
173 
174 }
175 
std::string mac_algo() const
std::string prf_algo() const
std::string kex_algo() const
std::vector< std::string > split_on(const std::string &str, char delim)
Definition: parsing.cpp:142
static bool is_scsv(uint16_t suite)
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:29
static std::vector< std::string > providers(const std::string &algo_spec)
static std::vector< std::string > providers(const std::string &algo_spec)
Definition: hash.cpp:355
Definition: alg_id.cpp:13
static std::vector< std::string > providers(const std::string &algo_spec)
std::string sig_algo() const
static Ciphersuite by_id(uint16_t suite)
std::string cipher_algo() const
static const std::vector< Ciphersuite > & all_known_ciphersuites()