OCSP implementation.
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Fri, 11 Jul 2014 12:03:54 +0000 (14:03 +0200)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Fri, 12 Sep 2014 12:58:50 +0000 (14:58 +0200)
Change-Id: I4cf8d99b0c3ec262c7f65e5fc3b7ef2fca2b3287

19 files changed:
packaging/key-manager.manifest
src/CMakeLists.txt
src/include/ckm/ckm-error.h
src/include/ckm/ckm-manager.h
src/manager/client/client-manager-impl.cpp
src/manager/client/client-manager-impl.h
src/manager/client/client-manager.cpp
src/manager/common/protocols.cpp
src/manager/common/protocols.h
src/manager/main/key-manager-main.cpp
src/manager/service/ckm-logic.cpp
src/manager/service/ckm-service.cpp
src/manager/service/ckm-service.h
src/manager/service/ocsp-logic.cpp [new file with mode: 0644]
src/manager/service/ocsp-logic.h [new file with mode: 0644]
src/manager/service/ocsp-service.cpp [new file with mode: 0644]
src/manager/service/ocsp-service.h [new file with mode: 0644]
src/manager/service/ocsp.cpp
src/manager/service/ocsp.h

index afdffa8..a76fdba 100644 (file)
@@ -2,7 +2,4 @@
        <request>
                <domain name="_" />
        </request>
-       <assign>
-               <filesystem path="/usr/bin/key-manager" label="key-manager" exec_label="key-manager"/>
-       </assign>
 </manifest>
