| /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
| /** |
| * Copyright (c) 2013-2014 Regents of the University of California. |
| * |
| * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions). |
| * |
| * ndn-cxx library is free software: you can redistribute it and/or modify it under the |
| * terms of the GNU Lesser General Public License as published by the Free Software |
| * Foundation, either version 3 of the License, or (at your option) any later version. |
| * |
| * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
| * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. |
| * |
| * You should have received copies of the GNU General Public License and GNU Lesser |
| * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see |
| * <http://www.gnu.org/licenses/>. |
| * |
| * See AUTHORS.md for complete list of ndn-cxx authors and contributors. |
| * |
| * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/> |
| * @author Jeff Thompson <jefft0@remap.ucla.edu> |
| */ |
| |
| #include "sec-public-info-sqlite3.hpp" |
| #include "identity-certificate.hpp" |
| #include "signature-sha256-with-rsa.hpp" |
| #include "signature-sha256-with-ecdsa.hpp" |
| #include "../data.hpp" |
| |
| #include <sqlite3.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <sstream> |
| #include <fstream> |
| #include <boost/filesystem.hpp> |
| |
| namespace ndn { |
| |
| using std::string; |
| using std::vector; |
| |
| const std::string SecPublicInfoSqlite3::SCHEME("pib-sqlite3"); |
| |
| static const string INIT_TPM_INFO_TABLE = |
| "CREATE TABLE IF NOT EXISTS " |
| " TpmInfo( " |
| " tpm_locator BLOB NOT NULL," |
| " PRIMARY KEY (tpm_locator) " |
| " ); "; |
| |
| static const string INIT_ID_TABLE = |
| "CREATE TABLE IF NOT EXISTS " |
| " Identity( " |
| " identity_name BLOB NOT NULL, " |
| " default_identity INTEGER DEFAULT 0, " |
| " PRIMARY KEY (identity_name) " |
| " ); " |
| "CREATE INDEX identity_index ON Identity(identity_name);"; |
| |
| static const string INIT_KEY_TABLE = |
| "CREATE TABLE IF NOT EXISTS " |
| " Key( " |
| " identity_name BLOB NOT NULL, " |
| " key_identifier BLOB NOT NULL, " |
| " key_type INTEGER, " |
| " public_key BLOB, " |
| " default_key INTEGER DEFAULT 0, " |
| " active INTEGER DEFAULT 0, " |
| " PRIMARY KEY (identity_name, key_identifier)" |
| " ); " |
| "CREATE INDEX key_index ON Key(identity_name); "; |
| |
| |
| static const string INIT_CERT_TABLE = |
| "CREATE TABLE IF NOT EXISTS " |
| " Certificate( " |
| " cert_name BLOB NOT NULL, " |
| " cert_issuer BLOB NOT NULL, " |
| " identity_name BLOB NOT NULL, " |
| " key_identifier BLOB NOT NULL, " |
| " not_before TIMESTAMP, " |
| " not_after TIMESTAMP, " |
| " certificate_data BLOB NOT NULL, " |
| " valid_flag INTEGER DEFAULT 1, " |
| " default_cert INTEGER DEFAULT 0, " |
| " PRIMARY KEY (cert_name) " |
| " ); " |
| "CREATE INDEX cert_index ON Certificate(cert_name); " |
| "CREATE INDEX subject ON Certificate(identity_name);"; |
| |
| /** |
| * A utility function to call the normal sqlite3_bind_text where the value and length are |
| * value.c_str() and value.size(). |
| */ |
| static int |
| sqlite3_bind_string(sqlite3_stmt* statement, |
| int index, |
| const string& value, |
| void(*destructor)(void*)) |
| { |
| return sqlite3_bind_text(statement, index, value.c_str(), value.size(), destructor); |
| } |
| |
| static string |
| sqlite3_column_string(sqlite3_stmt* statement, int column) |
| { |
| return string(reinterpret_cast<const char*>(sqlite3_column_text(statement, column)), |
| sqlite3_column_bytes(statement, column)); |
| } |
| |
| SecPublicInfoSqlite3::SecPublicInfoSqlite3(const std::string& dir) |
| : SecPublicInfo(dir) |
| , m_database(nullptr) |
| { |
| boost::filesystem::path identityDir; |
| if (dir == "") |
| identityDir = boost::filesystem::path(getenv("HOME")) / ".ndn"; |
| else |
| identityDir = boost::filesystem::path(dir) / ".ndn"; |
| boost::filesystem::create_directories(identityDir); |
| |
| /// @todo Add define for windows/unix in wscript. The following may completely fail on windows |
| int res = sqlite3_open_v2((identityDir / "ndnsec-public-info.db").c_str(), &m_database, |
| SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, |
| #ifdef NDN_CXX_DISABLE_SQLITE3_FS_LOCKING |
| "unix-dotfile" |
| #else |
| 0 |
| #endif |
| ); |
| if (res != SQLITE_OK) |
| throw Error("identity DB cannot be opened/created"); |
| |
| |
| BOOST_ASSERT(m_database != nullptr); |
| |
| initializeTable("TpmInfo", INIT_TPM_INFO_TABLE); // Check if TpmInfo table exists; |
| initializeTable("Identity", INIT_ID_TABLE); // Check if Identity table exists; |
| initializeTable("Key", INIT_KEY_TABLE); // Check if Key table exists; |
| initializeTable("Certificate", INIT_CERT_TABLE); // Check if Certificate table exists; |
| } |
| |
| SecPublicInfoSqlite3::~SecPublicInfoSqlite3() |
| { |
| sqlite3_close(m_database); |
| m_database = nullptr; |
| } |
| |
| bool |
| SecPublicInfoSqlite3::doesTableExist(const string& tableName) |
| { |
| // Check if the table exists; |
| bool doesTableExist = false; |
| string checkingString = |
| "SELECT name FROM sqlite_master WHERE type='table' AND name='" + tableName + "'"; |
| |
| sqlite3_stmt* statement = nullptr; |
| sqlite3_prepare_v2(m_database, checkingString.c_str(), -1, &statement, 0); |
| |
| int result = sqlite3_step(statement); |
| if (result == SQLITE_ROW) |
| doesTableExist = true; |
| sqlite3_finalize(statement); |
| |
| return doesTableExist; |
| } |
| |
| bool |
| SecPublicInfoSqlite3::initializeTable(const string& tableName, const string& initCommand) |
| { |
| // Create the table if it does not exist |
| if (!doesTableExist(tableName)) { |
| char* errorMessage = 0; |
| int result = sqlite3_exec(m_database, initCommand.c_str(), NULL, NULL, &errorMessage); |
| |
| if (result != SQLITE_OK && errorMessage != 0) { |
| sqlite3_free(errorMessage); |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| void |
| SecPublicInfoSqlite3::deleteTable(const string& tableName) |
| { |
| string query = "DROP TABLE IF EXISTS " + tableName; |
| |
| sqlite3_stmt* statement = nullptr; |
| sqlite3_prepare_v2(m_database, query.c_str(), -1, &statement, 0); |
| |
| sqlite3_step(statement); |
| sqlite3_finalize(statement); |
| } |
| |
| void |
| SecPublicInfoSqlite3::setTpmLocator(const string& tpmLocator) |
| { |
| string currentTpm; |
| try { |
| currentTpm = getTpmLocator(); |
| } |
| catch (SecPublicInfo::Error&) { |
| setTpmLocatorInternal(tpmLocator, false); // set tpmInfo without resetting |
| return; |
| } |
| |
| if (currentTpm == tpmLocator) |
| return; // if the same, nothing will be changed |
| |
| setTpmLocatorInternal(tpmLocator, true); // set tpmInfo and reset pib |
| } |
| |
| string |
| SecPublicInfoSqlite3::getTpmLocator() |
| { |
| sqlite3_stmt* statement = nullptr; |
| sqlite3_prepare_v2(m_database, "SELECT tpm_locator FROM TpmInfo", -1, &statement, 0); |
| |
| int res = sqlite3_step(statement); |
| |
| if (res == SQLITE_ROW) { |
| string tpmLocator = sqlite3_column_string(statement, 0); |
| sqlite3_finalize(statement); |
| return tpmLocator; |
| } |
| else { |
| sqlite3_finalize(statement); |
| throw SecPublicInfo::Error("TPM info does not exist"); |
| } |
| } |
| |
| void |
| SecPublicInfoSqlite3::setTpmLocatorInternal(const string& tpmLocator, bool needReset) |
| { |
| sqlite3_stmt* statement = nullptr; |
| |
| if (needReset) { |
| deleteTable("Identity"); |
| deleteTable("Key"); |
| deleteTable("Certificate"); |
| |
| initializeTable("Identity", INIT_ID_TABLE); |
| initializeTable("Key", INIT_KEY_TABLE); |
| initializeTable("Certificate", INIT_CERT_TABLE); |
| |
| sqlite3_prepare_v2(m_database, "UPDATE TpmInfo SET tpm_locator = ?", |
| -1, &statement, 0); |
| sqlite3_bind_string(statement, 1, tpmLocator, SQLITE_TRANSIENT); |
| } |
| else { |
| // no reset implies there is no tpmLocator record, insert one |
| sqlite3_prepare_v2(m_database, "INSERT INTO TpmInfo (tpm_locator) VALUES (?)", |
| -1, &statement, 0); |
| sqlite3_bind_string(statement, 1, tpmLocator, SQLITE_TRANSIENT); |
| } |
| |
| sqlite3_step(statement); |
| sqlite3_finalize(statement); |
| } |
| |
| std::string |
| SecPublicInfoSqlite3::getPibLocator() |
| { |
| return string("pib-sqlite3:").append(m_location); |
| } |
| |
| bool |
| SecPublicInfoSqlite3::doesIdentityExist(const Name& identityName) |
| { |
| bool result = false; |
| |
| sqlite3_stmt* statement = nullptr; |
| sqlite3_prepare_v2(m_database, |
| "SELECT count(*) FROM Identity WHERE identity_name=?", |
| -1, &statement, 0); |
| |
| sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT); |
| int res = sqlite3_step(statement); |
| |
| if (res == SQLITE_ROW) { |
| int countAll = sqlite3_column_int(statement, 0); |
| if (countAll > 0) |
| result = true; |
| } |
| |
| sqlite3_finalize(statement); |
| |
| return result; |
| } |
| |
| void |
| SecPublicInfoSqlite3::addIdentity(const Name& identityName) |
| { |
| if (doesIdentityExist(identityName)) |
| return; |
| |
| sqlite3_stmt* statement = nullptr; |
| |
| sqlite3_prepare_v2(m_database, |
| "INSERT OR REPLACE INTO Identity (identity_name) values (?)", |
| -1, &statement, 0); |
| |
| sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT); |
| |
| sqlite3_step(statement); |
| |
| sqlite3_finalize(statement); |
| } |
| |
| bool |
| SecPublicInfoSqlite3::revokeIdentity() |
| { |
| //TODO: |
| return false; |
| } |
| |
| bool |
| SecPublicInfoSqlite3::doesPublicKeyExist(const Name& keyName) |
| { |
| if (keyName.empty()) |
| throw Error("Incorrect key name " + keyName.toUri()); |
| |
| string keyId = keyName.get(-1).toUri(); |
| Name identityName = keyName.getPrefix(-1); |
| |
| sqlite3_stmt* statement = nullptr; |
| sqlite3_prepare_v2(m_database, |
| "SELECT count(*) FROM Key WHERE identity_name=? AND key_identifier=?", |
| -1, &statement, 0); |
| |
| sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT); |
| sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT); |
| |
| int res = sqlite3_step(statement); |
| |
| bool keyIdExist = false; |
| if (res == SQLITE_ROW) { |
| int countAll = sqlite3_column_int(statement, 0); |
| if (countAll > 0) |
| keyIdExist = true; |
| } |
| |
| sqlite3_finalize(statement); |
| |
| return keyIdExist; |
| } |
| |
| void |
| SecPublicInfoSqlite3::addKey(const Name& keyName, |
| const PublicKey& publicKeyDer) |
| { |
| if (keyName.empty()) |
| return; |
| |
| if (doesPublicKeyExist(keyName)) |
| return; |
| |
| string keyId = keyName.get(-1).toUri(); |
| Name identityName = keyName.getPrefix(-1); |
| |
| addIdentity(identityName); |
| |
| sqlite3_stmt* statement = nullptr; |
| sqlite3_prepare_v2(m_database, |
| "INSERT OR REPLACE INTO Key \ |
| (identity_name, key_identifier, key_type, public_key) \ |
| values (?, ?, ?, ?)", |
| -1, &statement, 0); |
| |
| sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT); |
| sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT); |
| sqlite3_bind_int(statement, 3, publicKeyDer.getKeyType()); |
| sqlite3_bind_blob(statement, 4, |
| publicKeyDer.get().buf(), |
| publicKeyDer.get().size(), |
| SQLITE_STATIC); |
| |
| sqlite3_step(statement); |
| |
| sqlite3_finalize(statement); |
| } |
| |
| shared_ptr<PublicKey> |
| SecPublicInfoSqlite3::getPublicKey(const Name& keyName) |
| { |
| if (keyName.empty()) |
| throw Error("SecPublicInfoSqlite3::getPublicKey Empty keyName"); |
| |
| string keyId = keyName.get(-1).toUri(); |
| Name identityName = keyName.getPrefix(-1); |
| |
| sqlite3_stmt* statement = nullptr; |
| sqlite3_prepare_v2(m_database, |
| "SELECT public_key FROM Key WHERE identity_name=? AND key_identifier=?", |
| -1, &statement, 0); |
| |
| sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT); |
| sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT); |
| |
| int res = sqlite3_step(statement); |
| |
| shared_ptr<PublicKey> result; |
| if (res == SQLITE_ROW) { |
| result = make_shared<PublicKey>(static_cast<const uint8_t*>(sqlite3_column_blob(statement, 0)), |
| sqlite3_column_bytes(statement, 0)); |
| sqlite3_finalize(statement); |
| return result; |
| } |
| else { |
| sqlite3_finalize(statement); |
| throw Error("SecPublicInfoSqlite3::getPublicKey public key does not exist"); |
| } |
| } |
| |
| KeyType |
| SecPublicInfoSqlite3::getPublicKeyType(const Name& keyName) |
| { |
| if (keyName.empty()) |
| return KEY_TYPE_NULL; |
| |
| string keyId = keyName.get(-1).toUri(); |
| Name identityName = keyName.getPrefix(-1); |
| |
| sqlite3_stmt* statement = nullptr; |
| sqlite3_prepare_v2(m_database, |
| "SELECT key_type FROM Key WHERE identity_name=? AND key_identifier=?", |
| -1, &statement, 0); |
| |
| sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT); |
| sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT); |
| |
| int res = sqlite3_step(statement); |
| |
| if (res == SQLITE_ROW) { |
| int typeValue = sqlite3_column_int(statement, 0); |
| sqlite3_finalize(statement); |
| return static_cast<KeyType>(typeValue); |
| } |
| else { |
| sqlite3_finalize(statement); |
| return KEY_TYPE_NULL; |
| } |
| } |
| |
| bool |
| SecPublicInfoSqlite3::doesCertificateExist(const Name& certificateName) |
| { |
| sqlite3_stmt* statement = nullptr; |
| sqlite3_prepare_v2(m_database, |
| "SELECT count(*) FROM Certificate WHERE cert_name=?", |
| -1, &statement, 0); |
| |
| sqlite3_bind_string(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT); |
| |
| int res = sqlite3_step(statement); |
| |
| bool certExist = false; |
| if (res == SQLITE_ROW) { |
| int countAll = sqlite3_column_int(statement, 0); |
| if (countAll > 0) |
| certExist = true; |
| } |
| |
| sqlite3_finalize(statement); |
| |
| return certExist; |
| } |
| |
| void |
| SecPublicInfoSqlite3::addCertificate(const IdentityCertificate& certificate) |
| { |
| const Name& certificateName = certificate.getName(); |
| // KeyName is from IdentityCertificate name, so should be qualified. |
| Name keyName = |
| IdentityCertificate::certificateNameToPublicKeyName(certificate.getName()); |
| |
| addKey(keyName, certificate.getPublicKeyInfo()); |
| |
| if (doesCertificateExist(certificateName)) |
| return; |
| |
| string keyId = keyName.get(-1).toUri(); |
| Name identity = keyName.getPrefix(-1); |
| |
| // Insert the certificate |
| sqlite3_stmt* statement = nullptr; |
| sqlite3_prepare_v2(m_database, |
| "INSERT OR REPLACE INTO Certificate \ |
| (cert_name, cert_issuer, identity_name, key_identifier, \ |
| not_before, not_after, certificate_data) \ |
| values (?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?)", |
| -1, &statement, 0); |
| |
| sqlite3_bind_string(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT); |
| |
| try { |
| // this will throw an exception if the signature is not the standard one |
| // or there is no key locator present |
| std::string signerName = certificate.getSignature().getKeyLocator().getName().toUri(); |
| sqlite3_bind_string(statement, 2, signerName, SQLITE_TRANSIENT); |
| } |
| catch (tlv::Error&) { |
| return; |
| } |
| |
| sqlite3_bind_string(statement, 3, identity.toUri(), SQLITE_TRANSIENT); |
| sqlite3_bind_string(statement, 4, keyId, SQLITE_STATIC); |
| |
| sqlite3_bind_int64(statement, 5, |
| static_cast<sqlite3_int64>(time::toUnixTimestamp(certificate.getNotBefore()).count())); |
| sqlite3_bind_int64(statement, 6, |
| static_cast<sqlite3_int64>(time::toUnixTimestamp(certificate.getNotAfter()).count())); |
| |
| sqlite3_bind_blob(statement, 7, |
| certificate.wireEncode().wire(), |
| certificate.wireEncode().size(), |
| SQLITE_TRANSIENT); |
| |
| sqlite3_step(statement); |
| |
| sqlite3_finalize(statement); |
| } |
| |
| shared_ptr<IdentityCertificate> |
| SecPublicInfoSqlite3::getCertificate(const Name& certificateName) |
| { |
| sqlite3_stmt* statement = nullptr; |
| |
| sqlite3_prepare_v2(m_database, |
| "SELECT certificate_data FROM Certificate WHERE cert_name=?", |
| -1, &statement, 0); |
| |
| sqlite3_bind_string(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT); |
| |
| int res = sqlite3_step(statement); |
| |
| if (res == SQLITE_ROW) { |
| shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>(); |
| try { |
| certificate->wireDecode(Block(static_cast<const uint8_t*>(sqlite3_column_blob(statement, 0)), |
| sqlite3_column_bytes(statement, 0))); |
| } |
| catch (tlv::Error&) { |
| sqlite3_finalize(statement); |
| throw Error("SecPublicInfoSqlite3::getCertificate certificate cannot be decoded"); |
| } |
| |
| sqlite3_finalize(statement); |
| return certificate; |
| } |
| else { |
| sqlite3_finalize(statement); |
| throw Error("SecPublicInfoSqlite3::getCertificate certificate does not exist"); |
| } |
| } |
| |
| |
| Name |
| SecPublicInfoSqlite3::getDefaultIdentity() |
| { |
| sqlite3_stmt* statement = nullptr; |
| sqlite3_prepare_v2(m_database, |
| "SELECT identity_name FROM Identity WHERE default_identity=1", |
| -1, &statement, 0); |
| |
| int res = sqlite3_step(statement); |
| |
| if (res == SQLITE_ROW) { |
| Name identity(sqlite3_column_string(statement, 0)); |
| sqlite3_finalize(statement); |
| return identity; |
| } |
| else { |
| sqlite3_finalize(statement); |
| throw Error("SecPublicInfoSqlite3::getDefaultIdentity no default identity"); |
| } |
| } |
| |
| void |
| SecPublicInfoSqlite3::setDefaultIdentityInternal(const Name& identityName) |
| { |
| addIdentity(identityName); |
| |
| sqlite3_stmt* statement = nullptr; |
| |
| //Reset previous default identity |
| sqlite3_prepare_v2(m_database, |
| "UPDATE Identity SET default_identity=0 WHERE default_identity=1", |
| -1, &statement, 0); |
| |
| while (sqlite3_step(statement) == SQLITE_ROW) |
| ; |
| |
| sqlite3_finalize(statement); |
| |
| //Set current default identity |
| sqlite3_prepare_v2(m_database, |
| "UPDATE Identity SET default_identity=1 WHERE identity_name=?", |
| -1, &statement, 0); |
| |
| sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT); |
| |
| sqlite3_step(statement); |
| |
| sqlite3_finalize(statement); |
| } |
| |
| Name |
| SecPublicInfoSqlite3::getDefaultKeyNameForIdentity(const Name& identityName) |
| { |
| sqlite3_stmt* statement = nullptr; |
| sqlite3_prepare_v2(m_database, |
| "SELECT key_identifier FROM Key WHERE identity_name=? AND default_key=1", |
| -1, &statement, 0); |
| |
| sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT); |
| |
| int res = sqlite3_step(statement); |
| |
| if (res == SQLITE_ROW) { |
| Name keyName = identityName; |
| keyName.append(string(reinterpret_cast<const char*>(sqlite3_column_text(statement, 0)), |
| sqlite3_column_bytes(statement, 0))); |
| sqlite3_finalize(statement); |
| return keyName; |
| } |
| else { |
| sqlite3_finalize(statement); |
| throw Error("SecPublicInfoSqlite3::getDefaultKeyNameForIdentity key not found"); |
| } |
| } |
| |
| void |
| SecPublicInfoSqlite3::setDefaultKeyNameForIdentityInternal(const Name& keyName) |
| { |
| if (!doesPublicKeyExist(keyName)) |
| throw Error("Key does not exist:" + keyName.toUri()); |
| |
| string keyId = keyName.get(-1).toUri(); |
| Name identityName = keyName.getPrefix(-1); |
| |
| sqlite3_stmt* statement = nullptr; |
| |
| //Reset previous default Key |
| sqlite3_prepare_v2(m_database, |
| "UPDATE Key SET default_key=0 WHERE default_key=1 and identity_name=?", |
| -1, &statement, 0); |
| |
| sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT); |
| |
| while (sqlite3_step(statement) == SQLITE_ROW) |
| ; |
| |
| sqlite3_finalize(statement); |
| |
| //Set current default Key |
| sqlite3_prepare_v2(m_database, |
| "UPDATE Key SET default_key=1 WHERE identity_name=? AND key_identifier=?", |
| -1, &statement, 0); |
| |
| sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT); |
| sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT); |
| |
| sqlite3_step(statement); |
| |
| sqlite3_finalize(statement); |
| } |
| |
| Name |
| SecPublicInfoSqlite3::getDefaultCertificateNameForKey(const Name& keyName) |
| { |
| if (keyName.empty()) |
| throw Error("SecPublicInfoSqlite3::getDefaultCertificateNameForKey wrong key"); |
| |
| string keyId = keyName.get(-1).toUri(); |
| Name identityName = keyName.getPrefix(-1); |
| |
| sqlite3_stmt* statement = nullptr; |
| sqlite3_prepare_v2(m_database, |
| "SELECT cert_name FROM Certificate \ |
| WHERE identity_name=? AND key_identifier=? AND default_cert=1", |
| -1, &statement, 0); |
| |
| sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT); |
| sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT); |
| |
| int res = sqlite3_step(statement); |
| |
| if (res == SQLITE_ROW) { |
| Name certName(string(reinterpret_cast<const char*>(sqlite3_column_text(statement, 0)), |
| sqlite3_column_bytes(statement, 0))); |
| sqlite3_finalize(statement); |
| return certName; |
| } |
| else { |
| sqlite3_finalize(statement); |
| throw Error("certificate not found"); |
| } |
| } |
| |
| void |
| SecPublicInfoSqlite3::setDefaultCertificateNameForKeyInternal(const Name& certificateName) |
| { |
| if (!doesCertificateExist(certificateName)) |
| throw Error("certificate does not exist:" + certificateName.toUri()); |
| |
| Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName); |
| string keyId = keyName.get(-1).toUri(); |
| Name identityName = keyName.getPrefix(-1); |
| |
| sqlite3_stmt* statement = nullptr; |
| |
| //Reset previous default Key |
| sqlite3_prepare_v2(m_database, |
| "UPDATE Certificate SET default_cert=0 \ |
| WHERE default_cert=1 AND identity_name=? AND key_identifier=?", |
| -1, &statement, 0); |
| |
| sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT); |
| sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT); |
| |
| while (sqlite3_step(statement) == SQLITE_ROW) |
| ; |
| |
| sqlite3_finalize(statement); |
| |
| //Set current default Key |
| sqlite3_prepare_v2(m_database, |
| "UPDATE Certificate SET default_cert=1 \ |
| WHERE identity_name=? AND key_identifier=? AND cert_name=?", |
| -1, &statement, 0); |
| |
| sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT); |
| sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT); |
| sqlite3_bind_string(statement, 3, certificateName.toUri(), SQLITE_TRANSIENT); |
| |
| sqlite3_step(statement); |
| |
| sqlite3_finalize(statement); |
| } |
| |
| void |
| SecPublicInfoSqlite3::getAllIdentities(vector<Name>& nameList, bool isDefault) |
| { |
| sqlite3_stmt* stmt; |
| if (isDefault) |
| sqlite3_prepare_v2(m_database, |
| "SELECT identity_name FROM Identity WHERE default_identity=1", |
| -1, &stmt, 0); |
| else |
| sqlite3_prepare_v2(m_database, |
| "SELECT identity_name FROM Identity WHERE default_identity=0", |
| -1, &stmt, 0); |
| |
| while (sqlite3_step(stmt) == SQLITE_ROW) |
| nameList.push_back(Name(string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)), |
| sqlite3_column_bytes(stmt, 0)))); |
| |
| sqlite3_finalize(stmt); |
| } |
| |
| void |
| SecPublicInfoSqlite3::getAllKeyNames(vector<Name>& nameList, bool isDefault) |
| { |
| sqlite3_stmt* stmt; |
| |
| if (isDefault) |
| sqlite3_prepare_v2(m_database, |
| "SELECT identity_name, key_identifier FROM Key WHERE default_key=1", |
| -1, &stmt, 0); |
| else |
| sqlite3_prepare_v2(m_database, |
| "SELECT identity_name, key_identifier FROM Key WHERE default_key=0", |
| -1, &stmt, 0); |
| |
| while (sqlite3_step(stmt) == SQLITE_ROW) { |
| Name keyName(string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)), |
| sqlite3_column_bytes(stmt, 0))); |
| keyName.append(string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1)), |
| sqlite3_column_bytes(stmt, 1))); |
| nameList.push_back(keyName); |
| } |
| sqlite3_finalize(stmt); |
| } |
| |
| void |
| SecPublicInfoSqlite3::getAllKeyNamesOfIdentity(const Name& identity, |
| vector<Name>& nameList, |
| bool isDefault) |
| { |
| sqlite3_stmt* stmt; |
| |
| if (isDefault) |
| sqlite3_prepare_v2(m_database, |
| "SELECT key_identifier FROM Key WHERE default_key=1 and identity_name=?", |
| -1, &stmt, 0); |
| else |
| sqlite3_prepare_v2(m_database, |
| "SELECT key_identifier FROM Key WHERE default_key=0 and identity_name=?", |
| -1, &stmt, 0); |
| |
| sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT); |
| |
| while (sqlite3_step(stmt) == SQLITE_ROW) { |
| Name keyName(identity); |
| keyName.append(string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)), |
| sqlite3_column_bytes(stmt, 0))); |
| nameList.push_back(keyName); |
| } |
| sqlite3_finalize(stmt); |
| } |
| |
| void |
| SecPublicInfoSqlite3::getAllCertificateNames(vector<Name>& nameList, bool isDefault) |
| { |
| sqlite3_stmt* stmt; |
| |
| if (isDefault) |
| sqlite3_prepare_v2(m_database, |
| "SELECT cert_name FROM Certificate WHERE default_cert=1", |
| -1, &stmt, 0); |
| else |
| sqlite3_prepare_v2(m_database, |
| "SELECT cert_name FROM Certificate WHERE default_cert=0", |
| -1, &stmt, 0); |
| |
| while (sqlite3_step(stmt) == SQLITE_ROW) |
| nameList.push_back(string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)), |
| sqlite3_column_bytes(stmt, 0))); |
| |
| sqlite3_finalize(stmt); |
| } |
| |
| void |
| SecPublicInfoSqlite3::getAllCertificateNamesOfKey(const Name& keyName, |
| vector<Name>& nameList, |
| bool isDefault) |
| { |
| if (keyName.empty()) |
| return; |
| |
| sqlite3_stmt* stmt; |
| if (isDefault) |
| sqlite3_prepare_v2(m_database, |
| "SELECT cert_name FROM Certificate \ |
| WHERE default_cert=1 and identity_name=? and key_identifier=?", |
| -1, &stmt, 0); |
| else |
| sqlite3_prepare_v2(m_database, |
| "SELECT cert_name FROM Certificate \ |
| WHERE default_cert=0 and identity_name=? and key_identifier=?", |
| -1, &stmt, 0); |
| |
| Name identity = keyName.getPrefix(-1); |
| sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT); |
| |
| std::string baseKeyName = keyName.get(-1).toUri(); |
| sqlite3_bind_string(stmt, 2, baseKeyName, SQLITE_TRANSIENT); |
| |
| while (sqlite3_step(stmt) == SQLITE_ROW) |
| nameList.push_back(string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)), |
| sqlite3_column_bytes(stmt, 0))); |
| |
| sqlite3_finalize(stmt); |
| } |
| |
| void |
| SecPublicInfoSqlite3::deleteCertificateInfo(const Name& certName) |
| { |
| if (certName.empty()) |
| return; |
| |
| sqlite3_stmt* stmt; |
| sqlite3_prepare_v2(m_database, "DELETE FROM Certificate WHERE cert_name=?", -1, &stmt, 0); |
| sqlite3_bind_string(stmt, 1, certName.toUri(), SQLITE_TRANSIENT); |
| sqlite3_step(stmt); |
| sqlite3_finalize(stmt); |
| } |
| |
| void |
| SecPublicInfoSqlite3::deletePublicKeyInfo(const Name& keyName) |
| { |
| if (keyName.empty()) |
| return; |
| |
| string identity = keyName.getPrefix(-1).toUri(); |
| string keyId = keyName.get(-1).toUri(); |
| |
| sqlite3_stmt* stmt; |
| sqlite3_prepare_v2(m_database, |
| "DELETE FROM Certificate WHERE identity_name=? and key_identifier=?", |
| -1, &stmt, 0); |
| sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT); |
| sqlite3_bind_string(stmt, 2, keyId, SQLITE_TRANSIENT); |
| sqlite3_step(stmt); |
| sqlite3_finalize(stmt); |
| |
| sqlite3_prepare_v2(m_database, |
| "DELETE FROM Key WHERE identity_name=? and key_identifier=?", |
| -1, &stmt, 0); |
| sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT); |
| sqlite3_bind_string(stmt, 2, keyId, SQLITE_TRANSIENT); |
| sqlite3_step(stmt); |
| sqlite3_finalize(stmt); |
| } |
| |
| void |
| SecPublicInfoSqlite3::deleteIdentityInfo(const Name& identityName) |
| { |
| string identity = identityName.toUri(); |
| |
| sqlite3_stmt* stmt; |
| sqlite3_prepare_v2(m_database, "DELETE FROM Certificate WHERE identity_name=?", -1, &stmt, 0); |
| sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT); |
| sqlite3_step(stmt); |
| sqlite3_finalize(stmt); |
| |
| sqlite3_prepare_v2(m_database, "DELETE FROM Key WHERE identity_name=?", -1, &stmt, 0); |
| sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT); |
| sqlite3_step(stmt); |
| sqlite3_finalize(stmt); |
| |
| sqlite3_prepare_v2(m_database, "DELETE FROM Identity WHERE identity_name=?", -1, &stmt, 0); |
| sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT); |
| sqlite3_step(stmt); |
| sqlite3_finalize(stmt); |
| } |
| |
| std::string |
| SecPublicInfoSqlite3::getScheme() |
| { |
| return SCHEME; |
| } |
| |
| } // namespace ndn |