Revert "[IOT-2761] Multiple CAs allowed" 29/23229/1
authorNathan Heldt-Sheller <nathan.heldt-sheller@intel.com>
Wed, 15 Nov 2017 17:56:05 +0000 (09:56 -0800)
committerNathan Heldt-Sheller <nathan.heldt-sheller@intel.com>
Wed, 15 Nov 2017 17:57:50 +0000 (09:57 -0800)
This reverts commit 7f9d8c71fadc2eb8968e953f78e3b4afce262c52.

22967 caused a regression in the CTT; we'll fix and re-submit
after regression testing.

Change-Id: Ie06cf59b6463072c54b23c61d322bdb7f09cc22f
Signed-off-by: Nathan Heldt-Sheller <nathan.heldt-sheller@intel.com>
16 files changed:
resource/c_common/experimental/byte_array.h
resource/csdk/connectivity/api/casecurityinterface.h
resource/csdk/connectivity/common/SConscript
resource/csdk/connectivity/common/inc/parsechain.h [deleted file]
resource/csdk/connectivity/common/src/parsechain.c [deleted file]
resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c
resource/csdk/connectivity/test/ca_api_unittest.cpp
resource/csdk/connectivity/test/ssladapter_test.cpp
resource/csdk/security/include/internal/certhelpers.h
resource/csdk/security/include/internal/credresource.h
resource/csdk/security/src/certhelpers.c
resource/csdk/security/src/credresource.c
resource/csdk/security/src/pkix_interface.c
resource/csdk/security/src/rolesresource.c
resource/csdk/security/tool/svrdbeditor_src/svrdbeditorcommon.h
resource/csdk/security/tool/svrdbeditor_src/svrdbeditorcred.c

index 9e36176..2810112 100644 (file)
@@ -45,13 +45,6 @@ typedef struct ByteArray
     size_t len;      /**< Data size */
 } ByteArray_t;
 
-typedef struct ByteArrayLL ByteArrayLL_t;
-
-struct ByteArrayLL
-{
-    ByteArray_t *cert;
-    ByteArrayLL_t *next;
-};
 
 /**@def BYTE_ARRAY_INITIALIZER
  *
@@ -60,13 +53,6 @@ struct ByteArrayLL
 #undef BYTE_ARRAY_INITIALIZER
 #define BYTE_ARRAY_INITIALIZER {NULL, 0}
 
-/**@def CERT_CHAIN_INITIALIZER
- *
- * Initializes of existing certificate chain pointer to \a NULL.
- */
-#undef CERT_CHAIN_INITIALIZER
-#define CERT_CHAIN_INITIALIZER {NULL, NULL}
-
 /**@def INIT_BYTE_ARRAY(array)
  *
  * Initializes of existing byte array \a array.
index 9c0e7b1..dbf0044 100644 (file)
@@ -108,7 +108,6 @@ bool CAGetSecureEndpointAttributes(const CAEndpoint_t* peer, uint32_t* allAttrib
  *
  */
 typedef void (*CAgetCredentialTypesHandler)(bool * list, const char* deviceId);
-
 /**
  * Binary structure containing PKIX related info
  * own certificate chain, public key, CA's and CRL's
@@ -119,9 +118,9 @@ typedef void (*CAgetCredentialTypesHandler)(bool * list, const char* deviceId);
  */
 typedef struct
 {
-    ByteArrayLL_t crt;  /**< own certificate chain as a null-terminated PEM string of certificates */
+    ByteArray_t crt;    /**< own certificate chain as a null-terminated PEM string of certificates */
     ByteArray_t key;    /**< own private key as binary-encoded DER */
-    ByteArrayLL_t ca;   /**< trusted CAs as a null-terminated PEM string of certificates */
+    ByteArray_t ca;     /**< trusted CAs as a null-terminated PEM string of certificates */
     ByteArray_t crl;    /**< trusted CRLs as binary-encoded DER */
 } PkiInfo_t;
 
@@ -298,3 +297,4 @@ void CAcloseSslConnectionAll(CATransportAdapter_t transportType);
 
 
 #endif /* CA_SECURITY_INTERFACE_H_ */
+
index f55ef28..837c63f 100644 (file)
@@ -27,9 +27,6 @@ ca_common_src = [
         os.path.join(ca_common_src_path, 'caremotehandler.c')
     ]
 
-if connectivity_env.get('SECURED') == '1':
-    ca_common_src.append(os.path.join(ca_common_src_path, 'parsechain.c'))
-
 if connectivity_env['POSIX_SUPPORTED'] or target_os in ['windows']:
     ca_common_src.append(os.path.join(ca_common_src_path, 'cathreadpool_pthreads.c'))
 
diff --git a/resource/csdk/connectivity/common/inc/parsechain.h b/resource/csdk/connectivity/common/inc/parsechain.h
deleted file mode 100644 (file)
index af4ada2..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* ****************************************************************
- *
- * Copyright 2017 Samsung Electronics 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.
- *
- ******************************************************************/
-
-#ifndef U_PARSECHAIN_H_
-#define U_PARSECHAIN_H_
-
-#include <mbedtls/ssl.h>
-#include "casecurityinterface.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * Parse chain of X.509 certificates.
- *
- * @param[out] crt     container for X.509 certificates
- * @param[in]  certs   array of X.509 certificates
- * @param[in]  errNum  number certificates that failed to parse
- *
- * @return  number of successfully parsed certificates or -1 on error
- */
-int ParseChain(mbedtls_x509_crt *crt, const ByteArrayLL_t *certs, int *errNum);
-
-/**
- * Free chain of X.509 certificates.
- */
-void FreeCertChain(ByteArrayLL_t *certs);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* U_ARRAYLIST_H_ */
diff --git a/resource/csdk/connectivity/common/src/parsechain.c b/resource/csdk/connectivity/common/src/parsechain.c
deleted file mode 100644 (file)
index 6b5a2a3..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/******************************************************************
- *
- * Copyright 2014 Samsung Electronics 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.
- *
- ******************************************************************/
-
-#include "parsechain.h"
-#include "utlist.h"
-#include "caadapterutils.h"
-#include "oic_malloc.h"
-
-#define PARSE_CHAIN_TAG "OIC_PARSE_CHAIN"
-
-int ParseChain(mbedtls_x509_crt *crt, const ByteArrayLL_t *certs, int *errNum)
-{
-    OIC_LOG_V(DEBUG, PARSE_CHAIN_TAG, "In %s", __func__);
-    VERIFY_NON_NULL_RET(crt, PARSE_CHAIN_TAG, "Param crt is NULL", -1);
-    VERIFY_NON_NULL_RET(certs, PARSE_CHAIN_TAG, "Param certs is NULL", -1);
-    VERIFY_NON_NULL_RET(errNum, PARSE_CHAIN_TAG, "Param errNum is NULL", -1);
-    VERIFY_NON_NULL_RET(certs->cert, PARSE_CHAIN_TAG, "certs->cert is NULL", -1);
-
-    int count = 0;
-    int ret = 0;
-    *errNum = 0;
-
-    const ByteArrayLL_t *temp = certs;
-    LL_FOREACH(certs, temp)
-    {
-        ret = mbedtls_x509_crt_parse(crt, temp->cert->data, temp->cert->len);
-        if (0 == ret)
-        {
-            count++;
-        }
-        else
-        {
-            (*errNum)++;
-            OIC_LOG_V(ERROR, PARSE_CHAIN_TAG, "mbedtls_x509_crt_parse returned -0x%04x\n", -(ret));
-            return -1;
-        }
-    }
-    OIC_LOG_V(DEBUG, PARSE_CHAIN_TAG, "%s successfully parsed %d certificates", __func__, count);
-    OIC_LOG_V(DEBUG, PARSE_CHAIN_TAG, "Out %s", __func__);
-    return count;
-}
-
-void FreeCertChain(ByteArrayLL_t *certs)
-{
-    ByteArrayLL_t *tmp0 = certs, *tmp1 = NULL, *tmp2 = NULL;
-    LL_FOREACH_SAFE(tmp0, tmp1, tmp2)
-    {
-        LL_DELETE(tmp0, tmp1);
-        if (NULL != tmp1->cert) {
-            if (NULL != tmp1->cert->data)
-            {
-                OICFree(tmp1->cert->data);
-            }
-            OICFree(tmp1->cert);
-        }
-        tmp1 = NULL;
-    }
-}
index 802e8df..c1fd537 100644 (file)
@@ -37,8 +37,6 @@
 #include "experimental/byte_array.h"
 #include "octhread.h"
 #include "octimer.h"
-#include "utlist.h"
-#include "parsechain.h"
 
 // headers required for mbed TLS
 #include "mbedtls/platform.h"
@@ -635,6 +633,57 @@ static int RecvCallBack(void * tep, unsigned char * data, size_t dataLen)
     return (int)retLen;
 }
 
