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,
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 != m_counter) {
75 return CKM_API_ERROR_UNKNOWN;
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;
86 return saveBinaryData(alias, DBDataType(key->getType()), key->getDER(), policy);
87 } Catch (DBDataType::Exception::Base) {
88 LogError("Error in key conversion. Could not convert KeyType::NONE to DBDataType!");
90 return CKM_API_ERROR_INPUT_PARAM;
93 int ManagerImpl::saveCertificate(
95 const CertificateShPtr &cert,
98 if (cert.get() == NULL)
99 return CKM_API_ERROR_INPUT_PARAM;
100 return saveBinaryData(alias, DBDataType::CERTIFICATE, cert->getDER(), policy);
103 int ManagerImpl::saveData(const Alias &alias, const RawBuffer &rawData, const Policy &policy) {
104 if (!policy.extractable)
105 return CKM_API_ERROR_INPUT_PARAM;
106 return saveBinaryData(alias, DBDataType::BINARY_DATA, rawData, policy);
109 int ManagerImpl::removeAlias(const Alias &alias)
111 return try_catch([&] {
113 return CKM_API_ERROR_INPUT_PARAM;
116 AliasSupport helper(alias);
117 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
122 int retCode = m_storageConnection.processRequest(send.Pop(), recv);
123 if (CKM_API_SUCCESS != retCode)
128 recv.Deserialize(command, counter, retCode);
130 if (counter != m_counter) {
131 return CKM_API_ERROR_UNKNOWN;
138 int ManagerImpl::getBinaryData(
140 DBDataType sendDataType,
141 const Password &password,
142 DBDataType &recvDataType,
145 return try_catch([&] {
147 return CKM_API_ERROR_INPUT_PARAM;
150 AliasSupport helper(alias);
151 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
153 static_cast<int>(sendDataType),
158 int retCode = m_storageConnection.processRequest(send.Pop(), recv);
159 if (CKM_API_SUCCESS != retCode)
165 recv.Deserialize(command, counter, retCode, tmpDataType, rawData);
166 recvDataType = DBDataType(tmpDataType);
168 if (counter != m_counter) {
169 return CKM_API_ERROR_UNKNOWN;
176 int ManagerImpl::getKey(const Alias &alias, const Password &password, KeyShPtr &key) {
177 DBDataType recvDataType;
180 int retCode = getBinaryData(
182 DBDataType::KEY_RSA_PUBLIC,
187 if (retCode != CKM_API_SUCCESS)
190 KeyShPtr keyParsed(new KeyImpl(rawData));
192 if (keyParsed->empty()) {
193 LogDebug("Key empty - failed to parse!");
194 return CKM_API_ERROR_BAD_RESPONSE;
199 return CKM_API_SUCCESS;
202 int ManagerImpl::getCertificate(const Alias &alias, const Password &password, CertificateShPtr &cert)
204 DBDataType recvDataType;
207 int retCode = getBinaryData(
209 DBDataType::CERTIFICATE,
214 if (retCode != CKM_API_SUCCESS)
217 if (recvDataType != DBDataType::CERTIFICATE)
218 return CKM_API_ERROR_BAD_RESPONSE;
220 CertificateShPtr certParsed(new CertificateImpl(rawData, DataFormat::FORM_DER));
222 if (certParsed->empty())
223 return CKM_API_ERROR_BAD_RESPONSE;
227 return CKM_API_SUCCESS;
230 int ManagerImpl::getData(const Alias &alias, const Password &password, RawBuffer &rawData)
232 DBDataType recvDataType = DBDataType::BINARY_DATA;
234 int retCode = getBinaryData(
236 DBDataType::BINARY_DATA,
241 if (retCode != CKM_API_SUCCESS)
244 if (recvDataType != DBDataType::BINARY_DATA)
245 return CKM_API_ERROR_BAD_RESPONSE;
247 return CKM_API_SUCCESS;
250 int ManagerImpl::getBinaryDataAliasVector(DBDataType dataType, AliasVector &aliasVector)
252 return try_catch([&] {
255 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
257 static_cast<int>(dataType));
259 int retCode = m_storageConnection.processRequest(send.Pop(), recv);
260 if (CKM_API_SUCCESS != retCode)
266 LabelNameVector labelNameVector;
267 recv.Deserialize(command, counter, retCode, tmpDataType, labelNameVector);
268 if ((command != static_cast<int>(LogicCommand::GET_LIST)) || (counter != m_counter)) {
269 return CKM_API_ERROR_UNKNOWN;
272 for(const auto &it : labelNameVector)
273 aliasVector.push_back( AliasSupport::merge(it.first, it.second) );
279 int ManagerImpl::getKeyAliasVector(AliasVector &aliasVector) {
280 // in fact datatype has no meaning here - if not certificate or binary data
281 // then manager decides to list all between DB_KEY_FIRST and DB_KEY_LAST
282 return getBinaryDataAliasVector(DBDataType::DB_KEY_LAST, aliasVector);
285 int ManagerImpl::getCertificateAliasVector(AliasVector &aliasVector) {
286 return getBinaryDataAliasVector(DBDataType::CERTIFICATE, aliasVector);
289 int ManagerImpl::getDataAliasVector(AliasVector &aliasVector) {
290 return getBinaryDataAliasVector(DBDataType::BINARY_DATA, aliasVector);
293 int ManagerImpl::createKeyPairRSA(
295 const Alias &privateKeyAlias,
296 const Alias &publicKeyAlias,
297 const Policy &policyPrivateKey,
298 const Policy &policyPublicKey)
300 return this->createKeyPair(CKM::KeyType::KEY_RSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
303 int ManagerImpl::createKeyPairDSA(
305 const Alias &privateKeyAlias,
306 const Alias &publicKeyAlias,
307 const Policy &policyPrivateKey,
308 const Policy &policyPublicKey)
310 return this->createKeyPair(CKM::KeyType::KEY_DSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
313 int ManagerImpl::createKeyPairECDSA(
315 const Alias &privateKeyAlias,
316 const Alias &publicKeyAlias,
317 const Policy &policyPrivateKey,
318 const Policy &policyPublicKey)
320 return this->createKeyPair(CKM::KeyType::KEY_ECDSA_PUBLIC, static_cast<int>(type), privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
323 int ManagerImpl::createKeyPair(
324 const KeyType key_type,
325 const int additional_param,
326 const Alias &privateKeyAlias,
327 const Alias &publicKeyAlias,
328 const Policy &policyPrivateKey,
329 const Policy &policyPublicKey)
332 LogicCommand cmd_type;
335 case KeyType::KEY_RSA_PUBLIC:
336 case KeyType::KEY_RSA_PRIVATE:
337 cmd_type = LogicCommand::CREATE_KEY_PAIR_RSA;
340 case KeyType::KEY_DSA_PUBLIC:
341 case KeyType::KEY_DSA_PRIVATE:
342 cmd_type = LogicCommand::CREATE_KEY_PAIR_DSA;
345 case KeyType::KEY_ECDSA_PUBLIC:
346 case KeyType::KEY_ECDSA_PRIVATE:
347 cmd_type = LogicCommand::CREATE_KEY_PAIR_ECDSA;
351 return CKM_API_ERROR_INPUT_PARAM;
354 // proceed with sending request
356 int my_counter = m_counter;
357 return try_catch([&] {
360 AliasSupport privateHelper(privateKeyAlias);
361 AliasSupport publicHelper(publicKeyAlias);
362 auto send = MessageBuffer::Serialize(static_cast<int>(cmd_type),
364 static_cast<int>(additional_param),
365 PolicySerializable(policyPrivateKey),
366 PolicySerializable(policyPublicKey),
367 privateHelper.getName(),
368 privateHelper.getLabel(),
369 publicHelper.getName(),
370 publicHelper.getLabel());
372 int retCode = m_storageConnection.processRequest(send.Pop(), recv);
373 if (CKM_API_SUCCESS != retCode)
378 recv.Deserialize(command, counter, retCode);
379 if (counter != my_counter) {
380 return CKM_API_ERROR_UNKNOWN;
390 LogicCommand command,
392 const CertificateShPtr &certificate,
394 CertificateShPtrVector &certificateChainVector,
395 ServiceConnection & service_connection)
397 return try_catch([&] {
400 auto send = MessageBuffer::Serialize(static_cast<int>(command),
402 certificate->getDER(),
405 int retCode = service_connection.processRequest(send.Pop(), recv);
406 if (CKM_API_SUCCESS != retCode)
411 RawBufferVector rawBufferVector;
412 recv.Deserialize(retCommand, retCounter, retCode, rawBufferVector);
414 if ((counter != retCounter) || (static_cast<int>(command) != retCommand)) {
415 return CKM_API_ERROR_UNKNOWN;
418 if (retCode != CKM_API_SUCCESS) {
422 for (auto &e: rawBufferVector) {
423 CertificateShPtr cert(new CertificateImpl(e, DataFormat::FORM_DER));
425 return CKM_API_ERROR_BAD_RESPONSE;
426 certificateChainVector.push_back(cert);
434 int ManagerImpl::getCertificateChain(
435 const CertificateShPtr &certificate,
436 const CertificateShPtrVector &untrustedCertificates,
437 CertificateShPtrVector &certificateChainVector)
439 RawBufferVector rawBufferVector;
441 for (auto &e: untrustedCertificates) {
442 rawBufferVector.push_back(e->getDER());
446 LogicCommand::GET_CHAIN_CERT,
450 certificateChainVector,
451 m_storageConnection);
454 int ManagerImpl::getCertificateChain(
455 const CertificateShPtr &certificate,
456 const AliasVector &untrustedCertificates,
457 CertificateShPtrVector &certificateChainVector)
459 LabelNameVector untrusted_certs;
460 for (auto &e: untrustedCertificates) {
461 AliasSupport helper(e);
462 untrusted_certs.push_back(std::make_pair(helper.getLabel(), helper.getName()));
466 LogicCommand::GET_CHAIN_ALIAS,
470 certificateChainVector,
471 m_storageConnection);
474 int ManagerImpl::createSignature(
475 const Alias &privateKeyAlias,
476 const Password &password, // password for private_key
477 const RawBuffer &message,
478 const HashAlgorithm hash,
479 const RSAPaddingAlgorithm padding,
480 RawBuffer &signature)
483 int my_counter = m_counter;
484 return try_catch([&] {
487 AliasSupport helper(privateKeyAlias);
488 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
494 static_cast<int>(hash),
495 static_cast<int>(padding));
497 int retCode = m_storageConnection.processRequest(send.Pop(), recv);
498 if (CKM_API_SUCCESS != retCode)
503 recv.Deserialize(command, counter, retCode, signature);
505 if ((command != static_cast<int>(LogicCommand::CREATE_SIGNATURE))
506 || (counter != my_counter))
508 return CKM_API_ERROR_UNKNOWN;
515 int ManagerImpl::verifySignature(
516 const Alias &publicKeyOrCertAlias,
517 const Password &password, // password for public_key (optional)
518 const RawBuffer &message,
519 const RawBuffer &signature,
520 const HashAlgorithm hash,
521 const RSAPaddingAlgorithm padding)
524 int my_counter = m_counter;
525 return try_catch([&] {
528 AliasSupport helper(publicKeyOrCertAlias);
529 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
536 static_cast<int>(hash),
537 static_cast<int>(padding));
539 int retCode = m_storageConnection.processRequest(send.Pop(), recv);
540 if (CKM_API_SUCCESS != retCode)
545 recv.Deserialize(command, counter, retCode);
547 if ((command != static_cast<int>(LogicCommand::VERIFY_SIGNATURE))
548 || (counter != my_counter))
550 return CKM_API_ERROR_UNKNOWN;
557 int ManagerImpl::ocspCheck(const CertificateShPtrVector &certChain, int &ocspStatus)
559 return try_catch([&] {
560 int my_counter = ++m_counter;
563 RawBufferVector rawCertChain;
564 for (auto &e: certChain) {
565 rawCertChain.push_back(e->getDER());
568 auto send = MessageBuffer::Serialize(my_counter, rawCertChain);
570 int retCode = m_ocspConnection.processRequest(send.Pop(), recv);
571 if (CKM_API_SUCCESS != retCode)
575 recv.Deserialize(counter, retCode, ocspStatus);
577 if (my_counter != counter) {
578 return CKM_API_ERROR_UNKNOWN;
585 int ManagerImpl::setPermission(const Alias &alias,
586 const Label &accessor,
587 Permission newPermission)
590 int my_counter = m_counter;
591 return try_catch([&] {
593 AliasSupport helper(alias);
594 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SET_PERMISSION),
599 static_cast<int>(newPermission));
601 int retCode = m_storageConnection.processRequest(send.Pop(), recv);
602 if (CKM_API_SUCCESS != retCode)
607 recv.Deserialize(command, counter, retCode);
609 if (my_counter != counter) {
610 return CKM_API_ERROR_UNKNOWN;
617 ManagerShPtr Manager::create() {
619 return std::make_shared<ManagerImpl>();
620 } catch (const std::bad_alloc &) {
621 LogDebug("Bad alloc was caught during ManagerImpl creation.");
623 LogError("Critical error: Unknown exception was caught during ManagerImpl creation!");
625 return ManagerShPtr();