index 1c9a353..e068408 100644 (file)
@@ -23,6 +23,8 @@ SET(KEY_MANAGER_SOURCES
     ${KEY_MANAGER_PATH}/service/CryptoService.cpp
     ${KEY_MANAGER_PATH}/service/file-system.cpp
     ${KEY_MANAGER_PATH}/service/db-crypto.cpp
+    ${KEY_MANAGER_PATH}/service/ocsp-service.cpp
+    ${KEY_MANAGER_PATH}/service/ocsp-logic.cpp
     )
 
 SET_SOURCE_FILES_PROPERTIES(
@@ -88,7 +90,7 @@ ADD_LIBRARY(${TARGET_KEY_MANAGER_CLIENT} SHARED ${KEY_MANAGER_CLIENT_SOURCES})
 SET_TARGET_PROPERTIES(
     ${TARGET_KEY_MANAGER_CLIENT}
     PROPERTIES
-        COMPILE_FLAGS "-D_GNU_SOURCE -fPIC -fvisibility=default" 
+        COMPILE_FLAGS "-D_GNU_SOURCE -fPIC -fvisibility=default"
         SOVERSION ${KEY_MANAGER_CLIENT_VERSION_MAJOR}
         VERSION ${KEY_MANAGER_CLIENT_VERSION}
     )
@@ -124,7 +126,7 @@ ADD_LIBRARY(${TARGET_KEY_MANAGER_CONTROL_CLIENT} SHARED ${KEY_MANAGER_CONTROL_CL
 SET_TARGET_PROPERTIES(
     ${TARGET_KEY_MANAGER_CONTROL_CLIENT}
     PROPERTIES
-        COMPILE_FLAGS "-D_GNU_SOURCE -fPIC -fvisibility=default" 
+        COMPILE_FLAGS "-D_GNU_SOURCE -fPIC -fvisibility=default"
         SOVERSION ${KEY_MANAGER_CONTROL_CLIENT_VERSION_MAJOR}
         VERSION ${KEY_MANAGER_CONTROL_CLIENT_VERSION}
     )
index e919976..2aeb435 100644 (file)
@@ -87,6 +87,15 @@ extern "C" {
 /*! \brief   indicating that provided file doesn't exists or cannot be accessed in the file system */
 #define CKM_API_ERROR_FILE_ACCESS_DENIED -18
 
+#define CKM_API_OCSP_STATUS_GOOD                0
+#define CKM_API_OCSP_STATUS_UNKNOWN             -21
+#define CKM_API_OCSP_STATUS_REVOKED             -22
+#define CKM_API_OCSP_STATUS_NET_ERROR           -23
+#define CKM_API_OCSP_STATUS_INVALID_URL         -24
+#define CKM_API_OCSP_STATUS_INVALID_RESPONSE    -25
+#define CKM_API_OCSP_STATUS_REMOTE_ERROR        -26
+#define CKM_API_OCSP_STATUS_INTERNAL_ERROR      -27
+
 /*! \brief   indicating the error with unknown reason */
 #define CKM_API_ERROR_UNKNOWN -255
 /** @}*/
index 4cedae2..2d3a1f0 100644 (file)
@@ -70,12 +70,13 @@ public:
 //  Key getKey() const;
 
     // This function  will return openssl struct X509*.
+    // You should not free the memory.
+    // Memory will be freed in ~Certificate.
     void *getX509();
     RawBuffer getDER() const;
     CertificateImpl* getImpl();
 
 //    // *** standard certificate operation begin ***
-//    RawBuffer getDER() const;
 //    bool isSignedBy(const Certificate &parent) const;
 //    RawBuffer getFingerprint(FingerprintType type) const;
 //    bool isCA() const;
@@ -187,8 +188,10 @@ public:
         const HashAlgorithm hash,
         const RSAPaddingAlgorithm padding);
 
-//     // This function will check all certificates in chain except Root CA.
-//     int ocspCheck(const CertificateVector &certificateChainVector);
+    // This function will check all certificates in chain except Root CA.
+    // This function will delegate task to service. You may use this even
+    // if application does not have permission to use network.
+    int ocspCheck(const CertificateVector &certificateChainVector, int &ocspStatus);
 
 private:
     class ManagerImpl;
index f9b978f..ec3fea9 100644 (file)
@@ -599,5 +599,42 @@ int Manager::ManagerImpl::verifySignature(
     });
 }
 
+int Manager::ManagerImpl::ocspCheck(const CertificateVector &certChain, int &ocspStatus)
+{
+    return try_catch([&] {
+        int my_counter = ++m_counter;
+        MessageBuffer send, recv;
+
+        RawBufferVector rawCertChain;
+        for (auto &e: certChain) {
+            rawCertChain.push_back(e.getDER());
+        }
+
+        Serialization::Serialize(send, my_counter);
+        Serialization::Serialize(send, rawCertChain);
+
+        int retCode = sendToServer(
+            SERVICE_SOCKET_OCSP,
+            send.Pop(),
+            recv);
+
+        if (CKM_API_SUCCESS != retCode) {
+            return retCode;
+        }
+
+        int counter;
+
+        Deserialization::Deserialize(recv, counter);
+        Deserialization::Deserialize(recv, retCode);
+        Deserialization::Deserialize(recv, ocspStatus);
+
+        if (my_counter != counter) {
+            return CKM_API_ERROR_UNKNOWN;
+        }
+
+        return retCode;
+    });
+}
+
 } // namespace CKM
 
index af84bf8..6fd185d 100644 (file)
@@ -87,6 +87,8 @@ public:
         const HashAlgorithm hash,
         const RSAPaddingAlgorithm padding);
 
+    int ocspCheck(const CertificateVector &certificateChain, int &ocspCheck);
+
 protected:
     int saveBinaryData(
         const Alias &alias,
index 8d6d176..0a07336 100644 (file)
@@ -136,5 +136,10 @@ int Manager::verifySignature(
     return m_impl->verifySignature(publicKeyOrCertAlias, password, message, signature, hash, padding);
 }
 
+int Manager::ocspCheck(const CertificateVector &certificateChainVector, int &ocspStatus)
+{
+    return m_impl->ocspCheck(certificateChainVector, ocspStatus);
+}
+
 } // namespace CKM
 
