proxygen
fizz::sm Namespace Reference

Classes

class  EventHandler
 
class  EventHandlerBase
 
struct  Or
 
struct  Or< Condition, Conditions... >
 
class  StateMachine
 
struct  StateSame
 
struct  StateSame< SM, s, s >
 

Functions

 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::Uninitialized, Event::Connect, StateEnum::ExpectingServerHello)
 
 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::ExpectingServerHello, Event::HelloRetryRequest, StateEnum::ExpectingServerHello)
 
 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::ExpectingServerHello, Event::ServerHello, StateEnum::ExpectingEncryptedExtensions)
 
 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::ExpectingServerHello, Event::EarlyAppWrite, StateEnum::Error)
 
 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::ExpectingEncryptedExtensions, Event::EncryptedExtensions, StateEnum::ExpectingCertificate, StateEnum::ExpectingFinished)
 
 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::ExpectingEncryptedExtensions, Event::EarlyAppWrite, StateEnum::Error)
 
 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::ExpectingCertificate, Event::CertificateRequest, StateEnum::ExpectingCertificate)
 
 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::ExpectingCertificate, Event::Certificate, StateEnum::ExpectingCertificateVerify)
 
 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::ExpectingCertificate, Event::CompressedCertificate, StateEnum::ExpectingCertificateVerify)
 
 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::ExpectingCertificate, Event::EarlyAppWrite, StateEnum::Error)
 
 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::ExpectingCertificateVerify, Event::CertificateVerify, StateEnum::ExpectingFinished)
 
 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::ExpectingCertificateVerify, Event::EarlyAppWrite, StateEnum::Error)
 
 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::ExpectingFinished, Event::Finished, StateEnum::Established)
 
 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::ExpectingFinished, Event::EarlyAppWrite, StateEnum::Error)
 
 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::Established, Event::EarlyAppWrite, StateEnum::Error)
 
 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::Established, Event::NewSessionTicket, StateEnum::Error)
 
 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::Established, Event::AppData, StateEnum::Error)
 
 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::Established, Event::AppWrite, StateEnum::Error)
 
 FIZZ_DECLARE_EVENT_HANDLER (ClientTypes, StateEnum::Established, Event::KeyUpdate, StateEnum::Error)
 
static folly::Optional< CachedPskvalidatePsk (const FizzClientContext &context, folly::Optional< CachedPsk > psk)
 
static std::map< NamedGroup, std::unique_ptr< KeyExchange > > getKeyExchangers (const Factory &factory, const std::vector< NamedGroup > &groups)
 
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 ClientPresharedKey getPskExtension (const CachedPsk &psk)
 
static Buf encodeAndAddBinders (ClientHello chlo, const CachedPsk &psk, KeyScheduler &scheduler, HandshakeContext &handshakeContext)
 
static Optional< EarlyDataParamsgetEarlyDataParams (const FizzClientContext &context, const Optional< CachedPsk > &psk)
 
template<typename ServerMessage >
static std::pair< ProtocolVersion, CipherSuitegetAndValidateVersionAndCipher (const ServerMessage &msg, const std::vector< ProtocolVersion > &supportedVersions, const std::vector< CipherSuite > &supportedCiphers)
 
static auto negotiateParameters (const ServerHello &shlo, const std::vector< ProtocolVersion > &supportedVersions, const std::vector< CipherSuite > &supportedCiphers, const std::map< NamedGroup, std::unique_ptr< KeyExchange >> &keyExchangers)
 
static void validateNegotiationConsistency (const State &state, ProtocolVersion version, CipherSuite cipher)
 
static NegotiatedPsk negotiatePsk (const std::vector< PskKeyExchangeMode > &supportedPskModes, const folly::Optional< CachedPsk > &attemptedPsk, const ServerHello &shlo, ProtocolVersion version, CipherSuite cipher, bool hasExchange)
 
static HrrParams negotiateParameters (const HelloRetryRequest &hrr, const std::vector< ProtocolVersion > &supportedVersions, const std::vector< CipherSuite > &supportedCiphers, const std::vector< NamedGroup > &supportedGroups)
 
static std::map< NamedGroup, std::unique_ptr< KeyExchange > > getHrrKeyExchangers (const Factory &factory, std::map< NamedGroup, std::unique_ptr< KeyExchange >> previous, Optional< NamedGroup > negotiatedGroup)
 
static void validateAcceptedEarly (const State &state, const Optional< std::string > &alpn)
 
static std::tuple< folly::Optional< SignatureScheme >, std::shared_ptr< const SelfCert > > getClientCert (const State &state, const std::vector< SignatureScheme > &schemes)
 
static MutateState handleCertMsg (const State &state, CertificateMsg certMsg, folly::Optional< CertificateCompressionAlgorithm > algo)
 
static uint32_t getMaxEarlyDataSize (const NewSessionTicket &nst)
 
static Actions ignoreEarlyAppWrite (const State &state, EarlyAppWrite write)
 
static Actions handleEarlyAppWrite (const State &state, EarlyAppWrite appWrite)
 
 FIZZ_DECLARE_EVENT_HANDLER (ServerTypes, StateEnum::Uninitialized, Event::Accept, StateEnum::ExpectingClientHello)
 
 FIZZ_DECLARE_EVENT_HANDLER (ServerTypes, StateEnum::ExpectingClientHello, Event::ClientHello, StateEnum::ExpectingClientHello, StateEnum::ExpectingCertificate, StateEnum::ExpectingFinished, StateEnum::AcceptingEarlyData, StateEnum::Error)
 
 FIZZ_DECLARE_EVENT_HANDLER (ServerTypes, StateEnum::AcceptingEarlyData, Event::AppData, StateEnum::Error)
 
 FIZZ_DECLARE_EVENT_HANDLER (ServerTypes, StateEnum::AcceptingEarlyData, Event::AppWrite, StateEnum::Error)
 
 FIZZ_DECLARE_EVENT_HANDLER (ServerTypes, StateEnum::AcceptingEarlyData, Event::EndOfEarlyData, StateEnum::ExpectingFinished)
 
 FIZZ_DECLARE_EVENT_HANDLER (ServerTypes, StateEnum::ExpectingCertificate, Event::Certificate, StateEnum::ExpectingCertificateVerify, StateEnum::ExpectingFinished) FIZZ_DECLARE_EVENT_HANDLER(ServerTypes
 
 FIZZ_DECLARE_EVENT_HANDLER (ServerTypes, StateEnum::ExpectingFinished, Event::AppWrite, StateEnum::Error)
 
 FIZZ_DECLARE_EVENT_HANDLER (ServerTypes, StateEnum::ExpectingFinished, Event::Finished, StateEnum::AcceptingData)
 
 FIZZ_DECLARE_EVENT_HANDLER (ServerTypes, StateEnum::AcceptingData, Event::WriteNewSessionTicket, StateEnum::Error)
 
 FIZZ_DECLARE_EVENT_HANDLER (ServerTypes, StateEnum::AcceptingData, Event::AppData, StateEnum::Error)
 
 FIZZ_DECLARE_EVENT_HANDLER (ServerTypes, StateEnum::AcceptingData, Event::AppWrite, StateEnum::Error)
 
 FIZZ_DECLARE_EVENT_HANDLER (ServerTypes, StateEnum::AcceptingData, Event::KeyUpdate, StateEnum::AcceptingData)
 
static void addHandshakeLogging (const State &state, const ClientHello &chlo)
 
static void validateClientHello (const ClientHello &chlo)
 
static Optional< ProtocolVersionnegotiateVersion (const ClientHello &chlo, const std::vector< ProtocolVersion > &versions)
 
static Optional< CookieStategetCookieState (const ClientHello &chlo, ProtocolVersion version, CipherSuite cipher, const CookieCipher *cookieCipher)
 
static ResumptionStateResult getResumptionState (const ClientHello &chlo, const TicketCipher *ticketCipher, const std::vector< PskKeyExchangeMode > &supportedModes)
 
Future< ReplayCacheResultgetReplayCacheResult (const ClientHello &chlo, bool zeroRttEnabled, ReplayCache *replayCache)
 
static bool validateResumptionState (const ResumptionState &resState, PskKeyExchangeMode, ProtocolVersion version, CipherSuite cipher)
 
static CipherSuite negotiateCipher (const ClientHello &chlo, const std::vector< std::vector< CipherSuite >> &supportedCiphers)
 
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)
 
static void validateGroups (const std::vector< KeyShareEntry > &client_shares)
 
static std::tuple< NamedGroup, Optional< Buf > > negotiateGroup (ProtocolVersion version, const ClientHello &chlo, const std::vector< NamedGroup > &supportedGroups)
 
static Buf doKex (const Factory &factory, NamedGroup group, const Buf &clientShare, KeyScheduler &scheduler)
 
static Buf getHelloRetryRequest (ProtocolVersion version, CipherSuite cipher, NamedGroup group, Buf legacySessionId, HandshakeContext &handshakeContext)
 
static Buf getServerHello (ProtocolVersion version, Random random, CipherSuite cipher, bool psk, Optional< NamedGroup > group, Optional< Buf > serverShare, Buf legacy_session_id, HandshakeContext &handshakeContext)
 
static Optional< std::stringnegotiateAlpn (const ClientHello &chlo, folly::Optional< std::string > zeroRttAlpn, const FizzServerContext &context)
 
static Optional< std::chrono::milliseconds > getClockSkew (const Optional< ResumptionState > &psk, Optional< uint32_t > obfuscatedAge)
 
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)
 
static Buf getEncryptedExt (HandshakeContext &handshakeContext, const folly::Optional< std::string > &selectedAlpn, EarlyDataType earlyData, std::vector< Extension > otherExtensions)
 
static std::pair< std::shared_ptr< SelfCert >, SignatureSchemechooseCert (const FizzServerContext &context, const ClientHello &chlo)
 
static std::tuple< Buf, folly::Optional< CertificateCompressionAlgorithm > > getCertificate (const std::shared_ptr< const SelfCert > &serverCert, const FizzServerContext &context, const ClientHello &chlo, HandshakeContext &handshakeContext)
 
static Buf getCertificateVerify (SignatureScheme sigScheme, Buf signature, HandshakeContext &handshakeContext)
 
static Buf getCertificateRequest (const std::vector< SignatureScheme > &acceptableSigSchemes, const CertificateVerifier *const verifier, HandshakeContext &handshakeContext)
 
static WriteToSocket writeNewSessionTicket (const FizzServerContext &context, const WriteRecordLayer &recordLayer, std::chrono::seconds ticketLifetime, uint32_t ticketAgeAdd, Buf nonce, Buf ticket, ProtocolVersion version)
 
static Future< Optional< WriteToSocket > > generateTicket (const State &state, const std::vector< uint8_t > &resumptionMasterSecret, Buf appToken=nullptr)
 

Function Documentation

static void fizz::sm::addHandshakeLogging ( const State state,
const ClientHello chlo 
)
static

Definition at line 311 of file ServerProtocol.cpp.

References fizz::ClientHello::cipher_suites, fizz::server::HandshakeLogging::clientCiphers, fizz::server::HandshakeLogging::clientExtensions, fizz::server::HandshakeLogging::clientKeyExchangeModes, fizz::server::HandshakeLogging::clientKeyShares, fizz::server::HandshakeLogging::clientLegacyVersion, fizz::server::HandshakeLogging::clientRandom, fizz::server::HandshakeLogging::clientRecordVersion, fizz::server::HandshakeLogging::clientSessionIdSent, fizz::server::HandshakeLogging::clientSignatureAlgorithms, fizz::server::HandshakeLogging::clientSni, fizz::server::HandshakeLogging::clientSupportedGroups, fizz::server::HandshakeLogging::clientSupportedVersions, fizz::ClientHello::extensions, fizz::server::State::handshakeLogging(), fizz::ClientHello::legacy_session_id, fizz::ClientHello::legacy_version, folly::gen::move, fizz::ClientHello::random, fizz::server::State::readRecordLayer(), and sni.

Referenced by getCertificateRequest().

311  {
312  if (state.handshakeLogging()) {
313  state.handshakeLogging()->clientLegacyVersion = chlo.legacy_version;
314  auto supportedVersions = getExtension<SupportedVersions>(chlo.extensions);
315  if (supportedVersions) {
317  supportedVersions->versions;
318  }
319  state.handshakeLogging()->clientCiphers = chlo.cipher_suites;
320  state.handshakeLogging()->clientExtensions.clear();
321  for (const auto& extension : chlo.extensions) {
322  state.handshakeLogging()->clientExtensions.push_back(
323  extension.extension_type);
324  }
325  auto plaintextReadRecord =
326  dynamic_cast<PlaintextReadRecordLayer*>(state.readRecordLayer());
327  if (plaintextReadRecord) {
329  plaintextReadRecord->getReceivedRecordVersion();
330  }
331  auto sni = getExtension<ServerNameList>(chlo.extensions);
332  if (sni && !sni->server_name_list.empty()) {
333  state.handshakeLogging()->clientSni = sni->server_name_list.front()
334  .hostname->moveToFbString()
335  .toStdString();
336  }
337  auto supportedGroups = getExtension<SupportedGroups>(chlo.extensions);
338  if (supportedGroups) {
340  std::move(supportedGroups->named_group_list);
341  }
342 
343  auto keyShare = getExtension<ClientKeyShare>(chlo.extensions);
344  if (keyShare && !state.handshakeLogging()->clientKeyShares) {
345  std::vector<NamedGroup> shares;
346  for (const auto& entry : keyShare->client_shares) {
347  shares.push_back(entry.group);
348  }
349  state.handshakeLogging()->clientKeyShares = std::move(shares);
350  }
351 
352  auto exchangeModes = getExtension<PskKeyExchangeModes>(chlo.extensions);
353  if (exchangeModes) {
355  std::move(exchangeModes->modes);
356  }
357 
358  auto clientSigSchemes = getExtension<SignatureAlgorithms>(chlo.extensions);
359  if (clientSigSchemes) {
361  std::move(clientSigSchemes->supported_signature_algorithms);
362  }
363 
365  chlo.legacy_session_id && !chlo.legacy_session_id->empty();
366  state.handshakeLogging()->clientRandom = chlo.random;
367  }
368 }
std::vector< CipherSuite > clientCiphers
Definition: State.h:42
folly::Optional< ProtocolVersion > clientRecordVersion
Definition: State.h:44
static const std::string chlo
folly::Optional< bool > clientSessionIdSent
Definition: State.h:50
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
folly::Optional< std::vector< NamedGroup > > clientKeyShares
Definition: State.h:47
std::vector< PskKeyExchangeMode > clientKeyExchangeModes
Definition: State.h:48
folly::Optional< Random > clientRandom
Definition: State.h:51
ReadRecordLayer * readRecordLayer() const
Definition: State.h:213
folly::Optional< std::string > clientSni
Definition: State.h:45
folly::Optional< ProtocolVersion > clientLegacyVersion
Definition: State.h:40
std::vector< ProtocolVersion > clientSupportedVersions
Definition: State.h:41
std::vector< SignatureScheme > clientSignatureAlgorithms
Definition: State.h:49
HandshakeLogging * handshakeLogging() const
Definition: State.h:193
StringPiece sni
std::vector< ExtensionType > clientExtensions
Definition: State.h:43
std::vector< NamedGroup > clientSupportedGroups
Definition: State.h:46
static std::pair<std::shared_ptr<SelfCert>, SignatureScheme> fizz::sm::chooseCert ( const FizzServerContext context,
const ClientHello chlo 
)
static