+/**
+ * Parse chain of X.509 certificates.
+ *
+ * @param[out] crt     container for X.509 certificates
+ * @param[in]  buf     buffer with X.509 certificates. Certificates must be in a single null-terminated
+ *                     string, with each certificate in PEM encoding with headers.
+ * @param[in]  bufLen  buffer length
+ * @param[in]  errNum  number certificates that failed to parse
+ *
+ * @return  number of successfully parsed certificates or -1 on error
+ */
+static int ParseChain(mbedtls_x509_crt * crt, unsigned char * buf, size_t bufLen, int * errNum)
+{
+    int ret;
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+    VERIFY_NON_NULL_RET(crt, NET_SSL_TAG, "Param crt is NULL", -1);
+    VERIFY_NON_NULL_RET(buf, NET_SSL_TAG, "Param buf is NULL", -1);
+
+    if (NULL != errNum)
+    {
+        *errNum = 0;
+    }
+
+    if ((bufLen >= 2) && (buf[0] == 0x30) && (buf[1] == 0x82))
+    {
+        OIC_LOG_V(ERROR, NET_SSL_TAG, "DER-encoded certificate passed to ParseChain");
+        return -1;
+    }
+
+    ret = mbedtls_x509_crt_parse(crt, buf, bufLen);
+    if (0 > ret)
+    {
+        OIC_LOG_V(ERROR, NET_SSL_TAG, "mbedtls_x509_crt_parse failed: -0x%04x", -(ret));
+        return -1;
+    }
+
+    if (NULL != errNum)
+    {
+        *errNum = ret;
+    }
+
+    ret = 0;
+    for (const mbedtls_x509_crt *cur = crt; cur != NULL; cur = cur->next)
+    {
+        ret++;
+    }
+
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+    return ret;
+}
+
 /**
  * Deinit Pki Info
  *
@@ -651,9 +700,9 @@ static void DeInitPkixInfo(PkiInfo_t * inf)
         return;
     }
 
-    FreeCertChain(&(inf->crt));
+    DEINIT_BYTE_ARRAY(inf->crt);
     DEINIT_BYTE_ARRAY(inf->key);
-    FreeCertChain(&(inf->ca));
+    DEINIT_BYTE_ARRAY(inf->ca);
     DEINIT_BYTE_ARRAY(inf->crl);
 
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
@@ -666,9 +715,9 @@ static int InitPKIX(CATransportAdapter_t adapter)
     VERIFY_NON_NULL_RET(g_getPkixInfoCallback, NET_SSL_TAG, "PKIX info callback is NULL", -1);
     // load pk key, cert, trust chain and crl
     PkiInfo_t pkiInfo = {
-        CERT_CHAIN_INITIALIZER,
         BYTE_ARRAY_INITIALIZER,
-        CERT_CHAIN_INITIALIZER,
+        BYTE_ARRAY_INITIALIZER,
+        BYTE_ARRAY_INITIALIZER,
         BYTE_ARRAY_INITIALIZER
     };
 
@@ -676,6 +725,7 @@ static int InitPKIX(CATransportAdapter_t adapter)
     {
         g_getPkixInfoCallback(&pkiInfo);
     }
+
     VERIFY_NON_NULL_RET(g_caSslContext, NET_SSL_TAG, "SSL Context is NULL", -1);
 
     mbedtls_x509_crt_free(&g_caSslContext->ca);
@@ -687,6 +737,7 @@ static int InitPKIX(CATransportAdapter_t adapter)
     mbedtls_x509_crt_init(&g_caSslContext->crt);
     mbedtls_pk_init(&g_caSslContext->pkey);
     mbedtls_x509_crl_init(&g_caSslContext->crl);
+
     mbedtls_ssl_config * serverConf = (adapter == CA_ADAPTER_IP ||
                                    adapter == CA_ADAPTER_GATT_BTLE ?
                                    &g_caSslContext->serverDtlsConf : &g_caSslContext->serverTlsConf);
@@ -696,7 +747,7 @@ static int InitPKIX(CATransportAdapter_t adapter)
     // optional
     int ret;
     int errNum;
-    int count = ParseChain(&g_caSslContext->crt, &(pkiInfo.crt), &errNum);
+    int count = ParseChain(&g_caSslContext->crt, pkiInfo.crt.data, pkiInfo.crt.len, &errNum);
     if (0 >= count)
     {
         OIC_LOG(WARNING, NET_SSL_TAG, "Own certificate chain parsing error");
@@ -745,7 +796,7 @@ static int InitPKIX(CATransportAdapter_t adapter)
     }
 
     required:
-    count = ParseChain(&g_caSslContext->ca, &(pkiInfo.ca), &errNum);
+    count = ParseChain(&g_caSslContext->ca, pkiInfo.ca.data, pkiInfo.ca.len, &errNum);
     if(0 >= count)
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "CA chain parsing error");
index afc6195..1f741f0 100644 (file)
@@ -81,7 +81,7 @@ void adapter_handler(CATransportAdapter_t /*adapter*/,
 {
 }
 