index 36f63d3..d4fc5d4 100644 (file)
@@ -31,6 +31,7 @@ namespace CKM {
 char const * const SERVICE_SOCKET_ECHO = "/tmp/.central-key-manager-echo.sock";
 char const * const SERVICE_SOCKET_CKM_CONTROL = "/tmp/.central-key-manager-api-control.sock";
 char const * const SERVICE_SOCKET_CKM_STORAGE = "/tmp/.central-key-manager-api-storage.sock";
+char const * const SERVICE_SOCKET_OCSP = "/tmp/.central-key-manager-api-ocsp.sock";
 
 DBDataType toDBDataType(KeyType key) {
     switch(key) {
index 0f4cb76..4eac680 100644 (file)
@@ -31,6 +31,7 @@ namespace CKM {
 extern char const * const SERVICE_SOCKET_ECHO;
 extern char const * const SERVICE_SOCKET_CKM_CONTROL;
 extern char const * const SERVICE_SOCKET_CKM_STORAGE;
+extern char const * const SERVICE_SOCKET_OCSP;
 
 enum class ControlCommand : int {
     UNLOCK_USER_KEY,
index 1a14cc0..fdc032e 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <echo.h>
 #include <ckm-service.h>
+#include <ocsp-service.h>
 
 #include <key-provider.h>
 #include <CryptoService.h>
@@ -97,6 +98,7 @@ int main(void) {
 
             REGISTER_SOCKET_SERVICE(manager, CKM::EchoService);
             REGISTER_SOCKET_SERVICE(manager, CKM::CKMService);
+            REGISTER_SOCKET_SERVICE(manager, CKM::OCSPService);
 
             manager.MainLoop();
         }
index 696ff73..3b86e58 100644 (file)
@@ -21,8 +21,6 @@
  */
 #include <dpl/serialization.h>
 #include <dpl/log/log.h>
-#include <ckm/ckm-manager.h>
-#include <ckm/ckm-control.h>
 #include <ckm/ckm-error.h>
 #include <ckm/ckm-type.h>
 #include <key-provider.h>
index dbc73c9..ab29eb3 100644 (file)
  *  limitations under the License
  *
  *
- * @file        ckm-service.h
+ * @file        ckm-service.cpp
  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
  * @version     1.0
- * @brief       Sample service implementation.
+ * @brief       CKM service implementation.
  */
 #include <service-thread.h>
 #include <generic-socket-manager.h>
index 770e954..f305a05 100644 (file)
@@ -17,7 +17,7 @@
  * @file        ckm-service.h
  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
  * @version     1.0
- * @brief       Sample service implementation.
+ * @brief       CKM service implementation.
  */
 #pragma once
 
diff --git a/src/manager/service/ocsp-logic.cpp b/src/manager/service/ocsp-logic.cpp
new file mode 100644 (file)
index 0000000..a12867f
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co.
+ *
+ *  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        ocsp-logic.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       OCSP logic implementation.
+ */
+#include <ckm/ckm-error.h>
+
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+
+#include <message-buffer.h>
+
+#include <ocsp-logic.h>
+#include <ocsp.h>
+
+namespace CKM {
+
+RawBuffer OCSPLogic::ocspCheck(int commandId, const RawBufferVector &rawChain) {
+    CertificateImplVector certChain;
+    OCSPModule ocsp;
+    int retCode = CKM_API_SUCCESS;
+    int ocspStatus = CKM_API_OCSP_STATUS_INTERNAL_ERROR;
+
+    for (auto &e: rawChain) {
+        certChain.push_back(CertificateImpl(e, DataFormat::FORM_DER));
+        if (certChain.rbegin()->empty()) {
+            LogDebug("Error in parsing certificates!");
+            retCode = CKM_API_ERROR_INPUT_PARAM;
+            break;
+        }
+    }
+
+    if (retCode == CKM_API_SUCCESS)
+        ocspStatus = ocsp.verify(certChain);
+
+    MessageBuffer response;
+    Serialization::Serialize(response, commandId);
+    Serialization::Serialize(response, retCode);
+    Serialization::Serialize(response, ocspStatus);
+
+    return response.Pop();
+}
+
+} // namespace CKM
+
diff --git a/src/manager/service/ocsp-logic.h b/src/manager/service/ocsp-logic.h
new file mode 100644 (file)
index 0000000..f0dcab4
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co.
+ *
+ *  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        ocsp-logic.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       OCSP logic implementation.
+ */
+#pragma once
+
+#include <ckm/ckm-type.h>
+
+namespace CKM {
+
+class OCSPLogic {
+public:
+    OCSPLogic(){}
+    OCSPLogic(const OCSPLogic &) = delete;
+    OCSPLogic(OCSPLogic &&) = delete;
+    OCSPLogic& operator=(const OCSPLogic &) = delete;
+    OCSPLogic& operator=(OCSPLogic &&) = delete;
+
+    RawBuffer ocspCheck(int commandId, const RawBufferVector &rawChain);
+    virtual ~OCSPLogic(){}
+};
+
+
+
+} // namespace CKM
+
diff --git a/src/manager/service/ocsp-service.cpp b/src/manager/service/ocsp-service.cpp
new file mode 100644 (file)
index 0000000..6f1f2ab
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co.
+ *
+ *  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        ocsp-service.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       OCSP service implementation.
+ */
+#include <service-thread.h>
+#include <generic-socket-manager.h>
+#include <connection-info.h>
+#include <message-buffer.h>
+#include <protocols.h>
+
+#include <dpl/serialization.h>
+#include <dpl/log/log.h>
+
+#include <ocsp-service.h>
+#include <ocsp-logic.h>
+
+namespace {
+const CKM::InterfaceID SOCKET_ID_OCSP = 0;
+} // namespace anonymous
+
+namespace CKM {
+
+OCSPService::OCSPService()
+  : m_logic(new OCSPLogic())
+{}
+
+OCSPService::~OCSPService() {
+    delete m_logic;
+}
+
+GenericSocketService::ServiceDescriptionVector OCSPService::GetServiceDescription()
+{
+    return ServiceDescriptionVector {
+        {SERVICE_SOCKET_OCSP, "ckm::api-ocsp", SOCKET_ID_OCSP}
+    };
+}
+
+void OCSPService::accept(const AcceptEvent &event) {
+    LogDebug("Accept event");
+    auto &info = m_connectionInfoMap[event.connectionID.counter];
+    info.interfaceID = event.interfaceID;
+    info.credentials = event.credentials;
+}
+
+void OCSPService::write(const WriteEvent &event) {
+    LogDebug("Write event (" << event.size << " bytes )");
+}
+
+void OCSPService::process(const ReadEvent &event) {
+    LogDebug("Read event");
+    auto &info = m_connectionInfoMap[event.connectionID.counter];
+    info.buffer.Push(event.rawBuffer);
+    while(processOne(event.connectionID, info));
+}
+
+bool OCSPService::processOne(
+    const ConnectionID &conn,
+    ConnectionInfo &info)
+{
+    LogDebug ("process One");
+
+    Try {
+        if (!info.buffer.Ready())
+            return false;
+
+        auto &buffer = info.buffer;
+
+        int commandId;
+        RawBufferVector chainVector;
+        Deserialization::Deserialize(buffer, commandId);
+        Deserialization::Deserialize(buffer, chainVector);
+
+        RawBuffer response = m_logic->ocspCheck(commandId, chainVector);
+        m_serviceManager->Write(conn, response);
+
+        return true;
+    } Catch (MessageBuffer::Exception::Base) {
+        LogError("Broken protocol. Closing socket.");
+    } catch (const std::string &e) {
+        LogError("String exception(" << e << "). Closing socket");
+    } catch (...) {
+        LogError("Unknown exception. Closing socket.");
+    }
+
+    m_serviceManager->Close(conn);
+    return false;
+}
+
+void OCSPService::close(const CloseEvent &event) {
+    LogDebug("Close event");
+    m_connectionInfoMap.erase(event.connectionID.counter);
+}
+
+} // namespace CKM
+
diff --git a/src/manager/service/ocsp-service.h b/src/manager/service/ocsp-service.h
new file mode 100644 (file)
index 0000000..c288d14
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co.
+ *
+ *  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        ocsp-service.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       OCSP service implementation.
+ */
+#pragma once
+
+#include <service-thread.h>
+#include <generic-socket-manager.h>
+#include <connection-info.h>
+#include <message-buffer.h>
+
+namespace CKM {
+
+class OCSPLogic;
+
+class OCSPService
+  : public CKM::GenericSocketService
+  , public CKM::ServiceThread<OCSPService>
+{
+public:
+    OCSPService();
+    OCSPService(const OCSPService &) = delete;
+    OCSPService(OCSPService &&) = delete;
+    OCSPService& operator=(const OCSPService &) = delete;
+    OCSPService& operator=(OCSPService &&) = delete;
+    virtual ~OCSPService();
+
+    ServiceDescriptionVector GetServiceDescription();
+
+    DECLARE_THREAD_EVENT(AcceptEvent, accept)
+    DECLARE_THREAD_EVENT(WriteEvent, write)
+    DECLARE_THREAD_EVENT(ReadEvent, process)
+    DECLARE_THREAD_EVENT(CloseEvent, close)
+
+    void accept(const AcceptEvent &event);
+    void write(const WriteEvent &event);
+    void process(const ReadEvent &event);
+    void close(const CloseEvent &event);
+private:
+    bool processOne(
+        const ConnectionID &conn,
+        ConnectionInfo &info);
+
+    ConnectionInfoMap m_connectionInfoMap;
+    OCSPLogic *m_logic;
+};
+
+} // namespace CKM
+
index 125a337..1934385 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2014 Samsung Electronics Co.
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
 #include <key-manager-util.h>
 #include <dpl/log/log.h>
 
+#include <ckm/ckm-error.h>
+
 /* Maximum leeway in validity period: default 5 minutes */
 #define MAX_VALIDITY_PERIOD     (5 * 60)
 
-#define CKM_OCSP_OPER_SUCCESS  1
-#define CKM_OCSP_OPER_FAIL             0
-
 #define CKM_DEF_STRING_LEN             256
 
 namespace CKM {
@@ -51,77 +50,34 @@ OCSPModule::~OCSPModule(){
 }
 
 int OCSPModule::verify(const CertificateImplVector &certificateChain) {
-       X509 *cert = NULL;
-       X509 *issuer = NULL;
-       char url[CKM_DEF_STRING_LEN];
-       int ocspStatus = -1;
-       int result = -1;
-
-       if(&certificateChain == NULL) {
-               LogError("Error in certificateChain value");
-               ThrowMsg(OCSPModule::Exception::OCSP_Internal, "Error in certificateChain value");
-       }
-
-       if((systemCerts = loadSystemCerts(CKM_SYSTEM_CERTS_PATH)) == NULL) {
-               LogError("Error in loadSystemCerts function");
-               ThrowMsg(OCSPModule::Exception::Openssl_Error, "Error in loadSystemCerts function");
-       }
-
-       Try {
-               if((cert = X509_new()) == NULL) {
-                       LogError("Error in X509_new function");
-                       ThrowMsg(OCSPModule::Exception::Openssl_Error, "Error in X509_new function");
-               }
-
-               if((issuer = X509_new()) ==NULL) {
-                       LogError("Error in X509_new function");
-                       ThrowMsg(OCSPModule::Exception::Openssl_Error, "Error in X509_new function");
-               }
-
-               for(unsigned int i=0; i < certificateChain.size() -1; i++) {// except root certificate
-                       rawBufferToX509(&cert, certificateChain[i].getDER());
-                       rawBufferToX509(&issuer, certificateChain[i+1].getDER());
-                       extractAIAUrl(cert, url);
-                       result = ocsp_verify(cert, issuer, systemCerts, url, &ocspStatus);
-                       if(result != OCSP_STATUS_GOOD) {
-                               LogError("Fail to OCSP certification checking");
-                               ThrowMsg(OCSPModule::Exception::OCSP_Internal, "Fail to OCSP certification checking");
-                       }
-               }
-       } Catch(OCSPModule::Exception::Openssl_Error) {
-               if(cert != NULL) {
-                       X509_free(cert);
-               }
-
-               if(issuer != NULL) {
-                       X509_free(issuer);
-               }
-               ReThrowMsg(OCSPModule::Exception::Openssl_Error,"Error in openssl function !!");
-       }
-       Catch(OCSPModule::Exception::OCSP_Internal) {
-                       if(cert != NULL) {
-                               X509_free(cert);
-                       }
-
-                       if(issuer != NULL) {
-                               X509_free(issuer);
-                       }
-                       ReThrowMsg(OCSPModule::Exception::OCSP_Internal,"Fail to OCSP certification checking !!");
-       }
-
-       if(cert != NULL) {
-               X509_free(cert);
-       }
-
-       if(issuer != NULL) {
-               X509_free(issuer);
-       }
-
-       return OCSP_STATUS_GOOD;
+    char url[CKM_DEF_STRING_LEN];
+    int result = -1;
+
+    if((systemCerts = loadSystemCerts(CKM_SYSTEM_CERTS_PATH)) == NULL) {
+        LogDebug("Error in loadSystemCerts function");
+        return CKM_API_OCSP_STATUS_INTERNAL_ERROR;
+    }
+
+    for(unsigned int i=0; i < certificateChain.size() -1; i++) {// except root certificate
+        if (certificateChain[i].empty() || certificateChain[i+1].empty()) {
+            LogDebug("Error. Broken certificate chain.");
+            return CKM_API_OCSP_STATUS_INTERNAL_ERROR;
+        }
+        X509 *cert   = certificateChain[i].getX509();
+        X509 *issuer = certificateChain[i+1].getX509();
+        extractAIAUrl(cert, url);
+        result = ocsp_verify(cert, issuer, systemCerts, url);
+        if(result != CKM_API_OCSP_STATUS_GOOD) {
+            LogDebug("Fail to OCSP certification checking: " << result);
+            return result;
+        }
+    }
+
+    return CKM_API_OCSP_STATUS_GOOD;
 }
 
 
-int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCerts, char *url, int *ocspStatus) {
+int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCerts, char *url) {
        OCSP_REQUEST *req = NULL;
        OCSP_RESPONSE *resp = NULL;
        OCSP_BASICRESP *bs = NULL;
@@ -133,9 +89,9 @@ int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCert
        ASN1_GENERALIZEDTIME *thisupd = NULL;
        ASN1_GENERALIZEDTIME *nextupd = NULL;
        int use_ssl = 0;
+    int ocspStatus = -1;
        int i = 0 ,tmpIdx = 0;
        long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
-       int ret = 0;
        char subj_buf[256];
        int reason = 0;
        //    const char *reason_str = NULL;0
@@ -143,14 +99,14 @@ int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCert
 
        if (!OCSP_parse_url(url, &host, &port, &path, &use_ssl)) {
                /* report error */
-               return OCSP_STATUS_INVALID_URL;
+               return CKM_API_OCSP_STATUS_INVALID_URL;
        }
 
        cbio = BIO_new_connect(host);
        if (cbio == NULL) {
                /*BIO_printf(bio_err, "Error creating connect BIO\n");*/
                /* report error */
-               return OCSP_STATUS_INTERNAL_ERROR;
+               return CKM_API_OCSP_STATUS_INTERNAL_ERROR;
        }
 
        if (port != NULL) {
@@ -162,20 +118,20 @@ int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCert
                use_ssl_ctx = SSL_CTX_new(SSLv23_client_method());
                if (use_ssl_ctx == NULL) {
                        /* report error */
-                       return OCSP_STATUS_INTERNAL_ERROR;
+                       return CKM_API_OCSP_STATUS_INTERNAL_ERROR;
                }
 
                SSL_CTX_set_mode(use_ssl_ctx, SSL_MODE_AUTO_RETRY);
                sbio = BIO_new_ssl(use_ssl_ctx, 1);
                if (sbio == NULL) {
                        /* report error */
-                       return OCSP_STATUS_INTERNAL_ERROR;
+                       return CKM_API_OCSP_STATUS_INTERNAL_ERROR;
                }
 
                cbio = BIO_push(sbio, cbio);
                if (cbio == NULL) {
                        /* report error */
-                       return OCSP_STATUS_INTERNAL_ERROR;
+                       return CKM_API_OCSP_STATUS_INTERNAL_ERROR;
                }
        }
 
@@ -207,21 +163,24 @@ int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCert
                }
                cbio = NULL;
 
-               return OCSP_STATUS_NET_ERROR;
+               return CKM_API_OCSP_STATUS_NET_ERROR;
        }
 
        req = OCSP_REQUEST_new();
 
        if(req == NULL) {
-               return OCSP_STATUS_INTERNAL_ERROR;
+        LogDebug("Error in OCPS_REQUEST_new");
+               return CKM_API_OCSP_STATUS_INTERNAL_ERROR;
        }
        certid = OCSP_cert_to_id(NULL, cert, issuer);
        if(certid == NULL)  {
-               return OCSP_STATUS_INTERNAL_ERROR;
+        LogDebug("Error in OCSP_cert_to_id");
+               return CKM_API_OCSP_STATUS_INTERNAL_ERROR;
        }
 
        if(OCSP_request_add0_id(req, certid) == NULL) {
-               return OCSP_STATUS_INTERNAL_ERROR;
+        LogDebug("Error in OCSP_request_add0_id");
+               return CKM_API_OCSP_STATUS_INTERNAL_ERROR;
        }
 
        resp = OCSP_sendreq_bio(cbio, path, req);
@@ -255,7 +214,7 @@ int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCert
                /* report error */
                /* free stuff */
                OCSP_REQUEST_free(req);
-               return OCSP_STATUS_NET_ERROR;
+               return CKM_API_OCSP_STATUS_NET_ERROR;
        }
 
        i = OCSP_response_status(resp);
@@ -267,7 +226,7 @@ int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCert
                /* free stuff */
                OCSP_REQUEST_free(req);
                OCSP_RESPONSE_free(resp);
-               return OCSP_STATUS_REMOTE_ERROR;
+               return CKM_API_OCSP_STATUS_REMOTE_ERROR;
        }
 
        bs = OCSP_response_get1_basic(resp);
@@ -277,7 +236,7 @@ int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCert
                /* free stuff */
                OCSP_REQUEST_free(req);
                OCSP_RESPONSE_free(resp);
-               return OCSP_STATUS_INVALID_RESPONSE;
+               return CKM_API_OCSP_STATUS_INVALID_RESPONSE;
        }
 
        if(systemCerts != NULL) {
@@ -299,7 +258,7 @@ int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCert
                char errStr[100];
                ERR_error_string(err,errStr);
                // printf("OCSP_basic_verify fail.error = %s\n", errStr);
-               return OCSP_STATUS_INVALID_RESPONSE;
+               return CKM_API_OCSP_STATUS_INVALID_RESPONSE;
        }
 
        if ((i = OCSP_check_nonce(req, bs)) <= 0) {
@@ -313,12 +272,12 @@ int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCert
                        OCSP_RESPONSE_free(resp);
                        OCSP_BASICRESP_free(bs);
                        X509_STORE_free(trustedStore);
-                       return OCSP_STATUS_INVALID_RESPONSE;
+                       return CKM_API_OCSP_STATUS_INVALID_RESPONSE;
                }
        }
 
        (void)X509_NAME_oneline(X509_get_subject_name(cert), subj_buf, 255);
