1 /* Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
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
7 * http://www.apache.org/licenses/LICENSE-2.0
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
16 * @file client-manager-impl.cpp
17 * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
19 * @brief Manager implementation.
21 #include <openssl/evp.h>
23 #include <dpl/serialization.h>
24 #include <dpl/log/log.h>
27 #include <client-manager-impl.h>
28 #include <client-common.h>
29 #include <message-buffer.h>
30 #include <protocols.h>
32 #include <certificate-impl.h>
36 ManagerImpl::ManagerImpl()
37 : m_counter(0), m_storageConnection(SERVICE_SOCKET_CKM_STORAGE), m_ocspConnection(SERVICE_SOCKET_OCSP)
43 int ManagerImpl::saveBinaryData(
46 const RawBuffer &rawData,
49 int my_counter = ++m_counter;
51 return try_catch([&] {
52 if (alias.empty() || rawData.empty())
53 return CKM_API_ERROR_INPUT_PARAM;
56 AliasSupport helper(alias);
57 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
59 static_cast<int>(dataType),
63 PolicySerializable(policy));
65 int retCode = m_storageConnection.processRequest(send.Pop(), recv);
66 if (CKM_API_SUCCESS != retCode)
72 recv.Deserialize(command, counter, retCode, opType);
74 if (counter != my_counter)
75 return CKM_API_ERROR_UNKNOWN;
81 int ManagerImpl::saveKey(const Alias &alias, const KeyShPtr &key, const Policy &policy) {
82 if (key.get() == NULL)
83 return CKM_API_ERROR_INPUT_PARAM;
85 return saveBinaryData(alias, DBDataType(key->getType()), key->getDER(), policy);
86 } Catch (DBDataType::Exception::Base) {
87 LogError("Error in key conversion. Could not convert KeyType::NONE to DBDataType!");
89 return CKM_API_ERROR_INPUT_PARAM;
92 int ManagerImpl::saveCertificate(
94 const CertificateShPtr &cert,
97 if (cert.get() == NULL)
98 return CKM_API_ERROR_INPUT_PARAM;
99 return saveBinaryData(alias, DBDataType::CERTIFICATE, cert->getDER(), policy);
102 int ManagerImpl::saveData(const Alias &alias, const RawBuffer &rawData, const Policy &policy) {
103 if (!policy.extractable)
104 return CKM_API_ERROR_INPUT_PARAM;
105 return saveBinaryData(alias, DBDataType::BINARY_DATA, rawData, policy);
109 int ManagerImpl::savePKCS12(
111 const PKCS12ShPtr &pkcs,
112 const Policy &keyPolicy,
113 const Policy &certPolicy)
115 if (alias.empty() || pkcs.get()==NULL)
116 return CKM_API_ERROR_INPUT_PARAM;
118 int my_counter = ++m_counter;
120 return try_catch([&] {
122 AliasSupport helper(alias);
123 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE_PKCS12),
127 PKCS12Serializable(*pkcs.get()),
128 PolicySerializable(keyPolicy),
129 PolicySerializable(certPolicy));
131 int retCode = m_storageConnection.processRequest(send.Pop(), recv);
132 if (CKM_API_SUCCESS != retCode)
137 recv.Deserialize(command, counter, retCode);
139 if (counter != my_counter)
140 return CKM_API_ERROR_UNKNOWN;
146 int ManagerImpl::getPKCS12(const Alias &alias, PKCS12ShPtr &pkcs)
149 return CKM_API_ERROR_INPUT_PARAM;
151 int my_counter = ++m_counter;
153 return try_catch([&] {
155 AliasSupport helper(alias);
156 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12),
161 int retCode = m_storageConnection.processRequest(send.Pop(), recv);
162 if (CKM_API_SUCCESS != retCode)
167 PKCS12Serializable gotPkcs;
168 recv.Deserialize(command, counter, retCode, gotPkcs);
170 if (counter != my_counter)
171 return CKM_API_ERROR_UNKNOWN;
173 pkcs = std::make_shared<PKCS12Impl>(std::move(gotPkcs));
180 int ManagerImpl::removeAlias(const Alias &alias)
183 return CKM_API_ERROR_INPUT_PARAM;
185 int my_counter = ++m_counter;
187 return try_catch([&] {
189 AliasSupport helper(alias);
190 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
195 int retCode = m_storageConnection.processRequest(send.Pop(), recv);
196 if (CKM_API_SUCCESS != retCode)
201 recv.Deserialize(command, counter, retCode);
203 if (counter != my_counter)
204 return CKM_API_ERROR_UNKNOWN;
210 int ManagerImpl::getBinaryData(
212 DBDataType sendDataType,
213 const Password &password,
214 DBDataType &recvDataType,
218 return CKM_API_ERROR_INPUT_PARAM;
220 int my_counter = ++m_counter;
222 return try_catch([&] {
224 AliasSupport helper(alias);
225 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
227 static_cast<int>(sendDataType),
232 int retCode = m_storageConnection.processRequest(send.Pop(), recv);
233 if (CKM_API_SUCCESS != retCode)
239 recv.Deserialize(command, counter, retCode, tmpDataType, rawData);
240 recvDataType = DBDataType(tmpDataType);
242 if (counter != my_counter)
243 return CKM_API_ERROR_UNKNOWN;
249 int ManagerImpl::getKey(const Alias &alias, const Password &password, KeyShPtr &key) {
250 DBDataType recvDataType;
253 int retCode = getBinaryData(
255 DBDataType::KEY_RSA_PUBLIC,
260 if (retCode != CKM_API_SUCCESS)
263 KeyShPtr keyParsed(new KeyImpl(rawData));
265 if (keyParsed->empty()) {
266 LogDebug("Key empty - failed to parse!");
267 return CKM_API_ERROR_BAD_RESPONSE;
272 return CKM_API_SUCCESS;
275 int ManagerImpl::getCertificate(const Alias &alias, const Password &password, CertificateShPtr &cert)
277 DBDataType recvDataType;
280 int retCode = getBinaryData(
282 DBDataType::CERTIFICATE,
287 if (retCode != CKM_API_SUCCESS)
290 if (recvDataType != DBDataType::CERTIFICATE)
291 return CKM_API_ERROR_BAD_RESPONSE;
293 CertificateShPtr certParsed(new CertificateImpl(rawData, DataFormat::FORM_DER));
295 if (certParsed->empty())
296 return CKM_API_ERROR_BAD_RESPONSE;
300 return CKM_API_SUCCESS;
303 int ManagerImpl::getData(const Alias &alias, const Password &password, RawBuffer &rawData)
305 DBDataType recvDataType = DBDataType::BINARY_DATA;
307 int retCode = getBinaryData(
309 DBDataType::BINARY_DATA,
314 if (retCode != CKM_API_SUCCESS)
317 if (recvDataType != DBDataType::BINARY_DATA)
318 return CKM_API_ERROR_BAD_RESPONSE;
320 return CKM_API_SUCCESS;
323 int ManagerImpl::getBinaryDataAliasVector(DBDataType dataType, AliasVector &aliasVector)
325 int my_counter = ++m_counter;
327 return try_catch([&] {
329 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
331 static_cast<int>(dataType));
333 int retCode = m_storageConnection.processRequest(send.Pop(), recv);
334 if (CKM_API_SUCCESS != retCode)
340 LabelNameVector labelNameVector;
341 recv.Deserialize(command, counter, retCode, tmpDataType, labelNameVector);
342 if ((command != static_cast<int>(LogicCommand::GET_LIST)) || (counter != my_counter)) {
343 return CKM_API_ERROR_UNKNOWN;
346 for(const auto &it : labelNameVector)
347 aliasVector.push_back( AliasSupport::merge(it.first, it.second) );
353 int ManagerImpl::getKeyAliasVector(AliasVector &aliasVector) {
354 // in fact datatype has no meaning here - if not certificate or binary data
355 // then manager decides to list all between DB_KEY_FIRST and DB_KEY_LAST
356 return getBinaryDataAliasVector(DBDataType::DB_KEY_LAST, aliasVector);
359 int ManagerImpl::getCertificateAliasVector(AliasVector &aliasVector) {
360 return getBinaryDataAliasVector(DBDataType::CERTIFICATE, aliasVector);
363 int ManagerImpl::getDataAliasVector(AliasVector &aliasVector) {
364 return getBinaryDataAliasVector(DBDataType::BINARY_DATA, aliasVector);
367 int ManagerImpl::createKeyPairRSA(
369 const Alias &privateKeyAlias,
370 const Alias &publicKeyAlias,
371 const Policy &policyPrivateKey,
372 const Policy &policyPublicKey)
374 return this->createKeyPair(CKM::KeyType::KEY_RSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
377 int ManagerImpl::createKeyPairDSA(
379 const Alias &privateKeyAlias,
380 const Alias &publicKeyAlias,
381 const Policy &policyPrivateKey,
382 const Policy &policyPublicKey)
384 return this->createKeyPair(CKM::KeyType::KEY_DSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
387 int ManagerImpl::createKeyPairECDSA(
389 const Alias &privateKeyAlias,
390 const Alias &publicKeyAlias,
391 const Policy &policyPrivateKey,
392 const Policy &policyPublicKey)
394 return this->createKeyPair(CKM::KeyType::KEY_ECDSA_PUBLIC, static_cast<int>(type), privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
397 int ManagerImpl::createKeyPair(
398 const KeyType key_type,
399 const int additional_param,
400 const Alias &privateKeyAlias,
401 const Alias &publicKeyAlias,
402 const Policy &policyPrivateKey,
403 const Policy &policyPublicKey)
406 LogicCommand cmd_type;
409 case KeyType::KEY_RSA_PUBLIC:
410 case KeyType::KEY_RSA_PRIVATE:
411 cmd_type = LogicCommand::CREATE_KEY_PAIR_RSA;
414 case KeyType::KEY_DSA_PUBLIC:
415 case KeyType::KEY_DSA_PRIVATE:
416 cmd_type = LogicCommand::CREATE_KEY_PAIR_DSA;
419 case KeyType::KEY_ECDSA_PUBLIC:
420 case KeyType::KEY_ECDSA_PRIVATE:
421 cmd_type = LogicCommand::CREATE_KEY_PAIR_ECDSA;
425 return CKM_API_ERROR_INPUT_PARAM;
428 // proceed with sending request
429 int my_counter = ++m_counter;
431 return try_catch([&] {
434 AliasSupport privateHelper(privateKeyAlias);
435 AliasSupport publicHelper(publicKeyAlias);
436 auto send = MessageBuffer::Serialize(static_cast<int>(cmd_type),
438 static_cast<int>(additional_param),
439 PolicySerializable(policyPrivateKey),
440 PolicySerializable(policyPublicKey),
441 privateHelper.getName(),
442 privateHelper.getLabel(),
443 publicHelper.getName(),
444 publicHelper.getLabel());
446 int retCode = m_storageConnection.processRequest(send.Pop(), recv);
447 if (CKM_API_SUCCESS != retCode)
452 recv.Deserialize(command, counter, retCode);
453 if (counter != my_counter) {
454 return CKM_API_ERROR_UNKNOWN;
464 LogicCommand command,
466 const CertificateShPtr &certificate,
468 CertificateShPtrVector &certificateChainVector,
469 ServiceConnection & service_connection)
471 return try_catch([&] {
474 auto send = MessageBuffer::Serialize(static_cast<int>(command),
476 certificate->getDER(),
479 int retCode = service_connection.processRequest(send.Pop(), recv);
480 if (CKM_API_SUCCESS != retCode)
485 RawBufferVector rawBufferVector;
486 recv.Deserialize(retCommand, retCounter, retCode, rawBufferVector);
488 if ((counter != retCounter) || (static_cast<int>(command) != retCommand)) {
489 return CKM_API_ERROR_UNKNOWN;
492 if (retCode != CKM_API_SUCCESS) {
496 for (auto &e: rawBufferVector) {
497 CertificateShPtr cert(new CertificateImpl(e, DataFormat::FORM_DER));
499 return CKM_API_ERROR_BAD_RESPONSE;
500 certificateChainVector.push_back(cert);
508 int ManagerImpl::getCertificateChain(
509 const CertificateShPtr &certificate,
510 const CertificateShPtrVector &untrustedCertificates,
511 CertificateShPtrVector &certificateChainVector)
513 RawBufferVector rawBufferVector;
515 for (auto &e: untrustedCertificates) {
516 rawBufferVector.push_back(e->getDER());
520 LogicCommand::GET_CHAIN_CERT,
524 certificateChainVector,
525 m_storageConnection);
528 int ManagerImpl::getCertificateChain(
529 const CertificateShPtr &certificate,
530 const AliasVector &untrustedCertificates,
531 CertificateShPtrVector &certificateChainVector)
533 LabelNameVector untrusted_certs;
534 for (auto &e: untrustedCertificates) {
535 AliasSupport helper(e);
536 untrusted_certs.push_back(std::make_pair(helper.getLabel(), helper.getName()));
540 LogicCommand::GET_CHAIN_ALIAS,
544 certificateChainVector,
545 m_storageConnection);
548 int ManagerImpl::createSignature(
549 const Alias &privateKeyAlias,
550 const Password &password, // password for private_key
551 const RawBuffer &message,
552 const HashAlgorithm hash,
553 const RSAPaddingAlgorithm padding,
554 RawBuffer &signature)
556 int my_counter = ++m_counter;
558 return try_catch([&] {
561 AliasSupport helper(privateKeyAlias);
562 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
568 static_cast<int>(hash),
569 static_cast<int>(padding));
571 int retCode = m_storageConnection.processRequest(send.Pop(), recv);
572 if (CKM_API_SUCCESS != retCode)
577 recv.Deserialize(command, counter, retCode, signature);
579 if ((command != static_cast<int>(LogicCommand::CREATE_SIGNATURE))
580 || (counter != my_counter))
582 return CKM_API_ERROR_UNKNOWN;
589 int ManagerImpl::verifySignature(
590 const Alias &publicKeyOrCertAlias,
591 const Password &password, // password for public_key (optional)
592 const RawBuffer &message,
593 const RawBuffer &signature,
594 const HashAlgorithm hash,
595 const RSAPaddingAlgorithm padding)
597 int my_counter = ++m_counter;
599 return try_catch([&] {
601 AliasSupport helper(publicKeyOrCertAlias);
602 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
609 static_cast<int>(hash),
610 static_cast<int>(padding));
612 int retCode = m_storageConnection.processRequest(send.Pop(), recv);
613 if (CKM_API_SUCCESS != retCode)
618 recv.Deserialize(command, counter, retCode);
620 if ((command != static_cast<int>(LogicCommand::VERIFY_SIGNATURE))
621 || (counter != my_counter))
623 return CKM_API_ERROR_UNKNOWN;
630 int ManagerImpl::ocspCheck(const CertificateShPtrVector &certChain, int &ocspStatus)
632 return try_catch([&] {
633 int my_counter = ++m_counter;
636 RawBufferVector rawCertChain;
637 for (auto &e: certChain) {
638 rawCertChain.push_back(e->getDER());
641 auto send = MessageBuffer::Serialize(my_counter, rawCertChain);
643 int retCode = m_ocspConnection.processRequest(send.Pop(), recv);
644 if (CKM_API_SUCCESS != retCode)
648 recv.Deserialize(counter, retCode, ocspStatus);
650 if (my_counter != counter) {
651 return CKM_API_ERROR_UNKNOWN;
658 int ManagerImpl::setPermission(const Alias &alias,
659 const Label &accessor,
660 Permission newPermission)
662 int my_counter = ++m_counter;
664 return try_catch([&] {
666 AliasSupport helper(alias);
667 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SET_PERMISSION),
672 static_cast<int>(newPermission));
674 int retCode = m_storageConnection.processRequest(send.Pop(), recv);
675 if (CKM_API_SUCCESS != retCode)
680 recv.Deserialize(command, counter, retCode);
682 if (my_counter != counter) {
683 return CKM_API_ERROR_UNKNOWN;
690 ManagerShPtr Manager::create() {
692 return std::make_shared<ManagerImpl>();
693 } catch (const std::bad_alloc &) {
694 LogDebug("Bad alloc was caught during ManagerImpl creation.");
696 LogError("Critical error: Unknown exception was caught during ManagerImpl creation!");
698 return ManagerShPtr();