c83b1e1bcd8289bdc898e18f67152f41f1fba6ad
[platform/core/security/key-manager.git] / src / manager / service / db-crypto.h
1 /*
2  * Copyright (c) 2014 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
23 #ifndef DB_CRYPTO_H
24 #define DB_CRYPTO_H
25
26 #include <vector>
27 #include <string>
28
29 #include <dpl/db/sql_connection.h>
30
31 #include <ckm/ckm-type.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 namespace DB {
41     class Crypto {
42          public:
43             typedef boost::optional<Row> RowOptional;
44             typedef boost::optional<RawBuffer> RawBufferOptional;
45             class Exception
46             {
47             public:
48                 DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
49                 DECLARE_EXCEPTION_TYPE(Base, InternalError)
50                 DECLARE_EXCEPTION_TYPE(Base, TransactionError)
51                 DECLARE_EXCEPTION_TYPE(Base, InvalidArgs)
52             };
53             Crypto() :
54                 m_connection(NULL),
55                 m_inUserTransaction(false)
56               {};
57             // user name instead of path?
58             Crypto(const std::string &path, const RawBuffer &rawPass);
59             Crypto(const Crypto &other) = delete;
60             Crypto(Crypto &&other);
61
62             Crypto& operator=(const Crypto& ) = delete;
63             Crypto& operator=(Crypto&& other);
64
65             virtual ~Crypto();
66
67             void saveRow(
68                     const Row &row);
69
70             void saveRows(
71                     const Name &name,
72                     const Label &owner,
73                     const RowVector &rows);
74
75             bool isNameLabelPresent(
76                     const Name &name,
77                     const Label &owner) const;
78
79             RowOptional getRow(
80                     const Name &name,
81                     const Label &ownerLabel,
82                     DataType type);
83
84             RowOptional getRow(
85                     const Name &name,
86                     const Label &ownerLabel,
87                     DataType typeRangeStart,
88                     DataType typeRangeStop);
89
90             void getRows(
91                     const Name &name,
92                     const Label &ownerLabel,
93                     DataType type,
94                     RowVector &output);
95
96             void getRows(
97                     const Name &name,
98                     const Label &ownerLabel,
99                     DataType typeRangeStart,
100                     DataType typeRangeStop,
101                     RowVector &output);
102
103             void listNames(
104                     const Label &smackLabel,
105                     LabelNameVector& labelNameVector,
106                     DataType type);
107
108             void listNames(
109                     const Label &smackLabel,
110                     LabelNameVector& labelNameVector,
111                     DataType typeRangeStart,
112                     DataType typeRangeStop);
113
114             bool deleteRow(
115                     const Name &name,
116                     const Label &ownerLabel);
117
118             // keys
119             void saveKey(const Label& label, const RawBuffer &key);
120             RawBufferOptional getKey(const Label& label);
121             void deleteKey(const Label& label);
122
123
124             // permissions
125             void setPermission(
126                     const Name &name,
127                     const Label &ownerLabel,
128                     const Label &accessorLabel,
129                     const PermissionMask permissionMask);
130
131             PermissionMaskOptional getPermissionRow(
132                     const Name &name,
133                     const Label &ownerLabel,
134                     const Label &accessorLabel) const;
135
136
137             // transactions
138             int beginTransaction();
139             int commitTransaction();
140             int rollbackTransaction();
141
142             class Transaction {
143             public:
144                 Transaction(Crypto *db)
145                     : m_db(db),
146                       m_inTransaction(false) {
147                     if(!m_db->m_inUserTransaction) {
148                         Try {
149                             m_db->m_connection->ExecCommand("BEGIN EXCLUSIVE");
150                             m_db->m_inUserTransaction = true;
151                             m_inTransaction = true;
152                         } Catch (SqlConnection::Exception::InternalError) {
153                             LogError("sqlite got into infinite busy state");
154                             ReThrow(Crypto::Exception::TransactionError);
155                         } Catch (SqlConnection::Exception::Base) {
156                             LogError("Couldn't begin transaction");
157                             ReThrow(Crypto::Exception::TransactionError);
158                         }
159                     }
160                 }
161                 void commit() {
162                     if(m_inTransaction) {
163                         Try {
164                             m_db->m_connection->CommitTransaction();
165                             m_db->m_inUserTransaction = false;
166                             m_inTransaction = false;
167                         } Catch (SqlConnection::Exception::InternalError) {
168                             LogError("sqlite got into infinite busy state");
169                             ReThrow(Crypto::Exception::TransactionError);
170                         } Catch (SqlConnection::Exception::Base) {
171                             LogError("Couldn't commit transaction");
172                             ReThrow(Crypto::Exception::TransactionError);
173                         }
174                     }
175                 }
176                 void rollback() {
177                     if(m_inTransaction) {
178                         Try {
179                             m_db->m_connection->RollbackTransaction();
180                             m_db->m_inUserTransaction = false;
181                             m_inTransaction = false;
182                         } Catch (SqlConnection::Exception::InternalError) {
183                             LogError("sqlite got into infinite busy state");
184                             ReThrow(Crypto::Exception::TransactionError);
185                         } Catch (SqlConnection::Exception::Base) {
186                             LogError("Couldn't rollback transaction");
187                             ReThrow(Crypto::Exception::TransactionError);
188                         }
189                     }
190                 }
191                 ~Transaction() {
192                     Try {
193                         if(m_inTransaction) {
194                             m_db->m_inUserTransaction = false;
195                             m_db->m_connection->RollbackTransaction();
196                         }
197                     } Catch (SqlConnection::Exception::InternalError) {
198                         LogError("sqlite got into infinite busy state");
199                         ReThrow(Crypto::Exception::TransactionError);
200                     } Catch (SqlConnection::Exception::Base) {
201                         LogError("Transaction rollback failed!");
202                     }
203                 }
204             private:
205                 Crypto *m_db;
206                 bool m_inTransaction;
207             };
208
209          protected:
210             SqlConnection* m_connection;
211          private:
212             bool m_inUserTransaction;
213
214             void resetDB();
215             void initDatabase();
216             void createDBSchema();
217             /**
218              * return current database version
219              *
220              * @param[out] schemaVersion    if success, will contain DB schema version code
221              *
222              * @return false on DB empty or corrupted, true if information read
223              */
224             bool getDBVersion(int & schemaVersion);
225             typedef boost::optional<std::string> ScriptOptional;
226             ScriptOptional getScript(const std::string &scriptName) const;
227             ScriptOptional getMigrationScript(int db_version) const;
228
229             Row getRow(
230                     const SqlConnection::DataCommandUniquePtr &selectCommand) const;
231
232             void createTable(
233                     const char *create_cmd,
234                     const char *table_name);
235
236             void createView(
237                     const char* create_cmd);
238
239             class SchemaInfo {
240             public:
241                 explicit SchemaInfo(const Crypto *db) : m_db(db) {}
242
243                 void        setVersionInfo();
244                 bool        getVersionInfo(int & version) const;
245
246             private:
247                 const Crypto *m_db;
248             };
249
250         public:
251             class NameTable {
252             public:
253                 explicit NameTable(SqlConnection* connection) : m_connection(connection) {}
254
255                 void addRow(
256                         const Name &name,
257                         const Label &ownerLabel);
258
259                 void deleteRow(
260                         const Name &name,
261                         const Label &ownerLabel);
262
263                 void deleteAllRows(
264                         const Label &ownerLabel);
265
266                 bool isPresent(
267                         const Name &name,
268                         const Label &ownerLabel) const;
269
270             private:
271                 SqlConnection* m_connection;
272             };
273
274             class ObjectTable {
275             public:
276                 explicit ObjectTable(SqlConnection* connection) : m_connection(connection) {}
277
278                 void addRow(
279                         const Row &row);
280
281             private:
282                 SqlConnection* m_connection;
283             };
284
285             class PermissionTable {
286             public:
287                 explicit PermissionTable(SqlConnection* connection) : m_connection(connection) {}
288
289                 void setPermission(
290                         const Name &name,
291                         const Label &ownerLabel,
292                         const Label &accessorLabel,
293                         const PermissionMask permissionMask);
294
295                 PermissionMaskOptional getPermissionRow(
296                         const Name &name,
297                         const Label &ownerLabel,
298                         const Label &accessorLabel) const;
299
300             private:
301                 SqlConnection* m_connection;
302             };
303     };
304 } // namespace DB
305 } // namespace CKM
306
307 #pragma GCC diagnostic pop
308 #endif //DB_CRYPTO_H
309