in fizz/client/ClientProtocol.cpp [1053:1104]
static NegotiatedPsk negotiatePsk(
const std::vector<PskKeyExchangeMode>& supportedPskModes,
const folly::Optional<CachedPsk>& attemptedPsk,
const ServerHello& shlo,
ProtocolVersion version,
CipherSuite cipher,
bool hasExchange) {
auto serverPsk = getExtension<ServerPresharedKey>(shlo.extensions);
if (!attemptedPsk) {
if (serverPsk) {
throw FizzException(
"server accepted unattempted psk",
AlertDescription::illegal_parameter);
} else if (!supportedPskModes.empty()) {
return NegotiatedPsk(PskType::NotAttempted);
} else {
return NegotiatedPsk(PskType::NotSupported);
}
} else {
if (!serverPsk) {
return NegotiatedPsk(PskType::Rejected);
}
if (serverPsk->selected_identity != 0) {
throw FizzException(
"server accepted non-0 psk", AlertDescription::illegal_parameter);
}
if (version != attemptedPsk->version) {
throw FizzException(
"different version in psk", AlertDescription::handshake_failure);
}
if (getHashFunction(cipher) != getHashFunction(attemptedPsk->cipher)) {
throw FizzException(
"incompatible cipher in psk", AlertDescription::handshake_failure);
}
PskKeyExchangeMode mode = hasExchange ? PskKeyExchangeMode::psk_dhe_ke
: PskKeyExchangeMode::psk_ke;
if (std::find(supportedPskModes.begin(), supportedPskModes.end(), mode) ==
supportedPskModes.end()) {
throw FizzException(
"server choose unsupported psk mode",
AlertDescription::handshake_failure);
}
return NegotiatedPsk(
attemptedPsk->type,
mode,
attemptedPsk->serverCert,
attemptedPsk->clientCert);
}
}