diff options
author | lloyd <[email protected]> | 2010-04-17 18:56:53 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2010-04-17 18:56:53 +0000 |
commit | aaa9e92697e16278fb91552f075c020f2b4c26cb (patch) | |
tree | 1393248e823a35f7134894e60174f0e65a62d876 /src/ssl/tls_suites.cpp | |
parent | 0abc80f498c6bc2e8f630e34b90d5c6d24c29f58 (diff) |
Clean up ciphersuite handling
Diffstat (limited to 'src/ssl/tls_suites.cpp')
-rw-r--r-- | src/ssl/tls_suites.cpp | 216 |
1 files changed, 177 insertions, 39 deletions
diff --git a/src/ssl/tls_suites.cpp b/src/ssl/tls_suites.cpp index 26fa75428..cf6bd45e5 100644 --- a/src/ssl/tls_suites.cpp +++ b/src/ssl/tls_suites.cpp @@ -1,40 +1,188 @@ /** -* TLS Cipher Suites -* (C) 2004-2006 Jack Lloyd +* 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> -#include <botan/parsing.h> -#include <vector> -#include <string> namespace Botan { namespace { /** -* Convert an SSL/TLS ciphersuite to a string +* Convert an SSL/TLS ciphersuite to algorithm fields */ -std::string lookup_ciphersuite(u16bit suite) +TLS_Ciphersuite_Algos lookup_ciphersuite(u16bit suite) { - if(suite == RSA_RC4_MD5) return "RSA/NONE/ARC4/16/MD5"; - if(suite == RSA_RC4_SHA) return "RSA/NONE/ARC4/16/SHA1"; - if(suite == RSA_3DES_SHA) return "RSA/NONE/3DES/24/SHA1"; - if(suite == RSA_AES128_SHA) return "RSA/NONE/AES/16/SHA1"; - if(suite == RSA_AES256_SHA) return "RSA/NONE/AES/32/SHA1"; + 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_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_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_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_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_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); + } + +std::pair<std::string, u32bit> cipher_code_to_name(TLS_Ciphersuite_Algos algo) + { + if((algo & TLS_ALGO_CIPHER_MASK) == TLS_ALGO_CIPHER_RC4_128) + return std::make_pair("RC4", 128); + + if((algo & TLS_ALGO_CIPHER_MASK) == TLS_ALGO_CIPHER_3DES_CBC) + return std::make_pair("3DES", 24); - if(suite == DHE_RSA_3DES_SHA) return "RSA/DH/3DES/24/SHA1"; - if(suite == DHE_RSA_AES128_SHA) return "RSA/DH/AES/16/SHA1"; - if(suite == DHE_RSA_AES256_SHA) return "RSA/DH/AES/32/SHA1"; + if((algo & TLS_ALGO_CIPHER_MASK) == TLS_ALGO_CIPHER_AES128_CBC) + return std::make_pair("AES-128", 16); - if(suite == DHE_DSS_3DES_SHA) return "DSA/DH/3DES/24/SHA1"; - if(suite == DHE_DSS_AES128_SHA) return "DSA/DH/AES/16/SHA1"; - if(suite == DHE_DSS_AES256_SHA) return "DSA/DH/AES/32/SHA1"; + if((algo & TLS_ALGO_CIPHER_MASK) == TLS_ALGO_CIPHER_AES256_CBC) + return std::make_pair("AES-256", 32); - return ""; + 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)); } } @@ -47,31 +195,21 @@ CipherSuite::CipherSuite(u16bit suite_code) if(suite_code == 0) return; - std::string suite_string = lookup_ciphersuite(suite_code); + TLS_Ciphersuite_Algos algos = lookup_ciphersuite(suite_code); + + if(algos == 0) + throw Invalid_Argument("Unknown ciphersuite: " + to_string(suite_code)); - if(suite_string == "") - throw Invalid_Argument("Unknown ciphersuite: " + - to_string(suite_code)); + sig_algo = TLS_Ciphersuite_Algos(algos & TLS_ALGO_SIGNER_MASK); - std::vector<std::string> suite_info = split_on(suite_string, '/'); + kex_algo = TLS_Ciphersuite_Algos(algos & TLS_ALGO_KEYEXCH_MASK); - if(suite_info[0] == "RSA") sig_algo = RSA_SIG; - else if(suite_info[0] == "DSA") sig_algo = DSA_SIG; - else if(suite_info[0] == "NONE") sig_algo = NO_SIG; - else - throw TLS_Exception(INTERNAL_ERROR, - "CipherSuite: Unknown sig type " + suite_info[0]); + std::pair<std::string, u32bit> cipher_info = cipher_code_to_name(algos); - if(suite_info[1] == "DH") kex_algo = DH_KEX; - else if(suite_info[1] == "RSA") kex_algo = RSA_KEX; - else if(suite_info[1] == "NONE") kex_algo = NO_KEX; - else - throw TLS_Exception(INTERNAL_ERROR, - "CipherSuite: Unknown kex type " + suite_info[1]); + cipher = cipher_info.first; + cipher_key_length = cipher_info.second; - cipher = suite_info[2]; - cipher_key_length = to_u32bit(suite_info[3]); - mac = suite_info[4]; + mac = mac_code_to_name(algos); } } |