[IOT-1475] Remove DER/PEM mixing in ParseChain
authorKevin Kane <kkane@microsoft.com>
Tue, 7 Mar 2017 22:43:57 +0000 (14:43 -0800)
committerGreg Zaverucha <gregz@microsoft.com>
Thu, 23 Mar 2017 17:35:25 +0000 (17:35 +0000)
Change cred resource to always provide own certificate as a PEM
string, and no longer require ParseChain to heuristically parse
a mixed bag of DER and PEM certs.

Also, go back to having ParseChain return an int rather than a size_t
which was changed during /W4 warning cleanup; it must be able to return
negative values to indicate errors.

Change-Id: Id36962ed580eb3bccc110aac0350349b05674ee7
Signed-off-by: Kevin Kane <kkane@microsoft.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/17835
Tested-by: jenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: Alex Kelley <alexke@microsoft.com>
Reviewed-by: Greg Zaverucha <gregz@microsoft.com>
resource/csdk/connectivity/api/casecurityinterface.h
resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c
resource/csdk/connectivity/test/ssladapter_test.cpp
resource/csdk/security/include/internal/credresource.h
resource/csdk/security/src/credresource.c
resource/csdk/security/src/pkix_interface.c

index 1238a48..ed05a36 100644 (file)
@@ -114,14 +114,10 @@ typedef void (*CAgetCredentialTypesHandler)(bool * list);
  */
 typedef struct
 {
-    // own certificate chain
-    ByteArray_t crt;
-    // own public key
-    ByteArray_t key;
-    // trusted CA's
-    ByteArray_t ca;
-    // trusted CRL's
-    ByteArray_t crl;
+    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 */
 } PkiInfo_t;
 
 /**
index dd28412..9261663 100755 (executable)
@@ -562,116 +562,51 @@ static int RecvCallBack(void * tep, unsigned char * data, size_t dataLen)
  * Parse chain of X.509 certificates.
  *
  * @param[out] crt     container for X.509 certificates
- * @param[in]  data    buffer with X.509 certificates. Certificates may be in either in PEM
                      or DER format in a jumble, delimiting symbols does not matter.
+ * @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 size_t ParseChain(mbedtls_x509_crt * crt, unsigned char * buf, size_t bufLen, int * errNum)
+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);
 
-    char pemCertHeader[] = {
-        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
-    };
-    char pemCertFooter[] = {
-        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
-    };
-    size_t pemCertHeaderLen = sizeof(pemCertHeader);
-    size_t pemCertFooterLen = sizeof(pemCertFooter);
-
-    size_t len = 0;
-    unsigned char * tmp = NULL;
-    size_t count = 0;
-    int ret = 0;
-    size_t pos = 0;
+    if (NULL != errNum)
+    {
+        *errNum = 0;
+    }
 
-    *errNum = 0;
-    while (pos < bufLen)
+    if ((bufLen >= 2) && (buf[0] == 0x30) && (buf[1] == 0x82))
     {
-        if (buf[pos] == 0x30 && buf[pos + 1] == 0x82)
-        {
-            tmp = (unsigned char *)buf + pos + 1;
-            CHECK_MBEDTLS_RET(mbedtls_asn1_get_len, &tmp, buf + bufLen, &len);
-            if (pos + len < bufLen)
-            {
-                ret = mbedtls_x509_crt_parse_der(crt, buf + pos, len + 4);
-                if (0 == ret)
-                {
-                    count++;
-                }
-                else
-                {
-                    (*errNum)++;
-                    OIC_LOG_V(ERROR, NET_SSL_TAG, "mbedtls_x509_crt_parse_der returned -0x%04x\n", -(ret));
-                }
-            }
-            pos += len + 4;
-        }
-        else if ((buf + pos + pemCertHeaderLen < buf + bufLen) &&
-                 (0 == memcmp(buf + pos, pemCertHeader, pemCertHeaderLen)))
-        {
-            void * endPos = NULL;
-            endPos = memmem(&(buf[pos]), bufLen - pos, pemCertFooter, pemCertFooterLen);
-            if (NULL == endPos)
-            {
-                OIC_LOG(ERROR, NET_SSL_TAG, "Error: end of PEM certificate not found.");
-                OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
-                return -1;
-            }
-            len = (char*)endPos - ((char*)buf + pos) + pemCertFooterLen;
-            if (pos + len + 1 <= bufLen)
-            {
-                char con = buf[pos + len];
-                buf[pos + len] = 0x00;
-                ret = mbedtls_x509_crt_parse(crt, buf + pos, len + 1);
-                if (0 == ret)
-                {
-                    count++;
-                }
-                else
-                {
-                    (*errNum)++;
-                    OIC_LOG_V(ERROR, NET_SSL_TAG, "mbedtls_x509_crt_parse returned -0x%04x\n", -(ret));
-                }
-                buf[pos + len] = con;
-            }
-            else
-            {
-                unsigned char * lastCert = (unsigned char *)OICMalloc((len + 1) * sizeof(unsigned char));
-                memcpy(lastCert, buf + pos, len);
-                lastCert[len] = 0x00;
-                ret = mbedtls_x509_crt_parse(crt, lastCert, len + 1);
-                if (0 == ret)
-                {
-                    count++;
-                }
-                else
-                {
-                    (*errNum)++;
-                    OIC_LOG_V(ERROR, NET_SSL_TAG, "mbedtls_x509_crt_parse returned -0x%04x\n", -(ret));
-                }
-                OICFree(lastCert);
-            }
-            pos += len;
-        }
-        else
-        {
-            pos++;
-        }
+        OIC_LOG_V(ERROR, NET_SSL_TAG, "DER-encoded certificate passed to ParseChain");
+        return -1;
     }
-    OIC_LOG_V(DEBUG, NET_SSL_TAG, "%s successfully parsed %d certificates", __func__, count);
-    OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
-    return count;
 
-exit:
-    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;
 }
 
 //Loads PKIX related information from SRM
@@ -706,7 +641,7 @@ static int InitPKIX(CATransportAdapter_t adapter)
     // optional
     int ret;
     int errNum;
-    size_t count = ParseChain(&g_caSslContext->crt, g_pkiInfo.crt.data, g_pkiInfo.crt.len, &errNum);
+    int count = ParseChain(&g_caSslContext->crt, g_pkiInfo.crt.data, g_pkiInfo.crt.len, &errNum);
     if (0 >= count)
     {
         OIC_LOG(WARNING, NET_SSL_TAG, "Own certificate chain parsing error");
index a6188ce..28864b7 100644 (file)
  *
  * *************************/
 
