Return proper error for wrong wrapped key type
[platform/core/security/key-manager.git] / src / manager / client / client-manager-impl.cpp
index 2e3529b..961f31d 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+/* Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
  * @version     1.0
  * @brief       Manager implementation.
  */
+#include <openssl/evp.h>
+
 #include <dpl/serialization.h>
+#include <dpl/log/log.h>
 
 #include <client-manager-impl.h>
 #include <client-common.h>
-#include <client-key-impl.h>
+#include <exception.h>
 #include <message-buffer.h>
 #include <protocols.h>
+#include <key-impl.h>
+#include <key-aes-impl.h>
+#include <certificate-impl.h>
 
 namespace CKM {
 
-int Manager::ManagerImpl::saveBinaryData(
-    const Alias &alias,
-    DBDataType dataType,
-    const RawData &rawData,
-    const Policy &policy)
+namespace {
+template <class...T>
+int deserializeResponse(const int msgId, MessageBuffer &recv, T&&...t)
+{
+       int retMsgId, retCode;
+       recv.Deserialize(retMsgId, retCode, std::forward<T>(t)...);
+       return msgId != retMsgId ? CKM_API_ERROR_UNKNOWN : retCode;
+}
+
+template <class T>
+int getCertChain(
+       ServiceConnection &serviceConnection,
+       LogicCommand command,
+       Manager::Impl &impl,
+       const CertificateShPtr &certificate,
+       const T &untrustedVector,
+       const T &trustedVector,
+       bool useTrustedSystemCertificates,
+       CertificateShPtrVector &certificateChainVector)
 {
-    m_counter++;
+       EXCEPTION_GUARD_START_CPPAPI
 
-    return try_catch([&] {
-        if (alias.empty() || rawData.empty())
-            return KEY_MANAGER_API_ERROR_INPUT_PARAM;
+       Manager::Impl::Request rq(impl, command, serviceConnection,
+                       certificate->getDER(), untrustedVector, trustedVector, useTrustedSystemCertificates);
+       if (!rq)
+               return rq.err();
 
-        MessageBuffer send, recv;
-        Serialization::Serialize(send, static_cast<int>(LogicCommand::SAVE));
-        Serialization::Serialize(send, m_counter);
-        Serialization::Serialize(send, static_cast<int>(dataType));
-        Serialization::Serialize(send, alias);
-        Serialization::Serialize(send, rawData);
-        Serialization::Serialize(send, PolicySerializable(policy));
+       RawBufferVector rawBufferVector;
+       int retCode = rq.deserialize(rawBufferVector);
 
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
+       if (retCode != CKM_API_SUCCESS)
+               return retCode;
 
-        if (KEY_MANAGER_API_SUCCESS != retCode) {
-            return retCode;
-        }
+       for (auto &e : rawBufferVector) {
+               CertificateShPtr cert(new CertificateImpl(e, DataFormat::FORM_DER));
 
-        int command;
-        int counter;
-        int opType;
-        Deserialization::Deserialize(recv, command);
-        Deserialization::Deserialize(recv, counter);
-        Deserialization::Deserialize(recv, retCode);
-        Deserialization::Deserialize(recv, opType);
+               if (cert->empty())
+                       return CKM_API_ERROR_BAD_RESPONSE;
 
-        if (counter != m_counter) {
-            return KEY_MANAGER_API_ERROR_UNKNOWN;
-        }
+               certificateChainVector.push_back(std::move(cert));
+       }
 
-        return retCode;
-    });
+       return retCode;
+
+       EXCEPTION_GUARD_END
 }
 
-int Manager::ManagerImpl::saveKey(const Alias &alias, const Key &key, const Policy &policy) {
-    return saveBinaryData(alias, toDBDataType(key.getType()), key.getKey(), policy);
+template <class...T>
+int doRequest(MessageBuffer &recv, CKM::ServiceConnection &conn, T&&...t)
+{
+       return conn.processRequest(SerializeMessage(std::forward<T>(t)...), recv);
 }
 
-int Manager::ManagerImpl::saveCertificate(
-    const Alias &alias,
-    const Certificate &cert,
-    const Policy &policy)
+} // namespace
+
+Manager::Impl::Impl()
+       : m_storageConnection(SERVICE_SOCKET_CKM_STORAGE),
+         m_ocspConnection(SERVICE_SOCKET_OCSP),
+         m_encryptionConnection(SERVICE_SOCKET_ENCRYPTION)
 {
-    return saveBinaryData(alias, DBDataType::CERTIFICATE, cert.getDER(), policy);
 }
 
-int Manager::ManagerImpl::saveData(const Alias &alias, const RawData &rawData, const Policy &policy) {
-    return saveBinaryData(alias, DBDataType::BINARY_DATA, rawData, policy);
+template <class Cmd, class...T>
+Manager::Impl::Request::Request(Manager::Impl &impl, Cmd cmd, CKM::ServiceConnection &conn, T&&...t)
+{
+       static_assert(sizeof cmd <= sizeof(int));
+       const auto msgId = m_msgId = ++impl.m_counter;
+       m_retCode = doRequest(m_recv, conn, cmd, msgId, std::forward<T>(t)...);
+}
+
+Manager::Impl::Request::operator bool() const {
+       return CKM_API_SUCCESS == m_retCode;
 }
 
-int Manager::ManagerImpl::removeBinaryData(const Alias &alias, DBDataType dataType)
+int Manager::Impl::Request::err() const {
+       assert(!*this);
+       return m_retCode;
+}
+
+template <class...T>
+int Manager::Impl::Request::deserialize(T&&...t)
 {
-    return try_catch([&] {
-        if (alias.empty())
-            return KEY_MANAGER_API_ERROR_INPUT_PARAM;
+       assert(*this);
+       return deserializeResponse(m_msgId, m_recv, std::forward<T>(t)...);
+}
 
-        MessageBuffer send, recv;
-        Serialization::Serialize(send, static_cast<int>(LogicCommand::REMOVE));
-        Serialization::Serialize(send, m_counter);
-        Serialization::Serialize(send, static_cast<int>(dataType));
-        Serialization::Serialize(send, alias);
+template <class...T>
+int Manager::Impl::Request::maybeDeserialize(T&&...t)
+{
+       return *this ? deserialize(std::forward<T>(t)...) : err();
+}
 
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
+int Manager::Impl::saveBinaryData(
+       const Alias &alias,
+       DataType dataType,
+       const RawBuffer &rawData,
+       const Policy &policy)
+{
+       EXCEPTION_GUARD_START_CPPAPI
 
-        if (KEY_MANAGER_API_SUCCESS != retCode) {
-            return retCode;
-        }
+       if (alias.empty() || rawData.empty())
+               return CKM_API_ERROR_INPUT_PARAM;
 
-        int command;
-        int counter;
-        int opType;
-        Deserialization::Deserialize(recv, command);
-        Deserialization::Deserialize(recv, counter);
-        Deserialization::Deserialize(recv, retCode);
-        Deserialization::Deserialize(recv, opType);
+       AliasSupport helper(alias);
 
-        if (counter != m_counter) {
-            return KEY_MANAGER_API_ERROR_UNKNOWN;
-        }
+       int opType;
+       return Request(*this, LogicCommand::SAVE, m_storageConnection,
+                       dataType, helper.getName(), helper.getOwner(), rawData, PolicySerializable(policy)
+               ).maybeDeserialize(opType);
 
-        return retCode;
-    });
+       EXCEPTION_GUARD_END
 }
 
-int Manager::ManagerImpl::removeKey(const Alias &alias) {
-    return removeBinaryData(alias, DBDataType::KEY_RSA_PUBLIC);
+int Manager::Impl::saveKey(const Alias &alias, const KeyShPtr &key,
+                                                  const Policy &policy)
+{
+       if (key.get() == NULL || key->empty())
+               return CKM_API_ERROR_INPUT_PARAM;
+       try {
+               return saveBinaryData(alias, DataType(key->getType()), key->getDER(), policy);
+       } catch (const Exc::Exception &e) {
+               LogError("Exception: " << e.what());
+               return e.error();
+       }
 }
 
-int Manager::ManagerImpl::removeCertificate(const Alias &alias) {
-    return removeBinaryData(alias, DBDataType::CERTIFICATE);
+int Manager::Impl::saveCertificate(
+       const Alias &alias,
+       const CertificateShPtr &cert,
+       const Policy &policy)
+{
+       return cert.get() == NULL || cert->empty()
+               ? CKM_API_ERROR_INPUT_PARAM
+               : saveBinaryData(alias, DataType::CERTIFICATE, cert->getDER(), policy);
 }
 
-int Manager::ManagerImpl::removeData(const Alias &alias) {
-    return removeBinaryData(alias, DBDataType::BINARY_DATA);
+int Manager::Impl::saveData(const Alias &alias, const RawBuffer &rawData,
+                                                       const Policy &policy)
+{
+       return saveBinaryData(alias, DataType::BINARY_DATA, rawData, policy);
 }
 
-int Manager::ManagerImpl::getBinaryData(
-    const Alias &alias,
-    DBDataType sendDataType,
-    const RawData &password,
-    DBDataType &recvDataType,
-    RawData &rawData)
+
+int Manager::Impl::savePKCS12(
+       const Alias &alias,
+       const PKCS12ShPtr &pkcs,
+       const Policy &keyPolicy,
+       const Policy &certPolicy)
 {
-    return try_catch([&] {
-        if (alias.empty())
-            return KEY_MANAGER_API_ERROR_INPUT_PARAM;
+       if (alias.empty() || pkcs.get() == NULL)
+               return CKM_API_ERROR_INPUT_PARAM;
+
+       EXCEPTION_GUARD_START_CPPAPI
 
-        MessageBuffer send, recv;
-        Serialization::Serialize(send, static_cast<int>(LogicCommand::GET));
-        Serialization::Serialize(send, m_counter);
-        Serialization::Serialize(send, static_cast<int>(sendDataType));
-        Serialization::Serialize(send, alias);
-        Serialization::Serialize(send, password);
+       AliasSupport helper(alias);
 
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
+       return Request(*this, LogicCommand::SAVE_PKCS12, m_storageConnection,
+                       helper.getName(), helper.getOwner(), PKCS12Serializable(*pkcs.get()),
+                       PolicySerializable(keyPolicy), PolicySerializable(certPolicy)
+               ).maybeDeserialize();
 
-        if (KEY_MANAGER_API_SUCCESS != retCode) {
-            return retCode;
-        }
+       EXCEPTION_GUARD_END
+}
 
-        int command;
-        int counter;
-        Deserialization::Deserialize(recv, command);
-        Deserialization::Deserialize(recv, counter);
-        Deserialization::Deserialize(recv, retCode);
+int Manager::Impl::getPKCS12(const Alias &alias, PKCS12ShPtr &pkcs)
+{
+       return getPKCS12(alias, Password(), Password(), pkcs);
+}
 
-        if (retCode == KEY_MANAGER_API_SUCCESS) {
-            int tmpDataType;
-            Deserialization::Deserialize(recv, tmpDataType);
-            Deserialization::Deserialize(recv, rawData);
-            recvDataType = static_cast<DBDataType>(tmpDataType);
-        }
+int Manager::Impl::getPKCS12(const Alias &alias, const Password &keyPass,
+                                                        const Password &certPass, PKCS12ShPtr &pkcs)
+{
+       if (alias.empty())
+               return CKM_API_ERROR_INPUT_PARAM;
 
-        if (counter != m_counter) {
-            return KEY_MANAGER_API_ERROR_UNKNOWN;
-        }
+       EXCEPTION_GUARD_START_CPPAPI
 
-        return retCode;
-    });
+       AliasSupport helper(alias);
+
+       int msgId = ++m_counter;
+       MessageBuffer recv;
+
+       int retCode = doRequest(recv, m_storageConnection, LogicCommand::GET_PKCS12, msgId,
+                       helper.getName(), helper.getOwner(), keyPass, certPass);
+
+       if (CKM_API_SUCCESS != retCode)
+               return retCode;
+
+       int retMsgId;
+       PKCS12Serializable gotPkcs;
+       recv.Deserialize(retMsgId, retCode, gotPkcs);
+
+       if (retMsgId != msgId)
+               return CKM_API_ERROR_UNKNOWN;
+
+       pkcs = std::make_shared<PKCS12Impl>(std::move(gotPkcs));
+
+       return retCode;
+
+       EXCEPTION_GUARD_END
 }
 
-int Manager::ManagerImpl::getKey(const Alias &alias, const RawData &password, Key &key) {
-    DBDataType recvDataType;
-    RawData rawData;
 
-    int retCode = getBinaryData(
-        alias,
-        DBDataType::KEY_RSA_PUBLIC,
-        password,
-        recvDataType,
-        rawData);
+int Manager::Impl::removeAlias(const Alias &alias)
+{
+       if (alias.empty())
+               return CKM_API_ERROR_INPUT_PARAM;
+
+       EXCEPTION_GUARD_START_CPPAPI
+
+       AliasSupport helper(alias);
+
+       return Request(*this, LogicCommand::REMOVE, m_storageConnection,
+                       helper.getName(), helper.getOwner()
+               ).maybeDeserialize();
 
-    if (retCode != KEY_MANAGER_API_SUCCESS)
-        return retCode;
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::getBinaryData(
+       const Alias &alias,
+       DataType sendDataType,
+       const Password &password,
+       DataType &recvDataType,
+       RawBuffer &rawData)
+{
+       if (alias.empty())
+               return CKM_API_ERROR_INPUT_PARAM;
 
-    Key keyParsed(rawData, toKeyType(recvDataType));
+       EXCEPTION_GUARD_START_CPPAPI
 
-    if (keyParsed.empty())
-        return KEY_MANAGER_API_ERROR_BAD_RESPONSE;
+       AliasSupport helper(alias);
 
-    key = keyParsed;
+       return Request(*this, LogicCommand::GET, m_storageConnection,
+                       sendDataType, helper.getName(), helper.getOwner(), password
+               ).maybeDeserialize(recvDataType, rawData);
 
-    return KEY_MANAGER_API_SUCCESS;
+       EXCEPTION_GUARD_END
 }
 
-int Manager::ManagerImpl::getCertificate(const Alias &alias, const RawData &password, Certificate &cert)
+int Manager::Impl::getBinaryDataEncryptionStatus(const DataType sendDataType,
+                                               const Alias &alias, bool &status)
 {
-    DBDataType recvDataType;
-    RawData rawData;
+       status = false;
+       if (alias.empty())
+               return CKM_API_ERROR_INPUT_PARAM;
+
+       EXCEPTION_GUARD_START_CPPAPI
+
+       AliasSupport helper(alias);
+       DataType tmpDataType;
+
+       int retCode = Request(*this, LogicCommand::GET_PROTECTION_STATUS, m_storageConnection,
+                       sendDataType, helper.getName(), helper.getOwner()
+               ).maybeDeserialize(tmpDataType, status);
 
-    int retCode = getBinaryData(
-        alias,
-        DBDataType::CERTIFICATE,
-        password,
-        recvDataType,
-        rawData);
+       if (retCode != CKM_API_SUCCESS)
+               status = false;
 
-    if (retCode != KEY_MANAGER_API_SUCCESS)
-        return retCode;
+       return retCode;
 
-    if (recvDataType != DBDataType::CERTIFICATE)
-        return KEY_MANAGER_API_ERROR_BAD_RESPONSE;
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::getKey(const Alias &alias, const Password &password,
+                                                 KeyShPtr &key)
+{
+       DataType recvDataType;
+       RawBuffer rawData;
 
-    Certificate certParsed(rawData, Certificate::Format::FORM_DER);
+       int retCode = getBinaryData(alias, DataType::KEY_RSA_PUBLIC, password, recvDataType, rawData);
 
-    if (certParsed.empty())
-        return KEY_MANAGER_API_ERROR_BAD_RESPONSE;
+       if (retCode != CKM_API_SUCCESS)
+               return retCode;
 
-    cert = certParsed;
+       KeyShPtr keyParsed = recvDataType.isSymmetricKey() ? Key::createAES(rawData) : Key::create(rawData);
 
-    return KEY_MANAGER_API_SUCCESS;
+       if (!keyParsed) {
+               LogDebug("Key empty - failed to parse!");
+               return CKM_API_ERROR_BAD_RESPONSE;
+       }
+
+       key = keyParsed;
+
+       return CKM_API_SUCCESS;
 }
 
-int Manager::ManagerImpl::getData(const Alias &alias, const RawData &password, RawData &rawData)
+int Manager::Impl::getCertificate(const Alias &alias, const Password &password,
+                                                                 CertificateShPtr &cert)
 {
-    DBDataType recvDataType;
+       DataType recvDataType;
+       RawBuffer rawData;
+
+       int retCode = getBinaryData(alias, DataType::CERTIFICATE, password, recvDataType, rawData);
 
-    int retCode = getBinaryData(
-        alias,
-        DBDataType::CERTIFICATE,
-        password,
-        recvDataType,
-        rawData);
+       if (retCode != CKM_API_SUCCESS)
+               return retCode;
 
-    if (retCode != KEY_MANAGER_API_SUCCESS)
-        return retCode;
+       if (!recvDataType.isCertificate())
+               return CKM_API_ERROR_BAD_RESPONSE;
 
-    if (recvDataType != DBDataType::BINARY_DATA)
-        return KEY_MANAGER_API_ERROR_BAD_RESPONSE;
+       CertificateShPtr certParsed(new CertificateImpl(rawData, DataFormat::FORM_DER));
 
-    return KEY_MANAGER_API_SUCCESS;
+       if (certParsed->empty())
+               return CKM_API_ERROR_BAD_RESPONSE;
+
+       cert = std::move(certParsed);
+
+       return CKM_API_SUCCESS;
 }
 
-} // namespace CKM
+int Manager::Impl::getData(const Alias &alias, const Password &password,
+                                                  RawBuffer &rawData)
+{
+       DataType recvDataType = DataType::BINARY_DATA;
+
+       int retCode = getBinaryData(alias, DataType::BINARY_DATA, password, recvDataType, rawData);
+
+       if (retCode != CKM_API_SUCCESS)
+               return retCode;
+
+       return recvDataType.isBinaryData() ? CKM_API_SUCCESS : CKM_API_ERROR_BAD_RESPONSE;
+}
+
+int Manager::Impl::getAliasInfoVectorHelper(DataType dataType, AliasInfoVector &aliasInfoVector)
+{
+       DataType tmpDataType;
+       AliasInfoSerializableVector aisv(aliasInfoVector);
+       return Request(*this,
+                      LogicCommand::GET_LIST,
+                      m_storageConnection,
+                      dataType).maybeDeserialize(tmpDataType, aisv);
+}
+
+int Manager::Impl::getAliasVectorHelper(DataType dataType, AliasVector &aliasVector)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+       AliasInfoVector aliasInfoVector;
+       int retCode = getAliasInfoVectorHelper(dataType, aliasInfoVector);
+
+       if (retCode != CKM_API_SUCCESS)
+               return retCode;
+
+       for (const auto &it : aliasInfoVector)
+               aliasVector.push_back(it.alias);
+
+       return CKM_API_SUCCESS;
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::getKeyAliasVector(AliasVector &aliasVector)
+{
+       // in fact datatype has no meaning here - if not certificate or binary data
+       // then manager decides to list all between DB_KEY_FIRST and DB_KEY_LAST
+       return getAliasVectorHelper(DataType::DB_KEY_LAST, aliasVector);
+}
+
+int Manager::Impl::getCertificateAliasVector(AliasVector &aliasVector)
+{
+       return getAliasVectorHelper(DataType::CERTIFICATE, aliasVector);
+}
+
+int Manager::Impl::getDataAliasVector(AliasVector &aliasVector)
+{
+       return getAliasVectorHelper(DataType::BINARY_DATA, aliasVector);
+}
+
+int Manager::Impl::getKeyAliasInfoVector(AliasInfoVector &aliasInfoVector)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+       return getAliasInfoVectorHelper(DataType::DB_KEY_LAST, aliasInfoVector);
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::getKeyEncryptionStatus(const Alias &alias, bool &status)
+{
+       return getBinaryDataEncryptionStatus(DataType::DB_KEY_LAST, alias, status);
+}
+
+int Manager::Impl::getCertificateAliasInfoVector(AliasInfoVector &aliasInfoVector)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+       return getAliasInfoVectorHelper(DataType::CERTIFICATE, aliasInfoVector);
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::getCertificateEncryptionStatus(const Alias &alias, bool &status)
+{
+       return getBinaryDataEncryptionStatus(DataType::CERTIFICATE, alias, status);
+}
+
+int Manager::Impl::getDataAliasInfoVector(AliasInfoVector &aliasInfoVector)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+       return getAliasInfoVectorHelper(DataType::BINARY_DATA, aliasInfoVector);
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::getDataEncryptionStatus(const Alias &alias, bool &status)
+{
+       return getBinaryDataEncryptionStatus(DataType::BINARY_DATA, alias, status);
+}
+
+int Manager::Impl::createKeyPairRSA(
+       const int size,
+       const Alias &privateKeyAlias,
+       const Alias &publicKeyAlias,
+       const Policy &policyPrivateKey,
+       const Policy &policyPublicKey)
+{
+       return this->createKeyPair(CKM::KeyType::KEY_RSA_PUBLIC, size, privateKeyAlias,
+                                                          publicKeyAlias, policyPrivateKey, policyPublicKey);
+}
+
+int Manager::Impl::createKeyPairDSA(
+       const int size,
+       const Alias &privateKeyAlias,
+       const Alias &publicKeyAlias,
+       const Policy &policyPrivateKey,
+       const Policy &policyPublicKey)
+{
+       return this->createKeyPair(CKM::KeyType::KEY_DSA_PUBLIC, size, privateKeyAlias,
+                                                          publicKeyAlias, policyPrivateKey, policyPublicKey);
+}
+
+int Manager::Impl::createKeyPairECDSA(
+       ElipticCurve type,
+       const Alias &privateKeyAlias,
+       const Alias &publicKeyAlias,
+       const Policy &policyPrivateKey,
+       const Policy &policyPublicKey)
+{
+       return this->createKeyPair(CKM::KeyType::KEY_ECDSA_PUBLIC,
+                                                          static_cast<int>(type), privateKeyAlias, publicKeyAlias,
+                                                          policyPrivateKey, policyPublicKey);
+}
+
+int Manager::Impl::createKeyAES(
+       const int size,
+       const Alias &keyAlias,
+       const Policy &policyKey)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+
+       AliasSupport aliasHelper(keyAlias);
+
+       return Request(*this, LogicCommand::CREATE_KEY_AES, m_storageConnection,
+                       size, PolicySerializable(policyKey),
+                       aliasHelper.getName(), aliasHelper.getOwner()
+               ).maybeDeserialize();
+
+       EXCEPTION_GUARD_END
+}
+
+
+int Manager::Impl::createKeyPair(
+       const KeyType key_type,
+       const int     additional_param,
+       const Alias  &privateKeyAlias,
+       const Alias  &publicKeyAlias,
+       const Policy &policyPrivateKey,
+       const Policy &policyPublicKey)
+{
+       // input type check
+       CryptoAlgorithm keyGenAlgorithm;
+
+       switch (key_type) {
+       case KeyType::KEY_RSA_PUBLIC:
+       case KeyType::KEY_RSA_PRIVATE:
+               keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_GEN);
+               keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, additional_param);
+               break;
+
+       case KeyType::KEY_DSA_PUBLIC:
+       case KeyType::KEY_DSA_PRIVATE:
+               keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::DSA_GEN);
+               keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, additional_param);
+               break;
+
+       case KeyType::KEY_ECDSA_PUBLIC:
+       case KeyType::KEY_ECDSA_PRIVATE:
+               keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN);
+               keyGenAlgorithm.setParam(ParamName::GEN_EC, additional_param);
+               break;
+
+       default:
+               return CKM_API_ERROR_INPUT_PARAM;
+       }
+
+       EXCEPTION_GUARD_START_CPPAPI
+
+       AliasSupport privateHelper(privateKeyAlias);
+       AliasSupport publicHelper(publicKeyAlias);
+
+       return Request(*this, LogicCommand::CREATE_KEY_PAIR, m_storageConnection,
+                       CryptoAlgorithmSerializable(keyGenAlgorithm),
+                       PolicySerializable(policyPrivateKey),
+                       PolicySerializable(policyPublicKey),
+                       privateHelper.getName(), privateHelper.getOwner(),
+                       publicHelper.getName(), publicHelper.getOwner()
+               ).maybeDeserialize();
+
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::getCertificateChain(
+       const CertificateShPtr &certificate,
+       const CertificateShPtrVector &untrustedCertificates,
+       const CertificateShPtrVector &trustedCertificates,
+       bool useTrustedSystemCertificates,
+       CertificateShPtrVector &certificateChainVector)
+{
+       RawBufferVector untrustedVector;
+       RawBufferVector trustedVector;
+
+       if (!certificate || certificate->empty())
+               return CKM_API_ERROR_INPUT_PARAM;
+
+       for (auto &e : untrustedCertificates) {
+               if (!e || e->empty())
+                       return CKM_API_ERROR_INPUT_PARAM;
+               untrustedVector.push_back(e->getDER());
+       }
+
+       for (auto &e : trustedCertificates) {
+               if (!e || e->empty())
+                       return CKM_API_ERROR_INPUT_PARAM;
+               trustedVector.push_back(e->getDER());
+       }
+
+       return getCertChain(m_storageConnection, LogicCommand::GET_CHAIN_CERT, *this,
+                           certificate, untrustedVector, trustedVector,
+                           useTrustedSystemCertificates, certificateChainVector);
+}
+
+int Manager::Impl::getCertificateChain(
+       const CertificateShPtr &certificate,
+       const AliasVector &untrustedCertificates,
+       const AliasVector &trustedCertificates,
+       bool useTrustedSystemCertificates,
+       CertificateShPtrVector &certificateChainVector)
+{
+       OwnerNameVector untrustedVector;
+       OwnerNameVector trustedVector;
+
+       if (!certificate || certificate->empty())
+               return CKM_API_ERROR_INPUT_PARAM;
+
+       for (auto &e : untrustedCertificates) {
+               AliasSupport helper(e);
+               untrustedVector.push_back(std::make_pair(helper.getOwner(), helper.getName()));
+       }
+
+       for (auto &e : trustedCertificates) {
+               AliasSupport helper(e);
+               trustedVector.push_back(std::make_pair(helper.getOwner(), helper.getName()));
+       }
+
+       return getCertChain(m_storageConnection, LogicCommand::GET_CHAIN_ALIAS, *this,
+                           certificate, untrustedVector, trustedVector,
+                           useTrustedSystemCertificates, certificateChainVector);
+}
 
+int Manager::Impl::createSignature(
+       const Alias &privateKeyAlias,
+       const Password &password,           // password for private_key
+       const RawBuffer &message,
+       const CryptoAlgorithm &cAlgorithm,
+       RawBuffer &signature)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+
+       AliasSupport helper(privateKeyAlias);
+
+       return Request(*this, LogicCommand::CREATE_SIGNATURE, m_storageConnection,
+                       helper.getName(), helper.getOwner(), password, message,
+                       CryptoAlgorithmSerializable(cAlgorithm)
+               ).maybeDeserialize(signature);
+
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::verifySignature(
+       const Alias &publicKeyOrCertAlias,
+       const Password &password,           // password for public_key (optional)
+       const RawBuffer &message,
+       const RawBuffer &signature,
+       const CryptoAlgorithm &cAlg)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+
+       AliasSupport helper(publicKeyOrCertAlias);
+
+       return Request(*this, LogicCommand::VERIFY_SIGNATURE, m_storageConnection,
+                       helper.getName(), helper.getOwner(), password, message, signature,
+                       CryptoAlgorithmSerializable(cAlg)
+               ).maybeDeserialize();
+
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::ocspCheck(const CertificateShPtrVector &certChain,
+                                                        int &ocspStatus)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+
+       int msgId = ++m_counter;
+       MessageBuffer recv;
+
+       RawBufferVector rawCertChain;
+
+       for (auto &e : certChain) {
+               if (!e || e->empty()) {
+                       LogError("Empty certificate");
+                       return CKM_API_ERROR_INPUT_PARAM;
+               }
+
+               rawCertChain.push_back(e->getDER());
+       }
+
+       int retCode = doRequest(recv, m_ocspConnection, msgId, rawCertChain);
+
+       if (CKM_API_SUCCESS != retCode)
+               return retCode;
+
+       return deserializeResponse(msgId, recv, ocspStatus);
+
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::setPermission(const Alias &alias,
+                                                                const ClientId &accessor,
+                                                                PermissionMask permissionMask)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+
+       AliasSupport helper(alias);
+
+       return Request(*this, LogicCommand::SET_PERMISSION, m_storageConnection,
+                       helper.getName(), helper.getOwner(), accessor, permissionMask
+               ).maybeDeserialize();
+
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::crypt(EncryptionCommand command,
+                                                const CryptoAlgorithm &algo,
+                                                const Alias &keyAlias,
+                                                const Password &password,
+                                                const RawBuffer &input,
+                                                RawBuffer &output)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+
+       AliasSupport helper(keyAlias);
+       CryptoAlgorithmSerializable cas(algo);
+
+       return Request(*this, command, m_encryptionConnection,
+                       cas, helper.getName(), helper.getOwner(), password, input
+               ).maybeDeserialize(output);
+
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::encrypt(const CryptoAlgorithm &algo,
+                                                  const Alias &keyAlias,
+                                                  const Password &password,
+                                                  const RawBuffer &plain,
+                                                  RawBuffer &encrypted)
+{
+       return crypt(EncryptionCommand::ENCRYPT, algo, keyAlias, password, plain,
+                                encrypted);
+}
+
+int Manager::Impl::decrypt(const CryptoAlgorithm &algo,
+                                                  const Alias &keyAlias,
+                                                  const Password &password,
+                                                  const RawBuffer &encrypted,
+                                                  RawBuffer &decrypted)
+{
+       return crypt(EncryptionCommand::DECRYPT, algo, keyAlias, password, encrypted,
+                                decrypted);
+}
+
+int Manager::Impl::deriveKey(const CryptoAlgorithm &algo,
+                                                        const Alias &secretAlias,
+                                                        const Password &secretPassword,
+                                                        const Alias &newKeyAlias,
+                                                        const Policy &newKeyPolicy)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+
+       AliasSupport secret(secretAlias);
+       AliasSupport newKey(newKeyAlias);
+       CryptoAlgorithmSerializable cas(algo);
+
+       return Request(*this, LogicCommand::DERIVE, m_storageConnection,
+                       cas, secret.getName(), secret.getOwner(), secretPassword,
+                       newKey.getName(), newKey.getOwner(), PolicySerializable(newKeyPolicy)
+               ).maybeDeserialize();
+
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::importWrappedKey(const CryptoAlgorithm &params,
+                                                                       const Alias &wrappingKeyAlias,
+                                                                       const Password &wrappingKeyPassword,
+                                                                       const Alias &alias,
+                                                                       const RawBuffer &wrappedKey,
+                                                                       const KeyType keyType,
+                                                                       const Policy &policy)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+
+       if (keyType == KeyType::KEY_NONE)
+               return CKM_API_ERROR_INPUT_PARAM;
+
+       AliasSupport wrapping_helper(wrappingKeyAlias);
+       AliasSupport helper(alias);
+
+       return Request(*this,
+               LogicCommand::IMPORT_WRAPPED_KEY,
+               m_storageConnection,
+               CryptoAlgorithmSerializable(params),
+               wrapping_helper.getName(),
+               wrapping_helper.getOwner(),
+               wrappingKeyPassword,
+               helper.getName(),
+               helper.getOwner(),
+               wrappedKey,
+               DataType(keyType),
+               PolicySerializable(policy)
+       ).maybeDeserialize();
+
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::exportWrappedKey(const CryptoAlgorithm &params,
+                                                                       const Alias &wrappingKeyAlias,
+                                                                       const Password &wrappingKeyPassword,
+                                                                       const Alias &alias,
+                                                                       const Password &password,
+                                                                       KeyType &keyType,
+                                                                       RawBuffer &wrappedKey)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+
+       AliasSupport wrapping_helper(wrappingKeyAlias);
+       AliasSupport helper(alias);
+       DataType dataTypeKey;
+
+       int retCode = Request(*this,
+               LogicCommand::EXPORT_WRAPPED_KEY,
+               m_storageConnection,
+               CryptoAlgorithmSerializable(params),
+               wrapping_helper.getName(),
+               wrapping_helper.getOwner(),
+               wrappingKeyPassword,
+               helper.getName(),
+               helper.getOwner(),
+               password
+       ).maybeDeserialize(dataTypeKey, wrappedKey);
+
+       if (retCode != CKM_API_SUCCESS)
+               return retCode;
+
+       if (dataTypeKey.isSymmetricKey()) {
+               keyType = KeyType::KEY_AES;
+       } else if (dataTypeKey.isKeyPrivate()) {
+               keyType = KeyType::KEY_RSA_PRIVATE;
+       } else {
+               return CKM_API_ERROR_INVALID_FORMAT;
+       }
+
+       return retCode;
+
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::initializeCipher(
+       const CryptoAlgorithm &params,
+       const Alias &keyAlias,
+       const Password &keyPassword,
+       bool encrypt,
+       int &requestId)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+
+       AliasSupport helper(keyAlias);
+
+       return Request(*this,
+               EncryptionCommand::INITIALIZE_CIPHER,
+               m_encryptionConnection,
+               requestId,
+               CryptoAlgorithmSerializable(params),
+               helper.getName(),
+               helper.getOwner(),
+               keyPassword,
+               encrypt
+       ).maybeDeserialize(requestId);
+
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::updateCipher(int requestId, const RawBuffer &in, RawBuffer &out)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+
+       return Request(*this,
+               EncryptionCommand::UPDATE_CIPHER,
+               m_encryptionConnection,
+               requestId,
+               in
+       ).maybeDeserialize(out);
+
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::finalizeCipher(int requestId, const RawBuffer &in, RawBuffer &out)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+
+       return Request(*this,
+               EncryptionCommand::FINALIZE_CIPHER,
+               m_encryptionConnection,
+               requestId,
+               in
+       ).maybeDeserialize(out);
+
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::getBackendInfo(BackendId backend, BackendInfo& info)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+
+       BackendInfoSerializable bis(info);
+       return Request(*this,
+               LogicCommand::GET_BACKEND_INFO,
+               m_storageConnection,
+               backend
+       ).maybeDeserialize(bis);
+
+       EXCEPTION_GUARD_END
+}
+
+} // namespace CKM