Return proper error for wrong wrapped key type
[platform/core/security/key-manager.git] / src / manager / client / client-manager-impl.cpp
index 7a81943..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.
@@ -23,7 +23,6 @@
 #include <dpl/serialization.h>
 #include <dpl/log/log.h>
 
-#include <crypto-init.h>
 #include <client-manager-impl.h>
 #include <client-common.h>
 #include <exception.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,
-       int counter,
+       Manager::Impl &impl,
        const CertificateShPtr &certificate,
        const T &untrustedVector,
        const T &trustedVector,
@@ -49,26 +56,13 @@ int getCertChain(
 {
        EXCEPTION_GUARD_START_CPPAPI
 
-       MessageBuffer recv;
-       auto send = MessageBuffer::Serialize(static_cast<int>(command),
-                                                                                counter,
-                                                                                certificate->getDER(),
-                                                                                untrustedVector,
-                                                                                trustedVector,
-                                                                                useTrustedSystemCertificates);
-
-       int retCode = serviceConnection.processRequest(send.Pop(), recv);
-
-       if (CKM_API_SUCCESS != retCode)
-               return retCode;
+       Manager::Impl::Request rq(impl, command, serviceConnection,
+                       certificate->getDER(), untrustedVector, trustedVector, useTrustedSystemCertificates);
+       if (!rq)
+               return rq.err();
 
-       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;
+       int retCode = rq.deserialize(rawBufferVector);
 
        if (retCode != CKM_API_SUCCESS)
                return retCode;
@@ -79,7 +73,7 @@ int getCertChain(
                if (cert->empty())
                        return CKM_API_ERROR_BAD_RESPONSE;
 
-               certificateChainVector.push_back(cert);
+               certificateChainVector.push_back(std::move(cert));
        }
 
        return retCode;
@@ -87,17 +81,50 @@ int getCertChain(
        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
 
 Manager::Impl::Impl()
-       : m_counter(0),
-         m_storageConnection(SERVICE_SOCKET_CKM_STORAGE),
+       : m_storageConnection(SERVICE_SOCKET_CKM_STORAGE),
          m_ocspConnection(SERVICE_SOCKET_OCSP),
          m_encryptionConnection(SERVICE_SOCKET_ENCRYPTION)
 {
-       initOpenSslOnce();
 }
 
+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::Impl::Request::err() const {
+       assert(!*this);
+       return m_retCode;
+}
+
+template <class...T>
+int Manager::Impl::Request::deserialize(T&&...t)
+{
+       assert(*this);
+       return deserializeResponse(m_msgId, m_recv, std::forward<T>(t)...);
+}
+
+template <class...T>
+int Manager::Impl::Request::maybeDeserialize(T&&...t)
+{
+       return *this ? deserialize(std::forward<T>(t)...) : err();
+}
 
 int Manager::Impl::saveBinaryData(
        const Alias &alias,
@@ -105,37 +132,17 @@ int Manager::Impl::saveBinaryData(
        const RawBuffer &rawData,
        const Policy &policy)
 {
-       int my_counter = ++m_counter;
-
        EXCEPTION_GUARD_START_CPPAPI
 
        if (alias.empty() || rawData.empty())
                return CKM_API_ERROR_INPUT_PARAM;
 
-       MessageBuffer recv;
        AliasSupport helper(alias);
-       auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
-                                                                                my_counter,
-                                                                                static_cast<int>(dataType),
-                                                                                helper.getName(),
-                                                                                helper.getOwner(),
-                                                                                rawData,
-                                                                                PolicySerializable(policy));
-
-       int retCode = m_storageConnection.processRequest(send.Pop(), recv);
 
-       if (CKM_API_SUCCESS != retCode)
-               return retCode;
-
-       int command;
-       int counter;
        int opType;
-       recv.Deserialize(command, counter, retCode, opType);
-
-       if (counter != my_counter)
-               return CKM_API_ERROR_UNKNOWN;
-
-       return retCode;
+       return Request(*this, LogicCommand::SAVE, m_storageConnection,
+                       dataType, helper.getName(), helper.getOwner(), rawData, PolicySerializable(policy)
+               ).maybeDeserialize(opType);
 
        EXCEPTION_GUARD_END
 }
@@ -145,7 +152,6 @@ int Manager::Impl::saveKey(const Alias &alias, const KeyShPtr &key,
 {
        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) {
@@ -159,18 +165,14 @@ int Manager::Impl::saveCertificate(
        const CertificateShPtr &cert,
        const Policy &policy)
 {
-       if (cert.get() == NULL || cert->empty())
-               return CKM_API_ERROR_INPUT_PARAM;
-
-       return saveBinaryData(alias, DataType::CERTIFICATE, cert->getDER(), policy);
+       return cert.get() == NULL || cert->empty()
+               ? CKM_API_ERROR_INPUT_PARAM
+               : saveBinaryData(alias, DataType::CERTIFICATE, cert->getDER(), policy);
 }
 
 int Manager::Impl::saveData(const Alias &alias, const RawBuffer &rawData,
                                                        const Policy &policy)
 {
-       if (!policy.extractable)
-               return CKM_API_ERROR_INPUT_PARAM;
-
        return saveBinaryData(alias, DataType::BINARY_DATA, rawData, policy);
 }
 
@@ -184,34 +186,14 @@ int Manager::Impl::savePKCS12(
        if (alias.empty() || pkcs.get() == NULL)
                return CKM_API_ERROR_INPUT_PARAM;
 
-       int my_counter = ++m_counter;
-
        EXCEPTION_GUARD_START_CPPAPI
 
-       MessageBuffer recv;
        AliasSupport helper(alias);
-       auto send = MessageBuffer::Serialize(static_cast<int>
-                                                                                (LogicCommand::SAVE_PKCS12),
-                                                                                my_counter,
-                                                                                helper.getName(),
-                                                                                helper.getOwner(),
-                                                                                PKCS12Serializable(*pkcs.get()),
-                                                                                PolicySerializable(keyPolicy),
-                                                                                PolicySerializable(certPolicy));
-
-       int retCode = m_storageConnection.processRequest(send.Pop(), recv);
-
-       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 retCode;
+       return Request(*this, LogicCommand::SAVE_PKCS12, m_storageConnection,
+                       helper.getName(), helper.getOwner(), PKCS12Serializable(*pkcs.get()),
+                       PolicySerializable(keyPolicy), PolicySerializable(certPolicy)
+               ).maybeDeserialize();
 
        EXCEPTION_GUARD_END
 }
@@ -227,30 +209,24 @@ int Manager::Impl::getPKCS12(const Alias &alias, const Password &keyPass,
        if (alias.empty())
                return CKM_API_ERROR_INPUT_PARAM;
 
-       int my_counter = ++m_counter;
-
        EXCEPTION_GUARD_START_CPPAPI
 
-       MessageBuffer recv;
        AliasSupport helper(alias);
-       auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12),
-                                                                                my_counter,
-                                                                                helper.getName(),
-                                                                                helper.getOwner(),
-                                                                                keyPass,
-                                                                                certPass);
 
-       int retCode = m_storageConnection.processRequest(send.Pop(), recv);
+       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 command;
-       int counter;
+       int retMsgId;
        PKCS12Serializable gotPkcs;
-       recv.Deserialize(command, counter, retCode, gotPkcs);
+       recv.Deserialize(retMsgId, retCode, gotPkcs);
 
-       if (counter != my_counter)
+       if (retMsgId != msgId)
                return CKM_API_ERROR_UNKNOWN;
 
        pkcs = std::make_shared<PKCS12Impl>(std::move(gotPkcs));
@@ -266,30 +242,13 @@ int Manager::Impl::removeAlias(const Alias &alias)
        if (alias.empty())
                return CKM_API_ERROR_INPUT_PARAM;
 
-       int my_counter = ++m_counter;
-
        EXCEPTION_GUARD_START_CPPAPI
 
-       MessageBuffer recv;
        AliasSupport helper(alias);
-       auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
-                                                                                my_counter,
-                                                                                helper.getName(),
-                                                                                helper.getOwner());
 
-       int retCode = m_storageConnection.processRequest(send.Pop(), recv);
-
-       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 retCode;
+       return Request(*this, LogicCommand::REMOVE, m_storageConnection,
+                       helper.getName(), helper.getOwner()
+               ).maybeDeserialize();
 
        EXCEPTION_GUARD_END
 }
@@ -304,32 +263,35 @@ int Manager::Impl::getBinaryData(
        if (alias.empty())
                return CKM_API_ERROR_INPUT_PARAM;
 
-       int my_counter = ++m_counter;
-
        EXCEPTION_GUARD_START_CPPAPI
 
-       MessageBuffer recv;
        AliasSupport helper(alias);
-       auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
-                                                                                my_counter,
-                                                                                static_cast<int>(sendDataType),
-                                                                                helper.getName(),
-                                                                                helper.getOwner(),
-                                                                                password);
 
-       int retCode = m_storageConnection.processRequest(send.Pop(), recv);
+       return Request(*this, LogicCommand::GET, m_storageConnection,
+                       sendDataType, helper.getName(), helper.getOwner(), password
+               ).maybeDeserialize(recvDataType, rawData);
 
-       if (CKM_API_SUCCESS != retCode)
-               return retCode;
+       EXCEPTION_GUARD_END
+}
+
+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
 
-       int command;
-       int counter;
-       int tmpDataType;
-       recv.Deserialize(command, counter, retCode, tmpDataType, rawData);
-       recvDataType = DataType(tmpDataType);
+       AliasSupport helper(alias);
+       DataType tmpDataType;
 
-       if (counter != my_counter)
-               return CKM_API_ERROR_UNKNOWN;
+       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;
 
@@ -342,24 +304,14 @@ int Manager::Impl::getKey(const Alias &alias, const Password &password,
        DataType recvDataType;
        RawBuffer rawData;
 
-       int retCode = getBinaryData(
-                                         alias,
-                                         DataType::KEY_RSA_PUBLIC,
-                                         password,
-                                         recvDataType,
-                                         rawData);
+       int retCode = getBinaryData(alias, DataType::KEY_RSA_PUBLIC, password, recvDataType, rawData);
 
        if (retCode != CKM_API_SUCCESS)
                return retCode;
 
-       KeyShPtr keyParsed;
-
-       if (DataType::KEY_AES == recvDataType)
-               keyParsed = KeyShPtr(new KeyAESImpl(rawData));
-       else
-               keyParsed = KeyShPtr(new KeyImpl(rawData));
+       KeyShPtr keyParsed = recvDataType.isSymmetricKey() ? Key::createAES(rawData) : Key::create(rawData);
 
-       if (keyParsed->empty()) {
+       if (!keyParsed) {
                LogDebug("Key empty - failed to parse!");
                return CKM_API_ERROR_BAD_RESPONSE;
        }
@@ -375,17 +327,12 @@ int Manager::Impl::getCertificate(const Alias &alias, const Password &password,
        DataType recvDataType;
        RawBuffer rawData;
 
-       int retCode = getBinaryData(
-                                         alias,
-                                         DataType::CERTIFICATE,
-                                         password,
-                                         recvDataType,
-                                         rawData);
+       int retCode = getBinaryData(alias, DataType::CERTIFICATE, password, recvDataType, rawData);
 
        if (retCode != CKM_API_SUCCESS)
                return retCode;
 
-       if (recvDataType != DataType::CERTIFICATE)
+       if (!recvDataType.isCertificate())
                return CKM_API_ERROR_BAD_RESPONSE;
 
        CertificateShPtr certParsed(new CertificateImpl(rawData, DataFormat::FORM_DER));
@@ -393,7 +340,7 @@ int Manager::Impl::getCertificate(const Alias &alias, const Password &password,
        if (certParsed->empty())
                return CKM_API_ERROR_BAD_RESPONSE;
 
-       cert = certParsed;
+       cert = std::move(certParsed);
 
        return CKM_API_SUCCESS;
 }
@@ -403,54 +350,37 @@ int Manager::Impl::getData(const Alias &alias, const Password &password,
 {
        DataType recvDataType = DataType::BINARY_DATA;
 
-       int retCode = getBinaryData(
-                                         alias,
-                                         DataType::BINARY_DATA,
-                                         password,
-                                         recvDataType,
-                                         rawData);
+       int retCode = getBinaryData(alias, DataType::BINARY_DATA, password, recvDataType, rawData);
 
        if (retCode != CKM_API_SUCCESS)
                return retCode;
 
-       if (recvDataType != DataType::BINARY_DATA)
-               return CKM_API_ERROR_BAD_RESPONSE;
-
-       return CKM_API_SUCCESS;
+       return recvDataType.isBinaryData() ? CKM_API_SUCCESS : CKM_API_ERROR_BAD_RESPONSE;
 }
 
-int Manager::Impl::getBinaryDataAliasVector(DataType dataType,
-               AliasVector &aliasVector)
+int Manager::Impl::getAliasInfoVectorHelper(DataType dataType, AliasInfoVector &aliasInfoVector)
 {
-       int my_counter = ++m_counter;
+       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);
 
-       MessageBuffer recv;
-       auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
-                                                                                my_counter,
-                                                                                static_cast<int>(dataType));
-
-       int retCode = m_storageConnection.processRequest(send.Pop(), recv);
-
-       if (CKM_API_SUCCESS != retCode)
+       if (retCode != CKM_API_SUCCESS)
                return retCode;
 
-       int command;
-       int counter;
-       int tmpDataType;
-       OwnerNameVector ownerNameVector;
-       recv.Deserialize(command, counter, retCode, tmpDataType, ownerNameVector);
-
-       if ((command != static_cast<int>(LogicCommand::GET_LIST)) ||
-                       (counter != my_counter))
-               return CKM_API_ERROR_UNKNOWN;
-
-       for (const auto &it : ownerNameVector)
-               aliasVector.push_back(AliasSupport::merge(it.first, it.second));
-
-       return retCode;
+       for (const auto &it : aliasInfoVector)
+               aliasVector.push_back(it.alias);
 
+       return CKM_API_SUCCESS;
        EXCEPTION_GUARD_END
 }
 
@@ -458,17 +388,53 @@ 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 getBinaryDataAliasVector(DataType::DB_KEY_LAST, aliasVector);
+       return getAliasVectorHelper(DataType::DB_KEY_LAST, aliasVector);
 }
 
 int Manager::Impl::getCertificateAliasVector(AliasVector &aliasVector)
 {
-       return getBinaryDataAliasVector(DataType::CERTIFICATE, aliasVector);
+       return getAliasVectorHelper(DataType::CERTIFICATE, aliasVector);
 }
 
 int Manager::Impl::getDataAliasVector(AliasVector &aliasVector)
 {
-       return getBinaryDataAliasVector(DataType::BINARY_DATA, 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(
@@ -501,8 +467,8 @@ int Manager::Impl::createKeyPairECDSA(
        const Policy &policyPublicKey)
 {
        return this->createKeyPair(CKM::KeyType::KEY_ECDSA_PUBLIC,
-                                                          static_cast<int>(type), privateKeyAlias, publicKeyAlias, policyPrivateKey,
-                                                          policyPublicKey);
+                                                          static_cast<int>(type), privateKeyAlias, publicKeyAlias,
+                                                          policyPrivateKey, policyPublicKey);
 }
 
 int Manager::Impl::createKeyAES(
@@ -510,34 +476,14 @@ int Manager::Impl::createKeyAES(
        const Alias &keyAlias,
        const Policy &policyKey)
 {
-       // proceed with sending request
-       int my_counter = ++m_counter;
-
        EXCEPTION_GUARD_START_CPPAPI
 
-       MessageBuffer recv;
        AliasSupport aliasHelper(keyAlias);
-       auto send = MessageBuffer::Serialize(static_cast<int>
-                                                                                (LogicCommand::CREATE_KEY_AES),
-                                                                                my_counter,
-                                                                                static_cast<int>(size),
-                                                                                PolicySerializable(policyKey),
-                                                                                aliasHelper.getName(),
-                                                                                aliasHelper.getOwner());
-
-       int retCode = m_storageConnection.processRequest(send.Pop(), recv);
-
-       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 retCode;
+       return Request(*this, LogicCommand::CREATE_KEY_AES, m_storageConnection,
+                       size, PolicySerializable(policyKey),
+                       aliasHelper.getName(), aliasHelper.getOwner()
+               ).maybeDeserialize();
 
        EXCEPTION_GUARD_END
 }
@@ -577,38 +523,18 @@ int Manager::Impl::createKeyPair(
                return CKM_API_ERROR_INPUT_PARAM;
        }
 
-       // proceed with sending request
-       int my_counter = ++m_counter;
-
        EXCEPTION_GUARD_START_CPPAPI
 
-       MessageBuffer recv;
        AliasSupport privateHelper(privateKeyAlias);
        AliasSupport publicHelper(publicKeyAlias);
-       auto send = MessageBuffer::Serialize(static_cast<int>
-                                                                                (LogicCommand::CREATE_KEY_PAIR),
-                                                                                my_counter,
-                                                                                CryptoAlgorithmSerializable(keyGenAlgorithm),
-                                                                                PolicySerializable(policyPrivateKey),
-                                                                                PolicySerializable(policyPublicKey),
-                                                                                privateHelper.getName(),
-                                                                                privateHelper.getOwner(),
-                                                                                publicHelper.getName(),
-                                                                                publicHelper.getOwner());
-
-       int retCode = m_storageConnection.processRequest(send.Pop(), recv);
 
-       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 retCode;
+       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
 }
@@ -638,15 +564,9 @@ int Manager::Impl::getCertificateChain(
                trustedVector.push_back(e->getDER());
        }
 
-       return getCertChain(
-                          m_storageConnection,
-                          LogicCommand::GET_CHAIN_CERT,
-                          ++m_counter,
-                          certificate,
-                          untrustedVector,
-                          trustedVector,
-                          useTrustedSystemCertificates,
-                          certificateChainVector);
+       return getCertChain(m_storageConnection, LogicCommand::GET_CHAIN_CERT, *this,
+                           certificate, untrustedVector, trustedVector,
+                           useTrustedSystemCertificates, certificateChainVector);
 }
 
 int Manager::Impl::getCertificateChain(
@@ -672,15 +592,9 @@ int Manager::Impl::getCertificateChain(
                trustedVector.push_back(std::make_pair(helper.getOwner(), helper.getName()));
        }
 
-       return getCertChain(
-                          m_storageConnection,
-                          LogicCommand::GET_CHAIN_ALIAS,
-                          ++m_counter,
-                          certificate,
-                          untrustedVector,
-                          trustedVector,
-                          useTrustedSystemCertificates,
-                          certificateChainVector);
+       return getCertChain(m_storageConnection, LogicCommand::GET_CHAIN_ALIAS, *this,
+                           certificate, untrustedVector, trustedVector,
+                           useTrustedSystemCertificates, certificateChainVector);
 }
 
 int Manager::Impl::createSignature(
@@ -690,35 +604,14 @@ int Manager::Impl::createSignature(
        const CryptoAlgorithm &cAlgorithm,
        RawBuffer &signature)
 {
-       int my_counter = ++m_counter;
-
        EXCEPTION_GUARD_START_CPPAPI
 
-       MessageBuffer recv;
        AliasSupport helper(privateKeyAlias);
-       auto send = MessageBuffer::Serialize(static_cast<int>
-                                                                                (LogicCommand::CREATE_SIGNATURE),
-                                                                                my_counter,
-                                                                                helper.getName(),
-                                                                                helper.getOwner(),
-                                                                                password,
-                                                                                message,
-                                                                                CryptoAlgorithmSerializable(cAlgorithm));
-
-       int retCode = m_storageConnection.processRequest(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;
+       return Request(*this, LogicCommand::CREATE_SIGNATURE, m_storageConnection,
+                       helper.getName(), helper.getOwner(), password, message,
+                       CryptoAlgorithmSerializable(cAlgorithm)
+               ).maybeDeserialize(signature);
 
        EXCEPTION_GUARD_END
 }
@@ -730,36 +623,14 @@ int Manager::Impl::verifySignature(
        const RawBuffer &signature,
        const CryptoAlgorithm &cAlg)
 {
-       int my_counter = ++m_counter;
-
        EXCEPTION_GUARD_START_CPPAPI
 
-       MessageBuffer recv;
        AliasSupport helper(publicKeyOrCertAlias);
-       auto send = MessageBuffer::Serialize(static_cast<int>
-                                                                                (LogicCommand::VERIFY_SIGNATURE),
-                                                                                my_counter,
-                                                                                helper.getName(),
-                                                                                helper.getOwner(),
-                                                                                password,
-                                                                                message,
-                                                                                signature,
-                                                                                CryptoAlgorithmSerializable(cAlg));
-
-       int retCode = m_storageConnection.processRequest(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;
+       return Request(*this, LogicCommand::VERIFY_SIGNATURE, m_storageConnection,
+                       helper.getName(), helper.getOwner(), password, message, signature,
+                       CryptoAlgorithmSerializable(cAlg)
+               ).maybeDeserialize();
 
        EXCEPTION_GUARD_END
 }
@@ -769,7 +640,7 @@ int Manager::Impl::ocspCheck(const CertificateShPtrVector &certChain,
 {
        EXCEPTION_GUARD_START_CPPAPI
 
-       int my_counter = ++m_counter;
+       int msgId = ++m_counter;
        MessageBuffer recv;
 
        RawBufferVector rawCertChain;
@@ -783,20 +654,12 @@ int Manager::Impl::ocspCheck(const CertificateShPtrVector &certChain,
                rawCertChain.push_back(e->getDER());
        }
 
-       auto send = MessageBuffer::Serialize(my_counter, rawCertChain);
-
-       int retCode = m_ocspConnection.processRequest(send.Pop(), recv);
+       int retCode = doRequest(recv, m_ocspConnection, msgId, rawCertChain);
 
        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;
+       return deserializeResponse(msgId, recv, ocspStatus);
 
        EXCEPTION_GUARD_END
 }
@@ -805,33 +668,13 @@ int Manager::Impl::setPermission(const Alias &alias,
                                                                 const ClientId &accessor,
                                                                 PermissionMask permissionMask)
 {
-       int my_counter = ++m_counter;
-
        EXCEPTION_GUARD_START_CPPAPI
 
-       MessageBuffer recv;
        AliasSupport helper(alias);
-       auto send = MessageBuffer::Serialize(static_cast<int>
-                                                                                (LogicCommand::SET_PERMISSION),
-                                                                                my_counter,
-                                                                                helper.getName(),
-                                                                                helper.getOwner(),
-                                                                                accessor,
-                                                                                permissionMask);
-
-       int retCode = m_storageConnection.processRequest(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;
+       return Request(*this, LogicCommand::SET_PERMISSION, m_storageConnection,
+                       helper.getName(), helper.getOwner(), accessor, permissionMask
+               ).maybeDeserialize();
 
        EXCEPTION_GUARD_END
 }
@@ -843,34 +686,14 @@ int Manager::Impl::crypt(EncryptionCommand command,
                                                 const RawBuffer &input,
                                                 RawBuffer &output)
 {
-       int my_counter = ++m_counter;
-
        EXCEPTION_GUARD_START_CPPAPI
 
-       MessageBuffer recv;
        AliasSupport helper(keyAlias);
        CryptoAlgorithmSerializable cas(algo);
-       auto send = MessageBuffer::Serialize(static_cast<int>(command),
-                                                                                my_counter,
-                                                                                cas,
-                                                                                helper.getName(),
-                                                                                helper.getOwner(),
-                                                                                password,
-                                                                                input);
-
-       int retCode = m_encryptionConnection.processRequest(send.Pop(), recv);
 
-       if (CKM_API_SUCCESS != retCode)
-               return retCode;
-
-       int retCommand;
-       int counter;
-       recv.Deserialize(retCommand, counter, retCode, output);
-
-       if (my_counter != counter || retCommand != static_cast<int>(command))
-               return CKM_API_ERROR_UNKNOWN;
-
-       return retCode;
+       return Request(*this, command, m_encryptionConnection,
+                       cas, helper.getName(), helper.getOwner(), password, input
+               ).maybeDeserialize(output);
 
        EXCEPTION_GUARD_END
 }
@@ -895,4 +718,166 @@ int Manager::Impl::decrypt(const CryptoAlgorithm &algo,
                                 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