From 8d1787751a15605dfd2729a9ddf67ce826d739f4 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 18 Jan 2012 17:51:57 +0000 Subject: Read only support for signature_algorithms extension used in TLS 1.2 --- src/tls/tls_extensions.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'src/tls/tls_extensions.h') diff --git a/src/tls/tls_extensions.h b/src/tls/tls_extensions.h index 62f179998..94be97d7f 100644 --- a/src/tls/tls_extensions.h +++ b/src/tls/tls_extensions.h @@ -176,6 +176,39 @@ class Next_Protocol_Notification : public TLS_Extension std::vector m_protocols; }; +/** +* Signature Algorithms Extension for TLS 1.2 (RFC 5246) +*/ +class Signature_Algorithms : public TLS_Extension + { + public: + TLS_Handshake_Extension_Type type() const + { return TLSEXT_NEXT_PROTOCOL; } + + std::vector > + supported_signature_algorthms() const + { + return m_supported_algos; + } + + MemoryVector serialize() const; + + bool empty() const { return false; } + + Signature_Algorithms(); + + Signature_Algorithms(TLS_Data_Reader& reader, + u16bit extension_size); + private: + static TLS_Ciphersuite_Algos hash_algo_code(byte code); + static byte hash_algo_code(TLS_Ciphersuite_Algos code); + + static TLS_Ciphersuite_Algos sig_algo_code(byte code); + static byte sig_algo_code(TLS_Ciphersuite_Algos code); + + std::vector > m_supported_algos; + }; + /** * Represents a block of extensions in a hello message */ -- cgit v1.2.3 From 265cf8e312723e688f4dbc8e4d90e0eae5445c97 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 19 Jan 2012 18:14:20 +0000 Subject: Kinda maybe working TLS 1.2 for clients. Not well tested at all, but a basic connection with a GnuTLS server does work. Currently we don't respect the signature_algorithms extension at all, and using SHA-256 with a 12-byte finished value is hardcoded though the spec is that it can depend on the ciphersuite (likely relevant for GOST ciphersuites in particular). --- doc/examples/tls_client.cpp | 2 +- src/kdf/prf_tls/info.txt | 1 + src/libstate/get_enc.cpp | 11 +++++--- src/tls/cert_ver.cpp | 10 +++++-- src/tls/finished.cpp | 27 ++++++++++++++----- src/tls/rec_read.cpp | 3 --- src/tls/rec_wri.cpp | 3 --- src/tls/s_hello.cpp | 12 ++++++++- src/tls/s_kex.cpp | 58 ++++++++++++++++++++++++----------------- src/tls/tls_client.cpp | 23 +++++++++------- src/tls/tls_extensions.cpp | 6 ++--- src/tls/tls_extensions.h | 12 ++++----- src/tls/tls_handshake_hash.cpp | 33 +++++++++++++++++------ src/tls/tls_handshake_hash.h | 4 +-- src/tls/tls_handshake_state.cpp | 18 ++++++++++--- src/tls/tls_handshake_state.h | 4 ++- src/tls/tls_magic.h | 2 +- src/tls/tls_messages.h | 8 +++++- src/tls/tls_reader.h | 7 +++-- src/tls/tls_session_key.cpp | 2 ++ src/tls/tls_suites.cpp | 11 +++----- src/tls/tls_suites.h | 5 ++++ 22 files changed, 173 insertions(+), 89 deletions(-) (limited to 'src/tls/tls_extensions.h') diff --git a/doc/examples/tls_client.cpp b/doc/examples/tls_client.cpp index a23332f22..29a5414e1 100644 --- a/doc/examples/tls_client.cpp +++ b/doc/examples/tls_client.cpp @@ -23,7 +23,7 @@ using namespace std::tr1::placeholders; class Client_TLS_Policy : public TLS_Policy { public: - Version_Code pref_version() const { return SSL_V3; } + Version_Code pref_version() const { return TLS_V12; } bool check_cert(const std::vector& certs) const { diff --git a/src/kdf/prf_tls/info.txt b/src/kdf/prf_tls/info.txt index 9531a6a83..113c92251 100644 --- a/src/kdf/prf_tls/info.txt +++ b/src/kdf/prf_tls/info.txt @@ -1,4 +1,5 @@ define TLS_V10_PRF +define TLS_V12_PRF hmac diff --git a/src/libstate/get_enc.cpp b/src/libstate/get_enc.cpp index 6a87268e8..6b74f8793 100644 --- a/src/libstate/get_enc.cpp +++ b/src/libstate/get_enc.cpp @@ -200,9 +200,14 @@ KDF* get_kdf(const std::string& algo_spec) return new TLS_PRF; #endif -#if defined(BOTAN_HAS_SSL_V3_PRF) - if(request.algo_name() == "SSL3-PRF" && request.arg_count() == 0) - return new SSL3_PRF; +#if defined(BOTAN_HAS_TLS_V10_PRF) + if(request.algo_name() == "TLS-PRF" && request.arg_count() == 0) + return new TLS_PRF; +#endif + +#if defined(BOTAN_HAS_TLS_V12_PRF) + if(request.algo_name() == "TLS-12-PRF" && request.arg_count() == 1) + return new TLS_12_PRF(af.make_mac("HMAC(" + request.arg(0) + ")")); #endif throw Algorithm_Not_Found(algo_spec); diff --git a/src/tls/cert_ver.cpp b/src/tls/cert_ver.cpp index 77d9fe74b..f35202734 100644 --- a/src/tls/cert_ver.cpp +++ b/src/tls/cert_ver.cpp @@ -27,8 +27,14 @@ Certificate_Verify::Certificate_Verify(Record_Writer& writer, { BOTAN_ASSERT_NONNULL(priv_key); + // FIXME: this should respect server's hash preferences + if(state->version >= TLS_V12) + hash_algo = TLS_ALGO_HASH_SHA256; + else + hash_algo = TLS_ALGO_NONE; + std::pair format = - state->choose_sig_format(priv_key, true); + state->choose_sig_format(priv_key, hash_algo, true); PK_Signer signer(*priv_key, format.first, format.second); @@ -86,7 +92,7 @@ bool Certificate_Verify::verify(const X509_Certificate& cert, std::auto_ptr key(cert.subject_public_key()); std::pair format = - state->choose_sig_format(key.get(), true); + state->choose_sig_format(key.get(), hash_algo, true); PK_Verifier verifier(*key, format.first, format.second); diff --git a/src/tls/finished.cpp b/src/tls/finished.cpp index baa663798..2eec244f2 100644 --- a/src/tls/finished.cpp +++ b/src/tls/finished.cpp @@ -7,11 +7,27 @@ #include #include +#include +#include +#include + +#include namespace Botan { namespace { +KDF* choose_tls_prf(Version_Code version) + { + if(version == TLS_V10 || version == TLS_V11) + return new TLS_PRF; + else if(version == TLS_V12) + return new TLS_12_PRF(new HMAC(new SHA_256)); // might depend on ciphersuite + else + throw TLS_Exception(PROTOCOL_VERSION, + "Unknown version for PRF"); + } + /* * Compute the verify_data */ @@ -32,7 +48,7 @@ MemoryVector finished_compute_verify(TLS_Handshake_State* state, return state->hash.final_ssl3(state->keys.master_secret()); } - else if(state->version == TLS_V10 || state->version == TLS_V11) + else { const byte TLS_CLIENT_LABEL[] = { 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x69, @@ -42,19 +58,18 @@ MemoryVector finished_compute_verify(TLS_Handshake_State* state, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x66, 0x69, 0x6E, 0x69, 0x73, 0x68, 0x65, 0x64 }; - TLS_PRF prf; + std::auto_ptr prf(choose_tls_prf(state->version)); MemoryVector input; if(side == CLIENT) input += std::make_pair(TLS_CLIENT_LABEL, sizeof(TLS_CLIENT_LABEL)); else input += std::make_pair(TLS_SERVER_LABEL, sizeof(TLS_SERVER_LABEL)); - input += state->hash.final(); - return prf.derive_key(12, state->keys.master_secret(), input); + input += state->hash.final(state->version); + + return prf->derive_key(12, state->keys.master_secret(), input); } - else - throw Invalid_Argument("Finished message: Unknown protocol version"); } } diff --git a/src/tls/rec_read.cpp b/src/tls/rec_read.cpp index 20dfaae2e..2376dfd2b 100644 --- a/src/tls/rec_read.cpp +++ b/src/tls/rec_read.cpp @@ -57,9 +57,6 @@ void Record_Reader::set_maximum_fragment_size(size_t max_fragment) */ void Record_Reader::set_version(Version_Code version) { - if(version != SSL_V3 && version != TLS_V10 && version != TLS_V11) - throw Invalid_Argument("Record_Reader: Invalid protocol version"); - m_major = (version >> 8) & 0xFF; m_minor = (version & 0xFF); } diff --git a/src/tls/rec_wri.cpp b/src/tls/rec_wri.cpp index c0a79a631..7a67ed962 100644 --- a/src/tls/rec_wri.cpp +++ b/src/tls/rec_wri.cpp @@ -60,9 +60,6 @@ void Record_Writer::reset() */ void Record_Writer::set_version(Version_Code version) { - if(version != SSL_V3 && version != TLS_V10 && version != TLS_V11) - throw Invalid_Argument("Record_Writer: Invalid protocol version"); - m_major = (version >> 8) & 0xFF; m_minor = (version & 0xFF); } diff --git a/src/tls/s_hello.cpp b/src/tls/s_hello.cpp index fa185599d..21619fe0c 100644 --- a/src/tls/s_hello.cpp +++ b/src/tls/s_hello.cpp @@ -104,7 +104,10 @@ Server_Hello::Server_Hello(const MemoryRegion& buf) s_version = static_cast(reader.get_u16bit()); - if(s_version != SSL_V3 && s_version != TLS_V10 && s_version != TLS_V11) + if(s_version != SSL_V3 && + s_version != TLS_V10 && + s_version != TLS_V11 && + s_version != TLS_V12) { throw TLS_Exception(PROTOCOL_VERSION, "Server_Hello: Unsupported server version"); @@ -135,6 +138,10 @@ Server_Hello::Server_Hello(const MemoryRegion& buf) m_next_protocols = npn->protocols(); m_next_protocol = true; } + else if(Signature_Algorithms* sigs = dynamic_cast(extn)) + { + // save in handshake state + } } } @@ -167,6 +174,9 @@ MemoryVector Server_Hello::serialize() const if(m_next_protocol) extensions.push_back(new Next_Protocol_Notification(m_next_protocols)); + if(s_version == TLS_V12) + extensions.push_back(new Signature_Algorithms()); + buf += extensions.serialize(); return buf; diff --git a/src/tls/s_kex.cpp b/src/tls/s_kex.cpp index 7008c89de..2e2bc4cb0 100644 --- a/src/tls/s_kex.cpp +++ b/src/tls/s_kex.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -34,8 +35,14 @@ Server_Key_Exchange::Server_Key_Exchange(Record_Writer& writer, throw Invalid_Argument("Unknown key type " + state->kex_priv->algo_name() + " for TLS key exchange"); + // FIXME: this should respect client's hash preferences + if(state->version >= TLS_V12) + hash_algo = TLS_ALGO_HASH_SHA256; + else + hash_algo = TLS_ALGO_NONE; + std::pair format = - state->choose_sig_format(private_key, false); + state->choose_sig_format(private_key, hash_algo, false); PK_Signer signer(*private_key, format.first, format.second); @@ -53,6 +60,10 @@ Server_Key_Exchange::Server_Key_Exchange(Record_Writer& writer, MemoryVector Server_Key_Exchange::serialize() const { MemoryVector buf = serialize_params(); + + if(hash_algo != TLS_ALGO_NONE) + {} + append_tls_length_value(buf, signature, 2); return buf; } @@ -73,39 +84,38 @@ MemoryVector Server_Key_Exchange::serialize_params() const /** * Deserialize a Server Key Exchange message */ -Server_Key_Exchange::Server_Key_Exchange(const MemoryRegion& buf) +Server_Key_Exchange::Server_Key_Exchange(const MemoryRegion& buf, + TLS_Ciphersuite_Algos kex_alg, + TLS_Ciphersuite_Algos sig_alg, + Version_Code version) { if(buf.size() < 6) throw Decoding_Error("Server_Key_Exchange: Packet corrupted"); - MemoryVector values[4]; - size_t so_far = 0; + TLS_Data_Reader reader(buf); - for(size_t i = 0; i != 4; ++i) + if(kex_alg == TLS_ALGO_KEYEXCH_DH) { - const u16bit len = make_u16bit(buf[so_far], buf[so_far+1]); - so_far += 2; - - if(len + so_far > buf.size()) - throw Decoding_Error("Server_Key_Exchange: Packet corrupted"); + // 3 bigints, DH p, g, Y - values[i].resize(len); - copy_mem(&values[i][0], &buf[so_far], len); - so_far += len; - - if(i == 2 && so_far == buf.size()) - break; + for(size_t i = 0; i != 3; ++i) + { + BigInt v = BigInt::decode(reader.get_range(2, 1, 65535)); + params.push_back(v); + } } + else + throw Decoding_Error("Unsupported server key exchange type"); - params.push_back(BigInt::decode(values[0])); - params.push_back(BigInt::decode(values[1])); - if(values[3].size()) + if(sig_alg != TLS_ALGO_SIGNER_ANON) { - params.push_back(BigInt::decode(values[2])); - signature = values[3]; + if(version < TLS_V12) + hash_algo = TLS_ALGO_NONE; // use old defaults + else + hash_algo = Signature_Algorithms::hash_algo_code(reader.get_byte()); + + signature = reader.get_range(2, 0, 65535); } - else - signature = values[2]; } /** @@ -128,7 +138,7 @@ bool Server_Key_Exchange::verify(const X509_Certificate& cert, std::auto_ptr key(cert.subject_public_key()); std::pair format = - state->choose_sig_format(key.get(), false); + state->choose_sig_format(key.get(), hash_algo, false); PK_Verifier verifier(*key, format.first, format.second); diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp index ef96c04fb..c8fcd8144 100644 --- a/src/tls/tls_client.cpp +++ b/src/tls/tls_client.cpp @@ -277,7 +277,19 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, state->set_expected_next(CERTIFICATE_REQUEST); // optional state->set_expected_next(SERVER_HELLO_DONE); - state->server_kex = new Server_Key_Exchange(contents); + state->server_kex = new Server_Key_Exchange(contents, + state->suite.kex_type(), + state->suite.sig_type(), + state->version); + + if(state->suite.sig_type() != TLS_ALGO_SIGNER_ANON) + { + if(!state->server_kex->verify(peer_certs[0], state)) + { + throw TLS_Exception(DECRYPT_ERROR, + "Bad signature on server key exchange"); + } + } if(state->kex_pub) delete state->kex_pub; @@ -290,15 +302,6 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, throw TLS_Exception(HANDSHAKE_FAILURE, "Server sent DH key but negotiated something else"); } - - if(state->suite.sig_type() != TLS_ALGO_SIGNER_ANON) - { - if(!state->server_kex->verify(peer_certs[0], state)) - { - throw TLS_Exception(DECRYPT_ERROR, - "Bad signature on server key exchange"); - } - } } else if(type == CERTIFICATE_REQUEST) { diff --git a/src/tls/tls_extensions.cpp b/src/tls/tls_extensions.cpp index d414a979d..9f80744f9 100644 --- a/src/tls/tls_extensions.cpp +++ b/src/tls/tls_extensions.cpp @@ -288,7 +288,7 @@ TLS_Ciphersuite_Algos Signature_Algorithms::hash_algo_code(byte code) case 6: return TLS_ALGO_HASH_SHA512; default: - return TLS_ALGO_UNKNOWN; + return TLS_ALGO_NONE; } } @@ -324,7 +324,7 @@ TLS_Ciphersuite_Algos Signature_Algorithms::sig_algo_code(byte code) case 3: return TLS_ALGO_SIGNER_ECDSA; default: - return TLS_ALGO_UNKNOWN; + return TLS_ALGO_NONE; } } @@ -399,7 +399,7 @@ Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, TLS_Ciphersuite_Algos sig_code = sig_algo_code(reader.get_byte()); // If not something we know, ignore completely - if(hash_code == TLS_ALGO_UNKNOWN || sig_code == TLS_ALGO_UNKNOWN) + if(hash_code == TLS_ALGO_NONE || sig_code == TLS_ALGO_NONE) 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 94be97d7f..1811bab01 100644 --- a/src/tls/tls_extensions.h +++ b/src/tls/tls_extensions.h @@ -182,6 +182,12 @@ class Next_Protocol_Notification : public TLS_Extension class Signature_Algorithms : public TLS_Extension { public: + static TLS_Ciphersuite_Algos hash_algo_code(byte code); + static byte hash_algo_code(TLS_Ciphersuite_Algos code); + + static TLS_Ciphersuite_Algos sig_algo_code(byte code); + static byte sig_algo_code(TLS_Ciphersuite_Algos code); + TLS_Handshake_Extension_Type type() const { return TLSEXT_NEXT_PROTOCOL; } @@ -200,12 +206,6 @@ class Signature_Algorithms : public TLS_Extension Signature_Algorithms(TLS_Data_Reader& reader, u16bit extension_size); private: - static TLS_Ciphersuite_Algos hash_algo_code(byte code); - static byte hash_algo_code(TLS_Ciphersuite_Algos code); - - static TLS_Ciphersuite_Algos sig_algo_code(byte code); - static byte sig_algo_code(TLS_Ciphersuite_Algos code); - std::vector > m_supported_algos; }; diff --git a/src/tls/tls_handshake_hash.cpp b/src/tls/tls_handshake_hash.cpp index 9621af535..14d5cd5a1 100644 --- a/src/tls/tls_handshake_hash.cpp +++ b/src/tls/tls_handshake_hash.cpp @@ -6,8 +6,10 @@ */ #include +#include #include #include +#include #include namespace Botan { @@ -27,17 +29,32 @@ void TLS_Handshake_Hash::update(Handshake_Type handshake_type, /** * Return a TLS Handshake Hash */ -SecureVector TLS_Handshake_Hash::final() +SecureVector TLS_Handshake_Hash::final(Version_Code version) { - MD5 md5; - SHA_160 sha1; + SecureVector output; - md5.update(data); - sha1.update(data); + if(version == TLS_V10 || version == TLS_V11) + { + MD5 md5; + SHA_160 sha1; + + md5.update(data); + sha1.update(data); + + output += md5.final(); + output += sha1.final(); + } + else if(version == TLS_V12) + { + // This might depend on the ciphersuite + SHA_256 sha256; + sha256.update(data); + output += sha256.final(); + } + else + throw TLS_Exception(PROTOCOL_VERSION, + "Unknown version for handshake hashes"); - SecureVector output; - output += md5.final(); - output += sha1.final(); return output; } diff --git a/src/tls/tls_handshake_hash.h b/src/tls/tls_handshake_hash.h index 4ee1fc1b9..1ca11b99f 100644 --- a/src/tls/tls_handshake_hash.h +++ b/src/tls/tls_handshake_hash.h @@ -33,8 +33,8 @@ class TLS_Handshake_Hash void update(Handshake_Type handshake_type, const MemoryRegion& handshake_msg); - SecureVector final(); - SecureVector final_ssl3(const MemoryRegion&); + SecureVector final(Version_Code version); + SecureVector final_ssl3(const MemoryRegion& master_secret); const SecureVector& get_contents() const { return data; } diff --git a/src/tls/tls_handshake_state.cpp b/src/tls/tls_handshake_state.cpp index f2f6a2baf..a816e9f6a 100644 --- a/src/tls/tls_handshake_state.cpp +++ b/src/tls/tls_handshake_state.cpp @@ -130,7 +130,9 @@ bool TLS_Handshake_State::received_handshake_msg(Handshake_Type handshake_msg) c } std::pair -TLS_Handshake_State::choose_sig_format(const Public_Key* key, bool for_client_auth) +TLS_Handshake_State::choose_sig_format(const Public_Key* key, + TLS_Ciphersuite_Algos hash_algo, + bool for_client_auth) { const std::string algo_name = key->algo_name(); @@ -140,8 +142,13 @@ TLS_Handshake_State::choose_sig_format(const Public_Key* key, bool for_client_au if(for_client_auth && this->version == SSL_V3) padding = "EMSA3(Raw)"; - else + 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 + ")"; + } return std::make_pair(padding, IEEE_1363); } @@ -151,8 +158,13 @@ TLS_Handshake_State::choose_sig_format(const Public_Key* key, bool for_client_au if(for_client_auth && this->version == SSL_V3) padding = "Raw"; - else + 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 + ")"; + } return std::make_pair(padding, DER_SEQUENCE); } diff --git a/src/tls/tls_handshake_state.h b/src/tls/tls_handshake_state.h index e58a83f3e..1beaf74b3 100644 --- a/src/tls/tls_handshake_state.h +++ b/src/tls/tls_handshake_state.h @@ -47,7 +47,9 @@ class TLS_Handshake_State void set_expected_next(Handshake_Type handshake_msg); std::pair - choose_sig_format(const Public_Key* key, bool for_client_auth); + choose_sig_format(const Public_Key* key, + TLS_Ciphersuite_Algos hash_algo, + bool for_client_auth); Version_Code version; diff --git a/src/tls/tls_magic.h b/src/tls/tls_magic.h index 231ac363f..ac3c562dc 100644 --- a/src/tls/tls_magic.h +++ b/src/tls/tls_magic.h @@ -167,7 +167,7 @@ enum Ciphersuite_Code { * being randomly assigned codepoints. */ enum TLS_Ciphersuite_Algos { - TLS_ALGO_UNKNOWN = 0x00000000, + TLS_ALGO_NONE = 0x00000000, TLS_ALGO_SIGNER_MASK = 0xFF000000, TLS_ALGO_SIGNER_ANON = 0x01000000, diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h index d3735972e..f2052c5e7 100644 --- a/src/tls/tls_messages.h +++ b/src/tls/tls_messages.h @@ -300,6 +300,7 @@ class Certificate_Verify : public Handshake_Message private: MemoryVector serialize() const; + TLS_Ciphersuite_Algos hash_algo; // hash used to create signature MemoryVector signature; }; @@ -360,12 +361,17 @@ class Server_Key_Exchange : public Handshake_Message RandomNumberGenerator& rng, const Private_Key* priv_key); - Server_Key_Exchange(const MemoryRegion& buf); + Server_Key_Exchange(const MemoryRegion& buf, + TLS_Ciphersuite_Algos kex_alg, + TLS_Ciphersuite_Algos sig_alg, + Version_Code version); private: MemoryVector serialize() const; MemoryVector serialize_params() const; std::vector params; + + TLS_Ciphersuite_Algos hash_algo; // hash used to create signature MemoryVector signature; }; diff --git a/src/tls/tls_reader.h b/src/tls/tls_reader.h index 6a0bcd5b1..3f7123b89 100644 --- a/src/tls/tls_reader.h +++ b/src/tls/tls_reader.h @@ -151,10 +151,9 @@ class TLS_Data_Reader void assert_at_least(size_t n) const { if(buf.size() - offset < n) - { - abort(); - throw Decoding_Error("TLS_Data_Reader: Corrupt packet"); - } + throw Decoding_Error("TLS_Data_Reader: Expected " + to_string(n) + + "bytes remaining, only " + to_string(buf.size()-offset) + + " left"); } const MemoryRegion& buf; diff --git a/src/tls/tls_session_key.cpp b/src/tls/tls_session_key.cpp index 66a02542b..cb55499f0 100644 --- a/src/tls/tls_session_key.cpp +++ b/src/tls/tls_session_key.cpp @@ -21,6 +21,8 @@ std::string lookup_prf_name(Version_Code version) return "SSL3-PRF"; else if(version == TLS_V10 || version == TLS_V11) return "TLS-PRF"; + else if(version == TLS_V12) + return "TLS-12-PRF(SHA-256)"; else throw Invalid_Argument("Session_Keys: Unknown version code"); } diff --git a/src/tls/tls_suites.cpp b/src/tls/tls_suites.cpp index 3b715b04c..f3a967b3e 100644 --- a/src/tls/tls_suites.cpp +++ b/src/tls/tls_suites.cpp @@ -254,9 +254,8 @@ TLS_Ciphersuite_Algos TLS_Cipher_Suite::lookup_ciphersuite(u16bit suite) return TLS_Ciphersuite_Algos(0); } -namespace { - -std::pair cipher_code_to_name(TLS_Ciphersuite_Algos algo) +std::pair +TLS_Cipher_Suite::cipher_code_to_name(TLS_Ciphersuite_Algos algo) { if((algo & TLS_ALGO_CIPHER_MASK) == TLS_ALGO_CIPHER_RC4_128) return std::make_pair("ARC4", 16); @@ -277,7 +276,7 @@ std::pair cipher_code_to_name(TLS_Ciphersuite_Algos algo) "TLS_Cipher_Suite: Unknown cipher type " + to_string(algo)); } -std::string mac_code_to_name(TLS_Ciphersuite_Algos 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"; @@ -301,8 +300,6 @@ std::string mac_code_to_name(TLS_Ciphersuite_Algos algo) "TLS_Cipher_Suite: Unknown MAC type " + to_string(algo)); } -} - /** * TLS_Cipher_Suite Constructor */ @@ -325,7 +322,7 @@ TLS_Cipher_Suite::TLS_Cipher_Suite(u16bit suite_code) cipher = cipher_info.first; cipher_key_length = cipher_info.second; - mac = mac_code_to_name(algos); + mac = hash_code_to_name(algos); } } diff --git a/src/tls/tls_suites.h b/src/tls/tls_suites.h index 3256dc198..adb40a692 100644 --- a/src/tls/tls_suites.h +++ b/src/tls/tls_suites.h @@ -22,6 +22,11 @@ class BOTAN_DLL TLS_Cipher_Suite public: static TLS_Ciphersuite_Algos lookup_ciphersuite(u16bit suite); + static std::pair + cipher_code_to_name(TLS_Ciphersuite_Algos algo); + + static std::string hash_code_to_name(TLS_Ciphersuite_Algos algo); + std::string cipher_algo() const { return cipher; } std::string mac_algo() const { return mac; } -- cgit v1.2.3 From 4c3d3e1c56451c635fb81dadfb249ce1856af0ce Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 19 Jan 2012 20:02:07 +0000 Subject: Various and sundry bug fixes --- src/tls/c_hello.cpp | 3 +++ src/tls/s_hello.cpp | 3 --- src/tls/s_kex.cpp | 22 ++++++++++++++++++++-- src/tls/tls_extensions.h | 2 +- src/tls/tls_messages.h | 2 ++ src/tls/tls_policy.cpp | 4 ++-- src/tls/tls_policy.h | 2 +- src/tls/tls_server.cpp | 2 +- src/tls/tls_session.h | 2 +- 9 files changed, 31 insertions(+), 11 deletions(-) (limited to 'src/tls/tls_extensions.h') diff --git a/src/tls/c_hello.cpp b/src/tls/c_hello.cpp index 60f6de487..a70713a80 100644 --- a/src/tls/c_hello.cpp +++ b/src/tls/c_hello.cpp @@ -151,6 +151,9 @@ MemoryVector Client_Hello::serialize() const extensions.push_back(new Server_Name_Indicator(m_hostname)); extensions.push_back(new SRP_Identifier(m_srp_identifier)); + if(m_version >= TLS_V12) + extensions.push_back(new Signature_Algorithms()); + if(m_next_protocol) extensions.push_back(new Next_Protocol_Notification()); } diff --git a/src/tls/s_hello.cpp b/src/tls/s_hello.cpp index 21619fe0c..652544806 100644 --- a/src/tls/s_hello.cpp +++ b/src/tls/s_hello.cpp @@ -174,9 +174,6 @@ MemoryVector Server_Hello::serialize() const if(m_next_protocol) extensions.push_back(new Next_Protocol_Notification(m_next_protocols)); - if(s_version == TLS_V12) - extensions.push_back(new Signature_Algorithms()); - buf += extensions.serialize(); return buf; diff --git a/src/tls/s_kex.cpp b/src/tls/s_kex.cpp index 2e2bc4cb0..ac6ee15ee 100644 --- a/src/tls/s_kex.cpp +++ b/src/tls/s_kex.cpp @@ -37,9 +37,15 @@ Server_Key_Exchange::Server_Key_Exchange(Record_Writer& writer, // FIXME: this should respect client's hash preferences if(state->version >= TLS_V12) + { hash_algo = TLS_ALGO_HASH_SHA256; + sig_algo = TLS_ALGO_SIGNER_RSA; + } else + { hash_algo = TLS_ALGO_NONE; + sig_algo = TLS_ALGO_NONE; + } std::pair format = state->choose_sig_format(private_key, hash_algo, false); @@ -62,7 +68,10 @@ MemoryVector Server_Key_Exchange::serialize() const MemoryVector buf = serialize_params(); if(hash_algo != TLS_ALGO_NONE) - {} + { + buf.push_back(Signature_Algorithms::hash_algo_code(hash_algo)); + buf.push_back(Signature_Algorithms::sig_algo_code(sig_algo)); + } append_tls_length_value(buf, signature, 2); return buf; @@ -110,9 +119,16 @@ Server_Key_Exchange::Server_Key_Exchange(const MemoryRegion& buf, if(sig_alg != TLS_ALGO_SIGNER_ANON) { if(version < TLS_V12) - hash_algo = TLS_ALGO_NONE; // use old defaults + { + // 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()); + } signature = reader.get_range(2, 0, 65535); } @@ -137,6 +153,8 @@ bool Server_Key_Exchange::verify(const X509_Certificate& cert, { std::auto_ptr key(cert.subject_public_key()); + printf("Checking %s vs code %d\n", key->algo_name().c_str(), sig_algo); + std::pair format = state->choose_sig_format(key.get(), hash_algo, false); diff --git a/src/tls/tls_extensions.h b/src/tls/tls_extensions.h index 1811bab01..2f4f711c2 100644 --- a/src/tls/tls_extensions.h +++ b/src/tls/tls_extensions.h @@ -189,7 +189,7 @@ class Signature_Algorithms : public TLS_Extension static byte sig_algo_code(TLS_Ciphersuite_Algos code); TLS_Handshake_Extension_Type type() const - { return TLSEXT_NEXT_PROTOCOL; } + { return TLSEXT_SIGNATURE_ALGORITHMS; } std::vector > supported_signature_algorthms() const diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h index f2052c5e7..9ea0b1a2d 100644 --- a/src/tls/tls_messages.h +++ b/src/tls/tls_messages.h @@ -300,6 +300,7 @@ class Certificate_Verify : public Handshake_Message private: MemoryVector serialize() const; + TLS_Ciphersuite_Algos sig_algo; // sig algo used to create signature TLS_Ciphersuite_Algos hash_algo; // hash used to create signature MemoryVector signature; }; @@ -371,6 +372,7 @@ class Server_Key_Exchange : public Handshake_Message std::vector params; + TLS_Ciphersuite_Algos sig_algo; // sig algo used to create signature TLS_Ciphersuite_Algos hash_algo; // hash used to create signature MemoryVector signature; }; diff --git a/src/tls/tls_policy.cpp b/src/tls/tls_policy.cpp index 391e8e758..b510c3d4b 100644 --- a/src/tls/tls_policy.cpp +++ b/src/tls/tls_policy.cpp @@ -72,8 +72,8 @@ std::vector TLS_Policy::suite_list(bool use_rsa, if(use_rsa) { - suites.push_back(TLS_RSA_WITH_AES_256_CBC_SHA_256); - suites.push_back(TLS_RSA_WITH_AES_128_CBC_SHA_256); + suites.push_back(TLS_RSA_WITH_AES_256_CBC_SHA256); + suites.push_back(TLS_RSA_WITH_AES_128_CBC_SHA256); suites.push_back(TLS_RSA_WITH_AES_256_CBC_SHA); suites.push_back(TLS_RSA_WITH_AES_128_CBC_SHA); diff --git a/src/tls/tls_policy.h b/src/tls/tls_policy.h index 48ff9185e..a0bca4e7f 100644 --- a/src/tls/tls_policy.h +++ b/src/tls/tls_policy.h @@ -52,7 +52,7 @@ class BOTAN_DLL TLS_Policy /* * @return the version we would prefer to negotiate */ - virtual Version_Code pref_version() const { return TLS_V11; } + virtual Version_Code pref_version() const { return TLS_V12; } virtual bool check_cert(const std::vector& cert_chain) const = 0; diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp index e3e2fe208..503d55610 100644 --- a/src/tls/tls_server.cpp +++ b/src/tls/tls_server.cpp @@ -25,7 +25,7 @@ Version_Code choose_version(Version_Code client, Version_Code minimum) throw TLS_Exception(PROTOCOL_VERSION, "Client version is unacceptable by policy"); - if(client == SSL_V3 || client == TLS_V10 || client == TLS_V11) + if(client == SSL_V3 || client == TLS_V10 || client == TLS_V11 || client == TLS_V12) return client; return TLS_V11; } diff --git a/src/tls/tls_session.h b/src/tls/tls_session.h index f1352a0e0..12b76bcab 100644 --- a/src/tls/tls_session.h +++ b/src/tls/tls_session.h @@ -75,7 +75,7 @@ class BOTAN_DLL TLS_Session /** * Get the minor version of the saved session */ - byte minor_version() const { return get_byte(0, m_version); } + byte minor_version() const { return get_byte(1, m_version); } /** * Get the ciphersuite of the saved session -- cgit v1.2.3 From f7f94a9ade8869caca24aed9bde92bce117991f7 Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 20 Jan 2012 13:52:54 +0000 Subject: Many fixes for TLS 1.2 though some things in particular client auth remain broken. New interface for querying the TLS extensions, much cleaner. --- src/tls/c_hello.cpp | 68 +++++++++++++++++++++------------------- src/tls/cert_req.cpp | 54 ++++++++++++++++---------------- src/tls/cert_ver.cpp | 47 ++++++++++++++++------------ src/tls/s_hello.cpp | 34 ++++++++------------ src/tls/s_kex.cpp | 20 ++---------- src/tls/tls_client.cpp | 5 ++- src/tls/tls_extensions.cpp | 19 +++++++----- src/tls/tls_extensions.h | 52 +++++++++++++++++++++++-------- src/tls/tls_handshake_state.cpp | 69 +++++++++++++++++++++++++++++++++++++++++ src/tls/tls_handshake_state.h | 7 +++++ src/tls/tls_messages.h | 14 +++++---- src/tls/tls_policy.h | 2 +- src/tls/tls_server.cpp | 10 ++++-- 13 files changed, 251 insertions(+), 150 deletions(-) (limited to 'src/tls/tls_extensions.h') diff --git a/src/tls/c_hello.cpp b/src/tls/c_hello.cpp index a70713a80..71c0c3de9 100644 --- a/src/tls/c_hello.cpp +++ b/src/tls/c_hello.cpp @@ -147,20 +147,20 @@ MemoryVector Client_Hello::serialize() const // Initial handshake if(m_renegotiation_info.empty()) { - extensions.push_back(new Renegotation_Extension(m_renegotiation_info)); - extensions.push_back(new Server_Name_Indicator(m_hostname)); - extensions.push_back(new SRP_Identifier(m_srp_identifier)); + extensions.add(new Renegotation_Extension(m_renegotiation_info)); + extensions.add(new Server_Name_Indicator(m_hostname)); + extensions.add(new SRP_Identifier(m_srp_identifier)); if(m_version >= TLS_V12) - extensions.push_back(new Signature_Algorithms()); + extensions.add(new Signature_Algorithms()); if(m_next_protocol) - extensions.push_back(new Next_Protocol_Notification()); + extensions.add(new Next_Protocol_Notification()); } else { // renegotiation - extensions.push_back(new Renegotation_Extension(m_renegotiation_info)); + extensions.add(new Renegotation_Extension(m_renegotiation_info)); } buf += extensions.serialize(); @@ -237,35 +237,39 @@ void Client_Hello::deserialize(const MemoryRegion& buf) TLS_Extensions extensions(reader); - for(size_t i = 0; i != extensions.count(); ++i) + if(Server_Name_Indicator* sni = extensions.get()) { - TLS_Extension* extn = extensions.at(i); + m_hostname = sni->host_name(); + } - if(Server_Name_Indicator* sni = dynamic_cast(extn)) - { - m_hostname = sni->host_name(); - } - else if(SRP_Identifier* srp = dynamic_cast(extn)) - { - m_srp_identifier = srp->identifier(); - } - else if(Next_Protocol_Notification* npn = dynamic_cast(extn)) - { - if(!npn->protocols().empty()) - throw Decoding_Error("Client sent non-empty NPN extension"); + if(SRP_Identifier* srp = extensions.get()) + { + m_srp_identifier = srp->identifier(); + } - m_next_protocol = true; - } - else if(Maximum_Fragment_Length* frag = dynamic_cast(extn)) - { - m_fragment_size = frag->fragment_size(); - } - else if(Renegotation_Extension* reneg = dynamic_cast(extn)) - { - // checked by TLS_Client / TLS_Server as they know the handshake state - m_secure_renegotiation = true; - m_renegotiation_info = reneg->renegotiation_info(); - } + if(Next_Protocol_Notification* npn = extensions.get()) + { + if(!npn->protocols().empty()) + throw Decoding_Error("Client sent non-empty NPN extension"); + + m_next_protocol = true; + } + + if(Maximum_Fragment_Length* frag = extensions.get()) + { + m_fragment_size = frag->fragment_size(); + } + + if(Renegotation_Extension* reneg = extensions.get()) + { + // checked by TLS_Client / TLS_Server as they know the handshake state + m_secure_renegotiation = true; + m_renegotiation_info = reneg->renegotiation_info(); + } + + if(Signature_Algorithms* sigs = extensions.get()) + { + // save in handshake state } if(value_exists(m_suites, static_cast(TLS_EMPTY_RENEGOTIATION_INFO_SCSV))) diff --git a/src/tls/cert_req.cpp b/src/tls/cert_req.cpp index bdb25057c..c3e46a5ae 100644 --- a/src/tls/cert_req.cpp +++ b/src/tls/cert_req.cpp @@ -7,11 +7,14 @@ #include #include +#include #include #include #include #include +#include + namespace Botan { /** @@ -20,18 +23,16 @@ namespace Botan { Certificate_Req::Certificate_Req(Record_Writer& writer, TLS_Handshake_Hash& hash, const std::vector& ca_certs, - const std::vector& cert_types) + Version_Code version) { for(size_t i = 0; i != ca_certs.size(); ++i) names.push_back(ca_certs[i].subject_dn()); - if(cert_types.empty()) // default is RSA/DSA is OK - { - types.push_back(RSA_CERT); - types.push_back(DSS_CERT); - } - else - types = cert_types; + cert_types.push_back(RSA_CERT); + cert_types.push_back(DSS_CERT); + + if(version >= TLS_V12) + sig_and_hash_algos = Signature_Algorithms().serialize(); send(writer, hash); } @@ -39,39 +40,36 @@ Certificate_Req::Certificate_Req(Record_Writer& writer, /** * Deserialize a Certificate Request message */ -Certificate_Req::Certificate_Req(const MemoryRegion& buf) +Certificate_Req::Certificate_Req(const MemoryRegion& buf, + Version_Code version) { if(buf.size() < 4) throw Decoding_Error("Certificate_Req: Bad certificate request"); - const size_t types_size = buf[0]; + TLS_Data_Reader reader(buf); - if(buf.size() < types_size + 3) - throw Decoding_Error("Certificate_Req: Bad certificate request"); + cert_types = reader.get_range_vector(1, 1, 255); - for(size_t i = 0; i != types_size; ++i) - types.push_back(static_cast(buf[i+1])); + if(version >= TLS_V12) + { + std::vector sig_hash_algs = reader.get_range_vector(2, 2, 65534); - const size_t names_size = make_u16bit(buf[types_size+1], buf[types_size+2]); + // FIXME, do something with this + } - if(buf.size() != names_size + types_size + 3) - throw Decoding_Error("Certificate_Req: Bad certificate request"); + u16bit purported_size = reader.get_u16bit(); - size_t offset = types_size + 3; + if(reader.remaining_bytes() != purported_size) + throw Decoding_Error("Inconsistent length in certificate request"); - while(offset < buf.size()) + while(reader.has_remaining()) { - const size_t name_size = make_u16bit(buf[offset], buf[offset+1]); - - if(offset + 2 + name_size > buf.size()) - throw Decoding_Error("Certificate_Req: Bad certificate request"); + std::vector name_bits = reader.get_range_vector(2, 0, 65535); - BER_Decoder decoder(&buf[offset + 2], name_size); + BER_Decoder decoder(&name_bits[0], name_bits.size()); X509_DN name; decoder.decode(name); names.push_back(name); - - offset += (2 + name_size); } } @@ -82,7 +80,9 @@ MemoryVector Certificate_Req::serialize() const { MemoryVector buf; - append_tls_length_value(buf, types, 1); + append_tls_length_value(buf, cert_types, 1); + + buf += sig_and_hash_algos; for(size_t i = 0; i != names.size(); ++i) { diff --git a/src/tls/cert_ver.cpp b/src/tls/cert_ver.cpp index f35202734..f7386dd13 100644 --- a/src/tls/cert_ver.cpp +++ b/src/tls/cert_ver.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -27,14 +28,8 @@ Certificate_Verify::Certificate_Verify(Record_Writer& writer, { BOTAN_ASSERT_NONNULL(priv_key); - // FIXME: this should respect server's hash preferences - if(state->version >= TLS_V12) - hash_algo = TLS_ALGO_HASH_SHA256; - else - hash_algo = TLS_ALGO_NONE; - std::pair format = - state->choose_sig_format(priv_key, hash_algo, true); + state->choose_sig_format(priv_key, hash_algo, sig_algo, true); PK_Signer signer(*priv_key, format.first, format.second); @@ -48,13 +43,10 @@ Certificate_Verify::Certificate_Verify(Record_Writer& writer, else signature = signer.sign_message(md5_sha, rng); } - else if(state->version == TLS_V10 || state->version == TLS_V11) + else { signature = signer.sign_message(state->hash.get_contents(), rng); } - else - throw TLS_Exception(PROTOCOL_VERSION, - "Unknown TLS version in certificate verification"); send(writer, state->hash); } @@ -62,9 +54,23 @@ Certificate_Verify::Certificate_Verify(Record_Writer& writer, /* * Deserialize a Certificate Verify message */ -Certificate_Verify::Certificate_Verify(const MemoryRegion& buf) +Certificate_Verify::Certificate_Verify(const MemoryRegion& buf, + Version_Code version) { TLS_Data_Reader reader(buf); + + 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()); + } + signature = reader.get_range(2, 0, 65535); } @@ -75,6 +81,12 @@ MemoryVector Certificate_Verify::serialize() const { MemoryVector buf; + if(hash_algo != TLS_ALGO_NONE) + { + buf.push_back(Signature_Algorithms::hash_algo_code(hash_algo)); + buf.push_back(Signature_Algorithms::sig_algo_code(sig_algo)); + } + const u16bit sig_len = signature.size(); buf.push_back(get_byte(0, sig_len)); buf.push_back(get_byte(1, sig_len)); @@ -92,7 +104,7 @@ bool Certificate_Verify::verify(const X509_Certificate& cert, std::auto_ptr key(cert.subject_public_key()); std::pair format = - state->choose_sig_format(key.get(), hash_algo, true); + state->choose_sig_format(key.get(), hash_algo, sig_algo, true); PK_Verifier verifier(*key, format.first, format.second); @@ -104,13 +116,8 @@ bool Certificate_Verify::verify(const X509_Certificate& cert, return verifier.verify_message(&md5_sha[16], md5_sha.size()-16, &signature[0], signature.size()); } - else if(state->version == TLS_V10 || state->version == TLS_V11) - { - return verifier.verify_message(state->hash.get_contents(), signature); - } - else - throw TLS_Exception(PROTOCOL_VERSION, - "Unknown TLS version in certificate verification"); + + return verifier.verify_message(state->hash.get_contents(), signature); } } diff --git a/src/tls/s_hello.cpp b/src/tls/s_hello.cpp index 652544806..e6aff94e3 100644 --- a/src/tls/s_hello.cpp +++ b/src/tls/s_hello.cpp @@ -123,25 +123,17 @@ Server_Hello::Server_Hello(const MemoryRegion& buf) TLS_Extensions extensions(reader); - for(size_t i = 0; i != extensions.count(); ++i) + if(Renegotation_Extension* reneg = extensions.get()) { - TLS_Extension* extn = extensions.at(i); - - if(Renegotation_Extension* reneg = dynamic_cast(extn)) - { - // checked by TLS_Client / TLS_Server as they know the handshake state - m_secure_renegotiation = true; - m_renegotiation_info = reneg->renegotiation_info(); - } - else if(Next_Protocol_Notification* npn = dynamic_cast(extn)) - { - m_next_protocols = npn->protocols(); - m_next_protocol = true; - } - else if(Signature_Algorithms* sigs = dynamic_cast(extn)) - { - // save in handshake state - } + // checked by TLS_Client / TLS_Server as they know the handshake state + m_secure_renegotiation = true; + m_renegotiation_info = reneg->renegotiation_info(); + } + + if(Next_Protocol_Notification* npn = extensions.get()) + { + m_next_protocols = npn->protocols(); + m_next_protocol = true; } } @@ -166,13 +158,13 @@ MemoryVector Server_Hello::serialize() const TLS_Extensions extensions; if(m_secure_renegotiation) - extensions.push_back(new Renegotation_Extension(m_renegotiation_info)); + extensions.add(new Renegotation_Extension(m_renegotiation_info)); if(m_fragment_size != 0) - extensions.push_back(new Maximum_Fragment_Length(m_fragment_size)); + extensions.add(new Maximum_Fragment_Length(m_fragment_size)); if(m_next_protocol) - extensions.push_back(new Next_Protocol_Notification(m_next_protocols)); + extensions.add(new Next_Protocol_Notification(m_next_protocols)); buf += extensions.serialize(); diff --git a/src/tls/s_kex.cpp b/src/tls/s_kex.cpp index ac6ee15ee..6b87e6ac6 100644 --- a/src/tls/s_kex.cpp +++ b/src/tls/s_kex.cpp @@ -1,6 +1,6 @@ /* * Server Key Exchange Message -* (C) 2004-2010 Jack Lloyd +* (C) 2004-2010,2012 Jack Lloyd * * Released under the terms of the Botan license */ @@ -35,20 +35,8 @@ Server_Key_Exchange::Server_Key_Exchange(Record_Writer& writer, throw Invalid_Argument("Unknown key type " + state->kex_priv->algo_name() + " for TLS key exchange"); - // FIXME: this should respect client's hash preferences - if(state->version >= TLS_V12) - { - hash_algo = TLS_ALGO_HASH_SHA256; - sig_algo = TLS_ALGO_SIGNER_RSA; - } - else - { - hash_algo = TLS_ALGO_NONE; - sig_algo = TLS_ALGO_NONE; - } - std::pair format = - state->choose_sig_format(private_key, hash_algo, false); + state->choose_sig_format(private_key, hash_algo, sig_algo, false); PK_Signer signer(*private_key, format.first, format.second); @@ -153,10 +141,8 @@ bool Server_Key_Exchange::verify(const X509_Certificate& cert, { std::auto_ptr key(cert.subject_public_key()); - printf("Checking %s vs code %d\n", key->algo_name().c_str(), sig_algo); - std::pair format = - state->choose_sig_format(key.get(), hash_algo, false); + state->choose_sig_format(key.get(), hash_algo, sig_algo, false); PK_Verifier verifier(*key, format.first, format.second); diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp index c8fcd8144..ed7de501f 100644 --- a/src/tls/tls_client.cpp +++ b/src/tls/tls_client.cpp @@ -306,7 +306,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, else if(type == CERTIFICATE_REQUEST) { state->set_expected_next(SERVER_HELLO_DONE); - state->cert_req = new Certificate_Req(contents); + state->cert_req = new Certificate_Req(contents, state->version); } else if(type == SERVER_HELLO_DONE) { @@ -316,8 +316,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, if(state->received_handshake_msg(CERTIFICATE_REQUEST)) { - std::vector types = - state->cert_req->acceptable_types(); + std::vector types = state->cert_req->acceptable_types(); std::vector client_certs = creds.cert_chain("", // use types here diff --git a/src/tls/tls_extensions.cpp b/src/tls/tls_extensions.cpp index 9f80744f9..21c3b67fc 100644 --- a/src/tls/tls_extensions.cpp +++ b/src/tls/tls_extensions.cpp @@ -54,7 +54,7 @@ TLS_Extensions::TLS_Extensions(TLS_Data_Reader& reader) extension_size); if(extn) - extensions.push_back(extn); + this->add(extn); else // unknown/unhandled extension reader.discard_next(extension_size); } @@ -65,14 +65,15 @@ MemoryVector TLS_Extensions::serialize() const { MemoryVector buf(2); // 2 bytes for length field - for(size_t i = 0; i != extensions.size(); ++i) + for(std::map::const_iterator i = extensions.begin(); + i != extensions.end(); ++i) { - if(extensions[i]->empty()) + if(i->second->empty()) continue; - const u16bit extn_code = extensions[i]->type(); + const u16bit extn_code = i->second->type(); - MemoryVector extn_val = extensions[i]->serialize(); + MemoryVector extn_val = i->second->serialize(); buf.push_back(get_byte(0, extn_code)); buf.push_back(get_byte(1, extn_code)); @@ -97,8 +98,12 @@ MemoryVector TLS_Extensions::serialize() const TLS_Extensions::~TLS_Extensions() { - for(size_t i = 0; i != extensions.size(); ++i) - delete extensions[i]; + for(std::map::const_iterator i = extensions.begin(); + i != extensions.end(); ++i) + { + delete i->second; + } + extensions.clear(); } diff --git a/src/tls/tls_extensions.h b/src/tls/tls_extensions.h index 2f4f711c2..a90cb4f2b 100644 --- a/src/tls/tls_extensions.h +++ b/src/tls/tls_extensions.h @@ -12,6 +12,7 @@ #include #include #include +#include namespace Botan { @@ -24,6 +25,7 @@ class TLS_Extension { public: virtual TLS_Handshake_Extension_Type type() const = 0; + virtual MemoryVector serialize() const = 0; virtual bool empty() const = 0; @@ -37,9 +39,11 @@ class TLS_Extension class Server_Name_Indicator : public TLS_Extension { public: - TLS_Handshake_Extension_Type type() const + static TLS_Handshake_Extension_Type static_type() { return TLSEXT_SERVER_NAME_INDICATION; } + TLS_Handshake_Extension_Type type() const { return static_type(); } + Server_Name_Indicator(const std::string& host_name) : sni_host_name(host_name) {} @@ -61,9 +65,11 @@ class Server_Name_Indicator : public TLS_Extension class SRP_Identifier : public TLS_Extension { public: - TLS_Handshake_Extension_Type type() const + static TLS_Handshake_Extension_Type static_type() { return TLSEXT_SRP_IDENTIFIER; } + TLS_Handshake_Extension_Type type() const { return static_type(); } + SRP_Identifier(const std::string& identifier) : srp_identifier(identifier) {} @@ -85,9 +91,11 @@ class SRP_Identifier : public TLS_Extension class Renegotation_Extension : public TLS_Extension { public: - TLS_Handshake_Extension_Type type() const + static TLS_Handshake_Extension_Type static_type() { return TLSEXT_SAFE_RENEGOTIATION; } + TLS_Handshake_Extension_Type type() const { return static_type(); } + Renegotation_Extension() {} Renegotation_Extension(const MemoryRegion& bits) : @@ -112,9 +120,11 @@ class Renegotation_Extension : public TLS_Extension class Maximum_Fragment_Length : public TLS_Extension { public: - TLS_Handshake_Extension_Type type() const + static TLS_Handshake_Extension_Type static_type() { return TLSEXT_MAX_FRAGMENT_LENGTH; } + TLS_Handshake_Extension_Type type() const { return static_type(); } + bool empty() const { return val != 0; } size_t fragment_size() const; @@ -149,9 +159,11 @@ class Maximum_Fragment_Length : public TLS_Extension class Next_Protocol_Notification : public TLS_Extension { public: - TLS_Handshake_Extension_Type type() const + static TLS_Handshake_Extension_Type static_type() { return TLSEXT_NEXT_PROTOCOL; } + TLS_Handshake_Extension_Type type() const { return static_type(); } + const std::vector& protocols() const { return m_protocols; } @@ -182,15 +194,17 @@ class Next_Protocol_Notification : public TLS_Extension class Signature_Algorithms : public TLS_Extension { public: + static TLS_Handshake_Extension_Type static_type() + { return TLSEXT_SIGNATURE_ALGORITHMS; } + + 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 TLS_Ciphersuite_Algos sig_algo_code(byte code); static byte sig_algo_code(TLS_Ciphersuite_Algos code); - TLS_Handshake_Extension_Type type() const - { return TLSEXT_SIGNATURE_ALGORITHMS; } - std::vector > supported_signature_algorthms() const { @@ -215,12 +229,24 @@ class Signature_Algorithms : public TLS_Extension class TLS_Extensions { public: - size_t count() const { return extensions.size(); } + template + T* get() const + { + TLS_Handshake_Extension_Type type = T::static_type(); - TLS_Extension* at(size_t idx) { return extensions.at(idx); } + std::map::const_iterator i = + extensions.find(type); - void push_back(TLS_Extension* extn) - { extensions.push_back(extn); } + if(i != extensions.end()) + return dynamic_cast(i->second); + return 0; + } + + void add(TLS_Extension* extn) + { + delete extensions[extn->type()]; // or hard error if already exists? + extensions[extn->type()] = extn; + } MemoryVector serialize() const; @@ -233,7 +259,7 @@ class TLS_Extensions TLS_Extensions(const TLS_Extensions&) {} TLS_Extensions& operator=(const TLS_Extensions&) { return (*this); } - std::vector extensions; + std::map extensions; }; } diff --git a/src/tls/tls_handshake_state.cpp b/src/tls/tls_handshake_state.cpp index a816e9f6a..48fb70ae1 100644 --- a/src/tls/tls_handshake_state.cpp +++ b/src/tls/tls_handshake_state.cpp @@ -129,15 +129,80 @@ bool TLS_Handshake_State::received_handshake_msg(Handshake_Type handshake_msg) c return (hand_received_mask & mask); } +std::pair +TLS_Handshake_State::choose_sig_format(const Private_Key* key, + TLS_Ciphersuite_Algos& hash_algo, + TLS_Ciphersuite_Algos& sig_algo, + bool for_client_auth) + { + const std::string algo_name = key->algo_name(); + + hash_algo = TLS_ALGO_NONE; + sig_algo = TLS_ALGO_NONE; + + /* + 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. + */ + + if(algo_name == "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)"; + 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 + ")"; + } + + return std::make_pair(padding, IEEE_1363); + } + else if(algo_name == "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)"; + 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 + ")"; + } + + return std::make_pair(padding, DER_SEQUENCE); + } + + throw Invalid_Argument(algo_name + " is invalid/unknown for TLS signatures"); + } + std::pair TLS_Handshake_State::choose_sig_format(const Public_Key* key, TLS_Ciphersuite_Algos hash_algo, + TLS_Ciphersuite_Algos sig_algo, bool for_client_auth) { const std::string algo_name = key->algo_name(); if(algo_name == "RSA") { + 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"); + std::string padding = ""; if(for_client_auth && this->version == SSL_V3) @@ -154,6 +219,10 @@ TLS_Handshake_State::choose_sig_format(const Public_Key* key, } 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) diff --git a/src/tls/tls_handshake_state.h b/src/tls/tls_handshake_state.h index 1beaf74b3..3480ee85f 100644 --- a/src/tls/tls_handshake_state.h +++ b/src/tls/tls_handshake_state.h @@ -49,6 +49,13 @@ class TLS_Handshake_State std::pair choose_sig_format(const Public_Key* key, TLS_Ciphersuite_Algos hash_algo, + TLS_Ciphersuite_Algos sig_algo, + bool for_client_auth); + + std::pair + choose_sig_format(const Private_Key* key, + TLS_Ciphersuite_Algos& hash_algo, + TLS_Ciphersuite_Algos& sig_algo, bool for_client_auth); Version_Code version; diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h index 9ea0b1a2d..95c1ba0a0 100644 --- a/src/tls/tls_messages.h +++ b/src/tls/tls_messages.h @@ -258,21 +258,22 @@ class Certificate_Req : public Handshake_Message public: Handshake_Type type() const { return CERTIFICATE_REQUEST; } - std::vector acceptable_types() const { return types; } + std::vector acceptable_types() const { return cert_types; } std::vector acceptable_CAs() const { return names; } Certificate_Req(Record_Writer& writer, TLS_Handshake_Hash& hash, const std::vector& allowed_cas, - const std::vector& types = - std::vector()); + Version_Code version); - Certificate_Req(const MemoryRegion& buf); + Certificate_Req(const MemoryRegion& buf, + Version_Code version); private: MemoryVector serialize() const; std::vector names; - std::vector types; + std::vector cert_types; + MemoryVector sig_and_hash_algos; // for TLS 1.2 }; /** @@ -296,7 +297,8 @@ class Certificate_Verify : public Handshake_Message RandomNumberGenerator& rng, const Private_Key* key); - Certificate_Verify(const MemoryRegion& buf); + Certificate_Verify(const MemoryRegion& buf, + Version_Code version); private: MemoryVector serialize() const; diff --git a/src/tls/tls_policy.h b/src/tls/tls_policy.h index a0bca4e7f..48ff9185e 100644 --- a/src/tls/tls_policy.h +++ b/src/tls/tls_policy.h @@ -52,7 +52,7 @@ class BOTAN_DLL TLS_Policy /* * @return the version we would prefer to negotiate */ - virtual Version_Code pref_version() const { return TLS_V12; } + virtual Version_Code pref_version() const { return TLS_V11; } virtual bool check_cert(const std::vector& cert_chain) const = 0; diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp index 503d55610..44f8ec2b4 100644 --- a/src/tls/tls_server.cpp +++ b/src/tls/tls_server.cpp @@ -278,8 +278,12 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, { // FIXME: figure out the allowed CAs/cert types - state->cert_req = new Certificate_Req(writer, state->hash, - std::vector()); + std::vector allowed_cas; + + state->cert_req = new Certificate_Req(writer, + state->hash, + allowed_cas, + state->version); state->set_expected_next(CERTIFICATE); } @@ -325,7 +329,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, } else if(type == CERTIFICATE_VERIFY) { - state->client_verify = new Certificate_Verify(contents); + state->client_verify = new Certificate_Verify(contents, state->version); const std::vector& client_certs = state->client_certs->cert_chain(); -- cgit v1.2.3 From b9980348ccd1687f44f53532f81c605aa4a1d752 Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 20 Jan 2012 16:04:08 +0000 Subject: TLS_Ciphersuite_Algos was just a strange level of indirection between the ciphersuite code and a set of strings specifying the underlying suite algorithms. Remove it entirely. Some things are likely broken. One I know about is that we always send the hash/signature type indicator but should only do so for TLS >= 1.2 --- src/libstate/get_enc.cpp | 4 + src/tls/c_hello.cpp | 14 +- src/tls/c_kex.cpp | 4 +- src/tls/cert_ver.cpp | 19 +-- src/tls/rec_read.cpp | 2 +- src/tls/rec_wri.cpp | 2 +- src/tls/s_kex.cpp | 57 ++++---- src/tls/tls_client.cpp | 30 ++--- src/tls/tls_extensions.cpp | 118 ++++++++--------- src/tls/tls_extensions.h | 12 +- src/tls/tls_handshake_state.cpp | 109 ++++++++-------- src/tls/tls_handshake_state.h | 10 +- src/tls/tls_magic.h | 35 ----- src/tls/tls_messages.h | 20 +-- src/tls/tls_record.h | 4 +- src/tls/tls_server.cpp | 10 +- src/tls/tls_suites.cpp | 280 ++++++++-------------------------------- src/tls/tls_suites.h | 30 ++--- 18 files changed, 254 insertions(+), 506 deletions(-) (limited to 'src/tls/tls_extensions.h') 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& 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& 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 #include #include -#include -#include -#include -#include -#include #include namespace Botan { @@ -59,16 +54,10 @@ Certificate_Verify::Certificate_Verify(const MemoryRegion& 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(2, 0, 65535); @@ -81,7 +70,7 @@ MemoryVector Certificate_Verify::serialize() const { MemoryVector 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 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 Server_Key_Exchange::serialize() const { MemoryVector 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 Server_Key_Exchange::serialize_params() const { MemoryVector 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 Server_Key_Exchange::serialize_params() const * Deserialize a Server Key Exchange message */ Server_Key_Exchange::Server_Key_Exchange(const MemoryRegion& 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& 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(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(2, 0, 65535); + m_signature = reader.get_range(2, 0, 65535); } } @@ -127,8 +122,8 @@ Server_Key_Exchange::Server_Key_Exchange(const MemoryRegion& 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 key(cert.subject_public_key()); std::pair 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(state->kex_pub)) - is_dsa = true; - else if(dynamic_cast(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(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 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 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::vector > 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 > m_supported_algos; + std::vector > 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 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 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 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 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 m_renegotiation_info; - std::vector > m_supported_algos; + std::vector > m_supported_algos; }; /** @@ -214,7 +214,7 @@ class Client_Key_Exchange : public Handshake_Message Version_Code pref_version); Client_Key_Exchange(const MemoryRegion& buf, - const TLS_Cipher_Suite& suite, + const TLS_Ciphersuite& suite, Version_Code using_version); private: MemoryVector serialize() const; @@ -298,8 +298,8 @@ class Certificate_Verify : public Handshake_Message private: MemoryVector 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 signature; }; @@ -361,18 +361,18 @@ class Server_Key_Exchange : public Handshake_Message const Private_Key* priv_key); Server_Key_Exchange(const MemoryRegion& 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 serialize() const; MemoryVector serialize_params() const; - std::vector params; + std::vector m_params; - TLS_Ciphersuite_Algos sig_algo; // sig algo used to create signature - TLS_Ciphersuite_Algos hash_algo; // hash used to create signature - MemoryVector signature; + std::string m_sig_algo; // sig algo used to create signature + std::string m_hash_algo; // hash used to create signature + MemoryVector 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& 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 -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 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 - 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; }; } -- cgit v1.2.3 From 415efed94cb5b185ae31140285a6a5e2fef64765 Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 20 Jan 2012 19:05:42 +0000 Subject: Instead of using a hardcoded value for signature_algothms, go with policy. Only functional change here from before is we now send DSA with SHA-2. This is fine, OpenSSL does it as well and while the spec says to wait until NIST comes up with a way to prevent hash impersonation, it doesn't really make sense to avoid possible hash substitution attacks by using the weakest available hash... --- src/tls/c_hello.cpp | 11 ++++++++++- src/tls/cert_req.cpp | 15 +++++++++++++-- src/tls/tls_extensions.cpp | 15 --------------- src/tls/tls_extensions.h | 3 ++- src/tls/tls_messages.h | 4 +++- src/tls/tls_policy.cpp | 3 +++ src/tls/tls_server.cpp | 1 + 7 files changed, 32 insertions(+), 20 deletions(-) (limited to 'src/tls/tls_extensions.h') diff --git a/src/tls/c_hello.cpp b/src/tls/c_hello.cpp index e56996ee5..d821482fd 100644 --- a/src/tls/c_hello.cpp +++ b/src/tls/c_hello.cpp @@ -94,6 +94,13 @@ Client_Hello::Client_Hello(Record_Writer& writer, m_secure_renegotiation(true), m_renegotiation_info(reneg_info) { + std::vector hashes = policy.allowed_hashes(); + std::vector sigs = policy.allowed_signature_methods(); + + for(size_t i = 0; i != hashes.size(); ++i) + for(size_t j = 0; j != sigs.size(); ++j) + m_supported_algos.push_back(std::make_pair(hashes[i], sigs[j])); + send(writer, hash); } @@ -117,6 +124,8 @@ Client_Hello::Client_Hello(Record_Writer& writer, m_suites.push_back(session.ciphersuite()); m_comp_methods.push_back(session.compression_method()); + // set m_supported_algos here? + send(writer, hash); } @@ -164,7 +173,7 @@ MemoryVector Client_Hello::serialize() const extensions.add(new SRP_Identifier(m_srp_identifier)); if(m_version >= TLS_V12) - extensions.add(new Signature_Algorithms()); + extensions.add(new Signature_Algorithms(m_supported_algos)); if(m_next_protocol) extensions.add(new Next_Protocol_Notification()); diff --git a/src/tls/cert_req.cpp b/src/tls/cert_req.cpp index c3e46a5ae..4e86a3270 100644 --- a/src/tls/cert_req.cpp +++ b/src/tls/cert_req.cpp @@ -22,6 +22,7 @@ namespace Botan { */ Certificate_Req::Certificate_Req(Record_Writer& writer, TLS_Handshake_Hash& hash, + const TLS_Policy& policy, const std::vector& ca_certs, Version_Code version) { @@ -32,7 +33,14 @@ Certificate_Req::Certificate_Req(Record_Writer& writer, cert_types.push_back(DSS_CERT); if(version >= TLS_V12) - sig_and_hash_algos = Signature_Algorithms().serialize(); + { + std::vector hashes = policy.allowed_hashes(); + std::vector sigs = policy.allowed_signature_methods(); + + for(size_t i = 0; i != hashes.size(); ++i) + for(size_t j = 0; j != sigs.size(); ++j) + m_supported_algos.push_back(std::make_pair(hashes[i], sigs[j])); + } send(writer, hash); } @@ -82,7 +90,10 @@ MemoryVector Certificate_Req::serialize() const append_tls_length_value(buf, cert_types, 1); - buf += sig_and_hash_algos; + if(!m_supported_algos.empty()) + { + buf += Signature_Algorithms(m_supported_algos).serialize(); + } for(size_t i = 0; i != names.size(); ++i) { diff --git a/src/tls/tls_extensions.cpp b/src/tls/tls_extensions.cpp index 41977f975..4fbcdbad1 100644 --- a/src/tls/tls_extensions.cpp +++ b/src/tls/tls_extensions.cpp @@ -365,21 +365,6 @@ MemoryVector Signature_Algorithms::serialize() const return buf; } -Signature_Algorithms::Signature_Algorithms() - { - /* - Declare we support everything except MD5 for RSA, and SHA-1 with DSA. - We prefer hashes strongest (SHA-512) to weakest (SHA-1). - */ - - 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, u16bit extension_size) { diff --git a/src/tls/tls_extensions.h b/src/tls/tls_extensions.h index fea700756..2b386d9f5 100644 --- a/src/tls/tls_extensions.h +++ b/src/tls/tls_extensions.h @@ -215,7 +215,8 @@ class Signature_Algorithms : public TLS_Extension bool empty() const { return false; } - Signature_Algorithms(); + Signature_Algorithms(const std::vector >& algos) : + m_supported_algos(algos) {} Signature_Algorithms(TLS_Data_Reader& reader, u16bit extension_size); diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h index b0f6b503f..c86d71045 100644 --- a/src/tls/tls_messages.h +++ b/src/tls/tls_messages.h @@ -259,6 +259,7 @@ class Certificate_Req : public Handshake_Message Certificate_Req(Record_Writer& writer, TLS_Handshake_Hash& hash, + const TLS_Policy& policy, const std::vector& allowed_cas, Version_Code version); @@ -269,7 +270,8 @@ class Certificate_Req : public Handshake_Message std::vector names; std::vector cert_types; - MemoryVector sig_and_hash_algos; // for TLS 1.2 + + std::vector > m_supported_algos; }; /** diff --git a/src/tls/tls_policy.cpp b/src/tls/tls_policy.cpp index bc0cd53f5..b041d84b0 100644 --- a/src/tls/tls_policy.cpp +++ b/src/tls/tls_policy.cpp @@ -26,7 +26,10 @@ std::vector TLS_Policy::allowed_ciphers() const std::vector TLS_Policy::allowed_hashes() const { std::vector allowed; + allowed.push_back("SHA-512"); + allowed.push_back("SHA-384"); allowed.push_back("SHA-256"); + allowed.push_back("SHA-224"); allowed.push_back("SHA-1"); // Note that MD5 is not included by default return allowed; diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp index 90ce3bf88..5d07d22ba 100644 --- a/src/tls/tls_server.cpp +++ b/src/tls/tls_server.cpp @@ -274,6 +274,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, { state->cert_req = new Certificate_Req(writer, state->hash, + policy, client_auth_CAs, state->version); -- cgit v1.2.3 From e0065f2af522b9573aaf364391139ac12e77eecb Mon Sep 17 00:00:00 2001 From: lloyd Date: Sun, 22 Jan 2012 01:50:19 +0000 Subject: Basic outline of the supported curves extension from RFC 4492 --- src/tls/tls_extensions.cpp | 156 +++++++++++++++++++++++++++++++++++++++++---- src/tls/tls_extensions.h | 25 ++++++++ 2 files changed, 167 insertions(+), 14 deletions(-) (limited to 'src/tls/tls_extensions.h') diff --git a/src/tls/tls_extensions.cpp b/src/tls/tls_extensions.cpp index 099bdfde6..d9351fdb1 100644 --- a/src/tls/tls_extensions.cpp +++ b/src/tls/tls_extensions.cpp @@ -17,20 +17,32 @@ TLS_Extension* make_extension(TLS_Data_Reader& reader, u16bit code, u16bit size) { - if(code == TLSEXT_SERVER_NAME_INDICATION) - return new Server_Name_Indicator(reader, size); - else if(code == TLSEXT_MAX_FRAGMENT_LENGTH) - return new Maximum_Fragment_Length(reader, size); - else if(code == TLSEXT_SRP_IDENTIFIER) - return new SRP_Identifier(reader, size); - else if(code == TLSEXT_SAFE_RENEGOTIATION) - return new Renegotation_Extension(reader, size); - else if(code == TLSEXT_SIGNATURE_ALGORITHMS) - return new Signature_Algorithms(reader, size); - else if(code == TLSEXT_NEXT_PROTOCOL) - return new Next_Protocol_Notification(reader, size); - else - return 0; // not known + switch(code) + { + case TLSEXT_SERVER_NAME_INDICATION: + return new Server_Name_Indicator(reader, size); + + case TLSEXT_MAX_FRAGMENT_LENGTH: + return new Maximum_Fragment_Length(reader, size); + + case TLSEXT_SRP_IDENTIFIER: + return new SRP_Identifier(reader, size); + + case TLSEXT_USABLE_ELLIPTIC_CURVES: + return new Supported_Elliptic_Curves(reader, size); + + case TLSEXT_SAFE_RENEGOTIATION: + return new Renegotation_Extension(reader, size); + + case TLSEXT_SIGNATURE_ALGORITHMS: + return new Signature_Algorithms(reader, size); + + case TLSEXT_NEXT_PROTOCOL: + return new Next_Protocol_Notification(reader, size); + + default: + return 0; // not known + } } } @@ -276,6 +288,122 @@ MemoryVector Next_Protocol_Notification::serialize() const return buf; } +namespace { + +std::string tls_curve_id_to_name(u16bit id) + { + switch(id) + { + case 15: + return "secp160k1"; + case 16: + return "secp160r1"; + case 17: + return "secp160r2"; + case 18: + return "secp192k1"; + case 19: + return "secp192r1"; + case 20: + return "secp224k1"; + case 21: + return "secp224r1"; + case 22: + return "secp256k1"; + case 23: + return "secp256r1"; + case 24: + return "secp384r1"; + case 25: + return "secp521r1"; + default: + return ""; // something we don't know or support + } + } + +u16bit tls_name_to_curve_id(const std::string& name) + { + if(name == "secp160k1") + return 15; + if(name == "secp160r1") + return 16; + if(name == "secp160r2") + return 17; + if(name == "secp192k1") + return 18; + if(name == "secp192r1") + return 19; + if(name == "secp224k1") + return 20; + if(name == "secp224r1") + return 21; + if(name == "secp256k1") + return 22; + if(name == "secp256r1") + return 23; + if(name == "secp384r1") + return 24; + if(name == "secp521r1") + return 25; + + throw Invalid_Argument("tls_name_to_curve_id unknown name " + name); + } + +} + +MemoryVector Supported_Elliptic_Curves::serialize() const + { + MemoryVector buf(2); + + for(size_t i = 0; i != m_curves.size(); ++i) + { + const u16bit id = tls_name_to_curve_id(m_curves[i]); + buf.push_back(get_byte(0, id)); + buf.push_back(get_byte(1, id)); + } + + buf[0] = get_byte(0, buf.size()-2); + buf[1] = get_byte(1, buf.size()-2); + } + +Supported_Elliptic_Curves::Supported_Elliptic_Curves() + { + m_curves.push_back("secp521r1"); + m_curves.push_back("secp384r1"); + m_curves.push_back("secp256r1"); + m_curves.push_back("secp256k1"); + m_curves.push_back("secp224r1"); + m_curves.push_back("secp224k1"); + m_curves.push_back("secp192r1"); + m_curves.push_back("secp192k1"); + m_curves.push_back("secp160r2"); + m_curves.push_back("secp160r1"); + m_curves.push_back("secp160k1"); + } + +Supported_Elliptic_Curves::Supported_Elliptic_Curves(TLS_Data_Reader& reader, + u16bit extension_size) + { + u16bit len = reader.get_u16bit(); + + if(len + 2 != extension_size) + throw Decoding_Error("Inconsistent length field in elliptic curve list"); + + if(len % 2 == 1) + throw Decoding_Error("Elliptic curve list of strange size"); + + len /= 2; + + for(size_t i = 0; i != len; ++i) + { + const u16bit id = reader.get_u16bit(); + const std::string name = tls_curve_id_to_name(id); + + if(name != "") + m_curves.push_back(name); + } + } + std::string Signature_Algorithms::hash_algo_name(byte code) { switch(code) diff --git a/src/tls/tls_extensions.h b/src/tls/tls_extensions.h index 2b386d9f5..d0aee6d04 100644 --- a/src/tls/tls_extensions.h +++ b/src/tls/tls_extensions.h @@ -188,6 +188,31 @@ class Next_Protocol_Notification : public TLS_Extension std::vector m_protocols; }; +/** +* Supported Elliptic Curves Extension (RFC 4492) +*/ +class Supported_Elliptic_Curves : public TLS_Extension + { + public: + static TLS_Handshake_Extension_Type static_type() + { return TLSEXT_USABLE_ELLIPTIC_CURVES; } + + TLS_Handshake_Extension_Type type() const { return static_type(); } + + const std::vector& curves() const { return m_curves; } + + MemoryVector serialize() const; + + Supported_Elliptic_Curves(); // default values, for client + + Supported_Elliptic_Curves(TLS_Data_Reader& reader, + u16bit extension_size); + + bool empty() const { return m_curves.empty(); } + private: + std::vector m_curves; + }; + /** * Signature Algorithms Extension for TLS 1.2 (RFC 5246) */ -- cgit v1.2.3 From a445f7f4a1089fc034c35c500e1572eb9518f44f Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 23 Jan 2012 15:30:29 +0000 Subject: Since this branch is hugely API breaking already, go ahead and put everything into a new namespace (Botan::TLS), removing the TLS_ prefixes on everything. --- doc/examples/asio_tls_server.cpp | 20 ++++----- doc/examples/tls_client.cpp | 17 ++++---- doc/examples/tls_server.cpp | 16 ++++---- src/tls/c_hello.cpp | 22 ++++++---- src/tls/c_kex.cpp | 8 +++- src/tls/cert_req.cpp | 10 +++-- src/tls/cert_ver.cpp | 8 +++- src/tls/finished.cpp | 12 ++++-- src/tls/next_protocol.cpp | 6 ++- src/tls/rec_read.cpp | 6 ++- src/tls/rec_wri.cpp | 6 ++- src/tls/s_hello.cpp | 18 ++++---- src/tls/s_kex.cpp | 8 +++- src/tls/tls_alerts.h | 4 ++ src/tls/tls_channel.cpp | 26 +++++++----- src/tls/tls_channel.h | 16 +++++--- src/tls/tls_client.cpp | 38 +++++++++-------- src/tls/tls_client.h | 18 ++++---- src/tls/tls_exceptn.h | 4 ++ src/tls/tls_extensions.cpp | 22 ++++++---- src/tls/tls_extensions.h | 72 ++++++++++++++++---------------- src/tls/tls_handshake_hash.cpp | 10 +++-- src/tls/tls_handshake_hash.h | 6 ++- src/tls/tls_handshake_state.cpp | 18 ++++---- src/tls/tls_handshake_state.h | 14 ++++--- src/tls/tls_magic.h | 6 ++- src/tls/tls_messages.h | 46 +++++++++++---------- src/tls/tls_policy.cpp | 30 ++++++++------ src/tls/tls_policy.h | 8 +++- src/tls/tls_reader.h | 4 ++ src/tls/tls_record.h | 8 +++- src/tls/tls_server.cpp | 42 ++++++++++--------- src/tls/tls_server.h | 20 +++++---- src/tls/tls_session.cpp | 10 +++-- src/tls/tls_session.h | 12 ++++-- src/tls/tls_session_key.cpp | 6 ++- src/tls/tls_session_key.h | 6 ++- src/tls/tls_session_manager.cpp | 24 ++++++----- src/tls/tls_session_manager.h | 32 ++++++++------- src/tls/tls_suites.cpp | 88 +++++++++++++++++++++------------------- src/tls/tls_suites.h | 12 ++++-- 41 files changed, 456 insertions(+), 303 deletions(-) (limited to 'src/tls/tls_extensions.h') diff --git a/doc/examples/asio_tls_server.cpp b/doc/examples/asio_tls_server.cpp index 2ff640983..90f4fc20a 100644 --- a/doc/examples/asio_tls_server.cpp +++ b/doc/examples/asio_tls_server.cpp @@ -23,9 +23,9 @@ class tls_server_session : public boost::enable_shared_from_this pointer; static pointer create(asio::io_service& io_service, - Botan::TLS_Session_Manager& session_manager, + Botan::TLS::Session_Manager& session_manager, Botan::Credentials_Manager& credentials, - Botan::TLS_Policy& policy, + Botan::TLS::Policy& policy, Botan::RandomNumberGenerator& rng) { return pointer( @@ -53,9 +53,9 @@ class tls_server_session : public boost::enable_shared_from_this m_write_buf; @@ -215,7 +215,7 @@ class Credentials_Manager_Simple : public Botan::Credentials_Manager std::map certs_and_keys; }; -class Server_TLS_Policy : public Botan::TLS_Policy +class Server_TLS_Policy : public Botan::TLS::Policy { public: //bool require_client_auth() const { return true; } @@ -289,7 +289,7 @@ class tls_server tcp::acceptor m_acceptor; Botan::AutoSeeded_RNG m_rng; - Botan::TLS_Session_Manager_In_Memory m_session_manager; + Botan::TLS::Session_Manager_In_Memory m_session_manager; Server_TLS_Policy m_policy; Credentials_Manager_Simple m_creds; }; diff --git a/doc/examples/tls_client.cpp b/doc/examples/tls_client.cpp index 42fecaf37..3d4dd38b7 100644 --- a/doc/examples/tls_client.cpp +++ b/doc/examples/tls_client.cpp @@ -20,7 +20,7 @@ using namespace Botan; using namespace std::tr1::placeholders; -class Client_TLS_Policy : public TLS_Policy +class Client_TLS_Policy : public TLS::Policy { public: //Version_Code pref_version() const { return TLS_V12; } @@ -72,11 +72,12 @@ int connect_to_host(const std::string& host, u16bit port) return fd; } -bool handshake_complete(const TLS_Session& session) +bool handshake_complete(const TLS::Session& session) { std::cout << "Handshake complete!\n"; std::cout << "Protocol version " << (int)session.major_version() << "." << (int)session.minor_version() << "\n"; + std::cout << "Ciphersuite " << std::hex << session.ciphersuite() << "\n"; std::cout << "Session ID " << hex_encode(session.session_id()) << "\n"; return true; @@ -108,7 +109,7 @@ bool got_alert = false; void process_data(const byte buf[], size_t buf_size, u16bit alert_info) { - if(alert_info != NULL_ALERT) + if(alert_info != TLS::NULL_ALERT) { std::cout << "Alert: " << alert_info << "\n"; got_alert = true; @@ -128,15 +129,15 @@ std::string protocol_chooser(const std::vector& protocols) } void doit(RandomNumberGenerator& rng, - TLS_Policy& policy, - TLS_Session_Manager& session_manager, + TLS::Policy& policy, + TLS::Session_Manager& session_manager, Credentials_Manager& creds, const std::string& host, u16bit port) { int sockfd = connect_to_host(host, port); - TLS_Client client(std::tr1::bind(socket_write, sockfd, _1, _2), + TLS::Client client(std::tr1::bind(socket_write, sockfd, _1, _2), process_data, handshake_complete, session_manager, @@ -180,7 +181,7 @@ void doit(RandomNumberGenerator& rng, } const size_t needed = client.received_data(buf, got); - std::cout << "Socket - got " << got << " bytes, need " << needed << "\n"; + //std::cout << "Socket - got " << got << " bytes, need " << needed << "\n"; } else if(FD_ISSET(STDIN_FILENO, &readfds)) { @@ -251,7 +252,7 @@ int main(int argc, char* argv[]) LibraryInitializer botan_init; AutoSeeded_RNG rng; Client_TLS_Policy policy; - TLS_Session_Manager_In_Memory session_manager; + TLS::Session_Manager_In_Memory session_manager; Credentials_Manager_Simple creds(rng); diff --git a/doc/examples/tls_server.cpp b/doc/examples/tls_server.cpp index 2dbfb4aeb..6f986c7a1 100644 --- a/doc/examples/tls_server.cpp +++ b/doc/examples/tls_server.cpp @@ -52,7 +52,7 @@ class Credentials_Manager_Simple : public Credentials_Manager std::map certs_and_keys; }; -bool handshake_complete(const TLS_Session& session) +bool handshake_complete(const TLS::Session& session) { printf("Handshake complete, protocol=%04X ciphersuite=%04X compression=%d\n", session.version(), session.ciphersuite(), @@ -69,9 +69,9 @@ class Blocking_TLS_Server Blocking_TLS_Server(std::tr1::function output_fn, std::tr1::function input_fn, std::vector& protocols, - TLS_Session_Manager& sessions, + TLS::Session_Manager& sessions, Credentials_Manager& creds, - TLS_Policy& policy, + TLS::Policy& policy, RandomNumberGenerator& rng) : input_fn(input_fn), server( @@ -109,7 +109,7 @@ class Blocking_TLS_Server bool is_active() const { return server.is_active(); } - TLS_Server& underlying() { return server; } + TLS::Server& underlying() { return server; } private: void read_loop(size_t init_desired = 0) { @@ -135,7 +135,7 @@ class Blocking_TLS_Server void reader_fn(const byte buf[], size_t buf_len, u16bit alert_code) { - if(buf_len == 0 && alert_code != NULL_ALERT) + if(buf_len == 0 && alert_code != TLS::NULL_ALERT) { printf("Alert: %d\n", alert_code); //exit = true; @@ -153,12 +153,12 @@ class Blocking_TLS_Server } std::tr1::function input_fn; - TLS_Server server; + TLS::Server server; SecureQueue read_queue; bool exit; }; -class Server_TLS_Policy : public TLS_Policy +class Server_TLS_Policy : public TLS::Policy { public: //bool require_client_auth() const { return true; } @@ -194,7 +194,7 @@ int main(int argc, char* argv[]) Server_TLS_Policy policy; - TLS_Session_Manager_In_Memory sessions; + TLS::Session_Manager_In_Memory sessions; Credentials_Manager_Simple creds(rng); diff --git a/src/tls/c_hello.cpp b/src/tls/c_hello.cpp index 2d94de462..4fdadd455 100644 --- a/src/tls/c_hello.cpp +++ b/src/tls/c_hello.cpp @@ -15,6 +15,8 @@ namespace Botan { +namespace TLS { + MemoryVector make_hello_random(RandomNumberGenerator& rng) { MemoryVector buf(32); @@ -27,7 +29,7 @@ MemoryVector make_hello_random(RandomNumberGenerator& rng) /* * Encode and send a Handshake message */ -void Handshake_Message::send(Record_Writer& writer, TLS_Handshake_Hash& hash) const +void Handshake_Message::send(Record_Writer& writer, Handshake_Hash& hash) const { MemoryVector buf = serialize(); MemoryVector send_buf(4); @@ -51,7 +53,7 @@ void Handshake_Message::send(Record_Writer& writer, TLS_Handshake_Hash& hash) co */ Hello_Request::Hello_Request(Record_Writer& writer) { - TLS_Handshake_Hash dummy; // FIXME: *UGLY* + Handshake_Hash dummy; // FIXME: *UGLY* send(writer, dummy); } @@ -76,8 +78,8 @@ MemoryVector Hello_Request::serialize() const * Create a new Client Hello message */ Client_Hello::Client_Hello(Record_Writer& writer, - TLS_Handshake_Hash& hash, - const TLS_Policy& policy, + Handshake_Hash& hash, + const Policy& policy, RandomNumberGenerator& rng, const MemoryRegion& reneg_info, bool next_protocol, @@ -108,9 +110,9 @@ Client_Hello::Client_Hello(Record_Writer& writer, * Create a new Client Hello message */ Client_Hello::Client_Hello(Record_Writer& writer, - TLS_Handshake_Hash& hash, + Handshake_Hash& hash, RandomNumberGenerator& rng, - const TLS_Session& session, + const Session& session, bool next_protocol) : m_version(session.version()), m_session_id(session.session_id()), @@ -163,7 +165,7 @@ MemoryVector Client_Hello::serialize() const * send that extension. */ - TLS_Extensions extensions; + Extensions extensions; // Initial handshake if(m_renegotiation_info.empty()) @@ -249,7 +251,7 @@ void Client_Hello::deserialize(const MemoryRegion& buf) m_comp_methods = reader.get_range_vector(1, 1, 255); - TLS_Extensions extensions(reader); + Extensions extensions(reader); if(Server_Name_Indicator* sni = extensions.get()) { @@ -276,7 +278,7 @@ void Client_Hello::deserialize(const MemoryRegion& buf) if(Renegotation_Extension* reneg = extensions.get()) { - // checked by TLS_Client / TLS_Server as they know the handshake state + // checked by Client / Server as they know the handshake state m_secure_renegotiation = true; m_renegotiation_info = reneg->renegotiation_info(); } @@ -346,3 +348,5 @@ bool Client_Hello::offered_suite(u16bit ciphersuite) const } } + +} diff --git a/src/tls/c_kex.cpp b/src/tls/c_kex.cpp index 63ba6fcb7..de8f54fbe 100644 --- a/src/tls/c_kex.cpp +++ b/src/tls/c_kex.cpp @@ -16,6 +16,8 @@ namespace Botan { +namespace TLS { + namespace { SecureVector strip_leading_zeros(const MemoryRegion& input) @@ -40,7 +42,7 @@ SecureVector strip_leading_zeros(const MemoryRegion& input) * Create a new Client Key Exchange message */ Client_Key_Exchange::Client_Key_Exchange(Record_Writer& writer, - TLS_Handshake_State* state, + Handshake_State* state, const std::vector& peer_certs, RandomNumberGenerator& rng) { @@ -113,7 +115,7 @@ Client_Key_Exchange::Client_Key_Exchange(Record_Writer& writer, * Read a Client Key Exchange message */ Client_Key_Exchange::Client_Key_Exchange(const MemoryRegion& contents, - const TLS_Ciphersuite& suite, + const Ciphersuite& suite, Version_Code using_version) { include_length = true; @@ -199,3 +201,5 @@ Client_Key_Exchange::pre_master_secret(RandomNumberGenerator& rng, } } + +} diff --git a/src/tls/cert_req.cpp b/src/tls/cert_req.cpp index 7fbe2a809..d5a73f64e 100644 --- a/src/tls/cert_req.cpp +++ b/src/tls/cert_req.cpp @@ -17,12 +17,14 @@ namespace Botan { +namespace TLS { + /** * Create a new Certificate Request message */ Certificate_Req::Certificate_Req(Record_Writer& writer, - TLS_Handshake_Hash& hash, - const TLS_Policy& policy, + Handshake_Hash& hash, + const Policy& policy, const std::vector& ca_certs, Version_Code version) { @@ -125,7 +127,7 @@ MemoryVector Certificate_Req::serialize() const * Create a new Certificate message */ Certificate::Certificate(Record_Writer& writer, - TLS_Handshake_Hash& hash, + Handshake_Hash& hash, const std::vector& cert_list) { certs = cert_list; @@ -190,3 +192,5 @@ MemoryVector Certificate::serialize() const } } + +} diff --git a/src/tls/cert_ver.cpp b/src/tls/cert_ver.cpp index f11ae4dcc..923cdbb42 100644 --- a/src/tls/cert_ver.cpp +++ b/src/tls/cert_ver.cpp @@ -13,11 +13,13 @@ namespace Botan { +namespace TLS { + /* * Create a new Certificate Verify message */ Certificate_Verify::Certificate_Verify(Record_Writer& writer, - TLS_Handshake_State* state, + Handshake_State* state, RandomNumberGenerator& rng, const Private_Key* priv_key) { @@ -88,7 +90,7 @@ MemoryVector Certificate_Verify::serialize() const * Verify a Certificate Verify message */ bool Certificate_Verify::verify(const X509_Certificate& cert, - TLS_Handshake_State* state) + Handshake_State* state) { std::auto_ptr key(cert.subject_public_key()); @@ -110,3 +112,5 @@ bool Certificate_Verify::verify(const X509_Certificate& cert, } } + +} diff --git a/src/tls/finished.cpp b/src/tls/finished.cpp index ecb7c315a..f7f8a7eb8 100644 --- a/src/tls/finished.cpp +++ b/src/tls/finished.cpp @@ -15,6 +15,8 @@ namespace Botan { +namespace TLS { + namespace { KDF* choose_tls_prf(Version_Code version) @@ -31,7 +33,7 @@ KDF* choose_tls_prf(Version_Code version) /* * Compute the verify_data */ -MemoryVector finished_compute_verify(TLS_Handshake_State* state, +MemoryVector finished_compute_verify(Handshake_State* state, Connection_Side side) { if(state->version == SSL_V3) @@ -39,7 +41,7 @@ MemoryVector finished_compute_verify(TLS_Handshake_State* state, const byte SSL_CLIENT_LABEL[] = { 0x43, 0x4C, 0x4E, 0x54 }; const byte SSL_SERVER_LABEL[] = { 0x53, 0x52, 0x56, 0x52 }; - TLS_Handshake_Hash hash = state->hash; // don't modify state + Handshake_Hash hash = state->hash; // don't modify state MemoryVector ssl3_finished; @@ -80,7 +82,7 @@ MemoryVector finished_compute_verify(TLS_Handshake_State* state, * Create a new Finished message */ Finished::Finished(Record_Writer& writer, - TLS_Handshake_State* state, + Handshake_State* state, Connection_Side side) { verification_data = finished_compute_verify(state, side); @@ -106,10 +108,12 @@ Finished::Finished(const MemoryRegion& buf) /* * Verify a Finished message */ -bool Finished::verify(TLS_Handshake_State* state, +bool Finished::verify(Handshake_State* state, Connection_Side side) { return (verification_data == finished_compute_verify(state, side)); } } + +} diff --git a/src/tls/next_protocol.cpp b/src/tls/next_protocol.cpp index a0d4278f1..97b072440 100644 --- a/src/tls/next_protocol.cpp +++ b/src/tls/next_protocol.cpp @@ -11,8 +11,10 @@ namespace Botan { +namespace TLS { + Next_Protocol::Next_Protocol(Record_Writer& writer, - TLS_Handshake_Hash& hash, + Handshake_Hash& hash, const std::string& protocol) : m_protocol(protocol) { @@ -48,3 +50,5 @@ MemoryVector Next_Protocol::serialize() const } } + +} diff --git a/src/tls/rec_read.cpp b/src/tls/rec_read.cpp index d3666abf6..4db50262d 100644 --- a/src/tls/rec_read.cpp +++ b/src/tls/rec_read.cpp @@ -14,6 +14,8 @@ namespace Botan { +namespace TLS { + Record_Reader::Record_Reader() : m_readbuf(TLS_HEADER_SIZE + MAX_CIPHERTEXT_SIZE), m_mac(0) @@ -64,7 +66,7 @@ void Record_Reader::set_version(Version_Code version) /* * Set the keys for reading */ -void Record_Reader::activate(const TLS_Ciphersuite& suite, +void Record_Reader::activate(const Ciphersuite& suite, const Session_Keys& keys, Connection_Side side) { @@ -336,3 +338,5 @@ size_t Record_Reader::add_input(const byte input_array[], size_t input_sz, } } + +} diff --git a/src/tls/rec_wri.cpp b/src/tls/rec_wri.cpp index 7f8b4445b..139d84c50 100644 --- a/src/tls/rec_wri.cpp +++ b/src/tls/rec_wri.cpp @@ -16,6 +16,8 @@ namespace Botan { +namespace TLS { + /* * Record_Writer Constructor */ @@ -67,7 +69,7 @@ void Record_Writer::set_version(Version_Code version) /* * Set the keys for writing */ -void Record_Writer::activate(const TLS_Ciphersuite& suite, +void Record_Writer::activate(const Ciphersuite& suite, const Session_Keys& keys, Connection_Side side) { @@ -284,3 +286,5 @@ void Record_Writer::alert(Alert_Level level, Alert_Type type) } } + +} diff --git a/src/tls/s_hello.cpp b/src/tls/s_hello.cpp index e6aff94e3..9e61f62af 100644 --- a/src/tls/s_hello.cpp +++ b/src/tls/s_hello.cpp @@ -14,15 +14,17 @@ namespace Botan { +namespace TLS { + /* * Create a new Server Hello message */ Server_Hello::Server_Hello(Record_Writer& writer, - TLS_Handshake_Hash& hash, + Handshake_Hash& hash, Version_Code version, const Client_Hello& c_hello, const std::vector& certs, - const TLS_Policy& policy, + const Policy& policy, bool client_has_secure_renegotiation, const MemoryRegion& reneg_info, bool client_has_npn, @@ -64,7 +66,7 @@ Server_Hello::Server_Hello(Record_Writer& writer, * Create a new Server Hello message */ Server_Hello::Server_Hello(Record_Writer& writer, - TLS_Handshake_Hash& hash, + Handshake_Hash& hash, const MemoryRegion& session_id, Version_Code ver, u16bit ciphersuite, @@ -121,11 +123,11 @@ Server_Hello::Server_Hello(const MemoryRegion& buf) comp_method = reader.get_byte(); - TLS_Extensions extensions(reader); + Extensions extensions(reader); if(Renegotation_Extension* reneg = extensions.get()) { - // checked by TLS_Client / TLS_Server as they know the handshake state + // checked by Client / Server as they know the handshake state m_secure_renegotiation = true; m_renegotiation_info = reneg->renegotiation_info(); } @@ -155,7 +157,7 @@ MemoryVector Server_Hello::serialize() const buf.push_back(comp_method); - TLS_Extensions extensions; + Extensions extensions; if(m_secure_renegotiation) extensions.add(new Renegotation_Extension(m_renegotiation_info)); @@ -175,7 +177,7 @@ MemoryVector Server_Hello::serialize() const * Create a new Server Hello Done message */ Server_Hello_Done::Server_Hello_Done(Record_Writer& writer, - TLS_Handshake_Hash& hash) + Handshake_Hash& hash) { send(writer, hash); } @@ -198,3 +200,5 @@ MemoryVector Server_Hello_Done::serialize() const } } + +} diff --git a/src/tls/s_kex.cpp b/src/tls/s_kex.cpp index bbad6fd83..359ef6f4a 100644 --- a/src/tls/s_kex.cpp +++ b/src/tls/s_kex.cpp @@ -15,11 +15,13 @@ namespace Botan { +namespace TLS { + /** * Create a new Server Key Exchange message */ Server_Key_Exchange::Server_Key_Exchange(Record_Writer& writer, - TLS_Handshake_State* state, + Handshake_State* state, RandomNumberGenerator& rng, const Private_Key* private_key) { @@ -121,7 +123,7 @@ Server_Key_Exchange::Server_Key_Exchange(const MemoryRegion& buf, * Verify a Server Key Exchange message */ bool Server_Key_Exchange::verify(const X509_Certificate& cert, - TLS_Handshake_State* state) const + Handshake_State* state) const { std::auto_ptr key(cert.subject_public_key()); @@ -138,3 +140,5 @@ bool Server_Key_Exchange::verify(const X509_Certificate& cert, } } + +} diff --git a/src/tls/tls_alerts.h b/src/tls/tls_alerts.h index 0634d6763..2ccb1ad79 100644 --- a/src/tls/tls_alerts.h +++ b/src/tls/tls_alerts.h @@ -12,6 +12,8 @@ namespace Botan { +namespace TLS { + /** * SSL/TLS Alert Message */ @@ -57,4 +59,6 @@ class Alert } +} + #endif diff --git a/src/tls/tls_channel.cpp b/src/tls/tls_channel.cpp index a1e9fd8cd..a3ff69d87 100644 --- a/src/tls/tls_channel.cpp +++ b/src/tls/tls_channel.cpp @@ -14,9 +14,11 @@ namespace Botan { -TLS_Channel::TLS_Channel(std::tr1::function socket_output_fn, +namespace TLS { + +Channel::Channel(std::tr1::function socket_output_fn, std::tr1::function proc_fn, - std::tr1::function handshake_complete) : + std::tr1::function handshake_complete) : proc_fn(proc_fn), handshake_fn(handshake_complete), writer(socket_output_fn), @@ -26,13 +28,13 @@ TLS_Channel::TLS_Channel(std::tr1::function socket_ { } -TLS_Channel::~TLS_Channel() +Channel::~Channel() { delete state; state = 0; } -size_t TLS_Channel::received_data(const byte buf[], size_t buf_size) +size_t Channel::received_data(const byte buf[], size_t buf_size) { try { @@ -130,13 +132,13 @@ size_t TLS_Channel::received_data(const byte buf[], size_t buf_size) /* * Split up and process handshake messages */ -void TLS_Channel::read_handshake(byte rec_type, +void Channel::read_handshake(byte rec_type, const MemoryRegion& rec_buf) { if(rec_type == HANDSHAKE) { if(!state) - state = new TLS_Handshake_State; + state = new Handshake_State; state->queue.write(&rec_buf[0], rec_buf.size()); } @@ -183,7 +185,7 @@ void TLS_Channel::read_handshake(byte rec_type, } } -void TLS_Channel::send(const byte buf[], size_t buf_size) +void Channel::send(const byte buf[], size_t buf_size) { if(!is_active()) throw std::runtime_error("Data cannot be sent on inactive TLS connection"); @@ -191,7 +193,7 @@ void TLS_Channel::send(const byte buf[], size_t buf_size) writer.send(APPLICATION_DATA, buf, buf_size); } -void TLS_Channel::alert(Alert_Level alert_level, Alert_Type alert_code) +void Channel::alert(Alert_Level alert_level, Alert_Type alert_code) { if(alert_code != NULL_ALERT && !connection_closed) { @@ -214,7 +216,7 @@ void TLS_Channel::alert(Alert_Level alert_level, Alert_Type alert_code) } } -void TLS_Channel::Secure_Renegotiation_State::update(Client_Hello* client_hello) +void Channel::Secure_Renegotiation_State::update(Client_Hello* client_hello) { if(initial_handshake) { @@ -246,7 +248,7 @@ void TLS_Channel::Secure_Renegotiation_State::update(Client_Hello* client_hello) } } -void TLS_Channel::Secure_Renegotiation_State::update(Server_Hello* server_hello) +void Channel::Secure_Renegotiation_State::update(Server_Hello* server_hello) { if(initial_handshake) { @@ -283,7 +285,7 @@ void TLS_Channel::Secure_Renegotiation_State::update(Server_Hello* server_hello) initial_handshake = false; } -void TLS_Channel::Secure_Renegotiation_State::update(Finished* client_finished, +void Channel::Secure_Renegotiation_State::update(Finished* client_finished, Finished* server_finished) { client_verify = client_finished->verify_data(); @@ -291,3 +293,5 @@ void TLS_Channel::Secure_Renegotiation_State::update(Finished* client_finished, } } + +} diff --git a/src/tls/tls_channel.h b/src/tls/tls_channel.h index 2b4e6d161..6021b65b2 100644 --- a/src/tls/tls_channel.h +++ b/src/tls/tls_channel.h @@ -16,10 +16,12 @@ namespace Botan { +namespace TLS { + /** * Generic interface for TLS endpoint */ -class BOTAN_DLL TLS_Channel +class BOTAN_DLL Channel { public: /** @@ -59,11 +61,11 @@ class BOTAN_DLL TLS_Channel */ std::vector peer_cert_chain() const { return peer_certs; } - TLS_Channel(std::tr1::function socket_output_fn, + Channel(std::tr1::function socket_output_fn, std::tr1::function proc_fn, - std::tr1::function handshake_complete); + std::tr1::function handshake_complete); - virtual ~TLS_Channel(); + virtual ~Channel(); protected: /** @@ -83,14 +85,14 @@ class BOTAN_DLL TLS_Channel virtual void alert_notify(bool fatal_alert, Alert_Type type) = 0; std::tr1::function proc_fn; - std::tr1::function handshake_fn; + std::tr1::function handshake_fn; Record_Writer writer; Record_Reader reader; std::vector peer_certs; - class TLS_Handshake_State* state; + class Handshake_State* state; class Secure_Renegotiation_State { @@ -131,4 +133,6 @@ class BOTAN_DLL TLS_Channel } +} + #endif diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp index 48f0aec16..d1b31f137 100644 --- a/src/tls/tls_client.cpp +++ b/src/tls/tls_client.cpp @@ -13,19 +13,21 @@ namespace Botan { +namespace TLS { + /* * TLS Client Constructor */ -TLS_Client::TLS_Client(std::tr1::function output_fn, +Client::Client(std::tr1::function output_fn, std::tr1::function proc_fn, - std::tr1::function handshake_fn, - TLS_Session_Manager& session_manager, + std::tr1::function handshake_fn, + Session_Manager& session_manager, Credentials_Manager& creds, - const TLS_Policy& policy, + const Policy& policy, RandomNumberGenerator& rng, const std::string& hostname, std::tr1::function)> next_protocol) : - TLS_Channel(output_fn, proc_fn, handshake_fn), + Channel(output_fn, proc_fn, handshake_fn), policy(policy), rng(rng), session_manager(session_manager), @@ -33,7 +35,7 @@ TLS_Client::TLS_Client(std::tr1::function output_fn { writer.set_version(SSL_V3); - state = new TLS_Handshake_State; + state = new Handshake_State; state->set_expected_next(SERVER_HELLO); state->client_npn_cb = next_protocol; @@ -44,7 +46,7 @@ TLS_Client::TLS_Client(std::tr1::function output_fn if(hostname != "") { - TLS_Session session_info; + Session session_info; if(session_manager.load_from_host_info(hostname, 0, session_info)) { if(session_info.srp_identifier() == srp_identifier) @@ -80,12 +82,12 @@ TLS_Client::TLS_Client(std::tr1::function output_fn /* * Send a new client hello to renegotiate */ -void TLS_Client::renegotiate() +void Client::renegotiate() { if(state) return; // currently in handshake - state = new TLS_Handshake_State; + state = new Handshake_State; state->set_expected_next(SERVER_HELLO); state->client_hello = new Client_Hello(writer, state->hash, policy, rng, @@ -94,7 +96,7 @@ void TLS_Client::renegotiate() secure_renegotiation.update(state->client_hello); } -void TLS_Client::alert_notify(bool, Alert_Type type) +void Client::alert_notify(bool, Alert_Type type) { if(type == NO_RENEGOTIATION) { @@ -109,7 +111,7 @@ void TLS_Client::alert_notify(bool, Alert_Type type) /* * Process a handshake message */ -void TLS_Client::process_handshake_msg(Handshake_Type type, +void Client::process_handshake_msg(Handshake_Type type, const MemoryRegion& contents) { if(state == 0) @@ -178,7 +180,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, secure_renegotiation.update(state->server_hello); - state->suite = TLS_Ciphersuite::lookup_ciphersuite(state->server_hello->ciphersuite()); + state->suite = Ciphersuite::lookup_ciphersuite(state->server_hello->ciphersuite()); if(!state->server_hello->session_id().empty() && (state->server_hello->session_id() == state->client_hello->session_id())) @@ -206,13 +208,13 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, if(state->version > state->client_hello->version()) { throw TLS_Exception(HANDSHAKE_FAILURE, - "TLS_Client: Server replied with bad version"); + "Client: Server replied with bad version"); } if(state->version < policy.min_version()) { throw TLS_Exception(PROTOCOL_VERSION, - "TLS_Client: Server is too old for specified policy"); + "Client: Server is too old for specified policy"); } if(state->suite.sig_algo() != "") @@ -247,11 +249,11 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, peer_certs = state->server_certs->cert_chain(); if(peer_certs.size() == 0) throw TLS_Exception(HANDSHAKE_FAILURE, - "TLS_Client: No certificates sent by server"); + "Client: No certificates sent by server"); if(!policy.check_cert(peer_certs)) throw TLS_Exception(BAD_CERTIFICATE, - "TLS_Client: Server certificate is not valid"); + "Client: Server certificate is not valid"); std::auto_ptr peer_key(peer_certs[0].subject_public_key()); @@ -368,7 +370,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, state->client_finished = new Finished(writer, state, CLIENT); } - TLS_Session session_info( + Session session_info( state->server_hello->session_id(), state->keys.master_secret(), state->server_hello->version(), @@ -398,3 +400,5 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, } } + +} diff --git a/src/tls/tls_client.h b/src/tls/tls_client.h index 95b5c8f61..d67a14b75 100644 --- a/src/tls/tls_client.h +++ b/src/tls/tls_client.h @@ -15,10 +15,12 @@ namespace Botan { +namespace TLS { + /** * SSL/TLS Client */ -class BOTAN_DLL TLS_Client : public TLS_Channel +class BOTAN_DLL Client : public Channel { public: /** @@ -40,12 +42,12 @@ class BOTAN_DLL TLS_Client : public TLS_Channel * called with the list of protocols the server advertised; * the client should return the protocol it would like to use. */ - TLS_Client(std::tr1::function socket_output_fn, + Client(std::tr1::function socket_output_fn, std::tr1::function proc_fn, - std::tr1::function handshake_complete, - TLS_Session_Manager& session_manager, + std::tr1::function handshake_complete, + Session_Manager& session_manager, Credentials_Manager& creds, - const TLS_Policy& policy, + const Policy& policy, RandomNumberGenerator& rng, const std::string& servername = "", std::tr1::function)> next_protocol = @@ -58,12 +60,14 @@ class BOTAN_DLL TLS_Client : public TLS_Channel void alert_notify(bool is_fatal, Alert_Type type); - const TLS_Policy& policy; + const Policy& policy; RandomNumberGenerator& rng; - TLS_Session_Manager& session_manager; + Session_Manager& session_manager; Credentials_Manager& creds; }; } +} + #endif diff --git a/src/tls/tls_exceptn.h b/src/tls/tls_exceptn.h index 37b9c0d27..f29f008be 100644 --- a/src/tls/tls_exceptn.h +++ b/src/tls/tls_exceptn.h @@ -13,6 +13,8 @@ namespace Botan { +namespace TLS { + /** * Exception Base Class */ @@ -40,4 +42,6 @@ struct BOTAN_DLL Unexpected_Message : public TLS_Exception } +} + #endif diff --git a/src/tls/tls_extensions.cpp b/src/tls/tls_extensions.cpp index 570c7161c..631095c1e 100644 --- a/src/tls/tls_extensions.cpp +++ b/src/tls/tls_extensions.cpp @@ -11,11 +11,13 @@ namespace Botan { +namespace TLS { + namespace { -TLS_Extension* make_extension(TLS_Data_Reader& reader, - u16bit code, - u16bit size) +Extension* make_extension(TLS_Data_Reader& reader, + u16bit code, + u16bit size) { switch(code) { @@ -47,7 +49,7 @@ TLS_Extension* make_extension(TLS_Data_Reader& reader, } -TLS_Extensions::TLS_Extensions(TLS_Data_Reader& reader) +Extensions::Extensions(TLS_Data_Reader& reader) { if(reader.has_remaining()) { @@ -61,7 +63,7 @@ TLS_Extensions::TLS_Extensions(TLS_Data_Reader& reader) const u16bit extension_code = reader.get_u16bit(); const u16bit extension_size = reader.get_u16bit(); - TLS_Extension* extn = make_extension(reader, + Extension* extn = make_extension(reader, extension_code, extension_size); @@ -73,11 +75,11 @@ TLS_Extensions::TLS_Extensions(TLS_Data_Reader& reader) } } -MemoryVector TLS_Extensions::serialize() const +MemoryVector Extensions::serialize() const { MemoryVector buf(2); // 2 bytes for length field - for(std::map::const_iterator i = extensions.begin(); + for(std::map::const_iterator i = extensions.begin(); i != extensions.end(); ++i) { if(i->second->empty()) @@ -108,9 +110,9 @@ MemoryVector TLS_Extensions::serialize() const return buf; } -TLS_Extensions::~TLS_Extensions() +Extensions::~Extensions() { - for(std::map::const_iterator i = extensions.begin(); + for(std::map::const_iterator i = extensions.begin(); i != extensions.end(); ++i) { delete i->second; @@ -516,3 +518,5 @@ Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, } } + +} diff --git a/src/tls/tls_extensions.h b/src/tls/tls_extensions.h index d0aee6d04..7f9321331 100644 --- a/src/tls/tls_extensions.h +++ b/src/tls/tls_extensions.h @@ -16,33 +16,35 @@ namespace Botan { +namespace TLS { + class TLS_Data_Reader; /** * Base class representing a TLS extension of some kind */ -class TLS_Extension +class Extension { public: - virtual TLS_Handshake_Extension_Type type() const = 0; + virtual Handshake_Extension_Type type() const = 0; virtual MemoryVector serialize() const = 0; virtual bool empty() const = 0; - virtual ~TLS_Extension() {} + virtual ~Extension() {} }; /** * Server Name Indicator extension (RFC 3546) */ -class Server_Name_Indicator : public TLS_Extension +class Server_Name_Indicator : public Extension { public: - static TLS_Handshake_Extension_Type static_type() + static Handshake_Extension_Type static_type() { return TLSEXT_SERVER_NAME_INDICATION; } - TLS_Handshake_Extension_Type type() const { return static_type(); } + Handshake_Extension_Type type() const { return static_type(); } Server_Name_Indicator(const std::string& host_name) : sni_host_name(host_name) {} @@ -62,13 +64,13 @@ class Server_Name_Indicator : public TLS_Extension /** * SRP identifier extension (RFC 5054) */ -class SRP_Identifier : public TLS_Extension +class SRP_Identifier : public Extension { public: - static TLS_Handshake_Extension_Type static_type() + static Handshake_Extension_Type static_type() { return TLSEXT_SRP_IDENTIFIER; } - TLS_Handshake_Extension_Type type() const { return static_type(); } + Handshake_Extension_Type type() const { return static_type(); } SRP_Identifier(const std::string& identifier) : srp_identifier(identifier) {} @@ -88,13 +90,13 @@ class SRP_Identifier : public TLS_Extension /** * Renegotiation Indication Extension (RFC 5746) */ -class Renegotation_Extension : public TLS_Extension +class Renegotation_Extension : public Extension { public: - static TLS_Handshake_Extension_Type static_type() + static Handshake_Extension_Type static_type() { return TLSEXT_SAFE_RENEGOTIATION; } - TLS_Handshake_Extension_Type type() const { return static_type(); } + Handshake_Extension_Type type() const { return static_type(); } Renegotation_Extension() {} @@ -117,13 +119,13 @@ class Renegotation_Extension : public TLS_Extension /** * Maximum Fragment Length Negotiation Extension (RFC 4366 sec 3.2) */ -class Maximum_Fragment_Length : public TLS_Extension +class Maximum_Fragment_Length : public Extension { public: - static TLS_Handshake_Extension_Type static_type() + static Handshake_Extension_Type static_type() { return TLSEXT_MAX_FRAGMENT_LENGTH; } - TLS_Handshake_Extension_Type type() const { return static_type(); } + Handshake_Extension_Type type() const { return static_type(); } bool empty() const { return val != 0; } @@ -156,13 +158,13 @@ class Maximum_Fragment_Length : public TLS_Extension * spec (implemented in Chromium); the internet draft leaves the format * unspecified. */ -class Next_Protocol_Notification : public TLS_Extension +class Next_Protocol_Notification : public Extension { public: - static TLS_Handshake_Extension_Type static_type() + static Handshake_Extension_Type static_type() { return TLSEXT_NEXT_PROTOCOL; } - TLS_Handshake_Extension_Type type() const { return static_type(); } + Handshake_Extension_Type type() const { return static_type(); } const std::vector& protocols() const { return m_protocols; } @@ -191,13 +193,13 @@ class Next_Protocol_Notification : public TLS_Extension /** * Supported Elliptic Curves Extension (RFC 4492) */ -class Supported_Elliptic_Curves : public TLS_Extension +class Supported_Elliptic_Curves : public Extension { public: - static TLS_Handshake_Extension_Type static_type() + static Handshake_Extension_Type static_type() { return TLSEXT_USABLE_ELLIPTIC_CURVES; } - TLS_Handshake_Extension_Type type() const { return static_type(); } + Handshake_Extension_Type type() const { return static_type(); } const std::vector& curves() const { return m_curves; } @@ -216,13 +218,13 @@ class Supported_Elliptic_Curves : public TLS_Extension /** * Signature Algorithms Extension for TLS 1.2 (RFC 5246) */ -class Signature_Algorithms : public TLS_Extension +class Signature_Algorithms : public Extension { public: - static TLS_Handshake_Extension_Type static_type() + static Handshake_Extension_Type static_type() { return TLSEXT_SIGNATURE_ALGORITHMS; } - TLS_Handshake_Extension_Type type() const { return static_type(); } + Handshake_Extension_Type type() const { return static_type(); } static std::string hash_algo_name(byte code); static byte hash_algo_code(const std::string& name); @@ -252,15 +254,15 @@ class Signature_Algorithms : public TLS_Extension /** * Represents a block of extensions in a hello message */ -class TLS_Extensions +class Extensions { public: template T* get() const { - TLS_Handshake_Extension_Type type = T::static_type(); + Handshake_Extension_Type type = T::static_type(); - std::map::const_iterator i = + std::map::const_iterator i = extensions.find(type); if(i != extensions.end()) @@ -268,7 +270,7 @@ class TLS_Extensions return 0; } - void add(TLS_Extension* extn) + void add(Extension* extn) { delete extensions[extn->type()]; // or hard error if already exists? extensions[extn->type()] = extn; @@ -276,18 +278,20 @@ class TLS_Extensions MemoryVector serialize() const; - TLS_Extensions() {} + Extensions() {} - TLS_Extensions(TLS_Data_Reader& reader); // deserialize + Extensions(TLS_Data_Reader& reader); // deserialize - ~TLS_Extensions(); + ~Extensions(); private: - TLS_Extensions(const TLS_Extensions&) {} - TLS_Extensions& operator=(const TLS_Extensions&) { return (*this); } + Extensions(const Extensions&) {} + Extensions& operator=(const Extensions&) { return (*this); } - std::map extensions; + std::map extensions; }; } +} + #endif diff --git a/src/tls/tls_handshake_hash.cpp b/src/tls/tls_handshake_hash.cpp index 14d5cd5a1..e521ea342 100644 --- a/src/tls/tls_handshake_hash.cpp +++ b/src/tls/tls_handshake_hash.cpp @@ -14,7 +14,9 @@ namespace Botan { -void TLS_Handshake_Hash::update(Handshake_Type handshake_type, +namespace TLS { + +void Handshake_Hash::update(Handshake_Type handshake_type, const MemoryRegion& handshake_msg) { update(static_cast(handshake_type)); @@ -29,7 +31,7 @@ void TLS_Handshake_Hash::update(Handshake_Type handshake_type, /** * Return a TLS Handshake Hash */ -SecureVector TLS_Handshake_Hash::final(Version_Code version) +SecureVector Handshake_Hash::final(Version_Code version) { SecureVector output; @@ -61,7 +63,7 @@ SecureVector TLS_Handshake_Hash::final(Version_Code version) /** * Return a SSLv3 Handshake Hash */ -SecureVector TLS_Handshake_Hash::final_ssl3(const MemoryRegion& secret) +SecureVector Handshake_Hash::final_ssl3(const MemoryRegion& secret) { const byte PAD_INNER = 0x36, PAD_OUTER = 0x5C; @@ -97,3 +99,5 @@ SecureVector TLS_Handshake_Hash::final_ssl3(const MemoryRegion& secr } } + +} diff --git a/src/tls/tls_handshake_hash.h b/src/tls/tls_handshake_hash.h index 1ca11b99f..a6c2b44e1 100644 --- a/src/tls/tls_handshake_hash.h +++ b/src/tls/tls_handshake_hash.h @@ -13,12 +13,14 @@ namespace Botan { +namespace TLS { + using namespace Botan; /** * TLS Handshake Hash */ -class TLS_Handshake_Hash +class Handshake_Hash { public: void update(const byte in[], size_t length) @@ -45,4 +47,6 @@ class TLS_Handshake_Hash } +} + #endif diff --git a/src/tls/tls_handshake_state.cpp b/src/tls/tls_handshake_state.cpp index 6ad9b630c..5eb44414e 100644 --- a/src/tls/tls_handshake_state.cpp +++ b/src/tls/tls_handshake_state.cpp @@ -11,6 +11,8 @@ namespace Botan { +namespace TLS { + namespace { u32bit bitmask_for_handshake_type(Handshake_Type type) @@ -73,7 +75,7 @@ u32bit bitmask_for_handshake_type(Handshake_Type type) /* * Initialize the SSL/TLS Handshake State */ -TLS_Handshake_State::TLS_Handshake_State() +Handshake_State::Handshake_State() { client_hello = 0; server_hello = 0; @@ -97,7 +99,7 @@ TLS_Handshake_State::TLS_Handshake_State() hand_received_mask = 0; } -void TLS_Handshake_State::confirm_transition_to(Handshake_Type handshake_msg) +void Handshake_State::confirm_transition_to(Handshake_Type handshake_msg) { const u32bit mask = bitmask_for_handshake_type(handshake_msg); @@ -117,12 +119,12 @@ void TLS_Handshake_State::confirm_transition_to(Handshake_Type handshake_msg) hand_expecting_mask = 0; } -void TLS_Handshake_State::set_expected_next(Handshake_Type handshake_msg) +void Handshake_State::set_expected_next(Handshake_Type handshake_msg) { hand_expecting_mask |= bitmask_for_handshake_type(handshake_msg); } -bool TLS_Handshake_State::received_handshake_msg(Handshake_Type handshake_msg) const +bool Handshake_State::received_handshake_msg(Handshake_Type handshake_msg) const { const u32bit mask = bitmask_for_handshake_type(handshake_msg); @@ -130,7 +132,7 @@ bool TLS_Handshake_State::received_handshake_msg(Handshake_Type handshake_msg) c } std::pair -TLS_Handshake_State::choose_sig_format(const Private_Key* key, +Handshake_State::choose_sig_format(const Private_Key* key, std::string& hash_algo_out, std::string& sig_algo_out, bool for_client_auth) @@ -182,7 +184,7 @@ TLS_Handshake_State::choose_sig_format(const Private_Key* key, } std::pair -TLS_Handshake_State::understand_sig_format(const Public_Key* key, +Handshake_State::understand_sig_format(const Public_Key* key, std::string hash_algo, std::string sig_algo, bool for_client_auth) @@ -247,7 +249,7 @@ TLS_Handshake_State::understand_sig_format(const Public_Key* key, /* * Destroy the SSL/TLS Handshake State */ -TLS_Handshake_State::~TLS_Handshake_State() +Handshake_State::~Handshake_State() { delete client_hello; delete server_hello; @@ -267,3 +269,5 @@ TLS_Handshake_State::~TLS_Handshake_State() } } + +} diff --git a/src/tls/tls_handshake_state.h b/src/tls/tls_handshake_state.h index 18b289fe1..54e0da892 100644 --- a/src/tls/tls_handshake_state.h +++ b/src/tls/tls_handshake_state.h @@ -32,14 +32,16 @@ namespace Botan { +namespace TLS { + /** * SSL/TLS Handshake State */ -class TLS_Handshake_State +class Handshake_State { public: - TLS_Handshake_State(); - ~TLS_Handshake_State(); + Handshake_State(); + ~Handshake_State(); bool received_handshake_msg(Handshake_Type handshake_msg) const; @@ -78,9 +80,9 @@ class TLS_Handshake_State Private_Key* kex_priv; - TLS_Ciphersuite suite; + Ciphersuite suite; Session_Keys keys; - TLS_Handshake_Hash hash; + Handshake_Hash hash; SecureQueue queue; @@ -100,4 +102,6 @@ class TLS_Handshake_State } +} + #endif diff --git a/src/tls/tls_magic.h b/src/tls/tls_magic.h index 3426088bd..09919c26f 100644 --- a/src/tls/tls_magic.h +++ b/src/tls/tls_magic.h @@ -10,6 +10,8 @@ namespace Botan { +namespace TLS { + /** * Protocol Constants for SSL/TLS */ @@ -167,7 +169,7 @@ enum Compression_Method { DEFLATE_COMPRESSION = 0x01 }; -enum TLS_Handshake_Extension_Type { +enum Handshake_Extension_Type { TLSEXT_SERVER_NAME_INDICATION = 0, TLSEXT_MAX_FRAGMENT_LENGTH = 1, TLSEXT_CLIENT_CERT_URL = 2, @@ -189,4 +191,6 @@ enum TLS_Handshake_Extension_Type { } +} + #endif diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h index 3579f7828..89eb4af16 100644 --- a/src/tls/tls_messages.h +++ b/src/tls/tls_messages.h @@ -20,6 +20,8 @@ namespace Botan { +namespace TLS { + class Record_Writer; class Record_Reader; @@ -29,7 +31,7 @@ class Record_Reader; class Handshake_Message { public: - void send(Record_Writer& writer, TLS_Handshake_Hash& hash) const; + void send(Record_Writer& writer, Handshake_Hash& hash) const; virtual Handshake_Type type() const = 0; @@ -82,8 +84,8 @@ class Client_Hello : public Handshake_Message size_t fragment_size() const { return m_fragment_size; } Client_Hello(Record_Writer& writer, - TLS_Handshake_Hash& hash, - const TLS_Policy& policy, + Handshake_Hash& hash, + const Policy& policy, RandomNumberGenerator& rng, const MemoryRegion& reneg_info, bool next_protocol = false, @@ -91,9 +93,9 @@ class Client_Hello : public Handshake_Message const std::string& srp_identifier = ""); Client_Hello(Record_Writer& writer, - TLS_Handshake_Hash& hash, + Handshake_Hash& hash, RandomNumberGenerator& rng, - const TLS_Session& resumed_session, + const Session& resumed_session, bool next_protocol = false); Client_Hello(const MemoryRegion& buf, @@ -153,11 +155,11 @@ class Server_Hello : public Handshake_Message const MemoryVector& random() const { return s_random; } Server_Hello(Record_Writer& writer, - TLS_Handshake_Hash& hash, + Handshake_Hash& hash, Version_Code version, const Client_Hello& other, const std::vector& certs, - const TLS_Policy& policies, + const Policy& policies, bool client_has_secure_renegotiation, const MemoryRegion& reneg_info, bool client_has_npn, @@ -165,7 +167,7 @@ class Server_Hello : public Handshake_Message RandomNumberGenerator& rng); Server_Hello(Record_Writer& writer, - TLS_Handshake_Hash& hash, + Handshake_Hash& hash, const MemoryRegion& session_id, Version_Code ver, u16bit ciphersuite, @@ -210,12 +212,12 @@ class Client_Key_Exchange : public Handshake_Message Version_Code version); Client_Key_Exchange(Record_Writer& output, - TLS_Handshake_State* state, + Handshake_State* state, const std::vector& peer_certs, RandomNumberGenerator& rng); Client_Key_Exchange(const MemoryRegion& buf, - const TLS_Ciphersuite& suite, + const Ciphersuite& suite, Version_Code using_version); private: MemoryVector serialize() const; @@ -237,7 +239,7 @@ class Certificate : public Handshake_Message bool empty() const { return certs.empty(); } Certificate(Record_Writer& writer, - TLS_Handshake_Hash& hash, + Handshake_Hash& hash, const std::vector& certs); Certificate(const MemoryRegion& buf); @@ -262,8 +264,8 @@ class Certificate_Req : public Handshake_Message { return m_supported_algos; } Certificate_Req(Record_Writer& writer, - TLS_Handshake_Hash& hash, - const TLS_Policy& policy, + Handshake_Hash& hash, + const Policy& policy, const std::vector& allowed_cas, Version_Code version); @@ -292,10 +294,10 @@ class Certificate_Verify : public Handshake_Message * @param state the handshake state */ bool verify(const X509_Certificate& cert, - TLS_Handshake_State* state); + Handshake_State* state); Certificate_Verify(Record_Writer& writer, - TLS_Handshake_State* state, + Handshake_State* state, RandomNumberGenerator& rng, const Private_Key* key); @@ -320,11 +322,11 @@ class Finished : public Handshake_Message MemoryVector verify_data() const { return verification_data; } - bool verify(TLS_Handshake_State* state, + bool verify(Handshake_State* state, Connection_Side side); Finished(Record_Writer& writer, - TLS_Handshake_State* state, + Handshake_State* state, Connection_Side side); Finished(const MemoryRegion& buf); @@ -360,10 +362,10 @@ class Server_Key_Exchange : public Handshake_Message const std::vector& params() const { return m_params; } bool verify(const X509_Certificate& cert, - TLS_Handshake_State* state) const; + Handshake_State* state) const; Server_Key_Exchange(Record_Writer& writer, - TLS_Handshake_State* state, + Handshake_State* state, RandomNumberGenerator& rng, const Private_Key* priv_key); @@ -390,7 +392,7 @@ class Server_Hello_Done : public Handshake_Message public: Handshake_Type type() const { return SERVER_HELLO_DONE; } - Server_Hello_Done(Record_Writer& writer, TLS_Handshake_Hash& hash); + Server_Hello_Done(Record_Writer& writer, Handshake_Hash& hash); Server_Hello_Done(const MemoryRegion& buf); private: MemoryVector serialize() const; @@ -407,7 +409,7 @@ class Next_Protocol : public Handshake_Message std::string protocol() const { return m_protocol; } Next_Protocol(Record_Writer& writer, - TLS_Handshake_Hash& hash, + Handshake_Hash& hash, const std::string& protocol); Next_Protocol(const MemoryRegion& buf); @@ -419,4 +421,6 @@ class Next_Protocol : public Handshake_Message } +} + #endif diff --git a/src/tls/tls_policy.cpp b/src/tls/tls_policy.cpp index c02f35a9a..ca6286b72 100644 --- a/src/tls/tls_policy.cpp +++ b/src/tls/tls_policy.cpp @@ -12,7 +12,9 @@ namespace Botan { -std::vector TLS_Policy::allowed_ciphers() const +namespace TLS { + +std::vector Policy::allowed_ciphers() const { std::vector allowed; allowed.push_back("AES-256"); @@ -23,7 +25,7 @@ std::vector TLS_Policy::allowed_ciphers() const return allowed; } -std::vector TLS_Policy::allowed_hashes() const +std::vector Policy::allowed_hashes() const { std::vector allowed; allowed.push_back("SHA-512"); @@ -35,7 +37,7 @@ std::vector TLS_Policy::allowed_hashes() const return allowed; } -std::vector TLS_Policy::allowed_key_exchange_methods() const +std::vector Policy::allowed_key_exchange_methods() const { std::vector allowed; //allowed.push_back("ECDH"); @@ -45,7 +47,7 @@ std::vector TLS_Policy::allowed_key_exchange_methods() const return allowed; } -std::vector TLS_Policy::allowed_signature_methods() const +std::vector Policy::allowed_signature_methods() const { std::vector allowed; //allowed.push_back("ECDSA"); @@ -65,7 +67,7 @@ class Ciphersuite_Preference_Ordering const std::vector& sigs) : m_ciphers(ciphers), m_hashes(hashes), m_kex(kex), m_sigs(sigs) {} - bool operator()(const TLS_Ciphersuite& a, const TLS_Ciphersuite& b) const + bool operator()(const Ciphersuite& a, const Ciphersuite& b) const { if(a.kex_algo() != b.kex_algo()) { @@ -120,7 +122,7 @@ class Ciphersuite_Preference_Ordering } -std::vector TLS_Policy::ciphersuite_list(bool have_srp) const +std::vector Policy::ciphersuite_list(bool have_srp) const { std::vector ciphers = allowed_ciphers(); std::vector hashes = allowed_hashes(); @@ -137,12 +139,12 @@ std::vector TLS_Policy::ciphersuite_list(bool have_srp) const Ciphersuite_Preference_Ordering order(ciphers, hashes, kex, sigs); - std::map ciphersuites(order); + std::map ciphersuites(order); // When in doubt use brute force :) for(u32bit i = 0; i != 65536; ++i) { - TLS_Ciphersuite suite = TLS_Ciphersuite::lookup_ciphersuite(i); + Ciphersuite suite = Ciphersuite::lookup_ciphersuite(i); if(suite.cipher_keylen() == 0) continue; // not a ciphersuite we know @@ -157,7 +159,7 @@ std::vector TLS_Policy::ciphersuite_list(bool have_srp) const std::vector ciphersuite_codes; - for(std::map::iterator i = ciphersuites.begin(); + for(std::map::iterator i = ciphersuites.begin(); i != ciphersuites.end(); ++i) { ciphersuite_codes.push_back(i->second); @@ -169,7 +171,7 @@ std::vector TLS_Policy::ciphersuite_list(bool have_srp) const /* * Return allowed compression algorithms */ -std::vector TLS_Policy::compression() const +std::vector Policy::compression() const { std::vector algs; algs.push_back(NO_COMPRESSION); @@ -179,7 +181,7 @@ std::vector TLS_Policy::compression() const /* * Choose which ciphersuite to use */ -u16bit TLS_Policy::choose_suite(const std::vector& client_suites, +u16bit Policy::choose_suite(const std::vector& client_suites, bool have_rsa, bool have_dsa, bool have_srp) const @@ -187,7 +189,7 @@ u16bit TLS_Policy::choose_suite(const std::vector& client_suites, for(size_t i = 0; i != client_suites.size(); ++i) { u16bit suite_id = client_suites[i]; - TLS_Ciphersuite suite = TLS_Ciphersuite::lookup_ciphersuite(suite_id); + Ciphersuite suite = Ciphersuite::lookup_ciphersuite(suite_id); if(suite.cipher_keylen() == 0) continue; // not a ciphersuite we know @@ -216,7 +218,7 @@ u16bit TLS_Policy::choose_suite(const std::vector& client_suites, /* * Choose which compression algorithm to use */ -byte TLS_Policy::choose_compression(const std::vector& c_comp) const +byte Policy::choose_compression(const std::vector& c_comp) const { std::vector s_comp = compression(); @@ -229,3 +231,5 @@ byte TLS_Policy::choose_compression(const std::vector& c_comp) const } } + +} diff --git a/src/tls/tls_policy.h b/src/tls/tls_policy.h index 5bf60742b..f8e608cdb 100644 --- a/src/tls/tls_policy.h +++ b/src/tls/tls_policy.h @@ -15,11 +15,13 @@ namespace Botan { +namespace TLS { + /** * TLS Policy Base Class * Inherit and overload as desired to suite local policy concerns */ -class BOTAN_DLL TLS_Policy +class BOTAN_DLL Policy { public: /* @@ -77,9 +79,11 @@ class BOTAN_DLL TLS_Policy */ virtual Version_Code pref_version() const { return TLS_V12; } - virtual ~TLS_Policy() {} + virtual ~Policy() {} }; } +} + #endif diff --git a/src/tls/tls_reader.h b/src/tls/tls_reader.h index 1cf7adab0..09487c5f9 100644 --- a/src/tls/tls_reader.h +++ b/src/tls/tls_reader.h @@ -17,6 +17,8 @@ namespace Botan { +namespace TLS { + /** * Helper class for decoding TLS protocol messages */ @@ -205,4 +207,6 @@ void append_tls_length_value(MemoryRegion& buf, } +} + #endif diff --git a/src/tls/tls_record.h b/src/tls/tls_record.h index c4b483c80..979154001 100644 --- a/src/tls/tls_record.h +++ b/src/tls/tls_record.h @@ -30,6 +30,8 @@ namespace Botan { +namespace TLS { + class Session_Keys; /** @@ -43,7 +45,7 @@ class BOTAN_DLL Record_Writer void alert(Alert_Level level, Alert_Type type); - void activate(const TLS_Ciphersuite& suite, + void activate(const Ciphersuite& suite, const Session_Keys& keys, Connection_Side side); @@ -97,7 +99,7 @@ class BOTAN_DLL Record_Reader byte& msg_type, MemoryVector& msg); - void activate(const TLS_Ciphersuite& suite, + void activate(const Ciphersuite& suite, const Session_Keys& keys, Connection_Side side); @@ -132,4 +134,6 @@ class BOTAN_DLL Record_Reader } +} + #endif diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp index 5d07d22ba..6c6977b91 100644 --- a/src/tls/tls_server.cpp +++ b/src/tls/tls_server.cpp @@ -13,10 +13,12 @@ namespace Botan { +namespace TLS { + namespace { -bool check_for_resume(TLS_Session& session_info, - TLS_Session_Manager& session_manager, +bool check_for_resume(Session& session_info, + Session_Manager& session_manager, Client_Hello* client_hello) { MemoryVector client_session_id = client_hello->session_id(); @@ -64,15 +66,15 @@ bool check_for_resume(TLS_Session& session_info, /* * TLS Server Constructor */ -TLS_Server::TLS_Server(std::tr1::function output_fn, +Server::Server(std::tr1::function output_fn, std::tr1::function proc_fn, - std::tr1::function handshake_fn, - TLS_Session_Manager& session_manager, + std::tr1::function handshake_fn, + Session_Manager& session_manager, Credentials_Manager& creds, - const TLS_Policy& policy, + const Policy& policy, RandomNumberGenerator& rng, const std::vector& next_protocols) : - TLS_Channel(output_fn, proc_fn, handshake_fn), + Channel(output_fn, proc_fn, handshake_fn), policy(policy), rng(rng), session_manager(session_manager), @@ -84,17 +86,17 @@ TLS_Server::TLS_Server(std::tr1::function output_fn /* * Send a hello request to the client */ -void TLS_Server::renegotiate() +void Server::renegotiate() { if(state) return; // currently in handshake - state = new TLS_Handshake_State; + state = new Handshake_State; state->set_expected_next(CLIENT_HELLO); Hello_Request hello_req(writer); } -void TLS_Server::alert_notify(bool, Alert_Type type) +void Server::alert_notify(bool, Alert_Type type) { if(type == NO_RENEGOTIATION) { @@ -109,22 +111,22 @@ void TLS_Server::alert_notify(bool, Alert_Type type) /* * Split up and process handshake messages */ -void TLS_Server::read_handshake(byte rec_type, +void Server::read_handshake(byte rec_type, const MemoryRegion& rec_buf) { if(rec_type == HANDSHAKE && !state) { - state = new TLS_Handshake_State; + state = new Handshake_State; state->set_expected_next(CLIENT_HELLO); } - TLS_Channel::read_handshake(rec_type, rec_buf); + Channel::read_handshake(rec_type, rec_buf); } /* * Process a handshake message */ -void TLS_Server::process_handshake_msg(Handshake_Type type, +void Server::process_handshake_msg(Handshake_Type type, const MemoryRegion& contents) { if(state == 0) @@ -169,7 +171,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, writer.set_version(state->version); reader.set_version(state->version); - TLS_Session session_info; + Session session_info; const bool resuming = check_for_resume(session_info, session_manager, state->client_hello); @@ -198,7 +200,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, writer.set_maximum_fragment_size(session_info.fragment_size()); } - state->suite = TLS_Ciphersuite::lookup_ciphersuite(state->server_hello->ciphersuite()); + state->suite = Ciphersuite::lookup_ciphersuite(state->server_hello->ciphersuite()); state->keys = Session_Keys(state, session_info.master_secret(), true); @@ -245,7 +247,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, writer.set_maximum_fragment_size(state->client_hello->fragment_size()); } - state->suite = TLS_Ciphersuite::lookup_ciphersuite(state->server_hello->ciphersuite()); + state->suite = Ciphersuite::lookup_ciphersuite(state->server_hello->ciphersuite()); if(state->suite.sig_algo() != "") { @@ -259,7 +261,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, if(state->suite.kex_algo() == "DH") state->kex_priv = new DH_PrivateKey(rng, policy.dh_group()); else - throw Internal_Error("TLS_Server: Unknown ciphersuite kex type " + + throw Internal_Error("Server: Unknown ciphersuite kex type " + state->suite.kex_algo()); state->server_kex = @@ -386,7 +388,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, peer_certs = state->client_certs->cert_chain(); } - TLS_Session session_info( + Session session_info( state->server_hello->session_id(), state->keys.master_secret(), state->server_hello->version(), @@ -417,3 +419,5 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, } } + +} diff --git a/src/tls/tls_server.h b/src/tls/tls_server.h index f8c3a8563..c283d4a18 100644 --- a/src/tls/tls_server.h +++ b/src/tls/tls_server.h @@ -15,21 +15,23 @@ namespace Botan { +namespace TLS { + /** * TLS Server */ -class BOTAN_DLL TLS_Server : public TLS_Channel +class BOTAN_DLL Server : public Channel { public: /** - * TLS_Server initialization + * Server initialization */ - TLS_Server(std::tr1::function socket_output_fn, + Server(std::tr1::function socket_output_fn, std::tr1::function proc_fn, - std::tr1::function handshake_complete, - TLS_Session_Manager& session_manager, + std::tr1::function handshake_complete, + Session_Manager& session_manager, Credentials_Manager& creds, - const TLS_Policy& policy, + const Policy& policy, RandomNumberGenerator& rng, const std::vector& protocols = std::vector()); @@ -55,9 +57,9 @@ class BOTAN_DLL TLS_Server : public TLS_Channel void alert_notify(bool is_fatal, Alert_Type type); - const TLS_Policy& policy; + const Policy& policy; RandomNumberGenerator& rng; - TLS_Session_Manager& session_manager; + Session_Manager& session_manager; Credentials_Manager& creds; std::vector m_possible_protocols; @@ -67,4 +69,6 @@ class BOTAN_DLL TLS_Server : public TLS_Channel } +} + #endif diff --git a/src/tls/tls_session.cpp b/src/tls/tls_session.cpp index deaddb227..3716878e1 100644 --- a/src/tls/tls_session.cpp +++ b/src/tls/tls_session.cpp @@ -13,7 +13,9 @@ namespace Botan { -TLS_Session::TLS_Session(const MemoryRegion& session_identifier, +namespace TLS { + +Session::Session(const MemoryRegion& session_identifier, const MemoryRegion& master_secret, Version_Code version, u16bit ciphersuite, @@ -41,7 +43,7 @@ TLS_Session::TLS_Session(const MemoryRegion& session_identifier, m_peer_certificate = certs[0].BER_encode(); } -TLS_Session::TLS_Session(const byte ber[], size_t ber_len) +Session::Session(const byte ber[], size_t ber_len) { BER_Decoder decoder(ber, ber_len); @@ -70,7 +72,7 @@ TLS_Session::TLS_Session(const byte ber[], size_t ber_len) m_connection_side = static_cast(side_code); } -SecureVector TLS_Session::BER_encode() const +SecureVector Session::BER_encode() const { return DER_Encoder() .start_cons(SEQUENCE) @@ -92,3 +94,5 @@ SecureVector TLS_Session::BER_encode() const } } + +} diff --git a/src/tls/tls_session.h b/src/tls/tls_session.h index 12b76bcab..9b3f5b194 100644 --- a/src/tls/tls_session.h +++ b/src/tls/tls_session.h @@ -14,17 +14,19 @@ namespace Botan { +namespace TLS { + /** * Class representing a TLS session state */ -class BOTAN_DLL TLS_Session +class BOTAN_DLL Session { public: /** * Uninitialized session */ - TLS_Session() : + Session() : m_start_time(0), m_version(0), m_ciphersuite(0), @@ -37,7 +39,7 @@ class BOTAN_DLL TLS_Session /** * New session (sets session start time) */ - TLS_Session(const MemoryRegion& session_id, + Session(const MemoryRegion& session_id, const MemoryRegion& master_secret, Version_Code version, u16bit ciphersuite, @@ -52,7 +54,7 @@ class BOTAN_DLL TLS_Session /** * Load a session from BER (created by BER_encode) */ - TLS_Session(const byte ber[], size_t ber_len); + Session(const byte ber[], size_t ber_len); /** * Encode this session data for storage @@ -154,4 +156,6 @@ class BOTAN_DLL TLS_Session } +} + #endif diff --git a/src/tls/tls_session_key.cpp b/src/tls/tls_session_key.cpp index cb55499f0..42727273a 100644 --- a/src/tls/tls_session_key.cpp +++ b/src/tls/tls_session_key.cpp @@ -13,6 +13,8 @@ namespace Botan { +namespace TLS { + namespace { std::string lookup_prf_name(Version_Code version) @@ -32,7 +34,7 @@ std::string lookup_prf_name(Version_Code version) /** * Session_Keys Constructor */ -Session_Keys::Session_Keys(TLS_Handshake_State* state, +Session_Keys::Session_Keys(Handshake_State* state, const MemoryRegion& pre_master_secret, bool resuming) { @@ -101,3 +103,5 @@ Session_Keys::Session_Keys(TLS_Handshake_State* state, } } + +} diff --git a/src/tls/tls_session_key.h b/src/tls/tls_session_key.h index 8ba3d2b72..736475be6 100644 --- a/src/tls/tls_session_key.h +++ b/src/tls/tls_session_key.h @@ -14,6 +14,8 @@ namespace Botan { +namespace TLS { + /** * TLS Session Keys */ @@ -33,7 +35,7 @@ class Session_Keys Session_Keys() {} - Session_Keys(class TLS_Handshake_State* state, + Session_Keys(class Handshake_State* state, const MemoryRegion& pre_master, bool resuming); @@ -45,4 +47,6 @@ class Session_Keys } +} + #endif diff --git a/src/tls/tls_session_manager.cpp b/src/tls/tls_session_manager.cpp index e5ec75c88..59fc75b9f 100644 --- a/src/tls/tls_session_manager.cpp +++ b/src/tls/tls_session_manager.cpp @@ -11,10 +11,12 @@ namespace Botan { -bool TLS_Session_Manager_In_Memory::load_from_session_str( - const std::string& session_str, TLS_Session& session) +namespace TLS { + +bool Session_Manager_In_Memory::load_from_session_str( + const std::string& session_str, Session& session) { - std::map::iterator i = sessions.find(session_str); + std::map::iterator i = sessions.find(session_str); if(i == sessions.end()) return false; @@ -31,14 +33,14 @@ bool TLS_Session_Manager_In_Memory::load_from_session_str( return true; } -bool TLS_Session_Manager_In_Memory::load_from_session_id( - const MemoryRegion& session_id, TLS_Session& session) +bool Session_Manager_In_Memory::load_from_session_id( + const MemoryRegion& session_id, Session& session) { return load_from_session_str(hex_encode(session_id), session); } -bool TLS_Session_Manager_In_Memory::load_from_host_info( - const std::string& hostname, u16bit port, TLS_Session& session) +bool Session_Manager_In_Memory::load_from_host_info( + const std::string& hostname, u16bit port, Session& session) { std::map::iterator i; @@ -59,17 +61,17 @@ bool TLS_Session_Manager_In_Memory::load_from_host_info( return false; } -void TLS_Session_Manager_In_Memory::remove_entry( +void Session_Manager_In_Memory::remove_entry( const MemoryRegion& session_id) { - std::map::iterator i = + std::map::iterator i = sessions.find(hex_encode(session_id)); if(i != sessions.end()) sessions.erase(i); } -void TLS_Session_Manager_In_Memory::save(const TLS_Session& session) +void Session_Manager_In_Memory::save(const Session& session) { if(max_sessions != 0) { @@ -90,3 +92,5 @@ void TLS_Session_Manager_In_Memory::save(const TLS_Session& session) } } + +} diff --git a/src/tls/tls_session_manager.h b/src/tls/tls_session_manager.h index 289b76a3b..c25fecac4 100644 --- a/src/tls/tls_session_manager.h +++ b/src/tls/tls_session_manager.h @@ -13,8 +13,10 @@ namespace Botan { +namespace TLS { + /** -* TLS_Session_Manager is an interface to systems which can save +* Session_Manager is an interface to systems which can save * session parameters for supporting session resumption. * * Saving sessions is done on a best-effort basis; an implementation is @@ -22,7 +24,7 @@ namespace Botan { * * Implementations should strive to be thread safe */ -class BOTAN_DLL TLS_Session_Manager +class BOTAN_DLL Session_Manager { public: /** @@ -33,7 +35,7 @@ class BOTAN_DLL TLS_Session_Manager * @return true if session was modified */ virtual bool load_from_session_id(const MemoryRegion& session_id, - TLS_Session& session) = 0; + Session& session) = 0; /** * Try to load a saved session (client side) @@ -44,7 +46,7 @@ class BOTAN_DLL TLS_Session_Manager * @return true if session was modified */ virtual bool load_from_host_info(const std::string& hostname, u16bit port, - TLS_Session& session) = 0; + Session& session) = 0; /** * Remove this session id from the cache, if it exists @@ -59,18 +61,18 @@ class BOTAN_DLL TLS_Session_Manager * * @param session to save */ - virtual void save(const TLS_Session& session) = 0; + virtual void save(const Session& session) = 0; - virtual ~TLS_Session_Manager() {} + virtual ~Session_Manager() {} }; /** -* A simple implementation of TLS_Session_Manager that just saves +* A simple implementation of Session_Manager that just saves * values in memory, with no persistance abilities * * @todo add locking */ -class BOTAN_DLL TLS_Session_Manager_In_Memory : public TLS_Session_Manager +class BOTAN_DLL Session_Manager_In_Memory : public Session_Manager { public: /** @@ -79,32 +81,34 @@ class BOTAN_DLL TLS_Session_Manager_In_Memory : public TLS_Session_Manager * @param session_lifetime sessions are expired after this many * seconds have elapsed from initial handshake. */ - TLS_Session_Manager_In_Memory(size_t max_sessions = 1000, + Session_Manager_In_Memory(size_t max_sessions = 1000, size_t session_lifetime = 7200) : max_sessions(max_sessions), session_lifetime(session_lifetime) {} bool load_from_session_id(const MemoryRegion& session_id, - TLS_Session& session); + Session& session); bool load_from_host_info(const std::string& hostname, u16bit port, - TLS_Session& session); + Session& session); void remove_entry(const MemoryRegion& session_id); - void save(const TLS_Session& session_data); + void save(const Session& session_data); private: bool load_from_session_str(const std::string& session_str, - TLS_Session& session); + Session& session); size_t max_sessions, session_lifetime; - std::map sessions; // hex(session_id) -> session + std::map sessions; // hex(session_id) -> session std::map host_sessions; }; } +} + #endif diff --git a/src/tls/tls_suites.cpp b/src/tls/tls_suites.cpp index c24cdb9f7..442d261cd 100644 --- a/src/tls/tls_suites.cpp +++ b/src/tls/tls_suites.cpp @@ -10,149 +10,151 @@ namespace Botan { +namespace TLS { + /** * Convert an SSL/TLS ciphersuite to algorithm fields */ -TLS_Ciphersuite TLS_Ciphersuite::lookup_ciphersuite(u16bit suite) +Ciphersuite Ciphersuite::lookup_ciphersuite(u16bit suite) { switch(suite) { // RSA ciphersuites case TLS_RSA_WITH_AES_128_CBC_SHA: - return TLS_Ciphersuite("RSA", "", "SHA-1", "AES-128", 16); + return Ciphersuite("RSA", "", "SHA-1", "AES-128", 16); case TLS_RSA_WITH_AES_256_CBC_SHA: - return TLS_Ciphersuite("RSA", "", "SHA-1", "AES-256", 32); + return Ciphersuite("RSA", "", "SHA-1", "AES-256", 32); case TLS_RSA_WITH_AES_128_CBC_SHA256: - return TLS_Ciphersuite("RSA", "", "SHA-256", "AES-128", 16); + return Ciphersuite("RSA", "", "SHA-256", "AES-128", 16); case TLS_RSA_WITH_AES_256_CBC_SHA256: - return TLS_Ciphersuite("RSA", "", "SHA-256", "AES-256", 32); + return Ciphersuite("RSA", "", "SHA-256", "AES-256", 32); case TLS_RSA_WITH_3DES_EDE_CBC_SHA: - return TLS_Ciphersuite("RSA", "", "SHA-1", "TripleDES", 24); + return Ciphersuite("RSA", "", "SHA-1", "TripleDES", 24); case TLS_RSA_WITH_RC4_128_SHA: - return TLS_Ciphersuite("RSA", "", "SHA-1", "ARC4", 16); + return Ciphersuite("RSA", "", "SHA-1", "ARC4", 16); case TLS_RSA_WITH_RC4_128_MD5: - return TLS_Ciphersuite("RSA", "", "MD5", "ARC4", 16); + return Ciphersuite("RSA", "", "MD5", "ARC4", 16); case TLS_RSA_WITH_SEED_CBC_SHA: - return TLS_Ciphersuite("RSA", "", "SHA-1", "SEED", 16); + return Ciphersuite("RSA", "", "SHA-1", "SEED", 16); // DH/DSS ciphersuites case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: - return TLS_Ciphersuite("DSA", "DH", "SHA-1", "AES-128", 16); + return Ciphersuite("DSA", "DH", "SHA-1", "AES-128", 16); case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: - return TLS_Ciphersuite("DSA", "DH", "SHA-1", "AES-256", 32); + return Ciphersuite("DSA", "DH", "SHA-1", "AES-256", 32); case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: - return TLS_Ciphersuite("DSA", "DH", "SHA-256", "AES-128", 16); + return Ciphersuite("DSA", "DH", "SHA-256", "AES-128", 16); case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: - return TLS_Ciphersuite("DSA", "DH", "SHA-256", "AES-256", 32); + return Ciphersuite("DSA", "DH", "SHA-256", "AES-256", 32); case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: - return TLS_Ciphersuite("DSA", "DH", "SHA-1", "TripleDES", 24); + return Ciphersuite("DSA", "DH", "SHA-1", "TripleDES", 24); case TLS_DHE_DSS_WITH_RC4_128_SHA: - return TLS_Ciphersuite("DSA", "DH", "SHA-1", "ARC4", 16); + return Ciphersuite("DSA", "DH", "SHA-1", "ARC4", 16); case TLS_DHE_DSS_WITH_SEED_CBC_SHA: - return TLS_Ciphersuite("DSA", "DH", "SHA-1", "SEED", 16); + return Ciphersuite("DSA", "DH", "SHA-1", "SEED", 16); // DH/RSA ciphersuites case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: - return TLS_Ciphersuite("RSA", "DH", "SHA-1", "AES-128", 16); + return Ciphersuite("RSA", "DH", "SHA-1", "AES-128", 16); case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: - return TLS_Ciphersuite("RSA", "DH", "SHA-1", "AES-256", 32); + return Ciphersuite("RSA", "DH", "SHA-1", "AES-256", 32); case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: - return TLS_Ciphersuite("RSA", "DH", "SHA-256", "AES-128", 16); + return Ciphersuite("RSA", "DH", "SHA-256", "AES-128", 16); case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: - return TLS_Ciphersuite("RSA", "DH", "SHA-256", "AES-256", 32); + return Ciphersuite("RSA", "DH", "SHA-256", "AES-256", 32); case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: - return TLS_Ciphersuite("RSA", "DH", "SHA-1", "TripleDES", 24); + return Ciphersuite("RSA", "DH", "SHA-1", "TripleDES", 24); case TLS_DHE_RSA_WITH_SEED_CBC_SHA: - return TLS_Ciphersuite("RSA", "DH", "SHA-1", "SEED", 16); + return Ciphersuite("RSA", "DH", "SHA-1", "SEED", 16); // ECDH/RSA ciphersuites case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: - return TLS_Ciphersuite("RSA", "ECDH", "SHA-1", "AES-128", 16); + return Ciphersuite("RSA", "ECDH", "SHA-1", "AES-128", 16); case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - return TLS_Ciphersuite("RSA", "ECDH", "SHA-1", "AES-256", 32); + return Ciphersuite("RSA", "ECDH", "SHA-1", "AES-256", 32); case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: - return TLS_Ciphersuite("RSA", "ECDH", "SHA-1", "TripleDES", 24); + return Ciphersuite("RSA", "ECDH", "SHA-1", "TripleDES", 24); case TLS_ECDHE_RSA_WITH_RC4_128_SHA: - return TLS_Ciphersuite("RSA", "ECDH", "SHA-1", "ARC4", 16); + return Ciphersuite("RSA", "ECDH", "SHA-1", "ARC4", 16); // SRP/RSA ciphersuites case TLS_SRP_SHA_RSA_WITH_AES_128_SHA: - return TLS_Ciphersuite("RSA", "SRP", "SHA-1", "AES-128", 16); + return Ciphersuite("RSA", "SRP", "SHA-1", "AES-128", 16); case TLS_SRP_SHA_RSA_WITH_AES_256_SHA: - return TLS_Ciphersuite("RSA", "SRP", "SHA-1", "AES-256", 32); + return Ciphersuite("RSA", "SRP", "SHA-1", "AES-256", 32); case TLS_SRP_SHA_RSA_WITH_3DES_EDE_SHA: - return TLS_Ciphersuite("RSA", "SRP", "SHA-1", "TripleDES", 24); + return Ciphersuite("RSA", "SRP", "SHA-1", "TripleDES", 24); // SRP/DSA ciphersuites case TLS_SRP_SHA_DSS_WITH_AES_128_SHA: - return TLS_Ciphersuite("DSA", "SRP", "SHA-1", "AES-128", 16); + return Ciphersuite("DSA", "SRP", "SHA-1", "AES-128", 16); case TLS_SRP_SHA_DSS_WITH_AES_256_SHA: - return TLS_Ciphersuite("DSA", "SRP", "SHA-1", "AES-256", 32); + return Ciphersuite("DSA", "SRP", "SHA-1", "AES-256", 32); case TLS_SRP_SHA_DSS_WITH_3DES_EDE_SHA: - return TLS_Ciphersuite("DSA", "SRP", "SHA-1", "TripleDES", 24); + return Ciphersuite("DSA", "SRP", "SHA-1", "TripleDES", 24); // ECDH/ECDSA ciphersuites case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: - return TLS_Ciphersuite("ECDSA", "ECDH", "SHA-1", "AES-128", 16); + return Ciphersuite("ECDSA", "ECDH", "SHA-1", "AES-128", 16); case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: - return TLS_Ciphersuite("ECDSA", "ECDH", "SHA-1", "AES-256", 32); + return Ciphersuite("ECDSA", "ECDH", "SHA-1", "AES-256", 32); case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: - return TLS_Ciphersuite("ECDSA", "ECDH", "SHA-256", "AES-128", 16); + return Ciphersuite("ECDSA", "ECDH", "SHA-256", "AES-128", 16); case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: - return TLS_Ciphersuite("ECDSA", "ECDH", "SHA-384", "AES-256", 32); + return Ciphersuite("ECDSA", "ECDH", "SHA-384", "AES-256", 32); case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: - return TLS_Ciphersuite("ECDSA", "ECDH", "SHA-256", "AES-128", 16); + return Ciphersuite("ECDSA", "ECDH", "SHA-256", "AES-128", 16); case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: - return TLS_Ciphersuite("ECDSA", "ECDH", "SHA-384", "AES-256", 32); + return Ciphersuite("ECDSA", "ECDH", "SHA-384", "AES-256", 32); case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: - return TLS_Ciphersuite("ECDSA", "ECDH", "SHA-1", "ARC4", 16); + return Ciphersuite("ECDSA", "ECDH", "SHA-1", "ARC4", 16); case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: - return TLS_Ciphersuite("ECDSA", "ECDH", "SHA-1", "TripleDES", 24); + return Ciphersuite("ECDSA", "ECDH", "SHA-1", "TripleDES", 24); default: - return TLS_Ciphersuite(); // some unknown ciphersuite + return Ciphersuite(); // some unknown ciphersuite } } -TLS_Ciphersuite::TLS_Ciphersuite(const std::string& sig_algo, +Ciphersuite::Ciphersuite(const std::string& sig_algo, const std::string& kex_algo, const std::string& mac_algo, const std::string& cipher_algo, @@ -166,3 +168,5 @@ TLS_Ciphersuite::TLS_Ciphersuite(const std::string& sig_algo, } } + +} diff --git a/src/tls/tls_suites.h b/src/tls/tls_suites.h index 65203bdf7..1fd975beb 100644 --- a/src/tls/tls_suites.h +++ b/src/tls/tls_suites.h @@ -14,13 +14,15 @@ namespace Botan { +namespace TLS { + /** * Ciphersuite Information */ -class BOTAN_DLL TLS_Ciphersuite +class BOTAN_DLL Ciphersuite { public: - static TLS_Ciphersuite lookup_ciphersuite(u16bit suite); + static Ciphersuite lookup_ciphersuite(u16bit suite); const std::string kex_algo() const { return m_kex_algo; } const std::string sig_algo() const { return m_sig_algo; } @@ -30,9 +32,9 @@ class BOTAN_DLL TLS_Ciphersuite size_t cipher_keylen() const { return m_cipher_keylen; } - TLS_Ciphersuite() : m_cipher_keylen(0) {} + Ciphersuite() : m_cipher_keylen(0) {} - TLS_Ciphersuite(const std::string& sig_algo, + Ciphersuite(const std::string& sig_algo, const std::string& kex_algo, const std::string& mac_algo, const std::string& cipher_algo, @@ -44,4 +46,6 @@ class BOTAN_DLL TLS_Ciphersuite } +} + #endif -- cgit v1.2.3 From fdd56bed26a37177eeccb7df25f2eeae8a324d2b Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 24 Jan 2012 13:52:30 +0000 Subject: Expose the named curve ID/string conversion functions, needed for server key exchange --- src/tls/tls_extensions.cpp | 14 +++++--------- src/tls/tls_extensions.h | 3 +++ 2 files changed, 8 insertions(+), 9 deletions(-) (limited to 'src/tls/tls_extensions.h') diff --git a/src/tls/tls_extensions.cpp b/src/tls/tls_extensions.cpp index 631095c1e..8754405b0 100644 --- a/src/tls/tls_extensions.cpp +++ b/src/tls/tls_extensions.cpp @@ -290,9 +290,7 @@ MemoryVector Next_Protocol_Notification::serialize() const return buf; } -namespace { - -std::string tls_curve_id_to_name(u16bit id) +std::string Supported_Elliptic_Curves::curve_id_to_name(u16bit id) { switch(id) { @@ -323,7 +321,7 @@ std::string tls_curve_id_to_name(u16bit id) } } -u16bit tls_name_to_curve_id(const std::string& name) +u16bit Supported_Elliptic_Curves::name_to_curve_id(const std::string& name) { if(name == "secp160k1") return 15; @@ -348,18 +346,16 @@ u16bit tls_name_to_curve_id(const std::string& name) if(name == "secp521r1") return 25; - throw Invalid_Argument("tls_name_to_curve_id unknown name " + name); + throw Invalid_Argument("name_to_curve_id unknown name " + name); } -} - MemoryVector Supported_Elliptic_Curves::serialize() const { MemoryVector buf(2); for(size_t i = 0; i != m_curves.size(); ++i) { - const u16bit id = tls_name_to_curve_id(m_curves[i]); + const u16bit id = name_to_curve_id(m_curves[i]); buf.push_back(get_byte(0, id)); buf.push_back(get_byte(1, id)); } @@ -401,7 +397,7 @@ Supported_Elliptic_Curves::Supported_Elliptic_Curves(TLS_Data_Reader& reader, for(size_t i = 0; i != len; ++i) { const u16bit id = reader.get_u16bit(); - const std::string name = tls_curve_id_to_name(id); + const std::string name = curve_id_to_name(id); if(name != "") m_curves.push_back(name); diff --git a/src/tls/tls_extensions.h b/src/tls/tls_extensions.h index 7f9321331..cad9ad41c 100644 --- a/src/tls/tls_extensions.h +++ b/src/tls/tls_extensions.h @@ -201,6 +201,9 @@ class Supported_Elliptic_Curves : public Extension Handshake_Extension_Type type() const { return static_type(); } + static std::string curve_id_to_name(u16bit id); + static u16bit name_to_curve_id(const std::string& name); + const std::vector& curves() const { return m_curves; } MemoryVector serialize() const; -- cgit v1.2.3 From 9e37cd76af978147cbb36faa09b9832b5f15f20a Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 24 Jan 2012 15:10:14 +0000 Subject: Send the supported elliptic curves extension. Instead of hardcoding the values let policy specify them. Also choose an ECC curve for server kex from the client hello. Choice is via policy, default implementation is to choose the first curve the client supports out of the server's preference list. --- src/tls/c_hello.cpp | 5 ++++- src/tls/s_hello.cpp | 7 ++++--- src/tls/tls_extensions.cpp | 15 --------------- src/tls/tls_extensions.h | 3 ++- src/tls/tls_messages.h | 5 +++-- src/tls/tls_policy.cpp | 31 +++++++++++++++++++++++++++++++ src/tls/tls_policy.h | 10 ++++++++++ src/tls/tls_server.cpp | 13 ++++++++++++- 8 files changed, 66 insertions(+), 23 deletions(-) (limited to 'src/tls/tls_extensions.h') diff --git a/src/tls/c_hello.cpp b/src/tls/c_hello.cpp index 9e3824c57..7397f9122 100644 --- a/src/tls/c_hello.cpp +++ b/src/tls/c_hello.cpp @@ -99,6 +99,8 @@ Client_Hello::Client_Hello(Record_Writer& writer, std::vector hashes = policy.allowed_hashes(); std::vector sigs = policy.allowed_signature_methods(); + m_supported_curves = policy.allowed_ecc_curves(); + for(size_t i = 0; i != hashes.size(); ++i) for(size_t j = 0; j != sigs.size(); ++j) m_supported_algos.push_back(std::make_pair(hashes[i], sigs[j])); @@ -126,7 +128,7 @@ Client_Hello::Client_Hello(Record_Writer& writer, m_suites.push_back(session.ciphersuite_code()); m_comp_methods.push_back(session.compression_method()); - // set m_supported_algos here? + // set m_supported_algos + m_supported_curves here? send(writer, hash); } @@ -173,6 +175,7 @@ MemoryVector Client_Hello::serialize() const extensions.add(new Renegotation_Extension(m_renegotiation_info)); extensions.add(new Server_Name_Indicator(m_hostname)); extensions.add(new SRP_Identifier(m_srp_identifier)); + extensions.add(new Supported_Elliptic_Curves(m_supported_curves)); if(m_version >= Protocol_Version::TLS_V12) extensions.add(new Signature_Algorithms(m_supported_algos)); diff --git a/src/tls/s_hello.cpp b/src/tls/s_hello.cpp index 10e3a96fa..7b7e4a753 100644 --- a/src/tls/s_hello.cpp +++ b/src/tls/s_hello.cpp @@ -51,9 +51,10 @@ Server_Hello::Server_Hello(Record_Writer& writer, have_dsa = true; } - suite = policy.choose_suite(c_hello.ciphersuites(), - !c_hello.supported_ecc_curves().empty(), - have_rsa, have_dsa, false); + suite = policy.choose_suite( + c_hello.ciphersuites(), + policy.choose_curve(c_hello.supported_ecc_curves()) != "", + have_rsa, have_dsa, false); if(suite == 0) throw TLS_Exception(HANDSHAKE_FAILURE, diff --git a/src/tls/tls_extensions.cpp b/src/tls/tls_extensions.cpp index 8754405b0..20f687514 100644 --- a/src/tls/tls_extensions.cpp +++ b/src/tls/tls_extensions.cpp @@ -366,21 +366,6 @@ MemoryVector Supported_Elliptic_Curves::serialize() const return buf; } -Supported_Elliptic_Curves::Supported_Elliptic_Curves() - { - m_curves.push_back("secp521r1"); - m_curves.push_back("secp384r1"); - m_curves.push_back("secp256r1"); - m_curves.push_back("secp256k1"); - m_curves.push_back("secp224r1"); - m_curves.push_back("secp224k1"); - m_curves.push_back("secp192r1"); - m_curves.push_back("secp192k1"); - m_curves.push_back("secp160r2"); - m_curves.push_back("secp160r1"); - m_curves.push_back("secp160k1"); - } - Supported_Elliptic_Curves::Supported_Elliptic_Curves(TLS_Data_Reader& reader, u16bit extension_size) { diff --git a/src/tls/tls_extensions.h b/src/tls/tls_extensions.h index cad9ad41c..36c41c9a5 100644 --- a/src/tls/tls_extensions.h +++ b/src/tls/tls_extensions.h @@ -208,7 +208,8 @@ class Supported_Elliptic_Curves : public Extension MemoryVector serialize() const; - Supported_Elliptic_Curves(); // default values, for client + Supported_Elliptic_Curves(const std::vector& curves) : + m_curves(curves) {} Supported_Elliptic_Curves(TLS_Data_Reader& reader, u16bit extension_size); diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h index ec2229c21..33cd9e493 100644 --- a/src/tls/tls_messages.h +++ b/src/tls/tls_messages.h @@ -60,10 +60,11 @@ class Client_Hello : public Handshake_Message return v; } - std::vector > supported_algos() const + const std::vector >& supported_algos() const { return m_supported_algos; } - const std::vector supported_ecc_curves() const { return m_supported_curves; } + const std::vector& supported_ecc_curves() const + { return m_supported_curves; } std::vector ciphersuites() const { return m_suites; } std::vector compression_methods() const { return m_comp_methods; } diff --git a/src/tls/tls_policy.cpp b/src/tls/tls_policy.cpp index bdcebab71..c0ce15641 100644 --- a/src/tls/tls_policy.cpp +++ b/src/tls/tls_policy.cpp @@ -56,6 +56,23 @@ std::vector Policy::allowed_signature_methods() const return allowed; } +std::vector Policy::allowed_ecc_curves() const + { + std::vector curves; + curves.push_back("secp521r1"); + curves.push_back("secp384r1"); + curves.push_back("secp256r1"); + curves.push_back("secp256k1"); + curves.push_back("secp224r1"); + curves.push_back("secp224k1"); + curves.push_back("secp192r1"); + curves.push_back("secp192k1"); + curves.push_back("secp160r2"); + curves.push_back("secp160r1"); + curves.push_back("secp160k1"); + return curves; + } + namespace { class Ciphersuite_Preference_Ordering @@ -178,6 +195,20 @@ std::vector Policy::compression() const return algs; } +/* +* Choose an ECC curve to use +*/ +std::string Policy::choose_curve(const std::vector& curve_names) const + { + std::vector our_curves; + + for(size_t i = 0; i != our_curves.size(); ++i) + if(value_exists(curve_names, our_curves[i])) + return our_curves[i]; + + return ""; // no shared curve + } + /* * Choose which ciphersuite to use */ diff --git a/src/tls/tls_policy.h b/src/tls/tls_policy.h index 50793c899..6b7387f46 100644 --- a/src/tls/tls_policy.h +++ b/src/tls/tls_policy.h @@ -53,6 +53,11 @@ class BOTAN_DLL Policy */ virtual std::vector allowed_signature_methods() const; + /** + * Return list of ECC curves we are willing to use in order of preference + */ + virtual std::vector allowed_ecc_curves() const; + /** * Returns a list of signature algorithms we are willing to use, * in order of preference. Allowed values any value of @@ -60,6 +65,11 @@ class BOTAN_DLL Policy */ virtual std::vector compression() const; + /** + * Choose an elliptic curve to use + */ + virtual std::string choose_curve(const std::vector& curve_names) const; + /** * Require support for RFC 5746 extensions to enable * renegotiation. diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp index 47c62a96a..207d40990 100644 --- a/src/tls/tls_server.cpp +++ b/src/tls/tls_server.cpp @@ -265,7 +265,18 @@ void Server::process_handshake_msg(Handshake_Type type, state->kex_priv = new DH_PrivateKey(rng, policy.dh_group()); else if(kex_algo == "ECDH") { - EC_Group ec_group("secp256r1"); // FIXME, use client known groups + const std::vector& curves = + state->client_hello->supported_ecc_curves(); + + if(curves.empty()) + throw Internal_Error("Client sent no ECC extension but we negotiated ECDH"); + + const std::string curve_name = policy.choose_curve(curves); + + if(curve_name == "") // shouldn't happen + throw Internal_Error("Could not agree on an ECC curve with the client"); + + EC_Group ec_group(curve_name); state->kex_priv = new ECDH_PrivateKey(rng, ec_group); } else -- cgit v1.2.3 From cc937eff86e8df7fb4ef0cf849bd37c8b08098e9 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 24 Jan 2012 20:44:59 +0000 Subject: Move extension type here, no need to make it visible to apps --- src/tls/tls_extensions.h | 20 ++++++++++++++++++++ src/tls/tls_magic.h | 20 -------------------- 2 files changed, 20 insertions(+), 20 deletions(-) (limited to 'src/tls/tls_extensions.h') diff --git a/src/tls/tls_extensions.h b/src/tls/tls_extensions.h index 36c41c9a5..180216b8b 100644 --- a/src/tls/tls_extensions.h +++ b/src/tls/tls_extensions.h @@ -20,6 +20,26 @@ namespace TLS { class TLS_Data_Reader; +enum Handshake_Extension_Type { + TLSEXT_SERVER_NAME_INDICATION = 0, + TLSEXT_MAX_FRAGMENT_LENGTH = 1, + TLSEXT_CLIENT_CERT_URL = 2, + TLSEXT_TRUSTED_CA_KEYS = 3, + TLSEXT_TRUNCATED_HMAC = 4, + + TLSEXT_CERTIFICATE_TYPES = 9, + TLSEXT_USABLE_ELLIPTIC_CURVES = 10, + TLSEXT_EC_POINT_FORMATS = 11, + TLSEXT_SRP_IDENTIFIER = 12, + TLSEXT_SIGNATURE_ALGORITHMS = 13, + + TLSEXT_SESSION_TICKET = 35, + + TLSEXT_NEXT_PROTOCOL = 13172, + + TLSEXT_SAFE_RENEGOTIATION = 65281, +}; + /** * Base class representing a TLS extension of some kind */ diff --git a/src/tls/tls_magic.h b/src/tls/tls_magic.h index 05ad4ea9f..c238f1324 100644 --- a/src/tls/tls_magic.h +++ b/src/tls/tls_magic.h @@ -151,26 +151,6 @@ enum Compression_Method { DEFLATE_COMPRESSION = 0x01 }; -enum Handshake_Extension_Type { - TLSEXT_SERVER_NAME_INDICATION = 0, - TLSEXT_MAX_FRAGMENT_LENGTH = 1, - TLSEXT_CLIENT_CERT_URL = 2, - TLSEXT_TRUSTED_CA_KEYS = 3, - TLSEXT_TRUNCATED_HMAC = 4, - - TLSEXT_CERTIFICATE_TYPES = 9, - TLSEXT_USABLE_ELLIPTIC_CURVES = 10, - TLSEXT_EC_POINT_FORMATS = 11, - TLSEXT_SRP_IDENTIFIER = 12, - TLSEXT_SIGNATURE_ALGORITHMS = 13, - - TLSEXT_SESSION_TICKET = 35, - - TLSEXT_NEXT_PROTOCOL = 13172, - - TLSEXT_SAFE_RENEGOTIATION = 65281, -}; - } } -- cgit v1.2.3