| Index: chrome/browser/chromeos/login/auth/key.cc
|
| diff --git a/chrome/browser/chromeos/login/auth/key.cc b/chrome/browser/chromeos/login/auth/key.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ab6abd86500843945a3494a6fb07542188f0f651
|
| --- /dev/null
|
| +++ b/chrome/browser/chromeos/login/auth/key.cc
|
| @@ -0,0 +1,117 @@
|
| +// Copyright 2014 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/chromeos/login/auth/key.h"
|
| +
|
| +#include "base/base64.h"
|
| +#include "base/logging.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/strings/string_number_conversions.h"
|
| +#include "base/strings/string_util.h"
|
| +#include "crypto/sha2.h"
|
| +#include "crypto/symmetric_key.h"
|
| +
|
| +namespace chromeos {
|
| +
|
| +namespace {
|
| +
|
| +// Parameters for the transformation to KEY_TYPE_SALTED_AES256_1234.
|
| +const int kNumIterations = 1234;
|
| +const int kKeySizeInBits = 256;
|
| +
|
| +} // namespace
|
| +
|
| +Key::Key() : key_type_(KEY_TYPE_PASSWORD_PLAIN) {
|
| +}
|
| +
|
| +Key::Key(const Key& other) : key_type_(other.key_type_),
|
| + salt_(other.salt_),
|
| + secret_(other.secret_),
|
| + label_(other.label_) {
|
| +}
|
| +
|
| +Key::Key(const std::string& plain_text_password)
|
| + : key_type_(KEY_TYPE_PASSWORD_PLAIN),
|
| + secret_(plain_text_password) {
|
| +}
|
| +
|
| +Key::Key(KeyType key_type, const std::string& salt, const std::string& secret)
|
| + : key_type_(key_type),
|
| + salt_(salt),
|
| + secret_(secret) {
|
| +
|
| +}
|
| +
|
| +Key::~Key() {
|
| +}
|
| +
|
| +bool Key::operator==(const Key& other) const {
|
| + return other.key_type_ == key_type_ &&
|
| + other.salt_ == salt_ &&
|
| + other.secret_ == secret_ &&
|
| + other.label_ == label_;
|
| +}
|
| +
|
| +Key::KeyType Key::GetKeyType() const {
|
| + return key_type_;
|
| +}
|
| +
|
| +const std::string& Key::GetSecret() const {
|
| + return secret_;
|
| +}
|
| +
|
| +const std::string& Key::GetLabel() const {
|
| + return label_;
|
| +}
|
| +
|
| +void Key::SetLabel(const std::string& label) {
|
| + label_ = label;
|
| +}
|
| +
|
| +void Key::ClearSecret() {
|
| + secret_.clear();
|
| +}
|
| +
|
| +void Key::Transform(KeyType target_key_type, const std::string& salt) {
|
| + if (key_type_ != KEY_TYPE_PASSWORD_PLAIN) {
|
| + NOTREACHED();
|
| + return;
|
| + }
|
| +
|
| + switch (target_key_type) {
|
| + case KEY_TYPE_SALTED_SHA256_TOP_HALF: {
|
| + // TODO(stevenjb/nkostylev): Handle empty salt gracefully.
|
| + CHECK(!salt.empty());
|
| + char hash[crypto::kSHA256Length];
|
| + crypto::SHA256HashString(salt + secret_, &hash, sizeof(hash));
|
| +
|
| + // Keep only the first half of the hash for 'weak' hashing so that the
|
| + // plain text secret cannot be reconstructed even if the hashing is
|
| + // reversed.
|
| + secret_ = StringToLowerASCII(base::HexEncode(
|
| + reinterpret_cast<const void*>(hash), sizeof(hash) / 2));
|
| + break;
|
| + } case KEY_TYPE_SALTED_PBKDF2_AES256_1234: {
|
| + scoped_ptr<crypto::SymmetricKey> key(
|
| + crypto::SymmetricKey::DeriveKeyFromPassword(crypto::SymmetricKey::AES,
|
| + secret_,
|
| + salt,
|
| + kNumIterations,
|
| + kKeySizeInBits));
|
| + std::string raw_secret;
|
| + key->GetRawKey(&raw_secret);
|
| + base::Base64Encode(raw_secret, &secret_);
|
| + break;
|
| + } default:
|
| + // The resulting key will be sent to cryptohomed. It should always be
|
| + // hashed. If hashing fails, crash instead of sending a plain-text key.
|
| + CHECK(false);
|
| + return;
|
| + }
|
| +
|
| + key_type_ = target_key_type;
|
| + salt_ = salt;
|
| +}
|
| +
|
| +} // namespace chromeos
|
|
|