Add test case for certificate rewriter 90/163990/1
authorJaroslaw Pelczar <j.pelczar@samsung.com>
Thu, 14 Dec 2017 10:46:31 +0000 (11:46 +0100)
committerJaroslaw Pelczar <j.pelczar@samsung.com>
Thu, 14 Dec 2017 10:53:19 +0000 (11:53 +0100)
Change-Id: I10a3746c12ba922becb1e92b8e746d6c01b57338
Signed-off-by: Jaroslaw Pelczar <j.pelczar@samsung.com>
packaging/device-certificate-manager.spec
tests/CMakeLists.txt
tests/test_cert_rewriter.cpp [new file with mode: 0644]
tests/test_data/cert.pem [new file with mode: 0644]
tests/test_data/cert2.pem [new file with mode: 0644]
tests/test_data/create_data.sh [new file with mode: 0755]
tests/test_data/server.csr [new file with mode: 0644]
tests/test_data/server.key [new file with mode: 0644]
tests/test_data/server.pass.key [new file with mode: 0644]
tests/test_data/server2.csr [new file with mode: 0644]
tests/test_data/tizen.org.pem [new file with mode: 0644]

index 1d722f2..0c57923 100644 (file)
@@ -117,3 +117,4 @@ fi
 %license LICENSE
 %{_bindir}/dcm_example_client
 %{_bindir}/dcm_hw_api_test
+%{_bindir}/dcm_test_cert_rewriter
index 3122c2a..68742eb 100644 (file)
@@ -1,6 +1,12 @@
-include_directories(../dcm-client ../shared)
+include_directories(../dcm-client ../shared ../dcm-daemon)
 include_directories(${CMAKE_BINARY_DIR}/dcm-client)
 
+include_directories(${Boost_INCLUDE_DIRS})
+link_directories(${Boost_LIBRARY_DIRS})
+
+ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK)
+ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK)
+
 add_executable(dcm_example_client example_client.cpp)
 target_link_libraries(dcm_example_client device-certificate-manager)
 
