aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libstate/get_enc.cpp4
-rw-r--r--src/tls/c_hello.cpp14
-rw-r--r--src/tls/c_kex.cpp4
-rw-r--r--src/tls/cert_ver.cpp19
-rw-r--r--src/tls/rec_read.cpp2
-rw-r--r--src/tls/rec_wri.cpp2
-rw-r--r--src/tls/s_kex.cpp57
-rw-r--r--src/tls/tls_client.cpp30
-rw-r--r--src/tls/tls_extensions.cpp118
-rw-r--r--src/tls/tls_extensions.h12
-rw-r--r--src/tls/tls_handshake_state.cpp109
-rw-r--r--src/tls/tls_handshake_state.h10
-rw-r--r--src/tls/tls_magic.h35
-rw-r--r--src/tls/tls_messages.h20
-rw-r--r--src/tls/tls_record.h4
-rw-r--r--src/tls/tls_server.cpp10
-rw-r--r--src/tls/tls_suites.cpp280
-rw-r--r--src/tls/tls_suites.h30
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;
};
}