| // Copyright 2019 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_CERTIFICATE_PROVIDER_TEST_CERTIFICATE_PROVIDER_EXTENSION_H_ |
| #define CHROME_BROWSER_CERTIFICATE_PROVIDER_TEST_CERTIFICATE_PROVIDER_EXTENSION_H_ |
| |
| #include <memory> |
| #include <string> |
| |
| #include "base/functional/callback.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "base/values.h" |
| #include "extensions/common/extension_id.h" |
| #include "extensions/test/extension_test_message_listener.h" |
| #include "net/cert/x509_certificate.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| #include "third_party/boringssl/src/include/openssl/base.h" |
| |
| namespace base { |
| class FilePath; |
| class Value; |
| } // namespace base |
| |
| namespace content { |
| class BrowserContext; |
| } |
| |
| namespace crypto { |
| class RSAPrivateKey; |
| } |
| |
| namespace ash { |
| |
| // This class provides the C++ side of the test certificate provider extension's |
| // implementation (the JavaScript side is in |
| // chrome/test/data/extensions/test_certificate_provider). |
| // |
| // It subscribes itself for requests from the JavaScript side of the extension, |
| // and implements the cryptographic operations using the "client_1" test |
| // certificate and private key (see src/net/data/ssl/certificates). The |
| // supported signature algorithms are currently hardcoded to PKCS #1 v1.5 with |
| // SHA-1 and SHA-256. |
| class TestCertificateProviderExtension final { |
| public: |
| static extensions::ExtensionId extension_id(); |
| static base::FilePath GetExtensionSourcePath(); |
| static base::FilePath GetExtensionPemPath(); |
| // Returns the certificate provided by the extension. |
| static scoped_refptr<net::X509Certificate> GetCertificate(); |
| static std::string GetCertificateSpki(); |
| |
| explicit TestCertificateProviderExtension( |
| content::BrowserContext* browser_context); |
| |
| TestCertificateProviderExtension(const TestCertificateProviderExtension&) = |
| delete; |
| TestCertificateProviderExtension& operator=( |
| const TestCertificateProviderExtension&) = delete; |
| |
| ~TestCertificateProviderExtension(); |
| |
| // Causes the extension to call chrome.certificateProvider.setCertificates, |
| // providing the certificates that are currently available. |
| void TriggerSetCertificates(); |
| |
| int certificate_request_count() const { return certificate_request_count_; } |
| |
| // Sets the PIN that will be required when doing every signature request. |
| // (By default, no PIN is requested.) |
| void set_require_pin(const std::string& pin) { required_pin_ = pin; } |
| |
| // Sets the number of remaining PIN attempts. |
| // Zero number means the lockout state, when no attempts are allowed anymore. |
| // A negative number denotes infinite number of attempts, which is the default |
| // behavior. |
| void set_remaining_pin_attempts(int remaining_pin_attempts) { |
| remaining_pin_attempts_ = remaining_pin_attempts; |
| } |
| |
| // Sets whether the extension should return any certificates in response to a |
| // onCertificatesRequested request or a TriggerSetCertificates() call. |
| void set_should_provide_certificates(bool should_provide_certificates) { |
| should_provide_certificates_ = should_provide_certificates; |
| } |
| |
| // Sets whether the extension should respond with a failure to the |
| // onSignDigestRequested requests. |
| void set_should_fail_sign_digest_requests( |
| bool should_fail_sign_digest_requests) { |
| should_fail_sign_digest_requests_ = should_fail_sign_digest_requests; |
| } |
| |
| private: |
| using ReplyToJsCallback = |
| base::OnceCallback<void(const base::Value& response)>; |
| |
| void HandleMessage(const std::string& message); |
| |
| void HandleCertificatesRequest(ReplyToJsCallback callback); |
| void HandleSignatureRequest(const base::Value& sign_request, |
| const base::Value& pin_status, |
| const base::Value& pin, |
| ReplyToJsCallback callback); |
| |
| const raw_ptr<content::BrowserContext> browser_context_; |
| const scoped_refptr<net::X509Certificate> certificate_; |
| std::unique_ptr<crypto::RSAPrivateKey> private_key_; |
| int certificate_request_count_ = 0; |
| // When non-empty, contains the expected PIN; the implementation will request |
| // the PIN on every signature request in this case. |
| absl::optional<std::string> required_pin_; |
| // The number of remaining PIN attempts. |
| // When equal to zero, signature requests will be failed immediately; when is |
| // negative, infinite number of attempts is allowed. |
| int remaining_pin_attempts_ = -1; |
| bool should_provide_certificates_ = true; |
| bool should_fail_sign_digest_requests_ = false; |
| ExtensionTestMessageListener message_listener_; |
| }; |
| |
| } // namespace ash |
| |
| #endif // CHROME_BROWSER_CERTIFICATE_PROVIDER_TEST_CERTIFICATE_PROVIDER_EXTENSION_H_ |