@@ -11,6 +17,36 @@ install(TARGETS dcm_example_client dcm_hw_api_test
        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 IF(Boost_UNIT_TEST_FRAMEWORK_FOUND)
+       add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cert_pem.c
+               COMMAND $<TARGET_FILE:helper_bin2c> ${CMAKE_CURRENT_SOURCE_DIR}/test_data/cert.pem ${CMAKE_CURRENT_BINARY_DIR}/cert_pem.c test_data_cert_pem
+               DEPENDS helper_bin2c ${CMAKE_CURRENT_SOURCE_DIR}/test_data/cert.pem)
+       
+       add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cert_pem2.c
+               COMMAND $<TARGET_FILE:helper_bin2c> ${CMAKE_CURRENT_SOURCE_DIR}/test_data/cert2.pem ${CMAKE_CURRENT_BINARY_DIR}/cert_pem2.c test_data_cert_pem2
+               DEPENDS helper_bin2c ${CMAKE_CURRENT_SOURCE_DIR}/test_data/cert2.pem)
+       
+       add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/tizen_org_pem.c
+               COMMAND $<TARGET_FILE:helper_bin2c> ${CMAKE_CURRENT_SOURCE_DIR}/test_data/tizen.org.pem ${CMAKE_CURRENT_BINARY_DIR}/tizen_org_pem.c tizen_org_pem
+               DEPENDS helper_bin2c ${CMAKE_CURRENT_SOURCE_DIR}/test_data/tizen.org.pem)
+       
+       add_executable(dcm_test_cert_rewriter
+               test_cert_rewriter.cpp
+               ../dcm-daemon/cert_utils.cpp
+               ${CMAKE_CURRENT_BINARY_DIR}/cert_pem.c
+               ${CMAKE_CURRENT_BINARY_DIR}/cert_pem2.c
+               ${CMAKE_CURRENT_BINARY_DIR}/tizen_org_pem.c)
+               
+       target_link_libraries(dcm_test_cert_rewriter 
+                       ${Boost_LOG_LIBRARY}
+                       ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}
+                       ${Boost_SYSTEM_LIBRARY}  
+                       ${CMAKE_THREAD_LIBS_INIT}
+                       ${MBEDTLS_LIB}
+                       ${MBEDCRYPTO_LIB}
+                       ${MBEDX509_LIB})
+
+       install(TARGETS dcm_test_cert_rewriter
+               RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 ELSE()
        message(STATUS "Boost::test library not found. Disabling unit test build")
 ENDIF()
diff --git a/tests/test_cert_rewriter.cpp b/tests/test_cert_rewriter.cpp
new file mode 100644 (file)
index 0000000..cd3d50a
--- /dev/null
@@ -0,0 +1,285 @@
+/******************************************************************
+ *
+ * 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.
+ *
+ ******************************************************************/
+
+#define BOOST_TEST_MODULE Cert Parser
+#include <boost/test/unit_test.hpp>
+#include <mbedtls_wrapper.h>
+#include <mbedtls/pem.h>
+#include <cert_utils.h>
+#include <cstdio>
+#include <iostream>
+#include <algorithm>
+
+#define PEM_BEGIN_CRT           "-----BEGIN CERTIFICATE-----\n"
+#define PEM_END_CRT             "-----END CERTIFICATE-----\n"
+
+namespace bt = boost::unit_test;
+
+extern "C" {
+       extern size_t test_data_cert_pem_size;
+       extern unsigned char test_data_cert_pem[];
+       extern size_t test_data_cert_pem2_size;
+       extern unsigned char test_data_cert_pem2[];
+       extern size_t tizen_org_pem_size;
+       extern unsigned char tizen_org_pem[];
+}
+
+BOOST_AUTO_TEST_CASE(test_create_destroy)
+{
+       x509_crt_rewriter test_obj;
+       std::unique_ptr<x509_crt_rewriter> test_obj2(new x509_crt_rewriter());
+}
+
+BOOST_AUTO_TEST_CASE(test_parse_invalid_cert)
+{
+       x509_crt_rewriter test_obj;
+
+       std::string invalid_cert("eir09r0934iut9083ug09854ug98u489ghu3908tguj");
+
+       int error = test_obj.parse(reinterpret_cast<const unsigned char *>(invalid_cert.c_str()),
+                       invalid_cert.size());
+
+       BOOST_REQUIRE_NE(error, 0);
+}
+
+BOOST_AUTO_TEST_CASE(test_parse_valid_pem)
+{
+       x509_crt_rewriter test_obj;
+
+       int error = test_obj.parse(test_data_cert_pem, test_data_cert_pem_size + 1);
+       BOOST_REQUIRE_EQUAL(error, 0);
+       error = test_obj.parse(test_data_cert_pem2, test_data_cert_pem2_size + 1);
+       BOOST_REQUIRE_EQUAL(error, 0);
+}
+
+BOOST_AUTO_TEST_CASE(test_parse_pem_without_null)
+{
+       x509_crt_rewriter test_obj;
+
+       int error = test_obj.parse(test_data_cert_pem, test_data_cert_pem_size);
+
+       BOOST_REQUIRE_NE(error, 0);
+}
+
+BOOST_AUTO_TEST_CASE(test_parse_write_pem_without_sorting)
+{
+       x509_crt_rewriter test_obj;
+
+       int error = test_obj.parse(test_data_cert_pem, test_data_cert_pem_size + 1);
+       BOOST_REQUIRE_EQUAL(error, 0);
+
+       BOOST_REQUIRE_THROW(test_obj.emit_pem(), std::exception);
+}
+
+BOOST_AUTO_TEST_CASE(test_parse_write_1_pem_with_sorting)
+{
+       x509_crt_rewriter test_obj;
+
+       int error = test_obj.parse(test_data_cert_pem, test_data_cert_pem_size + 1);
+       BOOST_REQUIRE(error == 0);
+
+       test_obj.sort_chain();
+
+       std::string output_cert = test_obj.emit_pem();
+
+       BOOST_REQUIRE(!output_cert.empty());
+       BOOST_REQUIRE_EQUAL(output_cert[output_cert.length() - 1], 0);
+       BOOST_REQUIRE_EQUAL(output_cert.substr(0, sizeof(PEM_BEGIN_CRT) - 1), PEM_BEGIN_CRT);
+
+       std::string cert_end = output_cert.substr(output_cert.length() - sizeof(PEM_END_CRT), sizeof(PEM_END_CRT) - 1);
+
+       BOOST_REQUIRE_EQUAL(cert_end, PEM_END_CRT);
+
+       BOOST_CHECK_EQUAL(output_cert, std::string((const char *)test_data_cert_pem, test_data_cert_pem_size + 1));
+}
+
+BOOST_AUTO_TEST_CASE(test_parse_same_cert_twice)
+{
+       x509_crt_rewriter test_obj;
+
+       std::string primary_cert((const char *)test_data_cert_pem, test_data_cert_pem_size);
+
+       std::string to_parse(primary_cert);
+       to_parse += primary_cert;
+
+       int error = test_obj.parse((const unsigned char *)to_parse.c_str(), to_parse.length() + 1);
+       BOOST_REQUIRE(error == 0);
+
+       test_obj.sort_chain();
+
+       BOOST_REQUIRE_THROW(test_obj.emit_pem(), std::exception);
+}
+
+BOOST_AUTO_TEST_CASE(test_parse_same_cert_three_times)
+{
+       x509_crt_rewriter test_obj;
+
+       std::string primary_cert((const char *)test_data_cert_pem, test_data_cert_pem_size);
+
+       std::string to_parse(primary_cert);
+       to_parse += primary_cert;
+       to_parse += primary_cert;
+
+       int error = test_obj.parse((const unsigned char *)to_parse.c_str(), to_parse.length() + 1);
+       BOOST_REQUIRE(error == 0);
+
+       test_obj.sort_chain();
+
+       BOOST_REQUIRE_THROW(test_obj.emit_pem(), std::exception);
+}
+
+BOOST_AUTO_TEST_CASE(test_parse_different_certs)
+{
+       x509_crt_rewriter test_obj;
+
+       std::string cert1((const char *)test_data_cert_pem, test_data_cert_pem_size);
+       std::string cert2((const char *)test_data_cert_pem2, test_data_cert_pem2_size);
+
+       std::string to_parse(cert1);
+       to_parse += cert2;
+
+       int error = test_obj.parse((const unsigned char *)to_parse.c_str(), to_parse.length() + 1);
+       BOOST_REQUIRE_EQUAL(error, 0);
+
+       test_obj.sort_chain();
+
+       std::string result_pem = test_obj.emit_pem();
+
+       std::string result_pem_without_zero = result_pem.substr(0, result_pem.length() - 1);
+
+       BOOST_REQUIRE((result_pem_without_zero == cert1 + cert2) || (result_pem_without_zero == cert2 + cert1));
+}
+
+BOOST_AUTO_TEST_CASE(test_parse_server_pem_tizen_org)
+{
+       x509_crt_rewriter test_obj;
+
+       int error = test_obj.parse(tizen_org_pem, tizen_org_pem_size + 1);
+       BOOST_REQUIRE(error == 0);
+
+       test_obj.sort_chain();
+
+       std::string output_cert = test_obj.emit_pem();
+
+       BOOST_CHECK_EQUAL(output_cert, std::string((const char *)tizen_org_pem, tizen_org_pem_size + 1));
+}
+
+static std::string serialize_cert_chain(const std::vector<mbedtls_x509_crt *>& vec)
+{
+       std::string buffer;
+
+       size_t all_size = 0;
+
+       for(auto cert : vec) {
+               all_size += cert->raw.len * 4 + sizeof(PEM_BEGIN_CRT) + sizeof(PEM_END_CRT);
+       }
+
+       buffer.resize(all_size);
+
+       unsigned char * out_buffer = (unsigned char *)buffer.c_str();
+       size_t out_capacity = buffer.size();
+       size_t total_size = 0;
+       size_t this_len;
+
+       for(auto cert : vec) {
+               int error = mbedtls_pem_write_buffer(PEM_BEGIN_CRT,
+                               PEM_END_CRT,
+                               cert->raw.p,
+                               cert->raw.len,
+                               out_buffer + total_size,
+                               out_capacity - total_size,
+                               &this_len);
+
+               if(error != 0) {
+                       throw std::runtime_error("Certificate write failure");
+               }
+
+               // Account for final 0 byte
+               total_size += this_len - 1;
+       }
+
+       buffer.resize(total_size);
+       buffer.push_back(0);
+
+       return buffer;
+}
+
+BOOST_AUTO_TEST_CASE(test_case_shuffle_certificates)
+{
+       mbedtls_x509_crt_wrapper chain;
+
+       int parse_result = mbedtls_x509_crt_parse(&chain, tizen_org_pem, tizen_org_pem_size + 1);
+       BOOST_REQUIRE_EQUAL(parse_result, 0);
+
+       std::vector<mbedtls_x509_crt *> certs;
+
+       for(mbedtls_x509_crt * cert = &chain ; cert ; cert = cert->next)
+               certs.push_back(cert);
+
+       std::sort(certs.begin(), certs.end());
+
+       std::string correct_pem(std::string((const char *)tizen_org_pem, tizen_org_pem_size + 1));
+
+       do {
+               std::string permuted_chain = serialize_cert_chain(certs);
+
+               x509_crt_rewriter test_obj;
+
+               int error = test_obj.parse((unsigned char *)permuted_chain.c_str(), permuted_chain.length());
+               BOOST_REQUIRE(error == 0);
+
+               test_obj.sort_chain();
+
+               std::string pem = test_obj.emit_pem();
+
+               BOOST_CHECK_EQUAL(pem, correct_pem);
+       } while(std::next_permutation(certs.begin(), certs.end()));
+}
+
+BOOST_AUTO_TEST_CASE(test_case_incomplete_chain)
+{
+       mbedtls_x509_crt_wrapper chain;
+
+       int parse_result = mbedtls_x509_crt_parse(&chain, tizen_org_pem, tizen_org_pem_size + 1);
+       BOOST_REQUIRE_EQUAL(parse_result, 0);
+
+       std::vector<mbedtls_x509_crt *> certs;
+
+       for(mbedtls_x509_crt * cert = &chain ; cert ; cert = cert->next)
+               certs.push_back(cert);
+
+       // Remove one from chain
+       certs.erase(certs.begin() + 1);
+
+       std::string correct_pem(std::string((const char *)tizen_org_pem, tizen_org_pem_size + 1));
+
+       std::string broken_chain = serialize_cert_chain(certs);
+
+       x509_crt_rewriter test_obj;
+
+       int error = test_obj.parse((unsigned char *)broken_chain.c_str(), broken_chain.length());
+       BOOST_REQUIRE(error == 0);
+
+       test_obj.sort_chain();
+
+       std::string pem = test_obj.emit_pem();
+
+       BOOST_CHECK_NE(pem, correct_pem);
+}
diff --git a/tests/test_data/cert.pem b/tests/test_data/cert.pem
new file mode 100644 (file)
index 0000000..cb20658
--- /dev/null
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC/DCCAeQCCQD0NJTBwmAEfzANBgkqhkiG9w0BAQsFADBAMQswCQYDVQQGEwJG
+UjEMMAoGA1UECgwDZm9vMQwwCgYDVQQLDANCYXIxFTATBgNVBAMMDGV4YW1wbGUx
+LmNvbTAeFw0xNzEyMTQxMDEwMTFaFw0xODEyMTQxMDEwMTFaMEAxCzAJBgNVBAYT
+AkZSMQwwCgYDVQQKDANmb28xDDAKBgNVBAsMA0JhcjEVMBMGA1UEAwwMZXhhbXBs
+ZTEuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1DQ1DoZ2useB
+jW8gDSRhmMsK9QLRHOmrQNNjnYFv8yC+Q9juzc5UBdXxb0+e6fb7O2NQC4oV5M4W
+1aJ6iRsiQu/Z/UkLJFvO6+ftMTZ6CivZbO/5v43tt6grZeXQKiJNm9T4eUF1uEPx
+fN8E4LGA/Tc0oPt7Om6MUsIQjOOUhMkCCfKnb9b10yK/i8Fwf0lFdIwQLZC/67e6
+dGKsQKUOzUizsPdPc8tYvL27n4CHGeAm88KqGi7+ayoKsLNNVo6c4xaKEOzFqNNf
+Z9L8hAvwkKQNqe5WiqSbsX+/DUVP3h9ReneAJrCbA25FFpxtsyV5/Pqv5QbSNis8
+wzPGUaETjwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCUktsuWOe/mPY6eMfk7aHC
+rMQwozyjqAY8zXrJWjTS8UTRal4fBwzsk6qOkPf5ftdNOOlIf8IABYFOEUrqAVRM
+YBhgkocFjJ1Xp5NwlQP5BE3mcoE3+v/KzDnls6naFzcJORZMF9dsHy9fa5MQcBFm
+mIHN89y6RcjMJi3DCENfYtfbmc7o/0tLj5GBBLuloHoXh99+Kf1M63w5YcBzYv9Y
+mKrOuB/A3C6i7Q43m6ouxJq66Dwcd5rrWbEi2P7ei2magnqdH5zf8y7vSuBYlHn8
+J1Vuwy3vOFM5l0uOEwy1wuX/jKRWauFlYiVBsA2dpYNK/yItoIPBZR+nxyNOE4DE
+-----END CERTIFICATE-----
diff --git a/tests/test_data/cert2.pem b/tests/test_data/cert2.pem
new file mode 100644 (file)
index 0000000..54af3f5
--- /dev/null
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC/DCCAeQCCQCzOfilAMPqATANBgkqhkiG9w0BAQsFADBAMQswCQYDVQQGEwJG
+UjEMMAoGA1UECgwDZm9vMQwwCgYDVQQLDANCYXIxFTATBgNVBAMMDGV4YW1wbGUy
+LmNvbTAeFw0xNzEyMTQxMDEwMTFaFw0xODEyMTQxMDEwMTFaMEAxCzAJBgNVBAYT
+AkZSMQwwCgYDVQQKDANmb28xDDAKBgNVBAsMA0JhcjEVMBMGA1UEAwwMZXhhbXBs
+ZTIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1DQ1DoZ2useB
+jW8gDSRhmMsK9QLRHOmrQNNjnYFv8yC+Q9juzc5UBdXxb0+e6fb7O2NQC4oV5M4W
+1aJ6iRsiQu/Z/UkLJFvO6+ftMTZ6CivZbO/5v43tt6grZeXQKiJNm9T4eUF1uEPx
+fN8E4LGA/Tc0oPt7Om6MUsIQjOOUhMkCCfKnb9b10yK/i8Fwf0lFdIwQLZC/67e6
+dGKsQKUOzUizsPdPc8tYvL27n4CHGeAm88KqGi7+ayoKsLNNVo6c4xaKEOzFqNNf
+Z9L8hAvwkKQNqe5WiqSbsX+/DUVP3h9ReneAJrCbA25FFpxtsyV5/Pqv5QbSNis8
+wzPGUaETjwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQC+YpsMfU7PnAW28KXjlEnk
+m1Z7NJ+tan64Xmdr8kNZEFqfpO5xTQimgvThe/eRvWEt9oG9cdcLXkSOM3mDbRPa
+TdF4GED8SZFTcoymibfZAIcslkW9//P0x4U6TMOHdYYmhvs+8G2hfR3r3ufjtONo
+RfhypkfPAmdU3mQk/ibJXnZaBR+RHoFp6JaSna3l64CO3e8xjsHQZuNpm6RuBYIj
+8bQTcmwLQ+ijOCLYG8GDH9VdOr8DIe1x1Cw8KmvE/g1EXQyhj35SyA3l5fY5AfkL
+h07BpDZZsNJ5OFk9oQ+rOzoN8f18ZrbsSyuqfXacn+Aey3RdOPDCCrOCPgF8gI1t
+-----END CERTIFICATE-----
diff --git a/tests/test_data/create_data.sh b/tests/test_data/create_data.sh
new file mode 100755 (executable)
index 0000000..1fcb242
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/sh
+openssl genrsa -des3 -passout pass:x -out server.pass.key
+openssl rsa -passin pass:x -in server.pass.key -out server.key
+openssl req -new -key server.key -out server.csr -subj "/C=FR/O=foo/OU=Bar/CN=example1.com"
+openssl x509 -req -days 365 -in server.csr -signkey server.key -out cert.pem
+openssl req -new -key server.key -out server2.csr -subj "/C=FR/O=foo/OU=Bar/CN=example2.com"
+openssl x509 -req -days 365 -in server2.csr -signkey server.key -out cert2.pem
diff --git a/tests/test_data/server.csr b/tests/test_data/server.csr
new file mode 100644 (file)
index 0000000..b58b889
--- /dev/null
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIChTCCAW0CAQAwQDELMAkGA1UEBhMCRlIxDDAKBgNVBAoMA2ZvbzEMMAoGA1UE
+CwwDQmFyMRUwEwYDVQQDDAxleGFtcGxlMS5jb20wggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQDUNDUOhna6x4GNbyANJGGYywr1AtEc6atA02OdgW/zIL5D
+2O7NzlQF1fFvT57p9vs7Y1ALihXkzhbVonqJGyJC79n9SQskW87r5+0xNnoKK9ls
+7/m/je23qCtl5dAqIk2b1Ph5QXW4Q/F83wTgsYD9NzSg+3s6boxSwhCM45SEyQIJ
+8qdv1vXTIr+LwXB/SUV0jBAtkL/rt7p0YqxApQ7NSLOw909zy1i8vbufgIcZ4Cbz
+wqoaLv5rKgqws01WjpzjFooQ7MWo019n0vyEC/CQpA2p7laKpJuxf78NRU/eH1F6
+d4AmsJsDbkUWnG2zJXn8+q/lBtI2KzzDM8ZRoROPAgMBAAGgADANBgkqhkiG9w0B
+AQsFAAOCAQEAvlGH6Xq0/2DKpkqUaslehAnGIPAPMDufz1r5zlO7vsikiuURrcgx
+kwXvUuOsgt6pdImtfqhhGgUeJw9HgJcHPsoQJob4AnpD2FjaJbffQHJmoOJeWtjg
+vmaLDzHL0R7IMPLwuWXUB8h8Z0bayK2cQRpREGdFl7fA53ShbyVX+Bx4ul0q0uF9
+Ns5UHQPQd5rs8nuLryJ8l/SrHI+9zSBH/NMJ69suwkxoyUN6tW72ZbGE7XTIsJ1C
+kpVt4FehB6a5V0WblROzH9NIruncPBON+C+MEasku8o9FFh2B4p6RNuR4ZuD8VIk
+e7vmifHoo76/yay6Pa4KwoOL1vTxK7jvQw==
+-----END CERTIFICATE REQUEST-----
diff --git a/tests/test_data/server.key b/tests/test_data/server.key
new file mode 100644 (file)
index 0000000..56de1d1
--- /dev/null
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEA1DQ1DoZ2useBjW8gDSRhmMsK9QLRHOmrQNNjnYFv8yC+Q9ju
+zc5UBdXxb0+e6fb7O2NQC4oV5M4W1aJ6iRsiQu/Z/UkLJFvO6+ftMTZ6CivZbO/5
+v43tt6grZeXQKiJNm9T4eUF1uEPxfN8E4LGA/Tc0oPt7Om6MUsIQjOOUhMkCCfKn
+b9b10yK/i8Fwf0lFdIwQLZC/67e6dGKsQKUOzUizsPdPc8tYvL27n4CHGeAm88Kq
+Gi7+ayoKsLNNVo6c4xaKEOzFqNNfZ9L8hAvwkKQNqe5WiqSbsX+/DUVP3h9ReneA
+JrCbA25FFpxtsyV5/Pqv5QbSNis8wzPGUaETjwIDAQABAoIBAQDHW+zkoor02u3p
+dBcGgcF3DHpUyLqwkQ6krnQNy0bjgUV+9FUV4NurR921F3ZSlAhfOORAkxASj1OA
+jU7VdDpx7Gg9vtvK4r25f4ClFWr+F0gDQki+H5bPThzHdGpmyydiWWi+cjMoVByR
+lew9NEXcnnrBKsIQmT8XmN53nm8vdvk0lhiE8CMBvefHNZhnGNVceLdmj4eySNTF
+ywDrDf+pvXQz90W2m9F7H8PIIAP/LWe9yAPrGIl/vEr+h2aNrI4n5RrvGivQizh8
+mw0/7mpgX5dp0quHa4Nm4CPfbA+DMY13QGI/Y03UEdS/gq7d07+57DEoCrSKa/Gq
+t2aamq6RAoGBAPxJTpLPe+FgzRs8og1hDgFQhSKv24RLcfrIADj0FXGphGphk8Ix
+Sq3hKbziPCBspnlPTzanTapojZ0Ov6+xfylyvcRzyCAcoUUKNYkIhqc/g8Q+Jq6W
+Pr5QUTsfmvWHM+xrbSqtSFNb2L4PB4W1m9chjRtlGxuuemS2ec1dK1PlAoGBANdT
+23vWR9ZlJFkfMXvc4726YBKseMbECUfVKndD80zHCqeFgod9ONPPDsgQVX1KXsvB
+znnuLx6Sd0MegMvARe2UG4Xn9qxnt/UHW5lwlBqQAoaRrsUPNBmXnlE8yjtGaIka
+qHfRtsrDXk68HEKJ0DJyRH7vnkqDIbrPD5G3CvpjAoGAYVu82cT+LoSXwnoMo5Mf
+v3weVLt+wDgJPVkvVMtE9z8O3arYRamWAzIQVFcOEwk62Te0/wdjXm7Ir6KAcMHT
+q+AewZBY26OQzL7a2A4VQLevFu1RKjDK99Cw+FsDBtttO0BduYlzjs+z/ex4362s
+/UFyXe8PngggLXuJ16mrzc0CgYEAorqFDLmL4MLfDVs9klYE5sWLBZHCVLSiLt8y
+EKARptxleOS1GJ/R6oB4s0lk0iL6MRJucEdI5Nnbt6W9wD22my1q/2+mQ/S+WTcO
+So+B3fEnd3txkQtEXHLw+oPucY1sQvEakDK06ddr1iTjVoXACd/BVAzSm40uWHdT
+VNP4P/ECgYEA78ANRGKUAfgq+plyx8PVxbjC3XwgcD0yx3MLpiDsZFGsfHiw0Ma4
+bKhesp16FV9r3I12poDgInVNk+yoJjSrJeEcRz7gTJnJLNTjYmYycwjlqtDS99L2
+iC2e0ljyUiX8liVxgSq9gXPJrD8vV2+MVyTL6BKOF5OIMeqRZ7PNMIE=
+-----END RSA PRIVATE KEY-----
diff --git a/tests/test_data/server.pass.key b/tests/test_data/server.pass.key
new file mode 100644 (file)
index 0000000..79dcb19
--- /dev/null
@@ -0,0 +1,30 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,FEF8E8441D7B11E2
+
+AhioldkpxwjW0fh4KtrLuQOmNONGeufvAbWD8RYUuHflWENgCj/GXuw4wIRL0K2x
+aippkr0nvOLNpdsko/RcUS9D5CMO2AxNHoJqD1MppgJ3pygwrY6PbQXruRz1/H2R
+lDq1ibqtSjllQxycs+0g4J93j9x6dMpkcw54/854H4zTF6NtPROVOWWrVwRAeFXR
+V6tZXTPOM4+iRGv5Dx6gO+HAR05CDjqGBVq0QUOuKFUcceJuGYRLETM3JzvcRkl1
+Uk1mZgXmhkeU/B6ouMQm7jqkE1tjHdcW83odYW82JyBYu+TqAAfHTvxvcblJGUNE
++duUiuU7uFPyYaV03vjLznB1l4/eKcJr9ln9HSf2kVw5KgIeR5+SyBwH/58meYQW
+8+pQYuvE8N97nlNVm8KgNUsTqXR+9EEWvvo3mbfOO5iziWM8fuJurja4QJIHRcNV
+uHOCECH+qyeUZmrtIrTAvWNwlMjCbfMVkq/laa0vp87T6yEvOpF5H+JMxIhensLj
+LcfsIqIqg0M/wp/YJX9KRE5wdyQIH+PdrLH6pHbBRergmvsgAUdAqua+ODma0Va1
+xGdMdU0E3l+EF/Z5oNfwmYSp+JW9lpfAcjunwsY+DNSJ8USBw9EJXP9sDkkSskN1
+JS2iG0ynLtwyPe2lFgRraHAI6BXARfCIv+WX0INqivk0g6CrInnNxmQYIldJAKik
+B0sqV0TYN2O9DaCszPcEM48m0qp2sxyP7ar9WS5fY5F2X7W2XB1+tVSgqdXboYEh
+Gq38vDJRWmD6hTyNarYV9ENXspaNdOrPXm1evIAXUwL33xLe85JvugrrA4o8Fxfw
+i5pQJ4UkEAYFoEhDyl9rj3JjK23G55eYIpBjpR8PUfeMji4HYVEG4mMtDr0YWHCH
+Ey+1YaRDc4BnJnj2Hus0phpfPnn4fc90Y2Y2JocDDcPu+geaWn67WQm/urk4REHM
+snwbuqJPTy2xMcdq5qSjd634MbxF++nqhc1DZFvTTujnw8JB8GDdpdRCfjr7JYr3
+n5HHpaRFLCQU1v4eURxNdfyLrHueHs5yS/I/ivV/Q/c+rnVSWrKyBgCC8xQlmuIX
+R8yjv+xDvBOOJdSwXYj/OIpW97RG5pf2SS90tthfen4jQ5tsCX6MMXersN2av3h1
+AhzmJSgli/gHkrsDEh/vUnFASTbmDVCeufpSKG2DdnQw0gQOC6I/GlyvaKJi/ZTy
+2TAOnegMbphnhkx7izP/hhGxrJmjQhU+H+OWKPA8jj25fonkwF4MiLuh8LeRQsnw
+0fvdVTMRfN7xaQmLD7haAshw2SHE/ZPde+2AqiO6TA2RaT6ekU9IJKyuK4FLpb1X
+zwy0TQsq6h1rmU3RZ7CME/0ay6c83XhntDys+aqkSx0IyDmXnYaMWm2kxNurqYDo
+oV+MEbcQJ7WSdhOikeC4auWk8j3p+XZzvI4pbrRAlRKY5D3jL+HH7K7J9+XC9HEL
+vIJWlYQaHhBsjozPE/KXp4iO5n9jm8WesGX5LZuQ5vBCV3Z6VNR3dqIPDyGz+Gd3
+i4UkeZQSbuuWFL98Wp/cxdgU1/5UdbTum6Gc+Lnbnvjhg+8SAlj4GuSRBV4AsjZC
+-----END RSA PRIVATE KEY-----
diff --git a/tests/test_data/server2.csr b/tests/test_data/server2.csr
new file mode 100644 (file)
index 0000000..1ad8626
--- /dev/null
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIChTCCAW0CAQAwQDELMAkGA1UEBhMCRlIxDDAKBgNVBAoMA2ZvbzEMMAoGA1UE
+CwwDQmFyMRUwEwYDVQQDDAxleGFtcGxlMi5jb20wggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQDUNDUOhna6x4GNbyANJGGYywr1AtEc6atA02OdgW/zIL5D
+2O7NzlQF1fFvT57p9vs7Y1ALihXkzhbVonqJGyJC79n9SQskW87r5+0xNnoKK9ls
+7/m/je23qCtl5dAqIk2b1Ph5QXW4Q/F83wTgsYD9NzSg+3s6boxSwhCM45SEyQIJ
+8qdv1vXTIr+LwXB/SUV0jBAtkL/rt7p0YqxApQ7NSLOw909zy1i8vbufgIcZ4Cbz
+wqoaLv5rKgqws01WjpzjFooQ7MWo019n0vyEC/CQpA2p7laKpJuxf78NRU/eH1F6
+d4AmsJsDbkUWnG2zJXn8+q/lBtI2KzzDM8ZRoROPAgMBAAGgADANBgkqhkiG9w0B
+AQsFAAOCAQEAGARVyLpEtRh8h+JKF1UMqSgNl63p/eC7i0MOhA4N+sap4Bs54X23
+VVRHysVGTY3eLEh5qFaMs0k2zYCl/YYZ8LAY8OLIcvVWbOzX9AIFuCBTsxV+Bbu1
+kY+aqRJiiemGHDIqfPgL4C1FIOY9RtZ/Pe9H2Z5lFL/i5JP2H6kP2jCGTDUPqcsC
+DcCKouVF88tWLl7Vl8Ix39b79lETDyyku4CPXsT9GVfXLQRTdt/T80xp98VR4Fqy
+xP7bH1UxOvrvm8SF3C7RQc1f1So3/N9DDrOo5MqPs3RpzY6yVrv9mh6hu0MgPz73
+Lr7NKH6bQ3xG3SgMWswc8ag71lCmFFBtFQ==
+-----END CERTIFICATE REQUEST-----
diff --git a/tests/test_data/tizen.org.pem b/tests/test_data/tizen.org.pem
new file mode 100644 (file)
index 0000000..9ff89a2
--- /dev/null
@@ -0,0 +1,103 @@
+-----BEGIN CERTIFICATE-----
+MIIESjCCAzKgAwIBAgIQB05X0Drmfzqaz/KXYK8KozANBgkqhkiG9w0BAQsFADBG
+MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg
+Q0EgMUIxDzANBgNVBAMTBkFtYXpvbjAeFw0xNzA1MTgwMDAwMDBaFw0xODA2MTgx
+MjAwMDBaMBYxFDASBgNVBAMMCyoudGl6ZW4ub3JnMIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEArgawWTsdalcH6TC7U/lWYagGsBxHYSyplt5qRKB8g6ac
+86P7MlMXrg8SDOcwdj5EUoaFmOIABhBamXtyM5CRtRJ68XqAiFCfKbx2wTN9XtI6
+AhknlOHvRa4ZWkXpyL87Uye6YNMqx868GDlVXF1He4ijk+foJi+/u29dfxIlFkpd
+JXUu104AqaVCCMnszsAcm0baLBc1sUzO0+XSq/RKwiPSh7RFkGUOC7jwhLffMhwj
+FoFMIQXOYaJZMrbczkWR7M0vuopQUjTY+Te7a3wvxD4+ttceoTfoiJwyqG8bJmnH
+u3I3iM2KJAnPZP12LW0fdMMP4DFJ2yIHFkQrj84IcwIDAQABo4IBYjCCAV4wHwYD
+VR0jBBgwFoAUWaRmBlKge5WSPKOUByeWdFv5PdAwHQYDVR0OBBYEFF6fs6+80KAV
+OI3Zg87EBRvRbYmPMBYGA1UdEQQPMA2CCyoudGl6ZW4ub3JnMA4GA1UdDwEB/wQE
+AwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwOwYDVR0fBDQwMjAw
+oC6gLIYqaHR0cDovL2NybC5zY2ExYi5hbWF6b250cnVzdC5jb20vc2NhMWIuY3Js
+MBMGA1UdIAQMMAowCAYGZ4EMAQIBMHUGCCsGAQUFBwEBBGkwZzAtBggrBgEFBQcw
+AYYhaHR0cDovL29jc3Auc2NhMWIuYW1hem9udHJ1c3QuY29tMDYGCCsGAQUFBzAC
+hipodHRwOi8vY3J0LnNjYTFiLmFtYXpvbnRydXN0LmNvbS9zY2ExYi5jcnQwDAYD
+VR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAQEAPKDqqxsCFFKFA1aqTwo09sOJ
+rMt0Ohq3TbX/zivY7f+HjLGbA4FsIOh3hkP8TfwKyaDeg3cGTH+gKDWYU9m40f0N
+L+V632ieNXbVwL+9OkSMhurOvlzg4uQ3uYI2xGlmVrUT2iZFuJ5bhRQOGwjuU0qw
+zDg5lRhuHnqoG8XN440t0S6QsCfj4QyrL7qqsC8U/fXWEyGSoU6q6gbzyuIBob5p
+TCLujK3R/rIRrjX3doz0/WITpMcuiBCPBZv6tNdcN40GRoN03CVI66ujCDYGh6lY
+h67OqAWbvUsa0/WmGZts0DD3//lD/2qs8v+6MJ6nQKd5XoCvmsbN+UYo5Xr4Fg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIESTCCAzGgAwIBAgITBn+UV4WH6Kx33rJTMlu8mYtWDTANBgkqhkiG9w0BAQsF
+ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
+b24gUm9vdCBDQSAxMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjEL
+MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENB
+IDFCMQ8wDQYDVQQDEwZBbWF6b24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQDCThZn3c68asg3Wuw6MLAd5tES6BIoSMzoKcG5blPVo+sDORrMd4f2AbnZ
+cMzPa43j4wNxhplty6aUKk4T1qe9BOwKFjwK6zmxxLVYo7bHViXsPlJ6qOMpFge5
+blDP+18x+B26A0piiQOuPkfyDyeR4xQghfj66Yo19V+emU3nazfvpFA+ROz6WoVm
+B5x+F2pV8xeKNR7u6azDdU5YVX1TawprmxRC1+WsAYmz6qP+z8ArDITC2FMVy2fw
+0IjKOtEXc/VfmtTFch5+AfGYMGMqqvJ6LcXiAhqG5TI+Dr0RtM88k+8XUBCeQ8IG
+KuANaL7TiItKZYxK1MMuTJtV9IblAgMBAAGjggE7MIIBNzASBgNVHRMBAf8ECDAG
+AQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUWaRmBlKge5WSPKOUByeW
+dFv5PdAwHwYDVR0jBBgwFoAUhBjMhTTsvAyUlC4IWZzHshBOCggwewYIKwYBBQUH
+AQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5yb290Y2ExLmFtYXpvbnRy
+dXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDovL2NydC5yb290Y2ExLmFtYXpvbnRy
+dXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3Js
+LnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jvb3RjYTEuY3JsMBMGA1UdIAQMMAow
+CAYGZ4EMAQIBMA0GCSqGSIb3DQEBCwUAA4IBAQCFkr41u3nPo4FCHOTjY3NTOVI1
+59Gt/a6ZiqyJEi+752+a1U5y6iAwYfmXss2lJwJFqMp2PphKg5625kXg8kP2CN5t
+6G7bMQcT8C8xDZNtYTd7WPD8UZiRKAJPBXa30/AbwuZe0GaFEQ8ugcYQgSn+IGBI
+8/LwhBNTZTUVEWuCUUBVV18YtbAiPq3yXqMB48Oz+ctBWuZSkbvkNodPLamkB2g1
+upRyzQ7qDn1X8nn8N8V7YJ6y68AtkHcNSRAnpTitxBKjtKPISLMVCx7i4hncxHZS
+yLyKQXhw2W2Xs0qLeC1etA+jTGDK4UfLeC0SF7FSi8o5LL21L8IzApar2pR/
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEkjCCA3qgAwIBAgITBn+USionzfP6wq4rAfkI7rnExjANBgkqhkiG9w0BAQsF
+ADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNj
+b3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4x
+OzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1
+dGhvcml0eSAtIEcyMB4XDTE1MDUyNTEyMDAwMFoXDTM3MTIzMTAxMDAwMFowOTEL
+MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
+b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
+ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
+9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
+IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
+VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
+93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
+jgSubJrIqg0CAwEAAaOCATEwggEtMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
+BAQDAgGGMB0GA1UdDgQWBBSEGMyFNOy8DJSULghZnMeyEE4KCDAfBgNVHSMEGDAW
+gBScXwDfqgHXMCs4iKK4bUqc8hGRgzB4BggrBgEFBQcBAQRsMGowLgYIKwYBBQUH
+MAGGImh0dHA6Ly9vY3NwLnJvb3RnMi5hbWF6b250cnVzdC5jb20wOAYIKwYBBQUH
+MAKGLGh0dHA6Ly9jcnQucm9vdGcyLmFtYXpvbnRydXN0LmNvbS9yb290ZzIuY2Vy
+MD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly9jcmwucm9vdGcyLmFtYXpvbnRydXN0
+LmNvbS9yb290ZzIuY3JsMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQsF
+AAOCAQEAYjdCXLwQtT6LLOkMm2xF4gcAevnFWAu5CIw+7bMlPLVvUOTNNWqnkzSW
+MiGpSESrnO09tKpzbeR/FoCJbM8oAxiDR3mjEH4wW6w7sGDgd9QIpuEdfF7Au/ma
+eyKdpwAJfqxGF4PcnCZXmTA5YpaP7dreqsXMGz7KQ2hsVxa81Q4gLv7/wmpdLqBK
+bRRYh5TmOTFffHPLkIhqhBGWJ6bt2YFGpn6jcgAKUj6DiAdjd4lpFw85hdKrCEVN
+0FE6/V1dN2RMfjCyVSRCnTawXZwXgWHxyvkQAiSr6w10kY17RSlQOYiypok1JR4U
+akcjMS9cmvqtmg5iUaQqqcT5NJ0hGA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEdTCCA12gAwIBAgIJAKcOSkw0grd/MA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNV
+BAYTAlVTMSUwIwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTIw
+MAYDVQQLEylTdGFyZmllbGQgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
+eTAeFw0wOTA5MDIwMDAwMDBaFw0zNDA2MjgxNzM5MTZaMIGYMQswCQYDVQQGEwJV
+UzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTElMCMGA1UE
+ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjE7MDkGA1UEAxMyU3RhcmZp
+ZWxkIFNlcnZpY2VzIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVDDrEKvlO4vW+GZdfjohTsR8/
+y8+fIBNtKTrID30892t2OGPZNmCom15cAICyL1l/9of5JUOG52kbUpqQ4XHj2C0N
+Tm/2yEnZtvMaVq4rtnQU68/7JuMauh2WLmo7WJSJR1b/JaCTcFOD2oR0FMNnngRo
+Ot+OQFodSk7PQ5E751bWAHDLUu57fa4657wx+UX2wmDPE1kCK4DMNEffud6QZW0C
+zyyRpqbn3oUYSXxmTqM6bam17jQuug0DuDPfR+uxa40l2ZvOgdFFRjKWcIfeAg5J
+Q4W2bHO7ZOphQazJ1FTfhy/HIrImzJ9ZVGif/L4qL8RVHHVAYBeFAlU5i38FAgMB
+AAGjgfAwge0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0O
+BBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMB8GA1UdIwQYMBaAFL9ft9HO3R+G9FtV
+rNzXEMIOqYjnME8GCCsGAQUFBwEBBEMwQTAcBggrBgEFBQcwAYYQaHR0cDovL28u
+c3MyLnVzLzAhBggrBgEFBQcwAoYVaHR0cDovL3guc3MyLnVzL3guY2VyMCYGA1Ud
+HwQfMB0wG6AZoBeGFWh0dHA6Ly9zLnNzMi51cy9yLmNybDARBgNVHSAECjAIMAYG
+BFUdIAAwDQYJKoZIhvcNAQELBQADggEBACMd44pXyn3pF3lM8R5V/cxTbj5HD9/G
+VfKyBDbtgB9TxF00KGu+x1X8Z+rLP3+QsjPNG1gQggL4+C/1E2DUBc7xgQjB3ad1
+l08YuW3e95ORCLp+QCztweq7dp4zBncdDQh/U90bZKuCJ/Fp1U1ervShw3WnWEQt
+8jxwmKy6abaVd38PMV4s/KCHOkdp8Hlf9BRUpJVeEXgSYCfOn8J3/yNTd126/+pZ
+59vPr5KW7ySaNRB6nJHGDn2Z9j8Z3/VyVOEVqQdZe4O/Ui5GjLIAZHYcSNPYeehu
+VsyuLAOQ1xk4meTKCRlb/weWsKh/NEnfVqn3sF/tM+2MR7cwA130A4w=
+-----END CERTIFICATE-----