1 // Copyright 2024 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "crypto/scoped_fake_user_verifying_key_provider.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "base/base64.h"
11 #include "base/containers/flat_map.h"
12 #include "base/containers/span.h"
13 #include "base/functional/bind.h"
14 #include "base/functional/callback.h"
15 #include "crypto/signature_verifier.h"
16 #include "crypto/unexportable_key.h"
17 #include "crypto/user_verifying_key.h"
18
19 namespace crypto {
20
21 namespace {
22
23 // Wraps a software `UnexportableSigningKey`.
24 class FakeUserVerifyingSigningKey : public UserVerifyingSigningKey {
25 public:
FakeUserVerifyingSigningKey(UserVerifyingKeyLabel label,std::unique_ptr<UnexportableSigningKey> software_key)26 FakeUserVerifyingSigningKey(
27 UserVerifyingKeyLabel label,
28 std::unique_ptr<UnexportableSigningKey> software_key)
29 : label_(std::move(label)), software_key_(std::move(software_key)) {}
30
31 ~FakeUserVerifyingSigningKey() override = default;
32
Sign(base::span<const uint8_t> data,base::OnceCallback<void (std::optional<std::vector<uint8_t>>)> callback)33 void Sign(base::span<const uint8_t> data,
34 base::OnceCallback<void(std::optional<std::vector<uint8_t>>)>
35 callback) override {
36 std::move(callback).Run(software_key_->SignSlowly(data));
37 }
38
GetPublicKey() const39 std::vector<uint8_t> GetPublicKey() const override {
40 return software_key_->GetSubjectPublicKeyInfo();
41 }
42
GetKeyLabel() const43 const UserVerifyingKeyLabel& GetKeyLabel() const override { return label_; }
44
45 private:
46 const UserVerifyingKeyLabel label_;
47 std::unique_ptr<UnexportableSigningKey> software_key_;
48 };
49
50 class FakeUserVerifyingKeyProvider : public UserVerifyingKeyProvider {
51 public:
52 ~FakeUserVerifyingKeyProvider() override = default;
53
GenerateUserVerifyingSigningKey(base::span<const SignatureVerifier::SignatureAlgorithm> acceptable_algorithms,base::OnceCallback<void (std::unique_ptr<UserVerifyingSigningKey>)> callback)54 void GenerateUserVerifyingSigningKey(
55 base::span<const SignatureVerifier::SignatureAlgorithm>
56 acceptable_algorithms,
57 base::OnceCallback<void(std::unique_ptr<UserVerifyingSigningKey>)>
58 callback) override {
59 auto software_unexportable_key =
60 GetSoftwareUnsecureUnexportableKeyProvider()->GenerateSigningKeySlowly(
61 acceptable_algorithms);
62 UserVerifyingKeyLabel key_label =
63 base::Base64Encode(software_unexportable_key->GetWrappedKey());
64 std::move(callback).Run(std::make_unique<FakeUserVerifyingSigningKey>(
65 std::move(key_label), std::move(software_unexportable_key)));
66 }
67
GetUserVerifyingSigningKey(UserVerifyingKeyLabel key_label,base::OnceCallback<void (std::unique_ptr<UserVerifyingSigningKey>)> callback)68 void GetUserVerifyingSigningKey(
69 UserVerifyingKeyLabel key_label,
70 base::OnceCallback<void(std::unique_ptr<UserVerifyingSigningKey>)>
71 callback) override {
72 std::vector<SignatureVerifier::SignatureAlgorithm> algorithms = {
73 SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256};
74 std::optional<std::vector<uint8_t>> wrapped_key =
75 base::Base64Decode(key_label);
76 CHECK(wrapped_key);
77 auto software_unexportable_key =
78 GetSoftwareUnsecureUnexportableKeyProvider()
79 ->FromWrappedSigningKeySlowly(*wrapped_key);
80 CHECK(software_unexportable_key);
81 std::move(callback).Run(std::make_unique<FakeUserVerifyingSigningKey>(
82 std::move(key_label), std::move(software_unexportable_key)));
83 }
84
DeleteUserVerifyingKey(UserVerifyingKeyLabel key_label,base::OnceCallback<void (bool)> callback)85 void DeleteUserVerifyingKey(
86 UserVerifyingKeyLabel key_label,
87 base::OnceCallback<void(bool)> callback) override {
88 // The mock does not store any keys.
89 std::move(callback).Run(true);
90 }
91 };
92
GetMockUserVerifyingKeyProvider()93 std::unique_ptr<UserVerifyingKeyProvider> GetMockUserVerifyingKeyProvider() {
94 return std::make_unique<FakeUserVerifyingKeyProvider>();
95 }
96
GetNullUserVerifyingKeyProvider()97 std::unique_ptr<UserVerifyingKeyProvider> GetNullUserVerifyingKeyProvider() {
98 return nullptr;
99 }
100
101 } // namespace
102
ScopedFakeUserVerifyingKeyProvider()103 ScopedFakeUserVerifyingKeyProvider::ScopedFakeUserVerifyingKeyProvider() {
104 internal::SetUserVerifyingKeyProviderForTesting(
105 GetMockUserVerifyingKeyProvider);
106 }
107
~ScopedFakeUserVerifyingKeyProvider()108 ScopedFakeUserVerifyingKeyProvider::~ScopedFakeUserVerifyingKeyProvider() {
109 internal::SetUserVerifyingKeyProviderForTesting(nullptr);
110 }
111
ScopedNullUserVerifyingKeyProvider()112 ScopedNullUserVerifyingKeyProvider::ScopedNullUserVerifyingKeyProvider() {
113 internal::SetUserVerifyingKeyProviderForTesting(
114 GetNullUserVerifyingKeyProvider);
115 }
116
~ScopedNullUserVerifyingKeyProvider()117 ScopedNullUserVerifyingKeyProvider::~ScopedNullUserVerifyingKeyProvider() {
118 internal::SetUserVerifyingKeyProviderForTesting(nullptr);
119 }
120
121 } // namespace crypto
122