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