blob: 0e2ce8705fca43087f2df8e7d9e1b891688e4cb7 [file] [log] [blame]
Yingdi Yu77627ab2015-07-21 16:13:49 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2015 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#include "pib-db.hpp"
23#include <sqlite3.h>
24#include <boost/filesystem.hpp>
25#include <boost/algorithm/string.hpp>
26
27namespace ndn {
28namespace pib {
29
30using std::string;
31using std::vector;
32using std::set;
33
34const Name PibDb::NON_EXISTING_IDENTITY("/localhost/reserved/non-existing-identity");
35const Name PibDb::NON_EXISTING_KEY("/localhost/reserved/non-existing-key");
36const Name PibDb::NON_EXISTING_CERTIFICATE("/localhost/reserved/non-existing-certificate");
37
38const Name PibDb::LOCALHOST_PIB("/localhost/pib");
39const name::Component PibDb::MGMT_LABEL("mgmt");
40
41
42static const string INITIALIZATION =
43 "CREATE TABLE IF NOT EXISTS \n"
44 " mgmt( \n"
45 " id INTEGER PRIMARY KEY,\n"
46 " owner BLOB NOT NULL, \n"
47 " tpm_locator BLOB, \n"
48 " local_management_cert BLOB NOT NULL \n"
49 " ); \n"
50 "CREATE TRIGGER IF NOT EXISTS \n"
51 " mgmt_insert_trigger \n"
52 " BEFORE INSERT ON mgmt \n"
53 " FOR EACH ROW \n"
54 " BEGIN \n"
55 " DELETE FROM mgmt; \n"
56 " END; \n"
57 " \n"
58 "CREATE TABLE IF NOT EXISTS \n"
59 " identities( \n"
60 " id INTEGER PRIMARY KEY,\n"
61 " identity BLOB NOT NULL, \n"
62 " is_default INTEGER DEFAULT 0 \n"
63 " ); \n"
64 "CREATE UNIQUE INDEX IF NOT EXISTS \n"
65 " identityIndex ON identities(identity); \n"
66 "CREATE TRIGGER IF NOT EXISTS \n"
67 " identity_default_before_insert_trigger \n"
68 " BEFORE INSERT ON identities \n"
69 " FOR EACH ROW \n"
70 " WHEN NEW.is_default=1 \n"
71 " BEGIN \n"
72 " UPDATE identities SET is_default=0; \n"
73 " END; \n"
74 "CREATE TRIGGER IF NOT EXISTS \n"
75 " identity_default_after_insert_trigger \n"
76 " AFTER INSERT ON identities \n"
77 " FOR EACH ROW \n"
78 " WHEN NOT EXISTS \n"
79 " (SELECT id \n"
80 " FROM identities \n"
81 " WHERE is_default=1) \n"
82 " BEGIN \n"
83 " UPDATE identities \n"
84 " SET is_default=1 \n"
85 " WHERE identity=NEW.identity; \n"
86 " END; \n"
87 "CREATE TRIGGER IF NOT EXISTS \n"
88 " identity_default_update_trigger \n"
89 " BEFORE UPDATE ON identities \n"
90 " FOR EACH ROW \n"
91 " WHEN NEW.is_default=1 AND OLD.is_default=0 \n"
92 " BEGIN \n"
93 " UPDATE identities SET is_default=0; \n"
94 " END; \n"
95 "CREATE TRIGGER IF NOT EXISTS \n"
96 " identity_delete_trigger \n"
97 " AFTER DELETE ON identities \n"
98 " FOR EACH ROW \n"
99 " BEGIN \n"
100 " SELECT identityDeleted (OLD.identity); \n"
101 " END; \n"
102 " \n"
103 "CREATE TABLE IF NOT EXISTS \n"
104 " keys( \n"
105 " id INTEGER PRIMARY KEY,\n"
106 " identity_id INTEGER NOT NULL, \n"
107 " key_name BLOB NOT NULL, \n"
108 " key_type INTEGER NOT NULL, \n"
109 " key_bits BLOB NOT NULL, \n"
110 " is_default INTEGER DEFAULT 0, \n"
111 " FOREIGN KEY(identity_id) \n"
112 " REFERENCES identities(id) \n"
113 " ON DELETE CASCADE \n"
114 " ON UPDATE CASCADE \n"
115 " ); \n"
116 "CREATE UNIQUE INDEX IF NOT EXISTS \n"
117 " keyIndex ON keys(key_name); \n"
118 "CREATE TRIGGER IF NOT EXISTS \n"
119 " key_default_before_insert_trigger \n"
120 " BEFORE INSERT ON keys \n"
121 " FOR EACH ROW \n"
122 " WHEN NEW.is_default=1 \n"
123 " BEGIN \n"
124 " UPDATE keys \n"
125 " SET is_default=0 \n"
126 " WHERE identity_id=NEW.identity_id; \n"
127 " END; \n"
128 "CREATE TRIGGER IF NOT EXISTS \n"
129 " key_default_after_insert_trigger \n"
130 " AFTER INSERT ON keys \n"
131 " FOR EACH ROW \n"
132 " WHEN NOT EXISTS \n"
133 " (SELECT id \n"
134 " FROM keys \n"
135 " WHERE is_default=1 \n"
136 " AND identity_id=NEW.identity_id) \n"
137 " BEGIN \n"
138 " UPDATE keys \n"
139 " SET is_default=1 \n"
140 " WHERE key_name=NEW.key_name; \n"
141 " END; \n"
142 "CREATE TRIGGER IF NOT EXISTS \n"
143 " key_default_update_trigger \n"
144 " BEFORE UPDATE ON keys \n"
145 " FOR EACH ROW \n"
146 " WHEN NEW.is_default=1 AND OLD.is_default=0 \n"
147 " BEGIN \n"
148 " UPDATE keys \n"
149 " SET is_default=0 \n"
150 " WHERE identity_id=NEW.identity_id; \n"
151 " END; \n"
152 "CREATE TRIGGER IF NOT EXISTS \n"
153 " key_delete_trigger \n"
154 " AFTER DELETE ON keys \n"
155 " FOR EACH ROW \n"
156 " BEGIN \n"
157 " SELECT keyDeleted (OLD.key_name); \n"
158 " END; \n"
159 " \n"
160 "CREATE TABLE IF NOT EXISTS \n"
161 " certificates( \n"
162 " id INTEGER PRIMARY KEY,\n"
163 " key_id INTEGER NOT NULL, \n"
164 " certificate_name BLOB NOT NULL, \n"
165 " certificate_data BLOB NOT NULL, \n"
166 " is_default INTEGER DEFAULT 0, \n"
167 " FOREIGN KEY(key_id) \n"
168 " REFERENCES keys(id) \n"
169 " ON DELETE CASCADE \n"
170 " ON UPDATE CASCADE \n"
171 " ); \n"
172 "CREATE UNIQUE INDEX IF NOT EXISTS \n"
173 " certIndex ON certificates(certificate_name);\n"
174 "CREATE TRIGGER IF NOT EXISTS \n"
175 " cert_default_before_insert_trigger \n"
176 " BEFORE INSERT ON certificates \n"
177 " FOR EACH ROW \n"
178 " WHEN NEW.is_default=1 \n"
179 " BEGIN \n"
180 " UPDATE certificates \n"
181 " SET is_default=0 \n"
182 " WHERE key_id=NEW.key_id; \n"
183 " END; \n"
184 "CREATE TRIGGER IF NOT EXISTS \n"
185 " cert_default_after_insert_trigger \n"
186 " AFTER INSERT ON certificates \n"
187 " FOR EACH ROW \n"
188 " WHEN NOT EXISTS \n"
189 " (SELECT id \n"
190 " FROM certificates \n"
191 " WHERE is_default=1 \n"
192 " AND key_id=NEW.key_id) \n"
193 " BEGIN \n"
194 " UPDATE certificates \n"
195 " SET is_default=1 \n"
196 " WHERE certificate_name=NEW.certificate_name;\n"
197 " END; \n"
198 "CREATE TRIGGER IF NOT EXISTS \n"
199 " cert_default_update_trigger \n"
200 " BEFORE UPDATE ON certificates \n"
201 " FOR EACH ROW \n"
202 " WHEN NEW.is_default=1 AND OLD.is_default=0 \n"
203 " BEGIN \n"
204 " UPDATE certificates \n"
205 " SET is_default=0 \n"
206 " WHERE key_id=NEW.key_id; \n"
207 " END; \n"
208 "CREATE TRIGGER IF NOT EXISTS \n"
209 " cert_delete_trigger \n"
210 " AFTER DELETE ON certificates \n"
211 " FOR EACH ROW \n"
212 " BEGIN \n"
213 " SELECT certDeleted (OLD.certificate_name);\n"
214 " END; \n"
215 "CREATE TRIGGER IF NOT EXISTS \n"
216 " cert_insert_trigger \n"
217 " AFTER INSERT ON certificates \n"
218 " FOR EACH ROW \n"
219 " BEGIN \n"
220 " SELECT certInserted (NEW.certificate_name);\n"
221 " END; \n";
222
223
224/**
225 * A utility function to call the normal sqlite3_bind_text where the value and length are
226 * value.c_str() and value.size().
227 */
228static int
229sqlite3_bind_string(sqlite3_stmt* statement,
230 int index,
231 const string& value,
232 void(*destructor)(void*))
233{
234 return sqlite3_bind_text(statement, index, value.c_str(), value.size(), destructor);
235}
236
237/**
238 * A utility function to call the normal sqlite3_bind_blob where the value and length are
239 * block.wire() and block.size().
240 */
241static int
242sqlite3_bind_block(sqlite3_stmt* statement,
243 int index,
244 const Block& block,
245 void(*destructor)(void*))
246{
247 return sqlite3_bind_blob(statement, index, block.wire(), block.size(), destructor);
248}
249
250/**
251 * A utility function to generate string by calling the normal sqlite3_column_text.
252 */
253static string
254sqlite3_column_string(sqlite3_stmt* statement, int column)
255{
256 return string(reinterpret_cast<const char*>(sqlite3_column_text(statement, column)),
257 sqlite3_column_bytes(statement, column));
258}
259
260/**
261 * A utility function to generate block by calling the normal sqlite3_column_text.
262 */
263static Block
264sqlite3_column_block(sqlite3_stmt* statement, int column)
265{
266 return Block(sqlite3_column_blob(statement, column), sqlite3_column_bytes(statement, column));
267}
268
269PibDb::PibDb(const string& dbDir)
270{
271 // Determine the path of PIB DB
272 boost::filesystem::path dir;
273 if (dbDir == "") {
274 dir = boost::filesystem::path(getenv("HOME")) / ".ndn";
275 boost::filesystem::create_directories(dir);
276 }
277 else {
278 dir = boost::filesystem::path(dbDir);
279 boost::filesystem::create_directories(dir);
280 }
281 // Open PIB
282 int result = sqlite3_open_v2((dir / "pib.db").c_str(), &m_database,
283 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
284#ifdef NDN_CXX_DISABLE_SQLITE3_FS_LOCKING
285 "unix-dotfile"
286#else
287 nullptr
288#endif
289 );
290
291 if (result != SQLITE_OK)
292 throw Error("PIB DB cannot be opened/created: " + dbDir);
293
294
295 // enable foreign key
296 sqlite3_exec(m_database, "PRAGMA foreign_keys = ON", nullptr, nullptr, nullptr);
297
298 // initialize PIB specific tables
299 char* errorMessage = nullptr;
300 result = sqlite3_exec(m_database, INITIALIZATION.c_str(), nullptr, nullptr, &errorMessage);
301 if (result != SQLITE_OK && errorMessage != nullptr) {
302 sqlite3_free(errorMessage);
303 throw Error("PIB DB cannot be initialized");
304 }
305
306 // create delete trigger functions
307 createDbDeleteTrigger();
308
309 getOwnerName();
310}
311
312void
313PibDb::createDbDeleteTrigger()
314{
315 int res = 0;
316
317 res = sqlite3_create_function(m_database, "identityDeleted", -1, SQLITE_UTF8,
318 reinterpret_cast<void*>(this),
319 PibDb::identityDeletedFun, nullptr, nullptr);
320 if (res != SQLITE_OK)
321 throw Error("Cannot create function ``identityDeleted''");
322
323 res = sqlite3_create_function(m_database, "keyDeleted", -1, SQLITE_UTF8,
324 reinterpret_cast<void*>(this),
325 PibDb::keyDeletedFun, nullptr, nullptr);
326 if (res != SQLITE_OK)
327 throw Error("Cannot create function ``keyDeleted''");
328
329 res = sqlite3_create_function(m_database, "certDeleted", -1, SQLITE_UTF8,
330 reinterpret_cast<void*>(this),
331 PibDb::certDeletedFun, nullptr, nullptr);
332 if (res != SQLITE_OK)
333 throw Error("Cannot create function ``certDeleted''");
334
335 res = sqlite3_create_function(m_database, "certInserted", -1, SQLITE_UTF8,
336 reinterpret_cast<void*>(this),
337 PibDb::certInsertedFun, nullptr, nullptr);
338 if (res != SQLITE_OK)
339 throw Error("Cannot create function ``certInserted''");
340}
341
342void
343PibDb::identityDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv)
344{
345 BOOST_ASSERT(argc == 1);
346
347 PibDb* pibDb = reinterpret_cast<PibDb*>(sqlite3_user_data(context));
348 Name identity(Block(sqlite3_value_blob(argv[0]), sqlite3_value_bytes(argv[0])));
349
350 pibDb->identityDeleted(identity);
351}
352
353void
354PibDb::keyDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv)
355{
356 BOOST_ASSERT(argc == 1);
357
358 PibDb* pibDb = reinterpret_cast<PibDb*>(sqlite3_user_data(context));
359 Name keyName(Block(sqlite3_value_blob(argv[0]), sqlite3_value_bytes(argv[0])));
360
361 pibDb->keyDeleted(keyName);
362}
363
364void
365PibDb::certDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv)
366{
367 BOOST_ASSERT(argc == 1);
368
369 PibDb* pibDb = reinterpret_cast<PibDb*>(sqlite3_user_data(context));
370 Name certName(Block(sqlite3_value_blob(argv[0]), sqlite3_value_bytes(argv[0])));
371
372 pibDb->certificateDeleted(certName);
373}
374
375void
376PibDb::certInsertedFun(sqlite3_context* context, int argc, sqlite3_value** argv)
377{
378 BOOST_ASSERT(argc == 1);
379
380 PibDb* pibDb = reinterpret_cast<PibDb*>(sqlite3_user_data(context));
381 Name certName(Block(sqlite3_value_blob(argv[0]), sqlite3_value_bytes(argv[0])));
382
383 pibDb->certificateInserted(certName);
384}
385
386void
387PibDb::updateMgmtCertificate(const IdentityCertificate& certificate)
388{
389 const Name& keyName = certificate.getPublicKeyName();
390
391 // Name of mgmt key should be "/localhost/pib/[UserName]/mgmt/[KeyID]"
392 if (keyName.size() != 5 ||
393 keyName.compare(0, 2, LOCALHOST_PIB) ||
394 keyName.get(3) != MGMT_LABEL)
395 throw Error("PibDb::updateMgmtCertificate: certificate does not follow the naming convention");
396
397 string owner = keyName.get(2).toUri();
398 sqlite3_stmt* statement;
399 if (!m_owner.empty()) {
400 if (m_owner != owner)
401 throw Error("PibDb::updateMgmtCertificate: owner name does not match");
402 else {
403 sqlite3_prepare_v2(m_database,
404 "UPDATE mgmt SET local_management_cert=? WHERE owner=?",
405 -1, &statement, nullptr);
406 }
407 }
408 else {
409 sqlite3_prepare_v2(m_database,
410 "INSERT INTO mgmt (local_management_cert, owner) VALUES (?, ?)",
411 -1, &statement, nullptr);
412 }
413
414 sqlite3_bind_block(statement, 1, certificate.wireEncode(), SQLITE_TRANSIENT);
415 sqlite3_bind_string(statement, 2, owner, SQLITE_TRANSIENT);
416 sqlite3_step(statement);
417 sqlite3_finalize(statement);
418
419 m_owner = owner;
420
421 mgmtCertificateChanged();
422}
423
424string
425PibDb::getOwnerName() const
426{
427 sqlite3_stmt* statement;
428 sqlite3_prepare_v2(m_database, "SELECT owner FROM mgmt", -1, &statement, nullptr);
429
430 if (sqlite3_step(statement) == SQLITE_ROW) {
431 m_owner = sqlite3_column_string(statement, 0);
432 }
433
434 sqlite3_finalize(statement);
435 return m_owner;
436}
437
438shared_ptr<IdentityCertificate>
439PibDb::getMgmtCertificate() const
440{
441 sqlite3_stmt* statement;
442 sqlite3_prepare_v2(m_database, "SELECT local_management_cert FROM mgmt", -1, &statement, nullptr);
443
444 shared_ptr<IdentityCertificate> certificate;
445 if (sqlite3_step(statement) == SQLITE_ROW) {
446 certificate = make_shared<IdentityCertificate>();
447 certificate->wireDecode(sqlite3_column_block(statement, 0));
448 }
449
450 sqlite3_finalize(statement);
451 return certificate;
452}
453
454void
455PibDb::setTpmLocator(const std::string& tpmLocator)
456{
457 sqlite3_stmt* statement;
458 sqlite3_prepare_v2(m_database,
459 "UPDATE mgmt SET tpm_locator=? WHERE owner=?",
460 -1, &statement, nullptr);
461 sqlite3_bind_string(statement, 1, tpmLocator, SQLITE_TRANSIENT);
462 sqlite3_bind_string(statement, 2, m_owner, SQLITE_TRANSIENT);
463 sqlite3_step(statement);
464 sqlite3_finalize(statement);
465}
466
467std::string
468PibDb::getTpmLocator() const
469{
470 sqlite3_stmt* statement;
471 sqlite3_prepare_v2(m_database, "SELECT tpm_locator FROM mgmt", -1, &statement, nullptr);
472
473 string tpmLocator;
474 if (sqlite3_step(statement) == SQLITE_ROW) {
475 tpmLocator = sqlite3_column_string(statement, 0);
476 }
477
478 sqlite3_finalize(statement);
479 return tpmLocator;
480}
481
482int64_t
483PibDb::addIdentity(const Name& identity)
484{
485 sqlite3_stmt* statement;
486 sqlite3_prepare_v2(m_database,
487 "INSERT INTO identities (identity) values (?)",
488 -1, &statement, nullptr);
489 sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
490 sqlite3_step(statement);
491 sqlite3_finalize(statement);
492
493 return sqlite3_last_insert_rowid(m_database);
494}
495
496void
497PibDb::deleteIdentity(const Name& identity)
498{
499 sqlite3_stmt* statement;
500 sqlite3_prepare_v2(m_database,
501 "DELETE FROM identities WHERE identity=?",
502 -1, &statement, nullptr);
503 sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
504 sqlite3_step(statement);
505 sqlite3_finalize(statement);
506}
507
508bool
509PibDb::hasIdentity(const Name& identity) const
510{
511 sqlite3_stmt* statement;
512 sqlite3_prepare_v2(m_database,
513 "SELECT id FROM identities WHERE identity=?",
514 -1, &statement, nullptr);
515 sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
516 int result = sqlite3_step(statement);
517 sqlite3_finalize(statement);
518
519 if (result == SQLITE_ROW)
520 return true;
521 else
522 return false;
523}
524
525void
526PibDb::setDefaultIdentity(const Name& identity)
527{
528 sqlite3_stmt* statement;
529 sqlite3_prepare_v2(m_database,
530 "UPDATE identities SET is_default=1 WHERE identity=?",
531 -1, &statement, nullptr);
532 sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
533 sqlite3_step(statement);
534 sqlite3_finalize(statement);
535}
536
537Name
538PibDb::getDefaultIdentity() const
539{
540 sqlite3_stmt* statement;
541 sqlite3_prepare_v2(m_database,
542 "SELECT identity FROM identities WHERE is_default=1",
543 -1, &statement, nullptr);
544
545 Name identity = NON_EXISTING_IDENTITY;
546 if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_bytes(statement, 0) != 0) {
547 identity = Name(sqlite3_column_block(statement, 0));
548 }
549 sqlite3_finalize(statement);
550 return identity;
551}
552
553vector<Name>
554PibDb::listIdentities() const
555{
556 vector<Name> identities;
557
558 sqlite3_stmt* statement;
559 sqlite3_prepare_v2(m_database, "SELECT identity FROM identities", -1, &statement, nullptr);
560
561 identities.clear();
562 while (sqlite3_step(statement) == SQLITE_ROW) {
563 Name name(sqlite3_column_block(statement, 0));
564 identities.push_back(name);
565 }
566 sqlite3_finalize(statement);
567
568 return identities;
569}
570
571int64_t
572PibDb::addKey(const Name& keyName, const PublicKey& key)
573{
574 if (keyName.empty())
575 return 0;
576
577 Name&& identity = keyName.getPrefix(-1);
578 if (!hasIdentity(identity))
579 addIdentity(identity);
580
581 sqlite3_stmt* statement;
582 sqlite3_prepare_v2(m_database,
583 "INSERT INTO keys (identity_id, key_name, key_type, key_bits) \
584 values ((SELECT id FROM identities WHERE identity=?), ?, ?, ?)",
585 -1, &statement, nullptr);
586 sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
587 sqlite3_bind_block(statement, 2, keyName.wireEncode(), SQLITE_TRANSIENT);
588 sqlite3_bind_int(statement, 3, key.getKeyType());
589 sqlite3_bind_blob(statement, 4, key.get().buf(), key.get().size(), SQLITE_STATIC);
590 sqlite3_step(statement);
591 sqlite3_finalize(statement);
592
593 return sqlite3_last_insert_rowid(m_database);
594}
595
596shared_ptr<PublicKey>
597PibDb::getKey(const Name& keyName) const
598{
599 sqlite3_stmt* statement;
600 sqlite3_prepare_v2(m_database,
601 "SELECT key_bits FROM keys WHERE key_name=?"
602 , -1, &statement, nullptr);
603 sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
604
605 shared_ptr<PublicKey> key;
606 if (sqlite3_step(statement) == SQLITE_ROW) {
607 key = make_shared<PublicKey>(static_cast<const uint8_t*>(sqlite3_column_blob(statement, 0)),
608 sqlite3_column_bytes(statement, 0));
609 }
610 sqlite3_finalize(statement);
611 return key;
612}
613
614void
615PibDb::deleteKey(const Name& keyName)
616{
617 sqlite3_stmt* statement;
618 sqlite3_prepare_v2(m_database,
619 "DELETE FROM keys WHERE key_name=?",
620 -1, &statement, nullptr);
621 sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
622 sqlite3_step(statement);
623 sqlite3_finalize(statement);
624}
625
626bool
627PibDb::hasKey(const Name& keyName) const
628{
629 sqlite3_stmt* statement;
630 sqlite3_prepare_v2(m_database,
631 "SELECT id FROM keys WHERE key_name=?",
632 -1, &statement, nullptr);
633 sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
634
635 int result = sqlite3_step(statement);
636 sqlite3_finalize(statement);
637
638 if (result == SQLITE_ROW)
639 return true;
640 else
641 return false;
642}
643
644void
645PibDb::setDefaultKeyNameOfIdentity(const Name& keyName)
646{
647 sqlite3_stmt* statement;
648 sqlite3_prepare_v2(m_database,
649 "UPDATE keys SET is_default=1 WHERE key_name=?",
650 -1, &statement, nullptr);
651 sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
652 sqlite3_step(statement);
653 sqlite3_finalize(statement);
654}
655
656Name
657PibDb::getDefaultKeyNameOfIdentity(const Name& identity) const
658{
659 sqlite3_stmt* statement;
660 sqlite3_prepare_v2(m_database,
661 "SELECT key_name FROM keys JOIN identities ON keys.identity_id=identities.id\
662 WHERE identities.identity=? AND keys.is_default=1",
663 -1, &statement, nullptr);
664 sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
665
666 Name keyName = NON_EXISTING_KEY;
667 if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_bytes(statement, 0) != 0) {
668 keyName = Name(sqlite3_column_block(statement, 0));
669 }
670
671 sqlite3_finalize(statement);
672 return keyName;
673}
674
675vector<Name>
676PibDb::listKeyNamesOfIdentity(const Name& identity) const
677{
678 vector<Name> keyNames;
679
680 sqlite3_stmt* statement;
681 sqlite3_prepare_v2(m_database,
682 "SELECT key_name FROM keys JOIN identities ON keys.identity_id=identities.id\
683 WHERE identities.identity=?",
684 -1, &statement, nullptr);
685 sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
686
687 keyNames.clear();
688 while (sqlite3_step(statement) == SQLITE_ROW) {
689 Name keyName(sqlite3_column_block(statement, 0));
690 keyNames.push_back(keyName);
691 }
692
693 sqlite3_finalize(statement);
694 return keyNames;
695}
696
697
698int64_t
699PibDb::addCertificate(const IdentityCertificate& certificate)
700{
701 const Name& certName = certificate.getName();
702 const Name& keyName = certificate.getPublicKeyName();
703
704 if (!hasKey(keyName))
705 addKey(keyName, certificate.getPublicKeyInfo());
706
707 sqlite3_stmt* statement;
708 sqlite3_prepare_v2(m_database,
709 "INSERT INTO certificates \
710 (key_id, certificate_name, certificate_data) \
711 values ((SELECT id FROM keys WHERE key_name=?), ?, ?)",
712 -1, &statement, nullptr);
713 sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
714 sqlite3_bind_block(statement, 2, certName.wireEncode(), SQLITE_TRANSIENT);
715 sqlite3_bind_block(statement, 3, certificate.wireEncode(), SQLITE_STATIC);
716 sqlite3_step(statement);
717 sqlite3_finalize(statement);
718
719 return sqlite3_last_insert_rowid(m_database);
720}
721
722shared_ptr<IdentityCertificate>
723PibDb::getCertificate(const Name& certificateName) const
724{
725 sqlite3_stmt* statement;
726 sqlite3_prepare_v2(m_database,
727 "SELECT certificate_data FROM certificates WHERE certificate_name=?",
728 -1, &statement, nullptr);
729 sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
730
731 shared_ptr<IdentityCertificate> certificate;
732 if (sqlite3_step(statement) == SQLITE_ROW) {
733 certificate = make_shared<IdentityCertificate>();
734 certificate->wireDecode(sqlite3_column_block(statement, 0));
735 }
736
737 sqlite3_finalize(statement);
738 return certificate;
739}
740
741void
742PibDb::deleteCertificate(const Name& certificateName)
743{
744 sqlite3_stmt* statement;
745 sqlite3_prepare_v2(m_database,
746 "DELETE FROM certificates WHERE certificate_name=?",
747 -1, &statement, nullptr);
748 sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
749 sqlite3_step(statement);
750 sqlite3_finalize(statement);
751}
752
753bool
754PibDb::hasCertificate(const Name& certificateName) const
755{
756 sqlite3_stmt* statement;
757 sqlite3_prepare_v2(m_database,
758 "SELECT id FROM certificates WHERE certificate_name=?",
759 -1, &statement, nullptr);
760 sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
761 int result = sqlite3_step(statement);
762 sqlite3_finalize(statement);
763
764 if (result == SQLITE_ROW)
765 return true;
766 else
767 return false;
768}
769
770void
771PibDb::setDefaultCertNameOfKey(const Name& certificateName)
772{
773 sqlite3_stmt* statement;
774 sqlite3_prepare_v2(m_database,
775 "UPDATE certificates SET is_default=1 WHERE certificate_name=?",
776 -1, &statement, nullptr);
777 sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
778 sqlite3_step(statement);
779 sqlite3_finalize(statement);
780}
781
782Name
783PibDb::getDefaultCertNameOfKey(const Name& keyName) const
784{
785 sqlite3_stmt* statement;
786 sqlite3_prepare_v2(m_database,
787 "SELECT certificate_name\
788 FROM certificates JOIN keys ON certificates.key_id=keys.id\
789 WHERE keys.key_name=? AND certificates.is_default=1",
790 -1, &statement, nullptr);
791 sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
792
793 Name certName = NON_EXISTING_CERTIFICATE;
794 if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_bytes(statement, 0) != 0) {
795 certName = Name(sqlite3_column_block(statement, 0));
796 }
797 sqlite3_finalize(statement);
798 return certName;
799}
800
801vector<Name>
802PibDb::listCertNamesOfKey(const Name& keyName) const
803{
804 vector<Name> certNames;
805
806 sqlite3_stmt* statement;
807 sqlite3_prepare_v2(m_database,
808 "SELECT certificate_name\
809 FROM certificates JOIN keys ON certificates.key_id=keys.id\
810 WHERE keys.key_name=?",
811 -1, &statement, nullptr);
812 sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
813
814 certNames.clear();
815 while (sqlite3_step(statement) == SQLITE_ROW) {
816 Name name(sqlite3_column_block(statement, 0));
817 certNames.push_back(name);
818 }
819 sqlite3_finalize(statement);
820
821 return certNames;
822}
823
824} // namespace pib
825} // namespace ndn