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>
26 #include <client-manager-impl.h>
27 #include <client-common.h>
28 #include <message-buffer.h>
29 #include <protocols.h>
31 #include <certificate-impl.h>
35 void clientInitialize(void) {
36 OpenSSL_add_all_ciphers();
37 OpenSSL_add_all_algorithms();
38 OpenSSL_add_all_digests();
41 } // namespace anonymous
45 bool ManagerImpl::s_isInit = false;
47 ManagerImpl::ManagerImpl()
50 // TODO secure with mutex
59 int ManagerImpl::saveBinaryData(
62 const RawBuffer &rawData,
67 return try_catch([&] {
68 if (alias.empty() || rawData.empty())
69 return CKM_API_ERROR_INPUT_PARAM;
72 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
74 static_cast<int>(dataType),
77 PolicySerializable(policy));
79 int retCode = sendToServer(
80 SERVICE_SOCKET_CKM_STORAGE,
84 if (CKM_API_SUCCESS != retCode) {
91 recv.Deserialize(command, counter, retCode, opType);
93 if (counter != m_counter) {
94 return CKM_API_ERROR_UNKNOWN;
101 int ManagerImpl::saveKey(const Alias &alias, const KeyShPtr &key, const Policy &policy) {
102 if (key.get() == NULL)
103 return CKM_API_ERROR_INPUT_PARAM;
104 return saveBinaryData(alias, toDBDataType(key->getType()), key->getDER(), policy);
107 int ManagerImpl::saveCertificate(
109 const CertificateShPtr &cert,
110 const Policy &policy)
112 if (cert.get() == NULL)
113 return CKM_API_ERROR_INPUT_PARAM;
114 return saveBinaryData(alias, DBDataType::CERTIFICATE, cert->getDER(), policy);
117 int ManagerImpl::saveData(const Alias &alias, const RawBuffer &rawData, const Policy &policy) {
118 if (!policy.extractable)
119 return CKM_API_ERROR_INPUT_PARAM;
120 return saveBinaryData(alias, DBDataType::BINARY_DATA, rawData, policy);
123 int ManagerImpl::removeBinaryData(const Alias &alias, DBDataType dataType)
125 return try_catch([&] {
127 return CKM_API_ERROR_INPUT_PARAM;
130 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
132 static_cast<int>(dataType),
134 int retCode = sendToServer(
135 SERVICE_SOCKET_CKM_STORAGE,
139 if (CKM_API_SUCCESS != retCode) {
146 recv.Deserialize(command, counter, retCode, opType);
148 if (counter != m_counter) {
149 return CKM_API_ERROR_UNKNOWN;
156 int ManagerImpl::removeKey(const Alias &alias) {
157 return removeBinaryData(alias, DBDataType::KEY_RSA_PUBLIC);
160 int ManagerImpl::removeCertificate(const Alias &alias) {
161 return removeBinaryData(alias, DBDataType::CERTIFICATE);
164 int ManagerImpl::removeData(const Alias &alias) {
165 return removeBinaryData(alias, DBDataType::BINARY_DATA);
168 int ManagerImpl::getBinaryData(
170 DBDataType sendDataType,
171 const Password &password,
172 DBDataType &recvDataType,
175 return try_catch([&] {
177 return CKM_API_ERROR_INPUT_PARAM;
180 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
182 static_cast<int>(sendDataType),
185 int retCode = sendToServer(
186 SERVICE_SOCKET_CKM_STORAGE,
190 if (CKM_API_SUCCESS != retCode) {
197 recv.Deserialize(command, counter, retCode, tmpDataType,rawData);
198 recvDataType = static_cast<DBDataType>(tmpDataType);
200 if (counter != m_counter) {
201 return CKM_API_ERROR_UNKNOWN;
208 int ManagerImpl::getKey(const Alias &alias, const Password &password, KeyShPtr &key) {
209 DBDataType recvDataType;
212 int retCode = getBinaryData(
214 DBDataType::KEY_RSA_PUBLIC,
219 if (retCode != CKM_API_SUCCESS)
222 KeyShPtr keyParsed(new KeyImpl(rawData));
224 if (keyParsed->empty()) {
225 LogDebug("Key empty - failed to parse!");
226 return CKM_API_ERROR_BAD_RESPONSE;
231 return CKM_API_SUCCESS;
234 int ManagerImpl::getCertificate(const Alias &alias, const Password &password, CertificateShPtr &cert)
236 DBDataType recvDataType;
239 int retCode = getBinaryData(
241 DBDataType::CERTIFICATE,
246 if (retCode != CKM_API_SUCCESS)
249 if (recvDataType != DBDataType::CERTIFICATE)
250 return CKM_API_ERROR_BAD_RESPONSE;
252 CertificateShPtr certParsed(new CertificateImpl(rawData, DataFormat::FORM_DER));
254 if (certParsed->empty())
255 return CKM_API_ERROR_BAD_RESPONSE;
259 return CKM_API_SUCCESS;
262 int ManagerImpl::getData(const Alias &alias, const Password &password, RawBuffer &rawData)
264 DBDataType recvDataType;
266 int retCode = getBinaryData(
268 DBDataType::BINARY_DATA,
273 if (retCode != CKM_API_SUCCESS)
276 if (recvDataType != DBDataType::BINARY_DATA)
277 return CKM_API_ERROR_BAD_RESPONSE;
279 return CKM_API_SUCCESS;
282 int ManagerImpl::getBinaryDataAliasVector(DBDataType dataType, AliasVector &aliasVector)
284 return try_catch([&] {
287 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
289 static_cast<int>(dataType));
290 int retCode = sendToServer(
291 SERVICE_SOCKET_CKM_STORAGE,
295 if (CKM_API_SUCCESS != retCode) {
302 recv.Deserialize(command, counter, retCode, tmpDataType, aliasVector);
303 if ((command != static_cast<int>(LogicCommand::GET_LIST)) || (counter != m_counter)) {
304 return CKM_API_ERROR_UNKNOWN;
311 int ManagerImpl::getKeyAliasVector(AliasVector &aliasVector) {
312 // in fact datatype has no meaning here - if not certificate or binary data
313 // then manager decides to list all between DB_KEY_FIRST and DB_KEY_LAST
314 return getBinaryDataAliasVector(DBDataType::DB_KEY_LAST, aliasVector);
317 int ManagerImpl::getCertificateAliasVector(AliasVector &aliasVector) {
318 return getBinaryDataAliasVector(DBDataType::CERTIFICATE, aliasVector);
321 int ManagerImpl::getDataAliasVector(AliasVector &aliasVector) {
322 return getBinaryDataAliasVector(DBDataType::BINARY_DATA, aliasVector);
325 int ManagerImpl::createKeyPairRSA(
327 const Alias &privateKeyAlias,
328 const Alias &publicKeyAlias,
329 const Policy &policyPrivateKey,
330 const Policy &policyPublicKey)
332 return this->createKeyPair(CKM::KeyType::KEY_RSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
335 int ManagerImpl::createKeyPairDSA(
337 const Alias &privateKeyAlias,
338 const Alias &publicKeyAlias,
339 const Policy &policyPrivateKey,
340 const Policy &policyPublicKey)
342 return this->createKeyPair(CKM::KeyType::KEY_DSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
345 int ManagerImpl::createKeyPairECDSA(
347 const Alias &privateKeyAlias,
348 const Alias &publicKeyAlias,
349 const Policy &policyPrivateKey,
350 const Policy &policyPublicKey)
352 return this->createKeyPair(CKM::KeyType::KEY_ECDSA_PUBLIC, static_cast<int>(type), privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
355 int ManagerImpl::createKeyPair(
356 const KeyType key_type,
357 const int additional_param,
358 const Alias &privateKeyAlias,
359 const Alias &publicKeyAlias,
360 const Policy &policyPrivateKey,
361 const Policy &policyPublicKey)
364 LogicCommand cmd_type;
367 case KeyType::KEY_RSA_PUBLIC:
368 case KeyType::KEY_RSA_PRIVATE:
369 cmd_type = LogicCommand::CREATE_KEY_PAIR_RSA;
372 case KeyType::KEY_DSA_PUBLIC:
373 case KeyType::KEY_DSA_PRIVATE:
374 cmd_type = LogicCommand::CREATE_KEY_PAIR_DSA;
377 case KeyType::KEY_ECDSA_PUBLIC:
378 case KeyType::KEY_ECDSA_PRIVATE:
379 cmd_type = LogicCommand::CREATE_KEY_PAIR_ECDSA;
383 return CKM_API_ERROR_INPUT_PARAM;
386 // proceed with sending request
388 int my_counter = m_counter;
389 return try_catch([&] {
392 auto send = MessageBuffer::Serialize(static_cast<int>(cmd_type),
394 static_cast<int>(additional_param),
395 PolicySerializable(policyPrivateKey),
396 PolicySerializable(policyPublicKey),
399 int retCode = sendToServer(
400 SERVICE_SOCKET_CKM_STORAGE,
404 if (CKM_API_SUCCESS != retCode) {
410 recv.Deserialize(command, counter, retCode);
411 if (counter != my_counter) {
412 return CKM_API_ERROR_UNKNOWN;
422 LogicCommand command,
424 const CertificateShPtr &certificate,
426 CertificateShPtrVector &certificateChainVector)
428 return try_catch([&] {
431 auto send = MessageBuffer::Serialize(static_cast<int>(command),
433 certificate->getDER(),
435 int retCode = sendToServer(
436 SERVICE_SOCKET_CKM_STORAGE,
440 if (CKM_API_SUCCESS != retCode) {
446 RawBufferVector rawBufferVector;
447 recv.Deserialize(retCommand, retCounter, retCode, rawBufferVector);
449 if ((counter != retCounter) || (static_cast<int>(command) != retCommand)) {
450 return CKM_API_ERROR_UNKNOWN;
453 if (retCode != CKM_API_SUCCESS) {
457 for (auto &e: rawBufferVector) {
458 CertificateShPtr cert(new CertificateImpl(e, DataFormat::FORM_DER));
460 return CKM_API_ERROR_BAD_RESPONSE;
461 certificateChainVector.push_back(cert);
469 int ManagerImpl::getCertificateChain(
470 const CertificateShPtr &certificate,
471 const CertificateShPtrVector &untrustedCertificates,
472 CertificateShPtrVector &certificateChainVector)
474 RawBufferVector rawBufferVector;
476 for (auto &e: untrustedCertificates) {
477 rawBufferVector.push_back(e->getDER());
481 LogicCommand::GET_CHAIN_CERT,
485 certificateChainVector);
488 int ManagerImpl::getCertificateChain(
489 const CertificateShPtr &certificate,
490 const AliasVector &untrustedCertificates,
491 CertificateShPtrVector &certificateChainVector)
494 LogicCommand::GET_CHAIN_ALIAS,
497 untrustedCertificates,
498 certificateChainVector);
501 int ManagerImpl::createSignature(
502 const Alias &privateKeyAlias,
503 const Password &password, // password for private_key
504 const RawBuffer &message,
505 const HashAlgorithm hash,
506 const RSAPaddingAlgorithm padding,
507 RawBuffer &signature)
510 int my_counter = m_counter;
511 return try_catch([&] {
514 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
519 static_cast<int>(hash),
520 static_cast<int>(padding));
521 int retCode = sendToServer(
522 SERVICE_SOCKET_CKM_STORAGE,
526 if (CKM_API_SUCCESS != retCode) {
533 recv.Deserialize(command, counter, retCode, signature);
535 if ((command != static_cast<int>(LogicCommand::CREATE_SIGNATURE))
536 || (counter != my_counter))
538 return CKM_API_ERROR_UNKNOWN;
545 int ManagerImpl::verifySignature(
546 const Alias &publicKeyOrCertAlias,
547 const Password &password, // password for public_key (optional)
548 const RawBuffer &message,
549 const RawBuffer &signature,
550 const HashAlgorithm hash,
551 const RSAPaddingAlgorithm padding)
554 int my_counter = m_counter;
555 return try_catch([&] {
558 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
560 publicKeyOrCertAlias,
564 static_cast<int>(hash),
565 static_cast<int>(padding));
566 int retCode = sendToServer(
567 SERVICE_SOCKET_CKM_STORAGE,
571 if (CKM_API_SUCCESS != retCode) {
578 recv.Deserialize(command, counter, retCode);
580 if ((command != static_cast<int>(LogicCommand::VERIFY_SIGNATURE))
581 || (counter != my_counter))
583 return CKM_API_ERROR_UNKNOWN;
590 int ManagerImpl::ocspCheck(const CertificateShPtrVector &certChain, int &ocspStatus)
592 return try_catch([&] {
593 int my_counter = ++m_counter;
596 RawBufferVector rawCertChain;
597 for (auto &e: certChain) {
598 rawCertChain.push_back(e->getDER());
601 auto send = MessageBuffer::Serialize(my_counter, rawCertChain);
603 int retCode = sendToServer(
608 if (CKM_API_SUCCESS != retCode) {
614 recv.Deserialize(counter, retCode, ocspStatus);
616 if (my_counter != counter) {
617 return CKM_API_ERROR_UNKNOWN;
624 int ManagerImpl::allowAccess(const std::string &alias,
625 const std::string &accessor,
629 int my_counter = m_counter;
630 return try_catch([&] {
632 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::ALLOW_ACCESS),
636 static_cast<int>(granted));
637 int retCode = sendToServer(
638 SERVICE_SOCKET_CKM_STORAGE,
642 if (CKM_API_SUCCESS != retCode) {
648 recv.Deserialize(command, counter, retCode);
650 if (my_counter != counter) {
651 return CKM_API_ERROR_UNKNOWN;
658 int ManagerImpl::denyAccess(const std::string &alias, const std::string &accessor)
661 int my_counter = m_counter;
662 return try_catch([&] {
664 auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::DENY_ACCESS),
668 int retCode = sendToServer(
669 SERVICE_SOCKET_CKM_STORAGE,
673 if (CKM_API_SUCCESS != retCode) {
679 recv.Deserialize(command, counter, retCode);
681 if (my_counter != counter) {
682 return CKM_API_ERROR_UNKNOWN;
689 ManagerShPtr Manager::create() {
691 return std::make_shared<ManagerImpl>();
692 } catch (const std::bad_alloc &) {
693 LogDebug("Bad alloc was caught during ManagerImpl creation.");
695 LogError("Critical error: Unknown exception was caught during ManagerImpl creation!");
697 return ManagerShPtr();