PageRenderTime 56ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/ash/services/device_sync/cryptauth_key.cc

https://github.com/chromium/chromium
C++ | 164 lines | 123 code | 35 blank | 6 comment | 26 complexity | a39d2d9ae6df19a091c9d191f068491f MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, Apache-2.0, BSD-3-Clause
  1. // Copyright 2019 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 "ash/services/device_sync/cryptauth_key.h"
  5. #include "ash/services/device_sync/value_string_encoding.h"
  6. #include "base/base64url.h"
  7. #include "crypto/sha2.h"
  8. namespace ash {
  9. namespace device_sync {
  10. namespace {
  11. // Strings used as the DictionaryValue keys in As*DictionaryValue().
  12. const char kHandleDictKey[] = "handle";
  13. const char kStatusDictKey[] = "status";
  14. const char kTypeDictKey[] = "type";
  15. const char kSymmetricKeyDictKey[] = "symmetric_key";
  16. const char kPublicKeyDictKey[] = "public_key";
  17. const char kPrivateKeyDictKey[] = "private_key";
  18. // Returns the base64url-encoded SHA256 hash of the input string.
  19. std::string CreateHandle(const std::string& string_to_hash) {
  20. std::string handle;
  21. base::Base64UrlEncode(crypto::SHA256HashString(string_to_hash),
  22. base::Base64UrlEncodePolicy::INCLUDE_PADDING, &handle);
  23. return handle;
  24. }
  25. bool IsSymmetricKeyType(cryptauthv2::KeyType type) {
  26. return (type == cryptauthv2::KeyType::RAW128 ||
  27. type == cryptauthv2::KeyType::RAW256);
  28. }
  29. bool IsAsymmetricKeyType(cryptauthv2::KeyType type) {
  30. return (type == cryptauthv2::KeyType::P256 ||
  31. type == cryptauthv2::KeyType::CURVE25519);
  32. }
  33. } // namespace
  34. // static
  35. absl::optional<CryptAuthKey> CryptAuthKey::FromDictionary(
  36. const base::Value& dict) {
  37. if (!dict.is_dict())
  38. return absl::nullopt;
  39. absl::optional<int> opt_status = dict.FindIntKey(kStatusDictKey);
  40. if (!opt_status)
  41. return absl::nullopt;
  42. CryptAuthKey::Status status = static_cast<CryptAuthKey::Status>(*opt_status);
  43. absl::optional<int> opt_type = dict.FindIntKey(kTypeDictKey);
  44. if (!opt_type || !cryptauthv2::KeyType_IsValid(*opt_type))
  45. return absl::nullopt;
  46. cryptauthv2::KeyType type = static_cast<cryptauthv2::KeyType>(*opt_type);
  47. const std::string* handle = dict.FindStringKey(kHandleDictKey);
  48. if (!handle || handle->empty())
  49. return absl::nullopt;
  50. if (IsSymmetricKeyType(type)) {
  51. absl::optional<std::string> symmetric_key =
  52. util::DecodeFromValueString(dict.FindKey(kSymmetricKeyDictKey));
  53. if (!symmetric_key || symmetric_key->empty())
  54. return absl::nullopt;
  55. return CryptAuthKey(*symmetric_key, status, type, *handle);
  56. }
  57. DCHECK(IsAsymmetricKeyType(type));
  58. absl::optional<std::string> public_key =
  59. util::DecodeFromValueString(dict.FindKey(kPublicKeyDictKey));
  60. absl::optional<std::string> private_key =
  61. util::DecodeFromValueString(dict.FindKey(kPrivateKeyDictKey));
  62. if (!public_key || !private_key || public_key->empty()) {
  63. return absl::nullopt;
  64. }
  65. return CryptAuthKey(*public_key, *private_key, status, type, *handle);
  66. }
  67. CryptAuthKey::CryptAuthKey(const std::string& symmetric_key,
  68. Status status,
  69. cryptauthv2::KeyType type,
  70. const absl::optional<std::string>& handle)
  71. : symmetric_key_(symmetric_key),
  72. status_(status),
  73. type_(type),
  74. handle_(handle ? *handle : CreateHandle(symmetric_key)) {
  75. DCHECK(IsSymmetricKey());
  76. DCHECK(!symmetric_key_.empty());
  77. DCHECK(!handle_.empty());
  78. }
  79. CryptAuthKey::CryptAuthKey(const std::string& public_key,
  80. const std::string& private_key,
  81. Status status,
  82. cryptauthv2::KeyType type,
  83. const absl::optional<std::string>& handle)
  84. : public_key_(public_key),
  85. private_key_(private_key),
  86. status_(status),
  87. type_(type),
  88. handle_(handle ? *handle : CreateHandle(public_key)) {
  89. DCHECK(IsAsymmetricKey());
  90. DCHECK(!public_key_.empty());
  91. DCHECK(!handle_.empty());
  92. }
  93. CryptAuthKey::CryptAuthKey(const CryptAuthKey&) = default;
  94. CryptAuthKey::~CryptAuthKey() = default;
  95. bool CryptAuthKey::IsSymmetricKey() const {
  96. return IsSymmetricKeyType(type_);
  97. }
  98. bool CryptAuthKey::IsAsymmetricKey() const {
  99. return IsAsymmetricKeyType(type_);
  100. }
  101. base::Value CryptAuthKey::AsSymmetricKeyDictionary() const {
  102. DCHECK(IsSymmetricKey());
  103. base::Value dict(base::Value::Type::DICTIONARY);
  104. dict.SetKey(kHandleDictKey, base::Value(handle_));
  105. dict.SetKey(kStatusDictKey, base::Value(status_));
  106. dict.SetKey(kTypeDictKey, base::Value(type_));
  107. dict.SetKey(kSymmetricKeyDictKey, util::EncodeAsValueString(symmetric_key_));
  108. return dict;
  109. }
  110. base::Value CryptAuthKey::AsAsymmetricKeyDictionary() const {
  111. DCHECK(IsAsymmetricKey());
  112. base::Value dict(base::Value::Type::DICTIONARY);
  113. dict.SetKey(kHandleDictKey, base::Value(handle_));
  114. dict.SetKey(kStatusDictKey, base::Value(status_));
  115. dict.SetKey(kTypeDictKey, base::Value(type_));
  116. dict.SetKey(kPublicKeyDictKey, util::EncodeAsValueString(public_key_));
  117. dict.SetKey(kPrivateKeyDictKey, util::EncodeAsValueString(private_key_));
  118. return dict;
  119. }
  120. bool CryptAuthKey::operator==(const CryptAuthKey& other) const {
  121. return handle_ == other.handle_ && status_ == other.status_ &&
  122. type_ == other.type_ && symmetric_key_ == other.symmetric_key_ &&
  123. public_key_ == other.public_key_ && private_key_ == other.private_key_;
  124. }
  125. bool CryptAuthKey::operator!=(const CryptAuthKey& other) const {
  126. return !(*this == other);
  127. }
  128. } // namespace device_sync
  129. } // namespace ash