Implementation of getCertificateChain.
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Wed, 25 Jun 2014 17:32:12 +0000 (19:32 +0200)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Fri, 12 Sep 2014 12:58:32 +0000 (14:58 +0200)
Change-Id: Ie4b8b6f9d54decb3e8e09a04a3bab101630d355a

16 files changed:
src/include/ckm/ckm-error.h
src/include/ckm/ckm-type.h
src/include/ckm/key-manager.h
src/manager/CMakeLists.txt
src/manager/client/client-certificate.cpp
src/manager/client/client-manager-impl.cpp
src/manager/client/client-manager-impl.h
src/manager/client/client-manager.cpp
src/manager/common/certificate-impl.cpp
src/manager/common/certificate-impl.h
src/manager/common/certificate-store.cpp [new file with mode: 0644]
src/manager/common/certificate-store.h [new file with mode: 0644]
src/manager/common/protocols.h
src/manager/service/ckm-logic.cpp
src/manager/service/ckm-logic.h
src/manager/service/ckm-service.cpp

index 891e528..34370b3 100644 (file)
@@ -99,6 +99,9 @@
 /*! \brief   indicating that request give to database returned no result */
 #define CKM_API_ERROR_DB_ALIAS_UNKNOWN -15
 
+/*! \brief   indicating that CA certificate(s) were unknown and chain could not be created */
+#define CKM_API_ERROR_VERIFICATION_FAILED -16
+
 /*! \brief   indicating the error with unknown reason */
 #define CKM_API_ERROR_UNKNOWN -255
 /** @}*/