-       if(!OCSP_resp_find_status(bs, certid, ocspStatus, &reason,
+       if(!OCSP_resp_find_status(bs, certid, &ocspStatus, &reason,
                        &rev, &thisupd, &nextupd)) {
                /* report error */
 
@@ -328,7 +287,7 @@ int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCert
                OCSP_BASICRESP_free(bs);
                X509_STORE_free(trustedStore);
 
-               return OCSP_STATUS_INVALID_RESPONSE;
+               return CKM_API_OCSP_STATUS_INVALID_RESPONSE;
        }
 
 
@@ -345,7 +304,7 @@ int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCert
                OCSP_BASICRESP_free(bs);
                X509_STORE_free(trustedStore);
 
-               return OCSP_STATUS_INVALID_RESPONSE;
+               return CKM_API_OCSP_STATUS_INVALID_RESPONSE;
        }
 
        if (req != NULL) {
@@ -368,16 +327,17 @@ int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCert
                trustedStore = NULL;
        }
 
-       switch(*ocspStatus) {
-       case V_OCSP_CERTSTATUS_GOOD :
-               ret = OCSP_STATUS_GOOD; break;
-       case V_OCSP_CERTSTATUS_REVOKED :
-               ret = OCSP_STATUS_REVOKED; break;
-       case V_OCSP_CERTSTATUS_UNKNOWN :
-               ret = OCSP_STATUS_UNKNOWN; break;
-       }
-
-       return ret;
+    switch(ocspStatus) {
+        case V_OCSP_CERTSTATUS_GOOD:
+            return CKM_API_OCSP_STATUS_GOOD;
+        case V_OCSP_CERTSTATUS_REVOKED:
+            return CKM_API_OCSP_STATUS_REVOKED;
+        case V_OCSP_CERTSTATUS_UNKNOWN:
+            return CKM_API_OCSP_STATUS_UNKNOWN;
+        default:
+            LogError("Internal openssl error: Certificate status have value is out of bound.");
+            return CKM_API_OCSP_STATUS_INTERNAL_ERROR;
+    }
 }
 
 void OCSPModule::extractAIAUrl(X509 *cert, char *url) {
@@ -391,4 +351,5 @@ void OCSPModule::extractAIAUrl(X509 *cert, char *url) {
        return;
 }
 
-}
+} // namespace CKM
+
index 3ebefbf..d924a22 100644 (file)
@@ -1,21 +1,31 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co.
+ *
+ *  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        ocsp.h
+ * @author      Dongsun Lee (ds73.lee@samsung.com)
+ * @version     1.0
+ * @brief       OCSP implementation.
+ */
 #pragma once
 
