text: // Copyright (c) 2017 The Chromium Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  #ifndef QUICHE_QUIC_CORE_TLS_SERVER_HANDSHAKER_H_
  #define QUICHE_QUIC_CORE_TLS_SERVER_HANDSHAKER_H_
  
  #include <string>
  
  #include "absl/strings/string_view.h"
  #include "third_party/boringssl/src/include/openssl/pool.h"
  #include "third_party/boringssl/src/include/openssl/ssl.h"
  #include "quic/core/crypto/quic_crypto_server_config.h"
  #include "quic/core/crypto/tls_server_connection.h"
  #include "quic/core/proto/cached_network_parameters_proto.h"
  #include "quic/core/quic_crypto_server_stream_base.h"
  #include "quic/core/quic_crypto_stream.h"
  #include "quic/core/quic_time_accumulator.h"
  #include "quic/core/quic_types.h"
  #include "quic/core/tls_handshaker.h"
  #include "quic/platform/api/quic_export.h"
  #include "quic/platform/api/quic_flag_utils.h"
  #include "quic/platform/api/quic_flags.h"
  
  namespace quic {
  
  // An implementation of QuicCryptoServerStreamBase which uses
  // TLS 1.3 for the crypto handshake protocol.
  class QUIC_EXPORT_PRIVATE TlsServerHandshaker
      : public TlsHandshaker,
        public TlsServerConnection::Delegate,
        public ProofSourceHandleCallback,
        public QuicCryptoServerStreamBase {
   public:
    // |crypto_config| must outlive TlsServerHandshaker.
    TlsServerHandshaker(QuicSession* session,
                        const QuicCryptoServerConfig* crypto_config);
    TlsServerHandshaker(const TlsServerHandshaker&) = delete;
    TlsServerHandshaker& operator=(const TlsServerHandshaker&) = delete;
  
    ~TlsServerHandshaker() override;
  
    // From QuicCryptoServerStreamBase
    void CancelOutstandingCallbacks() override;
    bool GetBase64SHA256ClientChannelID(std::string* output) const override;
    void SendServerConfigUpdate(
        const CachedNetworkParameters* cached_network_params) override;
    bool IsZeroRtt() const override;
    bool IsResumption() const override;
    bool ResumptionAttempted() const override;
    int NumServerConfigUpdateMessagesSent() const override;
    const CachedNetworkParameters* PreviousCachedNetworkParams() const override;
    void SetPreviousCachedNetworkParams(
        CachedNetworkParameters cached_network_params) override;
    void OnPacketDecrypted(EncryptionLevel level) override;
    void OnOneRttPacketAcknowledged() override {}
    void OnHandshakePacketSent() override {}
    void OnConnectionClosed(QuicErrorCode error,
                            ConnectionCloseSource source) override;
    void OnHandshakeDoneReceived() override;
    std::string GetAddressToken() const override;
    bool ValidateAddressToken(absl::string_view token) const override;
    void OnNewTokenReceived(absl::string_view token) override;
    bool ShouldSendExpectCTHeader() const override;
    const ProofSource::Details* ProofSourceDetails() const override;
  
    // From QuicCryptoServerStreamBase and TlsHandshaker
    ssl_early_data_reason_t EarlyDataReason() const override;
    bool encryption_established() const override;
    bool one_rtt_keys_available() const override;
    const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
        const override;
    CryptoMessageParser* crypto_message_parser() override;
    HandshakeState GetHandshakeState() const override;
    void SetServerApplicationStateForResumption(
        std::unique_ptr<ApplicationState> state) override;
    size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
    bool KeyUpdateSupportedLocally() const override;
    std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
        override;
    std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
    void SetWriteSecret(EncryptionLevel level,
                        const SSL_CIPHER* cipher,
                        const std::vector<uint8_t>& write_secret) override;
  
    // Called with normalized SNI hostname as |hostname|.  Return value will be
    // sent in an ACCEPT_CH frame in the TLS ALPS extension, unless empty.
    virtual std::string GetAcceptChValueForHostname(
        const std::string& hostname) const;
  
   protected:
    // Override for tracing.
    void InfoCallback(int type, int value) override;
  
    // Creates a proof source handle for selecting cert and computing signature.
    virtual std::unique_ptr<ProofSourceHandle> MaybeCreateProofSourceHandle();
  
    // Hook to allow the server to override parts of the QuicConfig based on SNI
    // before we generate transport parameters.
    virtual void OverrideQuicConfigDefaults(QuicConfig* config);
  
    virtual bool ValidateHostname(const std::string& hostname) const;
  
    const TlsConnection* tls_connection() const override {
      return &tls_connection_;
    }
  
    virtual void ProcessAdditionalTransportParameters(
        const TransportParameters& /*params*/) {}
  
    // Called when a potentially async operation is done and the done callback
    // needs to advance the handshake.
    void AdvanceHandshakeFromCallback();
  
    // TlsHandshaker implementation:
    void FinishHandshake() override;
    void ProcessPostHandshakeMessage() override {}
    QuicAsyncStatus VerifyCertChain(
        const std::vector<std::string>& certs,
        std::string* error_details,
        std::unique_ptr<ProofVerifyDetails>* details,
        uint8_t* out_alert,
        std::unique_ptr<ProofVerifierCallback> callback) override;
    void OnProofVerifyDetailsAvailable(
        const ProofVerifyDetails& verify_details) override;
  
    // TlsServerConnection::Delegate implementation:
    // Used to select certificates and process transport parameters.
    ssl_select_cert_result_t EarlySelectCertCallback(
        const SSL_CLIENT_HELLO* client_hello) override;
    int TlsExtServernameCallback(int* out_alert) override;
    int SelectAlpn(const uint8_t** out,
                   uint8_t* out_len,
                   const uint8_t* in,
                   unsigned in_len) override;
    ssl_private_key_result_t PrivateKeySign(uint8_t* out,
                                            size_t* out_len,
                                            size_t max_out,
                                            uint16_t sig_alg,
                                            absl::string_view in) override;
    ssl_private_key_result_t PrivateKeyComplete(uint8_t* out,
                                                size_t* out_len,
                                                size_t max_out) override;
    size_t SessionTicketMaxOverhead() override;
    int SessionTicketSeal(uint8_t* out,
                          size_t* out_len,
                          size_t max_out_len,
                          absl::string_view in) override;
    ssl_ticket_aead_result_t SessionTicketOpen(uint8_t* out,
                                               size_t* out_len,
                                               size_t max_out_len,
                                               absl::string_view in) override;
    // Called when ticket_decryption_callback_ is done to determine a final
    // decryption result.
    ssl_ticket_aead_result_t FinalizeSessionTicketOpen(uint8_t* out,
                                                       size_t* out_len,
                                                       size_t max_out_len);
    TlsConnection::Delegate* ConnectionDelegate() override { return this; }
  
    // The status of cert selection. nullopt means it hasn't started.
    const absl::optional<QuicAsyncStatus>& select_cert_status() const {
      return select_cert_status_;
    }
    // Whether |cert_verify_sig_| contains a valid signature.
    // NOTE: BoringSSL queries the result of a async signature operation using
    // PrivateKeyComplete(), a successful PrivateKeyComplete() will clear the
    // content of |cert_verify_sig_|, this function should not be called after
    // that.
    bool HasValidSignature(size_t max_signature_size) const;
  
    // ProofSourceHandleCallback implementation:
    void OnSelectCertificateDone(
        bool ok, bool is_sync, const ProofSource::Chain* chain,
        absl::string_view handshake_hints,
        absl::string_view ticket_encryption_key) override;
  
    void OnComputeSignatureDone(
        bool ok,
        bool is_sync,
        std::string signature,
        std::unique_ptr<ProofSource::Details> details) override;
  
    void set_encryption_established(bool encryption_established) {
      encryption_established_ = encryption_established;
    }
  
    bool WillNotCallComputeSignature() const override;
  
    void SetIgnoreTicketOpen(bool value) { ignore_ticket_open_ = value; }
  
   private:
    class QUIC_EXPORT_PRIVATE DecryptCallback
        : public ProofSource::DecryptCallback {
     public:
      explicit DecryptCallback(TlsServerHandshaker* handshaker);
      void Run(std::vector<uint8_t> plaintext) override;
  
      // If called, Cancel causes the pending callback to be a no-op.
      void Cancel();
  
     private:
      TlsServerHandshaker* handshaker_;
    };
  
    // DefaultProofSourceHandle delegates all operations to the shared proof
    // source.
    class QUIC_EXPORT_PRIVATE DefaultProofSourceHandle
        : public ProofSourceHandle {
     public:
      DefaultProofSourceHandle(TlsServerHandshaker* handshaker,
                               ProofSource* proof_source);
  
      ~DefaultProofSourceHandle() override;
  
      // Close the handle. Cancel the pending signature operation, if any.
      void CloseHandle() override;
  
      // Delegates to proof_source_->GetCertChain.
      // Returns QUIC_SUCCESS or QUIC_FAILURE. Never returns QUIC_PENDING.
      QuicAsyncStatus SelectCertificate(
          const QuicSocketAddress& server_address,
          const QuicSocketAddress& client_address,
          absl::string_view ssl_capabilities,
          const std::string& hostname,
          absl::string_view client_hello,
          const std::string& alpn,
          absl::optional<std::string> alps,
          const std::vector<uint8_t>& quic_transport_params,
          const absl::optional<std::vector<uint8_t>>& early_data_context,
          const QuicSSLConfig& ssl_config) override;
  
      // Delegates to proof_source_->ComputeTlsSignature.
      // Returns QUIC_SUCCESS, QUIC_FAILURE or QUIC_PENDING.
      QuicAsyncStatus ComputeSignature(const QuicSocketAddress& server_address,
                                       const QuicSocketAddress& client_address,
                                       const std::string& hostname,
                                       uint16_t signature_algorithm,
                                       absl::string_view in,
                                       size_t max_signature_size) override;
  
     protected:
      ProofSourceHandleCallback* callback() override { return handshaker_; }
  
     private:
      class QUIC_EXPORT_PRIVATE DefaultSignatureCallback
          : public ProofSource::SignatureCallback {
       public:
        explicit DefaultSignatureCallback(DefaultProofSourceHandle* handle)
            : handle_(handle) {}
  
        void Run(bool ok,
                 std::string signature,
                 std::unique_ptr<ProofSource::Details> details) override {
          if (handle_ == nullptr) {
            // Operation has been canceled, or Run has been called.
            return;
          }
  
          DefaultProofSourceHandle* handle = handle_;
          handle_ = nullptr;
  
          handle->signature_callback_ = nullptr;
          if (handle->handshaker_ != nullptr) {
            handle->handshaker_->OnComputeSignatureDone(
                ok, is_sync_, std::move(signature), std::move(details));
          }
        }
  
        // If called, Cancel causes the pending callback to be a no-op.
        void Cancel() { handle_ = nullptr; }
  
        void set_is_sync(bool is_sync) { is_sync_ = is_sync; }
  
       private:
        DefaultProofSourceHandle* handle_;
        // Set to false if handle_->ComputeSignature returns QUIC_PENDING.
        bool is_sync_ = true;
      };
  
      // Not nullptr on construction. Set to nullptr when cancelled.
      TlsServerHandshaker* handshaker_;  // Not owned.
      ProofSource* proof_source_;        // Not owned.
      DefaultSignatureCallback* signature_callback_ = nullptr;
    };
  
    struct QUIC_NO_EXPORT SetTransportParametersResult {
      bool success = false;
      // Empty vector if QUIC transport params are not set successfully.
      std::vector<uint8_t> quic_transport_params;
      // absl::nullopt if there is no application state to begin with.
      // Empty vector if application state is not set successfully.
      absl::optional<std::vector<uint8_t>> early_data_context;
    };
  
    SetTransportParametersResult SetTransportParameters();
    bool ProcessTransportParameters(const SSL_CLIENT_HELLO* client_hello,
                                    std::string* error_details);
  
    struct QUIC_NO_EXPORT SetApplicationSettingsResult {
      bool success = false;
      std::unique_ptr<char[]> alps_buffer;
      size_t alps_length = 0;
    };
    SetApplicationSettingsResult SetApplicationSettings(absl::string_view alpn);
  
    QuicConnectionStats& connection_stats() {
      return session()->connection()->mutable_stats();
    }
    QuicTime now() const { return session()->GetClock()->Now(); }
  
    std::unique_ptr<ProofSourceHandle> proof_source_handle_;
    ProofSource* proof_source_;
  
    // State to handle potentially asynchronous session ticket decryption.
    // |ticket_decryption_callback_| points to the non-owned callback that was
    // passed to ProofSource::TicketCrypter::Decrypt but hasn't finished running
    // yet.
    DecryptCallback* ticket_decryption_callback_ = nullptr;
    // |decrypted_session_ticket_| contains the decrypted session ticket after the
    // callback has run but before it is passed to BoringSSL.
    std::vector<uint8_t> decrypted_session_ticket_;
    // |ticket_received_| tracks whether we received a resumption ticket from the
    // client. It does not matter whether we were able to decrypt said ticket or
    // if we actually resumed a session with it - the presence of this ticket
    // indicates that the client attempted a resumption.
    bool ticket_received_ = false;
  
    // Force SessionTicketOpen to return ssl_ticket_aead_ignore_ticket if called.
    bool ignore_ticket_open_ = false;
  
    // nullopt means select cert hasn't started.
    absl::optional<QuicAsyncStatus> select_cert_status_;
  
    std::string cert_verify_sig_;
    std::unique_ptr<ProofSource::Details> proof_source_details_;
  
    // Count the duration of the current async operation, if any.
    absl::optional<QuicTimeAccumulator> async_op_timer_;
  
    std::unique_ptr<ApplicationState> application_state_;
  
    // Pre-shared key used during the handshake.
    std::string pre_shared_key_;
  
    // (optional) Key to use for encrypting TLS resumption tickets.
    std::string ticket_encryption_key_;
  
    HandshakeState state_ = HANDSHAKE_START;
    bool encryption_established_ = false;
    bool valid_alpn_received_ = false;
    QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters>
        crypto_negotiated_params_;
    TlsServerConnection tls_connection_;
    const QuicCryptoServerConfig* crypto_config_;  // Unowned.
  };
  
  }  // namespace quic
  
  #endif  // QUICHE_QUIC_CORE_TLS_SERVER_HANDSHAKER_H_
  