-// Data blob contains 10 certificates in PEM and DER encoding
+// 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,
@@ -167,8 +167,6 @@ unsigned char certChain[] = {
     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,
-    // NULL terminator
-    0x00,
     // 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,
@@ -231,45 +229,6 @@ unsigned char certChain[] = {
     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,
-    // garbage data
-    0x01, 0x02, 0x03, 0x04, 0x05,
-    // DER encoded certificate
-    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,
     // 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,
@@ -374,8 +333,6 @@ unsigned char certChain[] = {
     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,
-    // \n NULL terminator
-    0x0a, 0x00,
     // 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,
@@ -467,84 +424,6 @@ unsigned char certChain[] = {
     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,
-    // \r \n NULL terminator
-    0x0d, 0x0a, 0x00,
-    // DER encoded certificate
-    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,
-    // DER encoded certificate
-    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,
-    // NULL \n terminator
-    0x00, 0x0a,
     // 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,
@@ -607,8 +486,6 @@ unsigned char certChain[] = {
     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,
-    // \r terminator
-    0x0d,
     // 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,
@@ -761,48 +638,27 @@ unsigned char certChain[] = {
     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
+    0x2d, 0x2d, 0x2d,
+    // NULL terminator
+    0x00
 };
 int certChainLen = sizeof(certChain);
 
-unsigned char serverCert[] = {
-    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 serverCert[] =
+    "-----BEGIN CERTIFICATE-----"
+    "MIICOTCCAd8CAQEwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMCVVMxEjAQBgNVBAgM"
+    "CVNvbWVzdGF0ZTERMA8GA1UEBwwIU29tZWNpdHkxCzAJBgNVBAoMAkJCMRYwFAYD"
+    "VQQLDA1TZXF1cml0eSBQYXJ0MQswCQYDVQQDDAJvYjEUMBIGCSqGSIb3DQEJARYF"
+    "b2JAYmIwHhcNMTYwODE1MTMxMTE3WhcNMTkwNTEyMTMxMTE3WjCB1DELMAkGA1UE"
+    "BhMCVUExDDAKBgNVBAgMA0FzZDEPMA0GA1UEBwwGR290aGFtMQswCQYDVQQKDAJa"
+    "WjERMA8GA1UECwwIQmVhbVRlYW0xHDAaBgkqhkiG9w0BCQEWDXJhaWxAbWFpbC5j"
+    "b20xMjAwBgNVBAMMKXV1aWQ6MzIzMjMyMzItMzIzMi0zMjMyLTMyMzItMzIzMjMy"
+    "MzIzMjMyMTQwMgYDVR0RDCt1c2VyaWQ6Njc2NzY3NjctNjc2Ny02NzY3LTY3Njct"
+    "Njc2NzY3Njc2NzY3MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9xNcc3LOEOUJ"
+    "l5r48nCmPYn1xeRE4kq2YagSjbTcK0eEYAwlZung5awivxXccbGITxa/wnc3dj/g"
+    "Z8YdI/58izAKBggqhkjOPQQDAgNIADBFAiBHzEGKJ8fQqrSrhb8JTQbXfg05+Tah"
+    "PZYj4iRkmGMhugIhAOWPf/GmggNqGHpU5w4ld9hG+paKfhTEyyEyPonZuow/"
+    "-----END CERTIFICATE-----";
 int serverCertLen = sizeof(serverCert);
 
 unsigned char serverPrivateKey[] = {
@@ -818,45 +674,22 @@ unsigned char serverPrivateKey[] = {
 
 int serverPrivateKeyLen = sizeof(serverPrivateKey);
 
-unsigned char caCert[] = {
-    0x30, 0x82, 0x02, 0x3e, 0x30, 0x82, 0x01, 0xe5, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
-    0x87, 0xa7, 0x68, 0x01, 0x7c, 0xe9, 0xf8, 0xf0, 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, 0x37, 0x32, 0x35, 0x31, 0x31, 0x31, 0x36,
-    0x31, 0x31, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x35, 0x31, 0x35, 0x31, 0x31, 0x31, 0x36, 0x31,
-    0x31, 0x5a, 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, 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, 0x2e, 0xcf, 0xc3, 0xfa, 0x2e,
-    0x04, 0x11, 0x62, 0x34, 0x63, 0x6f, 0xdf, 0xb6, 0x67, 0xfb, 0x5a, 0x50, 0x8c, 0x15, 0x73, 0xc9,
-    0xc1, 0x57, 0x3a, 0x9e, 0xf8, 0xf4, 0xa8, 0x0c, 0x1a, 0xe9, 0x91, 0x51, 0x9d, 0x03, 0x26, 0x48,
-    0xaa, 0x46, 0x84, 0x12, 0x06, 0x2d, 0xfc, 0x66, 0xbe, 0x41, 0xed, 0xfd, 0xcd, 0x32, 0xa3, 0x9b,
-    0x34, 0xf2, 0xaa, 0x95, 0x1f, 0x8e, 0x5d, 0x49, 0x77, 0x80, 0xc2, 0xa3, 0x50, 0x30, 0x4e, 0x30,
-    0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x1e, 0x81, 0xc3, 0x62, 0xff, 0x8c,
-    0x5a, 0x98, 0x90, 0xac, 0x2c, 0xc3, 0x65, 0xb9, 0x3f, 0x8f, 0x04, 0x55, 0xfa, 0x7c, 0x30, 0x1f,
-    0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x1e, 0x81, 0xc3, 0x62, 0xff,
-    0x8c, 0x5a, 0x98, 0x90, 0xac, 0x2c, 0xc3, 0x65, 0xb9, 0x3f, 0x8f, 0x04, 0x55, 0xfa, 0x7c, 0x30,
-    0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0a, 0x06,
-    0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20,
-    0x1c, 0xa1, 0x55, 0xa8, 0x04, 0xbc, 0x5b, 0x00, 0xa8, 0xac, 0x2f, 0xe6, 0xb7, 0x3c, 0x7c, 0xf3,
-    0x7e, 0x93, 0xce, 0xe0, 0xdf, 0x6e, 0x36, 0xe4, 0x36, 0x20, 0xcb, 0x36, 0x9c, 0x13, 0x3b, 0xc4,
-    0x02, 0x20, 0x7f, 0x18, 0x13, 0x7d, 0x1b, 0x8c, 0xe3, 0x5b, 0xd9, 0xac, 0x74, 0x8c, 0xc0, 0xe9,
-    0xbf, 0x1b, 0x48, 0x6f, 0xb6, 0x6a, 0x45, 0x03, 0xa6, 0x5d, 0x4d, 0x65, 0xf7, 0x96, 0xa0, 0x08,
-    0x83, 0x7c
-};
+unsigned char caCert[] = 
+    "-----BEGIN CERTIFICATE-----"
+    "MIICPjCCAeWgAwIBAgIJAIenaAF86fjwMAoGCCqGSM49BAMCMHwxCzAJBgNVBAYT"
+    "AlVTMRIwEAYDVQQIDAlTb21lc3RhdGUxETAPBgNVBAcMCFNvbWVjaXR5MQswCQYD"
+    "VQQKDAJCQjEWMBQGA1UECwwNU2VxdXJpdHkgUGFydDELMAkGA1UEAwwCb2IxFDAS"
+    "BgkqhkiG9w0BCQEWBW9iQGJiMB4XDTE2MDcyNTExMTYxMVoXDTE5MDUxNTExMTYx"
+    "MVowfDELMAkGA1UEBhMCVVMxEjAQBgNVBAgMCVNvbWVzdGF0ZTERMA8GA1UEBwwI"
+    "U29tZWNpdHkxCzAJBgNVBAoMAkJCMRYwFAYDVQQLDA1TZXF1cml0eSBQYXJ0MQsw"
+    "CQYDVQQDDAJvYjEUMBIGCSqGSIb3DQEJARYFb2JAYmIwWTATBgcqhkjOPQIBBggq"
+    "hkjOPQMBBwNCAAQuz8P6LgQRYjRjb9+2Z/taUIwVc8nBVzqe+PSoDBrpkVGdAyZI"
+    "qkaEEgYt/Ga+Qe39zTKjmzTyqpUfjl1Jd4DCo1AwTjAdBgNVHQ4EFgQUHoHDYv+M"
+    "WpiQrCzDZbk/jwRV+nwwHwYDVR0jBBgwFoAUHoHDYv+MWpiQrCzDZbk/jwRV+nww"
+    "DAYDVR0TBAUwAwEB/zAKBggqhkjOPQQDAgNHADBEAiAcoVWoBLxbAKisL+a3PHzz"
+    "fpPO4N9uNuQ2IMs2nBM7xAIgfxgTfRuM41vZrHSMwOm/G0hvtmpFA6ZdTWX3lqAI"
+    "g3w="
+    "-----END CERTIFICATE-----";
 int caCertLen = sizeof(caCert);
 
 unsigned char control_server_message_ECDHE_ECDSA_WITH_AES_128_CCM[] = {
@@ -3420,5 +3253,6 @@ TEST(TLSAdapter, Test_ParseChain)
     size_t ret = ParseChain(&crt, certChain, certChainLen, &errNum);
     mbedtls_x509_crt_free(&crt);
 
-    EXPECT_EQ(10, ret + errNum);
+    EXPECT_EQ(7, ret);
+    EXPECT_EQ(0, errNum);
 }
index 9f71dad..64b1830 100644 (file)
@@ -219,19 +219,12 @@ OCStackResult GetCredRownerId(OicUuid_t *rowneruuid);
  */
 OCStackResult GetPemCaCert(ByteArray_t * crt, const char * usage);
 /**
- * Used by mbedTLS to retrieve trusted CA certificates as DER
- *
- * @param[out] crt certificates to be filled.
- * @param[in] usage credential usage string.
- */
-void GetDerCaCert(ByteArray_t * crt, const char * usage);
-/**
  * Used by mbedTLS to retrieve own certificate chain
  *
  * @param[out] crt certificate chain to be filled.
  * @param[in] usage credential usage string.
  */
-void GetDerOwnCert(ByteArray_t * crt, const char * usage);
+void GetPemOwnCert(ByteArray_t * crt, const char * usage);
 /**
  * Used by mbedTLS to retrieve owm private key
  *
index c9ba13e..cb72e89 100755 (executable)
@@ -65,9 +65,9 @@
 
 #if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
 #include <mbedtls/ssl_ciphersuites.h>
-#include "mbedtls/pk.h"
-#include "mbedtls/base64.h"
-#include "mbedtls/pem.h"
+#include <mbedtls/pk.h>
+#include <mbedtls/base64.h>
+#include <mbedtls/pem.h>
 #endif
 
 #define TAG  "OIC_SRM_CREDL"
@@ -2880,7 +2880,7 @@ 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*/
+    /* Get the length required for output */
     size_t pemLen;
     int ret = mbedtls_pem_write_buffer(pemHeader, 
         pemFooter,
@@ -2911,7 +2911,7 @@ static int ConvertDerCertToPem(const uint8_t* der, size_t derLen, uint8_t** pem)
         &pemLen);
     if (ret < 0)
     {
-        OIC_LOG_V(ERROR, TAG, "Couldn't convert cert into PEM, failed getting required length: %d", ret);
+        OIC_LOG_V(ERROR, TAG, "Couldn't convert cert into PEM, failed writing PEM: %d", ret);
         OICFreeAndSetToNull(pem);
         return ret;
     }
@@ -3034,17 +3034,12 @@ static OCStackResult GetCaCert(ByteArray_t * crt, const char * usage, OicEncodin
     return OC_STACK_OK;
 }
 
-void GetDerCaCert(ByteArray_t * crt, const char * usage)
-{
-    (void)GetCaCert(crt, usage, OIC_ENCODING_DER);
-}
-
 OCStackResult GetPemCaCert(ByteArray_t * crt, const char * usage)
 {
     return GetCaCert(crt, usage, OIC_ENCODING_PEM);
 }
 
-void GetDerOwnCert(ByteArray_t * crt, const char * usage)
+void GetPemOwnCert(ByteArray_t * crt, const char * usage)
 {
     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
     if (NULL == crt || NULL == usage)
@@ -3060,9 +3055,90 @@ void GetDerOwnCert(ByteArray_t * crt, const char * usage)
             temp->credUsage != NULL &&
             0 == strcmp(temp->credUsage, usage))
         {
-            crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
-            memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
-            crt->len += temp->publicData.len;
+            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)
+            {
+            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;
+            }
+
+            p = crt->data;
+            crt->data = OICRealloc(crt->data, crt->len + pemLen + (mustAddNull ? 1 : 0));
+            if (NULL == crt->data)
+            {
+                OIC_LOG(ERROR, TAG, "No memory reallocating crt->data");
+                OICFree(p);
+                if (mustFreePem)
+                {
+                    OICFree(pem);
+                }
+                return;
+            }
+
+            /* 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) 
+            {
+                assert(crt->data[crt->len - 1] == '\0');
+                memcpy(crt->data + crt->len - 1, pem, pemLen);
+                crt->len += pemLen - 1;
+            }
+            else
+            {
+                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);
         }
     }
index 7c4daaa..5fffd05 100644 (file)
@@ -35,9 +35,9 @@ void GetPkixInfo(PkiInfo_t * inf)
         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
         return;
     }
-    GetDerOwnCert(&inf->crt, PRIMARY_CERT);
+    GetPemOwnCert(&inf->crt, PRIMARY_CERT);
     GetDerKey(&inf->key, PRIMARY_CERT);
-    GetDerCaCert(&inf->ca, TRUST_CA);
+    (void)GetPemCaCert(&inf->ca, TRUST_CA);
     GetDerCrl(&inf->crl);
     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 }
@@ -51,9 +51,9 @@ void GetManufacturerPkixInfo(PkiInfo_t * inf)
         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
         return;
     }
-    GetDerOwnCert(&inf->crt, MF_PRIMARY_CERT);
+    GetPemOwnCert(&inf->crt, MF_PRIMARY_CERT);
     GetDerKey(&inf->key, MF_PRIMARY_CERT);
-    GetDerCaCert(&inf->ca, MF_TRUST_CA);
+    (void)GetPemCaCert(&inf->ca, MF_TRUST_CA);
     // CRL not provided
     inf->crl.data = NULL;
     inf->crl.len = 0;