From 55072b35a3aac687471a16c99a438e5fa6a02fc8 Mon Sep 17 00:00:00 2001
From: Oleksii Beketov
Date: Thu, 6 Oct 2016 15:33:07 +0300
Subject: [PATCH] parseChain() fix
parseChain() from ca_adapter_net_tls.c that parse chain of X509 certificates
in DER or PEM format bug fixed. Line endings for PEM certificates corrected.
Change-Id: Ieed09114fea10eb5adb6ff88d59ca58074ea19bb
Signed-off-by: Oleksii Beketov
Reviewed-on: https://gerrit.iotivity.org/gerrit/12045
Tested-by: jenkins-iotivity
Reviewed-by: Kevin Kane
Reviewed-by: Randeep Singh
---
.../src/adapter_util/ca_adapter_net_tls.c | 72 +++++++++++++++++-----
1 file changed, 57 insertions(+), 15 deletions(-)
diff --git a/resource/csdk/connectivity/src/adapter_util/ca_adapter_net_tls.c b/resource/csdk/connectivity/src/adapter_util/ca_adapter_net_tls.c
index 66a5f97..34c239b 100644
--- a/resource/csdk/connectivity/src/adapter_util/ca_adapter_net_tls.c
+++ b/resource/csdk/connectivity/src/adapter_util/ca_adapter_net_tls.c
@@ -434,60 +434,102 @@ static int recvTls(void * tep, unsigned char * data, size_t dataLen)
*
* @return 0 on success, -1 on error
*/
-static int parseChain(mbedtls_x509_crt * crt, const unsigned char * buf, int buflen)
+static int parseChain(mbedtls_x509_crt * crt, const unsigned char * buf, uint32_t buflen)
{
+ OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
VERIFY_NON_NULL_RET(crt, NET_TLS_TAG, "Param crt is NULL" , -1);
VERIFY_NON_NULL_RET(buf, NET_TLS_TAG, "Param buf is NULL" , -1);
+ uint32_t pos = 0;
+ size_t len = 0;
+
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, 0x0a, 0x00
+ 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
};
+ char derCertHeader[] = { 0x30, 0x82 };
size_t pemCertHeaderLen = sizeof(pemCertHeader);
size_t pemCertFooterLen = sizeof(pemCertFooter);
+ size_t derCertHeaderLen = sizeof(derCertHeader);
+ size_t derCertLengthSectionLen = 2; // for two length bytes after der header
- int pos = 0;
- int len = 0;
- int ret = 0;
while (pos < buflen)
{
- if (0x30 == buf[pos] && 0x82 == buf[pos + 1] && pos + 3 < buflen)
+ int ret = 0;
+ if (0 == memcmp(buf + pos, derCertHeader, derCertHeaderLen))
{
- len = (((int) buf[pos+2]) << 8) | buf[pos+3];
+ unsigned char * derPtr = NULL;
+ derPtr = (unsigned char *)buf + pos + 1;
+ ret = mbedtls_asn1_get_len(&derPtr, buf + buflen, &len);
+ if(0 != ret)
+ {
+ OIC_LOG_V(ERROR, NET_TLS_TAG, "mbedtls_asn1_get_len returned -0x%x", -ret);
+ OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
+ return -1;
+ }
if (pos + len < buflen)
{
- ret = mbedtls_x509_crt_parse_der(crt, buf+pos, len + 4);
+ len += derCertHeaderLen + derCertLengthSectionLen;
+ ret = mbedtls_x509_crt_parse_der(crt, buf + pos, len);
if( 0 != ret)
{
- OIC_LOG_V(ERROR, NET_TLS_TAG, "mbedtls_x509_crt_parse returned -0x%x", -ret);
+ OIC_LOG_V(ERROR, NET_TLS_TAG,
+ "mbedtls_x509_crt_parse_der returned -0x%x", -ret);
+ OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
return -1;
}
}
- pos += len + 4;
+ pos += len;
}
else if (0 == memcmp(buf + pos, pemCertHeader, pemCertHeaderLen))
{
- void * endPos = NULL;
- endPos = memmem(&(buf[pos]), buflen - pos, pemCertFooter, pemCertFooterLen);
+ char * endPos = NULL;
+ endPos = (char*)memmem(&(buf[pos]), buflen - pos, pemCertFooter, pemCertFooterLen);
if (NULL == endPos)
{
OIC_LOG(ERROR, NET_TLS_TAG, "Error: end of PEM certificate not found.");
+ OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
+ return -1;
+ }
+ if ((*(endPos + pemCertFooterLen + 0) == '\r') &&
+ (*(endPos + pemCertFooterLen + 1) == '\n') &&
+ (*(endPos + pemCertFooterLen + 2) == '\0'))
+ {
+ len = endPos - ((char*)buf + pos) + pemCertFooterLen + sizeof("\r\n");
+ }
+ else if ((*(endPos + pemCertFooterLen + 0) == '\n') &&
+ (*(endPos + pemCertFooterLen + 1) == '\0'))
+ {
+ len = endPos - ((char*)buf + pos) + pemCertFooterLen + sizeof("\n");
+ }
+ else
+ {
+ OIC_LOG_V(ERROR, NET_TLS_TAG, "Incorrect PEM certificate ending");
+ OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
+ return -1;
+ }
+ ret = mbedtls_x509_crt_parse(crt, buf + pos, len);
+ if(0 != ret)
+ {
+ OIC_LOG_V(ERROR, NET_TLS_TAG, "mbedtls_x509_crt_parse returned -0x%x", -ret);
+ OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
return -1;
}
- len = (char*)endPos - ((char*)(buf + pos)) + pemCertFooterLen;
- ret = mbedtls_x509_crt_parse(crt, buf, len);
pos += len;
}
else
{
- OIC_LOG_V(ERROR, NET_TLS_TAG, "mbedtls_x509_crt_parse returned -0x%x", -ret);
+ OIC_LOG_BUFFER(DEBUG, NET_TLS_TAG, buf, buflen);
+ OIC_LOG_V(ERROR, NET_TLS_TAG, "parseChain returned -0x%x", -ret);
+ OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
return -1;
}
}
+ OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
return 0;
}
//Loads PKIX related information from SRM
--
2.7.4