Algorithm for obtaining uuid from TLS data changed 26/204726/1
authori.metelytsia <i.metelytsia@samsung.com>
Mon, 22 Apr 2019 12:52:26 +0000 (15:52 +0300)
committerDoHyun Pyun <dh79.pyun@samsung.com>
Fri, 26 Apr 2019 04:14:02 +0000 (13:14 +0900)
https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/487
(cherry picked from d42e96b2cea21f6c5ffa623d3a89f88789fdc260

Change-Id: I533bda62a54e3bad053764aaa99ac564b32e947e
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c

index af3a839..47e2199 100644 (file)
  */
 #define UUID_LENGTH (128/8)
 /**
+ * @def UUID_STR_SIZE
+ * @brief Size of string representation RFC4122 based UUID.
+ * 32 chars for hex data and 4 '-' symbols.
+ */
+#define UUID_STR_SIZE (36)
+
+/**
  * @def MASTER_SECRET_LEN
  * @brief TLS master secret length
  */
@@ -2357,6 +2364,83 @@ void CAsetSslHandshakeCallback(CAErrorCallback tlsHandshakeCallback)
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
 }
 
+/**
+ * Check RFC4122 based UUID
+ *
+ * @param uuidString    string representation of UUID
+ * @return true for success, otherwise false
+ */
+static bool CheckUuidFormat(const char uuidString[UUID_STR_SIZE])
+{
+    // Indexes of '-' symbols in string representation of UUID
+    static const int dash_idxs[4] = {8,13,18,23};
+
+    VERIFY_NON_NULL_RET(uuidString, NET_SSL_TAG, "uuidString is NULL" , false);
+
+    // Check for '-' symbols
+    for (int i = 0; i < 4; i++)
+    {
+        if (uuidString[dash_idxs[i]] != '-')
+        {
+            return false;
+        }
+    }
+
+    for (int i = 0; i < UUID_STR_SIZE; i++)
+    {
+        // Skip '-' symbols
+        if (i == dash_idxs[0] || i == dash_idxs[1] || i == dash_idxs[2] || i == dash_idxs[3])
+        {
+            continue;
+        }
+
+        if ((uuidString[i] >= 'a' && uuidString[i] <= 'f')
+                || (uuidString[i] >= 'A' && uuidString[i] <= 'F')
+                || (uuidString[i] >= '0' && uuidString[i] <= '9') )
+        {
+            continue;
+        }
+
+        return false;
+    }
+
+    return true;
+}
+
+/**
+ * FindUuid function finds the first entry of RFC4122 based UUID
+ *
+ * @param data  pointer to unformatted data
+ * @param size  data size
+ *
+ * @return pointer to string representation of the found UUID if success, otherwise NULL
+ */
+static const char* FindUuid(const char* data, size_t size)
+{
+    const char* result = NULL;
+
+    VERIFY_NON_NULL_RET(data, NET_SSL_TAG, "data is NULL" , NULL);
+    if (size < UUID_STR_SIZE)
+    {
+        OIC_LOG(ERROR, NET_SSL_TAG, "Buffer size is too small");
+        return NULL;
+    }
+
+    const char* currentPtr = data;
+    int currentSize = size;
+    while (!result
+           && (currentPtr = (const char*)memchr((const void*)++currentPtr, '-', currentSize - 1))
+           && ((currentSize = (size - (currentPtr - data))) >= (UUID_STR_SIZE - 8)))
+    {
+        if (currentPtr - data >= 8 && CheckUuidFormat(currentPtr - 8))
+        {
+            result = currentPtr - 8;
+        }
+    }
+
+    return result;
+}
+
 /* Read data from TLS connection
  */
 CAResult_t CAdecryptSsl(const CASecureEndpoint_t *sep, uint8_t *data, uint32_t dataLen)
@@ -2454,9 +2538,6 @@ CAResult_t CAdecryptSsl(const CASecureEndpoint_t *sep, uint8_t *data, uint32_t d
             if (MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 != selectedCipher &&
                 MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256 != selectedCipher)
             {
-                char uuid[UUID_LENGTH * 2 + 5] = {0};
-                void * uuidPos = NULL;
-                void * userIdPos = NULL;
                 const mbedtls_x509_crt * peerCert = mbedtls_ssl_get_peer_cert(&peer->ssl);
                 ret = (NULL == peerCert ? -1 : 0);
                 if (g_CertificateVerificationCallback)
@@ -2479,27 +2560,12 @@ CAResult_t CAdecryptSsl(const CASecureEndpoint_t *sep, uint8_t *data, uint32_t d
                 //                            CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_NO_CERT);
                 if (0 == ret)
                 {
-                    uuidPos = memmem(peerCert->subject_raw.p, peerCert->subject_raw.len,
-                                                     UUID_PREFIX, sizeof(UUID_PREFIX) - 1);
-
-                    if (NULL == uuidPos)
-                    {
-                        void * posLeftBrace = NULL;
-                        void * posRightBrace = NULL;
-                        posLeftBrace = memmem(peerCert->subject_raw.p, peerCert->subject_raw.len, "(", 1);
-                        if (NULL != posLeftBrace)
-                        {
-                            posRightBrace = memmem(peerCert->subject_raw.p, peerCert->subject_raw.len, ")", 1);
-                            if (NULL != posRightBrace && posRightBrace - posLeftBrace - 1 == UUID_LENGTH * 2 + 4)
-                            {
-                                uuidPos = posLeftBrace;
-                            }
-                        }
-                    }
-
-                    if (NULL != uuidPos)
+                    const char* uuidptr = FindUuid((const char*)peerCert->subject_raw.p, peerCert->subject_raw.len);
+                    if (uuidptr)
                     {
-                        memcpy(uuid, (char*) uuidPos + sizeof(UUID_PREFIX) - 1, UUID_LENGTH * 2 + 4);
+                        char uuid[UUID_STR_SIZE + 1] = {0};
+                        strncpy(uuid, uuidptr, UUID_STR_SIZE);
+                        uuid[UUID_STR_SIZE] = '\0';
                         OIC_LOG_V(DEBUG, NET_SSL_TAG, "certificate uuid string: %s" , uuid);
                         ret = OCConvertStringToUuid(uuid, peer->sep.identity.id);
                         SSL_CHECK_FAIL(peer, ret, "Failed to convert subject", 1,
@@ -2509,20 +2575,6 @@ CAResult_t CAdecryptSsl(const CASecureEndpoint_t *sep, uint8_t *data, uint32_t d
                     {
                         OIC_LOG(WARNING, NET_SSL_TAG, "uuid not found");
                     }
-
-                    userIdPos = memmem(peerCert->subject_raw.p, peerCert->subject_raw.len,
-                                                 USERID_PREFIX, sizeof(USERID_PREFIX) - 1);
-                    if (NULL != userIdPos)
-                    {
-                        memcpy(uuid, (char*) userIdPos + sizeof(USERID_PREFIX) - 1, UUID_LENGTH * 2 + 4);
-                        ret = OCConvertStringToUuid(uuid, peer->sep.userId.id);
-                        SSL_CHECK_FAIL(peer, ret, "Failed to convert subject alt name", 1,
-                                          CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT);
-                    }
-                    else
-                    {
-                        OIC_LOG(WARNING, NET_SSL_TAG, "Subject alternative name not found");
-                    }
                 }
             }