-
 #include <openssl/x509v3.h>
 #include <ckm/ckm-type.h>
 #include <certificate-impl.h>
 #include <dpl/exception.h>
 
-#define OCSP_STATUS_GOOD                               1
-#define OCSP_STATUS_UNKNOWN                            2
-#define OCSP_STATUS_REVOKED                            3
-#define OCSP_STATUS_NET_ERROR                  4
-#define OCSP_STATUS_INVALID_URL                        5
-#define OCSP_STATUS_INVALID_RESPONSE   6
-#define OCSP_STATUS_REMOTE_ERROR               7
-#define OCSP_STATUS_INTERNAL_ERROR             8
-
-
 namespace CKM {
 
 
@@ -24,18 +34,11 @@ public:
        OCSPModule();
        virtual ~OCSPModule();
 
-    class Exception {
-       public:
-           DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
-               DECLARE_EXCEPTION_TYPE(Base, OCSP_Internal);
-                       DECLARE_EXCEPTION_TYPE(Base, Openssl_Error);
-    };
-
        // all error code from project will be defined in public client api
        // OK, UNKNOWN, REVOKED, NO_NETWORK, TIMEOUT
     int verify(const CertificateImplVector &certificateChain);
 private:
-    int ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCerts, char *url, int *ocspStatus);
+    int ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCerts, char *url);
     void extractAIAUrl(X509 *cert, char *url);
     STACK_OF(X509) *systemCerts;