Chromium Code Reviews| Index: src/platform/cryptohome/username_passkey.cc |
| diff --git a/src/platform/cryptohome/username_passkey.cc b/src/platform/cryptohome/username_passkey.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..3d6ad84c7541d5be98747bc98a784b10fad72473 |
| --- /dev/null |
| +++ b/src/platform/cryptohome/username_passkey.cc |
| @@ -0,0 +1,138 @@ |
| +// Copyright (c) 2009-2010 The Chromium OS 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 "cryptohome/username_passkey.h" |
| + |
| +#include <openssl/sha.h> |
| + |
| +#include "base/logging.h" |
| +#include "chromeos/utility.h" |
| + |
| +namespace cryptohome { |
| +using std::string; |
| + |
| +UsernamePasskey::UsernamePasskey(const char *username, |
| + const int username_length, |
| + const char *passkey, |
| + const int passkey_length) |
| + : username_(username, username_length), |
| + passkey_(passkey_length) { |
| + memcpy(&passkey_[0], passkey, passkey_length); |
| +} |
| + |
| +UsernamePasskey::UsernamePasskey(const char *username, |
| + const int username_length, |
| + const chromeos::Blob& passkey) |
| + : username_(username, username_length), |
| + passkey_() { |
| + passkey_.assign(passkey.begin(), passkey.end()); |
| +} |
| + |
| +UsernamePasskey::UsernamePasskey(const char *username, |
| + const int username_length, |
| + const std::string& passkey) |
| + : username_(username, username_length), |
| + passkey_() { |
| + passkey_.resize(passkey.length()); |
| + memcpy(&passkey_[0], passkey.c_str(), passkey.length()); |
| +} |
| + |
| +UsernamePasskey::UsernamePasskey(const UsernamePasskey& rhs) |
| + : username_(rhs.username_), |
| + passkey_(rhs.passkey_) { |
| +} |
| + |
| +UsernamePasskey::~UsernamePasskey() { |
| +} |
| + |
| +UsernamePasskey& UsernamePasskey::operator=(const UsernamePasskey& rhs) { |
| + this->username_ = rhs.username_; |
| + this->passkey_ = rhs.passkey_; |
| + return *this; |
| +} |
| + |
| +UsernamePasskey UsernamePasskey::FromUsernamePassword(const char* username, |
| + const char* password, |
| + const chromeos::Blob& salt) { |
| + SecureBlob passkey = PasswordToPasskey(password, salt); |
| + return UsernamePasskey(username, strlen(username), passkey); |
| +} |
| + |
| +SecureBlob UsernamePasskey::PasswordToPasskey(const char *password, |
| + const chromeos::Blob& salt) { |
| + CHECK(password); |
| + |
| + std::string ascii_salt = chromeos::AsciiEncode(salt); |
| + // Convert a raw password to a password hash |
| + SHA256_CTX sha_ctx; |
| + unsigned char md_value[SHA256_DIGEST_LENGTH]; |
| + |
| + SHA256_Init(&sha_ctx); |
| + SHA256_Update(&sha_ctx, |
| + reinterpret_cast<const unsigned char*>(ascii_salt.data()), |
| + static_cast<unsigned int>(ascii_salt.length())); |
| + SHA256_Update(&sha_ctx, password, strlen(password)); |
| + SHA256_Final(md_value, &sha_ctx); |
| + |
| + SecureBlob password_hash(SHA256_DIGEST_LENGTH); |
| + AsciiEncodeToBuffer(md_value, SHA256_DIGEST_LENGTH / 2, |
| + reinterpret_cast<char*>(&password_hash[0]), |
|
mschilder
2010/05/27 04:20:18
Add a void* data() method to SecureBlob? This cast
|
| + password_hash.size()); |
| + chromeos::SecureMemset(md_value, sizeof(md_value), 0); |
| + return password_hash; |
| +} |
| + |
| +void UsernamePasskey::AsciiEncodeToBuffer(const unsigned char* source, |
| + int source_length, char* buffer, |
| + int buffer_length) { |
| + const char hex_chars[] = "0123456789abcdef"; |
| + int i = 0; |
| + for (int index = 0; |
| + (index < source_length) && ((i + 1) < buffer_length); |
| + index++) { |
| + buffer[i++] = hex_chars[(source[index] >> 4) & 0x0f]; |
| + buffer[i++] = hex_chars[source[index] & 0x0f]; |
| + } |
| + if (i < buffer_length) { |
| + buffer[i] = '\0'; |
| + } |
| +} |
| + |
| +void UsernamePasskey::GetFullUsername(char *name_buffer, int length) const { |
| + strncpy(name_buffer, username_.c_str(), length); |
| +} |
| + |
| +std::string UsernamePasskey::GetFullUsername() const { |
| + return username_; |
| +} |
| + |
| +void UsernamePasskey::GetPartialUsername(char *name_buffer, int length) const { |
| + size_t at_index = username_.find('@'); |
| + string partial = username_.substr(0, at_index); |
| + strncpy(name_buffer, partial.c_str(), length); |
| +} |
| + |
| +string UsernamePasskey::GetObfuscatedUsername( |
| + const chromeos::Blob &system_salt) const { |
| + CHECK(!username_.empty()); |
| + |
| + SHA_CTX ctx; |
| + unsigned char md_value[SHA_DIGEST_LENGTH]; |
| + |
| + SHA1_Init(&ctx); |
| + SHA1_Update(&ctx, &system_salt[0], system_salt.size()); |
| + SHA1_Update(&ctx, username_.c_str(), username_.length()); |
| + SHA1_Final(md_value, &ctx); |
| + |
| + chromeos::Blob md_blob(md_value, |
| + md_value + (SHA_DIGEST_LENGTH * sizeof(unsigned char))); |
| + |
| + return chromeos::AsciiEncode(md_blob); |
| +} |
| + |
| +SecureBlob UsernamePasskey::GetPasskey() const { |
| + return passkey_; |
| +} |
| + |
| +} // namespace cryptohome |