Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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
26 bool Ciphersuite::psk_ciphersuite() const
27 {
28 return (kex_algo() == "PSK" ||
29 kex_algo() == "DHE_PSK" ||
30 kex_algo() == "ECDHE_PSK");
31 }
32
33 bool Ciphersuite::ecc_ciphersuite() const
34 {
35 return (sig_algo() == "ECDSA" || kex_algo() == "ECDH" || kex_algo() == "ECDHE_PSK");
36 }
37
38 bool Ciphersuite::cbc_ciphersuite() const
39 {
40 return (mac_algo() != "AEAD");
41 }
42
43 Ciphersuite Ciphersuite::by_id(uint16_t suite)
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
Botan::TLS::Ciphersuite::cbc_ciphersuite
bool cbc_ciphersuite() const
Definition: tls_ciphersuite.cpp:38
Botan::TLS::Ciphersuite::psk_ciphersuite
bool psk_ciphersuite() const
Definition: tls_ciphersuite.cpp:26
Botan::TLS::Ciphersuite::sig_algo
std::string sig_algo() const
Definition: tls_ciphersuite.h:78
Botan::TLS::Ciphersuite::is_scsv
static bool is_scsv(uint16_t suite)
Definition: tls_ciphersuite.cpp:20
Botan::split_on
std::vector< std::string > split_on(const std::string &str, char delim)
Definition: parsing.cpp:138
Botan::TLS::Ciphersuite
Definition: tls_ciphersuite.h:22
BOTAN_ASSERT
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:27
Botan::BlockCipher::providers
static std::vector< std::string > providers(const std::string &algo_spec)
Definition: block_cipher.cpp:295
Botan::TLS::Ciphersuite::ecc_ciphersuite
bool ecc_ciphersuite() const
Definition: tls_ciphersuite.cpp:33
Botan::TLS::Ciphersuite::prf_algo
std::string prf_algo() const
Definition: tls_ciphersuite.h:90
Botan::TLS::Ciphersuite::kex_algo
std::string kex_algo() const
Definition: tls_ciphersuite.h:73
Botan::HashFunction::providers
static std::vector< std::string > providers(const std::string &algo_spec)
Definition: hash.cpp:313
Botan
Definition: alg_id.cpp:13
Botan::StreamCipher::providers
static std::vector< std::string > providers(const std::string &algo_spec)
Definition: stream_cipher.cpp:133
Botan::TLS::Ciphersuite::Ciphersuite
Ciphersuite()=default
Botan::TLS::Ciphersuite::by_id
static Ciphersuite by_id(uint16_t suite)
Definition: tls_ciphersuite.cpp:43
Botan::TLS::Ciphersuite::mac_algo
std::string mac_algo() const
Definition: tls_ciphersuite.h:88
Botan::TLS::Ciphersuite::cipher_algo
std::string cipher_algo() const
Definition: tls_ciphersuite.h:83
Botan::TLS::Ciphersuite::all_known_ciphersuites
static const std::vector< Ciphersuite > & all_known_ciphersuites()
Definition: tls_suite_info.cpp:18