Added certificate reversing for broken libSEE API 66/163266/1
authorJaroslaw Pelczar <j.pelczar@samsung.com>
Mon, 4 Dec 2017 09:07:23 +0000 (10:07 +0100)
committerJaroslaw Pelczar <j.pelczar@samsung.com>
Mon, 4 Dec 2017 09:57:52 +0000 (10:57 +0100)
Change-Id: I3ce62b70675feb4fa05a81ec357bea0c58a92bca
Signed-off-by: Jaroslaw Pelczar <j.pelczar@samsung.com>
CMakeLists.txt
cmake/CheckFrameworks.cmake
dcm-daemon/CMakeLists.txt
dcm-daemon/dummy-backend/dummycryptobackend.cpp
dcm-daemon/main.cpp
dcm-daemon/mbedtls_wrapper.h [new file with mode: 0644]
dcm-daemon/see-backend/seebackendcontext.cpp
dcm-daemon/see-backend/seebackendcontext.h
tests/hw_api_test.cpp

index bc49dfc..68f1c4f 100644 (file)
@@ -33,6 +33,11 @@ INCLUDE(cmake/CheckFrameworks.cmake)
 INCLUDE(cmake/CStandard.cmake)
 
 option(ENABLE_DUMMY_BACKEND "Enable dummy crypto backend" OFF)
+option(ENABLE_SYSTEMD_SUPPORT "Enable support for systemd" ON)
+
+IF(ENABLE_SYSTEMD_SUPPORT AND NOT SYSTEMD_FOUND)
+       message(FATAL_ERROR "systemd support required but systemd not found")
+ENDIF() 
 
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/dcm_build_config.h.in
        ${CMAKE_CURRENT_BINARY_DIR}/dcm_build_config.h)
