diff options
-rw-r--r-- | src/tls/c_hello.cpp | 2 | ||||
-rw-r--r-- | src/tls/c_kex.cpp | 2 | ||||
-rw-r--r-- | src/tls/finished.cpp | 2 | ||||
-rw-r--r-- | src/tls/info.txt | 3 | ||||
-rw-r--r-- | src/tls/rec_read.cpp | 19 | ||||
-rw-r--r-- | src/tls/rec_wri.cpp | 8 | ||||
-rw-r--r-- | src/tls/s_hello.cpp | 4 | ||||
-rw-r--r-- | src/tls/s_kex.cpp | 2 | ||||
-rw-r--r-- | src/tls/tls_alert.cpp | 46 | ||||
-rw-r--r-- | src/tls/tls_alert.h | 101 | ||||
-rw-r--r-- | src/tls/tls_alerts.h | 64 | ||||
-rw-r--r-- | src/tls/tls_channel.cpp | 38 | ||||
-rw-r--r-- | src/tls/tls_channel.h | 7 | ||||
-rw-r--r-- | src/tls/tls_client.cpp | 28 | ||||
-rw-r--r-- | src/tls/tls_client.h | 2 | ||||
-rw-r--r-- | src/tls/tls_exceptn.h | 10 | ||||
-rw-r--r-- | src/tls/tls_extensions.cpp | 2 | ||||
-rw-r--r-- | src/tls/tls_handshake_hash.cpp | 2 | ||||
-rw-r--r-- | src/tls/tls_magic.h | 39 | ||||
-rw-r--r-- | src/tls/tls_policy.cpp | 1 | ||||
-rw-r--r-- | src/tls/tls_record.h | 3 | ||||
-rw-r--r-- | src/tls/tls_server.cpp | 14 | ||||
-rw-r--r-- | src/tls/tls_server.h | 2 |
23 files changed, 224 insertions, 177 deletions
diff --git a/src/tls/c_hello.cpp b/src/tls/c_hello.cpp index 7397f9122..ecb6f43d6 100644 --- a/src/tls/c_hello.cpp +++ b/src/tls/c_hello.cpp @@ -336,7 +336,7 @@ void Client_Hello::deserialize(const MemoryRegion<byte>& buf) { if(!m_renegotiation_info.empty()) { - throw TLS_Exception(HANDSHAKE_FAILURE, + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Client send SCSV and non-empty extension"); } } diff --git a/src/tls/c_kex.cpp b/src/tls/c_kex.cpp index df96d9dec..2156973f1 100644 --- a/src/tls/c_kex.cpp +++ b/src/tls/c_kex.cpp @@ -138,7 +138,7 @@ Client_Key_Exchange::Client_Key_Exchange(Record_Writer& writer, append_tls_length_value(key_material, encrypted_key, 2); } else - throw TLS_Exception(HANDSHAKE_FAILURE, + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Expected a RSA key in server cert but got " + pub_key->algo_name()); } diff --git a/src/tls/finished.cpp b/src/tls/finished.cpp index 80385bd5e..140a3cb59 100644 --- a/src/tls/finished.cpp +++ b/src/tls/finished.cpp @@ -24,7 +24,7 @@ KDF* choose_tls_prf(Protocol_Version version) else if(version == Protocol_Version::TLS_V12) return new TLS_12_PRF(new HMAC(new SHA_256)); // might depend on ciphersuite else - throw TLS_Exception(PROTOCOL_VERSION, + throw TLS_Exception(Alert::PROTOCOL_VERSION, "Unknown version for PRF"); } diff --git a/src/tls/info.txt b/src/tls/info.txt index 0c52e14f0..31ce43c1e 100644 --- a/src/tls/info.txt +++ b/src/tls/info.txt @@ -8,6 +8,7 @@ serious bugs or security issues. uses_tr1 yes <header:public> +tls_alert.h tls_channel.h tls_client.h tls_exceptn.h @@ -22,7 +23,6 @@ tls_version.h </header:public> <header:internal> -tls_alerts.h tls_extensions.h tls_handshake_hash.h tls_handshake_state.h @@ -32,6 +32,7 @@ tls_session_key.h </header:internal> <source> +tls_alert.cpp c_hello.cpp c_kex.cpp cert_req.cpp diff --git a/src/tls/rec_read.cpp b/src/tls/rec_read.cpp index c4773d279..d1fab4692 100644 --- a/src/tls/rec_read.cpp +++ b/src/tls/rec_read.cpp @@ -147,7 +147,7 @@ size_t Record_Reader::fill_buffer_to(const byte*& input, const size_t taken = std::min(input_size, desired - m_readbuf_pos); if(taken > space_available) - throw TLS_Exception(RECORD_OVERFLOW, + throw TLS_Exception(Alert::RECORD_OVERFLOW, "Record is larger than allowed maximum size"); copy_mem(&m_readbuf[m_readbuf_pos], input, taken); @@ -184,7 +184,7 @@ size_t Record_Reader::add_input(const byte input_array[], size_t input_sz, if((!m_mac) && (m_readbuf[0] & 0x80) && (m_readbuf[2] == 1)) { if(m_readbuf[3] == 0 && m_readbuf[4] == 2) - throw TLS_Exception(PROTOCOL_VERSION, + throw TLS_Exception(Alert::PROTOCOL_VERSION, "Client claims to only support SSLv2, rejecting"); if(m_readbuf[3] >= 3) // SSLv2 mapped TLS hello, then? @@ -218,9 +218,8 @@ size_t Record_Reader::add_input(const byte input_array[], size_t input_sz, m_readbuf[0] != HANDSHAKE && m_readbuf[0] != APPLICATION_DATA) { - throw TLS_Exception(UNEXPECTED_MESSAGE, - "Unknown record type " + to_string(m_readbuf[0]) + - " from counterparty"); + throw Unexpected_Message( + "Unknown record type " + to_string(m_readbuf[0]) + " from counterparty"); } const size_t record_len = make_u16bit(m_readbuf[3], m_readbuf[4]); @@ -230,13 +229,13 @@ size_t Record_Reader::add_input(const byte input_array[], size_t input_sz, if(m_readbuf[1] != m_version.major_version() || m_readbuf[2] != m_version.minor_version()) { - throw TLS_Exception(PROTOCOL_VERSION, + throw TLS_Exception(Alert::PROTOCOL_VERSION, "Got unexpected version from counterparty"); } } if(record_len > MAX_CIPHERTEXT_SIZE) - throw TLS_Exception(RECORD_OVERFLOW, + throw TLS_Exception(Alert::RECORD_OVERFLOW, "Got message that exceeds maximum size"); if(size_t needed = fill_buffer_to(input, input_sz, consumed, @@ -254,7 +253,7 @@ size_t Record_Reader::add_input(const byte input_array[], size_t input_sz, m_readbuf[0] != ALERT && m_readbuf[0] != HANDSHAKE) { - throw TLS_Exception(DECODE_ERROR, "Invalid msg type received during handshake"); + throw Decoding_Error("Invalid msg type received during handshake"); } msg_type = m_readbuf[0]; @@ -316,7 +315,7 @@ size_t Record_Reader::add_input(const byte input_array[], size_t input_sz, const u16bit plain_length = record_len - mac_pad_iv_size; if(plain_length > m_max_fragment) - throw TLS_Exception(RECORD_OVERFLOW, "Plaintext record is too large"); + throw TLS_Exception(Alert::RECORD_OVERFLOW, "Plaintext record is too large"); m_mac->update_be(m_seq_no); m_mac->update(m_readbuf[0]); // msg_type @@ -337,7 +336,7 @@ size_t Record_Reader::add_input(const byte input_array[], size_t input_sz, const size_t mac_offset = record_len - (m_macbuf.size() + pad_size); if(!same_mem(&m_readbuf[TLS_HEADER_SIZE + mac_offset], &m_macbuf[0], m_macbuf.size())) - throw TLS_Exception(BAD_RECORD_MAC, "Message authentication failure"); + throw TLS_Exception(Alert::BAD_RECORD_MAC, "Message authentication failure"); msg_type = m_readbuf[0]; diff --git a/src/tls/rec_wri.cpp b/src/tls/rec_wri.cpp index 3e4ed01fb..602d25397 100644 --- a/src/tls/rec_wri.cpp +++ b/src/tls/rec_wri.cpp @@ -284,10 +284,12 @@ void Record_Writer::send_record(byte type, const byte input[], size_t length) /* * Send an alert */ -void Record_Writer::alert(Alert_Level level, Alert_Type type) +void Record_Writer::send_alert(const Alert& alert) { - byte alert[2] = { level, type }; - send(ALERT, alert, sizeof(alert)); + const byte alert_bits[2] = { alert.is_fatal() ? 2 : 1, + alert.type() }; + + send(ALERT, alert_bits, sizeof(alert_bits)); } } diff --git a/src/tls/s_hello.cpp b/src/tls/s_hello.cpp index caf89fb44..0ad78fc5b 100644 --- a/src/tls/s_hello.cpp +++ b/src/tls/s_hello.cpp @@ -46,7 +46,7 @@ Server_Hello::Server_Hello(Record_Writer& writer, false); if(suite == 0) - throw TLS_Exception(HANDSHAKE_FAILURE, + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Can't agree on a ciphersuite with client"); comp_method = policy.choose_compression(c_hello.compression_methods()); @@ -106,7 +106,7 @@ Server_Hello::Server_Hello(const MemoryRegion<byte>& buf) s_version != Protocol_Version::TLS_V11 && s_version != Protocol_Version::TLS_V12) { - throw TLS_Exception(PROTOCOL_VERSION, + throw TLS_Exception(Alert::PROTOCOL_VERSION, "Server_Hello: Unsupported server version"); } diff --git a/src/tls/s_kex.cpp b/src/tls/s_kex.cpp index 2c699ccd1..3ebdc3027 100644 --- a/src/tls/s_kex.cpp +++ b/src/tls/s_kex.cpp @@ -52,7 +52,7 @@ Server_Key_Exchange::Server_Key_Exchange(Record_Writer& writer, const std::string curve_name = policy.choose_curve(curves); if(curve_name == "") - throw TLS_Exception(HANDSHAKE_FAILURE, + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Could not agree on an ECC curve with the client"); EC_Group ec_group(curve_name); diff --git a/src/tls/tls_alert.cpp b/src/tls/tls_alert.cpp new file mode 100644 index 000000000..63cac9d79 --- /dev/null +++ b/src/tls/tls_alert.cpp @@ -0,0 +1,46 @@ +/* +* Alert Message +* (C) 2004-2006,2011 Jack Lloyd +* +* Released under the terms of the Botan license +*/ + +#include <botan/tls_alert.h> +#include <botan/exceptn.h> + +namespace Botan { + +namespace TLS { + +Alert::Alert(const MemoryRegion<byte>& buf) + { + if(buf.size() != 2) + throw Decoding_Error("Alert: Bad size " + to_string(buf.size()) + + " for alert message"); + + if(buf[0] == 1) fatal = false; + else if(buf[0] == 2) fatal = true; + else + throw Decoding_Error("Alert: Bad code for alert level"); + + const byte dc = buf[1]; + + /* + * This is allowed by the specification but is not allocated and we're + * using it internally as a special 'no alert' type. + */ + if(dc == 255) + throw Decoding_Error("Alert: description code 255, rejecting"); + + type_code = static_cast<Type>(dc); + } + +std::string Alert::type_string() const + { + return ""; + } + + +} + +} diff --git a/src/tls/tls_alert.h b/src/tls/tls_alert.h new file mode 100644 index 000000000..5a888805e --- /dev/null +++ b/src/tls/tls_alert.h @@ -0,0 +1,101 @@ +/* +* Alert Message +* (C) 2004-2006,2011 Jack Lloyd +* +* Released under the terms of the Botan license +*/ + +#ifndef BOTAN_TLS_ALERT_H__ +#define BOTAN_TLS_ALERT_H__ + +#include <botan/secmem.h> +#include <string> + +namespace Botan { + +namespace TLS { + +/** +* SSL/TLS Alert Message +*/ +class Alert + { + public: + enum Level { + WARNING = 1, + FATAL = 2 + }; + + enum Type { + CLOSE_NOTIFY = 0, + UNEXPECTED_MESSAGE = 10, + BAD_RECORD_MAC = 20, + DECRYPTION_FAILED = 21, + RECORD_OVERFLOW = 22, + DECOMPRESSION_FAILURE = 30, + HANDSHAKE_FAILURE = 40, + NO_CERTIFICATE = 41, // SSLv3 only + BAD_CERTIFICATE = 42, + UNSUPPORTED_CERTIFICATE = 43, + CERTIFICATE_REVOKED = 44, + CERTIFICATE_EXPIRED = 45, + CERTIFICATE_UNKNOWN = 46, + ILLEGAL_PARAMETER = 47, + UNKNOWN_CA = 48, + ACCESS_DENIED = 49, + DECODE_ERROR = 50, + DECRYPT_ERROR = 51, + EXPORT_RESTRICTION = 60, + PROTOCOL_VERSION = 70, + INSUFFICIENT_SECURITY = 71, + INTERNAL_ERROR = 80, + USER_CANCELED = 90, + NO_RENEGOTIATION = 100, + + UNSUPPORTED_EXTENSION = 110, + UNRECOGNIZED_NAME = 112, + + UNKNOWN_PSK_IDENTITY = 115, + + NULL_ALERT = 255 + }; + + /** + * @return true iff this alert is non-empty + */ + bool is_valid() const { return (type_code != NULL_ALERT); } + + /** + * @return if this alert is a fatal one or not + */ + bool is_fatal() const { return fatal; } + + /** + * @return type of alert + */ + Type type() const { return type_code; } + + /** + * @return type of alert + */ + std::string type_string() const; + + /** + * Deserialize an Alert message + * @param buf the serialized alert + */ + Alert(const MemoryRegion<byte>& buf); + + Alert(Level level, Type code) : fatal(level == FATAL), type_code(code) {} + + Alert() : fatal(false), type_code(NULL_ALERT) {} + private: + bool fatal; + Type type_code; + }; + +} + +} + +#endif diff --git a/src/tls/tls_alerts.h b/src/tls/tls_alerts.h deleted file mode 100644 index 2ccb1ad79..000000000 --- a/src/tls/tls_alerts.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -* Alert Message -* (C) 2004-2006,2011 Jack Lloyd -* -* Released under the terms of the Botan license -*/ - -#ifndef BOTAN_TLS_ALERT_H__ -#define BOTAN_TLS_ALERT_H__ - -#include <botan/tls_exceptn.h> - -namespace Botan { - -namespace TLS { - -/** -* SSL/TLS Alert Message -*/ -class Alert - { - public: - /** - * @return if this alert is a fatal one or not - */ - bool is_fatal() const { return fatal; } - - /** - * @return type of alert - */ - Alert_Type type() const { return type_code; } - - /** - * Deserialize an Alert message - * @param buf the serialized alert - */ - Alert(const MemoryRegion<byte>& buf) - { - if(buf.size() != 2) - throw Decoding_Error("Alert: Bad size " + to_string(buf.size()) + - " for alert message"); - - if(buf[0] == 1) fatal = false; - else if(buf[0] == 2) fatal = true; - else - throw Decoding_Error("Alert: Bad code for alert level"); - - const byte dc = buf[1]; - - if(dc == 255) - throw Decoding_Error("Alert: description code 255, rejecting"); - - type_code = static_cast<Alert_Type>(dc); - } - private: - bool fatal; - Alert_Type type_code; - }; - -} - -} - -#endif diff --git a/src/tls/tls_channel.cpp b/src/tls/tls_channel.cpp index 801dfdfe3..4c8cc4fbf 100644 --- a/src/tls/tls_channel.cpp +++ b/src/tls/tls_channel.cpp @@ -6,7 +6,6 @@ */ #include <botan/tls_channel.h> -#include <botan/internal/tls_alerts.h> #include <botan/internal/tls_handshake_state.h> #include <botan/internal/tls_messages.h> #include <botan/internal/assert.h> @@ -67,7 +66,7 @@ size_t Channel::received_data(const byte buf[], size_t buf_size) * following record. Avoid spurious callbacks. */ if(record.size() > 0) - proc_fn(&record[0], record.size(), NULL_ALERT); + proc_fn(&record[0], record.size(), Alert::NULL_ALERT); } else { @@ -82,16 +81,16 @@ size_t Channel::received_data(const byte buf[], size_t buf_size) { Alert alert_msg(record); - alert_notify(alert_msg.is_fatal(), alert_msg.type()); + alert_notify(alert_msg); proc_fn(0, 0, alert_msg.type()); - if(alert_msg.type() == CLOSE_NOTIFY) + if(alert_msg.type() == Alert::CLOSE_NOTIFY) { if(connection_closed) reader.reset(); else - alert(WARNING, CLOSE_NOTIFY); // reply in kind + send_alert(Alert(Alert::WARNING, Alert::CLOSE_NOTIFY)); // reply in kind } else if(alert_msg.is_fatal()) { @@ -114,22 +113,22 @@ size_t Channel::received_data(const byte buf[], size_t buf_size) } catch(TLS_Exception& e) { - alert(FATAL, e.type()); + send_alert(Alert(Alert::FATAL, e.type())); throw; } catch(Decoding_Error& e) { - alert(FATAL, DECODE_ERROR); + send_alert(Alert(Alert::FATAL, Alert::DECODE_ERROR)); throw; } catch(Internal_Error& e) { - alert(FATAL, INTERNAL_ERROR); + send_alert(Alert(Alert::FATAL, Alert::INTERNAL_ERROR)); throw; } catch(std::exception& e) { - alert(FATAL, INTERNAL_ERROR); + send_alert(Alert(Alert::FATAL, Alert::INTERNAL_ERROR)); throw; } } @@ -198,19 +197,18 @@ void Channel::send(const byte buf[], size_t buf_size) writer.send(APPLICATION_DATA, buf, buf_size); } -void Channel::alert(Alert_Level alert_level, Alert_Type alert_code) +void Channel::send_alert(const Alert& alert) { - if(alert_code != NULL_ALERT && !connection_closed) + if(alert.is_valid() && !connection_closed) { try { - writer.alert(alert_level, alert_code); + writer.send_alert(alert); } catch(...) { /* swallow it */ } } - if(!connection_closed && - (alert_code == CLOSE_NOTIFY || alert_level == FATAL)) + if(!connection_closed && (alert.type() == Alert::CLOSE_NOTIFY || alert.is_fatal())) { connection_closed = true; @@ -230,7 +228,7 @@ void Channel::Secure_Renegotiation_State::update(Client_Hello* client_hello) else { if(secure_renegotiation != client_hello->secure_renegotiation()) - throw TLS_Exception(HANDSHAKE_FAILURE, + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Client changed its mind about secure renegotiation"); } @@ -241,13 +239,13 @@ void Channel::Secure_Renegotiation_State::update(Client_Hello* client_hello) if(initial_handshake) { if(!data.empty()) - throw TLS_Exception(HANDSHAKE_FAILURE, + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Client sent renegotiation data on initial handshake"); } else { if(data != for_client_hello()) - throw TLS_Exception(HANDSHAKE_FAILURE, + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Client sent bad renegotiation data"); } } @@ -265,7 +263,7 @@ void Channel::Secure_Renegotiation_State::update(Server_Hello* server_hello) else { if(secure_renegotiation != server_hello->secure_renegotiation()) - throw TLS_Exception(HANDSHAKE_FAILURE, + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Server changed its mind about secure renegotiation"); } @@ -276,13 +274,13 @@ void Channel::Secure_Renegotiation_State::update(Server_Hello* server_hello) if(initial_handshake) { if(!data.empty()) - throw TLS_Exception(HANDSHAKE_FAILURE, + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Server sent renegotiation data on initial handshake"); } else { if(data != for_server_hello()) - throw TLS_Exception(HANDSHAKE_FAILURE, + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Server sent bad renegotiation data"); } } diff --git a/src/tls/tls_channel.h b/src/tls/tls_channel.h index 6021b65b2..75d2b5918 100644 --- a/src/tls/tls_channel.h +++ b/src/tls/tls_channel.h @@ -11,6 +11,7 @@ #include <botan/tls_policy.h> #include <botan/tls_record.h> #include <botan/tls_session.h> +#include <botan/tls_alert.h> #include <botan/x509cert.h> #include <vector> @@ -39,7 +40,7 @@ class BOTAN_DLL Channel /** * Send a close notification alert */ - void close() { alert(WARNING, CLOSE_NOTIFY); } + void close() { send_alert(Alert(Alert::WARNING, Alert::CLOSE_NOTIFY)); } /** * @return true iff the connection is active for sending application data @@ -74,7 +75,7 @@ class BOTAN_DLL Channel * @param level is warning or fatal * @param type is the type of alert */ - void alert(Alert_Level level, Alert_Type type); + void send_alert(const Alert& alert); virtual void read_handshake(byte rec_type, const MemoryRegion<byte>& rec_buf); @@ -82,7 +83,7 @@ class BOTAN_DLL Channel virtual void process_handshake_msg(Handshake_Type type, const MemoryRegion<byte>& contents) = 0; - virtual void alert_notify(bool fatal_alert, Alert_Type type) = 0; + virtual void alert_notify(const Alert& alert) = 0; std::tr1::function<void (const byte[], size_t, u16bit)> proc_fn; std::tr1::function<bool (const Session&)> handshake_fn; diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp index d733733be..0fb80e034 100644 --- a/src/tls/tls_client.cpp +++ b/src/tls/tls_client.cpp @@ -96,9 +96,9 @@ void Client::renegotiate() secure_renegotiation.update(state->client_hello); } -void Client::alert_notify(bool, Alert_Type type) +void Client::alert_notify(bool, Alert::Type type) { - if(type == NO_RENEGOTIATION) + if(type == Alert::NO_RENEGOTIATION) { if(handshake_completed && state) { @@ -131,7 +131,7 @@ void Client::process_handshake_msg(Handshake_Type type, state = 0; // RFC 5746 section 4.2 - alert(WARNING, NO_RENEGOTIATION); + send_alert(Alert(Alert::WARNING, Alert::NO_RENEGOTIATION)); return; } @@ -155,21 +155,21 @@ void Client::process_handshake_msg(Handshake_Type type, if(!state->client_hello->offered_suite(state->server_hello->ciphersuite())) { - throw TLS_Exception(HANDSHAKE_FAILURE, + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Server replied with ciphersuite we didn't send"); } if(!value_exists(state->client_hello->compression_methods(), state->server_hello->compression_method())) { - throw TLS_Exception(HANDSHAKE_FAILURE, + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Server replied with compression method we didn't send"); } if(!state->client_hello->next_protocol_notification() && state->server_hello->next_protocol_notification()) { - throw TLS_Exception(HANDSHAKE_FAILURE, + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Server sent next protocol but we didn't request it"); } @@ -192,7 +192,7 @@ void Client::process_handshake_msg(Handshake_Type type, * session, and the server must resume with the same version. */ if(state->server_hello->version() != state->client_hello->version()) - throw TLS_Exception(HANDSHAKE_FAILURE, + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Server resumed session but with wrong version"); state->keys = Session_Keys(state, @@ -207,13 +207,13 @@ void Client::process_handshake_msg(Handshake_Type type, if(state->version > state->client_hello->version()) { - throw TLS_Exception(HANDSHAKE_FAILURE, + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Client: Server replied with bad version"); } if(state->version < policy.min_version()) { - throw TLS_Exception(PROTOCOL_VERSION, + throw TLS_Exception(Alert::PROTOCOL_VERSION, "Client: Server is too old for specified policy"); } @@ -248,7 +248,7 @@ void Client::process_handshake_msg(Handshake_Type type, peer_certs = state->server_certs->cert_chain(); if(peer_certs.size() == 0) - throw TLS_Exception(HANDSHAKE_FAILURE, + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Client: No certificates sent by server"); try @@ -258,13 +258,13 @@ void Client::process_handshake_msg(Handshake_Type type, } catch(std::exception& e) { - throw TLS_Exception(BAD_CERTIFICATE, e.what()); + throw TLS_Exception(Alert::BAD_CERTIFICATE, e.what()); } std::auto_ptr<Public_Key> peer_key(peer_certs[0].subject_public_key()); if(peer_key->algo_name() != state->suite.sig_algo()) - throw TLS_Exception(ILLEGAL_PARAMETER, + throw TLS_Exception(Alert::ILLEGAL_PARAMETER, "Certificate key type did not match ciphersuite"); } else if(type == SERVER_KEX) @@ -281,7 +281,7 @@ void Client::process_handshake_msg(Handshake_Type type, { if(!state->server_kex->verify(peer_certs[0], state)) { - throw TLS_Exception(DECRYPT_ERROR, + throw TLS_Exception(Alert::DECRYPT_ERROR, "Bad signature on server key exchange"); } } @@ -365,7 +365,7 @@ void Client::process_handshake_msg(Handshake_Type type, state->server_finished = new Finished(contents); if(!state->server_finished->verify(state, SERVER)) - throw TLS_Exception(DECRYPT_ERROR, + throw TLS_Exception(Alert::DECRYPT_ERROR, "Finished message didn't verify"); state->hash.update(type, contents); diff --git a/src/tls/tls_client.h b/src/tls/tls_client.h index d67a14b75..9f8e33f30 100644 --- a/src/tls/tls_client.h +++ b/src/tls/tls_client.h @@ -58,7 +58,7 @@ class BOTAN_DLL Client : public Channel void process_handshake_msg(Handshake_Type type, const MemoryRegion<byte>& contents); - void alert_notify(bool is_fatal, Alert_Type type); + void alert_notify(bool is_fatal, Alert::Type type); const Policy& policy; RandomNumberGenerator& rng; diff --git a/src/tls/tls_exceptn.h b/src/tls/tls_exceptn.h index f29f008be..ad19c6c9d 100644 --- a/src/tls/tls_exceptn.h +++ b/src/tls/tls_exceptn.h @@ -9,7 +9,7 @@ #define BOTAN_TLS_EXCEPTION_H__ #include <botan/exceptn.h> -#include <botan/tls_magic.h> +#include <botan/tls_alert.h> namespace Botan { @@ -21,14 +21,14 @@ namespace TLS { class BOTAN_DLL TLS_Exception : public Exception { public: - Alert_Type type() const throw() { return alert_type; } + Alert::Type type() const throw() { return alert_type; } - TLS_Exception(Alert_Type type, + TLS_Exception(Alert::Type type, const std::string& err_msg = "Unknown error") : Exception(err_msg), alert_type(type) {} private: - Alert_Type alert_type; + Alert::Type alert_type; }; /** @@ -37,7 +37,7 @@ class BOTAN_DLL TLS_Exception : public Exception struct BOTAN_DLL Unexpected_Message : public TLS_Exception { Unexpected_Message(const std::string& err) : - TLS_Exception(UNEXPECTED_MESSAGE, err) {} + TLS_Exception(Alert::UNEXPECTED_MESSAGE, err) {} }; } diff --git a/src/tls/tls_extensions.cpp b/src/tls/tls_extensions.cpp index 20f687514..250f25035 100644 --- a/src/tls/tls_extensions.cpp +++ b/src/tls/tls_extensions.cpp @@ -223,7 +223,7 @@ size_t Maximum_Fragment_Length::fragment_size() const case 4: return 4096; default: - throw TLS_Exception(ILLEGAL_PARAMETER, + throw TLS_Exception(Alert::ILLEGAL_PARAMETER, "Bad value in maximum fragment extension"); } } diff --git a/src/tls/tls_handshake_hash.cpp b/src/tls/tls_handshake_hash.cpp index 491b4f6c0..1e5bd63a3 100644 --- a/src/tls/tls_handshake_hash.cpp +++ b/src/tls/tls_handshake_hash.cpp @@ -54,7 +54,7 @@ SecureVector<byte> Handshake_Hash::final(Protocol_Version version) output += sha256.final(); } else - throw TLS_Exception(PROTOCOL_VERSION, + throw TLS_Exception(Alert::PROTOCOL_VERSION, "Unknown version for handshake hashes"); return output; diff --git a/src/tls/tls_magic.h b/src/tls/tls_magic.h index e6a055b57..169b4b1e0 100644 --- a/src/tls/tls_magic.h +++ b/src/tls/tls_magic.h @@ -55,45 +55,6 @@ enum Handshake_Type { HANDSHAKE_NONE = 255 // Null value }; -enum Alert_Level { - WARNING = 1, - FATAL = 2 -}; - -enum Alert_Type { - CLOSE_NOTIFY = 0, - UNEXPECTED_MESSAGE = 10, - BAD_RECORD_MAC = 20, - DECRYPTION_FAILED = 21, - RECORD_OVERFLOW = 22, - DECOMPRESSION_FAILURE = 30, - HANDSHAKE_FAILURE = 40, - NO_CERTIFICATE = 41, // SSLv3 only - BAD_CERTIFICATE = 42, - UNSUPPORTED_CERTIFICATE = 43, - CERTIFICATE_REVOKED = 44, - CERTIFICATE_EXPIRED = 45, - CERTIFICATE_UNKNOWN = 46, - ILLEGAL_PARAMETER = 47, - UNKNOWN_CA = 48, - ACCESS_DENIED = 49, - DECODE_ERROR = 50, - DECRYPT_ERROR = 51, - EXPORT_RESTRICTION = 60, - PROTOCOL_VERSION = 70, - INSUFFICIENT_SECURITY = 71, - INTERNAL_ERROR = 80, - USER_CANCELED = 90, - NO_RENEGOTIATION = 100, - - UNSUPPORTED_EXTENSION = 110, - UNRECOGNIZED_NAME = 112, - - UNKNOWN_PSK_IDENTITY = 115, - - NULL_ALERT = 255 -}; - enum Ciphersuite_Code { TLS_RSA_WITH_RC4_128_MD5 = 0x0004, TLS_RSA_WITH_RC4_128_SHA = 0x0005, diff --git a/src/tls/tls_policy.cpp b/src/tls/tls_policy.cpp index 6d95ada40..870afc6d0 100644 --- a/src/tls/tls_policy.cpp +++ b/src/tls/tls_policy.cpp @@ -7,6 +7,7 @@ #include <botan/tls_policy.h> #include <botan/tls_ciphersuite.h> +#include <botan/tls_magic.h> #include <botan/tls_exceptn.h> #include <botan/internal/stl_util.h> diff --git a/src/tls/tls_record.h b/src/tls/tls_record.h index 74b7e56a2..3bc58a0da 100644 --- a/src/tls/tls_record.h +++ b/src/tls/tls_record.h @@ -9,6 +9,7 @@ #define BOTAN_TLS_RECORDS_H__ #include <botan/tls_ciphersuite.h> +#include <botan/tls_alert.h> #include <botan/tls_magic.h> #include <botan/tls_version.h> #include <botan/pipe.h> @@ -45,7 +46,7 @@ class BOTAN_DLL Record_Writer void send(byte type, const byte input[], size_t length); void send(byte type, byte val) { send(type, &val, 1); } - void alert(Alert_Level level, Alert_Type type); + void send_alert(const Alert& alert); void activate(Connection_Side side, const Ciphersuite& suite, diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp index d3137a29e..d5357f86e 100644 --- a/src/tls/tls_server.cpp +++ b/src/tls/tls_server.cpp @@ -97,9 +97,9 @@ void Server::renegotiate() Hello_Request hello_req(writer); } -void Server::alert_notify(bool, Alert_Type type) +void Server::alert_notify(bool, Alert::Type type) { - if(type == NO_RENEGOTIATION) + if(type == Alert::NO_RENEGOTIATION) { if(handshake_completed && state) { @@ -159,7 +159,7 @@ void Server::process_handshake_msg(Handshake_Type type, Protocol_Version client_version = state->client_hello->version(); if(client_version < policy.min_version()) - throw TLS_Exception(PROTOCOL_VERSION, + throw TLS_Exception(Alert::PROTOCOL_VERSION, "Client version is unacceptable by policy"); if(client_version <= policy.pref_version()) @@ -322,7 +322,7 @@ void Server::process_handshake_msg(Handshake_Type type, // Is this allowed by the protocol? if(state->client_certs->count() > 1) - throw TLS_Exception(CERTIFICATE_UNKNOWN, + throw TLS_Exception(Alert::CERTIFICATE_UNKNOWN, "Client sent more than one certificate"); state->set_expected_next(CLIENT_KEX); @@ -360,7 +360,7 @@ void Server::process_handshake_msg(Handshake_Type type, * unable to correctly verify a signature, ..." */ if(!sig_valid) - throw TLS_Exception(DECRYPT_ERROR, "Client cert verify failed"); + throw TLS_Exception(Alert::DECRYPT_ERROR, "Client cert verify failed"); try { @@ -368,7 +368,7 @@ void Server::process_handshake_msg(Handshake_Type type, } catch(std::exception& e) { - throw TLS_Exception(BAD_CERTIFICATE, e.what()); + throw TLS_Exception(Alert::BAD_CERTIFICATE, e.what()); } state->set_expected_next(HANDSHAKE_CCS); @@ -398,7 +398,7 @@ void Server::process_handshake_msg(Handshake_Type type, state->client_finished = new Finished(contents); if(!state->client_finished->verify(state, CLIENT)) - throw TLS_Exception(DECRYPT_ERROR, + throw TLS_Exception(Alert::DECRYPT_ERROR, "Finished message didn't verify"); // already sent it if resuming diff --git a/src/tls/tls_server.h b/src/tls/tls_server.h index c283d4a18..5be2b1bb0 100644 --- a/src/tls/tls_server.h +++ b/src/tls/tls_server.h @@ -55,7 +55,7 @@ class BOTAN_DLL Server : public Channel void process_handshake_msg(Handshake_Type, const MemoryRegion<byte>&); - void alert_notify(bool is_fatal, Alert_Type type); + void alert_notify(bool is_fatal, Alert::Type type); const Policy& policy; RandomNumberGenerator& rng; |