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
23 #include <db-crypto.h>
24 #include <dpl/db/sql_connection.h>
25 #include <dpl/log/log.h>
26 #include <ckm/ckm-error.h>
28 #pragma GCC diagnostic push
29 #pragma GCC diagnostic warning "-Wdeprecated-declarations"
32 const char *main_table = "CKM_TABLE";
33 const char *key_table = "KEY_TABLE";
34 const char *permission_table = "PERMISSION_TABLE";
36 // CKM_TABLE (alias TEXT, label TEXT, restricted INT, exportable INT, dataType INT, algorithmType INT,
37 // encryptionScheme INT, iv BLOB, dataSize INT, data BLOB, tag BLOB, idx INT )
39 const char *db_create_main_cmd =
40 "CREATE TABLE CKM_TABLE("
41 " alias TEXT NOT NULL,"
42 " label TEXT NOT NULL,"
43 " exportable INTEGER NOT NULL,"
44 " dataType INTEGER NOT NULL,"
45 " algorithmType INTEGER NOT NULL,"
46 " encryptionScheme INTEGER NOT NULL,"
48 " dataSize INTEGER NOT NULL,"
49 " data BLOB NOT NULL,"
51 " idx INTEGER PRIMARY KEY AUTOINCREMENT,"
52 " UNIQUE(alias, label)"
53 "); CREATE INDEX ckm_index_label ON CKM_TABLE(label);"; // based on ANALYZE and performance test result
55 const char *insert_main_cmd =
56 "INSERT INTO CKM_TABLE("
58 " alias, label, exportable,"
60 " dataType, algorithmType, encryptionScheme,"
62 " iv, dataSize, data, tag) "
64 " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
66 const char *select_alias_cmd =
68 "SELECT * FROM CKM_TABLE WHERE alias=? AND dataType=?; ";
70 const char *select_check_alias_cmd =
72 "SELECT dataType FROM CKM_TABLE WHERE alias=?;";
74 const char *select_label_global_alias_cmd =
76 "SELECT label FROM CKM_TABLE WHERE alias=?;";
78 const char *select_label_index_global_alias_cmd =
80 "SELECT label, idx FROM CKM_TABLE WHERE alias=?;";
82 const char *select_key_alias_cmd =
84 "SELECT * FROM CKM_TABLE WHERE alias=?"
86 " AND dataType BETWEEN ? AND ?;";
88 const char *delete_alias_cmd =
90 "DELETE FROM CKM_TABLE WHERE alias=?;";
92 const char *delete_data_with_key_cmd =
94 "DELETE FROM CKM_TABLE WHERE label=?;";
96 // KEY_TABLE (label TEXT, key BLOB)
98 const char *db_create_key_cmd =
99 "CREATE TABLE KEY_TABLE("
100 " label TEXT PRIMARY KEY,"
104 const char *insert_key_cmd =
105 "INSERT INTO KEY_TABLE(label, key) VALUES (?, ?);";
106 const char *select_key_cmd =
107 "SELECT key FROM KEY_TABLE WHERE label=?;";
108 const char *delete_key_cmd =
109 "DELETE FROM KEY_TABLE WHERE label=?";
112 // PERMISSION_TABLE (alias TEXT, label TEXT, access_flags TEXT, idx INT)
114 const char *db_create_permission_cmd =
115 "CREATE TABLE PERMISSION_TABLE("
116 " alias TEXT NOT NULL,"
117 " label TEXT NOT NULL,"
118 " accessFlags TEXT NOT NULL,"
119 " idx INTEGER NOT NULL,"
120 " FOREIGN KEY(idx) REFERENCES CKM_TABLE(idx) ON DELETE CASCADE,"
121 " PRIMARY KEY(alias, label)"
122 "); CREATE INDEX perm_index_idx ON PERMISSION_TABLE(idx);"; // based on ANALYZE and performance test result
124 const char *set_permission_alias_cmd =
125 "REPLACE INTO PERMISSION_TABLE(alias, label, accessFlags, idx) VALUES (?, ?, ?, ?);";
127 const char *select_permission_cmd =
129 "SELECT accessFlags FROM PERMISSION_TABLE WHERE alias=? AND label=?;";
131 const char *delete_permission_cmd =
133 "DELETE FROM PERMISSION_TABLE WHERE alias=? AND label=?;";
136 // CKM_TABLE x PERMISSION_TABLE
138 const char *select_type_cross_cmd =
140 "SELECT C.label, C.alias FROM CKM_TABLE AS C LEFT JOIN PERMISSION_TABLE AS P ON C.alias = P.alias WHERE C.dataType=? AND (C.label=? OR (P.label=? AND P.accessFlags IS NOT NULL)) GROUP BY C.alias;";
142 const char *select_key_type_cross_cmd =
144 "SELECT C.label, C.alias FROM CKM_TABLE AS C LEFT JOIN PERMISSION_TABLE AS P ON C.alias=P.alias WHERE C.dataType>=? AND C.dataType<=? AND (C.label=? OR (P.label=? AND P.accessFlags IS NOT NULL)) GROUP BY C.alias;";
149 DBCrypto::DBCrypto(const std::string& path,
150 const RawBuffer &rawPass) {
152 m_inUserTransaction = false;
154 m_connection = new SqlConnection(path, SqlConnection::Flag::Option::CRW);
155 m_connection->SetKey(rawPass);
156 m_connection->ExecCommand("VACUUM;");
158 } Catch(SqlConnection::Exception::ConnectionBroken) {
159 LogError("Couldn't connect to database: " << path);
160 ReThrow(DBCrypto::Exception::InternalError);
161 } Catch(SqlConnection::Exception::InvalidArguments) {
162 LogError("Couldn't set the key for database");
163 ReThrow(DBCrypto::Exception::InternalError);
164 } Catch(SqlConnection::Exception::SyntaxError) {
165 LogError("Couldn't initiate the database");
166 ReThrow(DBCrypto::Exception::InternalError);
167 } Catch(SqlConnection::Exception::InternalError) {
168 LogError("Couldn't create the database");
169 ReThrow(DBCrypto::Exception::InternalError);
173 DBCrypto::DBCrypto(DBCrypto &&other) :
174 m_connection(other.m_connection),
175 m_inUserTransaction(other.m_inUserTransaction){
176 other.m_connection = NULL;
177 other.m_inUserTransaction = false;
180 DBCrypto::~DBCrypto() {
184 DBCrypto& DBCrypto::operator=(DBCrypto&& other) {
189 m_connection = other.m_connection;
190 other.m_connection = NULL;
192 m_inUserTransaction = other.m_inUserTransaction;
193 other.m_inUserTransaction = false;
198 void DBCrypto::createTable(
199 const char* create_cmd,
200 const char *table_name)
203 m_connection->ExecCommand(create_cmd);
204 } Catch(SqlConnection::Exception::SyntaxError) {
205 LogError("Couldn't create table : " << table_name << "!");
207 } Catch(SqlConnection::Exception::InternalError) {
208 LogError("Sqlite got into infinite busy state");
213 void DBCrypto::initDatabase() {
214 Transaction transaction(this);
215 if(!m_connection->CheckTableExist(main_table)) {
216 createTable(db_create_main_cmd, main_table);
218 if(!m_connection->CheckTableExist(key_table)) {
219 createTable(db_create_key_cmd, key_table);
221 if(!m_connection->CheckTableExist(permission_table)) {
222 createTable(db_create_permission_cmd, permission_table);
224 transaction.commit();
227 void DBCrypto::getLabelForAlias(const std::string& alias, std::string & label) const {
228 SqlConnection::DataCommandUniquePtr checkCmd =
229 m_connection->PrepareDataCommand(select_label_global_alias_cmd);
230 checkCmd->BindString(1, alias.c_str());
231 if(checkCmd->Step()) {
232 label = checkCmd->GetColumnString(0);
237 void DBCrypto::getLabelForAlias(const std::string& alias, std::string & label, int & index) const
239 SqlConnection::DataCommandUniquePtr checkCmd =
240 m_connection->PrepareDataCommand(select_label_index_global_alias_cmd);
241 checkCmd->BindString(1, alias.c_str());
242 if(checkCmd->Step()) {
243 label = checkCmd->GetColumnString(0);
244 index = checkCmd->GetColumnInteger(1);
253 bool DBCrypto::checkGlobalAliasExist(const std::string& alias) const {
255 getLabelForAlias(alias, label);
256 if(label.empty() == false) {
257 LogDebug("Global alias '" << alias << "' exists already for label " << label);
263 bool DBCrypto::checkAliasExist(const std::string& alias) const {
264 SqlConnection::DataCommandUniquePtr checkCmd =
265 m_connection->PrepareDataCommand(select_check_alias_cmd);
266 checkCmd->BindString(1, alias.c_str());
267 if(checkCmd->Step()) {
268 LogDebug("Private alias '" << alias << "' exists already for type "
269 << checkCmd->GetColumnInteger(0));
275 void DBCrypto::saveDBRow(const DBRow &row){
278 //Sqlite does not support partial index in our version,
279 //so we do it by hand
280 Transaction transaction(this);
281 if(checkAliasExist(row.alias)) {
282 ThrowMsg(DBCrypto::Exception::AliasExists,
283 "Alias exists for alias: " << row.alias);
286 SqlConnection::DataCommandUniquePtr insertCommand =
287 m_connection->PrepareDataCommand(insert_main_cmd);
288 insertCommand->BindString(1, row.alias.c_str());
289 insertCommand->BindString(2, row.smackLabel.c_str());
290 insertCommand->BindInteger(3, row.exportable);
291 insertCommand->BindInteger(4, static_cast<int>(row.dataType));
292 insertCommand->BindInteger(5, static_cast<int>(row.algorithmType));
293 insertCommand->BindInteger(6, row.encryptionScheme);
294 insertCommand->BindBlob(7, row.iv);
295 insertCommand->BindInteger(8, row.dataSize);
296 insertCommand->BindBlob(9, row.data);
297 insertCommand->BindBlob(10, row.tag);
299 insertCommand->Step();
300 transaction.commit();
303 } Catch(SqlConnection::Exception::SyntaxError) {
304 LogError("Couldn't prepare insert statement");
305 } Catch(SqlConnection::Exception::InternalError) {
306 LogError("Couldn't execute insert statement");
308 ThrowMsg(DBCrypto::Exception::InternalError,
309 "Couldn't save DBRow");
312 DBRow DBCrypto::getRow(const SqlConnection::DataCommandUniquePtr &selectCommand) {
314 row.alias = selectCommand->GetColumnString(0);
315 row.smackLabel = selectCommand->GetColumnString(1);
316 row.exportable = selectCommand->GetColumnInteger(2);
317 row.dataType = static_cast<DBDataType>(selectCommand->GetColumnInteger(3));
318 row.algorithmType = static_cast<DBCMAlgType>(selectCommand->GetColumnInteger(4));
319 row.encryptionScheme = selectCommand->GetColumnInteger(5);
320 row.iv = selectCommand->GetColumnBlob(6);
321 row.dataSize = selectCommand->GetColumnInteger(7);
322 row.data = selectCommand->GetColumnBlob(8);
323 row.tag = selectCommand->GetColumnBlob(9);
327 std::string DBCrypto::getPermissionsForAliasAndLabel(const Alias &alias, const std::string &label) const
330 SqlConnection::DataCommandUniquePtr selectCommand =
331 m_connection->PrepareDataCommand(select_permission_cmd);
332 selectCommand->BindString(1, alias.c_str());
333 selectCommand->BindString(2, label.c_str());
335 if(selectCommand->Step())
336 return selectCommand->GetColumnString(0);
338 return std::string();
339 } Catch (SqlConnection::Exception::InvalidColumn) {
340 LogError("Select statement invalid column error");
341 } Catch (SqlConnection::Exception::SyntaxError) {
342 LogError("Couldn't prepare select statement");
343 } Catch (SqlConnection::Exception::InternalError) {
344 LogError("Couldn't execute select statement");
346 return std::string();
350 bool DBCrypto::rowAccessControlCheck(const Alias &alias,
351 const std::string &owner_label,
352 const std::string &clnt_label,
353 DBCrypto::DBOperationType access_type) const
355 // owner of the entry have all the permissions by default
356 // check if requesting client is the entry owner - if so, exit (permission granted)
357 if(owner_label == clnt_label)
360 // perform permissions DB query
361 std::string permission_string = this->getPermissionsForAliasAndLabel(alias, clnt_label);
363 // check if requested operation is in the permission string
364 LogDebug("pair <" << alias << "," << clnt_label << "> permission rights: \"" << permission_string << "\"");
365 if(permission_string.find(access_type) != std::string::npos)
370 bool DBCrypto::rowAccessControlCheck(const DBRow & input_row,
371 const std::string &clnt_label,
372 DBCrypto::DBOperationType access_type) const
374 return this->rowAccessControlCheck(input_row.alias, input_row.smackLabel, clnt_label, access_type);
378 DBCrypto::DBRowOptional DBCrypto::getDBRow(
380 const std::string &clnt_label,
384 Transaction transaction(this);
385 SqlConnection::DataCommandUniquePtr selectCommand =
386 m_connection->PrepareDataCommand(select_alias_cmd);
387 selectCommand->BindString(1, alias.c_str());
388 selectCommand->BindInteger(2, static_cast<int>(type));
390 if(selectCommand->Step())
393 DBRow current_row = getRow(selectCommand);
395 // check access rights here
396 if( ! this->rowAccessControlCheck(current_row, clnt_label, DBCrypto::DB_OPERATION_READ) )
397 ThrowMsg(Exception::PermissionDenied, "Not enough permissions to perform requested operation");
399 // finalize DB operations
400 transaction.commit();
403 return DBRowOptional(current_row);
405 return DBRowOptional();
407 } Catch (SqlConnection::Exception::InvalidColumn) {
408 LogError("Select statement invalid column error");
409 } Catch (SqlConnection::Exception::SyntaxError) {
410 LogError("Couldn't prepare select statement");
411 } Catch (SqlConnection::Exception::InternalError) {
412 LogError("Couldn't execute select statement");
414 ThrowMsg(DBCrypto::Exception::InternalError,
415 "Couldn't get row for type " << static_cast<int>(type) <<
416 " alias " << alias << " using client label " << clnt_label);
419 DBCrypto::DBRowOptional DBCrypto::getKeyDBRow(
421 const std::string &clnt_label)
424 Transaction transaction(this);
425 SqlConnection::DataCommandUniquePtr selectCommand =
426 m_connection->PrepareDataCommand(select_key_alias_cmd);
427 selectCommand->BindString(1, alias.c_str());
428 selectCommand->BindInteger(2, static_cast<int>(DBDataType::DB_KEY_FIRST));
429 selectCommand->BindInteger(3, static_cast<int>(DBDataType::DB_KEY_LAST));
431 if(selectCommand->Step())
434 DBRow current_row = getRow(selectCommand);
436 // check access rights here
437 if( ! this->rowAccessControlCheck(current_row, clnt_label, DBCrypto::DB_OPERATION_READ) )
438 ThrowMsg(Exception::PermissionDenied, "Not enough permissions to perform requested operation");
440 // finalize DB operations
441 transaction.commit();
444 return DBRowOptional(current_row);
446 return DBRowOptional();
448 } Catch (SqlConnection::Exception::InvalidColumn) {
449 LogError("Select statement invalid column error");
450 } Catch (SqlConnection::Exception::SyntaxError) {
451 LogError("Couldn't prepare select statement");
452 } Catch (SqlConnection::Exception::InternalError) {
453 LogError("Couldn't execute select statement");
455 ThrowMsg(DBCrypto::Exception::InternalError,
456 "Couldn't get Key for alias " << alias
457 << " using client label " << clnt_label);
460 void DBCrypto::getSingleType(
461 const std::string &clnt_label,
463 LabelAliasVector& aliases) const
466 SqlConnection::DataCommandUniquePtr selectCommand =
467 m_connection->PrepareDataCommand(select_type_cross_cmd);
468 selectCommand->BindInteger(1, static_cast<int>(type));
469 selectCommand->BindString(2, clnt_label.c_str());
470 selectCommand->BindString(3, clnt_label.c_str());
472 while(selectCommand->Step()) {
473 std::string label = selectCommand->GetColumnString(0);
474 Alias alias = selectCommand->GetColumnString(1);
475 aliases.push_back(std::make_pair(label, alias));
478 } Catch (SqlConnection::Exception::InvalidColumn) {
479 LogError("Select statement invalid column error");
480 } Catch (SqlConnection::Exception::SyntaxError) {
481 LogError("Couldn't prepare select statement");
482 } Catch (SqlConnection::Exception::InternalError) {
483 LogError("Couldn't execute select statement");
485 ThrowMsg(DBCrypto::Exception::InternalError,
486 "Couldn't get type " << static_cast<int>(type));
489 void DBCrypto::getAliases(
490 const std::string &clnt_label,
492 LabelAliasVector& aliases)
494 getSingleType(clnt_label, type, aliases);
498 void DBCrypto::getKeyAliases(const std::string &clnt_label, LabelAliasVector &aliases)
501 Transaction transaction(this);
502 SqlConnection::DataCommandUniquePtr selectCommand =
503 m_connection->PrepareDataCommand(select_key_type_cross_cmd);
504 selectCommand->BindInteger(1, static_cast<int>(DBDataType::DB_KEY_FIRST));
505 selectCommand->BindInteger(2, static_cast<int>(DBDataType::DB_KEY_LAST));
506 selectCommand->BindString(3, clnt_label.c_str());
507 selectCommand->BindString(4, clnt_label.c_str());
509 while(selectCommand->Step()) {
510 std::string label = selectCommand->GetColumnString(0);
511 Alias alias = selectCommand->GetColumnString(1);
512 aliases.push_back(std::make_pair(label, alias));
514 transaction.commit();
516 } Catch (SqlConnection::Exception::InvalidColumn) {
517 LogError("Select statement invalid column error");
518 } Catch (SqlConnection::Exception::SyntaxError) {
519 LogError("Couldn't prepare select statement");
520 } Catch (SqlConnection::Exception::InternalError) {
521 LogError("Couldn't execute select statement");
523 ThrowMsg(DBCrypto::Exception::InternalError, "Couldn't get key aliases");
526 bool DBCrypto::deleteDBRow(const Alias &alias, const std::string &clnt_label)
529 Transaction transaction(this);
531 std::string owner_label;
532 getLabelForAlias(alias, owner_label);
533 if( ! owner_label.empty() )
535 // check access rights here
536 if( ! this->rowAccessControlCheck(alias, owner_label, clnt_label, DBCrypto::DB_OPERATION_REMOVE) )
537 ThrowMsg(Exception::PermissionDenied, "Not enough permissions to perform requested remove operation");
539 // if here, access right is granted - proceed with removal
540 // note: PERMISSION_TABLE entry will be deleted automatically by SQL (cascade relation between tables)
541 SqlConnection::DataCommandUniquePtr deleteCommand =
542 m_connection->PrepareDataCommand(delete_alias_cmd);
543 deleteCommand->BindString(1, alias.c_str());
544 deleteCommand->Step();
546 transaction.commit();
551 LogError("Error: no such alias: " << alias);
554 } Catch (SqlConnection::Exception::SyntaxError) {
555 LogError("Couldn't prepare delete statement");
556 } Catch (SqlConnection::Exception::InternalError) {
557 LogError("Couldn't execute delete statement");
559 ThrowMsg(DBCrypto::Exception::InternalError,
560 "Couldn't delete DBRow for alias " << alias << " using client label " << clnt_label);
563 void DBCrypto::saveKey(
564 const std::string& label,
565 const RawBuffer &key)
568 Transaction transaction(this);
569 SqlConnection::DataCommandUniquePtr insertCommand =
570 m_connection->PrepareDataCommand(insert_key_cmd);
571 insertCommand->BindString(1, label.c_str());
572 insertCommand->BindBlob(2, key);
573 insertCommand->Step();
574 transaction.commit();
576 } Catch (SqlConnection::Exception::SyntaxError) {
577 LogError("Couldn't prepare insert key statement");
578 } Catch (SqlConnection::Exception::InternalError) {
579 LogError("Couldn't execute insert statement");
581 ThrowMsg(DBCrypto::Exception::InternalError,
582 "Couldn't save key for label " << label);
585 DBCrypto::RawBufferOptional DBCrypto::getKey(
586 const std::string& label)
589 Transaction transaction(this);
590 SqlConnection::DataCommandUniquePtr selectCommand =
591 m_connection->PrepareDataCommand(select_key_cmd);
592 selectCommand->BindString(1, label.c_str());
594 if (selectCommand->Step()) {
595 transaction.commit();
596 return RawBufferOptional(
597 selectCommand->GetColumnBlob(0));
599 transaction.commit();
600 return RawBufferOptional();
603 } Catch (SqlConnection::Exception::InvalidColumn) {
604 LogError("Select statement invalid column error");
605 } Catch (SqlConnection::Exception::SyntaxError) {
606 LogError("Couldn't prepare insert key statement");
607 } Catch (SqlConnection::Exception::InternalError) {
608 LogError("Couldn't execute insert statement");
610 ThrowMsg(DBCrypto::Exception::InternalError,
611 "Couldn't get key for label " << label);
614 void DBCrypto::deleteKey(const std::string& label) {
616 Transaction transaction(this);
618 SqlConnection::DataCommandUniquePtr deleteCommand =
619 m_connection->PrepareDataCommand(delete_key_cmd);
620 deleteCommand->BindString(1, label.c_str());
621 deleteCommand->Step();
623 SqlConnection::DataCommandUniquePtr deleteData =
624 m_connection->PrepareDataCommand(delete_data_with_key_cmd);
625 deleteData->BindString(1, label.c_str());
628 transaction.commit();
630 } Catch (SqlConnection::Exception::SyntaxError) {
631 LogError("Couldn't prepare insert key statement");
632 } Catch (SqlConnection::Exception::InternalError) {
633 LogError("Couldn't execute insert statement");
635 ThrowMsg(DBCrypto::Exception::InternalError,
636 "Couldn't delete key for label " << label);
640 int DBCrypto::setAccessRights( const std::string& clnt_label,
642 const std::string& accessor_label,
643 const AccessRight value_to_set)
646 Transaction transaction(this);
648 // check if label is present
650 std::string owner_label;
651 getLabelForAlias(alias, owner_label, ckm_tab_index);
652 if( ! owner_label.empty() )
654 // owner can not add permissions to itself
655 if(owner_label.compare(accessor_label) == 0)
656 ThrowMsg(Exception::InvalidArgs, "Invalid accessor label: equal to owner label");
658 // check access rights here - only owner can modify permissions
659 if(owner_label != clnt_label)
660 ThrowMsg(Exception::PermissionDenied, "Not enough permissions to perform requested write operation");
662 // if here, access right is granted - proceed to set permissions
663 SqlConnection::DataCommandUniquePtr setPermissionCommand =
664 m_connection->PrepareDataCommand(set_permission_alias_cmd);
665 setPermissionCommand->BindString(1, alias.c_str());
666 setPermissionCommand->BindString(2, accessor_label.c_str());
667 setPermissionCommand->BindString(3, toDBAccessRight(value_to_set));
668 setPermissionCommand->BindInteger(4, ckm_tab_index);
669 setPermissionCommand->Step();
670 transaction.commit();
671 return CKM_API_SUCCESS;
675 LogError("Error: no such alias: " << alias);
676 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
678 } Catch (SqlConnection::Exception::SyntaxError) {
679 LogError("Couldn't prepare set statement");
680 } Catch (SqlConnection::Exception::InternalError) {
681 LogError("Couldn't execute set statement");
683 ThrowMsg(DBCrypto::Exception::InternalError,
684 "Couldn't set permissions for alias " << alias << " using client label " << clnt_label);
687 int DBCrypto::clearAccessRights(const std::string& clnt_label,
689 const std::string& accessor_label)
692 Transaction transaction(this);
694 std::string owner_label;
695 getLabelForAlias(alias, owner_label);
696 if( ! owner_label.empty() )
698 // check access rights here - only owner can modify permissions
699 if(owner_label != clnt_label)
700 ThrowMsg(Exception::PermissionDenied, "Not enough permissions to perform requested write operation");
702 // check if permission for <label, accessor_label> is defined - otherwise nothing to drop
703 if( this->getPermissionsForAliasAndLabel(alias, accessor_label).empty() )
704 ThrowMsg(Exception::InvalidArgs, "Permission not found");
706 // if here, access right is granted - proceed to delete permissions
707 SqlConnection::DataCommandUniquePtr deletePermissionCommand =
708 m_connection->PrepareDataCommand(delete_permission_cmd);
709 deletePermissionCommand->BindString(1, alias.c_str());
710 deletePermissionCommand->BindString(2, accessor_label.c_str());
711 deletePermissionCommand->Step();
712 transaction.commit();
713 return CKM_API_SUCCESS;
717 LogError("Error: no such alias: " << alias);
718 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
720 } Catch (SqlConnection::Exception::SyntaxError) {
721 LogError("Couldn't prepare delete statement");
722 } Catch (SqlConnection::Exception::InternalError) {
723 LogError("Couldn't execute delete statement");
725 ThrowMsg(DBCrypto::Exception::InternalError,
726 "Couldn't delete permissions for alias " << alias << " using client label " << clnt_label);
731 #pragma GCC diagnostic pop