Definition at line 891 of file ServerProtocol.cpp.

References fizz::ClientHello::extensions, fizz::server::FizzServerContext::getCert(), fizz::handshake_failure, fizz::missing_extension, and sni.

Referenced by getCertificateRequest().

893  {
894  const auto& clientSigSchemes =
895  getExtension<SignatureAlgorithms>(chlo.extensions);
896  if (!clientSigSchemes) {
897  throw FizzException("no sig schemes", AlertDescription::missing_extension);
898  }
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()
904  .toStdString();
905  }
906 
907  auto certAndScheme =
908  context.getCert(sni, clientSigSchemes->supported_signature_algorithms);
909  if (!certAndScheme) {
910  throw FizzException(
911  "could not find suitable cert", AlertDescription::handshake_failure);
912  }
913  return *certAndScheme;
914 }
folly::Optional< std::pair< std::shared_ptr< SelfCert >, SignatureScheme > > getCert(const folly::Optional< std::string > &sni, const std::vector< SignatureScheme > &peerSigSchemes) const
static const std::string chlo
StringPiece sni
static Buf fizz::sm::doKex ( const Factory factory,
NamedGroup  group,
const Buf clientShare,
KeyScheduler scheduler 
)
static

Definition at line 659 of file ServerProtocol.cpp.

References fizz::KeyScheduler::deriveHandshakeSecret(), and fizz::Factory::makeKeyExchange().

Referenced by getCertificateRequest().

663  {
664  auto kex = factory.makeKeyExchange(group);
665  kex->generateKeyPair();
666  auto sharedSecret = kex->generateSharedSecret(clientShare->coalesce());
667  scheduler.deriveHandshakeSecret(sharedSecret->coalesce());
668  return kex->getKeyShare();
669 }
std::shared_ptr< folly::FunctionScheduler > scheduler
Definition: FilePoller.cpp:50
Optional< NamedGroup > group
static Buf fizz::sm::encodeAndAddBinders ( ClientHello  chlo,
const CachedPsk psk,
KeyScheduler scheduler,
HandshakeContext handshakeContext 
)
static

Returns the encoded client hello after updating the binder.

Will derive the early secret on the key scheduler and append the client hello to the handshake context.

Definition at line 452 of file ClientProtocol.cpp.

References folly::IOBufQueue::append(), fizz::HandshakeContext::appendToTranscript(), fizz::PskBinder::binder, folly::IOBufQueue::cacheChainLength(), folly::IOBufQueue::chainLength(), fizz::KeyScheduler::deriveEarlySecret(), fizz::encodeExtension(), fizz::encodeHandshake(), fizz::ClientHello::extensions, fizz::External, fizz::ExternalPskBinder, fizz::getBinderLength(), fizz::HandshakeContext::getBlankContext(), fizz::HandshakeContext::getFinishedData(), getPskExtension(), fizz::KeyScheduler::getSecret(), folly::IOBufQueue::move(), folly::gen::move, folly::range(), fizz::ResumptionPskBinder, fizz::client::CachedPsk::secret, folly::IOBufQueue::split(), and fizz::client::CachedPsk::type.

Referenced by getEarlyDataParams(), and getHrrKeyExchangers().

456  {
457  scheduler.deriveEarlySecret(folly::range(psk.secret));
458 
459  auto binderKey = scheduler.getSecret(
460  psk.type == PskType::External ? EarlySecrets::ExternalPskBinder
461  : EarlySecrets::ResumptionPskBinder,
462  handshakeContext.getBlankContext());
463 
464  auto pskExt = getPskExtension(psk);
465  chlo.extensions.push_back(encodeExtension(pskExt));
466 
467  size_t binderLength = getBinderLength(chlo);
468 
469  auto preEncoded = encodeHandshake(chlo);
470 
471  // Add the ClientHello up to the binder list to the transcript.
472  {
474  chloQueue.append(std::move(preEncoded));
475  auto chloPrefix = chloQueue.split(chloQueue.chainLength() - binderLength);
476  handshakeContext.appendToTranscript(chloPrefix);
477  }
478 
479  PskBinder binder;
480  binder.binder = handshakeContext.getFinishedData(folly::range(binderKey));
481  pskExt.binders.clear();
482  pskExt.binders.push_back(std::move(binder));
483 
484  chlo.extensions.pop_back();
485  chlo.extensions.push_back(encodeExtension(std::move(pskExt)));
486 
487  auto encoded = encodeHandshake(std::move(chlo));
488 
489  // Add the binder list to the transcript.
491  chloQueue.append(encoded->clone());
492  chloQueue.split(chloQueue.chainLength() - binderLength);
493  handshakeContext.appendToTranscript(chloQueue.move());
494 
495  return encoded;
496 }
Buf encodeHandshake(T &&handshakeMsg)
Definition: Types-inl.h:515
size_t getBinderLength(const ClientHello &chlo)
static const std::string chlo
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::shared_ptr< folly::FunctionScheduler > scheduler
Definition: FilePoller.cpp:50
static Options cacheChainLength()
Definition: IOBufQueue.h:83
std::string secret
Definition: PskCache.h:22
constexpr Range< Iter > range(Iter first, Iter last)
Definition: Range.h:1114
static ClientPresharedKey getPskExtension(const CachedPsk &psk)
Extension encodeExtension(const TokenBindingParameters &params)
Definition: Types.cpp:113
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::Uninitialized  ,
Event::Connect  ,
StateEnum::ExpectingServerHello   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::ExpectingServerHello  ,
Event::HelloRetryRequest  ,
StateEnum::ExpectingServerHello   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ServerTypes  ,
StateEnum::Uninitialized  ,
Event::Accept  ,
StateEnum::ExpectingClientHello   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::ExpectingServerHello  ,
Event::ServerHello  ,
StateEnum::ExpectingEncryptedExtensions   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ServerTypes  ,
StateEnum::ExpectingClientHello  ,
Event::ClientHello  ,
StateEnum::ExpectingClientHello  ,
StateEnum::ExpectingCertificate  ,
StateEnum::ExpectingFinished  ,
StateEnum::AcceptingEarlyData  ,
StateEnum::Error   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::ExpectingServerHello  ,
Event::EarlyAppWrite  ,
StateEnum::Error   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::ExpectingEncryptedExtensions  ,
Event::EncryptedExtensions  ,
StateEnum::ExpectingCertificate  ,
StateEnum::ExpectingFinished   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ServerTypes  ,
StateEnum::AcceptingEarlyData  ,
Event::AppData  ,
StateEnum::Error   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ServerTypes  ,
StateEnum::AcceptingEarlyData  ,
Event::AppWrite  ,
StateEnum::Error   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::ExpectingEncryptedExtensions  ,
Event::EarlyAppWrite  ,
StateEnum::Error   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ServerTypes  ,
StateEnum::AcceptingEarlyData  ,
Event::EndOfEarlyData  ,
StateEnum::ExpectingFinished   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::ExpectingCertificate  ,
Event::CertificateRequest  ,
StateEnum::ExpectingCertificate   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::ExpectingCertificate  ,
Event::Certificate  ,
StateEnum::ExpectingCertificateVerify   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ServerTypes  ,
StateEnum::ExpectingCertificate  ,
Event::Certificate  ,
StateEnum::ExpectingCertificateVerify  ,
StateEnum::ExpectingFinished   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::ExpectingCertificate  ,
Event::CompressedCertificate  ,
StateEnum::ExpectingCertificateVerify   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::ExpectingCertificate  ,
Event::EarlyAppWrite  ,
StateEnum::Error   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ServerTypes  ,
StateEnum::ExpectingFinished  ,
Event::AppWrite  ,
StateEnum::Error   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::ExpectingCertificateVerify  ,
Event::CertificateVerify  ,
StateEnum::ExpectingFinished   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ServerTypes  ,
StateEnum::ExpectingFinished  ,
Event::Finished  ,
StateEnum::AcceptingData   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::ExpectingCertificateVerify  ,
Event::EarlyAppWrite  ,
StateEnum::Error   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ServerTypes  ,
StateEnum::AcceptingData  ,
Event::WriteNewSessionTicket  ,
StateEnum::Error   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::ExpectingFinished  ,
Event::Finished  ,
StateEnum::Established   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ServerTypes  ,
StateEnum::AcceptingData  ,
Event::AppData  ,
StateEnum::Error   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::ExpectingFinished  ,
Event::EarlyAppWrite  ,
StateEnum::Error   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ServerTypes  ,
StateEnum::AcceptingData  ,
Event::AppWrite  ,
StateEnum::Error   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::Established  ,
Event::EarlyAppWrite  ,
StateEnum::Error   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ServerTypes  ,
StateEnum::AcceptingData  ,
Event::KeyUpdate  ,
StateEnum::AcceptingData   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::Established  ,
Event::NewSessionTicket  ,
StateEnum::Error   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::Established  ,
Event::AppData  ,
StateEnum::Error   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::Established  ,
Event::AppWrite  ,
StateEnum::Error   
)
fizz::sm::FIZZ_DECLARE_EVENT_HANDLER ( ClientTypes  ,
StateEnum::Established  ,
Event::KeyUpdate  ,
StateEnum::Error   
)
static Future<Optional<WriteToSocket> > fizz::sm::generateTicket ( const State state,
const std::vector< uint8_t > &  resumptionMasterSecret,
Buf  appToken = nullptr 
)
static

Definition at line 1641 of file ServerProtocol.cpp.

References fizz::server::AcceptingData, fizz::server::detail::actions(), fizz::server::ResumptionState::alpn, fizz::server::State::alpn(), fizz::server::ResumptionState::appToken, fizz::AppTraffic, fizz::test::appWrite(), fizz::bad_certificate, fizz::AppWrite::callback, fizz::certificate_required, fizz::CertificateVerify, fizz::server::ResumptionState::cipher, fizz::server::State::cipher(), fizz::KeyScheduler::clearMasterSecret(), fizz::Client, fizz::ClientAppTraffic, fizz::server::ResumptionState::clientCert, fizz::server::State::clientCert(), fizz::server::State::clientHandshakeSecret(), fizz::KeyScheduler::clientKeyUpdate(), fizz::WriteToSocket::contents, fizz::server::State::context(), folly::IOBuf::copyBuffer(), folly::IOBuf::create(), fizz::AppWrite::data, fizz::CryptoUtils::equal(), fizz::server::State::executor(), fizz::server::ExpectingCertificateVerify, fizz::finished, fizz::AppWrite::flags, fizz::server::FizzServerContext::getClientAuthMode(), fizz::server::FizzServerContext::getClientCertVerifier(), fizz::server::FizzServerContext::getFactory(), fizz::Protocol::getKeyUpdated(), fizz::getRealDraftVersion(), fizz::KeyScheduler::getResumptionSecret(), fizz::KeyScheduler::getSecret(), fizz::server::FizzServerContext::getSendNewSessionTicket(), fizz::server::FizzServerContext::getSupportedSigSchemes(), fizz::server::FizzServerContext::getTicketCipher(), fizz::handshake_failure, fizz::server::State::handshakeContext(), fizz::ReadRecordLayer::hasUnparsedHandshakeData(), fizz::illegal_parameter, fizz::server::State::keyScheduler(), fizz::Factory::makeEncryptedReadRecordLayer(), fizz::Factory::makeEncryptedWriteRecordLayer(), fizz::Factory::makePeerCert(), fizz::Factory::makeTicketAgeAdd(), folly::gen::move, folly::none, fizz::NotSupported, now(), fizz::server::Optional, fizz::server::State::pskType(), folly::range(), fizz::server::State::readRecordLayer(), fizz::ResumptionMaster, fizz::server::State::resumptionMasterSecret(), fizz::server::ResumptionState::resumptionSecret, fizz::ServerAppTraffic, fizz::server::ResumptionState::serverCert, fizz::server::State::serverCert(), fizz::KeyScheduler::serverKeyUpdate(), fizz::Protocol::setAead(), ticket, fizz::server::ResumptionState::ticketAgeAdd, fizz::server::ResumptionState::ticketIssueTime, fizz::tls_1_3_20, fizz::toString(), fizz::server::State::unverifiedCertChain(), fizz::update_not_requested, fizz::server::ResumptionState::version, fizz::server::State::version(), fizz::detail::write(), fizz::WriteRecordLayer::writeAppData(), fizz::WriteRecordLayer::writeHandshake(), fizz::WriteNewSessionTicket, writeNewSessionTicket(), and fizz::server::State::writeRecordLayer().

