Skip to content

Commit 1ac0e00

Browse files
committed
fix disable-encryption patch
1 parent f3b4dda commit 1ac0e00

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Copyright 2024 The Chromium Authors and Alex313031
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 "components/os_crypt/async/browser/dpapi_key_provider.h"
6+
7+
#include <windows.h>
8+
9+
#include <wincrypt.h>
10+
11+
#include "base/base64.h"
12+
#include "base/command_line.h"
13+
#include "base/logging.h"
14+
#include "base/metrics/histogram_functions.h"
15+
#include "base/types/expected.h"
16+
#include "base/win/scoped_localalloc.h"
17+
#include "components/os_crypt/async/common/algorithm.mojom.h"
18+
#include "components/prefs/pref_service.h"
19+
20+
namespace os_crypt_async {
21+
22+
namespace {
23+
24+
// Legacy (OSCrypt) random key encrypted with DPAPI imported by this code.
25+
// This should match the pref name defined in os_crypt_win.cc until sync is
26+
// deprecated and the pref registration can be moved here.
27+
constexpr char kOsCryptEncryptedKeyPrefName[] = "os_crypt.encrypted_key";
28+
29+
// Data prefix for data encrypted with DPAPI. This must match
30+
// kEncryptionVersionPrefix in os_crypt_win.cc to ensure data is compatible.
31+
constexpr char kKeyTag[] = "v10";
32+
33+
// Key prefix for a key encrypted with DPAPI. This must match kDPAPIKeyPrefix in
34+
// os_crypt_win.cc to ensure the same key can be decrypted successfully.
35+
constexpr uint8_t kDPAPIKeyPrefix[] = {'D', 'P', 'A', 'P', 'I'};
36+
37+
std::optional<std::vector<uint8_t>> DecryptKeyWithDPAPI(
38+
base::span<const uint8_t> ciphertext) {
39+
40+
if (base::CommandLine::ForCurrentProcess()->HasSwitch("disable-encryption")) {
41+
return std::vector<uint8_t>(ciphertext.data(),
42+
ciphertext.data() + ciphertext.size());
43+
}
44+
45+
DATA_BLOB input = {};
46+
input.pbData = const_cast<BYTE*>(ciphertext.data());
47+
input.cbData = static_cast<DWORD>(ciphertext.size());
48+
49+
BOOL result = FALSE;
50+
DATA_BLOB output;
51+
result = ::CryptUnprotectData(&input, nullptr, nullptr, nullptr, nullptr, 0,
52+
&output);
53+
54+
if (!result) {
55+
return std::nullopt;
56+
}
57+
58+
auto local_alloc = base::win::TakeLocalAlloc(output.pbData);
59+
60+
return std::vector<uint8_t>(local_alloc.get(),
61+
local_alloc.get() + output.cbData);
62+
}
63+
64+
} // namespace
65+
66+
DPAPIKeyProvider::DPAPIKeyProvider(PrefService* local_state)
67+
: local_state_(local_state) {}
68+
DPAPIKeyProvider::~DPAPIKeyProvider() = default;
69+
70+
base::expected<Encryptor::Key, DPAPIKeyProvider::KeyStatus>
71+
DPAPIKeyProvider::GetKeyInternal() {
72+
if (!local_state_->HasPrefPath(kOsCryptEncryptedKeyPrefName)) {
73+
return base::unexpected(KeyStatus::kKeyNotFound);
74+
}
75+
76+
const std::string base64_encrypted_key =
77+
local_state_->GetString(kOsCryptEncryptedKeyPrefName);
78+
79+
std::optional<std::vector<uint8_t>> decoded =
80+
base::Base64Decode(base64_encrypted_key);
81+
82+
if (!decoded) {
83+
return base::unexpected(KeyStatus::kKeyDecodeFailure);
84+
}
85+
86+
if (decoded->size() < std::size(kDPAPIKeyPrefix)) {
87+
return base::unexpected(KeyStatus::kKeyTooShort);
88+
}
89+
90+
if (!std::equal(decoded->begin(),
91+
decoded->begin() + std::size(kDPAPIKeyPrefix),
92+
kDPAPIKeyPrefix)) {
93+
return base::unexpected(KeyStatus::kInvalidKeyHeader);
94+
}
95+
96+
auto encrypted_key_data = std::vector<uint8_t>(
97+
decoded->cbegin() + std::size(kDPAPIKeyPrefix), decoded->cend());
98+
99+
auto decrypted_key = DecryptKeyWithDPAPI(encrypted_key_data);
100+
101+
if (!decrypted_key) {
102+
return base::unexpected(KeyStatus::kDPAPIDecryptFailure);
103+
}
104+
105+
if (decrypted_key->size() != Encryptor::Key::kAES256GCMKeySize) {
106+
return base::unexpected(KeyStatus::kInvalidKeyLength);
107+
}
108+
109+
return Encryptor::Key(*decrypted_key, mojom::Algorithm::kAES256GCM);
110+
}
111+
112+
void DPAPIKeyProvider::GetKey(KeyCallback callback) {
113+
auto result = GetKeyInternal();
114+
115+
base::UmaHistogramEnumeration("OSCrypt.DPAPIProvider.Status",
116+
result.error_or(KeyStatus::kSuccess));
117+
118+
if (result.has_value()) {
119+
std::move(callback).Run(kKeyTag, std::move(result.value()));
120+
} else {
121+
std::move(callback).Run(std::string(), std::nullopt);
122+
}
123+
}
124+
125+
bool DPAPIKeyProvider::UseForEncryption() {
126+
return true;
127+
}
128+
129+
} // namespace os_crypt_async

0 commit comments

Comments
 (0)