Release 0.1.53
[platform/core/security/key-manager.git] / src / manager / service / db-crypto.h
1 /*
2  * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved
3  *
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
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 /*
17  * @file        db-crypto.h
18  * @author      Zofia Abramowska (z.abramowska@samsung.com)
19  * @version     1.0
20  * @brief       Header of encrypted db access layer
21  */
22 #ifndef CKM_DB_CRYPTO_H
23 #define CKM_DB_CRYPTO_H
24
25 #include <vector>
26 #include <string>
27
28 #include <dpl/db/sql_connection.h>
29
30 #include <ckm/ckm-type.h>
31 #include <exception.h>
32 #include <db-row.h>
33 #include <permission.h>
34 #include <protocols.h>
35
36 #pragma GCC diagnostic push
37 #pragma GCC diagnostic warning "-Wdeprecated-declarations"
38
39 namespace CKM {
40
41 class CKMLogicExt;
42
43 namespace DB {
44 class Crypto {
45 public:
46         using RowOptional = boost::optional<Row>;
47         using RawBufferOptional = boost::optional<RawBuffer>;
48
49         Crypto() : m_inUserTransaction(false) {}
50
51         // user name instead of path?
52         // in no way to I condone the use of std::string for legacyPath; see: review
53         Crypto(const std::string &legacyPath, const std::string &path, const RawBuffer &rawPass);
54         Crypto(const Crypto &other) = delete;
55         Crypto(Crypto &&other);
56
57         Crypto &operator=(const Crypto &) = delete;
58         Crypto &operator=(Crypto &&other);
59
60         virtual ~Crypto() = default;
61
62         void saveRow(
63                 const Row &row);
64
65         void saveRows(
66                 const Name &name,
67                 const ClientId &owner,
68                 const RowVector &rows);
69
70         void updateRow(
71                 const Row &row);
72
73         bool isNameOwnerPresent(
74                 const Name &name,
75                 const ClientId &owner) const;
76
77         RowOptional getRow(
78                 const Name &name,
79                 const ClientId &owner,
80                 DataType type);
81
82         RowOptional getRow(
83                 const Name &name,
84                 const ClientId &owner,
85                 DataType typeRangeStart,
86                 DataType typeRangeStop);
87
88         void getRows(
89                 const Name &name,
90                 const ClientId &owner,
91                 DataType type,
92                 RowVector &output);
93
94         void getRows(
95                 const Name &name,
96                 const ClientId &owner,
97                 DataType typeRangeStart,
98                 DataType typeRangeStop,
99                 RowVector &output);
100
101         void listInfos(
102                 const ClientId &owner,
103                 AliasInfoVector &aliasInfoVector,
104                 DataType type);
105
106         void listInfos(
107                 const ClientId &owner,
108                 AliasInfoVector &aliasInfoVector,
109                 DataType typeRangeStart,
110                 DataType typeRangeStop);
111
112         bool deleteRow(
113                 const Name &name,
114                 const ClientId &owner);
115
116         // keys
117         void saveKey(const ClientId &owner, const RawBuffer &key);
118         RawBufferOptional getKey(const ClientId &owner);
119         void deleteKey(const ClientId &owner);
120
121         // permissions
122         void setPermission(
123                 const Name &name,
124                 const ClientId &owner,
125                 const ClientId &accessor,
126                 const PermissionMask permissionMask);
127
128         PermissionMaskOptional getPermissionRow(
129                 const Name &name,
130                 const ClientId &owner,
131                 const ClientId &accessor) const;
132
133         class Transaction {
134         public:
135                 explicit Transaction(Crypto *db) : m_db(db), m_inTransaction(false)
136                 {
137                         if (!m_db->m_inUserTransaction) {
138                                 try {
139                                         m_db->m_connection->BeginTransaction();
140                                         m_db->m_inUserTransaction = true;
141                                         m_inTransaction = true;
142                                 } catch (const SqlConnection::Exception::InternalError &) {
143                                         ThrowErr(Exc::TransactionFailed, "sqlite got into infinite busy state");
144                                 } catch (const SqlConnection::Exception::Base &) {
145                                         ThrowErr(Exc::TransactionFailed, "Couldn't begin transaction");
146                                 }
147                         }
148                 }
149
150                 Transaction(Transaction&& other)
151                 {
152                         m_db = other.m_db;
153                         m_inTransaction = other.m_inTransaction;
154                         other.m_inTransaction = false;
155                 }
156
157                 Transaction& operator=(Transaction&& other)
158                 {
159                         if (this == &other)
160                                 return *this;
161
162                         m_db = other.m_db;
163                         m_inTransaction = other.m_inTransaction;
164                         other.m_inTransaction = false;
165
166                         return *this;
167                 }
168
169                 void commit()
170                 {
171                         if (m_inTransaction) {
172                                 try {
173                                         m_db->m_connection->CommitTransaction();
174                                         m_db->m_inUserTransaction = false;
175                                         m_inTransaction = false;
176                                 } catch (const SqlConnection::Exception::InternalError &) {
177                                         ThrowErr(Exc::TransactionFailed, "sqlite got into infinite busy state");
178                                 } catch (const SqlConnection::Exception::Base &) {
179                                         ThrowErr(Exc::TransactionFailed, "Couldn't commit transaction");
180                                 }
181                         }
182                 }
183
184                 void rollback()
185                 {
186                         if (m_inTransaction) {
187                                 try {
188                                         m_db->m_connection->RollbackTransaction();
189                                         m_db->m_inUserTransaction = false;
190                                         m_inTransaction = false;
191                                 } catch (const SqlConnection::Exception::InternalError &) {
192                                         ThrowErr(Exc::TransactionFailed, "sqlite got into infinite busy state");
193                                 } catch (const SqlConnection::Exception::Base &) {
194                                         ThrowErr(Exc::TransactionFailed, "Couldn't rollback transaction");
195                                 }
196                         }
197                 }
198
199                 ~Transaction()
200                 {
201                         try {
202                                 if (m_inTransaction) {
203                                         m_db->m_inUserTransaction = false;
204                                         m_db->m_connection->RollbackTransaction();
205                                 }
206                         } catch (const SqlConnection::Exception::InternalError &) {
207                                 LogError("sqlite got into infinite busy state");
208                         } catch (const SqlConnection::Exception::Base &) {
209                                 LogError("Transaction rollback failed!");
210                         }
211                 }
212
213         private:
214                 Crypto *m_db;
215                 bool m_inTransaction;
216         };
217
218 protected:
219         std::unique_ptr<SqlConnection> m_connection;
220
221         Row getRow(
222                 const SqlConnection::DataCommandUniquePtr &selectCommand) const;
223
224 private:
225         bool m_inUserTransaction;
226
227         friend CKMLogicExt;
228
229         void resetDB();
230         void initDatabase();
231         void createDBSchema();
232         /**
233          * return current database version
234          *
235          * @param[out] schemaVersion    if success, will contain DB schema version code
236          *
237          * @return false on DB empty or corrupted, true if information read
238          */
239         bool getDBVersion(int &schemaVersion);
240
241         using ScriptOptional = boost::optional<std::string>;
242         ScriptOptional getScript(const std::string &scriptName) const;
243         ScriptOptional getMigrationScript(int db_version) const;
244
245         class SchemaInfo {
246         public:
247                 explicit SchemaInfo(SqlConnection *connection) : m_connection(connection) {}
248
249                 void setVersionInfo();
250                 bool getVersionInfo(int &version);
251
252         private:
253                 SqlConnection *m_connection;
254         };
255
256 public:
257         class NameTable {
258         public:
259                 explicit NameTable(SqlConnection *connection) : m_connection(connection) {}
260
261                 void addRow(
262                         const Name &name,
263                         const ClientId &owner);
264
265                 void deleteRow(
266                         const Name &name,
267                         const ClientId &owner);
268
269                 void deleteAllRows(
270                         const ClientId &owner);
271
272                 bool isPresent(
273                         const Name &name,
274                         const ClientId &owner) const;
275
276         private:
277                 SqlConnection *m_connection;
278         };
279
280         class ObjectTable {
281         public:
282                 explicit ObjectTable(SqlConnection *connection) : m_connection(connection) {}
283
284                 void addRow(
285                         const Row &row);
286                 void updateRow(
287                         const Row &row);
288
289         private:
290                 SqlConnection *m_connection;
291         };
292
293         class PermissionTable {
294         public:
295                 explicit PermissionTable(SqlConnection *connection) : m_connection(
296                                 connection) {}
297
298                 void setPermission(
299                         const Name &name,
300                         const ClientId &owner,
301                         const ClientId &accessor,
302                         const PermissionMask permissionMask);
303
304                 PermissionMaskOptional getPermissionRow(
305                         const Name &name,
306                         const ClientId &owner,
307                         const ClientId &accessor) const;
308
309         private:
310                 SqlConnection *m_connection;
311         };
312 };
313
314 } // namespace DB
315
316 } // namespace CKM
317
318 #pragma GCC diagnostic pop
319 #endif // CKM_DB_CRYPTO_H