Teach QUIC about the concept of "fallback" key exchange

In the Leto world, GFE's QUIC stack will be configured with a bunch of ServerConfigs whose private keys live remotely, on the Leto server.  Each GFE will also generate a ServerConfig with a local keypair, to which it will fall back in a Leto outage.

The QUIC stack will need to be able to distinguish the fallback ServerConfig from the others.  This CL takes a step in that direction, by adding an 'is_fallback' argument to KeyExchangeSource::Create, which instructs it not to create a Leto-aware KeyExchange, but a local one.

For non-Leto-configured GFEs, this argument is simply ignored, since all KeyExchanges will already be local.

This CL also modifies the LetoKeyExchange infrastructure to behave reasonably if the private key passed to KeyExchangeSource::Create is empty (i.e. the private key lives remotely on Leto and is not mirrored on the GFE).

This CL is not flag-protected.  The changes are all no-ops in the GFE for the following reasons:
- The is_fallback argument is currently set to false everywhere in the GFE.
- The private_key argument is always set in the GFE.

Subsequent CLs will change these arguments, and *those* will be flag-protected.

gfe-relnote: Adding codepaths not yet reachable in the GFE.  Not flag-protected.
PiperOrigin-RevId: 239603863
Change-Id: I34fc2311559db2221a26c83d8c6dfa05954b5fd5
diff --git a/quic/core/crypto/quic_crypto_server_config.cc b/quic/core/crypto/quic_crypto_server_config.cc
index 4c77e21..daa8d07 100644
--- a/quic/core/crypto/quic_crypto_server_config.cc
+++ b/quic/core/crypto/quic_crypto_server_config.cc
@@ -76,6 +76,7 @@
 
   std::unique_ptr<AsynchronousKeyExchange> Create(
       std::string server_config_id,
+      bool /* is_fallback */,
       QuicTag type,
       QuicStringPiece private_key) override {
     if (private_key.empty()) {
@@ -1577,8 +1578,8 @@
       }
     }
 
-    std::unique_ptr<AsynchronousKeyExchange> ka =
-        key_exchange_source_->Create(config->id, tag, private_key);
+    std::unique_ptr<AsynchronousKeyExchange> ka = key_exchange_source_->Create(
+        config->id, /* is_fallback = */ false, tag, private_key);
     if (!ka) {
       return nullptr;
     }
diff --git a/quic/core/crypto/quic_crypto_server_config.h b/quic/core/crypto/quic_crypto_server_config.h
index 0304bf3..2ba028e 100644
--- a/quic/core/crypto/quic_crypto_server_config.h
+++ b/quic/core/crypto/quic_crypto_server_config.h
@@ -160,10 +160,14 @@
   // Returns the default KeyExchangeSource.
   static std::unique_ptr<KeyExchangeSource> Default();
 
-  // Create a new KeyExchange of the specified type using the specified
-  // private key.
+  // Create a new KeyExchange using the curve specified by |type| using the
+  // specified private key.  |private_key| may be empty for key-exchange
+  // mechanisms which do not hold the private key in-process.  If |is_fallback|
+  // is set, |private_key| is required to be set, and a local key-exchange
+  // object should be returned.
   virtual std::unique_ptr<AsynchronousKeyExchange> Create(
       std::string server_config_id,
+      bool is_fallback,
       QuicTag type,
       QuicStringPiece private_key) = 0;
 };