TLSPacketBuilder.h 2.3 KB

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