1644  {
1645  auto ticketCipher = state.context()->getTicketCipher();
1646 
1647  if (!ticketCipher || *state.pskType() == PskType::NotSupported) {
1648  return folly::none;
1649  }
1650 
1651  Buf ticketNonce;
1652  Buf resumptionSecret;
1653  auto realDraftVersion = getRealDraftVersion(*state.version());
1654  if (realDraftVersion == ProtocolVersion::tls_1_3_20) {
1655  ticketNonce = nullptr;
1656  resumptionSecret =
1657  folly::IOBuf::copyBuffer(folly::range(resumptionMasterSecret));
1658  } else {
1659  ticketNonce = folly::IOBuf::create(0);
1660  resumptionSecret = state.keyScheduler()->getResumptionSecret(
1661  folly::range(resumptionMasterSecret), ticketNonce->coalesce());
1662  }
1663 
1664  ResumptionState resState;
1665  resState.version = *state.version();
1666  resState.cipher = *state.cipher();
1667  resState.resumptionSecret = std::move(resumptionSecret);
1668  resState.serverCert = state.serverCert();
1669  resState.clientCert = state.clientCert();
1670  resState.alpn = state.alpn();
1671  resState.ticketAgeAdd = state.context()->getFactory()->makeTicketAgeAdd();
1673  resState.appToken = std::move(appToken);
1674 
1675  auto ticketFuture = ticketCipher->encrypt(std::move(resState));
1676  return ticketFuture.via(state.executor())
1677  .thenValue(
1678  [&state,
1679  ticketAgeAdd = resState.ticketAgeAdd,
1680  ticketNonce = std::move(ticketNonce)](
1683  if (!ticket) {
1684  return folly::none;
1685  }
1686  return writeNewSessionTicket(
1687  *state.context(),
1688  *state.writeRecordLayer(),
1689  ticket->second,
1690  ticketAgeAdd,
1691  std::move(ticketNonce),
1692  std::move(ticket->first),
1693  *state.version());
1694  });
1695 }
folly::Optional< ProtocolVersion > version() const
Definition: State.h:104
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
const TicketCipher * getTicketCipher() const
std::chrono::steady_clock::time_point now()
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
folly::Optional< std::string > alpn
std::chrono::system_clock::time_point ticketIssueTime
KeyScheduler * keyScheduler() const
Definition: State.h:203
static constexpr StringPiece ticket
folly::Executor * executor() const
Definition: State.h:76
const Factory * getFactory() const
const std::shared_ptr< const Cert > & clientCert() const
Definition: State.h:97
const WriteRecordLayer * writeRecordLayer() const
Definition: State.h:223
virtual Buf getResumptionSecret(folly::ByteRange resumptionMasterSecret, folly::ByteRange ticketNonce) const
constexpr Range< Iter > range(Iter first, Iter last)
Definition: Range.h:1114
folly::Optional< PskType > pskType() const
Definition: State.h:133
virtual uint32_t makeTicketAgeAdd() const
Definition: Factory.h:124
const FizzServerContext * context() const
Definition: State.h:83
std::unique_ptr< folly::IOBuf > Buf
Definition: Types.h:22
ProtocolVersion getRealDraftVersion(ProtocolVersion version)
Definition: Types.cpp:16
const folly::Optional< std::string > & alpn() const
Definition: State.h:168
std::shared_ptr< const Cert > serverCert
static std::unique_ptr< IOBuf > copyBuffer(const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
Definition: IOBuf.h:1587
std::shared_ptr< const Cert > clientCert
std::shared_ptr< const Cert > serverCert() const
Definition: State.h:90
folly::Optional< CipherSuite > cipher() const
Definition: State.h:111
constexpr None none
Definition: Optional.h:87
static WriteToSocket writeNewSessionTicket(const FizzServerContext &context, const WriteRecordLayer &recordLayer, std::chrono::seconds ticketLifetime, uint32_t ticketAgeAdd, Buf nonce, Buf ticket, ProtocolVersion version)
template<typename ServerMessage >
static std::pair<ProtocolVersion, CipherSuite> fizz::sm::getAndValidateVersionAndCipher ( const ServerMessage &  msg,
const std::vector< ProtocolVersion > &  supportedVersions,
const std::vector< CipherSuite > &  supportedCiphers 
)
static

Definition at line 689 of file ClientProtocol.cpp.

References fizz::handshake_failure, fizz::illegal_parameter, fizz::protocol_version, fizz::tls_1_2, and fizz::toString().

Referenced by negotiateParameters().

692  {
693  if (msg.legacy_version != ProtocolVersion::tls_1_2) {
694  throw FizzException(
695  folly::to<std::string>(
696  "received server legacy version ", toString(msg.legacy_version)),
697  AlertDescription::protocol_version);
698  }
699 
700  if (msg.legacy_compression_method != 0x00) {
701  throw FizzException(
702  "compression method not null", AlertDescription::illegal_parameter);
703  }
704 
705  auto supportedVersionsExt =
706  getExtension<ServerSupportedVersions>(msg.extensions);
707  if (!supportedVersionsExt) {
708  throw FizzException(
709  "no supported versions in shlo", AlertDescription::protocol_version);
710  }
711  auto selectedVersion = supportedVersionsExt->selected_version;
712  auto selectedCipher = msg.cipher_suite;
713 
714  if (std::find(
715  supportedVersions.begin(),
716  supportedVersions.end(),
717  selectedVersion) == supportedVersions.end()) {
718  throw FizzException(
719  "received unsupported server version",
720  AlertDescription::protocol_version);
721  }
722  if (std::find(
723  supportedCiphers.begin(), supportedCiphers.end(), selectedCipher) ==
724  supportedCiphers.end()) {
725  throw FizzException(
726  "server choose unsupported cipher suite",
727  AlertDescription::handshake_failure);
728  }
729 
730  return std::make_pair(selectedVersion, selectedCipher);
731 }
folly::StringPiece toString(StateEnum state)
Definition: State.cpp:16
static std::tuple<Buf, folly::Optional<CertificateCompressionAlgorithm> > fizz::sm::getCertificate ( const std::shared_ptr< const SelfCert > &  serverCert,
const FizzServerContext context,
const ClientHello chlo,
HandshakeContext handshakeContext 
)
static

Definition at line 917 of file ServerProtocol.cpp.

References fizz::HandshakeContext::appendToTranscript(), encodedCertificate, fizz::encodeHandshake(), fizz::ClientHello::extensions, fizz::server::FizzServerContext::getSupportedCompressionAlgorithms(), std::tr1::make_tuple(), folly::gen::move, and fizz::server::negotiate().

Referenced by getCertificateRequest().

921  {
922  // Check for compression support first, and if so, send compressed.
925  auto compAlgos =
926  getExtension<CertificateCompressionAlgorithms>(chlo.extensions);
927  if (compAlgos && !context.getSupportedCompressionAlgorithms().empty()) {
928  algo = negotiate(
929  context.getSupportedCompressionAlgorithms(), compAlgos->algorithms);
930  }
931 
932  if (algo) {
933  encodedCertificate = encodeHandshake(serverCert->getCompressedCert(*algo));
934  } else {
935  encodedCertificate = encodeHandshake(serverCert->getCertMessage());
936  }
937  handshakeContext.appendToTranscript(encodedCertificate);
938  return std::make_tuple(std::move(encodedCertificate), std::move(algo));
939 }
const auto & getSupportedCompressionAlgorithms() const
Buf encodeHandshake(T &&handshakeMsg)
Definition: Types-inl.h:515
static const std::string chlo
folly::Optional< T > negotiate(const std::vector< std::vector< T >> &serverPref, const std::vector< T > &clientPref)
Definition: Negotiator.h:22
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
tuple make_tuple()
Definition: gtest-tuple.h:675
static const std::string encodedCertificate
std::shared_ptr< const Cert > serverCert
std::unique_ptr< folly::IOBuf > Buf
Definition: Types.h:22
static Buf fizz::sm::getCertificateRequest ( const std::vector< SignatureScheme > &  acceptableSigSchemes,
const CertificateVerifier *const  verifier,
HandshakeContext handshakeContext 
)
static

Definition at line 953 of file ServerProtocol.cpp.

References fizz::Accepted, fizz::server::AcceptingEarlyData, fizz::server::detail::actions(), addHandshakeLogging(), alpn, folly::IOBufQueue::append(), fizz::HandshakeContext::appendToTranscript(), fizz::server::State::appTokenValidator(), fizz::AppTraffic, fizz::test::appWrite(), fizz::AppWrite::callback, fizz::change_cipher_spec, chlo, chooseCert(), fizz::server::State::cipher(), cipher, clientCert, fizz::ClientEarlyTraffic, fizz::ClientHandshakeTraffic, fizz::server::AttemptVersionFallback::clientHello, folly::fibers::collectAll(), fizz::WriteToSocket::contents, fizz::TLSContent::contentType, fizz::server::State::context(), folly::IOBuf::copyBuffer(), fizz::TLSContent::data, fizz::AppWrite::data, doKex(), fizz::EarlyData, fizz::server::State::earlyDataType(), fizz::EarlyExporter, fizz::server::State::earlyExporterMasterSecret(), folly::IOBufQueue::empty(), encodedCertificate, encodedCertRequest, fizz::encodeExtension(), fizz::encodeHandshake(), fizz::TLSContent::encryptionLevel, fizz::EndOfEarlyData, fizz::server::State::executor(), fizz::ExporterMaster, fizz::server::State::extensions(), fizz::CertificateRequest::extensions, fizz::FakeChangeCipherSpec, fizz::AppWrite::flags, fizz::server::FizzServerContext::getAcceptEarlyData(), getCertificate(), fizz::CertificateVerifier::getCertificateRequestExtensions(), getCertificateVerify(), fizz::server::FizzServerContext::getClientAuthMode(), fizz::server::FizzServerContext::getClientCertVerifier(), getClockSkew(), fizz::server::FizzServerContext::getClockSkewTolerance(), fizz::server::FizzServerContext::getCookieCipher(), fizz::server::getCookieState(), getEncryptedExt(), fizz::ServerExtensions::getExtensions(), fizz::server::FizzServerContext::getFactory(), fizz::Protocol::getFinished(), getHelloRetryRequest(), fizz::getRealDraftVersion(), fizz::server::FizzServerContext::getReplayCache(), getReplayCacheResult(), getResumptionState(), getServerHello(), fizz::server::FizzServerContext::getSupportedCiphers(), fizz::server::FizzServerContext::getSupportedGroups(), fizz::server::FizzServerContext::getSupportedPskModes(), fizz::server::FizzServerContext::getSupportedSigSchemes(), fizz::server::FizzServerContext::getSupportedVersions(), fizz::server::FizzServerContext::getTicketCipher(), fizz::server::FizzServerContext::getVersionFallbackEnabled(), fizz::server::State::group(), group, fizz::Handshake, fizz::server::State::handshakeContext(), fizz::server::State::handshakeReadRecordLayer(), fizz::message_hash::hash, fizz::ReadRecordLayer::hasUnparsedHandshakeData(), folly::Optional< Value >::hasValue(), fizz::HelloRetryRequest, fizz::illegal_parameter, fizz::server::State::keyExchangeType(), fizz::Factory::makeEncryptedReadRecordLayer(), fizz::Factory::makeEncryptedWriteRecordLayer(), fizz::Factory::makeHandshakeContext(), fizz::Factory::makePlaintextReadRecordLayer(), fizz::Factory::makeRandom(), folly::IOBufQueue::move(), folly::gen::move, negotiateAlpn(), negotiateCipher(), negotiateEarlyDataType(), negotiateGroup(), negotiateVersion(), fizz::None, fizz::server::None, folly::none, obfuscatedAge, fizz::OneRtt, fizz::Plaintext, fizz::protocol_version, fizz::psk_ke, pskMode, folly::range(), fizz::server::State::readRecordLayer(), fizz::Rejected, fizz::server::State::replayCacheResult(), scheduler, fizz::Server, fizz::ServerAppTraffic, serverCert, fizz::ServerHandshakeTraffic, fizz::Protocol::setAead(), fizz::WriteRecordLayer::setProtocolVersion(), setupSchedulerAndContext(), folly::sig, folly::IOBufQueue::splitAtMost(), fizz::SignatureAlgorithms::supported_signature_algorithms, fizz::tls_1_3_20, fizz::tls_1_3_21, fizz::toString(), fizz::unexpected_message, validateClientHello(), validateResumptionState(), fizz::server::State::version(), version, folly::Future< T >::via(), folly::IOBuf::wrapBuffer(), fizz::detail::write(), fizz::WriteRecordLayer::writeAppData(), fizz::WriteRecordLayer::writeHandshake(), fizz::PlaintextWriteRecordLayer::writeInitialClientHello(), and fizz::server::State::writeRecordLayer().

956  {
957  CertificateRequest request;
958  SignatureAlgorithms algos;
959  algos.supported_signature_algorithms = acceptableSigSchemes;
960  request.extensions.push_back(encodeExtension(std::move(algos)));
961  if (verifier) {
962  auto verifierExtensions = verifier->getCertificateRequestExtensions();
963  for (auto& ext : verifierExtensions) {
964  request.extensions.push_back(std::move(ext));
965  }
966  }
967  auto encodedCertificateRequest = encodeHandshake(std::move(request));
968  handshakeContext.appendToTranscript(encodedCertificateRequest);
969  return encodedCertificateRequest;
970 }
Buf encodeHandshake(T &&handshakeMsg)
Definition: Types-inl.h:515
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
Extension encodeExtension(const TokenBindingParameters &params)
Definition: Types.cpp:113
static Buf fizz::sm::getCertificateVerify ( SignatureScheme  sigScheme,
Buf  signature,
HandshakeContext handshakeContext 
)
static

Definition at line 941 of file ServerProtocol.cpp.

References fizz::CertificateVerify::algorithm, fizz::HandshakeContext::appendToTranscript(), fizz::encodeHandshake(), folly::gen::move, fizz::CertificateVerify::signature, and verify().

Referenced by getCertificateRequest().

944  {
946  verify.algorithm = sigScheme;
947  verify.signature = std::move(signature);
948  auto encodedCertificateVerify = encodeHandshake(std::move(verify));
949  handshakeContext.appendToTranscript(encodedCertificateVerify);
950  return encodedCertificateVerify;
951 }
Buf encodeHandshake(T &&handshakeMsg)
Definition: Types-inl.h:515
void verify(int extras)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static std::tuple< folly::Optional<SignatureScheme>, std::shared_ptr<const SelfCert> > fizz::sm::getClientCert ( const State state,
const std::vector< SignatureScheme > &  schemes 
)
static

Definition at line 1278 of file ClientProtocol.cpp.

References fizz::client::detail::actions(), fizz::CertificateRequest, fizz::client::State::clientAuthRequested(), clientCert, fizz::client::State::context(), fizz::client::ExpectingCertificate, fizz::client::FizzClientContext::getClientCertificate(), fizz::client::FizzClientContext::getSupportedSigSchemes(), fizz::client::State::handshakeContext(), fizz::illegal_parameter, std::tr1::make_tuple(), folly::gen::move, fizz::client::RequestedNoMatch, fizz::client::Sent, and fizz::unexpected_message.

1278  {
1279  folly::Optional<SignatureScheme> selectedScheme;
1280  auto clientCert = state.context()->getClientCertificate();
1281  const auto& supportedSchemes = state.context()->getSupportedSigSchemes();
1282 
1283  if (clientCert) {
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;
1290  break;
1291  }
1292  }
1293 
1294  if (!selectedScheme) {
1295  VLOG(1) << "client cert/context doesn't support any signature algorithms "
1296  << "specified by the server";
1297  }
1298  }
1299 
1300  if (!selectedScheme) {
1301  clientCert = nullptr;
1302  }
1303 
1304  return std::make_tuple(std::move(selectedScheme), std::move(clientCert));
1305 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
tuple make_tuple()
Definition: gtest-tuple.h:675
const auto & getSupportedSigSchemes() const
const FizzClientContext * context() const
Definition: State.h:70
std::shared_ptr< const Cert > clientCert
const auto & getClientCertificate() const
static ClientHello fizz::sm::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

