Implementation of getCertificateChain.
[platform/core/security/key-manager.git] / src / manager / client / client-manager-impl.cpp
1 /* Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
2  *
3  *  Licensed under the Apache License, Version 2.0 (the "License");
4  *  you may not use this file except in compliance with the License.
5  *  You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  *  Unless required by applicable law or agreed to in writing, software
10  *  distributed under the License is distributed on an "AS IS" BASIS,
11  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  *  See the License for the specific language governing permissions and
13  *  limitations under the License
14  *
15  *
16  * @file        client-manager-impl.cpp
17  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
18  * @version     1.0
19  * @brief       Manager implementation.
20  */
21 #include <openssl/evp.h>
22
23 #include <dpl/serialization.h>
24 #include <dpl/log/log.h>
25
26 #include <client-manager-impl.h>
27 #include <client-common.h>
28 #include <message-buffer.h>
29 #include <protocols.h>
30
31
32 namespace {
33
34 void clientInitialize(void) {
35     OpenSSL_add_all_ciphers();
36     OpenSSL_add_all_algorithms();
37     OpenSSL_add_all_digests();
38 }
39
40 } // namespace anonymous
41
42 namespace CKM {
43
44 bool Manager::ManagerImpl::s_isInit = false;
45
46 Manager::ManagerImpl::ManagerImpl()
47   : m_counter(0)
48 {
49     // TODO secure with mutex
50     if (!s_isInit) {
51         s_isInit = true;
52         clientInitialize();
53     }
54
55 }
56
57
58 int Manager::ManagerImpl::saveBinaryData(
59     const Alias &alias,
60     DBDataType dataType,
61     const RawBuffer &rawData,
62     const Policy &policy)
63 {
64     m_counter++;
65
66     return try_catch([&] {
67         if (alias.empty() || rawData.empty())
68             return CKM_API_ERROR_INPUT_PARAM;
69
70         MessageBuffer send, recv;
71         Serialization::Serialize(send, static_cast<int>(LogicCommand::SAVE));
72         Serialization::Serialize(send, m_counter);
73         Serialization::Serialize(send, static_cast<int>(dataType));
74         Serialization::Serialize(send, alias);
75         Serialization::Serialize(send, rawData);
76         Serialization::Serialize(send, PolicySerializable(policy));
77
78         int retCode = sendToServer(
79             SERVICE_SOCKET_CKM_STORAGE,
80             send.Pop(),
81             recv);
82
83         if (CKM_API_SUCCESS != retCode) {
84             return retCode;
85         }
86
87         int command;
88         int counter;
89         int opType;
90         Deserialization::Deserialize(recv, command);
91         Deserialization::Deserialize(recv, counter);
92         Deserialization::Deserialize(recv, retCode);
93         Deserialization::Deserialize(recv, opType);
94
95         if (counter != m_counter) {
96             return CKM_API_ERROR_UNKNOWN;
97         }
98
99         return retCode;
100     });
101 }
102
103 int Manager::ManagerImpl::saveKey(const Alias &alias, const Key &key, const Policy &policy) {
104     if (key.empty())
105         return CKM_API_ERROR_INPUT_PARAM;
106     return saveBinaryData(alias, toDBDataType(key.getType()), key.getDER(), policy);
107 }
108
109 int Manager::ManagerImpl::saveCertificate(
110     const Alias &alias,
111     const Certificate &cert,
112     const Policy &policy)
113 {
114     return saveBinaryData(alias, DBDataType::CERTIFICATE, cert.getDER(), policy);
115 }
116
117 int Manager::ManagerImpl::saveData(const Alias &alias, const RawBuffer &rawData, const Policy &policy) {
118     if (!policy.extractable)
119         return CKM_API_ERROR_INPUT_PARAM;
120     return saveBinaryData(alias, DBDataType::BINARY_DATA, rawData, policy);
121 }
122
123 int Manager::ManagerImpl::removeBinaryData(const Alias &alias, DBDataType dataType)
124 {
125     return try_catch([&] {
126         if (alias.empty())
127             return CKM_API_ERROR_INPUT_PARAM;
128
129         MessageBuffer send, recv;
130         Serialization::Serialize(send, static_cast<int>(LogicCommand::REMOVE));
131         Serialization::Serialize(send, m_counter);
132         Serialization::Serialize(send, static_cast<int>(dataType));
133         Serialization::Serialize(send, alias);
134
135         int retCode = sendToServer(
136             SERVICE_SOCKET_CKM_STORAGE,
137             send.Pop(),
138             recv);
139
140         if (CKM_API_SUCCESS != retCode) {
141             return retCode;
142         }
143
144         int command;
145         int counter;
146         int opType;
147         Deserialization::Deserialize(recv, command);
148         Deserialization::Deserialize(recv, counter);
149         Deserialization::Deserialize(recv, retCode);
150         Deserialization::Deserialize(recv, opType);
151
152         if (counter != m_counter) {
153             return CKM_API_ERROR_UNKNOWN;
154         }
155
156         return retCode;
157     });
158 }
159
160 int Manager::ManagerImpl::removeKey(const Alias &alias) {
161     return removeBinaryData(alias, DBDataType::KEY_RSA_PUBLIC);
162 }
163
164 int Manager::ManagerImpl::removeCertificate(const Alias &alias) {
165     return removeBinaryData(alias, DBDataType::CERTIFICATE);
166 }
167
168 int Manager::ManagerImpl::removeData(const Alias &alias) {
169     return removeBinaryData(alias, DBDataType::BINARY_DATA);
170 }
171
172 int Manager::ManagerImpl::getBinaryData(
173     const Alias &alias,
174     DBDataType sendDataType,
175     const std::string &password,
176     DBDataType &recvDataType,
177     RawBuffer &rawData)
178 {
179     return try_catch([&] {
180         if (alias.empty())
181             return CKM_API_ERROR_INPUT_PARAM;
182
183         MessageBuffer send, recv;
184         Serialization::Serialize(send, static_cast<int>(LogicCommand::GET));
185         Serialization::Serialize(send, m_counter);
186         Serialization::Serialize(send, static_cast<int>(sendDataType));
187         Serialization::Serialize(send, alias);
188         Serialization::Serialize(send, password);
189
190         int retCode = sendToServer(
191             SERVICE_SOCKET_CKM_STORAGE,
192             send.Pop(),
193             recv);
194
195         if (CKM_API_SUCCESS != retCode) {
196             return retCode;
197         }
198
199         int command;
200         int counter;
201         int tmpDataType;
202         Deserialization::Deserialize(recv, command);
203         Deserialization::Deserialize(recv, counter);
204         Deserialization::Deserialize(recv, retCode);
205         Deserialization::Deserialize(recv, tmpDataType);
206         Deserialization::Deserialize(recv, rawData);
207         recvDataType = static_cast<DBDataType>(tmpDataType);
208
209         if (counter != m_counter) {
210             return CKM_API_ERROR_UNKNOWN;
211         }
212
213         return retCode;
214     });
215 }
216
217 int Manager::ManagerImpl::getKey(const Alias &alias, const std::string &password, Key &key) {
218     DBDataType recvDataType;
219     RawBuffer rawData;
220
221     int retCode = getBinaryData(
222         alias,
223         DBDataType::KEY_RSA_PUBLIC,
224         password,
225         recvDataType,
226         rawData);
227
228     if (retCode != CKM_API_SUCCESS)
229         return retCode;
230
231     Key keyParsed(rawData);
232
233     if (keyParsed.empty()) {
234         LogDebug("Key empty - failed to parse!");
235         return CKM_API_ERROR_BAD_RESPONSE;
236     }
237
238     key = keyParsed;
239
240     return CKM_API_SUCCESS;
241 }
242
243 int Manager::ManagerImpl::getCertificate(const Alias &alias, const std::string &password, Certificate &cert)
244 {
245     DBDataType recvDataType;
246     RawBuffer rawData;
247
248     int retCode = getBinaryData(
249         alias,
250         DBDataType::CERTIFICATE,
251         password,
252         recvDataType,
253         rawData);
254
255     if (retCode != CKM_API_SUCCESS)
256         return retCode;
257
258     if (recvDataType != DBDataType::CERTIFICATE)
259         return CKM_API_ERROR_BAD_RESPONSE;
260
261     Certificate certParsed(rawData, DataFormat::FORM_DER);
262
263     if (certParsed.empty())
264         return CKM_API_ERROR_BAD_RESPONSE;
265
266     cert = certParsed;
267
268     return CKM_API_SUCCESS;
269 }
270
271 int Manager::ManagerImpl::getData(const Alias &alias, const std::string &password, RawBuffer &rawData)
272 {
273     DBDataType recvDataType;
274
275     int retCode = getBinaryData(
276         alias,
277         DBDataType::BINARY_DATA,
278         password,
279         recvDataType,
280         rawData);
281
282     if (retCode != CKM_API_SUCCESS)
283         return retCode;
284
285     if (recvDataType != DBDataType::BINARY_DATA)
286         return CKM_API_ERROR_BAD_RESPONSE;
287
288     return CKM_API_SUCCESS;
289 }
290
291 int Manager::ManagerImpl::getBinaryDataAliasVector(DBDataType dataType, AliasVector &aliasVector)
292 {
293     return try_catch([&] {
294
295         MessageBuffer send, recv;
296         Serialization::Serialize(send, static_cast<int>(LogicCommand::GET_LIST));
297         Serialization::Serialize(send, m_counter);
298         Serialization::Serialize(send, static_cast<int>(dataType));
299
300         int retCode = sendToServer(
301             SERVICE_SOCKET_CKM_STORAGE,
302             send.Pop(),
303             recv);
304
305         if (CKM_API_SUCCESS != retCode) {
306             return retCode;
307         }
308
309         int command;
310         int counter;
311         int tmpDataType;
312
313         Deserialization::Deserialize(recv, command);
314         Deserialization::Deserialize(recv, counter);
315         Deserialization::Deserialize(recv, retCode);
316         Deserialization::Deserialize(recv, tmpDataType);
317         Deserialization::Deserialize(recv, aliasVector);
318         if ((command != static_cast<int>(LogicCommand::GET_LIST)) || (counter != m_counter)) {
319             return CKM_API_ERROR_UNKNOWN;
320         }
321
322         return retCode;
323     });
324 }
325
326 int Manager::ManagerImpl::getKeyAliasVector(AliasVector &aliasVector) {
327     return getBinaryDataAliasVector(DBDataType::KEY_RSA_PUBLIC, aliasVector);
328 }
329
330 int Manager::ManagerImpl::getCertificateAliasVector(AliasVector &aliasVector) {
331     return getBinaryDataAliasVector(DBDataType::CERTIFICATE, aliasVector);
332 }
333
334 int Manager::ManagerImpl::getDataAliasVector(AliasVector &aliasVector) {
335     return getBinaryDataAliasVector(DBDataType::BINARY_DATA, aliasVector);
336 }
337
338 int Manager::ManagerImpl::createKeyPairRSA(
339     const int size,              // size in bits [1024, 2048, 4096]
340     const Alias &privateKeyAlias,
341     const Alias &publicKeyAlias,
342     const Policy &policyPrivateKey,
343     const Policy &policyPublicKey)
344 {
345     m_counter++;
346     int my_counter = m_counter;
347     return try_catch([&] {
348
349         MessageBuffer send, recv;
350         Serialization::Serialize(send, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
351         Serialization::Serialize(send, my_counter);
352         Serialization::Serialize(send, static_cast<int>(size));
353         Serialization::Serialize(send, PolicySerializable(policyPrivateKey));
354         Serialization::Serialize(send, PolicySerializable(policyPublicKey));
355         Serialization::Serialize(send, privateKeyAlias);
356         Serialization::Serialize(send, publicKeyAlias);
357
358         int retCode = sendToServer(
359             SERVICE_SOCKET_CKM_STORAGE,
360             send.Pop(),
361             recv);
362
363         if (CKM_API_SUCCESS != retCode) {
364             return retCode;
365         }
366
367         int command;
368         int counter;
369
370         Deserialization::Deserialize(recv, command);
371         Deserialization::Deserialize(recv, counter);
372         Deserialization::Deserialize(recv, retCode);
373         if (counter != my_counter) {
374             return CKM_API_ERROR_UNKNOWN;
375         }
376
377         return retCode;
378     });
379 }
380
381 int Manager::ManagerImpl::createKeyPairECDSA(
382     ElipticCurve type,
383     const Alias &privateKeyAlias,
384     const Alias &publicKeyAlias,
385     const Policy &policyPrivateKey,
386     const Policy &policyPublicKey)
387 {
388     m_counter++;
389     int my_counter = m_counter;
390     return try_catch([&] {
391
392         MessageBuffer send, recv;
393         Serialization::Serialize(send, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_ECDSA));
394         Serialization::Serialize(send, my_counter);
395         Serialization::Serialize(send, static_cast<unsigned int>(type));
396         Serialization::Serialize(send, PolicySerializable(policyPrivateKey));
397         Serialization::Serialize(send, PolicySerializable(policyPublicKey));
398         Serialization::Serialize(send, privateKeyAlias);
399         Serialization::Serialize(send, publicKeyAlias);
400
401         int retCode = sendToServer(
402             SERVICE_SOCKET_CKM_STORAGE,
403             send.Pop(),
404             recv);
405
406         if (CKM_API_SUCCESS != retCode) {
407             return retCode;
408         }
409
410         int command;
411         int counter;
412
413         Deserialization::Deserialize(recv, command);
414         Deserialization::Deserialize(recv, counter);
415         Deserialization::Deserialize(recv, retCode);
416
417         if (counter != my_counter) {
418             return CKM_API_ERROR_UNKNOWN;
419         }
420
421         return retCode;
422     });
423 }
424
425 template <class T>
426 int getCertChain(
427     LogicCommand command,
428     int counter,
429     const Certificate &certificate,
430     const T &sendData,
431     CertificateVector &certificateChainVector)
432 {
433     return try_catch([&] {
434
435         MessageBuffer send, recv;
436         Serialization::Serialize(send, static_cast<int>(command));
437         Serialization::Serialize(send, counter);
438         Serialization::Serialize(send, certificate.getDER());
439         Serialization::Serialize(send, sendData);
440         int retCode = sendToServer(
441             SERVICE_SOCKET_CKM_STORAGE,
442             send.Pop(),
443             recv);
444
445         if (CKM_API_SUCCESS != retCode) {
446             return retCode;
447         }
448
449         int retCommand;
450         int retCounter;
451         RawBufferVector rawBufferVector;
452
453         Deserialization::Deserialize(recv, retCommand);
454         Deserialization::Deserialize(recv, retCounter);
455         Deserialization::Deserialize(recv, retCode);
456         Deserialization::Deserialize(recv, rawBufferVector);
457
458         if ((counter != retCounter) || (static_cast<int>(command) != retCommand)) {
459             return CKM_API_ERROR_UNKNOWN;
460         }
461
462         if (retCode != CKM_API_SUCCESS) {
463             return retCode;
464         }
465
466         for (auto &e: rawBufferVector)
467             certificateChainVector.push_back(Certificate(e, DataFormat::FORM_DER));
468
469         return retCode;
470     });
471 }
472
473
474 int Manager::ManagerImpl::getCertificateChain(
475     const Certificate &certificate,
476     const CertificateVector &untrustedCertificates,
477     CertificateVector &certificateChainVector)
478 {
479     RawBufferVector rawBufferVector;
480
481     for (auto &e: untrustedCertificates) {
482         rawBufferVector.push_back(e.getDER());
483     }
484
485     return getCertChain(
486         LogicCommand::GET_CHAIN_CERT,
487         ++m_counter,
488         certificate,
489         rawBufferVector,
490         certificateChainVector);
491 }
492
493 int Manager::ManagerImpl::getCertificateChain(
494     const Certificate &certificate,
495     const AliasVector &untrustedCertificates,
496     CertificateVector &certificateChainVector)
497 {
498     return getCertChain(
499         LogicCommand::GET_CHAIN_ALIAS,
500         ++m_counter,
501         certificate,
502         untrustedCertificates,
503         certificateChainVector);
504 }
505
506 int Manager::ManagerImpl::createSignature(
507     const Alias &privateKeyAlias,
508     const std::string &password,           // password for private_key
509     const RawBuffer &message,
510     const HashAlgorithm hash,
511     const RSAPaddingAlgorithm padding,
512     RawBuffer &signature)
513 {
514     m_counter++;
515     int my_counter = m_counter;
516     return try_catch([&] {
517
518         MessageBuffer send, recv;
519         Serialization::Serialize(send, static_cast<int>(LogicCommand::CREATE_SIGNATURE));
520         Serialization::Serialize(send, my_counter);
521         Serialization::Serialize(send, privateKeyAlias);
522         Serialization::Serialize(send, password);
523         Serialization::Serialize(send, message);
524         Serialization::Serialize(send, static_cast<int>(hash));
525         Serialization::Serialize(send, static_cast<int>(padding));
526
527         int retCode = sendToServer(
528             SERVICE_SOCKET_CKM_STORAGE,
529             send.Pop(),
530             recv);
531
532         if (CKM_API_SUCCESS != retCode) {
533             return retCode;
534         }
535
536         int command;
537         int counter;
538
539         Deserialization::Deserialize(recv, command);
540         Deserialization::Deserialize(recv, counter);
541         Deserialization::Deserialize(recv, retCode);
542         Deserialization::Deserialize(recv, signature);
543
544         if ((command != static_cast<int>(LogicCommand::CREATE_SIGNATURE))
545             || (counter != my_counter))
546         {
547             return CKM_API_ERROR_UNKNOWN;
548         }
549
550         return retCode;
551     });
552 }
553
554 int Manager::ManagerImpl::verifySignature(
555     const Alias &publicKeyOrCertAlias,
556     const std::string &password,           // password for public_key (optional)
557     const RawBuffer &message,
558     const RawBuffer &signature,
559     const HashAlgorithm hash,
560     const RSAPaddingAlgorithm padding)
561 {
562     m_counter++;
563     int my_counter = m_counter;
564     return try_catch([&] {
565
566         MessageBuffer send, recv;
567         Serialization::Serialize(send, static_cast<int>(LogicCommand::VERIFY_SIGNATURE));
568         Serialization::Serialize(send, my_counter);
569         Serialization::Serialize(send, publicKeyOrCertAlias);
570         Serialization::Serialize(send, password);
571         Serialization::Serialize(send, message);
572         Serialization::Serialize(send, signature);
573         Serialization::Serialize(send, static_cast<int>(hash));
574         Serialization::Serialize(send, static_cast<int>(padding));
575
576         int retCode = sendToServer(
577             SERVICE_SOCKET_CKM_STORAGE,
578             send.Pop(),
579             recv);
580
581         if (CKM_API_SUCCESS != retCode) {
582             return retCode;
583         }
584
585         int command;
586         int counter;
587
588         Deserialization::Deserialize(recv, command);
589         Deserialization::Deserialize(recv, counter);
590         Deserialization::Deserialize(recv, retCode);
591
592         if ((command != static_cast<int>(LogicCommand::VERIFY_SIGNATURE))
593             || (counter != my_counter))
594         {
595             return CKM_API_ERROR_UNKNOWN;
596         }
597
598         return retCode;
599     });
600 }
601
602 } // namespace CKM
603