Skip to content

Instantly share code, notes, and snippets.

@stelar7
Created January 17, 2022 21:47
Show Gist options
  • Save stelar7/27ef3eb274a39e19df3463bd81e1aa2d to your computer and use it in GitHub Desktop.
Save stelar7/27ef3eb274a39e19df3463bd81e1aa2d to your computer and use it in GitHub Desktop.
/*
* Copyright (c) 2021, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/ByteBuffer.h>
#include <AK/Endian.h>
#include <AK/MemoryStream.h>
#include <AK/Random.h>
#include <AK/Types.h>
namespace FTP {
class ByteReader {
public:
ByteReader(AK::InputMemoryStream stream)
: m_stream(stream)
{
}
u8 read_1_bytes()
{
u8 byte1 = {};
m_stream >> byte1;
return byte1;
}
u16 read_2_bytes()
{
u8 byte1 = {};
u8 byte2 = {};
m_stream >> byte1;
m_stream >> byte2;
return (byte2 | byte1 << 8);
}
u32 read_3_bytes()
{
u8 byte1 = {};
u8 byte2 = {};
u8 byte3 = {};
m_stream >> byte1;
m_stream >> byte2;
m_stream >> byte3;
return (byte3 | byte2 << 8 | byte1 << 16);
}
ByteBuffer read_bytes(size_t count)
{
u32 read {};
u8 byte;
ByteBuffer output = ByteBuffer::create_zeroed(count);
while (!m_stream.eof() && read < count) {
m_stream >> byte;
output.overwrite(read, (const u8*)&byte, 1);
read++;
}
return output;
}
size_t remaining()
{
return m_stream.remaining();
}
private:
AK::InputMemoryStream m_stream;
};
}
/*
* Copyright (c) 2021, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/ByteBuffer.h>
#include <AK/ByteReader.h>
#include <AK/Endian.h>
#include <AK/Types.h>
namespace FTP {
class ByteWriter {
public:
ByteWriter()
{
m_data = ByteBuffer::create_uninitialized(256);
}
inline void write_bytes(ReadonlyBytes data)
{
write_bytes(data.data(), data.size());
}
inline void write_1_bytes(u8 value)
{
write_bytes((const u8*)&value, 1);
}
inline void write_2_bytes(u16 value)
{
u8 buf[2];
buf[0] = (value & 0xFF00) >> 8;
buf[1] = value & 0xFF;
write_bytes(buf, 2);
}
inline void write_3_bytes(u32 value)
{
u8 buf[3];
buf[0] = (value & 0xFF0000) >> 16;
buf[1] = (value & 0xFF00) >> 8;
buf[2] = value & 0xFF;
write_bytes(buf, 3);
}
inline void write_bytes(const u8* data, size_t bytes)
{
if (bytes == 0) {
return;
}
auto old_length = m_current_length;
m_current_length += bytes;
if (m_data.size() < m_current_length) {
m_data.resize(m_current_length);
}
m_data.overwrite(old_length, data, bytes);
}
inline ByteBuffer build()
{
return m_data.slice(0, m_current_length);
}
inline void set_1_bytes(size_t offset, u8 value)
{
m_data[offset] = value;
}
inline void set_2_bytes(size_t offset, u16 value)
{
m_data[offset] = (value & 0xFF00) >> 8;
m_data[offset + 1] = value & 0xFF;
}
inline void set_3_bytes(size_t offset, u32 value)
{
m_data[offset] = (value & 0xFF0000) >> 16;
m_data[offset + 1] = (value & 0xFF00) >> 8;
m_data[offset + 2] = value & 0xFF;
}
size_t length() const { return m_current_length; }
private:
ByteBuffer m_data;
size_t m_current_length {};
};
}
/*
* Copyright (c) 2021, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "Extensions.h"
RecordSizeLimit::RecordSizeLimit() { }
RecordSizeLimit::~RecordSizeLimit() { }
PSKKeyExchangeModes::PSKKeyExchangeModes() { }
PSKKeyExchangeModes::~PSKKeyExchangeModes() { }
RenegotiationInfo::RenegotiationInfo() { }
RenegotiationInfo::~RenegotiationInfo() { }
SupportedVersions::SupportedVersions() { }
SupportedVersions::~SupportedVersions() { }
KeyShares::KeyShares() { }
KeyShares::~KeyShares() { }
ExtendMasterSecret::ExtendMasterSecret() { }
ExtendMasterSecret::~ExtendMasterSecret() { }
SessionTicket::SessionTicket() { }
SessionTicket::~SessionTicket() { }
EncryptThenMac::EncryptThenMac() { }
EncryptThenMac::~EncryptThenMac() { }
SignatureSchemes::SignatureSchemes() { }
SignatureSchemes::~SignatureSchemes() { }
ECPointFormats::ECPointFormats() { }
ECPointFormats::~ECPointFormats() { }
SupportedGroups::SupportedGroups() { }
SupportedGroups::~SupportedGroups() { }
CertificateStatusRequest::CertificateStatusRequest() { }
CertificateStatusRequest::~CertificateStatusRequest() { }
/*
* Copyright (c) 2021, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "../Transport.h"
#include <AK/Vector.h>
#pragma once
#define _ENUM_KEY_VALUE(name, value) name = value,
#define __ENUM_CONTENT_TYPE \
_ENUM_KEY_VALUE(CHANGE_CIPHER_SPEC, 20) \
_ENUM_KEY_VALUE(ALERT, 21) \
_ENUM_KEY_VALUE(HANDSHAKE, 22) \
_ENUM_KEY_VALUE(APPLICATION_DATA, 23) \
_ENUM_KEY_VALUE(HEARTBEAT, 24) \
_ENUM_KEY_VALUE(TLS12_CID, 25) \
_ENUM_KEY_VALUE(ACK, 26)
#define __ENUM_HANDSHAKE_TYPE \
_ENUM_KEY_VALUE(HELLO_REQUEST, 0) \
_ENUM_KEY_VALUE(CLIENT_HELLO, 1) \
_ENUM_KEY_VALUE(SERVER_HELLO, 2) \
_ENUM_KEY_VALUE(HELLO_VERIFY_REQUEST, 3) \
_ENUM_KEY_VALUE(NEW_SESSION_TICKET, 4) \
_ENUM_KEY_VALUE(END_OF_EARLY_DATA, 5) \
_ENUM_KEY_VALUE(HELLO_RETRY_REQUEST, 6) \
_ENUM_KEY_VALUE(ENCRYPTED_EXTENSIONS, 8) \
_ENUM_KEY_VALUE(REQUESTCONNECTIONID, 9) \
_ENUM_KEY_VALUE(NEWCONNECTIONID, 10) \
_ENUM_KEY_VALUE(CERTIFICATE, 11) \
_ENUM_KEY_VALUE(SERVER_KEY_EXCHANGE, 12) \
_ENUM_KEY_VALUE(CERTIFICATE_REQUEST, 13) \
_ENUM_KEY_VALUE(SERVER_HELLO_DONE, 14) \
_ENUM_KEY_VALUE(CERTIFICATE_VERIFY, 15) \
_ENUM_KEY_VALUE(CLIENT_KEY_EXCHANGE, 16) \
_ENUM_KEY_VALUE(FINISHED, 20) \
_ENUM_KEY_VALUE(CERTIFICATE_URL, 21) \
_ENUM_KEY_VALUE(CERTIFICATE_STATUS, 22) \
_ENUM_KEY_VALUE(SUPPLEMENTAL_DATA, 23) \
_ENUM_KEY_VALUE(KEY_UPDATE, 24) \
_ENUM_KEY_VALUE(COMPRESSED_CERTIFICATE, 25) \
_ENUM_KEY_VALUE(EKT_KEY, 26) \
_ENUM_KEY_VALUE(MESSAGE_HASH, 254)
#define __ENUM_SSL_VERSION \
_ENUM_KEY_VALUE(VERSION_1_3, 0x0304) \
_ENUM_KEY_VALUE(VERSION_1_2, 0x0303) \
_ENUM_KEY_VALUE(VERSION_1_1, 0x0302) \
_ENUM_KEY_VALUE(VERSION_1_0, 0x0301)
#define __ENUM_CIPHER_SUITE \
_ENUM_KEY_VALUE(TLS_NULL_WITH_NULL_NULL, 0x0000) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_NULL_MD5, 0x0001) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_NULL_SHA, 0x0002) \
_ENUM_KEY_VALUE(TLS_RSA_EXPORT_WITH_RC4_40_MD5, 0x0003) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_RC4_128_MD5, 0x0004) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_RC4_128_SHA, 0x0005) \
_ENUM_KEY_VALUE(TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, 0x0006) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_IDEA_CBC_SHA, 0x0007) \
_ENUM_KEY_VALUE(TLS_RSA_EXPORT_WITH_DES40_CBC_SHA, 0x0008) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_DES_CBC_SHA, 0x0009) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_3DES_EDE_CBC_SHA, 0x000A) \
_ENUM_KEY_VALUE(TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, 0x000B) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_DES_CBC_SHA, 0x000C) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, 0x000D) \
_ENUM_KEY_VALUE(TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, 0x000E) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_DES_CBC_SHA, 0x000F) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, 0x0010) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, 0x0011) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_DES_CBC_SHA, 0x0012) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 0x0013) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, 0x0014) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_DES_CBC_SHA, 0x0015) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 0x0016) \
_ENUM_KEY_VALUE(TLS_DH_anon_EXPORT_WITH_RC4_40_MD5, 0x0017) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_RC4_128_MD5, 0x0018) \
_ENUM_KEY_VALUE(TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA, 0x0019) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_DES_CBC_SHA, 0x001A) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, 0x001B) \
_ENUM_KEY_VALUE(TLS_KRB5_WITH_DES_CBC_SHA, 0x001E) \
_ENUM_KEY_VALUE(TLS_KRB5_WITH_3DES_EDE_CBC_SHA, 0x001F) \
_ENUM_KEY_VALUE(TLS_KRB5_WITH_RC4_128_SHA, 0x0020) \
_ENUM_KEY_VALUE(TLS_KRB5_WITH_IDEA_CBC_SHA, 0x0021) \
_ENUM_KEY_VALUE(TLS_KRB5_WITH_DES_CBC_MD5, 0x0022) \
_ENUM_KEY_VALUE(TLS_KRB5_WITH_3DES_EDE_CBC_MD5, 0x0023) \
_ENUM_KEY_VALUE(TLS_KRB5_WITH_RC4_128_MD5, 0x0024) \
_ENUM_KEY_VALUE(TLS_KRB5_WITH_IDEA_CBC_MD5, 0x0025) \
_ENUM_KEY_VALUE(TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA, 0x0026) \
_ENUM_KEY_VALUE(TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA, 0x0027) \
_ENUM_KEY_VALUE(TLS_KRB5_EXPORT_WITH_RC4_40_SHA, 0x0028) \
_ENUM_KEY_VALUE(TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5, 0x0029) \
_ENUM_KEY_VALUE(TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5, 0x002A) \
_ENUM_KEY_VALUE(TLS_KRB5_EXPORT_WITH_RC4_40_MD5, 0x002B) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_NULL_SHA, 0x002C) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_NULL_SHA, 0x002D) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_NULL_SHA, 0x002E) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_AES_128_CBC_SHA, 0x002F) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_AES_128_CBC_SHA, 0x0030) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_AES_128_CBC_SHA, 0x0031) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 0x0032) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 0x0033) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_AES_128_CBC_SHA, 0x0034) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_AES_256_CBC_SHA, 0x0035) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_AES_256_CBC_SHA, 0x0036) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_AES_256_CBC_SHA, 0x0037) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 0x0038) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 0x0039) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_AES_256_CBC_SHA, 0x003A) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_NULL_SHA256, 0x003B) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_AES_128_CBC_SHA256, 0x003C) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_AES_256_CBC_SHA256, 0x003D) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_AES_128_CBC_SHA256, 0x003E) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_AES_128_CBC_SHA256, 0x003F) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, 0x0040) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, 0x0041) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA, 0x0042) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA, 0x0043) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, 0x0044) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, 0x0045) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA, 0x0046) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, 0x0067) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_AES_256_CBC_SHA256, 0x0068) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_AES_256_CBC_SHA256, 0x0069) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, 0x006A) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, 0x006B) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_AES_128_CBC_SHA256, 0x006C) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_AES_256_CBC_SHA256, 0x006D) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, 0x0084) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA, 0x0085) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA, 0x0086) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, 0x0087) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, 0x0088) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA, 0x0089) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_RC4_128_SHA, 0x008A) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_3DES_EDE_CBC_SHA, 0x008B) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_AES_128_CBC_SHA, 0x008C) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_AES_256_CBC_SHA, 0x008D) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_RC4_128_SHA, 0x008E) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, 0x008F) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_AES_128_CBC_SHA, 0x0090) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_AES_256_CBC_SHA, 0x0091) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_RC4_128_SHA, 0x0092) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, 0x0093) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_AES_128_CBC_SHA, 0x0094) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_AES_256_CBC_SHA, 0x0095) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_SEED_CBC_SHA, 0x0096) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_SEED_CBC_SHA, 0x0097) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_SEED_CBC_SHA, 0x0098) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_SEED_CBC_SHA, 0x0099) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_SEED_CBC_SHA, 0x009A) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_SEED_CBC_SHA, 0x009B) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_AES_128_GCM_SHA256, 0x009C) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_AES_256_GCM_SHA384, 0x009D) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 0x009E) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, 0x009F) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_AES_128_GCM_SHA256, 0x00A0) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_AES_256_GCM_SHA384, 0x00A1) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, 0x00A2) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, 0x00A3) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_AES_128_GCM_SHA256, 0x00A4) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_AES_256_GCM_SHA384, 0x00A5) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_AES_128_GCM_SHA256, 0x00A6) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_AES_256_GCM_SHA384, 0x00A7) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_AES_128_GCM_SHA256, 0x00A8) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_AES_256_GCM_SHA384, 0x00A9) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, 0x00AA) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, 0x00AB) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, 0x00AC) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, 0x00AD) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_AES_128_CBC_SHA256, 0x00AE) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_AES_256_CBC_SHA384, 0x00AF) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_NULL_SHA256, 0x00B0) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_NULL_SHA384, 0x00B1) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, 0x00B2) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, 0x00B3) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_NULL_SHA256, 0x00B4) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_NULL_SHA384, 0x00B5) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, 0x00B6) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, 0x00B7) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_NULL_SHA256, 0x00B8) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_NULL_SHA384, 0x00B9) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, 0x00BA) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256, 0x00BB) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256, 0x00BC) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256, 0x00BD) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, 0x00BE) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256, 0x00BF) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, 0x00C0) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256, 0x00C1) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256, 0x00C2) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256, 0x00C3) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, 0x00C4) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256, 0x00C5) \
_ENUM_KEY_VALUE(TLS_SM4_GCM_SM3, 0x00C6) \
_ENUM_KEY_VALUE(TLS_SM4_CCM_SM3, 0x00C7) \
_ENUM_KEY_VALUE(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, 0x00FF) \
_ENUM_KEY_VALUE(TLS_AES_128_GCM_SHA256, 0x1301) \
_ENUM_KEY_VALUE(TLS_AES_256_GCM_SHA384, 0x1302) \
_ENUM_KEY_VALUE(TLS_CHACHA20_POLY1305_SHA256, 0x1303) \
_ENUM_KEY_VALUE(TLS_AES_128_CCM_SHA256, 0x1304) \
_ENUM_KEY_VALUE(TLS_AES_128_CCM_8_SHA256, 0x1305) \
_ENUM_KEY_VALUE(TLS_FALLBACK_SCSV, 0x5600) \
_ENUM_KEY_VALUE(TLS_ECDH_ECDSA_WITH_NULL_SHA, 0xC001) \
_ENUM_KEY_VALUE(TLS_ECDH_ECDSA_WITH_RC4_128_SHA, 0xC002) \
_ENUM_KEY_VALUE(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, 0xC003) \
_ENUM_KEY_VALUE(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, 0xC004) \
_ENUM_KEY_VALUE(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, 0xC005) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_NULL_SHA, 0xC006) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 0xC007) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, 0xC008) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 0xC009) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 0xC00A) \
_ENUM_KEY_VALUE(TLS_ECDH_RSA_WITH_NULL_SHA, 0xC00B) \
_ENUM_KEY_VALUE(TLS_ECDH_RSA_WITH_RC4_128_SHA, 0xC00C) \
_ENUM_KEY_VALUE(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, 0xC00D) \
_ENUM_KEY_VALUE(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, 0xC00E) \
_ENUM_KEY_VALUE(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, 0xC00F) \
_ENUM_KEY_VALUE(TLS_ECDHE_RSA_WITH_NULL_SHA, 0xC010) \
_ENUM_KEY_VALUE(TLS_ECDHE_RSA_WITH_RC4_128_SHA, 0xC011) \
_ENUM_KEY_VALUE(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 0xC012) \
_ENUM_KEY_VALUE(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0xC013) \
_ENUM_KEY_VALUE(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0xC014) \
_ENUM_KEY_VALUE(TLS_ECDH_anon_WITH_NULL_SHA, 0xC015) \
_ENUM_KEY_VALUE(TLS_ECDH_anon_WITH_RC4_128_SHA, 0xC016) \
_ENUM_KEY_VALUE(TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, 0xC017) \
_ENUM_KEY_VALUE(TLS_ECDH_anon_WITH_AES_128_CBC_SHA, 0xC018) \
_ENUM_KEY_VALUE(TLS_ECDH_anon_WITH_AES_256_CBC_SHA, 0xC019) \
_ENUM_KEY_VALUE(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, 0xC01A) \
_ENUM_KEY_VALUE(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, 0xC01B) \
_ENUM_KEY_VALUE(TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, 0xC01C) \
_ENUM_KEY_VALUE(TLS_SRP_SHA_WITH_AES_128_CBC_SHA, 0xC01D) \
_ENUM_KEY_VALUE(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, 0xC01E) \
_ENUM_KEY_VALUE(TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, 0xC01F) \
_ENUM_KEY_VALUE(TLS_SRP_SHA_WITH_AES_256_CBC_SHA, 0xC020) \
_ENUM_KEY_VALUE(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, 0xC021) \
_ENUM_KEY_VALUE(TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, 0xC022) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 0xC023) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, 0xC024) \
_ENUM_KEY_VALUE(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, 0xC025) \
_ENUM_KEY_VALUE(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, 0xC026) \
_ENUM_KEY_VALUE(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 0xC027) \
_ENUM_KEY_VALUE(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, 0xC028) \
_ENUM_KEY_VALUE(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, 0xC029) \
_ENUM_KEY_VALUE(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, 0xC02A) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0xC02B) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 0xC02C) \
_ENUM_KEY_VALUE(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, 0xC02D) \
_ENUM_KEY_VALUE(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, 0xC02E) \
_ENUM_KEY_VALUE(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0xC02F) \
_ENUM_KEY_VALUE(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0xC030) \
_ENUM_KEY_VALUE(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, 0xC031) \
_ENUM_KEY_VALUE(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, 0xC032) \
_ENUM_KEY_VALUE(TLS_ECDHE_PSK_WITH_RC4_128_SHA, 0xC033) \
_ENUM_KEY_VALUE(TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, 0xC034) \
_ENUM_KEY_VALUE(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, 0xC035) \
_ENUM_KEY_VALUE(TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, 0xC036) \
_ENUM_KEY_VALUE(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, 0xC037) \
_ENUM_KEY_VALUE(TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, 0xC038) \
_ENUM_KEY_VALUE(TLS_ECDHE_PSK_WITH_NULL_SHA, 0xC039) \
_ENUM_KEY_VALUE(TLS_ECDHE_PSK_WITH_NULL_SHA256, 0xC03A) \
_ENUM_KEY_VALUE(TLS_ECDHE_PSK_WITH_NULL_SHA384, 0xC03B) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_ARIA_128_CBC_SHA256, 0xC03C) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_ARIA_256_CBC_SHA384, 0xC03D) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256, 0xC03E) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384, 0xC03F) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256, 0xC040) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384, 0xC041) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256, 0xC042) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384, 0xC043) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256, 0xC044) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384, 0xC045) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_ARIA_128_CBC_SHA256, 0xC046) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_ARIA_256_CBC_SHA384, 0xC047) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256, 0xC048) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384, 0xC049) \
_ENUM_KEY_VALUE(TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256, 0xC04A) \
_ENUM_KEY_VALUE(TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384, 0xC04B) \
_ENUM_KEY_VALUE(TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256, 0xC04C) \
_ENUM_KEY_VALUE(TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384, 0xC04D) \
_ENUM_KEY_VALUE(TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256, 0xC04E) \
_ENUM_KEY_VALUE(TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384, 0xC04F) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_ARIA_128_GCM_SHA256, 0xC050) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_ARIA_256_GCM_SHA384, 0xC051) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256, 0xC052) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384, 0xC053) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256, 0xC054) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384, 0xC055) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256, 0xC056) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384, 0xC057) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256, 0xC058) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384, 0xC059) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_ARIA_128_GCM_SHA256, 0xC05A) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_ARIA_256_GCM_SHA384, 0xC05B) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256, 0xC05C) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384, 0xC05D) \
_ENUM_KEY_VALUE(TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256, 0xC05E) \
_ENUM_KEY_VALUE(TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384, 0xC05F) \
_ENUM_KEY_VALUE(TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256, 0xC060) \
_ENUM_KEY_VALUE(TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384, 0xC061) \
_ENUM_KEY_VALUE(TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256, 0xC062) \
_ENUM_KEY_VALUE(TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384, 0xC063) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_ARIA_128_CBC_SHA256, 0xC064) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_ARIA_256_CBC_SHA384, 0xC065) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256, 0xC066) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384, 0xC067) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256, 0xC068) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384, 0xC069) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_ARIA_128_GCM_SHA256, 0xC06A) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_ARIA_256_GCM_SHA384, 0xC06B) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256, 0xC06C) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384, 0xC06D) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, 0xC06E) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, 0xC06F) \
_ENUM_KEY_VALUE(TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256, 0xC070) \
_ENUM_KEY_VALUE(TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384, 0xC071) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, 0xC072) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, 0xC073) \
_ENUM_KEY_VALUE(TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, 0xC074) \
_ENUM_KEY_VALUE(TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, 0xC075) \
_ENUM_KEY_VALUE(TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, 0xC076) \
_ENUM_KEY_VALUE(TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, 0xC077) \
_ENUM_KEY_VALUE(TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, 0xC078) \
_ENUM_KEY_VALUE(TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, 0xC079) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, 0xC07A) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, 0xC07B) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, 0xC07C) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, 0xC07D) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256, 0xC07E) \
_ENUM_KEY_VALUE(TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384, 0xC07F) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256, 0xC080) \
_ENUM_KEY_VALUE(TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384, 0xC081) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256, 0xC082) \
_ENUM_KEY_VALUE(TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384, 0xC083) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256, 0xC084) \
_ENUM_KEY_VALUE(TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384, 0xC085) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, 0xC086) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, 0xC087) \
_ENUM_KEY_VALUE(TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, 0xC088) \
_ENUM_KEY_VALUE(TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, 0xC089) \
_ENUM_KEY_VALUE(TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, 0xC08A) \
_ENUM_KEY_VALUE(TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, 0xC08B) \
_ENUM_KEY_VALUE(TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, 0xC08C) \
_ENUM_KEY_VALUE(TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, 0xC08D) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, 0xC08E) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, 0xC08F) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, 0xC090) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, 0xC091) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, 0xC092) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, 0xC093) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, 0xC094) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, 0xC095) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, 0xC096) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, 0xC097) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, 0xC098) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, 0xC099) \
_ENUM_KEY_VALUE(TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, 0xC09A) \
_ENUM_KEY_VALUE(TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, 0xC09B) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_AES_128_CCM, 0xC09C) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_AES_256_CCM, 0xC09D) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_AES_128_CCM, 0xC09E) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_AES_256_CCM, 0xC09F) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_AES_128_CCM_8, 0xC0A0) \
_ENUM_KEY_VALUE(TLS_RSA_WITH_AES_256_CCM_8, 0xC0A1) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_AES_128_CCM_8, 0xC0A2) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_AES_256_CCM_8, 0xC0A3) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_AES_128_CCM, 0xC0A4) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_AES_256_CCM, 0xC0A5) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_AES_128_CCM, 0xC0A6) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_AES_256_CCM, 0xC0A7) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_AES_128_CCM_8, 0xC0A8) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_AES_256_CCM_8, 0xC0A9) \
_ENUM_KEY_VALUE(TLS_PSK_DHE_WITH_AES_128_CCM_8, 0xC0AA) \
_ENUM_KEY_VALUE(TLS_PSK_DHE_WITH_AES_256_CCM_8, 0xC0AB) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_AES_128_CCM, 0xC0AC) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_AES_256_CCM, 0xC0AD) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, 0xC0AE) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, 0xC0AF) \
_ENUM_KEY_VALUE(TLS_ECCPWD_WITH_AES_128_GCM_SHA256, 0xC0B0) \
_ENUM_KEY_VALUE(TLS_ECCPWD_WITH_AES_256_GCM_SHA384, 0xC0B1) \
_ENUM_KEY_VALUE(TLS_ECCPWD_WITH_AES_128_CCM_SHA256, 0xC0B2) \
_ENUM_KEY_VALUE(TLS_ECCPWD_WITH_AES_256_CCM_SHA384, 0xC0B3) \
_ENUM_KEY_VALUE(TLS_SHA256_SHA256, 0xC0B4) \
_ENUM_KEY_VALUE(TLS_SHA384_SHA384, 0xC0B5) \
_ENUM_KEY_VALUE(TLS_GOSTR341112_256_WITH_KUZNYECHIK_CTR_OMAC, 0xC100) \
_ENUM_KEY_VALUE(TLS_GOSTR341112_256_WITH_MAGMA_CTR_OMAC, 0xC101) \
_ENUM_KEY_VALUE(TLS_GOSTR341112_256_WITH_28147_CNT_IMIT, 0xC102) \
_ENUM_KEY_VALUE(TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_L, 0xC103) \
_ENUM_KEY_VALUE(TLS_GOSTR341112_256_WITH_MAGMA_MGM_L, 0xC104) \
_ENUM_KEY_VALUE(TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_S, 0xC105) \
_ENUM_KEY_VALUE(TLS_GOSTR341112_256_WITH_MAGMA_MGM_S, 0xC106) \
_ENUM_KEY_VALUE(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0xCCA8) \
_ENUM_KEY_VALUE(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0xCCA9) \
_ENUM_KEY_VALUE(TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0xCCAA) \
_ENUM_KEY_VALUE(TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, 0xCCAB) \
_ENUM_KEY_VALUE(TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, 0xCCAC) \
_ENUM_KEY_VALUE(TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, 0xCCAD) \
_ENUM_KEY_VALUE(TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, 0xCCAE) \
_ENUM_KEY_VALUE(TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256, 0xD001) \
_ENUM_KEY_VALUE(TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384, 0xD002) \
_ENUM_KEY_VALUE(TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256, 0xD003) \
_ENUM_KEY_VALUE(TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256, 0xD005)
#define __ENUM_COMPRESSION_METHOD \
_ENUM_KEY_VALUE(NONE, 0) \
_ENUM_KEY_VALUE(DEFLATE, 1)
#define __ENUM_EXTENSION_TYPE \
_ENUM_KEY_VALUE(SERVER_NAME, 0) \
_ENUM_KEY_VALUE(MAX_FRAGMENT_LENGTH, 1) \
_ENUM_KEY_VALUE(CLIENT_CERTIFICATE_URL, 2) \
_ENUM_KEY_VALUE(TRUSTED_CA_KEYS, 3) \
_ENUM_KEY_VALUE(TRUNCATED_HMAC, 4) \
_ENUM_KEY_VALUE(STATUS_REQUEST, 5) \
_ENUM_KEY_VALUE(USER_MAPPING, 6) \
_ENUM_KEY_VALUE(CLIENT_AUTHZ, 7) \
_ENUM_KEY_VALUE(SERVER_AUTHZ, 8) \
_ENUM_KEY_VALUE(CERT_TYPE, 9) \
_ENUM_KEY_VALUE(SUPPORTED_GROUPS, 10) \
_ENUM_KEY_VALUE(EC_POINT_FORMATS, 11) \
_ENUM_KEY_VALUE(SRP, 12) \
_ENUM_KEY_VALUE(SIGNATURE_ALGORITHMS, 13) \
_ENUM_KEY_VALUE(USE_SRTP, 14) \
_ENUM_KEY_VALUE(HEARTBEAT, 15) \
_ENUM_KEY_VALUE(APPLICATION_LAYER_PROTOCOL_NEGOTIATION, 16) \
_ENUM_KEY_VALUE(STATUS_REQUEST_V2, 17) \
_ENUM_KEY_VALUE(SIGNED_CERTIFICATE_TIMESTAMP, 18) \
_ENUM_KEY_VALUE(CLIENT_CERTIFICATE_TYPE, 19) \
_ENUM_KEY_VALUE(SERVER_CERTIFICATE_TYPE, 20) \
_ENUM_KEY_VALUE(PADDING, 21) \
_ENUM_KEY_VALUE(ENCRYPT_THEN_MAC, 22) \
_ENUM_KEY_VALUE(EXTENDED_MASTER_SECRET, 23) \
_ENUM_KEY_VALUE(TOKEN_BINDING, 24) \
_ENUM_KEY_VALUE(CACHED_INFO, 25) \
_ENUM_KEY_VALUE(TLS_LTS, 26) \
_ENUM_KEY_VALUE(COMPRESS_CERTIFICATE, 27) \
_ENUM_KEY_VALUE(RECORD_SIZE_LIMIT, 28) \
_ENUM_KEY_VALUE(PWD_PROTECT, 29) \
_ENUM_KEY_VALUE(PWD_CLEAR, 30) \
_ENUM_KEY_VALUE(PASSWORD_SALT, 31) \
_ENUM_KEY_VALUE(TICKET_PINNING, 32) \
_ENUM_KEY_VALUE(TLS_CERT_WITH_EXTERN_PSK, 33) \
_ENUM_KEY_VALUE(DELEGATED_CREDENTIALS, 34) \
_ENUM_KEY_VALUE(SESSION_TICKET, 35) \
_ENUM_KEY_VALUE(TLMSP, 36) \
_ENUM_KEY_VALUE(TLMSP_PROXYING, 37) \
_ENUM_KEY_VALUE(TLMSP_DELEGATE, 38) \
_ENUM_KEY_VALUE(SUPPORTED_EKT_CIPHERS, 39) \
_ENUM_KEY_VALUE(PRE_SHARED_KEY, 41) \
_ENUM_KEY_VALUE(EARLY_DATA, 42) \
_ENUM_KEY_VALUE(SUPPORTED_VERSIONS, 43) \
_ENUM_KEY_VALUE(COOKIE, 44) \
_ENUM_KEY_VALUE(PSK_KEY_EXCHANGE_MODES, 45) \
_ENUM_KEY_VALUE(CERTIFICATE_AUTHORITIES, 47) \
_ENUM_KEY_VALUE(OID_FILTERS, 48) \
_ENUM_KEY_VALUE(POST_HANDSHAKE_AUTH, 49) \
_ENUM_KEY_VALUE(SIGNATURE_ALGORITHMS_CERT, 50) \
_ENUM_KEY_VALUE(KEY_SHARE, 51) \
_ENUM_KEY_VALUE(TRANSPARENCY_INFO, 52) \
_ENUM_KEY_VALUE(CONNECTION_ID_DEPRECATED, 53) \
_ENUM_KEY_VALUE(CONNECTION_ID, 54) \
_ENUM_KEY_VALUE(EXTERNAL_ID_HASH, 55) \
_ENUM_KEY_VALUE(EXTERNAL_SESSION_ID, 56) \
_ENUM_KEY_VALUE(QUIC_TRANSPORT_PARAMETERS, 57) \
_ENUM_KEY_VALUE(TICKET_REQUEST, 58) \
_ENUM_KEY_VALUE(DNSSEC_CHAIN, 59) \
_ENUM_KEY_VALUE(RENEGOTIATION_INFO, 65281)
#define __ENUM_CERTIFICATE_STATUS \
_ENUM_KEY_VALUE(OCSP, 1) \
_ENUM_KEY_VALUE(OCSP_MULTI, 2)
#define __ENUM_SUPPORTED_GROUP \
_ENUM_KEY_VALUE(SECT163K1, 1) \
_ENUM_KEY_VALUE(SECT163R1, 2) \
_ENUM_KEY_VALUE(SECT163R2, 3) \
_ENUM_KEY_VALUE(SECT193R1, 4) \
_ENUM_KEY_VALUE(SECT193R2, 5) \
_ENUM_KEY_VALUE(SECT233K1, 6) \
_ENUM_KEY_VALUE(SECT233R1, 7) \
_ENUM_KEY_VALUE(SECT239K1, 8) \
_ENUM_KEY_VALUE(SECT283K1, 9) \
_ENUM_KEY_VALUE(SECT283R1, 10) \
_ENUM_KEY_VALUE(SECT409K1, 11) \
_ENUM_KEY_VALUE(SECT409R1, 12) \
_ENUM_KEY_VALUE(SECT571K1, 13) \
_ENUM_KEY_VALUE(SECT571R1, 14) \
_ENUM_KEY_VALUE(SECP160K1, 15) \
_ENUM_KEY_VALUE(SECP160R1, 16) \
_ENUM_KEY_VALUE(SECP160R2, 17) \
_ENUM_KEY_VALUE(SECP192K1, 18) \
_ENUM_KEY_VALUE(SECP192R1, 19) \
_ENUM_KEY_VALUE(SECP224K1, 20) \
_ENUM_KEY_VALUE(SECP224R1, 21) \
_ENUM_KEY_VALUE(SECP256K1, 22) \
_ENUM_KEY_VALUE(SECP256R1, 23) \
_ENUM_KEY_VALUE(SECP384R1, 24) \
_ENUM_KEY_VALUE(SECP521R1, 25) \
_ENUM_KEY_VALUE(BRAINPOOLP256R1, 26) \
_ENUM_KEY_VALUE(BRAINPOOLP384R1, 27) \
_ENUM_KEY_VALUE(BRAINPOOLP512R1, 28) \
_ENUM_KEY_VALUE(X25519, 29) \
_ENUM_KEY_VALUE(X448, 30) \
_ENUM_KEY_VALUE(BRAINPOOLP256R1TLS13, 31) \
_ENUM_KEY_VALUE(BRAINPOOLP384R1TLS13, 32) \
_ENUM_KEY_VALUE(BRAINPOOLP512R1TLS13, 33) \
_ENUM_KEY_VALUE(GC256A, 34) \
_ENUM_KEY_VALUE(GC256B, 35) \
_ENUM_KEY_VALUE(GC256C, 36) \
_ENUM_KEY_VALUE(GC256D, 37) \
_ENUM_KEY_VALUE(GC512A, 38) \
_ENUM_KEY_VALUE(GC512B, 39) \
_ENUM_KEY_VALUE(GC512C, 40) \
_ENUM_KEY_VALUE(CURVESM2, 41) \
_ENUM_KEY_VALUE(FFDHE2048, 256) \
_ENUM_KEY_VALUE(FFDHE3072, 257) \
_ENUM_KEY_VALUE(FFDHE4096, 258) \
_ENUM_KEY_VALUE(FFDHE6144, 259) \
_ENUM_KEY_VALUE(FFDHE8192, 260) \
_ENUM_KEY_VALUE(ARBITRARY_EXPLICIT_PRIME_CURVES, 65281) \
_ENUM_KEY_VALUE(ARBITRARY_EXPLICIT_CHAR2_CURVES, 65282)
#define __ENUM_EC_POINT_FORMAT \
_ENUM_KEY_VALUE(UNCOMPRESSED, 0) \
_ENUM_KEY_VALUE(ANSIX962_COMPRESSED_PRIME, 1) \
_ENUM_KEY_VALUE(ANSIX962_COMPRESSED_CHAR2, 2)
#define __ENUM_SIGNATURE_SCHEME \
_ENUM_KEY_VALUE(RSA_PKCS1_SHA1, 0x0201) \
_ENUM_KEY_VALUE(ECDSA_SHA1, 0x0203) \
_ENUM_KEY_VALUE(RSA_PKCS1_SHA256, 0x0401) \
_ENUM_KEY_VALUE(ECDSA_SECP256R1_SHA256, 0x0403) \
_ENUM_KEY_VALUE(RSA_PKCS1_SHA256_LEGACY, 0x0420) \
_ENUM_KEY_VALUE(RSA_PKCS1_SHA384, 0x0501) \
_ENUM_KEY_VALUE(ECDSA_SECP384R1_SHA384, 0x0503) \
_ENUM_KEY_VALUE(RSA_PKCS1_SHA384_LEGACY, 0x0520) \
_ENUM_KEY_VALUE(RSA_PKCS1_SHA512, 0x0601) \
_ENUM_KEY_VALUE(ECDSA_SECP521R1_SHA512, 0x0603) \
_ENUM_KEY_VALUE(RSA_PKCS1_SHA512_LEGACY, 0x0620) \
_ENUM_KEY_VALUE(ECCSI_SHA256, 0x0704) \
_ENUM_KEY_VALUE(ISO_IBS1, 0x0705) \
_ENUM_KEY_VALUE(ISO_IBS2, 0x0706) \
_ENUM_KEY_VALUE(ISO_CHINESE_IBS, 0x0707) \
_ENUM_KEY_VALUE(SM2SIG_SM3, 0x0708) \
_ENUM_KEY_VALUE(GOSTR34102012_256A, 0x0709) \
_ENUM_KEY_VALUE(GOSTR34102012_256B, 0x070A) \
_ENUM_KEY_VALUE(GOSTR34102012_256C, 0x070B) \
_ENUM_KEY_VALUE(GOSTR34102012_256D, 0x070C) \
_ENUM_KEY_VALUE(GOSTR34102012_512A, 0x070D) \
_ENUM_KEY_VALUE(GOSTR34102012_512B, 0x070E) \
_ENUM_KEY_VALUE(GOSTR34102012_512C, 0x070F) \
_ENUM_KEY_VALUE(RSA_PSS_RSAE_SHA256, 0x0804) \
_ENUM_KEY_VALUE(RSA_PSS_RSAE_SHA384, 0x0805) \
_ENUM_KEY_VALUE(RSA_PSS_RSAE_SHA512, 0x0806) \
_ENUM_KEY_VALUE(ED25519, 0x0807) \
_ENUM_KEY_VALUE(ED448, 0x0808) \
_ENUM_KEY_VALUE(RSA_PSS_PSS_SHA256, 0x0809) \
_ENUM_KEY_VALUE(RSA_PSS_PSS_SHA384, 0x080A) \
_ENUM_KEY_VALUE(RSA_PSS_PSS_SHA512, 0x080B) \
_ENUM_KEY_VALUE(ECDSA_BRAINPOOLP256R1TLS13_SHA256, 0x081A) \
_ENUM_KEY_VALUE(ECDSA_BRAINPOOLP384R1TLS13_SHA384, 0x081B) \
_ENUM_KEY_VALUE(ECDSA_BRAINPOOLP512R1TLS13_SHA512, 0x081C)
#define __ENUM_PSK_KEY_EXCHANGE_MODE \
_ENUM_KEY_VALUE(PSK_KE, 0) \
_ENUM_KEY_VALUE(PSK_DHE_KE, 1)
enum class ContentType : u8 {
__ENUM_CONTENT_TYPE
};
enum class HandshakeType : u8 {
__ENUM_HANDSHAKE_TYPE
};
enum class SSLVersion : u16 {
__ENUM_SSL_VERSION
};
enum class CipherSuite : u16 {
__ENUM_CIPHER_SUITE
};
enum class CompressionMethod : u8 {
__ENUM_COMPRESSION_METHOD
};
enum class ExtensionType : u16 {
__ENUM_EXTENSION_TYPE
};
enum class CertificateStatusType : u8 {
__ENUM_CERTIFICATE_STATUS
};
enum class SupportedGroup : u16 {
__ENUM_SUPPORTED_GROUP
};
enum class ECPointFormat : u8 {
__ENUM_EC_POINT_FORMAT
};
enum class SignatureScheme : u16 {
__ENUM_SIGNATURE_SCHEME
};
enum class PSKKeyExchangeMode : u8 {
__ENUM_PSK_KEY_EXCHANGE_MODE
};
#undef _ENUM_KEY_VALUE
inline String enum_to_string(ContentType type)
{
switch (type) {
#define _ENUM_KEY_VALUE(key, value) \
case ContentType::key: \
return #key;
__ENUM_CONTENT_TYPE
#undef _ENUM_KEY_VALUE
default:
VERIFY_NOT_REACHED();
}
}
inline String enum_to_string(HandshakeType type)
{
switch (type) {
#define _ENUM_KEY_VALUE(key, value) \
case HandshakeType::key: \
return #key;
__ENUM_HANDSHAKE_TYPE
#undef _ENUM_KEY_VALUE
default:
VERIFY_NOT_REACHED();
}
}
inline String enum_to_string(SSLVersion type)
{
switch (type) {
#define _ENUM_KEY_VALUE(key, value) \
case SSLVersion::key: \
return #key;
__ENUM_SSL_VERSION
#undef _ENUM_KEY_VALUE
default:
VERIFY_NOT_REACHED();
}
}
inline String enum_to_string(CipherSuite type)
{
switch (type) {
#define _ENUM_KEY_VALUE(key, value) \
case CipherSuite::key: \
return #key;
__ENUM_CIPHER_SUITE
#undef _ENUM_KEY_VALUE
default:
VERIFY_NOT_REACHED();
}
}
inline String enum_to_string(CompressionMethod type)
{
switch (type) {
#define _ENUM_KEY_VALUE(key, value) \
case CompressionMethod::key: \
return #key;
__ENUM_COMPRESSION_METHOD
#undef _ENUM_KEY_VALUE
default:
VERIFY_NOT_REACHED();
}
}
inline String enum_to_string(ExtensionType type)
{
switch (type) {
#define _ENUM_KEY_VALUE(key, value) \
case ExtensionType::key: \
return #key;
__ENUM_EXTENSION_TYPE
#undef _ENUM_KEY_VALUE
default:
VERIFY_NOT_REACHED();
}
}
inline String enum_to_string(CertificateStatusType type)
{
switch (type) {
#define _ENUM_KEY_VALUE(key, value) \
case CertificateStatusType::key: \
return #key;
__ENUM_CERTIFICATE_STATUS
#undef _ENUM_KEY_VALUE
default:
VERIFY_NOT_REACHED();
}
}
inline String enum_to_string(SupportedGroup type)
{
switch (type) {
#define _ENUM_KEY_VALUE(key, value) \
case SupportedGroup::key: \
return #key;
__ENUM_SUPPORTED_GROUP
#undef _ENUM_KEY_VALUE
default:
VERIFY_NOT_REACHED();
}
}
inline String enum_to_string(ECPointFormat type)
{
switch (type) {
#define _ENUM_KEY_VALUE(key, value) \
case ECPointFormat::key: \
return #key;
__ENUM_EC_POINT_FORMAT
#undef _ENUM_KEY_VALUE
default:
VERIFY_NOT_REACHED();
}
}
inline String enum_to_string(SignatureScheme type)
{
switch (type) {
#define _ENUM_KEY_VALUE(key, value) \
case SignatureScheme::key: \
return #key;
__ENUM_SIGNATURE_SCHEME
#undef _ENUM_KEY_VALUE
default:
VERIFY_NOT_REACHED();
}
}
inline String enum_to_string(PSKKeyExchangeMode type)
{
switch (type) {
#define _ENUM_KEY_VALUE(key, value) \
case PSKKeyExchangeMode::key: \
return #key;
__ENUM_PSK_KEY_EXCHANGE_MODE
#undef _ENUM_KEY_VALUE
default:
VERIFY_NOT_REACHED();
}
}
class TLSExtension : public RefCounted<TLSExtension> {
public:
ExtensionType type;
u16 size {};
virtual String to_string(size_t) { VERIFY_NOT_REACHED(); }
virtual ~TLSExtension() {};
};
class CertificateStatusRequest : public TLSExtension {
public:
CertificateStatusRequest();
virtual ~CertificateStatusRequest() override;
CertificateStatusType status_type;
ByteBuffer responder_id;
ByteBuffer request_extension_info;
String to_string(size_t indent = 0)
{
StringBuilder builder;
builder.appendff(String::repeated('\t', indent));
builder.appendff("Certificate Status Request:\n");
builder.appendff(String::repeated('\t', indent));
builder.appendff("\tCertificate type: {}\n", enum_to_string(status_type));
builder.appendff(String::repeated('\t', indent));
builder.appendff("\tResponder ID: {:hex-dump}\n", responder_id.bytes());
builder.appendff(String::repeated('\t', indent));
builder.appendff("\tRequest Extension Info: {:hex-dump}\n", request_extension_info.bytes());
return builder.to_string();
}
};
class SupportedGroups : public TLSExtension {
public:
SupportedGroups();
virtual ~SupportedGroups() override;
Vector<SupportedGroup> groups;
String to_string(size_t indent = 0)
{
StringBuilder builder;
builder.appendff(String::repeated('\t', indent));
builder.appendff("Supported Groups:\n");
for (auto group : groups) {
builder.appendff(String::repeated('\t', indent));
builder.appendff("\t{}\n", enum_to_string(group));
}
return builder.to_string();
}
};
class ECPointFormats : public TLSExtension {
public:
ECPointFormats();
virtual ~ECPointFormats() override;
Vector<ECPointFormat> formats;
String to_string(size_t indent = 0)
{
StringBuilder builder;
builder.appendff(String::repeated('\t', indent));
builder.appendff("EC Point Formats:\n");
for (auto format : formats) {
builder.appendff(String::repeated('\t', indent));
builder.appendff("\t{}\n", enum_to_string(format));
}
return builder.to_string();
}
};
class SignatureSchemes : public TLSExtension {
public:
SignatureSchemes();
virtual ~SignatureSchemes() override;
Vector<SignatureScheme> signatures;
String to_string(size_t indent = 0)
{
StringBuilder builder;
builder.appendff(String::repeated('\t', indent));
builder.appendff("Signature Schemes:\n");
for (auto signature : signatures) {
builder.appendff(String::repeated('\t', indent));
builder.appendff("\t{}\n", enum_to_string(signature));
}
return builder.to_string();
}
};
class EncryptThenMac : public TLSExtension {
public:
EncryptThenMac();
virtual ~EncryptThenMac() override;
String to_string(size_t indent = 0)
{
StringBuilder builder;
builder.appendff(String::repeated('\t', indent));
builder.appendff("Encrypt Then MAC\n");
return builder.to_string();
}
};
class SessionTicket : public TLSExtension {
public:
SessionTicket();
virtual ~SessionTicket() override;
String to_string(size_t indent = 0)
{
StringBuilder builder;
builder.appendff(String::repeated('\t', indent));
builder.appendff("Session Ticket\n");
return builder.to_string();
}
};
class ExtendMasterSecret : public TLSExtension {
public:
ExtendMasterSecret();
virtual ~ExtendMasterSecret() override;
String to_string(size_t indent = 0)
{
StringBuilder builder;
builder.appendff(String::repeated('\t', indent));
builder.appendff("Extend Master Secret\n");
return builder.to_string();
}
};
class KeyShareEntry {
public:
SupportedGroup group;
ByteBuffer key;
String to_string()
{
return String::formatted("{}: {:hex-dump}", enum_to_string(group), key.bytes());
}
};
class KeyShares : public TLSExtension {
public:
KeyShares();
virtual ~KeyShares() override;
Vector<KeyShareEntry> keys;
String to_string(size_t indent = 0)
{
StringBuilder builder;
builder.appendff(String::repeated('\t', indent));
builder.appendff("Key Shares:\n");
for (auto key : keys) {
builder.appendff(String::repeated('\t', indent));
builder.appendff("\t{}\n", key.to_string());
}
return builder.to_string();
}
};
class SupportedVersions : public TLSExtension {
public:
SupportedVersions();
virtual ~SupportedVersions() override;
Vector<SSLVersion> versions;
String to_string(size_t indent = 0)
{
StringBuilder builder;
builder.appendff(String::repeated('\t', indent));
builder.appendff("Supported Versions:\n");
for (auto version : versions) {
builder.appendff(String::repeated('\t', indent));
builder.appendff("\t{}\n", enum_to_string(version));
}
return builder.to_string();
}
};
class RenegotiationInfo : public TLSExtension {
public:
RenegotiationInfo();
virtual ~RenegotiationInfo() override;
ByteBuffer data;
String to_string(size_t indent = 0)
{
StringBuilder builder;
builder.appendff(String::repeated('\t', indent));
builder.appendff("Renegotiation Info:\n");
builder.appendff(String::repeated('\t', indent));
builder.appendff("\t{:hex-dump}\n", data.bytes());
return builder.to_string();
}
};
class PSKKeyExchangeModes : public TLSExtension {
public:
PSKKeyExchangeModes();
virtual ~PSKKeyExchangeModes() override;
Vector<PSKKeyExchangeMode> modes;
String to_string(size_t indent = 0)
{
StringBuilder builder;
builder.appendff(String::repeated('\t', indent));
builder.appendff("PSK Key Exchange Modes:\n");
for (auto mode : modes) {
builder.appendff(String::repeated('\t', indent));
builder.appendff("\t{}\n", enum_to_string(mode));
}
return builder.to_string();
}
};
class RecordSizeLimit : public TLSExtension {
public:
RecordSizeLimit();
virtual ~RecordSizeLimit() override;
u16 limit;
String to_string(size_t indent = 0)
{
StringBuilder builder;
builder.appendff(String::repeated('\t', indent));
builder.appendff("Record Size Limit:\n");
builder.appendff(String::repeated('\t', indent));
builder.appendff("\tLimit: {}\n", limit);
return builder.to_string();
}
};
/*
* Copyright (c) 2021, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "TLSTransport.h"
#include "ByteReader.h"
#include "ByteWriter.h"
#include <AK/MemoryStream.h>
#include <AK/Random.h>
#include <LibCore/FileStream.h>
#include <LibCore/Socket.h>
static ByteBuffer get_random_bytes(u32 count)
{
ByteBuffer buffer = ByteBuffer::create_uninitialized(count);
fill_with_random(buffer.data(), count);
return buffer;
}
ByteBuffer TLSTransport::receive(int max_size, RefPtr<Core::Socket> socket)
{
dbgln("send on tls transport");
return socket->receive(max_size);
}
bool TLSTransport::send(ReadonlyBytes data, RefPtr<Core::Socket> socket)
{
dbgln("send on tls transport");
return socket->send(data);
}
TLSRecord TLSTransport::decode_tls_record(ReadonlyBytes input)
{
FTP::ByteReader data { InputMemoryStream(input) };
TLSRecord packet;
packet.content_type = static_cast<ContentType>(data.read_1_bytes());
packet.ssl_version = static_cast<SSLVersion>(data.read_2_bytes());
u16 packet_payload_size = data.read_2_bytes();
VERIFY(data.remaining() >= packet_payload_size);
auto handshake_type = static_cast<HandshakeType>(data.read_1_bytes());
u32 header_payload_size = data.read_3_bytes();
VERIFY(data.remaining() >= header_payload_size);
dbgln("got handshake: {}", enum_to_string(handshake_type));
switch (handshake_type) {
case HandshakeType::CLIENT_HELLO: {
packet.header = parse_client_hello(data);
break;
}
case HandshakeType::CLIENT_KEY_EXCHANGE: {
packet.header = parse_client_key_exchange(data);
break;
}
default: {
dbgln("unhandled packet type: {}", enum_to_string(handshake_type));
VERIFY_NOT_REACHED();
break;
}
}
return packet;
}
void TLSTransport::init(ReadonlyBytes input, RefPtr<Core::Socket> socket)
{
dbgln("Received raw: {:hex-dump}", input);
dbgln("in tls init");
TLSRecord record = decode_tls_record(input);
switch (static_cast<HandshakeType>(record.header->handshake_type)) {
case HandshakeType::CLIENT_HELLO: {
auto client_hello = static_ptr_cast<ClientHello>(record.header);
m_context.client_random = client_hello->client_random;
dbgln(client_hello->to_string());
m_context.server_random = get_random_bytes(32);
ByteBuffer server_hello = build_server_hello(client_hello);
send(server_hello, socket);
ByteBuffer server_certificate = build_server_certificate();
send(server_certificate, socket);
/*
ByteBuffer server_key_exchange = build_server_key_exchange();
send(server_key_exchange, socket);
*/
ByteBuffer server_hello_done = build_server_hello_done();
send(server_hello_done, socket);
break;
}
case HandshakeType::CLIENT_KEY_EXCHANGE: {
auto client_exchange = static_ptr_cast<ClientKeyExchange>(record.header);
dbgln(client_exchange->to_string());
break;
}
default: {
dbgln("packet type: {}", enum_to_string(record.header->handshake_type));
VERIFY_NOT_REACHED();
break;
}
}
}
RefPtr<ClientHello> TLSTransport::parse_client_hello(FTP::ByteReader& header_stream)
{
auto client_hello = create<ClientHello>();
client_hello->handshake_type = HandshakeType::CLIENT_HELLO;
client_hello->ssl_version = static_cast<SSLVersion>(header_stream.read_2_bytes());
client_hello->client_random = header_stream.read_bytes(32);
u8 session_id_size = header_stream.read_1_bytes();
client_hello->session_id = header_stream.read_bytes(session_id_size);
u16 cipher_suite_size = header_stream.read_2_bytes();
for (u16 i = 0; i < cipher_suite_size / sizeof(CipherSuite); i++) {
client_hello->cipher_suites.append(static_cast<CipherSuite>(header_stream.read_2_bytes()));
}
u8 compression_methods_size = header_stream.read_1_bytes();
for (u8 i = 0; i < compression_methods_size; i++) {
client_hello->compression_methods.append(static_cast<CompressionMethod>(header_stream.read_1_bytes()));
}
u16 extension_data_size = header_stream.read_2_bytes();
if (extension_data_size == 0) {
return client_hello;
}
while (extension_data_size > 0) {
ExtensionType extension_type = static_cast<ExtensionType>(header_stream.read_2_bytes());
u16 extension_size = header_stream.read_2_bytes();
dbgln("parsing type: {}, remaining bytes: {}", enum_to_string(extension_type), header_stream.remaining());
extension_data_size -= 4;
extension_data_size -= extension_size;
switch (extension_type) {
case ExtensionType::STATUS_REQUEST: {
auto status_request = create<CertificateStatusRequest>();
status_request->type = extension_type;
status_request->size = extension_size;
status_request->status_type = static_cast<CertificateStatusType>(header_stream.read_1_bytes());
u16 responder_id_size = header_stream.read_2_bytes();
status_request->responder_id = header_stream.read_bytes(responder_id_size);
u16 request_extension_info_size = header_stream.read_2_bytes();
status_request->request_extension_info = header_stream.read_bytes(request_extension_info_size);
client_hello->extensions.append(move(status_request));
break;
}
case ExtensionType::SUPPORTED_GROUPS: {
auto supported_groups = create<SupportedGroups>();
supported_groups->type = extension_type;
supported_groups->size = extension_size;
u16 groups_count = header_stream.read_2_bytes();
for (u16 i = 0; i < groups_count / sizeof(SupportedGroup); i++) {
supported_groups->groups.append(static_cast<SupportedGroup>(header_stream.read_2_bytes()));
}
client_hello->extensions.append(move(supported_groups));
break;
}
case ExtensionType::EC_POINT_FORMATS: {
auto point_formats = create<ECPointFormats>();
point_formats->type = extension_type;
point_formats->size = extension_size;
u8 format_count = header_stream.read_1_bytes();
for (u8 i = 0; i < format_count; i++) {
point_formats->formats.append(static_cast<ECPointFormat>(header_stream.read_1_bytes()));
}
client_hello->extensions.append(move(point_formats));
break;
}
case ExtensionType::SIGNATURE_ALGORITHMS: {
auto signature_schemes = create<SignatureSchemes>();
signature_schemes->type = extension_type;
signature_schemes->size = extension_size;
u16 signature_count = header_stream.read_2_bytes();
for (u8 i = 0; i < signature_count / sizeof(SignatureScheme); i++) {
signature_schemes->signatures.append(static_cast<SignatureScheme>(header_stream.read_2_bytes()));
}
client_hello->extensions.append(move(signature_schemes));
break;
}
case ExtensionType::SESSION_TICKET: {
auto session_ticket = create<SessionTicket>();
session_ticket->type = extension_type;
session_ticket->size = extension_size;
client_hello->extensions.append(move(session_ticket));
break;
}
case ExtensionType::ENCRYPT_THEN_MAC: {
auto encrypt_then_mac = create<EncryptThenMac>();
encrypt_then_mac->type = extension_type;
encrypt_then_mac->size = extension_size;
client_hello->extensions.append(move(encrypt_then_mac));
break;
}
case ExtensionType::EXTENDED_MASTER_SECRET: {
auto extend_master_secret = create<ExtendMasterSecret>();
extend_master_secret->type = extension_type;
extend_master_secret->size = extension_size;
client_hello->extensions.append(move(extend_master_secret));
break;
}
case ExtensionType::KEY_SHARE: {
auto key_share = create<KeyShares>();
key_share->type = extension_type;
key_share->size = extension_size;
u16 key_share_byte_size = header_stream.read_2_bytes();
while (key_share_byte_size > 0) {
SupportedGroup group = static_cast<SupportedGroup>(header_stream.read_2_bytes());
u16 key_size = header_stream.read_2_bytes();
ByteBuffer key = header_stream.read_bytes(key_size);
key_share->keys.append(KeyShareEntry { group, key });
key_share_byte_size -= 4;
key_share_byte_size -= key_size;
}
client_hello->extensions.append(move(key_share));
break;
}
case ExtensionType::SUPPORTED_VERSIONS: {
auto supported_versions = create<SupportedVersions>();
supported_versions->type = extension_type;
supported_versions->size = extension_size;
u8 version_count = header_stream.read_1_bytes();
for (u8 i = 0; i < version_count / sizeof(SSLVersion); i++) {
supported_versions->versions.append(static_cast<SSLVersion>(header_stream.read_2_bytes()));
}
client_hello->extensions.append(move(supported_versions));
break;
}
case ExtensionType::RENEGOTIATION_INFO: {
auto renegotiation_info = create<RenegotiationInfo>();
renegotiation_info->type = extension_type;
renegotiation_info->size = extension_size;
u8 data_size = header_stream.read_1_bytes();
renegotiation_info->data = header_stream.read_bytes(data_size);
break;
}
case ExtensionType::PSK_KEY_EXCHANGE_MODES: {
auto exchange_modes = create<PSKKeyExchangeModes>();
exchange_modes->type = extension_type;
exchange_modes->size = extension_size;
u8 mode_counts = header_stream.read_1_bytes();
for (u8 i = 0; i < mode_counts; i++) {
exchange_modes->modes.append(static_cast<PSKKeyExchangeMode>(header_stream.read_1_bytes()));
}
client_hello->extensions.append(move(exchange_modes));
break;
}
case ExtensionType::RECORD_SIZE_LIMIT: {
auto size_limit = create<RecordSizeLimit>();
size_limit->type = extension_type;
size_limit->size = extension_size;
size_limit->limit = header_stream.read_2_bytes();
client_hello->extensions.append(move(size_limit));
break;
}
default:
dbgln("unhandled extension type: {}", static_cast<u16>(extension_type));
VERIFY_NOT_REACHED();
break;
}
}
return client_hello;
}
RefPtr<ClientKeyExchange> TLSTransport::parse_client_key_exchange(FTP::ByteReader& header_stream)
{
auto key_exchange = create<ClientKeyExchange>();
key_exchange->handshake_type = HandshakeType::CLIENT_KEY_EXCHANGE;
u32 key_length = header_stream.read_1_bytes();
key_exchange->public_key = header_stream.read_bytes(key_length);
dbgln("remaining: {}", header_stream.remaining());
return key_exchange;
}
ByteBuffer TLSTransport::build_server_hello(ClientHello* client_hello)
{
FTP::ByteWriter output;
// Packet header
output.write_1_bytes(static_cast<u8>(ContentType::HANDSHAKE));
output.write_2_bytes(static_cast<u16>(SSLVersion::VERSION_1_2));
u8 packet_size_offset = output.length();
output.write_2_bytes(0);
// TLS header (Server hello)
output.write_1_bytes(static_cast<u8>(HandshakeType::SERVER_HELLO));
u8 message_size_offset = output.length();
output.write_3_bytes(0);
output.write_2_bytes(static_cast<u16>(SSLVersion::VERSION_1_2));
output.write_bytes(m_context.server_random);
output.write_1_bytes(client_hello->session_id.size());
output.write_bytes(client_hello->session_id.bytes());
// FIXME: find first supported cipher in the list from the client_hello
output.write_2_bytes(static_cast<u16>(CipherSuite::TLS_RSA_WITH_AES_128_CBC_SHA));
output.write_1_bytes(static_cast<u8>(CompressionMethod::NONE));
// extensions
u8 extensions_size_offset = output.length();
output.write_2_bytes(0);
output.write_2_bytes(static_cast<u16>(ExtensionType::RENEGOTIATION_INFO));
output.write_2_bytes(1);
output.write_1_bytes(0);
// Since the offset includes the "size" part as well, we skip an additional "size" bytes
output.set_2_bytes(extensions_size_offset, output.length() - extensions_size_offset - 2);
output.set_3_bytes(message_size_offset, output.length() - message_size_offset - 3);
output.set_2_bytes(packet_size_offset, output.length() - packet_size_offset - 2);
return output.build();
}
ByteBuffer TLSTransport::build_server_certificate()
{
FTP::ByteWriter output;
// Packet header
output.write_1_bytes(static_cast<u8>(ContentType::HANDSHAKE));
output.write_2_bytes(static_cast<u16>(SSLVersion::VERSION_1_2));
u8 packet_size_offset = output.length();
output.write_2_bytes(0);
// TLS header (Server certificate)
output.write_1_bytes(static_cast<u8>(HandshakeType::CERTIFICATE));
u8 message_size_offset = output.length();
output.write_3_bytes(0);
u8 certificates_size_offset = output.length();
output.write_3_bytes(0);
u8 certificate_size_offset = output.length();
output.write_3_bytes(0);
auto stream_or_error = Core::InputFileStream::open("/usr/cert.der");
if (!stream_or_error.is_error()) {
auto& stream = stream_or_error.value();
auto buffer = ByteBuffer::create_uninitialized(4 * KiB);
while (!stream.has_any_error() && buffer.size() > 0) {
auto nread = stream.read(buffer);
buffer.resize(nread);
output.write_bytes(buffer.bytes());
}
}
// Since the offset includes the "size" part as well, we skip an additional "size" bytes
output.set_3_bytes(certificate_size_offset, output.length() - certificate_size_offset - 3);
output.set_3_bytes(certificates_size_offset, output.length() - certificates_size_offset - 3);
output.set_3_bytes(message_size_offset, output.length() - message_size_offset - 3);
output.set_2_bytes(packet_size_offset, output.length() - packet_size_offset - 2);
return output.build();
}
ByteBuffer TLSTransport::build_server_key_exchange()
{
FTP::ByteWriter output;
output.write_1_bytes(static_cast<u8>(ContentType::HANDSHAKE));
output.write_2_bytes(static_cast<u16>(SSLVersion::VERSION_1_2));
// TODO
return output.build();
}
ByteBuffer TLSTransport::build_server_hello_done()
{
FTP::ByteWriter output;
output.write_1_bytes(static_cast<u8>(ContentType::HANDSHAKE));
output.write_2_bytes(static_cast<u16>(SSLVersion::VERSION_1_2));
u8 packet_size_offset = output.length();
output.write_2_bytes(0);
output.write_1_bytes(static_cast<u8>(HandshakeType::SERVER_HELLO_DONE));
output.write_3_bytes(0); // 0 bytes of data
output.set_2_bytes(packet_size_offset, output.length() - packet_size_offset - 2);
return output.build();
}
String ClientHello::to_string()
{
StringBuilder builder;
builder.appendff("Client Hello:\n");
builder.appendff("\tSSL Version: {}\n", enum_to_string(ssl_version));
builder.appendff("\tClient random: {:hex-dump}\n", client_random.bytes());
builder.appendff("\tSession ID: {:hex-dump}\n", session_id.bytes());
builder.appendff("\tCipher suits:\n");
for (auto cipher : cipher_suites) {
builder.appendff("\t\t{}\n", enum_to_string(cipher));
}
builder.appendff("\tCompression methods:\n");
for (auto compression : compression_methods) {
builder.appendff("\t\t{}\n", enum_to_string(compression));
}
builder.appendff("\tExtensions:\n");
for (auto& extension : extensions) {
builder.appendff("{}", extension.to_string(2));
}
return builder.to_string();
}
String ClientKeyExchange::to_string()
{
StringBuilder builder;
builder.appendff("Client Key Exchange:\n");
builder.appendff("\tPublic Key: {:hex-dump}\n", public_key.bytes());
return builder.to_string();
}
/*
* Copyright (c) 2021, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "../Transport.h"
#include "ByteReader.h"
#include "Extensions.h"
#include <AK/NonnullRefPtrVector.h>
#include <AK/RefPtr.h>
#include <AK/Vector.h>
#include <LibCore/TCPSocket.h>
#pragma once
class TLSContext {
public:
ByteBuffer client_random;
ByteBuffer server_random;
};
class TLSHeader : public RefCounted<TLSHeader> {
public:
HandshakeType handshake_type {};
SSLVersion ssl_version {};
virtual ~TLSHeader() {};
};
class TLSRecord {
public:
ContentType content_type;
SSLVersion ssl_version {};
RefPtr<TLSHeader> header;
};
class ClientHello : public TLSHeader {
public:
SSLVersion ssl_version;
ByteBuffer client_random;
ByteBuffer session_id;
Vector<CipherSuite> cipher_suites;
Vector<CompressionMethod> compression_methods;
NonnullRefPtrVector<TLSExtension> extensions;
String to_string();
};
class ClientKeyExchange : public TLSHeader {
public:
ByteBuffer public_key;
String to_string();
};
class TLSTransport : public TransportBase {
public:
void init(ReadonlyBytes input, RefPtr<Core::Socket> connection);
ByteBuffer receive(int max_size, RefPtr<Core::Socket> connection);
bool send(ReadonlyBytes, RefPtr<Core::Socket> connection);
bool is_init() { return false; }
private:
TLSRecord decode_tls_record(ReadonlyBytes);
RefPtr<ClientHello> parse_client_hello(FTP::ByteReader&);
RefPtr<ClientKeyExchange> parse_client_key_exchange(FTP::ByteReader&);
ByteBuffer build_server_hello(ClientHello*);
ByteBuffer build_server_certificate();
ByteBuffer build_server_key_exchange();
ByteBuffer build_server_hello_done();
TLSContext m_context;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment