28 void ClientHelloParser::Parse(
const uint8_t*
data,
size_t avail) {
31 if (!ParseRecordHeader(data, avail))
35 ParseHeader(data, avail);
48 bool ClientHelloParser::ParseRecordHeader(
const uint8_t* data,
size_t avail) {
53 if (data[0] == kChangeCipherSpec ||
55 data[0] == kHandshake ||
56 data[0] == kApplicationData) {
57 frame_len_ = (data[3] << 8) + data[4];
67 if (frame_len_ >= kMaxTLSFrameLen) {
76 void ClientHelloParser::ParseHeader(
const uint8_t* data,
size_t avail) {
80 if (body_offset_ + frame_len_ > avail)
89 if (data[body_offset_ + 4] != 0x03 ||
90 data[body_offset_ + 5] < 0x01 ||
91 data[body_offset_ + 5] > 0x03) {
95 if (data[body_offset_] == kClientHello) {
96 if (state_ == kTLSHeader) {
97 if (!ParseTLSClientHello(data, avail))
105 if (session_id_ ==
nullptr ||
106 session_size_ > 32 ||
107 session_id_ + session_size_ > data + avail) {
113 hello.session_id_ = session_id_;
114 hello.session_size_ = session_size_;
115 hello.has_ticket_ = tls_ticket_ !=
nullptr && tls_ticket_size_ != 0;
116 hello.ocsp_request_ = ocsp_request_;
117 hello.servername_ = servername_;
118 hello.servername_size_ =
static_cast<uint8_t
>(servername_size_);
119 onhello_cb_(cb_arg_, hello);
127 void ClientHelloParser::ParseExtension(
const uint16_t type,
138 uint32_t server_names_len = (data[0] << 8) + data[1];
139 if (server_names_len + 2 > len)
141 for (
size_t offset = 2; offset < 2 + server_names_len; ) {
142 if (offset + 3 > len)
144 uint8_t name_type = data[offset];
145 if (name_type != kServernameHostname)
147 uint16_t name_len = (data[offset + 1] << 8) + data[offset + 2];
149 if (offset + name_len > len)
151 servername_ = data + offset;
152 servername_size_ = name_len;
159 if (len < kMinStatusRequestSize)
163 if (data[0] != kStatusRequestOCSP)
169 case kTLSSessionTicket:
170 tls_ticket_size_ =
len;
171 tls_ticket_ = data +
len;
180 bool ClientHelloParser::ParseTLSClientHello(
const uint8_t* data,
size_t avail) {
184 size_t session_offset = body_offset_ + 4 + 2 + 32;
186 if (session_offset + 1 >= avail)
189 body = data + session_offset;
190 session_size_ = *body;
191 session_id_ = body + 1;
193 size_t cipher_offset = session_offset + 1 + session_size_;
196 if (cipher_offset + 1 >= avail)
199 uint16_t cipher_len =
200 (data[cipher_offset] << 8) + data[cipher_offset + 1];
201 size_t comp_offset = cipher_offset + 2 + cipher_len;
204 if (comp_offset >= avail)
207 uint8_t comp_len = data[comp_offset];
208 size_t extension_offset = comp_offset + 1 + comp_len;
211 if (extension_offset > avail)
215 if (extension_offset == avail)
218 size_t ext_off = extension_offset + 2;
221 while (ext_off < avail) {
223 if (ext_off + 4 > avail)
226 uint16_t ext_type = (data[ext_off] << 8) + data[ext_off + 1];
227 uint16_t ext_len = (data[ext_off + 2] << 8) + data[ext_off + 3];
231 if (ext_off + ext_len > avail)
234 ParseExtension(ext_type,
union node::cares_wrap::@8::CaresAsyncData::@0 data