Return proper error for wrong wrapped key type
[platform/core/security/key-manager.git] / src / manager / client / client-manager-impl.cpp
index fb66bcb..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.
 
 #include <client-manager-impl.h>
 #include <client-common.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 {
+
 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)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+
+       Manager::Impl::Request rq(impl, command, serviceConnection,
+                       certificate->getDER(), untrustedVector, trustedVector, useTrustedSystemCertificates);
+       if (!rq)
+               return rq.err();
+
+       RawBufferVector rawBufferVector;
+       int retCode = rq.deserialize(rawBufferVector);
 
-void clientInitialize(void) {
-    OpenSSL_add_all_ciphers();
-    OpenSSL_add_all_algorithms();
-    OpenSSL_add_all_digests();
+       if (retCode != CKM_API_SUCCESS)
+               return retCode;
+
+       for (auto &e : rawBufferVector) {
+               CertificateShPtr cert(new CertificateImpl(e, DataFormat::FORM_DER));
+
+               if (cert->empty())
+                       return CKM_API_ERROR_BAD_RESPONSE;
+
+               certificateChainVector.push_back(std::move(cert));
+       }
+
+       return retCode;
+
+       EXCEPTION_GUARD_END
 }
 
-} // namespace anonymous
+template <class...T>
+int doRequest(MessageBuffer &recv, CKM::ServiceConnection &conn, T&&...t)
+{
+       return conn.processRequest(SerializeMessage(std::forward<T>(t)...), recv);
+}
 
-namespace CKM {
+} // namespace
 
-bool ManagerImpl::s_isInit = false;
+Manager::Impl::Impl()
+       : m_storageConnection(SERVICE_SOCKET_CKM_STORAGE),
+         m_ocspConnection(SERVICE_SOCKET_OCSP),
+         m_encryptionConnection(SERVICE_SOCKET_ENCRYPTION)
+{
+}
 
