diff options
27 files changed, 1171 insertions, 747 deletions
diff --git a/src/cli/tls_utils.cpp b/src/cli/tls_utils.cpp index 81c4fa328..784125de1 100644 --- a/src/cli/tls_utils.cpp +++ b/src/cli/tls_utils.cpp @@ -228,14 +228,14 @@ class TLS_Client_Hello_Reader final : public Command oss << "Supported signature schemes: "; - if(hello.supported_algos().empty()) + if(hello.signature_schemes().empty()) { oss << "Did not send signature_algorithms extension\n"; } else { - for(auto&& hash_and_sig : hello.supported_algos()) - oss << hash_and_sig.second << '+' << hash_and_sig.first << ' '; + for(Botan::TLS::Signature_Scheme scheme : hello.signature_schemes()) + oss << sig_scheme_to_string(scheme) << " "; oss << "\n"; } diff --git a/src/lib/tls/info.txt b/src/lib/tls/info.txt index 68e560f2d..2bda6622f 100644 --- a/src/lib/tls/info.txt +++ b/src/lib/tls/info.txt @@ -7,6 +7,7 @@ load_on auto <header:public> credentials_manager.h tls_alert.h +tls_algos.h tls_blocking.h tls_callbacks.h tls_channel.h diff --git a/src/lib/tls/msg_cert_req.cpp b/src/lib/tls/msg_cert_req.cpp index c6d09481e..90c936978 100644 --- a/src/lib/tls/msg_cert_req.cpp +++ b/src/lib/tls/msg_cert_req.cpp @@ -61,12 +61,7 @@ Certificate_Req::Certificate_Req(Handshake_IO& io, { if(version.supports_negotiable_signature_algorithms()) { - std::vector<std::string> hashes = policy.allowed_signature_hashes(); - std::vector<std::string> 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])); + m_schemes = policy.allowed_signature_schemes(); } hash.update(io.send(*this)); @@ -97,16 +92,14 @@ Certificate_Req::Certificate_Req(const std::vector<uint8_t>& buf, if(version.supports_negotiable_signature_algorithms()) { - std::vector<uint8_t> sig_hash_algs = reader.get_range_vector<uint8_t>(2, 2, 65534); + const std::vector<uint8_t> algs = reader.get_range_vector<uint8_t>(2, 2, 65534); - if(sig_hash_algs.size() % 2 != 0) + if(algs.size() % 2 != 0) throw Decoding_Error("Bad length for signature IDs in certificate request"); - for(size_t i = 0; i != sig_hash_algs.size(); i += 2) + for(size_t i = 0; i != algs.size(); i += 2) { - std::string hash = Signature_Algorithms::hash_algo_name(sig_hash_algs[i]); - std::string sig = Signature_Algorithms::sig_algo_name(sig_hash_algs[i+1]); - m_supported_algos.push_back(std::make_pair(hash, sig)); + m_schemes.push_back(static_cast<Signature_Scheme>(make_uint16(algs[i], algs[i+1]))); } } @@ -140,8 +133,8 @@ std::vector<uint8_t> Certificate_Req::serialize() const append_tls_length_value(buf, cert_types, 1); - if(!m_supported_algos.empty()) - buf += Signature_Algorithms(m_supported_algos).serialize(); + if(m_schemes.size() > 0) + buf += Signature_Algorithms(m_schemes).serialize(); std::vector<uint8_t> encoded_names; diff --git a/src/lib/tls/msg_cert_verify.cpp b/src/lib/tls/msg_cert_verify.cpp index ce7a30374..8ca01043a 100644 --- a/src/lib/tls/msg_cert_verify.cpp +++ b/src/lib/tls/msg_cert_verify.cpp @@ -28,7 +28,7 @@ Certificate_Verify::Certificate_Verify(Handshake_IO& io, BOTAN_ASSERT_NONNULL(priv_key); std::pair<std::string, Signature_Format> format = - state.choose_sig_format(*priv_key, m_hash_algo, m_sig_algo, true, policy); + state.choose_sig_format(*priv_key, m_scheme, true, policy); m_signature = state.callbacks().tls_sign_message(*priv_key, rng, format.first, format.second, @@ -47,8 +47,7 @@ Certificate_Verify::Certificate_Verify(const std::vector<uint8_t>& buf, if(version.supports_negotiable_signature_algorithms()) { - m_hash_algo = Signature_Algorithms::hash_algo_name(reader.get_byte()); - m_sig_algo = Signature_Algorithms::sig_algo_name(reader.get_byte()); + m_scheme = static_cast<Signature_Scheme>(reader.get_uint16_t()); } m_signature = reader.get_range<uint8_t>(2, 0, 65535); @@ -61,10 +60,11 @@ std::vector<uint8_t> Certificate_Verify::serialize() const { std::vector<uint8_t> buf; - if(!m_hash_algo.empty() && !m_sig_algo.empty()) + if(m_scheme != Signature_Scheme::NONE) { - buf.push_back(Signature_Algorithms::hash_algo_code(m_hash_algo)); - buf.push_back(Signature_Algorithms::sig_algo_code(m_sig_algo)); + const uint16_t scheme_code = static_cast<uint16_t>(m_scheme); + buf.push_back(get_byte(0, scheme_code)); + buf.push_back(get_byte(1, scheme_code)); } const uint16_t sig_len = static_cast<uint16_t>(m_signature.size()); @@ -87,8 +87,7 @@ bool Certificate_Verify::verify(const X509_Certificate& cert, policy.check_peer_key_acceptable(*key); std::pair<std::string, Signature_Format> format = - state.parse_sig_format(*key.get(), m_hash_algo, m_sig_algo, - true, policy); + state.parse_sig_format(*key.get(), m_scheme, true, policy); const bool signature_valid = state.callbacks().tls_verify_message(*key, format.first, format.second, diff --git a/src/lib/tls/msg_client_hello.cpp b/src/lib/tls/msg_client_hello.cpp index 68753fa26..158238de2 100644 --- a/src/lib/tls/msg_client_hello.cpp +++ b/src/lib/tls/msg_client_hello.cpp @@ -115,8 +115,7 @@ Client_Hello::Client_Hello(Handshake_IO& io, m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols)); if(m_version.supports_negotiable_signature_algorithms()) - m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(), - policy.allowed_signature_methods())); + m_extensions.add(new Signature_Algorithms(policy.allowed_signature_schemes())); if(m_version.is_datagram_protocol()) m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles())); @@ -138,10 +137,6 @@ Client_Hello::Client_Hello(Handshake_IO& io, m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression())); } - if(m_version.supports_negotiable_signature_algorithms()) - m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(), - policy.allowed_signature_methods())); - cb.tls_modify_extensions(m_extensions, CLIENT); if(policy.send_fallback_scsv(client_settings.protocol_version())) @@ -200,8 +195,7 @@ Client_Hello::Client_Hello(Handshake_IO& io, #endif if(m_version.supports_negotiable_signature_algorithms()) - m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(), - policy.allowed_signature_methods())); + m_extensions.add(new Signature_Algorithms(policy.allowed_signature_schemes())); if(reneg_info.empty() && !next_protocols.empty()) m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols)); @@ -318,19 +312,16 @@ bool Client_Hello::offered_suite(uint16_t ciphersuite) const return false; } -std::vector<std::pair<std::string, std::string>> Client_Hello::supported_algos() const +std::vector<Signature_Scheme> Client_Hello::signature_schemes() const { + std::vector<Signature_Scheme> schemes; + if(Signature_Algorithms* sigs = m_extensions.get<Signature_Algorithms>()) - return sigs->supported_signature_algorthms(); - return std::vector<std::pair<std::string, std::string>>(); - } + { + schemes = sigs->supported_schemes(); + } -std::set<std::string> Client_Hello::supported_sig_algos() const - { - std::set<std::string> sig; - for(auto&& hash_and_sig : supported_algos()) - sig.insert(hash_and_sig.second); - return sig; + return schemes; } std::vector<std::string> Client_Hello::supported_ecc_curves() const diff --git a/src/lib/tls/msg_client_kex.cpp b/src/lib/tls/msg_client_kex.cpp index 0ff99462c..6e767d4d6 100644 --- a/src/lib/tls/msg_client_kex.cpp +++ b/src/lib/tls/msg_client_kex.cpp @@ -42,9 +42,9 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, const std::string& hostname, RandomNumberGenerator& rng) { - const std::string kex_algo = state.ciphersuite().kex_algo(); + const Kex_Algo kex_algo = state.ciphersuite().kex_method(); - if(kex_algo == "PSK") + if(kex_algo == Kex_Algo::PSK) { std::string identity_hint = ""; @@ -72,7 +72,8 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, SymmetricKey psk; - if(kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") + if(kex_algo == Kex_Algo::DHE_PSK || + kex_algo == Kex_Algo::ECDHE_PSK) { std::string identity_hint = reader.get_string(2, 0, 65535); @@ -84,7 +85,8 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, psk = creds.psk("tls-client", hostname, psk_identity); } - if(kex_algo == "DH" || kex_algo == "DHE_PSK") + if(kex_algo == Kex_Algo::DH || + kex_algo == Kex_Algo::DHE_PSK) { const std::vector<uint8_t> modulus = reader.get_range<uint8_t>(2, 1, 65535); const std::vector<uint8_t> generator = reader.get_range<uint8_t>(2, 1, 65535); @@ -96,7 +98,7 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, const std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> dh_result = state.callbacks().tls_dh_agree(modulus, generator, peer_public_value, policy, rng); - if(kex_algo == "DH") + if(kex_algo == Kex_Algo::DH) m_pre_master = dh_result.first; else { @@ -106,7 +108,8 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, append_tls_length_value(m_key_material, dh_result.second, 2); } - else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") + else if(kex_algo == Kex_Algo::ECDH || + kex_algo == Kex_Algo::ECDHE_PSK) { const uint8_t curve_type = reader.get_byte(); @@ -131,7 +134,7 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, state.callbacks().tls_ecdh_agree(curve_name, peer_public_value, policy, rng, state.server_hello()->prefers_compressed_ec_points()); - if(kex_algo == "ECDH") + if(kex_algo == Kex_Algo::ECDH) m_pre_master = ecdh_result.first; else { @@ -142,7 +145,7 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, append_tls_length_value(m_key_material, ecdh_result.second, 1); } #if defined(BOTAN_HAS_SRP6) - else if(kex_algo == "SRP_SHA") + else if(kex_algo == Kex_Algo::SRP_SHA) { const BigInt N = BigInt::decode(reader.get_range<uint8_t>(2, 1, 65535)); const BigInt g = BigInt::decode(reader.get_range<uint8_t>(2, 1, 65535)); @@ -172,7 +175,7 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, #endif #if defined(BOTAN_HAS_CECPQ1) - else if(kex_algo == "CECPQ1") + else if(kex_algo == Kex_Algo::CECPQ1) { const std::vector<uint8_t> cecpq1_offer = reader.get_range<uint8_t>(2, 1, 65535); @@ -188,7 +191,7 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, #endif else { - throw Internal_Error("Client_Key_Exchange: Unknown kex " + kex_algo); + throw Internal_Error("Client_Key_Exchange: Unknown key exchange method was negotiated"); } reader.assert_done(); @@ -197,8 +200,8 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, { // No server key exchange msg better mean RSA kex + RSA key in cert - if(kex_algo != "RSA") - throw Unexpected_Message("No server kex but negotiated kex " + kex_algo); + if(kex_algo != Kex_Algo::STATIC_RSA) + throw Unexpected_Message("No server kex message, but negotiated a key exchange that required it"); if(!server_public_key) throw Internal_Error("No server public key for RSA exchange"); @@ -236,9 +239,9 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector<uint8_t>& contents, const Policy& policy, RandomNumberGenerator& rng) { - const std::string kex_algo = state.ciphersuite().kex_algo(); + const Kex_Algo kex_algo = state.ciphersuite().kex_method(); - if(kex_algo == "RSA") + if(kex_algo == Kex_Algo::STATIC_RSA) { BOTAN_ASSERT(state.server_certs() && !state.server_certs()->cert_chain().empty(), "RSA key exchange negotiated so server sent a certificate"); @@ -283,7 +286,7 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector<uint8_t>& contents, SymmetricKey psk; - if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") + if(key_exchange_is_psk(kex_algo)) { const std::string psk_identity = reader.get_string(2, 0, 65535); @@ -301,14 +304,14 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector<uint8_t>& contents, } } - if(kex_algo == "PSK") + if(kex_algo == Kex_Algo::PSK) { std::vector<uint8_t> zeros(psk.length()); append_tls_length_value(m_pre_master, zeros, 2); append_tls_length_value(m_pre_master, psk.bits_of(), 2); } #if defined(BOTAN_HAS_SRP6) - else if(kex_algo == "SRP_SHA") + else if(kex_algo == Kex_Algo::SRP_SHA) { SRP6_Server_Session& srp = state.server_kex()->server_srp_params(); @@ -316,7 +319,7 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector<uint8_t>& contents, } #endif #if defined(BOTAN_HAS_CECPQ1) - else if(kex_algo == "CECPQ1") + else if(kex_algo == Kex_Algo::CECPQ1) { const CECPQ1_key& cecpq1_offer = state.server_kex()->cecpq1_key(); @@ -328,8 +331,10 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector<uint8_t>& contents, CECPQ1_finish(m_pre_master.data(), cecpq1_offer, cecpq1_accept.data()); } #endif - else if(kex_algo == "DH" || kex_algo == "DHE_PSK" || - kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") + else if(kex_algo == Kex_Algo::DH || + kex_algo == Kex_Algo::DHE_PSK || + kex_algo == Kex_Algo::ECDH || + kex_algo == Kex_Algo::ECDHE_PSK) { const Private_Key& private_key = state.server_kex()->server_kex_key(); @@ -360,7 +365,8 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector<uint8_t>& contents, if(ka_key->algo_name() == "DH") shared_secret = CT::strip_leading_zeros(shared_secret); - if(kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") + if(kex_algo == Kex_Algo::DHE_PSK || + kex_algo == Kex_Algo::ECDHE_PSK) { append_tls_length_value(m_pre_master, shared_secret, 2); append_tls_length_value(m_pre_master, psk.bits_of(), 2); @@ -380,7 +386,7 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector<uint8_t>& contents, } } else - throw Internal_Error("Client_Key_Exchange: Unknown kex type " + kex_algo); + throw Internal_Error("Client_Key_Exchange: Unknown key exchange negotiated"); } } diff --git a/src/lib/tls/msg_server_kex.cpp b/src/lib/tls/msg_server_kex.cpp index 631273eb7..56ff3017f 100644 --- a/src/lib/tls/msg_server_kex.cpp +++ b/src/lib/tls/msg_server_kex.cpp @@ -45,9 +45,9 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io, const Private_Key* signing_key) { const std::string hostname = state.client_hello()->sni_hostname(); - const std::string kex_algo = state.ciphersuite().kex_algo(); + const Kex_Algo kex_algo = state.ciphersuite().kex_method(); - if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") + if(kex_algo == Kex_Algo::PSK || kex_algo == Kex_Algo::DHE_PSK || kex_algo == Kex_Algo::ECDHE_PSK) { std::string identity_hint = creds.psk_identity_hint("tls-server", hostname); @@ -55,7 +55,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io, append_tls_length_value(m_params, identity_hint, 2); } - if(kex_algo == "DH" || kex_algo == "DHE_PSK") + if(kex_algo == Kex_Algo::DH || kex_algo == Kex_Algo::DHE_PSK) { const std::vector<std::string>& dh_groups = state.client_hello()->supported_dh_groups(); @@ -85,7 +85,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io, append_tls_length_value(m_params, dh->public_value(), 2); m_kex_key.reset(dh.release()); } - else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") + else if(kex_algo == Kex_Algo::ECDH || kex_algo == Kex_Algo::ECDHE_PSK) { const std::vector<std::string>& curves = state.client_hello()->supported_ecc_curves(); @@ -135,7 +135,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io, append_tls_length_value(m_params, ecdh_public_val, 1); } #if defined(BOTAN_HAS_SRP6) - else if(kex_algo == "SRP_SHA") + else if(kex_algo == Kex_Algo::SRP_SHA) { const std::string srp_identifier = state.client_hello()->srp_identifier(); @@ -166,7 +166,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io, } #endif #if defined(BOTAN_HAS_CECPQ1) - else if(kex_algo == "CECPQ1") + else if(kex_algo == Kex_Algo::CECPQ1) { std::vector<uint8_t> cecpq1_offer(CECPQ1_OFFER_BYTES); m_cecpq1_key.reset(new CECPQ1_key); @@ -174,17 +174,18 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io, append_tls_length_value(m_params, cecpq1_offer, 2); } #endif - else if(kex_algo != "PSK") + else if(kex_algo != Kex_Algo::PSK) { - throw Internal_Error("Server_Key_Exchange: Unknown kex type " + kex_algo); + throw Internal_Error("Server_Key_Exchange: Unknown kex type " + + kex_method_to_string(kex_algo)); } - if(state.ciphersuite().sig_algo() != "") + if(state.ciphersuite().signature_used()) { BOTAN_ASSERT(signing_key, "Signing key was set"); std::pair<std::string, Signature_Format> format = - state.choose_sig_format(*signing_key, m_hash_algo, m_sig_algo, false, policy); + state.choose_sig_format(*signing_key, m_scheme, false, policy); std::vector<uint8_t> buf = state.client_hello()->random(); @@ -203,8 +204,8 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io, * Deserialize a Server Key Exchange message */ Server_Key_Exchange::Server_Key_Exchange(const std::vector<uint8_t>& buf, - const std::string& kex_algo, - const std::string& sig_algo, + const Kex_Algo kex_algo, + const Auth_Method auth_method, Protocol_Version version) { TLS_Data_Reader reader("ServerKeyExchange", buf); @@ -215,12 +216,12 @@ Server_Key_Exchange::Server_Key_Exchange(const std::vector<uint8_t>& buf, * is prepared. */ - if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") + if(kex_algo == Kex_Algo::PSK || kex_algo == Kex_Algo::DHE_PSK || kex_algo == Kex_Algo::ECDHE_PSK) { reader.get_string(2, 0, 65535); // identity hint } - if(kex_algo == "DH" || kex_algo == "DHE_PSK") + if(kex_algo == Kex_Algo::DH || kex_algo == Kex_Algo::DHE_PSK) { // 3 bigints, DH p, g, Y @@ -229,13 +230,13 @@ Server_Key_Exchange::Server_Key_Exchange(const std::vector<uint8_t>& buf, reader.get_range<uint8_t>(2, 1, 65535); } } - else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") + else if(kex_algo == Kex_Algo::ECDH || kex_algo == Kex_Algo::ECDHE_PSK) { reader.get_byte(); // curve type reader.get_uint16_t(); // curve id reader.get_range<uint8_t>(1, 1, 255); // public key } - else if(kex_algo == "SRP_SHA") + else if(kex_algo == Kex_Algo::SRP_SHA) { // 2 bigints (N,g) then salt, then server B @@ -244,22 +245,22 @@ Server_Key_Exchange::Server_Key_Exchange(const std::vector<uint8_t>& buf, reader.get_range<uint8_t>(1, 1, 255); reader.get_range<uint8_t>(2, 1, 65535); } - else if(kex_algo == "CECPQ1") + else if(kex_algo == Kex_Algo::CECPQ1) { // u16 blob reader.get_range<uint8_t>(2, 1, 65535); } - else if(kex_algo != "PSK") - throw Decoding_Error("Server_Key_Exchange: Unsupported kex type " + kex_algo); + else if(kex_algo != Kex_Algo::PSK) + throw Decoding_Error("Server_Key_Exchange: Unsupported kex type " + + kex_method_to_string(kex_algo)); m_params.assign(buf.data(), buf.data() + reader.read_so_far()); - if(sig_algo != "") + if(auth_method != Auth_Method::ANONYMOUS && auth_method != Auth_Method::IMPLICIT) { if(version.supports_negotiable_signature_algorithms()) { - m_hash_algo = Signature_Algorithms::hash_algo_name(reader.get_byte()); - m_sig_algo = Signature_Algorithms::sig_algo_name(reader.get_byte()); + m_scheme = static_cast<Signature_Scheme>(reader.get_uint16_t()); } m_signature = reader.get_range<uint8_t>(2, 0, 65535); @@ -277,11 +278,11 @@ std::vector<uint8_t> Server_Key_Exchange::serialize() const if(m_signature.size()) { - // This should be an explicit version check - if(m_hash_algo != "" && m_sig_algo != "") + if(m_scheme != Signature_Scheme::NONE) { - buf.push_back(Signature_Algorithms::hash_algo_code(m_hash_algo)); - buf.push_back(Signature_Algorithms::sig_algo_code(m_sig_algo)); + const uint16_t scheme_code = static_cast<uint16_t>(m_scheme); + buf.push_back(get_byte(0, scheme_code)); + buf.push_back(get_byte(1, scheme_code)); } append_tls_length_value(buf, m_signature, 2); @@ -300,8 +301,7 @@ bool Server_Key_Exchange::verify(const Public_Key& server_key, policy.check_peer_key_acceptable(server_key); std::pair<std::string, Signature_Format> format = - state.parse_sig_format(server_key, m_hash_algo, m_sig_algo, - false, policy); + state.parse_sig_format(server_key, m_scheme, false, policy); std::vector<uint8_t> buf = state.client_hello()->random(); diff --git a/src/lib/tls/tls_algos.cpp b/src/lib/tls/tls_algos.cpp new file mode 100644 index 000000000..415d3eb66 --- /dev/null +++ b/src/lib/tls/tls_algos.cpp @@ -0,0 +1,355 @@ +/* +* (C) 2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/tls_algos.h> +#include <botan/exceptn.h> + +namespace Botan { + +namespace TLS { + +std::string kdf_algo_to_string(KDF_Algo algo) + { + switch(algo) + { + case KDF_Algo::SHA_1: + return "SHA-1"; + case KDF_Algo::SHA_256: + return "SHA-256"; + case KDF_Algo::SHA_384: + return "SHA-384"; + } + + throw Invalid_State("kdf_algo_to_string unknown enum value"); + } + +std::string kex_method_to_string(Kex_Algo method) + { + switch(method) + { + case Kex_Algo::STATIC_RSA: + return "RSA"; + case Kex_Algo::DH: + return "DH"; + case Kex_Algo::ECDH: + return "ECDH"; + case Kex_Algo::CECPQ1: + return "CECPQ1"; + case Kex_Algo::SRP_SHA: + return "SRP_SHA"; + case Kex_Algo::PSK: + return "PSK"; + case Kex_Algo::DHE_PSK: + return "DHE_PSK"; + case Kex_Algo::ECDHE_PSK: + return "ECDHE_PSK"; + } + + throw Invalid_State("kex_method_to_string unknown enum value"); + } + +Kex_Algo kex_method_from_string(const std::string& str) + { + if(str == "RSA") + return Kex_Algo::STATIC_RSA; + + if(str == "DH") + return Kex_Algo::DH; + + if(str == "ECDH") + return Kex_Algo::ECDH; + + if(str == "CECPQ1") + return Kex_Algo::CECPQ1; + + if(str == "SRP_SHA") + return Kex_Algo::SRP_SHA; + + if(str == "PSK") + return Kex_Algo::PSK; + + if(str == "DHE_PSK") + return Kex_Algo::DHE_PSK; + + if(str == "ECDHE_PSK") + return Kex_Algo::ECDHE_PSK; + + throw Invalid_Argument("Unknown kex method " + str); + } + +std::string auth_method_to_string(Auth_Method method) + { + switch(method) + { + case Auth_Method::RSA: + return "RSA"; + case Auth_Method::DSA: + return "DSA"; + case Auth_Method::ECDSA: + return "ECDSA"; + case Auth_Method::IMPLICIT: + return "IMPLICIT"; + case Auth_Method::ANONYMOUS: + return "ANONYMOUS"; + } + + throw Invalid_State("auth_method_to_string unknown enum value"); + } + +Auth_Method auth_method_from_string(const std::string& str) + { + if(str == "RSA") + return Auth_Method::RSA; + if(str == "DSA") + return Auth_Method::DSA; + if(str == "ECDSA") + return Auth_Method::ECDSA; + if(str == "ANONYMOUS" || str == "") + return Auth_Method::ANONYMOUS; + + throw Invalid_Argument("Bad signature method " + str); + } + +std::string group_param_to_string(Group_Params group) + { + switch(group) + { + case Group_Params::SECP256R1: + return "secp256r1"; + case Group_Params::SECP384R1: + return "secp384r1"; + case Group_Params::SECP521R1: + return "secp521r1"; + case Group_Params::BRAINPOOL256R1: + return "brainpool256r1"; + case Group_Params::BRAINPOOL384R1: + return "brainpool384r1"; + case Group_Params::BRAINPOOL512R1: + return "brainpool512r1"; + case Group_Params::X25519: + return "x25519"; + + case Group_Params::FFDHE_2048: + return "ffdhe/ietf/2048"; + case Group_Params::FFDHE_3072: + return "ffdhe/ietf/3072"; + case Group_Params::FFDHE_4096: + return "ffdhe/ietf/4096"; + case Group_Params::FFDHE_6144: + return "ffdhe/ietf/6144"; + case Group_Params::FFDHE_8192: + return "ffdhe/ietf/8192"; + +#if defined(BOTAN_HOUSE_ECC_CURVE_NAME) + case BOTAN_HOUSE_ECC_CURVE_TLS_ID: + return BOTAN_HOUSE_ECC_CURVE_NAME; +#endif + + default: + return ""; + } + } + + +std::string hash_function_of_scheme(Signature_Scheme scheme) + { + switch(scheme) + { + case Signature_Scheme::DSA_SHA1: + case Signature_Scheme::ECDSA_SHA1: + case Signature_Scheme::RSA_PKCS1_SHA1: + return "SHA-1"; + + case Signature_Scheme::DSA_SHA256: + case Signature_Scheme::ECDSA_SHA256: + case Signature_Scheme::RSA_PKCS1_SHA256: + case Signature_Scheme::RSA_PSS_SHA256: + return "SHA-256"; + + case Signature_Scheme::DSA_SHA384: + case Signature_Scheme::ECDSA_SHA384: + case Signature_Scheme::RSA_PKCS1_SHA384: + case Signature_Scheme::RSA_PSS_SHA384: + return "SHA-384"; + + case Signature_Scheme::DSA_SHA512: + case Signature_Scheme::ECDSA_SHA512: + case Signature_Scheme::RSA_PKCS1_SHA512: + case Signature_Scheme::RSA_PSS_SHA512: + return "SHA-512"; + + case Signature_Scheme::EDDSA_25519: + case Signature_Scheme::EDDSA_448: + return "Pure"; + + case Signature_Scheme::NONE: + return ""; + } + + throw Invalid_State("Unknown signature algorithm enum"); + } + +const std::vector<Signature_Scheme>& all_signature_schemes() + { + static const std::vector<Signature_Scheme> all_schemes = { + Signature_Scheme::RSA_PKCS1_SHA1, + Signature_Scheme::RSA_PKCS1_SHA256, + Signature_Scheme::RSA_PKCS1_SHA384, + Signature_Scheme::RSA_PKCS1_SHA512, + Signature_Scheme::DSA_SHA1, + Signature_Scheme::DSA_SHA256, + Signature_Scheme::DSA_SHA384, + Signature_Scheme::DSA_SHA512, + Signature_Scheme::ECDSA_SHA1, + Signature_Scheme::ECDSA_SHA256, + Signature_Scheme::ECDSA_SHA384, + Signature_Scheme::ECDSA_SHA512, + Signature_Scheme::RSA_PSS_SHA256, + Signature_Scheme::RSA_PSS_SHA384, + Signature_Scheme::RSA_PSS_SHA512, + Signature_Scheme::EDDSA_25519, + Signature_Scheme::EDDSA_448, + }; + + return all_schemes; + } + +std::string signature_algorithm_of_scheme(Signature_Scheme scheme) + { + switch(scheme) + { + case Signature_Scheme::RSA_PKCS1_SHA1: + case Signature_Scheme::RSA_PKCS1_SHA256: + case Signature_Scheme::RSA_PKCS1_SHA384: + case Signature_Scheme::RSA_PKCS1_SHA512: + case Signature_Scheme::RSA_PSS_SHA256: + case Signature_Scheme::RSA_PSS_SHA384: + case Signature_Scheme::RSA_PSS_SHA512: + return "RSA"; + + case Signature_Scheme::DSA_SHA1: + case Signature_Scheme::DSA_SHA256: + case Signature_Scheme::DSA_SHA384: + case Signature_Scheme::DSA_SHA512: + return "DSA"; + + case Signature_Scheme::ECDSA_SHA1: + case Signature_Scheme::ECDSA_SHA256: + case Signature_Scheme::ECDSA_SHA384: + case Signature_Scheme::ECDSA_SHA512: + return "ECDSA"; + + case Signature_Scheme::EDDSA_25519: + return "Ed25519"; + + case Signature_Scheme::EDDSA_448: + return "Ed448"; + + case Signature_Scheme::NONE: + return ""; + } + + throw Invalid_State("Unknown signature algorithm enum"); + } + +std::string sig_scheme_to_string(Signature_Scheme scheme) + { + switch(scheme) + { + case Signature_Scheme::RSA_PKCS1_SHA1: + return "RSA_PKCS1_SHA1"; + case Signature_Scheme::RSA_PKCS1_SHA256: + return "RSA_PKCS1_SHA256"; + case Signature_Scheme::RSA_PKCS1_SHA384: + return "RSA_PKCS1_SHA384"; + case Signature_Scheme::RSA_PKCS1_SHA512: + return "RSA_PKCS1_SHA512"; + + case Signature_Scheme::DSA_SHA1: + return "DSA_SHA1"; + case Signature_Scheme::DSA_SHA256: + return "DSA_SHA256"; + case Signature_Scheme::DSA_SHA384: + return "DSA_SHA384"; + case Signature_Scheme::DSA_SHA512: + return "DSA_SHA512"; + + case Signature_Scheme::ECDSA_SHA1: + return "ECDSA_SHA1"; + case Signature_Scheme::ECDSA_SHA256: + return "ECDSA_SHA256"; + case Signature_Scheme::ECDSA_SHA384: + return "ECDSA_SHA384"; + case Signature_Scheme::ECDSA_SHA512: + return "ECDSA_SHA512"; + + case Signature_Scheme::RSA_PSS_SHA256: + return "RSA_PSS_SHA256"; + case Signature_Scheme::RSA_PSS_SHA384: + return "RSA_PSS_SHA384"; + case Signature_Scheme::RSA_PSS_SHA512: + return "RSA_PSS_SHA512"; + + case Signature_Scheme::EDDSA_25519: + return "EDDSA_25519"; + case Signature_Scheme::EDDSA_448: + return "EDDSA_448"; + + case Signature_Scheme::NONE: + return ""; + } + + throw Invalid_State("Unknown signature algorithm enum"); + } + +std::string padding_string_for_scheme(Signature_Scheme scheme) + { + switch(scheme) + { + case Signature_Scheme::RSA_PKCS1_SHA1: + return "EMSA_PKCS1(SHA-1)"; + case Signature_Scheme::RSA_PKCS1_SHA256: + return "EMSA_PKCS1(SHA-256)"; + case Signature_Scheme::RSA_PKCS1_SHA384: + return "EMSA_PKCS1(SHA-384)"; + case Signature_Scheme::RSA_PKCS1_SHA512: + return "EMSA_PKCS1(SHA-512)"; + + case Signature_Scheme::DSA_SHA1: + case Signature_Scheme::ECDSA_SHA1: + return "EMSA1(SHA-1)"; + case Signature_Scheme::DSA_SHA256: + case Signature_Scheme::ECDSA_SHA256: + return "EMSA1(SHA-256)"; + case Signature_Scheme::DSA_SHA384: + case Signature_Scheme::ECDSA_SHA384: + return "EMSA1(SHA-384)"; + case Signature_Scheme::DSA_SHA512: + case Signature_Scheme::ECDSA_SHA512: + return "EMSA1(SHA-512)"; + + case Signature_Scheme::RSA_PSS_SHA256: + return "PSSR(SHA-256,MGF1,32)"; + case Signature_Scheme::RSA_PSS_SHA384: + return "PSSR(SHA-384,MGF1,48)"; + case Signature_Scheme::RSA_PSS_SHA512: + return "PSSR(SHA-512,MGF1,64)"; + + case Signature_Scheme::EDDSA_25519: + return "Pure"; + case Signature_Scheme::EDDSA_448: + return "Pure"; + + case Signature_Scheme::NONE: + return ""; + } + + throw Invalid_State("Unknown signature algorithm enum"); + } + +} + +} diff --git a/src/lib/tls/tls_algos.h b/src/lib/tls/tls_algos.h new file mode 100644 index 000000000..b65aad185 --- /dev/null +++ b/src/lib/tls/tls_algos.h @@ -0,0 +1,168 @@ +/* +* (C) 2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_TLS_ALGO_IDS_H_ +#define BOTAN_TLS_ALGO_IDS_H_ + +#include <botan/types.h> +#include <string> +#include <vector> + +namespace Botan { + +namespace TLS { + +enum class Cipher_Algo { + CHACHA20_POLY1305, + + AES_128_CBC_HMAC_SHA1 = 100, + AES_128_CBC_HMAC_SHA256, + AES_128_CCM, + AES_128_CCM_8, + AES_128_GCM, + AES_128_OCB, + + AES_256_CBC_HMAC_SHA1 = 200, + AES_256_CBC_HMAC_SHA256, + AES_256_CBC_HMAC_SHA384, + AES_256_CCM, + AES_256_CCM_8, + AES_256_GCM, + AES_256_OCB, + + CAMELLIA_128_CBC_HMAC_SHA1 = 300, + CAMELLIA_128_CBC_HMAC_SHA256, + CAMELLIA_128_GCM, + + CAMELLIA_256_CBC_HMAC_SHA1 = 400, + CAMELLIA_256_CBC_HMAC_SHA256, + CAMELLIA_256_CBC_HMAC_SHA384, + CAMELLIA_256_GCM, + + ARIA_128_GCM = 500, + ARIA_256_GCM, + + DES_EDE_CBC_HMAC_SHA1 = 1000, + SEED_CBC_HMAC_SHA1, +}; + +enum class KDF_Algo { + SHA_1, + SHA_256, + SHA_384, +}; + +std::string BOTAN_DLL kdf_algo_to_string(KDF_Algo algo); + +enum class Nonce_Format { + CBC_MODE, + AEAD_IMPLICIT_4, + AEAD_XOR_12, +}; + +// TODO encoding should match signature_algorithms extension +// TODO this should include hash etc as in TLS v1.3 +enum class Auth_Method { + RSA, + DSA, + ECDSA, + + // These are placed outside the encodable range + IMPLICIT = 0x10000, + ANONYMOUS +}; + +std::string auth_method_to_string(Auth_Method method); +Auth_Method auth_method_from_string(const std::string& str); + +/* +* This matches the wire encoding +*/ +enum class Signature_Scheme : uint16_t { + NONE = 0x0000, + + RSA_PKCS1_SHA1 = 0x0201, + RSA_PKCS1_SHA256 = 0x0401, + RSA_PKCS1_SHA384 = 0x0501, + RSA_PKCS1_SHA512 = 0x0601, + + DSA_SHA1 = 0x0202, + DSA_SHA256 = 0x0402, + DSA_SHA384 = 0x0502, + DSA_SHA512 = 0x0602, + + ECDSA_SHA1 = 0x0203, + ECDSA_SHA256 = 0x0403, + ECDSA_SHA384 = 0x0503, + ECDSA_SHA512 = 0x0603, + + RSA_PSS_SHA256 = 0x0804, + RSA_PSS_SHA384 = 0x0805, + RSA_PSS_SHA512 = 0x0806, + + EDDSA_25519 = 0x0807, + EDDSA_448 = 0x0808, +}; + +const std::vector<Signature_Scheme>& all_signature_schemes(); + +std::string BOTAN_UNSTABLE_API sig_scheme_to_string(Signature_Scheme scheme); +std::string hash_function_of_scheme(Signature_Scheme scheme); +std::string padding_string_for_scheme(Signature_Scheme scheme); +std::string signature_algorithm_of_scheme(Signature_Scheme scheme); + +/* +* Matches with wire encoding +*/ +enum class Group_Params : uint16_t { + SECP256R1 = 23, + SECP384R1 = 24, + SECP521R1 = 25, + BRAINPOOL256R1 = 26, + BRAINPOOL384R1 = 27, + BRAINPOOL512R1 = 28, + + X25519 = 29, + + FFDHE_2048 = 256, + FFDHE_3072 = 257, + FFDHE_4096 = 258, + FFDHE_6144 = 259, + FFDHE_8192 = 260, + +#if defined(BOTAN_HOUSE_ECC_CURVE_NAME) + HOUSE_CURVE = BOTAN_HOUSE_ECC_CURVE_TLS_ID, +#endif +}; + +std::string group_param_to_string(Group_Params group); + +enum class Kex_Algo { + STATIC_RSA, + DH, + ECDH, + CECPQ1, + SRP_SHA, + PSK, + DHE_PSK, + ECDHE_PSK, +}; + +std::string kex_method_to_string(Kex_Algo method); +Kex_Algo kex_method_from_string(const std::string& str); + +inline bool key_exchange_is_psk(Kex_Algo m) + { + return (m == Kex_Algo::PSK || + m == Kex_Algo::DHE_PSK || + m == Kex_Algo::ECDHE_PSK); + } + +} + +} + +#endif diff --git a/src/lib/tls/tls_ciphersuite.cpp b/src/lib/tls/tls_ciphersuite.cpp index cef6bb3c7..d1a509d78 100644 --- a/src/lib/tls/tls_ciphersuite.cpp +++ b/src/lib/tls/tls_ciphersuite.cpp @@ -16,6 +16,26 @@ namespace Botan { namespace TLS { +size_t Ciphersuite::nonce_bytes_from_handshake() const + { + switch(m_nonce_format) + { + case Nonce_Format::CBC_MODE: + { + if(cipher_algo() == "3DES") + return 8; + else + return 16; + } + case Nonce_Format::AEAD_IMPLICIT_4: + return 4; + case Nonce_Format::AEAD_XOR_12: + return 12; + } + + throw Invalid_State("In Ciphersuite::nonce_bytes_from_handshake invalid enum value"); + } + bool Ciphersuite::is_scsv(uint16_t suite) { // TODO: derive from IANA file in script @@ -24,14 +44,16 @@ bool Ciphersuite::is_scsv(uint16_t suite) bool Ciphersuite::psk_ciphersuite() const { - return (kex_algo() == "PSK" || - kex_algo() == "DHE_PSK" || - kex_algo() == "ECDHE_PSK"); + return kex_method() == Kex_Algo::PSK || + kex_method() == Kex_Algo::DHE_PSK || + kex_method() == Kex_Algo::ECDHE_PSK; } bool Ciphersuite::ecc_ciphersuite() const { - return (sig_algo() == "ECDSA" || kex_algo() == "ECDH" || kex_algo() == "ECDHE_PSK"); + return kex_method() == Kex_Algo::ECDH || + kex_method() == Kex_Algo::ECDHE_PSK || + auth_method() == Auth_Method::ECDSA; } bool Ciphersuite::cbc_ciphersuite() const @@ -39,6 +61,12 @@ bool Ciphersuite::cbc_ciphersuite() const return (mac_algo() != "AEAD"); } +bool Ciphersuite::signature_used() const + { + return auth_method() != Auth_Method::ANONYMOUS && + auth_method() != Auth_Method::IMPLICIT; + } + Ciphersuite Ciphersuite::by_id(uint16_t suite) { const std::vector<Ciphersuite>& all_suites = all_known_ciphersuites(); @@ -122,44 +150,44 @@ bool Ciphersuite::is_usable() const return false; } - if(kex_algo() == "SRP_SHA") + if(kex_method() == Kex_Algo::SRP_SHA) { #if !defined(BOTAN_HAS_SRP6) return false; #endif } - else if(kex_algo() == "ECDH" || kex_algo() == "ECDHE_PSK") + else if(kex_method() == Kex_Algo::ECDH || kex_method() == Kex_Algo::ECDHE_PSK) { #if !defined(BOTAN_HAS_ECDH) return false; #endif } - else if(kex_algo() == "DH" || kex_algo() == "DHE_PSK") + else if(kex_method() == Kex_Algo::DH || kex_method() == Kex_Algo::DHE_PSK) { #if !defined(BOTAN_HAS_DIFFIE_HELLMAN) return false; #endif } - else if(kex_algo() == "CECPQ1") + else if(kex_method() == Kex_Algo::CECPQ1) { #if !defined(BOTAN_HAS_CECPQ1) return false; #endif } - if(sig_algo() == "DSA") + if(auth_method() == Auth_Method::DSA) { #if !defined(BOTAN_HAS_DSA) return false; #endif } - else if(sig_algo() == "ECDSA") + else if(auth_method() == Auth_Method::ECDSA) { #if !defined(BOTAN_HAS_ECDSA) return false; #endif } - else if(sig_algo() == "RSA") + else if(auth_method() == Auth_Method::RSA) { #if !defined(BOTAN_HAS_RSA) return false; diff --git a/src/lib/tls/tls_ciphersuite.h b/src/lib/tls/tls_ciphersuite.h index 6c2836f9d..2ee3df20e 100644 --- a/src/lib/tls/tls_ciphersuite.h +++ b/src/lib/tls/tls_ciphersuite.h @@ -9,6 +9,7 @@ #define BOTAN_TLS_CIPHER_SUITES_H_ #include <botan/types.h> +#include <botan/tls_algos.h> #include <string> #include <vector> @@ -67,15 +68,21 @@ class BOTAN_PUBLIC_API(2,0) Ciphersuite final */ bool cbc_ciphersuite() const; + bool signature_used() const; + /** * @return key exchange algorithm used by this ciphersuite */ - std::string kex_algo() const { return m_kex_algo; } + std::string kex_algo() const { return kex_method_to_string(kex_method()); } + + Kex_Algo kex_method() const { return m_kex_algo; } /** * @return signature algorithm used by this ciphersuite */ - std::string sig_algo() const { return m_sig_algo; } + std::string sig_algo() const { return auth_method_to_string(auth_method()); } + + Auth_Method auth_method() const { return m_auth_method; } /** * @return symmetric cipher algorithm used by this ciphersuite @@ -89,9 +96,7 @@ class BOTAN_PUBLIC_API(2,0) Ciphersuite final std::string prf_algo() const { - if(m_prf_algo && *m_prf_algo) - return m_prf_algo; - return m_mac_algo; + return kdf_algo_to_string(m_prf_algo); } /** @@ -99,9 +104,9 @@ class BOTAN_PUBLIC_API(2,0) Ciphersuite final */ size_t cipher_keylen() const { return m_cipher_keylen; } - size_t nonce_bytes_from_record() const { return m_nonce_bytes_from_record; } + size_t nonce_bytes_from_handshake() const; - size_t nonce_bytes_from_handshake() const { return m_nonce_bytes_from_handshake; } + Nonce_Format nonce_format() const { return m_nonce_format; } size_t mac_keylen() const { return m_mac_keylen; } @@ -121,25 +126,23 @@ class BOTAN_PUBLIC_API(2,0) Ciphersuite final Ciphersuite(uint16_t ciphersuite_code, const char* iana_id, - const char* sig_algo, - const char* kex_algo, + Auth_Method auth_method, + Kex_Algo kex_algo, const char* cipher_algo, size_t cipher_keylen, - size_t nonce_bytes_from_handshake, - size_t nonce_bytes_from_record, const char* mac_algo, size_t mac_keylen, - const char* prf_algo) : + KDF_Algo prf_algo, + Nonce_Format nonce_format) : m_ciphersuite_code(ciphersuite_code), m_iana_id(iana_id), - m_sig_algo(sig_algo), + m_auth_method(auth_method), m_kex_algo(kex_algo), m_prf_algo(prf_algo), + m_nonce_format(nonce_format), m_cipher_algo(cipher_algo), m_mac_algo(mac_algo), m_cipher_keylen(cipher_keylen), - m_nonce_bytes_from_handshake(nonce_bytes_from_handshake), - m_nonce_bytes_from_record(nonce_bytes_from_record), m_mac_keylen(mac_keylen) { m_usable = is_usable(); @@ -153,16 +156,15 @@ class BOTAN_PUBLIC_API(2,0) Ciphersuite final */ const char* m_iana_id = nullptr; - const char* m_sig_algo = nullptr; - const char* m_kex_algo = nullptr; - const char* m_prf_algo = nullptr; + Auth_Method m_auth_method = Auth_Method::ANONYMOUS; + Kex_Algo m_kex_algo = Kex_Algo::STATIC_RSA; + KDF_Algo m_prf_algo = KDF_Algo::SHA_1; + Nonce_Format m_nonce_format = Nonce_Format::CBC_MODE; const char* m_cipher_algo = nullptr; const char* m_mac_algo = nullptr; size_t m_cipher_keylen = 0; - size_t m_nonce_bytes_from_handshake = 0; - size_t m_nonce_bytes_from_record = 0; size_t m_mac_keylen = 0; bool m_usable = false; diff --git a/src/lib/tls/tls_client.cpp b/src/lib/tls/tls_client.cpp index c35149d6b..39e69d8ea 100644 --- a/src/lib/tls/tls_client.cpp +++ b/src/lib/tls/tls_client.cpp @@ -361,11 +361,11 @@ void Client::process_handshake_msg(const Handshake_State* active_state, " is unacceptable by policy"); } - if(state.ciphersuite().sig_algo() != "") + if(state.ciphersuite().signature_used() || state.ciphersuite().kex_method() == Kex_Algo::STATIC_RSA) { state.set_expected_next(CERTIFICATE); } - else if(state.ciphersuite().kex_algo() == "PSK") + else if(state.ciphersuite().kex_method() == Kex_Algo::PSK) { /* PSK is anonymous so no certificate/cert req message is ever sent. The server may or may not send a server kex, @@ -378,7 +378,7 @@ void Client::process_handshake_msg(const Handshake_State* active_state, state.set_expected_next(SERVER_KEX); state.set_expected_next(SERVER_HELLO_DONE); } - else if(state.ciphersuite().kex_algo() != "RSA") + else if(state.ciphersuite().kex_method() != Kex_Algo::STATIC_RSA) { state.set_expected_next(SERVER_KEX); } @@ -408,13 +408,16 @@ void Client::process_handshake_msg(const Handshake_State* active_state, std::unique_ptr<Public_Key> peer_key(server_certs[0].subject_public_key()); - if(peer_key->algo_name() != state.ciphersuite().sig_algo()) + const std::string expected_key_type = + state.ciphersuite().signature_used() ? state.ciphersuite().sig_algo() : "RSA"; + + if(peer_key->algo_name() != expected_key_type) throw TLS_Exception(Alert::ILLEGAL_PARAMETER, "Certificate key type did not match ciphersuite"); state.server_public_key.reset(peer_key.release()); - if(state.ciphersuite().kex_algo() != "RSA") + if(state.ciphersuite().kex_method() != Kex_Algo::STATIC_RSA) { state.set_expected_next(SERVER_KEX); } @@ -451,7 +454,7 @@ void Client::process_handshake_msg(const Handshake_State* active_state, { state.server_cert_status(new Certificate_Status(contents)); - if(state.ciphersuite().kex_algo() != "RSA") + if(state.ciphersuite().kex_method() != Kex_Algo::STATIC_RSA) { state.set_expected_next(SERVER_KEX); } @@ -468,12 +471,12 @@ void Client::process_handshake_msg(const Handshake_State* active_state, state.server_kex( new Server_Key_Exchange(contents, - state.ciphersuite().kex_algo(), - state.ciphersuite().sig_algo(), + state.ciphersuite().kex_method(), + state.ciphersuite().auth_method(), state.version()) ); - if(state.ciphersuite().sig_algo() != "") + if(state.ciphersuite().signature_used()) { const Public_Key& server_key = state.get_server_public_key(); diff --git a/src/lib/tls/tls_extensions.cpp b/src/lib/tls/tls_extensions.cpp index 522cf4a4f..6d69d7b45 100644 --- a/src/lib/tls/tls_extensions.cpp +++ b/src/lib/tls/tls_extensions.cpp @@ -442,16 +442,19 @@ Supported_Groups::Supported_Groups(TLS_Data_Reader& reader, for(size_t i = 0; i != len; ++i) { const uint16_t id = reader.get_uint16_t(); - const std::string name = curve_id_to_name(id); + const Group_Params group_id = static_cast<Group_Params>(id); + + const bool is_dh = (id >= 256 && id <= 511); + const std::string name = group_param_to_string(group_id); if(!name.empty()) { m_groups.push_back(name); - if(is_dh_group(name)) + if(is_dh) { m_dh_groups.push_back(name); } - else + else { m_curves.push_back(name); } @@ -501,137 +504,41 @@ Supported_Point_Formats::Supported_Point_Formats(TLS_Data_Reader& reader, } } -std::string Signature_Algorithms::hash_algo_name(uint8_t code) - { - switch(code) - { - // code 1 is MD5 - ignore it - - case 2: - return "SHA-1"; - - // code 3 is SHA-224 - - case 4: - return "SHA-256"; - case 5: - return "SHA-384"; - case 6: - return "SHA-512"; - default: - return ""; - } - } - -uint8_t Signature_Algorithms::hash_algo_code(const std::string& name) - { - if(name == "SHA-1") - return 2; - - if(name == "SHA-256") - return 4; - - if(name == "SHA-384") - return 5; - - if(name == "SHA-512") - return 6; - - throw Internal_Error("Unknown hash ID " + name + " for signature_algorithms"); - } - -std::string Signature_Algorithms::sig_algo_name(uint8_t code) - { - switch(code) - { - case 1: - return "RSA"; - case 2: - return "DSA"; - case 3: - return "ECDSA"; - default: - return ""; - } - } - -uint8_t Signature_Algorithms::sig_algo_code(const std::string& name) +std::vector<uint8_t> Signature_Algorithms::serialize() const { - if(name == "RSA") - return 1; - - if(name == "DSA") - return 2; + std::vector<uint8_t> buf; - if(name == "ECDSA") - return 3; + const uint16_t len = m_schemes.size() * 2; - throw Internal_Error("Unknown sig ID " + name + " for signature_algorithms"); - } + buf.push_back(get_byte(0, len)); + buf.push_back(get_byte(1, len)); -std::vector<uint8_t> Signature_Algorithms::serialize() const - { - std::vector<uint8_t> buf(2); - - for(size_t i = 0; i != m_supported_algos.size(); ++i) + for(Signature_Scheme scheme : m_schemes) { - try - { - const uint8_t hash_code = hash_algo_code(m_supported_algos[i].first); - const uint8_t sig_code = sig_algo_code(m_supported_algos[i].second); + const uint16_t scheme_code = static_cast<uint16_t>(scheme); - buf.push_back(hash_code); - buf.push_back(sig_code); - } - catch(...) - {} + buf.push_back(get_byte(0, scheme_code)); + buf.push_back(get_byte(1, scheme_code)); } - buf[0] = get_byte(0, static_cast<uint16_t>(buf.size()-2)); - buf[1] = get_byte(1, static_cast<uint16_t>(buf.size()-2)); - return buf; } -Signature_Algorithms::Signature_Algorithms(const std::vector<std::string>& hashes, - const std::vector<std::string>& sigs) - { - 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])); - } - Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, uint16_t extension_size) { uint16_t len = reader.get_uint16_t(); if(len + 2 != extension_size || len % 2 == 1 || len == 0) + { throw Decoding_Error("Bad encoding on signature algorithms extension"); + } while(len) { - const uint8_t hash_code = reader.get_byte(); - const uint8_t sig_code = reader.get_byte(); + const uint16_t scheme_code = reader.get_uint16_t(); + m_schemes.push_back(static_cast<Signature_Scheme>(scheme_code)); len -= 2; - - if(sig_code == 0) - { - /* - RFC 5247 7.4.1.4.1 explicitly prohibits anonymous (0) signature code in - the client hello. ("It MUST NOT appear in this extension.") - */ - throw TLS_Exception(Alert::DECODE_ERROR, "Client sent ANON signature"); - } - - const std::string hash_name = hash_algo_name(hash_code); - const std::string sig_name = sig_algo_name(sig_code); - - // If not something we know, ignore it completely - if(hash_name.empty() || sig_name.empty()) - continue; - - m_supported_algos.push_back(std::make_pair(hash_name, sig_name)); } } diff --git a/src/lib/tls/tls_extensions.h b/src/lib/tls/tls_extensions.h index 5ba3c0b8e..a1ed3f858 100644 --- a/src/lib/tls/tls_extensions.h +++ b/src/lib/tls/tls_extensions.h @@ -10,8 +10,9 @@ #ifndef BOTAN_TLS_EXTENSIONS_H_ #define BOTAN_TLS_EXTENSIONS_H_ +#include <botan/tls_algos.h> #include <botan/secmem.h> -#include <botan/ocsp.h> +#include <botan/x509_dn.h> #include <vector> #include <string> #include <map> @@ -306,33 +307,19 @@ class Signature_Algorithms final : public Extension Handshake_Extension_Type type() const override { return static_type(); } - static std::string hash_algo_name(uint8_t code); - static uint8_t hash_algo_code(const std::string& name); - - static std::string sig_algo_name(uint8_t code); - static uint8_t sig_algo_code(const std::string& name); - - // [(hash,sig),(hash,sig),...] - const std::vector<std::pair<std::string, std::string>>& - supported_signature_algorthms() const - { - return m_supported_algos; - } + const std::vector<Signature_Scheme>& supported_schemes() const { return m_schemes; } std::vector<uint8_t> serialize() const override; - bool empty() const override { return false; } - - Signature_Algorithms(const std::vector<std::string>& hashes, - const std::vector<std::string>& sig_algos); + bool empty() const override { return m_schemes.empty(); } - explicit Signature_Algorithms(const std::vector<std::pair<std::string, std::string>>& algos) : - m_supported_algos(algos) {} + explicit Signature_Algorithms(const std::vector<Signature_Scheme>& schemes) : + m_schemes(schemes) {} Signature_Algorithms(TLS_Data_Reader& reader, uint16_t extension_size); private: - std::vector<std::pair<std::string, std::string>> m_supported_algos; + std::vector<Signature_Scheme> m_schemes; }; /** diff --git a/src/lib/tls/tls_handshake_state.cpp b/src/lib/tls/tls_handshake_state.cpp index 0fcf0d2ab..ab023834b 100644 --- a/src/lib/tls/tls_handshake_state.cpp +++ b/src/lib/tls/tls_handshake_state.cpp @@ -341,7 +341,7 @@ std::string Handshake_State::srp_identifier() const { #if defined(BOTAN_HAS_SRP6) // Authenticated via the successful key exchange - if(ciphersuite().valid() && ciphersuite().kex_algo() == "SRP_SHA") + if(ciphersuite().valid() && ciphersuite().kex_method() == Kex_Algo::SRP_SHA) return client_hello()->srp_identifier(); #endif @@ -373,93 +373,70 @@ KDF* Handshake_State::protocol_specific_prf() const return get_kdf("TLS-PRF"); } -namespace { - -std::string choose_hash(const std::string& sig_algo, - std::vector<std::pair<std::string, std::string>>& supported_algos, - Protocol_Version negotiated_version, - const Policy& policy) +std::pair<std::string, Signature_Format> +Handshake_State::choose_sig_format(const Private_Key& key, + Signature_Scheme& chosen_scheme, + bool for_client_auth, + const Policy& policy) const { - if(!negotiated_version.supports_negotiable_signature_algorithms()) - { - if(sig_algo == "RSA") - return "Parallel(MD5,SHA-160)"; + const std::string sig_algo = key.algo_name(); - if(sig_algo == "DSA") - return "SHA-1"; + if(this->version().supports_negotiable_signature_algorithms()) + { + const std::vector<Signature_Scheme> allowed = policy.allowed_signature_schemes(); - if(sig_algo == "ECDSA") - return "SHA-1"; + std::vector<Signature_Scheme> schemes = + (for_client_auth) ? cert_req()->signature_schemes() : client_hello()->signature_schemes(); - throw Internal_Error("Unknown TLS signature algo " + sig_algo); - } - - if(!supported_algos.empty()) - { - const std::vector<std::string> hashes = policy.allowed_signature_hashes(); + if(schemes.empty()) + { + // Implicit SHA-1 + schemes.push_back(Signature_Scheme::RSA_PKCS1_SHA1); + schemes.push_back(Signature_Scheme::ECDSA_SHA1); + schemes.push_back(Signature_Scheme::DSA_SHA1); + } - /* - * Choose our most preferred hash that the counterparty supports - * in pairing with the signature algorithm we want to use. - */ - for(std::string hash : hashes) + for(Signature_Scheme scheme : schemes) { - for(auto algo : supported_algos) + if(signature_algorithm_of_scheme(scheme) == sig_algo) { - if(algo.first == hash && algo.second == sig_algo) - return hash; + if(std::find(allowed.begin(), allowed.end(), scheme) != allowed.end()) + { + chosen_scheme = scheme; + break; + } } } - } - // TLS v1.2 default hash if the counterparty sent nothing - return "SHA-1"; - } + const std::string hash = hash_function_of_scheme(chosen_scheme); -} - -std::pair<std::string, Signature_Format> -Handshake_State::choose_sig_format(const Private_Key& key, - std::string& hash_algo_out, - std::string& sig_algo_out, - bool for_client_auth, - const Policy& policy) const - { - const std::string sig_algo = key.algo_name(); - - std::vector<std::pair<std::string, std::string>> supported_algos = - (for_client_auth) ? cert_req()->supported_algos() : client_hello()->supported_algos(); - - const std::string hash_algo = choose_hash(sig_algo, - supported_algos, - this->version(), - policy); - - if(this->version().supports_negotiable_signature_algorithms()) - { - // We skip this check for v1.0 since you're stuck with SHA-1 regardless - - if(!policy.allowed_signature_hash(hash_algo)) + if(!policy.allowed_signature_hash(hash)) { throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Policy refuses to accept signing with any hash supported by peer"); } - hash_algo_out = hash_algo; - sig_algo_out = sig_algo; - } - - if(sig_algo == "RSA") - { - const std::string padding = "EMSA3(" + hash_algo + ")"; - - return std::make_pair(padding, IEEE_1363); + if(sig_algo == "RSA") + { + return std::make_pair(padding_string_for_scheme(chosen_scheme), IEEE_1363); + } + else if(sig_algo == "DSA" || sig_algo == "ECDSA") + { + return std::make_pair(padding_string_for_scheme(chosen_scheme), DER_SEQUENCE); + } } - else if(sig_algo == "DSA" || sig_algo == "ECDSA") + else { - const std::string padding = "EMSA1(" + hash_algo + ")"; - - return std::make_pair(padding, DER_SEQUENCE); + if(sig_algo == "RSA") + { + const std::string padding = "EMSA3(Parallel(MD5,SHA-160))"; + return std::make_pair(padding, IEEE_1363); + } + else if(sig_algo == "DSA" || sig_algo == "ECDSA") + { + const std::string padding = "EMSA1(SHA-1)"; + return std::make_pair(padding, DER_SEQUENCE); + } } throw Invalid_Argument(sig_algo + " is invalid/unknown for TLS signatures"); @@ -468,13 +445,14 @@ Handshake_State::choose_sig_format(const Private_Key& key, namespace { bool supported_algos_include( - const std::vector<std::pair<std::string, std::string>>& algos, + const std::vector<Signature_Scheme>& schemes, const std::string& key_type, const std::string& hash_type) { - for(auto&& algo : algos) + for(Signature_Scheme scheme : schemes) { - if(algo.first == hash_type && algo.second == key_type) + if(hash_function_of_scheme(scheme) == hash_type && + signature_algorithm_of_scheme(scheme) == key_type) { return true; } @@ -487,8 +465,7 @@ bool supported_algos_include( std::pair<std::string, Signature_Format> Handshake_State::parse_sig_format(const Public_Key& key, - const std::string& input_hash_algo, - const std::string& input_sig_algo, + Signature_Scheme scheme, bool for_client_auth, const Policy& policy) const { @@ -500,73 +477,67 @@ Handshake_State::parse_sig_format(const Public_Key& key, "Rejecting " + key_type + " signature"); } - std::string hash_algo; - - if(this->version().supports_negotiable_signature_algorithms()) + if(this->version().supports_negotiable_signature_algorithms() == false) { - if(input_sig_algo != key_type) - throw Decoding_Error("Counterparty sent inconsistent key and sig types"); - - if(input_hash_algo == "") - throw Decoding_Error("Counterparty did not send hash/sig IDS"); - - hash_algo = input_hash_algo; - - if(for_client_auth && !cert_req()) - { - throw TLS_Exception(Alert::HANDSHAKE_FAILURE, - "No certificate verify set"); - } + if(scheme != Signature_Scheme::NONE) + throw Decoding_Error("Counterparty sent hash/sig IDs with old version"); /* - Confirm the signature type we just received against the - supported_algos list that we sent; it better be there. + There is no check on the acceptability of a v1.0/v1.1 hash type, + since it's implicit with use of the protocol */ - const auto supported_algos = - for_client_auth ? cert_req()->supported_algos() : - client_hello()->supported_algos(); - - if(!supported_algos_include(supported_algos, key_type, hash_algo)) - { - throw TLS_Exception(Alert::HANDSHAKE_FAILURE, - "TLS signature extension did not allow for " + - key_type + "/" + hash_algo + " signature"); - } - } - else - { - if(input_hash_algo != "" || input_sig_algo != "") - throw Decoding_Error("Counterparty sent hash/sig IDs with old version"); - if(key_type == "RSA") { - hash_algo = "Parallel(MD5,SHA-160)"; + const std::string padding = "EMSA3(Parallel(MD5,SHA-160))"; + return std::make_pair(padding, IEEE_1363); } else if(key_type == "DSA" || key_type == "ECDSA") { - hash_algo = "SHA-1"; + const std::string padding = "EMSA1(SHA-1)"; + return std::make_pair(padding, DER_SEQUENCE); } else - { throw Invalid_Argument(key_type + " is invalid/unknown for TLS signatures"); - } + } - /* - There is no check on the acceptability of a v1.0/v1.1 hash type, - since it's implicit with use of the protocol - */ + if(scheme == Signature_Scheme::NONE) + throw Decoding_Error("Counterparty did not send hash/sig IDS"); + + if(key_type != signature_algorithm_of_scheme(scheme)) + throw Decoding_Error("Counterparty sent inconsistent key and sig types"); + + if(for_client_auth && !cert_req()) + { + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, + "No certificate verify set"); + } + + /* + Confirm the signature type we just received against the + supported_algos list that we sent; it better be there. + */ + + const std::vector<Signature_Scheme> supported_algos = + for_client_auth ? cert_req()->signature_schemes() : + client_hello()->signature_schemes(); + + const std::string hash_algo = hash_function_of_scheme(scheme); + + if(!supported_algos_include(supported_algos, key_type, hash_algo)) + { + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, + "TLS signature extension did not allow for " + + key_type + "/" + hash_algo + " signature"); } if(key_type == "RSA") { - const std::string padding = "EMSA3(" + hash_algo + ")"; - return std::make_pair(padding, IEEE_1363); + return std::make_pair(padding_string_for_scheme(scheme), IEEE_1363); } else if(key_type == "DSA" || key_type == "ECDSA") { - const std::string padding = "EMSA1(" + hash_algo + ")"; - return std::make_pair(padding, DER_SEQUENCE); + return std::make_pair(padding_string_for_scheme(scheme), DER_SEQUENCE); } throw Invalid_Argument(key_type + " is invalid/unknown for TLS signatures"); diff --git a/src/lib/tls/tls_handshake_state.h b/src/lib/tls/tls_handshake_state.h index 437625ced..3321a6210 100644 --- a/src/lib/tls/tls_handshake_state.h +++ b/src/lib/tls/tls_handshake_state.h @@ -83,15 +83,13 @@ class Handshake_State std::pair<std::string, Signature_Format> parse_sig_format(const Public_Key& key, - const std::string& hash_algo, - const std::string& sig_algo, + Signature_Scheme scheme, bool for_client_auth, const Policy& policy) const; std::pair<std::string, Signature_Format> choose_sig_format(const Private_Key& key, - std::string& hash_algo, - std::string& sig_algo, + Signature_Scheme& scheme, bool for_client_auth, const Policy& policy) const; diff --git a/src/lib/tls/tls_messages.h b/src/lib/tls/tls_messages.h index cd06517d7..03b07fe27 100644 --- a/src/lib/tls/tls_messages.h +++ b/src/lib/tls/tls_messages.h @@ -16,6 +16,7 @@ #include <botan/tls_ciphersuite.h> #include <botan/pk_keys.h> #include <botan/x509cert.h> +#include <botan/ocsp.h> #include <vector> #include <string> #include <set> @@ -103,9 +104,7 @@ class BOTAN_UNSTABLE_API Client_Hello final : public Handshake_Message bool sent_fallback_scsv() const; - std::vector<std::pair<std::string, std::string>> supported_algos() const; - - std::set<std::string> supported_sig_algos() const; + std::vector<Signature_Scheme> signature_schemes() const; std::vector<std::string> supported_ecc_curves() const; @@ -414,8 +413,10 @@ class BOTAN_UNSTABLE_API Certificate_Req final : public Handshake_Message const std::vector<X509_DN>& acceptable_CAs() const { return m_names; } - std::vector<std::pair<std::string, std::string> > supported_algos() const - { return m_supported_algos; } + const std::vector<Signature_Scheme>& signature_schemes() const + { + return m_schemes; + } Certificate_Req(Handshake_IO& io, Handshake_Hash& hash, @@ -431,7 +432,7 @@ class BOTAN_UNSTABLE_API Certificate_Req final : public Handshake_Message std::vector<X509_DN> m_names; std::vector<std::string> m_cert_key_types; - std::vector<std::pair<std::string, std::string> > m_supported_algos; + std::vector<Signature_Scheme> m_schemes; }; /** @@ -463,9 +464,8 @@ class BOTAN_UNSTABLE_API Certificate_Verify final : public Handshake_Message private: std::vector<uint8_t> serialize() const override; - std::string m_sig_algo; // sig algo used to create signature - std::string m_hash_algo; // hash used to create signature std::vector<uint8_t> m_signature; + Signature_Scheme m_scheme = Signature_Scheme::NONE; }; /** @@ -550,8 +550,8 @@ class BOTAN_UNSTABLE_API Server_Key_Exchange final : public Handshake_Message const Private_Key* signing_key = nullptr); Server_Key_Exchange(const std::vector<uint8_t>& buf, - const std::string& kex_alg, - const std::string& sig_alg, + Kex_Algo kex_alg, + Auth_Method sig_alg, Protocol_Version version); ~Server_Key_Exchange() = default; @@ -570,9 +570,8 @@ class BOTAN_UNSTABLE_API Server_Key_Exchange final : public Handshake_Message std::vector<uint8_t> m_params; - std::string m_sig_algo; // sig algo used to create signature - std::string m_hash_algo; // hash used to create signature std::vector<uint8_t> m_signature; + Signature_Scheme m_scheme = Signature_Scheme::NONE; }; /** diff --git a/src/lib/tls/tls_policy.cpp b/src/lib/tls/tls_policy.cpp index a46fcee92..2c63aa840 100644 --- a/src/lib/tls/tls_policy.cpp +++ b/src/lib/tls/tls_policy.cpp @@ -20,6 +20,24 @@ namespace Botan { namespace TLS { +std::vector<Signature_Scheme> Policy::allowed_signature_schemes() const + { + std::vector<Signature_Scheme> schemes; + + for(Signature_Scheme scheme : all_signature_schemes()) + { + const bool sig_allowed = allowed_signature_method(signature_algorithm_of_scheme(scheme)); + const bool hash_allowed = allowed_signature_hash(hash_function_of_scheme(scheme)); + + if(sig_allowed && hash_allowed) + { + schemes.push_back(scheme); + } + } + + return schemes; + } + std::vector<std::string> Policy::allowed_ciphers() const { return { @@ -90,7 +108,8 @@ std::vector<std::string> Policy::allowed_signature_methods() const "ECDSA", "RSA", //"DSA", - //"" (anon) + //"IMPLICIT", + //"ANONYMOUS" (anon) }; } @@ -153,6 +172,9 @@ std::string Policy::choose_curve(const std::vector<std::string>& curve_names) co */ std::string Policy::choose_dh_group(const std::vector<std::string>& dh_groups) const { + if(dh_groups.empty()) + return dh_group(); + const std::vector<std::string> our_groups = allowed_groups(); for(size_t i = 0; i != our_groups.size(); ++i) @@ -365,7 +387,7 @@ class Ciphersuite_Preference_Ordering final bool operator()(const Ciphersuite& a, const Ciphersuite& b) const { - if(a.kex_algo() != b.kex_algo()) + if(a.kex_method() != b.kex_method()) { for(size_t i = 0; i != m_kex.size(); ++i) { @@ -395,7 +417,7 @@ class Ciphersuite_Preference_Ordering final return true; } - if(a.sig_algo() != b.sig_algo()) + if(a.auth_method() != b.auth_method()) { for(size_t i = 0; i != m_sigs.size(); ++i) { @@ -446,7 +468,7 @@ std::vector<uint16_t> Policy::ciphersuite_list(Protocol_Version version, continue; // Are we doing SRP? - if(!have_srp && suite.kex_algo() == "SRP_SHA") + if(!have_srp && suite.kex_method() == Kex_Algo::SRP_SHA) continue; if(!version.supports_aead_modes()) @@ -472,7 +494,7 @@ std::vector<uint16_t> Policy::ciphersuite_list(Protocol_Version version, if(!value_exists(sigs, suite.sig_algo())) { // allow if it's an empty sig algo and we want to use PSK - if(suite.sig_algo() != "" || !suite.psk_ciphersuite()) + if(suite.auth_method() != Auth_Method::IMPLICIT || !suite.psk_ciphersuite()) continue; } @@ -481,7 +503,7 @@ std::vector<uint16_t> Policy::ciphersuite_list(Protocol_Version version, removal of x25519 from the ECC curve list as equivalent to saying they do not trust CECPQ1 */ - if(suite.kex_algo() == "CECPQ1" && allowed_ecc_curve("x25519") == false) + if(suite.kex_method() == Kex_Algo::CECPQ1 && allowed_ecc_curve("x25519") == false) continue; // OK, consider it diff --git a/src/lib/tls/tls_policy.h b/src/lib/tls/tls_policy.h index 84da00bfb..a3d175201 100644 --- a/src/lib/tls/tls_policy.h +++ b/src/lib/tls/tls_policy.h @@ -10,6 +10,7 @@ #define BOTAN_TLS_POLICY_H_ #include <botan/tls_version.h> +#include <botan/tls_algos.h> #include <botan/tls_ciphersuite.h> #include <vector> #include <map> @@ -58,6 +59,8 @@ class BOTAN_PUBLIC_API(2,0) Policy */ virtual std::vector<std::string> allowed_signature_methods() const; + virtual std::vector<Signature_Scheme> allowed_signature_schemes() const; + /** * The minimum signature strength we will accept * Returning 80 allows RSA 1024 and SHA-1. Values larger than 80 disable SHA-1 support. diff --git a/src/lib/tls/tls_record.cpp b/src/lib/tls/tls_record.cpp index 996abbfc4..8c86ef3c7 100644 --- a/src/lib/tls/tls_record.cpp +++ b/src/lib/tls/tls_record.cpp @@ -31,9 +31,7 @@ Connection_Cipher_State::Connection_Cipher_State(Protocol_Version version, const Ciphersuite& suite, const Session_Keys& keys, bool uses_encrypt_then_mac) : - m_start_time(std::chrono::system_clock::now()), - m_nonce_bytes_from_handshake(suite.nonce_bytes_from_handshake()), - m_nonce_bytes_from_record(suite.nonce_bytes_from_record()) + m_start_time(std::chrono::system_clock::now()) { SymmetricKey mac_key, cipher_key; InitializationVector iv; @@ -51,27 +49,11 @@ Connection_Cipher_State::Connection_Cipher_State(Protocol_Version version, mac_key = keys.server_mac_key(); } - BOTAN_ASSERT_EQUAL(iv.length(), nonce_bytes_from_handshake(), "Matching nonce sizes"); - m_nonce = unlock(iv.bits_of()); + m_nonce_bytes_from_handshake = m_nonce.size(); + m_nonce_format = suite.nonce_format(); - if(suite.mac_algo() == "AEAD") - { - m_aead.reset(get_aead(suite.cipher_algo(), our_side ? ENCRYPTION : DECRYPTION)); - BOTAN_ASSERT(m_aead, "Have AEAD"); - - m_aead->set_key(cipher_key + mac_key); - - BOTAN_ASSERT(nonce_bytes_from_record() == 0 || nonce_bytes_from_record() == 8, - "Ciphersuite uses implemented IV length"); - - m_cbc_nonce = false; - if(m_nonce.size() != 12) - { - m_nonce.resize(m_nonce.size() + 8); - } - } - else + if(nonce_format() == Nonce_Format::CBC_MODE) { #if defined(BOTAN_HAS_TLS_CBC) // legacy CBC+HMAC mode @@ -98,7 +80,8 @@ Connection_Cipher_State::Connection_Cipher_State(Protocol_Version version, m_aead->set_key(cipher_key + mac_key); - m_cbc_nonce = true; + m_nonce_bytes_from_record = 0; + if(version.supports_explicit_cbc_ivs()) m_nonce_bytes_from_record = m_nonce_bytes_from_handshake; else if(our_side == false) @@ -107,77 +90,89 @@ Connection_Cipher_State::Connection_Cipher_State(Protocol_Version version, throw Exception("Negotiated disabled TLS CBC+HMAC ciphersuite"); #endif } + else + { + m_aead.reset(get_aead(suite.cipher_algo(), our_side ? ENCRYPTION : DECRYPTION)); + BOTAN_ASSERT(m_aead, "Have AEAD"); + + m_aead->set_key(cipher_key + mac_key); + + if(nonce_format() == Nonce_Format::AEAD_IMPLICIT_4) + { + m_nonce_bytes_from_record = 8; + m_nonce.resize(m_nonce.size() + 8); + } + else if(nonce_format() != Nonce_Format::AEAD_XOR_12) + { + throw Invalid_State("Invalid AEAD nonce format used"); + } + } } std::vector<uint8_t> Connection_Cipher_State::aead_nonce(uint64_t seq, RandomNumberGenerator& rng) { - if(m_cbc_nonce) + switch(m_nonce_format) { - if(m_nonce.size()) + case Nonce_Format::CBC_MODE: { - std::vector<uint8_t> nonce; - nonce.swap(m_nonce); + if(m_nonce.size()) + { + std::vector<uint8_t> nonce; + nonce.swap(m_nonce); + return nonce; + } + std::vector<uint8_t> nonce(nonce_bytes_from_record()); + rng.randomize(nonce.data(), nonce.size()); + return nonce; + } + case Nonce_Format::AEAD_XOR_12: + { + std::vector<uint8_t> nonce(12); + store_be(seq, nonce.data() + 4); + xor_buf(nonce, m_nonce.data(), m_nonce.size()); + return nonce; + } + case Nonce_Format::AEAD_IMPLICIT_4: + { + std::vector<uint8_t> nonce = m_nonce; + store_be(seq, &nonce[nonce_bytes_from_handshake()]); return nonce; } - std::vector<uint8_t> nonce(nonce_bytes_from_record()); - rng.randomize(nonce.data(), nonce.size()); - return nonce; - } - else if(nonce_bytes_from_handshake() == 12) - { - std::vector<uint8_t> nonce(12); - store_be(seq, nonce.data() + 4); - xor_buf(nonce, m_nonce.data(), m_nonce.size()); - return nonce; - } - else - { - std::vector<uint8_t> nonce = m_nonce; - store_be(seq, &nonce[nonce_bytes_from_handshake()]); - return nonce; } + + throw Invalid_State("Unknown nonce format specified"); } std::vector<uint8_t> Connection_Cipher_State::aead_nonce(const uint8_t record[], size_t record_len, uint64_t seq) { - if(m_cbc_nonce) - { - if(record_len < nonce_bytes_from_record()) - throw Decoding_Error("Invalid CBC packet too short to be valid"); - std::vector<uint8_t> nonce(record, record + nonce_bytes_from_record()); - return nonce; - } - else if(nonce_bytes_from_handshake() == 12) - { - /* - Assumes if the suite specifies 12 bytes come from the handshake then - use the XOR nonce construction from draft-ietf-tls-chacha20-poly1305 - */ - - std::vector<uint8_t> nonce(12); - store_be(seq, nonce.data() + 4); - xor_buf(nonce, m_nonce.data(), m_nonce.size()); - return nonce; - } - else if(nonce_bytes_from_record() > 0) - { - if(record_len < nonce_bytes_from_record()) - throw Decoding_Error("Invalid AEAD packet too short to be valid"); - std::vector<uint8_t> nonce = m_nonce; - copy_mem(&nonce[nonce_bytes_from_handshake()], record, nonce_bytes_from_record()); - return nonce; - } - else + switch(m_nonce_format) { - /* - nonce_len == 0 is assumed to mean no nonce in the message but - instead the AEAD uses the seq number in network order. - */ - std::vector<uint8_t> nonce = m_nonce; - store_be(seq, &nonce[nonce_bytes_from_handshake()]); - return nonce; + case Nonce_Format::CBC_MODE: + { + if(record_len < nonce_bytes_from_record()) + throw Decoding_Error("Invalid CBC packet too short to be valid"); + std::vector<uint8_t> nonce(record, record + nonce_bytes_from_record()); + return nonce; + } + case Nonce_Format::AEAD_XOR_12: + { + std::vector<uint8_t> nonce(12); + store_be(seq, nonce.data() + 4); + xor_buf(nonce, m_nonce.data(), m_nonce.size()); + return nonce; + } + case Nonce_Format::AEAD_IMPLICIT_4: + { + if(record_len < nonce_bytes_from_record()) + throw Decoding_Error("Invalid AEAD packet too short to be valid"); + std::vector<uint8_t> nonce = m_nonce; + copy_mem(&nonce[nonce_bytes_from_handshake()], record, nonce_bytes_from_record()); + return nonce; + } } + + throw Invalid_State("Unknown nonce format specified"); } std::vector<uint8_t> @@ -251,7 +246,7 @@ void write_record(secure_vector<uint8_t>& output, if(cs->nonce_bytes_from_record() > 0) { - if(cs->cbc_nonce()) + if(cs->nonce_format() == Nonce_Format::CBC_MODE) output += nonce; else output += std::make_pair(&nonce[cs->nonce_bytes_from_handshake()], cs->nonce_bytes_from_record()); diff --git a/src/lib/tls/tls_record.h b/src/lib/tls/tls_record.h index 1fe3a558b..7ccd78b86 100644 --- a/src/lib/tls/tls_record.h +++ b/src/lib/tls/tls_record.h @@ -9,6 +9,7 @@ #ifndef BOTAN_TLS_RECORDS_H_ #define BOTAN_TLS_RECORDS_H_ +#include <botan/tls_algos.h> #include <botan/tls_magic.h> #include <botan/tls_version.h> #include <botan/aead.h> @@ -53,7 +54,8 @@ class Connection_Cipher_State final size_t nonce_bytes_from_handshake() const { return m_nonce_bytes_from_handshake; } size_t nonce_bytes_from_record() const { return m_nonce_bytes_from_record; } - bool cbc_nonce() const { return m_cbc_nonce; } + + Nonce_Format nonce_format() const { return m_nonce_format; } std::chrono::seconds age() const { @@ -66,9 +68,9 @@ class Connection_Cipher_State final std::unique_ptr<AEAD_Mode> m_aead; std::vector<uint8_t> m_nonce; - size_t m_nonce_bytes_from_handshake; - size_t m_nonce_bytes_from_record; - bool m_cbc_nonce; + Nonce_Format m_nonce_format = Nonce_Format::CBC_MODE; + size_t m_nonce_bytes_from_handshake = 0; + size_t m_nonce_bytes_from_record = 0; }; class Record final diff --git a/src/lib/tls/tls_server.cpp b/src/lib/tls/tls_server.cpp index 38c5cf2ca..61a360ba9 100644 --- a/src/lib/tls/tls_server.cpp +++ b/src/lib/tls/tls_server.cpp @@ -177,8 +177,6 @@ uint16_t choose_ciphersuite( if(!our_choice) std::swap(pref_list, other_list); - const std::set<std::string> client_sig_algos = client_hello.supported_sig_algos(); - for(auto suite_id : pref_list) { if(!value_exists(other_list, suite_id)) @@ -187,39 +185,50 @@ uint16_t choose_ciphersuite( const Ciphersuite suite = Ciphersuite::by_id(suite_id); if(suite.valid() == false) + { continue; + } - if(suite.ecc_ciphersuite() && have_shared_ecc_curve == false) + if(have_shared_ecc_curve == false && suite.ecc_ciphersuite()) + { continue; + } // For non-anon ciphersuites - if(suite.sig_algo() != "") + if(suite.signature_used()) { + const std::string sig_algo = suite.sig_algo(); + // Do we have any certificates for this sig? - if(cert_chains.count(suite.sig_algo()) == 0) + if(cert_chains.count(sig_algo) == 0) + { continue; + } - // Client reques - if(!client_sig_algos.empty() && client_sig_algos.count(suite.sig_algo()) == 0) - continue; - } + if(version.supports_negotiable_signature_algorithms()) + { + const std::vector<Signature_Scheme> allowed = + policy.allowed_signature_schemes(); - if(version.supports_negotiable_signature_algorithms() && suite.sig_algo() != "") - { - const std::vector<std::pair<std::string, std::string>> client_sig_hash_pairs = - client_hello.supported_algos(); + std::vector<Signature_Scheme> client_sig_methods = + client_hello.signature_schemes(); - if(client_hello.supported_algos().empty() == false) - { - bool we_support_some_hash_by_client = false; + if(client_sig_methods.empty()) + { + // If empty, then implicit SHA-1 (TLS v1.2 rules) + client_sig_methods.push_back(Signature_Scheme::RSA_PKCS1_SHA1); + client_sig_methods.push_back(Signature_Scheme::ECDSA_SHA1); + client_sig_methods.push_back(Signature_Scheme::DSA_SHA1); + } + + bool we_support_some_hash_by_client = true; - for(auto&& hash_and_sig : client_hello.supported_algos()) + for(Signature_Scheme scheme : client_sig_methods) { - if(hash_and_sig.second == suite.sig_algo() && - policy.allowed_signature_hash(hash_and_sig.first)) + if(signature_algorithm_of_scheme(scheme) == suite.sig_algo() && + policy.allowed_signature_hash(hash_function_of_scheme(scheme))) { we_support_some_hash_by_client = true; - break; } } @@ -229,13 +238,6 @@ uint16_t choose_ciphersuite( "Policy does not accept any hash function supported by client"); } } - else - { - if(policy.allowed_signature_hash("SHA-1") == false) - throw TLS_Exception(Alert::HANDSHAKE_FAILURE, - "Client did not send signature_algorithms extension " - "and policy prohibits SHA-1 fallback"); - } } #if defined(BOTAN_HAS_SRP6) @@ -247,7 +249,7 @@ uint16_t choose_ciphersuite( client hello message. - RFC 5054 section 2.5.1.2 */ - if(suite.kex_algo() == "SRP_SHA" && client_hello.srp_identifier() == "") + if(suite.kex_method() == Kex_Algo::SRP_SHA && client_hello.srp_identifier() == "") throw TLS_Exception(Alert::UNKNOWN_PSK_IDENTITY, "Client wanted SRP but did not send username"); #endif @@ -806,23 +808,22 @@ void Server::session_create(Server_Handshake_State& pending_state, secure_renegotiation_check(pending_state.server_hello()); - const std::string sig_algo = pending_state.ciphersuite().sig_algo(); - const std::string kex_algo = pending_state.ciphersuite().kex_algo(); + const Ciphersuite& pending_suite = pending_state.ciphersuite(); - if(sig_algo != "") + Private_Key* private_key = nullptr; + + if(pending_suite.signature_used() || pending_suite.kex_method() == Kex_Algo::STATIC_RSA) { - BOTAN_ASSERT(!cert_chains[sig_algo].empty(), - "Attempting to send empty certificate chain"); + const std::string algo_used = + pending_suite.signature_used() ? pending_suite.sig_algo() : "RSA"; + + BOTAN_ASSERT(!cert_chains[algo_used].empty(), + "Attempting to send empty certificate chain"); pending_state.server_certs(new Certificate(pending_state.handshake_io(), pending_state.hash(), - cert_chains[sig_algo])); - } + cert_chains[algo_used])); - Private_Key* private_key = nullptr; - - if(kex_algo == "RSA" || sig_algo != "") - { private_key = m_creds.private_key_for( pending_state.server_certs()->cert_chain()[0], "tls-server", @@ -832,7 +833,7 @@ void Server::session_create(Server_Handshake_State& pending_state, throw Internal_Error("No private key located for associated server cert"); } - if(kex_algo == "RSA") + if(pending_suite.kex_method() == Kex_Algo::STATIC_RSA) { pending_state.set_server_rsa_kex_key(private_key); } @@ -853,7 +854,7 @@ void Server::session_create(Server_Handshake_State& pending_state, client_auth_CAs.insert(client_auth_CAs.end(), subjects.begin(), subjects.end()); } - if(!client_auth_CAs.empty() && pending_state.ciphersuite().sig_algo() != "") + if(!client_auth_CAs.empty() && pending_state.ciphersuite().signature_used()) { pending_state.cert_req( new Certificate_Req(pending_state.handshake_io(), diff --git a/src/lib/tls/tls_suite_info.cpp b/src/lib/tls/tls_suite_info.cpp index 90b158457..574b4e5b8 100644 --- a/src/lib/tls/tls_suite_info.cpp +++ b/src/lib/tls/tls_suite_info.cpp @@ -3,7 +3,7 @@ * * This file was automatically generated from the IANA assignments * (tls-parameters.txt hash ac96406c0080f669ca9442b0f5efcb31549ecb2e) -* by ./src/scripts/tls_suite_info.py on 2017-11-03 +* by ./src/scripts/tls_suite_info.py on 2017-11-05 * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -19,192 +19,189 @@ const std::vector<Ciphersuite>& Ciphersuite::all_known_ciphersuites() { // Note that this list of ciphersuites is ordered by id! static const std::vector<Ciphersuite> g_ciphersuite_list = { - Ciphersuite(0x000A, "RSA_WITH_3DES_EDE_CBC_SHA", "RSA", "RSA", "3DES", 24, 8, 0, "SHA-1", 20, ""), - Ciphersuite(0x0013, "DHE_DSS_WITH_3DES_EDE_CBC_SHA", "DSA", "DH", "3DES", 24, 8, 0, "SHA-1", 20, ""), - Ciphersuite(0x0016, "DHE_RSA_WITH_3DES_EDE_CBC_SHA", "RSA", "DH", "3DES", 24, 8, 0, "SHA-1", 20, ""), - Ciphersuite(0x001B, "DH_anon_WITH_3DES_EDE_CBC_SHA", "", "DH", "3DES", 24, 8, 0, "SHA-1", 20, ""), - Ciphersuite(0x002F, "RSA_WITH_AES_128_CBC_SHA", "RSA", "RSA", "AES-128", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x0032, "DHE_DSS_WITH_AES_128_CBC_SHA", "DSA", "DH", "AES-128", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x0033, "DHE_RSA_WITH_AES_128_CBC_SHA", "RSA", "DH", "AES-128", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x0034, "DH_anon_WITH_AES_128_CBC_SHA", "", "DH", "AES-128", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x0035, "RSA_WITH_AES_256_CBC_SHA", "RSA", "RSA", "AES-256", 32, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x0038, "DHE_DSS_WITH_AES_256_CBC_SHA", "DSA", "DH", "AES-256", 32, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x0039, "DHE_RSA_WITH_AES_256_CBC_SHA", "RSA", "DH", "AES-256", 32, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x003A, "DH_anon_WITH_AES_256_CBC_SHA", "", "DH", "AES-256", 32, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x003C, "RSA_WITH_AES_128_CBC_SHA256", "RSA", "RSA", "AES-128", 16, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0x003D, "RSA_WITH_AES_256_CBC_SHA256", "RSA", "RSA", "AES-256", 32, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0x0040, "DHE_DSS_WITH_AES_128_CBC_SHA256", "DSA", "DH", "AES-128", 16, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0x0041, "RSA_WITH_CAMELLIA_128_CBC_SHA", "RSA", "RSA", "Camellia-128", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x0044, "DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", "DSA", "DH", "Camellia-128", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x0045, "DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", "RSA", "DH", "Camellia-128", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x0046, "DH_anon_WITH_CAMELLIA_128_CBC_SHA", "", "DH", "Camellia-128", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x0067, "DHE_RSA_WITH_AES_128_CBC_SHA256", "RSA", "DH", "AES-128", 16, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0x006A, "DHE_DSS_WITH_AES_256_CBC_SHA256", "DSA", "DH", "AES-256", 32, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0x006B, "DHE_RSA_WITH_AES_256_CBC_SHA256", "RSA", "DH", "AES-256", 32, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0x006C, "DH_anon_WITH_AES_128_CBC_SHA256", "", "DH", "AES-128", 16, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0x006D, "DH_anon_WITH_AES_256_CBC_SHA256", "", "DH", "AES-256", 32, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0x0084, "RSA_WITH_CAMELLIA_256_CBC_SHA", "RSA", "RSA", "Camellia-256", 32, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x0087, "DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", "DSA", "DH", "Camellia-256", 32, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x0088, "DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", "RSA", "DH", "Camellia-256", 32, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x0089, "DH_anon_WITH_CAMELLIA_256_CBC_SHA", "", "DH", "Camellia-256", 32, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x008B, "PSK_WITH_3DES_EDE_CBC_SHA", "", "PSK", "3DES", 24, 8, 0, "SHA-1", 20, ""), - Ciphersuite(0x008C, "PSK_WITH_AES_128_CBC_SHA", "", "PSK", "AES-128", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x008D, "PSK_WITH_AES_256_CBC_SHA", "", "PSK", "AES-256", 32, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x008F, "DHE_PSK_WITH_3DES_EDE_CBC_SHA", "", "DHE_PSK", "3DES", 24, 8, 0, "SHA-1", 20, ""), - Ciphersuite(0x0090, "DHE_PSK_WITH_AES_128_CBC_SHA", "", "DHE_PSK", "AES-128", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x0091, "DHE_PSK_WITH_AES_256_CBC_SHA", "", "DHE_PSK", "AES-256", 32, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x0096, "RSA_WITH_SEED_CBC_SHA", "RSA", "RSA", "SEED", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x0099, "DHE_DSS_WITH_SEED_CBC_SHA", "DSA", "DH", "SEED", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x009A, "DHE_RSA_WITH_SEED_CBC_SHA", "RSA", "DH", "SEED", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x009B, "DH_anon_WITH_SEED_CBC_SHA", "", "DH", "SEED", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0x009C, "RSA_WITH_AES_128_GCM_SHA256", "RSA", "RSA", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0x009D, "RSA_WITH_AES_256_GCM_SHA384", "RSA", "RSA", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0x009E, "DHE_RSA_WITH_AES_128_GCM_SHA256", "RSA", "DH", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0x009F, "DHE_RSA_WITH_AES_256_GCM_SHA384", "RSA", "DH", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0x00A2, "DHE_DSS_WITH_AES_128_GCM_SHA256", "DSA", "DH", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0x00A3, "DHE_DSS_WITH_AES_256_GCM_SHA384", "DSA", "DH", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0x00A6, "DH_anon_WITH_AES_128_GCM_SHA256", "", "DH", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0x00A7, "DH_anon_WITH_AES_256_GCM_SHA384", "", "DH", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0x00A8, "PSK_WITH_AES_128_GCM_SHA256", "", "PSK", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0x00A9, "PSK_WITH_AES_256_GCM_SHA384", "", "PSK", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0x00AA, "DHE_PSK_WITH_AES_128_GCM_SHA256", "", "DHE_PSK", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0x00AB, "DHE_PSK_WITH_AES_256_GCM_SHA384", "", "DHE_PSK", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0x00AE, "PSK_WITH_AES_128_CBC_SHA256", "", "PSK", "AES-128", 16, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0x00AF, "PSK_WITH_AES_256_CBC_SHA384", "", "PSK", "AES-256", 32, 16, 0, "SHA-384", 48, ""), - Ciphersuite(0x00B2, "DHE_PSK_WITH_AES_128_CBC_SHA256", "", "DHE_PSK", "AES-128", 16, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0x00B3, "DHE_PSK_WITH_AES_256_CBC_SHA384", "", "DHE_PSK", "AES-256", 32, 16, 0, "SHA-384", 48, ""), - Ciphersuite(0x00BA, "RSA_WITH_CAMELLIA_128_CBC_SHA256", "RSA", "RSA", "Camellia-128", 16, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0x00BD, "DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256", "DSA", "DH", "Camellia-128", 16, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0x00BE, "DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", "RSA", "DH", "Camellia-128", 16, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0x00BF, "DH_anon_WITH_CAMELLIA_128_CBC_SHA256", "", "DH", "Camellia-128", 16, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0x00C0, "RSA_WITH_CAMELLIA_256_CBC_SHA256", "RSA", "RSA", "Camellia-256", 32, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0x00C3, "DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256", "DSA", "DH", "Camellia-256", 32, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0x00C4, "DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", "RSA", "DH", "Camellia-256", 32, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0x00C5, "DH_anon_WITH_CAMELLIA_256_CBC_SHA256", "", "DH", "Camellia-256", 32, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0x16B7, "CECPQ1_RSA_WITH_CHACHA20_POLY1305_SHA256", "RSA", "CECPQ1", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0x16B8, "CECPQ1_ECDSA_WITH_CHACHA20_POLY1305_SHA256", "ECDSA", "CECPQ1", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0x16B9, "CECPQ1_RSA_WITH_AES_256_GCM_SHA384", "RSA", "CECPQ1", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0x16BA, "CECPQ1_ECDSA_WITH_AES_256_GCM_SHA384", "ECDSA", "CECPQ1", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC008, "ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", "ECDSA", "ECDH", "3DES", 24, 8, 0, "SHA-1", 20, ""), - Ciphersuite(0xC009, "ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "ECDSA", "ECDH", "AES-128", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0xC00A, "ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "ECDSA", "ECDH", "AES-256", 32, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0xC012, "ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", "RSA", "ECDH", "3DES", 24, 8, 0, "SHA-1", 20, ""), - Ciphersuite(0xC013, "ECDHE_RSA_WITH_AES_128_CBC_SHA", "RSA", "ECDH", "AES-128", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0xC014, "ECDHE_RSA_WITH_AES_256_CBC_SHA", "RSA", "ECDH", "AES-256", 32, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0xC017, "ECDH_anon_WITH_3DES_EDE_CBC_SHA", "", "ECDH", "3DES", 24, 8, 0, "SHA-1", 20, ""), - Ciphersuite(0xC018, "ECDH_anon_WITH_AES_128_CBC_SHA", "", "ECDH", "AES-128", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0xC019, "ECDH_anon_WITH_AES_256_CBC_SHA", "", "ECDH", "AES-256", 32, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0xC01A, "SRP_SHA_WITH_3DES_EDE_CBC_SHA", "", "SRP_SHA", "3DES", 24, 8, 0, "SHA-1", 20, ""), - Ciphersuite(0xC01B, "SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", "RSA", "SRP_SHA", "3DES", 24, 8, 0, "SHA-1", 20, ""), - Ciphersuite(0xC01C, "SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", "DSA", "SRP_SHA", "3DES", 24, 8, 0, "SHA-1", 20, ""), - Ciphersuite(0xC01D, "SRP_SHA_WITH_AES_128_CBC_SHA", "", "SRP_SHA", "AES-128", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0xC01E, "SRP_SHA_RSA_WITH_AES_128_CBC_SHA", "RSA", "SRP_SHA", "AES-128", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0xC01F, "SRP_SHA_DSS_WITH_AES_128_CBC_SHA", "DSA", "SRP_SHA", "AES-128", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0xC020, "SRP_SHA_WITH_AES_256_CBC_SHA", "", "SRP_SHA", "AES-256", 32, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0xC021, "SRP_SHA_RSA_WITH_AES_256_CBC_SHA", "RSA", "SRP_SHA", "AES-256", 32, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0xC022, "SRP_SHA_DSS_WITH_AES_256_CBC_SHA", "DSA", "SRP_SHA", "AES-256", 32, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0xC023, "ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "ECDSA", "ECDH", "AES-128", 16, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0xC024, "ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "ECDSA", "ECDH", "AES-256", 32, 16, 0, "SHA-384", 48, ""), - Ciphersuite(0xC027, "ECDHE_RSA_WITH_AES_128_CBC_SHA256", "RSA", "ECDH", "AES-128", 16, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0xC028, "ECDHE_RSA_WITH_AES_256_CBC_SHA384", "RSA", "ECDH", "AES-256", 32, 16, 0, "SHA-384", 48, ""), - Ciphersuite(0xC02B, "ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "ECDSA", "ECDH", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC02C, "ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "ECDSA", "ECDH", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC02F, "ECDHE_RSA_WITH_AES_128_GCM_SHA256", "RSA", "ECDH", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC030, "ECDHE_RSA_WITH_AES_256_GCM_SHA384", "RSA", "ECDH", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC034, "ECDHE_PSK_WITH_3DES_EDE_CBC_SHA", "", "ECDHE_PSK", "3DES", 24, 8, 0, "SHA-1", 20, ""), - Ciphersuite(0xC035, "ECDHE_PSK_WITH_AES_128_CBC_SHA", "", "ECDHE_PSK", "AES-128", 16, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0xC036, "ECDHE_PSK_WITH_AES_256_CBC_SHA", "", "ECDHE_PSK", "AES-256", 32, 16, 0, "SHA-1", 20, ""), - Ciphersuite(0xC037, "ECDHE_PSK_WITH_AES_128_CBC_SHA256", "", "ECDHE_PSK", "AES-128", 16, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0xC038, "ECDHE_PSK_WITH_AES_256_CBC_SHA384", "", "ECDHE_PSK", "AES-256", 32, 16, 0, "SHA-384", 48, ""), - Ciphersuite(0xC050, "RSA_WITH_ARIA_128_GCM_SHA256", "RSA", "RSA", "ARIA-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC051, "RSA_WITH_ARIA_256_GCM_SHA384", "RSA", "RSA", "ARIA-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC052, "DHE_RSA_WITH_ARIA_128_GCM_SHA256", "RSA", "DH", "ARIA-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC053, "DHE_RSA_WITH_ARIA_256_GCM_SHA384", "RSA", "DH", "ARIA-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC056, "DHE_DSS_WITH_ARIA_128_GCM_SHA256", "DSA", "DH", "ARIA-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC057, "DHE_DSS_WITH_ARIA_256_GCM_SHA384", "DSA", "DH", "ARIA-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC05A, "DH_anon_WITH_ARIA_128_GCM_SHA256", "", "DH", "ARIA-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC05B, "DH_anon_WITH_ARIA_256_GCM_SHA384", "", "DH", "ARIA-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC05C, "ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256", "ECDSA", "ECDH", "ARIA-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC05D, "ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384", "ECDSA", "ECDH", "ARIA-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC060, "ECDHE_RSA_WITH_ARIA_128_GCM_SHA256", "RSA", "ECDH", "ARIA-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC061, "ECDHE_RSA_WITH_ARIA_256_GCM_SHA384", "RSA", "ECDH", "ARIA-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC06A, "PSK_WITH_ARIA_128_GCM_SHA256", "", "PSK", "ARIA-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC06B, "PSK_WITH_ARIA_256_GCM_SHA384", "", "PSK", "ARIA-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC06C, "DHE_PSK_WITH_ARIA_128_GCM_SHA256", "", "DHE_PSK", "ARIA-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC06D, "DHE_PSK_WITH_ARIA_256_GCM_SHA384", "", "DHE_PSK", "ARIA-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC072, "ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", "ECDSA", "ECDH", "Camellia-128", 16, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0xC073, "ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", "ECDSA", "ECDH", "Camellia-256", 32, 16, 0, "SHA-384", 48, ""), - Ciphersuite(0xC076, "ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", "RSA", "ECDH", "Camellia-128", 16, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0xC077, "ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384", "RSA", "ECDH", "Camellia-256", 32, 16, 0, "SHA-384", 48, ""), - Ciphersuite(0xC07A, "RSA_WITH_CAMELLIA_128_GCM_SHA256", "RSA", "RSA", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC07B, "RSA_WITH_CAMELLIA_256_GCM_SHA384", "RSA", "RSA", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC07C, "DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", "RSA", "DH", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC07D, "DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", "RSA", "DH", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC080, "DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256", "DSA", "DH", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC081, "DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384", "DSA", "DH", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC084, "DH_anon_WITH_CAMELLIA_128_GCM_SHA256", "", "DH", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC085, "DH_anon_WITH_CAMELLIA_256_GCM_SHA384", "", "DH", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC086, "ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", "ECDSA", "ECDH", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC087, "ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", "ECDSA", "ECDH", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC08A, "ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", "RSA", "ECDH", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC08B, "ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", "RSA", "ECDH", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC08E, "PSK_WITH_CAMELLIA_128_GCM_SHA256", "", "PSK", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC08F, "PSK_WITH_CAMELLIA_256_GCM_SHA384", "", "PSK", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC090, "DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256", "", "DHE_PSK", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC091, "DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384", "", "DHE_PSK", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xC094, "PSK_WITH_CAMELLIA_128_CBC_SHA256", "", "PSK", "Camellia-128", 16, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0xC095, "PSK_WITH_CAMELLIA_256_CBC_SHA384", "", "PSK", "Camellia-256", 32, 16, 0, "SHA-384", 48, ""), - Ciphersuite(0xC096, "DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", "", "DHE_PSK", "Camellia-128", 16, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0xC097, "DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", "", "DHE_PSK", "Camellia-256", 32, 16, 0, "SHA-384", 48, ""), - Ciphersuite(0xC09A, "ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", "", "ECDHE_PSK", "Camellia-128", 16, 16, 0, "SHA-256", 32, ""), - Ciphersuite(0xC09B, "ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", "", "ECDHE_PSK", "Camellia-256", 32, 16, 0, "SHA-384", 48, ""), - Ciphersuite(0xC09C, "RSA_WITH_AES_128_CCM", "RSA", "RSA", "AES-128/CCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC09D, "RSA_WITH_AES_256_CCM", "RSA", "RSA", "AES-256/CCM", 32, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC09E, "DHE_RSA_WITH_AES_128_CCM", "RSA", "DH", "AES-128/CCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC09F, "DHE_RSA_WITH_AES_256_CCM", "RSA", "DH", "AES-256/CCM", 32, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC0A0, "RSA_WITH_AES_128_CCM_8", "RSA", "RSA", "AES-128/CCM(8)", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC0A1, "RSA_WITH_AES_256_CCM_8", "RSA", "RSA", "AES-256/CCM(8)", 32, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC0A2, "DHE_RSA_WITH_AES_128_CCM_8", "RSA", "DH", "AES-128/CCM(8)", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC0A3, "DHE_RSA_WITH_AES_256_CCM_8", "RSA", "DH", "AES-256/CCM(8)", 32, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC0A4, "PSK_WITH_AES_128_CCM", "", "PSK", "AES-128/CCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC0A5, "PSK_WITH_AES_256_CCM", "", "PSK", "AES-256/CCM", 32, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC0A6, "DHE_PSK_WITH_AES_128_CCM", "", "DHE_PSK", "AES-128/CCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC0A7, "DHE_PSK_WITH_AES_256_CCM", "", "DHE_PSK", "AES-256/CCM", 32, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC0A8, "PSK_WITH_AES_128_CCM_8", "", "PSK", "AES-128/CCM(8)", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC0A9, "PSK_WITH_AES_256_CCM_8", "", "PSK", "AES-256/CCM(8)", 32, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC0AA, "PSK_DHE_WITH_AES_128_CCM_8", "", "DHE_PSK", "AES-128/CCM(8)", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC0AB, "PSK_DHE_WITH_AES_256_CCM_8", "", "DHE_PSK", "AES-256/CCM(8)", 32, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC0AC, "ECDHE_ECDSA_WITH_AES_128_CCM", "ECDSA", "ECDH", "AES-128/CCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC0AD, "ECDHE_ECDSA_WITH_AES_256_CCM", "ECDSA", "ECDH", "AES-256/CCM", 32, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC0AE, "ECDHE_ECDSA_WITH_AES_128_CCM_8", "ECDSA", "ECDH", "AES-128/CCM(8)", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xC0AF, "ECDHE_ECDSA_WITH_AES_256_CCM_8", "ECDSA", "ECDH", "AES-256/CCM(8)", 32, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xCC13, "ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "RSA", "ECDH", "ChaCha20Poly1305", 32, 0, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xCC14, "ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", "ECDSA", "ECDH", "ChaCha20Poly1305", 32, 0, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xCC15, "DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "RSA", "DH", "ChaCha20Poly1305", 32, 0, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xCCA8, "ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "RSA", "ECDH", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xCCA9, "ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", "ECDSA", "ECDH", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xCCAA, "DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "RSA", "DH", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xCCAB, "PSK_WITH_CHACHA20_POLY1305_SHA256", "", "PSK", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xCCAC, "ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", "", "ECDHE_PSK", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xCCAD, "DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", "", "DHE_PSK", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xD001, "ECDHE_PSK_WITH_AES_128_GCM_SHA256", "", "ECDHE_PSK", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xD002, "ECDHE_PSK_WITH_AES_256_GCM_SHA384", "", "ECDHE_PSK", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"), - Ciphersuite(0xD003, "ECDHE_PSK_WITH_AES_128_CCM_8_SHA256", "", "ECDHE_PSK", "AES-128/CCM(8)", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xD005, "ECDHE_PSK_WITH_AES_128_CCM_SHA256", "", "ECDHE_PSK", "AES-128/CCM", 16, 4, 8, "AEAD", 0, "SHA-256"), - Ciphersuite(0xFFC0, "DHE_RSA_WITH_AES_128_OCB_SHA256", "RSA", "DH", "AES-128/OCB(12)", 16, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xFFC1, "DHE_RSA_WITH_AES_256_OCB_SHA256", "RSA", "DH", "AES-256/OCB(12)", 32, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xFFC2, "ECDHE_RSA_WITH_AES_128_OCB_SHA256", "RSA", "ECDH", "AES-128/OCB(12)", 16, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xFFC3, "ECDHE_RSA_WITH_AES_256_OCB_SHA256", "RSA", "ECDH", "AES-256/OCB(12)", 32, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xFFC4, "ECDHE_ECDSA_WITH_AES_128_OCB_SHA256", "ECDSA", "ECDH", "AES-128/OCB(12)", 16, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xFFC5, "ECDHE_ECDSA_WITH_AES_256_OCB_SHA256", "ECDSA", "ECDH", "AES-256/OCB(12)", 32, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xFFC6, "PSK_WITH_AES_128_OCB_SHA256", "", "PSK", "AES-128/OCB(12)", 16, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xFFC7, "PSK_WITH_AES_256_OCB_SHA256", "", "PSK", "AES-256/OCB(12)", 32, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xFFC8, "DHE_PSK_WITH_AES_128_OCB_SHA256", "", "DHE_PSK", "AES-128/OCB(12)", 16, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xFFC9, "DHE_PSK_WITH_AES_256_OCB_SHA256", "", "DHE_PSK", "AES-256/OCB(12)", 32, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xFFCA, "ECDHE_PSK_WITH_AES_128_OCB_SHA256", "", "ECDHE_PSK", "AES-128/OCB(12)", 16, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xFFCB, "ECDHE_PSK_WITH_AES_256_OCB_SHA256", "", "ECDHE_PSK", "AES-256/OCB(12)", 32, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xFFCC, "CECPQ1_RSA_WITH_AES_256_OCB_SHA256", "RSA", "CECPQ1", "AES-256/OCB(12)", 32, 12, 0, "AEAD", 0, "SHA-256"), - Ciphersuite(0xFFCD, "CECPQ1_ECDSA_WITH_AES_256_OCB_SHA256", "ECDSA", "CECPQ1", "AES-256/OCB(12)", 32, 12, 0, "AEAD", 0, "SHA-256"), + Ciphersuite(0x000A, "RSA_WITH_3DES_EDE_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "3DES", 24, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0013, "DHE_DSS_WITH_3DES_EDE_CBC_SHA", Auth_Method::DSA, Kex_Algo::DH, "3DES", 24, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0016, "DHE_RSA_WITH_3DES_EDE_CBC_SHA", Auth_Method::RSA, Kex_Algo::DH, "3DES", 24, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x001B, "DH_anon_WITH_3DES_EDE_CBC_SHA", Auth_Method::ANONYMOUS, Kex_Algo::DH, "3DES", 24, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x002F, "RSA_WITH_AES_128_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "AES-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0032, "DHE_DSS_WITH_AES_128_CBC_SHA", Auth_Method::DSA, Kex_Algo::DH, "AES-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0033, "DHE_RSA_WITH_AES_128_CBC_SHA", Auth_Method::RSA, Kex_Algo::DH, "AES-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0034, "DH_anon_WITH_AES_128_CBC_SHA", Auth_Method::ANONYMOUS, Kex_Algo::DH, "AES-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0035, "RSA_WITH_AES_256_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0038, "DHE_DSS_WITH_AES_256_CBC_SHA", Auth_Method::DSA, Kex_Algo::DH, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0039, "DHE_RSA_WITH_AES_256_CBC_SHA", Auth_Method::RSA, Kex_Algo::DH, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x003A, "DH_anon_WITH_AES_256_CBC_SHA", Auth_Method::ANONYMOUS, Kex_Algo::DH, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x003C, "RSA_WITH_AES_128_CBC_SHA256", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "AES-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0x003D, "RSA_WITH_AES_256_CBC_SHA256", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "AES-256", 32, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0x0040, "DHE_DSS_WITH_AES_128_CBC_SHA256", Auth_Method::DSA, Kex_Algo::DH, "AES-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0x0041, "RSA_WITH_CAMELLIA_128_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "Camellia-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0044, "DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", Auth_Method::DSA, Kex_Algo::DH, "Camellia-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0045, "DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", Auth_Method::RSA, Kex_Algo::DH, "Camellia-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0046, "DH_anon_WITH_CAMELLIA_128_CBC_SHA", Auth_Method::ANONYMOUS, Kex_Algo::DH, "Camellia-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0067, "DHE_RSA_WITH_AES_128_CBC_SHA256", Auth_Method::RSA, Kex_Algo::DH, "AES-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0x006A, "DHE_DSS_WITH_AES_256_CBC_SHA256", Auth_Method::DSA, Kex_Algo::DH, "AES-256", 32, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0x006B, "DHE_RSA_WITH_AES_256_CBC_SHA256", Auth_Method::RSA, Kex_Algo::DH, "AES-256", 32, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0x006C, "DH_anon_WITH_AES_128_CBC_SHA256", Auth_Method::ANONYMOUS, Kex_Algo::DH, "AES-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0x006D, "DH_anon_WITH_AES_256_CBC_SHA256", Auth_Method::ANONYMOUS, Kex_Algo::DH, "AES-256", 32, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0x0084, "RSA_WITH_CAMELLIA_256_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "Camellia-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0087, "DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", Auth_Method::DSA, Kex_Algo::DH, "Camellia-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0088, "DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", Auth_Method::RSA, Kex_Algo::DH, "Camellia-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0089, "DH_anon_WITH_CAMELLIA_256_CBC_SHA", Auth_Method::ANONYMOUS, Kex_Algo::DH, "Camellia-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x008B, "PSK_WITH_3DES_EDE_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::PSK, "3DES", 24, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x008C, "PSK_WITH_AES_128_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::PSK, "AES-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x008D, "PSK_WITH_AES_256_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::PSK, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x008F, "DHE_PSK_WITH_3DES_EDE_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "3DES", 24, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0090, "DHE_PSK_WITH_AES_128_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "AES-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0091, "DHE_PSK_WITH_AES_256_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0096, "RSA_WITH_SEED_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "SEED", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x0099, "DHE_DSS_WITH_SEED_CBC_SHA", Auth_Method::DSA, Kex_Algo::DH, "SEED", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x009A, "DHE_RSA_WITH_SEED_CBC_SHA", Auth_Method::RSA, Kex_Algo::DH, "SEED", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x009B, "DH_anon_WITH_SEED_CBC_SHA", Auth_Method::ANONYMOUS, Kex_Algo::DH, "SEED", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0x009C, "RSA_WITH_AES_128_GCM_SHA256", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "AES-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0x009D, "RSA_WITH_AES_256_GCM_SHA384", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "AES-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0x009E, "DHE_RSA_WITH_AES_128_GCM_SHA256", Auth_Method::RSA, Kex_Algo::DH, "AES-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0x009F, "DHE_RSA_WITH_AES_256_GCM_SHA384", Auth_Method::RSA, Kex_Algo::DH, "AES-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0x00A2, "DHE_DSS_WITH_AES_128_GCM_SHA256", Auth_Method::DSA, Kex_Algo::DH, "AES-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0x00A3, "DHE_DSS_WITH_AES_256_GCM_SHA384", Auth_Method::DSA, Kex_Algo::DH, "AES-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0x00A6, "DH_anon_WITH_AES_128_GCM_SHA256", Auth_Method::ANONYMOUS, Kex_Algo::DH, "AES-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0x00A7, "DH_anon_WITH_AES_256_GCM_SHA384", Auth_Method::ANONYMOUS, Kex_Algo::DH, "AES-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0x00A8, "PSK_WITH_AES_128_GCM_SHA256", Auth_Method::IMPLICIT, Kex_Algo::PSK, "AES-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0x00A9, "PSK_WITH_AES_256_GCM_SHA384", Auth_Method::IMPLICIT, Kex_Algo::PSK, "AES-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0x00AA, "DHE_PSK_WITH_AES_128_GCM_SHA256", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "AES-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0x00AB, "DHE_PSK_WITH_AES_256_GCM_SHA384", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "AES-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0x00AE, "PSK_WITH_AES_128_CBC_SHA256", Auth_Method::IMPLICIT, Kex_Algo::PSK, "AES-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0x00AF, "PSK_WITH_AES_256_CBC_SHA384", Auth_Method::IMPLICIT, Kex_Algo::PSK, "AES-256", 32, "SHA-384", 48, KDF_Algo::SHA_384, Nonce_Format::CBC_MODE), + Ciphersuite(0x00B2, "DHE_PSK_WITH_AES_128_CBC_SHA256", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "AES-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0x00B3, "DHE_PSK_WITH_AES_256_CBC_SHA384", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "AES-256", 32, "SHA-384", 48, KDF_Algo::SHA_384, Nonce_Format::CBC_MODE), + Ciphersuite(0x00BA, "RSA_WITH_CAMELLIA_128_CBC_SHA256", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "Camellia-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0x00BD, "DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256", Auth_Method::DSA, Kex_Algo::DH, "Camellia-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0x00BE, "DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", Auth_Method::RSA, Kex_Algo::DH, "Camellia-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0x00BF, "DH_anon_WITH_CAMELLIA_128_CBC_SHA256", Auth_Method::ANONYMOUS, Kex_Algo::DH, "Camellia-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0x00C0, "RSA_WITH_CAMELLIA_256_CBC_SHA256", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "Camellia-256", 32, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0x00C3, "DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256", Auth_Method::DSA, Kex_Algo::DH, "Camellia-256", 32, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0x00C4, "DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", Auth_Method::RSA, Kex_Algo::DH, "Camellia-256", 32, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0x00C5, "DH_anon_WITH_CAMELLIA_256_CBC_SHA256", Auth_Method::ANONYMOUS, Kex_Algo::DH, "Camellia-256", 32, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0x16B7, "CECPQ1_RSA_WITH_CHACHA20_POLY1305_SHA256", Auth_Method::RSA, Kex_Algo::CECPQ1, "ChaCha20Poly1305", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0x16B8, "CECPQ1_ECDSA_WITH_CHACHA20_POLY1305_SHA256", Auth_Method::ECDSA, Kex_Algo::CECPQ1, "ChaCha20Poly1305", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0x16B9, "CECPQ1_RSA_WITH_AES_256_GCM_SHA384", Auth_Method::RSA, Kex_Algo::CECPQ1, "AES-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0x16BA, "CECPQ1_ECDSA_WITH_AES_256_GCM_SHA384", Auth_Method::ECDSA, Kex_Algo::CECPQ1, "AES-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC008, "ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", Auth_Method::ECDSA, Kex_Algo::ECDH, "3DES", 24, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC009, "ECDHE_ECDSA_WITH_AES_128_CBC_SHA", Auth_Method::ECDSA, Kex_Algo::ECDH, "AES-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC00A, "ECDHE_ECDSA_WITH_AES_256_CBC_SHA", Auth_Method::ECDSA, Kex_Algo::ECDH, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC012, "ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", Auth_Method::RSA, Kex_Algo::ECDH, "3DES", 24, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC013, "ECDHE_RSA_WITH_AES_128_CBC_SHA", Auth_Method::RSA, Kex_Algo::ECDH, "AES-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC014, "ECDHE_RSA_WITH_AES_256_CBC_SHA", Auth_Method::RSA, Kex_Algo::ECDH, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC017, "ECDH_anon_WITH_3DES_EDE_CBC_SHA", Auth_Method::ANONYMOUS, Kex_Algo::ECDH, "3DES", 24, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC018, "ECDH_anon_WITH_AES_128_CBC_SHA", Auth_Method::ANONYMOUS, Kex_Algo::ECDH, "AES-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC019, "ECDH_anon_WITH_AES_256_CBC_SHA", Auth_Method::ANONYMOUS, Kex_Algo::ECDH, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC01A, "SRP_SHA_WITH_3DES_EDE_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::SRP_SHA, "3DES", 24, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC01B, "SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", Auth_Method::RSA, Kex_Algo::SRP_SHA, "3DES", 24, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC01C, "SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", Auth_Method::DSA, Kex_Algo::SRP_SHA, "3DES", 24, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC01D, "SRP_SHA_WITH_AES_128_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::SRP_SHA, "AES-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC01E, "SRP_SHA_RSA_WITH_AES_128_CBC_SHA", Auth_Method::RSA, Kex_Algo::SRP_SHA, "AES-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC01F, "SRP_SHA_DSS_WITH_AES_128_CBC_SHA", Auth_Method::DSA, Kex_Algo::SRP_SHA, "AES-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC020, "SRP_SHA_WITH_AES_256_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::SRP_SHA, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC021, "SRP_SHA_RSA_WITH_AES_256_CBC_SHA", Auth_Method::RSA, Kex_Algo::SRP_SHA, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC022, "SRP_SHA_DSS_WITH_AES_256_CBC_SHA", Auth_Method::DSA, Kex_Algo::SRP_SHA, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC023, "ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", Auth_Method::ECDSA, Kex_Algo::ECDH, "AES-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0xC024, "ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", Auth_Method::ECDSA, Kex_Algo::ECDH, "AES-256", 32, "SHA-384", 48, KDF_Algo::SHA_384, Nonce_Format::CBC_MODE), + Ciphersuite(0xC027, "ECDHE_RSA_WITH_AES_128_CBC_SHA256", Auth_Method::RSA, Kex_Algo::ECDH, "AES-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0xC028, "ECDHE_RSA_WITH_AES_256_CBC_SHA384", Auth_Method::RSA, Kex_Algo::ECDH, "AES-256", 32, "SHA-384", 48, KDF_Algo::SHA_384, Nonce_Format::CBC_MODE), + Ciphersuite(0xC02B, "ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", Auth_Method::ECDSA, Kex_Algo::ECDH, "AES-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC02C, "ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", Auth_Method::ECDSA, Kex_Algo::ECDH, "AES-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC02F, "ECDHE_RSA_WITH_AES_128_GCM_SHA256", Auth_Method::RSA, Kex_Algo::ECDH, "AES-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC030, "ECDHE_RSA_WITH_AES_256_GCM_SHA384", Auth_Method::RSA, Kex_Algo::ECDH, "AES-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC034, "ECDHE_PSK_WITH_3DES_EDE_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::ECDHE_PSK, "3DES", 24, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC035, "ECDHE_PSK_WITH_AES_128_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::ECDHE_PSK, "AES-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC036, "ECDHE_PSK_WITH_AES_256_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::ECDHE_PSK, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), + Ciphersuite(0xC037, "ECDHE_PSK_WITH_AES_128_CBC_SHA256", Auth_Method::IMPLICIT, Kex_Algo::ECDHE_PSK, "AES-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0xC038, "ECDHE_PSK_WITH_AES_256_CBC_SHA384", Auth_Method::IMPLICIT, Kex_Algo::ECDHE_PSK, "AES-256", 32, "SHA-384", 48, KDF_Algo::SHA_384, Nonce_Format::CBC_MODE), + Ciphersuite(0xC050, "RSA_WITH_ARIA_128_GCM_SHA256", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "ARIA-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC051, "RSA_WITH_ARIA_256_GCM_SHA384", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "ARIA-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC052, "DHE_RSA_WITH_ARIA_128_GCM_SHA256", Auth_Method::RSA, Kex_Algo::DH, "ARIA-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC053, "DHE_RSA_WITH_ARIA_256_GCM_SHA384", Auth_Method::RSA, Kex_Algo::DH, "ARIA-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC056, "DHE_DSS_WITH_ARIA_128_GCM_SHA256", Auth_Method::DSA, Kex_Algo::DH, "ARIA-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC057, "DHE_DSS_WITH_ARIA_256_GCM_SHA384", Auth_Method::DSA, Kex_Algo::DH, "ARIA-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC05A, "DH_anon_WITH_ARIA_128_GCM_SHA256", Auth_Method::ANONYMOUS, Kex_Algo::DH, "ARIA-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC05B, "DH_anon_WITH_ARIA_256_GCM_SHA384", Auth_Method::ANONYMOUS, Kex_Algo::DH, "ARIA-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC05C, "ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256", Auth_Method::ECDSA, Kex_Algo::ECDH, "ARIA-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC05D, "ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384", Auth_Method::ECDSA, Kex_Algo::ECDH, "ARIA-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC060, "ECDHE_RSA_WITH_ARIA_128_GCM_SHA256", Auth_Method::RSA, Kex_Algo::ECDH, "ARIA-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC061, "ECDHE_RSA_WITH_ARIA_256_GCM_SHA384", Auth_Method::RSA, Kex_Algo::ECDH, "ARIA-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC06A, "PSK_WITH_ARIA_128_GCM_SHA256", Auth_Method::IMPLICIT, Kex_Algo::PSK, "ARIA-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC06B, "PSK_WITH_ARIA_256_GCM_SHA384", Auth_Method::IMPLICIT, Kex_Algo::PSK, "ARIA-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC06C, "DHE_PSK_WITH_ARIA_128_GCM_SHA256", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "ARIA-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC06D, "DHE_PSK_WITH_ARIA_256_GCM_SHA384", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "ARIA-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC072, "ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", Auth_Method::ECDSA, Kex_Algo::ECDH, "Camellia-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0xC073, "ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", Auth_Method::ECDSA, Kex_Algo::ECDH, "Camellia-256", 32, "SHA-384", 48, KDF_Algo::SHA_384, Nonce_Format::CBC_MODE), + Ciphersuite(0xC076, "ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", Auth_Method::RSA, Kex_Algo::ECDH, "Camellia-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0xC077, "ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384", Auth_Method::RSA, Kex_Algo::ECDH, "Camellia-256", 32, "SHA-384", 48, KDF_Algo::SHA_384, Nonce_Format::CBC_MODE), + Ciphersuite(0xC07A, "RSA_WITH_CAMELLIA_128_GCM_SHA256", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "Camellia-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC07B, "RSA_WITH_CAMELLIA_256_GCM_SHA384", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "Camellia-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC07C, "DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", Auth_Method::RSA, Kex_Algo::DH, "Camellia-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC07D, "DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", Auth_Method::RSA, Kex_Algo::DH, "Camellia-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC080, "DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256", Auth_Method::DSA, Kex_Algo::DH, "Camellia-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC081, "DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384", Auth_Method::DSA, Kex_Algo::DH, "Camellia-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC084, "DH_anon_WITH_CAMELLIA_128_GCM_SHA256", Auth_Method::ANONYMOUS, Kex_Algo::DH, "Camellia-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC085, "DH_anon_WITH_CAMELLIA_256_GCM_SHA384", Auth_Method::ANONYMOUS, Kex_Algo::DH, "Camellia-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC086, "ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", Auth_Method::ECDSA, Kex_Algo::ECDH, "Camellia-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC087, "ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", Auth_Method::ECDSA, Kex_Algo::ECDH, "Camellia-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC08A, "ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", Auth_Method::RSA, Kex_Algo::ECDH, "Camellia-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC08B, "ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", Auth_Method::RSA, Kex_Algo::ECDH, "Camellia-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC08E, "PSK_WITH_CAMELLIA_128_GCM_SHA256", Auth_Method::IMPLICIT, Kex_Algo::PSK, "Camellia-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC08F, "PSK_WITH_CAMELLIA_256_GCM_SHA384", Auth_Method::IMPLICIT, Kex_Algo::PSK, "Camellia-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC090, "DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "Camellia-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC091, "DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "Camellia-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC094, "PSK_WITH_CAMELLIA_128_CBC_SHA256", Auth_Method::IMPLICIT, Kex_Algo::PSK, "Camellia-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0xC095, "PSK_WITH_CAMELLIA_256_CBC_SHA384", Auth_Method::IMPLICIT, Kex_Algo::PSK, "Camellia-256", 32, "SHA-384", 48, KDF_Algo::SHA_384, Nonce_Format::CBC_MODE), + Ciphersuite(0xC096, "DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "Camellia-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0xC097, "DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "Camellia-256", 32, "SHA-384", 48, KDF_Algo::SHA_384, Nonce_Format::CBC_MODE), + Ciphersuite(0xC09A, "ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", Auth_Method::IMPLICIT, Kex_Algo::ECDHE_PSK, "Camellia-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), + Ciphersuite(0xC09B, "ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", Auth_Method::IMPLICIT, Kex_Algo::ECDHE_PSK, "Camellia-256", 32, "SHA-384", 48, KDF_Algo::SHA_384, Nonce_Format::CBC_MODE), + Ciphersuite(0xC09C, "RSA_WITH_AES_128_CCM", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "AES-128/CCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC09D, "RSA_WITH_AES_256_CCM", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "AES-256/CCM", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC09E, "DHE_RSA_WITH_AES_128_CCM", Auth_Method::RSA, Kex_Algo::DH, "AES-128/CCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC09F, "DHE_RSA_WITH_AES_256_CCM", Auth_Method::RSA, Kex_Algo::DH, "AES-256/CCM", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC0A0, "RSA_WITH_AES_128_CCM_8", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "AES-128/CCM(8)", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC0A1, "RSA_WITH_AES_256_CCM_8", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "AES-256/CCM(8)", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC0A2, "DHE_RSA_WITH_AES_128_CCM_8", Auth_Method::RSA, Kex_Algo::DH, "AES-128/CCM(8)", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC0A3, "DHE_RSA_WITH_AES_256_CCM_8", Auth_Method::RSA, Kex_Algo::DH, "AES-256/CCM(8)", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC0A4, "PSK_WITH_AES_128_CCM", Auth_Method::IMPLICIT, Kex_Algo::PSK, "AES-128/CCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC0A5, "PSK_WITH_AES_256_CCM", Auth_Method::IMPLICIT, Kex_Algo::PSK, "AES-256/CCM", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC0A6, "DHE_PSK_WITH_AES_128_CCM", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "AES-128/CCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC0A7, "DHE_PSK_WITH_AES_256_CCM", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "AES-256/CCM", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC0A8, "PSK_WITH_AES_128_CCM_8", Auth_Method::IMPLICIT, Kex_Algo::PSK, "AES-128/CCM(8)", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC0A9, "PSK_WITH_AES_256_CCM_8", Auth_Method::IMPLICIT, Kex_Algo::PSK, "AES-256/CCM(8)", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC0AA, "PSK_DHE_WITH_AES_128_CCM_8", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "AES-128/CCM(8)", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC0AB, "PSK_DHE_WITH_AES_256_CCM_8", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "AES-256/CCM(8)", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC0AC, "ECDHE_ECDSA_WITH_AES_128_CCM", Auth_Method::ECDSA, Kex_Algo::ECDH, "AES-128/CCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC0AD, "ECDHE_ECDSA_WITH_AES_256_CCM", Auth_Method::ECDSA, Kex_Algo::ECDH, "AES-256/CCM", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC0AE, "ECDHE_ECDSA_WITH_AES_128_CCM_8", Auth_Method::ECDSA, Kex_Algo::ECDH, "AES-128/CCM(8)", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xC0AF, "ECDHE_ECDSA_WITH_AES_256_CCM_8", Auth_Method::ECDSA, Kex_Algo::ECDH, "AES-256/CCM(8)", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xCCA8, "ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", Auth_Method::RSA, Kex_Algo::ECDH, "ChaCha20Poly1305", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xCCA9, "ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", Auth_Method::ECDSA, Kex_Algo::ECDH, "ChaCha20Poly1305", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xCCAA, "DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", Auth_Method::RSA, Kex_Algo::DH, "ChaCha20Poly1305", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xCCAB, "PSK_WITH_CHACHA20_POLY1305_SHA256", Auth_Method::IMPLICIT, Kex_Algo::PSK, "ChaCha20Poly1305", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xCCAC, "ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", Auth_Method::IMPLICIT, Kex_Algo::ECDHE_PSK, "ChaCha20Poly1305", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xCCAD, "DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "ChaCha20Poly1305", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xD001, "ECDHE_PSK_WITH_AES_128_GCM_SHA256", Auth_Method::IMPLICIT, Kex_Algo::ECDHE_PSK, "AES-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xD002, "ECDHE_PSK_WITH_AES_256_GCM_SHA384", Auth_Method::IMPLICIT, Kex_Algo::ECDHE_PSK, "AES-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xD003, "ECDHE_PSK_WITH_AES_128_CCM_8_SHA256", Auth_Method::IMPLICIT, Kex_Algo::ECDHE_PSK, "AES-128/CCM(8)", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xD005, "ECDHE_PSK_WITH_AES_128_CCM_SHA256", Auth_Method::IMPLICIT, Kex_Algo::ECDHE_PSK, "AES-128/CCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), + Ciphersuite(0xFFC0, "DHE_RSA_WITH_AES_128_OCB_SHA256", Auth_Method::RSA, Kex_Algo::DH, "AES-128/OCB(12)", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xFFC1, "DHE_RSA_WITH_AES_256_OCB_SHA256", Auth_Method::RSA, Kex_Algo::DH, "AES-256/OCB(12)", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xFFC2, "ECDHE_RSA_WITH_AES_128_OCB_SHA256", Auth_Method::RSA, Kex_Algo::ECDH, "AES-128/OCB(12)", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xFFC3, "ECDHE_RSA_WITH_AES_256_OCB_SHA256", Auth_Method::RSA, Kex_Algo::ECDH, "AES-256/OCB(12)", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xFFC4, "ECDHE_ECDSA_WITH_AES_128_OCB_SHA256", Auth_Method::ECDSA, Kex_Algo::ECDH, "AES-128/OCB(12)", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xFFC5, "ECDHE_ECDSA_WITH_AES_256_OCB_SHA256", Auth_Method::ECDSA, Kex_Algo::ECDH, "AES-256/OCB(12)", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xFFC6, "PSK_WITH_AES_128_OCB_SHA256", Auth_Method::IMPLICIT, Kex_Algo::PSK, "AES-128/OCB(12)", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xFFC7, "PSK_WITH_AES_256_OCB_SHA256", Auth_Method::IMPLICIT, Kex_Algo::PSK, "AES-256/OCB(12)", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xFFC8, "DHE_PSK_WITH_AES_128_OCB_SHA256", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "AES-128/OCB(12)", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xFFC9, "DHE_PSK_WITH_AES_256_OCB_SHA256", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "AES-256/OCB(12)", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xFFCA, "ECDHE_PSK_WITH_AES_128_OCB_SHA256", Auth_Method::IMPLICIT, Kex_Algo::ECDHE_PSK, "AES-128/OCB(12)", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xFFCB, "ECDHE_PSK_WITH_AES_256_OCB_SHA256", Auth_Method::IMPLICIT, Kex_Algo::ECDHE_PSK, "AES-256/OCB(12)", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xFFCC, "CECPQ1_RSA_WITH_AES_256_OCB_SHA256", Auth_Method::RSA, Kex_Algo::CECPQ1, "AES-256/OCB(12)", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), + Ciphersuite(0xFFCD, "CECPQ1_ECDSA_WITH_AES_256_OCB_SHA256", Auth_Method::ECDSA, Kex_Algo::CECPQ1, "AES-256/OCB(12)", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), }; return g_ciphersuite_list; diff --git a/src/scripts/tls_suite_info.py b/src/scripts/tls_suite_info.py index fd944f376..124a583e1 100755 --- a/src/scripts/tls_suite_info.py +++ b/src/scripts/tls_suite_info.py @@ -19,16 +19,16 @@ def to_ciphersuite_info(code, name): (sig_and_kex,cipher_and_mac) = name.split('_WITH_') if sig_and_kex == 'RSA': - sig_algo = 'RSA' + sig_algo = 'IMPLICIT' kex_algo = 'RSA' elif 'PSK' in sig_and_kex: - sig_algo = '' + sig_algo = 'IMPLICIT' kex_algo = sig_and_kex elif 'SRP' in sig_and_kex: srp_info = sig_and_kex.split('_') if len(srp_info) == 2: # 'SRP_' + hash kex_algo = sig_and_kex - sig_algo = '' + sig_algo = 'IMPLICIT' else: kex_algo = '_'.join(srp_info[0:-1]) sig_algo = srp_info[-1] @@ -67,7 +67,9 @@ def to_ciphersuite_info(code, name): } tls_to_botan_names = { - 'anon': '', + 'IMPLICIT': 'IMPLICIT', + + 'anon': 'ANONYMOUS', 'MD5': 'MD5', 'SHA': 'SHA-1', 'SHA256': 'SHA-256', @@ -105,6 +107,8 @@ def to_ciphersuite_info(code, name): mac_algo = tls_to_botan_names[mac_algo] sig_algo = tls_to_botan_names[sig_algo] kex_algo = tls_to_botan_names[kex_algo] + if kex_algo == 'RSA': + kex_algo = 'STATIC_RSA' (cipher_algo, cipher_keylen) = cipher_info[cipher[0]] @@ -116,22 +120,14 @@ def to_ciphersuite_info(code, name): modestr = '' mode = '' - ivlen = 0 if cipher[0] == 'CHACHA20' and cipher[1] == 'POLY1305': - iv_len = 12 - if code in ['CC13', 'CC14', 'CC15']: - iv_len = 0 # Google variant - record_iv_len = 0 - - return (name, code, sig_algo, kex_algo, "ChaCha20Poly1305", cipher_keylen, iv_len, record_iv_len, "AEAD", 0, mac_algo) + return (name, code, sig_algo, kex_algo, "ChaCha20Poly1305", cipher_keylen, "AEAD", 0, mac_algo, 'AEAD_XOR_12') mode = cipher[-1] if mode not in ['CBC', 'GCM', 'CCM(8)', 'CCM', 'OCB']: print "#warning Unknown mode '%s' for ciphersuite %s (0x%d)" % (' '.join(cipher), name, code) - ivlen = 8 if cipher_algo == '3DES' else 16 - if mode != 'CBC': if mode == 'OCB': cipher_algo += '/OCB(12)' @@ -139,16 +135,16 @@ def to_ciphersuite_info(code, name): cipher_algo += '/' + mode if mode == 'CBC': - return (name, code, sig_algo, kex_algo, cipher_algo, cipher_keylen, ivlen, 0, mac_algo, mac_keylen[mac_algo], "") + return (name, code, sig_algo, kex_algo, cipher_algo, cipher_keylen, mac_algo, mac_keylen[mac_algo], mac_algo, 'CBC_MODE') elif mode == 'OCB': - return (name, code, sig_algo, kex_algo, cipher_algo, cipher_keylen, 12, 0, "AEAD", 0, mac_algo) + return (name, code, sig_algo, kex_algo, cipher_algo, cipher_keylen, "AEAD", 0, mac_algo, 'AEAD_XOR_12') else: iv_bytes_from_hs = 4 iv_bytes_from_rec = 8 - return (name, code, sig_algo, kex_algo, cipher_algo, cipher_keylen, iv_bytes_from_hs, iv_bytes_from_rec, "AEAD", 0, mac_algo) + return (name, code, sig_algo, kex_algo, cipher_algo, cipher_keylen, "AEAD", 0, mac_algo, 'AEAD_IMPLICIT_4') def open_input(args): iana_url = 'https://www.iana.org/assignments/tls-parameters/tls-parameters.txt' @@ -249,11 +245,6 @@ def main(args = None): def define_custom_ciphersuite(name, code): suites[code] = to_ciphersuite_info(code, name) - # Google servers - draft-agl-tls-chacha20poly1305-04 - define_custom_ciphersuite('ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256', 'CC13') - define_custom_ciphersuite('ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256', 'CC14') - define_custom_ciphersuite('DHE_RSA_WITH_CHACHA20_POLY1305_SHA256', 'CC15') - if options.with_cecpq1: # CECPQ1 key exchange define_custom_ciphersuite('CECPQ1_RSA_WITH_CHACHA20_POLY1305_SHA256', '16B7') @@ -328,9 +319,9 @@ const std::vector<Ciphersuite>& Ciphersuite::all_known_ciphersuites() for code in sorted(suites.keys()): info = suites[code] - assert len(info) == 11 - suite_expr = 'Ciphersuite(0x%s, "%s", "%s", "%s", "%s", %d, %d, %d, "%s", %d, "%s")' % ( - code, info[0], info[2], info[3], info[4], info[5], info[6], info[7], info[8], info[9], info[10]) + assert len(info) == 10 + suite_expr = 'Ciphersuite(0x%s, "%s", Auth_Method::%s, Kex_Algo::%s, "%s", %d, "%s", %d, KDF_Algo::%s, Nonce_Format::%s)' % ( + code, info[0], info[2], info[3], info[4], info[5], info[6], info[7], info[8].replace('-','_'), info[9]) suite_info += " " + suite_expr + ",\n" diff --git a/src/tests/data/tls-policy/compat.txt b/src/tests/data/tls-policy/compat.txt index 39564b51b..473453ab0 100644 --- a/src/tests/data/tls-policy/compat.txt +++ b/src/tests/data/tls-policy/compat.txt @@ -12,7 +12,7 @@ allow_dtls12 = false ciphers = ChaCha20Poly1305 AES-256/GCM AES-128/GCM AES-256 AES-128 3DES macs = AEAD SHA-256 SHA-384 SHA-1 signature_hashes = SHA-512 SHA-384 SHA-256 SHA-1 -signature_methods = ECDSA RSA +signature_methods = ECDSA RSA IMPLICIT key_exchange_methods = CECPQ1 ECDH DH RSA ecc_curves = x25519 secp256r1 secp521r1 secp384r1 brainpool256r1 brainpool384r1 brainpool512r1 allow_insecure_renegotiation = false diff --git a/src/tests/data/tls/cert_verify.vec b/src/tests/data/tls/cert_verify.vec index 7f09002ce..d36156cc2 100644 --- a/src/tests/data/tls/cert_verify.vec +++ b/src/tests/data/tls/cert_verify.vec @@ -24,7 +24,7 @@ Exception = #Incomplete algorithm Buffer = 06 Protocol = 0303 -Exception = Invalid argument Decoding error: Invalid CertificateVerify: Expected 1 bytes remaining, only 0 left +Exception = Invalid argument Decoding error: Invalid CertificateVerify: Expected 2 bytes remaining, only 1 left #Incomplete certificate Buffer = 0601000500 diff --git a/src/tests/unit_tls.cpp b/src/tests/unit_tls.cpp index f82d432b4..f9132d60a 100644 --- a/src/tests/unit_tls.cpp +++ b/src/tests/unit_tls.cpp @@ -879,9 +879,9 @@ class TLS_Unit_Tests final : public Test policy.set("key_exchange_methods", kex_policy); policy.set("negotiate_encrypt_then_mac", etm_policy); - if(kex_policy == "RSA") + if(kex_policy.find("RSA") != std::string::npos) { - policy.set("signature_methods", "RSA"); + policy.set("signature_methods", "IMPLICIT"); } std::vector<Botan::TLS::Protocol_Version> versions = @@ -927,6 +927,11 @@ class TLS_Unit_Tests final : public Test policy.set("macs", mac_policy); policy.set("key_exchange_methods", kex_policy); + if(kex_policy.find("RSA") != std::string::npos) + { + policy.set("signature_methods", "IMPLICIT"); + } + for(auto const& kv : extra_policies) { policy.set(kv.first, kv.second); |