diff options
-rw-r--r-- | doc/download.rst | 6 | ||||
-rw-r--r-- | doc/passhash.rst | 5 | ||||
-rw-r--r-- | doc/relnotes/1_11_4.rst | 25 | ||||
-rw-r--r-- | doc/relnotes/index.rst | 1 | ||||
-rw-r--r-- | doc/tls.rst | 28 | ||||
-rw-r--r-- | src/entropy/rdrand/info.txt | 2 | ||||
-rw-r--r-- | src/entropy/rdrand/rdrand.cpp | 2 | ||||
-rw-r--r-- | src/filters/filter.cpp | 11 | ||||
-rw-r--r-- | src/pk_pad/emsa2/emsa2.cpp | 5 | ||||
-rw-r--r-- | src/rng/randpool/randpool.cpp | 3 | ||||
-rw-r--r-- | src/tls/tls_channel.cpp | 25 | ||||
-rw-r--r-- | src/tls/tls_channel.h | 39 | ||||
-rw-r--r-- | src/tls/tls_client.cpp | 14 | ||||
-rw-r--r-- | src/tls/tls_client.h | 8 | ||||
-rw-r--r-- | src/tls/tls_policy.cpp | 7 | ||||
-rw-r--r-- | src/tls/tls_policy.h | 2 | ||||
-rw-r--r-- | src/tls/tls_server.cpp | 5 | ||||
-rw-r--r-- | src/tls/tls_server.h | 5 |
18 files changed, 123 insertions, 70 deletions
diff --git a/doc/download.rst b/doc/download.rst index 63688519c..f7d23986c 100644 --- a/doc/download.rst +++ b/doc/download.rst @@ -34,9 +34,9 @@ Current Development Series (1.11) ---------------------------------------- The latest version of the current development series, from branch -``net.randombit.botan``, is :doc:`relnotes/1_11_3`: -:tgz:`1.11.3` (:tgz_sig:`sig <1.11.3>`), -:tbz:`1.11.3` (:tbz_sig:`sig <1.11.3>`) +``net.randombit.botan``, is :doc:`relnotes/1_11_4`: +:tgz:`1.11.4` (:tgz_sig:`sig <1.11.4>`), +:tbz:`1.11.4` (:tbz_sig:`sig <1.11.4>`) To access the latest unreleased sources, see :doc:`vcs`. A script also creates regular snapshots of trunk, which are available `here diff --git a/doc/passhash.rst b/doc/passhash.rst index f6445e2f6..b40ac3d3f 100644 --- a/doc/passhash.rst +++ b/doc/passhash.rst @@ -113,9 +113,8 @@ Botan also provides a password hashing technique called passhash9, in RandomNumberGenerator& rng, u16bit work_factor = 10, byte alg_id = 1) Functions much like ``generate_bcrypt``. The last parameter, - ``alg_id``, specifies which PRF to use. Currently defined values - are 0: HMAC(SHA-1), 1: HMAC(SHA-256), 2: CMAC(Blowfish), - 3: HMAC(SHA-384), 4: HMAC(SHA-512) + ``alg_id``, specifies which PRF to use. Currently defined values are + 0: HMAC(SHA-1), 1: HMAC(SHA-256), 2: CMAC(Blowfish), 3: HMAC(SHA-384), 4: HMAC(SHA-512) Currently, this performs 10000 * ``work_factor`` PBKDF2 iterations, using 96 bits of salt taken from ``rng``. The iteration count is diff --git a/doc/relnotes/1_11_4.rst b/doc/relnotes/1_11_4.rst index 91a33ae58..a635531a7 100644 --- a/doc/relnotes/1_11_4.rst +++ b/doc/relnotes/1_11_4.rst @@ -1,4 +1,4 @@ -Version 1.11.4, Not Yet Released +Version 1.11.4, 2013-07-25 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * CPU specific extensions are now always compiled if support for the @@ -9,14 +9,29 @@ Version 1.11.4, Not Yet Released in x86 builds, relying on runtime cpuid checking to prevent their use on CPUs that do not support those operations. +* The default TLS policy now only accepts TLS, to minimize surprise + for servers which might not expect to negotiate DTLS. Previously a + server would by default negotiate either protocol type (clients + would only accept the same protocol type as they + offered). Applications which use DTLS or combined TLS/DTLS need to + override :cpp:func:`Policy::acceptable_protocol_version`. + +* The TLS channels now accept a new parameter specifying how many + bytes to preallocate for the record handling buffers, which allows + an application some control over how much memory is used at runtime + for a particular connection. + +* Applications can now send arbitrary TLS alert messages using + :cpp:func:`TLS::Channel::send_alert` + +* A new TLS policy :cpp:class:`NSA_Suite_B_128` is available, which + will negotiate only the 128-bit security NSA Suite B. See + :rfc:`6460` for more information about Suite B. + * Adds a new interface for benchmarking, :cpp:func:`time_algorithm_ops`, which returns a map of operations to operations per second. For instance now both encrypt and decrypt speed of a block cipher can be checked, as well as the key schedule of all keyed algorithms. It additionally supports AEAD modes. -* A new TLS policy :cpp:class:`NSA_Suite_B_128` is available, which - will negotiate only the 128-bit security NSA Suite B. See - :rfc:`6460` for more information about Suite B. - * Rename ARC4 to RC4 diff --git a/doc/relnotes/index.rst b/doc/relnotes/index.rst index 633ac79bb..c905796ba 100644 --- a/doc/relnotes/index.rst +++ b/doc/relnotes/index.rst @@ -8,6 +8,7 @@ Series 1.11 .. toctree:: :maxdepth: 1 + 1_11_4 1_11_3 1_11_2 1_11_1 diff --git a/doc/tls.rst b/doc/tls.rst index df08c088a..93955d31c 100644 --- a/doc/tls.rst +++ b/doc/tls.rst @@ -113,6 +113,11 @@ available: A close notification is sent to the counterparty, and the internal state is cleared. + .. cpp:function void send_alert(const Alert& alert) + + Some other alert is sent to the counterparty. If the alert is + fatal, the internal state is cleared. + .. cpp:function:: bool is_active() Returns true if and only if a handshake has been completed on @@ -181,7 +186,8 @@ TLS Clients RandomNumberGenerator& rng, \ const Server_Information& server_info, \ const Protocol_Version offer_version, \ - std::function<std::string, std::vector<std::string> > next_protocol) + std::function<std::string, std::vector<std::string> > next_protocol, \ + size_t reserved_io_buffer_size) Initialize a new TLS client. The constructor will immediately initiate a new session. @@ -249,6 +255,12 @@ TLS Clients server advertises, and the client can select from them or return an unadvertised protocol. + The optional *reserved_io_buffer_size* specifies how many bytes to + pre-allocate in the I/O buffers. Use this if you want to control + how much memory the channel uses initially (the buffers will be + resized as needed to process inputs). Otherwise some reasonable + default is used. + A simple TLS client example: .. literalinclude:: examples/tls_client.cpp @@ -266,11 +278,13 @@ TLS Servers Credentials_Manager& creds, \ const TLS::Policy& policy, \ RandomNumberGenerator& rng, \ - const std::vector<std::string>& protocols) + const std::vector<std::string>& protocols, \ + bool reserved_io_buffer_size) -The first 7 arguments are treated similiarly to the :ref:`client -<tls_client>`. The final (optional) argument, protocols, specifies -the protocols the server is willing to advertise it supports. +The first 7 arguments as well as the final argument +*reserved_io_buffer_size*, are treated similiarly to the :ref:`client +<tls_client>`. The (optional) argument, *protocols*, specifies the +protocols the server is willing to advertise it supports. .. cpp:function:: std::string TLS::Server::next_protocol() const @@ -544,7 +558,9 @@ be negotiated during a handshake. Return true if this version of the protocol is one that we are willing to negotiate. - Default: True for all known protocol versions + Default: True if a known TLS version. DTLS is not accepted by default; + to enable DTLS (or combined TLS/DTLS) in your application, override this + function. .. cpp:function:: bool server_uses_own_ciphersuite_preferences() const diff --git a/src/entropy/rdrand/info.txt b/src/entropy/rdrand/info.txt index 4b9362d61..f1a536e95 100644 --- a/src/entropy/rdrand/info.txt +++ b/src/entropy/rdrand/info.txt @@ -9,7 +9,7 @@ rdrand.h </header:internal> <arch> -x86 +x86_32 x86_64 </arch> diff --git a/src/entropy/rdrand/rdrand.cpp b/src/entropy/rdrand/rdrand.cpp index 51b2bd5f6..0dae697c8 100644 --- a/src/entropy/rdrand/rdrand.cpp +++ b/src/entropy/rdrand/rdrand.cpp @@ -40,7 +40,7 @@ void Intel_Rdrand::poll(Entropy_Accumulator& accum) for(size_t i = 0; i != RDRAND_POLLS; ++i) { - unsigned int r; + unsigned int r = 0; #if BOTAN_USE_GCC_INLINE_ASM int cf = 0; diff --git a/src/filters/filter.cpp b/src/filters/filter.cpp index 9432f0304..f4b2d34bc 100644 --- a/src/filters/filter.cpp +++ b/src/filters/filter.cpp @@ -104,17 +104,16 @@ Filter* Filter::get_next() const */ void Filter::set_next(Filter* filters[], size_t size) { - while(size && filters && filters[size-1] == nullptr) - --size; - next.clear(); - next.resize(size); port_num = 0; filter_owns = 0; - for(size_t j = 0; j != size; ++j) - next[j] = filters[j]; + while(size && filters && filters[size-1] == 0) + --size; + + if(filters && size) + next.assign(filters, filters + size); } /* diff --git a/src/pk_pad/emsa2/emsa2.cpp b/src/pk_pad/emsa2/emsa2.cpp index d299ddacd..02a3dbe72 100644 --- a/src/pk_pad/emsa2/emsa2.cpp +++ b/src/pk_pad/emsa2/emsa2.cpp @@ -99,12 +99,13 @@ EMSA2::EMSA2(HashFunction* hash_in) : hash(hash_in) { empty_hash = hash->final(); - hash_id = ieee1363_hash_id(hash->name()); + const std::string hash_name = hash->name(); + hash_id = ieee1363_hash_id(hash_name); if(hash_id == 0) { delete hash; - throw Encoding_Error("EMSA2 cannot be used with " + hash->name()); + throw Encoding_Error("EMSA2 no hash identifier for " + hash_name); } } diff --git a/src/rng/randpool/randpool.cpp b/src/rng/randpool/randpool.cpp index ef55f3975..aa029fef3 100644 --- a/src/rng/randpool/randpool.cpp +++ b/src/rng/randpool/randpool.cpp @@ -184,8 +184,7 @@ Randpool::Randpool(BlockCipher* cipher_in, { delete cipher; delete mac; - throw Internal_Error("Randpool: Invalid algorithm combination " + - cipher->name() + "/" + mac->name()); + throw Internal_Error("Randpool: Invalid algorithm combination"); } buffer.resize(BLOCK_SIZE); diff --git a/src/tls/tls_channel.cpp b/src/tls/tls_channel.cpp index 51e0c11e5..20d882a40 100644 --- a/src/tls/tls_channel.cpp +++ b/src/tls/tls_channel.cpp @@ -23,15 +23,25 @@ Channel::Channel(std::function<void (const byte[], size_t)> output_fn, std::function<void (const byte[], size_t, Alert)> proc_fn, std::function<bool (const Session&)> handshake_complete, Session_Manager& session_manager, - RandomNumberGenerator& rng) : + RandomNumberGenerator& rng, + size_t reserved_io_buffer_size) : m_handshake_fn(handshake_complete), m_proc_fn(proc_fn), m_output_fn(output_fn), m_rng(rng), m_session_manager(session_manager) { - m_writebuf.reserve(16*1024); - m_readbuf.reserve(16*1024); + m_writebuf.reserve(reserved_io_buffer_size); + m_readbuf.reserve(reserved_io_buffer_size); + } + +void Channel::reset_state() + { + m_active_state.reset(); + m_pending_state.reset(); + m_readbuf.clear(); + m_write_cipher_states.clear(); + m_read_cipher_states.clear(); } Channel::~Channel() @@ -379,9 +389,7 @@ size_t Channel::received_data(const byte input[], size_t input_size) if(alert_msg.type() == Alert::CLOSE_NOTIFY || alert_msg.is_fatal()) { - m_active_state.reset(); - m_pending_state.reset(); - + reset_state(); return 0; } } @@ -530,10 +538,7 @@ void Channel::send_alert(const Alert& alert) m_session_manager.remove_entry(active->server_hello()->session_id()); if(alert.type() == Alert::CLOSE_NOTIFY || alert.is_fatal()) - { - m_active_state.reset(); - m_pending_state.reset(); - } + reset_state(); } void Channel::secure_renegotiation_check(const Client_Hello* client_hello) diff --git a/src/tls/tls_channel.h b/src/tls/tls_channel.h index 29028e160..32609a14c 100644 --- a/src/tls/tls_channel.h +++ b/src/tls/tls_channel.h @@ -59,6 +59,23 @@ class BOTAN_DLL Channel } /** + * Send a TLS alert message. If the alert is fatal, the internal + * state (keys, etc) will be reset. + * @param alert the Alert to send + */ + void send_alert(const Alert& alert); + + /** + * Send a warning alert + */ + void send_warning_alert(Alert::Type type) { send_alert(Alert(type, false)); } + + /** + * Send a fatal alert + */ + void send_fatal_alert(Alert::Type type) { send_alert(Alert(type, true)); } + + /** * Send a close notification alert */ void close() { send_warning_alert(Alert::CLOSE_NOTIFY); } @@ -128,7 +145,8 @@ class BOTAN_DLL Channel std::function<void (const byte[], size_t, Alert)> proc_fn, std::function<bool (const Session&)> handshake_complete, Session_Manager& session_manager, - RandomNumberGenerator& rng); + RandomNumberGenerator& rng, + size_t reserved_io_buffer_size); Channel(const Channel&) = delete; @@ -152,23 +170,6 @@ class BOTAN_DLL Channel Handshake_State& create_handshake_state(Protocol_Version version); - /** - * Send a TLS alert message. If the alert is fatal, the internal - * state (keys, etc) will be reset. - * @param alert the Alert to send - */ - void send_alert(const Alert& alert); - - /** - * Send a warning alert - */ - void send_warning_alert(Alert::Type type) { send_alert(Alert(type, false)); } - - /** - * Send a fatal alert - */ - void send_fatal_alert(Alert::Type type) { send_alert(Alert(type, true)); } - void activate_session(); void change_cipher_spec_reader(Connection_Side side); @@ -209,6 +210,8 @@ class BOTAN_DLL Channel std::shared_ptr<Connection_Cipher_State> write_cipher_state_epoch(u16bit epoch) const; + void reset_state(); + const Handshake_State* active_state() const { return m_active_state.get(); } const Handshake_State* pending_state() const { return m_pending_state.get(); } diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp index e24e9739b..a6093e474 100644 --- a/src/tls/tls_client.cpp +++ b/src/tls/tls_client.cpp @@ -56,8 +56,9 @@ Client::Client(std::function<void (const byte[], size_t)> output_fn, RandomNumberGenerator& rng, const Server_Information& info, const Protocol_Version offer_version, - std::function<std::string (std::vector<std::string>)> next_protocol) : - Channel(output_fn, proc_fn, handshake_fn, session_manager, rng), + std::function<std::string (std::vector<std::string>)> next_protocol, + size_t io_buf_sz) : + Channel(output_fn, proc_fn, handshake_fn, session_manager, rng, io_buf_sz), m_policy(policy), m_creds(creds), m_info(info) @@ -253,9 +254,12 @@ void Client::process_handshake_msg(const Handshake_State* active_state, { // new session - BOTAN_ASSERT_EQUAL(state.client_hello()->version().is_datagram_protocol(), - state.server_hello()->version().is_datagram_protocol(), - "Server replied with same protocol type client offered"); + if(state.client_hello()->version().is_datagram_protocol() != + state.server_hello()->version().is_datagram_protocol()) + { + throw TLS_Exception(Alert::PROTOCOL_VERSION, + "Server replied with different protocol type than we offered"); + } if(state.version() > state.client_hello()->version()) { diff --git a/src/tls/tls_client.h b/src/tls/tls_client.h index b40896e94..c8c2edd4e 100644 --- a/src/tls/tls_client.h +++ b/src/tls/tls_client.h @@ -52,6 +52,10 @@ class BOTAN_DLL Client : public Channel * and if the server supports NPN the function will be * called with the list of protocols the server advertised; * the client should return the protocol it would like to use. + * + * @param reserved_io_buffer_size This many bytes of memory will + * be preallocated for the read and write buffers. Smaller + * values just mean reallocations and copies are more likely. */ Client(std::function<void (const byte[], size_t)> socket_output_fn, std::function<void (const byte[], size_t, Alert)> proc_fn, @@ -63,7 +67,9 @@ class BOTAN_DLL Client : public Channel const Server_Information& server_info = Server_Information(), const Protocol_Version offer_version = Protocol_Version::latest_tls_version(), std::function<std::string (std::vector<std::string>)> next_protocol = - std::function<std::string (std::vector<std::string>)>()); + std::function<std::string (std::vector<std::string>)>(), + size_t reserved_io_buffer_size = 16*1024 + ); private: std::vector<X509_Certificate> get_peer_cert_chain(const Handshake_State& state) const override; diff --git a/src/tls/tls_policy.cpp b/src/tls/tls_policy.cpp index 5a6cca2f6..12c761f98 100644 --- a/src/tls/tls_policy.cpp +++ b/src/tls/tls_policy.cpp @@ -134,10 +134,11 @@ u32bit Policy::session_ticket_lifetime() const bool Policy::acceptable_protocol_version(Protocol_Version version) const { - return version.known_version(); // accept any version we know about + if(!version.known_version()) + return false; - // maybe someday... - //return version >= Protocol_Version::TLS_V11; + // By default require TLS to minimize surprise + return !version.is_datagram_protocol(); } namespace { diff --git a/src/tls/tls_policy.h b/src/tls/tls_policy.h index f80bffb71..6cc41fc50 100644 --- a/src/tls/tls_policy.h +++ b/src/tls/tls_policy.h @@ -122,6 +122,8 @@ class BOTAN_DLL Policy /** * @return true if and only if we are willing to accept this version + * Default accepts only TLS, so override if you want to enable DTLS + * in your application. */ virtual bool acceptable_protocol_version(Protocol_Version version) const; diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp index 6f4aaf4c3..1e87af483 100644 --- a/src/tls/tls_server.cpp +++ b/src/tls/tls_server.cpp @@ -215,8 +215,9 @@ Server::Server(std::function<void (const byte[], size_t)> output_fn, Credentials_Manager& creds, const Policy& policy, RandomNumberGenerator& rng, - const std::vector<std::string>& next_protocols) : - Channel(output_fn, proc_fn, handshake_fn, session_manager, rng), + const std::vector<std::string>& next_protocols, + size_t io_buf_sz) : + Channel(output_fn, proc_fn, handshake_fn, session_manager, rng, io_buf_sz), m_policy(policy), m_creds(creds), m_possible_protocols(next_protocols) diff --git a/src/tls/tls_server.h b/src/tls/tls_server.h index 25c5b6506..f32636777 100644 --- a/src/tls/tls_server.h +++ b/src/tls/tls_server.h @@ -32,8 +32,9 @@ class BOTAN_DLL Server : public Channel Credentials_Manager& creds, const Policy& policy, RandomNumberGenerator& rng, - const std::vector<std::string>& protocols = - std::vector<std::string>()); + const std::vector<std::string>& protocols = std::vector<std::string>(), + size_t reserved_io_buffer_size = 16*1024 + ); /** * Return the protocol notification set by the client (using the |