static MutateState handleCertMsg()

in fizz/client/ClientProtocol.cpp [1657:1715]


static MutateState handleCertMsg(
    const State& state,
    CertificateMsg certMsg,
    folly::Optional<CertificateCompressionAlgorithm> algo) {
  if (!certMsg.certificate_request_context->empty()) {
    throw FizzException(
        "certificate request context must be empty",
        AlertDescription::illegal_parameter);
  }

  std::vector<std::shared_ptr<const PeerCert>> serverCerts;
  bool leaf = true;
  for (auto& certEntry : certMsg.certificate_list) {
    if (state.extensions()) {
      // Check that these extensions correspond to ones we requested.
      auto sentExtensions = state.extensions()->getClientHelloExtensions();
      for (auto& ext : certEntry.extensions) {
        auto extIt = std::find_if(
            sentExtensions.begin(),
            sentExtensions.end(),
            [type = ext.extension_type](const Extension& sentExt) {
              return sentExt.extension_type == type;
            });
        if (extIt == sentExtensions.end()) {
          throw FizzException(
              "unrequested certificate extension:" +
                  toString(ext.extension_type),
              AlertDescription::illegal_parameter);
        }
      }
    } else {
      if (!certEntry.extensions.empty()) {
        throw FizzException(
            "certificate extensions must be empty",
            AlertDescription::illegal_parameter);
      }
    }

    serverCerts.emplace_back(state.context()->getFactory()->makePeerCert(
        std::move(certEntry), leaf));
    leaf = false;
  }

  if (serverCerts.empty()) {
    throw FizzException(
        "no certificates received", AlertDescription::illegal_parameter);
  }

  ClientAuthType authType =
      state.clientAuthRequested().value_or(ClientAuthType::NotRequested);

  return [unverifiedCertChain = std::move(serverCerts),
          authType,
          compAlgo = std::move(algo)](State& newState) mutable {
    newState.unverifiedCertChain() = std::move(unverifiedCertChain);
    newState.clientAuthRequested() = authType;
    newState.serverCertCompAlgo() = std::move(compAlgo);
  };
}