aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2013-06-04 23:51:36 +0000
committerlloyd <[email protected]>2013-06-04 23:51:36 +0000
commit2e4a4e269d11fb27e71ff49b52d39e5c0ac9e9a1 (patch)
tree120d8559224343b4e945f9001103902b7c6dd5c3
parent4331c16ac6bd383a7caac97c501751d5be6ff996 (diff)
Have TLS::Ciphersuite::valid check that all algorithms are available,
which allows us to remove a number of algorithms as hard dependencies and instead simply allow their use if they are included in the build. Currently all key exchange algorithms (RSA, DH, ECDH, SRP) remain as hard dependencies as msg_{client,server}_key.cpp directly manipulate those types. While theoretically optional, MD5, SHA-1, SHA-2, and SSL3-MAC remain hard dependencies as their availability affects protocol support as well as ciphersuites, though in principle being able to disable MD5/SHA-1 and requiring v1.2 or higher would be useful.
-rw-r--r--src/tls/info.txt13
-rw-r--r--src/tls/tls_ciphersuite.cpp92
2 files changed, 84 insertions, 21 deletions
diff --git a/src/tls/info.txt b/src/tls/info.txt
index c1f2dfb36..669dcc781 100644
--- a/src/tls/info.txt
+++ b/src/tls/info.txt
@@ -2,11 +2,6 @@ define TLS
load_on auto
-<warning>
-The TLS code is complex, new, and not yet reviewed, there may be
-serious bugs or security issues.
-</warning>
-
<header:public>
tls_alert.h
tls_blocking.h
@@ -70,29 +65,23 @@ tls_version.cpp
</source>
<requires>
+aead
aes
asn1
-camellia
cbc
credentials
cryptobox
-des
dh
-dsa
ecdh
-ecdsa
eme_pkcs
emsa3
hmac
-gcm
kdf2
md5
prf_ssl3
prf_tls
-rc4
rng
rsa
-seed
sha1
sha2_32
srp6
diff --git a/src/tls/tls_ciphersuite.cpp b/src/tls/tls_ciphersuite.cpp
index 1dde8514e..841ce72e8 100644
--- a/src/tls/tls_ciphersuite.cpp
+++ b/src/tls/tls_ciphersuite.cpp
@@ -1,11 +1,12 @@
/*
* TLS Cipher Suite
-* (C) 2004-2010,2012 Jack Lloyd
+* (C) 2004-2010,2012,2013 Jack Lloyd
*
* Released under the terms of the Botan license
*/
#include <botan/tls_ciphersuite.h>
+#include <botan/libstate.h>
#include <botan/parsing.h>
#include <sstream>
#include <stdexcept>
@@ -24,14 +25,12 @@ std::vector<Ciphersuite> gather_known_ciphersuites()
{
std::vector<Ciphersuite> ciphersuites;
- for(size_t i = 0; i != 65536; ++i)
+ for(size_t i = 0; i <= 0xFFFF; ++i)
{
Ciphersuite suite = Ciphersuite::by_id(i);
- if(!suite.valid())
- continue; // not a ciphersuite we know, skip
-
- ciphersuites.push_back(suite);
+ if(suite.valid())
+ ciphersuites.push_back(suite);
}
return ciphersuites;
@@ -86,15 +85,90 @@ bool Ciphersuite::psk_ciphersuite() const
bool Ciphersuite::ecc_ciphersuite() const
{
- return (kex_algo() == "ECDH" || sig_algo() == "ECDSA");
+ return (sig_algo() == "ECDSA" || kex_algo() == "ECDH" || kex_algo() == "ECDHE_PSK");
}
bool Ciphersuite::valid() const
{
- if(!m_cipher_keylen)
+ if(!m_cipher_keylen) // uninitialized object
+ return false;
+
+ Algorithm_Factory& af = global_state().algorithm_factory();
+
+ if(!af.prototype_hash_function(prf_algo()))
return false;
- // fixme: check that all sub-algorithms are enabled
+ if(mac_algo() == "AEAD")
+ {
+ auto cipher_and_mode = split_on(cipher_algo(), '/');
+ BOTAN_ASSERT(cipher_and_mode.size() == 2, "Expected format for AEAD algo");
+ if(!af.prototype_block_cipher(cipher_and_mode[0]))
+ return false;
+
+ const auto mode = cipher_and_mode[1];
+
+#if !defined(BOTAN_HAS_AEAD_CCM)
+ if(mode == "CCM")
+ return false;
+#endif
+
+#if !defined(BOTAN_HAS_AEAD_GCM)
+ if(mode == "GCM")
+ return false;
+#endif
+
+#if !defined(BOTAN_HAS_AEAD_OCB)
+ if(mode == "OCB")
+ return false;
+#endif
+ }
+ else
+ {
+ if(!af.prototype_block_cipher(cipher_algo()) &&
+ !af.prototype_stream_cipher(cipher_algo()))
+ return false;
+
+ if(!af.prototype_hash_function(mac_algo()))
+ return false;
+ }
+
+ if(kex_algo() == "SRP_SHA")
+ {
+#if !defined(BOTAN_HAS_SRP6)
+ return false;
+#endif
+ }
+ else if(kex_algo() == "ECDH" || kex_algo() == "ECDHE_PSK")
+ {
+#if !defined(BOTAN_HAS_ECDH)
+ return false;
+#endif
+ }
+ else if(kex_algo() == "DH" || kex_algo() == "DHE_PSK")
+ {
+#if !defined(BOTAN_HAS_DIFFIE_HELLMAN)
+ return false;
+#endif
+ }
+
+ if(sig_algo() == "DSA")
+ {
+#if !defined(BOTAN_HAS_DSA)
+ return false;
+#endif
+ }
+ else if(sig_algo() == "ECDSA")
+ {
+#if !defined(BOTAN_HAS_ECDSA)
+ return false;
+#endif
+ }
+ else if(sig_algo() == "RSA")
+ {
+#if !defined(BOTAN_HAS_RSA)
+ return false;
+#endif
+ }
return true;
}