Definition at line 333 of file ClientProtocol.cpp.

References fizz::CertificateCompressionAlgorithms::algorithms, alpn, chlo, fizz::ClientHello::cipher_suites, fizz::ClientKeyShare::client_shares, cookie, fizz::Cookie::cookie, folly::IOBuf::copyBuffer(), fizz::encodeExtension(), fizz::ClientHello::extensions, fizz::ClientExtensions::getClientHelloExtensions(), fizz::KeyShareEntry::group, fizz::ServerName::hostname, fizz::KeyShareEntry::key_exchange, fizz::ClientHello::legacy_compression_methods, fizz::ClientHello::legacy_session_id, fizz::ClientHello::legacy_version, fizz::PskKeyExchangeModes::modes, folly::gen::move, fizz::ProtocolName::name, fizz::SupportedGroups::named_group_list, fizz::ProtocolNameList::protocol_name_list, random(), fizz::ClientHello::random, fizz::ServerNameList::server_name_list, folly::pushmi::operators::share, sni, fizz::SignatureAlgorithms::supported_signature_algorithms, fizz::tls_1_2, and fizz::SupportedVersions::versions.

Referenced by getEarlyDataParams(), getHrrKeyExchangers(), and fizz::server::test::TEST_F().

348  {
350  chlo.legacy_version = ProtocolVersion::tls_1_2;
351  chlo.random = random;
352  chlo.legacy_session_id = legacySessionId->clone();
353  chlo.cipher_suites = supportedCiphers;
354  chlo.legacy_compression_methods.push_back(0x00);
355 
356  SupportedVersions versions;
357  versions.versions = supportedVersions;
358  chlo.extensions.push_back(encodeExtension(std::move(versions)));
359 
360  SupportedGroups groups;
361  groups.named_group_list = supportedGroups;
362  chlo.extensions.push_back(encodeExtension(std::move(groups)));
363 
364  ClientKeyShare keyShare;
365  for (const auto& share : shares) {
366  KeyShareEntry entry;
367  entry.group = share.first;
368  entry.key_exchange = share.second->getKeyShare();
369  keyShare.client_shares.push_back(std::move(entry));
370  }
371  chlo.extensions.push_back(encodeExtension(std::move(keyShare)));
372 
373  SignatureAlgorithms sigAlgs;
374  sigAlgs.supported_signature_algorithms = supportedSigSchemes;
375  chlo.extensions.push_back(encodeExtension(std::move(sigAlgs)));
376 
377  if (hostname) {
378  ServerNameList sni;
379  ServerName sn;
380  sn.hostname = folly::IOBuf::copyBuffer(*hostname);
381  sni.server_name_list.push_back(std::move(sn));
382  chlo.extensions.push_back(encodeExtension(std::move(sni)));
383  }
384 
385  if (!supportedAlpns.empty()) {
386  ProtocolNameList alpn;
387  for (const auto& protoName : supportedAlpns) {
388  ProtocolName proto;
389  proto.name = folly::IOBuf::copyBuffer(protoName);
390  alpn.protocol_name_list.push_back(std::move(proto));
391  }
392  chlo.extensions.push_back(encodeExtension(std::move(alpn)));
393  }
394 
395  if (!supportedPskModes.empty()) {
396  PskKeyExchangeModes modes;
397  modes.modes = supportedPskModes;
398  chlo.extensions.push_back(encodeExtension(std::move(modes)));
399  }
400 
401  if (earlyDataParams) {
402  chlo.extensions.push_back(encodeExtension(ClientEarlyData()));
403  }
404 
405  if (cookie) {
406  Cookie monster;
407  monster.cookie = std::move(cookie);
408  chlo.extensions.push_back(encodeExtension(std::move(monster)));
409  }
410 
411  if (!compressionAlgos.empty()) {
412  CertificateCompressionAlgorithms algos;
413  algos.algorithms = compressionAlgos;
414  chlo.extensions.push_back(encodeExtension(std::move(algos)));
415  }
416 
417  if (extensions) {
418  auto additionalExtensions = extensions->getClientHelloExtensions();
419  for (auto& ext : additionalExtensions) {
420  chlo.extensions.push_back(std::move(ext));
421  }
422  }
423 
424  return chlo;
425 }
Integral2 random(Integral1 low, Integral2 up)
static const std::string chlo
PUSHMI_INLINE_VAR constexpr detail::share_fn< TN... > share
Definition: share.h:53
StringPiece cookie
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
StringPiece alpn
StringPiece sni
Extension encodeExtension(const TokenBindingParameters &params)
Definition: Types.cpp:113
static std::unique_ptr< IOBuf > copyBuffer(const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
Definition: IOBuf.h:1587
static Optional<std::chrono::milliseconds> fizz::sm::getClockSkew ( const Optional< ResumptionState > &  psk,
Optional< uint32_t obfuscatedAge 
)
static

Definition at line 778 of file ServerProtocol.cpp.

References folly::none, now(), fizz::server::ResumptionState::ticketAgeAdd, and fizz::server::ResumptionState::ticketIssueTime.

Referenced by getCertificateRequest().

780  {
781  if (!psk || !obfuscatedAge) {
782  return folly::none;
783  }
784 
785  auto age = std::chrono::milliseconds(
786  static_cast<uint32_t>(*obfuscatedAge - psk->ticketAgeAdd));
787 
788  auto expected = std::chrono::duration_cast<std::chrono::milliseconds>(
790 
791  return std::chrono::milliseconds(age - expected);
792 }
std::chrono::steady_clock::time_point now()
std::chrono::system_clock::time_point ticketIssueTime
constexpr None none
Definition: Optional.h:87
static Optional<CookieState> fizz::sm::getCookieState ( const ClientHello chlo,
ProtocolVersion  version,
CipherSuite  cipher,
const CookieCipher cookieCipher 
)
static

Definition at line 394 of file ServerProtocol.cpp.

References fizz::server::CookieCipher::decrypt(), fizz::decrypt_error, fizz::ClientHello::extensions, futureResState, fizz::handshake_failure, folly::gen::move, folly::none, obfuscatedAge, fizz::protocol_version, pskMode, and fizz::unsupported_extension.

398  {
399  auto cookieExt = getExtension<Cookie>(chlo.extensions);
400  if (!cookieExt) {
401  return folly::none;
402  }
403 
404  // If the client sent a cookie we can't use we have to consider it a fatal
405  // error since we can't reconstruct the handshake transcript.
406  if (!cookieCipher) {
407  throw FizzException(
408  "no cookie cipher", AlertDescription::unsupported_extension);
409  }
410 
411  auto cookieState = cookieCipher->decrypt(std::move(cookieExt->cookie));
412 
413  if (!cookieState) {
414  throw FizzException(
415  "could not decrypt cookie", AlertDescription::decrypt_error);
416  }
417 
418  if (cookieState->version != version) {
419  throw FizzException(
420  "version mismatch with cookie", AlertDescription::protocol_version);
421  }
422 
423  if (cookieState->cipher != cipher) {
424  throw FizzException(
425  "cipher mismatch with cookie", AlertDescription::handshake_failure);
426  }
427 
428  return cookieState;
429 }
static const std::string chlo
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
virtual folly::Optional< CookieState > decrypt(Buf) const =0
CipherSuite cipher
ProtocolVersion version
constexpr None none
Definition: Optional.h:87
static Optional<EarlyDataParams> fizz::sm::getEarlyDataParams ( const FizzClientContext context,
const Optional< CachedPsk > &  psk 
)
static

Definition at line 498 of file ClientProtocol.cpp.

References fizz::client::detail::actions(), fizz::client::CachedPsk::alpn, fizz::client::EarlyDataParams::alpn, fizz::Attempted, chlo, fizz::client::CachedPsk::cipher, fizz::client::EarlyDataParams::cipher, fizz::client::CachedPsk::clientCert, fizz::client::EarlyDataParams::clientCert, fizz::ClientEarlyTraffic, folly::netops::connect(), fizz::WriteToSocket::contents, context, folly::IOBuf::copyBuffer(), folly::IOBuf::create(), fizz::EarlyData, fizz::client::State::earlyDataParams(), fizz::EarlyExporter, fizz::client::State::earlyWriteRecordLayer(), encodeAndAddBinders(), fizz::encodeHandshake(), getClientHello(), getKeyExchangers(), fizz::client::FizzClientContext::getSendEarlyData(), fizz::client::FizzClientContext::getSupportedAlpns(), fizz::client::CachedPsk::group, fizz::client::CachedPsk::maxEarlyDataSize, fizz::client::ReportEarlyHandshakeSuccess::maxEarlyDataSize, folly::gen::move, folly::none, fizz::NotAttempted, params, fizz::pre_shared_key, random(), folly::range(), fizz::client::CachedPsk::serverCert, fizz::client::EarlyDataParams::serverCert, fizz::Protocol::setAead(), sni, validatePsk(), fizz::client::CachedPsk::version, fizz::client::EarlyDataParams::version, and fizz::detail::write().

Referenced by fizz::client::test::ClientProtocolTest::setupExpectingEncryptedExtensionsEarlySent(), and fizz::client::test::TEST_F().

500  {
501  if (!context.getSendEarlyData()) {
502  return folly::none;
503  }
504 
505  if (!psk || psk->maxEarlyDataSize == 0) {
506  return folly::none;
507  }
508 
509  if (psk->alpn &&
510  std::find(
511  context.getSupportedAlpns().begin(),
512  context.getSupportedAlpns().end(),
513  *psk->alpn) == context.getSupportedAlpns().end()) {
514  return folly::none;
515  }
516 
518  params.version = psk->version;
519  params.cipher = psk->cipher;
520  params.serverCert = psk->serverCert;
521  params.clientCert = psk->clientCert;
522  params.alpn = psk->alpn;
523  return std::move(params);
524 }
std::shared_ptr< const Cert > serverCert
Definition: State.h:52
std::shared_ptr< const Cert > clientCert
Definition: PskCache.h:29
const auto & getSupportedAlpns() const
folly::Optional< std::string > alpn
Definition: PskCache.h:32
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::shared_ptr< const Cert > clientCert
Definition: State.h:53
ProtocolVersion version
Definition: PskCache.h:25
constexpr Params params[]
std::shared_ptr< const Cert > serverCert
Definition: PskCache.h:28
folly::Optional< std::string > alpn
Definition: State.h:54
CipherSuite cipher
Definition: PskCache.h:26
uint32_t maxEarlyDataSize
Definition: PskCache.h:31
ProtocolVersion version
Definition: State.h:50
constexpr None none
Definition: Optional.h:87
static Buf fizz::sm::getEncryptedExt ( HandshakeContext handshakeContext,
const folly::Optional< std::string > &  selectedAlpn,
EarlyDataType  earlyData,
std::vector< Extension otherExtensions 
)
static

Definition at line 864 of file ServerProtocol.cpp.

References fizz::Accepted, alpn, fizz::HandshakeContext::appendToTranscript(), folly::IOBuf::copyBuffer(), fizz::encodeExtension(), fizz::EncryptedExtensions::extensions, folly::gen::move, fizz::ProtocolName::name, and fizz::ProtocolNameList::protocol_name_list.

Referenced by getCertificateRequest().

868  {
869  EncryptedExtensions encryptedExt;
870  if (selectedAlpn) {
871  ProtocolNameList alpn;
872  ProtocolName protocol;
873  protocol.name = folly::IOBuf::copyBuffer(*selectedAlpn);
874  alpn.protocol_name_list.push_back(std::move(protocol));
875  encryptedExt.extensions.push_back(encodeExtension(std::move(alpn)));
876  }
877 
878  if (earlyData == EarlyDataType::Accepted) {
879  encryptedExt.extensions.push_back(encodeExtension(ServerEarlyData()));
880  }
881 
882  for (auto& ext : otherExtensions) {
883  encryptedExt.extensions.push_back(std::move(ext));
884  }
885  auto encodedEncryptedExt =
886  encodeHandshake<EncryptedExtensions>(std::move(encryptedExt));
887  handshakeContext.appendToTranscript(encodedEncryptedExt);
888  return encodedEncryptedExt;
889 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
StringPiece alpn
Extension encodeExtension(const TokenBindingParameters &params)
Definition: Types.cpp:113
static std::unique_ptr< IOBuf > copyBuffer(const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
Definition: IOBuf.h:1587
static Buf fizz::sm::getHelloRetryRequest ( ProtocolVersion  version,
CipherSuite  cipher,
NamedGroup  group,
Buf  legacySessionId,
HandshakeContext handshakeContext 
)
static

Definition at line 671 of file ServerProtocol.cpp.

References fizz::HandshakeContext::appendToTranscript(), cipher, fizz::HelloRetryRequest::cipher_suite, fizz::encodeExtension(), fizz::encodeHandshake(), fizz::HelloRetryRequest::extensions, fizz::getRealDraftVersion(), group, fizz::HelloRetryRequest::legacy_session_id_echo, fizz::HelloRetryRequest::legacy_version, folly::gen::move, fizz::HelloRetryRequestKeyShare::preDraft23, fizz::HelloRetryRequestKeyShare::selected_group, fizz::ServerSupportedVersions::selected_version, fizz::tls_1_2, fizz::tls_1_3_20, fizz::tls_1_3_21, fizz::tls_1_3_22, and version.

Referenced by getCertificateRequest().

676  {
677  Buf encodedHelloRetryRequest;
678  auto realVersion = getRealDraftVersion(version);
679  if (realVersion == ProtocolVersion::tls_1_3_20 ||
680  realVersion == ProtocolVersion::tls_1_3_21) {
681  throw std::runtime_error("pre-22 HRR");
682  }
683 
684  HelloRetryRequest hrr;
685  hrr.legacy_version = ProtocolVersion::tls_1_2;
686  hrr.legacy_session_id_echo = std::move(legacySessionId);
687  hrr.cipher_suite = cipher;
688  ServerSupportedVersions versionExt;
689  versionExt.selected_version = version;
690  hrr.extensions.push_back(encodeExtension(std::move(versionExt)));
691  HelloRetryRequestKeyShare keyShare;
692 
693  if (realVersion == ProtocolVersion::tls_1_3_20 ||
694  realVersion == ProtocolVersion::tls_1_3_21 ||
695  realVersion == ProtocolVersion::tls_1_3_22) {
696  keyShare.preDraft23 = true;
697  }
698 
699  keyShare.selected_group = group;
700  hrr.extensions.push_back(encodeExtension(std::move(keyShare)));
701  encodedHelloRetryRequest = encodeHandshake(std::move(hrr));
702 
703  handshakeContext.appendToTranscript(encodedHelloRetryRequest);
704  return encodedHelloRetryRequest;
705 }
Buf encodeHandshake(T &&handshakeMsg)
Definition: Types-inl.h:515
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
CipherSuite cipher
ProtocolVersion version
Optional< NamedGroup > group
std::unique_ptr< folly::IOBuf > Buf
Definition: Types.h:22
ProtocolVersion getRealDraftVersion(ProtocolVersion version)
Definition: Types.cpp:16
Extension encodeExtension(const TokenBindingParameters &params)
Definition: Types.cpp:113
static std::map<NamedGroup, std::unique_ptr<KeyExchange> > fizz::sm::getHrrKeyExchangers ( const Factory factory,
std::map< NamedGroup, std::unique_ptr< KeyExchange >>  previous,
Optional< NamedGroup negotiatedGroup 
)
static

Definition at line 1036 of file ClientProtocol.cpp.

References fizz::client::detail::actions(), fizz::Attempted, fizz::client::State::attemptedPsk(), fizz::change_cipher_spec, fizz::Protocol::checkAllowedExtensions(), chlo, fizz::client::State::cipher(), cipher, fizz::client::State::clientRandom(), fizz::WriteToSocket::contents, fizz::TLSContent::contentType, fizz::client::State::context(), cookie, fizz::TLSContent::data, fizz::client::State::earlyDataType(), fizz::client::State::earlyWriteRecordLayer(), encodeAndAddBinders(), fizz::client::State::encodedClientHello(), fizz::encodeHandshake(), fizz::TLSContent::encryptionLevel, fizz::client::ExpectingServerHello, fizz::client::State::extensions(), fizz::FakeChangeCipherSpec, getClientHello(), fizz::client::FizzClientContext::getCompatibilityMode(), fizz::client::FizzClientContext::getFactory(), fizz::getHashFunction(), getKeyExchangers(), fizz::client::FizzClientContext::getSupportedAlpns(), fizz::client::FizzClientContext::getSupportedCertDecompressionAlgorithms(), fizz::client::FizzClientContext::getSupportedCiphers(), fizz::client::FizzClientContext::getSupportedGroups(), fizz::client::FizzClientContext::getSupportedPskModes(), fizz::client::FizzClientContext::getSupportedSigSchemes(), fizz::client::FizzClientContext::getSupportedVersions(), group, fizz::client::State::handshakeContext(), fizz::message_hash::hash, folly::Optional< Value >::hasValue(), fizz::HelloRetryRequest, fizz::illegal_parameter, fizz::client::State::keyExchangers(), fizz::client::State::keyExchangeType(), fizz::client::State::legacySessionId(), fizz::Factory::makeHandshakeContext(), fizz::Factory::makeKeyScheduler(), folly::gen::move, negotiateParameters(), folly::none, fizz::Plaintext, fizz::pre_shared_key, fizz::Rejected, fizz::client::State::requestedExtensions(), fizz::client::State::sentCCS(), fizz::client::State::sni(), fizz::unexpected_message, fizz::client::State::version(), version, folly::IOBuf::wrapBuffer(), fizz::WriteRecordLayer::writeHandshake(), and fizz::client::State::writeRecordLayer().

1039  {
1040  if (negotiatedGroup) {
1041  if (previous.find(*negotiatedGroup) != previous.end()) {
1042  throw FizzException(
1043  "hrr selected already-sent group",
1044  AlertDescription::illegal_parameter);
1045  }
1046  return getKeyExchangers(factory, {*negotiatedGroup});
1047  } else {
1048  return previous;
1049  }
1050 }
static std::map< NamedGroup, std::unique_ptr< KeyExchange > > getKeyExchangers(const Factory &factory, const std::vector< NamedGroup > &groups)
static std::map<NamedGroup, std::unique_ptr<KeyExchange> > fizz::sm::getKeyExchangers ( const Factory factory,
const std::vector< NamedGroup > &  groups 
)
static

Definition at line 321 of file ClientProtocol.cpp.

References group, fizz::Factory::makeKeyExchange(), and folly::gen::move.

Referenced by getEarlyDataParams(), and getHrrKeyExchangers().

323  {
324  std::map<NamedGroup, std::unique_ptr<KeyExchange>> keyExchangers;
325  for (auto group : groups) {
326  auto kex = factory.makeKeyExchange(group);
327  kex->generateKeyPair();
328  keyExchangers.emplace(group, std::move(kex));
329  }
330  return keyExchangers;
331 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
Optional< NamedGroup > group
static uint32_t fizz::sm::getMaxEarlyDataSize ( const NewSessionTicket nst)
static

Definition at line 1661 of file ClientProtocol.cpp.

References fizz::client::detail::actions(), fizz::client::CachedPsk::alpn, fizz::client::State::alpn(), fizz::AppTraffic, fizz::test::appWrite(), fizz::AppWrite::callback, fizz::client::CachedPsk::cipher, fizz::client::State::cipher(), fizz::ClientAppTraffic, fizz::client::CachedPsk::clientCert, fizz::client::State::clientCert(), fizz::KeyScheduler::clientKeyUpdate(), fizz::WriteToSocket::contents, fizz::client::State::context(), fizz::AppWrite::data, fizz::NewSessionTicket::extensions, fizz::AppWrite::flags, fizz::client::FizzClientContext::getFactory(), fizz::Protocol::getKeyUpdated(), fizz::KeyScheduler::getResumptionSecret(), fizz::KeyScheduler::getSecret(), fizz::client::CachedPsk::group, fizz::client::State::group(), fizz::ReadRecordLayer::hasUnparsedHandshakeData(), fizz::client::State::keyScheduler(), fizz::Factory::makeEncryptedReadRecordLayer(), fizz::Factory::makeEncryptedWriteRecordLayer(), fizz::client::CachedPsk::maxEarlyDataSize, folly::gen::move, now(), nst, fizz::client::CachedPsk::psk, fizz::client::NewCachedPsk::psk, folly::range(), fizz::client::State::readRecordLayer(), fizz::Resumption, fizz::client::State::resumptionSecret(), fizz::client::CachedPsk::secret, fizz::ServerAppTraffic, fizz::client::CachedPsk::serverCert, fizz::client::State::serverCert(), fizz::KeyScheduler::serverKeyUpdate(), fizz::Protocol::setAead(), string, fizz::client::CachedPsk::ticketAgeAdd, fizz::client::CachedPsk::ticketExpirationTime, fizz::client::CachedPsk::ticketIssueTime, fizz::client::CachedPsk::type, fizz::unexpected_message, fizz::update_not_requested, fizz::client::CachedPsk::version, fizz::client::State::version(), fizz::detail::write(), fizz::WriteRecordLayer::writeAppData(), fizz::WriteRecordLayer::writeHandshake(), and fizz::client::State::writeRecordLayer().

1661  {
1662  auto earlyData = getExtension<TicketEarlyData>(nst.extensions);
1663  if (earlyData) {
1664  return earlyData->max_early_data_size;
1665  } else {
1666  return 0;
1667  }
1668 }
static const std::string nst
static ClientPresharedKey fizz::sm::getPskExtension ( const CachedPsk psk)
static

Definition at line 427 of file ClientProtocol.cpp.

References fizz::PskBinder::binder, fizz::ClientPresharedKey::binders, fizz::client::CachedPsk::cipher, folly::IOBuf::copyBuffer(), count, folly::IOBuf::create(), fizz::getHashFunction(), fizz::getHashSize(), fizz::ClientPresharedKey::identities, folly::gen::move, now(), fizz::PskIdentity::obfuscated_ticket_age, fizz::client::CachedPsk::psk, fizz::PskIdentity::psk_identity, fizz::client::CachedPsk::ticketAgeAdd, and fizz::client::CachedPsk::ticketIssueTime.

Referenced by encodeAndAddBinders().

427  {
428  ClientPresharedKey pskExt;
429  PskIdentity ident;
430  ident.psk_identity = folly::IOBuf::copyBuffer(psk.psk);
431  ident.obfuscated_ticket_age =
432  std::chrono::duration_cast<std::chrono::milliseconds>(
434  .count();
435  ident.obfuscated_ticket_age += psk.ticketAgeAdd;
436  pskExt.identities.push_back(std::move(ident));
437  PskBinder binder;
438  size_t binderSize = getHashSize(getHashFunction(psk.cipher));
439  binder.binder = folly::IOBuf::create(binderSize);
440  memset(binder.binder->writableData(), 0, binderSize);
441  binder.binder->append(binderSize);
442  pskExt.binders.push_back(std::move(binder));
443  return pskExt;
444 }
std::chrono::system_clock::time_point ticketIssueTime
Definition: PskCache.h:35
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
size_t getHashSize(HashFunction hash)
Definition: Types.cpp:25
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::chrono::steady_clock::time_point now()
HashFunction getHashFunction(CipherSuite cipher)
Definition: Types.cpp:13
int * count
CipherSuite cipher
Definition: PskCache.h:26
static std::unique_ptr< IOBuf > copyBuffer(const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
Definition: IOBuf.h:1587
Future<ReplayCacheResult> fizz::sm::getReplayCacheResult ( const ClientHello chlo,
bool  zeroRttEnabled,
ReplayCache replayCache 
)

Definition at line 484 of file ServerProtocol.cpp.

References fizz::server::ReplayCache::check(), fizz::ClientHello::extensions, fizz::server::NotChecked, fizz::ClientHello::random, and folly::range().

Referenced by getCertificateRequest().

487  {
488  if (!zeroRttEnabled || !replayCache ||
489  !getExtension<ClientEarlyData>(chlo.extensions)) {
491  }
492 
493  return replayCache->check(folly::range(chlo.random));
494 }
static const std::string chlo
virtual folly::Future< ReplayCacheResult > check(folly::ByteRange identifier)=0
constexpr Range< Iter > range(Iter first, Iter last)
Definition: Range.h:1114
static ResumptionStateResult fizz::sm::getResumptionState ( const ClientHello chlo,
const TicketCipher ticketCipher,
const std::vector< PskKeyExchangeMode > &  supportedModes 
)
static

Definition at line 447 of file ServerProtocol.cpp.

References fizz::server::TicketCipher::decrypt(), fizz::ClientHello::extensions, kPskIndex, fizz::missing_extension, fizz::server::negotiate(), folly::none, fizz::NotAttempted, fizz::NotSupported, pskMode, and fizz::Rejected.

Referenced by getCertificateRequest().

450  {
451  auto psks = getExtension<ClientPresharedKey>(chlo.extensions);
452  auto clientModes = getExtension<PskKeyExchangeModes>(chlo.extensions);
453  if (psks && !clientModes) {
454  throw FizzException("no psk modes", AlertDescription::missing_extension);
455  }
456 
458  if (clientModes) {
459  pskMode = negotiate(supportedModes, clientModes->modes);
460  }
461  if (!psks && !pskMode) {
462  return ResumptionStateResult(
463  std::make_pair(PskType::NotSupported, folly::none));
464  } else if (!psks || psks->identities.size() <= kPskIndex) {
465  return ResumptionStateResult(
466  std::make_pair(PskType::NotAttempted, folly::none));
467  } else if (!ticketCipher) {
468  VLOG(8) << "No ticket cipher, rejecting PSK.";
469  return ResumptionStateResult(
470  std::make_pair(PskType::Rejected, folly::none));
471  } else if (!pskMode) {
472  VLOG(8) << "No psk mode match, rejecting PSK.";
473  return ResumptionStateResult(
474  std::make_pair(PskType::Rejected, folly::none));
475  } else {
476  const auto& ident = psks->identities[kPskIndex].psk_identity;
477  return ResumptionStateResult(
478  ticketCipher->decrypt(ident->clone()),
479  pskMode,
480  psks->identities[kPskIndex].obfuscated_ticket_age);
481  }
482 }
static const std::string chlo
folly::Optional< T > negotiate(const std::vector< std::vector< T >> &serverPref, const std::vector< T > &clientPref)
Definition: Negotiator.h:22
static constexpr uint16_t kPskIndex
virtual folly::Future< std::pair< PskType, folly::Optional< ResumptionState > > > decrypt(std::unique_ptr< folly::IOBuf > encryptedTicket) const =0
Optional< PskKeyExchangeMode > pskMode
constexpr None none
Definition: Optional.h:87
static Buf fizz::sm::getServerHello ( ProtocolVersion  version,
Random  random,
CipherSuite  cipher,
bool  psk,
Optional< NamedGroup group,
Optional< Buf serverShare,
Buf  legacy_session_id,
HandshakeContext handshakeContext 
)
static

Definition at line 707 of file ServerProtocol.cpp.

References fizz::HandshakeContext::appendToTranscript(), cipher, fizz::ServerHello::cipher_suite, fizz::encodeExtension(), fizz::encodeHandshake(), fizz::ServerHello::extensions, fizz::getRealDraftVersion(), fizz::KeyShareEntry::group, group, fizz::KeyShareEntry::key_exchange, kPskIndex, fizz::ServerHello::legacy_session_id_echo, fizz::ServerHello::legacy_version, folly::gen::move, fizz::ServerKeyShare::preDraft23, fizz::ServerHello::random, fizz::ServerPresharedKey::selected_identity, fizz::ServerSupportedVersions::selected_version, fizz::ServerKeyShare::server_share, fizz::tls_1_2, fizz::tls_1_3_20, fizz::tls_1_3_21, fizz::tls_1_3_22, and version.

Referenced by getCertificateRequest().

715  {
716  ServerHello serverHello;
717 
718  auto realVersion = getRealDraftVersion(version);
719  if (realVersion == ProtocolVersion::tls_1_3_20 ||
720  realVersion == ProtocolVersion::tls_1_3_21) {
721  serverHello.legacy_version = version;
722  } else {
723  serverHello.legacy_version = ProtocolVersion::tls_1_2;
724  ServerSupportedVersions versionExt;
725  versionExt.selected_version = version;
726  serverHello.extensions.push_back(encodeExtension(std::move(versionExt)));
727  serverHello.legacy_session_id_echo = std::move(legacy_session_id);
728  }
729 
730  serverHello.random = std::move(random);
731  serverHello.cipher_suite = cipher;
732  if (group) {
733  ServerKeyShare serverKeyShare;
734  serverKeyShare.server_share.group = *group;
735  serverKeyShare.server_share.key_exchange = std::move(*serverShare);
736 
737  if (realVersion == ProtocolVersion::tls_1_3_20 ||
738  realVersion == ProtocolVersion::tls_1_3_21 ||
739  realVersion == ProtocolVersion::tls_1_3_22) {
740  serverKeyShare.preDraft23 = true;
741  }
742 
743  serverHello.extensions.push_back(
744  encodeExtension(std::move(serverKeyShare)));
745  }
746  if (psk) {
747  ServerPresharedKey serverPsk;
748  serverPsk.selected_identity = kPskIndex;
749  serverHello.extensions.push_back(encodeExtension(std::move(serverPsk)));
750  }
751  auto encodedServerHello = encodeHandshake(std::move(serverHello));
752  handshakeContext.appendToTranscript(encodedServerHello);
753  return encodedServerHello;
754 }
Buf encodeHandshake(T &&handshakeMsg)
Definition: Types-inl.h:515
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static constexpr uint16_t kPskIndex
CipherSuite cipher
ProtocolVersion version
Optional< NamedGroup > group
ProtocolVersion getRealDraftVersion(ProtocolVersion version)
Definition: Types.cpp:16
Extension encodeExtension(const TokenBindingParameters &params)
Definition: Types.cpp:113
static MutateState fizz::sm::handleCertMsg ( const State state,
CertificateMsg  certMsg,
folly::Optional< CertificateCompressionAlgorithm algo 
)
static

Definition at line 1353 of file ClientProtocol.cpp.

References fizz::Accepted, fizz::client::detail::actions(), fizz::CertificateVerify::algorithm, fizz::AppTraffic, fizz::bad_certificate, fizz::bad_record_mac, fizz::CertificateMsg::certificate_list, fizz::CertificateMsg::certificate_request_context, fizz::CertificateVerify, fizz::change_cipher_spec, fizz::client::State::cipher(), fizz::KeyScheduler::clearMasterSecret(), fizz::Client, fizz::ClientAppTraffic, fizz::client::State::clientAuthRequested(), fizz::client::State::clientAuthSigScheme(), fizz::client::State::clientCert(), clientCert, fizz::client::State::clientHandshakeSecret(), fizz::CompressedCertificate, fizz::TLSContent::contentType, fizz::client::State::context(), folly::IOBuf::copyBuffer(), fizz::TLSContent::data, fizz::KeyScheduler::deriveAppTrafficSecrets(), fizz::KeyScheduler::deriveMasterSecret(), fizz::client::ReportHandshakeSuccess::earlyDataAccepted, fizz::client::State::earlyDataType(), fizz::client::State::earlyWriteRecordLayer(), encodedCertVerify, fizz::encodeHandshake(), fizz::TLSContent::encryptionLevel, fizz::CryptoUtils::equal(), fizz::client::ExpectingCertificate, fizz::client::ExpectingCertificateVerify, fizz::ExporterMaster, fizz::client::State::exporterMasterSecret(), fizz::FakeChangeCipherSpec, fizz::finished, fizz::client::FizzClientContext::getCertDecompressorForAlgorithm(), fizz::client::FizzClientContext::getCompatibilityMode(), fizz::client::FizzClientContext::getFactory(), fizz::Protocol::getFinished(), fizz::KeyScheduler::getSecret(), fizz::client::FizzClientContext::getSupportedCertDecompressionAlgorithms(), fizz::client::FizzClientContext::getSupportedSigSchemes(), fizz::client::State::handshakeContext(), fizz::ReadRecordLayer::hasUnparsedHandshakeData(), fizz::illegal_parameter, fizz::client::State::keyScheduler(), fizz::Factory::makeEncryptedReadRecordLayer(), fizz::Factory::makeEncryptedWriteRecordLayer(), fizz::Factory::makePeerCert(), folly::gen::move, folly::none, fizz::client::NotRequested, fizz::Plaintext, folly::range(), fizz::client::State::readRecordLayer(), fizz::client::RequestedNoMatch, fizz::ResumptionMaster, fizz::client::State::resumptionSecret(), fizz::client::State::selectedClientCert(), fizz::client::Sent, fizz::client::State::sentCCS(), fizz::Server, fizz::ServerAppTraffic, serverCert, fizz::client::State::serverHandshakeSecret(), fizz::Protocol::setAead(), fizz::CertificateVerify::signature, fizz::client::Stored, fizz::toString(), fizz::unexpected_message, fizz::client::State::unverifiedCertChain(), folly::Optional< Value >::value_or(), fizz::client::State::verifier(), fizz::CertificateVerifier::verify(), verify(), fizz::client::State::version(), folly::IOBuf::wrapBuffer(), fizz::WriteRecordLayer::writeHandshake(), and fizz::client::State::writeRecordLayer().

1356  {
1357  if (!certMsg.certificate_request_context->empty()) {
1358  throw FizzException(
1359  "certificate request context must be empty",
1360  AlertDescription::illegal_parameter);
1361  }
1362 
1363  std::vector<std::shared_ptr<const PeerCert>> serverCerts;
1364  for (auto& certEntry : certMsg.certificate_list) {
1365  // We don't request any certificate-related extensions
1366  if (!certEntry.extensions.empty()) {
1367  throw FizzException(
1368  "certificate extensions must be empty",
1369  AlertDescription::illegal_parameter);
1370  }
1371 
1372  serverCerts.emplace_back(state.context()->getFactory()->makePeerCert(
1373  std::move(certEntry.cert_data)));
1374  }
1375 
1376  if (serverCerts.empty()) {
1377  throw FizzException(
1378  "no certificates received", AlertDescription::illegal_parameter);
1379  }
1380 
1381  ClientAuthType authType =
1382  state.clientAuthRequested().value_or(ClientAuthType::NotRequested);
1383 
1384  return [unverifiedCertChain = std::move(serverCerts),
1385  authType,
1386  compAlgo = std::move(algo)](State& newState) mutable {
1387  newState.unverifiedCertChain() = std::move(unverifiedCertChain);
1388  newState.clientAuthRequested() = authType;
1389  newState.serverCertCompAlgo() = std::move(compAlgo);
1390  };
1391 }
ClientAuthType
Definition: State.h:42
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
const Factory * getFactory() const
virtual std::shared_ptr< PeerCert > makePeerCert(Buf certData) const
Definition: Factory.h:128
FOLLY_CPP14_CONSTEXPR Value value_or(U &&dflt) const &
Definition: Optional.h:330
const FizzClientContext * context() const
Definition: State.h:70
folly::Optional< ClientAuthType > clientAuthRequested() const
Definition: State.h:92
static Actions fizz::sm::handleEarlyAppWrite ( const State state,
EarlyAppWrite  appWrite 
)
static

Definition at line 1801 of file ClientProtocol.cpp.

References fizz::Accepted, fizz::client::detail::actions(), fizz::test::appWrite(), fizz::Attempted, fizz::WriteToSocket::callback, fizz::EarlyAppWrite::callback, fizz::AppWrite::callback, fizz::change_cipher_spec, fizz::WriteToSocket::contents, fizz::TLSContent::contentType, fizz::client::State::context(), fizz::TLSContent::data, fizz::EarlyAppWrite::data, fizz::AppWrite::data, fizz::EarlyAppWrite, fizz::client::State::earlyDataType(), fizz::client::State::earlyWriteRecordLayer(), fizz::TLSContent::encryptionLevel, fizz::client::ExpectingCertificate, fizz::client::ExpectingCertificateVerify, fizz::client::ExpectingEncryptedExtensions, fizz::client::ExpectingServerHello, fizz::FakeChangeCipherSpec, fizz::WriteToSocket::flags, fizz::EarlyAppWrite::flags, fizz::AppWrite::flags, fizz::client::FizzClientContext::getCompatibilityMode(), ignoreEarlyAppWrite(), folly::gen::move, folly::none, fizz::NotAttempted, fizz::Plaintext, fizz::Rejected, fizz::client::State::sentCCS(), folly::IOBuf::wrapBuffer(), fizz::detail::write(), fizz::WriteRecordLayer::writeAppData(), and fizz::client::State::writeRecordLayer().

1801  {
1802  switch (*state.earlyDataType()) {
1803  case EarlyDataType::NotAttempted:
1804  throw FizzException("invalid early write", folly::none);
1805  case EarlyDataType::Rejected:
1806  return ignoreEarlyAppWrite(state, std::move(appWrite));
1807  case EarlyDataType::Attempted:
1808  case EarlyDataType::Accepted: {
1809  WriteToSocket write;
1810  write.callback = appWrite.callback;
1811  write.flags = appWrite.flags;
1812  auto appData =
1814 
1815  if (!state.sentCCS() && state.context()->getCompatibilityMode()) {
1816  TLSContent writeCCS;
1818  writeCCS.contentType = ContentType::change_cipher_spec;
1819  writeCCS.encryptionLevel = EncryptionLevel::Plaintext;
1820  write.contents.emplace_back(std::move(writeCCS));
1821  write.contents.emplace_back(std::move(appData));
1822  return actions(
1823  [](State& newState) { newState.sentCCS() = true; },
1824  std::move(write));
1825  } else {
1826  write.contents.emplace_back(std::move(appData));
1827  return actions(std::move(write));
1828  }
1829  }
1830  }
1831  LOG(FATAL) << "Bad EarlyDataType";
1832 }
static Actions ignoreEarlyAppWrite(const State &state, EarlyAppWrite write)
void write(const T &in, folly::io::Appender &appender)
Definition: Types-inl.h:112
folly::Optional< EarlyDataType > earlyDataType() const
Definition: State.h:156
static std::unique_ptr< IOBuf > wrapBuffer(const void *buf, std::size_t capacity)
Definition: IOBuf.cpp:353
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static AppWrite appWrite(const std::string &str)
constexpr folly::StringPiece FakeChangeCipherSpec
Definition: Types.h:59
Actions actions(Args &&...act)
Definition: Actions.h:86
bool sentCCS() const
Definition: State.h:215
const FizzClientContext * context() const
Definition: State.h:70
TLSContent writeAppData(std::unique_ptr< folly::IOBuf > &&appData) const
Definition: RecordLayer.h:69
const WriteRecordLayer * earlyWriteRecordLayer() const
Definition: State.h:254
std::unique_ptr< folly::IOBuf > data
Definition: Params.h:54
constexpr None none
Definition: Optional.h:87
folly::WriteFlags flags
Definition: Params.h:55
folly::AsyncTransportWrapper::WriteCallback * callback
Definition: Params.h:53
static Actions fizz::sm::ignoreEarlyAppWrite ( const State state,
EarlyAppWrite  write 
)
static

Definition at line 1791 of file ClientProtocol.cpp.

References fizz::client::detail::actions(), fizz::client::State::earlyDataType(), folly::gen::move, folly::none, fizz::Rejected, and fizz::client::ReportEarlyWriteFailed::write.

Referenced by handleEarlyAppWrite().

1791  {
1792  if (*state.earlyDataType() != EarlyDataType::Rejected) {
1793  throw FizzException("ignoring valid early write", folly::none);
1794  }
1795 
1796  ReportEarlyWriteFailed failedWrite;
1797  failedWrite.write = std::move(write);
1798  return actions(std::move(failedWrite));
1799 }
void write(const T &in, folly::io::Appender &appender)
Definition: Types-inl.h:112
folly::Optional< EarlyDataType > earlyDataType() const
Definition: State.h:156
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
Actions actions(Args &&...act)
Definition: Actions.h:86
constexpr None none
Definition: Optional.h:87
static Optional<std::string> fizz::sm::negotiateAlpn ( const ClientHello chlo,
folly::Optional< std::string zeroRttAlpn,
const FizzServerContext context 
)
static

Definition at line 756 of file ServerProtocol.cpp.

References fizz::ClientHello::extensions, and fizz::server::FizzServerContext::negotiateAlpn().

Referenced by getCertificateRequest().

759  {
760  auto ext = getExtension<ProtocolNameList>(chlo.extensions);
761  std::vector<std::string> clientProtocols;
762  if (ext) {
763  for (auto& protocol : ext->protocol_name_list) {
764  clientProtocols.push_back(protocol.name->moveToFbString().toStdString());
765  }
766  } else {
767  VLOG(6) << "Client did not send ALPN extension";
768  }
769  auto selected = context.negotiateAlpn(clientProtocols, zeroRttAlpn);
770  if (!selected) {
771  VLOG(6) << "ALPN mismatch";
772  } else {
773  VLOG(6) << "ALPN: " << *selected;
774  }
775  return selected;
776 }
static const std::string chlo
folly::Optional< std::string > negotiateAlpn(const std::vector< std::string > &clientProtocols, const folly::Optional< std::string > &zeroRttAlpn) const
static CipherSuite fizz::sm::negotiateCipher ( const ClientHello chlo,
const std::vector< std::vector< CipherSuite >> &  supportedCiphers 
)
static

Definition at line 514 of file ServerProtocol.cpp.

References cipher, fizz::ClientHello::cipher_suites, fizz::handshake_failure, and fizz::server::negotiate().

Referenced by getCertificateRequest().

516  {
517  auto cipher = negotiate(supportedCiphers, chlo.cipher_suites);
518  if (!cipher) {
519  throw FizzException("no cipher match", AlertDescription::handshake_failure);
520  }
521  return *cipher;
522 }
static const std::string chlo
folly::Optional< T > negotiate(const std::vector< std::vector< T >> &serverPref, const std::vector< T > &clientPref)
Definition: Negotiator.h:22
CipherSuite cipher
static EarlyDataType fizz::sm::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 
)
static

Definition at line 794 of file ServerProtocol.cpp.

References fizz::Accepted, fizz::server::ClockSkewTolerance::after, fizz::server::ResumptionState::alpn, fizz::server::ClockSkewTolerance::before, fizz::server::ResumptionState::cipher, fizz::ClientHello::extensions, fizz::HelloRetryRequest, fizz::NotAttempted, fizz::server::NotReplay, fizz::Rejected, and fizz::server::AppTokenValidator::validate().

Referenced by getCertificateRequest().

805  {
806  if (!getExtension<ClientEarlyData>(chlo.extensions)) {
807  return EarlyDataType::NotAttempted;
808  }
809 
810  if (!acceptEarlyData) {
811  VLOG(5) << "Rejecting early data: disabled";
812  return EarlyDataType::Rejected;
813  }
814 
815  if (!psk) {
816  VLOG(5) << "Rejected early data: psk rejected";
817  return EarlyDataType::Rejected;
818  }
819 
820  if (psk->cipher != cipher) {
821  VLOG(5) << "Rejected early data: cipher mismatch";
822  return EarlyDataType::Rejected;
823  }
824 
825  if (psk->alpn != alpn) {
826  VLOG(5) << "Rejecting early data: alpn mismatch";
827  return EarlyDataType::Rejected;
828  }
829 
830  if (keyExchangeType &&
831  *keyExchangeType == KeyExchangeType::HelloRetryRequest) {
832  VLOG(5) << "Rejecting early data: HelloRetryRequest";
833  return EarlyDataType::Rejected;
834  }
835 
836  if (cookieState) {
837  VLOG(5) << "Rejecting early data: Cookie";
838  return EarlyDataType::Rejected;
839  }
840 
841  if (replayCacheResult != ReplayCacheResult::NotReplay) {
842  VLOG(5) << "Rejecting early data: replay";
843  return EarlyDataType::Rejected;
844  }
845 
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())
850  : "(none)")
851  << " toleranceBefore=" << clockSkewTolerance.before.count()
852  << " toleranceAfter=" << clockSkewTolerance.after.count();
853  return EarlyDataType::Rejected;
854  }
855 
856  if (appTokenValidator && !appTokenValidator->validate(*psk)) {
857  VLOG(5) << "Rejecting early data: invalid app token";
858  return EarlyDataType::Rejected;
859  }
860 
861  return EarlyDataType::Accepted;
862 }
static const std::string chlo
folly::Optional< std::string > alpn
virtual bool validate(const ResumptionState &) const =0
CipherSuite cipher
std::chrono::milliseconds after
std::chrono::milliseconds before
static std::tuple<NamedGroup, Optional<Buf> > fizz::sm::negotiateGroup ( ProtocolVersion  version,
const ClientHello chlo,
const std::vector< NamedGroup > &  supportedGroups 
)
static

Definition at line 617 of file ServerProtocol.cpp.

References fizz::ClientHello::extensions, fizz::getRealDraftVersion(), group, fizz::handshake_failure, fizz::illegal_parameter, std::tr1::make_tuple(), fizz::missing_extension, fizz::server::negotiate(), folly::none, folly::pushmi::operators::share, fizz::tls_1_3_20, fizz::tls_1_3_21, fizz::tls_1_3_22, and validateGroups().

Referenced by getCertificateRequest().

620  {
621  auto groups = getExtension<SupportedGroups>(chlo.extensions);
622  if (!groups) {
623  throw FizzException("no named groups", AlertDescription::missing_extension);
624  }
625  auto group = negotiate(supportedGroups, groups->named_group_list);
626  if (!group) {
627  throw FizzException("no group match", AlertDescription::handshake_failure);
628  }
629  auto clientShares = getExtension<ClientKeyShare>(chlo.extensions);
630  if (!clientShares) {
631  throw FizzException(
632  "no client shares", AlertDescription::missing_extension);
633  }
634 
635  auto realVersion = getRealDraftVersion(version);
636  if (realVersion == ProtocolVersion::tls_1_3_20 ||
637  realVersion == ProtocolVersion::tls_1_3_21 ||
638  realVersion == ProtocolVersion::tls_1_3_22) {
639  if (!clientShares->preDraft23) {
640  throw FizzException(
641  "post-23 client share", AlertDescription::illegal_parameter);
642  }
643  } else {
644  if (clientShares->preDraft23) {
645  throw FizzException(
646  "pre-23 client share", AlertDescription::illegal_parameter);
647  }
648  }
649 
650  validateGroups(clientShares->client_shares);
651  for (const auto& share : clientShares->client_shares) {
652  if (share.group == *group) {
653  return std::make_tuple(*group, share.key_exchange->clone());
654  }
655  }
657 }
static const std::string chlo
PUSHMI_INLINE_VAR constexpr detail::share_fn< TN... > share
Definition: share.h:53
static void validateGroups(const std::vector< KeyShareEntry > &client_shares)
folly::Optional< T > negotiate(const std::vector< std::vector< T >> &serverPref, const std::vector< T > &clientPref)
Definition: Negotiator.h:22
tuple make_tuple()
Definition: gtest-tuple.h:675
ProtocolVersion version
Optional< NamedGroup > group
ProtocolVersion getRealDraftVersion(ProtocolVersion version)
Definition: Types.cpp:16
constexpr None none
Definition: Optional.h:87
static auto fizz::sm::negotiateParameters ( const ServerHello shlo,
const std::vector< ProtocolVersion > &  supportedVersions,
const std::vector< CipherSuite > &  supportedCiphers,
const std::map< NamedGroup, std::unique_ptr< KeyExchange >> &  keyExchangers 
)
static

Definition at line 733 of file ClientProtocol.cpp.

References cipher, folly::exchange(), fizz::ServerHello::extensions, getAndValidateVersionAndCipher(), fizz::handshake_failure, std::tr1::make_tuple(), folly::gen::move, and version.

737  {
740  std::tie(version, cipher) =
741  getAndValidateVersionAndCipher(shlo, supportedVersions, supportedCiphers);
742 
744  const auto serverShare = getExtension<ServerKeyShare>(shlo.extensions);
745  if (serverShare) {
746  auto kex = keyExchangers.find(serverShare->server_share.group);
747  if (kex == keyExchangers.end()) {
748  throw FizzException(
749  "server choose unsupported group",
750  AlertDescription::handshake_failure);
751  }
752  exchange = std::make_tuple(
753  serverShare->server_share.group,
754  serverShare->server_share.key_exchange->clone(),
755  kex->second.get());
756  }
757 
758  return std::make_tuple(version, cipher, std::move(exchange));
759 }
static std::pair< ProtocolVersion, CipherSuite > getAndValidateVersionAndCipher(const ServerMessage &msg, const std::vector< ProtocolVersion > &supportedVersions, const std::vector< CipherSuite > &supportedCiphers)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
CipherSuite
Definition: Types.h:153
tuple make_tuple()
Definition: gtest-tuple.h:675
CipherSuite cipher
ProtocolVersion
Definition: Types.h:24
ProtocolVersion version
T exchange(T &obj, U &&new_value)
Definition: Utility.h:120
static HrrParams fizz::sm::negotiateParameters ( const HelloRetryRequest hrr,
const std::vector< ProtocolVersion > &  supportedVersions,
const std::vector< CipherSuite > &  supportedCiphers,
const std::vector< NamedGroup > &  supportedGroups 
)
static

Definition at line 1011 of file ClientProtocol.cpp.

References fizz::HelloRetryRequest::extensions, getAndValidateVersionAndCipher(), and fizz::handshake_failure.

Referenced by getHrrKeyExchangers(), and negotiatePsk().

1015  {
1016  HrrParams negotiated;
1017  std::tie(negotiated.version, negotiated.cipher) =
1018  getAndValidateVersionAndCipher(hrr, supportedVersions, supportedCiphers);
1019 
1020  auto keyShare = getExtension<HelloRetryRequestKeyShare>(hrr.extensions);
1021  if (keyShare) {
1022  if (std::find(
1023  supportedGroups.begin(),
1024  supportedGroups.end(),
1025  keyShare->selected_group) == supportedGroups.end()) {
1026  throw FizzException(
1027  "server choose unsupported group in hrr",
1028  AlertDescription::handshake_failure);
1029  }
1030  negotiated.group = keyShare->selected_group;
1031  }
1032 
1033  return negotiated;
1034 }
static std::pair< ProtocolVersion, CipherSuite > getAndValidateVersionAndCipher(const ServerMessage &msg, const std::vector< ProtocolVersion > &supportedVersions, const std::vector< CipherSuite > &supportedCiphers)
static NegotiatedPsk fizz::sm::negotiatePsk ( const std::vector< PskKeyExchangeMode > &  supportedPskModes,
const folly::Optional< CachedPsk > &  attemptedPsk,
const ServerHello shlo,
ProtocolVersion  version,
CipherSuite  cipher,
bool  hasExchange 
)
static

Definition at line 794 of file ClientProtocol.cpp.

References fizz::client::detail::actions(), fizz::client::State::attemptedPsk(), fizz::Protocol::checkAllowedExtensions(), fizz::client::CachedPsk::cipher, cipher, fizz::client::CachedPsk::clientCert, clientCert, fizz::ClientHandshakeTraffic, fizz::client::State::context(), folly::IOBuf::copyBuffer(), fizz::client::State::encodedClientHello(), folly::exchange(), fizz::ServerHello::extensions, fizz::KeyExchange::generateSharedSecret(), fizz::client::FizzClientContext::getFactory(), fizz::getHashFunction(), fizz::client::FizzClientContext::getSupportedCiphers(), fizz::client::FizzClientContext::getSupportedPskModes(), fizz::client::FizzClientContext::getSupportedVersions(), group, fizz::Handshake, fizz::handshake_failure, fizz::client::State::handshakeContext(), fizz::ReadRecordLayer::hasUnparsedHandshakeData(), folly::Optional< Value >::hasValue(), fizz::illegal_parameter, fizz::client::State::keyExchangers(), fizz::client::State::keyExchangeType(), fizz::client::State::legacySessionId(), fizz::Factory::makeEncryptedReadRecordLayer(), fizz::Factory::makeEncryptedWriteRecordLayer(), fizz::Factory::makeHandshakeContext(), fizz::Factory::makeKeyScheduler(), mode, folly::gen::move, negotiateParameters(), fizz::None, fizz::NotAttempted, fizz::client::NotRequested, fizz::NotSupported, fizz::OneRtt, fizz::psk_dhe_ke, fizz::psk_ke, pskMode, folly::range(), fizz::client::State::readRecordLayer(), fizz::Rejected, fizz::client::State::requestedExtensions(), scheduler, fizz::client::CachedPsk::serverCert, serverCert, fizz::ServerHandshakeTraffic, fizz::Protocol::setAead(), fizz::client::Stored, fizz::client::CachedPsk::type, fizz::unexpected_message, validateNegotiationConsistency(), fizz::client::CachedPsk::version, and version.

800  {
801  auto serverPsk = getExtension<ServerPresharedKey>(shlo.extensions);
802  if (!attemptedPsk) {
803  if (serverPsk) {
804  throw FizzException(
805  "server accepted unattempted psk",
806  AlertDescription::illegal_parameter);
807  } else if (!supportedPskModes.empty()) {
808  return NegotiatedPsk(PskType::NotAttempted);
809  } else {
810  return NegotiatedPsk(PskType::NotSupported);
811  }
812  } else {
813  if (!serverPsk) {
814  return NegotiatedPsk(PskType::Rejected);
815  }
816  if (serverPsk->selected_identity != 0) {
817  throw FizzException(
818  "server accepted non-0 psk", AlertDescription::illegal_parameter);
819  }
820 
821  if (version != attemptedPsk->version) {
822  throw FizzException(
823  "different version in psk", AlertDescription::handshake_failure);
824  }
825  if (getHashFunction(cipher) != getHashFunction(attemptedPsk->cipher)) {
826  throw FizzException(
827  "incompatible cipher in psk", AlertDescription::handshake_failure);
828  }
829 
830  PskKeyExchangeMode mode = hasExchange ? PskKeyExchangeMode::psk_dhe_ke
831  : PskKeyExchangeMode::psk_ke;
832  if (std::find(supportedPskModes.begin(), supportedPskModes.end(), mode) ==
833  supportedPskModes.end()) {
834  throw FizzException(
835  "server choose unsupported psk mode",
836  AlertDescription::handshake_failure);
837  }
838 
839  return NegotiatedPsk(
840  attemptedPsk->type,
841  mode,
842  attemptedPsk->serverCert,
843  attemptedPsk->clientCert);
844  }
845 }
std::shared_ptr< const Cert > clientCert
Definition: PskCache.h:29
CipherSuite cipher
ProtocolVersion version
Definition: PskCache.h:25
folly::Optional< PskKeyExchangeMode > mode
HashFunction getHashFunction(CipherSuite cipher)
Definition: Types.cpp:13
ProtocolVersion version
std::shared_ptr< const Cert > serverCert
Definition: PskCache.h:28
CipherSuite cipher
Definition: PskCache.h:26
PskKeyExchangeMode
Definition: Types.h:163
static Optional<ProtocolVersion> fizz::sm::negotiateVersion ( const ClientHello chlo,
const std::vector< ProtocolVersion > &  versions 
)
static

Definition at line 380 of file ServerProtocol.cpp.

References fizz::ClientHello::extensions, fizz::server::negotiate(), folly::none, and version.

Referenced by getCertificateRequest().

382  {
383  const auto& clientVersions = getExtension<SupportedVersions>(chlo.extensions);
384  if (!clientVersions) {
385  return folly::none;
386  }
387  auto version = negotiate(versions, clientVersions->versions);
388  if (!version) {
389  return folly::none;
390  }
391  return version;
392 }
static const std::string chlo
folly::Optional< T > negotiate(const std::vector< std::vector< T >> &serverPref, const std::vector< T > &clientPref)
Definition: Negotiator.h:22
ProtocolVersion version
constexpr None none
Definition: Optional.h:87
static std:: pair<std::unique_ptr<KeyScheduler>, std::unique_ptr<HandshakeContext> > fizz::sm::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   
)
static

Definition at line 536 of file ServerProtocol.cpp.

References folly::IOBufQueue::append(), fizz::bad_record_mac, folly::IOBufQueue::cacheChainLength(), folly::IOBufQueue::chainLength(), fizz::server::CookieState::chloHash, fizz::server::CookieState::cipher, cookie, fizz::encodeHandshake(), fizz::CryptoUtils::equal(), fizz::ClientHello::extensions, fizz::External, fizz::ExternalPskBinder, fizz::getBinderLength(), fizz::server::getStatelessHelloRetryRequest(), fizz::server::CookieState::group, fizz::message_hash::hash, fizz::illegal_parameter, kPskIndex, fizz::Factory::makeHandshakeContext(), fizz::Factory::makeKeyScheduler(), folly::IOBufQueue::move(), folly::gen::move, fizz::HandshakeStruct< e, t >::originalEncoding, folly::range(), fizz::ResumptionPskBinder, fizz::server::ResumptionState::resumptionSecret, scheduler, folly::IOBufQueue::split(), and fizz::server::CookieState::version.

Referenced by getCertificateRequest().

544  {
545  auto scheduler = factory.makeKeyScheduler(cipher);
546 
547  if (cookieState) {
548  if (handshakeContext) {
549  throw FizzException(
550  "cookie after statefull hrr", AlertDescription::illegal_parameter);
551  }
552 
553  handshakeContext = factory.makeHandshakeContext(cipher);
554 
555  message_hash chloHash;
556  chloHash.hash = cookieState->chloHash->clone();
557  handshakeContext->appendToTranscript(encodeHandshake(std::move(chloHash)));
558 
559  auto cookie = getExtension<Cookie>(chlo.extensions);
560  handshakeContext->appendToTranscript(getStatelessHelloRetryRequest(
561  cookieState->version,
562  cookieState->cipher,
563  cookieState->group,
564  std::move(cookie->cookie)));
565  } else if (!handshakeContext) {
566  handshakeContext = factory.makeHandshakeContext(cipher);
567  }
568 
569  if (resState) {
570  scheduler->deriveEarlySecret(resState->resumptionSecret->coalesce());
571 
572  auto binderKey = scheduler->getSecret(
573  pskType == PskType::External ? EarlySecrets::ExternalPskBinder
574  : EarlySecrets::ResumptionPskBinder,
575  handshakeContext->getBlankContext());
576 
578  chloQueue.append((*chlo.originalEncoding)->clone());
579  auto chloPrefix =
580  chloQueue.split(chloQueue.chainLength() - getBinderLength(chlo));
581  handshakeContext->appendToTranscript(chloPrefix);
582 
583  const auto& psks = getExtension<ClientPresharedKey>(chlo.extensions);
584  if (!psks || psks->binders.size() <= kPskIndex) {
585  throw FizzException("no binders", AlertDescription::illegal_parameter);
586  }
587  auto expectedBinder =
588  handshakeContext->getFinishedData(folly::range(binderKey));
589  if (!CryptoUtils::equal(
590  expectedBinder->coalesce(),
591  psks->binders[kPskIndex].binder->coalesce())) {
592  throw FizzException(
593  "binder does not match", AlertDescription::bad_record_mac);
594  }
595 
596  handshakeContext->appendToTranscript(chloQueue.move());
597  return std::make_pair(std::move(scheduler), std::move(handshakeContext));
598  } else {
599  handshakeContext->appendToTranscript(*chlo.originalEncoding);
600  return std::make_pair(std::move(scheduler), std::move(handshakeContext));
601  }
602 }
Buf getStatelessHelloRetryRequest(ProtocolVersion version, CipherSuite cipher, folly::Optional< NamedGroup > group, Buf cookie)
Buf encodeHandshake(T &&handshakeMsg)
Definition: Types-inl.h:515
size_t getBinderLength(const ClientHello &chlo)
static const std::string chlo
StringPiece cookie
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::shared_ptr< folly::FunctionScheduler > scheduler
Definition: FilePoller.cpp:50
static constexpr uint16_t kPskIndex
CipherSuite cipher
static Options cacheChainLength()
Definition: IOBufQueue.h:83
constexpr Range< Iter > range(Iter first, Iter last)
Definition: Range.h:1114
ProtocolVersion version
Definition: CookieCipher.h:18
folly::Optional< NamedGroup > group
Definition: CookieCipher.h:20
static void fizz::sm::validateAcceptedEarly ( const State state,
const Optional< std::string > &  alpn 
)
static

Definition at line 1179 of file ClientProtocol.cpp.

References fizz::Accepted, fizz::client::detail::actions(), alpn, fizz::Attempted, fizz::client::State::attemptedPsk(), fizz::Protocol::checkAllowedExtensions(), fizz::client::State::cipher(), fizz::client::State::context(), fizz::client::State::earlyDataParams(), fizz::client::State::earlyDataType(), fizz::client::State::earlyWriteRecordLayer(), fizz::EncryptedExtensions, fizz::client::ExpectingEncryptedExtensions, fizz::client::State::extensions(), fizz::client::FizzClientContext::getSupportedAlpns(), fizz::client::State::handshakeContext(), fizz::illegal_parameter, folly::gen::move, folly::none, fizz::ClientExtensions::onEncryptedExtensions(), params, fizz::client::State::pskType(), fizz::Rejected, fizz::client::State::requestedExtensions(), and fizz::client::State::serverCert().

1181  {
1182  const auto& params = state.earlyDataParams();
1183 
1184  if (!state.attemptedPsk() || state.pskType() == PskType::Rejected ||
1185  !params) {
1186  throw FizzException(
1187  "early accepted without psk", AlertDescription::illegal_parameter);
1188  }
1189 
1190  if (params->cipher != state.cipher()) {
1191  throw FizzException(
1192  "early accepted with different cipher",
1193  AlertDescription::illegal_parameter);
1194  }
1195 
1196  if (params->alpn != alpn) {
1197  throw FizzException(
1198  "early accepted with different alpn",
1199  AlertDescription::illegal_parameter);
1200  }
1201 
1202  if (!state.earlyWriteRecordLayer()) {
1203  throw FizzException(
1204  "no early record layer", AlertDescription::illegal_parameter);
1205  }
1206 }
folly::Optional< CipherSuite > cipher() const
Definition: State.h:113
constexpr Params params[]
const folly::Optional< EarlyDataParams > & earlyDataParams() const
Definition: State.h:163
folly::Optional< PskType > pskType() const
Definition: State.h:135
const WriteRecordLayer * earlyWriteRecordLayer() const
Definition: State.h:254
const folly::Optional< CachedPsk > & attemptedPsk() const
Definition: State.h:336
static void fizz::sm::validateClientHello ( const ClientHello chlo)
static

Definition at line 370 of file ServerProtocol.cpp.

References fizz::Protocol::checkDuplicateExtensions(), fizz::ClientHello::extensions, fizz::illegal_parameter, and fizz::ClientHello::legacy_compression_methods.

Referenced by getCertificateRequest().

370  {
371  if (chlo.legacy_compression_methods.size() != 1 ||
372  chlo.legacy_compression_methods.front() != 0x00) {
373  throw FizzException(
374  "client compression methods not exactly NULL",
375  AlertDescription::illegal_parameter);
376  }
377  Protocol::checkDuplicateExtensions(chlo.extensions);
378 }
static const std::string chlo
static void fizz::sm::validateGroups ( const std::vector< KeyShareEntry > &  client_shares)
static

Definition at line 604 of file ServerProtocol.cpp.

References fizz::illegal_parameter, and folly::pushmi::operators::share.

Referenced by negotiateGroup().

604  {
605  std::set<NamedGroup> setOfNamedGroups;
606 
607  for (const auto& share : client_shares) {
608  if (setOfNamedGroups.find(share.group) != setOfNamedGroups.end()) {
609  throw FizzException(
610  "duplicate client key share", AlertDescription::illegal_parameter);
611  }
612 
613  setOfNamedGroups.insert(share.group);
614  }
615 }
PUSHMI_INLINE_VAR constexpr detail::share_fn< TN... > share
Definition: share.h:53
static void fizz::sm::validateNegotiationConsistency ( const State state,
ProtocolVersion  version,
CipherSuite  cipher 
)
static

Definition at line 761 of file ClientProtocol.cpp.

References fizz::client::State::cipher(), cipher, fizz::handshake_failure, fizz::client::State::version(), and version.

Referenced by negotiatePsk().

764  {
765  if (state.version() && *state.version() != version) {
766  throw FizzException(
767  "version does not match", AlertDescription::handshake_failure);
768  }
769  if (state.cipher() && *state.cipher() != cipher) {
770  throw FizzException(
771  "cipher does not match", AlertDescription::handshake_failure);
772  }
773 }
folly::Optional< ProtocolVersion > version() const
Definition: State.h:106
CipherSuite cipher
folly::Optional< CipherSuite > cipher() const
Definition: State.h:113
ProtocolVersion version
static folly::Optional<CachedPsk> fizz::sm::validatePsk ( const FizzClientContext context,
folly::Optional< CachedPsk psk 
)
static

Definition at line 290 of file ClientProtocol.cpp.

References fizz::client::CachedPsk::cipher, fizz::client::FizzClientContext::getSupportedCiphers(), fizz::client::FizzClientContext::getSupportedVersions(), folly::none, now(), fizz::client::CachedPsk::ticketExpirationTime, fizz::toString(), and fizz::client::CachedPsk::version.

Referenced by getEarlyDataParams().

292  {
293  if (!psk) {
294  return folly::none;
295  }
296 
298  VLOG(1) << "Ignoring expired cached psk";
299  return folly::none;
300  }
301 
302  if (std::find(
303  context.getSupportedVersions().begin(),
304  context.getSupportedVersions().end(),
305  psk->version) == context.getSupportedVersions().end()) {
306  VLOG(1) << "Ignoring cached psk with protocol version "
307  << toString(psk->version);
308  return folly::none;
309  }
310  if (std::find(
311  context.getSupportedCiphers().begin(),
312  context.getSupportedCiphers().end(),
313  psk->cipher) == context.getSupportedCiphers().end()) {
314  VLOG(1) << "Ignoring cached psk with cipher " << toString(psk->cipher);
315  return folly::none;
316  }
317 
318  return psk;
319 }
folly::StringPiece toString(StateEnum state)
Definition: State.cpp:16
const auto & getSupportedVersions() const
std::chrono::steady_clock::time_point now()
ProtocolVersion version
Definition: PskCache.h:25
const auto & getSupportedCiphers() const
CipherSuite cipher
Definition: PskCache.h:26
std::chrono::system_clock::time_point ticketExpirationTime
Definition: PskCache.h:36
constexpr None none
Definition: Optional.h:87
static bool fizz::sm::validateResumptionState ( const ResumptionState resState,
PskKeyExchangeMode  ,
ProtocolVersion  version,
CipherSuite  cipher 
)
static

Definition at line 496 of file ServerProtocol.cpp.

References fizz::server::ResumptionState::cipher, fizz::getHashFunction(), and fizz::server::ResumptionState::version.

Referenced by getCertificateRequest().

500  {
501  if (resState.version != version) {
502  VLOG(8) << "Protocol version mismatch, rejecting PSK.";
503  return false;
504  }
505 
506  if (getHashFunction(resState.cipher) != getHashFunction(cipher)) {
507  VLOG(8) << "Hash mismatch, rejecting PSK.";
508  return false;
509  }
510 
511  return true;
512 }
CipherSuite cipher
HashFunction getHashFunction(CipherSuite cipher)
Definition: Types.cpp:13
ProtocolVersion version
static WriteToSocket fizz::sm::writeNewSessionTicket ( const FizzServerContext context,
const WriteRecordLayer recordLayer,
std::chrono::seconds  ticketLifetime,
uint32_t  ticketAgeAdd,
Buf  nonce,
Buf  ticket,
ProtocolVersion  version 
)
static

Definition at line 1614 of file ServerProtocol.cpp.

References fizz::WriteToSocket::contents, fizz::encodeExtension(), fizz::encodeHandshake(), fizz::NewSessionTicket::extensions, fizz::server::FizzServerContext::getAcceptEarlyData(), fizz::server::FizzServerContext::getMaxEarlyDataSize(), fizz::TicketEarlyData::max_early_data_size, folly::gen::move, nst, fizz::NewSessionTicket::ticket, fizz::NewSessionTicket::ticket_age_add, fizz::NewSessionTicket::ticket_lifetime, fizz::NewSessionTicket::ticket_nonce, and fizz::WriteRecordLayer::writeHandshake().

Referenced by generateTicket().

1621  {
1623  nst.ticket_lifetime = ticketLifetime.count();
1624  nst.ticket_age_add = ticketAgeAdd;
1625  nst.ticket_nonce = std::move(nonce);
1626  nst.ticket = std::move(ticket);
1627 
1628  if (context.getAcceptEarlyData(version)) {
1629  TicketEarlyData early;
1630  early.max_early_data_size = context.getMaxEarlyDataSize();
1631  nst.extensions.push_back(encodeExtension(std::move(early)));
1632  }
1633 
1634  auto encodedNst = encodeHandshake(std::move(nst));
1635  WriteToSocket nstWrite;
1636  nstWrite.contents.emplace_back(
1637  recordLayer.writeHandshake(std::move(encodedNst)));
1638  return nstWrite;
1639 }
Buf encodeHandshake(T &&handshakeMsg)
Definition: Types-inl.h:515
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static constexpr StringPiece ticket
ProtocolVersion version
bool getAcceptEarlyData(ProtocolVersion version) const
static const std::string nst
Extension encodeExtension(const TokenBindingParameters &params)
Definition: Types.cpp:113