146 std::shared_ptr<const FizzClientContext>
context,
147 std::shared_ptr<const CertificateVerifier> verifier,
150 const std::shared_ptr<ClientExtensions>& extensions) {
167 ReportError(
"attempting to process data without record layer"),
171 if (!param.hasValue()) {
175 }
catch (
const std::exception& e) {
217 }
catch (
const std::exception& e) {
232 auto transition = [](
State& newState) {
234 newState.writeRecordLayer() =
nullptr;
235 newState.readRecordLayer() =
nullptr;
249 auto transition = [](
State& newState) {
251 newState.writeRecordLayer() =
nullptr;
252 newState.readRecordLayer() =
nullptr;
267 auto&
alert = boost::get<Alert>(param);
269 folly::to<std::string>(
277 folly::to<std::string>(
298 VLOG(1) <<
"Ignoring expired cached psk";
306 VLOG(1) <<
"Ignoring cached psk with protocol version " 314 VLOG(1) <<
"Ignoring cached psk with cipher " <<
toString(psk->
cipher);
323 const std::vector<NamedGroup>& groups) {
324 std::map<NamedGroup, std::unique_ptr<KeyExchange>> keyExchangers;
325 for (
auto group : groups) {
327 kex->generateKeyPair();
330 return keyExchangers;
336 const std::vector<CipherSuite>& supportedCiphers,
337 const std::vector<ProtocolVersion>& supportedVersions,
338 const std::vector<NamedGroup>& supportedGroups,
340 const std::vector<SignatureScheme>& supportedSigSchemes,
341 const std::vector<PskKeyExchangeMode>& supportedPskModes,
343 const std::vector<std::string>& supportedAlpns,
344 const std::vector<CertificateCompressionAlgorithm>& compressionAlgos,
346 const Buf& legacySessionId,
348 Buf cookie =
nullptr) {
357 versions.
versions = supportedVersions;
365 for (
const auto&
share : shares) {
385 if (!supportedAlpns.empty()) {
387 for (
const auto& protoName : supportedAlpns) {
395 if (!supportedPskModes.empty()) {
397 modes.
modes = supportedPskModes;
401 if (earlyDataParams) {
411 if (!compressionAlgos.empty()) {
419 for (
auto& ext : additionalExtensions) {
432 std::chrono::duration_cast<std::chrono::milliseconds>(
440 memset(binder.
binder->writableData(), 0, binderSize);
441 binder.
binder->append(binderSize);
481 pskExt.binders.clear();
482 pskExt.binders.push_back(
std::move(binder));
491 chloQueue.
append(encoded->clone());
530 auto&
connect = boost::get<Connect>(param);
537 auto random = context->getFactory()->makeRandom();
541 std::vector<NamedGroup> selectedShares;
542 if (psk && psk->
group &&
544 context->getSupportedGroups().begin(),
545 context->getSupportedGroups().end(),
546 *psk->
group) != context->getSupportedGroups().end()) {
548 selectedShares = {*psk->
group};
549 }
else if (psk && !psk->
group) {
553 selectedShares = context->getDefaultShares();
559 if (context->getCompatibilityMode()) {
566 auto keyExchangers =
getKeyExchangers(*context->getFactory(), selectedShares);
569 *context->getFactory(),
571 context->getSupportedCiphers(),
572 context->getSupportedVersions(),
573 context->getSupportedGroups(),
575 context->getSupportedSigSchemes(),
576 context->getSupportedPskModes(),
578 context->getSupportedAlpns(),
579 context->getSupportedCertDecompressionAlgorithms(),
584 std::vector<ExtensionType> requestedExtensions;
585 for (
const auto& extension : chlo.extensions) {
586 requestedExtensions.push_back(extension.extension_type);
589 Buf encodedClientHello;
590 std::unique_ptr<EncryptedWriteRecordLayer> earlyWriteRecordLayer;
594 auto keyScheduler = context->getFactory()->makeKeyScheduler(psk->
cipher);
595 auto handshakeContext =
596 context->getFactory()->makeHandshakeContext(psk->
cipher);
599 std::move(chlo), *psk, *keyScheduler, *handshakeContext);
601 if (earlyDataParams) {
602 earlyWriteRecordLayer =
603 context->getFactory()->makeEncryptedWriteRecordLayer(
605 earlyWriteRecordLayer->setProtocolVersion(psk->
version);
606 auto earlyWriteSecret = keyScheduler->getSecret(
608 handshakeContext->getHandshakeContext()->coalesce());
610 *earlyWriteRecordLayer,
613 *context->getFactory(),
616 auto earlyExporterVector = keyScheduler->getSecret(
618 handshakeContext->getHandshakeContext()->coalesce());
619 earlyDataParams->earlyExporterSecret =
629 auto readRecordLayer = context->getFactory()->makePlaintextReadRecordLayer();
630 auto writeRecordLayer =
631 context->getFactory()->makePlaintextWriteRecordLayer();
635 writeRecordLayer->writeInitialClientHello(encodedClientHello->clone()));
640 auto saveState = [context =
std::move(context),
642 encodedClientHello =
std::move(encodedClientHello),
643 readRecordLayer =
std::move(readRecordLayer),
644 writeRecordLayer =
std::move(writeRecordLayer),
645 keyExchangers =
std::move(keyExchangers),
648 legacySessionId =
std::move(legacySessionId),
650 extensions =
connect.extensions,
651 requestedExtensions =
std::move(requestedExtensions),
652 earlyDataType](
State& newState)
mutable {
654 newState.verifier() = verifier;
655 newState.encodedClientHello() =
std::move(encodedClientHello);
656 newState.readRecordLayer() =
std::move(readRecordLayer);
657 newState.writeRecordLayer() =
std::move(writeRecordLayer);
658 newState.keyExchangers() =
std::move(keyExchangers);
661 newState.legacySessionId() =
std::move(legacySessionId);
662 newState.attemptedPsk() =
std::move(psk);
663 newState.extensions() = extensions;
664 newState.requestedExtensions() =
std::move(requestedExtensions);
665 newState.earlyDataType() = earlyDataType;
668 if (reportEarlySuccess) {
671 [earlyDataParams =
std::move(*earlyDataParams),
672 earlyWriteRecordLayer =
679 &Transition<StateEnum::ExpectingServerHello>);
684 &Transition<StateEnum::ExpectingServerHello>);
688 template <
typename ServerMessage>
690 const ServerMessage& msg,
691 const std::vector<ProtocolVersion>& supportedVersions,
692 const std::vector<CipherSuite>& supportedCiphers) {
695 folly::to<std::string>(
696 "received server legacy version ",
toString(msg.legacy_version)),
700 if (msg.legacy_compression_method != 0x00) {
705 auto supportedVersionsExt =
706 getExtension<ServerSupportedVersions>(msg.extensions);
707 if (!supportedVersionsExt) {
711 auto selectedVersion = supportedVersionsExt->selected_version;
712 auto selectedCipher = msg.cipher_suite;
715 supportedVersions.begin(),
716 supportedVersions.end(),
717 selectedVersion) == supportedVersions.end()) {
719 "received unsupported server version",
723 supportedCiphers.begin(), supportedCiphers.end(), selectedCipher) ==
724 supportedCiphers.end()) {
726 "server choose unsupported cipher suite",
730 return std::make_pair(selectedVersion, selectedCipher);
735 const std::vector<ProtocolVersion>& supportedVersions,
736 const std::vector<CipherSuite>& supportedCiphers,
740 std::tie(version, cipher) =
744 const auto serverShare = getExtension<ServerKeyShare>(shlo.
extensions);
746 auto kex = keyExchangers.find(serverShare->server_share.group);
747 if (kex == keyExchangers.end()) {
749 "server choose unsupported group",
753 serverShare->server_share.group,
754 serverShare->server_share.key_exchange->clone(),
776 struct NegotiatedPsk {
782 explicit NegotiatedPsk(
785 std::shared_ptr<const Cert> serverCert =
nullptr,
786 std::shared_ptr<const Cert> clientCert =
nullptr)
789 serverCert(serverCert),
790 clientCert(clientCert) {}
795 const std::vector<PskKeyExchangeMode>& supportedPskModes,
801 auto serverPsk = getExtension<ServerPresharedKey>(shlo.
extensions);
805 "server accepted unattempted psk",
807 }
else if (!supportedPskModes.empty()) {
816 if (serverPsk->selected_identity != 0) {
821 if (version != attemptedPsk->
version) {
832 if (std::find(supportedPskModes.begin(), supportedPskModes.end(),
mode) ==
833 supportedPskModes.end()) {
835 "server choose unsupported psk mode",
839 return NegotiatedPsk(
850 auto shlo =
std::move(boost::get<ServerHello>(param));
880 !(negotiatedPsk.mode &&
886 std::unique_ptr<HandshakeContext> handshakeContext;
894 handshakeContext->appendToTranscript(*shlo.originalEncoding);
898 if (negotiatedPsk.mode) {
913 std::tie(group, serverShare, kex) =
std::move(*exchange);
915 scheduler->deriveHandshakeSecret(sharedSecret->coalesce());
926 auto handshakeWriteRecordLayer =
929 handshakeWriteRecordLayer->setProtocolVersion(version);
930 auto handshakeWriteSecret =
scheduler->getSecret(
932 handshakeContext->getHandshakeContext()->coalesce());
934 *handshakeWriteRecordLayer,
940 auto handshakeReadRecordLayer =
943 handshakeReadRecordLayer->setProtocolVersion(version);
944 auto handshakeReadSecret =
scheduler->getSecret(
946 handshakeContext->getHandshakeContext()->coalesce());
948 *handshakeReadRecordLayer,
954 auto clientHandshakeSecret =
956 auto serverHandshakeSecret =
960 if (negotiatedPsk.clientCert) {
962 }
else if (negotiatedPsk.serverCert) {
968 readRecordLayer =
std::move(handshakeReadRecordLayer),
969 writeRecordLayer =
std::move(handshakeWriteRecordLayer),
970 handshakeContext =
std::move(handshakeContext),
974 clientHandshakeSecret =
std::move(clientHandshakeSecret),
975 serverHandshakeSecret =
std::move(serverHandshakeSecret),
977 pskType = negotiatedPsk.type,
982 newState.keyScheduler() = std::move(keyScheduler);
983 newState.readRecordLayer() = std::move(readRecordLayer);
984 newState.writeRecordLayer() = std::move(writeRecordLayer);
985 newState.handshakeContext() = std::move(handshakeContext);
986 newState.version() = version;
987 newState.cipher() = cipher;
988 newState.group() = group;
989 newState.encodedClientHello() = folly::none;
990 newState.keyExchangers() = folly::none;
991 newState.clientHandshakeSecret() = std::move(clientHandshakeSecret);
992 newState.serverHandshakeSecret() = std::move(serverHandshakeSecret);
993 newState.keyExchangeType() = keyExchangeType;
994 newState.pskType() = pskType;
995 newState.pskMode() = pskMode;
996 newState.serverCert() = std::move(serverCert);
997 newState.clientCert() = std::move(clientCert);
998 newState.clientAuthRequested() = std::move(authType);
1000 &Transition<StateEnum::ExpectingEncryptedExtensions>);
1013 const std::vector<ProtocolVersion>& supportedVersions,
1014 const std::vector<CipherSuite>& supportedCiphers,
1015 const std::vector<NamedGroup>& supportedGroups) {
1016 HrrParams negotiated;
1017 std::tie(negotiated.version, negotiated.cipher) =
1020 auto keyShare = getExtension<HelloRetryRequestKeyShare>(hrr.
extensions);
1023 supportedGroups.begin(),
1024 supportedGroups.end(),
1025 keyShare->selected_group) == supportedGroups.end()) {
1027 "server choose unsupported group in hrr",
1030 negotiated.group = keyShare->selected_group;
1040 if (negotiatedGroup) {
1041 if (previous.find(*negotiatedGroup) != previous.end()) {
1043 "hrr selected already-sent group",
1056 auto hrr =
std::move(boost::get<HelloRetryRequest>(param));
1074 auto cookie = getExtension<Cookie>(hrr.extensions);
1104 auto firstHandshakeContext =
1109 chloHash.
hash = firstHandshakeContext->getHandshakeContext();
1111 auto handshakeContext =
1113 handshakeContext->appendToTranscript(
encodeHandshake(std::move(chloHash)));
1114 handshakeContext->appendToTranscript(*hrr.originalEncoding);
1116 std::vector<ExtensionType> requestedExtensions;
1117 for (
const auto& extension :
chlo.extensions) {
1118 requestedExtensions.push_back(extension.extension_type);
1121 Buf encodedClientHello;
1127 std::move(
chlo), *attemptedPsk, *keyScheduler, *handshakeContext);
1130 handshakeContext->appendToTranscript(encodedClientHello);
1141 bool sentCCS = state.
sentCCS();
1148 clientFlight.
contents.emplace_back(std::move(writeCCS));
1151 clientFlight.
contents.emplace_back(std::move(chloWrite));
1157 encodedClientHello = std::move(encodedClientHello),
1158 keyExchangers = std::move(keyExchangers),
1159 handshakeContext = std::move(handshakeContext),
1160 attemptedPsk = std::move(attemptedPsk),
1161 requestedExtensions = std::move(requestedExtensions),
1162 sentCCS](
State& newState)
mutable {
1176 &Transition<StateEnum::ExpectingServerHello>);
1192 "early accepted with different cipher",
1196 if (
params->alpn != alpn) {
1198 "early accepted with different alpn",
1212 auto ee =
std::move(boost::get<EncryptedExtensions>(param));
1219 auto alpn = getExtension<ProtocolNameList>(ee.extensions);
1221 if (
alpn->protocol_name_list.size() != 1) {
1223 "alpn list does not contain exactly one protocol",
1227 alpn->protocol_name_list.front().name->moveToFbString().toStdString();
1233 folly::to<std::string>(
"alpn mismatch: server choose ", *appProto),
1238 auto serverEarly = getExtension<ServerEarlyData>(ee.extensions);
1250 "unexpected accepted early data",
1259 auto mutateState = [appProto =
std::move(appProto),
1260 earlyDataType](
State& newState)
mutable {
1263 newState.earlyDataType() = earlyDataType;
1268 std::move(mutateState), &Transition<StateEnum::ExpectingFinished>);
1271 std::move(mutateState), &Transition<StateEnum::ExpectingCertificate>);
1277 std::shared_ptr<const SelfCert>>
1279 folly::Optional<SignatureScheme> selectedScheme;
1284 const auto certSchemes =
clientCert->getSigSchemes();
1285 for (
const auto& scheme : supportedSchemes) {
1286 if (std::find(certSchemes.begin(), certSchemes.end(), scheme) !=
1287 certSchemes.end() &&
1288 std::find(schemes.begin(), schemes.end(), scheme) != schemes.end()) {
1289 selectedScheme = scheme;
1294 if (!selectedScheme) {
1295 VLOG(1) <<
"client cert/context doesn't support any signature algorithms " 1296 <<
"specified by the server";
1300 if (!selectedScheme) {
1313 "duplicate certificate request message",
1317 auto certRequest =
std::move(boost::get<CertificateRequest>(param));
1318 state.
handshakeContext()->appendToTranscript(*certRequest.originalEncoding);
1320 if (!certRequest.certificate_request_context->empty()) {
1322 "certificate request context must be empty",
1326 auto sigAlgsExtension =
1327 getExtension<SignatureAlgorithms>(certRequest.extensions);
1328 if (!sigAlgsExtension) {
1330 "certificate request without signature algorithms",
1334 folly::Optional<SignatureScheme> scheme;
1335 std::shared_ptr<const SelfCert> cert;
1336 std::tie(scheme, cert) =
1337 getClientCert(state, sigAlgsExtension->supported_signature_algorithms);
1341 auto mutateState = [scheme =
std::move(scheme),
1343 authType](
State& newState)
mutable {
1344 newState.clientAuthRequested() = authType;
1345 newState.selectedClientCert() =
std::move(cert);
1346 newState.clientAuthSigScheme() =
std::move(scheme);
1350 std::move(mutateState), &Transition<StateEnum::ExpectingCertificate>);
1359 "certificate request context must be empty",
1363 std::vector<std::shared_ptr<const PeerCert>> serverCerts;
1366 if (!certEntry.extensions.empty()) {
1368 "certificate extensions must be empty",
1376 if (serverCerts.empty()) {
1384 return [unverifiedCertChain =
std::move(serverCerts),
1387 newState.unverifiedCertChain() =
std::move(unverifiedCertChain);
1388 newState.clientAuthRequested() = authType;
1389 newState.serverCertCompAlgo() =
std::move(compAlgo);
1399 "compressed certificate received unexpectedly",
1403 auto compCert =
std::move(boost::get<CompressedCertificate>(param));
1407 if (std::find(algos.begin(),
1409 compCert.algorithm) == algos.end()) {
1411 "certificate compressed with unsupported algorithm: " +
1418 DCHECK(decompressor);
1422 msg = decompressor->decompress(compCert);
1423 }
catch (
const std::exception& e) {
1425 folly::to<std::string>(
"certificate decompression failed: ", e.what()),
1431 &Transition<StateEnum::ExpectingCertificateVerify>);
1437 auto certMsg =
std::move(boost::get<CertificateMsg>(param));
1443 &Transition<StateEnum::ExpectingCertificateVerify>);
1450 auto certVerify =
std::move(boost::get<CertificateVerify>(param));
1455 certVerify.algorithm) ==
1458 folly::to<std::string>(
1459 "server choose unsupported sig scheme: ",
1468 certVerify.algorithm,
1471 certVerify.signature->coalesce());
1477 std::rethrow_exception(std::current_exception());
1478 }
catch (
const std::exception& e) {
1480 folly::to<std::string>(
"verifier failure: ", e.what()),
1485 state.
handshakeContext()->appendToTranscript(*certVerify.originalEncoding);
1488 [sigScheme = certVerify.algorithm,
1490 newState.sigScheme() = sigScheme;
1491 newState.serverCert() = std::move(serverCert);
1492 newState.unverifiedCertChain() = folly::none;
1494 &Transition<StateEnum::ExpectingFinished>);
1510 expectedFinished->coalesce(),
finished.verify_data->coalesce())) {
1516 auto clientFinishedContext = state.
handshakeContext()->getHandshakeContext();
1547 auto signature = selectedCert->sign(
1556 clientCert = selectedCert;
1565 auto exporterMaster =
1570 auto resumptionSecret =
1577 bool sentCCS = state.
sentCCS();
1583 clientFlight.contents.emplace_back(
std::move(writeCCS));
1588 clientFlight.contents.emplace_back(
std::move(*eoedWrite));
1600 clientFlight.contents.emplace_back(
1605 clientFinishedContext->coalesce());
1608 auto writeRecordLayer =
1611 writeRecordLayer->setProtocolVersion(*state.
version());
1621 auto readRecordLayer =
1624 readRecordLayer->setProtocolVersion(*state.
version());
1639 [readRecordLayer =
std::move(readRecordLayer),
1640 writeRecordLayer =
std::move(writeRecordLayer),
1641 resumptionSecret =
std::move(resumptionSecret),
1642 exporterMaster =
std::move(exporterMaster),
1644 sentCCS](
State& newState)
mutable {
1656 &Transition<StateEnum::Established>,
1662 auto earlyData = getExtension<TicketEarlyData>(nst.
extensions);
1664 return earlyData->max_early_data_size;
1673 auto nst =
std::move(boost::get<NewSessionTicket>(param));
1678 auto pskRange =
nst.ticket->coalesce();
1679 auto secretRange = derivedResumptionSecret->coalesce();
1694 std::chrono::seconds(
nst.ticket_lifetime);
1704 auto& appData = boost::get<AppData>(param);
1713 auto&
appWrite = boost::get<AppWrite>(param);
1717 write.contents.emplace_back(
1728 auto& keyUpdate = boost::get<KeyUpdate>(param);
1735 auto readRecordLayer =
1738 readRecordLayer->setProtocolVersion(*state.
version());
1750 [rRecordLayer =
std::move(readRecordLayer)](
State& newState)
mutable {
1755 auto encodedKeyUpdated =
1763 auto writeRecordLayer =
1766 writeRecordLayer->setProtocolVersion(*state.
version());
1777 [rRecordLayer =
std::move(readRecordLayer),
1778 wRecordLayer =
std::move(writeRecordLayer)](
State& newState)
mutable {
1831 LOG(FATAL) <<
"Bad EarlyDataType";
1839 state,
std::move(boost::get<EarlyAppWrite>(param)));
1847 state,
std::move(boost::get<EarlyAppWrite>(param)));
1855 state,
std::move(boost::get<EarlyAppWrite>(param)));
1863 state,
std::move(boost::get<EarlyAppWrite>(param)));
1870 state,
std::move(boost::get<EarlyAppWrite>(param)));
std::vector< Extension > extensions
std::shared_ptr< const Cert > serverCert
std::unique_ptr< folly::IOBuf > split(size_t n)
const Buf & encodedClientHello() const
const auto & getSupportedGroups() const
std::unique_ptr< folly::IOBuf > data
std::shared_ptr< const client::FizzClientContext > context
TLSContent writeHandshake(Buf &&encodedHandshakeMsg, Args &&...args) const
static std::pair< ProtocolVersion, CipherSuite > getAndValidateVersionAndCipher(const ServerMessage &msg, const std::vector< ProtocolVersion > &supportedVersions, const std::vector< CipherSuite > &supportedCiphers)
static void setAead(Type &recordLayer, CipherSuite cipher, folly::ByteRange secret, const Factory &factory, const KeyScheduler &scheduler)
uint32_t obfuscated_ticket_age
Buf encodeHandshake(T &&handshakeMsg)
std::shared_ptr< const CertificateVerifier > verifier
auto & handshakeContext() const
Integral2 random(Integral1 low, Integral2 up)
folly::Optional< client::CachedPsk > cachedPsk
folly::StringPiece toString(StateEnum state)
virtual bool hasUnparsedHandshakeData() const
std::vector< PskBinder > binders
static Buf getFinished(folly::ByteRange handshakeWriteSecret, HandshakeContext &handshakeContext)
void append(std::unique_ptr< folly::IOBuf > &&buf, bool pack=false)
static Optional< EarlyDataParams > getEarlyDataParams(const FizzClientContext &context, const Optional< CachedPsk > &psk)
size_t getBinderLength(const ClientHello &chlo)
std::shared_ptr< const Cert > clientCert
static Actions ignoreEarlyAppWrite(const State &state, EarlyAppWrite write)
size_t chainLength() const
std::chrono::system_clock::time_point ticketIssueTime
const Buf & clientHandshakeSecret() const
#define FIZZ_DECLARE_EVENT_HANDLER(sm, statename, eventname,...)
virtual void deriveEarlySecret(folly::ByteRange psk)
void write(const T &in, folly::io::Appender &appender)
int connect(NetworkSocket s, const sockaddr *name, socklen_t namelen)
TLSContent writeAlert(Alert &&alert) const
bool getSendEarlyData() const
boost::variant< ClientHello, ServerHello, EndOfEarlyData, HelloRetryRequest, EncryptedExtensions, CertificateRequest, CompressedCertificate, CertificateMsg, CertificateVerify, Finished, NewSessionTicket, KeyUpdate, Alert, Accept, Connect, AppData, AppWrite, EarlyAppWrite, WriteNewSessionTicket > Param
const auto & getSupportedAlpns() const
folly::Optional< EarlyDataType > earlyDataType() const
static const std::string chlo
folly::Optional< std::string > alpn
static std::unique_ptr< IOBuf > create(std::size_t capacity)
const auto & getSupportedVersions() const
size_t getHashSize(HashFunction hash)
PUSHMI_INLINE_VAR constexpr detail::share_fn< TN... > share
static std::unique_ptr< IOBuf > wrapBuffer(const void *buf, std::size_t capacity)
virtual std::vector< uint8_t > getSecret(EarlySecrets s, folly::ByteRange transcript) const
Actions handleError(const State &state, ReportError error, Optional< AlertDescription > alertDesc)
std::shared_ptr< ClientExtensions > extensions
static bool equal(folly::ByteRange a, folly::ByteRange b)
virtual void appendToTranscript(const Buf &transcript)=0
std::shared_ptr< const SelfCert > selectedClientCert() const
virtual Buf getFinishedData(folly::ByteRange baseKey) const =0
std::unique_ptr< folly::IOBuf > hash
std::chrono::steady_clock::time_point now()
constexpr detail::Map< Move > move
static uint32_t getMaxEarlyDataSize(const NewSessionTicket &nst)
folly::small_vector< TLSContent, 4 > contents
folly::Optional< NamedGroup > group() const
std::shared_ptr< CertificateDecompressor > getCertDecompressorForAlgorithm(CertificateCompressionAlgorithm algo) const
virtual std::unique_ptr< KeyScheduler > makeKeyScheduler(CipherSuite cipher) const
std::vector< PskKeyExchangeMode > modes
virtual void onEncryptedExtensions(const std::vector< Extension > &extensions)=0
const Buf & legacySessionId() const
std::unique_ptr< folly::IOBuf > move()
std::vector< NamedGroup > named_group_list
Actions handleAppClose(const State &state)
ReadRecordLayer * readRecordLayer() const
static AppWrite appWrite(const std::string &str)
ProtocolVersion legacy_version
virtual std::unique_ptr< KeyExchange > makeKeyExchange(NamedGroup group) const
std::shared_ptr< const Cert > clientCert
const Buf & serverHandshakeSecret() const
constexpr folly::StringPiece FakeChangeCipherSpec
folly::Optional< ProtocolVersion > version() const
static const std::string encodedCertVerify
std::shared_ptr< folly::FunctionScheduler > scheduler
std::vector< Extension > extensions
requires And< SemiMovable< VN >... > &&SemiMovable< E > auto error(E e)
Buf certificate_request_context
virtual Actions processEarlyAppWrite(const State &, EarlyAppWrite)
std::vector< KeyShareEntry > client_shares
const Factory * getFactory() const
virtual folly::ByteRange getBlankContext() const =0
const std::vector< std::shared_ptr< const PeerCert > > & unverifiedCertChain() const
static ClientHello getClientHello(const Factory &, const Random &random, const std::vector< CipherSuite > &supportedCiphers, const std::vector< ProtocolVersion > &supportedVersions, const std::vector< NamedGroup > &supportedGroups, const std::map< NamedGroup, std::unique_ptr< KeyExchange >> &shares, const std::vector< SignatureScheme > &supportedSigSchemes, const std::vector< PskKeyExchangeMode > &supportedPskModes, const folly::Optional< std::string > &hostname, const std::vector< std::string > &supportedAlpns, const std::vector< CertificateCompressionAlgorithm > &compressionAlgos, const Optional< EarlyDataParams > &earlyDataParams, const Buf &legacySessionId, ClientExtensions *extensions, Buf cookie=nullptr)
static std::map< NamedGroup, std::unique_ptr< KeyExchange > > getKeyExchangers(const Factory &factory, const std::vector< NamedGroup > &groups)
const auto & getSupportedCiphers() const
const Buf & resumptionSecret() const
virtual Actions processConnect(const State &, std::shared_ptr< const FizzClientContext > context, std::shared_ptr< const CertificateVerifier > verifier, folly::Optional< std::string > sni, folly::Optional< CachedPsk > cachedPsk, const std::shared_ptr< ClientExtensions > &extensions)
folly::Optional< CipherSuite > cipher() const
folly::Optional< PskKeyExchangeMode > mode
const folly::Optional< std::string > & alpn() const
virtual Actions processAppClose(const State &)
virtual std::shared_ptr< PeerCert > makePeerCert(Buf certData) const
const Random & clientRandom() const
HashFunction getHashFunction(CipherSuite cipher)
virtual std::unique_ptr< EncryptedReadRecordLayer > makeEncryptedReadRecordLayer(EncryptionLevel encryptionLevel) const
std::vector< CertificateEntry > certificate_list
std::shared_ptr< const Cert > clientCert() const
auto & keyExchangers() const
folly::Optional< NamedGroup > group
bool getCompatibilityMode() const
static NegotiatedPsk negotiatePsk(const std::vector< PskKeyExchangeMode > &supportedPskModes, const folly::Optional< CachedPsk > &attemptedPsk, const ServerHello &shlo, ProtocolVersion version, CipherSuite cipher, bool hasExchange)
constexpr Params params[]
virtual uint32_t serverKeyUpdate()
static MutateState handleCertMsg(const State &state, CertificateMsg certMsg, folly::Optional< CertificateCompressionAlgorithm > algo)
static Options cacheChainLength()
virtual Actions processAppWrite(const State &, AppWrite)
folly::Optional< KeyExchangeType > keyExchangeType() const
folly::Optional< AlertDescription > getAlert() const
std::vector< Action > Actions
const folly::Optional< std::string > & sni() const
virtual folly::Optional< Param > readEvent(folly::IOBufQueue &socketBuf)
static Buf encodeAndAddBinders(ClientHello chlo, const CachedPsk &psk, KeyScheduler &scheduler, HandshakeContext &handshakeContext)
const folly::Optional< EarlyDataParams > & earlyDataParams() const
ClientExtensions * extensions() const
folly::Optional< PskType > pskType() const
const WriteRecordLayer * writeRecordLayer() const
static HrrParams negotiateParameters(const HelloRetryRequest &hrr, const std::vector< ProtocolVersion > &supportedVersions, const std::vector< CipherSuite > &supportedCiphers, const std::vector< NamedGroup > &supportedGroups)
static EventHandlerFun getHandler(typename SM::StateEnum state, typename SM::Event event)
virtual Buf getResumptionSecret(folly::ByteRange resumptionMasterSecret, folly::ByteRange ticketNonce) const
static std::tuple< folly::Optional< SignatureScheme >, std::shared_ptr< const SelfCert > > getClientCert(const State &state, const std::vector< SignatureScheme > &schemes)
FOLLY_CPP14_CONSTEXPR bool hasValue() const noexcept
constexpr Range< Iter > range(Iter first, Iter last)
std::vector< SignatureScheme > supported_signature_algorithms
EncryptionLevel encryptionLevel
virtual std::unique_ptr< HandshakeContext > makeHandshakeContext(CipherSuite cipher) const
KeyScheduler * keyScheduler() const
virtual Actions processWriteNewSessionTicket(const State &, WriteNewSessionTicket)
std::vector< Extension > extensions
virtual Actions processSocketData(const State &, folly::IOBufQueue &)
std::shared_ptr< const Cert > serverCert
std::vector< ProtocolVersion > versions
std::array< uint8_t, 32 > Random
std::vector< CipherSuite > cipher_suites
folly::AsyncTransportWrapper::WriteCallback * callback
std::shared_ptr< const Cert > serverCert
static ClientPresharedKey getPskExtension(const CachedPsk &psk)
static folly::Optional< CachedPsk > validatePsk(const FizzClientContext &context, folly::Optional< CachedPsk > psk)
FOLLY_CPP14_CONSTEXPR Value value_or(U &&dflt) const &
virtual void deriveAppTrafficSecrets(folly::ByteRange transcript)
Actions actions(Args &&...act)
const auto & getSupportedSigSchemes() const
static void checkAllowedExtensions(const EncryptedExtensions &ee, const std::vector< ExtensionType > &requestedExtensions)
Optional< NamedGroup > group
SignatureScheme algorithm
virtual std::unique_ptr< EncryptedWriteRecordLayer > makeEncryptedWriteRecordLayer(EncryptionLevel encryptionLevel) const
T exchange(T &obj, U &&new_value)
folly::Optional< SignatureScheme > clientAuthSigScheme() const
std::vector< Extension > extensions
std::vector< CertificateCompressionAlgorithm > getSupportedCertDecompressionAlgorithms() const
const auto & getSupportedPskModes() const
static const std::string nst
const folly::Optional< std::vector< ExtensionType > > & requestedExtensions() const
virtual std::vector< Extension > getClientHelloExtensions() const =0
virtual void clearMasterSecret()
decltype(auto) apply_visitor(Visitor &&visitor, const DiscriminatedPtr< Args... > &variant)
std::unique_ptr< folly::IOBuf > Buf
virtual void verify(const std::vector< std::shared_ptr< const PeerCert >> &certs) const =0
std::shared_ptr< const Cert > serverCert() const
Optional< PskKeyExchangeMode > pskMode
virtual void deriveMasterSecret()
const FizzClientContext * context() const
const CertificateVerifier * verifier() const
std::shared_ptr< const Cert > clientCert
std::vector< ProtocolName > protocol_name_list
folly::Optional< std::string > alpn
static Buf getKeyUpdated(KeyUpdateRequest request_update)
std::vector< PskIdentity > identities
std::vector< uint8_t > legacy_compression_methods
const auto & getClientCertificate() const
virtual std::unique_ptr< folly::IOBuf > generateSharedSecret(folly::ByteRange keyShare) const =0
TLSContent writeAppData(std::unique_ptr< folly::IOBuf > &&appData) const
Extension encodeExtension(const TokenBindingParameters ¶ms)
uint32_t maxEarlyDataSize
static void validateAcceptedEarly(const State &state, const Optional< std::string > &alpn)
folly::Optional< ClientAuthType > clientAuthRequested() const
Actions handleInvalidEvent(const State &state, Event event, Param param)
folly::Optional< std::string > sni
const WriteRecordLayer * earlyWriteRecordLayer() const
Actions processEvent(const State &state, Param param)
static std::unique_ptr< IOBuf > copyBuffer(const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
const folly::Optional< Buf > & exporterMasterSecret() const
uint32_t maxEarlyDataSize
static void validateNegotiationConsistency(const State &state, ProtocolVersion version, CipherSuite cipher)
static std::map< NamedGroup, std::unique_ptr< KeyExchange > > getHrrKeyExchangers(const Factory &factory, std::map< NamedGroup, std::unique_ptr< KeyExchange >> previous, Optional< NamedGroup > negotiatedGroup)
std::unique_ptr< folly::IOBuf > data
static Actions handleEarlyAppWrite(const State &state, EarlyAppWrite appWrite)
std::chrono::system_clock::time_point ticketExpirationTime
folly::AsyncTransportWrapper::WriteCallback * callback
std::vector< CertificateCompressionAlgorithm > algorithms
const folly::Optional< CachedPsk > & attemptedPsk() const
folly::AsyncTransportWrapper::WriteCallback * callback
std::vector< ServerName > server_name_list
virtual uint32_t clientKeyUpdate()