diff options
author | Mouse <[email protected]> | 2015-10-20 11:25:13 -0400 |
---|---|---|
committer | Mouse <[email protected]> | 2015-10-20 11:25:13 -0400 |
commit | b81c246c9c741ef669a79749bc31795175a2a555 (patch) | |
tree | b1291dc5ad4fff2193551e597aa01203327ffb5a /src/lib/tls | |
parent | 44e90e8cf98c7f132c88510b51492c8630fb092c (diff) | |
parent | 194d7d3682bddbd534e211357dd5f817d01ab7ed (diff) |
Merge pull request #2 from randombit/master
Update to match current Botan-1.11.22
Diffstat (limited to 'src/lib/tls')
-rw-r--r-- | src/lib/tls/credentials_manager.cpp | 135 | ||||
-rw-r--r-- | src/lib/tls/credentials_manager.h | 189 | ||||
-rw-r--r-- | src/lib/tls/info.txt | 2 | ||||
-rw-r--r-- | src/lib/tls/msg_hello_verify.cpp | 3 | ||||
-rw-r--r-- | src/lib/tls/sessions_sql/tls_session_manager_sql.cpp | 1 | ||||
-rw-r--r-- | src/lib/tls/tls_ciphersuite.cpp | 10 | ||||
-rw-r--r-- | src/lib/tls/tls_handshake_hash.cpp | 3 | ||||
-rw-r--r-- | src/lib/tls/tls_record.cpp | 23 | ||||
-rw-r--r-- | src/lib/tls/tls_server.cpp | 2 | ||||
-rw-r--r-- | src/lib/tls/tls_version.h | 2 |
10 files changed, 341 insertions, 29 deletions
diff --git a/src/lib/tls/credentials_manager.cpp b/src/lib/tls/credentials_manager.cpp new file mode 100644 index 000000000..6443bb246 --- /dev/null +++ b/src/lib/tls/credentials_manager.cpp @@ -0,0 +1,135 @@ +/* +* Credentials Manager +* (C) 2011,2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/credentials_manager.h> +#include <botan/x509path.h> + +namespace Botan { + +std::string Credentials_Manager::psk_identity_hint(const std::string&, + const std::string&) + { + return ""; + } + +std::string Credentials_Manager::psk_identity(const std::string&, + const std::string&, + const std::string&) + { + return ""; + } + +SymmetricKey Credentials_Manager::psk(const std::string&, + const std::string&, + const std::string& identity) + { + throw Internal_Error("No PSK set for identity " + identity); + } + +bool Credentials_Manager::attempt_srp(const std::string&, + const std::string&) + { + return false; + } + +std::string Credentials_Manager::srp_identifier(const std::string&, + const std::string&) + { + return ""; + } + +std::string Credentials_Manager::srp_password(const std::string&, + const std::string&, + const std::string&) + { + return ""; + } + +bool Credentials_Manager::srp_verifier(const std::string&, + const std::string&, + const std::string&, + std::string&, + BigInt&, + std::vector<byte>&, + bool) + { + return false; + } + +std::vector<X509_Certificate> Credentials_Manager::cert_chain( + const std::vector<std::string>&, + const std::string&, + const std::string&) + { + return std::vector<X509_Certificate>(); + } + +std::vector<X509_Certificate> Credentials_Manager::cert_chain_single_type( + const std::string& cert_key_type, + const std::string& type, + const std::string& context) + { + std::vector<std::string> cert_types; + cert_types.push_back(cert_key_type); + return cert_chain(cert_types, type, context); + } + +Private_Key* Credentials_Manager::private_key_for(const X509_Certificate&, + const std::string&, + const std::string&) + { + return nullptr; + } + +std::vector<Certificate_Store*> +Credentials_Manager::trusted_certificate_authorities( + const std::string&, + const std::string&) + { + return std::vector<Certificate_Store*>(); + } + +namespace { + +bool cert_in_some_store(const std::vector<Certificate_Store*>& trusted_CAs, + const X509_Certificate& trust_root) + { + for(auto CAs : trusted_CAs) + if(CAs->certificate_known(trust_root)) + return true; + return false; + } + +} + +void Credentials_Manager::verify_certificate_chain( + const std::string& type, + const std::string& purported_hostname, + const std::vector<X509_Certificate>& cert_chain) + { + if(cert_chain.empty()) + throw std::invalid_argument("Certificate chain was empty"); + + auto trusted_CAs = trusted_certificate_authorities(type, purported_hostname); + + Path_Validation_Restrictions restrictions; + + auto result = x509_path_validate(cert_chain, + restrictions, + trusted_CAs); + + if(!result.successful_validation()) + throw std::runtime_error("Certificate validation failure: " + result.result_string()); + + if(!cert_in_some_store(trusted_CAs, result.trust_root())) + throw std::runtime_error("Certificate chain roots in unknown/untrusted CA"); + + if(purported_hostname != "" && !cert_chain[0].matches_dns_name(purported_hostname)) + throw std::runtime_error("Certificate did not match hostname"); + } + +} diff --git a/src/lib/tls/credentials_manager.h b/src/lib/tls/credentials_manager.h new file mode 100644 index 000000000..96e840d13 --- /dev/null +++ b/src/lib/tls/credentials_manager.h @@ -0,0 +1,189 @@ +/* +* Credentials Manager +* (C) 2011,2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_CREDENTIALS_MANAGER_H__ +#define BOTAN_CREDENTIALS_MANAGER_H__ + +#include <botan/x509cert.h> +#include <botan/certstor.h> +#include <botan/symkey.h> +#include <string> + +namespace Botan { + +class BigInt; + +/** +* Interface for a credentials manager. +* +* A type is a fairly static value that represents the general nature +* of the transaction occurring. Currently used values are "tls-client" +* and "tls-server". Context represents a hostname, email address, +* username, or other identifier. +*/ +class BOTAN_DLL Credentials_Manager + { + public: + virtual ~Credentials_Manager() {} + + /** + * Return a list of the certificates of CAs that we trust in this + * type/context. + * + * @param type specifies the type of operation occurring + * + * @param context specifies a context relative to type. For instance + * for type "tls-client", context specifies the servers name. + */ + virtual std::vector<Certificate_Store*> trusted_certificate_authorities( + const std::string& type, + const std::string& context); + + /** + * Check the certificate chain is valid up to a trusted root, and + * optionally (if hostname != "") that the hostname given is + * consistent with the leaf certificate. + * + * This function should throw an exception derived from + * std::exception with an informative what() result if the + * certificate chain cannot be verified. + + * @param type specifies the type of operation occurring + * @param hostname specifies the purported hostname + * @param cert_chain specifies a certificate chain leading to a + * trusted root CA certificate. + */ + virtual void verify_certificate_chain( + const std::string& type, + const std::string& hostname, + const std::vector<X509_Certificate>& cert_chain); + + /** + * Return a cert chain we can use, ordered from leaf to root, + * or else an empty vector. + * + * It is assumed that the caller can get the private key of the + * leaf with private_key_for + * + * @param cert_key_types specifies the key types desired ("RSA", + * "DSA", "ECDSA", etc), or empty if there + * is no preference by the caller. + * + * @param type specifies the type of operation occurring + * + * @param context specifies a context relative to type. + */ + virtual std::vector<X509_Certificate> cert_chain( + const std::vector<std::string>& cert_key_types, + const std::string& type, + const std::string& context); + + /** + * Return a cert chain we can use, ordered from leaf to root, + * or else an empty vector. + * + * It is assumed that the caller can get the private key of the + * leaf with private_key_for + * + * @param cert_key_type specifies the type of key requested + * ("RSA", "DSA", "ECDSA", etc) + * + * @param type specifies the type of operation occurring + * + * @param context specifies a context relative to type. + */ + std::vector<X509_Certificate> cert_chain_single_type( + const std::string& cert_key_type, + const std::string& type, + const std::string& context); + + /** + * @return private key associated with this certificate if we should + * use it with this context. cert was returned by cert_chain + * @note this object should retain ownership of the returned key; + * it should not be deleted by the caller. + */ + virtual Private_Key* private_key_for(const X509_Certificate& cert, + const std::string& type, + const std::string& context); + + /** + * @param type specifies the type of operation occurring + * @param context specifies a context relative to type. + * @return true if we should attempt SRP authentication + */ + virtual bool attempt_srp(const std::string& type, + const std::string& context); + + /** + * @param type specifies the type of operation occurring + * @param context specifies a context relative to type. + * @return identifier for client-side SRP auth, if available + for this type/context. Should return empty string + if password auth not desired/available. + */ + virtual std::string srp_identifier(const std::string& type, + const std::string& context); + + /** + * @param type specifies the type of operation occurring + * @param context specifies a context relative to type. + * @param identifier specifies what identifier we want the + * password for. This will be a value previously returned + * by srp_identifier. + * @return password for client-side SRP auth, if available + for this identifier/type/context. + */ + virtual std::string srp_password(const std::string& type, + const std::string& context, + const std::string& identifier); + + /** + * Retrieve SRP verifier parameters + */ + virtual bool srp_verifier(const std::string& type, + const std::string& context, + const std::string& identifier, + std::string& group_name, + BigInt& verifier, + std::vector<byte>& salt, + bool generate_fake_on_unknown); + + /** + * @param type specifies the type of operation occurring + * @param context specifies a context relative to type. + * @return the PSK identity hint for this type/context + */ + virtual std::string psk_identity_hint(const std::string& type, + const std::string& context); + + /** + * @param type specifies the type of operation occurring + * @param context specifies a context relative to type. + * @param identity_hint was passed by the server (but may be empty) + * @return the PSK identity we want to use + */ + virtual std::string psk_identity(const std::string& type, + const std::string& context, + const std::string& identity_hint); + + /** + * @param type specifies the type of operation occurring + * @param context specifies a context relative to type. + * @param identity is a PSK identity previously returned by + psk_identity for the same type and context. + * @return the PSK used for identity, or throw an exception if no + * key exists + */ + virtual SymmetricKey psk(const std::string& type, + const std::string& context, + const std::string& identity); + }; + +} + +#endif diff --git a/src/lib/tls/info.txt b/src/lib/tls/info.txt index 3f3b323f1..1b0cf1415 100644 --- a/src/lib/tls/info.txt +++ b/src/lib/tls/info.txt @@ -3,6 +3,7 @@ define TLS 20150319 load_on auto <header:public> +credentials_manager.h tls_alert.h tls_blocking.h tls_channel.h @@ -36,7 +37,6 @@ tls_session_key.h aead aes asn1 -credentials dh ecdh ecdsa diff --git a/src/lib/tls/msg_hello_verify.cpp b/src/lib/tls/msg_hello_verify.cpp index a3c439750..c1dc574d4 100644 --- a/src/lib/tls/msg_hello_verify.cpp +++ b/src/lib/tls/msg_hello_verify.cpp @@ -7,7 +7,6 @@ #include <botan/internal/tls_messages.h> #include <botan/mac.h> -#include <botan/lookup.h> namespace Botan { @@ -36,7 +35,7 @@ Hello_Verify_Request::Hello_Verify_Request(const std::vector<byte>& client_hello const std::string& client_identity, const SymmetricKey& secret_key) { - std::unique_ptr<MessageAuthenticationCode> hmac(get_mac("HMAC(SHA-256)")); + std::unique_ptr<MessageAuthenticationCode> hmac(MessageAuthenticationCode::create("HMAC(SHA-256)")); hmac->set_key(secret_key); hmac->update_be(client_hello_bits.size()); diff --git a/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp b/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp index 508f8ff2f..ed207972e 100644 --- a/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp +++ b/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp @@ -8,7 +8,6 @@ #include <botan/tls_session_manager_sql.h> #include <botan/database.h> #include <botan/pbkdf.h> -#include <botan/lookup.h> #include <botan/hex.h> #include <botan/loadstor.h> #include <chrono> diff --git a/src/lib/tls/tls_ciphersuite.cpp b/src/lib/tls/tls_ciphersuite.cpp index c0f9dbf76..4fdf33811 100644 --- a/src/lib/tls/tls_ciphersuite.cpp +++ b/src/lib/tls/tls_ciphersuite.cpp @@ -7,7 +7,6 @@ #include <botan/tls_ciphersuite.h> #include <botan/parsing.h> -#include <botan/lookup.h> #include <botan/block_cipher.h> #include <botan/stream_cipher.h> #include <botan/hash.h> @@ -104,16 +103,13 @@ namespace { bool have_hash(const std::string& prf) { - return (!get_hash_function_providers(prf).empty()); + return (HashFunction::providers(prf).size() > 0); } bool have_cipher(const std::string& cipher) { - if(!get_block_cipher_providers(cipher).empty()) - return true; - if(!get_stream_cipher_providers(cipher).empty()) - return true; - return false; + return (BlockCipher::providers(cipher).size() > 0) || + (StreamCipher::providers(cipher).size() > 0); } } diff --git a/src/lib/tls/tls_handshake_hash.cpp b/src/lib/tls/tls_handshake_hash.cpp index 94c2774c5..615767cc2 100644 --- a/src/lib/tls/tls_handshake_hash.cpp +++ b/src/lib/tls/tls_handshake_hash.cpp @@ -7,7 +7,6 @@ #include <botan/internal/tls_handshake_hash.h> #include <botan/tls_exceptn.h> -#include <botan/lookup.h> #include <botan/hash.h> namespace Botan { @@ -29,7 +28,7 @@ secure_vector<byte> Handshake_Hash::final(Protocol_Version version, return mac_algo.c_str(); }; - std::unique_ptr<HashFunction> hash(make_hash_function(choose_hash())); + std::unique_ptr<HashFunction> hash(HashFunction::create(choose_hash())); hash->update(data); return hash->final(); } diff --git a/src/lib/tls/tls_record.cpp b/src/lib/tls/tls_record.cpp index 3ba02f039..71542de16 100644 --- a/src/lib/tls/tls_record.cpp +++ b/src/lib/tls/tls_record.cpp @@ -12,8 +12,6 @@ #include <botan/internal/tls_seq_numbers.h> #include <botan/internal/tls_session_key.h> #include <botan/internal/rounding.h> -#include <botan/internal/xor_buf.h> -#include <botan/lookup.h> #include <botan/rng.h> namespace Botan { @@ -63,20 +61,17 @@ Connection_Cipher_State::Connection_Cipher_State(Protocol_Version version, return; } - if(BlockCipher* bc = get_block_cipher(cipher_algo)) - { - m_block_cipher.reset(bc); - m_block_cipher->set_key(cipher_key); - m_block_cipher_cbc_state = iv.bits_of(); - m_block_size = bc->block_size(); - - if(version.supports_explicit_cbc_ivs()) - m_iv_size = m_block_size; - } - else + m_block_cipher = BlockCipher::create(cipher_algo); + m_mac = MessageAuthenticationCode::create("HMAC(" + mac_algo + ")"); + if(!m_block_cipher) throw Invalid_Argument("Unknown TLS cipher " + cipher_algo); - m_mac.reset(get_mac("HMAC(" + mac_algo + ")")); + m_block_cipher->set_key(cipher_key); + m_block_cipher_cbc_state = iv.bits_of(); + m_block_size = m_block_cipher->block_size(); + + if(version.supports_explicit_cbc_ivs()) + m_iv_size = m_block_size; m_mac->set_key(mac_key); } diff --git a/src/lib/tls/tls_server.cpp b/src/lib/tls/tls_server.cpp index 2f5a0e00d..330135e63 100644 --- a/src/lib/tls/tls_server.cpp +++ b/src/lib/tls/tls_server.cpp @@ -371,7 +371,7 @@ void Server::process_handshake_msg(const Handshake_State* active_state, catch(...) {} m_next_protocol = ""; - if(state.client_hello()->supports_alpn()) + if(m_choose_next_protocol && state.client_hello()->supports_alpn()) m_next_protocol = m_choose_next_protocol(state.client_hello()->next_protocols()); if(resuming) diff --git a/src/lib/tls/tls_version.h b/src/lib/tls/tls_version.h index a025b27ba..73968bb8c 100644 --- a/src/lib/tls/tls_version.h +++ b/src/lib/tls/tls_version.h @@ -8,7 +8,7 @@ #ifndef BOTAN_TLS_PROTOCOL_VERSION_H__ #define BOTAN_TLS_PROTOCOL_VERSION_H__ -#include <botan/get_byte.h> +#include <botan/loadstor.h> #include <string> namespace Botan { |