key_storage_keyring.cc 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // Copyright 2016 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. #include "components/os_crypt/key_storage_keyring.h"
  5. #include "base/base64.h"
  6. #include "base/bind.h"
  7. #include "base/logging.h"
  8. #include "base/rand_util.h"
  9. #include "base/strings/string_number_conversions.h"
  10. #include "base/task/single_thread_task_runner.h"
  11. #include "build/branding_buildflags.h"
  12. #include "components/os_crypt/keyring_util_linux.h"
  13. namespace {
  14. const GnomeKeyringPasswordSchema kSchema = {
  15. GNOME_KEYRING_ITEM_GENERIC_SECRET,
  16. {{"application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING}, {nullptr}}};
  17. } // namespace
  18. KeyStorageKeyring::KeyStorageKeyring(
  19. scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner,
  20. std::string application_name)
  21. : main_thread_runner_(main_thread_runner),
  22. application_name_(std::move(application_name)) {}
  23. KeyStorageKeyring::~KeyStorageKeyring() {}
  24. base::SequencedTaskRunner* KeyStorageKeyring::GetTaskRunner() {
  25. return main_thread_runner_.get();
  26. }
  27. bool KeyStorageKeyring::Init() {
  28. DCHECK(main_thread_runner_->RunsTasksInCurrentSequence());
  29. return GnomeKeyringLoader::LoadGnomeKeyring();
  30. }
  31. absl::optional<std::string> KeyStorageKeyring::GetKeyImpl() {
  32. DCHECK(main_thread_runner_->RunsTasksInCurrentSequence());
  33. absl::optional<std::string> password;
  34. gchar* password_c = nullptr;
  35. GnomeKeyringResult result =
  36. GnomeKeyringLoader::gnome_keyring_find_password_sync_ptr(
  37. &kSchema, &password_c, "application", application_name_.c_str(),
  38. nullptr);
  39. if (result == GNOME_KEYRING_RESULT_OK) {
  40. password = password_c;
  41. GnomeKeyringLoader::gnome_keyring_free_password_ptr(password_c);
  42. } else if (result == GNOME_KEYRING_RESULT_NO_MATCH) {
  43. password = KeyStorageKeyring::AddRandomPasswordInKeyring();
  44. } else {
  45. VLOG(1) << "OSCrypt failed to use gnome-keyring";
  46. }
  47. return password;
  48. }
  49. absl::optional<std::string> KeyStorageKeyring::AddRandomPasswordInKeyring() {
  50. // Generate password
  51. std::string password;
  52. base::Base64Encode(base::RandBytesAsString(16), &password);
  53. // Store generated password
  54. GnomeKeyringResult result =
  55. GnomeKeyringLoader::gnome_keyring_store_password_sync_ptr(
  56. &kSchema, nullptr /* default keyring */, KeyStorageLinux::kKey,
  57. password.c_str(), "application", application_name_.c_str(), nullptr);
  58. if (result != GNOME_KEYRING_RESULT_OK) {
  59. VLOG(1) << "OSCrypt failed to store generated password to gnome-keyring";
  60. return absl::nullopt;
  61. }
  62. VLOG(1) << "OSCrypt generated a new password and stored it to gnome-keyring";
  63. // password.value() is not empty since result == GNOME_KEYRING_RESULT_OK
  64. return std::move(password);
  65. }