1 /** 2 * TLS Heartbeats 3 * 4 * Copyright: 5 * (C) 2012 Jack Lloyd 6 * (C) 2014-2015 Etienne Cimon 7 * 8 * License: 9 * Botan is released under the Simplified BSD License (see LICENSE.md) 10 */ 11 module botan.tls.heartbeats; 12 13 import botan.constants; 14 static if (BOTAN_HAS_TLS): 15 package: 16 17 import memutils.vector; 18 import botan.tls.extensions; 19 import botan.tls.reader; 20 import botan.tls.exceptn; 21 import botan.utils.types; 22 23 /** 24 * TLS Heartbeat message 25 */ 26 struct HeartbeatMessage 27 { 28 public: 29 alias MessageType = ubyte; 30 enum : MessageType { REQUEST = 1, RESPONSE = 2 } 31 32 Vector!ubyte contents() const 33 { 34 Vector!ubyte send_buf = Vector!ubyte(3 + m_payload.length + 16); 35 send_buf[0] = m_type; 36 send_buf[1] = get_byte(0, cast(ushort) m_payload.length); 37 send_buf[2] = get_byte(1, cast(ushort) m_payload.length); 38 copyMem(&send_buf[3], m_payload.ptr, m_payload.length); 39 // leave padding as all zeros 40 41 return send_buf; 42 } 43 44 ref const(Vector!ubyte) payload() const { return m_payload; } 45 46 bool isRequest() const { return m_type == REQUEST; } 47 48 this()(auto const ref Vector!ubyte buf) 49 { 50 TLSDataReader reader = TLSDataReader("Heartbeat", buf); 51 52 const ubyte type = reader.get_byte(); 53 54 if (type != 1 && type != 2) 55 throw new TLSException(TLSAlert.ILLEGAL_PARAMETER, 56 "Unknown heartbeat message type"); 57 58 m_type = cast(MessageType)(type); 59 60 m_payload = reader.getRange!ubyte(2, 0, 16*1024); 61 62 // padding follows and is ignored 63 } 64 65 this(MessageType type, 66 const(ubyte)* payload, 67 size_t payload_len) 68 { 69 m_type = type; 70 m_payload = Vector!ubyte(payload[0 .. payload_len]); 71 } 72 private: 73 MessageType m_type; 74 Vector!ubyte m_payload; 75 }