2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * @author Zofia Abramowska (z.abramowska@samsung.com)
20 * @brief Implementation of encrypted db access layer
24 #include <db-crypto.h>
25 #include <dpl/db/sql_connection.h>
26 #include <dpl/log/log.h>
27 #include <ckm/ckm-error.h>
29 #pragma GCC diagnostic push
30 #pragma GCC diagnostic warning "-Wdeprecated-declarations"
33 const CKM::PermissionMask DEFAULT_PERMISSIONS =
34 static_cast<CKM::PermissionMask>(CKM::Permission::READ | CKM::Permission::REMOVE);
36 const char *SCRIPTS_PATH = "/usr/share/ckm/scripts/";
38 enum DBVersion : int {
41 /* ... since version 3, there is no need to manually
42 * recognize database version.
43 * Remember only that if doing changes to the database,
44 * increment and update DB_VERSION_CURRENT,
45 * then provide migration mechanism!
47 DB_VERSION_CURRENT = 3
50 const char *SCRIPT_CREATE_SCHEMA = "create_schema";
51 const char *SCRIPT_DROP_ALL_ITEMS = "drop_all";
52 const char *SCRIPT_MIGRATE = "migrate_";
54 // common substitutions:
59 // 104 - permissionLabel
60 // 105 - permissionMask
61 const char *DB_CMD_SCHEMA_SET =
62 "REPLACE INTO SCHEMA_INFO(name, value) "
63 " VALUES(?101, ?103);";
65 const char *DB_CMD_SCHEMA_GET =
66 "SELECT * FROM SCHEMA_INFO WHERE name IS ?101;";
68 const char *DB_SCHEMA_VERSION_FIELD = "schema_version";
71 const char *DB_CMD_NAME_INSERT =
74 " VALUES(?101, ?102);";
76 const char *DB_CMD_NAME_COUNT_ROWS =
77 "SELECT COUNT(idx) FROM NAMES WHERE name IS ?101 AND label IS ?102;";
79 const char *DB_CMD_NAME_DELETE =
80 "DELETE FROM NAMES WHERE name IS ?101 AND label IS ?102;";
82 const char *DB_CMD_NAME_DELETE_BY_LABEL =
83 "DELETE FROM NAMES WHERE label IS ?102;";
86 const char *DB_CMD_OBJECT_INSERT =
87 "INSERT INTO OBJECTS("
88 " exportable, dataType,"
89 " algorithmType, encryptionScheme,"
90 " iv, dataSize, data, tag, idx) "
91 " VALUES(?001, ?002, ?003, ?004, ?005, "
93 " (SELECT idx FROM NAMES WHERE name IS ?101 and label IS ?102)"
96 const char *DB_CMD_OBJECT_SELECT_BY_NAME_AND_LABEL =
97 "SELECT * FROM [join_name_object_tables] "
98 " WHERE (dataType BETWEEN ?001 AND ?002) "
99 " AND name IS ?101 and label IS ?102;";
102 const char *DB_CMD_KEY_INSERT =
103 "INSERT INTO KEYS(label, key) VALUES (?, ?);";
104 const char *DB_CMD_KEY_SELECT =
105 "SELECT key FROM KEYS WHERE label IS ?;";
106 const char *DB_CMD_KEY_DELETE =
107 "DELETE FROM KEYS WHERE label IS ?;";
110 const char *DB_CMD_PERMISSION_SET = // SQLite does not support updating views
111 "REPLACE INTO PERMISSIONS(permissionLabel, permissionMask, idx) "
112 " VALUES (?104, ?105, (SELECT idx FROM NAMES WHERE name IS ?101 and label IS ?102));";
114 const char *DB_CMD_PERMISSION_SELECT =
115 "SELECT permissionMask FROM [join_name_permission_tables] "
116 " WHERE permissionLabel IS ?104 "
117 " AND name IS ?101 AND label IS ?102;";
119 const char *DB_CMD_PERMISSION_DELETE = // SQLite does not support updating views
120 "DELETE FROM PERMISSIONS WHERE permissionLabel IS ?104 AND "
121 " idx IS (SELECT idx FROM NAMES WHERE name IS ?101 AND label IS ?102);";
125 * GROUP BY is necessary because of the following case:
126 * -There are several permissions to L1, N1 (label, name) from other accessors. When listing
127 * objects accessible by L1 the query will produce one result (L1, N1) for each allowed
128 * accessor but GROUP BY will reduce them to one so L1 will have (L1, N1) on its list only once
130 const char *DB_CMD_NAME_SELECT_BY_TYPE_AND_PERMISSION =
131 "SELECT label, name FROM [join_all_tables] "
132 " WHERE (dataType BETWEEN ?001 AND ?002) "
133 " AND permissionLabel IS ?104 AND permissionMask&?004 IS NOT 0 GROUP BY idx;";
138 Crypto::Crypto(const std::string& path, const RawBuffer &rawPass)
141 m_inUserTransaction = false;
143 m_connection = new SqlConnection(path, SqlConnection::Flag::Option::CRW);
144 m_connection->SetKey(rawPass);
146 m_connection->ExecCommand("VACUUM;");
147 } Catch(SqlConnection::Exception::ConnectionBroken) {
148 LogError("Couldn't connect to database: " << path);
149 ReThrow(Crypto::Exception::InternalError);
150 } Catch(SqlConnection::Exception::InvalidArguments) {
151 LogError("Couldn't set the key for database");
152 ReThrow(Crypto::Exception::InternalError);
153 } Catch(SqlConnection::Exception::SyntaxError) {
154 LogError("Couldn't initiate the database");
155 ReThrow(Crypto::Exception::InternalError);
156 } Catch(SqlConnection::Exception::InternalError) {
157 LogError("Couldn't create the database");
158 ReThrow(Crypto::Exception::InternalError);
162 Crypto::Crypto(Crypto &&other) :
163 m_connection(other.m_connection),
164 m_inUserTransaction(other.m_inUserTransaction)
166 other.m_connection = NULL;
167 other.m_inUserTransaction = false;
174 Crypto& Crypto::operator=(Crypto&& other) {
179 m_connection = other.m_connection;
180 other.m_connection = NULL;
182 m_inUserTransaction = other.m_inUserTransaction;
183 other.m_inUserTransaction = false;
188 void Crypto::createTable(
189 const char* create_cmd,
190 const char *table_name)
193 m_connection->ExecCommand(create_cmd);
194 } Catch(SqlConnection::Exception::SyntaxError) {
195 LogError("Couldn't create table : " << table_name << "!");
197 } Catch(SqlConnection::Exception::InternalError) {
198 LogError("Sqlite got into infinite busy state");
203 void Crypto::createView(
204 const char* create_cmd)
207 m_connection->ExecCommand(create_cmd);
208 } Catch(SqlConnection::Exception::SyntaxError) {
209 LogError("Couldn't create view!");
211 } Catch(SqlConnection::Exception::InternalError) {
212 LogError("Sqlite got into infinite busy state");
217 bool Crypto::getDBVersion(int & schemaVersion)
219 SchemaInfo SchemaInfo(this);
223 * SCHEMA_INFO exists from schema version 3
225 if (m_connection->CheckTableExist("SCHEMA_INFO")
226 && SchemaInfo.getVersionInfo(schemaVersion)) {
227 LogDebug("Current DB version: " << schemaVersion);
232 * SCHEMA_INFO (x) / CKM_TABLE (o)
233 * CKM_TABLE exists only in schema version 1
234 * -> schema version 1
236 if (m_connection->CheckTableExist("CKM_TABLE")) {
237 schemaVersion = DB_VERSION_1;
242 * SCHEMA_INFO (x) / CKM_TABLE (x) / NAME_TABLE (o)
243 * NAME_TABLE exists only in schema version 2
244 * -> schema version 2
246 if (m_connection->CheckTableExist("NAME_TABLE")) {
247 schemaVersion = DB_VERSION_2;
251 // not recognized - proceed with an empty DBs
255 void Crypto::initDatabase()
257 // run migration if old database is present
259 if( getDBVersion(schemaVersion)==false || // DB empty or corrupted
260 schemaVersion > DB_VERSION_CURRENT) // or too new scheme
262 LogDebug("no database or database corrupted, initializing the DB");
268 LogDebug("DB migration from version " << schemaVersion << " to version " << DB_VERSION_CURRENT << " started.");
269 Transaction transaction(this);
270 for(int vi=schemaVersion; vi<DB_VERSION_CURRENT; vi++)
272 ScriptOptional script = getMigrationScript(vi);
275 LogError("Error, script to migrate database from version: " << vi <<
276 " to version: " << vi+1 << " not available, resetting the DB");
281 LogInfo("migrating from version " << vi << " to version " << vi+1);
282 m_connection->ExecCommand((*script).c_str());
284 // update DB version info
285 SchemaInfo SchemaInfo(this);
286 SchemaInfo.setVersionInfo();
287 transaction.commit();
291 Crypto::ScriptOptional Crypto::getScript(const std::string &scriptName) const
293 std::string scriptPath = SCRIPTS_PATH + scriptName + std::string(".sql");
294 std::ifstream is(scriptPath);
296 LogError("Script " << scriptPath << " not found!");
297 return ScriptOptional();
300 std::istreambuf_iterator<char> begin(is),end;
301 return ScriptOptional(std::string(begin, end));
304 Crypto::ScriptOptional Crypto::getMigrationScript(int db_version) const
306 std::string scriptPath = std::string(SCRIPT_MIGRATE) + std::to_string(db_version);
307 return getScript(scriptPath);
310 void Crypto::createDBSchema() {
311 Transaction transaction(this);
313 ScriptOptional script = getScript(SCRIPT_CREATE_SCHEMA);
316 std::string errmsg = "Can not create the database schema: no initialization script";
318 ThrowMsg(Exception::InternalError, errmsg);
321 m_connection->ExecCommand((*script).c_str());
322 SchemaInfo SchemaInfo(this);
323 SchemaInfo.setVersionInfo();
324 transaction.commit();
327 void Crypto::resetDB() {
328 Transaction transaction(this);
329 ScriptOptional script = getScript(SCRIPT_DROP_ALL_ITEMS);
332 std::string errmsg = "Can not clear the database: no clearing script";
334 ThrowMsg(Exception::InternalError, errmsg);
337 m_connection->ExecCommand((*script).c_str());
339 transaction.commit();
342 bool Crypto::isNameLabelPresent(const Name &name, const Label &owner) const {
344 NameTable nameTable(this->m_connection);
345 return nameTable.isPresent(name, owner);
346 } Catch(SqlConnection::Exception::SyntaxError) {
347 LogError("Couldn't prepare insert statement");
348 } Catch(SqlConnection::Exception::InternalError) {
349 LogError("Couldn't execute insert statement");
351 ThrowMsg(Crypto::Exception::InternalError,
352 "Couldn't check if name and label pair is present");
355 void Crypto::saveRows(const Name &name, const Label &owner, const RowVector &rows)
358 // transaction is present in the layer above
359 NameTable nameTable(this->m_connection);
360 ObjectTable objectTable(this->m_connection);
361 PermissionTable permissionTable(this->m_connection);
362 nameTable.addRow(name, owner);
363 for (const auto &i: rows)
364 objectTable.addRow(i);
365 permissionTable.setPermission(name,
368 static_cast<int>(DEFAULT_PERMISSIONS));
370 } Catch(SqlConnection::Exception::SyntaxError) {
371 LogError("Couldn't prepare insert statement");
372 } Catch(SqlConnection::Exception::InternalError) {
373 LogError("Couldn't execute insert statement: " << _rethrown_exception.GetMessage());
375 ThrowMsg(Crypto::Exception::InternalError,
376 "Couldn't save Row");
379 void Crypto::saveRow(const Row &row) {
381 // transaction is present in the layer above
382 NameTable nameTable(this->m_connection);
383 ObjectTable objectTable(this->m_connection);
384 PermissionTable permissionTable(this->m_connection);
385 nameTable.addRow(row.name, row.ownerLabel);
386 objectTable.addRow(row);
387 permissionTable.setPermission(row.name,
390 static_cast<int>(DEFAULT_PERMISSIONS));
392 } Catch(SqlConnection::Exception::SyntaxError) {
393 LogError("Couldn't prepare insert statement");
394 } Catch(SqlConnection::Exception::InternalError) {
395 LogError("Couldn't execute insert statement");
397 ThrowMsg(Crypto::Exception::InternalError,
398 "Couldn't save Row");
401 bool Crypto::deleteRow(
403 const Label &ownerLabel)
406 // transaction is present in the layer above
407 NameTable nameTable(this->m_connection);
408 if(nameTable.isPresent(name, ownerLabel))
410 nameTable.deleteRow(name, ownerLabel);
414 } Catch (SqlConnection::Exception::SyntaxError) {
415 LogError("Couldn't prepare delete statement");
416 } Catch (SqlConnection::Exception::InternalError) {
417 LogError("Couldn't execute delete statement");
419 ThrowMsg(Crypto::Exception::InternalError,
420 "Couldn't delete Row for name " << name << " using ownerLabel " << ownerLabel);
424 const SqlConnection::DataCommandUniquePtr &selectCommand) const {
426 row.name = selectCommand->GetColumnString(0);
427 row.ownerLabel = selectCommand->GetColumnString(1);
428 row.exportable = selectCommand->GetColumnInteger(2);
429 row.dataType = DataType(selectCommand->GetColumnInteger(3));
430 row.algorithmType = static_cast<DBCMAlgType>(selectCommand->GetColumnInteger(4));
431 row.encryptionScheme = selectCommand->GetColumnInteger(5);
432 row.iv = selectCommand->GetColumnBlob(6);
433 row.dataSize = selectCommand->GetColumnInteger(7);
434 row.data = selectCommand->GetColumnBlob(8);
435 row.tag = selectCommand->GetColumnBlob(9);
439 PermissionMaskOptional Crypto::getPermissionRow(
441 const Label &ownerLabel,
442 const Label &accessorLabel) const
445 PermissionTable permissionTable(this->m_connection);
446 return permissionTable.getPermissionRow(name, ownerLabel, accessorLabel);
447 } Catch (SqlConnection::Exception::InvalidColumn) {
448 LogError("Select statement invalid column error");
449 } Catch (SqlConnection::Exception::SyntaxError) {
450 LogError("Couldn't prepare select statement");
451 } Catch (SqlConnection::Exception::InternalError) {
452 LogError("Couldn't execute select statement");
454 return PermissionMaskOptional();
457 Crypto::RowOptional Crypto::getRow(
459 const Label &ownerLabel,
462 return getRow(name, ownerLabel, type, type);
465 Crypto::RowOptional Crypto::getRow(
467 const Label &ownerLabel,
468 DataType typeRangeStart,
469 DataType typeRangeStop)
472 SqlConnection::DataCommandUniquePtr selectCommand =
473 m_connection->PrepareDataCommand(DB_CMD_OBJECT_SELECT_BY_NAME_AND_LABEL);
474 selectCommand->BindInteger(1, typeRangeStart);
475 selectCommand->BindInteger(2, typeRangeStop);
477 // name table reference
478 selectCommand->BindString (101, name.c_str());
479 selectCommand->BindString (102, ownerLabel.c_str());
481 if(selectCommand->Step())
484 Row current_row = getRow(selectCommand);
487 return RowOptional(current_row);
489 return RowOptional();
491 } Catch (SqlConnection::Exception::InvalidColumn) {
492 LogError("Select statement invalid column error");
493 } Catch (SqlConnection::Exception::SyntaxError) {
494 LogError("Couldn't prepare select statement");
495 } Catch (SqlConnection::Exception::InternalError) {
496 LogError("Couldn't execute select statement");
498 ThrowMsg(Crypto::Exception::InternalError,
499 "Couldn't get row of type <" <<
500 static_cast<int>(typeRangeStart) << "," <<
501 static_cast<int>(typeRangeStop) << ">" <<
502 " name " << name << " with owner label " << ownerLabel);
505 void Crypto::getRows(
507 const Label &ownerLabel,
511 getRows(name, ownerLabel, type, type, output);
514 void Crypto::getRows(
516 const Label &ownerLabel,
517 DataType typeRangeStart,
518 DataType typeRangeStop,
522 SqlConnection::DataCommandUniquePtr selectCommand =
523 m_connection->PrepareDataCommand(DB_CMD_OBJECT_SELECT_BY_NAME_AND_LABEL);
524 selectCommand->BindInteger(1, typeRangeStart);
525 selectCommand->BindInteger(2, typeRangeStop);
527 // name table reference
528 selectCommand->BindString (101, name.c_str());
529 selectCommand->BindString (102, ownerLabel.c_str());
531 while(selectCommand->Step())
534 output.push_back(getRow(selectCommand));
537 } Catch (SqlConnection::Exception::InvalidColumn) {
538 LogError("Select statement invalid column error");
539 } Catch (SqlConnection::Exception::SyntaxError) {
540 LogError("Couldn't prepare select statement");
541 } Catch (SqlConnection::Exception::InternalError) {
542 LogError("Couldn't execute select statement");
544 ThrowMsg(Crypto::Exception::InternalError,
545 "Couldn't get row of type <" <<
546 static_cast<int>(typeRangeStart) << "," <<
547 static_cast<int>(typeRangeStop) << ">" <<
548 " name " << name << " with owner label " << ownerLabel);
551 void Crypto::listNames(
552 const Label &smackLabel,
553 LabelNameVector& labelNameVector,
556 listNames(smackLabel, labelNameVector, type, type);
559 void Crypto::listNames(
560 const Label &smackLabel,
561 LabelNameVector& labelNameVector,
562 DataType typeRangeStart,
563 DataType typeRangeStop)
566 Transaction transaction(this);
567 SqlConnection::DataCommandUniquePtr selectCommand =
568 m_connection->PrepareDataCommand(DB_CMD_NAME_SELECT_BY_TYPE_AND_PERMISSION);
569 selectCommand->BindInteger(1, static_cast<int>(typeRangeStart));
570 selectCommand->BindInteger(2, static_cast<int>(typeRangeStop));
571 selectCommand->BindString(104, smackLabel.c_str());
572 selectCommand->BindInteger(4, static_cast<int>(Permission::READ | Permission::REMOVE));
574 while(selectCommand->Step()) {
575 Label ownerLabel = selectCommand->GetColumnString(0);
576 Name name = selectCommand->GetColumnString(1);
577 labelNameVector.push_back(std::make_pair(ownerLabel, name));
580 } Catch (SqlConnection::Exception::InvalidColumn) {
581 LogError("Select statement invalid column error");
582 } Catch (SqlConnection::Exception::SyntaxError) {
583 LogError("Couldn't prepare select statement");
584 } Catch (SqlConnection::Exception::InternalError) {
585 LogError("Couldn't execute select statement");
587 ThrowMsg(Crypto::Exception::InternalError,
588 "Couldn't list names of type <" <<
589 static_cast<int>(typeRangeStart) << "," <<
590 static_cast<int>(typeRangeStop) << ">" <<
591 " accessible to client label " << smackLabel);
596 void Crypto::saveKey(
598 const RawBuffer &key)
601 SqlConnection::DataCommandUniquePtr insertCommand =
602 m_connection->PrepareDataCommand(DB_CMD_KEY_INSERT);
603 insertCommand->BindString(1, label.c_str());
604 insertCommand->BindBlob(2, key);
605 insertCommand->Step();
607 } Catch (SqlConnection::Exception::SyntaxError) {
608 LogError("Couldn't prepare insert key statement");
609 } Catch (SqlConnection::Exception::InternalError) {
610 LogError("Couldn't execute insert statement");
612 ThrowMsg(Crypto::Exception::InternalError,
613 "Couldn't save key for label " << label);
616 Crypto::RawBufferOptional Crypto::getKey(const Label& label)
619 SqlConnection::DataCommandUniquePtr selectCommand =
620 m_connection->PrepareDataCommand(DB_CMD_KEY_SELECT);
621 selectCommand->BindString(1, label.c_str());
623 if (selectCommand->Step()) {
624 return RawBufferOptional(
625 selectCommand->GetColumnBlob(0));
627 return RawBufferOptional();
630 } Catch (SqlConnection::Exception::InvalidColumn) {
631 LogError("Select statement invalid column error");
632 } Catch (SqlConnection::Exception::SyntaxError) {
633 LogError("Couldn't prepare insert key statement");
634 } Catch (SqlConnection::Exception::InternalError) {
635 LogError("Couldn't execute insert statement");
637 ThrowMsg(Crypto::Exception::InternalError,
638 "Couldn't get key for label " << label);
641 void Crypto::deleteKey(const Label& label) {
643 Transaction transaction(this);
645 SqlConnection::DataCommandUniquePtr deleteCommand =
646 m_connection->PrepareDataCommand(DB_CMD_KEY_DELETE);
647 deleteCommand->BindString(1, label.c_str());
648 deleteCommand->Step();
650 NameTable nameTable(this->m_connection);
651 nameTable.deleteAllRows(label);
653 transaction.commit();
655 } Catch (SqlConnection::Exception::SyntaxError) {
656 LogError("Couldn't prepare insert key statement");
657 } Catch (SqlConnection::Exception::InternalError) {
658 LogError("Couldn't execute insert statement");
660 ThrowMsg(Crypto::Exception::InternalError,
661 "Couldn't delete key for label " << label);
664 void Crypto::setPermission(
666 const Label& ownerLabel,
667 const Label& accessorLabel,
668 const PermissionMask permissionMask)
671 PermissionTable permissionTable(this->m_connection);
672 permissionTable.setPermission(name, ownerLabel, accessorLabel, permissionMask);
674 } Catch (SqlConnection::Exception::SyntaxError) {
675 LogError("Couldn't prepare set statement");
676 } Catch (SqlConnection::Exception::InternalError) {
677 LogError("Couldn't execute set statement");
679 ThrowMsg(Crypto::Exception::InternalError,
680 "Couldn't set permissions for name " << name );
684 void Crypto::SchemaInfo::setVersionInfo() {
685 SqlConnection::DataCommandUniquePtr insertContextCommand =
686 m_db->m_connection->PrepareDataCommand(DB_CMD_SCHEMA_SET);
687 insertContextCommand->BindString(101, DB_SCHEMA_VERSION_FIELD);
688 insertContextCommand->BindString(103, std::to_string(DB_VERSION_CURRENT).c_str());
689 insertContextCommand->Step();
692 bool Crypto::SchemaInfo::getVersionInfo(int & version) const
694 // Try..Catch mandatory here - we don't need to escalate the error
695 // if it happens - we just won't return the version, allowing CKM to work
697 SqlConnection::DataCommandUniquePtr selectCommand =
698 m_db->m_connection->PrepareDataCommand(DB_CMD_SCHEMA_GET);
699 selectCommand->BindString(101, DB_SCHEMA_VERSION_FIELD);
701 if(selectCommand->Step()) {
702 version = static_cast<int>(atoi(selectCommand->GetColumnString(1).c_str()));
705 } Catch (SqlConnection::Exception::InvalidColumn) {
706 LogError("Select statement invalid column error");
707 } Catch (SqlConnection::Exception::SyntaxError) {
708 LogError("Couldn't prepare select statement");
709 } Catch (SqlConnection::Exception::InternalError) {
710 LogError("Couldn't execute select statement");
715 void Crypto::PermissionTable::setPermission(
717 const Label& ownerLabel,
718 const Label& accessorLabel,
719 const PermissionMask permissionMask)
721 if(permissionMask == Permission::NONE)
724 SqlConnection::DataCommandUniquePtr deletePermissionCommand =
725 m_connection->PrepareDataCommand(DB_CMD_PERMISSION_DELETE);
726 deletePermissionCommand->BindString(104, accessorLabel.c_str());
727 deletePermissionCommand->BindString(101, name.c_str());
728 deletePermissionCommand->BindString(102, ownerLabel.c_str());
729 deletePermissionCommand->Step();
733 // add new permissions
734 SqlConnection::DataCommandUniquePtr setPermissionCommand =
735 m_connection->PrepareDataCommand(DB_CMD_PERMISSION_SET);
736 setPermissionCommand->BindString(104, accessorLabel.c_str());
737 setPermissionCommand->BindInteger(105, static_cast<int>(permissionMask));
738 setPermissionCommand->BindString(101, name.c_str());
739 setPermissionCommand->BindString(102, ownerLabel.c_str());
740 setPermissionCommand->Step();
744 PermissionMaskOptional Crypto::PermissionTable::getPermissionRow(
746 const Label &ownerLabel,
747 const Label &accessorLabel) const
749 SqlConnection::DataCommandUniquePtr selectCommand =
750 m_connection->PrepareDataCommand(DB_CMD_PERMISSION_SELECT);
751 selectCommand->BindString(104, accessorLabel.c_str());
753 // name table reference
754 selectCommand->BindString(101, name.c_str());
755 selectCommand->BindString(102, ownerLabel.c_str());
757 if(selectCommand->Step())
759 // there is entry for the <name, ownerLabel> pair
760 return PermissionMaskOptional(PermissionMask(selectCommand->GetColumnInteger(0)));
762 return PermissionMaskOptional();
765 void Crypto::NameTable::addRow(
767 const Label &ownerLabel)
770 SqlConnection::DataCommandUniquePtr insertNameCommand =
771 m_connection->PrepareDataCommand(DB_CMD_NAME_INSERT);
772 insertNameCommand->BindString (101, name.c_str());
773 insertNameCommand->BindString (102, ownerLabel.c_str());
774 insertNameCommand->Step();
777 void Crypto::NameTable::deleteRow(
779 const Label &ownerLabel)
781 SqlConnection::DataCommandUniquePtr deleteCommand =
782 m_connection->PrepareDataCommand(DB_CMD_NAME_DELETE);
783 deleteCommand->BindString(101, name.c_str());
784 deleteCommand->BindString(102, ownerLabel.c_str());
786 // Step() result code does not provide information whether
787 // anything was removed.
788 deleteCommand->Step();
791 void Crypto::NameTable::deleteAllRows(const Label &ownerLabel)
793 SqlConnection::DataCommandUniquePtr deleteData =
794 m_connection->PrepareDataCommand(DB_CMD_NAME_DELETE_BY_LABEL);
795 deleteData->BindString(102, ownerLabel.c_str());
797 // Step() result code does not provide information whether
798 // anything was removed.
802 bool Crypto::NameTable::isPresent(const Name &name, const Label &ownerLabel) const
804 SqlConnection::DataCommandUniquePtr checkCmd =
805 m_connection->PrepareDataCommand(DB_CMD_NAME_COUNT_ROWS);
806 checkCmd->BindString(101, name.c_str());
807 checkCmd->BindString(102, ownerLabel.c_str());
808 if(checkCmd->Step()) {
809 int element_count = checkCmd->GetColumnInteger(0);
810 LogDebug("Item name: " << name << " ownerLabel: " << ownerLabel <<
811 " hit count: " << element_count);
812 if(element_count > 0)
818 void Crypto::ObjectTable::addRow(const Row &row)
820 SqlConnection::DataCommandUniquePtr insertObjectCommand =
821 m_connection->PrepareDataCommand(DB_CMD_OBJECT_INSERT);
822 insertObjectCommand->BindInteger(1, row.exportable);
823 insertObjectCommand->BindInteger(2, static_cast<int>(row.dataType));
824 insertObjectCommand->BindInteger(3, static_cast<int>(row.algorithmType));
825 insertObjectCommand->BindInteger(4, row.encryptionScheme);
826 insertObjectCommand->BindBlob (5, row.iv);
827 insertObjectCommand->BindInteger(6, row.dataSize);
828 insertObjectCommand->BindBlob (7, row.data);
829 insertObjectCommand->BindBlob (8, row.tag);
831 // name table reference
832 insertObjectCommand->BindString (101, row.name.c_str());
833 insertObjectCommand->BindString (102, row.ownerLabel.c_str());
835 insertObjectCommand->Step();
840 #pragma GCC diagnostic pop