Fix parameter validation in ocsp
[platform/core/security/key-manager.git] / src / manager / client / client-manager-impl.cpp
index ba3473e..3bb1ef9 100644 (file)
  * @version     1.0
  * @brief       Manager implementation.
  */
+#include <openssl/evp.h>
+
 #include <dpl/serialization.h>
+#include <dpl/log/log.h>
 
+#include <crypto-init.h>
 #include <client-manager-impl.h>
 #include <client-common.h>
-#include <key-impl.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(
+namespace {
+template <class T>
+int getCertChain(
+    ServiceConnection & serviceConnection,
+    LogicCommand command,
+    int counter,
+    const CertificateShPtr &certificate,
+    const T &untrustedVector,
+    const T &trustedVector,
+    bool useTrustedSystemCertificates,
+    CertificateShPtrVector &certificateChainVector)
+{
+    return try_catch([&] {
+
+        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;
+
+        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;
+    });
+}
+
+} // namespace anonymous
+
+ManagerImpl::ManagerImpl()
+  : m_counter(0),
+    m_storageConnection(SERVICE_SOCKET_CKM_STORAGE),
+    m_ocspConnection(SERVICE_SOCKET_OCSP),
+    m_encryptionConnection(SERVICE_SOCKET_ENCRYPTION)
+{
+    initCryptoLib();
+}
+
+
+int ManagerImpl::saveBinaryData(
     const Alias &alias,
-    DBDataType dataType,
+    DataType dataType,
     const RawBuffer &rawData,
     const Policy &policy)
 {
-    m_counter++;
+    int my_counter = ++m_counter;
 
     return try_catch([&] {
         if (alias.empty() || rawData.empty())
-            return KEY_MANAGER_API_ERROR_INPUT_PARAM;
-
-        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));
-
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
-
-        if (KEY_MANAGER_API_SUCCESS != retCode) {
+            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.getLabel(),
+                                             rawData,
+                                             PolicySerializable(policy));
+
+        int retCode = m_storageConnection.processRequest(send.Pop(), recv);
+        if (CKM_API_SUCCESS != retCode)
             return retCode;
-        }
 
         int command;
         int counter;
         int opType;
-        Deserialization::Deserialize(recv, command);
-        Deserialization::Deserialize(recv, counter);
-        Deserialization::Deserialize(recv, retCode);
-        Deserialization::Deserialize(recv, opType);
+        recv.Deserialize(command, counter, retCode, opType);
 
-        if (counter != m_counter) {
-            return KEY_MANAGER_API_ERROR_UNKNOWN;
-        }
+        if (counter != my_counter)
+            return CKM_API_ERROR_UNKNOWN;
 
         return retCode;
     });
 }
 
