blob: 1dc00629ac99cdaf6da51cdc3e141b3b8b24f4f7 [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 Pkcs11Init.
#include "pkcs11_init.h"
#include <string.h>
#include <base/logging.h>
#include <base/string_util.h>
#include <base/stringprintf.h>
#include <chromeos/cryptohome.h>
#include <errno.h>
#include <glib.h>
namespace cryptohome {
// static
const CK_SLOT_ID Pkcs11Init::kDefaultTpmSlotId = 0;
const CK_ULONG Pkcs11Init::kMaxLabelLen = 32;
const CK_CHAR Pkcs11Init::kDefaultUserPin[] = "111111";
const CK_CHAR Pkcs11Init::kDefaultLabel[] = "User-Specific TPM Token";
extern const char* kTpmOwnedFile;
void Pkcs11Init::GetTpmTokenInfo(gchar **OUT_label,
gchar **OUT_user_pin) {
*OUT_label = g_strdup(reinterpret_cast<const gchar *>(kDefaultLabel));
*OUT_user_pin = g_strdup(reinterpret_cast<const gchar *>(kDefaultUserPin));
}
void Pkcs11Init::GetTpmTokenInfoForUser(gchar *username,
gchar **OUT_label,
gchar **OUT_user_pin) {
// TODO(ellyjones): make this work for real, perhaps? crosbug.com/22127
*OUT_label = g_strdup(reinterpret_cast<const gchar *>(kDefaultLabel));
*OUT_user_pin = g_strdup(reinterpret_cast<const gchar *>(kDefaultUserPin));
}
bool Pkcs11Init::IsUserTokenBroken() {
if (!platform_->FileExists(kTpmOwnedFile)) {
LOG(WARNING) << "TPM is not owned, token can not be valid.";
return true;
}
if (!CheckTokenInSlot(kDefaultTpmSlotId, kDefaultLabel)) {
LOG(WARNING) << "Token failed basic sanity checks. Can not be valid.";
return true;
}
LOG(INFO) << "PKCS#11 token looks ok.";
return false;
}
bool Pkcs11Init::CheckTokenInSlot(CK_SLOT_ID slot_id,
const CK_CHAR* expected_label) {
CK_RV rv;
CK_SESSION_HANDLE session_handle = 0;
CK_SESSION_INFO session_info;
CK_TOKEN_INFO token_info;
rv = C_Initialize(NULL);
if (rv != CKR_OK && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
LOG(WARNING) << "C_Initialize failed while checking token: "
<< std::hex << rv;
return false;
}
rv = C_OpenSession(slot_id, CKF_RW_SESSION | CKF_SERIAL_SESSION,
NULL, NULL,
&session_handle);
if (rv != CKR_OK) {
LOG(WARNING) << "Could not open session on slot " << slot_id
<< " while checking token." << std::hex << rv;
C_CloseAllSessions(slot_id);
return false;
}
memset(&session_info, 0, sizeof(session_info));
rv = C_GetSessionInfo(session_handle, &session_info);
if (rv != CKR_OK || session_info.slotID != slot_id) {
LOG(WARNING) << "Could not get session info on " << slot_id
<< " while checking token: " << std::hex << rv;
C_CloseAllSessions(slot_id);
return false;
}
rv = C_GetTokenInfo(slot_id, &token_info);
if (rv != CKR_OK || !(token_info.flags & CKF_TOKEN_INITIALIZED)) {
LOG(WARNING) << "Could not get token info on " << slot_id
<< " while checking token: " << std::hex << rv;
C_CloseAllSessions(slot_id);
return false;
}
if (strncmp(reinterpret_cast<const char*>(expected_label),
reinterpret_cast<const char*>(token_info.label),
kMaxLabelLen)) {
LOG(WARNING) << "Token Label (" << token_info.label << ") does not match "
<< "expected label (" << expected_label << ")";
return false;
}
C_CloseAllSessions(slot_id);
return true;
}
} // namespace cryptohome