-void connection_handler(const CAEndpoint_t * /*endpoint*/,
+void connection_handler(const CAEndpoint_t * /*endpoint*/, 
                         bool /*connected*/)
 {
 }
@@ -199,14 +199,12 @@ void provide_x509_cert_and_key(PkiInfo_t* inf)
 {
     /* PEM data must end in newline and be null terminated for IoTivity */
 
-    inf->crt.cert->data = (uint8_t*) our_cert;
-    inf->crt.cert->len = strlen(our_cert) + 1;
-    inf->crt.next = NULL;
+    inf->crt.data = (uint8_t*) our_cert;
+    inf->crt.len = strlen(our_cert) + 1;
     inf->key.data = (uint8_t*) our_key;
     inf->key.len = strlen(our_key) + 1;
-    inf->ca.cert->data = (uint8_t*) our_ca;
-    inf->ca.cert->len = strlen(our_ca) + 1;
-    inf->ca.next = NULL;
+    inf->ca.data = (uint8_t*) our_ca;
+    inf->ca.len = strlen(our_ca) + 1;
 
     // CRL not provided
     inf->crl.data = NULL;
@@ -224,11 +222,11 @@ void provide_supported_credential_types(bool* list, const char* /*deviceId*/)
 {
     list[1] = true;
     /*
-     * Note: there is a default implementation of this in credresource.c, exposed by
-     * pkix_interface.h, called InitManufacturerCipherSuiteList.  If the cred resource
-     * has a credential of the required type, it updates list accordingly.
+     * Note: there is a default implementation of this in credresource.c, exposed by 
+     * pkix_interface.h, called InitManufacturerCipherSuiteList.  If the cred resource 
+     * has a credential of the required type, it updates list accordingly. 
      *
-     * In a separate test, we could use the cred resource and APIs (credresource.h).
+     * In a separate test, we could use the cred resource and APIs (credresource.h). 
      */
     return;
 }
@@ -367,9 +365,9 @@ TEST_F(CATests, DISABLED_PkiTest)
 {
     // @todo: this test is disabled for now, it crashes with an invalid write. Cert data
     // provided by the provide_x509_cert_and_key is stored as const char, but ParseChain()
-    // (in ca_adapter_net_ssl.c) writes to it while reading.  We could change the test to
+    // (in ca_adapter_net_ssl.c) writes to it while reading.  We could change the test to 
     // provide data on the heap, but the CA stack should not be changing data provided to it
-    // by callbacks.
+    // by callbacks. 
 
     const char* local_addr = "127.0.0.1";
     uint16_t local_port = 5503;
@@ -393,7 +391,7 @@ TEST_F(CATests, DISABLED_PkiTest)
 
     // Register a working callback to provide the keys, expect success.
     EXPECT_EQ(CA_STATUS_OK, CAregisterPkixInfoHandler(provide_x509_cert_and_key));
-    EXPECT_EQ(CA_STATUS_OK, CAInitiateHandshake(serverAddr));
+    EXPECT_EQ(CA_STATUS_OK, CAInitiateHandshake(serverAddr)); 
 
     CADestroyEndpoint(serverAddr);
 }
index b1d0cbd..1d54125 100644 (file)
  *
  * *************************/
 
-// 10 certificates in PEM and DER encoding
-unsigned char cert0[] = {
+// Data blob contains 7 certificates in PEM and DER encoding
+unsigned char certChain[] = {
+    // PEM encoded certificate
     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
     0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43,
     0x6e, 0x44, 0x43, 0x43, 0x41, 0x6a, 0x2b, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55,
@@ -168,9 +169,8 @@ unsigned char cert0[] = {
     0x61, 0x6b, 0x76, 0x72, 0x4e, 0x4b, 0x66, 0x44, 0x79, 0x2b, 0x4f, 0x4e, 0x43, 0x6e, 0x4e, 0x6e,
     0x43, 0x59, 0x57, 0x4a, 0x37, 0x39, 0x35, 0x4b, 0x49, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
     0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
-    0x2d, 0x2d, 0x2d, 0x00
-};
-unsigned char cert1[] = {
+    0x2d, 0x2d, 0x2d,
+    // PEM encoded certificate
     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
     0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43,
     0x6e, 0x44, 0x43, 0x43, 0x41, 0x6a, 0x2b, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55,
@@ -231,9 +231,8 @@ unsigned char cert1[] = {
     0x61, 0x6b, 0x76, 0x72, 0x4e, 0x4b, 0x66, 0x44, 0x79, 0x2b, 0x4f, 0x4e, 0x43, 0x6e, 0x4e, 0x6e,
     0x43, 0x59, 0x57, 0x4a, 0x37, 0x39, 0x35, 0x4b, 0x49, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
     0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
-    0x2d, 0x2d, 0x2d, 0x00
-};
-unsigned char cert2[] = {
+    0x2d, 0x2d, 0x2d,
+    // PEM encoded certificate
     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
     0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0d, 0x0a, 0x4d, 0x49, 0x49,
     0x45, 0x67, 0x44, 0x43, 0x43, 0x41, 0x32, 0x69, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49,
@@ -337,9 +336,7 @@ unsigned char cert2[] = {
     0x56, 0x6e, 0x79, 0x63, 0x6e, 0x4a, 0x73, 0x43, 0x68, 0x65, 0x73, 0x0d, 0x0a, 0x46, 0x4c, 0x78,
     0x6f, 0x6c, 0x77, 0x3d, 0x3d, 0x0d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20,
     0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
-    0x00
-};
-unsigned char cert3[] = {
+    // PEM encoded certificate
     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
     0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44,
     0x38, 0x44, 0x43, 0x43, 0x41, 0x74, 0x69, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x44,
@@ -429,9 +426,8 @@ unsigned char cert3[] = {
     0x6c, 0x6d, 0x77, 0x75, 0x39, 0x52, 0x59, 0x32, 0x33, 0x6e, 0x48, 0x4d, 0x41, 0x63, 0x49, 0x53,
     0x0a, 0x77, 0x53, 0x48, 0x47, 0x46, 0x67, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
     0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
-    0x2d, 0x2d, 0x2d, 0x00
-  };
-  unsigned char cert4[] = {
+    0x2d, 0x2d, 0x2d,
+    // PEM encoded certificate
     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
     0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43,
     0x6e, 0x44, 0x43, 0x43, 0x41, 0x6a, 0x2b, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55,
@@ -492,9 +488,8 @@ unsigned char cert3[] = {
     0x61, 0x6b, 0x76, 0x72, 0x4e, 0x4b, 0x66, 0x44, 0x79, 0x2b, 0x4f, 0x4e, 0x43, 0x6e, 0x4e, 0x6e,
     0x43, 0x59, 0x57, 0x4a, 0x37, 0x39, 0x35, 0x4b, 0x49, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
     0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
-    0x2d, 0x2d, 0x2d, 0x00
-  };
-  unsigned char cert5[] = {
+    0x2d, 0x2d, 0x2d,
+    // PEM encoded certificate
     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
     0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44,
     0x38, 0x44, 0x43, 0x43, 0x41, 0x74, 0x69, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x44,
@@ -584,9 +579,8 @@ unsigned char cert3[] = {
     0x6c, 0x6d, 0x77, 0x75, 0x39, 0x52, 0x59, 0x32, 0x33, 0x6e, 0x48, 0x4d, 0x41, 0x63, 0x49, 0x53,
     0x0a, 0x77, 0x53, 0x48, 0x47, 0x46, 0x67, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
     0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
-    0x2d, 0x2d, 0x2d, 0x00
-  };
-  unsigned char cert6[] = {
+    0x2d, 0x2d, 0x2d,
+    // PEM encoded certificate
     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
     0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43,
     0x6e, 0x44, 0x43, 0x43, 0x41, 0x6a, 0x2b, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55,
@@ -647,122 +641,11 @@ unsigned char cert3[] = {
     0x61, 0x6b, 0x76, 0x72, 0x4e, 0x4b, 0x66, 0x44, 0x79, 0x2b, 0x4f, 0x4e, 0x43, 0x6e, 0x4e, 0x6e,
     0x43, 0x59, 0x57, 0x4a, 0x37, 0x39, 0x35, 0x4b, 0x49, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
     0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
-    0x2d, 0x2d, 0x2d, 0x00
-};
-unsigned char cert7[] = {
-    0x30, 0x82, 0x02, 0x39, 0x30, 0x82, 0x01, 0xdf, 0x02, 0x01, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a,
-    0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x7c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
-    0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
-    0x09, 0x53, 0x6f, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
-    0x55, 0x04, 0x07, 0x0c, 0x08, 0x53, 0x6f, 0x6d, 0x65, 0x63, 0x69, 0x74, 0x79, 0x31, 0x0b, 0x30,
-    0x09, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x02, 0x42, 0x42, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03,
-    0x55, 0x04, 0x0b, 0x0c, 0x0d, 0x53, 0x65, 0x71, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x50, 0x61,
-    0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x02, 0x6f, 0x62, 0x31,
-    0x14, 0x30, 0x12, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x05,
-    0x6f, 0x62, 0x40, 0x62, 0x62, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x38, 0x31, 0x35, 0x31,
-    0x33, 0x31, 0x31, 0x31, 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x35, 0x31, 0x32, 0x31, 0x33,
-    0x31, 0x31, 0x31, 0x37, 0x5a, 0x30, 0x81, 0xd4, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
-    0x06, 0x13, 0x02, 0x55, 0x41, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x03,
-    0x41, 0x73, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x06, 0x47, 0x6f,
-    0x74, 0x68, 0x61, 0x6d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x02, 0x5a,
-    0x5a, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x42, 0x65, 0x61, 0x6d,
-    0x54, 0x65, 0x61, 0x6d, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
-    0x01, 0x09, 0x01, 0x16, 0x0d, 0x72, 0x61, 0x69, 0x6c, 0x40, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x63,
-    0x6f, 0x6d, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x29, 0x75, 0x75, 0x69,
-    0x64, 0x3a, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x2d, 0x33, 0x32, 0x33, 0x32, 0x2d,
-    0x33, 0x32, 0x33, 0x32, 0x2d, 0x33, 0x32, 0x33, 0x32, 0x2d, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32,
-    0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x0c,
-    0x2b, 0x75, 0x73, 0x65, 0x72, 0x69, 0x64, 0x3a, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37,
-    0x2d, 0x36, 0x37, 0x36, 0x37, 0x2d, 0x36, 0x37, 0x36, 0x37, 0x2d, 0x36, 0x37, 0x36, 0x37, 0x2d,
-    0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x30, 0x59, 0x30, 0x13,
-    0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
-    0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xf7, 0x13, 0x5c, 0x73, 0x72, 0xce, 0x10, 0xe5, 0x09,
-    0x97, 0x9a, 0xf8, 0xf2, 0x70, 0xa6, 0x3d, 0x89, 0xf5, 0xc5, 0xe4, 0x44, 0xe2, 0x4a, 0xb6, 0x61,
-    0xa8, 0x12, 0x8d, 0xb4, 0xdc, 0x2b, 0x47, 0x84, 0x60, 0x0c, 0x25, 0x66, 0xe9, 0xe0, 0xe5, 0xac,
-    0x22, 0xbf, 0x15, 0xdc, 0x71, 0xb1, 0x88, 0x4f, 0x16, 0xbf, 0xc2, 0x77, 0x37, 0x76, 0x3f, 0xe0,
-    0x67, 0xc6, 0x1d, 0x23, 0xfe, 0x7c, 0x8b, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
-    0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x47, 0xcc, 0x41, 0x8a, 0x27, 0xc7,
-    0xd0, 0xaa, 0xb4, 0xab, 0x85, 0xbf, 0x09, 0x4d, 0x06, 0xd7, 0x7e, 0x0d, 0x39, 0xf9, 0x36, 0xa1,
-    0x3d, 0x96, 0x23, 0xe2, 0x24, 0x64, 0x98, 0x63, 0x21, 0xba, 0x02, 0x21, 0x00, 0xe5, 0x8f, 0x7f,
-    0xf1, 0xa6, 0x82, 0x03, 0x6a, 0x18, 0x7a, 0x54, 0xe7, 0x0e, 0x25, 0x77, 0xd8, 0x46, 0xfa, 0x96,
-    0x8a, 0x7e, 0x14, 0xc4, 0xcb, 0x21, 0x32, 0x3e, 0x89, 0xd9, 0xba, 0x8c, 0x3f
-};
-unsigned char cert8[] = {
-    0x30, 0x82, 0x02, 0x39, 0x30, 0x82, 0x01, 0xdf, 0x02, 0x01, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a,
-    0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x7c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
-    0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
-    0x09, 0x53, 0x6f, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
-    0x55, 0x04, 0x07, 0x0c, 0x08, 0x53, 0x6f, 0x6d, 0x65, 0x63, 0x69, 0x74, 0x79, 0x31, 0x0b, 0x30,
-    0x09, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x02, 0x42, 0x42, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03,
-    0x55, 0x04, 0x0b, 0x0c, 0x0d, 0x53, 0x65, 0x71, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x50, 0x61,
-    0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x02, 0x6f, 0x62, 0x31,
-    0x14, 0x30, 0x12, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x05,
-    0x6f, 0x62, 0x40, 0x62, 0x62, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x38, 0x31, 0x35, 0x31,
-    0x33, 0x31, 0x31, 0x31, 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x35, 0x31, 0x32, 0x31, 0x33,
-    0x31, 0x31, 0x31, 0x37, 0x5a, 0x30, 0x81, 0xd4, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
-    0x06, 0x13, 0x02, 0x55, 0x41, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x03,
-    0x41, 0x73, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x06, 0x47, 0x6f,
-    0x74, 0x68, 0x61, 0x6d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x02, 0x5a,
-    0x5a, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x42, 0x65, 0x61, 0x6d,
-    0x54, 0x65, 0x61, 0x6d, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
-    0x01, 0x09, 0x01, 0x16, 0x0d, 0x72, 0x61, 0x69, 0x6c, 0x40, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x63,
-    0x6f, 0x6d, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x29, 0x75, 0x75, 0x69,
-    0x64, 0x3a, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x2d, 0x33, 0x32, 0x33, 0x32, 0x2d,
-    0x33, 0x32, 0x33, 0x32, 0x2d, 0x33, 0x32, 0x33, 0x32, 0x2d, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32,
-    0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x0c,
-    0x2b, 0x75, 0x73, 0x65, 0x72, 0x69, 0x64, 0x3a, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37,
-    0x2d, 0x36, 0x37, 0x36, 0x37, 0x2d, 0x36, 0x37, 0x36, 0x37, 0x2d, 0x36, 0x37, 0x36, 0x37, 0x2d,
-    0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x30, 0x59, 0x30, 0x13,
-    0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
-    0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xf7, 0x13, 0x5c, 0x73, 0x72, 0xce, 0x10, 0xe5, 0x09,
-    0x97, 0x9a, 0xf8, 0xf2, 0x70, 0xa6, 0x3d, 0x89, 0xf5, 0xc5, 0xe4, 0x44, 0xe2, 0x4a, 0xb6, 0x61,
-    0xa8, 0x12, 0x8d, 0xb4, 0xdc, 0x2b, 0x47, 0x84, 0x60, 0x0c, 0x25, 0x66, 0xe9, 0xe0, 0xe5, 0xac,
-    0x22, 0xbf, 0x15, 0xdc, 0x71, 0xb1, 0x88, 0x4f, 0x16, 0xbf, 0xc2, 0x77, 0x37, 0x76, 0x3f, 0xe0,
-    0x67, 0xc6, 0x1d, 0x23, 0xfe, 0x7c, 0x8b, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
-    0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x47, 0xcc, 0x41, 0x8a, 0x27, 0xc7,
-    0xd0, 0xaa, 0xb4, 0xab, 0x85, 0xbf, 0x09, 0x4d, 0x06, 0xd7, 0x7e, 0x0d, 0x39, 0xf9, 0x36, 0xa1,
-    0x3d, 0x96, 0x23, 0xe2, 0x24, 0x64, 0x98, 0x63, 0x21, 0xba, 0x02, 0x21, 0x00, 0xe5, 0x8f, 0x7f,
-    0xf1, 0xa6, 0x82, 0x03, 0x6a, 0x18, 0x7a, 0x54, 0xe7, 0x0e, 0x25, 0x77, 0xd8, 0x46, 0xfa, 0x96,
-    0x8a, 0x7e, 0x14, 0xc4, 0xcb, 0x21, 0x32, 0x3e, 0x89, 0xd9, 0xba, 0x8c, 0x3f
-};
-unsigned char cert9[] = {
-    0x30, 0x82, 0x02, 0x39, 0x30, 0x82, 0x01, 0xdf, 0x02, 0x01, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a,
-    0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x7c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
-    0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
-    0x09, 0x53, 0x6f, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
-    0x55, 0x04, 0x07, 0x0c, 0x08, 0x53, 0x6f, 0x6d, 0x65, 0x63, 0x69, 0x74, 0x79, 0x31, 0x0b, 0x30,
-    0x09, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x02, 0x42, 0x42, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03,
-    0x55, 0x04, 0x0b, 0x0c, 0x0d, 0x53, 0x65, 0x71, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x50, 0x61,
-    0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x02, 0x6f, 0x62, 0x31,
-    0x14, 0x30, 0x12, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x05,
-    0x6f, 0x62, 0x40, 0x62, 0x62, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x38, 0x31, 0x35, 0x31,
-    0x33, 0x31, 0x31, 0x31, 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x35, 0x31, 0x32, 0x31, 0x33,
-    0x31, 0x31, 0x31, 0x37, 0x5a, 0x30, 0x81, 0xd4, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
-    0x06, 0x13, 0x02, 0x55, 0x41, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x03,
-    0x41, 0x73, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x06, 0x47, 0x6f,
-    0x74, 0x68, 0x61, 0x6d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x02, 0x5a,
-    0x5a, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x42, 0x65, 0x61, 0x6d,
-    0x54, 0x65, 0x61, 0x6d, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
-    0x01, 0x09, 0x01, 0x16, 0x0d, 0x72, 0x61, 0x69, 0x6c, 0x40, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x63,
-    0x6f, 0x6d, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x29, 0x75, 0x75, 0x69,
-    0x64, 0x3a, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x2d, 0x33, 0x32, 0x33, 0x32, 0x2d,
-    0x33, 0x32, 0x33, 0x32, 0x2d, 0x33, 0x32, 0x33, 0x32, 0x2d, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32,
-    0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x0c,
-    0x2b, 0x75, 0x73, 0x65, 0x72, 0x69, 0x64, 0x3a, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37,
-    0x2d, 0x36, 0x37, 0x36, 0x37, 0x2d, 0x36, 0x37, 0x36, 0x37, 0x2d, 0x36, 0x37, 0x36, 0x37, 0x2d,
-    0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x30, 0x59, 0x30, 0x13,
-    0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
-    0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xf7, 0x13, 0x5c, 0x73, 0x72, 0xce, 0x10, 0xe5, 0x09,
-    0x97, 0x9a, 0xf8, 0xf2, 0x70, 0xa6, 0x3d, 0x89, 0xf5, 0xc5, 0xe4, 0x44, 0xe2, 0x4a, 0xb6, 0x61,
-    0xa8, 0x12, 0x8d, 0xb4, 0xdc, 0x2b, 0x47, 0x84, 0x60, 0x0c, 0x25, 0x66, 0xe9, 0xe0, 0xe5, 0xac,
-    0x22, 0xbf, 0x15, 0xdc, 0x71, 0xb1, 0x88, 0x4f, 0x16, 0xbf, 0xc2, 0x77, 0x37, 0x76, 0x3f, 0xe0,
-    0x67, 0xc6, 0x1d, 0x23, 0xfe, 0x7c, 0x8b, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
-    0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x47, 0xcc, 0x41, 0x8a, 0x27, 0xc7,
-    0xd0, 0xaa, 0xb4, 0xab, 0x85, 0xbf, 0x09, 0x4d, 0x06, 0xd7, 0x7e, 0x0d, 0x39, 0xf9, 0x36, 0xa1,
-    0x3d, 0x96, 0x23, 0xe2, 0x24, 0x64, 0x98, 0x63, 0x21, 0xba, 0x02, 0x21, 0x00, 0xe5, 0x8f, 0x7f,
-    0xf1, 0xa6, 0x82, 0x03, 0x6a, 0x18, 0x7a, 0x54, 0xe7, 0x0e, 0x25, 0x77, 0xd8, 0x46, 0xfa, 0x96,
-    0x8a, 0x7e, 0x14, 0xc4, 0xcb, 0x21, 0x32, 0x3e, 0x89, 0xd9, 0xba, 0x8c, 0x3f
+    0x2d, 0x2d, 0x2d,
+    // NULL terminator
+    0x00
 };
+int certChainLen = sizeof(certChain);
 
 unsigned char serverCert[] =
     "-----BEGIN CERTIFICATE-----\n"
@@ -794,7 +677,7 @@ unsigned char serverPrivateKey[] = {
 
 int serverPrivateKeyLen = sizeof(serverPrivateKey);
 
-unsigned char caCert[] =
+unsigned char caCert[] = 
     "-----BEGIN CERTIFICATE-----\n"
     "MIICPjCCAeWgAwIBAgIJAIenaAF86fjwMAoGCCqGSM49BAMCMHwxCzAJBgNVBAYT\n"
     "AlVTMRIwEAYDVQQIDAlTb21lc3RhdGUxETAPBgNVBAcMCFNvbWVjaXR5MQswCQYD\n"
@@ -1035,26 +918,22 @@ static void PacketReceive(unsigned char *data, int * datalen)
 
 static void infoCallback_that_loads_x509(PkiInfo_t * inf)
 {
-    ByteArray_t * ca = (ByteArray_t *)OICMalloc(sizeof(ByteArray_t));
-    ca->data = (uint8_t *)OICMalloc(sizeof(serverCert));
-    ASSERT_TRUE(ca->data != NULL);
-    memcpy(ca->data, serverCert, sizeof(serverCert));
-    ca->len = sizeof(serverCert);
+    inf->crt.len = sizeof(serverCert);
+    inf->crt.data = (uint8_t*)OICMalloc(inf->crt.len);
+    ASSERT_TRUE(inf->crt.data != NULL);
+    memcpy(inf->crt.data, serverCert, inf->crt.len);
 
-    ByteArray_t * own = (ByteArray_t *)OICMalloc(sizeof(ByteArray_t));
-    own->data = (uint8_t *)OICMalloc(sizeof(caCert));
-    ASSERT_TRUE(own->data != NULL);
-    memcpy(own->data, caCert, sizeof(caCert));
-    own->len = sizeof(caCert);
+    inf->key.len = sizeof(serverPrivateKey);
+    inf->key.data = (uint8_t*)OICMalloc(inf->key.len);
+    ASSERT_TRUE(inf->key.data != NULL);
+    memcpy(inf->key.data, serverPrivateKey, inf->key.len);
 
-    inf->crt.cert = ca;
-    inf->crt.next = NULL;
 
-    inf->ca.cert = own;
-    inf->ca.next = NULL;
+    inf->ca.len = sizeof(caCert);
+    inf->ca.data = (uint8_t*)OICMalloc(inf->ca.len);
+    ASSERT_TRUE(inf->ca.data != NULL);
+    memcpy(inf->ca.data, caCert, inf->ca.len);
 
-    inf->key.data = (uint8_t*)serverPrivateKey;
-    inf->key.len = sizeof(serverPrivateKey);
 
     inf->crl.data = NULL;
     inf->crl.len = 0;
@@ -1514,7 +1393,7 @@ exit:
     !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_SSL_TLS_C) || \
     !defined(MBEDTLS_SSL_SRV_C) || !defined(MBEDTLS_NET_C) ||     \
     !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_CTR_DRBG_C) ||    \
-    !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_FS_IO)
+    !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_FS_IO) 
 
 /* int */void * server( void )
 {
@@ -3152,56 +3031,14 @@ TEST(TLSAdapter, Test_11)
 
 TEST(TLSAdapter, Test_ParseChain)
 {
+    int errNum;
     mbedtls_x509_crt crt;
     mbedtls_x509_crt_init(&crt);
-
-    ByteArray_t certs[10];
-    certs[0].data = cert0;
-    certs[0].len = sizeof(cert0);
-    certs[1].data = cert1;
-    certs[1].len = sizeof(cert1);
-    certs[2].data = cert2;
-    certs[2].len = sizeof(cert2);
-    certs[3].data = cert3;
-    certs[3].len = sizeof(cert3);
-    certs[4].data = cert4;
-    certs[4].len = sizeof(cert4);
-    certs[5].data = cert5;
-    certs[5].len = sizeof(cert5);
-    certs[6].data = cert6;
-    certs[6].len = sizeof(cert6);
-    certs[7].data = cert7;
-    certs[7].len = sizeof(cert7);
-    certs[8].data = cert8;
-    certs[8].len = sizeof(cert8);
-    certs[9].data = cert9;
-    certs[9].len = sizeof(cert9);
-
-    ByteArrayLL_t * certChain = (ByteArrayLL_t *) OICMalloc (sizeof(ByteArrayLL_t));
-    certChain->cert = (ByteArray_t*) OICMalloc (sizeof(ByteArray_t));
-    certChain->cert->data = (unsigned char *) OICMalloc (certs[0].len);
-    memcpy(certChain->cert->data, certs[0].data, certs[0].len);
-    certChain->cert->len = certs[0].len;
-    certChain->next = NULL;
-
-    ByteArrayLL_t * tmp = NULL;
-    for (int i = 1; i < 10; i++)
-    {
-        tmp = (ByteArrayLL_t *) OICMalloc (sizeof(ByteArrayLL_t));
-        tmp->cert = (ByteArray_t*) OICMalloc (sizeof(ByteArray_t));
-        tmp->cert->data = (unsigned char *) OICMalloc (certs[i].len);
-        memcpy(tmp->cert->data, certs[i].data, certs[i].len);
-        tmp->cert->len = certs[i].len;
-        LL_APPEND(certChain, tmp);
-    }
-
-    int errNum;
-    size_t ret = ParseChain(&crt, certChain, &errNum);
-
-    FreeCertChain(certChain);
+    size_t ret = ParseChain(&crt, certChain, certChainLen, &errNum);
     mbedtls_x509_crt_free(&crt);
 
-    EXPECT_EQ(10, ret + errNum);
+    EXPECT_EQ(7u, ret);
+    EXPECT_EQ(0, errNum);
 }
 
 TEST(TLSAdapter, TestCertsValid)
index f2a4cea..0313024 100644 (file)
@@ -23,9 +23,8 @@
 
 #if defined(__WITH_TLS__) || defined(__WITH_DTLS__)
 
-#include <mbedtls/pk.h>
+#include "mbedtls/pk.h"
 #include <time.h>
-#include "casecurityinterface.h"
 
 /**
  * Internal certificate request function; used by CSR resource handler
@@ -41,7 +40,7 @@
  *
  * @return 0 on success, <0 on failure
  */
-int OCInternalCSRRequest(const char *subject, mbedtls_pk_context *keyPair,
+int OCInternalCSRRequest(const char *subject, mbedtls_pk_context *keyPair, 
                          OicEncodingType_t encoding, OCByteString *csr);
 
 /**
@@ -66,7 +65,7 @@ int OCInternalGenerateKeyPair(mbedtls_pk_context *keyPair);
  * 3. It contains at least one Subject Alternative Name extension that validly encodes a role.
  *
  * It does NOT validate the cryptographic signature nor check its time validity.
- * These checks should be done when the certificate is being used as part of an access control check,
+ * These checks should be done when the certificate is being used as part of an access control check, 
  * as that is when the time validity check should be made, and when trusted CAs are known.
  *
  * @param[in] buf           Buffer containing certificate as a PEM string
@@ -87,7 +86,7 @@ OCStackResult OCInternalIsValidRoleCertificate(const uint8_t *buf, size_t bufLen
 /**
  * Determine if a buffer contains a valid chain of certificates. This is intended to verify
  * one or more intermediate CA certificates are valid.
- *
+ * 
  * This only checks that they are valid X.509 structures; no verification of the cryptographic
  * signature of time-validity is performed. These should be done at point of use.
  *
@@ -111,7 +110,8 @@ OCStackResult OCInternalIsValidCertChain(const uint8_t *buf, size_t bufLen);
  * parameters.
  *
  * @param[in] certificateChain      OicSecKey_t containing one or more certificates
- * @param[in] trustedCaCerts        Trusted CAs certificates chain container
+ * @param[in] trustedCaCerts        PEM string containing the trusted CAs certificates
+ * @param[in] trustedCaCertsLength  Length of trustedCaCerts (including terminating NULL)
  * @param[out] roles                Pointer to receive array of OicSecRole_t objects listing roles
  *                                  Caller must call OICFree to release this memory when finished
  * @param[out] rolesLength          Length of returned roles array
@@ -121,8 +121,7 @@ OCStackResult OCInternalIsValidCertChain(const uint8_t *buf, size_t bufLen);
  *         OC_STACK_INVALID_PARAM if the certificate is not valid.
  *         OC_STACK_NO_MEMORY or OC_STACK_ERROR if some other error arose during validation.
  */
-OCStackResult OCInternalVerifyRoleCertificate(const OicSecKey_t *certificateChain,
-                                              const ByteArrayLL_t *trustedCaCerts,
-                                              OicSecRole_t **roles, size_t *rolesLength,
-                                              struct tm *notValidAfter);
+OCStackResult OCInternalVerifyRoleCertificate(const OicSecKey_t *certificateChain, const uint8_t *trustedCaCerts,
+                                              size_t trustedCaCertsLength, OicSecRole_t **roles,
+                                              size_t *rolesLength, struct tm *notValidAfter);
 #endif
index 4169c19..a39e3ac 100644 (file)
@@ -237,7 +237,7 @@ OCStackResult GetCredRownerId(OicUuid_t *rowneruuid);
  * @param[out] crt certificates to be filled.
  * @param[in] usage credential usage string.
  */
-void GetCaCert(ByteArrayLL_t * crt, const char * usage);
+OCStackResult GetPemCaCert(ByteArray_t * crt, const char * usage);
 
 /**
  * Get a list of all role certificates. Used when asserting roles.
@@ -256,7 +256,7 @@ OCStackResult GetAllRoleCerts(RoleCertChain_t** roleCerts);
  * @param[out] crt certificate chain to be filled.
  * @param[in] usage credential usage string.
  */
-void GetOwnCert(ByteArrayLL_t * crt, const char * usage);
+void GetPemOwnCert(ByteArray_t * crt, const char * usage);
 /**
  * Used by mbedTLS to retrieve own private key
  *
index 57343a8..89bc527 100644 (file)
@@ -29,7 +29,6 @@
 #include "cacommon.h"
 #include "ocrandom.h"
 #include "cacommonutil.h"
-#include "parsechain.h"
 
 #include "ocpayload.h"
 #include "payload_logging.h"
@@ -441,10 +440,9 @@ static const mbedtls_x509_crt_profile s_certProfile = {
     0                                                   /* RSA minimum key length - not used because we only use EC key pairs */
 };
 
-OCStackResult OCInternalVerifyRoleCertificate(const OicSecKey_t *certificateChain,
-                                              const ByteArrayLL_t *trustedCaCerts,
-                                              OicSecRole_t **roles, size_t *rolesLength,
-                                              struct tm *notValidAfter)
+OCStackResult OCInternalVerifyRoleCertificate(const OicSecKey_t *certificateChain, const uint8_t *trustedCaCerts,
+                                              size_t trustedCaCertsLength, OicSecRole_t **roles,
+                                              size_t *rolesLength, struct tm *notValidAfter)
 {
     bool freeData = false;
     uint8_t *data = certificateChain->data;
@@ -504,17 +502,10 @@ OCStackResult OCInternalVerifyRoleCertificate(const OicSecKey_t *certificateChai
         goto exit;
     }
 
-    int errNum;
-    int count = ParseChain(&trustedCas, trustedCaCerts, &errNum);
-    if (0 >= count)
-    {
-        OIC_LOG(WARNING, TAG, "Could not parse trusted CA certs");
-        res = OC_STACK_ERROR;
-        goto exit;
-    }
-    if (0 != errNum)
+    mbedRet = mbedtls_x509_crt_parse(&trustedCas, trustedCaCerts, trustedCaCertsLength);
+    if (0 > mbedRet)
     {
-        OIC_LOG_V(WARNING, TAG, "Trusted CA certs parsing error: %d certs failed to parse", errNum);
+        OIC_LOG_V(ERROR, TAG, "Could not parse trusted CA certs: %d", mbedRet);
         res = OC_STACK_ERROR;
         goto exit;
     }
@@ -649,4 +640,4 @@ exit:
     OIC_LOG_V(DEBUG, TAG, "OCInternalVerifyRoleCertificate out: %d", res);
 
     return res;
-}
+}
\ No newline at end of file
index 702b7f0..ef50835 100644 (file)
@@ -3160,14 +3160,112 @@ bool IsCredRowneruuidTheNilUuid()
 }
 
 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
-void GetCaCert(ByteArrayLL_t * chain, const char * usage)
+/* Caller must call OICFree on *der when finished. */
+static int ConvertPemCertToDer(const char *pem, size_t pemLen, uint8_t** der, size_t* derLen)
+{
+    const char* pemHeader = "-----BEGIN CERTIFICATE-----"; /* no newlines allowed here */
+    const char* pemFooter = "-----END CERTIFICATE-----";
+
+    mbedtls_pem_context ctx;
+    int ret;
+
+    OC_UNUSED(pemLen);
+
+    mbedtls_pem_init(&ctx);
+    size_t usedLen;
+    ret = mbedtls_pem_read_buffer(&ctx, pemHeader, pemFooter, (const uint8_t*) pem, NULL, 0, &usedLen);
+    if (ret != 0)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: failed reading PEM cert", __func__);
+        goto exit;
+    }
+
+    uint8_t *buf = OICCalloc(1, ctx.buflen);
+    if (NULL == buf)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to allocate memory");
+        ret = -1;
+        goto exit;
+    }
+
+    memcpy(buf, ctx.buf, ctx.buflen);
+
+    *der = buf;
+    *derLen = ctx.buflen;
+
+exit:
+    mbedtls_pem_free(&ctx);
+
+    return ret;
+}
+
+/* Caller must call OICFree on *pem when finished. */
+static int ConvertDerCertToPem(const uint8_t* der, size_t derLen, uint8_t** pem)
+{
+    const char* pemHeader = "-----BEGIN CERTIFICATE-----\n";
+    const char* pemFooter = "-----END CERTIFICATE-----\n";
+
+    /* Get the length required for output */
+    size_t pemLen;
+    int ret = mbedtls_pem_write_buffer(pemHeader,
+        pemFooter,
+        der,
+        derLen,
+        NULL,
+        0,
+        &pemLen);
+    if (ret != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL)
+    {
+        OIC_LOG_V(ERROR, TAG, "Couldn't convert cert into PEM, failed getting required length: %d", ret);
+        return ret;
+    }
+
+    *pem = OICCalloc(1, pemLen + 1);
+    if (*pem == NULL)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to allocate memory for PEM cert");
+        return ret;
+    }
+
+    /* Try the conversion */
+    ret = mbedtls_pem_write_buffer(pemHeader,
+        pemFooter,
+        der,
+        derLen,
+        *pem,
+        pemLen,
+        &pemLen);
+    if (ret < 0)
+    {
+        OIC_LOG_V(ERROR, TAG, "Couldn't convert cert into PEM, failed writing PEM: %d", ret);
+        OICFreeAndSetToNull((void **) pem);
+        return ret;
+    }
+
+    return 0;
+}
+
+static OCStackResult GetCaCert(ByteArray_t * crt, const char * usage, OicEncodingType_t desiredEncoding)
 {
     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
-    if (NULL == chain || NULL == usage)
+    if (NULL == crt || NULL == usage)
     {
         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
-        return;
+        return OC_STACK_INVALID_PARAM;
     }
+
+    switch (desiredEncoding)
+    {
+    case OIC_ENCODING_PEM:
+    case OIC_ENCODING_DER:
+    case OIC_ENCODING_BASE64:
+        break;
+    default:
+        OIC_LOG_V(ERROR, TAG, "%s: Unsupported encoding %d", __func__, desiredEncoding);
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    crt->len = 0;
     OicSecCred_t* temp = NULL;
 
     LL_FOREACH(gCred, temp)
@@ -3176,6 +3274,7 @@ void GetCaCert(ByteArrayLL_t * chain, const char * usage)
             (temp->credUsage != NULL) &&
             (0 == strcmp(temp->credUsage, usage)) && (false == temp->optionalData.revstat))
         {
+
             if ((OIC_ENCODING_BASE64 != temp->publicData.encoding) &&
                 (OIC_ENCODING_PEM != temp->publicData.encoding) &&
                 (OIC_ENCODING_DER != temp->publicData.encoding))
@@ -3184,114 +3283,118 @@ void GetCaCert(ByteArrayLL_t * chain, const char * usage)
                 continue;
             }
 
-            if ((OIC_ENCODING_BASE64 == temp->publicData.encoding) ||
-                (OIC_ENCODING_PEM == temp->publicData.encoding))
+            if (OIC_ENCODING_DER == desiredEncoding)
             {
-                size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->publicData.len + 1));
-                uint8_t * buf = OICCalloc(1, bufSize);
-                if(NULL == buf)
-                {
-                    OIC_LOG(ERROR, TAG, "Failed to allocate memory");
-                    return;
-                }
-                size_t outSize;
-                if(B64_OK != b64Decode((char*)(temp->publicData.data),
-                                       temp->publicData.len, buf, bufSize, &outSize))
+                if ((OIC_ENCODING_BASE64 == temp->publicData.encoding) ||
+                    (OIC_ENCODING_PEM == temp->publicData.encoding))
                 {
-                    OICFree(buf);
-                    OIC_LOG(ERROR, TAG, "Failed to decode base64 data");
-                    return;
-                }
+                    uint8_t* buf = NULL;
+                    size_t outSize = 0;
+                    int ret = ConvertPemCertToDer((const char*)temp->publicData.data, temp->publicData.len, &buf, &outSize);
+                    if (0 > ret)
+                    {
+                        OIC_LOG(ERROR, TAG, "Could not convert PEM cert to DER");
+                        return OC_STACK_ERROR;
+                    }
 
-                // mbedtls_x509_crt_parse requires a null terminator in case of PEM certificate
-                if (buf[outSize - 1] != 0x0)
-                {
-                    OIC_LOG_V(DEBUG, TAG, "%s: adding null terminator at the end of the cert", __func__);
-                    uint8_t * oldBuf = buf;
-                    buf = OICRealloc(buf, outSize + 1);
-                    if (NULL == buf)
+                    uint8_t *savePtr = crt->data;
+                    crt->data = OICRealloc(crt->data, crt->len + outSize);
+                    if (NULL == crt->data)
                     {
-                        OIC_LOG(ERROR, TAG, "No memory reallocating buf");
-                        OICFree(oldBuf);
-                        return;
+                        OIC_LOG(ERROR, TAG, "No memory reallocating crt->data");
+                        OICFree(savePtr);
+                        OICFree(buf);
+                        return OC_STACK_NO_MEMORY;
                     }
-                    buf[outSize] = 0x0;
-                    outSize += 1;
-                }
-                ByteArray_t * item = (ByteArray_t *) OICMalloc (sizeof(ByteArray_t));
-                if(NULL == item)
-                {
-                    OIC_LOG(ERROR, TAG, "Failed to allocate memory");
+                    memcpy(crt->data + crt->len, buf, outSize);
+                    crt->len += outSize;
                     OICFree(buf);
-                    return;
-                }
-                item->data = buf;
-                item->len = outSize;
-
-                if (chain->cert == NULL)
-                {
-                    chain->cert = item;
                 }
                 else
                 {
-                    ByteArrayLL_t * tmp = (ByteArrayLL_t *) OICMalloc (sizeof(ByteArrayLL_t));
-                    if(NULL == tmp)
+                    uint8_t *savePtr = crt->data;
+                    crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
+                    if (NULL == crt->data)
                     {
-                        OIC_LOG(ERROR, TAG, "Failed to allocate memory");
-                        OICFree(buf);
-                        OICFree(item);
-                        return;
+                        OIC_LOG(ERROR, TAG, "No memory reallocating crt->data");
+                        OICFree(savePtr);
+                        return OC_STACK_NO_MEMORY;
                     }
-                    tmp->cert = item;
-                    LL_APPEND(chain, tmp);
+                    memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
+                    crt->len += temp->publicData.len;
                 }
+                OIC_LOG_V(DEBUG, TAG, "%s found", usage);
             }
             else
             {
-                ByteArray_t * item = (ByteArray_t *) OICMalloc (sizeof(ByteArray_t));
-                if(NULL == item)
+                /* PEM/Base64 */
+                uint8_t *pem = NULL;
+                size_t pemLen = 0;
+                if ((OIC_ENCODING_BASE64 == temp->publicData.encoding) ||
+                    (OIC_ENCODING_PEM == temp->publicData.encoding))
                 {
-                    OIC_LOG(ERROR, TAG, "Failed to allocate memory");
-                    return;
-                }
-                item->data = (uint8_t *) OICMalloc (temp->publicData.len);
-                if(NULL == item->data)
-                {
-                    OIC_LOG(ERROR, TAG, "Failed to allocate memory");
-                    OICFree(item);
-                    return;
-                }
-                memcpy(item->data, temp->publicData.data, temp->publicData.len);
-                item->len = temp->publicData.len;
-
-                if (chain->cert == NULL)
-                {
-                    chain->cert = item;
+                    pem = temp->publicData.data;
+                    pemLen = temp->publicData.len;
                 }
                 else
                 {
-                    ByteArrayLL_t * tmp = (ByteArrayLL_t *) OICMalloc (sizeof(ByteArrayLL_t));
-                    if(NULL == tmp)
+                    int ret = ConvertDerCertToPem(temp->publicData.data, temp->publicData.len, &pem);
+                    if (0 > ret)
                     {
-                        OIC_LOG(ERROR, TAG, "Failed to allocate memory");
-                        OICFree(item->data);
-                        OICFree(item);
-                        return;
+                        OIC_LOG_V(ERROR, TAG, "Failed converting DER cert to PEM: %d", ret);
+                        return OC_STACK_ERROR;
                     }
-                    tmp->cert = item;
-                    LL_APPEND(chain, tmp);
+                    pemLen = strlen((char *)pem) + 1;
+                }
+
+                uint8_t *oldData = crt->data;
+                crt->data = OICRealloc(crt->data, crt->len + pemLen);
+                if (NULL == crt->data)
+                {
+                    OIC_LOG(ERROR, TAG, "No memory reallocating crt->data");
+                    OICFree(oldData);
+                    return OC_STACK_NO_MEMORY;
                 }
+                memcpy(crt->data + crt->len, pem, pemLen);
+                crt->len += pemLen;
             }
-            OIC_LOG_V(DEBUG, TAG, "%s found", usage);
         }
     }
-    if(NULL == chain->cert)
+    if(0 == crt->len)
     {
         OIC_LOG_V(WARNING, TAG, "%s not found", usage);
+        return OC_STACK_NO_RESOURCE;
+    }
+
+    if (OIC_ENCODING_PEM == desiredEncoding)
+    {
+        /* mbedtls_x509_crt_parse requires a null terminator to determine that the format is PEM */
+        size_t crtLength = crt->len;
+        bool addNull = (crt->data[crtLength - 1] != 0);
+
+        if (addNull)
+        {
+            OIC_LOG_V(DEBUG, TAG, "%s: adding null terminator at the end of the cert", __func__);
+            uint8_t *oldData = crt->data;
+            crt->data = OICRealloc(crt->data, crtLength + 1);
+            if (NULL == crt->data)
+            {
+                OIC_LOG(ERROR, TAG, "No memory reallocating crt->data");
+                OICFree(oldData);
+                return OC_STACK_NO_MEMORY;
+            }
+            crt->data[crtLength] = 0;
+            crt->len = crtLength + 1;
+        }
     }
 
     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
-    return;
+    return OC_STACK_OK;
+}
+
+OCStackResult GetPemCaCert(ByteArray_t * crt, const char * usage)
+{
+    return GetCaCert(crt, usage, OIC_ENCODING_PEM);
 }
 
 static int cloneSecKey(OicSecKey_t * dst, OicSecKey_t * src)
