Integration DBCryptoModule, KeyProvider and CKMLogic.
[platform/core/security/key-manager.git] / src / manager / service / ckm-logic.cpp
1 /*
2  *  Copyright (c) 2000 - 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        ckm-logic.cpp
18  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
19  * @version     1.0
20  * @brief       Sample service implementation.
21  */
22 #include <dpl/serialization.h>
23 #include <dpl/log/log.h>
24
25 #include <ckm/ckm-error.h>
26 #include <ckm/ckm-type.h>
27 #include <key-provider.h>
28 #include <file-system.h>
29
30 #include <ckm-logic.h>
31
32 namespace CKM {
33
34 CKMLogic::CKMLogic(){
35     int retCode = FileSystem::init();
36     // TODO what can I do when init went wrong? exit(-1) ??
37     if (retCode) {
38         LogError("Fatal error in FileSystem::init()");
39     }
40 }
41
42 CKMLogic::~CKMLogic(){}
43
44 RawBuffer CKMLogic::unlockUserKey(uid_t user, const std::string &password) {
45     // TODO try catch for all errors that should be supported by error code
46     int retCode = KEY_MANAGER_API_SUCCESS;
47
48     try {
49         if (0 == m_userDataMap.count(user) || !(m_userDataMap[user].keyProvider.isInitialized())) {
50             auto &handle = m_userDataMap[user];
51             FileSystem fs(user);
52             auto wrappedDomainKEK = fs.getDomainKEK();
53
54             if (wrappedDomainKEK.empty()) {
55                 wrappedDomainKEK = KeyProvider::generateDomainKEK(std::to_string(user), password);
56                 fs.saveDomainKEK(wrappedDomainKEK);
57             }
58
59             handle.keyProvider = KeyProvider(wrappedDomainKEK, password);
60
61             RawBuffer key = handle.keyProvider.getPureDomainKEK();
62             handle.database = DBCrypto(fs.getDBPath(), key);
63             handle.crypto = DBCryptoModule(key);
64             // TODO wipe key
65         }
66     } catch (const KeyProvider::Exception::Base &e) {
67         LogError("Error in KeyProvider " << e.GetMessage());
68         retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
69     }
70
71     MessageBuffer response;
72     Serialization::Serialize(response, retCode);
73     return response.Pop();
74 }
75
76 RawBuffer CKMLogic::lockUserKey(uid_t user) {
77     int retCode = KEY_MANAGER_API_SUCCESS;
78     // TODO try catch for all errors that should be supported by error code
79     m_userDataMap.erase(user);
80
81     MessageBuffer response;
82     Serialization::Serialize(response, retCode);
83     return response.Pop();
84 }
85
86 RawBuffer CKMLogic::removeUserData(uid_t user) {
87     int retCode = KEY_MANAGER_API_SUCCESS;
88     // TODO try catch for all errors that should be supported by error code
89     m_userDataMap.erase(user);
90
91     FileSystem fs(user);
92     fs.removeUserData();
93
94     MessageBuffer response;
95     Serialization::Serialize(response, retCode);
96     return response.Pop();
97 }
98
99 RawBuffer CKMLogic::changeUserPassword(
100     uid_t user,
101     const std::string &oldPassword,
102     const std::string &newPassword)
103 {
104     int retCode = KEY_MANAGER_API_SUCCESS;
105     // TODO try-catch
106     FileSystem fs(user);
107     auto wrappedDomainKEK = fs.getDomainKEK();
108     if (wrappedDomainKEK.empty()) {
109         retCode = KEY_MANAGER_API_ERROR_BAD_REQUEST;
110     } else {
111         wrappedDomainKEK = KeyProvider::reencrypt(wrappedDomainKEK, oldPassword, newPassword);
112         fs.saveDomainKEK(wrappedDomainKEK);
113     }
114     MessageBuffer response;
115     Serialization::Serialize(response, retCode);
116     return response.Pop();
117 }
118
119 RawBuffer CKMLogic::resetUserPassword(
120     uid_t user,
121     const std::string &newPassword)
122 {
123     int retCode = KEY_MANAGER_API_SUCCESS;
124     // TODO try-catch
125     if (0 == m_userDataMap.count(user)) {
126         retCode = KEY_MANAGER_API_ERROR_BAD_REQUEST;
127     } else {
128         auto &handler = m_userDataMap[user];
129         FileSystem fs(user);
130         fs.saveDomainKEK(handler.keyProvider.getWrappedDomainKEK(newPassword));
131     }
132
133     MessageBuffer response;
134     Serialization::Serialize(response, retCode);
135     return response.Pop();
136 }
137
138 int CKMLogic::saveDataHelper(
139     Credentials &cred,
140     DBDataType dataType,
141     const Alias &alias,
142     const RawBuffer &key,
143     const PolicySerializable &policy)
144 {
145     if (0 == m_userDataMap.count(cred.uid))
146         return KEY_MANAGER_API_ERROR_DB_LOCKED;
147
148     DBRow row = {   alias,  cred.smackLabel, policy.restricted,
149          policy.extractable, dataType, DBCMAlgType::NONE,
150          0, RawBuffer(10, 'c'), key.size(), key };
151
152     auto &handler = m_userDataMap[cred.uid];
153     if (!handler.crypto.haveKey(cred.smackLabel)) {
154         RawBuffer key;
155         int status = handler.database.getKey(cred.smackLabel, key);
156         if (KEY_MANAGER_API_ERROR_DB_BAD_REQUEST == status) {
157             key = handler.keyProvider.generateDEK(cred.smackLabel);
158             if (KEY_MANAGER_API_SUCCESS != handler.database.saveKey(cred.smackLabel, key))
159                 return KEY_MANAGER_API_ERROR_DB_ERROR;
160         }
161         key = handler.keyProvider.getPureDEK(key);
162         handler.crypto.pushKey(cred.smackLabel, key);
163     }
164     handler.crypto.encryptRow(policy.password, row);
165     return handler.database.saveDBRow(row);
166 }
167
168 RawBuffer CKMLogic::saveData(
169     Credentials &cred,
170     int commandId,
171     DBDataType dataType,
172     const Alias &alias,
173     const RawBuffer &key,
174     const PolicySerializable &policy)
175 {
176     int retCode = KEY_MANAGER_API_SUCCESS;
177
178     try {
179         retCode = saveDataHelper(cred, dataType, alias, key, policy);
180     } catch (const KeyProvider::Exception::Base &e) {
181         LogError("KeyProvider failed with message: " << e.GetMessage());
182         retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
183     } catch (const DBCryptoModule::Exception::Base &e) {
184         LogError("DBCryptoModule failed with message: " << e.GetMessage());
185         retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
186     }
187
188     MessageBuffer response;
189     Serialization::Serialize(response, static_cast<int>(LogicCommand::SAVE));
190     Serialization::Serialize(response, commandId);
191     Serialization::Serialize(response, retCode);
192     Serialization::Serialize(response, static_cast<int>(dataType));
193
194     return response.Pop();
195 }
196
197 RawBuffer CKMLogic::removeData(
198     Credentials &cred,
199     int commandId,
200     DBDataType dataType,
201     const Alias &alias)
202 {
203     (void)cred;
204     (void)alias;
205
206     int retCode = KEY_MANAGER_API_SUCCESS;
207
208     if (0 == m_userDataMap.count(cred.uid)) {
209         retCode = KEY_MANAGER_API_ERROR_DB_LOCKED;
210     } else {
211         // TODO
212         auto &handler = m_userDataMap[cred.uid];
213         (void)handler;
214     }
215
216     MessageBuffer response;
217     Serialization::Serialize(response, static_cast<int>(LogicCommand::REMOVE));
218     Serialization::Serialize(response, commandId);
219     Serialization::Serialize(response, retCode);
220     Serialization::Serialize(response, static_cast<int>(dataType));
221
222     return response.Pop();
223 }
224
225 int CKMLogic::getDataHelper(
226     Credentials &cred,
227     DBDataType dataType,
228     const Alias &alias,
229     const std::string &password,
230     DBRow &row)
231 {
232     (void) dataType;
233
234     if (0 == m_userDataMap.count(cred.uid))
235         return KEY_MANAGER_API_ERROR_DB_LOCKED;
236
237     auto &handler = m_userDataMap[cred.uid];
238     int retCode = handler.database.getDBRow(alias, cred.smackLabel, row);
239
240     if (KEY_MANAGER_API_SUCCESS != retCode){
241         LogDebug("DBCrypto::getDBRow failed with code: " << retCode);
242         return retCode;
243     }
244
245     if (!handler.crypto.haveKey(row.smackLabel)) {
246         RawBuffer key;
247         retCode = handler.database.getKey(row.smackLabel, key);
248         if (KEY_MANAGER_API_SUCCESS != retCode) {
249             LogDebug("DBCrypto::getKey failed with: " << retCode);
250             return retCode;
251         }
252         key = handler.keyProvider.getPureDEK(key);
253         handler.crypto.pushKey(cred.smackLabel, key);
254     }
255     handler.crypto.decryptRow(password, row);
256
257     return KEY_MANAGER_API_SUCCESS;
258 }
259
260 RawBuffer CKMLogic::getData(
261     Credentials &cred,
262     int commandId,
263     DBDataType dataType,
264     const Alias &alias,
265     const std::string &password)
266 {
267     int retCode = KEY_MANAGER_API_SUCCESS;
268     DBRow row;
269
270     try {
271         retCode = getDataHelper(cred, dataType, alias, password, row);
272     } catch (const KeyProvider::Exception::Base &e) {
273         LogError("KeyProvider failed with error: " << e.GetMessage());
274         retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
275     } catch (const DBCryptoModule::Exception::Base &e) {
276         LogError("DBCryptoModule failed with message: " << e.GetMessage());
277         retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
278     }
279
280     MessageBuffer response;
281     Serialization::Serialize(response, static_cast<int>(LogicCommand::GET));
282     Serialization::Serialize(response, commandId);
283     Serialization::Serialize(response, retCode);
284     Serialization::Serialize(response, static_cast<int>(row.dataType));
285     Serialization::Serialize(response, row.data);
286     return response.Pop();
287 }
288
289 RawBuffer CKMLogic::getDataList(
290     Credentials &cred,
291     int commandId,
292     DBDataType dataType)
293 {
294     int retCode = KEY_MANAGER_API_SUCCESS;
295
296     if (0 == m_userDataMap.count(cred.uid)) {
297         retCode = KEY_MANAGER_API_ERROR_DB_LOCKED;
298     } else {
299         auto &handler = m_userDataMap[cred.uid];
300         // TODO
301         (void)handler;
302     }
303
304     MessageBuffer response;
305     Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_LIST));
306     Serialization::Serialize(response, commandId);
307     Serialization::Serialize(response, retCode);
308     Serialization::Serialize(response, static_cast<int>(dataType));
309     Serialization::Serialize(response, AliasVector());
310     return response.Pop();
311 }
312
313 RawBuffer CKMLogic::createKeyPairRSA(
314     Credentials &cred,
315     int commandId,
316     int size,
317     const Alias &privateKeyAlias,
318     const Alias &publicKeyAlias,
319     PolicySerializable policyPrivateKey,
320     PolicySerializable policyPublicKey)
321
322     (void)cred;
323     (void)size;
324     (void)privateKeyAlias;
325     (void)publicKeyAlias,
326     (void)policyPrivateKey;
327     (void)policyPublicKey;
328     MessageBuffer response;
329     Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
330     Serialization::Serialize(response, commandId);
331     Serialization::Serialize(response, static_cast<int>(KEY_MANAGER_API_SUCCESS));
332  
333     return response.Pop();
334 }
335
336 RawBuffer CKMLogic::createKeyPairECDSA(
337     Credentials &cred,
338     int commandId,
339     int type,
340     const Alias &privateKeyAlias,
341     const Alias &publicKeyAlias,
342     PolicySerializable policyPrivateKey,
343     PolicySerializable policyPublicKey)
344 {
345     (void)cred;
346     (void)type;
347     (void)privateKeyAlias;
348     (void)publicKeyAlias,
349     (void)policyPrivateKey;
350     (void)policyPublicKey;
351     
352     MessageBuffer response;
353     Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
354     Serialization::Serialize(response, commandId);
355     Serialization::Serialize(response, static_cast<int>(KEY_MANAGER_API_SUCCESS));
356  
357     return response.Pop();
358 }
359
360 } // namespace CKM
361