diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/filters/threaded_fork.cpp | 5 | ||||
-rw-r--r-- | src/lib/hash/hash.cpp | 2 | ||||
-rw-r--r-- | src/lib/misc/tss/info.txt | 1 | ||||
-rw-r--r-- | src/lib/misc/tss/tss.cpp | 1 | ||||
-rw-r--r-- | src/lib/rng/hmac_drbg/hmac_drbg.cpp | 54 | ||||
-rw-r--r-- | src/lib/rng/hmac_drbg/hmac_drbg.h | 53 | ||||
-rw-r--r-- | src/lib/tls/msg_client_hello.cpp | 18 | ||||
-rw-r--r-- | src/lib/tls/tls_callbacks.h | 30 | ||||
-rw-r--r-- | src/lib/tls/tls_client.cpp | 29 |
9 files changed, 139 insertions, 54 deletions
diff --git a/src/lib/filters/threaded_fork.cpp b/src/lib/filters/threaded_fork.cpp index f558ac9c2..ff54bcbc6 100644 --- a/src/lib/filters/threaded_fork.cpp +++ b/src/lib/filters/threaded_fork.cpp @@ -136,6 +136,11 @@ void Threaded_Fork::thread_entry(Filter* filter) { while(true) { + /* + * This is plain wrong: a single thread can get the semaphore + * more than one time, meaning it will process the input twice + * and some other thread/filter will not see this input. + */ m_thread_data->m_input_ready_semaphore.acquire(); if(!m_thread_data->m_input) diff --git a/src/lib/hash/hash.cpp b/src/lib/hash/hash.cpp index 7a32ccede..ede2f8c99 100644 --- a/src/lib/hash/hash.cpp +++ b/src/lib/hash/hash.cpp @@ -269,7 +269,7 @@ std::unique_ptr<HashFunction> HashFunction::create(const std::string& algo_spec, #endif #if defined(BOTAN_HAS_COMB4P) - if(req.algo_name() == "Comb4p" && req.arg_count() == 2) + if(req.algo_name() == "Comb4P" && req.arg_count() == 2) { std::unique_ptr<HashFunction> h1(HashFunction::create(req.arg(0))); std::unique_ptr<HashFunction> h2(HashFunction::create(req.arg(1))); diff --git a/src/lib/misc/tss/info.txt b/src/lib/misc/tss/info.txt index 5d0615170..5aaca6707 100644 --- a/src/lib/misc/tss/info.txt +++ b/src/lib/misc/tss/info.txt @@ -2,7 +2,6 @@ define THRESHOLD_SECRET_SHARING 20131128 <requires> rng -filters hex sha1 sha2_32 diff --git a/src/lib/misc/tss/tss.cpp b/src/lib/misc/tss/tss.cpp index e1727dc33..b77e6c2b9 100644 --- a/src/lib/misc/tss/tss.cpp +++ b/src/lib/misc/tss/tss.cpp @@ -7,7 +7,6 @@ #include <botan/tss.h> #include <botan/loadstor.h> -#include <botan/pipe.h> #include <botan/hex.h> #include <botan/sha2_32.h> #include <botan/sha160.h> diff --git a/src/lib/rng/hmac_drbg/hmac_drbg.cpp b/src/lib/rng/hmac_drbg/hmac_drbg.cpp index 6ea66aa2e..2e056e726 100644 --- a/src/lib/rng/hmac_drbg/hmac_drbg.cpp +++ b/src/lib/rng/hmac_drbg/hmac_drbg.cpp @@ -12,38 +12,63 @@ namespace Botan { HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf, RandomNumberGenerator& underlying_rng, - size_t reseed_interval) : + size_t reseed_interval, + size_t max_number_of_bytes_per_request) : Stateful_RNG(underlying_rng, reseed_interval), - m_mac(std::move(prf)) + m_mac(std::move(prf)), + m_max_number_of_bytes_per_request(max_number_of_bytes_per_request) { BOTAN_ASSERT_NONNULL(m_mac); + + if(m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024) + { + throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request"); + } + clear(); } HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf, RandomNumberGenerator& underlying_rng, Entropy_Sources& entropy_sources, - size_t reseed_interval) : + size_t reseed_interval, + size_t max_number_of_bytes_per_request ) : Stateful_RNG(underlying_rng, entropy_sources, reseed_interval), - m_mac(std::move(prf)) + m_mac(std::move(prf)), + m_max_number_of_bytes_per_request(max_number_of_bytes_per_request) { BOTAN_ASSERT_NONNULL(m_mac); + + if(m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024) + { + throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request"); + } + clear(); } HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf, Entropy_Sources& entropy_sources, - size_t reseed_interval) : + size_t reseed_interval, + size_t max_number_of_bytes_per_request) : Stateful_RNG(entropy_sources, reseed_interval), - m_mac(std::move(prf)) + m_mac(std::move(prf)), + m_max_number_of_bytes_per_request(max_number_of_bytes_per_request) { BOTAN_ASSERT_NONNULL(m_mac); + + if(m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024) + { + throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request"); + } + clear(); } HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf) : Stateful_RNG(), - m_mac(std::move(prf)) + m_mac(std::move(prf)), + m_max_number_of_bytes_per_request(64*1024) { BOTAN_ASSERT_NONNULL(m_mac); clear(); @@ -76,22 +101,9 @@ void HMAC_DRBG::randomize(byte output[], size_t output_len) void HMAC_DRBG::randomize_with_input(byte output[], size_t output_len, const byte input[], size_t input_len) { - /** - * SP 800-90A requires we reject any request for a DRBG output - * longer than max_number_of_bits_per_request. This is an - * implementation-dependent value, but NIST requires for HMAC_DRBG - * that every implementation set a value no more than 2**19 bits - * (or 64 KiB). - * - * To avoid inconveniencing the caller who wants a large output for - * whatever reason, instead treat very long output requests as - * if multiple maximum-length requests had been made. - */ - const size_t max_number_of_bytes_per_request = 64*1024; - while(output_len > 0) { - size_t this_req = std::min(max_number_of_bytes_per_request, output_len); + size_t this_req = std::min(m_max_number_of_bytes_per_request, output_len); output_len -= this_req; reseed_check(); diff --git a/src/lib/rng/hmac_drbg/hmac_drbg.h b/src/lib/rng/hmac_drbg/hmac_drbg.h index 11d355d70..189edbcdf 100644 --- a/src/lib/rng/hmac_drbg/hmac_drbg.h +++ b/src/lib/rng/hmac_drbg/hmac_drbg.h @@ -24,7 +24,7 @@ class BOTAN_DLL HMAC_DRBG final : public Stateful_RNG /** * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC) * - * Automatic reseeding is disabled completely, as it as no access to + * Automatic reseeding is disabled completely, as it has no access to * any source for seed material. * * If a fork is detected, the RNG will be unable to reseed itself @@ -44,10 +44,22 @@ class BOTAN_DLL HMAC_DRBG final : public Stateful_RNG * to perform the periodic reseeding * @param reseed_interval specifies a limit of how many times * the RNG will be called before automatic reseeding is performed + * @param max_number_of_bytes_per_request requests that are in size higher + * than max_number_of_bytes_per_request are treated as if multiple single + * requests of max_number_of_bytes_per_request size had been made. + * In theory SP 800-90A requires that we reject any request for a DRBG + * output longer than max_number_of_bytes_per_request. To avoid inconveniencing + * the caller who wants an output larger than max_number_of_bytes_per_request, + * instead treat these requests as if multiple requests of + * max_number_of_bytes_per_request size had been made. NIST requires for + * HMAC_DRBG that every implementation set a value no more than 2**19 bits + * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for + * example every 512 bit automatic reseeding occurs. */ HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf, RandomNumberGenerator& underlying_rng, - size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL); + size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, + size_t max_number_of_bytes_per_request = 64 * 1024); /** * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC) @@ -59,10 +71,22 @@ class BOTAN_DLL HMAC_DRBG final : public Stateful_RNG * @param entropy_sources will be polled to perform reseeding periodically * @param reseed_interval specifies a limit of how many times * the RNG will be called before automatic reseeding is performed. + * @param max_number_of_bytes_per_request requests that are in size higher + * than max_number_of_bytes_per_request are treated as if multiple single + * requests of max_number_of_bytes_per_request size had been made. + * In theory SP 800-90A requires that we reject any request for a DRBG + * output longer than max_number_of_bytes_per_request. To avoid inconveniencing + * the caller who wants an output larger than max_number_of_bytes_per_request, + * instead treat these requests as if multiple requests of + * max_number_of_bytes_per_request size had been made. NIST requires for + * HMAC_DRBG that every implementation set a value no more than 2**19 bits + * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for + * example every 512 bit automatic reseeding occurs. */ HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf, Entropy_Sources& entropy_sources, - size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL); + size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, + size_t max_number_of_bytes_per_request = 64 * 1024); /** * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC) @@ -77,20 +101,32 @@ class BOTAN_DLL HMAC_DRBG final : public Stateful_RNG * @param entropy_sources will be polled to perform reseeding periodically * @param reseed_interval specifies a limit of how many times * the RNG will be called before automatic reseeding is performed. + * @param max_number_of_bytes_per_request requests that are in size higher + * than max_number_of_bytes_per_request are treated as if multiple single + * requests of max_number_of_bytes_per_request size had been made. + * In theory SP 800-90A requires that we reject any request for a DRBG + * output longer than max_number_of_bytes_per_request. To avoid inconveniencing + * the caller who wants an output larger than max_number_of_bytes_per_request, + * instead treat these requests as if multiple requests of + * max_number_of_bytes_per_request size had been made. NIST requires for + * HMAC_DRBG that every implementation set a value no more than 2**19 bits + * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for + * example every 512 bit automatic reseeding occurs. */ HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf, RandomNumberGenerator& underlying_rng, Entropy_Sources& entropy_sources, - size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL); + size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, + size_t max_number_of_bytes_per_request = 64 * 1024); /** * Constructor taking a string for the hash */ - HMAC_DRBG(const std::string& hmac_hash) : Stateful_RNG() + HMAC_DRBG(const std::string& hmac_hash) : + Stateful_RNG(), + m_mac(MessageAuthenticationCode::create_or_throw("HMAC(" + hmac_hash + ")")), + m_max_number_of_bytes_per_request(64 * 1024) { - m_mac = MessageAuthenticationCode::create("HMAC(" + hmac_hash + ")"); - if(!m_mac) - throw Algorithm_Not_Found(hmac_hash); clear(); } @@ -112,6 +148,7 @@ class BOTAN_DLL HMAC_DRBG final : public Stateful_RNG std::unique_ptr<MessageAuthenticationCode> m_mac; secure_vector<byte> m_V; + const size_t m_max_number_of_bytes_per_request; }; } diff --git a/src/lib/tls/msg_client_hello.cpp b/src/lib/tls/msg_client_hello.cpp index 36335e7ce..50c83c10c 100644 --- a/src/lib/tls/msg_client_hello.cpp +++ b/src/lib/tls/msg_client_hello.cpp @@ -84,7 +84,7 @@ Client_Hello::Client_Hello(Handshake_IO& io, "Our policy accepts the version we are offering"); /* - * Place all empty extensions in front to avoid a bug in some sytems + * Place all empty extensions in front to avoid a bug in some systems * which reject hellos when the last extension in the list is empty. */ m_extensions.add(new Extended_Master_Secret); @@ -170,14 +170,7 @@ Client_Hello::Client_Hello(Handshake_IO& io, m_extensions.add(new Supported_Point_Formats()); } - if(m_version.supports_negotiable_signature_algorithms()) - m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(), - policy.allowed_signature_methods())); - - if(reneg_info.empty() && !next_protocols.empty()) - m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols)); - - if(policy.negotiate_encrypt_then_mac()) + if(session.supports_encrypt_then_mac()) m_extensions.add(new Encrypt_then_MAC); #if defined(BOTAN_HAS_SRP6) @@ -189,6 +182,13 @@ 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())); + + if(reneg_info.empty() && !next_protocols.empty()) + m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols)); + hash.update(io.send(*this)); } diff --git a/src/lib/tls/tls_callbacks.h b/src/lib/tls/tls_callbacks.h index 17cd19b81..4a14055f9 100644 --- a/src/lib/tls/tls_callbacks.h +++ b/src/lib/tls/tls_callbacks.h @@ -99,9 +99,35 @@ class BOTAN_DLL Callbacks virtual std::string tls_server_choose_app_protocol(const std::vector<std::string>& client_protos); /** - * Optional callback: debug logging. (not currently used) + * Optional callback: error logging. (not currently called) + * @param err An error message related to this connection. */ - virtual bool tls_log_debug(const char*) { return false; } + virtual void tls_log_error(const char* err) + { + BOTAN_UNUSED(err); + } + + /** + * Optional callback: debug logging. (not currently called) + * @param what Some hopefully informative string + */ + virtual void tls_log_debug(const char* what) + { + BOTAN_UNUSED(what); + } + + /** + * Optional callback: debug logging taking a buffer. (not currently called) + * @param descr What this buffer is + * @param val the bytes + * @param val_len length of val + */ + virtual void tls_log_debug_bin(const char* descr, const uint8_t val[], size_t val_len) + { + BOTAN_UNUSED(descr); + BOTAN_UNUSED(val); + BOTAN_UNUSED(val_len); + } }; /** diff --git a/src/lib/tls/tls_client.cpp b/src/lib/tls/tls_client.cpp index 0e72b9a28..183886c66 100644 --- a/src/lib/tls/tls_client.cpp +++ b/src/lib/tls/tls_client.cpp @@ -149,18 +149,25 @@ void Client::send_client_hello(Handshake_State& state_base, Session session_info; if(session_manager().load_from_server_info(m_info, session_info)) { - if(srp_identifier == "" || session_info.srp_identifier() == srp_identifier) + /* + Ensure that the session protocol type matches what we want to use + If not skip the resume and establish a new session + */ + if(version == session_info.version()) { - state.client_hello(new Client_Hello( - state.handshake_io(), - state.hash(), - policy(), - rng(), - secure_renegotiation_data_for_client_hello(), - session_info, - next_protocols)); - - state.resume_master_secret = session_info.master_secret(); + if(srp_identifier == "" || session_info.srp_identifier() == srp_identifier) + { + state.client_hello( + new Client_Hello(state.handshake_io(), + state.hash(), + policy(), + rng(), + secure_renegotiation_data_for_client_hello(), + session_info, + next_protocols)); + + state.resume_master_secret = session_info.master_secret(); + } } } } |