diff options
-rw-r--r-- | src/libstate/get_enc.cpp | 4 | ||||
-rw-r--r-- | src/tls/c_hello.cpp | 14 | ||||
-rw-r--r-- | src/tls/c_kex.cpp | 4 | ||||
-rw-r--r-- | src/tls/cert_ver.cpp | 19 | ||||
-rw-r--r-- | src/tls/rec_read.cpp | 2 | ||||
-rw-r--r-- | src/tls/rec_wri.cpp | 2 | ||||
-rw-r--r-- | src/tls/s_kex.cpp | 57 | ||||
-rw-r--r-- | src/tls/tls_client.cpp | 30 | ||||
-rw-r--r-- | src/tls/tls_extensions.cpp | 118 | ||||
-rw-r--r-- | src/tls/tls_extensions.h | 12 | ||||
-rw-r--r-- | src/tls/tls_handshake_state.cpp | 109 | ||||
-rw-r--r-- | src/tls/tls_handshake_state.h | 10 | ||||
-rw-r--r-- | src/tls/tls_magic.h | 35 | ||||
-rw-r--r-- | src/tls/tls_messages.h | 20 | ||||
-rw-r--r-- | src/tls/tls_record.h | 4 | ||||
-rw-r--r-- | src/tls/tls_server.cpp | 10 | ||||
-rw-r--r-- | src/tls/tls_suites.cpp | 280 | ||||
-rw-r--r-- | src/tls/tls_suites.h | 30 |
18 files changed, 254 insertions, 506 deletions
diff --git a/src/libstate/get_enc.cpp b/src/libstate/get_enc.cpp index 6b74f8793..67b9ac9df 100644 --- a/src/libstate/get_enc.cpp +++ b/src/libstate/get_enc.cpp @@ -96,7 +96,11 @@ EMSA* get_emsa(const std::string& algo_spec) #if defined(BOTAN_HAS_EMSA1) if(request.algo_name() == "EMSA1" && request.arg_count() == 1) + { + if(request.arg(0) == "Raw") + return new EMSA_Raw; return new EMSA1(af.make_hash_function(request.arg(0))); + } #endif #if defined(BOTAN_HAS_EMSA1_BSI) diff --git a/src/tls/c_hello.cpp b/src/tls/c_hello.cpp index e35c9027a..99011822e 100644 --- a/src/tls/c_hello.cpp +++ b/src/tls/c_hello.cpp @@ -290,21 +290,15 @@ void Client_Hello::deserialize(const MemoryRegion<byte>& buf) we can safely say it supports everything here and know that we'll filter it out later. */ - m_supported_algos.push_back(std::make_pair(TLS_ALGO_HASH_SHA1, - TLS_ALGO_SIGNER_RSA)); - - m_supported_algos.push_back(std::make_pair(TLS_ALGO_HASH_SHA1, - TLS_ALGO_SIGNER_DSA)); + m_supported_algos.push_back(std::make_pair("SHA-1", "RSA")); + m_supported_algos.push_back(std::make_pair("SHA-1", "DSA")); } else { // For versions before TLS 1.2, insert fake values for the old defaults - m_supported_algos.push_back(std::make_pair(TLS_ALGO_HASH_SHA1, - TLS_ALGO_SIGNER_RSA)); - - m_supported_algos.push_back(std::make_pair(TLS_ALGO_HASH_SHA1, - TLS_ALGO_SIGNER_DSA)); + m_supported_algos.push_back(std::make_pair("TLS.Digest.0", "RSA")); + m_supported_algos.push_back(std::make_pair("SHA-1", "DSA")); } } diff --git a/src/tls/c_kex.cpp b/src/tls/c_kex.cpp index 3d79116ca..8abea8fcd 100644 --- a/src/tls/c_kex.cpp +++ b/src/tls/c_kex.cpp @@ -82,12 +82,12 @@ Client_Key_Exchange::Client_Key_Exchange(Record_Writer& writer, * Read a Client Key Exchange message */ Client_Key_Exchange::Client_Key_Exchange(const MemoryRegion<byte>& contents, - const TLS_Cipher_Suite& suite, + const TLS_Ciphersuite& suite, Version_Code using_version) { include_length = true; - if(using_version == SSL_V3 && (suite.kex_type() == TLS_ALGO_KEYEXCH_NOKEX)) + if(using_version == SSL_V3 && (suite.kex_algo() == "")) include_length = false; if(include_length) diff --git a/src/tls/cert_ver.cpp b/src/tls/cert_ver.cpp index f7386dd13..97cd468b9 100644 --- a/src/tls/cert_ver.cpp +++ b/src/tls/cert_ver.cpp @@ -9,11 +9,6 @@ #include <botan/internal/tls_reader.h> #include <botan/internal/tls_extensions.h> #include <botan/internal/assert.h> -#include <botan/tls_exceptn.h> -#include <botan/pubkey.h> -#include <botan/rsa.h> -#include <botan/dsa.h> -#include <botan/loadstor.h> #include <memory> namespace Botan { @@ -59,16 +54,10 @@ Certificate_Verify::Certificate_Verify(const MemoryRegion<byte>& buf, { TLS_Data_Reader reader(buf); - if(version < TLS_V12) + if(version >= TLS_V12) { - // use old defaults - hash_algo = TLS_ALGO_NONE; - sig_algo = TLS_ALGO_NONE; - } - else - { - hash_algo = Signature_Algorithms::hash_algo_code(reader.get_byte()); - sig_algo = Signature_Algorithms::sig_algo_code(reader.get_byte()); + hash_algo = Signature_Algorithms::hash_algo_name(reader.get_byte()); + sig_algo = Signature_Algorithms::sig_algo_name(reader.get_byte()); } signature = reader.get_range<byte>(2, 0, 65535); @@ -81,7 +70,7 @@ MemoryVector<byte> Certificate_Verify::serialize() const { MemoryVector<byte> buf; - if(hash_algo != TLS_ALGO_NONE) + if(hash_algo != "" && sig_algo != "") { buf.push_back(Signature_Algorithms::hash_algo_code(hash_algo)); buf.push_back(Signature_Algorithms::sig_algo_code(sig_algo)); diff --git a/src/tls/rec_read.cpp b/src/tls/rec_read.cpp index 2376dfd2b..d3666abf6 100644 --- a/src/tls/rec_read.cpp +++ b/src/tls/rec_read.cpp @@ -64,7 +64,7 @@ void Record_Reader::set_version(Version_Code version) /* * Set the keys for reading */ -void Record_Reader::activate(const TLS_Cipher_Suite& suite, +void Record_Reader::activate(const TLS_Ciphersuite& suite, const Session_Keys& keys, Connection_Side side) { diff --git a/src/tls/rec_wri.cpp b/src/tls/rec_wri.cpp index 7a67ed962..7f8b4445b 100644 --- a/src/tls/rec_wri.cpp +++ b/src/tls/rec_wri.cpp @@ -67,7 +67,7 @@ void Record_Writer::set_version(Version_Code version) /* * Set the keys for writing */ -void Record_Writer::activate(const TLS_Cipher_Suite& suite, +void Record_Writer::activate(const TLS_Ciphersuite& suite, const Session_Keys& keys, Connection_Side side) { diff --git a/src/tls/s_kex.cpp b/src/tls/s_kex.cpp index 6b87e6ac6..0098dc12d 100644 --- a/src/tls/s_kex.cpp +++ b/src/tls/s_kex.cpp @@ -27,23 +27,23 @@ Server_Key_Exchange::Server_Key_Exchange(Record_Writer& writer, if(dh_pub) { - params.push_back(dh_pub->get_domain().get_p()); - params.push_back(dh_pub->get_domain().get_g()); - params.push_back(BigInt::decode(dh_pub->public_value())); + m_params.push_back(dh_pub->get_domain().get_p()); + m_params.push_back(dh_pub->get_domain().get_g()); + m_params.push_back(BigInt::decode(dh_pub->public_value())); } else throw Invalid_Argument("Unknown key type " + state->kex_priv->algo_name() + " for TLS key exchange"); std::pair<std::string, Signature_Format> format = - state->choose_sig_format(private_key, hash_algo, sig_algo, false); + state->choose_sig_format(private_key, m_hash_algo, m_sig_algo, false); PK_Signer signer(*private_key, format.first, format.second); signer.update(state->client_hello->random()); signer.update(state->server_hello->random()); signer.update(serialize_params()); - signature = signer.signature(rng); + m_signature = signer.signature(rng); send(writer, state->hash); } @@ -55,13 +55,14 @@ MemoryVector<byte> Server_Key_Exchange::serialize() const { MemoryVector<byte> buf = serialize_params(); - if(hash_algo != TLS_ALGO_NONE) + // NEEDS VERSION CHECK + if(m_hash_algo != "" && m_sig_algo != "") { - buf.push_back(Signature_Algorithms::hash_algo_code(hash_algo)); - buf.push_back(Signature_Algorithms::sig_algo_code(sig_algo)); + buf.push_back(Signature_Algorithms::hash_algo_code(m_hash_algo)); + buf.push_back(Signature_Algorithms::sig_algo_code(m_sig_algo)); } - append_tls_length_value(buf, signature, 2); + append_tls_length_value(buf, m_signature, 2); return buf; } @@ -72,8 +73,8 @@ MemoryVector<byte> Server_Key_Exchange::serialize_params() const { MemoryVector<byte> buf; - for(size_t i = 0; i != params.size(); ++i) - append_tls_length_value(buf, BigInt::encode(params[i]), 2); + for(size_t i = 0; i != m_params.size(); ++i) + append_tls_length_value(buf, BigInt::encode(m_params[i]), 2); return buf; } @@ -82,8 +83,8 @@ MemoryVector<byte> Server_Key_Exchange::serialize_params() const * Deserialize a Server Key Exchange message */ Server_Key_Exchange::Server_Key_Exchange(const MemoryRegion<byte>& buf, - TLS_Ciphersuite_Algos kex_alg, - TLS_Ciphersuite_Algos sig_alg, + const std::string& kex_algo, + const std::string& sig_algo, Version_Code version) { if(buf.size() < 6) @@ -91,34 +92,28 @@ Server_Key_Exchange::Server_Key_Exchange(const MemoryRegion<byte>& buf, TLS_Data_Reader reader(buf); - if(kex_alg == TLS_ALGO_KEYEXCH_DH) + if(kex_algo == "DH") { // 3 bigints, DH p, g, Y for(size_t i = 0; i != 3; ++i) { BigInt v = BigInt::decode(reader.get_range<byte>(2, 1, 65535)); - params.push_back(v); + m_params.push_back(v); } } else - throw Decoding_Error("Unsupported server key exchange type"); + throw Decoding_Error("Unsupported server key exchange type " + kex_algo); - if(sig_alg != TLS_ALGO_SIGNER_ANON) + if(sig_algo != "") { - if(version < TLS_V12) + if(version >= TLS_V12) { - // use old defaults - hash_algo = TLS_ALGO_NONE; - sig_algo = TLS_ALGO_NONE; - } - else - { - hash_algo = Signature_Algorithms::hash_algo_code(reader.get_byte()); - sig_algo = Signature_Algorithms::sig_algo_code(reader.get_byte()); + m_hash_algo = Signature_Algorithms::hash_algo_name(reader.get_byte()); + m_sig_algo = Signature_Algorithms::sig_algo_name(reader.get_byte()); } - signature = reader.get_range<byte>(2, 0, 65535); + m_signature = reader.get_range<byte>(2, 0, 65535); } } @@ -127,8 +122,8 @@ Server_Key_Exchange::Server_Key_Exchange(const MemoryRegion<byte>& buf, */ Public_Key* Server_Key_Exchange::key() const { - if(params.size() == 3) - return new DH_PublicKey(DL_Group(params[0], params[1]), params[2]); + if(m_params.size() == 3) + return new DH_PublicKey(DL_Group(m_params[0], m_params[1]), m_params[2]); else throw Internal_Error("Server_Key_Exchange::key: No key set"); } @@ -142,7 +137,7 @@ bool Server_Key_Exchange::verify(const X509_Certificate& cert, std::auto_ptr<Public_Key> key(cert.subject_public_key()); std::pair<std::string, Signature_Format> format = - state->choose_sig_format(key.get(), hash_algo, sig_algo, false); + state->choose_sig_format(key.get(), m_hash_algo, m_sig_algo, false); PK_Verifier verifier(*key, format.first, format.second); @@ -150,7 +145,7 @@ bool Server_Key_Exchange::verify(const X509_Certificate& cert, verifier.update(state->server_hello->random()); verifier.update(serialize_params()); - return verifier.check_signature(signature); + return verifier.check_signature(m_signature); } } diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp index ed7de501f..1d79327e8 100644 --- a/src/tls/tls_client.cpp +++ b/src/tls/tls_client.cpp @@ -180,7 +180,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, secure_renegotiation.update(state->server_hello); - state->suite = TLS_Cipher_Suite(state->server_hello->ciphersuite()); + state->suite = TLS_Ciphersuite::lookup_ciphersuite(state->server_hello->ciphersuite()); if(!state->server_hello->session_id().empty() && (state->server_hello->session_id() == state->client_hello->session_id())) @@ -217,11 +217,11 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, "TLS_Client: Server is too old for specified policy"); } - if(state->suite.sig_type() != TLS_ALGO_SIGNER_ANON) + if(state->suite.sig_algo() != "") { state->set_expected_next(CERTIFICATE); } - else if(state->suite.kex_type() != TLS_ALGO_KEYEXCH_NOKEX) + else if(state->suite.kex_algo() != "") { state->set_expected_next(SERVER_KEX); } @@ -234,7 +234,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, } else if(type == CERTIFICATE) { - if(state->suite.kex_type() != TLS_ALGO_KEYEXCH_NOKEX) + if(state->suite.kex_algo() != "") { state->set_expected_next(SERVER_KEX); } @@ -257,18 +257,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, state->kex_pub = peer_certs[0].subject_public_key(); - bool is_dsa = false, is_rsa = false; - - if(dynamic_cast<DSA_PublicKey*>(state->kex_pub)) - is_dsa = true; - else if(dynamic_cast<RSA_PublicKey*>(state->kex_pub)) - is_rsa = true; - else - throw TLS_Exception(UNSUPPORTED_CERTIFICATE, - "Unknown key type received in server kex"); - - if((is_dsa && state->suite.sig_type() != TLS_ALGO_SIGNER_DSA) || - (is_rsa && state->suite.sig_type() != TLS_ALGO_SIGNER_RSA)) + if(state->kex_pub->algo_name() != state->suite.sig_algo()) throw TLS_Exception(ILLEGAL_PARAMETER, "Certificate key type did not match ciphersuite"); } @@ -278,11 +267,11 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, state->set_expected_next(SERVER_HELLO_DONE); state->server_kex = new Server_Key_Exchange(contents, - state->suite.kex_type(), - state->suite.sig_type(), + state->suite.kex_algo(), + state->suite.sig_algo(), state->version); - if(state->suite.sig_type() != TLS_ALGO_SIGNER_ANON) + if(state->suite.sig_algo() != "") { if(!state->server_kex->verify(peer_certs[0], state)) { @@ -296,8 +285,9 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, state->kex_pub = state->server_kex->key(); + // this should be in client_key_exchange if(dynamic_cast<DH_PublicKey*>(state->kex_pub) && - state->suite.kex_type() != TLS_ALGO_KEYEXCH_DH) + state->suite.kex_algo() != "DH") { throw TLS_Exception(HANDSHAKE_FAILURE, "Server sent DH key but negotiated something else"); diff --git a/src/tls/tls_extensions.cpp b/src/tls/tls_extensions.cpp index 21c3b67fc..41977f975 100644 --- a/src/tls/tls_extensions.cpp +++ b/src/tls/tls_extensions.cpp @@ -276,76 +276,77 @@ MemoryVector<byte> Next_Protocol_Notification::serialize() const return buf; } -TLS_Ciphersuite_Algos Signature_Algorithms::hash_algo_code(byte code) +std::string Signature_Algorithms::hash_algo_name(byte code) { switch(code) { case 1: - return TLS_ALGO_HASH_MD5; + return "MD5"; case 2: - return TLS_ALGO_HASH_SHA1; + return "SHA-1"; case 3: - return TLS_ALGO_HASH_SHA224; + return "SHA-224"; case 4: - return TLS_ALGO_HASH_SHA256; + return "SHA-256"; case 5: - return TLS_ALGO_HASH_SHA384; + return "SHA-384"; case 6: - return TLS_ALGO_HASH_SHA512; + return "SHA-512"; default: - return TLS_ALGO_NONE; + return ""; } } -byte Signature_Algorithms::hash_algo_code(TLS_Ciphersuite_Algos code) +byte Signature_Algorithms::hash_algo_code(const std::string& name) { - switch(code) - { - case TLS_ALGO_HASH_MD5: - return 1; - case TLS_ALGO_HASH_SHA1: - return 2; - case TLS_ALGO_HASH_SHA224: - return 3; - case TLS_ALGO_HASH_SHA256: - return 4; - case TLS_ALGO_HASH_SHA384: - return 5; - case TLS_ALGO_HASH_SHA512: - return 6; - default: - throw Algorithm_Not_Found("Unknown hash ID for signature_algorithms"); - } + if(name == "MD5") + return 1; + + if(name == "SHA-1") + return 2; + + if(name == "SHA-224") + return 3; + + if(name == "SHA-256") + return 4; + + if(name == "SHA-384") + return 5; + + if(name == "SHA-512") + return 6; + + throw Algorithm_Not_Found("Unknown hash ID for signature_algorithms"); } -TLS_Ciphersuite_Algos Signature_Algorithms::sig_algo_code(byte code) +std::string Signature_Algorithms::sig_algo_name(byte code) { switch(code) { case 1: - return TLS_ALGO_SIGNER_RSA; + return "RSA"; case 2: - return TLS_ALGO_SIGNER_DSA; + return "DSA"; case 3: - return TLS_ALGO_SIGNER_ECDSA; + return "ECDSA"; default: - return TLS_ALGO_NONE; + return ""; } } -byte Signature_Algorithms::sig_algo_code(TLS_Ciphersuite_Algos code) +byte Signature_Algorithms::sig_algo_code(const std::string& name) { - switch(code) - { - case TLS_ALGO_SIGNER_RSA: - return 1; - case TLS_ALGO_SIGNER_DSA: - return 2; - case TLS_ALGO_SIGNER_ECDSA: - return 3; - default: - throw Algorithm_Not_Found("Unknown sig ID for signature_algorithms"); - } + if(name == "RSA") + return 1; + + if(name == "DSA") + return 2; + + if(name == "ECDSA") + return 3; + + throw Algorithm_Not_Found("Unknown sig ID for signature_algorithms"); } MemoryVector<byte> Signature_Algorithms::serialize() const @@ -371,23 +372,12 @@ Signature_Algorithms::Signature_Algorithms() We prefer hashes strongest (SHA-512) to weakest (SHA-1). */ - m_supported_algos.push_back(std::make_pair(TLS_ALGO_HASH_SHA512, - TLS_ALGO_SIGNER_RSA)); - - m_supported_algos.push_back(std::make_pair(TLS_ALGO_HASH_SHA384, - TLS_ALGO_SIGNER_RSA)); - - m_supported_algos.push_back(std::make_pair(TLS_ALGO_HASH_SHA256, - TLS_ALGO_SIGNER_RSA)); - - m_supported_algos.push_back(std::make_pair(TLS_ALGO_HASH_SHA224, - TLS_ALGO_SIGNER_RSA)); - - m_supported_algos.push_back(std::make_pair(TLS_ALGO_HASH_SHA1, - TLS_ALGO_SIGNER_RSA)); - - m_supported_algos.push_back(std::make_pair(TLS_ALGO_HASH_SHA1, - TLS_ALGO_SIGNER_DSA)); + m_supported_algos.push_back(std::make_pair("SHA-512", "RSA")); + m_supported_algos.push_back(std::make_pair("SHA-384", "RSA")); + m_supported_algos.push_back(std::make_pair("SHA-256", "RSA")); + m_supported_algos.push_back(std::make_pair("SHA-224", "RSA")); + m_supported_algos.push_back(std::make_pair("SHA-1", "RSA")); + m_supported_algos.push_back(std::make_pair("SHA-1", "DSA")); } Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, @@ -400,11 +390,11 @@ Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, while(len) { - TLS_Ciphersuite_Algos hash_code = hash_algo_code(reader.get_byte()); - TLS_Ciphersuite_Algos sig_code = sig_algo_code(reader.get_byte()); + const std::string hash_code = hash_algo_name(reader.get_byte()); + const std::string sig_code = sig_algo_name(reader.get_byte()); - // If not something we know, ignore completely - if(hash_code == TLS_ALGO_NONE || sig_code == TLS_ALGO_NONE) + // If not something we know, ignore it completely + if(hash_code == "" || sig_code == "") continue; m_supported_algos.push_back(std::make_pair(hash_code, sig_code)); diff --git a/src/tls/tls_extensions.h b/src/tls/tls_extensions.h index a90cb4f2b..fea700756 100644 --- a/src/tls/tls_extensions.h +++ b/src/tls/tls_extensions.h @@ -199,13 +199,13 @@ class Signature_Algorithms : public TLS_Extension TLS_Handshake_Extension_Type type() const { return static_type(); } - static TLS_Ciphersuite_Algos hash_algo_code(byte code); - static byte hash_algo_code(TLS_Ciphersuite_Algos code); + static std::string hash_algo_name(byte code); + static byte hash_algo_code(const std::string& name); - static TLS_Ciphersuite_Algos sig_algo_code(byte code); - static byte sig_algo_code(TLS_Ciphersuite_Algos code); + static std::string sig_algo_name(byte code); + static byte sig_algo_code(const std::string& name); - std::vector<std::pair<TLS_Ciphersuite_Algos, TLS_Ciphersuite_Algos> > + std::vector<std::pair<std::string, std::string> > supported_signature_algorthms() const { return m_supported_algos; @@ -220,7 +220,7 @@ class Signature_Algorithms : public TLS_Extension Signature_Algorithms(TLS_Data_Reader& reader, u16bit extension_size); private: - std::vector<std::pair<TLS_Ciphersuite_Algos, TLS_Ciphersuite_Algos> > m_supported_algos; + std::vector<std::pair<std::string, std::string> > m_supported_algos; }; /** diff --git a/src/tls/tls_handshake_state.cpp b/src/tls/tls_handshake_state.cpp index 48fb70ae1..cfbb05b6a 100644 --- a/src/tls/tls_handshake_state.cpp +++ b/src/tls/tls_handshake_state.cpp @@ -131,110 +131,103 @@ bool TLS_Handshake_State::received_handshake_msg(Handshake_Type handshake_msg) c std::pair<std::string, Signature_Format> TLS_Handshake_State::choose_sig_format(const Private_Key* key, - TLS_Ciphersuite_Algos& hash_algo, - TLS_Ciphersuite_Algos& sig_algo, + std::string& hash_algo, + std::string& sig_algo, bool for_client_auth) { - const std::string algo_name = key->algo_name(); - - hash_algo = TLS_ALGO_NONE; - sig_algo = TLS_ALGO_NONE; + sig_algo = key->algo_name(); /* - FIXME: This should respect the algo preferences in the client hello. - Either we are the client, and shouldn't confuse the server by claiming - one thing and doing another, or we're the server and the client might - be unhappy if we send it something it doesn't understand. + FIXME: This should respect the algo preferences in the client hello + (or certificate request, depending on value of for_client_auth). */ - if(algo_name == "RSA") + if(sig_algo == "RSA") { - std::string padding = ""; - if(for_client_auth && this->version == SSL_V3) - padding = "EMSA3(Raw)"; - else if(this->version == TLS_V10 || this->version == TLS_V11) - padding = "EMSA3(TLS.Digest.0)"; + { + hash_algo = "Raw"; + } + else if(this->version < TLS_V12) + { + hash_algo = "TLS.Digest.0"; + } else { - hash_algo = TLS_ALGO_HASH_SHA256; // should be policy - sig_algo = TLS_ALGO_SIGNER_RSA; - - std::string hash = TLS_Cipher_Suite::hash_code_to_name(hash_algo); - padding = "EMSA3(" + hash + ")"; + hash_algo = "SHA-256"; // should be policy } + const std::string padding = "EMSA3(" + hash_algo + ")"; + return std::make_pair(padding, IEEE_1363); } - else if(algo_name == "DSA") + else if(sig_algo == "DSA") { - std::string padding = ""; - if(for_client_auth && this->version == SSL_V3) - padding = "Raw"; - else if(this->version == TLS_V10 || this->version == TLS_V11) - padding = "EMSA1(SHA-1)"; + { + hash_algo = "Raw"; + } + else if(this->version < TLS_V12) + { + hash_algo = "SHA-1"; + } else { - hash_algo = TLS_ALGO_HASH_SHA1; // should be policy - sig_algo = TLS_ALGO_SIGNER_DSA; - - std::string hash = TLS_Cipher_Suite::hash_code_to_name(hash_algo); - padding = "EMSA1(" + hash + ")"; + hash_algo = "SHA-1"; // should be policy } + const std::string padding = "EMSA1(" + hash_algo + ")"; + return std::make_pair(padding, DER_SEQUENCE); } - throw Invalid_Argument(algo_name + " is invalid/unknown for TLS signatures"); + throw Invalid_Argument(sig_algo + " is invalid/unknown for TLS signatures"); } std::pair<std::string, Signature_Format> TLS_Handshake_State::choose_sig_format(const Public_Key* key, - TLS_Ciphersuite_Algos hash_algo, - TLS_Ciphersuite_Algos sig_algo, + std::string hash_algo, + std::string sig_algo, bool for_client_auth) { const std::string algo_name = key->algo_name(); - if(algo_name == "RSA") + if(this->version < TLS_V12) { - if(sig_algo != TLS_ALGO_NONE && sig_algo != TLS_ALGO_SIGNER_RSA) - throw TLS_Exception(DECODE_ERROR, - "Counterparty sent RSA key and non-RSA signature"); + if(hash_algo != "") + throw Decoding_Error("Counterparty sent hash/sig IDs with old version"); + } - std::string padding = ""; + if(sig_algo != "" && sig_algo != algo_name) + throw Decoding_Error("Counterparty sent inconsistent key and sig types"); + if(algo_name == "RSA") + { if(for_client_auth && this->version == SSL_V3) - padding = "EMSA3(Raw)"; - else if(hash_algo == TLS_ALGO_NONE) - padding = "EMSA3(TLS.Digest.0)"; - else { - std::string hash = TLS_Cipher_Suite::hash_code_to_name(hash_algo); - padding = "EMSA3(" + hash + ")"; + hash_algo = "Raw"; + } + else if(this->version < TLS_V12) + { + hash_algo = "TLS.Digest.0"; } + const std::string padding = "EMSA3(" + hash_algo + ")"; return std::make_pair(padding, IEEE_1363); } else if(algo_name == "DSA") { - if(sig_algo != TLS_ALGO_NONE && sig_algo != TLS_ALGO_SIGNER_DSA) - throw TLS_Exception(DECODE_ERROR, - "Counterparty sent RSA key and non-RSA signature"); - - std::string padding = ""; - if(for_client_auth && this->version == SSL_V3) - padding = "Raw"; - else if(hash_algo == TLS_ALGO_NONE) - padding = "EMSA1(SHA-1)"; - else { - std::string hash = TLS_Cipher_Suite::hash_code_to_name(hash_algo); - padding = "EMSA1(" + hash + ")"; + hash_algo = "Raw"; + } + else if(this->version < TLS_V12) + { + hash_algo = "SHA-1"; } + const std::string padding = "EMSA1(" + hash_algo + ")"; + return std::make_pair(padding, DER_SEQUENCE); } diff --git a/src/tls/tls_handshake_state.h b/src/tls/tls_handshake_state.h index 3480ee85f..f9b7dd384 100644 --- a/src/tls/tls_handshake_state.h +++ b/src/tls/tls_handshake_state.h @@ -48,14 +48,14 @@ class TLS_Handshake_State std::pair<std::string, Signature_Format> choose_sig_format(const Public_Key* key, - TLS_Ciphersuite_Algos hash_algo, - TLS_Ciphersuite_Algos sig_algo, + std::string hash_algo, + std::string sig_algo, bool for_client_auth); std::pair<std::string, Signature_Format> choose_sig_format(const Private_Key* key, - TLS_Ciphersuite_Algos& hash_algo, - TLS_Ciphersuite_Algos& sig_algo, + std::string& hash_algo, + std::string& sig_algo, bool for_client_auth); Version_Code version; @@ -79,7 +79,7 @@ class TLS_Handshake_State Public_Key* kex_pub; Private_Key* kex_priv; - TLS_Cipher_Suite suite; + TLS_Ciphersuite suite; Session_Keys keys; TLS_Handshake_Hash hash; diff --git a/src/tls/tls_magic.h b/src/tls/tls_magic.h index ac3c562dc..3426088bd 100644 --- a/src/tls/tls_magic.h +++ b/src/tls/tls_magic.h @@ -162,41 +162,6 @@ enum Ciphersuite_Code { TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF }; -/* -* Form of the ciphersuites broken down by field instead of -* being randomly assigned codepoints. -*/ -enum TLS_Ciphersuite_Algos { - TLS_ALGO_NONE = 0x00000000, - - TLS_ALGO_SIGNER_MASK = 0xFF000000, - TLS_ALGO_SIGNER_ANON = 0x01000000, - TLS_ALGO_SIGNER_RSA = 0x02000000, - TLS_ALGO_SIGNER_DSA = 0x03000000, - TLS_ALGO_SIGNER_ECDSA = 0x04000000, - - TLS_ALGO_KEYEXCH_MASK = 0x00FF0000, - TLS_ALGO_KEYEXCH_NOKEX = 0x00010000, // RSA using server cert key - TLS_ALGO_KEYEXCH_DH = 0x00020000, // Ephemeral DH - TLS_ALGO_KEYEXCH_ECDH = 0x00030000, // Ephemeral ECDH - TLS_ALGO_KEYEXCH_SRP = 0x00040000, - - TLS_ALGO_HASH_MASK = 0x0000FF00, - TLS_ALGO_HASH_MD5 = 0x00000100, - TLS_ALGO_HASH_SHA1 = 0x00000200, - TLS_ALGO_HASH_SHA224 = 0x00000300, - TLS_ALGO_HASH_SHA256 = 0x00000400, - TLS_ALGO_HASH_SHA384 = 0x00000500, - TLS_ALGO_HASH_SHA512 = 0x00000600, - - TLS_ALGO_CIPHER_MASK = 0x000000FF, - TLS_ALGO_CIPHER_RC4_128 = 0x00000001, - TLS_ALGO_CIPHER_3DES_CBC = 0x00000002, - TLS_ALGO_CIPHER_AES128_CBC = 0x00000003, - TLS_ALGO_CIPHER_AES256_CBC = 0x00000004, - TLS_ALGO_CIPHER_SEED_CBC = 0x00000005 -}; - enum Compression_Method { NO_COMPRESSION = 0x00, DEFLATE_COMPRESSION = 0x01 diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h index 91a1a218f..b0f6b503f 100644 --- a/src/tls/tls_messages.h +++ b/src/tls/tls_messages.h @@ -113,7 +113,7 @@ class Client_Hello : public Handshake_Message bool m_secure_renegotiation; MemoryVector<byte> m_renegotiation_info; - std::vector<std::pair<TLS_Ciphersuite_Algos, TLS_Ciphersuite_Algos> > m_supported_algos; + std::vector<std::pair<std::string, std::string> > m_supported_algos; }; /** @@ -214,7 +214,7 @@ class Client_Key_Exchange : public Handshake_Message Version_Code pref_version); Client_Key_Exchange(const MemoryRegion<byte>& buf, - const TLS_Cipher_Suite& suite, + const TLS_Ciphersuite& suite, Version_Code using_version); private: MemoryVector<byte> serialize() const; @@ -298,8 +298,8 @@ class Certificate_Verify : public Handshake_Message private: MemoryVector<byte> serialize() const; - TLS_Ciphersuite_Algos sig_algo; // sig algo used to create signature - TLS_Ciphersuite_Algos hash_algo; // hash used to create signature + std::string sig_algo; // sig algo used to create signature + std::string hash_algo; // hash used to create signature MemoryVector<byte> signature; }; @@ -361,18 +361,18 @@ class Server_Key_Exchange : public Handshake_Message const Private_Key* priv_key); Server_Key_Exchange(const MemoryRegion<byte>& buf, - TLS_Ciphersuite_Algos kex_alg, - TLS_Ciphersuite_Algos sig_alg, + const std::string& kex_alg, + const std::string& sig_alg, Version_Code version); private: MemoryVector<byte> serialize() const; MemoryVector<byte> serialize_params() const; - std::vector<BigInt> params; + std::vector<BigInt> m_params; - TLS_Ciphersuite_Algos sig_algo; // sig algo used to create signature - TLS_Ciphersuite_Algos hash_algo; // hash used to create signature - MemoryVector<byte> signature; + std::string m_sig_algo; // sig algo used to create signature + std::string m_hash_algo; // hash used to create signature + MemoryVector<byte> m_signature; }; /** diff --git a/src/tls/tls_record.h b/src/tls/tls_record.h index a9bcb8f26..c4b483c80 100644 --- a/src/tls/tls_record.h +++ b/src/tls/tls_record.h @@ -43,7 +43,7 @@ class BOTAN_DLL Record_Writer void alert(Alert_Level level, Alert_Type type); - void activate(const TLS_Cipher_Suite& suite, + void activate(const TLS_Ciphersuite& suite, const Session_Keys& keys, Connection_Side side); @@ -97,7 +97,7 @@ class BOTAN_DLL Record_Reader byte& msg_type, MemoryVector<byte>& msg); - void activate(const TLS_Cipher_Suite& suite, + void activate(const TLS_Ciphersuite& suite, const Session_Keys& keys, Connection_Side side); diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp index 44f8ec2b4..6f7ce9489 100644 --- a/src/tls/tls_server.cpp +++ b/src/tls/tls_server.cpp @@ -205,7 +205,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, writer.set_maximum_fragment_size(session_info.fragment_size()); } - state->suite = TLS_Cipher_Suite(state->server_hello->ciphersuite()); + state->suite = TLS_Ciphersuite::lookup_ciphersuite(state->server_hello->ciphersuite()); state->keys = Session_Keys(state, session_info.master_secret(), true); @@ -252,18 +252,18 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, writer.set_maximum_fragment_size(state->client_hello->fragment_size()); } - state->suite = TLS_Cipher_Suite(state->server_hello->ciphersuite()); + state->suite = TLS_Ciphersuite::lookup_ciphersuite(state->server_hello->ciphersuite()); - if(state->suite.sig_type() != TLS_ALGO_SIGNER_ANON) + if(state->suite.sig_algo() != "") { state->server_certs = new Certificate(writer, state->hash, server_certs); } - if(state->suite.kex_type() != TLS_ALGO_KEYEXCH_NOKEX) + if(state->suite.kex_algo() != "") { - if(state->suite.kex_type() == TLS_ALGO_KEYEXCH_DH) + if(state->suite.kex_algo() == "") state->kex_priv = new DH_PrivateKey(rng, policy.dh_group()); else throw Internal_Error("TLS_Server: Unknown ciphersuite kex type"); diff --git a/src/tls/tls_suites.cpp b/src/tls/tls_suites.cpp index f3a967b3e..46bc4d501 100644 --- a/src/tls/tls_suites.cpp +++ b/src/tls/tls_suites.cpp @@ -13,316 +13,144 @@ namespace Botan { /** * Convert an SSL/TLS ciphersuite to algorithm fields */ -TLS_Ciphersuite_Algos TLS_Cipher_Suite::lookup_ciphersuite(u16bit suite) +TLS_Ciphersuite TLS_Ciphersuite::lookup_ciphersuite(u16bit suite) { + // RSA ciphersuites if(suite == TLS_RSA_WITH_RC4_128_MD5) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_NOKEX | - TLS_ALGO_HASH_MD5 | - TLS_ALGO_CIPHER_RC4_128); + return TLS_Ciphersuite("RSA", "", "MD5", "ARC4", 16); if(suite == TLS_RSA_WITH_RC4_128_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_NOKEX | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_RC4_128); + return TLS_Ciphersuite("RSA", "", "SHA1", "ARC4", 16); if(suite == TLS_RSA_WITH_3DES_EDE_CBC_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_NOKEX | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_3DES_CBC); + return TLS_Ciphersuite("RSA", "", "SHA1", "TripleDES", 24); if(suite == TLS_RSA_WITH_AES_128_CBC_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_NOKEX | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_AES128_CBC); + return TLS_Ciphersuite("RSA", "", "SHA1", "AES-128", 16); if(suite == TLS_RSA_WITH_AES_256_CBC_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_NOKEX | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_AES256_CBC); + return TLS_Ciphersuite("RSA", "", "SHA1", "AES-256", 32); if(suite == TLS_RSA_WITH_SEED_CBC_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_NOKEX | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_SEED_CBC); + return TLS_Ciphersuite("RSA", "", "SHA1", "SEED", 16); if(suite == TLS_RSA_WITH_AES_128_CBC_SHA256) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_NOKEX | - TLS_ALGO_HASH_SHA256 | - TLS_ALGO_CIPHER_AES128_CBC); + return TLS_Ciphersuite("RSA", "", "SHA-256", "AES-128", 16); if(suite == TLS_RSA_WITH_AES_256_CBC_SHA256) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_NOKEX | - TLS_ALGO_HASH_SHA256 | - TLS_ALGO_CIPHER_AES256_CBC); + return TLS_Ciphersuite("RSA", "", "SHA-256", "AES-256", 32); + // DHE/DSS ciphersuites if(suite == TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_DSA | - TLS_ALGO_KEYEXCH_DH | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_3DES_CBC); + return TLS_Ciphersuite("DSA", "DH", "SHA1", "TripleDES", 24); if(suite == TLS_DHE_DSS_WITH_AES_128_CBC_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_DSA | - TLS_ALGO_KEYEXCH_DH | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_AES128_CBC); + return TLS_Ciphersuite("DSA", "DH", "SHA1", "AES-128", 16); if(suite == TLS_DHE_DSS_WITH_SEED_CBC_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_DSA | - TLS_ALGO_KEYEXCH_DH | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_SEED_CBC); + return TLS_Ciphersuite("DSA", "DH", "SHA1", "SEED", 16); if(suite == TLS_DHE_DSS_WITH_RC4_128_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_DSA | - TLS_ALGO_KEYEXCH_DH | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_RC4_128); + return TLS_Ciphersuite("DSA", "DH", "SHA1", "ARC4", 16); if(suite == TLS_DHE_DSS_WITH_AES_256_CBC_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_DSA | - TLS_ALGO_KEYEXCH_DH | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_AES256_CBC); + return TLS_Ciphersuite("DSA", "DH", "SHA1", "AES-256", 32); if(suite == TLS_DHE_DSS_WITH_AES_128_CBC_SHA256) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_DSA | - TLS_ALGO_KEYEXCH_DH | - TLS_ALGO_HASH_SHA256 | - TLS_ALGO_CIPHER_AES128_CBC); + return TLS_Ciphersuite("DSA", "DH", "SHA-256", "AES-128", 16); if(suite == TLS_DHE_DSS_WITH_AES_256_CBC_SHA256) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_DSA | - TLS_ALGO_KEYEXCH_DH | - TLS_ALGO_HASH_SHA256 | - TLS_ALGO_CIPHER_AES256_CBC); + return TLS_Ciphersuite("DSA", "DH", "SHA-256", "AES-256", 32); + // DHE/RSA ciphersuites if(suite == TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_DH | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_3DES_CBC); + return TLS_Ciphersuite("RSA", "DH", "SHA1", "TripleDES", 24); if(suite == TLS_DHE_RSA_WITH_AES_128_CBC_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_DH | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_AES128_CBC); + return TLS_Ciphersuite("RSA", "DH", "SHA1", "AES-128", 16); if(suite == TLS_DHE_DSS_WITH_SEED_CBC_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_DH | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_SEED_CBC); + return TLS_Ciphersuite("RSA", "DH", "SHA1", "SEED", 16); if(suite == TLS_DHE_RSA_WITH_AES_256_CBC_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_DH | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_AES256_CBC); + return TLS_Ciphersuite("RSA", "DH", "SHA1", "AES-256", 32); if(suite == TLS_DHE_RSA_WITH_AES_128_CBC_SHA256) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_DH | - TLS_ALGO_HASH_SHA256 | - TLS_ALGO_CIPHER_AES128_CBC); + return TLS_Ciphersuite("RSA", "DH", "SHA-256", "AES-128", 16); if(suite == TLS_DHE_RSA_WITH_AES_256_CBC_SHA256) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_DH | - TLS_ALGO_HASH_SHA256 | - TLS_ALGO_CIPHER_AES256_CBC); + return TLS_Ciphersuite("RSA", "DH", "SHA-256", "AES-256", 32); // SRP ciphersuites if(suite == TLS_SRP_SHA_RSA_WITH_3DES_EDE_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_SRP | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_3DES_CBC); + return TLS_Ciphersuite("RSA", "SRP", "SHA1", "TripleDES", 24); if(suite == TLS_SRP_SHA_DSS_WITH_3DES_EDE_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_DSA | - TLS_ALGO_KEYEXCH_SRP | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_3DES_CBC); + return TLS_Ciphersuite("DSA", "SRP", "SHA1", "TripleDES", 24); if(suite == TLS_SRP_SHA_RSA_WITH_AES_128_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_SRP | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_AES128_CBC); + return TLS_Ciphersuite("RSA", "SRP", "SHA1", "AES-128", 16); if(suite == TLS_SRP_SHA_DSS_WITH_AES_128_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_DSA | - TLS_ALGO_KEYEXCH_SRP | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_AES128_CBC); + return TLS_Ciphersuite("DSA", "SRP", "SHA1", "AES-128", 16); if(suite == TLS_SRP_SHA_RSA_WITH_AES_256_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_SRP | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_AES256_CBC); + return TLS_Ciphersuite("RSA", "SRP", "SHA1", "AES-256", 32); if(suite == TLS_SRP_SHA_DSS_WITH_AES_256_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_DSA | - TLS_ALGO_KEYEXCH_SRP | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_AES256_CBC); + return TLS_Ciphersuite("DSA", "SRP", "SHA1", "AES-256", 32); // ECC ciphersuites if(suite == TLS_ECDHE_ECDSA_WITH_RC4_128_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_ECDSA | - TLS_ALGO_KEYEXCH_ECDH | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_RC4_128); + return TLS_Ciphersuite("ECDSA", "ECDH", "SHA1", "ARC4", 16); if(suite == TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_ECDSA | - TLS_ALGO_KEYEXCH_ECDH | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_3DES_CBC); + return TLS_Ciphersuite("ECDSA", "ECDH", "SHA1", "TripleDES", 24); if(suite == TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_ECDSA | - TLS_ALGO_KEYEXCH_ECDH | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_AES128_CBC); + return TLS_Ciphersuite("ECDSA", "ECDH", "SHA1", "AES-128", 16); if(suite == TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_ECDSA | - TLS_ALGO_KEYEXCH_ECDH | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_AES256_CBC); + return TLS_Ciphersuite("ECDSA", "ECDH", "SHA1", "AES-256", 32); if(suite == TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_ECDSA | - TLS_ALGO_KEYEXCH_ECDH | - TLS_ALGO_HASH_SHA256 | - TLS_ALGO_CIPHER_AES128_CBC); + return TLS_Ciphersuite("ECDSA", "ECDH", "SHA-256", "AES-128", 16); if(suite == TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_ECDSA | - TLS_ALGO_KEYEXCH_ECDH | - TLS_ALGO_HASH_SHA384 | - TLS_ALGO_CIPHER_AES256_CBC); + return TLS_Ciphersuite("ECDSA", "ECDH", "SHA384", "AES-256", 32); if(suite == TLS_ECDHE_RSA_WITH_RC4_128_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_ECDH | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_RC4_128); + return TLS_Ciphersuite("RSA", "ECDH", "SHA1", "ARC4", 16); if(suite == TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_ECDH | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_3DES_CBC); + return TLS_Ciphersuite("RSA", "ECDH", "SHA1", "TripleDES", 24); if(suite == TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_ECDH | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_AES128_CBC); + return TLS_Ciphersuite("RSA", "ECDH", "SHA1", "AES-128", 16); if(suite == TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_RSA | - TLS_ALGO_KEYEXCH_ECDH | - TLS_ALGO_HASH_SHA1 | - TLS_ALGO_CIPHER_AES256_CBC); + return TLS_Ciphersuite("RSA", "ECDH", "SHA1", "AES-256", 32); if(suite == TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_ECDSA | - TLS_ALGO_KEYEXCH_ECDH | - TLS_ALGO_HASH_SHA256 | - TLS_ALGO_CIPHER_AES128_CBC); + return TLS_Ciphersuite("ECDSA", "ECDH", "SHA-256", "AES-128", 16); if(suite == TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) - return TLS_Ciphersuite_Algos(TLS_ALGO_SIGNER_ECDSA | - TLS_ALGO_KEYEXCH_ECDH | - TLS_ALGO_HASH_SHA384 | - TLS_ALGO_CIPHER_AES256_CBC); + return TLS_Ciphersuite("ECDSA", "ECDH", "SHA384", "AES-256", 32); - return TLS_Ciphersuite_Algos(0); + return TLS_Ciphersuite(); // some unknown ciphersuite } -std::pair<std::string, size_t> -TLS_Cipher_Suite::cipher_code_to_name(TLS_Ciphersuite_Algos algo) +TLS_Ciphersuite::TLS_Ciphersuite(const std::string& sig_algo, + const std::string& kex_algo, + const std::string& mac_algo, + const std::string& cipher_algo, + size_t cipher_algo_keylen) : + m_sig_algo(sig_algo), + m_kex_algo(kex_algo), + m_mac_algo(mac_algo), + m_cipher_algo(cipher_algo), + m_cipher_keylen(cipher_algo_keylen) { - 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, - "TLS_Cipher_Suite: Unknown cipher type " + to_string(algo)); - } - -std::string TLS_Cipher_Suite::hash_code_to_name(TLS_Ciphersuite_Algos algo) - { - if((algo & TLS_ALGO_HASH_MASK) == TLS_ALGO_HASH_MD5) - return "MD5"; - - if((algo & TLS_ALGO_HASH_MASK) == TLS_ALGO_HASH_SHA1) - return "SHA-1"; - - if((algo & TLS_ALGO_HASH_MASK) == TLS_ALGO_HASH_SHA224) - return "SHA-224"; - - if((algo & TLS_ALGO_HASH_MASK) == TLS_ALGO_HASH_SHA256) - return "SHA-256"; - - if((algo & TLS_ALGO_HASH_MASK) == TLS_ALGO_HASH_SHA384) - return "SHA-384"; - - if((algo & TLS_ALGO_HASH_MASK) == TLS_ALGO_HASH_SHA512) - return "SHA-512"; - - throw TLS_Exception(INTERNAL_ERROR, - "TLS_Cipher_Suite: Unknown MAC type " + to_string(algo)); - } - -/** -* TLS_Cipher_Suite Constructor -*/ -TLS_Cipher_Suite::TLS_Cipher_Suite(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 = hash_code_to_name(algos); } } diff --git a/src/tls/tls_suites.h b/src/tls/tls_suites.h index adb40a692..65203bdf7 100644 --- a/src/tls/tls_suites.h +++ b/src/tls/tls_suites.h @@ -17,29 +17,29 @@ namespace Botan { /** * Ciphersuite Information */ -class BOTAN_DLL TLS_Cipher_Suite +class BOTAN_DLL TLS_Ciphersuite { public: - static TLS_Ciphersuite_Algos lookup_ciphersuite(u16bit suite); + static TLS_Ciphersuite lookup_ciphersuite(u16bit suite); - static std::pair<std::string, size_t> - cipher_code_to_name(TLS_Ciphersuite_Algos algo); + const std::string kex_algo() const { return m_kex_algo; } + const std::string sig_algo() const { return m_sig_algo; } - static std::string hash_code_to_name(TLS_Ciphersuite_Algos algo); + std::string cipher_algo() const { return m_cipher_algo; } + std::string mac_algo() const { return m_mac_algo; } - std::string cipher_algo() const { return cipher; } - std::string mac_algo() const { return mac; } + size_t cipher_keylen() const { return m_cipher_keylen; } - size_t cipher_keylen() const { return cipher_key_length; } + TLS_Ciphersuite() : m_cipher_keylen(0) {} - TLS_Ciphersuite_Algos kex_type() const { return kex_algo; } - TLS_Ciphersuite_Algos sig_type() const { return sig_algo; } - - TLS_Cipher_Suite(u16bit ciphersuite_code = 0); + TLS_Ciphersuite(const std::string& sig_algo, + const std::string& kex_algo, + const std::string& mac_algo, + const std::string& cipher_algo, + size_t cipher_algo_keylen); private: - TLS_Ciphersuite_Algos kex_algo, sig_algo; - std::string cipher, mac; - size_t cipher_key_length; + std::string m_sig_algo, m_kex_algo, m_mac_algo, m_cipher_algo; + size_t m_cipher_keylen; }; } |