diff options
Diffstat (limited to 'src/tls')
-rw-r--r-- | src/tls/tls_channel.cpp | 41 | ||||
-rw-r--r-- | src/tls/tls_magic.h | 2 | ||||
-rw-r--r-- | src/tls/tls_record.cpp | 20 |
3 files changed, 22 insertions, 41 deletions
diff --git a/src/tls/tls_channel.cpp b/src/tls/tls_channel.cpp index 382671afe..9fb41c9f6 100644 --- a/src/tls/tls_channel.cpp +++ b/src/tls/tls_channel.cpp @@ -183,7 +183,7 @@ size_t Channel::received_data(const byte buf[], size_t buf_size) { while(buf_size) { - byte rec_type = CONNECTION_CLOSED; + byte rec_type = NO_RECORD; std::vector<byte> record; u64bit record_number = 0; Protocol_Version record_version; @@ -214,15 +214,14 @@ size_t Channel::received_data(const byte buf[], size_t buf_size) if(buf_size == 0 && needed != 0) return needed; // need more data to complete record + if(rec_type == NO_RECORD) + continue; + if(record.size() > m_max_fragment) throw TLS_Exception(Alert::RECORD_OVERFLOW, "Plaintext record is too large"); - if(rec_type == CONNECTION_CLOSED) - { - continue; - } - else if(rec_type == HANDSHAKE || rec_type == CHANGE_CIPHER_SPEC) + if(rec_type == HANDSHAKE || rec_type == CHANGE_CIPHER_SPEC) { if(!m_pending_state) { @@ -247,6 +246,9 @@ size_t Channel::received_data(const byte buf[], size_t buf_size) } else if(rec_type == HEARTBEAT && peer_supports_heartbeats()) { + if(!m_active_state) + throw Unexpected_Message("Heartbeat sent before handshake done"); + Heartbeat_Message heartbeat(record); const std::vector<byte>& payload = heartbeat.payload(); @@ -269,20 +271,16 @@ size_t Channel::received_data(const byte buf[], size_t buf_size) } else if(rec_type == APPLICATION_DATA) { - if(m_active_state) - { - /* - * OpenSSL among others sends empty records in versions - * before TLS v1.1 in order to randomize the IV of the - * following record. Avoid spurious callbacks. - */ - if(record.size() > 0) - m_proc_fn(&record[0], record.size(), Alert()); - } - else - { + if(!m_active_state) throw Unexpected_Message("Application data before handshake done"); - } + + /* + * OpenSSL among others sends empty records in versions + * before TLS v1.1 in order to randomize the IV of the + * following record. Avoid spurious callbacks. + */ + if(record.size() > 0) + m_proc_fn(&record[0], record.size(), Alert()); } else if(rec_type == ALERT) { @@ -317,8 +315,9 @@ size_t Channel::received_data(const byte buf[], size_t buf_size) } } else - throw Unexpected_Message("Unknown TLS message type " + - std::to_string(rec_type) + " received"); + throw Unexpected_Message("Unknown record type " + + std::to_string(readbuf[0]) + + " from counterparty"); } return 0; // on a record boundary diff --git a/src/tls/tls_magic.h b/src/tls/tls_magic.h index 0b3b15c06..5aae03281 100644 --- a/src/tls/tls_magic.h +++ b/src/tls/tls_magic.h @@ -29,7 +29,7 @@ enum Size_Limits { enum Connection_Side { CLIENT = 1, SERVER = 2 }; enum Record_Type { - CONNECTION_CLOSED = 0, + NO_RECORD = 0, CHANGE_CIPHER_SPEC = 20, ALERT = 21, diff --git a/src/tls/tls_record.cpp b/src/tls/tls_record.cpp index 5aa69747f..e77974a58 100644 --- a/src/tls/tls_record.cpp +++ b/src/tls/tls_record.cpp @@ -328,17 +328,6 @@ size_t read_record(std::vector<byte>& readbuf, } } - if(readbuf[0] != CHANGE_CIPHER_SPEC && - readbuf[0] != ALERT && - readbuf[0] != HANDSHAKE && - readbuf[0] != APPLICATION_DATA && - readbuf[0] != HEARTBEAT) - { - throw Unexpected_Message( - "Unknown record type " + std::to_string(readbuf[0]) + - " from counterparty"); - } - record_version = Protocol_Version(readbuf[1], readbuf[2]); if(record_version.is_datagram_protocol() && readbuf_pos < DTLS_HEADER_SIZE) @@ -385,15 +374,8 @@ size_t read_record(std::vector<byte>& readbuf, byte* record_contents = &readbuf[header_size]; - if(!cipherstate) // Only handshake messages allowed during initial handshake + if(!cipherstate) // Unencrypted initial handshake { - if(readbuf[0] != CHANGE_CIPHER_SPEC && - readbuf[0] != ALERT && - readbuf[0] != HANDSHAKE) - { - throw Decoding_Error("Invalid msg type received during handshake"); - } - msg_type = readbuf[0]; msg.assign(&record_contents[0], &record_contents[record_len]); |