From a3b5e1b9b03fcec8bc764b033b5c066838a8ffe9 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Wed, 1 Jul 2020 18:18:15 -0700 Subject: [PATCH] Add initial drop of TLS parser (#262) --- THIRD-PARTY-NOTICES.TXT | 28 + src/ReverseProxy/Utilities/TlsFrameHelper.cs | 809 ++++ .../Utilities/TlsFrameHelperTests.cs | 3506 +++++++++++++++++ 3 files changed, 4343 insertions(+) create mode 100644 THIRD-PARTY-NOTICES.TXT create mode 100644 src/ReverseProxy/Utilities/TlsFrameHelper.cs create mode 100644 test/ReverseProxy.Tests/Utilities/TlsFrameHelperTests.cs diff --git a/THIRD-PARTY-NOTICES.TXT b/THIRD-PARTY-NOTICES.TXT new file mode 100644 index 000000000..2264270f1 --- /dev/null +++ b/THIRD-PARTY-NOTICES.TXT @@ -0,0 +1,28 @@ +License notice for TlsFrame Parser +------------------------------- + +https://github.com/dotnet/runtime/blob/master/LICENSE.txt + +The MIT License (MIT) + +Copyright (c) .NET Foundation and Contributors + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/ReverseProxy/Utilities/TlsFrameHelper.cs b/src/ReverseProxy/Utilities/TlsFrameHelper.cs new file mode 100644 index 000000000..3d2edf9ed --- /dev/null +++ b/src/ReverseProxy/Utilities/TlsFrameHelper.cs @@ -0,0 +1,809 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Diagnostics; +using System.Buffers.Binary; +using System.Globalization; +using System.Net.Security; +using System.Security.Authentication; +using System.Text; + +#nullable enable +namespace Microsoft.ReverseProxy.Utilities.Tls +{ + // SSL3/TLS protocol frames definitions. + internal enum TlsContentType : byte + { + ChangeCipherSpec = 20, + Alert = 21, + Handshake = 22, + AppData = 23 + } + + internal enum TlsHandshakeType : byte + { + HelloRequest = 0, + ClientHello = 1, + ServerHello = 2, + NewSessionTicket = 4, + EndOfEarlyData = 5, + EncryptedExtensions = 8, + Certificate = 11, + ServerKeyExchange = 12, + CertificateRequest = 13, + ServerHelloDone = 14, + CertificateVerify = 15, + ClientKeyExchange = 16, + Finished = 20, + KeyEpdate = 24, + MessageHash = 254 + } + + internal enum TlsAlertLevel : byte + { + Warning = 1, + Fatal = 2, + } + + internal enum TlsAlertDescription : byte + { + CloseNotify = 0, // warning + UnexpectedMessage = 10, // error + BadRecordMac = 20, // error + DecryptionFailed = 21, // reserved + RecordOverflow = 22, // error + DecompressionFail = 30, // error + HandshakeFailure = 40, // error + BadCertificate = 42, // warning or error + UnsupportedCert = 43, // warning or error + CertificateRevoked = 44, // warning or error + CertificateExpired = 45, // warning or error + CertificateUnknown = 46, // warning or error + IllegalParameter = 47, // error + UnknownCA = 48, // error + AccessDenied = 49, // error + DecodeError = 50, // error + DecryptError = 51, // error + ExportRestriction = 60, // reserved + ProtocolVersion = 70, // error + InsuffientSecurity = 71, // error + InternalError = 80, // error + UserCanceled = 90, // warning or error + NoRenegotiation = 100, // warning + UnsupportedExt = 110, // error + } + + internal enum ExtensionType : ushort + { + ServerName = 0, + MaximumFagmentLength = 1, + ClientCertificateUrl = 2, + TrustedCaKeys = 3, + TruncatedHmac = 4, + CertificateStatusRequest = 5, + ApplicationProtocols = 16, + SupportedVersions = 43 + } + + internal struct TlsFrameHeader + { + public TlsContentType Type; + public SslProtocols Version; + public int Length; + + public override string ToString() => $"{Version}:{Type}[{Length}]"; + } + + internal class TlsFrameHelper + { + public const int HeaderSize = 5; + + [Flags] + public enum ProcessingOptions + { + All = 0, + ServerName = 0x1, + ApplicationProtocol = 0x2, + Versions = 0x4, + } + + [Flags] + public enum ApplicationProtocolInfo + { + None = 0, + Http11 = 1, + Http2 = 2, + Http3 = 4, + Other = 128 + } + + public struct TlsFrameInfo + { + public TlsFrameHeader Header; + public TlsHandshakeType HandshakeType; + public SslProtocols SupportedVersions; + public string TargetName; + public ApplicationProtocolInfo ApplicationProtocols; + public TlsAlertDescription AlertDescription; + + public override string ToString() + { + if (Header.Type == TlsContentType.Handshake) + { + if (HandshakeType == TlsHandshakeType.ClientHello) + { + return $"{Header.Version}:{HandshakeType}[{Header.Length}] TargetName='{TargetName}' SupportedVersion='{SupportedVersions}' ApplicationProtocols='{ApplicationProtocols}'"; + } + else if (HandshakeType == TlsHandshakeType.ServerHello) + { + return $"{Header.Version}:{HandshakeType}[{Header.Length}] SupportedVersion='{SupportedVersions}' ApplicationProtocols='{ApplicationProtocols}'"; + } + else + { + return $"{Header.Version}:{HandshakeType}[{Header.Length}] SupportedVersion='{SupportedVersions}'"; + } + } + else + { + return $"{Header.Version}:{Header.Type}[{Header.Length}]"; + } + } + } + + public delegate bool HelloExtensionCallback(ref TlsFrameInfo info, ExtensionType type, ReadOnlySpan extensionsData); + + private static byte[] s_protocolMismatch13 = new byte[] { (byte)TlsContentType.Alert, 3, 4, 0, 2, 2, 70 }; + private static byte[] s_protocolMismatch12 = new byte[] { (byte)TlsContentType.Alert, 3, 3, 0, 2, 2, 70 }; + private static byte[] s_protocolMismatch11 = new byte[] { (byte)TlsContentType.Alert, 3, 2, 0, 2, 2, 70 }; + private static byte[] s_protocolMismatch10 = new byte[] { (byte)TlsContentType.Alert, 3, 1, 0, 2, 2, 70 }; + private static byte[] s_protocolMismatch30 = new byte[] { (byte)TlsContentType.Alert, 3, 0, 0, 2, 2, 40 }; + + private const int UInt24Size = 3; + private const int RandomSize = 32; + private const int ProtocolVersionMajorOffset = 0; + private const int ProtocolVersionMinorOffset = 1; + private const int ProtocolVersionSize = 2; + private const int ProtocolVersionTlsMajorValue = 3; + + // Per spec "AllowUnassigned flag MUST be set". See comment above DecodeString() for more details. + private static readonly IdnMapping IdnMapping = new IdnMapping() { AllowUnassigned = true }; + private static readonly Encoding Utf8Encoding = Encoding.GetEncoding("utf-8", new EncoderExceptionFallback(), new DecoderExceptionFallback()); + + public static bool TryGetFrameHeader(ReadOnlySpan frame, ref TlsFrameHeader header) + { + bool result = frame.Length > 4; + + if (frame.Length >= 1) + { + header.Type = (TlsContentType)frame[0]; + + if (frame.Length >= 3) + { + // SSLv3, TLS or later + if (frame[1] == 3) + { + if (frame.Length > 4) + { + header.Length = ((frame[3] << 8) | frame[4]); + } + + header.Version = TlsMinorVersionToProtocol(frame[2]); + } + else + { + header.Length = -1; + header.Version = SslProtocols.None; + } + } + } + + return result; + } + + // Returns frame size e.g. header + content + public static int GetFrameSize(ReadOnlySpan frame) + { + if (frame.Length < 5 || frame[1] < 3) + { + return - 1; + } + + return ((frame[3] << 8) | frame[4]) + HeaderSize; + } + + // This function will try to parse TLS hello frame and fill details in provided info structure. + // If frame was fully processed without any error, function returns true. + // Otherwise it returns false and info may have partial data. + // It is OK to call it again if more data becomes available. + // It is also possible to limit what information is processed. + // If callback delegate is provided, it will be called on ALL extensions. + public static bool TryGetFrameInfo(ReadOnlySpan frame, ref TlsFrameInfo info, ProcessingOptions options = ProcessingOptions.All, HelloExtensionCallback? callback = null) + { + const int HandshakeTypeOffset = 5; + if (frame.Length < HeaderSize) + { + return false; + } + + // This will not fail since we have enough data. + bool gotHeader = TryGetFrameHeader(frame, ref info.Header); + Debug.Assert(gotHeader); + + info.SupportedVersions = info.Header.Version; + + if (info.Header.Type == TlsContentType.Alert) + { + TlsAlertLevel level = default; + TlsAlertDescription description = default; + if (TryGetAlertInfo(frame, ref level, ref description)) + { + info.AlertDescription = description; + return true; + } + + return false; + } + + if (info.Header.Type != TlsContentType.Handshake || frame.Length <= HandshakeTypeOffset) + { + return false; + } + + info.HandshakeType = (TlsHandshakeType)frame[HandshakeTypeOffset]; + + // Check if we have full frame. + bool isComplete = frame.Length >= HeaderSize + info.Header.Length; + + if (((int)info.Header.Version >= (int)SslProtocols.Tls) && + (info.HandshakeType == TlsHandshakeType.ClientHello || info.HandshakeType == TlsHandshakeType.ServerHello)) + { + if (!TryParseHelloFrame(frame.Slice(HeaderSize), ref info, options, callback)) + { + isComplete = false; + } + } + + return isComplete; + } + + // This is similar to TryGetFrameInfo but it will only process SNI. + // It returns TargetName as string or NULL if SNI is missing or parsing error happened. + public static string? GetServerName(ReadOnlySpan frame) + { + TlsFrameInfo info = default; + if (!TryGetFrameInfo(frame, ref info, ProcessingOptions.ServerName)) + { + return null; + } + + return info.TargetName; + } + + // This function will parse TLS Alert message and it will return alert level and description. + public static bool TryGetAlertInfo(ReadOnlySpan frame, ref TlsAlertLevel level, ref TlsAlertDescription description) + { + if (frame.Length < 7 || frame[0] != (byte)TlsContentType.Alert) + { + return false; + } + + level = (TlsAlertLevel)frame[5]; + description = (TlsAlertDescription)frame[6]; + + return true; + } + + private static byte[] CreateProtocolVersionAlert(SslProtocols version) => + version switch + { + SslProtocols.Tls13 => s_protocolMismatch13, + SslProtocols.Tls12 => s_protocolMismatch12, + SslProtocols.Tls11 => s_protocolMismatch11, + SslProtocols.Tls => s_protocolMismatch10, +#pragma warning disable 0618 + SslProtocols.Ssl3 => s_protocolMismatch30, +#pragma warning restore 0618 + _ => Array.Empty(), + }; + + public static byte[] CreateAlertFrame(SslProtocols version, TlsAlertDescription reason) + { + if (reason == TlsAlertDescription.ProtocolVersion) + { + return CreateProtocolVersionAlert(version); + } + else if ((int)version > (int)SslProtocols.Tls) + { + // Create TLS1.2 alert + byte[] buffer = new byte[] { (byte)TlsContentType.Alert, 3, 3, 0, 2, 2, (byte)reason }; + switch (version) + { + case SslProtocols.Tls13: + buffer[2] = 4; + break; + case SslProtocols.Tls11: + buffer[2] = 2; + break; + case SslProtocols.Tls: + buffer[2] = 1; + break; + } + + return buffer; + } + + return Array.Empty(); + } + + private static bool TryParseHelloFrame(ReadOnlySpan sslHandshake, ref TlsFrameInfo info, ProcessingOptions options, HelloExtensionCallback? callback) + { + // https://tools.ietf.org/html/rfc6101#section-5.6 + // struct { + // HandshakeType msg_type; /* handshake type */ + // uint24 length; /* bytes in message */ + // select (HandshakeType) { + // ... + // case client_hello: ClientHello; + // case server_hello: ServerHello; + // ... + // } body; + // } Handshake; + const int HandshakeTypeOffset = 0; + const int HelloLengthOffset = HandshakeTypeOffset + sizeof(TlsHandshakeType); + const int HelloOffset = HelloLengthOffset + UInt24Size; + + if (sslHandshake.Length < HelloOffset || + ((TlsHandshakeType)sslHandshake[HandshakeTypeOffset] != TlsHandshakeType.ClientHello && + (TlsHandshakeType)sslHandshake[HandshakeTypeOffset] != TlsHandshakeType.ServerHello)) + { + return false; + } + + int helloLength = ReadUInt24BigEndian(sslHandshake.Slice(HelloLengthOffset)); + ReadOnlySpan helloData = sslHandshake.Slice(HelloOffset); + + if (helloData.Length < helloLength) + { + return false; + } + + // ProtocolVersion may be different from frame header. + if (helloData[ProtocolVersionMajorOffset] == ProtocolVersionTlsMajorValue) + { + info.SupportedVersions |= TlsMinorVersionToProtocol(helloData[ProtocolVersionMinorOffset]); + } + + return (TlsHandshakeType)sslHandshake[HandshakeTypeOffset] == TlsHandshakeType.ClientHello ? + TryParseClientHello(helloData.Slice(0, helloLength), ref info, options, callback) : + TryParseServerHello(helloData.Slice(0, helloLength), ref info, options, callback); + } + + private static bool TryParseClientHello(ReadOnlySpan clientHello, ref TlsFrameInfo info, ProcessingOptions options, HelloExtensionCallback? callback) + { + // Basic structure: https://tools.ietf.org/html/rfc6101#section-5.6.1.2 + // Extended structure: https://tools.ietf.org/html/rfc3546#section-2.1 + // struct { + // ProtocolVersion client_version; // 2x uint8 + // Random random; // 32 bytes + // SessionID session_id; // opaque type + // CipherSuite cipher_suites<2..2^16-1>; // opaque type + // CompressionMethod compression_methods<1..2^8-1>; // opaque type + // Extension client_hello_extension_list<0..2^16-1>; + // } ClientHello; + + ReadOnlySpan p = SkipBytes(clientHello, ProtocolVersionSize + RandomSize); + + // Skip SessionID (max size 32 => size fits in 1 byte) + p = SkipOpaqueType1(p); + + // Skip cipher suites (max size 2^16-1 => size fits in 2 bytes) + p = SkipOpaqueType2(p); + + // Skip compression methods (max size 2^8-1 => size fits in 1 byte) + p = SkipOpaqueType1(p); + + // is invalid structure or no extensions? + if (p.IsEmpty) + { + return false; + } + + // client_hello_extension_list (max size 2^16-1 => size fits in 2 bytes) + int extensionListLength = BinaryPrimitives.ReadUInt16BigEndian(p); + p = SkipBytes(p, sizeof(ushort)); + if (extensionListLength != p.Length) + { + return false; + } + + return TryParseHelloExtensions(p, ref info, options, callback); + } + + private static bool TryParseServerHello(ReadOnlySpan serverHello, ref TlsFrameInfo info, ProcessingOptions options, HelloExtensionCallback? callback) + { + // Basic structure: https://tools.ietf.org/html/rfc6101#section-5.6.1.3 + // Extended structure: https://tools.ietf.org/html/rfc3546#section-2.2 + // struct { + // ProtocolVersion server_version; + // Random random; + // SessionID session_id; + // CipherSuite cipher_suite; + // CompressionMethod compression_method; + // Extension server_hello_extension_list<0..2^16-1>; + // } + // ServerHello; + const int CipherSuiteLength = 2; + const int CompressionMethiodLength = 1; + + ReadOnlySpan p = SkipBytes(serverHello, ProtocolVersionSize + RandomSize); + // Skip SessionID (max size 32 => size fits in 1 byte) + p = SkipOpaqueType1(p); + p = SkipBytes(p, CipherSuiteLength + CompressionMethiodLength); + + // is invalid structure or no extensions? + if (p.IsEmpty) + { + return false; + } + + // client_hello_extension_list (max size 2^16-1 => size fits in 2 bytes) + int extensionListLength = BinaryPrimitives.ReadUInt16BigEndian(p); + p = SkipBytes(p, sizeof(ushort)); + if (extensionListLength != p.Length) + { + return false; + } + + return TryParseHelloExtensions(p, ref info, options, callback); + } + + // This is common for ClientHello and ServerHello. + private static bool TryParseHelloExtensions(ReadOnlySpan extensions, ref TlsFrameInfo info, ProcessingOptions options, HelloExtensionCallback? callback) + { + const int ExtensionHeader = 4; + bool isComplete = true; + + while (extensions.Length >= ExtensionHeader) + { + ExtensionType extensionType = (ExtensionType)BinaryPrimitives.ReadUInt16BigEndian(extensions); + extensions = SkipBytes(extensions, sizeof(ushort)); + + ushort extensionLength = BinaryPrimitives.ReadUInt16BigEndian(extensions); + extensions = SkipBytes(extensions, sizeof(ushort)); + if (extensions.Length < extensionLength) + { + isComplete = false; + break; + } + + ReadOnlySpan extensionData = extensions.Slice(0, extensionLength); + + if (extensionType == ExtensionType.ServerName && (options == ProcessingOptions.All || + (options & ProcessingOptions.ServerName) == ProcessingOptions.ServerName)) + { + if (!TryGetSniFromServerNameList(extensionData, out string? sni)) + { + return false; + } + + info.TargetName = sni!; + } + else if (extensionType == ExtensionType.SupportedVersions && (options == ProcessingOptions.All || + (options & ProcessingOptions.Versions) == ProcessingOptions.Versions)) + { + if (!TryGetSupportedVersionsFromExtension(extensionData, out SslProtocols versions)) + { + return false; + } + + info.SupportedVersions |= versions; + } + else if (extensionType == ExtensionType.ApplicationProtocols && (options == ProcessingOptions.All || + (options & ProcessingOptions.ApplicationProtocol) == ProcessingOptions.ApplicationProtocol)) + { + if (!TryGetApplicationProtocolsFromExtension(extensionData, out ApplicationProtocolInfo alpn)) + { + return false; + } + + info.ApplicationProtocols |= alpn; + } + + callback?.Invoke(ref info, extensionType, extensionData); + extensions = extensions.Slice(extensionLength); + } + + return isComplete; + } + + private static bool TryGetSniFromServerNameList(ReadOnlySpan serverNameListExtension, out string? sni) + { + // https://tools.ietf.org/html/rfc3546#section-3.1 + // struct { + // ServerName server_name_list<1..2^16-1> + // } ServerNameList; + // ServerNameList is an opaque type (length of sufficient size for max data length is prepended) + const int ServerNameListOffset = sizeof(ushort); + sni = null; + + if (serverNameListExtension.Length < ServerNameListOffset) + { + return false; + } + + int serverNameListLength = BinaryPrimitives.ReadUInt16BigEndian(serverNameListExtension); + ReadOnlySpan serverNameList = serverNameListExtension.Slice(ServerNameListOffset); + + if (serverNameListLength != serverNameList.Length) + { + return false; + } + + ReadOnlySpan serverName = serverNameList.Slice(0, serverNameListLength); + + sni = GetSniFromServerName(serverName, out bool invalid); + return invalid == false; + } + + private static string? GetSniFromServerName(ReadOnlySpan serverName, out bool invalid) + { + // https://tools.ietf.org/html/rfc3546#section-3.1 + // struct { + // NameType name_type; + // select (name_type) { + // case host_name: HostName; + // } name; + // } ServerName; + // ServerName is an opaque type (length of sufficient size for max data length is prepended) + const int NameTypeOffset = 0; + const int HostNameStructOffset = NameTypeOffset + sizeof(NameType); + if (serverName.Length < HostNameStructOffset) + { + invalid = true; + return null; + } + + // Following can underflow but it is ok due to equality check below + int hostNameStructLength = BinaryPrimitives.ReadUInt16BigEndian(serverName) - sizeof(NameType); + NameType nameType = (NameType)serverName[NameTypeOffset]; + ReadOnlySpan hostNameStruct = serverName.Slice(HostNameStructOffset); + if (nameType != NameType.HostName) + { + invalid = true; + return null; + } + + return GetSniFromHostNameStruct(hostNameStruct, out invalid); + } + + private static string? GetSniFromHostNameStruct(ReadOnlySpan hostNameStruct, out bool invalid) + { + // https://tools.ietf.org/html/rfc3546#section-3.1 + // HostName is an opaque type (length of sufficient size for max data length is prepended) + const int HostNameLengthOffset = 0; + const int HostNameOffset = HostNameLengthOffset + sizeof(ushort); + + int hostNameLength = BinaryPrimitives.ReadUInt16BigEndian(hostNameStruct); + ReadOnlySpan hostName = hostNameStruct.Slice(HostNameOffset); + if (hostNameLength != hostName.Length) + { + invalid = true; + return null; + } + + invalid = false; + return DecodeString(hostName); + } + + private static bool TryGetSupportedVersionsFromExtension(ReadOnlySpan extensionData, out SslProtocols protocols) + { + // https://tools.ietf.org/html/rfc8446#section-4.2.1 + // struct { + // select(Handshake.msg_type) { + // case client_hello: + // ProtocolVersion versions<2..254 >; + // + // case server_hello: /* and HelloRetryRequest */ + // ProtocolVersion selected_version; + // }; + const int VersionListLengthOffset = 0; + const int VersionListNameOffset = VersionListLengthOffset + sizeof(byte); + const int VersionLength = 2; + + protocols = SslProtocols.None; + + byte supportedVersionLength = extensionData[VersionListLengthOffset]; + extensionData = extensionData.Slice(VersionListNameOffset); + + if (extensionData.Length != supportedVersionLength) + { + return false; + } + + // Get list of protocols we support.I nore the rest. + while (extensionData.Length >= VersionLength) + { + if (extensionData[ProtocolVersionMajorOffset] == ProtocolVersionTlsMajorValue) + { + protocols |= TlsMinorVersionToProtocol(extensionData[ProtocolVersionMinorOffset]); + } + + extensionData = extensionData.Slice(VersionLength); + } + + return true; + } + + private static bool TryGetApplicationProtocolsFromExtension(ReadOnlySpan extensionData, out ApplicationProtocolInfo alpn) + { + // https://tools.ietf.org/html/rfc7301#section-3.1 + // opaque ProtocolName<1..2 ^ 8 - 1 >; + // + // struct { + // ProtocolName protocol_name_list<2..2^16-1> + // } + // ProtocolNameList; + const int AlpnListLengthOffset = 0; + const int AlpnListOffset = AlpnListLengthOffset + sizeof(short); + + alpn = ApplicationProtocolInfo.None; + + if (extensionData.Length < AlpnListOffset) + { + return false; + } + + int AlpnListLength = BinaryPrimitives.ReadUInt16BigEndian(extensionData); + ReadOnlySpan alpnList = extensionData.Slice(AlpnListOffset); + if (AlpnListLength != alpnList.Length) + { + return false; + } + + while (!alpnList.IsEmpty) + { + byte protocolLength = alpnList[0]; + if (alpnList.Length < protocolLength + 1) + { + return false; + } + + ReadOnlySpan protocol = alpnList.Slice(1, protocolLength); + if (protocolLength == 2) + { + if (protocol.SequenceEqual(SslApplicationProtocol.Http2.Protocol.Span)) + { + alpn |= ApplicationProtocolInfo.Http2; + } +#if NET5 + else if (protocol.SequenceEqual(SslApplicationProtocol.Http3.Protocol.Span)) + { + alpn |= ApplicationProtocolInfo.Http3; + } +#endif + else + { + alpn |= ApplicationProtocolInfo.Other; + } + } + else if (protocolLength == SslApplicationProtocol.Http11.Protocol.Length && + protocol.SequenceEqual(SslApplicationProtocol.Http11.Protocol.Span)) + { + alpn |= ApplicationProtocolInfo.Http11; + } + else + { + alpn |= ApplicationProtocolInfo.Other; + } + + alpnList = alpnList.Slice(protocolLength + 1); + } + + return true; + } + + private static SslProtocols TlsMinorVersionToProtocol(byte value) + { + return value switch + { + 4 => SslProtocols.Tls13, + 3 => SslProtocols.Tls12, + 2 => SslProtocols.Tls11, + 1 => SslProtocols.Tls, +#pragma warning disable 0618 + 0 => SslProtocols.Ssl3, +#pragma warning restore 0618 + _ => SslProtocols.None, + }; + } + + private static string? DecodeString(ReadOnlySpan bytes) + { + // https://tools.ietf.org/html/rfc3546#section-3.1 + // Per spec: + // If the hostname labels contain only US-ASCII characters, then the + // client MUST ensure that labels are separated only by the byte 0x2E, + // representing the dot character U+002E (requirement 1 in section 3.1 + // of [IDNA] notwithstanding). If the server needs to match the HostName + // against names that contain non-US-ASCII characters, it MUST perform + // the conversion operation described in section 4 of [IDNA], treating + // the HostName as a "query string" (i.e. the AllowUnassigned flag MUST + // be set). Note that IDNA allows labels to be separated by any of the + // Unicode characters U+002E, U+3002, U+FF0E, and U+FF61, therefore + // servers MUST accept any of these characters as a label separator. If + // the server only needs to match the HostName against names containing + // exclusively ASCII characters, it MUST compare ASCII names case- + // insensitively. + + string idnEncodedString; + try + { + idnEncodedString = Utf8Encoding.GetString(bytes); + } + catch (DecoderFallbackException) + { + return null; + } + + try + { + return IdnMapping.GetUnicode(idnEncodedString); + } + catch (ArgumentException) + { + // client has not done IDN mapping + return idnEncodedString; + } + } + + private static int ReadUInt24BigEndian(ReadOnlySpan bytes) + { + return (bytes[0] << 16) | (bytes[1] << 8) | bytes[2]; + } + + private static ReadOnlySpan SkipBytes(ReadOnlySpan bytes, int numberOfBytesToSkip) + { + return (numberOfBytesToSkip < bytes.Length) ? bytes.Slice(numberOfBytesToSkip) : ReadOnlySpan.Empty; + } + + // Opaque type is of structure: + // - length (minimum number of bytes to hold the max value) + // - data (length bytes) + // We will only use opaque types which are of max size: 255 (length = 1) or 2^16-1 (length = 2). + // We will call them SkipOpaqueType`length` + private static ReadOnlySpan SkipOpaqueType1(ReadOnlySpan bytes) + { + const int OpaqueTypeLengthSize = sizeof(byte); + if (bytes.Length < OpaqueTypeLengthSize) + { + return ReadOnlySpan.Empty; + } + + byte length = bytes[0]; + int totalBytes = OpaqueTypeLengthSize + length; + + return SkipBytes(bytes, totalBytes); + } + + private static ReadOnlySpan SkipOpaqueType2(ReadOnlySpan bytes) + { + const int OpaqueTypeLengthSize = sizeof(ushort); + if (bytes.Length < OpaqueTypeLengthSize) + { + return ReadOnlySpan.Empty; + } + + ushort length = BinaryPrimitives.ReadUInt16BigEndian(bytes); + int totalBytes = OpaqueTypeLengthSize + length; + + return SkipBytes(bytes, totalBytes); + } + + private enum NameType : byte + { + HostName = 0x00 + } + } +} diff --git a/test/ReverseProxy.Tests/Utilities/TlsFrameHelperTests.cs b/test/ReverseProxy.Tests/Utilities/TlsFrameHelperTests.cs new file mode 100644 index 000000000..7a36f1579 --- /dev/null +++ b/test/ReverseProxy.Tests/Utilities/TlsFrameHelperTests.cs @@ -0,0 +1,3506 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Authentication; +using Xunit; + +namespace Microsoft.ReverseProxy.Utilities.Tls +{ + public class TlsFrameHelperTests + { + [Fact] + public void SniHelper_ValidData_Ok() + { + InvalidClientHello(s_validClientHello, -1, shouldPass: true); + } + + [Theory] + [MemberData(nameof(InvalidClientHelloData))] + public void SniHelper_InvalidData_Fails(int id, byte[] clientHello) + { + InvalidClientHello(clientHello, id, shouldPass: false); + } + + [Theory] + [MemberData(nameof(InvalidClientHelloDataTruncatedBytes))] + public void SniHelper_TruncatedData_Fails(int id, byte[] clientHello) + { + InvalidClientHello(clientHello, id, shouldPass: false); + } + + private void InvalidClientHello(byte[] clientHello, int id, bool shouldPass) + { + string ret = TlsFrameHelper.GetServerName(clientHello); + if (shouldPass) + Assert.NotNull(ret); + else + Assert.Null(ret); + } + + [Fact] + public void TlsFrameHelper_ValidData_Ok() + { + TlsFrameHelper.TlsFrameInfo info = default; + Assert.True(TlsFrameHelper.TryGetFrameInfo(s_validClientHello, ref info)); + + Assert.Equal(SslProtocols.Tls12, info.Header.Version); + Assert.Equal(203, info.Header.Length); + Assert.Equal(SslProtocols.Tls12, info.SupportedVersions); + Assert.Equal(TlsFrameHelper.ApplicationProtocolInfo.None, info.ApplicationProtocols); + } + + [Fact] + public void TlsFrameHelper_Tls12ClientHello_Ok() + { + TlsFrameHelper.TlsFrameInfo info = default; + Assert.True(TlsFrameHelper.TryGetFrameInfo(s_Tls12ClientHello, ref info)); + + Assert.Equal(SslProtocols.Tls, info.Header.Version); + Assert.Equal(SslProtocols.Tls|SslProtocols.Tls12, info.SupportedVersions); + Assert.Equal(TlsFrameHelper.ApplicationProtocolInfo.Http11 | TlsFrameHelper.ApplicationProtocolInfo.Http2, info.ApplicationProtocols); + } + + [Fact] + public void TlsFrameHelper_Tls13ClientHello_Ok() + { + TlsFrameHelper.TlsFrameInfo info = default; + Assert.True(TlsFrameHelper.TryGetFrameInfo(s_Tls13ClientHello, ref info)); + + Assert.Equal(SslProtocols.Tls, info.Header.Version); + Assert.Equal(SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, info.SupportedVersions); + Assert.Equal(TlsFrameHelper.ApplicationProtocolInfo.Other, info.ApplicationProtocols); + } + + [Fact] + public void TlsFrameHelper_Tls12ServerHello_Ok() + { + TlsFrameHelper.TlsFrameInfo info = default; + Assert.True(TlsFrameHelper.TryGetFrameInfo(s_Tls12ServerHello, ref info)); + + Assert.Equal(SslProtocols.Tls12, info.Header.Version); + Assert.Equal(SslProtocols.Tls12, info.SupportedVersions); + Assert.Equal(TlsFrameHelper.ApplicationProtocolInfo.Http2, info.ApplicationProtocols); + } + + public static IEnumerable InvalidClientHelloData() + { + int id = 0; + foreach (byte[] invalidClientHello in InvalidClientHello()) + { + id++; + yield return new object[] { id, invalidClientHello }; + } + } + + public static IEnumerable InvalidClientHelloDataTruncatedBytes() + { + // converting to base64 first to remove duplicated test cases + var uniqueInvalidHellos = new HashSet(); + foreach (byte[] invalidClientHello in InvalidClientHello()) + { + for (int i = 0; i < invalidClientHello.Length - 1; i++) + { + uniqueInvalidHellos.Add(Convert.ToBase64String(invalidClientHello.Take(i).ToArray())); + } + } + + for (int i = 0; i < s_validClientHello.Length - 1; i++) + { + uniqueInvalidHellos.Add(Convert.ToBase64String(s_validClientHello.Take(i).ToArray())); + } + + int id = 0; + foreach (string invalidClientHello in uniqueInvalidHellos) + { + id++; + yield return new object[] { id, Convert.FromBase64String(invalidClientHello) }; + } + } + + private static byte[] s_validClientHello = new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x0C, 0x3C, 0x85, 0x78, 0xCA, + 0x67, 0x70, 0xAA, 0x38, 0xCB, + 0x28, 0xBC, 0xDC, 0x3E, 0x30, + 0xBF, 0x11, 0x96, 0x95, 0x1A, + 0xB9, 0xF0, 0x99, 0xA4, 0x91, + 0x09, 0x13, 0xB4, 0x89, 0x94, + 0x27, 0x2E, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + private static byte[] s_Tls12ClientHello = new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x01, + // SslPlainText.length + 0x00, 0xD1, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xCD, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x0C, 0x3C, 0x85, 0x78, 0xCA, + 0x67, 0x70, 0xAA, 0x38, 0xCB, + 0x28, 0xBC, 0xDC, 0x3E, 0x30, + 0xBF, 0x11, 0x96, 0x95, 0x1A, + 0xB9, 0xF0, 0x99, 0xA4, 0x91, + 0x09, 0x13, 0xB4, 0x89, 0x94, + 0x27, 0x2E, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites_length + 0x00, 0x5C, + // ClientHello.cipher_suites + 0xC0, 0x30, 0xC0, 0x2C, 0xC0, 0x28, 0xC0, 0x24, + 0xC0, 0x14, 0xC0, 0x0A, 0x00, 0x9f, 0x00, 0x6B, + 0x00, 0x39, 0xCC, 0xA9, 0xCC, 0xA8, 0xCC, 0xAA, + 0xFF, 0x85, 0x00, 0xC4, 0x00, 0x88, 0x00, 0x81, + 0x00, 0x9D, 0x00, 0x3D, 0x00, 0x35, 0x00, 0xC0, + 0x00, 0x84, 0xC0, 0x2f, 0xC0, 0x2B, 0xC0, 0x27, + 0xC0, 0x23, 0xC0, 0x13, 0xC0, 0x09, 0x00, 0x9E, + 0x00, 0x67, 0x00, 0x33, 0x00, 0xBE, 0x00, 0x45, + 0x00, 0x9C, 0x00, 0x3C, 0x00, 0x2F, 0x00, 0xBA, + 0x00, 0x41, 0xC0, 0x11, 0xC0, 0x07, 0x00, 0x05, + 0x00, 0x04, 0xC0, 0x12, 0xC0, 0x08, 0x00, 0x16, + 0x00, 0x0a, 0x00, 0xff, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x48, + // Extension.extension_type (ec_point_formats) + 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (supported_groups) + 0x00, 0x0A, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1D, + 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (session_ticket) + 0x00, 0x23, 0x00, 0x00, + // Extension.extension_type (signature_algorithms) + 0x00, 0x0D, 0x00, 0x1C, 0x00, 0x1A, 0x06, 0x01, + 0x06, 0x03, 0xEF, 0xEF, 0x05, 0x01, 0x05, 0x03, + 0x04, 0x01, 0x04, 0x03, 0xEE, 0xEE, 0xED, 0xED, + 0x03, 0x01, 0x03, 0x03, 0x02, 0x01, 0x02, 0x03, + // Extension.extension_type (application_level_Protocol) + 0x00, 0x10, 0x00, 0x0e, 0x00, 0x0C, 0x02, 0x68, + 0x32, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2F, 0x31, + 0x2E, 0x31 + }; + + private static byte[] s_Tls13ClientHello = new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x01, + // SslPlainText.length + 0x01, 0x08, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x01, 0x04, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x0C, 0x3C, 0x85, 0x78, 0xCA, 0x67, 0x70, 0xAA, + 0x38, 0xCB, 0x28, 0xBC, 0xDC, 0x3E, 0x30, 0xBF, + 0x11, 0x96, 0x95, 0x1A, 0xB9, 0xF0, 0x99, 0xA4, + 0x91, 0x09, 0x13, 0xB4, 0x89, 0x94, 0x27, 0x2E, + // ClientHello.SessionId_Length + 0x20, + // ClientHello.SessionId + 0x0C, 0x3C, 0x85, 0x78, 0xCA, 0x67, 0x70, 0xAA, + 0x38, 0xCB, 0x28, 0xBC, 0xDC, 0x3E, 0x30, 0xBF, + 0x11, 0x96, 0x95, 0x1A, 0xB9, 0xF0, 0x99, 0xA4, + 0x91, 0x09, 0x13, 0xB4, 0x89, 0x94, 0x27, 0x2E, + // ClientHello.cipher_suites_length + 0x00, 0x0C, + // ClientHello.cipher_suites + 0x13, 0x02, 0x13, 0x03, 0x13, 0x01, 0xC0, 0x14, + 0xc0, 0x30, 0x00, 0xFF, + // ClientHello.compression_methods + 0x01, 0x00, + // ClientHello.extension_list_length + 0x00, 0xAF, + // Extension.extension_type (server_name) (10.211.55.2) + 0x00, 0x00, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, + 0x0B, 0x31, 0x30, 0x2E, 0x32, 0x31, 0x31, 0x2E, + 0x35, 0x35, 0x2E, 0x32, + // Extension.extension_type (ec_point_formats) + 0x00, 0x0B, 0x00, 0x04, 0x03, 0x00, 0x01, 0x02, + // Extension.extension_type (supported_groups) + 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0A, 0x00, 0x1D, + 0x00, 0x17, 0x00, 0x1E, 0x00, 0x19, 0x00, 0x18, + // Extension.extension_type (application_level_Protocol) (boo) + 0x00, 0x10, 0x00, 0x06, 0x00, 0x04, 0x03, 0x62, + 0x6f, 0x6f, + // Extension.extension_type (encrypt_then_mac) + 0x00, 0x16, 0x00, 0x00, + // Extension.extension_type (extended_master_key_secret) + 0x00, 0x17, 0x00, 0x00, + // Extension.extension_type (signature_algorithms) + 0x00, 0x0D, 0x00, 0x30, 0x00, 0x2E, + 0x06, 0x03, 0xEF, 0xEF, 0x05, 0x01, 0x05, 0x03, + 0x06, 0x03, 0xEF, 0xEF, 0x05, 0x01, 0x05, 0x03, + 0x06, 0x03, 0xEF, 0xEF, 0x05, 0x01, 0x05, 0x03, + 0x04, 0x01, 0x04, 0x03, 0xEE, 0xEE, 0xED, 0xED, + 0x03, 0x01, 0x03, 0x03, 0x02, 0x01, 0x02, 0x03, + 0x03, 0x01, 0x03, 0x03, 0x02, 0x01, + // Extension.extension_type (supported_versions) + 0x00, 0x2B, 0x00, 0x09, 0x08, 0x03, 0x04, 0x03, + 0x03, 0x03, 0x02, 0x03, 0x01, + // Extension.extension_type (psk_key_exchange_modes) + 0x00, 0x2D, 0x00, 0x02, 0x01, 0x01, + // Extension.extension_type (key_share) + 0x00, 0x33, 0x00, 0x26, 0x00, 0x24, 0x00, 0x1D, + 0x00, 0x20, + 0x04, 0x01, 0x04, 0x03, 0xEE, 0xEE, 0xED, 0xED, + 0x03, 0x01, 0x03, 0x03, 0x02, 0x01, 0x02, 0x03, + 0x04, 0x01, 0x04, 0x03, 0xEE, 0xEE, 0xED, 0xED, + 0x03, 0x01, 0x03, 0x03, 0x02, 0x01, 0x02, 0x03 + }; + + private static byte[] s_Tls12ServerHello = new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0x64, + // Handshake.msg_type (srever hello) + 0x02, + // Handshake.length + 0x00, 0x00, 0x60, + // ServerHello.client_version + 0x03, 0x03, + // ServerHello.random + 0x0C, 0x3C, 0x85, 0x78, 0xCA, + 0x67, 0x70, 0xAA, 0x38, 0xCB, + 0x28, 0xBC, 0xDC, 0x3E, 0x30, + 0xBF, 0x11, 0x96, 0x95, 0x1A, + 0xB9, 0xF0, 0x99, 0xA4, 0x91, + 0x09, 0x13, 0xB4, 0x89, 0x94, + 0x27, 0x2E, + // ServerHello.SessionId_Length + 0x20, + // ServerHello.SessionId + 0x0C, 0x3C, 0x85, 0x78, 0xCA, 0x67, 0x70, 0xAA, + 0x38, 0xCB, 0x28, 0xBC, 0xDC, 0x3E, 0x30, 0xBF, + 0x11, 0x96, 0x95, 0x1A, 0xB9, 0xF0, 0x99, 0xA4, + 0x91, 0x09, 0x13, 0xB4, 0x89, 0x94, 0x27, 0x2E, + // ServerHello.cipher_suite + 0xC0, 0x2B, + // ServerHello.compression_method + 0x00, + // ClientHello.extension_list_length + 0x00, 0x18, + // Extension.extension_type (extended_master_secreet) + 0x00, 0x17, 0x00, 0x00, + // Extension.extension_type (renegotiation_info) + 0xFF, 0x01, 0x00, 0x01, 0x00, + // Extension.extension_type (ec_point_formats) + 0x00, 0x0B, 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (application_level_Protocol) + 0x00, 0x10, 0x00, 0x05, 0x00, 0x03, 0x02, 0x68, 0x32, + }; + + private static IEnumerable InvalidClientHello() + { + // This test covers following test cases: + // - Length of structure off by 1 (search for "length off by 1") + // - Length of structure is max length (search for "max length") + // - Type is invalid or unknown (i.e. SslPlainText.ClientType is not 0x16 - search for "unknown") + // - Invalid utf-8 characters + // in each case sni will be null or will cause parsing error - we only expect some parsing errors, + // anything else is considered a bug + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 - length off by 1 + 0x00, 0x02, 0x00 + }; + + // #2 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 - max length + 0xFF, 0xFF, 0x00 + }; + + // #3 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 - length off by 1 + 0x00, 0x01, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #4 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 - max length + 0xFF, 0xFF, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #5 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 - length off by 1 + 0x00, 0x01, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #6 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 - max length + 0xFF, 0xFF, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #7 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D - length off by 1 + 0x00, 0x15, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #8 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D - max length + 0xFF, 0xFF, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #9 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B - length off by 1 + 0x00, 0x03, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #10 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B - max length + 0xFF, 0xFF, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #11 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A - length off by 1 + 0x00, 0x09, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #10 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A - max length + 0xFF, 0xFF, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #13 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length - length off by 1 + 0x00, 0x35, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #14 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length - max length + 0xFF, 0xFF, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #15 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type - unknown + 0x01, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #16 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length - length off by 1 + 0x00, 0x38, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #17 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length - max length + 0xFF, 0xFF, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #18 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length - length off by 1 + 0x00, 0x3A, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #19 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length - max length + 0xFF, 0xFF, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #20 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) - unknown + 0x01, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #21 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length - length off by 1 + 0x00, 0x75, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #22 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length - max length + 0xFF, 0xFF, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #23 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods - length off by 1 + 0x02, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #24 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods - max length + 0xFF, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #25 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites - length off by 1 + 0x00, 0x2B, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #26 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites - max length + 0xFF, 0xFF, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #27 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId - length off by 1 + 0x01, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #28 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId - max length + 0xFF, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #29 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length - length off by 1 + 0x00, 0x00, 0xC8, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #30 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length - max length + 0xFF, 0xFF, 0xFF, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #31 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) - unknown + 0x00, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #32 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length - length off by 1 + 0x00, 0xCC, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #33 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length - max length + 0xFF, 0xFF, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #34 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) - unknown + 0x01, 0x03, 0x04, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x58, 0xAA, 0x5F, 0xE7, 0x22, + 0xCF, 0x9F, 0x59, 0x8A, 0xC5, + 0x8B, 0x87, 0xC7, 0x62, 0x32, + 0x98, 0xD4, 0xD8, 0xA2, 0xBE, + 0x77, 0xCE, 0xA9, 0xCE, 0x42, + 0x25, 0x5A, 0x8B, 0xEE, 0x16, + 0x80, 0xF1, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + + // #35 + yield return new byte[] { + // SslPlainText.(ContentType+ProtocolVersion) + 0x16, 0x03, 0x03, + // SslPlainText.length + 0x00, 0xCB, + // Handshake.msg_type (client hello) + 0x01, + // Handshake.length + 0x00, 0x00, 0xC7, + // ClientHello.client_version + 0x03, 0x03, + // ClientHello.random + 0x0C, 0x3C, 0x85, 0x78, 0xCA, + 0x67, 0x70, 0xAA, 0x38, 0xCB, + 0x28, 0xBC, 0xDC, 0x3E, 0x30, + 0xBF, 0x11, 0x96, 0x95, 0x1A, + 0xB9, 0xF0, 0x99, 0xA4, 0x91, + 0x09, 0x13, 0xB4, 0x89, 0x94, + 0x27, 0x2E, + // ClientHello.SessionId + 0x00, + // ClientHello.cipher_suites + 0x00, 0x2A, 0xC0, 0x2C, 0xC0, + 0x2B, 0xC0, 0x30, 0xC0, 0x2F, + 0x00, 0x9F, 0x00, 0x9E, 0xC0, + 0x24, 0xC0, 0x23, 0xC0, 0x28, + 0xC0, 0x27, 0xC0, 0x0A, 0xC0, + 0x09, 0xC0, 0x14, 0xC0, 0x13, + 0x00, 0x9D, 0x00, 0x9C, 0x00, + 0x3D, 0x00, 0x3C, 0x00, 0x35, + 0x00, 0x2F, 0x00, 0x0A, + // ClientHello.compression_methods + 0x01, 0x01, + // ClientHello.extension_list_length + 0x00, 0x74, + // Extension.extension_type (server_name) + 0x00, 0x00, + // ServerNameListExtension.length + 0x00, 0x39, + // ServerName.length + 0x00, 0x37, + // ServerName.type + 0x00, + // HostName.length + 0x00, 0x34, + // HostName.bytes + 0x80, 0x80, 0x80, 0x80, 0x61, // 0x80 0x80 0x80 0x80 is a forbidden utf-8 sequence + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, + // Extension.extension_type (00 0A) + 0x00, 0x0A, + // Extension 0A + 0x00, 0x08, 0x00, 0x06, 0x00, + 0x1D, 0x00, 0x17, 0x00, 0x18, + // Extension.extension_type (00 0B) + 0x00, 0x0B, + // Extension 0B + 0x00, 0x02, 0x01, 0x00, + // Extension.extension_type (00 0D) + 0x00, 0x0D, + // Extension 0D + 0x00, 0x14, 0x00, 0x12, 0x04, + 0x01, 0x05, 0x01, 0x02, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x02, + 0x03, 0x02, 0x02, 0x06, 0x01, + 0x06, 0x03, + // Extension.extension_type (00 23) + 0x00, 0x23, + // Extension 00 23 + 0x00, 0x00, + // Extension.extension_type (00 17) + 0x00, 0x17, + // Extension 17 + 0x00, 0x00, + // Extension.extension_type (FF 01) + 0xFF, 0x01, + // Extension FF01 + 0x00, 0x01, 0x00 + }; + } + } +}