@@ -43,7 +48,12 @@ configure_file(packaging/device-certificate-manager-tests.manifest.in
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
 include_directories(shared)
 
-SET(DCM_UNIX_SOCKET_PATH               "/run/device-certificate-manager.socket")
+IF(ENABLE_SYSTEMD_SUPPORT)
+       SET(DCM_UNIX_SOCKET_PATH                "/run/device-certificate-manager.socket")
+ELSE()
+       SET(DCM_UNIX_SOCKET_PATH                "/tmp/device-certificate-manager.socket")
+ENDIF()
+
 add_definitions(-DDCM_UNIX_SOCKET_PATH="${DCM_UNIX_SOCKET_PATH}")
 
 add_subdirectory(dcm-daemon)
index cb5909d..34ed41b 100644 (file)
@@ -41,6 +41,9 @@ find_library(MBEDTLS_LIB
 
 find_library(MBEDCRYPTO_LIB
        mbedcrypto)
+       
+find_library(MBEDX509_LIB
+       mbedx509)
 
 IF(MBEDTLS_LIB-NOTFOUND)
        message(FATAL_ERROR "mbedtls not found ...")
@@ -50,6 +53,10 @@ IF(MBEDCRYPTO_LIB-NOTFOUND)
        message(FATAL_ERROR "mbedcrypto not found ...")
 ENDIF()
 
+IF(MBEDX509_LIB-NOTFOUND)
+       message(FATAL_ERROR "mbedx509 not found ...")
+ENDIF()
+
 CHECK_INCLUDE_FILES("mbedtls/rsa.h;mbedtls/ecdsa.h" MBEDTLS_HEADERS_OK)
 
 IF(NOT MBEDTLS_HEADERS_OK)
index 17a3593..90f64a4 100644 (file)
@@ -28,12 +28,12 @@ IF(SECURITY_MANAGER_FOUND)
        add_definitions(-DUSE_SECURITY_MANAGER=1)
 ENDIF(SECURITY_MANAGER_FOUND)
 
-IF(SYSTEMD_FOUND)
+IF(ENABLE_SYSTEMD_SUPPORT)
        include_directories(${SYSTEMD_INCLUDE_DIRS})
        link_directories(${SYSTEMD_LIBRARY_DIRS})
        add_definitions(${SYSTEMD_CFLAGS_OTHER})
        add_definitions(-DUSE_SYSTEMD_API=1)
-ENDIF(SYSTEMD_FOUND)
+ENDIF(ENABLE_SYSTEMD_SUPPORT)
 
 IF(ARTIK_SECURITY_FOUND)
        include_directories(${ARTIK_SECURITY_INCLUDE_DIRS})
@@ -96,7 +96,10 @@ target_link_libraries(device-certificate-managerd
        ${Boost_FILESYSTEM_LIBRARY}
        ${Boost_PROGRAM_OPTIONS_LIBRARY}
        ${Boost_SYSTEM_LIBRARY} 
-       ${CMAKE_THREAD_LIBS_INIT}       
+       ${CMAKE_THREAD_LIBS_INIT}
+       ${MBEDTLS_LIB}
+       ${MBEDCRYPTO_LIB}
+       ${MBEDX509_LIB}
        device-certificate-manager
        dl)
 
@@ -108,13 +111,13 @@ IF(SECURITY_MANAGER_FOUND)
        target_link_libraries(device-certificate-managerd ${SECURITY_MANAGER_LIBRARIES})
 ENDIF(SECURITY_MANAGER_FOUND)  
 
-IF(SYSTEMD_FOUND)
+IF(ENABLE_SYSTEMD_SUPPORT)
        target_link_libraries(device-certificate-managerd ${SYSTEMD_LIBRARIES})
-ENDIF(SYSTEMD_FOUND)   
+ENDIF(ENABLE_SYSTEMD_SUPPORT)  
 
 IF(SMACK_FOUND)
        target_link_libraries(device-certificate-managerd ${SMACK_LIBRARIES})
-ENDIF(SMACK_FOUND)     
+ENDIF(SMACK_FOUND)
 
 ###### Installation #######
 
index 059e37b..03c44a5 100644 (file)
 crypto_backend_registration<dummy_crypto_backend> dummy_crypto_backend::dummy_crypto_backend_registration;
 
 dummy_crypto_backend::dummy_crypto_backend() {
-
+       BOOST_LOG_FUNCTION();
 }
 
 dummy_crypto_backend::~dummy_crypto_backend() {
+       BOOST_LOG_FUNCTION();
 }
 
 std::shared_ptr<abstract_crypto_backend_context> dummy_crypto_backend::create_client_context(
index 7012b3a..03d75ac 100644 (file)
@@ -87,7 +87,7 @@ void init_logging()
        sink->locked_backend()->set_severity_mapper(mapping);
        sink->locked_backend()->set_log_domain("dcm-server");
 
-#if !defined(NDEBUG)
+#if defined(NDEBUG) && !defined(DEBUG)
        sink->set_filter(_severity >= log_severity::normal);
 #endif
 
diff --git a/dcm-daemon/mbedtls_wrapper.h b/dcm-daemon/mbedtls_wrapper.h
new file mode 100644 (file)
index 0000000..03d67b6
--- /dev/null
@@ -0,0 +1,49 @@
+/******************************************************************
+ *
+ * Copyright 2017 Samsung Electronics All Rights Reserved.
+ *
+ * Author: Jaroslaw Pelczar <j.pelczar@samsung.com>
+ *
+ * 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.
+ *
+ ******************************************************************/
+
+#ifndef DCM_DAEMON_MBEDTLS_WRAPPER_H_
+#define DCM_DAEMON_MBEDTLS_WRAPPER_H_
+
+#include <mbedtls/x509_crt.h>
+#include <mbedtls/error.h>
+#include <boost/noncopyable.hpp>
+#include <string>
+
+struct mbedtls_x509_crt_wrapper : public mbedtls_x509_crt, public boost::noncopyable {
+       mbedtls_x509_crt_wrapper() {
+               mbedtls_x509_crt_init(this);
+       }
+
+       ~mbedtls_x509_crt_wrapper() {
+               mbedtls_x509_crt_free(this);
+       }
+
+       int parse(const std::string& pem) {
+               return mbedtls_x509_crt_parse(this, reinterpret_cast<const unsigned char *>(pem.c_str()), pem.size() + 1);
+       }
+};
+
+static inline std::string mbedtls_error_to_string(int error) {
+       char buffer[256];
+       mbedtls_strerror(error, buffer, sizeof(buffer));
+       return std::string(buffer);
+}
+
+#endif /* DCM_DAEMON_MBEDTLS_WRAPPER_H_ */
index 2ebb4a8..4c06068 100644 (file)
@@ -47,6 +47,37 @@ see_backend_context::~see_backend_context()
        BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Deleting SEE context " << this;
 }
 
+static const std::string sPEMHeader("-----BEGIN CERTIFICATE-----\n");
+static const std::string sPEMFooter("-----END CERTIFICATE-----\n");
+
+void see_backend_context::fix_certificate_chain(std::string& cert_chain) {
+       BOOST_LOG_FUNCTION();
+
+       std::list<std::string> certs;
+
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Parse certificate chain";
+
+       auto it = cert_chain.find(sPEMHeader);
+       while(it != std::string::npos) {
+               auto footer_it = cert_chain.find(sPEMFooter, it + sPEMHeader.length() - 1);
+
+               if(footer_it == std::string::npos) {
+                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Invalid format of certificate list returned by backend: no footer";
+                       throw std::runtime_error("Can't find certificate footer");
+               }
+
+               std::string cert_pem(cert_chain.substr(it, footer_it + sPEMFooter.size() - it));
+
+               certs.emplace_front(std::move(cert_pem));
+               it = cert_chain.find(sPEMHeader, footer_it + sPEMFooter.length() - 1);
+       }
+
+       cert_chain.resize(0);
+
+       for(const auto& cert: certs)
+               cert_chain.append(cert);
+}
+
 int see_backend_context::request_certificate_chain(std::string& mutable_chain)
 {
        BOOST_LOG_FUNCTION();
@@ -74,6 +105,12 @@ int see_backend_context::request_certificate_chain(std::string& mutable_chain)
 
        try {
                mutable_chain.assign((const char *)cert.data, cert.length);
+
+               /*
+                * libSEE bug workaround - we need to reverse certificate order
+                * as library returns them in incorrect sequence
+                */
+               fix_certificate_chain(mutable_chain);
        } catch(...) {
                BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "SEE: Got exception when assigning data";
                free(cert.data);
index 14d7ad8..cb894b3 100644 (file)
@@ -39,6 +39,9 @@ public:
        virtual unsigned int key_length() override;
 
 private:
+       void fix_certificate_chain(std::string& cert_chain);
+
+private:
        CryptoKeyType                                   fKeyType;
        std::weak_ptr<see_backend>              fBackendPtr;
 };
index 70e21ce..19e929f 100644 (file)
@@ -9,6 +9,7 @@
 #include <mbedtls/ctr_drbg.h>
 #include <mbedtls/error.h>
 #include <mbedtls/certs.h>
+#include <mbedtls/x509_crt.h>
 
 #include <cassert>
 
@@ -70,6 +71,24 @@ int main()
        std::cerr << "Can't request certificate chain" << std::endl;
     } else {
        std::cout << "Certificate received" << std::endl;
+
+       mbedtls_x509_crt chain;
+       mbedtls_x509_crt_init(&chain);
+
+       int error = mbedtls_x509_crt_parse(&chain, certChain, certChainLen);
+
+       if(error != 0) {
+               std::cerr << "Can't parse certificate chain !!!" << std::endl;
+               DCM_HWFreeKeyContext(keyContext);
+               mbedtls_x509_crt_free(&chain);
+               mbedtls_ctr_drbg_free( &ctr_drbg );
+           mbedtls_entropy_free( &entropy );
+               return -1;
+       }
+
+       std::cout << "Certificate chain parsed successfuly" << std::endl;
+
+       mbedtls_x509_crt_free(&chain);
     }
 
        unsigned char to_sign[32] = {