-ManagerImpl::ManagerImpl()
-  : m_counter(0)
+template <class Cmd, class...T>
+Manager::Impl::Request::Request(Manager::Impl &impl, Cmd cmd, CKM::ServiceConnection &conn, T&&...t)
 {
-    // TODO secure with mutex
-    if (!s_isInit) {
-        s_isInit = true;
-        clientInitialize();
-    }
+       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::Impl::Request::err() const {
+       assert(!*this);
+       return m_retCode;
+}
 
-int ManagerImpl::saveBinaryData(
-    const Alias &alias,
-    DBDataType dataType,
-    const RawBuffer &rawData,
-    const Policy &policy)
+template <class...T>
+int Manager::Impl::Request::deserialize(T&&...t)
 {
-    m_counter++;
+       assert(*this);
+       return deserializeResponse(m_msgId, m_recv, std::forward<T>(t)...);
+}
 
-    return try_catch([&] {
-        if (alias.empty() || rawData.empty())
-            return CKM_API_ERROR_INPUT_PARAM;
+template <class...T>
+int Manager::Impl::Request::maybeDeserialize(T&&...t)
+{
+       return *this ? deserialize(std::forward<T>(t)...) : err();
+}
 
-        MessageBuffer recv;
-        auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
-                                             m_counter,
-                                             static_cast<int>(dataType),
-                                             alias,
-                                             rawData,
-                                             PolicySerializable(policy));
+int Manager::Impl::saveBinaryData(
+       const Alias &alias,
+       DataType dataType,
+       const RawBuffer &rawData,
+       const Policy &policy)
+{
+       EXCEPTION_GUARD_START_CPPAPI
 
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
+       if (alias.empty() || rawData.empty())
+               return CKM_API_ERROR_INPUT_PARAM;
 
-        if (CKM_API_SUCCESS != retCode) {
-            return retCode;
-        }
+       AliasSupport helper(alias);
 
-        int command;
-        int counter;
-        int opType;
-        recv.Deserialize(command, counter, retCode, opType);
+       int opType;
+       return Request(*this, LogicCommand::SAVE, m_storageConnection,
+                       dataType, helper.getName(), helper.getOwner(), rawData, PolicySerializable(policy)
+               ).maybeDeserialize(opType);
 
-        if (counter != m_counter) {
-            return CKM_API_ERROR_UNKNOWN;
-        }
+       EXCEPTION_GUARD_END
+}
 
-        return retCode;
-    });
+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 ManagerImpl::saveKey(const Alias &alias, const KeyShPtr &key, const Policy &policy) {
-    if (key.get() == NULL)
-        return CKM_API_ERROR_INPUT_PARAM;
-    return saveBinaryData(alias, toDBDataType(key->getType()), key->getDER(), policy);
+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 ManagerImpl::saveCertificate(
-    const Alias &alias,
-    const CertificateShPtr &cert,
-    const Policy &policy)
+int Manager::Impl::saveData(const Alias &alias, const RawBuffer &rawData,
+                                                       const Policy &policy)
 {
-    if (cert.get() == NULL)
-        return CKM_API_ERROR_INPUT_PARAM;
-    return saveBinaryData(alias, DBDataType::CERTIFICATE, cert->getDER(), policy);
+       return saveBinaryData(alias, DataType::BINARY_DATA, rawData, policy);
 }
 
-int ManagerImpl::saveData(const Alias &alias, const RawBuffer &rawData, const Policy &policy) {
-    if (!policy.extractable)
-        return CKM_API_ERROR_INPUT_PARAM;
-    return saveBinaryData(alias, DBDataType::BINARY_DATA, rawData, policy);
+
+int Manager::Impl::savePKCS12(
+       const Alias &alias,
+       const PKCS12ShPtr &pkcs,
+       const Policy &keyPolicy,
+       const Policy &certPolicy)
+{
+       if (alias.empty() || pkcs.get() == NULL)
+               return CKM_API_ERROR_INPUT_PARAM;
+
+       EXCEPTION_GUARD_START_CPPAPI
+
+       AliasSupport helper(alias);
+
+       return Request(*this, LogicCommand::SAVE_PKCS12, m_storageConnection,
+                       helper.getName(), helper.getOwner(), PKCS12Serializable(*pkcs.get()),
+                       PolicySerializable(keyPolicy), PolicySerializable(certPolicy)
+               ).maybeDeserialize();
+
+       EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::getPKCS12(const Alias &alias, PKCS12ShPtr &pkcs)
+{
+       return getPKCS12(alias, Password(), Password(), pkcs);
 }
 
-int ManagerImpl::removeBinaryData(const Alias &alias, DBDataType dataType)
+int Manager::Impl::getPKCS12(const Alias &alias, const Password &keyPass,
+                                                        const Password &certPass, PKCS12ShPtr &pkcs)
 {
-    return try_catch([&] {
-        if (alias.empty())
-            return CKM_API_ERROR_INPUT_PARAM;
+       if (alias.empty())
+               return CKM_API_ERROR_INPUT_PARAM;
 
-        MessageBuffer recv;
-        AliasSupport helper(alias);
-        auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
-                                             m_counter,
-                                             static_cast<int>(dataType),
-                                             helper.getName(),
-                                             helper.getLabel());
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
+       EXCEPTION_GUARD_START_CPPAPI
 
-        if (CKM_API_SUCCESS != retCode) {
-            return retCode;
-        }
+       AliasSupport helper(alias);
 
-        int command;
-        int counter;
-        int opType;
-        recv.Deserialize(command, counter, retCode, opType);
+       int msgId = ++m_counter;
+       MessageBuffer recv;
 
-        if (counter != m_counter) {
-            return CKM_API_ERROR_UNKNOWN;
-        }
+       int retCode = doRequest(recv, m_storageConnection, LogicCommand::GET_PKCS12, msgId,
+                       helper.getName(), helper.getOwner(), keyPass, certPass);
 
-        return retCode;
-    });
+       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 ManagerImpl::removeKey(const Alias &alias) {
-    return removeBinaryData(alias, DBDataType::KEY_RSA_PUBLIC);
+
+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();
+
+       EXCEPTION_GUARD_END
 }
 
-int ManagerImpl::removeCertificate(const Alias &alias) {
-    return removeBinaryData(alias, DBDataType::CERTIFICATE);
+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;
+
+       EXCEPTION_GUARD_START_CPPAPI
+
+       AliasSupport helper(alias);
+
+       return Request(*this, LogicCommand::GET, m_storageConnection,
+                       sendDataType, helper.getName(), helper.getOwner(), password
+               ).maybeDeserialize(recvDataType, rawData);
+
+       EXCEPTION_GUARD_END
 }
 
-int ManagerImpl::removeData(const Alias &alias) {
-    return removeBinaryData(alias, DBDataType::BINARY_DATA);
+int Manager::Impl::getBinaryDataEncryptionStatus(const DataType sendDataType,
+                                               const Alias &alias, bool &status)
+{
+       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);
+
+       if (retCode != CKM_API_SUCCESS)
+               status = false;
+
+       return retCode;
+
+       EXCEPTION_GUARD_END
 }
 
-int ManagerImpl::getBinaryData(
-    const Alias &alias,
-    DBDataType sendDataType,
-    const Password &password,
-    DBDataType &recvDataType,
-    RawBuffer &rawData)
+int Manager::Impl::getKey(const Alias &alias, const Password &password,
+                                                 KeyShPtr &key)
 {
-    return try_catch([&] {
-        if (alias.empty())
-            return CKM_API_ERROR_INPUT_PARAM;
+       DataType recvDataType;
+       RawBuffer rawData;
+
+       int retCode = getBinaryData(alias, DataType::KEY_RSA_PUBLIC, password, recvDataType, rawData);
 
-        MessageBuffer recv;
-        AliasSupport helper(alias);
-        auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
-                                             m_counter,
-                                             static_cast<int>(sendDataType),
-                                             helper.getName(),
-                                             helper.getLabel(),
-                                             password);
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
+       if (retCode != CKM_API_SUCCESS)
+               return retCode;
 
-        if (CKM_API_SUCCESS != retCode) {
-            return retCode;
-        }
+       KeyShPtr keyParsed = recvDataType.isSymmetricKey() ? Key::createAES(rawData) : Key::create(rawData);
 
-        int command;
-        int counter;
-        int tmpDataType;
-        recv.Deserialize(command, counter, retCode, tmpDataType,rawData);
-        recvDataType = static_cast<DBDataType>(tmpDataType);
+       if (!keyParsed) {
+               LogDebug("Key empty - failed to parse!");
+               return CKM_API_ERROR_BAD_RESPONSE;
+       }
 
-        if (counter != m_counter) {
-            return CKM_API_ERROR_UNKNOWN;
-        }
+       key = keyParsed;
 
-        return retCode;
-    });
+       return CKM_API_SUCCESS;
 }
 
-int ManagerImpl::getKey(const Alias &alias, const Password &password, KeyShPtr &key) {
-    DBDataType recvDataType;
-    RawBuffer rawData;
+int Manager::Impl::getCertificate(const Alias &alias, const Password &password,
+                                                                 CertificateShPtr &cert)
+{
+       DataType recvDataType;
+       RawBuffer rawData;
+
+       int retCode = getBinaryData(alias, DataType::CERTIFICATE, password, recvDataType, rawData);
 
-    int retCode = getBinaryData(
-        alias,
-        DBDataType::KEY_RSA_PUBLIC,
-        password,
-        recvDataType,
-        rawData);
+       if (retCode != CKM_API_SUCCESS)
+               return retCode;
 
-    if (retCode != CKM_API_SUCCESS)
-        return retCode;
+       if (!recvDataType.isCertificate())
+               return CKM_API_ERROR_BAD_RESPONSE;
 
-    KeyShPtr keyParsed(new KeyImpl(rawData));
+       CertificateShPtr certParsed(new CertificateImpl(rawData, DataFormat::FORM_DER));
 
-    if (keyParsed->empty()) {
-        LogDebug("Key empty - failed to parse!");
-        return CKM_API_ERROR_BAD_RESPONSE;
-    }
+       if (certParsed->empty())
+               return CKM_API_ERROR_BAD_RESPONSE;
 
-    key = keyParsed;
+       cert = std::move(certParsed);
 
-    return CKM_API_SUCCESS;
+       return CKM_API_SUCCESS;
 }
 
-int ManagerImpl::getCertificate(const Alias &alias, const Password &password, CertificateShPtr &cert)
+int Manager::Impl::getData(const Alias &alias, const Password &password,
+                                                  RawBuffer &rawData)
 {
-    DBDataType recvDataType;
-    RawBuffer rawData;
+       DataType recvDataType = DataType::BINARY_DATA;
 
-    int retCode = getBinaryData(
-        alias,
-        DBDataType::CERTIFICATE,
-        password,
-        recvDataType,
-        rawData);
+       int retCode = getBinaryData(alias, DataType::BINARY_DATA, password, recvDataType, rawData);
 
-    if (retCode != CKM_API_SUCCESS)
-        return retCode;
+       if (retCode != CKM_API_SUCCESS)
+               return retCode;
+
+       return recvDataType.isBinaryData() ? CKM_API_SUCCESS : CKM_API_ERROR_BAD_RESPONSE;
+}
 
-    if (recvDataType != DBDataType::CERTIFICATE)
-        return 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);
+}
 
-    CertificateShPtr certParsed(new CertificateImpl(rawData, DataFormat::FORM_DER));
+int Manager::Impl::getAliasVectorHelper(DataType dataType, AliasVector &aliasVector)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+       AliasInfoVector aliasInfoVector;
+       int retCode = getAliasInfoVectorHelper(dataType, aliasInfoVector);
 
-    if (certParsed->empty())
-        return CKM_API_ERROR_BAD_RESPONSE;
+       if (retCode != CKM_API_SUCCESS)
+               return retCode;
 
-    cert = certParsed;
+       for (const auto &it : aliasInfoVector)
+               aliasVector.push_back(it.alias);
 
-    return CKM_API_SUCCESS;
+       return CKM_API_SUCCESS;
+       EXCEPTION_GUARD_END
 }
 
