124 std::shared_ptr<const FizzServerContext>
context,
125 const std::shared_ptr<ServerExtensions>& extensions) {
140 ReportError(
"attempting to process data without record layer"),
144 if (!param.hasValue()) {
148 }
catch (
const std::exception& e) {
212 }
catch (
const std::exception& e) {
227 auto transition = [](
State& newState) {
229 newState.writeRecordLayer() =
nullptr;
230 newState.readRecordLayer() =
nullptr;
244 auto transition = [](
State& newState) {
246 newState.writeRecordLayer() =
nullptr;
247 newState.readRecordLayer() =
nullptr;
262 auto&
alert = boost::get<Alert>(param);
264 folly::to<std::string>(
272 folly::to<std::string>(
286 EventHandler<ServerTypes, StateEnum::Uninitialized, Event::Accept>::handle(
289 auto&
accept = boost::get<Accept>(param);
290 auto factory =
accept.context->getFactory();
291 auto readRecordLayer = factory->makePlaintextReadRecordLayer();
292 auto writeRecordLayer = factory->makePlaintextWriteRecordLayer();
293 auto handshakeLogging = std::make_unique<HandshakeLogging>();
299 handshakeLogging =
std::move(handshakeLogging),
300 extensions =
accept.extensions](
State& newState)
mutable {
301 newState.executor() = executor;
302 newState.context() = std::move(context);
303 newState.readRecordLayer() = std::move(rrl);
304 newState.writeRecordLayer() = std::move(wrl);
305 newState.handshakeLogging() = std::move(handshakeLogging);
306 newState.extensions() = std::move(extensions);
308 &Transition<StateEnum::ExpectingClientHello>);
314 auto supportedVersions = getExtension<SupportedVersions>(chlo.
extensions);
315 if (supportedVersions) {
317 supportedVersions->versions;
321 for (
const auto& extension : chlo.
extensions) {
323 extension.extension_type);
325 auto plaintextReadRecord =
327 if (plaintextReadRecord) {
329 plaintextReadRecord->getReceivedRecordVersion();
332 if (
sni && !
sni->server_name_list.empty()) {
334 .hostname->moveToFbString()
337 auto supportedGroups = getExtension<SupportedGroups>(chlo.
extensions);
338 if (supportedGroups) {
340 std::move(supportedGroups->named_group_list);
343 auto keyShare = getExtension<ClientKeyShare>(chlo.
extensions);
345 std::vector<NamedGroup> shares;
346 for (
const auto& entry : keyShare->client_shares) {
347 shares.push_back(entry.group);
352 auto exchangeModes = getExtension<PskKeyExchangeModes>(chlo.
extensions);
358 auto clientSigSchemes = getExtension<SignatureAlgorithms>(chlo.
extensions);
359 if (clientSigSchemes) {
361 std::move(clientSigSchemes->supported_signature_algorithms);
374 "client compression methods not exactly NULL",
382 const std::vector<ProtocolVersion>& versions) {
383 const auto& clientVersions = getExtension<SupportedVersions>(chlo.
extensions);
384 if (!clientVersions) {
399 auto cookieExt = getExtension<Cookie>(chlo.
extensions);
418 if (cookieState->version != version) {
423 if (cookieState->cipher != cipher) {
432 struct ResumptionStateResult {
433 explicit ResumptionStateResult(
450 const std::vector<PskKeyExchangeMode>& supportedModes) {
451 auto psks = getExtension<ClientPresharedKey>(chlo.
extensions);
452 auto clientModes = getExtension<PskKeyExchangeModes>(chlo.
extensions);
453 if (psks && !clientModes) {
459 pskMode =
negotiate(supportedModes, clientModes->modes);
461 if (!psks && !pskMode) {
462 return ResumptionStateResult(
464 }
else if (!psks || psks->identities.size() <=
kPskIndex) {
465 return ResumptionStateResult(
467 }
else if (!ticketCipher) {
468 VLOG(8) <<
"No ticket cipher, rejecting PSK.";
469 return ResumptionStateResult(
471 }
else if (!pskMode) {
472 VLOG(8) <<
"No psk mode match, rejecting PSK.";
473 return ResumptionStateResult(
476 const auto& ident = psks->identities[
kPskIndex].psk_identity;
477 return ResumptionStateResult(
478 ticketCipher->
decrypt(ident->clone()),
480 psks->identities[
kPskIndex].obfuscated_ticket_age);
488 if (!zeroRttEnabled || !replayCache ||
489 !getExtension<ClientEarlyData>(chlo.
extensions)) {
501 if (resState.
version != version) {
502 VLOG(8) <<
"Protocol version mismatch, rejecting PSK.";
507 VLOG(8) <<
"Hash mismatch, rejecting PSK.";
516 const std::vector<std::vector<CipherSuite>>& supportedCiphers) {
535 pair<std::unique_ptr<KeyScheduler>, std::unique_ptr<HandshakeContext>>
543 std::unique_ptr<HandshakeContext> handshakeContext,
548 if (handshakeContext) {
565 }
else if (!handshakeContext) {
575 handshakeContext->getBlankContext());
581 handshakeContext->appendToTranscript(chloPrefix);
583 const auto& psks = getExtension<ClientPresharedKey>(chlo.
extensions);
584 if (!psks || psks->binders.size() <=
kPskIndex) {
587 auto expectedBinder =
588 handshakeContext->getFinishedData(
folly::range(binderKey));
590 expectedBinder->coalesce(),
591 psks->binders[
kPskIndex].binder->coalesce())) {
596 handshakeContext->appendToTranscript(chloQueue.
move());
605 std::set<NamedGroup> setOfNamedGroups;
607 for (
const auto&
share : client_shares) {
608 if (setOfNamedGroups.find(
share.group) != setOfNamedGroups.end()) {
613 setOfNamedGroups.insert(
share.group);
620 const std::vector<NamedGroup>& supportedGroups) {
621 auto groups = getExtension<SupportedGroups>(chlo.
extensions);
625 auto group =
negotiate(supportedGroups, groups->named_group_list);
629 auto clientShares = getExtension<ClientKeyShare>(chlo.
extensions);
639 if (!clientShares->preDraft23) {
644 if (clientShares->preDraft23) {
651 for (
const auto&
share : clientShares->client_shares) {
662 const Buf& clientShare,
665 kex->generateKeyPair();
666 auto sharedSecret = kex->generateSharedSecret(clientShare->coalesce());
668 return kex->getKeyShare();
677 Buf encodedHelloRetryRequest;
681 throw std::runtime_error(
"pre-22 HRR");
704 return encodedHelloRetryRequest;
714 Buf legacy_session_id,
753 return encodedServerHello;
760 auto ext = getExtension<ProtocolNameList>(chlo.
extensions);
761 std::vector<std::string> clientProtocols;
763 for (
auto& protocol : ext->protocol_name_list) {
764 clientProtocols.push_back(protocol.name->moveToFbString().toStdString());
767 VLOG(6) <<
"Client did not send ALPN extension";
769 auto selected = context.
negotiateAlpn(clientProtocols, zeroRttAlpn);
771 VLOG(6) <<
"ALPN mismatch";
773 VLOG(6) <<
"ALPN: " << *selected;
781 if (!psk || !obfuscatedAge) {
785 auto age = std::chrono::milliseconds(
786 static_cast<uint32_t>(*obfuscatedAge - psk->
ticketAgeAdd));
788 auto expected = std::chrono::duration_cast<std::chrono::milliseconds>(
791 return std::chrono::milliseconds(age - expected);
795 bool acceptEarlyData,
806 if (!getExtension<ClientEarlyData>(chlo.
extensions)) {
810 if (!acceptEarlyData) {
811 VLOG(5) <<
"Rejecting early data: disabled";
816 VLOG(5) <<
"Rejected early data: psk rejected";
820 if (psk->
cipher != cipher) {
821 VLOG(5) <<
"Rejected early data: cipher mismatch";
825 if (psk->
alpn != alpn) {
826 VLOG(5) <<
"Rejecting early data: alpn mismatch";
830 if (keyExchangeType &&
832 VLOG(5) <<
"Rejecting early data: HelloRetryRequest";
837 VLOG(5) <<
"Rejecting early data: Cookie";
842 VLOG(5) <<
"Rejecting early data: replay";
846 if (!clockSkew || *clockSkew < clockSkewTolerance.
before ||
847 *clockSkew > clockSkewTolerance.
after) {
848 VLOG(5) <<
"Rejecting early data: clock skew clockSkew=" 849 << (clockSkew ? folly::to<std::string>(clockSkew->count())
851 <<
" toleranceBefore=" << clockSkewTolerance.
before.count()
852 <<
" toleranceAfter=" << clockSkewTolerance.
after.count();
856 if (appTokenValidator && !appTokenValidator->
validate(*psk)) {
857 VLOG(5) <<
"Rejecting early data: invalid app token";
868 std::vector<Extension> otherExtensions) {
882 for (
auto& ext : otherExtensions) {
885 auto encodedEncryptedExt =
886 encodeHandshake<EncryptedExtensions>(
std::move(encryptedExt));
888 return encodedEncryptedExt;
894 const auto& clientSigSchemes =
895 getExtension<SignatureAlgorithms>(chlo.
extensions);
896 if (!clientSigSchemes) {
900 auto serverNameList = getExtension<ServerNameList>(chlo.
extensions);
901 if (serverNameList && !serverNameList->server_name_list.empty()) {
902 sni = serverNameList->server_name_list.front()
903 .hostname->moveToFbString()
908 context.
getCert(sni, clientSigSchemes->supported_signature_algorithms);
909 if (!certAndScheme) {
913 return *certAndScheme;
916 static std::tuple<Buf, folly::Optional<CertificateCompressionAlgorithm>>
918 const std::shared_ptr<const SelfCert>&
serverCert,
926 getExtension<CertificateCompressionAlgorithms>(chlo.
extensions);
933 encodedCertificate =
encodeHandshake(serverCert->getCompressedCert(*algo));
950 return encodedCertificateVerify;
954 const std::vector<SignatureScheme>& acceptableSigSchemes,
963 for (
auto& ext : verifierExtensions) {
969 return encodedCertificateRequest;
990 "version mismatch with previous negotiation",
995 if (getExtension<ClientEarlyData>(
chlo.extensions)) {
997 "supported version mismatch with early data",
1036 collectAll(resStateResult.futureResState, replayCacheResultFuture);
1038 using FutureResultType = std::tuple<
1041 return results.via(state.
executor())
1047 pskMode = resStateResult.pskMode,
1049 FutureResultType result)
mutable {
1050 auto& resumption = *std::get<0>(result);
1051 auto pskType = resumption.first;
1052 auto resState =
std::move(resumption.second);
1053 auto replayCacheResult = *std::get<1>(result);
1065 Buf legacySessionId;
1069 legacySessionId =
nullptr;
1071 legacySessionId =
chlo.legacy_session_id->clone();
1074 std::unique_ptr<KeyScheduler>
scheduler;
1075 std::unique_ptr<HandshakeContext> handshakeContext;
1088 "cipher mismatch with previous negotiation",
1109 std::unique_ptr<EncryptedReadRecordLayer> earlyReadRecordLayer;
1110 Buf earlyExporterMaster;
1112 auto earlyContext = handshakeContext->getHandshakeContext();
1114 earlyReadRecordLayer =
1117 earlyReadRecordLayer->setProtocolVersion(
version);
1118 auto earlyReadSecret = scheduler->getSecret(
1121 *earlyReadRecordLayer,
1127 earlyExporterMaster =
1140 VLOG(8) <<
"Did not find key share for " <<
toString(*group);
1143 "key share not found for already negotiated group",
1156 chloHash.
hash = handshakeContext->getHandshakeContext();
1159 handshakeContext->appendToTranscript(
1166 legacySessionId ? legacySessionId->clone() :
nullptr,
1170 serverFlight.
contents.emplace_back(
1174 if (legacySessionId && !legacySessionId->empty()) {
1179 serverFlight.contents.emplace_back(
std::move(writeCCS));
1183 auto newReadRecordLayer =
1185 newReadRecordLayer->setSkipEncryptedRecords(
1189 [handshakeContext =
std::move(handshakeContext),
1195 newReadRecordLayer =
1212 &Transition<StateEnum::ExpectingClientHello>));
1221 serverShare =
doKex(
1225 scheduler->deriveHandshakeSecret();
1228 std::vector<Extension> additionalExtensions;
1235 "group mismatch with previous negotiation",
1242 if (cookieState && cookieState->group && group &&
1243 *group != *cookieState->group) {
1245 "group mismatch with cookie",
1253 resState.hasValue(),
1256 legacySessionId ? legacySessionId->clone() :
nullptr,
1260 auto handshakeWriteRecordLayer =
1263 handshakeWriteRecordLayer->setProtocolVersion(
version);
1264 auto handshakeWriteSecret = scheduler->getSecret(
1266 handshakeContext->getHandshakeContext()->coalesce());
1268 *handshakeWriteRecordLayer,
1274 auto handshakeReadRecordLayer =
1277 handshakeReadRecordLayer->setProtocolVersion(
version);
1278 handshakeReadRecordLayer->setSkipFailedDecryption(
1280 auto handshakeReadSecret = scheduler->getSecret(
1282 handshakeContext->getHandshakeContext()->coalesce());
1284 *handshakeReadRecordLayer,
1289 auto clientHandshakeSecret =
1302 bool requestClientAuth =
1306 if (requestClientAuth) {
1325 std::shared_ptr<const SelfCert> originalSelfCert;
1326 std::tie(originalSelfCert, sigScheme) =
1329 std::tie(encodedCertificate, certCompressionAlgo) =
getCertificate(
1330 originalSelfCert, *state.
context(),
chlo, *handshakeContext);
1332 auto toBeSigned = handshakeContext->getHandshakeContext();
1333 auto asyncSelfCert =
1335 if (asyncSelfCert) {
1336 signature = asyncSelfCert->signFuture(
1339 toBeSigned->coalesce());
1341 signature = originalSelfCert->sign(
1344 toBeSigned->coalesce());
1346 serverCert =
std::move(originalSelfCert);
1348 serverCert =
std::move(resState->serverCert);
1349 clientCert =
std::move(resState->clientCert);
1355 handshakeContext =
std::move(handshakeContext),
1358 encodedServerHello =
std::move(encodedServerHello),
1359 handshakeWriteRecordLayer =
1361 handshakeWriteSecret =
std::move(handshakeWriteSecret),
1362 handshakeReadRecordLayer =
1364 earlyReadRecordLayer =
std::move(earlyReadRecordLayer),
1365 earlyExporterMaster =
std::move(earlyExporterMaster),
1366 clientHandshakeSecret =
1368 encodedEncryptedExt =
std::move(encodedEncryptedExt),
1369 encodedCertificate =
std::move(encodedCertificate),
1370 encodedCertRequest =
std::move(encodedCertRequest),
1383 legacySessionId =
std::move(legacySessionId),
1384 serverCertCompAlgo =
1393 folly::range(handshakeWriteSecret), *handshakeContext);
1396 if (encodedCertificate) {
1397 if (encodedCertRequest) {
1417 auto serverEncrypted = handshakeWriteRecordLayer->writeHandshake(
1419 if (!combined.
empty()) {
1421 handshakeWriteRecordLayer->writeHandshake(combined.
move());
1425 splitRecord.encryptionLevel ==
1426 serverEncrypted.encryptionLevel);
1427 serverEncrypted.data->prependChain(
std::move(splitRecord.data));
1431 serverFlight.
contents.emplace_back(
1434 if (legacySessionId && !legacySessionId->empty()) {
1443 scheduler->deriveMasterSecret();
1444 auto clientFinishedContext =
1445 handshakeContext->getHandshakeContext();
1446 auto exporterMasterVector = scheduler->getSecret(
1448 clientFinishedContext->coalesce());
1449 auto exporterMaster =
1452 scheduler->deriveAppTrafficSecrets(
1453 clientFinishedContext->coalesce());
1454 auto appTrafficWriteRecordLayer =
1457 appTrafficWriteRecordLayer->setProtocolVersion(version);
1461 *appTrafficWriteRecordLayer,
1476 auto saveState = [appTrafficWriteRecordLayer =
1478 handshakeContext =
std::move(handshakeContext),
1480 exporterMaster =
std::move(exporterMaster),
1486 clientHandshakeSecret =
1496 serverCertCompAlgo](
State& newState)
mutable {
1497 newState.writeRecordLayer() =
1499 newState.handshakeContext() =
std::move(handshakeContext);
1500 newState.keyScheduler() =
std::move(scheduler);
1501 newState.exporterMasterSecret() =
std::move(exporterMaster);
1502 newState.serverCert() =
std::move(*serverCert);
1503 newState.clientCert() =
std::move(clientCert);
1505 newState.cipher() =
cipher;
1506 newState.group() =
group;
1507 newState.sigScheme() = sigScheme;
1508 newState.clientHandshakeSecret() =
1510 newState.pskType() = pskType;
1512 newState.keyExchangeType() = keyExchangeType;
1513 newState.earlyDataType() = earlyDataTypeSave;
1514 newState.replayCacheResult() = replayCacheResult;
1516 newState.clientClockSkew() = clockSkew;
1517 newState.serverCertCompAlgo() = serverCertCompAlgo;
1522 [handshakeReadRecordLayer =
1524 earlyReadRecordLayer =
std::move(earlyReadRecordLayer),
1525 earlyExporterMaster =
std::move(earlyExporterMaster)](
1526 State& newState)
mutable {
1536 &Transition<StateEnum::AcceptingEarlyData>,
1539 auto transition = requestClientAuth
1540 ? Transition<StateEnum::ExpectingCertificate>
1541 : Transition<StateEnum::ExpectingFinished>;
1544 handshakeReadRecordLayer)](
State& newState)
mutable {
1559 auto& appData = boost::get<AppData>(param);
1567 auto&
appWrite = boost::get<AppWrite>(param);
1571 write.contents.emplace_back(
1582 auto& eoed = boost::get<EndOfEarlyData>(param);
1594 [readRecordLayer =
std::move(readRecordLayer)](
State& newState)
mutable {
1597 &Transition<StateEnum::ExpectingFinished>);
1603 auto&
appWrite = boost::get<AppWrite>(param);
1607 write.contents.emplace_back(
1617 std::chrono::seconds ticketLifetime,
1643 const std::vector<uint8_t>& resumptionMasterSecret,
1644 Buf appToken =
nullptr) {
1652 Buf resumptionSecret;
1655 ticketNonce =
nullptr;
1661 folly::range(resumptionMasterSecret), ticketNonce->coalesce());
1675 auto ticketFuture = ticketCipher->encrypt(
std::move(resState));
1676 return ticketFuture.via(state.
executor())
1700 auto certMsg =
std::move(boost::get<CertificateMsg>(param));
1704 if (!certMsg.certificate_request_context->empty()) {
1706 "certificate request context must be empty",
1710 std::vector<std::shared_ptr<const PeerCert>> clientCerts;
1711 for (
auto& certEntry : certMsg.certificate_list) {
1713 if (!certEntry.extensions.empty()) {
1715 "certificate extensions must be empty",
1723 if (clientCerts.empty()) {
1725 VLOG(6) <<
"Client authentication not sent";
1728 &Transition<StateEnum::ExpectingFinished>);
1731 "certificate requested but none received",
1739 &Transition<StateEnum::ExpectingCertificateVerify>);
1747 auto certVerify =
std::move(boost::get<CertificateVerify>(param));
1752 certVerify.algorithm) ==
1755 folly::to<std::string>(
1756 "client chose unsupported sig scheme: ",
1762 auto leafCert = certs.front();
1764 certVerify.algorithm,
1767 certVerify.signature->coalesce());
1772 verifier->verify(certs);
1776 }
catch (
const std::exception& e) {
1778 folly::to<std::string>(
"client certificate failure: ", e.what()),
1782 state.
handshakeContext()->appendToTranscript(*certVerify.originalEncoding);
1789 &Transition<StateEnum::ExpectingFinished>);
1795 auto&
finished = boost::get<Finished>(param);
1800 expectedFinished->coalesce(),
finished.verify_data->coalesce())) {
1808 auto readRecordLayer =
1811 readRecordLayer->setProtocolVersion(*state.
version());
1828 auto saveState = [readRecordLayer =
std::move(readRecordLayer),
1829 resumptionMasterSecret](
State& newState)
mutable {
1830 newState.readRecordLayer() =
std::move(readRecordLayer);
1832 newState.resumptionMasterSecret() =
std::move(resumptionMasterSecret);
1838 &Transition<StateEnum::AcceptingData>,
1841 auto ticketFuture =
generateTicket(state, resumptionMasterSecret);
1842 return ticketFuture.via(state.
executor())
1843 .thenValue([saveState =
std::move(saveState)](
1848 &Transition<StateEnum::AcceptingData>,
1854 &Transition<StateEnum::AcceptingData>,
1870 return ticketFuture.via(state.
executor())
1883 auto& appData = boost::get<AppData>(param);
1892 auto&
appWrite = boost::get<AppWrite>(param);
1896 write.contents.emplace_back(
1907 auto& keyUpdate = boost::get<KeyUpdate>(param);
1913 auto readRecordLayer =
1916 readRecordLayer->setProtocolVersion(*state.
version());
1928 [rRecordLayer =
std::move(readRecordLayer)](
State& newState)
mutable {
1933 auto encodedKeyUpdated =
1941 auto writeRecordLayer =
1944 writeRecordLayer->setProtocolVersion(*state.
version());
1955 [rRecordLayer =
std::move(readRecordLayer),
1956 wRecordLayer =
std::move(writeRecordLayer)](
State& newState)
mutable {
std::vector< Extension > extensions
std::vector< Extension > extensions
Future< T > via(Executor *executor, int8_t priority=Executor::MID_PRI)&&
Buf getStatelessHelloRetryRequest(ProtocolVersion version, CipherSuite cipher, folly::Optional< NamedGroup > group, Buf cookie)
std::unique_ptr< folly::IOBuf > split(size_t n)
TLSContent writeHandshake(Buf &&encodedHandshakeMsg, Args &&...args) const
std::shared_ptr< const server::FizzServerContext > context
Future< ReplayCacheResult > getReplayCacheResult(const ClientHello &chlo, bool zeroRttEnabled, ReplayCache *replayCache)
uint32_t getMaxEarlyDataSize() const
std::vector< typename std::enable_if< !std::is_same< invoke_result_t< typename std::iterator_traits< InputIterator >::value_type >, void >::value, invoke_result_t< typename std::iterator_traits< InputIterator >::value_type > >::type > collectAll(InputIterator first, InputIterator last)
folly::Optional< std::pair< std::shared_ptr< SelfCert >, SignatureScheme > > getCert(const folly::Optional< std::string > &sni, const std::vector< SignatureScheme > &peerSigSchemes) const
const auto & getSupportedCompressionAlgorithms() const
static void setAead(Type &recordLayer, CipherSuite cipher, folly::ByteRange secret, const Factory &factory, const KeyScheduler &scheduler)
virtual std::vector< Extension > getCertificateRequestExtensions() const =0
const auto & getSupportedSigSchemes() const
Buf encodeHandshake(T &&handshakeMsg)
Integral2 random(Integral1 low, Integral2 up)
void setProtocolVersion(ProtocolVersion version) const
folly::StringPiece toString(StateEnum state)
virtual bool hasUnparsedHandshakeData() const
ServerExtensions * extensions() const
static Buf getFinished(folly::ByteRange handshakeWriteSecret, HandshakeContext &handshakeContext)
void append(std::unique_ptr< folly::IOBuf > &&buf, bool pack=false)
size_t getBinderLength(const ClientHello &chlo)
static Buf getEncryptedExt(HandshakeContext &handshakeContext, const folly::Optional< std::string > &selectedAlpn, EarlyDataType earlyData, std::vector< Extension > otherExtensions)
static std::tuple< NamedGroup, Optional< Buf > > negotiateGroup(ProtocolVersion version, const ClientHello &chlo, const std::vector< NamedGroup > &supportedGroups)
static EarlyDataType negotiateEarlyDataType(bool acceptEarlyData, const ClientHello &chlo, const Optional< ResumptionState > &psk, CipherSuite cipher, Optional< KeyExchangeType > keyExchangeType, const Optional< CookieState > &cookieState, Optional< std::string > alpn, ReplayCacheResult replayCacheResult, Optional< std::chrono::milliseconds > clockSkew, ClockSkewTolerance clockSkewTolerance, const AppTokenValidator *appTokenValidator)
Actions handleAppClose(const State &state)
const auto & getSupportedPskModes() const
size_t chainLength() const
#define FIZZ_DECLARE_EVENT_HANDLER(sm, statename, eventname,...)
std::vector< CipherSuite > clientCiphers
std::unique_ptr< folly::IOBuf > splitAtMost(size_t n)
void write(const T &in, folly::io::Appender &appender)
uint32_t max_early_data_size
TLSContent writeAlert(Alert &&alert) const
static Buf getServerHello(ProtocolVersion version, Random random, CipherSuite cipher, bool psk, Optional< NamedGroup > group, Optional< Buf > serverShare, Buf legacy_session_id, HandshakeContext &handshakeContext)
folly::Optional< ProtocolVersion > version() const
folly::Optional< ProtocolVersion > clientRecordVersion
boost::variant< ClientHello, ServerHello, EndOfEarlyData, HelloRetryRequest, EncryptedExtensions, CertificateRequest, CompressedCertificate, CertificateMsg, CertificateVerify, Finished, NewSessionTicket, KeyUpdate, Alert, Accept, Connect, AppData, AppWrite, EarlyAppWrite, WriteNewSessionTicket > Param
static const std::string chlo
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Actions actions(Args &&...act)
static ResumptionStateResult getResumptionState(const ClientHello &chlo, const TicketCipher *ticketCipher, const std::vector< PskKeyExchangeMode > &supportedModes)
folly::Optional< bool > clientSessionIdSent
auto & handshakeReadRecordLayer() const
PUSHMI_INLINE_VAR constexpr detail::share_fn< TN... > share
static std::unique_ptr< IOBuf > wrapBuffer(const void *buf, std::size_t capacity)
folly::Executor * executor
virtual std::vector< uint8_t > getSecret(EarlySecrets s, folly::ByteRange transcript) const
CookieState getCookieState(const Factory &factory, const std::vector< ProtocolVersion > &supportedVersions, const std::vector< std::vector< CipherSuite >> &supportedCiphers, const std::vector< NamedGroup > &supportedGroups, const ClientHello &chlo, Buf appToken)
virtual std::unique_ptr< PlaintextReadRecordLayer > makePlaintextReadRecordLayer() const
static bool equal(folly::ByteRange a, folly::ByteRange b)
static void validateGroups(const std::vector< KeyShareEntry > &client_shares)
virtual void appendToTranscript(const Buf &transcript)=0
std::shared_ptr< ServerExtensions > extensions
std::unique_ptr< folly::IOBuf > hash
const folly::Optional< Buf > & earlyExporterMasterSecret() const
KeyShareEntry server_share
const TicketCipher * getTicketCipher() const
folly::Optional< T > negotiate(const std::vector< std::vector< T >> &serverPref, const std::vector< T > &clientPref)
std::chrono::steady_clock::time_point now()
constexpr detail::Map< Move > move
folly::small_vector< TLSContent, 4 > contents
boost::variant< Actions, folly::Future< Actions >> AsyncActions
virtual TLSContent writeInitialClientHello(Buf encodedClientHello) const
virtual std::unique_ptr< KeyScheduler > makeKeyScheduler(CipherSuite cipher) const
const auto & getSupportedVersions() const
virtual folly::Future< ReplayCacheResult > check(folly::ByteRange identifier)=0
folly::Optional< std::vector< NamedGroup > > clientKeyShares
virtual std::vector< Extension > getExtensions(const ClientHello &chlo)=0
std::vector< PskKeyExchangeMode > clientKeyExchangeModes
std::unique_ptr< folly::IOBuf > move()
virtual folly::Optional< CookieState > decrypt(Buf) const =0
Buf legacy_session_id_echo
static bool validateResumptionState(const ResumptionState &resState, PskKeyExchangeMode, ProtocolVersion version, CipherSuite cipher)
virtual AsyncActions processEarlyAppWrite(const State &, EarlyAppWrite)
static AppWrite appWrite(const std::string &str)
folly::Optional< std::string > alpn
Buf legacy_session_id_echo
ProtocolVersion legacy_version
virtual std::unique_ptr< KeyExchange > makeKeyExchange(NamedGroup group) const
constexpr folly::StringPiece FakeChangeCipherSpec
std::shared_ptr< folly::FunctionScheduler > scheduler
std::vector< Extension > extensions
static constexpr uint16_t kPskIndex
virtual bool validate(const ResumptionState &) const =0
std::chrono::system_clock::time_point ticketIssueTime
requires And< SemiMovable< VN >... > &&SemiMovable< E > auto error(E e)
KeyScheduler * keyScheduler() const
virtual AsyncActions processAppWrite(const State &, AppWrite)
static std::pair< std::shared_ptr< SelfCert >, SignatureScheme > chooseCert(const FizzServerContext &context, const ClientHello &chlo)
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
folly::Optional< KeyExchangeType > keyExchangeType() const
static void validateClientHello(const ClientHello &chlo)
static constexpr StringPiece ticket
folly::Optional< Random > clientRandom
virtual std::shared_ptr< PeerCert > makePeerCert(Buf certData) const
static Buf doKex(const Factory &factory, NamedGroup group, const Buf &clientShare, KeyScheduler &scheduler)
HashFunction getHashFunction(CipherSuite cipher)
virtual std::unique_ptr< EncryptedReadRecordLayer > makeEncryptedReadRecordLayer(EncryptionLevel encryptionLevel) const
static void checkDuplicateExtensions(const std::vector< Extension > &exts)
bool getAcceptEarlyData(ProtocolVersion version) const
virtual Actions processAppClose(const State &)
ProtocolVersion selected_version
std::exception * get_exception() noexcept
folly::Optional< std::string > negotiateAlpn(const std::vector< std::string > &clientProtocols, const folly::Optional< std::string > &zeroRttAlpn) const
static CipherSuite negotiateCipher(const ClientHello &chlo, const std::vector< std::vector< CipherSuite >> &supportedCiphers)
Future< std::pair< PskType, Optional< ResumptionState > > > futureResState
bool getSendNewSessionTicket() const
virtual void deriveHandshakeSecret()
virtual folly::Future< std::pair< PskType, folly::Optional< ResumptionState > > > decrypt(std::unique_ptr< folly::IOBuf > encryptedTicket) const =0
virtual uint32_t serverKeyUpdate()
folly::Executor * executor() const
static const std::string encodedCertificate
static Options cacheChainLength()
ReadRecordLayer * readRecordLayer() const
virtual AsyncActions processSocketData(const State &, folly::IOBufQueue &)
const Factory * getFactory() const
folly::Optional< AlertDescription > getAlert() const
virtual AsyncActions processAccept(const State &, folly::Executor *executor, std::shared_ptr< const FizzServerContext > context, const std::shared_ptr< ServerExtensions > &extensions)
uint16_t selected_identity
const std::shared_ptr< const Cert > & clientCert() const
const WriteRecordLayer * writeRecordLayer() const
folly::Optional< std::string > clientSni
virtual folly::Optional< Param > readEvent(folly::IOBufQueue &socketBuf)
static Buf getCertificateVerify(SignatureScheme sigScheme, Buf signature, HandshakeContext &handshakeContext)
static std::tuple< Buf, folly::Optional< CertificateCompressionAlgorithm > > getCertificate(const std::shared_ptr< const SelfCert > &serverCert, const FizzServerContext &context, const ClientHello &chlo, HandshakeContext &handshakeContext)
std::vector< Extension > extensions
folly::Optional< ProtocolVersion > clientLegacyVersion
static EventHandlerFun getHandler(typename SM::StateEnum state, typename SM::Event event)
std::vector< ProtocolVersion > clientSupportedVersions
std::vector< SignatureScheme > clientSignatureAlgorithms
virtual Buf getResumptionSecret(folly::ByteRange resumptionMasterSecret, folly::ByteRange ticketNonce) const
folly::Optional< ReplayCacheResult > replayCacheResult() const
NamedGroup selected_group
FOLLY_CPP14_CONSTEXPR bool hasValue() const noexcept
static Optional< std::string > negotiateAlpn(const ClientHello &chlo, folly::Optional< std::string > zeroRttAlpn, const FizzServerContext &context)
constexpr Range< Iter > range(Iter first, Iter last)
std::vector< SignatureScheme > supported_signature_algorithms
static Buf getCertificateRequest(const std::vector< SignatureScheme > &acceptableSigSchemes, const CertificateVerifier *const verifier, HandshakeContext &handshakeContext)
EncryptionLevel encryptionLevel
constexpr detail::Sig< Sig > const sig
virtual std::unique_ptr< HandshakeContext > makeHandshakeContext(CipherSuite cipher) const
std::vector< Extension > extensions
Actions handleError(const State &state, ReportError error, Optional< AlertDescription > alertDesc)
std::shared_ptr< const Cert > serverCert
const CookieCipher * getCookieCipher() const
std::array< uint8_t, 32 > Random
std::vector< CipherSuite > cipher_suites
ReplayCache * getReplayCache() const
folly::Optional< PskType > pskType() const
const std::vector< uint8_t > & resumptionMasterSecret() const
HandshakeLogging * handshakeLogging() const
ProtocolVersion legacy_version
const std::shared_ptr< const CertificateVerifier > & getClientCertVerifier() const
Actions handleInvalidEvent(const State &state, Event event, Param param)
const folly::Optional< std::vector< std::shared_ptr< const PeerCert > > > & unverifiedCertChain() const
Optional< NamedGroup > group
SignatureScheme algorithm
static Optional< ProtocolVersion > negotiateVersion(const ClientHello &chlo, const std::vector< ProtocolVersion > &versions)
static Buf getHelloRetryRequest(ProtocolVersion version, CipherSuite cipher, NamedGroup group, Buf legacySessionId, HandshakeContext &handshakeContext)
virtual std::unique_ptr< EncryptedWriteRecordLayer > makeEncryptedWriteRecordLayer(EncryptionLevel encryptionLevel) const
virtual uint32_t makeTicketAgeAdd() const
std::chrono::milliseconds after
std::vector< Extension > extensions
static const std::string encodedCertRequest
Optional< uint32_t > obfuscatedAge
static const std::string nst
const FizzServerContext * context() const
folly::Optional< Buf > originalEncoding
ClockSkewTolerance getClockSkewTolerance() const
virtual AsyncActions processWriteNewSessionTicket(const State &, WriteNewSessionTicket)
virtual void clearMasterSecret()
ClientAuthMode getClientAuthMode() const
AsyncActions processEvent(const State &state, Param param)
decltype(auto) apply_visitor(Visitor &&visitor, const DiscriminatedPtr< Args... > &variant)
std::unique_ptr< folly::IOBuf > Buf
std::vector< ExtensionType > clientExtensions
const auto & getSupportedCiphers() const
folly::Optional< NamedGroup > group() const
folly::Optional< NamedGroup > group
const Buf & clientHandshakeSecret() const
const AppTokenValidator * appTokenValidator() const
Optional< PskKeyExchangeMode > pskMode
std::shared_ptr< const Cert > clientCert
decltype(auto) variant_match(Variant &&variant, Cases &&...cases)
ProtocolVersion getRealDraftVersion(ProtocolVersion version)
std::vector< ProtocolName > protocol_name_list
static Buf getKeyUpdated(KeyUpdateRequest request_update)
std::chrono::milliseconds before
auto & handshakeContext() const
std::vector< uint8_t > legacy_compression_methods
const folly::Optional< std::string > & alpn() const
static void addHandshakeLogging(const State &state, const ClientHello &chlo)
TLSContent writeAppData(std::unique_ptr< folly::IOBuf > &&appData) const
std::shared_ptr< const Cert > serverCert
Extension encodeExtension(const TokenBindingParameters ¶ms)
static Optional< std::chrono::milliseconds > getClockSkew(const Optional< ResumptionState > &psk, Optional< uint32_t > obfuscatedAge)
virtual Random makeRandom() const
const auto & getSupportedGroups() const
static std::unique_ptr< IOBuf > copyBuffer(const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
folly::Optional< EarlyDataType > earlyDataType() const
std::vector< NamedGroup > clientSupportedGroups
static Future< Optional< WriteToSocket > > generateTicket(const State &state, const std::vector< uint8_t > &resumptionMasterSecret, Buf appToken=nullptr)
std::shared_ptr< const Cert > clientCert
std::shared_ptr< const Cert > serverCert() const
folly::Optional< CipherSuite > cipher() const
ProtocolVersion legacy_version
std::unique_ptr< folly::IOBuf > data
static std::pair< std::unique_ptr< KeyScheduler >, std::unique_ptr< HandshakeContext > > setupSchedulerAndContext(const Factory &factory, CipherSuite cipher, const ClientHello &chlo, const Optional< ResumptionState > &resState, const Optional< CookieState > &cookieState, PskType pskType, std::unique_ptr< HandshakeContext > handshakeContext, ProtocolVersion)
std::unique_ptr< folly::IOBuf > clientHello
bool getVersionFallbackEnabled() const
folly::AsyncTransportWrapper::WriteCallback * callback
static WriteToSocket writeNewSessionTicket(const FizzServerContext &context, const WriteRecordLayer &recordLayer, std::chrono::seconds ticketLifetime, uint32_t ticketAgeAdd, Buf nonce, Buf ticket, ProtocolVersion version)
NetworkSocket accept(NetworkSocket s, sockaddr *addr, socklen_t *addrlen)
virtual uint32_t clientKeyUpdate()