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