-int ManagerImpl::getData(const Alias &alias, const Password &password, RawBuffer &rawData)
+int Manager::Impl::getKeyAliasVector(AliasVector &aliasVector)
 {
-    DBDataType recvDataType;
+       // 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 retCode = getBinaryData(
-        alias,
-        DBDataType::BINARY_DATA,
-        password,
-        recvDataType,
-        rawData);
+int Manager::Impl::getCertificateAliasVector(AliasVector &aliasVector)
+{
+       return getAliasVectorHelper(DataType::CERTIFICATE, aliasVector);
+}
 
-    if (retCode != CKM_API_SUCCESS)
-        return retCode;
+int Manager::Impl::getDataAliasVector(AliasVector &aliasVector)
+{
+       return getAliasVectorHelper(DataType::BINARY_DATA, aliasVector);
+}
 
-    if (recvDataType != DBDataType::BINARY_DATA)
-        return CKM_API_ERROR_BAD_RESPONSE;
+int Manager::Impl::getKeyAliasInfoVector(AliasInfoVector &aliasInfoVector)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+       return getAliasInfoVectorHelper(DataType::DB_KEY_LAST, aliasInfoVector);
+       EXCEPTION_GUARD_END
+}
 
-    return CKM_API_SUCCESS;
+int Manager::Impl::getKeyEncryptionStatus(const Alias &alias, bool &status)
+{
+       return getBinaryDataEncryptionStatus(DataType::DB_KEY_LAST, alias, status);
 }
 