index 30421b1..eec6302 100644 (file)
@@ -28,6 +28,7 @@ namespace CKM {
 
 // used to pass password and raw key data
 typedef std::vector<unsigned char> RawBuffer;
+typedef std::vector<RawBuffer> RawBufferVector;
 typedef std::string Alias;
 typedef std::vector<Alias> AliasVector;
 
index 4f97ae9..10223e3 100644 (file)
@@ -208,16 +208,16 @@ public:
 //
 //     // this fuction will return chains of certificates and check it with openssl
 //     // status : OK, INCOMPLETE_CHAIN, VERIFICATION_FAILED
-//     int getCertiticateChain(
-//                     const Certificate &certificate,
-//                     const CertificateVector &untrustedCertificates,
-//                     CertificateVector &certificateChainVector);
-//
-//     int getCertificateChain(
-//                     const Certificate &certificate,
-//                     const AliasVector &untrustedCertificates,
-//                     CertificateVector &certificateChainVector);
-//
+    int getCertificateChain(
+            const Certificate &certificate,
+            const CertificateVector &untrustedCertificates,
+            CertificateVector &certificateChainVector);
+
+    int getCertificateChain(
+            const Certificate &certificate,
+            const AliasVector &untrustedCertificates,
+            CertificateVector &certificateChainVector);
+
 //     int strictCACheck(const CertificateVector &certificateVector);
 //
 //     // This function will check all certificates in chain except Root CA.
index c7b572f..0db7ff3 100644 (file)
@@ -20,6 +20,7 @@ SET(COMMON_SOURCES
     ${COMMON_PATH}/common/message-buffer.cpp
     ${COMMON_PATH}/common/smack-check.cpp
     ${COMMON_PATH}/common/certificate-impl.cpp
+    ${COMMON_PATH}/common/certificate-store.cpp
     ${COMMON_PATH}/common/generic-key.cpp
     ${COMMON_PATH}/dpl/log/src/abstract_log_provider.cpp
     ${COMMON_PATH}/dpl/log/src/dlog_log_provider.cpp
index 9ef015c..360fdb9 100644 (file)
@@ -53,7 +53,8 @@ RawBuffer Certificate::getDER() const {
 }
 
 void* Certificate::getX509() {
-    // TODO
+    if (m_impl)
+        return m_impl->getX509();
     return NULL;
 }
 
index d2848b7..fd02923 100644 (file)
@@ -314,7 +314,7 @@ int Manager::ManagerImpl::createKeyPairRSA(
     const Alias &privateKeyAlias,
     const Alias &publicKeyAlias,
     const Policy &policyPrivateKey,
-    const Policy &policyPublicKey) 
+    const Policy &policyPublicKey)
 {
     m_counter++;
     int my_counter = m_counter;
@@ -328,8 +328,6 @@ int Manager::ManagerImpl::createKeyPairRSA(
         Serialization::Serialize(send, PolicySerializable(policyPublicKey));
         Serialization::Serialize(send, privateKeyAlias);
         Serialization::Serialize(send, publicKeyAlias);
-        
-        
 
         int retCode = sendToServer(
             SERVICE_SOCKET_CKM_STORAGE,
@@ -342,12 +340,11 @@ int Manager::ManagerImpl::createKeyPairRSA(
 
         int command;
         int counter;
-       
 
         Deserialization::Deserialize(recv, command);
         Deserialization::Deserialize(recv, counter);
         Deserialization::Deserialize(recv, retCode);
-        
+
         if (counter != my_counter) {
             return CKM_API_ERROR_UNKNOWN;
         }
@@ -361,7 +358,7 @@ int Manager::ManagerImpl::createKeyPairECDSA(
     const Alias &privateKeyAlias,
     const Alias &publicKeyAlias,
     const Policy &policyPrivateKey,
-    const Policy &policyPublicKey) 
+    const Policy &policyPublicKey)
 {
     m_counter++;
     int my_counter = m_counter;
@@ -375,7 +372,6 @@ int Manager::ManagerImpl::createKeyPairECDSA(
         Serialization::Serialize(send, PolicySerializable(policyPublicKey));
         Serialization::Serialize(send, privateKeyAlias);
         Serialization::Serialize(send, publicKeyAlias);
-        
 
         int retCode = sendToServer(
             SERVICE_SOCKET_CKM_STORAGE,
@@ -392,7 +388,7 @@ int Manager::ManagerImpl::createKeyPairECDSA(
         Deserialization::Deserialize(recv, command);
         Deserialization::Deserialize(recv, counter);
         Deserialization::Deserialize(recv, retCode);
-        
+
         if (counter != my_counter) {
             return CKM_API_ERROR_UNKNOWN;
         }
@@ -400,5 +396,85 @@ int Manager::ManagerImpl::createKeyPairECDSA(
         return retCode;
     });
 }
+
+template <class T>
+int getCertChain(
+    LogicCommand command,
+    int counter,
+    const Certificate &certificate,
+    const T &sendData,
+    CertificateVector &certificateChainVector)
+{
+    return try_catch([&] {
+
+        MessageBuffer send, recv;
+        Serialization::Serialize(send, static_cast<int>(command));
+        Serialization::Serialize(send, counter);
+        Serialization::Serialize(send, certificate.getDER());
+        Serialization::Serialize(send, sendData);
+
+        int retCode = sendToServer(
+            SERVICE_SOCKET_CKM_STORAGE,
+            send.Pop(),
+            recv);
+
+        if (CKM_API_SUCCESS != retCode) {
+            return retCode;
+        }
+
+        int retCommand;
+        int retCounter;
+        RawBufferVector rawBufferVector;
+
+        Deserialization::Deserialize(recv, retCommand);
+        Deserialization::Deserialize(recv, retCounter);
+        Deserialization::Deserialize(recv, retCode);
+        Deserialization::Deserialize(recv, 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)
+            certificateChainVector.push_back(Certificate(e, DataFormat::FORM_DER));
+
+        return retCode;
+    });
+}
+
+int Manager::ManagerImpl::getCertificateChain(
+    const Certificate &certificate,
+    const CertificateVector &untrustedCertificates,
+    CertificateVector &certificateChainVector)
+{
+    RawBufferVector rawBufferVector;
+
+    for (auto &e: untrustedCertificates) {
+        rawBufferVector.push_back(e.getDER());
+    }
+
+    return getCertChain(
+        LogicCommand::GET_CHAIN_CERT,
+        ++m_counter,
+        certificate,
+        rawBufferVector,
+        certificateChainVector);
+}
+
+int Manager::ManagerImpl::getCertificateChain(
+    const Certificate &certificate,
+    const AliasVector &untrustedCertificates,
+    CertificateVector &certificateChainVector)
+{
+    (void) certificate;
+    (void) untrustedCertificates;
+    (void) certificateChainVector;
+    return CKM_API_ERROR_UNKNOWN;
+}
+
 } // namespace CKM
 
index b89a75f..7fa1d5f 100644 (file)
@@ -63,6 +63,16 @@ public:
         const Policy &policyPrivateKey = Policy(),
         const Policy &policyPublicKey = Policy());
 
+    int getCertificateChain(
+        const Certificate &certificate,
+        const CertificateVector &untrustedCertificates,
+        CertificateVector &certificateChainVector);
+
+    int getCertificateChain(
+        const Certificate &certificate,
+        const AliasVector &untrustedCertificates,
+        CertificateVector &certificateChainVector);
+
 protected:
     int saveBinaryData(
         const Alias &alias,
@@ -73,7 +83,7 @@ protected:
     int removeBinaryData(
         const Alias &alias,
         DBDataType dataType);
-        
+
     int getBinaryData(
         const Alias &alias,
         DBDataType sendDataType,
index 7b12eef..91393fe 100644 (file)
@@ -97,5 +97,22 @@ int Manager::createKeyPairECDSA(
 {
     return m_impl->createKeyPairECDSA(type, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
 }
+
+int Manager::getCertificateChain(
+    const Certificate &certificate,
+    const CertificateVector &untrustedCertificates,
+    CertificateVector &certificateChainVector)
+{
+    return m_impl->getCertificateChain(certificate, untrustedCertificates, certificateChainVector);
+}
+
+int Manager::getCertificateChain(
+    const Certificate &certificate,
+    const AliasVector &untrustedCertificates,
+    CertificateVector &certificateChainVector)
+{
+    return m_impl->getCertificateChain(certificate, untrustedCertificates, certificateChainVector);
+}
+
 } // namespace CKM
 
index 242ab5f..0be48eb 100644 (file)
@@ -57,22 +57,46 @@ CertificateImpl::CertificateImpl(const RawBuffer &der, DataFormat format)
         LogError("Unknown certificate format");
     }
 
-//    if (!m_x509) {
-//        // TODO
-//        LogError("Internal Openssl error in d2i_X509 function.");
+    if (!m_x509) {
+        // TODO
+        LogError("Error in parsing certificate.");
 //        ThrowMsg(Exception::OpensslInternalError,
 //          "Internal Openssl error in d2i_X509 function.");
-//    }
+    }
 }
 
+CertificateImpl::CertificateImpl(X509 *x509)
+  : m_x509(X509_dup(x509))
+{}
+
 CertificateImpl::CertificateImpl(const CertificateImpl &second){
-   m_x509 = X509_dup(second.m_x509);
+    m_x509 = X509_dup(second.m_x509);
+}
+
+CertificateImpl::CertificateImpl(CertificateImpl &&second) {
+    m_x509 = second.m_x509;
+    second.m_x509 = NULL;
 }
 
+CertificateImpl& CertificateImpl::operator=(CertificateImpl &&second) {
+    if (this == &second)
+        return *this;
+    X509_free(m_x509);
+    m_x509 = second.m_x509;
+    second.m_x509 = NULL;
+    return *this;
+}
 
 CertificateImpl& CertificateImpl::operator=(const CertificateImpl &second) {
-   m_x509 = X509_dup(second.m_x509);
-   return *this;
+    if (this == &second)
+        return *this;
+    X509_free(m_x509);
+    m_x509 = X509_dup(second.m_x509);
+    return *this;
+}
+
+X509* CertificateImpl::getX509() const {
+    return m_x509;
 }
 
 RawBuffer CertificateImpl::getDER(void) const {
@@ -97,7 +121,9 @@ bool CertificateImpl::empty() const {
 }
 
 CertificateImpl::~CertificateImpl() {
+    LogDebug("free cert start ptr: " << (void*)m_x509);
     X509_free(m_x509);
+    LogDebug("free cert end");
 }
 
 } // namespace CKM
index f5df6cf..ca182c3 100644 (file)
@@ -35,14 +35,18 @@ namespace CKM {
 class CertificateImpl {
 public:
     CertificateImpl(){}
+    CertificateImpl(X509* x509);
     CertificateImpl(const RawBuffer &data, DataFormat format);
     CertificateImpl(const CertificateImpl &);
+    CertificateImpl(CertificateImpl &&);
     CertificateImpl& operator=(const CertificateImpl &);
+    CertificateImpl& operator=(CertificateImpl &&);
     RawBuffer getDER() const;
     bool empty() const;
 
-    ~CertificateImpl();
+    X509* getX509() const;
 
+    virtual ~CertificateImpl();
 protected:
     X509* m_x509;
 };
diff --git a/src/manager/common/certificate-store.cpp b/src/manager/common/certificate-store.cpp
new file mode 100644 (file)
index 0000000..f2783da
--- /dev/null
@@ -0,0 +1,130 @@
+/* Copyright (c) 2000 - 2013 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.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ *
+ *
+ * @file        certificate-stack.cpp
+ * @author      Barlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Certificate Stack Implmentation.
+ */
+#include <openssl/x509.h>
+
+#include <dpl/log/log.h>
+
+#include <certificate-store.h>
+#include <ckm/ckm-error.h>
+#include <ckm/ckm-type.h>
+
+namespace CKM {
+
+CertificateStore::CertificateStore()
+  : m_store(X509_STORE_new())
+{}
+
+int CertificateStore::loadFile(const std::string &path) {
+    if (!m_store) {
+        LogError("CertificateStore is not initialized!");
+        return CKM_API_ERROR_UNKNOWN;
+    }
+
+    auto lookup = X509_STORE_add_lookup(m_store, X509_LOOKUP_file());
+
+    if (!lookup) {
+        LogError("Error in X509_STORE_add_lookup");
+        return CKM_API_ERROR_UNKNOWN;
+    }
+
+    if (!X509_LOOKUP_load_file(lookup, path.c_str(), X509_FILETYPE_PEM)) {
+        LogError("Error in X509_LOOKUP_load_file");
+        return CKM_API_ERROR_UNKNOWN;
+    }
+    return CKM_API_SUCCESS;
+}
+
+int CertificateStore::setSystemCertificateDir(const char *path) {
+    if (!m_store) {
+        LogError("CertificateStore is not initialized!");
+        return CKM_API_ERROR_UNKNOWN;
+    }
+
+    auto lookup = X509_STORE_add_lookup(m_store, X509_LOOKUP_hash_dir());
+
+    if (!lookup) {
+        LogError("Error in X509_STORE_add_lookup");
+        return CKM_API_ERROR_UNKNOWN;
+    }
+
+    if (!X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM)) {
+        LogError("Error in X509_LOOKUP_add_dir");
+        return CKM_API_ERROR_UNKNOWN;
+    }
+    return CKM_API_SUCCESS;
+}
+
+int CertificateStore::verifyCertificate(
+    const CertificateImpl &cert,
+    const CertificateImplVector &untrustedVector,
+    CertificateImplVector &chainVector)
+{
+    STACK_OF(X509) *untrusted = NULL;
+
+    if (!untrustedVector.empty()) {
+        untrusted = sk_X509_new_null();
+        for (auto &e : untrustedVector)
+            sk_X509_push(untrusted, e.getX509());
+    }
+
+    X509_STORE_CTX *csc = X509_STORE_CTX_new();
+    if (!csc) {
+        LogError("failed to create csc");
+        return CKM_API_ERROR_UNKNOWN;
+    }
+
+    if (0 == X509_STORE_CTX_init(csc, m_store, cert.getX509(), untrusted)) {
+        LogError("failed to X509_STORE_CTX_init");
+        return CKM_API_ERROR_UNKNOWN;
+    }
+
+    int result = X509_verify_cert(csc); // 1 == ok; 0 == fail; -1 == error
+
+    LogDebug("Verification result: " << result);
+
+    if (result > 0) {
+        STACK_OF(X509) *chain = X509_STORE_CTX_get_chain(csc);
+        for (int i = 0; i < sk_X509_num(chain); ++i) {
+            X509* cert = (X509*)sk_X509_value(chain, i);
+            chainVector.push_back(CertificateImpl(cert));
+        }
+    }
+
+    X509_STORE_CTX_free(csc);
+    if (untrusted) {
+        // we don't want to free certificates because we did not create copies
+        // sk_X509_pop_free(untrusted, X509_free);
+        sk_X509_free(untrusted);
+    }
+
+    if (result == 1)
+        return CKM_API_SUCCESS;
+    if (result == 0)
+        return CKM_API_ERROR_VERIFICATION_FAILED;
+    return CKM_API_ERROR_UNKNOWN;
+}
+
+CertificateStore::~CertificateStore() {
+    if (m_store)
+        X509_STORE_free(m_store);
+}
+
+} // namespace CKM
diff --git a/src/manager/common/certificate-store.h b/src/manager/common/certificate-store.h
new file mode 100644 (file)
index 0000000..76f2edd
--- /dev/null
@@ -0,0 +1,53 @@
+/* Copyright (c) 2000 - 2013 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.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ *
+ *
+ * @file        certificate-stack.h
+ * @author      Barlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Certificate Stack Implmentation.
+ */
+#include <certificate-impl.h>
+
+extern "C" {
+struct x509_store_st;
+typedef struct x509_store_st X509_STORE;
+}
+
+namespace CKM {
+
+class CertificateStore {
+public:
+    CertificateStore();
+    CertificateStore(const CertificateStore &) = delete;
+    CertificateStore(CertificateStore &&) = delete;
+    CertificateStore& operator=(CertificateStore &&) = delete;
+    CertificateStore& operator=(const CertificateStore &) = delete;
+    virtual ~CertificateStore();
+
+    int loadFile(const std::string &path);
+
+    int setSystemCertificateDir(const char *path);
+
+    int verifyCertificate(
+        const CertificateImpl &cert,
+        const CertificateImplVector &untrustedVector,
+        CertificateImplVector &chainVector);
+
+protected:
+    X509_STORE *m_store;
+};
+
+} // namespace CKM
+
index 9988af7..6c6145b 100644 (file)
@@ -46,7 +46,9 @@ enum class LogicCommand : int {
     SAVE,
     REMOVE,
     CREATE_KEY_PAIR_RSA,
-    CREATE_KEY_PAIR_ECDSA
+    CREATE_KEY_PAIR_ECDSA,
+    GET_CHAIN_CERT,
+    GET_CHAIN_ALIAS
 };
 
 // Do not use DB_KEY_FIRST and DB_KEY_LAST in the code.
index 83e8a19..48fbd17 100644 (file)
 #include <ckm-logic.h>
 #include <generic-key.h>
 
+namespace {
+const char * const CERT_SYSTEM_DIR = "/etc/ssl/certs";
+} // anonymous namespace
+
 namespace CKM {
 
-CKMLogic::CKMLogic(){
+CKMLogic::CKMLogic()
+{
     int retCode = FileSystem::init();
     // TODO what can I do when init went wrong? exit(-1) ??
     if (retCode) {
         LogError("Fatal error in FileSystem::init()");
     }
+
+    if (CKM_API_SUCCESS != m_certStore.setSystemCertificateDir(CERT_SYSTEM_DIR)) {
+        LogError("Fatal error in CertificateStore::setSystemCertificateDir. Chain creation will not work");
+    }
 }
 
 CKMLogic::~CKMLogic(){}
@@ -530,5 +539,55 @@ RawBuffer CKMLogic::createKeyPairECDSA(
     return response.Pop();
 }
 
+RawBuffer CKMLogic::getCertificateChain(
+    Credentials &cred,
+    int commandId,
+    const RawBuffer &certificate,
+    const RawBufferVector &untrustedRawCertVector)
+{
+    (void)cred;
+
+    CertificateImpl cert(certificate, DataFormat::FORM_DER);
+    CertificateImplVector untrustedCertVector;
+    CertificateImplVector chainVector;
+    RawBufferVector chainRawVector;
+
+    for (auto &e: untrustedRawCertVector)
+        untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
+
+    int retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
+
+    if (retCode == CKM_API_SUCCESS) {
+        for (auto &e : chainVector)
+            chainRawVector.push_back(e.getDER());
+    }
+
+    MessageBuffer response;
+    Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_CHAIN_CERT));
+    Serialization::Serialize(response, commandId);
+    Serialization::Serialize(response, retCode);
+    Serialization::Serialize(response, chainRawVector);
+    return response.Pop();
+}
+
+RawBuffer CKMLogic::getCertificateChain(
+    Credentials &cred,
+    int commandId,
+    const RawBuffer &certificate,
+    const AliasVector &aliasVector)
+{
+    (void) cred;
+    (void) commandId;
+    (void) certificate;
+    (void) aliasVector;
+
+    MessageBuffer response;
+    Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_CHAIN_ALIAS));
+    Serialization::Serialize(response, commandId);
+    Serialization::Serialize(response, static_cast<int>(CKM_API_SUCCESS));
+    Serialization::Serialize(response, RawBufferVector());
+    return response.Pop();
+}
+
 } // namespace CKM
 
index 5341e23..06d08ec 100644 (file)
@@ -31,6 +31,7 @@
 #include <db-crypto.h>
 #include <key-provider.h>
 #include <DBCryptoModule.h>
+#include <certificate-store.h>
 
 namespace CKM {
 
@@ -108,7 +109,20 @@ public:
         const PolicySerializable &policyPrivate,
         const PolicySerializable &policyPublic);
 
+    RawBuffer getCertificateChain(
+        Credentials &cred,
+        int commandId,
+        const RawBuffer &certificate,
+        const RawBufferVector &untrustedCertificates);
+
+    RawBuffer getCertificateChain(
+        Credentials &cred,
+        int commandId,
+        const RawBuffer &certificate,
+        const AliasVector &aliasVector);
+
 private:
+
     int saveDataHelper(
         Credentials &cred,
         DBDataType dataType,
@@ -140,6 +154,7 @@ private:
         const PolicySerializable &policyPublic);
 
     std::map<uid_t, UserData> m_userDataMap;
+    CertificateStore m_certStore;
 };
 
 } // namespace CKM
