From e80f054d012f6092b05ca0d2322e2c3125f2ed75 Mon Sep 17 00:00:00 2001
From: Oleksii Beketov
Date: Thu, 25 Aug 2016 17:38:07 +0300
Subject: [PATCH] parseChain() PEM update
parseChain() from ca_adapter_net_tls.c modified in order to parse
PEM certificates. Input buffer may contain either PEM or DER
certificates in a jumble. Each PEM format certificate in a chain
must be terminated with null byte.
Change-Id: Id0e7ff5dddf4af4213dfb0ffe8a8ca05f96581a7
Signed-off-by: Oleksii Beketov
Reviewed-on: https://gerrit.iotivity.org/gerrit/10741
Reviewed-by: Jon A. Cruz
Tested-by: jenkins-iotivity
Reviewed-by: Joonghwan Lee
Reviewed-by: dongik Lee
Reviewed-by: Dmitriy Zhuravlev
---
.../src/adapter_util/ca_adapter_net_tls.c | 37 ++++++++++++++++++++--
1 file changed, 35 insertions(+), 2 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 faade61..36f0234 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
@@ -339,12 +339,32 @@ static int recvTls(void * tep, unsigned char * data, size_t dataLen)
return (int)retLen;
}
-//TODO add description
+/**
+ * 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. Each PEM certificate must be NULL-terminated.
+ * @param[in] buflen buffer length
+ *
+ * @return 0 on success, -1 on error
+ */
static int parseChain(mbedtls_x509_crt * crt, const unsigned char * buf, int buflen)
{
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);
+ 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
+ };
+ size_t pemCertHeaderLen = sizeof(pemCertHeader);
+ size_t pemCertFooterLen = sizeof(pemCertFooter);
+
int pos = 0;
int len = 0;
int ret = 0;
@@ -355,7 +375,7 @@ static int parseChain(mbedtls_x509_crt * crt, const unsigned char * buf, int buf
len = (((int) buf[pos+2]) << 8) | buf[pos+3];
if (pos + len < buflen)
{
- ret = mbedtls_x509_crt_parse_der(crt, buf+pos, len+4);
+ ret = mbedtls_x509_crt_parse_der(crt, buf+pos, len + 4);
if( 0 != ret)
{
OIC_LOG_V(ERROR, NET_TLS_TAG, "mbedtls_x509_crt_parse returned -0x%x", -ret);
@@ -364,6 +384,19 @@ static int parseChain(mbedtls_x509_crt * crt, const unsigned char * buf, int buf
}
pos += len + 4;
}
+ else if (0 == memcmp(buf + pos, pemCertHeader, pemCertHeaderLen))
+ {
+ void * endPos = NULL;
+ endPos = memmem(&(buf[pos]), buflen - pos, pemCertFooter, pemCertFooterLen);
+ if (NULL == endPos)
+ {
+ OIC_LOG(ERROR, NET_TLS_TAG, "Error: end of PEM certificate not found.");
+ 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);
--
2.7.4