-int ManagerImpl::getBinaryDataAliasVector(DBDataType dataType, AliasVector &aliasVector)
+int Manager::Impl::getCertificateAliasInfoVector(AliasInfoVector &aliasInfoVector)
 {
-    return try_catch([&] {
+       EXCEPTION_GUARD_START_CPPAPI
+       return getAliasInfoVectorHelper(DataType::CERTIFICATE, aliasInfoVector);
+       EXCEPTION_GUARD_END
+}
 
-        MessageBuffer recv;
-        auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
-                                             m_counter,
-                                             static_cast<int>(dataType));
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
+int Manager::Impl::getCertificateEncryptionStatus(const Alias &alias, bool &status)
+{
+       return getBinaryDataEncryptionStatus(DataType::CERTIFICATE, alias, status);
+}
 
-        if (CKM_API_SUCCESS != retCode) {
-            return retCode;
-        }
+int Manager::Impl::getDataAliasInfoVector(AliasInfoVector &aliasInfoVector)
+{
+       EXCEPTION_GUARD_START_CPPAPI
+       return getAliasInfoVectorHelper(DataType::BINARY_DATA, aliasInfoVector);
+       EXCEPTION_GUARD_END
+}
 
-        int command;
-        int counter;
-        int tmpDataType;
-        LabelNameVector labelNameVector;
-        recv.Deserialize(command, counter, retCode, tmpDataType, labelNameVector);
-        if ((command != static_cast<int>(LogicCommand::GET_LIST)) || (counter != m_counter)) {
-            return CKM_API_ERROR_UNKNOWN;
-        }
+int Manager::Impl::getDataEncryptionStatus(const Alias &alias, bool &status)
+{
+       return getBinaryDataEncryptionStatus(DataType::BINARY_DATA, alias, status);
+}
 
-        for(const auto &it : labelNameVector)
-            aliasVector.push_back( AliasSupport::merge(it.first, it.second) );
+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);
+}
 
