aboutsummaryrefslogtreecommitdiffstats
path: root/src/ssl/tls_suites.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2010-04-17 18:56:53 +0000
committerlloyd <[email protected]>2010-04-17 18:56:53 +0000
commitaaa9e92697e16278fb91552f075c020f2b4c26cb (patch)
tree1393248e823a35f7134894e60174f0e65a62d876 /src/ssl/tls_suites.cpp
parent0abc80f498c6bc2e8f630e34b90d5c6d24c29f58 (diff)
Clean up ciphersuite handling
Diffstat (limited to 'src/ssl/tls_suites.cpp')
-rw-r--r--src/ssl/tls_suites.cpp216
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);
}
}