[IOT-3298] Prefered cipher for cloud connection 66/29866/11
authorIurii Metelytsia <i.metelytsia@samsung.com>
Thu, 17 Oct 2019 15:16:17 +0000 (18:16 +0300)
committerAleksey Volkov <a.volkov@samsung.com>
Wed, 30 Oct 2019 09:10:20 +0000 (09:10 +0000)
Signed-off-by: Iurii Metelytsia <i.metelytsia@samsung.com>
Change-Id: I19fa4cd25dfa00bc92a1eceda3d3a26316f0719e

resource/csdk/connectivity/api/casecurityinterface.h
resource/csdk/connectivity/inc/ca_adapter_net_ssl.h
resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c
resource/csdk/connectivity/src/caconnectivitymanager.c
resource/csdk/connectivity/test/ssladapter_test.cpp
resource/csdk/security/provisioning/src/cloud/auth.c

index 5c4be77..c8c862c 100644 (file)
@@ -260,6 +260,16 @@ CAResult_t CAregisterPkixInfoHandler(CAgetPkixInfoHandler getPkixInfoHandler);
  */
 CAResult_t CASelectCipherSuite(const uint16_t cipher, CATransportAdapter_t adapter);
 
+#if defined(WITH_CLOUD)
+/**
+ * Enable cipher suites for use with (D)TLS cloud connection.
+ *
+ * @retval  ::CA_STATUS_OK    Successful.
+ * @retval  ::CA_STATUS_FAILED Operation failed.
+ */
+CAResult_t CAEnableCloudConnection(void);
+#endif
+
 /**
  * Enable TLS_ECDH_anon_WITH_AES_128_CBC_SHA cipher suite in dtls.
  *
index d0b1e99..174b12e 100644 (file)
@@ -237,6 +237,15 @@ bool SetCASecureEndpointAttribute(const CAEndpoint_t* peer, uint32_t newAttribut
  */
 bool GetCASecureEndpointAttributes(const CAEndpoint_t* peer, uint32_t* allAttributes);
 
+#if defined(WITH_CLOUD)
+/**
+ * Enable cipher suites for use with (D)TLS cloud connection.
+ *
+ * @return  true on success, false otherwise.
+ */
+bool CAEnableCloudCipherSuites(void);
+#endif
+
 #ifdef __cplusplus
 }
 #endif //__cplusplus
index 5d3d680..12a189c 100644 (file)
@@ -390,6 +390,9 @@ typedef struct SslContext
     int timerId;
 #endif
 
