TLSPacketBuilder.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * Copyright (c) 2020, Ali Mohammad Pur <mpfard@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/ByteBuffer.h>
  8. #include <AK/ByteReader.h>
  9. #include <AK/Endian.h>
  10. #include <AK/Types.h>
  11. namespace TLS {
  12. enum class MessageType : u8 {
  13. ChangeCipher = 0x14,
  14. Alert = 0x15,
  15. Handshake = 0x16,
  16. ApplicationData = 0x17,
  17. };
  18. enum class Version : u16 {
  19. V10 = 0x0301,
  20. V11 = 0x0302,
  21. V12 = 0x0303,
  22. V13 = 0x0304
  23. };
  24. class PacketBuilder {
  25. public:
  26. PacketBuilder(MessageType type, u16 version, size_t size_hint = 0xfdf)
  27. : PacketBuilder(type, (Version)version, size_hint)
  28. {
  29. }
  30. PacketBuilder(MessageType type, Version version, size_t size_hint = 0xfdf)
  31. {
  32. // FIXME: Handle possible OOM situation.
  33. m_packet_data = ByteBuffer::create_uninitialized(size_hint + 16).release_value();
  34. m_current_length = 5;
  35. m_packet_data[0] = (u8)type;
  36. ByteReader::store(m_packet_data.offset_pointer(1), AK::convert_between_host_and_network_endian((u16)version));
  37. }
  38. inline void append(u16 value)
  39. {
  40. value = AK::convert_between_host_and_network_endian(value);
  41. append((const u8*)&value, sizeof(value));
  42. }
  43. inline void append(u8 value)
  44. {
  45. append((const u8*)&value, sizeof(value));
  46. }
  47. inline void append(ReadonlyBytes data)
  48. {
  49. append(data.data(), data.size());
  50. }
  51. inline void append_u24(u32 value)
  52. {
  53. u8 buf[3];
  54. buf[0] = value / 0x10000;
  55. value %= 0x10000;
  56. buf[1] = value / 0x100;
  57. value %= 0x100;
  58. buf[2] = value;
  59. append(buf, 3);
  60. }
  61. inline void append(const u8* data, size_t bytes)
  62. {
  63. if (bytes == 0)
  64. return;
  65. auto old_length = m_current_length;
  66. m_current_length += bytes;
  67. if (m_packet_data.size() < m_current_length) {
  68. m_packet_data.resize(m_current_length);
  69. }
  70. m_packet_data.overwrite(old_length, data, bytes);
  71. }
  72. inline ByteBuffer build()
  73. {
  74. auto length = m_current_length;
  75. m_current_length = 0;
  76. return m_packet_data.slice(0, length);
  77. }
  78. inline void set(size_t offset, u8 value)
  79. {
  80. VERIFY(offset < m_current_length);
  81. m_packet_data[offset] = value;
  82. }
  83. size_t length() const { return m_current_length; }
  84. private:
  85. ByteBuffer m_packet_data;
  86. size_t m_current_length;
  87. };
  88. }