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