-        return retCode;
-    });
+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 ManagerImpl::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 getBinaryDataAliasVector(DBDataType::DB_KEY_LAST, aliasVector);
+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 ManagerImpl::getCertificateAliasVector(AliasVector &aliasVector) {
-    return getBinaryDataAliasVector(DBDataType::CERTIFICATE, aliasVector);
+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 ManagerImpl::getDataAliasVector(AliasVector &aliasVector) {
-    return getBinaryDataAliasVector(DBDataType::BINARY_DATA, aliasVector);
+
+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 ManagerImpl::createKeyPairRSA(
-    const int size,
-    const Alias &privateKeyAlias,
-    const Alias &publicKeyAlias,
-    const Policy &policyPrivateKey,
-    const Policy &policyPublicKey)
+int Manager::Impl::getCertificateChain(
+       const CertificateShPtr &certificate,
+       const CertificateShPtrVector &untrustedCertificates,
+       const CertificateShPtrVector &trustedCertificates,
+       bool useTrustedSystemCertificates,
+       CertificateShPtrVector &certificateChainVector)
 {
-    return this->createKeyPair(CKM::KeyType::KEY_RSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
+       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 ManagerImpl::createKeyPairDSA(
-    const int size,
-    const Alias &privateKeyAlias,
-    const Alias &publicKeyAlias,
-    const Policy &policyPrivateKey,
-    const Policy &policyPublicKey)
+int Manager::Impl::getCertificateChain(
+       const CertificateShPtr &certificate,
+       const AliasVector &untrustedCertificates,
+       const AliasVector &trustedCertificates,
+       bool useTrustedSystemCertificates,
+       CertificateShPtrVector &certificateChainVector)
 {
-    return this->createKeyPair(CKM::KeyType::KEY_DSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
+       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 ManagerImpl::createKeyPairECDSA(
-    ElipticCurve type,
-    const Alias &privateKeyAlias,
-    const Alias &publicKeyAlias,
-    const Policy &policyPrivateKey,
-    const Policy &policyPublicKey)
+int Manager::Impl::verifySignature(
+       const Alias &publicKeyOrCertAlias,
+       const Password &password,           // password for public_key (optional)
+       const RawBuffer &message,
+       const RawBuffer &signature,
+       const CryptoAlgorithm &cAlg)
 {
-    return this->createKeyPair(CKM::KeyType::KEY_ECDSA_PUBLIC, static_cast<int>(type), privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
+       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 ManagerImpl::createKeyPair(
-    const KeyType key_type,
-    const int     additional_param,
-    const Alias  &privateKeyAlias,
-    const Alias  &publicKeyAlias,
-    const Policy &policyPrivateKey,
-    const Policy &policyPublicKey)
+int Manager::Impl::ocspCheck(const CertificateShPtrVector &certChain,
+                                                        int &ocspStatus)
 {
-    // input type check
-    LogicCommand cmd_type;
-    switch(key_type)
-    {
-        case KeyType::KEY_RSA_PUBLIC:
-        case KeyType::KEY_RSA_PRIVATE:
-            cmd_type = LogicCommand::CREATE_KEY_PAIR_RSA;
-            break;
+       EXCEPTION_GUARD_START_CPPAPI
 
-        case KeyType::KEY_DSA_PUBLIC:
-        case KeyType::KEY_DSA_PRIVATE:
-            cmd_type = LogicCommand::CREATE_KEY_PAIR_DSA;
-            break;
+       int msgId = ++m_counter;
+       MessageBuffer recv;
 
-        case KeyType::KEY_ECDSA_PUBLIC:
-        case KeyType::KEY_ECDSA_PRIVATE:
-            cmd_type = LogicCommand::CREATE_KEY_PAIR_ECDSA;
-            break;
+       RawBufferVector rawCertChain;
 
-        default:
-            return CKM_API_ERROR_INPUT_PARAM;
-    }
+       for (auto &e : certChain) {
+               if (!e || e->empty()) {
+                       LogError("Empty certificate");
+                       return CKM_API_ERROR_INPUT_PARAM;
+               }
 
-    // proceed with sending request
-    m_counter++;
-    int my_counter = m_counter;
-    return try_catch([&] {
+               rawCertChain.push_back(e->getDER());
+       }
 
-        MessageBuffer recv;
-        auto send = MessageBuffer::Serialize(static_cast<int>(cmd_type),
-                                             my_counter,
-                                             static_cast<int>(additional_param),
-                                             PolicySerializable(policyPrivateKey),
-                                             PolicySerializable(policyPublicKey),
-                                             privateKeyAlias,
-                                             publicKeyAlias);
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
+       int retCode = doRequest(recv, m_ocspConnection, msgId, rawCertChain);
 
-        if (CKM_API_SUCCESS != retCode) {
-            return retCode;
-        }
+       if (CKM_API_SUCCESS != retCode)
+               return retCode;
 
-        int command;
-        int counter;
-        recv.Deserialize(command, counter, retCode);
-        if (counter != my_counter) {
-            return CKM_API_ERROR_UNKNOWN;
-        }
+       return deserializeResponse(msgId, recv, ocspStatus);
 
-        return retCode;
-    });
+       EXCEPTION_GUARD_END
 }
 
+int Manager::Impl::setPermission(const Alias &alias,
+                                                                const ClientId &accessor,
+                                                                PermissionMask permissionMask)
+{
+       EXCEPTION_GUARD_START_CPPAPI
 
-template <class T>
-int getCertChain(
-    LogicCommand command,
-    int counter,
-    const CertificateShPtr &certificate,
-    const T &sendData,
-    CertificateShPtrVector &certificateChainVector)
-{
-    return try_catch([&] {
-
-        MessageBuffer recv;
-        auto send = MessageBuffer::Serialize(static_cast<int>(command),
-                                             counter,
-                                             certificate->getDER(),
-                                             sendData);
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
-
-        if (CKM_API_SUCCESS != retCode) {
-            return retCode;
-        }
-
-        int retCommand;
-        int retCounter;
-        RawBufferVector rawBufferVector;
-        recv.Deserialize(retCommand, retCounter, retCode, rawBufferVector);
-
-        if ((counter != retCounter) || (static_cast<int>(command) != retCommand)) {
-            return CKM_API_ERROR_UNKNOWN;
-        }
-
-        if (retCode != CKM_API_SUCCESS) {
-            return retCode;
-        }
-
-        for (auto &e: rawBufferVector) {
-            CertificateShPtr cert(new CertificateImpl(e, DataFormat::FORM_DER));
-            if (cert->empty())
-                return CKM_API_ERROR_BAD_RESPONSE;
-            certificateChainVector.push_back(cert);
-        }
-
-        return retCode;
-    });
-}
-
-
-int ManagerImpl::getCertificateChain(
-    const CertificateShPtr &certificate,
-    const CertificateShPtrVector &untrustedCertificates,
-    CertificateShPtrVector &certificateChainVector)
-{
-    RawBufferVector rawBufferVector;
-
-    for (auto &e: untrustedCertificates) {
-        rawBufferVector.push_back(e->getDER());
-    }
-
-    return getCertChain(
-        LogicCommand::GET_CHAIN_CERT,
-        ++m_counter,
-        certificate,
-        rawBufferVector,
-        certificateChainVector);
-}
-
-int ManagerImpl::getCertificateChain(
-    const CertificateShPtr &certificate,
-    const AliasVector &untrustedCertificates,
-    CertificateShPtrVector &certificateChainVector)
-{
-    return getCertChain(
-        LogicCommand::GET_CHAIN_ALIAS,
-        ++m_counter,
-        certificate,
-        untrustedCertificates,
-        certificateChainVector);
-}
-
-int ManagerImpl::createSignature(
-    const Alias &privateKeyAlias,
-    const Password &password,           // password for private_key
-    const RawBuffer &message,
-    const HashAlgorithm hash,
-    const RSAPaddingAlgorithm padding,
-    RawBuffer &signature)
-{
-    m_counter++;
-    int my_counter = m_counter;
-    return try_catch([&] {
-
-        MessageBuffer recv;
-        AliasSupport helper(privateKeyAlias);
-        auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
-                                             my_counter,
-                                             helper.getName(),
-                                             helper.getLabel(),
-                                             password,
-                                             message,
-                                             static_cast<int>(hash),
-                                             static_cast<int>(padding));
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
-
-        if (CKM_API_SUCCESS != retCode) {
-            return retCode;
-        }
-
-        int command;
-        int counter;
-
-        recv.Deserialize(command, counter, retCode, signature);
-
-        if ((command != static_cast<int>(LogicCommand::CREATE_SIGNATURE))
-            || (counter != my_counter))
-        {
-            return CKM_API_ERROR_UNKNOWN;
-        }
-
-        return retCode;
-    });
-}
-
-int ManagerImpl::verifySignature(
-    const Alias &publicKeyOrCertAlias,
-    const Password &password,           // password for public_key (optional)
-    const RawBuffer &message,
-    const RawBuffer &signature,
-    const HashAlgorithm hash,
-    const RSAPaddingAlgorithm padding)
-{
-    m_counter++;
-    int my_counter = m_counter;
-    return try_catch([&] {
-
-        MessageBuffer recv;
-        AliasSupport helper(publicKeyOrCertAlias);
-        auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
-                                             my_counter,
-                                             helper.getName(),
-                                             helper.getLabel(),
-                                             password,
-                                             message,
-                                             signature,
-                                             static_cast<int>(hash),
-                                             static_cast<int>(padding));
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
-
-        if (CKM_API_SUCCESS != retCode) {
-            return retCode;
-        }
-
-        int command;
-        int counter;
-
-        recv.Deserialize(command, counter, retCode);
-
-        if ((command != static_cast<int>(LogicCommand::VERIFY_SIGNATURE))
-            || (counter != my_counter))
-        {
-            return CKM_API_ERROR_UNKNOWN;
-        }
-
-        return retCode;
-    });
-}
-
-int ManagerImpl::ocspCheck(const CertificateShPtrVector &certChain, int &ocspStatus)
-{
-    return try_catch([&] {
-        int my_counter = ++m_counter;
-        MessageBuffer recv;
-
-        RawBufferVector rawCertChain;
-        for (auto &e: certChain) {
-            rawCertChain.push_back(e->getDER());
-        }
-
-        auto send = MessageBuffer::Serialize(my_counter, rawCertChain);
-
-        int retCode = sendToServer(
-            SERVICE_SOCKET_OCSP,
-            send.Pop(),
-            recv);
-
-        if (CKM_API_SUCCESS != retCode) {
-            return retCode;
-        }
-
-        int counter;
-
-        recv.Deserialize(counter, retCode, ocspStatus);
-
-        if (my_counter != counter) {
-            return CKM_API_ERROR_UNKNOWN;
-        }
-
-        return retCode;
-    });
-}
-
-int ManagerImpl::allowAccess(const Alias &alias,
-                             const Label &accessor,
-                             AccessRight granted)
-{
-    m_counter++;
-    int my_counter = m_counter;
-    return try_catch([&] {
-        MessageBuffer recv;
-        auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::ALLOW_ACCESS),
-                                             my_counter,
-                                             alias,
-                                             accessor,
-                                             static_cast<int>(granted));
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
-
-        if (CKM_API_SUCCESS != retCode) {
-            return retCode;
-        }
-
-        int command;
-        int counter;
-        recv.Deserialize(command, counter, retCode);
-
-        if (my_counter != counter) {
-            return CKM_API_ERROR_UNKNOWN;
-        }
-
-        return retCode;
-    });
-}
-
-int ManagerImpl::denyAccess(const Alias &alias, const Label &accessor)
-{
-    m_counter++;
-    int my_counter = m_counter;
-    return try_catch([&] {
-        MessageBuffer recv;
-        auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::DENY_ACCESS),
-                                             my_counter,
-                                             alias,
-                                             accessor);
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
+       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);
 
-        if (CKM_API_SUCCESS != retCode) {
-            return retCode;
-        }
+       EXCEPTION_GUARD_END
+}
 
-        int command;
-        int counter;
-        recv.Deserialize(command, counter, retCode);
-
-        if (my_counter != counter) {
-            return CKM_API_ERROR_UNKNOWN;
-        }
+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);
+}
 
-        return retCode;
-    });
+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);
 }
 
-ManagerShPtr Manager::create() {
-    try {
-        return std::make_shared<ManagerImpl>();
-    } catch (const std::bad_alloc &) {
-        LogDebug("Bad alloc was caught during ManagerImpl creation.");
-    } catch (...) {
-        LogError("Critical error: Unknown exception was caught during ManagerImpl creation!");
-    }
-    return ManagerShPtr();
+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