diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bogo_shim/bogo_shim.cpp | 45 | ||||
-rw-r--r-- | src/bogo_shim/config.json | 14 | ||||
-rw-r--r-- | src/lib/tls/tls_channel.cpp | 39 | ||||
-rw-r--r-- | src/lib/tls/tls_channel.h | 2 |
4 files changed, 58 insertions, 42 deletions
diff --git a/src/bogo_shim/bogo_shim.cpp b/src/bogo_shim/bogo_shim.cpp index 3745bc4d8..16dc71fd9 100644 --- a/src/bogo_shim/bogo_shim.cpp +++ b/src/bogo_shim/bogo_shim.cpp @@ -132,6 +132,8 @@ std::string map_to_bogo_error(const std::string& e) { "Received a record that exceeds maximum size", ":ENCRYPTED_LENGTH_TOO_LONG:" }, { "Received unexpected record version in initial record", ":WRONG_VERSION_NUMBER:" }, { "Received unexpected record version", ":WRONG_VERSION_NUMBER:" }, + { "Received application data after connection closure", ":APPLICATION_DATA_ON_SHUTDOWN:" }, + { "Received handshake data after connection closure", ":NO_RENEGOTIATION:" }, { "Server certificate changed during renegotiation", ":SERVER_CERT_CHANGED:" }, { "Server changed its mind about extended master secret", ":RENEGOTIATION_EMS_MISMATCH:" }, { "Server changed its mind about secure renegotiation", ":RENEGOTIATION_MISMATCH:" }, @@ -1238,12 +1240,14 @@ class Shim_Callbacks final : public Botan::TLS::Callbacks m_channel = channel; } + bool saw_close_notify() const { return m_got_close; } + void tls_emit_data(const uint8_t data[], size_t size) override { + shim_log("sending record of len " + std::to_string(size)); + if(m_is_datagram) { - shim_log("sending record of len " + std::to_string(size)); - std::vector<uint8_t> packet(size + 5); packet[0] = 'P'; @@ -1289,6 +1293,8 @@ class Shim_Callbacks final : public Botan::TLS::Callbacks m_empty_records = 0; } + shim_log("Reflecting application_data len " + std::to_string(size)); + std::vector<uint8_t> buf(data, data + size); for(size_t i = 0; i != size; ++i) buf[i] ^= 0xFF; @@ -1361,13 +1367,21 @@ class Shim_Callbacks final : public Botan::TLS::Callbacks void tls_alert(Botan::TLS::Alert alert) override { - shim_log("Got an alert " + alert.type_string()); + if(alert.is_fatal()) + shim_log("Got a fatal alert " + alert.type_string()); + else + shim_log("Got a warning alert " + alert.type_string()); if(alert.type() == Botan::TLS::Alert::RECORD_OVERFLOW) { shim_exit_with_error(":TLSV1_ALERT_RECORD_OVERFLOW:"); } + if(alert.type() == Botan::TLS::Alert::DECOMPRESSION_FAILURE) + { + shim_exit_with_error(":SSLV3_ALERT_DECOMPRESSION_FAILURE:"); + } + if(!alert.is_fatal()) { m_warning_alerts++; @@ -1377,11 +1391,16 @@ class Shim_Callbacks final : public Botan::TLS::Callbacks if(alert.type() == Botan::TLS::Alert::CLOSE_NOTIFY) { - if(m_got_close == false) + if(m_got_close == false && !m_args.flag_set("shim-shuts-down")) { + shim_log("Sending return close notify"); m_channel->send_alert(alert); - m_got_close = true; } + m_got_close = true; + } + else if(alert.is_fatal()) + { + shim_exit_with_error("Unexpected fatal alert " + alert.type_string()); } } @@ -1466,7 +1485,10 @@ class Shim_Callbacks final : public Botan::TLS::Callbacks } if(m_args.flag_set("shim-shuts-down")) + { + shim_log("Shim shutting down"); m_channel->close(); + } if(m_args.flag_set("write-different-record-sizes")) { @@ -1607,14 +1629,25 @@ int main(int /*argc*/, char* argv[]) break; } + shim_log("Got packet of " + std::to_string(got)); + if(args->flag_set("use-exporter-between-reads") && chan->is_active()) { chan->key_material_export("some label", "some context", 42); } - chan->received_data(buf.data(), got); + const size_t needed = chan->received_data(buf.data(), got); + + if(needed) + shim_log("Short read still need " + std::to_string(needed)); } } + if(args->flag_set("check-close-notify")) + { + if(!callbacks.saw_close_notify()) + throw Shim_Exception("Unexpected SSL_shutdown result: -1 != 1"); + } + if(args->option_used("expect-total-renegotiations")) { const size_t exp = args->get_int_opt("expect-total-renegotiations"); diff --git a/src/bogo_shim/config.json b/src/bogo_shim/config.json index 905a7e8cd..ee488109f 100644 --- a/src/bogo_shim/config.json +++ b/src/bogo_shim/config.json @@ -88,11 +88,6 @@ "ALPNServer-SelectEmpty-*": "Botan treats empty ALPN from callback as a decline", - "ServerAuth-Verify-ECDSA-P521-SHA512-TLS12": "BoringSSL will sign SHA-1 and SHA-512 with ECDSA but not accept them.", - "ServerAuth-Verify-ECDSA-SHA1-TLS12": "BoringSSL will sign SHA-1 and SHA-512 with ECDSA but not accept them.", - "ClientAuth-Verify-ECDSA-P521-SHA512-TLS12": "BoringSSL will sign SHA-1 and SHA-512 with ECDSA but not accept them.", - "ClientAuth-Verify-ECDSA-SHA1-TLS12": "BoringSSL will sign SHA-1 and SHA-512 with ECDSA but not accept them.", - "AppDataAfterChangeCipherSpec-DTLS*": "BoringSSL DTLS drops out of order AppData, we reject", "Resume-Client-NoResume-TLS1-TLS11": "BoGo expects resumption attempt sends latest version", @@ -115,15 +110,6 @@ "DTLS-StrayRetransmitFinished-ClientFull": "Needs investigation", "DTLS-StrayRetransmitFinished-ServerResume": "Needs investigation", - "MixCompleteMessageWithFragments-DTLS": "Needs investigation", - "ReorderHandshakeFragments-Small-DTLS": "Needs investigation", - - "Shutdown-Shim-ApplicationData*": "Needs investigation", - "Shutdown-Shim-HelloRequest-CannotHandshake*": "Needs investigation", - "Shutdown-Shim-HelloRequest-Reject*": "Needs investigation", - "Shutdown-Shim-Renegotiate-Server-Forbidden*": "Needs investigation", - "Unclean-Shutdown": "Needs investigation", - "Unclean-Shutdown-Alert": "Needs investigation", "SRTP-Server-IgnoreMKI-*": "Non-empty MKI is rejected (bug)", diff --git a/src/lib/tls/tls_channel.cpp b/src/lib/tls/tls_channel.cpp index 366bef9c3..9d3f2d30d 100644 --- a/src/lib/tls/tls_channel.cpp +++ b/src/lib/tls/tls_channel.cpp @@ -35,7 +35,8 @@ Channel::Channel(Callbacks& callbacks, m_callbacks(callbacks), m_session_manager(session_manager), m_policy(policy), - m_rng(rng) + m_rng(rng), + m_has_been_closed(false) { init(reserved_io_buffer_size); } @@ -63,7 +64,8 @@ Channel::Channel(output_fn out, m_callbacks(*m_compat_callbacks.get()), m_session_manager(session_manager), m_policy(policy), - m_rng(rng) + m_rng(rng), + m_has_been_closed(false) { init(io_buf_sz); } @@ -281,23 +283,7 @@ bool Channel::is_active() const bool Channel::is_closed() const { - if(active_state() || pending_state()) - return false; - - /* - * If no active or pending state, then either we had a connection - * and it has been closed, or we are a server which has never - * received a connection. This case is detectable by also lacking - * m_sequence_numbers - */ - if(m_is_server) - { - return (m_sequence_numbers != nullptr); - } - else - { - return true; - } + return m_has_been_closed; } void Channel::activate_session() @@ -331,7 +317,7 @@ size_t Channel::received_data(const uint8_t input[], size_t input_size) try { - while(!is_closed() && input_size) + while(input_size) { size_t consumed = 0; @@ -415,10 +401,14 @@ size_t Channel::received_data(const uint8_t input[], size_t input_size) if(record.type() == HANDSHAKE || record.type() == CHANGE_CIPHER_SPEC) { + if(m_has_been_closed) + throw TLS_Exception(Alert::UNEXPECTED_MESSAGE, "Received handshake data after connection closure"); process_handshake_ccs(m_record_buf, record.sequence(), record.type(), record.version(), epoch0_restart); } else if(record.type() == APPLICATION_DATA) { + if(m_has_been_closed) + throw TLS_Exception(Alert::UNEXPECTED_MESSAGE, "Received application data after connection closure"); if(pending_state() != nullptr) throw TLS_Exception(Alert::UNEXPECTED_MESSAGE, "Can't interleave application and handshake data"); process_application_data(record.sequence(), m_record_buf); @@ -554,7 +544,7 @@ void Channel::process_alert(const secure_vector<uint8_t>& record) if(alert_msg.type() == Alert::CLOSE_NOTIFY || alert_msg.is_fatal()) { - reset_state(); + m_has_been_closed = true; } } @@ -670,8 +660,13 @@ void Channel::send_alert(const Alert& alert) if(auto active = active_state()) m_session_manager.remove_entry(active->server_hello()->session_id()); - if(alert.type() == Alert::CLOSE_NOTIFY || alert.is_fatal()) + if(alert.is_fatal()) reset_state(); + + if(alert.type() == Alert::CLOSE_NOTIFY || alert.is_fatal()) + { + m_has_been_closed = true; + } } void Channel::secure_renegotiation_check(const Client_Hello* client_hello) diff --git a/src/lib/tls/tls_channel.h b/src/lib/tls/tls_channel.h index 8f977932b..f0ead400d 100644 --- a/src/lib/tls/tls_channel.h +++ b/src/lib/tls/tls_channel.h @@ -311,6 +311,8 @@ class BOTAN_PUBLIC_API(2,0) Channel secure_vector<uint8_t> m_writebuf; secure_vector<uint8_t> m_readbuf; secure_vector<uint8_t> m_record_buf; + + bool m_has_been_closed; }; } |