index c409214..167ed08 100644 (file)
@@ -141,14 +141,11 @@ RawBuffer CKMService::processStorage(Credentials &cred, MessageBuffer &buffer){
     int tmpDataType;
     Alias alias;
     std::string user;
-    LogicCommand sc;
 
     Deserialization::Deserialize(buffer, command);
     Deserialization::Deserialize(buffer, commandId);
 
-    sc = static_cast<LogicCommand>(command);
-
-    switch(sc) {
+    switch(static_cast<LogicCommand>(command)) {
         case LogicCommand::SAVE:
         {
             RawBuffer rawData;
@@ -238,6 +235,30 @@ RawBuffer CKMService::processStorage(Credentials &cred, MessageBuffer &buffer){
                 policyPrivateKey,
                 policyPublicKey);
         }
+        case LogicCommand::GET_CHAIN_CERT:
+        {
+            RawBuffer certificate;
+            RawBufferVector rawBufferVector;
+            Deserialization::Deserialize(buffer, certificate);
+            Deserialization::Deserialize(buffer, rawBufferVector);
+            return m_logic->getCertificateChain(
+                cred,
+                commandId,
+                certificate,
+                rawBufferVector);
+        }
+        case LogicCommand::GET_CHAIN_ALIAS:
+        {
+            RawBuffer certificate;
+            AliasVector aliasVector;
+            Deserialization::Deserialize(buffer, certificate);
+            Deserialization::Deserialize(buffer, aliasVector);
+            return m_logic->getCertificateChain(
+                cred,
+                commandId,
+                certificate,
+                aliasVector);
+        }
         default:
         // TODO
             throw 1; // broken protocol