blob: 2c2cbb49fef467449c376d227a55fb721349af21 [file] [log] [blame]
// Copyright (c) 2012 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.
// Contains the implementation of class Mount
#include "cryptohome/user_session.h"
#include <string>
#include <openssl/evp.h>
#include <base/logging.h>
#include "cryptohome/cryptohome_metrics.h"
#include "cryptohome/cryptolib.h"
using brillo::SecureBlob;
namespace cryptohome {
const int kUserSessionIdLength = 128;
UserSession::UserSession() { }
UserSession::~UserSession() { }
void UserSession::Init(const SecureBlob& salt) {
username_salt_.assign(salt.begin(), salt.end());
}
bool UserSession::SetUser(const Credentials& credentials) {
obfuscated_username_ = credentials.GetObfuscatedUsername(username_salt_);
username_ = credentials.username();
key_data_ = credentials.key_data();
key_index_ = -1; // Invalid key index.
key_salt_ = CryptoLib::CreateSecureRandomBlob(PKCS5_SALT_LEN);
const auto plaintext =
CryptoLib::CreateSecureRandomBlob(kUserSessionIdLength);
SecureBlob passkey;
credentials.GetPasskey(&passkey);
SecureBlob aes_key;
SecureBlob aes_iv;
if (!CryptoLib::PasskeyToAesKey(passkey,
key_salt_,
cryptohome::kDefaultPasswordRounds,
&aes_key,
&aes_iv)) {
return false;
}
return CryptoLib::AesEncryptDeprecated(plaintext, aes_key, aes_iv, &cipher_);
}
void UserSession::Reset() {
username_ = "";
obfuscated_username_ = "";
key_salt_.resize(0);
cipher_.resize(0);
key_index_ = -1;
key_data_.Clear();
}
bool UserSession::CheckUser(const std::string& obfuscated_username) const {
return obfuscated_username_ == obfuscated_username;
}
bool UserSession::Verify(const Credentials& credentials) const {
ReportTimerStart(kSessionUnlockTimer);
if (!CheckUser(credentials.GetObfuscatedUsername(username_salt_))) {
return false;
}
// If the incoming credentials have no label, then just
// test the secret. If it is labeled, then the label must
// match.
if (!credentials.key_data().label().empty() &&
credentials.key_data().label() != key_data_.label()) {
return false;
}
SecureBlob passkey;
credentials.GetPasskey(&passkey);
SecureBlob aes_key;
SecureBlob aes_iv;
if (!CryptoLib::PasskeyToAesKey(passkey,
key_salt_,
cryptohome::kDefaultPasswordRounds,
&aes_key,
&aes_iv)) {
return false;
}
SecureBlob plaintext;
bool status =
CryptoLib::AesDecryptDeprecated(cipher_, aes_key, aes_iv, &plaintext);
ReportTimerStop(kSessionUnlockTimer);
return status;
}
void UserSession::GetObfuscatedUsername(std::string* username) const {
username->assign(obfuscated_username_);
}
int UserSession::key_index() const {
LOG_IF(WARNING, key_index_ < 0)
<< "Attempt to access an uninitialized key_index."
<< "Guest mount? Ephemeral mount?";
return key_index_;
}
} // namespace cryptohome