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