@@ -3368,58 +3471,110 @@ error:
     return OC_STACK_ERROR;
 }
 
-void GetOwnCert(ByteArrayLL_t * chain, const char * usage)
+void GetPemOwnCert(ByteArray_t * crt, const char * usage)
 {
     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
-    if (NULL == chain || NULL == usage)
+    if (NULL == crt || NULL == usage)
     {
         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
         return;
     }
+    crt->len = 0;
     OicSecCred_t * temp = NULL;
     LL_FOREACH(gCred, temp)
     {
         if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
+            temp->credUsage != NULL &&
             0 == strcmp(temp->credUsage, usage))
         {
-            ByteArray_t * item = (ByteArray_t *) OICMalloc (sizeof(ByteArray_t));
-            if(NULL == item)
+            uint8_t *p = NULL;
+            int mbedRet = 0;
+            uint8_t *pem = NULL;
+            size_t pemLen = 0;
+            bool mustFreePem = false;
+            bool mustAddNull = true;
+
+            switch (temp->publicData.encoding)
             {
-                OIC_LOG(ERROR, TAG, "Failed to allocate memory");
+            case OIC_ENCODING_DER:
+            case OIC_ENCODING_RAW:
+                mbedRet = ConvertDerCertToPem(temp->publicData.data, temp->publicData.len, &pem);
+                if (0 > mbedRet)
+                {
+                    OIC_LOG_V(ERROR, TAG, "Failed to ConvertDerCertToPem: %d", mbedRet);
+                    return;
+                }
+                mustFreePem = true;
+                mustAddNull = false; /* mbedTLS always NULL-terminates. */
+                pemLen = strlen((char *)pem) + 1;
+                break;
+
+            case OIC_ENCODING_PEM:
+            case OIC_ENCODING_BASE64:
+                pem = temp->publicData.data;
+                pemLen = temp->publicData.len;
+
+                /* Make sure the buffer has a terminating NULL. If not, make sure we add one later. */
+                for (size_t i = pemLen - 1; i > 0; i--)
+                {
+                    if ('\0' == (char)pem[i])
+                    {
+                        mustAddNull = false;
+                        break;
+                    }
+                }
+                break;
+
+            default:
+                OIC_LOG_V(ERROR, TAG, "Unsupported encoding %d", temp->publicData.encoding);
                 return;
             }
-            item->data = (uint8_t *) OICMalloc (temp->publicData.len);
-            if(NULL == item->data)
+
+            p = crt->data;
+            crt->data = OICRealloc(crt->data, crt->len + pemLen + (mustAddNull ? 1 : 0));
+            if (NULL == crt->data)
             {
-                OIC_LOG(ERROR, TAG, "Failed to allocate memory");
-                OICFree(item);
+                OIC_LOG(ERROR, TAG, "No memory reallocating crt->data");
+                OICFree(p);
+                if (mustFreePem)
+                {
+                    OICFree(pem);
+                }
                 return;
             }
-            memcpy(item->data, temp->publicData.data, temp->publicData.len);
-            item->len = temp->publicData.len;
 
-            if (chain->cert == NULL)
+            /* If we're appending, subtract one from crt->len below so we overwrite the current terminating
+             * NULL with the beginning of the new data.
+             */
+            if (0 < crt->len)
             {
-                chain->cert = item;
+                assert(crt->data[crt->len - 1] == '\0');
+                memcpy(crt->data + crt->len - 1, pem, pemLen);
+                crt->len += pemLen - 1;
             }
             else
             {
-                ByteArrayLL_t * tmp = (ByteArrayLL_t *) OICMalloc (sizeof(ByteArrayLL_t));
-                if(NULL == tmp)
-                {
-                    OIC_LOG(ERROR, TAG, "Failed to allocate memory");
-                    OICFree(item->data);
-                    OICFree(item);
-                    return;
-                }
-                tmp->cert = item;
-                LL_APPEND(chain, tmp);
+                memcpy(crt->data, pem, pemLen);
+                crt->len = pemLen;
+            }
+
+            /* If pem doesn't contain a terminating NULL, add one. */
+            if (mustAddNull)
+            {
+                assert(crt->data[crt->len - 1] != '\0');
+                crt->data[crt->len] = '\0';
+                crt->len += 1;
+            }
+
+            if (mustFreePem)
+            {
+                OICFree(pem);
             }
 
             OIC_LOG_V(DEBUG, TAG, "%s found", usage);
         }
     }
