1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_H_ 6 #define QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_H_ 7 8 #include <memory> 9 #include <string> 10 #include <vector> 11 12 #include "absl/strings/string_view.h" 13 #include "openssl/ssl.h" 14 #include "quiche/quic/core/crypto/certificate_view.h" 15 #include "quiche/quic/core/crypto/quic_crypto_proof.h" 16 #include "quiche/quic/core/quic_versions.h" 17 #include "quiche/quic/platform/api/quic_export.h" 18 #include "quiche/quic/platform/api/quic_socket_address.h" 19 #include "quiche/common/platform/api/quiche_reference_counted.h" 20 21 namespace quic { 22 23 namespace test { 24 class FakeProofSourceHandle; 25 } // namespace test 26 27 // CryptoBuffers is a RAII class to own a std::vector<CRYPTO_BUFFER*> and the 28 // buffers the elements point to. 29 struct QUIC_EXPORT_PRIVATE CryptoBuffers { 30 CryptoBuffers() = default; 31 CryptoBuffers(const CryptoBuffers&) = delete; 32 CryptoBuffers(CryptoBuffers&&) = default; 33 ~CryptoBuffers(); 34 35 std::vector<CRYPTO_BUFFER*> value; 36 }; 37 38 // ProofSource is an interface by which a QUIC server can obtain certificate 39 // chains and signatures that prove its identity. 40 class QUIC_EXPORT_PRIVATE ProofSource { 41 public: 42 // Chain is a reference-counted wrapper for a vector of stringified 43 // certificates. 44 struct QUIC_EXPORT_PRIVATE Chain : public quiche::QuicheReferenceCounted { 45 explicit Chain(const std::vector<std::string>& certs); 46 Chain(const Chain&) = delete; 47 Chain& operator=(const Chain&) = delete; 48 49 CryptoBuffers ToCryptoBuffers() const; 50 51 const std::vector<std::string> certs; 52 53 protected: 54 ~Chain() override; 55 }; 56 57 // Details is an abstract class which acts as a container for any 58 // implementation-specific details that a ProofSource wants to return. 59 class QUIC_EXPORT_PRIVATE Details { 60 public: ~Details()61 virtual ~Details() {} 62 }; 63 64 // Callback base class for receiving the results of an async call to GetProof. 65 class QUIC_EXPORT_PRIVATE Callback { 66 public: Callback()67 Callback() {} ~Callback()68 virtual ~Callback() {} 69 70 // Invoked upon completion of GetProof. 71 // 72 // |ok| indicates whether the operation completed successfully. If false, 73 // the values of the remaining three arguments are undefined. 74 // 75 // |chain| is a reference-counted pointer to an object representing the 76 // certificate chain. 77 // 78 // |signature| contains the signature of the server config. 79 // 80 // |leaf_cert_sct| holds the signed timestamp (RFC6962) of the leaf cert. 81 // 82 // |details| holds a pointer to an object representing the statistics, if 83 // any, gathered during the operation of GetProof. If no stats are 84 // available, this will be nullptr. 85 virtual void Run(bool ok, 86 const quiche::QuicheReferenceCountedPointer<Chain>& chain, 87 const QuicCryptoProof& proof, 88 std::unique_ptr<Details> details) = 0; 89 90 private: 91 Callback(const Callback&) = delete; 92 Callback& operator=(const Callback&) = delete; 93 }; 94 95 // Base class for signalling the completion of a call to ComputeTlsSignature. 96 class QUIC_EXPORT_PRIVATE SignatureCallback { 97 public: SignatureCallback()98 SignatureCallback() {} 99 virtual ~SignatureCallback() = default; 100 101 // Invoked upon completion of ComputeTlsSignature. 102 // 103 // |ok| indicates whether the operation completed successfully. 104 // 105 // |signature| contains the signature of the data provided to 106 // ComputeTlsSignature. Its value is undefined if |ok| is false. 107 // 108 // |details| holds a pointer to an object representing the statistics, if 109 // any, gathered during the operation of ComputeTlsSignature. If no stats 110 // are available, this will be nullptr. 111 virtual void Run(bool ok, std::string signature, 112 std::unique_ptr<Details> details) = 0; 113 114 private: 115 SignatureCallback(const SignatureCallback&) = delete; 116 SignatureCallback& operator=(const SignatureCallback&) = delete; 117 }; 118 ~ProofSource()119 virtual ~ProofSource() {} 120 121 // OnNewSslCtx changes SSL parameters if required by ProofSource 122 // implementation. It is called when new SSL_CTX is created for a listener. 123 // Default implementation does nothing. 124 // 125 // This function may be called concurrently. 126 virtual void OnNewSslCtx(SSL_CTX* ssl_ctx); 127 128 // GetProof finds a certificate chain for |hostname| (in leaf-first order), 129 // and calculates a signature of |server_config| using that chain. 130 // 131 // The signature uses SHA-256 as the hash function and PSS padding when the 132 // key is RSA. 133 // 134 // The signature uses SHA-256 as the hash function when the key is ECDSA. 135 // The signature may use an ECDSA key. 136 // 137 // The signature depends on |chlo_hash| which means that the signature can not 138 // be cached. 139 // 140 // |hostname| may be empty to signify that a default certificate should be 141 // used. 142 // 143 // This function may be called concurrently. 144 // 145 // Callers should expect that |callback| might be invoked synchronously. 146 virtual void GetProof(const QuicSocketAddress& server_address, 147 const QuicSocketAddress& client_address, 148 const std::string& hostname, 149 const std::string& server_config, 150 QuicTransportVersion transport_version, 151 absl::string_view chlo_hash, 152 std::unique_ptr<Callback> callback) = 0; 153 154 // Returns the certificate chain for |hostname| in leaf-first order. 155 // 156 // Sets *cert_matched_sni to true if the certificate matched the given 157 // hostname, false if a default cert not matching the hostname was used. 158 virtual quiche::QuicheReferenceCountedPointer<Chain> GetCertChain( 159 const QuicSocketAddress& server_address, 160 const QuicSocketAddress& client_address, const std::string& hostname, 161 bool* cert_matched_sni) = 0; 162 163 // Computes a signature using the private key of the certificate for 164 // |hostname|. The value in |in| is signed using the algorithm specified by 165 // |signature_algorithm|, which is an |SSL_SIGN_*| value (as defined in TLS 166 // 1.3). Implementations can only assume that |in| is valid during the call to 167 // ComputeTlsSignature - an implementation computing signatures asynchronously 168 // must copy it if the value to be signed is used outside of this function. 169 // 170 // Callers should expect that |callback| might be invoked synchronously. 171 virtual void ComputeTlsSignature( 172 const QuicSocketAddress& server_address, 173 const QuicSocketAddress& client_address, const std::string& hostname, 174 uint16_t signature_algorithm, absl::string_view in, 175 std::unique_ptr<SignatureCallback> callback) = 0; 176 177 // Return the list of TLS signature algorithms that is acceptable by the 178 // ComputeTlsSignature method. If the entire BoringSSL's default list of 179 // supported signature algorithms are acceptable, return an empty list. 180 // 181 // If returns a non-empty list, ComputeTlsSignature will only be called with a 182 // algorithm in the list. 183 virtual QuicSignatureAlgorithmVector SupportedTlsSignatureAlgorithms() 184 const = 0; 185 186 class QUIC_EXPORT_PRIVATE DecryptCallback { 187 public: 188 DecryptCallback() = default; 189 virtual ~DecryptCallback() = default; 190 191 virtual void Run(std::vector<uint8_t> plaintext) = 0; 192 193 private: 194 DecryptCallback(const Callback&) = delete; 195 DecryptCallback& operator=(const Callback&) = delete; 196 }; 197 198 // TicketCrypter is an interface for managing encryption and decryption of TLS 199 // session tickets. A TicketCrypter gets used as an 200 // SSL_CTX_set_ticket_aead_method in BoringSSL, which has a synchronous 201 // Encrypt/Seal operation and a potentially asynchronous Decrypt/Open 202 // operation. This interface allows for ticket decryptions to be performed on 203 // a remote service. 204 class QUIC_EXPORT_PRIVATE TicketCrypter { 205 public: 206 TicketCrypter() = default; 207 virtual ~TicketCrypter() = default; 208 209 // MaxOverhead returns the maximum number of bytes of overhead that may get 210 // added when encrypting the ticket. 211 virtual size_t MaxOverhead() = 0; 212 213 // Encrypt takes a serialized TLS session ticket in |in|, encrypts it, and 214 // returns the encrypted ticket. The resulting value must not be larger than 215 // MaxOverhead bytes larger than |in|. If encryption fails, this method 216 // returns an empty vector. 217 // 218 // If |encryption_key| is nonempty, this method should use it for minting 219 // TLS resumption tickets. If it is empty, this method may use an 220 // internally cached encryption key, if available. 221 virtual std::vector<uint8_t> Encrypt(absl::string_view in, 222 absl::string_view encryption_key) = 0; 223 224 // Decrypt takes an encrypted ticket |in|, decrypts it, and calls 225 // |callback->Run| with the decrypted ticket, which must not be larger than 226 // |in|. If decryption fails, the callback is invoked with an empty 227 // vector. 228 virtual void Decrypt(absl::string_view in, 229 std::shared_ptr<DecryptCallback> callback) = 0; 230 }; 231 232 // Returns the TicketCrypter used for encrypting and decrypting TLS 233 // session tickets, or nullptr if that functionality is not supported. The 234 // TicketCrypter returned (if not nullptr) must be valid for the lifetime of 235 // the ProofSource, and the caller does not take ownership of said 236 // TicketCrypter. 237 virtual TicketCrypter* GetTicketCrypter() = 0; 238 }; 239 240 // ProofSourceHandleCallback is an interface that contains the callbacks when 241 // the operations in ProofSourceHandle completes. 242 // TODO(wub): Consider deprecating ProofSource by moving all functionalities of 243 // ProofSource into ProofSourceHandle. 244 class QUIC_EXPORT_PRIVATE ProofSourceHandleCallback { 245 public: 246 virtual ~ProofSourceHandleCallback() = default; 247 248 // Called when a ProofSourceHandle::SelectCertificate operation completes. 249 // |ok| indicates whether the operation was successful. 250 // |is_sync| indicates whether the operation completed synchronously, i.e. 251 // whether it is completed before ProofSourceHandle::SelectCertificate 252 // returned. 253 // |chain| the certificate chain in leaf-first order. 254 // |handshake_hints| (optional) handshake hints that can be used by 255 // SSL_set_handshake_hints. 256 // |ticket_encryption_key| (optional) encryption key to be used for minting 257 // TLS resumption tickets. 258 // |cert_matched_sni| is true if the certificate matched the SNI hostname, 259 // false if a non-matching default cert was used. 260 // |delayed_ssl_config| contains SSL configs to be applied on the SSL object. 261 // 262 // When called asynchronously(is_sync=false), this method will be responsible 263 // to continue the handshake from where it left off. 264 virtual void OnSelectCertificateDone( 265 bool ok, bool is_sync, const ProofSource::Chain* chain, 266 absl::string_view handshake_hints, 267 absl::string_view ticket_encryption_key, bool cert_matched_sni, 268 QuicDelayedSSLConfig delayed_ssl_config) = 0; 269 270 // Called when a ProofSourceHandle::ComputeSignature operation completes. 271 virtual void OnComputeSignatureDone( 272 bool ok, bool is_sync, std::string signature, 273 std::unique_ptr<ProofSource::Details> details) = 0; 274 275 // Return true iff ProofSourceHandle::ComputeSignature won't be called later. 276 // The handle can use this function to release resources promptly. 277 virtual bool WillNotCallComputeSignature() const = 0; 278 }; 279 280 // ProofSourceHandle is an interface by which a TlsServerHandshaker can obtain 281 // certificate chains and signatures that prove its identity. 282 // The operations this interface supports are similar to those in ProofSource, 283 // the main difference is that ProofSourceHandle is per-handshaker, so 284 // an implementation can have states that are shared by multiple calls on the 285 // same handle. 286 // 287 // A handle object is owned by a TlsServerHandshaker. Since there might be an 288 // async operation pending when the handle destructs, an implementation must 289 // ensure when such operations finish, their corresponding callback method won't 290 // be invoked. 291 // 292 // A handle will have at most one async operation pending at a time. 293 class QUIC_EXPORT_PRIVATE ProofSourceHandle { 294 public: 295 virtual ~ProofSourceHandle() = default; 296 297 // Close the handle. Cancel the pending operation, if any. 298 // Once called, any completion method on |callback()| won't be invoked, and 299 // future SelectCertificate and ComputeSignature calls should return failure. 300 virtual void CloseHandle() = 0; 301 302 // Starts a select certificate operation. If the operation is not cancelled 303 // when it completes, callback()->OnSelectCertificateDone will be invoked. 304 // 305 // server_address and client_address should be normalized by the caller before 306 // sending down to this function. 307 // 308 // If the operation is handled synchronously: 309 // - QUIC_SUCCESS or QUIC_FAILURE will be returned. 310 // - callback()->OnSelectCertificateDone should be invoked before the function 311 // returns. 312 // 313 // If the operation is handled asynchronously: 314 // - QUIC_PENDING will be returned. 315 // - When the operation is done, callback()->OnSelectCertificateDone should be 316 // invoked. 317 virtual QuicAsyncStatus SelectCertificate( 318 const QuicSocketAddress& server_address, 319 const QuicSocketAddress& client_address, 320 const QuicConnectionId& original_connection_id, 321 absl::string_view ssl_capabilities, const std::string& hostname, 322 absl::string_view client_hello, const std::string& alpn, 323 absl::optional<std::string> alps, 324 const std::vector<uint8_t>& quic_transport_params, 325 const absl::optional<std::vector<uint8_t>>& early_data_context, 326 const QuicSSLConfig& ssl_config) = 0; 327 328 // Starts a compute signature operation. If the operation is not cancelled 329 // when it completes, callback()->OnComputeSignatureDone will be invoked. 330 // 331 // See the comments of SelectCertificate for sync vs. async operations. 332 virtual QuicAsyncStatus ComputeSignature( 333 const QuicSocketAddress& server_address, 334 const QuicSocketAddress& client_address, const std::string& hostname, 335 uint16_t signature_algorithm, absl::string_view in, 336 size_t max_signature_size) = 0; 337 338 protected: 339 // Returns the object that will be notified when an operation completes. 340 virtual ProofSourceHandleCallback* callback() = 0; 341 342 private: 343 friend class test::FakeProofSourceHandle; 344 }; 345 346 // Returns true if |chain| contains a parsable DER-encoded X.509 leaf cert and 347 // it matches with |key|. 348 QUIC_EXPORT_PRIVATE bool ValidateCertAndKey( 349 const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain, 350 const CertificatePrivateKey& key); 351 352 } // namespace quic 353 354 #endif // QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_H_ 355