TLSPacketBuilder.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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. m_packet_data = ByteBuffer::create_uninitialized(size_hint + 16);
  33. m_current_length = 5;
  34. m_packet_data[0] = (u8)type;
  35. ByteReader::store(m_packet_data.offset_pointer(1), AK::convert_between_host_and_network_endian((u16)version));
  36. }
  37. inline void append(u16 value)
  38. {
  39. value = AK::convert_between_host_and_network_endian(value);
  40. append((const u8*)&value, sizeof(value));
  41. }
  42. inline void append(u8 value)
  43. {
  44. append((const u8*)&value, sizeof(value));
  45. }
  46. inline void append(ReadonlyBytes data)
  47. {
  48. append(data.data(), data.size());
  49. }
  50. inline void append_u24(u32 value)
  51. {
  52. u8 buf[3];
  53. buf[0] = value / 0x10000;
  54. value %= 0x10000;
  55. buf[1] = value / 0x100;
  56. value %= 0x100;
  57. buf[2] = value;
  58. append(buf, 3);
  59. }
  60. inline void append(const u8* data, size_t bytes)
  61. {
  62. if (bytes == 0)
  63. return;
  64. auto old_length = m_current_length;
  65. m_current_length += bytes;
  66. if (m_packet_data.size() < m_current_length) {
  67. m_packet_data.resize(m_current_length);
  68. }
  69. m_packet_data.overwrite(old_length, data, bytes);
  70. }
  71. inline ByteBuffer build()
  72. {
  73. auto length = m_current_length;
  74. m_current_length = 0;
  75. return m_packet_data.slice(0, length);
  76. }
  77. inline void set(size_t offset, u8 value)
  78. {
  79. VERIFY(offset < m_current_length);
  80. m_packet_data[offset] = value;
  81. }
  82. size_t length() const { return m_current_length; }
  83. private:
  84. ByteBuffer m_packet_data;
  85. size_t m_current_length;
  86. };
  87. }