+#if defined(WITH_CLOUD)
+    bool cloudConn;
+#endif
 } SslContext_t;
 
 /**
@@ -1057,6 +1060,35 @@ bool GetCASecureEndpointAttributes(const CAEndpoint_t* peer, uint32_t* allAttrib
     return result;
 }
 
+#if defined(WITH_CLOUD)
+/**
+ * Enable cipher suites for use with (D)TLS cloud connection.
+ *
+ * @return  true on success, false otherwise.
+ */
+bool CAEnableCloudCipherSuites(void)
+{
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+
+    oc_mutex_lock(g_sslContextMutex);
+
+    if (NULL == g_caSslContext)
+    {
+        OIC_LOG(ERROR, NET_SSL_TAG, "Context is NULL");
+        oc_mutex_unlock(g_sslContextMutex);
+        return false;
+    }
+
+    // flag will be cleared after the connection is established
+    g_caSslContext->cloudConn = true;
+
+    oc_mutex_unlock(g_sslContextMutex);
+
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+    return true;
+}
+#endif
+
 /**
  * Deletes cached message.
  *
@@ -1631,6 +1663,49 @@ static bool SetupCipher(mbedtls_ssl_config * config, CATransportAdapter_t adapte
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
     return true;
 }
+
+#if defined(WITH_CLOUD)
+/**
+ * Select cipher suites for use with (D)TLS cloud connection.
+ *
+ * @param[in]  config     the (D)TLS configuration object
+ * @param[in]  adapter    the associated transport adapter
+ * @param[in]  deviceId   the device ID of the peer we will connect to
+ *
+ * @return  true on success or false on error
+ */
+static bool SetupCloudCipher(mbedtls_ssl_config * config, CATransportAdapter_t adapter,
+                             const char* deviceId)
+{
+    static const int csList[] =
+    {
+        MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, //prefered ciphersuite
+        MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+        MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+        MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+        0
+    };
+    OC_UNUSED(deviceId);
+
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+
+    VERIFY_NON_NULL_RET(config, NET_SSL_TAG, "Invailid param", false);
+    VERIFY_NON_NULL_RET(g_caSslContext, NET_SSL_TAG, "SSL Context is NULL", false);
+
+    // Retrieve the Cert credential from SRM
+    if (0 != InitPKIX(adapter))
+    {
+        OIC_LOG(ERROR, NET_SSL_TAG, "Failed to init X.509");
+        /* Don't return error, the connection may work with another cred type */
+    }
+
+    mbedtls_ssl_conf_ciphersuites(config, csList);
+
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+    return true;
+}
+#endif
+
 /**
  * Initiate TLS handshake with endpoint.
  *
@@ -1658,7 +1733,22 @@ static SslEndPoint_t * InitiateTlsHandshake(const CAEndpoint_t *endpoint)
     }
 
     //Load allowed SVR suites from SVR DB
-    if(!SetupCipher(config, endpoint->adapter, endpoint->remoteId))
+    bool setupCipherRes = false;
+#if defined(WITH_CLOUD)
+    // Check cloudConnection flag and set appropriate ciphersuite
+    if (!g_caSslContext->cloudConn)
+    {
+        setupCipherRes = SetupCipher(config, endpoint->adapter, endpoint->remoteId);
+    }
+    else
+    {
+        g_caSslContext->cloudConn = false;
+        setupCipherRes = SetupCloudCipher(config, endpoint->adapter, endpoint->remoteId);
+    }
+#else
+    setupCipherRes = SetupCipher(config, endpoint->adapter, endpoint->remoteId);
+#endif
+    if (!setupCipherRes)
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Failed to set up cipher");
         DeleteSslEndPoint(tep);
@@ -2116,6 +2206,14 @@ CAResult_t CAencryptSsl(const CAEndpoint_t *endpoint,
         return CA_STATUS_FAILED;
     }
 
+#if defined(WITH_CLOUD)
+    if (g_caSslContext->cloudConn && MBEDTLS_SSL_IS_CLIENT == tep->ssl.conf->endpoint)
+    {
+        // cloud connection exist just clear the flag
+        g_caSslContext->cloudConn = false;
+    }
+#endif
+
     if (MBEDTLS_SSL_HANDSHAKE_OVER == tep->ssl.state)
     {
         unsigned char *dataBuf = (unsigned char *)data;
index 3037894..dfaa6e9 100644 (file)
@@ -549,6 +549,21 @@ CAResult_t CASelectCipherSuite(const uint16_t cipher, CATransportAdapter_t adapt
     return res;
 }
 
+#if defined(WITH_CLOUD)
+CAResult_t CAEnableCloudConnection(void)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+    CAResult_t res = CA_NOT_SUPPORTED;
+#if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
+    res = CAEnableCloudCipherSuites() ? CA_STATUS_OK : CA_STATUS_FAILED;
+#else
+    OIC_LOG(ERROR, TAG, "Method not supported");
+#endif
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return res;
+}
+#endif
+
 CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
 {
     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
index 6410ac0..91a071c 100644 (file)
@@ -52,7 +52,9 @@
 #define CAsetCloseSslConnectionCallback CAsetCloseSslConnectionCallbackTest
 #define CAcleanupSslAdapter CAcleanupSslAdapterTest
 #define CAsetTlsAuthMode CAsetTlsAuthModeTest
-
+#if defined(WITH_CLOUD)
+#define CAEnableCloudCipherSuites CAEnableCloudCipherSuitesTest
+#endif
 
 #include "../src/adapter_util/ca_adapter_net_ssl.c"
 
index ee0006b..9b89a01 100644 (file)
@@ -708,7 +708,7 @@ OCStackResult OCCloudTokenRefresh(OicCloud_t *cloud)
     OIC_LOG_V(DEBUG, TAG, "%s: IN", __func__);
 
     char uri[MAX_URI_LENGTH] = { 0 };
-    OCStackResult ret = OC_STACK_OK;
+    OCStackResult ret = OC_STACK_ERROR;
 
     VERIFY_NOT_NULL_RETURN(TAG, cloud, ERROR, OC_STACK_INVALID_PARAM);
     if (OC_CLOUD_TOKEN_REFRESH4 < cloud->stat)
@@ -748,8 +748,11 @@ OCStackResult OCCloudTokenRefresh(OicCloud_t *cloud)
     }
     else
     {
-        ret = OCDoResource(NULL, OC_REST_POST, uri, NULL, (OCPayload *)payload,
-                           CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+        if (CA_STATUS_OK == CAEnableCloudConnection())
+        {
+            ret = OCDoResource(NULL, OC_REST_POST, uri, NULL, (OCPayload *)payload,
+                               CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+        }
     }
 
     OIC_LOG_V(DEBUG, TAG, "%s: OUT: %d", __func__, (int)ret);
@@ -1038,7 +1041,7 @@ static OCStackResult CloudSign(OicCloud_t *cloud, bool signIn)
     VERIFY_NOT_NULL_RETURN(TAG, cloud->session->uid, ERROR, OC_STACK_INVALID_PARAM);
     VERIFY_NOT_NULL_RETURN(TAG, cloud->session->accessToken, ERROR, OC_STACK_INVALID_PARAM);
 
-    OCStackResult ret = OC_STACK_OK;
+    OCStackResult ret = OC_STACK_ERROR;
     char uri[MAX_URI_QUERY] = { 0 };
 
     char *deviceId = getDeviceId();
@@ -1072,8 +1075,11 @@ static OCStackResult CloudSign(OicCloud_t *cloud, bool signIn)
 
     cloud->stat = signIn ? OC_CLOUD_SIGNIN : OC_CLOUD_SIGNOUT;
 
-    ret = OCDoResource(NULL, OC_REST_POST, uri, NULL, (OCPayload *)payload,
-                       CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+    if (CA_STATUS_OK == CAEnableCloudConnection())
+    {
+        ret = OCDoResource(NULL, OC_REST_POST, uri, NULL, (OCPayload *)payload,
+                           CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+    }
 
     OIC_LOG_V(DEBUG, TAG, "%s: OUT", __func__);
     return ret;
@@ -1337,7 +1343,7 @@ static OCStackResult OCCloudAccountResource(OicCloud_t *cloud, OCMethod method)
     OIC_LOG_V(DEBUG, TAG, "%s: IN", __func__);
 
     char uri[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = { 0 };
-    OCStackResult ret = OC_STACK_OK;
+    OCStackResult ret = OC_STACK_ERROR;
 
     VERIFY_NOT_NULL_RETURN(TAG, cloud, ERROR, OC_STACK_INVALID_PARAM);
     VERIFY_NOT_NULL_RETURN(TAG, cloud->cis, ERROR, OC_STACK_INVALID_PARAM);
@@ -1397,8 +1403,11 @@ static OCStackResult OCCloudAccountResource(OicCloud_t *cloud, OCMethod method)
         cbData.cb = handleCloudDeleteResponse;
     }
 
-    ret = OCDoResource(NULL, method, uri, NULL, (OCPayload *)payload,
-                       CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+    if (CA_STATUS_OK == CAEnableCloudConnection())
+    {
+        ret = OCDoResource(NULL, method, uri, NULL, (OCPayload *)payload,
+                           CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+    }
 
     OIC_LOG_V(INFO, TAG, "%s: cloud(%s) sign in", __func__, cloud->cis);