Fix implementation create methods.
[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 #include <generic-key.h>
31 #include <certificate-impl.h>
32
33 namespace {
34
35 void clientInitialize(void) {
36     OpenSSL_add_all_ciphers();
37     OpenSSL_add_all_algorithms();
38     OpenSSL_add_all_digests();
39 }
40
41 } // namespace anonymous
42
43 namespace CKM {
44
45 bool ManagerImpl::s_isInit = false;
46
47 ManagerImpl::ManagerImpl()
48   : m_counter(0)
49 {
50     // TODO secure with mutex
51     if (!s_isInit) {
52         s_isInit = true;
53         clientInitialize();
54     }
55
56 }
57
58
59 int ManagerImpl::saveBinaryData(
60     const Alias &alias,
61     DBDataType dataType,
62     const RawBuffer &rawData,
63     const Policy &policy)
64 {
65     m_counter++;
66
67     return try_catch([&] {
68         if (alias.empty() || rawData.empty())
69             return CKM_API_ERROR_INPUT_PARAM;
70
71         MessageBuffer send, recv;
72         Serialization::Serialize(send, static_cast<int>(LogicCommand::SAVE));
73         Serialization::Serialize(send, m_counter);
74         Serialization::Serialize(send, static_cast<int>(dataType));
75         Serialization::Serialize(send, alias);
76         Serialization::Serialize(send, rawData);
77         Serialization::Serialize(send, PolicySerializable(policy));
78
79         int retCode = sendToServer(
80             SERVICE_SOCKET_CKM_STORAGE,
81             send.Pop(),
82             recv);
83
84         if (CKM_API_SUCCESS != retCode) {
85             return retCode;
86         }
87
88         int command;
89         int counter;
90         int opType;
91         Deserialization::Deserialize(recv, command);
92         Deserialization::Deserialize(recv, counter);
93         Deserialization::Deserialize(recv, retCode);
94         Deserialization::Deserialize(recv, opType);
95
96         if (counter != m_counter) {
97             return CKM_API_ERROR_UNKNOWN;
98         }
99
100         return retCode;
101     });
102 }
103
104 int ManagerImpl::saveKey(const Alias &alias, const KeyShPtr &key, const Policy &policy) {
105     if (key.get() == NULL)
106         return CKM_API_ERROR_INPUT_PARAM;
107     return saveBinaryData(alias, toDBDataType(key->getType()), key->getDER(), policy);
108 }
109
110 int ManagerImpl::saveCertificate(
111     const Alias &alias,
112     const CertificateShPtr &cert,
113     const Policy &policy)
114 {
115     if (cert.get() == NULL)
116         return CKM_API_ERROR_INPUT_PARAM;
117     return saveBinaryData(alias, DBDataType::CERTIFICATE, cert->getDER(), policy);
118 }
119
120 int ManagerImpl::saveData(const Alias &alias, const RawBuffer &rawData, const Policy &policy) {
121     if (!policy.extractable)
122         return CKM_API_ERROR_INPUT_PARAM;
123     return saveBinaryData(alias, DBDataType::BINARY_DATA, rawData, policy);
124 }
125
126 int ManagerImpl::removeBinaryData(const Alias &alias, DBDataType dataType)
127 {
128     return try_catch([&] {
129         if (alias.empty())
130             return CKM_API_ERROR_INPUT_PARAM;
131
132         MessageBuffer send, recv;
133         Serialization::Serialize(send, static_cast<int>(LogicCommand::REMOVE));
134         Serialization::Serialize(send, m_counter);
135         Serialization::Serialize(send, static_cast<int>(dataType));
136         Serialization::Serialize(send, alias);
137
138         int retCode = sendToServer(
139             SERVICE_SOCKET_CKM_STORAGE,
140             send.Pop(),
141             recv);
142
143         if (CKM_API_SUCCESS != retCode) {
144             return retCode;
145         }
146
147         int command;
148         int counter;
149         int opType;
150         Deserialization::Deserialize(recv, command);
151         Deserialization::Deserialize(recv, counter);
152         Deserialization::Deserialize(recv, retCode);
153         Deserialization::Deserialize(recv, opType);
154
155         if (counter != m_counter) {
156             return CKM_API_ERROR_UNKNOWN;
157         }
158
159         return retCode;
160     });
161 }
162
163 int ManagerImpl::removeKey(const Alias &alias) {
164     return removeBinaryData(alias, DBDataType::KEY_RSA_PUBLIC);
165 }
166
167 int ManagerImpl::removeCertificate(const Alias &alias) {
168     return removeBinaryData(alias, DBDataType::CERTIFICATE);
169 }
170
171 int ManagerImpl::removeData(const Alias &alias) {
172     return removeBinaryData(alias, DBDataType::BINARY_DATA);
173 }
174
175 int ManagerImpl::getBinaryData(
176     const Alias &alias,
177     DBDataType sendDataType,
178     const Password &password,
179     DBDataType &recvDataType,
180     RawBuffer &rawData)
181 {
182     return try_catch([&] {
183         if (alias.empty())
184             return CKM_API_ERROR_INPUT_PARAM;
185
186         MessageBuffer send, recv;
187         Serialization::Serialize(send, static_cast<int>(LogicCommand::GET));
188         Serialization::Serialize(send, m_counter);
189         Serialization::Serialize(send, static_cast<int>(sendDataType));
190         Serialization::Serialize(send, alias);
191         Serialization::Serialize(send, password);
192
193         int retCode = sendToServer(
194             SERVICE_SOCKET_CKM_STORAGE,
195             send.Pop(),
196             recv);
197
198         if (CKM_API_SUCCESS != retCode) {
199             return retCode;
200         }
201
202         int command;
203         int counter;
204         int tmpDataType;
205         Deserialization::Deserialize(recv, command);
206         Deserialization::Deserialize(recv, counter);
207         Deserialization::Deserialize(recv, retCode);
208         Deserialization::Deserialize(recv, tmpDataType);
209         Deserialization::Deserialize(recv, rawData);
210         recvDataType = static_cast<DBDataType>(tmpDataType);
211
212         if (counter != m_counter) {
213             return CKM_API_ERROR_UNKNOWN;
214         }
215
216         return retCode;
217     });
218 }
219
220 int ManagerImpl::getKey(const Alias &alias, const Password &password, KeyShPtr &key) {
221     DBDataType recvDataType;
222     RawBuffer rawData;
223
224     int retCode = getBinaryData(
225         alias,
226         DBDataType::KEY_RSA_PUBLIC,
227         password,
228         recvDataType,
229         rawData);
230
231     if (retCode != CKM_API_SUCCESS)
232         return retCode;
233
234     KeyShPtr keyParsed(new GenericKey(rawData));
235
236     if (keyParsed->empty()) {
237         LogDebug("Key empty - failed to parse!");
238         return CKM_API_ERROR_BAD_RESPONSE;
239     }
240
241     key = keyParsed;
242
243     return CKM_API_SUCCESS;
244 }
245
246 int ManagerImpl::getCertificate(const Alias &alias, const Password &password, CertificateShPtr &cert)
247 {
248     DBDataType recvDataType;
249     RawBuffer rawData;
250
251     int retCode = getBinaryData(
252         alias,
253         DBDataType::CERTIFICATE,
254         password,
255         recvDataType,
256         rawData);
257
258     if (retCode != CKM_API_SUCCESS)
259         return retCode;
260
261     if (recvDataType != DBDataType::CERTIFICATE)
262         return CKM_API_ERROR_BAD_RESPONSE;
263
264     CertificateShPtr certParsed(new CertificateImpl(rawData, DataFormat::FORM_DER));
265
266     if (certParsed->empty())
267         return CKM_API_ERROR_BAD_RESPONSE;
268
269     cert = certParsed;
270
271     return CKM_API_SUCCESS;
272 }
273
274 int ManagerImpl::getData(const Alias &alias, const Password &password, RawBuffer &rawData)
275 {
276     DBDataType recvDataType;
277
278     int retCode = getBinaryData(
279         alias,
280         DBDataType::BINARY_DATA,
281         password,
282         recvDataType,
283         rawData);
284
285     if (retCode != CKM_API_SUCCESS)
286         return retCode;
287
288     if (recvDataType != DBDataType::BINARY_DATA)
289         return CKM_API_ERROR_BAD_RESPONSE;
290
291     return CKM_API_SUCCESS;
292 }
293
294 int ManagerImpl::getBinaryDataAliasVector(DBDataType dataType, AliasVector &aliasVector)
295 {
296     return try_catch([&] {
297
298         MessageBuffer send, recv;
299         Serialization::Serialize(send, static_cast<int>(LogicCommand::GET_LIST));
300         Serialization::Serialize(send, m_counter);
301         Serialization::Serialize(send, static_cast<int>(dataType));
302
303         int retCode = sendToServer(
304             SERVICE_SOCKET_CKM_STORAGE,
305             send.Pop(),
306             recv);
307
308         if (CKM_API_SUCCESS != retCode) {
309             return retCode;
310         }
311
312         int command;
313         int counter;
314         int tmpDataType;
315
316         Deserialization::Deserialize(recv, command);
317         Deserialization::Deserialize(recv, counter);
318         Deserialization::Deserialize(recv, retCode);
319         Deserialization::Deserialize(recv, tmpDataType);
320         Deserialization::Deserialize(recv, aliasVector);
321         if ((command != static_cast<int>(LogicCommand::GET_LIST)) || (counter != m_counter)) {
322             return CKM_API_ERROR_UNKNOWN;
323         }
324
325         return retCode;
326     });
327 }
328
329 int ManagerImpl::getKeyAliasVector(AliasVector &aliasVector) {
330     return getBinaryDataAliasVector(DBDataType::KEY_RSA_PUBLIC, aliasVector);
331 }
332
333 int ManagerImpl::getCertificateAliasVector(AliasVector &aliasVector) {
334     return getBinaryDataAliasVector(DBDataType::CERTIFICATE, aliasVector);
335 }
336
337 int ManagerImpl::getDataAliasVector(AliasVector &aliasVector) {
338     return getBinaryDataAliasVector(DBDataType::BINARY_DATA, aliasVector);
339 }
340
341 int ManagerImpl::createKeyPairRSA(
342     const int size,              // size in bits [1024, 2048, 4096]
343     const Alias &privateKeyAlias,
344     const Alias &publicKeyAlias,
345     const Policy &policyPrivateKey,
346     const Policy &policyPublicKey)
347 {
348     m_counter++;
349     int my_counter = m_counter;
350     return try_catch([&] {
351
352         MessageBuffer send, recv;
353         Serialization::Serialize(send, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
354         Serialization::Serialize(send, my_counter);
355         Serialization::Serialize(send, static_cast<int>(size));
356         Serialization::Serialize(send, PolicySerializable(policyPrivateKey));
357         Serialization::Serialize(send, PolicySerializable(policyPublicKey));
358         Serialization::Serialize(send, privateKeyAlias);
359         Serialization::Serialize(send, publicKeyAlias);
360
361         int retCode = sendToServer(
362             SERVICE_SOCKET_CKM_STORAGE,
363             send.Pop(),
364             recv);
365
366         if (CKM_API_SUCCESS != retCode) {
367             return retCode;
368         }
369
370         int command;
371         int counter;
372
373         Deserialization::Deserialize(recv, command);
374         Deserialization::Deserialize(recv, counter);
375         Deserialization::Deserialize(recv, retCode);
376         if (counter != my_counter) {
377             return CKM_API_ERROR_UNKNOWN;
378         }
379
380         return retCode;
381     });
382 }
383
384 int ManagerImpl::createKeyPairECDSA(
385     ElipticCurve type,
386     const Alias &privateKeyAlias,
387     const Alias &publicKeyAlias,
388     const Policy &policyPrivateKey,
389     const Policy &policyPublicKey)
390 {
391     m_counter++;
392     int my_counter = m_counter;
393     return try_catch([&] {
394
395         MessageBuffer send, recv;
396         Serialization::Serialize(send, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_ECDSA));
397         Serialization::Serialize(send, my_counter);
398         Serialization::Serialize(send, static_cast<unsigned int>(type));
399         Serialization::Serialize(send, PolicySerializable(policyPrivateKey));
400         Serialization::Serialize(send, PolicySerializable(policyPublicKey));
401         Serialization::Serialize(send, privateKeyAlias);
402         Serialization::Serialize(send, publicKeyAlias);
403
404         int retCode = sendToServer(
405             SERVICE_SOCKET_CKM_STORAGE,
406             send.Pop(),
407             recv);
408
409         if (CKM_API_SUCCESS != retCode) {
410             return retCode;
411         }
412
413         int command;
414         int counter;
415
416         Deserialization::Deserialize(recv, command);
417         Deserialization::Deserialize(recv, counter);
418         Deserialization::Deserialize(recv, retCode);
419
420         if (counter != my_counter) {
421             return CKM_API_ERROR_UNKNOWN;
422         }
423
424         return retCode;
425     });
426 }
427
428 template <class T>
429 int getCertChain(
430     LogicCommand command,
431     int counter,
432     const CertificateShPtr &certificate,
433     const T &sendData,
434     CertificateShPtrVector &certificateChainVector)
435 {
436     return try_catch([&] {
437
438         MessageBuffer send, recv;
439         Serialization::Serialize(send, static_cast<int>(command));
440         Serialization::Serialize(send, counter);
441         Serialization::Serialize(send, certificate->getDER());
442         Serialization::Serialize(send, sendData);
443         int retCode = sendToServer(
444             SERVICE_SOCKET_CKM_STORAGE,
445             send.Pop(),
446             recv);
447
448         if (CKM_API_SUCCESS != retCode) {
449             return retCode;
450         }
451
452         int retCommand;
453         int retCounter;
454         RawBufferVector rawBufferVector;
455
456         Deserialization::Deserialize(recv, retCommand);
457         Deserialization::Deserialize(recv, retCounter);
458         Deserialization::Deserialize(recv, retCode);
459         Deserialization::Deserialize(recv, rawBufferVector);
460
461         if ((counter != retCounter) || (static_cast<int>(command) != retCommand)) {
462             return CKM_API_ERROR_UNKNOWN;
463         }
464
465         if (retCode != CKM_API_SUCCESS) {
466             return retCode;
467         }
468
469         for (auto &e: rawBufferVector) {
470             CertificateShPtr cert(new CertificateImpl(e, DataFormat::FORM_DER));
471             if (cert->empty())
472                 return CKM_API_ERROR_BAD_RESPONSE;
473             certificateChainVector.push_back(cert);
474         }
475
476         return retCode;
477     });
478 }
479
480
481 int ManagerImpl::getCertificateChain(
482     const CertificateShPtr &certificate,
483     const CertificateShPtrVector &untrustedCertificates,
484     CertificateShPtrVector &certificateChainVector)
485 {
486     RawBufferVector rawBufferVector;
487
488     for (auto &e: untrustedCertificates) {
489         rawBufferVector.push_back(e->getDER());
490     }
491
492     return getCertChain(
493         LogicCommand::GET_CHAIN_CERT,
494         ++m_counter,
495         certificate,
496         rawBufferVector,
497         certificateChainVector);
498 }
499
500 int ManagerImpl::getCertificateChain(
501     const CertificateShPtr &certificate,
502     const AliasVector &untrustedCertificates,
503     CertificateShPtrVector &certificateChainVector)
504 {
505     return getCertChain(
506         LogicCommand::GET_CHAIN_ALIAS,
507         ++m_counter,
508         certificate,
509         untrustedCertificates,
510         certificateChainVector);
511 }
512
513 int ManagerImpl::createSignature(
514     const Alias &privateKeyAlias,
515     const Password &password,           // password for private_key
516     const RawBuffer &message,
517     const HashAlgorithm hash,
518     const RSAPaddingAlgorithm padding,
519     RawBuffer &signature)
520 {
521     m_counter++;
522     int my_counter = m_counter;
523     return try_catch([&] {
524
525         MessageBuffer send, recv;
526         Serialization::Serialize(send, static_cast<int>(LogicCommand::CREATE_SIGNATURE));
527         Serialization::Serialize(send, my_counter);
528         Serialization::Serialize(send, privateKeyAlias);
529         Serialization::Serialize(send, password);
530         Serialization::Serialize(send, message);
531         Serialization::Serialize(send, static_cast<int>(hash));
532         Serialization::Serialize(send, static_cast<int>(padding));
533
534         int retCode = sendToServer(
535             SERVICE_SOCKET_CKM_STORAGE,
536             send.Pop(),
537             recv);
538
539         if (CKM_API_SUCCESS != retCode) {
540             return retCode;
541         }
542
543         int command;
544         int counter;
545
546         Deserialization::Deserialize(recv, command);
547         Deserialization::Deserialize(recv, counter);
548         Deserialization::Deserialize(recv, retCode);
549         Deserialization::Deserialize(recv, signature);
550
551         if ((command != static_cast<int>(LogicCommand::CREATE_SIGNATURE))
552             || (counter != my_counter))
553         {
554             return CKM_API_ERROR_UNKNOWN;
555         }
556
557         return retCode;
558     });
559 }
560
561 int ManagerImpl::verifySignature(
562     const Alias &publicKeyOrCertAlias,
563     const Password &password,           // password for public_key (optional)
564     const RawBuffer &message,
565     const RawBuffer &signature,
566     const HashAlgorithm hash,
567     const RSAPaddingAlgorithm padding)
568 {
569     m_counter++;
570     int my_counter = m_counter;
571     return try_catch([&] {
572
573         MessageBuffer send, recv;
574         Serialization::Serialize(send, static_cast<int>(LogicCommand::VERIFY_SIGNATURE));
575         Serialization::Serialize(send, my_counter);
576         Serialization::Serialize(send, publicKeyOrCertAlias);
577         Serialization::Serialize(send, password);
578         Serialization::Serialize(send, message);
579         Serialization::Serialize(send, signature);
580         Serialization::Serialize(send, static_cast<int>(hash));
581         Serialization::Serialize(send, static_cast<int>(padding));
582
583         int retCode = sendToServer(
584             SERVICE_SOCKET_CKM_STORAGE,
585             send.Pop(),
586             recv);
587
588         if (CKM_API_SUCCESS != retCode) {
589             return retCode;
590         }
591
592         int command;
593         int counter;
594
595         Deserialization::Deserialize(recv, command);
596         Deserialization::Deserialize(recv, counter);
597         Deserialization::Deserialize(recv, retCode);
598
599         if ((command != static_cast<int>(LogicCommand::VERIFY_SIGNATURE))
600             || (counter != my_counter))
601         {
602             return CKM_API_ERROR_UNKNOWN;
603         }
604
605         return retCode;
606     });
607 }
608
609 int ManagerImpl::ocspCheck(const CertificateShPtrVector &certChain, int &ocspStatus)
610 {
611     return try_catch([&] {
612         int my_counter = ++m_counter;
613         MessageBuffer send, recv;
614
615         RawBufferVector rawCertChain;
616         for (auto &e: certChain) {
617             rawCertChain.push_back(e->getDER());
618         }
619
620         Serialization::Serialize(send, my_counter);
621         Serialization::Serialize(send, rawCertChain);
622
623         int retCode = sendToServer(
624             SERVICE_SOCKET_OCSP,
625             send.Pop(),
626             recv);
627
628         if (CKM_API_SUCCESS != retCode) {
629             return retCode;
630         }
631
632         int counter;
633
634         Deserialization::Deserialize(recv, counter);
635         Deserialization::Deserialize(recv, retCode);
636         Deserialization::Deserialize(recv, ocspStatus);
637
638         if (my_counter != counter) {
639             return CKM_API_ERROR_UNKNOWN;
640         }
641
642         return retCode;
643     });
644 }
645
646 ManagerShPtr Manager::create() {
647     try {
648         return std::make_shared<ManagerImpl>();
649     } catch (const std::bad_alloc &) {
650         LogDebug("Bad alloc was caught during ManagerImpl creation.");
651     } catch (...) {
652         LogError("Critical error: Unknown exception was caught during ManagerImpl creation!");
653     }
654     return ManagerShPtr();
655 }
656
657 } // namespace CKM
658