-int Manager::ManagerImpl::saveKey(const Alias &alias, const Key &key, const Policy &policy) {
-    return saveBinaryData(alias, toDBDataType(key.getType()), key.getKey(), policy);
+int ManagerImpl::saveKey(const Alias &alias, const KeyShPtr &key, const Policy &policy) {
+    if (key.get() == NULL)
+        return CKM_API_ERROR_INPUT_PARAM;
+    Try {
+        return saveBinaryData(alias, DataType(key->getType()), key->getDER(), policy);
+    } Catch (DataType::Exception::Base) {
+        LogError("Error in key conversion. Could not convert KeyType::NONE to DBDataType!");
+    }
+    return CKM_API_ERROR_INPUT_PARAM;
 }
 
-int Manager::ManagerImpl::saveCertificate(
+int ManagerImpl::saveCertificate(
     const Alias &alias,
-    const Certificate &cert,
+    const CertificateShPtr &cert,
     const Policy &policy)
 {
-    return saveBinaryData(alias, DBDataType::CERTIFICATE, cert.getDER(), policy);
+    if (cert.get() == NULL)
+        return CKM_API_ERROR_INPUT_PARAM;
+    return saveBinaryData(alias, DataType::CERTIFICATE, cert->getDER(), policy);
 }
 
-int Manager::ManagerImpl::saveData(const Alias &alias, const RawBuffer &rawData, const Policy &policy) {
-    return saveBinaryData(alias, DBDataType::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, DataType::BINARY_DATA, rawData, policy);
 }
 
-int Manager::ManagerImpl::removeBinaryData(const Alias &alias, DBDataType dataType)
-{
-    return try_catch([&] {
-        if (alias.empty())
-            return KEY_MANAGER_API_ERROR_INPUT_PARAM;
 
-        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);
+int ManagerImpl::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;
 
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
+    int my_counter = ++m_counter;
 
-        if (KEY_MANAGER_API_SUCCESS != retCode) {
+    return try_catch([&] {
+        MessageBuffer recv;
+        AliasSupport helper(alias);
+        auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE_PKCS12),
+                                             my_counter,
+                                             helper.getName(),
+                                             helper.getLabel(),
+                                             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;
-        int opType;
-        Deserialization::Deserialize(recv, command);
-        Deserialization::Deserialize(recv, counter);
-        Deserialization::Deserialize(recv, retCode);
-        Deserialization::Deserialize(recv, opType);
+        recv.Deserialize(command, counter, retCode);
 
-        if (counter != m_counter) {
-            return KEY_MANAGER_API_ERROR_UNKNOWN;
-        }
+        if (counter != my_counter)
+            return CKM_API_ERROR_UNKNOWN;
 
         return retCode;
     });
 }
 
-int Manager::ManagerImpl::removeKey(const Alias &alias) {
-    return removeBinaryData(alias, DBDataType::KEY_RSA_PUBLIC);
+int ManagerImpl::getPKCS12(const Alias &alias, PKCS12ShPtr &pkcs)
+{
+    return getPKCS12(alias, Password(), Password(), pkcs);
 }
 
-int Manager::ManagerImpl::removeCertificate(const Alias &alias) {
-    return removeBinaryData(alias, DBDataType::CERTIFICATE);
+int ManagerImpl::getPKCS12(const Alias &alias, const Password &keyPass, const Password &certPass, PKCS12ShPtr &pkcs)
+{
+    if (alias.empty())
+        return CKM_API_ERROR_INPUT_PARAM;
+
+    int my_counter = ++m_counter;
+
+    return try_catch([&] {
+        MessageBuffer recv;
+        AliasSupport helper(alias);
+        auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12),
+                                             my_counter,
+                                             helper.getName(),
+                                             helper.getLabel(),
+                                             keyPass,
+                                             certPass);
+
+        int retCode = m_storageConnection.processRequest(send.Pop(), recv);
+        if (CKM_API_SUCCESS != retCode)
+            return retCode;
+
+        int command;
+        int counter;
+        PKCS12Serializable gotPkcs;
+        recv.Deserialize(command, counter, retCode, gotPkcs);
+
+        if (counter != my_counter)
+            return CKM_API_ERROR_UNKNOWN;
+
+        pkcs = std::make_shared<PKCS12Impl>(std::move(gotPkcs));
+
+        return retCode;
+    });
 }
 
-int Manager::ManagerImpl::removeData(const Alias &alias) {
-    return removeBinaryData(alias, DBDataType::BINARY_DATA);
+
+int ManagerImpl::removeAlias(const Alias &alias)
+{
+    if (alias.empty())
+        return CKM_API_ERROR_INPUT_PARAM;
+
+    int my_counter = ++m_counter;
+
+    return try_catch([&] {
+        MessageBuffer recv;
+        AliasSupport helper(alias);
+        auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
+                                             my_counter,
+                                             helper.getName(),
+                                             helper.getLabel());
+
+        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;
+    });
 }
 
-int Manager::ManagerImpl::getBinaryData(
+int ManagerImpl::getBinaryData(
     const Alias &alias,
-    DBDataType sendDataType,
-    const std::string &password,
-    DBDataType &recvDataType,
+    DataType sendDataType,
+    const Password &password,
+    DataType &recvDataType,
     RawBuffer &rawData)
 {
+    if (alias.empty())
+        return CKM_API_ERROR_INPUT_PARAM;
+
+    int my_counter = ++m_counter;
+
     return try_catch([&] {
-        if (alias.empty())
-            return KEY_MANAGER_API_ERROR_INPUT_PARAM;
-
-        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);
-
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
-
-        if (KEY_MANAGER_API_SUCCESS != retCode) {
+        MessageBuffer recv;
+        AliasSupport helper(alias);
+        auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
+                                             my_counter,
+                                             static_cast<int>(sendDataType),
+                                             helper.getName(),
+                                             helper.getLabel(),
+                                             password);
+
+        int retCode = m_storageConnection.processRequest(send.Pop(), recv);
+        if (CKM_API_SUCCESS != retCode)
             return retCode;
-        }
 
         int command;
         int counter;
         int tmpDataType;
-        Deserialization::Deserialize(recv, command);
-        Deserialization::Deserialize(recv, counter);
-        Deserialization::Deserialize(recv, retCode);
-        Deserialization::Deserialize(recv, tmpDataType);
-        Deserialization::Deserialize(recv, rawData);
-        recvDataType = static_cast<DBDataType>(tmpDataType);
-
-        if (counter != m_counter) {
-            return KEY_MANAGER_API_ERROR_UNKNOWN;
-        }
+        recv.Deserialize(command, counter, retCode, tmpDataType, rawData);
+        recvDataType = DataType(tmpDataType);
+
+        if (counter != my_counter)
+            return CKM_API_ERROR_UNKNOWN;
 
         return retCode;
     });
 }
 
-int Manager::ManagerImpl::getKey(const Alias &alias, const std::string &password, Key &key) {
-    DBDataType recvDataType;
+int ManagerImpl::getKey(const Alias &alias, const Password &password, KeyShPtr &key) {
+    DataType recvDataType;
     RawBuffer rawData;
 
     int retCode = getBinaryData(
         alias,
-        DBDataType::KEY_RSA_PUBLIC,
+        DataType::KEY_RSA_PUBLIC,
         password,
         recvDataType,
         rawData);
 
-    if (retCode != KEY_MANAGER_API_SUCCESS)
+    if (retCode != CKM_API_SUCCESS)
         return retCode;
 
-    Key keyParsed(rawData, toKeyType(recvDataType));
+    KeyShPtr keyParsed;
+    if(DataType::KEY_AES == recvDataType)
+        keyParsed = KeyShPtr(new KeyAESImpl(rawData));
+    else
+        keyParsed = KeyShPtr(new KeyImpl(rawData));
 
-    if (keyParsed.empty())
-        return KEY_MANAGER_API_ERROR_BAD_RESPONSE;
+    if (keyParsed->empty()) {
+        LogDebug("Key empty - failed to parse!");
+        return CKM_API_ERROR_BAD_RESPONSE;
+    }
 
     key = keyParsed;
 
-    return KEY_MANAGER_API_SUCCESS;
+    return CKM_API_SUCCESS;
 }
 
-int Manager::ManagerImpl::getCertificate(const Alias &alias, const std::string &password, Certificate &cert)
+int ManagerImpl::getCertificate(const Alias &alias, const Password &password, CertificateShPtr &cert)
 {
-    DBDataType recvDataType;
+    DataType recvDataType;
     RawBuffer rawData;
 
     int retCode = getBinaryData(
         alias,
-        DBDataType::CERTIFICATE,
+        DataType::CERTIFICATE,
         password,
         recvDataType,
         rawData);
 
-    if (retCode != KEY_MANAGER_API_SUCCESS)
+    if (retCode != CKM_API_SUCCESS)
         return retCode;
 
-    if (recvDataType != DBDataType::CERTIFICATE)
-        return KEY_MANAGER_API_ERROR_BAD_RESPONSE;
+    if (recvDataType != DataType::CERTIFICATE)
+        return CKM_API_ERROR_BAD_RESPONSE;
 
-    Certificate certParsed(rawData, DataFormat::FORM_DER);
+    CertificateShPtr certParsed(new CertificateImpl(rawData, DataFormat::FORM_DER));
 
-    if (certParsed.empty())
-        return KEY_MANAGER_API_ERROR_BAD_RESPONSE;
+    if (certParsed->empty())
+        return CKM_API_ERROR_BAD_RESPONSE;
 
     cert = certParsed;
 
-    return KEY_MANAGER_API_SUCCESS;
+    return CKM_API_SUCCESS;
 }
 
-int Manager::ManagerImpl::getData(const Alias &alias, const std::string &password, RawBuffer &rawData)
+int ManagerImpl::getData(const Alias &alias, const Password &password, RawBuffer &rawData)
 {
-    DBDataType recvDataType;
+    DataType recvDataType = DataType::BINARY_DATA;
 
     int retCode = getBinaryData(
         alias,
-        DBDataType::CERTIFICATE,
+        DataType::BINARY_DATA,
         password,
         recvDataType,
         rawData);
 
-    if (retCode != KEY_MANAGER_API_SUCCESS)
+    if (retCode != CKM_API_SUCCESS)
         return retCode;
 
-    if (recvDataType != DBDataType::BINARY_DATA)
-        return KEY_MANAGER_API_ERROR_BAD_RESPONSE;
+    if (recvDataType != DataType::BINARY_DATA)
+        return CKM_API_ERROR_BAD_RESPONSE;
 
-    return KEY_MANAGER_API_SUCCESS;
+    return CKM_API_SUCCESS;
 }
 
-int Manager::ManagerImpl::requestBinaryDataAliasVector(DBDataType dataType, AliasVector &aliasVector)
+int ManagerImpl::getBinaryDataAliasVector(DataType dataType, AliasVector &aliasVector)
 {
-    return try_catch([&] {
+    int my_counter = ++m_counter;
 
-        MessageBuffer send, recv;
-        Serialization::Serialize(send, static_cast<int>(LogicCommand::GET_LIST));
-        Serialization::Serialize(send, m_counter);
-        Serialization::Serialize(send, static_cast<int>(dataType));
-
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
+    return try_catch([&] {
+        MessageBuffer recv;
+        auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
+                                             my_counter,
+                                             static_cast<int>(dataType));
 
-        if (KEY_MANAGER_API_SUCCESS != retCode) {
+        int retCode = m_storageConnection.processRequest(send.Pop(), recv);
+        if (CKM_API_SUCCESS != retCode)
             return retCode;
-        }
 
         int command;
         int counter;
         int tmpDataType;
-
-        Deserialization::Deserialize(recv, command);
-        Deserialization::Deserialize(recv, counter);
-        Deserialization::Deserialize(recv, retCode);
-        Deserialization::Deserialize(recv, tmpDataType);
-        Deserialization::Deserialize(recv, aliasVector);
-
-        if (counter != m_counter) {
-            return KEY_MANAGER_API_ERROR_UNKNOWN;
+        LabelNameVector labelNameVector;
+        recv.Deserialize(command, counter, retCode, tmpDataType, labelNameVector);
+        if ((command != static_cast<int>(LogicCommand::GET_LIST)) || (counter != my_counter)) {
+            return CKM_API_ERROR_UNKNOWN;
         }
 
+        for(const auto &it : labelNameVector)
+            aliasVector.push_back( AliasSupport::merge(it.first, it.second) );
+
         return retCode;
     });
 }
 
-int Manager::ManagerImpl::requestKeyAliasVector(AliasVector &aliasVector) {
-    return requestBinaryDataAliasVector(DBDataType::KEY_RSA_PUBLIC, aliasVector);
+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(DataType::DB_KEY_LAST, aliasVector);
+}
+
+int ManagerImpl::getCertificateAliasVector(AliasVector &aliasVector) {
+    return getBinaryDataAliasVector(DataType::CERTIFICATE, aliasVector);
 }
 
-int Manager::ManagerImpl::requestCertificateAliasVector(AliasVector &aliasVector) {
-    return requestBinaryDataAliasVector(DBDataType::CERTIFICATE, aliasVector);
+int ManagerImpl::getDataAliasVector(AliasVector &aliasVector) {
+    return getBinaryDataAliasVector(DataType::BINARY_DATA, aliasVector);
 }
 
-int Manager::ManagerImpl::requestDataAliasVector(AliasVector &aliasVector) {
-    return requestBinaryDataAliasVector(DBDataType::BINARY_DATA, aliasVector);
+int ManagerImpl::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::ManagerImpl::createKeyPairRSA(
-    const int size,              // size in bits [1024, 2048, 4096]
+int ManagerImpl::createKeyPairDSA(
+    const int size,
     const Alias &privateKeyAlias,
     const Alias &publicKeyAlias,
     const Policy &policyPrivateKey,
-    const Policy &policyPublicKey) 
+    const Policy &policyPublicKey)
 {
-    m_counter++;
-    int my_counter = m_counter;
+    return this->createKeyPair(CKM::KeyType::KEY_DSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
+}
+
+int ManagerImpl::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::createKeyAES(
+    const int size,
+    const Alias &keyAlias,
+    const Policy &policyKey)
+{
+    // proceed with sending request
+    int my_counter = ++m_counter;
+
     return try_catch([&] {
 
-        MessageBuffer send, recv;
-        Serialization::Serialize(send, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
-        Serialization::Serialize(send, my_counter);
-        Serialization::Serialize(send, static_cast<int>(size));
-        Serialization::Serialize(send, PolicySerializable(policyPrivateKey));
-        Serialization::Serialize(send, PolicySerializable(policyPublicKey));
-        Serialization::Serialize(send, privateKeyAlias);
-        Serialization::Serialize(send, publicKeyAlias);
-        
-        
-
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
-
-        if (KEY_MANAGER_API_SUCCESS != retCode) {
+        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.getLabel());
+
+        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;
+    });
+}
+
 
-        Deserialization::Deserialize(recv, command);
-        Deserialization::Deserialize(recv, counter);
-        Deserialization::Deserialize(recv, retCode);
-        
+int ManagerImpl::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;
+    }
+
+    // proceed with sending request
+    int my_counter = ++m_counter;
+
+    return try_catch([&] {
+
+        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.getLabel(),
+                                             publicHelper.getName(),
+                                             publicHelper.getLabel());
+
+        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 KEY_MANAGER_API_ERROR_UNKNOWN;
+            return CKM_API_ERROR_UNKNOWN;
         }
 
         return retCode;
     });
 }
 
-int Manager::ManagerImpl::createKeyPairECDSA(
-    ElipticCurve type,
+int ManagerImpl::getCertificateChain(
+    const CertificateShPtr &certificate,
+    const CertificateShPtrVector &untrustedCertificates,
+    const CertificateShPtrVector &trustedCertificates,
+    bool useTrustedSystemCertificates,
+    CertificateShPtrVector &certificateChainVector)
+{
+    RawBufferVector untrustedVector;
+    RawBufferVector trustedVector;
+
+    for (auto &e: untrustedCertificates) {
+        untrustedVector.push_back(e->getDER());
+    }
+    for (auto &e: trustedCertificates) {
+        trustedVector.push_back(e->getDER());
+    }
+
+    return getCertChain(
+            m_storageConnection,
+            LogicCommand::GET_CHAIN_CERT,
+            ++m_counter,
+            certificate,
+            untrustedVector,
+            trustedVector,
+            useTrustedSystemCertificates,
+            certificateChainVector);
+}
+
+int ManagerImpl::getCertificateChain(
+    const CertificateShPtr &certificate,
+    const AliasVector &untrustedCertificates,
+    const AliasVector &trustedCertificates,
+    bool useTrustedSystemCertificates,
+    CertificateShPtrVector &certificateChainVector)
+{
+    LabelNameVector untrustedVector;
+    LabelNameVector trustedVector;
+
+    for (auto &e: untrustedCertificates) {
+        AliasSupport helper(e);
+        untrustedVector.push_back(std::make_pair(helper.getLabel(), helper.getName()));
+    }
+    for (auto &e: trustedCertificates) {
+        AliasSupport helper(e);
+        trustedVector.push_back(std::make_pair(helper.getLabel(), helper.getName()));
+    }
+
+    return getCertChain(
+            m_storageConnection,
+            LogicCommand::GET_CHAIN_ALIAS,
+            ++m_counter,
+            certificate,
+            untrustedVector,
+            trustedVector,
+            useTrustedSystemCertificates,
+            certificateChainVector);
+}
+
+int ManagerImpl::createSignature(
     const Alias &privateKeyAlias,
-    const Alias &publicKeyAlias,
-    const Policy &policyPrivateKey,
-    const Policy &policyPublicKey) 
+    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;
+    int my_counter = ++m_counter;
+
     return try_catch([&] {
 
-        MessageBuffer send, recv;
-        Serialization::Serialize(send, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_ECDSA));
-        Serialization::Serialize(send, my_counter);
-        Serialization::Serialize(send, static_cast<unsigned int>(type));
-        Serialization::Serialize(send, PolicySerializable(policyPrivateKey));
-        Serialization::Serialize(send, PolicySerializable(policyPublicKey));
-        Serialization::Serialize(send, privateKeyAlias);
-        Serialization::Serialize(send, publicKeyAlias);
-        
-
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
-
-        if (KEY_MANAGER_API_SUCCESS != retCode) {
+        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 = 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;
+    });
+}
+
+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)
+{
+    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 = m_storageConnection.processRequest(send.Pop(), recv);
+        if (CKM_API_SUCCESS != retCode)
+            return retCode;
+
         int command;
         int counter;
+        recv.Deserialize(command, counter, retCode);
 
-        Deserialization::Deserialize(recv, command);
-        Deserialization::Deserialize(recv, counter);
-        Deserialization::Deserialize(recv, retCode);
-        
-        if (counter != my_counter) {
-            return KEY_MANAGER_API_ERROR_UNKNOWN;
+        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) {
+            if (!e || e->empty()) {
+                LogError("Empty certificate");
+                return CKM_API_ERROR_INPUT_PARAM;
+            }
+            rawCertChain.push_back(e->getDER());
+        }
+
+        auto send = MessageBuffer::Serialize(my_counter, rawCertChain);
+
+        int retCode = m_ocspConnection.processRequest(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::setPermission(const Alias &alias,
+                               const Label &accessor,
+                               PermissionMask permissionMask)
+{
+    int my_counter = ++m_counter;
+
+    return try_catch([&] {
+        MessageBuffer recv;
+        AliasSupport helper(alias);
+        auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SET_PERMISSION),
+                                             my_counter,
+                                             helper.getName(),
+                                             helper.getLabel(),
+                                             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;
     });
 }
-} // namespace CKM
 
+int ManagerImpl::crypt(EncryptionCommand command,
+          const CryptoAlgorithm &algo,
+          const Alias &keyAlias,
+          const Password &password,
+          const RawBuffer& input,
+          RawBuffer& output)
+{
+    int my_counter = ++m_counter;
+
+    return try_catch([&] {
+        MessageBuffer recv;
+        AliasSupport helper(keyAlias);
+        CryptoAlgorithmSerializable cas(algo);
+        auto send = MessageBuffer::Serialize(static_cast<int>(command),
+                                             my_counter,
+                                             cas,
+                                             helper.getName(),
+                                             helper.getLabel(),
+                                             password,
+                                             input);
+
+        int retCode = m_encryptionConnection.processRequest(send.Pop(), recv);
+        if (CKM_API_SUCCESS != retCode)
+            return retCode;
+
+        int command;
+        int counter;
+        recv.Deserialize(command, counter, retCode, output);
+
+        if (my_counter != counter) {
+            return CKM_API_ERROR_UNKNOWN;
+        }
+
+        return retCode;
+    });
+}
+
+int ManagerImpl::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 ManagerImpl::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();
+}
+
+} // namespace CKM