aboutsummaryrefslogtreecommitdiffstats
path: root/src/tls/tls_suites.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tls/tls_suites.cpp')
-rw-r--r--src/tls/tls_suites.cpp281
1 files changed, 281 insertions, 0 deletions
diff --git a/src/tls/tls_suites.cpp b/src/tls/tls_suites.cpp
new file mode 100644
index 000000000..07cbec608
--- /dev/null
+++ b/src/tls/tls_suites.cpp
@@ -0,0 +1,281 @@
+/*
+* TLS Cipher Suites
+* (C) 2004-2010 Jack Lloyd
+*
+* Released under the terms of the Botan license
+*/
+
+#include <botan/tls_suites.h>
+#include <botan/tls_exceptn.h>
+
+namespace Botan {
+
+/**
+* Convert an SSL/TLS ciphersuite to algorithm fields
+*/
+TLS_Ciphersuite_Algos CipherSuite::lookup_ciphersuite(u16bit suite)
+ {
+ if(suite == TLS_RSA_WITH_RC4_128_MD5)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
+ TLS_ALGO_KEYEXCH_NOKEX |
+ TLS_ALGO_MAC_MD5 |
+ TLS_ALGO_CIPHER_RC4_128);
+
+ if(suite == TLS_RSA_WITH_RC4_128_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
+ TLS_ALGO_KEYEXCH_NOKEX |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_RC4_128);
+
+ if(suite == TLS_RSA_WITH_3DES_EDE_CBC_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
+ TLS_ALGO_KEYEXCH_NOKEX |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_3DES_CBC);
+
+ if(suite == TLS_RSA_WITH_AES_128_CBC_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
+ TLS_ALGO_KEYEXCH_NOKEX |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_AES128_CBC);
+
+ if(suite == TLS_RSA_WITH_AES_256_CBC_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
+ TLS_ALGO_KEYEXCH_NOKEX |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_AES256_CBC);
+
+ if(suite == TLS_RSA_WITH_SEED_CBC_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
+ TLS_ALGO_KEYEXCH_NOKEX |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_SEED_CBC);
+
+ if(suite == TLS_RSA_WITH_AES_128_CBC_SHA256)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
+ TLS_ALGO_KEYEXCH_NOKEX |
+ TLS_ALGO_MAC_SHA256 |
+ TLS_ALGO_CIPHER_AES128_CBC);
+
+ if(suite == TLS_RSA_WITH_AES_256_CBC_SHA256)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
+ TLS_ALGO_KEYEXCH_NOKEX |
+ TLS_ALGO_MAC_SHA256 |
+ TLS_ALGO_CIPHER_AES256_CBC);
+
+ if(suite == TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_DSA |
+ TLS_ALGO_KEYEXCH_DH |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_3DES_CBC);
+
+ if(suite == TLS_DHE_DSS_WITH_AES_128_CBC_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_DSA |
+ TLS_ALGO_KEYEXCH_DH |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_AES128_CBC);
+
+ if(suite == TLS_DHE_DSS_WITH_SEED_CBC_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_DSA |
+ TLS_ALGO_KEYEXCH_DH |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_SEED_CBC);
+
+ if(suite == TLS_DHE_DSS_WITH_AES_256_CBC_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_DSA |
+ TLS_ALGO_KEYEXCH_DH |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_AES256_CBC);
+
+ if(suite == TLS_DHE_DSS_WITH_AES_128_CBC_SHA256)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_DSA |
+ TLS_ALGO_KEYEXCH_DH |
+ TLS_ALGO_MAC_SHA256 |
+ TLS_ALGO_CIPHER_AES128_CBC);
+
+ if(suite == TLS_DHE_DSS_WITH_AES_256_CBC_SHA256)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_DSA |
+ TLS_ALGO_KEYEXCH_DH |
+ TLS_ALGO_MAC_SHA256 |
+ TLS_ALGO_CIPHER_AES256_CBC);
+
+ if(suite == TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
+ TLS_ALGO_KEYEXCH_DH |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_3DES_CBC);
+
+ if(suite == TLS_DHE_RSA_WITH_AES_128_CBC_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
+ TLS_ALGO_KEYEXCH_DH |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_AES128_CBC);
+
+ if(suite == TLS_DHE_DSS_WITH_SEED_CBC_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
+ TLS_ALGO_KEYEXCH_DH |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_SEED_CBC);
+
+ if(suite == TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
+ TLS_ALGO_KEYEXCH_DH |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_AES256_CBC);
+
+ if(suite == TLS_DHE_RSA_WITH_AES_128_CBC_SHA256)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
+ TLS_ALGO_KEYEXCH_DH |
+ TLS_ALGO_MAC_SHA256 |
+ TLS_ALGO_CIPHER_AES128_CBC);
+
+ if(suite == TLS_DHE_RSA_WITH_AES_256_CBC_SHA256)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
+ TLS_ALGO_KEYEXCH_DH |
+ TLS_ALGO_MAC_SHA256 |
+ TLS_ALGO_CIPHER_AES256_CBC);
+
+ if(suite == TLS_ECDHE_ECDSA_WITH_RC4_128_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_ECDSA |
+ TLS_ALGO_KEYEXCH_ECDH |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_RC4_128);
+
+ if(suite == TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_ECDSA |
+ TLS_ALGO_KEYEXCH_ECDH |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_3DES_CBC);
+
+ if(suite == TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_ECDSA |
+ TLS_ALGO_KEYEXCH_ECDH |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_AES128_CBC);
+
+ if(suite == TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_ECDSA |
+ TLS_ALGO_KEYEXCH_ECDH |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_AES256_CBC);
+
+ if(suite == TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_ECDSA |
+ TLS_ALGO_KEYEXCH_ECDH |
+ TLS_ALGO_MAC_SHA256 |
+ TLS_ALGO_CIPHER_AES128_CBC);
+
+ if(suite == TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_ECDSA |
+ TLS_ALGO_KEYEXCH_ECDH |
+ TLS_ALGO_MAC_SHA384 |
+ TLS_ALGO_CIPHER_AES256_CBC);
+
+ if(suite == TLS_ECDHE_RSA_WITH_RC4_128_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
+ TLS_ALGO_KEYEXCH_ECDH |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_RC4_128);
+
+ if(suite == TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
+ TLS_ALGO_KEYEXCH_ECDH |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_3DES_CBC);
+
+ if(suite == TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
+ TLS_ALGO_KEYEXCH_ECDH |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_AES128_CBC);
+
+ if(suite == TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA |
+ TLS_ALGO_KEYEXCH_ECDH |
+ TLS_ALGO_MAC_SHA1 |
+ TLS_ALGO_CIPHER_AES256_CBC);
+
+ if(suite == TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_ECDSA |
+ TLS_ALGO_KEYEXCH_ECDH |
+ TLS_ALGO_MAC_SHA256 |
+ TLS_ALGO_CIPHER_AES128_CBC);
+
+ if(suite == TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384)
+ return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_ECDSA |
+ TLS_ALGO_KEYEXCH_ECDH |
+ TLS_ALGO_MAC_SHA384 |
+ TLS_ALGO_CIPHER_AES256_CBC);
+
+ return TLS_Ciphersuite_Algos(0);
+ }
+
+namespace {
+
+std::pair<std::string, size_t> cipher_code_to_name(TLS_Ciphersuite_Algos algo)
+ {
+ if((algo & TLS_ALGO_CIPHER_MASK) == TLS_ALGO_CIPHER_RC4_128)
+ return std::make_pair("ARC4", 16);
+
+ if((algo & TLS_ALGO_CIPHER_MASK) == TLS_ALGO_CIPHER_3DES_CBC)
+ return std::make_pair("3DES", 24);
+
+ if((algo & TLS_ALGO_CIPHER_MASK) == TLS_ALGO_CIPHER_AES128_CBC)
+ return std::make_pair("AES-128", 16);
+
+ if((algo & TLS_ALGO_CIPHER_MASK) == TLS_ALGO_CIPHER_AES256_CBC)
+ return std::make_pair("AES-256", 32);
+
+ if((algo & TLS_ALGO_CIPHER_MASK) == TLS_ALGO_CIPHER_SEED_CBC)
+ return std::make_pair("SEED", 16);
+
+ throw TLS_Exception(INTERNAL_ERROR,
+ "CipherSuite: Unknown cipher type " + to_string(algo));
+ }
+
+std::string mac_code_to_name(TLS_Ciphersuite_Algos algo)
+ {
+ if((algo & TLS_ALGO_MAC_MASK) == TLS_ALGO_MAC_MD5)
+ return "MD5";
+
+ if((algo & TLS_ALGO_MAC_MASK) == TLS_ALGO_MAC_SHA1)
+ return "SHA-1";
+
+ if((algo & TLS_ALGO_MAC_MASK) == TLS_ALGO_MAC_SHA256)
+ return "SHA-256";
+
+ if((algo & TLS_ALGO_MAC_MASK) == TLS_ALGO_MAC_SHA384)
+ return "SHA-384";
+
+ throw TLS_Exception(INTERNAL_ERROR,
+ "CipherSuite: Unknown MAC type " + to_string(algo));
+ }
+
+}
+
+/**
+* CipherSuite Constructor
+*/
+CipherSuite::CipherSuite(u16bit suite_code)
+ {
+ if(suite_code == 0)
+ return;
+
+ TLS_Ciphersuite_Algos algos = lookup_ciphersuite(suite_code);
+
+ if(algos == 0)
+ throw Invalid_Argument("Unknown ciphersuite: " + to_string(suite_code));
+
+ sig_algo = TLS_Ciphersuite_Algos(algos & TLS_ALGO_SIGNER_MASK);
+
+ kex_algo = TLS_Ciphersuite_Algos(algos & TLS_ALGO_KEYEXCH_MASK);
+
+ std::pair<std::string, size_t> cipher_info = cipher_code_to_name(algos);
+
+ cipher = cipher_info.first;
+ cipher_key_length = cipher_info.second;
+
+ mac = mac_code_to_name(algos);
+ }
+
+}