| // Copyright 2022 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. |
| |
| #include "chrome/browser/os_crypt/app_bound_encryption_win.h" |
| |
| #include <objbase.h> |
| #include <string.h> |
| #include <windows.h> |
| #include <wrl/client.h> |
| |
| #include "base/logging.h" |
| #include "base/win/com_init_util.h" |
| #include "base/win/scoped_bstr.h" |
| #include "chrome/elevation_service/elevation_service_idl.h" |
| #include "chrome/install_static/install_util.h" |
| |
| namespace os_crypt { |
| |
| HRESULT EncryptAppBoundString(ProtectionLevel protection_level, |
| const std::string& plaintext, |
| std::string& ciphertext, |
| DWORD& last_error) { |
| base::win::AssertComInitialized(); |
| Microsoft::WRL::ComPtr<IElevator> elevator; |
| last_error = ERROR_GEN_FAILURE; |
| HRESULT hr = ::CoCreateInstance( |
| install_static::GetElevatorClsid(), nullptr, CLSCTX_LOCAL_SERVER, |
| install_static::GetElevatorIid(), IID_PPV_ARGS_Helper(&elevator)); |
| |
| if (FAILED(hr)) |
| return hr; |
| |
| hr = ::CoSetProxyBlanket( |
| elevator.Get(), RPC_C_AUTHN_DEFAULT, RPC_C_AUTHZ_DEFAULT, |
| COLE_DEFAULT_PRINCIPAL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, |
| RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_DYNAMIC_CLOAKING); |
| if (FAILED(hr)) |
| return hr; |
| |
| base::win::ScopedBstr plaintext_data; |
| ::memcpy(plaintext_data.AllocateBytes(plaintext.length()), plaintext.data(), |
| plaintext.length()); |
| |
| base::win::ScopedBstr encrypted_data; |
| hr = elevator->EncryptData(protection_level, plaintext_data.Get(), |
| encrypted_data.Receive(), &last_error); |
| if (FAILED(hr)) |
| return hr; |
| |
| ciphertext.assign( |
| reinterpret_cast<std::string::value_type*>(encrypted_data.Get()), |
| encrypted_data.ByteLength()); |
| |
| last_error = ERROR_SUCCESS; |
| return S_OK; |
| } |
| |
| HRESULT DecryptAppBoundString(const std::string& ciphertext, |
| std::string& plaintext, |
| DWORD& last_error) { |
| DCHECK(!ciphertext.empty()); |
| base::win::AssertComInitialized(); |
| Microsoft::WRL::ComPtr<IElevator> elevator; |
| last_error = ERROR_GEN_FAILURE; |
| HRESULT hr = ::CoCreateInstance( |
| install_static::GetElevatorClsid(), nullptr, CLSCTX_LOCAL_SERVER, |
| install_static::GetElevatorIid(), IID_PPV_ARGS_Helper(&elevator)); |
| |
| if (FAILED(hr)) |
| return hr; |
| |
| hr = ::CoSetProxyBlanket( |
| elevator.Get(), RPC_C_AUTHN_DEFAULT, RPC_C_AUTHZ_DEFAULT, |
| COLE_DEFAULT_PRINCIPAL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, |
| RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_DYNAMIC_CLOAKING); |
| if (FAILED(hr)) |
| return hr; |
| |
| base::win::ScopedBstr ciphertext_data; |
| ::memcpy(ciphertext_data.AllocateBytes(ciphertext.length()), |
| ciphertext.data(), ciphertext.length()); |
| |
| base::win::ScopedBstr plaintext_data; |
| hr = elevator->DecryptData(ciphertext_data.Get(), plaintext_data.Receive(), |
| &last_error); |
| if (FAILED(hr)) |
| return hr; |
| |
| plaintext.assign( |
| reinterpret_cast<std::string::value_type*>(plaintext_data.Get()), |
| plaintext_data.ByteLength()); |
| |
| last_error = ERROR_SUCCESS; |
| return S_OK; |
| } |
| |
| } // namespace os_crypt |