Botan  1.11.15
src/lib/tls/tls_heartbeats.cpp
Go to the documentation of this file.
00001 /*
00002 * TLS Heartbeats
00003 * (C) 2012,2015 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/internal/tls_heartbeats.h>
00009 #include <botan/internal/tls_extensions.h>
00010 #include <botan/internal/tls_reader.h>
00011 #include <botan/tls_exceptn.h>
00012 
00013 namespace Botan {
00014 
00015 namespace TLS {
00016 
00017 Heartbeat_Message::Heartbeat_Message(const std::vector<byte>& buf)
00018    {
00019    TLS_Data_Reader reader("Heartbeat", buf);
00020 
00021    const byte type = reader.get_byte();
00022 
00023    if(type != 1 && type != 2)
00024       throw TLS_Exception(Alert::ILLEGAL_PARAMETER,
00025                           "Unknown heartbeat message type");
00026 
00027    m_type = static_cast<Type>(type);
00028 
00029    m_payload = reader.get_range<byte>(2, 0, 16*1024);
00030 
00031    m_padding = reader.get_remaining();
00032 
00033    if(m_padding.size() < 16)
00034       throw Decoding_Error("Invalid heartbeat padding");
00035    }
00036 
00037 Heartbeat_Message::Heartbeat_Message(Type type,
00038                                      const byte payload[],
00039                                      size_t payload_len,
00040                                      const std::vector<byte>& padding) :
00041    m_type(type),
00042    m_payload(payload, payload + payload_len),
00043    m_padding(padding)
00044    {
00045    if(payload_len >= 64*1024)
00046       throw std::runtime_error("Heartbeat payload too long");
00047    if(m_padding.size() < 16)
00048       throw std::runtime_error("Invalid heartbeat padding length");
00049    }
00050 
00051 std::vector<byte> Heartbeat_Message::contents() const
00052    {
00053    //std::vector<byte> send_buf(3 + m_payload.size() + 16);
00054    std::vector<byte> send_buf;
00055    send_buf.reserve(3 + m_payload.size() + m_padding.size());
00056 
00057    send_buf.push_back(m_type);
00058    send_buf.push_back(get_byte<u16bit>(0, m_payload.size()));
00059    send_buf.push_back(get_byte<u16bit>(1, m_payload.size()));
00060    send_buf += m_payload;
00061    send_buf += m_padding;
00062 
00063    return send_buf;
00064    }
00065 
00066 std::vector<byte> Heartbeat_Support_Indicator::serialize() const
00067    {
00068    std::vector<byte> heartbeat(1);
00069    heartbeat[0] = (m_peer_allowed_to_send ? 1 : 2);
00070    return heartbeat;
00071    }
00072 
00073 Heartbeat_Support_Indicator::Heartbeat_Support_Indicator(TLS_Data_Reader& reader,
00074                                                          u16bit extension_size)
00075    {
00076    if(extension_size != 1)
00077       throw Decoding_Error("Strange size for heartbeat extension");
00078 
00079    const byte code = reader.get_byte();
00080 
00081    if(code != 1 && code != 2)
00082       throw TLS_Exception(Alert::ILLEGAL_PARAMETER,
00083                           "Unknown heartbeat code " + std::to_string(code));
00084 
00085    m_peer_allowed_to_send = (code == 1);
00086    }
00087 
00088 }
00089 
00090 }