13daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// 23daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// Copyright (C) 2015 The Android Open Source Project 33daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// 43daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// Licensed under the Apache License, Version 2.0 (the "License"); 53daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// you may not use this file except in compliance with the License. 63daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// You may obtain a copy of the License at 73daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// 83daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// http://www.apache.org/licenses/LICENSE-2.0 93daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// 103daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// Unless required by applicable law or agreed to in writing, software 113daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// distributed under the License is distributed on an "AS IS" BASIS, 123daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// See the License for the specific language governing permissions and 143daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// limitations under the License. 153daa5a0d71ba8facd8be9370df54c20c23be6d8dUtkarsh Sanghi// 16d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 17d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn#include "attestation/server/pkcs11_key_store.h" 18d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 19d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn#include <memory> 20d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn#include <string> 21d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 22d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn#include <base/bind.h> 23d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn#include <base/callback.h> 24d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn#include <base/files/file_path.h> 25d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn#include <base/logging.h> 26d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn#include <base/stl_util.h> 27d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn#include <base/strings/string_util.h> 28d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn#include <chaps/isolate.h> 29d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn#include <chaps/pkcs11/cryptoki.h> 30d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn#include <chaps/token_manager_client.h> 31e270d8c69ab46b2ad2973d5b9395aae7c1f52bf6Alex Vakulenko#include <brillo/cryptohome.h> 32d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn#include <crypto/scoped_openssl_types.h> 33d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn#include <openssl/rsa.h> 34d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn#include <openssl/sha.h> 35d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn#include <openssl/x509.h> 36d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 37d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahnnamespace { 38d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 39d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahnstd::string Sha1(const std::string& input) { 40d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn unsigned char output[SHA_DIGEST_LENGTH]; 41d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn SHA1(reinterpret_cast<const unsigned char*>(input.data()), input.size(), 42d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn output); 43d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return std::string(reinterpret_cast<char*>(output), SHA_DIGEST_LENGTH); 44d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn} 45d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 46d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn} // namespace 47d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 48d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahnnamespace attestation { 49d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 50d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahntypedef crypto::ScopedOpenSSL<X509, X509_free> ScopedX509; 51d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 52d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn// An arbitrary application ID to identify PKCS #11 objects. 53d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahnconst char kApplicationID[] = "CrOS_d5bbc079d2497110feadfc97c40d718ae46f4658"; 54d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 55d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn// A helper class to scope a PKCS #11 session. 56d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahnclass ScopedSession { 57d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn public: 58d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn explicit ScopedSession(CK_SLOT_ID slot) : handle_(CK_INVALID_HANDLE) { 59d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_RV rv = C_Initialize(nullptr); 60d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (rv != CKR_OK && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) { 61d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn // This may be normal in a test environment. 62d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(INFO) << "PKCS #11 is not available."; 63d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return; 64d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 65d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_FLAGS flags = CKF_RW_SESSION | CKF_SERIAL_SESSION; 66d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (C_OpenSession(slot, flags, nullptr, nullptr, &handle_) != CKR_OK) { 67d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Failed to open PKCS #11 session."; 68d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return; 69d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 70d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 71d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 72d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn ~ScopedSession() { 73d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (IsValid() && (C_CloseSession(handle_) != CKR_OK)) { 74d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(WARNING) << "Failed to close PKCS #11 session."; 75d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn handle_ = CK_INVALID_HANDLE; 76d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 77d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 78d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 79d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_SESSION_HANDLE handle() const { 80d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return handle_; 81d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 82d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 83d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn bool IsValid() const { 84d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return (handle_ != CK_INVALID_HANDLE); 85d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 86d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 87d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn private: 88d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_SESSION_HANDLE handle_; 89d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 90d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn DISALLOW_COPY_AND_ASSIGN(ScopedSession); 91d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn}; 92d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 93d7ae21ca48a717fec15836b62701da26d9ec519dDarren KrahnPkcs11KeyStore::Pkcs11KeyStore(chaps::TokenManagerClient* token_manager) 94d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn : token_manager_(token_manager) {} 95d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 96d7ae21ca48a717fec15836b62701da26d9ec519dDarren KrahnPkcs11KeyStore::~Pkcs11KeyStore() {} 97d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 98d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahnbool Pkcs11KeyStore::Read(const std::string& username, 99d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const std::string& key_name, 100d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::string* key_data) { 101d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_SLOT_ID slot; 102d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!GetUserSlot(username, &slot)) { 103594849c7cf872d055575277b930f4f596bef1988Darren Krahn LOG(ERROR) << "Pkcs11KeyStore: No token for user."; 104d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 105d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 106d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn ScopedSession session(slot); 107d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!session.IsValid()) { 108d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Pkcs11KeyStore: Failed to open token session."; 109d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 110d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 111d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_OBJECT_HANDLE key_handle = FindObject(session.handle(), key_name); 112d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (key_handle == CK_INVALID_HANDLE) { 113d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(WARNING) << "Pkcs11KeyStore: Key does not exist: " << key_name; 114d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 115d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 116d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn // First get the attribute with a NULL buffer which will give us the length. 117d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_ATTRIBUTE attribute = {CKA_VALUE, nullptr, 0}; 118d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (C_GetAttributeValue(session.handle(), 119d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn key_handle, 120d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn &attribute, 1) != CKR_OK) { 121d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Pkcs11KeyStore: Failed to read key data: " << key_name; 122d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 123d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 124d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn key_data->resize(attribute.ulValueLen); 125d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn attribute.pValue = string_as_array(key_data); 126d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (C_GetAttributeValue(session.handle(), 127d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn key_handle, 128d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn &attribute, 1) != CKR_OK) { 129d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Pkcs11KeyStore: Failed to read key data: " << key_name; 130d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 131d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 132d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn key_data->resize(attribute.ulValueLen); 133d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return true; 134d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn} 135d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 136d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahnbool Pkcs11KeyStore::Write(const std::string& username, 137d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const std::string& key_name, 138d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const std::string& key_data) { 139d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn // Delete any existing key with the same name. 140d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!Delete(username, key_name)) { 141d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 142d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 143d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_SLOT_ID slot; 144d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!GetUserSlot(username, &slot)) { 145594849c7cf872d055575277b930f4f596bef1988Darren Krahn LOG(ERROR) << "Pkcs11KeyStore: No token for user."; 146d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 147d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 148d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn ScopedSession session(slot); 149d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!session.IsValid()) { 150d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Pkcs11KeyStore: Failed to open token session."; 151d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 152d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 153d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::string mutable_key_name(key_name); 154d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::string mutable_key_data(key_data); 155d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::string mutable_application_id(kApplicationID); 156d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn // Create a new data object for the key. 157d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_OBJECT_CLASS object_class = CKO_DATA; 158d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_BBOOL true_value = CK_TRUE; 159d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_BBOOL false_value = CK_FALSE; 160d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_ATTRIBUTE attributes[] = { 161d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_CLASS, &object_class, sizeof(object_class)}, 162d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn { 163d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CKA_LABEL, 164d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn string_as_array(&mutable_key_name), 165d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn mutable_key_name.size() 166d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn }, 167d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn { 168d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CKA_VALUE, 169d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn string_as_array(&mutable_key_data), 170d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn mutable_key_data.size() 171d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn }, 172d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn { 173d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CKA_APPLICATION, 174d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn string_as_array(&mutable_application_id), 175d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn mutable_application_id.size() 176d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn }, 177d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_TOKEN, &true_value, sizeof(true_value)}, 178d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_PRIVATE, &true_value, sizeof(true_value)}, 179d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_MODIFIABLE, &false_value, sizeof(false_value)} 180d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn }; 181d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_OBJECT_HANDLE key_handle = CK_INVALID_HANDLE; 182d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (C_CreateObject(session.handle(), 183d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn attributes, 184d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn arraysize(attributes), 185d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn &key_handle) != CKR_OK) { 186d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Pkcs11KeyStore: Failed to write key data: " << key_name; 187d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 188d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 189d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return true; 190d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn} 191d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 192d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahnbool Pkcs11KeyStore::Delete(const std::string& username, 193d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const std::string& key_name) { 194d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_SLOT_ID slot; 195d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!GetUserSlot(username, &slot)) { 196594849c7cf872d055575277b930f4f596bef1988Darren Krahn LOG(ERROR) << "Pkcs11KeyStore: No token for user."; 197d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 198d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 199d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn ScopedSession session(slot); 200d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!session.IsValid()) { 201d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Pkcs11KeyStore: Failed to open token session."; 202d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 203d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 204d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_OBJECT_HANDLE key_handle = FindObject(session.handle(), key_name); 205d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (key_handle != CK_INVALID_HANDLE) { 206d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (C_DestroyObject(session.handle(), key_handle) != CKR_OK) { 207d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Pkcs11KeyStore: Failed to delete key data."; 208d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 209d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 210d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 211d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return true; 212d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn} 213d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 214d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahnbool Pkcs11KeyStore::DeleteByPrefix(const std::string& username, 215d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const std::string& key_prefix) { 216d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_SLOT_ID slot; 217d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!GetUserSlot(username, &slot)) { 218594849c7cf872d055575277b930f4f596bef1988Darren Krahn LOG(ERROR) << "Pkcs11KeyStore: No token for user."; 219d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 220d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 221d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn ScopedSession session(slot); 222d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!session.IsValid()) { 223d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Pkcs11KeyStore: Failed to open token session."; 224d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 225d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 226d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn EnumObjectsCallback callback = base::Bind( 227d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn &Pkcs11KeyStore::DeleteIfMatchesPrefix, 228d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn base::Unretained(this), 229d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn session.handle(), 230d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn key_prefix); 231d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!EnumObjects(session.handle(), callback)) { 232d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Pkcs11KeyStore: Failed to delete key data."; 233d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 234d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 235d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return true; 236d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn} 237d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 238d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahnbool Pkcs11KeyStore::Register(const std::string& username, 239d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const std::string& label, 240594849c7cf872d055575277b930f4f596bef1988Darren Krahn KeyType key_type, 241594849c7cf872d055575277b930f4f596bef1988Darren Krahn KeyUsage key_usage, 242d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const std::string& private_key_blob, 243d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const std::string& public_key_der, 244d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const std::string& certificate) { 245d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const CK_ATTRIBUTE_TYPE kKeyBlobAttribute = CKA_VENDOR_DEFINED + 1; 246d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 247594849c7cf872d055575277b930f4f596bef1988Darren Krahn if (key_type != KEY_TYPE_RSA) { 248594849c7cf872d055575277b930f4f596bef1988Darren Krahn LOG(ERROR) << "Pkcs11KeyStore: Only RSA supported."; 249594849c7cf872d055575277b930f4f596bef1988Darren Krahn return false; 250594849c7cf872d055575277b930f4f596bef1988Darren Krahn } 251d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_SLOT_ID slot; 252d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!GetUserSlot(username, &slot)) { 253594849c7cf872d055575277b930f4f596bef1988Darren Krahn LOG(ERROR) << "Pkcs11KeyStore: No token for user."; 254d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 255d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 256d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn ScopedSession session(slot); 257d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!session.IsValid()) { 258d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Pkcs11KeyStore: Failed to open token session."; 259d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 260d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 261d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 262d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn // Extract the modulus from the public key. 263d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const unsigned char* asn1_ptr = reinterpret_cast<const unsigned char*>( 264d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn public_key_der.data()); 265d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn crypto::ScopedRSA public_key(d2i_RSAPublicKey(nullptr, 266d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn &asn1_ptr, 267d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn public_key_der.size())); 268d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!public_key.get()) { 269d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Pkcs11KeyStore: Failed to decode public key."; 270d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 271d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 272d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::string modulus(BN_num_bytes(public_key.get()->n), 0); 273d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn int length = BN_bn2bin(public_key.get()->n, reinterpret_cast<unsigned char*>( 274d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn string_as_array(&modulus))); 275d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (length <= 0) { 276d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Pkcs11KeyStore: Failed to extract public key modulus."; 277d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 278d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 279d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn modulus.resize(length); 280d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 281d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn // Construct a PKCS #11 template for the public key object. 282d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_BBOOL true_value = CK_TRUE; 283d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_BBOOL false_value = CK_FALSE; 284594849c7cf872d055575277b930f4f596bef1988Darren Krahn CK_KEY_TYPE p11_key_type = CKK_RSA; 285d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_OBJECT_CLASS public_key_class = CKO_PUBLIC_KEY; 286d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::string id = Sha1(modulus); 287d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::string mutable_label(label); 288d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_ULONG modulus_bits = modulus.size() * 8; 289594849c7cf872d055575277b930f4f596bef1988Darren Krahn CK_BBOOL sign_usage = (key_usage == KEY_USAGE_SIGN); 290594849c7cf872d055575277b930f4f596bef1988Darren Krahn CK_BBOOL decrypt_usage = (key_usage == KEY_USAGE_DECRYPT); 291d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn unsigned char public_exponent[] = {1, 0, 1}; 292d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_ATTRIBUTE public_key_attributes[] = { 293d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_CLASS, &public_key_class, sizeof(public_key_class)}, 294d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_TOKEN, &true_value, sizeof(true_value)}, 295d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_DERIVE, &false_value, sizeof(false_value)}, 296d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_WRAP, &false_value, sizeof(false_value)}, 297594849c7cf872d055575277b930f4f596bef1988Darren Krahn {CKA_VERIFY, &sign_usage, sizeof(sign_usage)}, 298d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_VERIFY_RECOVER, &false_value, sizeof(false_value)}, 299594849c7cf872d055575277b930f4f596bef1988Darren Krahn {CKA_ENCRYPT, &decrypt_usage, sizeof(decrypt_usage)}, 300594849c7cf872d055575277b930f4f596bef1988Darren Krahn {CKA_KEY_TYPE, &p11_key_type, sizeof(p11_key_type)}, 301d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_ID, string_as_array(&id), id.size()}, 302d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_LABEL, string_as_array(&mutable_label), mutable_label.size()}, 303d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_MODULUS_BITS, &modulus_bits, sizeof(modulus_bits)}, 304d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_PUBLIC_EXPONENT, public_exponent, arraysize(public_exponent)}, 305d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_MODULUS, string_as_array(&modulus), modulus.size()} 306d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn }; 307d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 308d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_OBJECT_HANDLE object_handle = CK_INVALID_HANDLE; 309d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (C_CreateObject(session.handle(), 310d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn public_key_attributes, 311d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn arraysize(public_key_attributes), 312d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn &object_handle) != CKR_OK) { 313d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Pkcs11KeyStore: Failed to create public key object."; 314d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 315d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 316d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 317d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn // Construct a PKCS #11 template for the private key object. 318d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::string mutable_private_key_blob(private_key_blob); 319d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_OBJECT_CLASS private_key_class = CKO_PRIVATE_KEY; 320d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_ATTRIBUTE private_key_attributes[] = { 321d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_CLASS, &private_key_class, sizeof(private_key_class)}, 322d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_TOKEN, &true_value, sizeof(true_value)}, 323d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_PRIVATE, &true_value, sizeof(true_value)}, 324d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_SENSITIVE, &true_value, sizeof(true_value)}, 325d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_EXTRACTABLE, &false_value, sizeof(false_value)}, 326d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_DERIVE, &false_value, sizeof(false_value)}, 327d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_UNWRAP, &false_value, sizeof(false_value)}, 328594849c7cf872d055575277b930f4f596bef1988Darren Krahn {CKA_SIGN, &sign_usage, sizeof(sign_usage)}, 329d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_SIGN_RECOVER, &false_value, sizeof(false_value)}, 330594849c7cf872d055575277b930f4f596bef1988Darren Krahn {CKA_DECRYPT, &decrypt_usage, sizeof(decrypt_usage)}, 331594849c7cf872d055575277b930f4f596bef1988Darren Krahn {CKA_KEY_TYPE, &p11_key_type, sizeof(p11_key_type)}, 332d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_ID, string_as_array(&id), id.size()}, 333d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_LABEL, string_as_array(&mutable_label), mutable_label.size()}, 334d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_PUBLIC_EXPONENT, public_exponent, arraysize(public_exponent)}, 335d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_MODULUS, string_as_array(&modulus), modulus.size()}, 336d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn { 337d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn kKeyBlobAttribute, 338d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn string_as_array(&mutable_private_key_blob), 339d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn mutable_private_key_blob.size() 340d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 341d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn }; 342d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 343d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (C_CreateObject(session.handle(), 344d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn private_key_attributes, 345d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn arraysize(private_key_attributes), 346d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn &object_handle) != CKR_OK) { 347d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Pkcs11KeyStore: Failed to create private key object."; 348d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 349d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 350d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 351d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!certificate.empty()) { 352d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::string subject; 353594849c7cf872d055575277b930f4f596bef1988Darren Krahn std::string issuer; 354594849c7cf872d055575277b930f4f596bef1988Darren Krahn std::string serial_number; 355594849c7cf872d055575277b930f4f596bef1988Darren Krahn if (!GetCertificateFields(certificate, &subject, &issuer, &serial_number)) { 356594849c7cf872d055575277b930f4f596bef1988Darren Krahn LOG(WARNING) << "Pkcs11KeyStore: Failed to find certificate fields."; 357d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 358d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn // Construct a PKCS #11 template for a certificate object. 359d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::string mutable_certificate = certificate; 360d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_OBJECT_CLASS certificate_class = CKO_CERTIFICATE; 361d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_CERTIFICATE_TYPE certificate_type = CKC_X_509; 362d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_ATTRIBUTE certificate_attributes[] = { 363d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_CLASS, &certificate_class, sizeof(certificate_class)}, 364d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_TOKEN, &true_value, sizeof(true_value)}, 365d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_PRIVATE, &false_value, sizeof(false_value)}, 366d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_ID, string_as_array(&id), id.size()}, 367d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_LABEL, string_as_array(&mutable_label), mutable_label.size()}, 368d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_CERTIFICATE_TYPE, &certificate_type, sizeof(certificate_type)}, 369d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_SUBJECT, string_as_array(&subject), subject.size()}, 370594849c7cf872d055575277b930f4f596bef1988Darren Krahn {CKA_ISSUER, string_as_array(&issuer), issuer.size()}, 371594849c7cf872d055575277b930f4f596bef1988Darren Krahn { 372594849c7cf872d055575277b930f4f596bef1988Darren Krahn CKA_SERIAL_NUMBER, 373594849c7cf872d055575277b930f4f596bef1988Darren Krahn string_as_array(&serial_number), 374594849c7cf872d055575277b930f4f596bef1988Darren Krahn serial_number.size() 375594849c7cf872d055575277b930f4f596bef1988Darren Krahn }, 376d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn { 377d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CKA_VALUE, 378d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn string_as_array(&mutable_certificate), 379d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn mutable_certificate.size() 380d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 381d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn }; 382d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 383d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (C_CreateObject(session.handle(), 384d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn certificate_attributes, 385d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn arraysize(certificate_attributes), 386d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn &object_handle) != CKR_OK) { 387d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Pkcs11KeyStore: Failed to create certificate object."; 388d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 389d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 390d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 391d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 392d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn // Close all sessions in an attempt to trigger other modules to find the new 393d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn // objects. 394d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn C_CloseAllSessions(slot); 395d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 396d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return true; 397d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn} 398d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 399d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahnbool Pkcs11KeyStore::RegisterCertificate(const std::string& username, 400d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const std::string& certificate) { 401d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_SLOT_ID slot; 402d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!GetUserSlot(username, &slot)) { 403594849c7cf872d055575277b930f4f596bef1988Darren Krahn LOG(ERROR) << "Pkcs11KeyStore: No token for user."; 404d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 405d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 406d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn ScopedSession session(slot); 407d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!session.IsValid()) { 408d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Pkcs11KeyStore: Failed to open token session."; 409d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 410d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 411d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 412d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (DoesCertificateExist(session.handle(), certificate)) { 413d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(INFO) << "Pkcs11KeyStore: Certificate already exists."; 414d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return true; 415d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 416d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::string subject; 417594849c7cf872d055575277b930f4f596bef1988Darren Krahn std::string issuer; 418594849c7cf872d055575277b930f4f596bef1988Darren Krahn std::string serial_number; 419594849c7cf872d055575277b930f4f596bef1988Darren Krahn if (!GetCertificateFields(certificate, &subject, &issuer, &serial_number)) { 420594849c7cf872d055575277b930f4f596bef1988Darren Krahn LOG(WARNING) << "Pkcs11KeyStore: Failed to find certificate fields."; 421d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 422d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn // Construct a PKCS #11 template for a certificate object. 423d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::string mutable_certificate = certificate; 424d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_OBJECT_CLASS certificate_class = CKO_CERTIFICATE; 425d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_CERTIFICATE_TYPE certificate_type = CKC_X_509; 426d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_BBOOL true_value = CK_TRUE; 427d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_BBOOL false_value = CK_FALSE; 428d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_ATTRIBUTE certificate_attributes[] = { 429d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_CLASS, &certificate_class, sizeof(certificate_class)}, 430d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_TOKEN, &true_value, sizeof(true_value)}, 431d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_PRIVATE, &false_value, sizeof(false_value)}, 432d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_CERTIFICATE_TYPE, &certificate_type, sizeof(certificate_type)}, 433d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_SUBJECT, string_as_array(&subject), subject.size()}, 434594849c7cf872d055575277b930f4f596bef1988Darren Krahn {CKA_ISSUER, string_as_array(&issuer), issuer.size()}, 435594849c7cf872d055575277b930f4f596bef1988Darren Krahn {CKA_SERIAL_NUMBER, string_as_array(&serial_number), serial_number.size()}, 436d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn { 437d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CKA_VALUE, 438d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn string_as_array(&mutable_certificate), 439d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn mutable_certificate.size() 440d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 441d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn }; 442d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_OBJECT_HANDLE object_handle = CK_INVALID_HANDLE; 443d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (C_CreateObject(session.handle(), 444d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn certificate_attributes, 445d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn arraysize(certificate_attributes), 446d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn &object_handle) != CKR_OK) { 447d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Pkcs11KeyStore: Failed to create certificate object."; 448d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 449d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 450d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return true; 451d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn} 452d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 453d7ae21ca48a717fec15836b62701da26d9ec519dDarren KrahnCK_OBJECT_HANDLE Pkcs11KeyStore::FindObject(CK_SESSION_HANDLE session_handle, 454d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const std::string& key_name) { 455d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn // Assemble a search template. 456d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::string mutable_key_name(key_name); 457d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::string mutable_application_id(kApplicationID); 458d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_OBJECT_CLASS object_class = CKO_DATA; 459d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_BBOOL true_value = CK_TRUE; 460d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_BBOOL false_value = CK_FALSE; 461d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_ATTRIBUTE attributes[] = { 462d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_CLASS, &object_class, sizeof(object_class)}, 463d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn { 464d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CKA_LABEL, 465d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn string_as_array(&mutable_key_name), 466d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn mutable_key_name.size() 467d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn }, 468d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn { 469d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CKA_APPLICATION, 470d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn string_as_array(&mutable_application_id), 471d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn mutable_application_id.size() 472d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn }, 473d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_TOKEN, &true_value, sizeof(true_value)}, 474d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_PRIVATE, &true_value, sizeof(true_value)}, 475d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_MODIFIABLE, &false_value, sizeof(false_value)} 476d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn }; 477d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_OBJECT_HANDLE key_handle = CK_INVALID_HANDLE; 478d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_ULONG count = 0; 479d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if ((C_FindObjectsInit(session_handle, 480d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn attributes, 481d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn arraysize(attributes)) != CKR_OK) || 482d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn (C_FindObjects(session_handle, &key_handle, 1, &count) != CKR_OK) || 483d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn (C_FindObjectsFinal(session_handle) != CKR_OK)) { 484d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Key search failed: " << key_name; 485d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return CK_INVALID_HANDLE; 486d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 487d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (count == 1) 488d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return key_handle; 489d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return CK_INVALID_HANDLE; 490d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn} 491d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 492d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahnbool Pkcs11KeyStore::GetUserSlot(const std::string& username, 493d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_SLOT_ID_PTR slot) { 494d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const char kChapsDaemonName[] = "chaps"; 495d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const char kChapsSystemToken[] = "/var/lib/chaps"; 496d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn base::FilePath token_path = username.empty() ? 497d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn base::FilePath(kChapsSystemToken) : 498e270d8c69ab46b2ad2973d5b9395aae7c1f52bf6Alex Vakulenko brillo::cryptohome::home::GetDaemonPath(username, kChapsDaemonName); 499d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_RV rv; 500d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn rv = C_Initialize(nullptr); 501d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (rv != CKR_OK && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) { 502d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(WARNING) << __func__ << ": C_Initialize failed."; 503d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 504d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 505d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_ULONG num_slots = 0; 506d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn rv = C_GetSlotList(CK_TRUE, nullptr, &num_slots); 507d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (rv != CKR_OK) { 508d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(WARNING) << __func__ << ": C_GetSlotList(nullptr) failed."; 509d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 510d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 511d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::unique_ptr<CK_SLOT_ID[]> slot_list(new CK_SLOT_ID[num_slots]); 512d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn rv = C_GetSlotList(CK_TRUE, slot_list.get(), &num_slots); 513d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (rv != CKR_OK) { 514d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(WARNING) << __func__ << ": C_GetSlotList failed."; 515d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 516d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 517d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn // Look through all slots for |token_path|. 518d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn for (CK_ULONG i = 0; i < num_slots; ++i) { 519d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn base::FilePath slot_path; 520d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (token_manager_->GetTokenPath( 521d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn chaps::IsolateCredentialManager::GetDefaultIsolateCredential(), 522d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn slot_list[i], 523d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn &slot_path) && (token_path == slot_path)) { 524d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn *slot = slot_list[i]; 525d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return true; 526d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 527d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 528d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(WARNING) << __func__ << ": Path not found."; 529d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 530d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn} 531d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 532d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahnbool Pkcs11KeyStore::EnumObjects( 533d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_SESSION_HANDLE session_handle, 534d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const Pkcs11KeyStore::EnumObjectsCallback& callback) { 535d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::string mutable_application_id(kApplicationID); 536d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn // Assemble a search template. 537d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_OBJECT_CLASS object_class = CKO_DATA; 538d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_BBOOL true_value = CK_TRUE; 539d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_BBOOL false_value = CK_FALSE; 540d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_ATTRIBUTE attributes[] = { 541d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_CLASS, &object_class, sizeof(object_class)}, 542d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn { 543d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CKA_APPLICATION, 544d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn string_as_array(&mutable_application_id), 545d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn mutable_application_id.size() 546d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn }, 547d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_TOKEN, &true_value, sizeof(true_value)}, 548d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_PRIVATE, &true_value, sizeof(true_value)}, 549d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_MODIFIABLE, &false_value, sizeof(false_value)} 550d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn }; 551d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const CK_ULONG kMaxHandles = 100; // Arbitrary. 552d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_OBJECT_HANDLE handles[kMaxHandles]; 553d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_ULONG count = 0; 554d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if ((C_FindObjectsInit(session_handle, 555d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn attributes, 556d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn arraysize(attributes)) != CKR_OK) || 557d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn (C_FindObjects(session_handle, handles, kMaxHandles, &count) != CKR_OK)) { 558d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Key search failed."; 559d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 560d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 561d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn while (count > 0) { 562d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn for (CK_ULONG i = 0; i < count; ++i) { 563d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::string key_name; 564d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!GetKeyName(session_handle, handles[i], &key_name)) { 565d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(WARNING) << "Found key object but failed to get name."; 566d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn continue; 567d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 568d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!callback.Run(key_name, handles[i])) 569d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 570d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 571d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (C_FindObjects(session_handle, handles, kMaxHandles, &count) != CKR_OK) { 572d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "Key search continuation failed."; 573d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 574d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 575d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 576d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (C_FindObjectsFinal(session_handle) != CKR_OK) { 577d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(WARNING) << "Failed to finalize key search."; 578d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 579d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return true; 580d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn} 581d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 582d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahnbool Pkcs11KeyStore::GetKeyName(CK_SESSION_HANDLE session_handle, 583d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_OBJECT_HANDLE object_handle, 584d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::string* key_name) { 585d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_ATTRIBUTE attribute = {CKA_LABEL, nullptr, 0}; 586d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (C_GetAttributeValue(session_handle, object_handle, &attribute, 1) != 587d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CKR_OK) { 588d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "C_GetAttributeValue(CKA_LABEL) [length] failed."; 589d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 590d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 591d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn key_name->resize(attribute.ulValueLen); 592d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn attribute.pValue = string_as_array(key_name); 593d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (C_GetAttributeValue(session_handle, object_handle, &attribute, 1) != 594d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CKR_OK) { 595d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "C_GetAttributeValue(CKA_LABEL) failed."; 596d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 597d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 598d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return true; 599d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn} 600d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 601d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahnbool Pkcs11KeyStore::DeleteIfMatchesPrefix(CK_SESSION_HANDLE session_handle, 602d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const std::string& key_prefix, 603d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const std::string& key_name, 604d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_OBJECT_HANDLE object_handle) { 6057e763a9434e12c7980529980de5f8eced22b310aAlex Vakulenko if (base::StartsWith(key_name, key_prefix, base::CompareCase::SENSITIVE)) { 606d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (C_DestroyObject(session_handle, object_handle) != CKR_OK) { 607d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(ERROR) << "C_DestroyObject failed."; 608d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 609d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 610d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 611d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return true; 612d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn} 613d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 614594849c7cf872d055575277b930f4f596bef1988Darren Krahnbool Pkcs11KeyStore::GetCertificateFields(const std::string& certificate, 615594849c7cf872d055575277b930f4f596bef1988Darren Krahn std::string* subject, 616594849c7cf872d055575277b930f4f596bef1988Darren Krahn std::string* issuer, 617594849c7cf872d055575277b930f4f596bef1988Darren Krahn std::string* serial_number) { 618d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const unsigned char* asn1_ptr = reinterpret_cast<const unsigned char*>( 619d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn certificate.data()); 620d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn ScopedX509 x509(d2i_X509(nullptr, &asn1_ptr, certificate.size())); 621d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (!x509.get() || !x509->cert_info || !x509->cert_info->subject) { 622d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(WARNING) << "Pkcs11KeyStore: Failed to decode certificate."; 623d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 624d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 625594849c7cf872d055575277b930f4f596bef1988Darren Krahn unsigned char* subject_buffer = nullptr; 626594849c7cf872d055575277b930f4f596bef1988Darren Krahn int length = i2d_X509_NAME(x509->cert_info->subject, &subject_buffer); 627594849c7cf872d055575277b930f4f596bef1988Darren Krahn crypto::ScopedOpenSSLBytes scoped_subject_buffer(subject_buffer); 628d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if (length <= 0) { 629d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn LOG(WARNING) << "Pkcs11KeyStore: Failed to encode certificate subject."; 630d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 631d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 632594849c7cf872d055575277b930f4f596bef1988Darren Krahn subject->assign(reinterpret_cast<char*>(subject_buffer), length); 633594849c7cf872d055575277b930f4f596bef1988Darren Krahn 634594849c7cf872d055575277b930f4f596bef1988Darren Krahn unsigned char* issuer_buffer = nullptr; 635594849c7cf872d055575277b930f4f596bef1988Darren Krahn length = i2d_X509_NAME(x509->cert_info->issuer, &issuer_buffer); 636594849c7cf872d055575277b930f4f596bef1988Darren Krahn crypto::ScopedOpenSSLBytes scoped_issuer_buffer(issuer_buffer); 637594849c7cf872d055575277b930f4f596bef1988Darren Krahn if (length <= 0) { 638594849c7cf872d055575277b930f4f596bef1988Darren Krahn LOG(WARNING) << "Pkcs11KeyStore: Failed to encode certificate issuer."; 639594849c7cf872d055575277b930f4f596bef1988Darren Krahn return false; 640594849c7cf872d055575277b930f4f596bef1988Darren Krahn } 641594849c7cf872d055575277b930f4f596bef1988Darren Krahn issuer->assign(reinterpret_cast<char*>(issuer_buffer), length); 642594849c7cf872d055575277b930f4f596bef1988Darren Krahn 643594849c7cf872d055575277b930f4f596bef1988Darren Krahn unsigned char* serial_number_buffer = nullptr; 644594849c7cf872d055575277b930f4f596bef1988Darren Krahn length = i2d_ASN1_INTEGER(x509->cert_info->serialNumber, 645594849c7cf872d055575277b930f4f596bef1988Darren Krahn &serial_number_buffer); 646594849c7cf872d055575277b930f4f596bef1988Darren Krahn crypto::ScopedOpenSSLBytes scoped_serial_number_buffer(serial_number_buffer); 647594849c7cf872d055575277b930f4f596bef1988Darren Krahn if (length <= 0) { 648594849c7cf872d055575277b930f4f596bef1988Darren Krahn LOG(WARNING) << "Pkcs11KeyStore: Failed to encode certificate serial " 649594849c7cf872d055575277b930f4f596bef1988Darren Krahn "number."; 650594849c7cf872d055575277b930f4f596bef1988Darren Krahn return false; 651594849c7cf872d055575277b930f4f596bef1988Darren Krahn } 652594849c7cf872d055575277b930f4f596bef1988Darren Krahn serial_number->assign(reinterpret_cast<char*>(serial_number_buffer), length); 653d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return true; 654d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn} 655d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 656d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahnbool Pkcs11KeyStore::DoesCertificateExist( 657d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_SESSION_HANDLE session_handle, 658d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn const std::string& certificate) { 659d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_OBJECT_CLASS object_class = CKO_CERTIFICATE; 660d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_BBOOL true_value = CK_TRUE; 661d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_BBOOL false_value = CK_FALSE; 662d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn std::string mutable_certificate = certificate; 663d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_ATTRIBUTE attributes[] = { 664d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_CLASS, &object_class, sizeof(object_class)}, 665d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_TOKEN, &true_value, sizeof(true_value)}, 666d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn {CKA_PRIVATE, &false_value, sizeof(false_value)}, 667d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn { 668d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CKA_VALUE, 669d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn string_as_array(&mutable_certificate), 670d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn mutable_certificate.size() 671d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 672d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn }; 673d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_OBJECT_HANDLE object_handle = CK_INVALID_HANDLE; 674d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn CK_ULONG count = 0; 675d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn if ((C_FindObjectsInit(session_handle, 676d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn attributes, 677d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn arraysize(attributes)) != CKR_OK) || 678d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn (C_FindObjects(session_handle, &object_handle, 1, &count) != CKR_OK) || 679d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn (C_FindObjectsFinal(session_handle) != CKR_OK)) { 680d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return false; 681d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn } 682d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn return (count > 0); 683d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn} 684d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn 685d7ae21ca48a717fec15836b62701da26d9ec519dDarren Krahn} // namespace attestation 686