Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(490)

Unified Diff: src/platform/pam_offline/authenticator.cc

Issue 2051003: Initial patch from Will. (Closed) Base URL: ssh://git@chromiumos-git/chromiumos
Patch Set: Address style nits. Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/platform/pam_offline/authenticator.cc
diff --git a/src/platform/pam_offline/authenticator.cc b/src/platform/pam_offline/authenticator.cc
deleted file mode 100644
index 66154fa0875221e667f05b2dce6ff213d32a8865..0000000000000000000000000000000000000000
--- a/src/platform/pam_offline/authenticator.cc
+++ /dev/null
@@ -1,210 +0,0 @@
-// 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 "pam_offline/authenticator.h"
-
-#include <openssl/sha.h>
-#include <openssl/evp.h>
-#include <openssl/err.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "chromeos/utility.h"
-#include "base/logging.h"
-
-namespace pam_offline {
-
-using std::string;
-
-// system salt and user dirs start here...
-const string kDefaultShadowRoot = "/home/.shadow/";
-
-// String that appears at the start of OpenSSL cipher text with embedded salt
-const string kOpenSSLMagic = "Salted__";
-
-Authenticator::Authenticator(const string &shadow_root)
- : shadow_root_(shadow_root)
-{}
-
-Authenticator::Authenticator() : shadow_root_(kDefaultShadowRoot) {}
-
-Authenticator::~Authenticator() {}
-
-bool Authenticator::Init() {
- return LoadFileBytes(PathAppend(shadow_root_, "salt"), &system_salt_);
-}
-
-Blob Authenticator::GetSystemSalt() const {
- return system_salt_;
-}
-
-// This is the analog to cryptohome::password_to_wrapper from the
-// cryptohome script. It computes a SHA1(salt + str) and returns an
-// ASCII encoded version of the result as a string. The hashing step is
-// repeated |iters| number of times.
-//
-string Authenticator::IteratedWrapHashedPassword(
- const string &master_salt_file, const string &hashed_password,
- const int iters) const {
-
- string master_salt;
- if (!LoadFileString(master_salt_file, &master_salt)) {
- return false;
- }
-
- Blob blob(hashed_password.begin(), hashed_password.end());
-
- for (int i = 0; i < iters; ++i) {
- SHA_CTX ctx;
- unsigned char md_value[SHA_DIGEST_LENGTH];
-
- SHA1_Init(&ctx);
- SHA1_Update(&ctx, master_salt.c_str(), master_salt.length());
- SHA1_Update(&ctx, &blob.front(), blob.size());
- SHA1_Final(md_value, &ctx);
-
- blob.assign(md_value, md_value + SHA_DIGEST_LENGTH);
- }
-
- return AsciiEncode(blob);
-}
-
-string Authenticator::WrapHashedPassword(
- const string &master_salt_file, const string &hashed_password) const {
- return IteratedWrapHashedPassword(master_salt_file, hashed_password, 1);
-}
-
-bool Authenticator::TestDecrypt(const string passphrase,
- const Blob salt,
- const Blob cipher_text) const {
- if (salt.size() < PKCS5_SALT_LEN) {
- LOG(ERROR) << "Invalid salt";
- return false;
- }
-
- unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
-
- int rv = EVP_BytesToKey(
- EVP_aes_256_cbc(), EVP_sha1(), &salt.front(),
- reinterpret_cast<const unsigned char *>(passphrase.c_str()),
- passphrase.size(), 1, key, iv);
-
- if (rv != EVP_MAX_KEY_LENGTH) {
- LOG(ERROR) << "Key size is " << rv << " bytes, should be "
- << EVP_MAX_KEY_LENGTH;
- return false;
- }
-
- int pt_size = cipher_text.size();
-
- unsigned char *plain_text = new unsigned char[pt_size];
- int final_size = 0;
-
- EVP_CIPHER_CTX d_ctx;
- EVP_CIPHER_CTX_init(&d_ctx);
- EVP_DecryptInit_ex(&d_ctx, EVP_aes_256_ecb(), NULL, key, iv);
- rv = EVP_DecryptUpdate(&d_ctx, plain_text, &pt_size,
- &cipher_text.front(),
- cipher_text.size());
-
- rv = EVP_DecryptFinal_ex(&d_ctx, plain_text + pt_size, &final_size);
-
- pt_size += final_size;
-
- chromeos::SecureMemset(plain_text, sizeof(plain_text), 0);
- delete plain_text;
-
- if (rv != 1) {
- unsigned long err = ERR_get_error();
- ERR_load_ERR_strings();
- ERR_load_crypto_strings();
-
- LOG(INFO) << "OpenSSL Error: " << err
- << ": " << ERR_lib_error_string(err)
- << ", " << ERR_func_error_string(err)
- << ", " << ERR_reason_error_string(err);
-
- return false;
- }
-
- return true;
-}
-
-bool Authenticator::TestOneMasterKey(const string &master_key_file,
- const string &hashed_password) const {
- if (system_salt_.empty()) {
- LOG(ERROR) << "System salt not loaded.";
- return false;
- }
-
- Blob cipher_text;
- if (!LoadFileBytes(master_key_file, &cipher_text)) {
- LOG(ERROR) << "Error loading master key from '" << master_key_file << "'";
- return false;
- }
-
- unsigned int header_size = kOpenSSLMagic.length() + PKCS5_SALT_LEN;
- if (cipher_text.size() <= header_size) {
- LOG(ERROR) << "Master key file too short: '" << master_key_file << "'";
- return false;
- }
-
- string magic(cipher_text.begin(),
- cipher_text.begin() + kOpenSSLMagic.length());
- if (magic != kOpenSSLMagic) {
- LOG(ERROR) << "Invalid magic in master key file: '" << master_key_file
- << "'";
- return false;
- }
-
- Blob salt(cipher_text.begin() + kOpenSSLMagic.length(),
- cipher_text.begin() + header_size);
-
- string passphrase = WrapHashedPassword(master_key_file + ".salt",
- hashed_password);
-
- cipher_text.erase(cipher_text.begin(), cipher_text.begin() + header_size);
- return TestDecrypt(passphrase, salt, cipher_text);
-}
-
-bool Authenticator::TestAllMasterKeys(const Credentials &credentials) const {
-#ifdef CHROMEOS_PAM_LOCALACCOUNT
- if (credentials.IsLocalAccount()) {
- LOG(WARNING) << "Logging in with local account credentials.";
- return true;
- }
-#endif
-
- if (system_salt_.empty()) {
- LOG(ERROR) << "System salt not loaded.";
- return false;
- }
-
- string user_path(PathAppend(shadow_root_,
- credentials.GetObfuscatedUsername(system_salt_)));
- string weak_hash(credentials.GetPasswordWeakHash(system_salt_));
- char index_str[5];
-
- // Test against all of the master keys (master.0, master.1, ...)
- for (int i = 0; /* loop forever */ ; ++i) {
- string master_key_file(PathAppend(user_path, "master."));
- if (0 == snprintf(index_str, sizeof(index_str), "%i", i))
- return false;
- master_key_file.append(index_str);
-
- if (0 != access(master_key_file.c_str(), R_OK)) {
- // master.N can't be read, assume we're done and have failed
- break;
- }
-
- if (TestOneMasterKey(master_key_file, weak_hash)) {
- // decrypted ok, return success
- return true;
- }
- }
-
- return false;
-}
-
-} // namespace pam_offline

Powered by Google App Engine
This is Rietveld 408576698