in fizz/server/ServerProtocol.cpp [823:891]
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) {
if (!getExtension<ClientEarlyData>(chlo.extensions)) {
return EarlyDataType::NotAttempted;
}
if (!acceptEarlyData) {
VLOG(5) << "Rejecting early data: disabled";
return EarlyDataType::Rejected;
}
if (!psk) {
VLOG(5) << "Rejected early data: psk rejected";
return EarlyDataType::Rejected;
}
if (psk->cipher != cipher) {
VLOG(5) << "Rejected early data: cipher mismatch";
return EarlyDataType::Rejected;
}
if (psk->alpn != alpn) {
VLOG(5) << "Rejecting early data: alpn mismatch";
return EarlyDataType::Rejected;
}
if (keyExchangeType &&
*keyExchangeType == KeyExchangeType::HelloRetryRequest) {
VLOG(5) << "Rejecting early data: HelloRetryRequest";
return EarlyDataType::Rejected;
}
if (cookieState) {
VLOG(5) << "Rejecting early data: Cookie";
return EarlyDataType::Rejected;
}
if (replayCacheResult != ReplayCacheResult::NotReplay) {
VLOG(5) << "Rejecting early data: replay";
return EarlyDataType::Rejected;
}
if (!clockSkew || *clockSkew < clockSkewTolerance.before ||
*clockSkew > clockSkewTolerance.after) {
VLOG(5) << "Rejecting early data: clock skew clockSkew="
<< (clockSkew ? folly::to<std::string>(clockSkew->count())
: "(none)")
<< " toleranceBefore=" << clockSkewTolerance.before.count()
<< " toleranceAfter=" << clockSkewTolerance.after.count();
return EarlyDataType::Rejected;
}
if (appTokenValidator && !appTokenValidator->validate(*psk)) {
VLOG(5) << "Rejecting early data: invalid app token";
return EarlyDataType::Rejected;
}
return EarlyDataType::Accepted;
}