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 = 4
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=?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=?101 AND label=?102;";
79 const char *DB_CMD_NAME_DELETE =
80 "DELETE FROM NAMES WHERE name=?101 AND label=?102;";
82 const char *DB_CMD_NAME_DELETE_BY_LABEL =
83 "DELETE FROM NAMES WHERE label=?102;";
86 const char *DB_CMD_OBJECT_INSERT =
87 "INSERT INTO OBJECTS("
88 " exportable, dataType,"
89 " algorithmType, encryptionScheme,"
90 " iv, dataSize, data, tag, idx, backendId) "
91 " VALUES(?001, ?002, ?003, ?004, ?005, "
93 " (SELECT idx FROM NAMES WHERE name=?101 and label=?102),"
97 const char *DB_CMD_OBJECT_SELECT_BY_NAME_AND_LABEL =
98 "SELECT * FROM [join_name_object_tables] "
99 " WHERE (dataType BETWEEN ?001 AND ?002) "
100 " AND name=?101 and label=?102;";
103 const char *DB_CMD_KEY_INSERT =
104 "INSERT INTO KEYS(label, key) VALUES (?, ?);";
105 const char *DB_CMD_KEY_SELECT =
106 "SELECT key FROM KEYS WHERE label=?;";
107 const char *DB_CMD_KEY_DELETE =
108 "DELETE FROM KEYS WHERE label=?";
111 const char *DB_CMD_PERMISSION_SET = // SQLite does not support updating views
112 "REPLACE INTO PERMISSIONS(permissionLabel, permissionMask, idx) "
113 " VALUES (?104, ?105, (SELECT idx FROM NAMES WHERE name=?101 and label=?102));";
115 const char *DB_CMD_PERMISSION_SELECT =
116 "SELECT permissionMask FROM [join_name_permission_tables] "
117 " WHERE permissionLabel=?104 "
118 " AND name=?101 and label=?102;";
120 const char *DB_CMD_PERMISSION_DELETE = // SQLite does not support updating views
121 "DELETE FROM PERMISSIONS WHERE permissionLabel=?104 AND "
122 " idx=(SELECT idx FROM NAMES WHERE name=?101 and label=?102);";
126 * GROUP BY is necessary because of the following case:
127 * -There are several permissions to L1, N1 (label, name) from other accessors. When listing
128 * objects accessible by L1 the query will produce one result (L1, N1) for each allowed
129 * accessor but GROUP BY will reduce them to one so L1 will have (L1, N1) on its list only once
131 const char *DB_CMD_NAME_SELECT_BY_TYPE_AND_PERMISSION =
132 "SELECT label, name FROM [join_all_tables] "
133 " WHERE dataType>=?001 AND dataType<=?002 "
134 " AND permissionLabel=?104 AND permissionMask&?004!=0 GROUP BY idx;";
139 Crypto::Crypto(const std::string& path, const RawBuffer &rawPass)
142 m_inUserTransaction = false;
144 m_connection = new SqlConnection(path, SqlConnection::Flag::Option::CRW);
145 m_connection->SetKey(rawPass);
147 m_connection->ExecCommand("VACUUM;");
148 } Catch(SqlConnection::Exception::ConnectionBroken) {
149 LogError("Couldn't connect to database: " << path);
150 ReThrow(Crypto::Exception::InternalError);
151 } Catch(SqlConnection::Exception::InvalidArguments) {
152 LogError("Couldn't set the key for database");
153 ReThrow(Crypto::Exception::InternalError);
154 } Catch(SqlConnection::Exception::SyntaxError) {
155 LogError("Couldn't initiate the database");
156 ReThrow(Crypto::Exception::InternalError);
157 } Catch(SqlConnection::Exception::InternalError) {
158 LogError("Couldn't create the database");
159 ReThrow(Crypto::Exception::InternalError);
163 Crypto::Crypto(Crypto &&other) :
164 m_connection(other.m_connection),
165 m_inUserTransaction(other.m_inUserTransaction)
167 other.m_connection = NULL;
168 other.m_inUserTransaction = false;
175 Crypto& Crypto::operator=(Crypto&& other) {
180 m_connection = other.m_connection;
181 other.m_connection = NULL;
183 m_inUserTransaction = other.m_inUserTransaction;
184 other.m_inUserTransaction = false;
189 void Crypto::createTable(
190 const char* create_cmd,
191 const char *table_name)
194 m_connection->ExecCommand(create_cmd);
195 } Catch(SqlConnection::Exception::SyntaxError) {
196 LogError("Couldn't create table : " << table_name << "!");
198 } Catch(SqlConnection::Exception::InternalError) {
199 LogError("Sqlite got into infinite busy state");
204 void Crypto::createView(
205 const char* create_cmd)
208 m_connection->ExecCommand(create_cmd);
209 } Catch(SqlConnection::Exception::SyntaxError) {
210 LogError("Couldn't create view!");
212 } Catch(SqlConnection::Exception::InternalError) {
213 LogError("Sqlite got into infinite busy state");
218 bool Crypto::getDBVersion(int & schemaVersion)
220 SchemaInfo SchemaInfo(this);
221 if(SchemaInfo.getVersionInfo(schemaVersion)) {
222 LogDebug("Current DB version: " << schemaVersion);
227 LogDebug("No DB version known or DB not present");
229 // special case: old CKM_TABLE exists
230 if(m_connection->CheckTableExist("CKM_TABLE")) {
231 schemaVersion = DB_VERSION_1;
235 // special case: new scheme exists, but no SCHEMA_INFO table present
236 else if(m_connection->CheckTableExist("NAME_TABLE")) {
237 schemaVersion = DB_VERSION_2;
241 // not recognized - proceed with an empty DBs
245 void Crypto::initDatabase()
247 // run migration if old database is present
249 if( getDBVersion(schemaVersion)==false || // DB empty or corrupted
250 schemaVersion > DB_VERSION_CURRENT) // or too new scheme
252 LogDebug("no database or database corrupted, initializing the DB");
258 LogDebug("DB migration from version " << schemaVersion << " to version " << DB_VERSION_CURRENT << " started.");
259 Transaction transaction(this);
260 for(int vi=schemaVersion; vi<DB_VERSION_CURRENT; vi++)
262 ScriptOptional script = getMigrationScript(vi);
265 LogError("Error, script to migrate database from version: " << vi <<
266 " to version: " << vi+1 << " not available, resetting the DB");
271 LogInfo("migrating from version " << vi << " to version " << vi+1);
272 m_connection->ExecCommand((*script).c_str());
274 // update DB version info
275 SchemaInfo SchemaInfo(this);
276 SchemaInfo.setVersionInfo();
277 transaction.commit();
281 Crypto::ScriptOptional Crypto::getScript(const std::string &scriptName) const
283 std::string scriptPath = SCRIPTS_PATH + scriptName + std::string(".sql");
284 std::ifstream is(scriptPath);
286 LogError("Script " << scriptPath << " not found!");
287 return ScriptOptional();
290 std::istreambuf_iterator<char> begin(is),end;
291 return ScriptOptional(std::string(begin, end));
294 Crypto::ScriptOptional Crypto::getMigrationScript(int db_version) const
296 std::string scriptPath = std::string(SCRIPT_MIGRATE) + std::to_string(db_version);
297 return getScript(scriptPath);
300 void Crypto::createDBSchema() {
301 Transaction transaction(this);
303 ScriptOptional script = getScript(SCRIPT_CREATE_SCHEMA);
306 std::string errmsg = "Can not create the database schema: no initialization script";
308 ThrowMsg(Exception::InternalError, errmsg);
311 m_connection->ExecCommand((*script).c_str());
312 SchemaInfo SchemaInfo(this);
313 SchemaInfo.setVersionInfo();
314 transaction.commit();
317 void Crypto::resetDB() {
318 Transaction transaction(this);
319 ScriptOptional script = getScript(SCRIPT_DROP_ALL_ITEMS);
322 std::string errmsg = "Can not clear the database: no clearing script";
324 ThrowMsg(Exception::InternalError, errmsg);
327 m_connection->ExecCommand((*script).c_str());
329 transaction.commit();
332 bool Crypto::isNameLabelPresent(const Name &name, const Label &owner) const {
334 NameTable nameTable(this->m_connection);
335 return nameTable.isPresent(name, owner);
336 } Catch(SqlConnection::Exception::SyntaxError) {
337 LogError("Couldn't prepare insert statement");
338 } Catch(SqlConnection::Exception::InternalError) {
339 LogError("Couldn't execute insert statement");
341 ThrowMsg(Crypto::Exception::InternalError,
342 "Couldn't check if name and label pair is present");
345 void Crypto::saveRows(const Name &name, const Label &owner, const RowVector &rows)
348 // transaction is present in the layer above
349 NameTable nameTable(this->m_connection);
350 ObjectTable objectTable(this->m_connection);
351 PermissionTable permissionTable(this->m_connection);
352 nameTable.addRow(name, owner);
353 for (const auto &i: rows)
354 objectTable.addRow(i);
355 permissionTable.setPermission(name,
358 static_cast<int>(DEFAULT_PERMISSIONS));
360 } Catch(SqlConnection::Exception::SyntaxError) {
361 LogError("Couldn't prepare insert statement");
362 } Catch(SqlConnection::Exception::InternalError) {
363 LogError("Couldn't execute insert statement: " << _rethrown_exception.GetMessage());
365 ThrowMsg(Crypto::Exception::InternalError,
366 "Couldn't save Row");
369 void Crypto::saveRow(const Row &row) {
371 // transaction is present in the layer above
372 NameTable nameTable(this->m_connection);
373 ObjectTable objectTable(this->m_connection);
374 PermissionTable permissionTable(this->m_connection);
375 nameTable.addRow(row.name, row.ownerLabel);
376 objectTable.addRow(row);
377 permissionTable.setPermission(row.name,
380 static_cast<int>(DEFAULT_PERMISSIONS));
382 } Catch(SqlConnection::Exception::SyntaxError) {
383 LogError("Couldn't prepare insert statement");
384 } Catch(SqlConnection::Exception::InternalError) {
385 LogError("Couldn't execute insert statement");
387 ThrowMsg(Crypto::Exception::InternalError,
388 "Couldn't save Row");
391 bool Crypto::deleteRow(
393 const Label &ownerLabel)
396 // transaction is present in the layer above
397 NameTable nameTable(this->m_connection);
398 if(nameTable.isPresent(name, ownerLabel))
400 nameTable.deleteRow(name, ownerLabel);
404 } Catch (SqlConnection::Exception::SyntaxError) {
405 LogError("Couldn't prepare delete statement");
406 } Catch (SqlConnection::Exception::InternalError) {
407 LogError("Couldn't execute delete statement");
409 ThrowMsg(Crypto::Exception::InternalError,
410 "Couldn't delete Row for name " << name << " using ownerLabel " << ownerLabel);
414 const SqlConnection::DataCommandUniquePtr &selectCommand) const {
416 row.name = selectCommand->GetColumnString(0);
417 row.ownerLabel = selectCommand->GetColumnString(1);
418 row.exportable = selectCommand->GetColumnInteger(2);
419 row.dataType = DataType(selectCommand->GetColumnInteger(3));
420 row.algorithmType = static_cast<DBCMAlgType>(selectCommand->GetColumnInteger(4));
421 row.encryptionScheme = selectCommand->GetColumnInteger(5);
422 row.iv = selectCommand->GetColumnBlob(6);
423 row.dataSize = selectCommand->GetColumnInteger(7);
424 row.data = selectCommand->GetColumnBlob(8);
425 row.tag = selectCommand->GetColumnBlob(9);
426 row.backendId = static_cast<CryptoBackend>(selectCommand->GetColumnInteger(11));
430 PermissionMaskOptional Crypto::getPermissionRow(
432 const Label &ownerLabel,
433 const Label &accessorLabel) const
436 PermissionTable permissionTable(this->m_connection);
437 return permissionTable.getPermissionRow(name, ownerLabel, accessorLabel);
438 } Catch (SqlConnection::Exception::InvalidColumn) {
439 LogError("Select statement invalid column error");
440 } Catch (SqlConnection::Exception::SyntaxError) {
441 LogError("Couldn't prepare select statement");
442 } Catch (SqlConnection::Exception::InternalError) {
443 LogError("Couldn't execute select statement");
445 return PermissionMaskOptional();
448 Crypto::RowOptional Crypto::getRow(
450 const Label &ownerLabel,
453 return getRow(name, ownerLabel, type, type);
456 Crypto::RowOptional Crypto::getRow(
458 const Label &ownerLabel,
459 DataType typeRangeStart,
460 DataType typeRangeStop)
463 SqlConnection::DataCommandUniquePtr selectCommand =
464 m_connection->PrepareDataCommand(DB_CMD_OBJECT_SELECT_BY_NAME_AND_LABEL);
465 selectCommand->BindInteger(1, typeRangeStart);
466 selectCommand->BindInteger(2, typeRangeStop);
468 // name table reference
469 selectCommand->BindString (101, name.c_str());
470 selectCommand->BindString (102, ownerLabel.c_str());
472 if(selectCommand->Step())
475 Row current_row = getRow(selectCommand);
478 return RowOptional(current_row);
480 return RowOptional();
482 } Catch (SqlConnection::Exception::InvalidColumn) {
483 LogError("Select statement invalid column error");
484 } Catch (SqlConnection::Exception::SyntaxError) {
485 LogError("Couldn't prepare select statement");
486 } Catch (SqlConnection::Exception::InternalError) {
487 LogError("Couldn't execute select statement");
489 ThrowMsg(Crypto::Exception::InternalError,
490 "Couldn't get row of type <" <<
491 static_cast<int>(typeRangeStart) << "," <<
492 static_cast<int>(typeRangeStop) << ">" <<
493 " name " << name << " with owner label " << ownerLabel);
496 void Crypto::getRows(
498 const Label &ownerLabel,
502 getRows(name, ownerLabel, type, type, output);
505 void Crypto::getRows(
507 const Label &ownerLabel,
508 DataType typeRangeStart,
509 DataType typeRangeStop,
513 SqlConnection::DataCommandUniquePtr selectCommand =
514 m_connection->PrepareDataCommand(DB_CMD_OBJECT_SELECT_BY_NAME_AND_LABEL);
515 selectCommand->BindInteger(1, typeRangeStart);
516 selectCommand->BindInteger(2, typeRangeStop);
518 // name table reference
519 selectCommand->BindString (101, name.c_str());
520 selectCommand->BindString (102, ownerLabel.c_str());
522 while(selectCommand->Step())
525 output.push_back(getRow(selectCommand));
528 } Catch (SqlConnection::Exception::InvalidColumn) {
529 LogError("Select statement invalid column error");
530 } Catch (SqlConnection::Exception::SyntaxError) {
531 LogError("Couldn't prepare select statement");
532 } Catch (SqlConnection::Exception::InternalError) {
533 LogError("Couldn't execute select statement");
535 ThrowMsg(Crypto::Exception::InternalError,
536 "Couldn't get row of type <" <<
537 static_cast<int>(typeRangeStart) << "," <<
538 static_cast<int>(typeRangeStop) << ">" <<
539 " name " << name << " with owner label " << ownerLabel);
542 void Crypto::listNames(
543 const Label &smackLabel,
544 LabelNameVector& labelNameVector,
547 listNames(smackLabel, labelNameVector, type, type);
550 void Crypto::listNames(
551 const Label &smackLabel,
552 LabelNameVector& labelNameVector,
553 DataType typeRangeStart,
554 DataType typeRangeStop)
557 Transaction transaction(this);
558 SqlConnection::DataCommandUniquePtr selectCommand =
559 m_connection->PrepareDataCommand(DB_CMD_NAME_SELECT_BY_TYPE_AND_PERMISSION);
560 selectCommand->BindInteger(1, static_cast<int>(typeRangeStart));
561 selectCommand->BindInteger(2, static_cast<int>(typeRangeStop));
562 selectCommand->BindString(104, smackLabel.c_str());
563 selectCommand->BindInteger(4, static_cast<int>(Permission::READ | Permission::REMOVE));
565 while(selectCommand->Step()) {
566 Label ownerLabel = selectCommand->GetColumnString(0);
567 Name name = selectCommand->GetColumnString(1);
568 labelNameVector.push_back(std::make_pair(ownerLabel, name));
571 } Catch (SqlConnection::Exception::InvalidColumn) {
572 LogError("Select statement invalid column error");
573 } Catch (SqlConnection::Exception::SyntaxError) {
574 LogError("Couldn't prepare select statement");
575 } Catch (SqlConnection::Exception::InternalError) {
576 LogError("Couldn't execute select statement");
578 ThrowMsg(Crypto::Exception::InternalError,
579 "Couldn't list names of type <" <<
580 static_cast<int>(typeRangeStart) << "," <<
581 static_cast<int>(typeRangeStop) << ">" <<
582 " accessible to client label " << smackLabel);
587 void Crypto::saveKey(
589 const RawBuffer &key)
592 SqlConnection::DataCommandUniquePtr insertCommand =
593 m_connection->PrepareDataCommand(DB_CMD_KEY_INSERT);
594 insertCommand->BindString(1, label.c_str());
595 insertCommand->BindBlob(2, key);
596 insertCommand->Step();
598 } Catch (SqlConnection::Exception::SyntaxError) {
599 LogError("Couldn't prepare insert key statement");
600 } Catch (SqlConnection::Exception::InternalError) {
601 LogError("Couldn't execute insert statement");
603 ThrowMsg(Crypto::Exception::InternalError,
604 "Couldn't save key for label " << label);
607 Crypto::RawBufferOptional Crypto::getKey(const Label& label)
610 SqlConnection::DataCommandUniquePtr selectCommand =
611 m_connection->PrepareDataCommand(DB_CMD_KEY_SELECT);
612 selectCommand->BindString(1, label.c_str());
614 if (selectCommand->Step()) {
615 return RawBufferOptional(
616 selectCommand->GetColumnBlob(0));
618 return RawBufferOptional();
621 } Catch (SqlConnection::Exception::InvalidColumn) {
622 LogError("Select statement invalid column error");
623 } Catch (SqlConnection::Exception::SyntaxError) {
624 LogError("Couldn't prepare insert key statement");
625 } Catch (SqlConnection::Exception::InternalError) {
626 LogError("Couldn't execute insert statement");
628 ThrowMsg(Crypto::Exception::InternalError,
629 "Couldn't get key for label " << label);
632 void Crypto::deleteKey(const Label& label) {
634 Transaction transaction(this);
636 SqlConnection::DataCommandUniquePtr deleteCommand =
637 m_connection->PrepareDataCommand(DB_CMD_KEY_DELETE);
638 deleteCommand->BindString(1, label.c_str());
639 deleteCommand->Step();
641 NameTable nameTable(this->m_connection);
642 nameTable.deleteAllRows(label);
644 transaction.commit();
646 } Catch (SqlConnection::Exception::SyntaxError) {
647 LogError("Couldn't prepare insert key statement");
648 } Catch (SqlConnection::Exception::InternalError) {
649 LogError("Couldn't execute insert statement");
651 ThrowMsg(Crypto::Exception::InternalError,
652 "Couldn't delete key for label " << label);
655 void Crypto::setPermission(
657 const Label& ownerLabel,
658 const Label& accessorLabel,
659 const PermissionMask permissionMask)
662 PermissionTable permissionTable(this->m_connection);
663 permissionTable.setPermission(name, ownerLabel, accessorLabel, permissionMask);
665 } Catch (SqlConnection::Exception::SyntaxError) {
666 LogError("Couldn't prepare set statement");
667 } Catch (SqlConnection::Exception::InternalError) {
668 LogError("Couldn't execute set statement");
670 ThrowMsg(Crypto::Exception::InternalError,
671 "Couldn't set permissions for name " << name );
675 void Crypto::SchemaInfo::setVersionInfo() {
676 SqlConnection::DataCommandUniquePtr insertContextCommand =
677 m_db->m_connection->PrepareDataCommand(DB_CMD_SCHEMA_SET);
678 insertContextCommand->BindString(101, DB_SCHEMA_VERSION_FIELD);
679 insertContextCommand->BindString(103, std::to_string(DB_VERSION_CURRENT).c_str());
680 insertContextCommand->Step();
683 bool Crypto::SchemaInfo::getVersionInfo(int & version) const
685 // Try..Catch mandatory here - we don't need to escalate the error
686 // if it happens - we just won't return the version, allowing CKM to work
688 SqlConnection::DataCommandUniquePtr selectCommand =
689 m_db->m_connection->PrepareDataCommand(DB_CMD_SCHEMA_GET);
690 selectCommand->BindString(101, DB_SCHEMA_VERSION_FIELD);
692 if(selectCommand->Step()) {
693 version = static_cast<int>(atoi(selectCommand->GetColumnString(1).c_str()));
696 } Catch (SqlConnection::Exception::InvalidColumn) {
697 LogError("Select statement invalid column error");
698 } Catch (SqlConnection::Exception::SyntaxError) {
699 LogError("Couldn't prepare select statement");
700 } Catch (SqlConnection::Exception::InternalError) {
701 LogError("Couldn't execute select statement");
706 void Crypto::PermissionTable::setPermission(
708 const Label& ownerLabel,
709 const Label& accessorLabel,
710 const PermissionMask permissionMask)
712 if(permissionMask == Permission::NONE)
715 SqlConnection::DataCommandUniquePtr deletePermissionCommand =
716 m_connection->PrepareDataCommand(DB_CMD_PERMISSION_DELETE);
717 deletePermissionCommand->BindString(104, accessorLabel.c_str());
718 deletePermissionCommand->BindString(101, name.c_str());
719 deletePermissionCommand->BindString(102, ownerLabel.c_str());
720 deletePermissionCommand->Step();
724 // add new permissions
725 SqlConnection::DataCommandUniquePtr setPermissionCommand =
726 m_connection->PrepareDataCommand(DB_CMD_PERMISSION_SET);
727 setPermissionCommand->BindString(104, accessorLabel.c_str());
728 setPermissionCommand->BindInteger(105, static_cast<int>(permissionMask));
729 setPermissionCommand->BindString(101, name.c_str());
730 setPermissionCommand->BindString(102, ownerLabel.c_str());
731 setPermissionCommand->Step();
735 PermissionMaskOptional Crypto::PermissionTable::getPermissionRow(
737 const Label &ownerLabel,
738 const Label &accessorLabel) const
740 SqlConnection::DataCommandUniquePtr selectCommand =
741 m_connection->PrepareDataCommand(DB_CMD_PERMISSION_SELECT);
742 selectCommand->BindString(104, accessorLabel.c_str());
744 // name table reference
745 selectCommand->BindString(101, name.c_str());
746 selectCommand->BindString(102, ownerLabel.c_str());
748 if(selectCommand->Step())
750 // there is entry for the <name, ownerLabel> pair
751 return PermissionMaskOptional(PermissionMask(selectCommand->GetColumnInteger(0)));
753 return PermissionMaskOptional();
756 void Crypto::NameTable::addRow(
758 const Label &ownerLabel)
761 SqlConnection::DataCommandUniquePtr insertNameCommand =
762 m_connection->PrepareDataCommand(DB_CMD_NAME_INSERT);
763 insertNameCommand->BindString (101, name.c_str());
764 insertNameCommand->BindString (102, ownerLabel.c_str());
765 insertNameCommand->Step();
768 void Crypto::NameTable::deleteRow(
770 const Label &ownerLabel)
772 SqlConnection::DataCommandUniquePtr deleteCommand =
773 m_connection->PrepareDataCommand(DB_CMD_NAME_DELETE);
774 deleteCommand->BindString(101, name.c_str());
775 deleteCommand->BindString(102, ownerLabel.c_str());
777 // Step() result code does not provide information whether
778 // anything was removed.
779 deleteCommand->Step();
782 void Crypto::NameTable::deleteAllRows(const Label &ownerLabel)
784 SqlConnection::DataCommandUniquePtr deleteData =
785 m_connection->PrepareDataCommand(DB_CMD_NAME_DELETE_BY_LABEL);
786 deleteData->BindString(102, ownerLabel.c_str());
788 // Step() result code does not provide information whether
789 // anything was removed.
793 bool Crypto::NameTable::isPresent(const Name &name, const Label &ownerLabel) const
795 SqlConnection::DataCommandUniquePtr checkCmd =
796 m_connection->PrepareDataCommand(DB_CMD_NAME_COUNT_ROWS);
797 checkCmd->BindString(101, name.c_str());
798 checkCmd->BindString(102, ownerLabel.c_str());
799 if(checkCmd->Step()) {
800 int element_count = checkCmd->GetColumnInteger(0);
801 LogDebug("Item name: " << name << " ownerLabel: " << ownerLabel <<
802 " hit count: " << element_count);
803 if(element_count > 0)
809 void Crypto::ObjectTable::addRow(const Row &row)
811 SqlConnection::DataCommandUniquePtr insertObjectCommand =
812 m_connection->PrepareDataCommand(DB_CMD_OBJECT_INSERT);
813 insertObjectCommand->BindInteger(1, row.exportable);
814 insertObjectCommand->BindInteger(2, static_cast<int>(row.dataType));
815 insertObjectCommand->BindInteger(3, static_cast<int>(row.algorithmType));
816 insertObjectCommand->BindInteger(4, row.encryptionScheme);
817 insertObjectCommand->BindBlob (5, row.iv);
818 insertObjectCommand->BindInteger(6, row.dataSize);
819 insertObjectCommand->BindBlob (7, row.data);
820 insertObjectCommand->BindBlob (8, row.tag);
821 insertObjectCommand->BindInteger(9, static_cast<int>(row.backendId));
823 // name table reference
824 insertObjectCommand->BindString (101, row.name.c_str());
825 insertObjectCommand->BindString (102, row.ownerLabel.c_str());
827 insertObjectCommand->Step();
832 #pragma GCC diagnostic pop