/ash/services/device_sync/cryptauth_key.cc
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
- // Copyright 2019 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 "ash/services/device_sync/cryptauth_key.h"
- #include "ash/services/device_sync/value_string_encoding.h"
- #include "base/base64url.h"
- #include "crypto/sha2.h"
- namespace ash {
- namespace device_sync {
- namespace {
- // Strings used as the DictionaryValue keys in As*DictionaryValue().
- const char kHandleDictKey[] = "handle";
- const char kStatusDictKey[] = "status";
- const char kTypeDictKey[] = "type";
- const char kSymmetricKeyDictKey[] = "symmetric_key";
- const char kPublicKeyDictKey[] = "public_key";
- const char kPrivateKeyDictKey[] = "private_key";
- // Returns the base64url-encoded SHA256 hash of the input string.
- std::string CreateHandle(const std::string& string_to_hash) {
- std::string handle;
- base::Base64UrlEncode(crypto::SHA256HashString(string_to_hash),
- base::Base64UrlEncodePolicy::INCLUDE_PADDING, &handle);
- return handle;
- }
- bool IsSymmetricKeyType(cryptauthv2::KeyType type) {
- return (type == cryptauthv2::KeyType::RAW128 ||
- type == cryptauthv2::KeyType::RAW256);
- }
- bool IsAsymmetricKeyType(cryptauthv2::KeyType type) {
- return (type == cryptauthv2::KeyType::P256 ||
- type == cryptauthv2::KeyType::CURVE25519);
- }
- } // namespace
- // static
- absl::optional<CryptAuthKey> CryptAuthKey::FromDictionary(
- const base::Value& dict) {
- if (!dict.is_dict())
- return absl::nullopt;
- absl::optional<int> opt_status = dict.FindIntKey(kStatusDictKey);
- if (!opt_status)
- return absl::nullopt;
- CryptAuthKey::Status status = static_cast<CryptAuthKey::Status>(*opt_status);
- absl::optional<int> opt_type = dict.FindIntKey(kTypeDictKey);
- if (!opt_type || !cryptauthv2::KeyType_IsValid(*opt_type))
- return absl::nullopt;
- cryptauthv2::KeyType type = static_cast<cryptauthv2::KeyType>(*opt_type);
- const std::string* handle = dict.FindStringKey(kHandleDictKey);
- if (!handle || handle->empty())
- return absl::nullopt;
- if (IsSymmetricKeyType(type)) {
- absl::optional<std::string> symmetric_key =
- util::DecodeFromValueString(dict.FindKey(kSymmetricKeyDictKey));
- if (!symmetric_key || symmetric_key->empty())
- return absl::nullopt;
- return CryptAuthKey(*symmetric_key, status, type, *handle);
- }
- DCHECK(IsAsymmetricKeyType(type));
- absl::optional<std::string> public_key =
- util::DecodeFromValueString(dict.FindKey(kPublicKeyDictKey));
- absl::optional<std::string> private_key =
- util::DecodeFromValueString(dict.FindKey(kPrivateKeyDictKey));
- if (!public_key || !private_key || public_key->empty()) {
- return absl::nullopt;
- }
- return CryptAuthKey(*public_key, *private_key, status, type, *handle);
- }
- CryptAuthKey::CryptAuthKey(const std::string& symmetric_key,
- Status status,
- cryptauthv2::KeyType type,
- const absl::optional<std::string>& handle)
- : symmetric_key_(symmetric_key),
- status_(status),
- type_(type),
- handle_(handle ? *handle : CreateHandle(symmetric_key)) {
- DCHECK(IsSymmetricKey());
- DCHECK(!symmetric_key_.empty());
- DCHECK(!handle_.empty());
- }
- CryptAuthKey::CryptAuthKey(const std::string& public_key,
- const std::string& private_key,
- Status status,
- cryptauthv2::KeyType type,
- const absl::optional<std::string>& handle)
- : public_key_(public_key),
- private_key_(private_key),
- status_(status),
- type_(type),
- handle_(handle ? *handle : CreateHandle(public_key)) {
- DCHECK(IsAsymmetricKey());
- DCHECK(!public_key_.empty());
- DCHECK(!handle_.empty());
- }
- CryptAuthKey::CryptAuthKey(const CryptAuthKey&) = default;
- CryptAuthKey::~CryptAuthKey() = default;
- bool CryptAuthKey::IsSymmetricKey() const {
- return IsSymmetricKeyType(type_);
- }
- bool CryptAuthKey::IsAsymmetricKey() const {
- return IsAsymmetricKeyType(type_);
- }
- base::Value CryptAuthKey::AsSymmetricKeyDictionary() const {
- DCHECK(IsSymmetricKey());
- base::Value dict(base::Value::Type::DICTIONARY);
- dict.SetKey(kHandleDictKey, base::Value(handle_));
- dict.SetKey(kStatusDictKey, base::Value(status_));
- dict.SetKey(kTypeDictKey, base::Value(type_));
- dict.SetKey(kSymmetricKeyDictKey, util::EncodeAsValueString(symmetric_key_));
- return dict;
- }
- base::Value CryptAuthKey::AsAsymmetricKeyDictionary() const {
- DCHECK(IsAsymmetricKey());
- base::Value dict(base::Value::Type::DICTIONARY);
- dict.SetKey(kHandleDictKey, base::Value(handle_));
- dict.SetKey(kStatusDictKey, base::Value(status_));
- dict.SetKey(kTypeDictKey, base::Value(type_));
- dict.SetKey(kPublicKeyDictKey, util::EncodeAsValueString(public_key_));
- dict.SetKey(kPrivateKeyDictKey, util::EncodeAsValueString(private_key_));
- return dict;
- }
- bool CryptAuthKey::operator==(const CryptAuthKey& other) const {
- return handle_ == other.handle_ && status_ == other.status_ &&
- type_ == other.type_ && symmetric_key_ == other.symmetric_key_ &&
- public_key_ == other.public_key_ && private_key_ == other.private_key_;
- }
- bool CryptAuthKey::operator!=(const CryptAuthKey& other) const {
- return !(*this == other);
- }
- } // namespace device_sync
- } // namespace ash