CT1.7.4.5: Avoid DER key parse error 05/23005/3
authorDan Mihai <Daniel.Mihai@microsoft.com>
Thu, 26 Oct 2017 03:09:48 +0000 (20:09 -0700)
committerNathan Heldt-Sheller <nathan.heldt-sheller@intel.com>
Thu, 26 Oct 2017 19:52:47 +0000 (19:52 +0000)
mbedtls_pk_parse_key was not able to parse the key converted to DER
by GetDerKey(). It encountered in the DER an unexpected key format
version.

However, mbedtls_pk_parse_key is able to parse correctly the original
PEM format of the same key.

This patch allows CT1.7.4.5 to establish a connection to an IoTivity
server. This test case still fails later on - to be investigated.

Change-Id: I933ea9d3b761ed159faa2c4f371890e477caf23f
Signed-off-by: Dan Mihai <Daniel.Mihai@microsoft.com>
resource/csdk/security/include/internal/credresource.h
resource/csdk/security/src/credresource.c
resource/csdk/security/src/pkix_interface.c

index b2bb3e9..01969d9 100644 (file)
@@ -241,12 +241,18 @@ OCStackResult GetAllRoleCerts(RoleCertChain_t** roleCerts);
  */
 void GetPemOwnCert(ByteArray_t * crt, const char * usage);
 /**
- * Used by mbedTLS to retrieve owm private key
+ * Used by mbedTLS to retrieve own private key
  *
  * @param[out] key key to be filled.
  * @param[in] usage credential usage string.
  */
 void GetDerKey(ByteArray_t * key, const char * usage);
+/**
+ * Used by mbedTLS to retrieve own primary cert private key
+ *
+ * @param[out] key key to be filled.
+ */
+void GetPrimaryCertKey(ByteArray_t * key);
 /**
  * Used by CA to retrieve credential types
  *
index 0090ad7..8c6d929 100644 (file)
@@ -3673,6 +3673,91 @@ void GetDerKey(ByteArray_t * key, const char * usage)
     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 }
 
+void GetPrimaryCertKey(ByteArray_t * key)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    VERIFY_NOT_NULL(TAG, key, ERROR);
+    
+    key->len = 0;
+    OicSecCred_t * temp = NULL;
+
+    LL_FOREACH(gCred, temp)
+    {
+        size_t length = temp->privateData.len;
+
+        if ((SIGNED_ASYMMETRIC_KEY == temp->credType || ASYMMETRIC_KEY == temp->credType) &&
+            (0 < length) &&
+            (NULL != temp->credUsage) &&
+            (0 == strcmp(temp->credUsage, PRIMARY_CERT)))
+        {
+            switch (temp->privateData.encoding)
+            {
+                case OIC_ENCODING_PEM:
+                case OIC_ENCODING_DER:
+                case OIC_ENCODING_RAW:
+                {
+                    bool addNull = false;
+                    uint8_t *data = temp->privateData.data;
+
+                    if ((OIC_ENCODING_PEM == temp->privateData.encoding) &&
+                        (0 != data[length - 1]))
+                    {
+                        /* mbedtls_pk_parse_key needs null terminator to determine the PEM key format */
+                        OIC_LOG_V(DEBUG, TAG, "%s: adding null terminator to key", __func__);
+                        addNull = true;
+                        data = OICCalloc(length + 1, sizeof(*data));
+                    }
+                    else
+                    {
+                        data = OICCalloc(length, sizeof(*data));
+                    }
+
+                    if (NULL == data)
+                    {
+                        key->data = NULL;
+                        OIC_LOG(ERROR, TAG, "Failed to allocate memory");
+                        return;
+                    }
+
+                    memcpy(data, temp->privateData.data, length);
+
+                    if (addNull)
+                    {
+                        data[length] = 0;
+                        length++;
+                    }
+
+                    key->data = data;
+                    key->len = length;
+
+                    OIC_LOG(DEBUG, TAG, "Key for PRIMARY_CERT found");
+                    break;
+                }
+
+                default:
+                {
+                    OIC_LOG_V(WARNING, TAG, "Key for PRIMARY_CERT found, but it has an unknown encoding (%d)", temp->privateData.encoding);
+                    break;
+                }
+            }
+
+            if (0 != key->len)
+            {
+                break;
+            }
+        }
+    }
+
+    if(0 == key->len)
+    {
+        OIC_LOG(WARNING, TAG, "Key for PRIMARY_CERT not found");
+    }
+
+exit:
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+}
+
 void InitCipherSuiteListInternal(bool * list, const char * usage, const char *deviceId)
 {
     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
index 672480a..1fad524 100644 (file)
@@ -42,7 +42,7 @@ void GetPkixInfo(PkiInfo_t * inf)
         OIC_LOG_V(WARNING, TAG, "%s: empty certificate", __func__);
     }
 
-    GetDerKey(&inf->key, PRIMARY_CERT);
+    GetPrimaryCertKey(&inf->key);
     if (inf->key.len == 0)
     {
         OIC_LOG_V(WARNING, TAG, "%s: empty key", __func__);