1 /* Copyright (c) 2014-2020 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 <exception.h>
29 #include <message-buffer.h>
30 #include <protocols.h>
32 #include <key-aes-impl.h>
33 #include <certificate-impl.h>
39 int deserializeResponse(const int msgId, MessageBuffer &recv, T&&...t)
41 int retMsgId, retCode;
42 recv.Deserialize(retMsgId, retCode, std::forward<T>(t)...);
43 return msgId != retMsgId ? CKM_API_ERROR_UNKNOWN : retCode;
48 ServiceConnection &serviceConnection,
51 const CertificateShPtr &certificate,
52 const T &untrustedVector,
53 const T &trustedVector,
54 bool useTrustedSystemCertificates,
55 CertificateShPtrVector &certificateChainVector)
57 EXCEPTION_GUARD_START_CPPAPI
59 Manager::Impl::Request rq(impl, command, serviceConnection,
60 certificate->getDER(), untrustedVector, trustedVector, useTrustedSystemCertificates);
64 RawBufferVector rawBufferVector;
65 int retCode = rq.deserialize(rawBufferVector);
67 if (retCode != CKM_API_SUCCESS)
70 for (auto &e : rawBufferVector) {
71 CertificateShPtr cert(new CertificateImpl(e, DataFormat::FORM_DER));
74 return CKM_API_ERROR_BAD_RESPONSE;
76 certificateChainVector.push_back(std::move(cert));
85 int doRequest(MessageBuffer &recv, CKM::ServiceConnection &conn, T&&...t)
87 return conn.processRequest(SerializeMessage(std::forward<T>(t)...), recv);
93 : m_storageConnection(SERVICE_SOCKET_CKM_STORAGE),
94 m_ocspConnection(SERVICE_SOCKET_OCSP),
95 m_encryptionConnection(SERVICE_SOCKET_ENCRYPTION)
99 template <class Cmd, class...T>
100 Manager::Impl::Request::Request(Manager::Impl &impl, Cmd cmd, CKM::ServiceConnection &conn, T&&...t)
102 static_assert(sizeof cmd <= sizeof(int));
103 const auto msgId = m_msgId = ++impl.m_counter;
104 m_retCode = doRequest(m_recv, conn, static_cast<int>(cmd), msgId, std::forward<T>(t)...);
107 Manager::Impl::Request::operator bool() const {
108 return CKM_API_SUCCESS == m_retCode;
111 int Manager::Impl::Request::err() const {
117 int Manager::Impl::Request::deserialize(T&&...t)
120 return deserializeResponse(m_msgId, m_recv, std::forward<T>(t)...);
124 int Manager::Impl::Request::maybeDeserialize(T&&...t)
126 return *this ? deserialize(std::forward<T>(t)...) : err();
129 int Manager::Impl::saveBinaryData(
132 const RawBuffer &rawData,
133 const Policy &policy)
135 EXCEPTION_GUARD_START_CPPAPI
137 if (alias.empty() || rawData.empty())
138 return CKM_API_ERROR_INPUT_PARAM;
140 AliasSupport helper(alias);
143 return Request(*this, LogicCommand::SAVE, m_storageConnection,
144 dataType, helper.getName(), helper.getOwner(), rawData, PolicySerializable(policy)
145 ).maybeDeserialize(opType);
150 int Manager::Impl::saveKey(const Alias &alias, const KeyShPtr &key,
151 const Policy &policy)
153 if (key.get() == NULL || key->empty())
154 return CKM_API_ERROR_INPUT_PARAM;
156 return saveBinaryData(alias, DataType(key->getType()), key->getDER(), policy);
157 } catch (const Exc::Exception &e) {
158 LogError("Exception: " << e.what());
163 int Manager::Impl::saveCertificate(
165 const CertificateShPtr &cert,
166 const Policy &policy)
168 return cert.get() == NULL || cert->empty()
169 ? CKM_API_ERROR_INPUT_PARAM
170 : saveBinaryData(alias, DataType::CERTIFICATE, cert->getDER(), policy);
173 int Manager::Impl::saveData(const Alias &alias, const RawBuffer &rawData,
174 const Policy &policy)
176 return !policy.extractable
177 ? CKM_API_ERROR_INPUT_PARAM
178 : saveBinaryData(alias, DataType::BINARY_DATA, rawData, policy);
182 int Manager::Impl::savePKCS12(
184 const PKCS12ShPtr &pkcs,
185 const Policy &keyPolicy,
186 const Policy &certPolicy)
188 if (alias.empty() || pkcs.get() == NULL)
189 return CKM_API_ERROR_INPUT_PARAM;
191 EXCEPTION_GUARD_START_CPPAPI
193 AliasSupport helper(alias);
195 return Request(*this, LogicCommand::SAVE_PKCS12, m_storageConnection,
196 helper.getName(), helper.getOwner(), PKCS12Serializable(*pkcs.get()),
197 PolicySerializable(keyPolicy), PolicySerializable(certPolicy)
198 ).maybeDeserialize();
203 int Manager::Impl::getPKCS12(const Alias &alias, PKCS12ShPtr &pkcs)
205 return getPKCS12(alias, Password(), Password(), pkcs);
208 int Manager::Impl::getPKCS12(const Alias &alias, const Password &keyPass,
209 const Password &certPass, PKCS12ShPtr &pkcs)
212 return CKM_API_ERROR_INPUT_PARAM;
214 EXCEPTION_GUARD_START_CPPAPI
216 AliasSupport helper(alias);
218 int msgId = ++m_counter;
221 int retCode = doRequest(recv, m_storageConnection,
222 static_cast<int>(LogicCommand::GET_PKCS12), msgId,
223 helper.getName(), helper.getOwner(), keyPass, certPass);
225 if (CKM_API_SUCCESS != retCode)
229 PKCS12Serializable gotPkcs;
230 recv.Deserialize(retMsgId, retCode, gotPkcs);
232 if (retMsgId != msgId)
233 return CKM_API_ERROR_UNKNOWN;
235 pkcs = std::make_shared<PKCS12Impl>(std::move(gotPkcs));
243 int Manager::Impl::removeAlias(const Alias &alias)
246 return CKM_API_ERROR_INPUT_PARAM;
248 EXCEPTION_GUARD_START_CPPAPI
250 AliasSupport helper(alias);
252 return Request(*this, LogicCommand::REMOVE, m_storageConnection,
253 helper.getName(), helper.getOwner()
254 ).maybeDeserialize();
259 int Manager::Impl::getBinaryData(
261 DataType sendDataType,
262 const Password &password,
263 DataType &recvDataType,
267 return CKM_API_ERROR_INPUT_PARAM;
269 EXCEPTION_GUARD_START_CPPAPI
271 AliasSupport helper(alias);
273 return Request(*this, LogicCommand::GET, m_storageConnection,
274 sendDataType, helper.getName(), helper.getOwner(), password
275 ).maybeDeserialize(recvDataType, rawData);
280 int Manager::Impl::getBinaryDataEncryptionStatus(const DataType sendDataType,
281 const Alias &alias, bool &status)
285 return CKM_API_ERROR_INPUT_PARAM;
287 EXCEPTION_GUARD_START_CPPAPI
289 AliasSupport helper(alias);
290 DataType tmpDataType;
292 int retCode = Request(*this, LogicCommand::GET_PROTECTION_STATUS, m_storageConnection,
293 sendDataType, helper.getName(), helper.getOwner()
294 ).maybeDeserialize(tmpDataType, status);
296 if (retCode != CKM_API_SUCCESS)
304 int Manager::Impl::getKey(const Alias &alias, const Password &password,
307 DataType recvDataType;
310 int retCode = getBinaryData(alias, DataType::KEY_RSA_PUBLIC, password, recvDataType, rawData);
312 if (retCode != CKM_API_SUCCESS)
315 KeyShPtr keyParsed = recvDataType.isSKey() ? Key::createAES(rawData) : Key::create(rawData);
318 LogDebug("Key empty - failed to parse!");
319 return CKM_API_ERROR_BAD_RESPONSE;
324 return CKM_API_SUCCESS;
327 int Manager::Impl::getCertificate(const Alias &alias, const Password &password,
328 CertificateShPtr &cert)
330 DataType recvDataType;
333 int retCode = getBinaryData(alias, DataType::CERTIFICATE, password, recvDataType, rawData);
335 if (retCode != CKM_API_SUCCESS)
338 if (!recvDataType.isCertificate())
339 return CKM_API_ERROR_BAD_RESPONSE;
341 CertificateShPtr certParsed(new CertificateImpl(rawData, DataFormat::FORM_DER));
343 if (certParsed->empty())
344 return CKM_API_ERROR_BAD_RESPONSE;
346 cert = std::move(certParsed);
348 return CKM_API_SUCCESS;
351 int Manager::Impl::getData(const Alias &alias, const Password &password,
354 DataType recvDataType = DataType::BINARY_DATA;
356 int retCode = getBinaryData(alias, DataType::BINARY_DATA, password, recvDataType, rawData);
358 if (retCode != CKM_API_SUCCESS)
361 return recvDataType.isBinaryData() ? CKM_API_SUCCESS : CKM_API_ERROR_BAD_RESPONSE;
364 int Manager::Impl::getBinaryDataAliasVectorHelper(DataType dataType,
365 OwnerNameVector &ownerNameVector)
367 DataType tmpDataType;
368 return Request(*this, LogicCommand::GET_LIST, m_storageConnection,
370 ).maybeDeserialize(tmpDataType, ownerNameVector);
373 int Manager::Impl::getBinaryDataAliasVector(DataType dataType,
374 AliasVector &aliasVector)
376 EXCEPTION_GUARD_START_CPPAPI
377 OwnerNameVector ownerNameVector;
378 int retCode = getBinaryDataAliasVectorHelper(dataType, ownerNameVector);
380 if (retCode != CKM_API_SUCCESS)
383 for (const auto &it : ownerNameVector)
384 aliasVector.push_back(AliasSupport::merge(it.first, it.second));
386 return CKM_API_SUCCESS;
390 int Manager::Impl::getBinaryDataAliasPwdVector(DataType dataType,
391 AliasPwdVector &aliasPwdVector)
393 EXCEPTION_GUARD_START_CPPAPI
394 OwnerNameVector ownerNameVector;
395 OwnerNameEncryptionStatusVector ownerNameEncryptionStatusVector;
396 int retCode = getBinaryDataAliasVectorHelper(dataType, ownerNameVector);
398 if (retCode != CKM_API_SUCCESS)
401 for (const auto &it : ownerNameVector)
403 Alias alias = AliasSupport::merge(std::get<0>(it), std::get<1>(it));
405 retCode = getBinaryDataEncryptionStatus(dataType, alias, status);
407 if (retCode != CKM_API_SUCCESS)
410 aliasPwdVector.push_back(std::make_pair(alias, status));
412 return CKM_API_SUCCESS;
416 int Manager::Impl::getKeyAliasVector(AliasVector &aliasVector)
418 // in fact datatype has no meaning here - if not certificate or binary data
419 // then manager decides to list all between DB_KEY_FIRST and DB_KEY_LAST
420 return getBinaryDataAliasVector(DataType::DB_KEY_LAST, aliasVector);
423 int Manager::Impl::getCertificateAliasVector(AliasVector &aliasVector)
425 return getBinaryDataAliasVector(DataType::CERTIFICATE, aliasVector);
428 int Manager::Impl::getDataAliasVector(AliasVector &aliasVector)
430 return getBinaryDataAliasVector(DataType::BINARY_DATA, aliasVector);
433 int Manager::Impl::getKeyAliasPwdVector(AliasPwdVector &aliasPwdVector)
435 return getBinaryDataAliasPwdVector(DataType::DB_KEY_LAST, aliasPwdVector);
438 int Manager::Impl::getKeyEncryptionStatus(const Alias &alias, bool &status)
440 return getBinaryDataEncryptionStatus(DataType::DB_KEY_LAST, alias, status);
443 int Manager::Impl::getCertificateAliasPwdVector(AliasPwdVector &aliasPwdVector)
445 return getBinaryDataAliasPwdVector(DataType::CERTIFICATE, aliasPwdVector);
448 int Manager::Impl::getCertificateEncryptionStatus(const Alias &alias, bool &status)
450 return getBinaryDataEncryptionStatus(DataType::CERTIFICATE, alias, status);
453 int Manager::Impl::getDataAliasPwdVector(AliasPwdVector &aliasPwdVector)
455 return getBinaryDataAliasPwdVector(DataType::BINARY_DATA, aliasPwdVector);
458 int Manager::Impl::getDataEncryptionStatus(const Alias &alias, bool &status)
460 return getBinaryDataEncryptionStatus(DataType::BINARY_DATA, alias, status);
463 int Manager::Impl::createKeyPairRSA(
465 const Alias &privateKeyAlias,
466 const Alias &publicKeyAlias,
467 const Policy &policyPrivateKey,
468 const Policy &policyPublicKey)
470 return this->createKeyPair(CKM::KeyType::KEY_RSA_PUBLIC, size, privateKeyAlias,
471 publicKeyAlias, policyPrivateKey, policyPublicKey);
474 int Manager::Impl::createKeyPairDSA(
476 const Alias &privateKeyAlias,
477 const Alias &publicKeyAlias,
478 const Policy &policyPrivateKey,
479 const Policy &policyPublicKey)
481 return this->createKeyPair(CKM::KeyType::KEY_DSA_PUBLIC, size, privateKeyAlias,
482 publicKeyAlias, policyPrivateKey, policyPublicKey);
485 int Manager::Impl::createKeyPairECDSA(
487 const Alias &privateKeyAlias,
488 const Alias &publicKeyAlias,
489 const Policy &policyPrivateKey,
490 const Policy &policyPublicKey)
492 return this->createKeyPair(CKM::KeyType::KEY_ECDSA_PUBLIC,
493 static_cast<int>(type), privateKeyAlias, publicKeyAlias,
494 policyPrivateKey, policyPublicKey);
497 int Manager::Impl::createKeyAES(
499 const Alias &keyAlias,
500 const Policy &policyKey)
502 EXCEPTION_GUARD_START_CPPAPI
504 AliasSupport aliasHelper(keyAlias);
506 return Request(*this, LogicCommand::CREATE_KEY_AES, m_storageConnection,
507 static_cast<int>(size), PolicySerializable(policyKey),
508 aliasHelper.getName(), aliasHelper.getOwner()
509 ).maybeDeserialize();
515 int Manager::Impl::createKeyPair(
516 const KeyType key_type,
517 const int additional_param,
518 const Alias &privateKeyAlias,
519 const Alias &publicKeyAlias,
520 const Policy &policyPrivateKey,
521 const Policy &policyPublicKey)
524 CryptoAlgorithm keyGenAlgorithm;
527 case KeyType::KEY_RSA_PUBLIC:
528 case KeyType::KEY_RSA_PRIVATE:
529 keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_GEN);
530 keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, additional_param);
533 case KeyType::KEY_DSA_PUBLIC:
534 case KeyType::KEY_DSA_PRIVATE:
535 keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::DSA_GEN);
536 keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, additional_param);
539 case KeyType::KEY_ECDSA_PUBLIC:
540 case KeyType::KEY_ECDSA_PRIVATE:
541 keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
542 keyGenAlgorithm.setParam(ParamName::GEN_EC, additional_param);
546 return CKM_API_ERROR_INPUT_PARAM;
549 EXCEPTION_GUARD_START_CPPAPI
551 AliasSupport privateHelper(privateKeyAlias);
552 AliasSupport publicHelper(publicKeyAlias);
554 return Request(*this, LogicCommand::CREATE_KEY_PAIR, m_storageConnection,
555 CryptoAlgorithmSerializable(keyGenAlgorithm),
556 PolicySerializable(policyPrivateKey),
557 PolicySerializable(policyPublicKey),
558 privateHelper.getName(), privateHelper.getOwner(),
559 publicHelper.getName(), publicHelper.getOwner()
560 ).maybeDeserialize();
565 int Manager::Impl::getCertificateChain(
566 const CertificateShPtr &certificate,
567 const CertificateShPtrVector &untrustedCertificates,
568 const CertificateShPtrVector &trustedCertificates,
569 bool useTrustedSystemCertificates,
570 CertificateShPtrVector &certificateChainVector)
572 RawBufferVector untrustedVector;
573 RawBufferVector trustedVector;
575 if (!certificate || certificate->empty())
576 return CKM_API_ERROR_INPUT_PARAM;
578 for (auto &e : untrustedCertificates) {
579 if (!e || e->empty())
580 return CKM_API_ERROR_INPUT_PARAM;
581 untrustedVector.push_back(e->getDER());
584 for (auto &e : trustedCertificates) {
585 if (!e || e->empty())
586 return CKM_API_ERROR_INPUT_PARAM;
587 trustedVector.push_back(e->getDER());
590 return getCertChain(m_storageConnection, LogicCommand::GET_CHAIN_CERT, *this,
591 certificate, untrustedVector, trustedVector,
592 useTrustedSystemCertificates, certificateChainVector);
595 int Manager::Impl::getCertificateChain(
596 const CertificateShPtr &certificate,
597 const AliasVector &untrustedCertificates,
598 const AliasVector &trustedCertificates,
599 bool useTrustedSystemCertificates,
600 CertificateShPtrVector &certificateChainVector)
602 OwnerNameVector untrustedVector;
603 OwnerNameVector trustedVector;
605 if (!certificate || certificate->empty())
606 return CKM_API_ERROR_INPUT_PARAM;
608 for (auto &e : untrustedCertificates) {
609 AliasSupport helper(e);
610 untrustedVector.push_back(std::make_pair(helper.getOwner(), helper.getName()));
613 for (auto &e : trustedCertificates) {
614 AliasSupport helper(e);
615 trustedVector.push_back(std::make_pair(helper.getOwner(), helper.getName()));
618 return getCertChain(m_storageConnection, LogicCommand::GET_CHAIN_ALIAS, *this,
619 certificate, untrustedVector, trustedVector,
620 useTrustedSystemCertificates, certificateChainVector);
623 int Manager::Impl::createSignature(
624 const Alias &privateKeyAlias,
625 const Password &password, // password for private_key
626 const RawBuffer &message,
627 const CryptoAlgorithm &cAlgorithm,
628 RawBuffer &signature)
630 EXCEPTION_GUARD_START_CPPAPI
632 AliasSupport helper(privateKeyAlias);
634 return Request(*this, LogicCommand::CREATE_SIGNATURE, m_storageConnection,
635 helper.getName(), helper.getOwner(), password, message,
636 CryptoAlgorithmSerializable(cAlgorithm)
637 ).maybeDeserialize(signature);
642 int Manager::Impl::verifySignature(
643 const Alias &publicKeyOrCertAlias,
644 const Password &password, // password for public_key (optional)
645 const RawBuffer &message,
646 const RawBuffer &signature,
647 const CryptoAlgorithm &cAlg)
649 EXCEPTION_GUARD_START_CPPAPI
651 AliasSupport helper(publicKeyOrCertAlias);
653 return Request(*this, LogicCommand::VERIFY_SIGNATURE, m_storageConnection,
654 helper.getName(), helper.getOwner(), password, message, signature,
655 CryptoAlgorithmSerializable(cAlg)
656 ).maybeDeserialize();
661 int Manager::Impl::ocspCheck(const CertificateShPtrVector &certChain,
664 EXCEPTION_GUARD_START_CPPAPI
666 int msgId = ++m_counter;
669 RawBufferVector rawCertChain;
671 for (auto &e : certChain) {
672 if (!e || e->empty()) {
673 LogError("Empty certificate");
674 return CKM_API_ERROR_INPUT_PARAM;
677 rawCertChain.push_back(e->getDER());
680 int retCode = doRequest(recv, m_ocspConnection, msgId, rawCertChain);
682 if (CKM_API_SUCCESS != retCode)
685 return deserializeResponse(msgId, recv, ocspStatus);
690 int Manager::Impl::setPermission(const Alias &alias,
691 const ClientId &accessor,
692 PermissionMask permissionMask)
694 EXCEPTION_GUARD_START_CPPAPI
696 AliasSupport helper(alias);
698 return Request(*this, LogicCommand::SET_PERMISSION, m_storageConnection,
699 helper.getName(), helper.getOwner(), accessor, permissionMask
700 ).maybeDeserialize();
705 int Manager::Impl::crypt(EncryptionCommand command,
706 const CryptoAlgorithm &algo,
707 const Alias &keyAlias,
708 const Password &password,
709 const RawBuffer &input,
712 EXCEPTION_GUARD_START_CPPAPI
714 AliasSupport helper(keyAlias);
715 CryptoAlgorithmSerializable cas(algo);
717 return Request(*this, command, m_encryptionConnection,
718 cas, helper.getName(), helper.getOwner(), password, input
719 ).maybeDeserialize(output);
724 int Manager::Impl::encrypt(const CryptoAlgorithm &algo,
725 const Alias &keyAlias,
726 const Password &password,
727 const RawBuffer &plain,
728 RawBuffer &encrypted)
730 return crypt(EncryptionCommand::ENCRYPT, algo, keyAlias, password, plain,
734 int Manager::Impl::decrypt(const CryptoAlgorithm &algo,
735 const Alias &keyAlias,
736 const Password &password,
737 const RawBuffer &encrypted,
738 RawBuffer &decrypted)
740 return crypt(EncryptionCommand::DECRYPT, algo, keyAlias, password, encrypted,