[IOT-3255] OCF profile CA cert check 71/27871/1
authorOleksii Beketov <ol.beketov@samsung.com>
Mon, 21 Jan 2019 13:29:22 +0000 (15:29 +0200)
committerOleksii Beketov <ol.beketov@samsung.com>
Mon, 21 Jan 2019 13:29:22 +0000 (15:29 +0200)
CA root cert check added to OCF profile chain validation

Change-Id: I4b33d8487f2064cb019dbd25df922b835098a4fc
Signed-off-by: Oleksii Beketov <ol.beketov@samsung.com>
Bug: https://jira.iotivity.org/browse/IOT-3255

resource/csdk/connectivity/inc/cacertprofile.h
resource/csdk/connectivity/src/adapter_util/cacertprofile.c

index 0dd8a07..0e57be5 100644 (file)
@@ -58,6 +58,8 @@ typedef enum
     CP_INVALID_CERT_INPUT,   /* Certificate input is invalid (or null) */
     CP_DATE_ERROR,           /* Problem setting or reading certificate validity dates */
     CP_BUF_TOO_SMALL,        /* Supplied buffer is not long enough for desired operation */
+    CP_MUL_CA_CERTS,         /* Multiple root CA certs in cert chain */
+    CP_NO_CA_CERT,           /* No root CA cert in cert chain */
     CP_STATUS_FAILED = 255   /* Failure */
 } CertProfileResult;
 
index f644c15..bff4612 100644 (file)
@@ -99,6 +99,42 @@ static CertProfileResult FindEndEntityCert(const mbedtls_x509_crt *certChain, mb
     return CP_STATUS_OK;
 }
 
+static CertProfileResult FindRootCACert(const mbedtls_x509_crt *certChain, mbedtls_x509_crt const **caCert)
+{
+    *caCert = NULL;
+
+    const mbedtls_x509_crt* curCert = certChain;
+    while (NULL != curCert)
+    {
+        if ((1 == curCert->ca_istrue) &&
+            (curCert->issuer_raw.len == curCert->subject_raw.len) &&
+            (0 == memcmp(curCert->issuer_raw.p, curCert->subject_raw.p, curCert->issuer_raw.len)))
+        {
+            // first CA
+            if (NULL == *caCert)
+            {
+                *caCert = curCert;
+            }
+            // more than 1 CA
+            else
+            {
+                *caCert = NULL;
+                OIC_LOG(ERROR, TAG, "More than 1 root CA cert in chain");
+                return CP_MUL_CA_CERTS;
+            }
+        }
+        curCert = curCert->next;
+    }
+
+    if (NULL == *caCert)
+    {
+        OIC_LOG(INFO, TAG, "No root CA cert in chain");
+        return CP_NO_CA_CERT;
+    }
+
+    return CP_STATUS_OK;
+}
+
 static CertProfileResult CheckMdAlgorithm(const mbedtls_x509_crt_profile *profile, mbedtls_md_type_t mdAlgorithm)
 {
     if ((MBEDTLS_X509_ID_FLAG(mdAlgorithm) & profile->allowed_mds) != 0)
@@ -412,6 +448,9 @@ int ValidateAuthCertChainProfiles(const mbedtls_x509_crt *certChain)
         return CP_INVALID_CERT_CHAIN;
     }
 
+    const mbedtls_x509_crt* caCert = NULL;
+    cpResult = FindRootCACert(certChain, &caCert);
+
     const mbedtls_x509_crt* curCert = certChain;
     while (NULL != curCert)
     {
@@ -419,6 +458,10 @@ int ValidateAuthCertChainProfiles(const mbedtls_x509_crt *certChain)
         {
             profileViolations = ValidateEndEntityCertProfile(curCert);
         }
+        else if (curCert == caCert)
+        {
+            profileViolations = ValidateRootCACertProfile(curCert);
+        }
         else
         {
             profileViolations = ValidateIntermediateCACertProfile(curCert);