in fizz/record/RecordLayer.cpp [130:186]
folly::Optional<Param> ReadRecordLayer::decodeHandshakeMessage(
folly::IOBufQueue& buf) {
folly::io::Cursor cursor(buf.front());
if (!cursor.canAdvance(kHandshakeHeaderSize)) {
return folly::none;
}
auto handshakeType =
static_cast<HandshakeType>(cursor.readBE<HandshakeTypeType>());
auto length = detail::readBits24(cursor);
if (length > kMaxHandshakeSize) {
throw std::runtime_error("handshake record too big");
}
if (buf.chainLength() < (cursor - buf.front()) + length) {
return folly::none;
}
Buf handshakeMsg;
cursor.clone(handshakeMsg, length);
auto original = buf.split(kHandshakeHeaderSize + length);
switch (handshakeType) {
case HandshakeType::client_hello:
return parse<ClientHello>(std::move(handshakeMsg), std::move(original));
case HandshakeType::server_hello:
return parse<ServerHello>(std::move(handshakeMsg), std::move(original));
case HandshakeType::end_of_early_data:
return parse<EndOfEarlyData>(
std::move(handshakeMsg), std::move(original));
case HandshakeType::new_session_ticket:
return parse<NewSessionTicket>(
std::move(handshakeMsg), std::move(original));
case HandshakeType::encrypted_extensions:
return parse<EncryptedExtensions>(
std::move(handshakeMsg), std::move(original));
case HandshakeType::certificate:
return parse<CertificateMsg>(
std::move(handshakeMsg), std::move(original));
case HandshakeType::compressed_certificate:
return parse<CompressedCertificate>(
std::move(handshakeMsg), std::move(original));
case HandshakeType::certificate_request:
return parse<CertificateRequest>(
std::move(handshakeMsg), std::move(original));
case HandshakeType::certificate_verify:
return parse<CertificateVerify>(
std::move(handshakeMsg), std::move(original));
case HandshakeType::finished:
return parse<Finished>(std::move(handshakeMsg), std::move(original));
case HandshakeType::key_update:
return parse<KeyUpdate>(std::move(handshakeMsg), std::move(original));
default:
throw std::runtime_error("unknown handshake type");
};
}