Roll src/third_party/WebKit abe9e39c:3d349bd (svn 182659:182669)
[chromium-blink-merge.git] / chromeos / login / auth / key.cc
blob01c3bcf1ffc89a03b21dc468d4b66b1374a4e01c
1 // Copyright 2014 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.
5 #include "chromeos/login/auth/key.h"
7 #include "base/base64.h"
8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h"
12 #include "crypto/sha2.h"
13 #include "crypto/symmetric_key.h"
15 namespace chromeos {
17 namespace {
19 // Parameters for the transformation to KEY_TYPE_SALTED_AES256_1234.
20 const int kNumIterations = 1234;
21 const int kKeySizeInBits = 256;
23 } // namespace
25 Key::Key() : key_type_(KEY_TYPE_PASSWORD_PLAIN) {
28 Key::Key(const Key& other)
29 : key_type_(other.key_type_),
30 salt_(other.salt_),
31 secret_(other.secret_),
32 label_(other.label_) {
35 Key::Key(const std::string& plain_text_password)
36 : key_type_(KEY_TYPE_PASSWORD_PLAIN), secret_(plain_text_password) {
39 Key::Key(KeyType key_type, const std::string& salt, const std::string& secret)
40 : key_type_(key_type), salt_(salt), secret_(secret) {
43 Key::~Key() {
46 bool Key::operator==(const Key& other) const {
47 return other.key_type_ == key_type_ && other.salt_ == salt_ &&
48 other.secret_ == secret_ && other.label_ == label_;
51 Key::KeyType Key::GetKeyType() const {
52 return key_type_;
55 const std::string& Key::GetSecret() const {
56 return secret_;
59 const std::string& Key::GetLabel() const {
60 return label_;
63 void Key::SetLabel(const std::string& label) {
64 label_ = label;
67 void Key::ClearSecret() {
68 secret_.clear();
71 void Key::Transform(KeyType target_key_type, const std::string& salt) {
72 if (key_type_ != KEY_TYPE_PASSWORD_PLAIN) {
73 NOTREACHED();
74 return;
77 switch (target_key_type) {
78 case KEY_TYPE_SALTED_SHA256_TOP_HALF: {
79 // TODO(stevenjb/nkostylev): Handle empty salt gracefully.
80 CHECK(!salt.empty());
81 char hash[crypto::kSHA256Length];
82 crypto::SHA256HashString(salt + secret_, &hash, sizeof(hash));
84 // Keep only the first half of the hash for 'weak' hashing so that the
85 // plain text secret cannot be reconstructed even if the hashing is
86 // reversed.
87 secret_ = base::StringToLowerASCII(base::HexEncode(
88 reinterpret_cast<const void*>(hash), sizeof(hash) / 2));
89 break;
91 case KEY_TYPE_SALTED_PBKDF2_AES256_1234: {
92 scoped_ptr<crypto::SymmetricKey> key(
93 crypto::SymmetricKey::DeriveKeyFromPassword(crypto::SymmetricKey::AES,
94 secret_,
95 salt,
96 kNumIterations,
97 kKeySizeInBits));
98 std::string raw_secret;
99 key->GetRawKey(&raw_secret);
100 base::Base64Encode(raw_secret, &secret_);
101 break;
103 case KEY_TYPE_SALTED_SHA256:
104 base::Base64Encode(crypto::SHA256HashString(salt + secret_), &secret_);
105 break;
107 default:
108 // The resulting key will be sent to cryptohomed. It should always be
109 // hashed. If hashing fails, crash instead of sending a plain-text key.
110 CHECK(false);
111 return;
114 key_type_ = target_key_type;
115 salt_ = salt;
118 } // namespace chromeos