-    if(NULL == chain->cert)
+    if(0 == crt->len)
     {
         OIC_LOG_V(WARNING, TAG, "%s not found", usage);
     }
index 3e77cbb..1fad524 100644 (file)
@@ -36,8 +36,8 @@ void GetPkixInfo(PkiInfo_t * inf)
         return;
     }
 
-    GetOwnCert(&inf->crt, PRIMARY_CERT);
-    if (NULL == inf->crt.cert || 0 == inf->crt.cert->len)
+    GetPemOwnCert(&inf->crt, PRIMARY_CERT);
+    if (inf->crt.len == 0)
     {
         OIC_LOG_V(WARNING, TAG, "%s: empty certificate", __func__);
     }
@@ -48,8 +48,8 @@ void GetPkixInfo(PkiInfo_t * inf)
         OIC_LOG_V(WARNING, TAG, "%s: empty key", __func__);
     }
 
-    GetCaCert(&inf->ca, TRUST_CA);
-    if (NULL == inf->ca.cert || 0 == inf->ca.cert->len)
+    (void)GetPemCaCert(&inf->ca, TRUST_CA);
+    if (inf->ca.len == 0)
     {
         OIC_LOG_V(WARNING, TAG, "%s: empty CA cert", __func__);
     }
@@ -67,17 +67,9 @@ void GetManufacturerPkixInfo(PkiInfo_t * inf)
         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
         return;
     }
