static NegotiatedPsk negotiatePsk()

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);
  }
}