-    GetOwnCert(&inf->crt, MF_PRIMARY_CERT);
-    if (NULL == inf->crt.cert || 0 == inf->crt.cert->len)
-    {
-        OIC_LOG_V(WARNING, TAG, "%s: empty certificate", __func__);
-    }
+    GetPemOwnCert(&inf->crt, MF_PRIMARY_CERT);
     GetDerKey(&inf->key, MF_PRIMARY_CERT);
-    GetCaCert(&inf->ca, MF_TRUST_CA);
-    if (NULL == inf->ca.cert || 0 == inf->ca.cert->len)
-    {
-        OIC_LOG_V(WARNING, TAG, "%s: empty CA cert", __func__);
-    }
+    (void)GetPemCaCert(&inf->ca, MF_TRUST_CA);
     // CRL not provided
     inf->crl.data = NULL;
     inf->crl.len = 0;
index 4f74f46..ce4b144 100644 (file)
@@ -49,7 +49,6 @@
 #include "ocstackinternal.h"
 #include "rolesresource.h"
 #include "secureresourcemanager.h"
-#include "parsechain.h"
 
 #define TAG  "OIC_SRM_ROLES"
 
@@ -1159,7 +1158,7 @@ OCStackResult GetEndpointRoles(const CAEndpoint_t *endpoint, OicSecRole_t **role
     RolesEntry_t *targetEntry = NULL;
     OicSecRole_t *rolesToReturn = NULL;
     size_t rolesToReturnCount = 0;
-    ByteArrayLL_t trustedCaCerts;
+    ByteArray_t trustedCaCerts;
     memset(&trustedCaCerts, 0, sizeof(trustedCaCerts));
 
     OCStackResult res = GetPeerPublicKeyFromEndpoint(endpoint, &publicKey, &publicKeyLength);
@@ -1274,8 +1273,8 @@ OCStackResult GetEndpointRoles(const CAEndpoint_t *endpoint, OicSecRole_t **role
     InvalidateRoleCache(targetEntry);
 
     /* Retrieve the current set of trusted CAs from the cred resource. */
-    GetCaCert(&trustedCaCerts, TRUST_CA);
-    if (NULL == trustedCaCerts.cert || 0 == trustedCaCerts.cert->len)
+    res = GetPemCaCert(&trustedCaCerts, TRUST_CA);
+    if (OC_STACK_OK != res)
     {
         OIC_LOG_V(ERROR, TAG, "Could not get CA certs: %d", res);
         OICFree(publicKey);
@@ -1291,7 +1290,8 @@ OCStackResult GetEndpointRoles(const CAEndpoint_t *endpoint, OicSecRole_t **role
         struct tm notValidAfter;
         memset(&notValidAfter, 0, sizeof(notValidAfter));
 
-        res = OCInternalVerifyRoleCertificate(&chain->certificate, &trustedCaCerts, &currCertRoles,
+        res = OCInternalVerifyRoleCertificate(&chain->certificate, trustedCaCerts.data,
+                                              trustedCaCerts.len, &currCertRoles,
                                               &currCertRolesCount, &notValidAfter);
 
         if (OC_STACK_OK != res)
@@ -1311,7 +1311,7 @@ OCStackResult GetEndpointRoles(const CAEndpoint_t *endpoint, OicSecRole_t **role
             {
                 OIC_LOG(ERROR, TAG, "No memory reallocating rolesToReturn");
                 memset(&targetEntry->cacheValidUntil, 0, sizeof(targetEntry->cacheValidUntil));
-                FreeCertChain(&trustedCaCerts);
+                OICFree(trustedCaCerts.data);
                 OICFree(savePtr);
                 OICFree(currCertRoles);
                 OICFree(publicKey);
@@ -1354,14 +1354,14 @@ OCStackResult GetEndpointRoles(const CAEndpoint_t *endpoint, OicSecRole_t **role
     if (NULL == *roles)
     {
         OICFree(publicKey);
-        FreeCertChain(&trustedCaCerts);
+        OICFree(trustedCaCerts.data);
         return OC_STACK_NO_MEMORY;
     }
     memcpy(*roles, targetEntry->cachedRoles, (targetEntry->cachedRolesLength * sizeof(OicSecRole_t)));
     *roleCount = targetEntry->cachedRolesLength;
 
     OICFree(publicKey);
-    FreeCertChain(&trustedCaCerts);
+    OICFree(trustedCaCerts.data);
     return OC_STACK_OK;
 }
 
index b6d35ec..5798c5e 100644 (file)
@@ -61,14 +61,6 @@ typedef enum SubOperationType
     BACK = 99
 } SubOperationType_t;
 
-typedef struct
-{
-    ByteArray_t crt;    /**< own certificate chain as a null-terminated PEM string of certificates */
-    ByteArray_t key;    /**< own private key as binary-encoded DER */
-    ByteArray_t ca;     /**< trusted CAs as a null-terminated PEM string of certificates */
-    ByteArray_t crl;    /**< trusted CRLs as binary-encoded DER */
-} PkiInfoCrt_t;
-
 void PrintUuid(const OicUuid_t *uuid);
 void PrintIntArray(const int *array, size_t length);
 void PrintStringArray(const char **array, size_t length);
index c0ccb12..1cf86e0 100644 (file)
@@ -266,10 +266,10 @@ void PrintCredList(const OicSecCred_t *creds)
                         char buf[2048];
                         mbedtls_x509_crt crt;
                         mbedtls_x509_crt *tmpCrt = NULL;
-                        PkiInfoCrt_t inf;
+                        PkiInfo_t inf;
                         int i = 0;
 
-                        memset(&inf, 0x00, sizeof(PkiInfoCrt_t));
+                        memset(&inf, 0x00, sizeof(PkiInfo_t));
                         mbedtls_x509_crt_init(&crt);
 
                         ParseDerOwnCert(&inf.crt, cred->credUsage, cred->credId);
@@ -310,10 +310,10 @@ void PrintCredList(const OicSecCred_t *creds)
                         char buf[2048];
                         mbedtls_x509_crt ca;
                         mbedtls_x509_crt *tmpCa = NULL;
-                        PkiInfoCrt_t inf;
+                        PkiInfo_t inf;
                         int i = 0;
 
-                        memset(&inf, 0x00, sizeof(PkiInfoCrt_t));
+                        memset(&inf, 0x00, sizeof(PkiInfo_t));
                         mbedtls_x509_crt_init(&ca);
 
                         ParseDerCaCert(&inf.ca, cred->credUsage, cred->credId);