replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / caconnectivitymanager.c
index edc9d85..c3247d2 100644 (file)
@@ -23,6 +23,8 @@
 #include <stdint.h>
 #include <stdbool.h>
 
+#include "octypes.h"
+#include "ocrandom.h"
 #include "cainterface.h"
 #include "caremotehandler.h"
 #include "camessagehandler.h"
 #include "canetworkconfigurator.h"
 #include "cainterfacecontroller.h"
 #include "logger.h"
-#ifdef __WITH_DTLS__
-#include "caadapternetdtls.h"
-#endif
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+#include "ca_adapter_net_ssl.h"
+#endif // __WITH_DTLS__ or __WITH_TLS__
 
 #ifdef TCP_ADAPTER
 #include "catcpadapter.h"
 #endif
 
-#include "ocrandom.h"
-
+CAGlobals_t caglobals = { .clientFlags = 0,
+                          .serverFlags = 0, };
 
-CAGlobals_t caglobals = { 0 };
-
-#define TAG "CA_CONN_MGR"
+#define TAG "OIC_CA_CONN_MGR"
 
 static bool g_isInitialized = false;
 
-#ifdef __WITH_DTLS__
-// CAAdapterNetDTLS will register the callback.
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
 // Taking callback all the way through adapters not the right approach, hence calling here.
-extern void CADTLSSetCredentialsCallback(CAGetDTLSPskCredentialsHandler credCallback);
-#endif
+extern void CAsetPkixInfoCallback(CAgetPkixInfoHandler infCallback);
+extern void CAsetPskCredentialsCallback(CAgetPskCredentialsHandler credCallback);
+extern void CAsetCredentialTypesCallback(CAgetCredentialTypesHandler credCallback);
+extern void CAsetSetupPkContextCallback(CAsetupPkContextHandler setupPkCtxCallback);
+#endif // __WITH_DTLS__ or __WITH_TLS__
 
-#ifdef __WITH_X509__
-// CAAdapterNetDTLS will register the callback.
-// Taking callback all the way through adapters not the right approach, hence calling here.
-extern void CADTLSSetX509CredentialsCallback(CAGetDTLSX509CredentialsHandler credCallback);
-extern void CADTLSSetCrlCallback(CAGetDTLSCrlHandler crlCallback);
-#endif
 
-CAResult_t CAInitialize()
+CAResult_t CAInitialize(CATransportAdapter_t transportType)
 {
-    OIC_LOG(DEBUG, TAG, "CAInitialize");
+    OIC_LOG_V(DEBUG, TAG, "IoTivity version is v%s", IOTIVITY_VERSION);
+    OIC_LOG_V(DEBUG, TAG, "CAInitialize type : %d", transportType);
 
     if (!g_isInitialized)
     {
@@ -71,10 +68,11 @@ CAResult_t CAInitialize()
             OIC_LOG(ERROR, TAG, "Seed Random Failed");
         }
 
-        CAResult_t res = CAInitializeMessageHandler();
+        CAResult_t res = CAInitializeMessageHandler(transportType);
         if (res != CA_STATUS_OK)
         {
             OIC_LOG(ERROR, TAG, "CAInitialize has failed");
+            CATerminateMessageHandler();
             return res;
         }
         g_isInitialized = true;
@@ -100,7 +98,7 @@ CAResult_t CAStartListeningServer()
 {
     OIC_LOG(DEBUG, TAG, "CAStartListeningServer");
 
-    if(!g_isInitialized)
+    if (!g_isInitialized)
     {
         return CA_STATUS_NOT_INITIALIZED;
     }
@@ -112,7 +110,7 @@ CAResult_t CAStopListeningServer()
 {
     OIC_LOG(DEBUG, TAG, "CAStopListeningServer");
 
-    if(!g_isInitialized)
+    if (!g_isInitialized)
     {
         return CA_STATUS_NOT_INITIALIZED;
     }
@@ -124,7 +122,7 @@ CAResult_t CAStartDiscoveryServer()
 {
     OIC_LOG(DEBUG, TAG, "CAStartDiscoveryServer");
 
-    if(!g_isInitialized)
+    if (!g_isInitialized)
     {
         return CA_STATUS_NOT_INITIALIZED;
     }
@@ -137,7 +135,7 @@ void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHand
 {
     OIC_LOG(DEBUG, TAG, "CARegisterHandler");
 
-    if(!g_isInitialized)
+    if (!g_isInitialized)
     {
         OIC_LOG(DEBUG, TAG, "CA is not initialized");
         return;
@@ -146,48 +144,87 @@ void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHand
     CASetInterfaceCallbacks(ReqHandler, RespHandler, ErrorHandler);
 }
 
-#ifdef __WITH_DTLS__
-CAResult_t CARegisterDTLSCredentialsHandler(CAGetDTLSPskCredentialsHandler GetDTLSCredentialsHandler)
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+#ifdef MULTIPLE_OWNER
+const CASecureEndpoint_t *CAGetSecureEndpointData(const CAEndpoint_t *peer)
 {
-    OIC_LOG(DEBUG, TAG, "CARegisterDTLSCredentialsHandler");
+    OIC_LOG(DEBUG, TAG, "IN CAGetSecurePeerInfo");
 
+    if (!g_isInitialized)
+    {
+        OIC_LOG(DEBUG, TAG, "CA is not initialized");
+        return NULL;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT CAGetSecurePeerInfo");
+    return GetCASecureEndpointData(peer);
+}
+#endif //MULTIPLE_OWNER
+
+CAResult_t CAregisterSslHandshakeCallback(CAErrorCallback tlsHandshakeCallback)
+{
+    OIC_LOG(DEBUG, TAG, "CAregisterSslHandshakeCallback");
     if(!g_isInitialized)
     {
         return CA_STATUS_NOT_INITIALIZED;
     }
 
-    CADTLSSetCredentialsCallback(GetDTLSCredentialsHandler);
+    CAsetSslHandshakeCallback(tlsHandshakeCallback);
     return CA_STATUS_OK;
 }
-#endif //__WITH_DTLS__
 
-#ifdef __WITH_X509__
-CAResult_t CARegisterDTLSX509CredentialsHandler(CAGetDTLSX509CredentialsHandler GetDTLSX509CredentialsHandler)
+CAResult_t CAregisterPskCredentialsHandler(CAgetPskCredentialsHandler getTlsCredentialsHandler)
 {
-    OIC_LOG(DEBUG, TAG, "CARegisterDTLSX509CredentialsHandler");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
 
-    if(!g_isInitialized)
+    if (!g_isInitialized)
     {
         return CA_STATUS_NOT_INITIALIZED;
     }
+    CAsetPskCredentialsCallback(getTlsCredentialsHandler);
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return CA_STATUS_OK;
+}
 
-    CADTLSSetX509CredentialsCallback(GetDTLSX509CredentialsHandler);
+CAResult_t CAregisterPkixInfoHandler(CAgetPkixInfoHandler getPkixInfoHandler)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    if (!g_isInitialized)
+    {
+        return CA_STATUS_NOT_INITIALIZED;
+    }
+    CAsetPkixInfoCallback(getPkixInfoHandler);
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
     return CA_STATUS_OK;
 }
 
-CAResult_t CARegisterDTLSCrlHandler(CAGetDTLSCrlHandler GetDTLSCrlHandler)
+CAResult_t CAregisterGetCredentialTypesHandler(CAgetCredentialTypesHandler getCredTypesHandler)
 {
-    OIC_LOG(DEBUG, TAG, "CARegisterDTLSCrlHandler");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
 
-    if(!g_isInitialized)
+    if (!g_isInitialized)
     {
         return CA_STATUS_NOT_INITIALIZED;
     }
+    CAsetCredentialTypesCallback(getCredTypesHandler);
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAregisterSetupPkContextHandler(CAsetupPkContextHandler setupPkContextCallback)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
 
-    CADTLSSetCrlCallback(GetDTLSCrlHandler);
+    if (!g_isInitialized)
+    {
+        return CA_STATUS_NOT_INITIALIZED;
+    }
+    CAsetSetupPkContextCallback(setupPkContextCallback);
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
     return CA_STATUS_OK;
 }
-#endif //__WITH_X509__
+#endif // __WITH_DTLS__ or __WITH_TLS__
 
 CAResult_t CACreateEndpoint(CATransportFlags_t flags,
                             CATransportAdapter_t adapter,
@@ -237,7 +274,7 @@ CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, uint32_t *size)
 {
     OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
 
-    if(!g_isInitialized)
+    if (!g_isInitialized)
     {
         return CA_STATUS_NOT_INITIALIZED;
     }
@@ -245,35 +282,102 @@ CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, uint32_t *size)
     return CAGetNetworkInformationInternal(info, size);
 }
 
-CAResult_t CASendRequest(const CAEndpoint_t *object,const CARequestInfo_t *requestInfo)
+static CAResult_t CASendMessageMultiAdapter(const CAEndpoint_t *object, const void *sendMsg,
+                                            CADataType_t dataType)
 {
-    OIC_LOG(DEBUG, TAG, "CASendGetRequest");
+    OIC_LOG(DEBUG, TAG, "CASendMessageMultipleAdapter");
 
-    if(!g_isInitialized)
+    CATransportAdapter_t connTypes[] = {
+            CA_ADAPTER_IP
+#ifdef LE_ADAPTER
+            ,CA_ADAPTER_GATT_BTLE
+#endif
+#ifdef EDR_ADAPTER
+            ,CA_ADAPTER_RFCOMM_BTEDR
+#endif
+#ifdef NFC_ADAPTER
+            ,CA_ADAPTER_NFC
+#endif
+#ifdef RA_ADAPTER
+            ,CA_ADAPTER_REMOTE_ACCESS
+#endif
+#ifdef TCP_ADAPTER
+            ,CA_ADAPTER_TCP
+#endif
+        };
+
+    CAEndpoint_t *cloneEp = CACloneEndpoint(object);
+    if (!cloneEp)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to clone CAEndpoint");
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    CAResult_t ret = CA_STATUS_OK;
+    size_t numConnTypes = sizeof(connTypes) / sizeof(connTypes[0]);
+
+    for (size_t i = 0; i < numConnTypes && ret == CA_STATUS_OK; i++)
+    {
+        cloneEp->adapter = connTypes[i];
+        ret = CADetachSendMessage(cloneEp, sendMsg, dataType);
+    }
+    CAFreeEndpoint(cloneEp);
+    return ret;
+}
+
+CAResult_t CASendRequest(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
+{
+    OIC_LOG(DEBUG, TAG, "CASendRequest");
+
+    if (!g_isInitialized)
     {
         return CA_STATUS_NOT_INITIALIZED;
     }
 
-    return CADetachRequestMessage(object, requestInfo);
+    if (requestInfo && requestInfo->isMulticast &&
+            (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
+    {
+        return CASendMessageMultiAdapter(object, requestInfo, CA_REQUEST_DATA);
+    }
+    else if (requestInfo && requestInfo->info.event == CA_REQ_DISCONNECT &&
+            (object->adapter == CA_ADAPTER_TCP || object->adapter == CA_ALL_ADAPTERS))
+    {
+        return CADetachSendNetworkReqMessage(object, requestInfo->info.event, CA_NETWORK_COMMAND);
+    }
+    else
+    {
+        return CADetachSendMessage(object, requestInfo, CA_REQUEST_DATA);
+    }
 }
 
 CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
 {
     OIC_LOG(DEBUG, TAG, "CASendResponse");
 
-    if(!g_isInitialized)
+    if (!g_isInitialized)
     {
         return CA_STATUS_NOT_INITIALIZED;
     }
 
-    return CADetachResponseMessage(object, responseInfo);
+    if (!responseInfo || !object)
+    {
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    if (responseInfo->isMulticast &&
+            (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
+    {
+        return CASendMessageMultiAdapter(object, responseInfo, responseInfo->info.dataType);
+    }
+    else
+    {
+        return CADetachSendMessage(object, responseInfo, responseInfo->info.dataType);
+    }
 }
 
 CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
 {
-    OIC_LOG_V(DEBUG, TAG, "Selected network : %d", interestedNetwork);
-
-    if(!g_isInitialized)
+    if (!g_isInitialized)
     {
         return CA_STATUS_NOT_INITIALIZED;
     }
@@ -313,7 +417,11 @@ CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
                   "CAAddNetworkType(CA_ADAPTER_TCP) function returns result : %d", res);
     }
 #endif
-
+    else if (interestedNetwork & CA_ADAPTER_NFC)
+    {
+        res = CAAddNetworkType(CA_ADAPTER_NFC);
+        OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_ADAPTER_NFC) function returns result : %d", res);
+    }
     else
     {
         res = CA_NOT_SUPPORTED;
@@ -325,7 +433,7 @@ CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork)
 {
     OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
 
-    if(!g_isInitialized)
+    if (!g_isInitialized)
     {
         return CA_STATUS_NOT_INITIALIZED;
     }
@@ -386,92 +494,119 @@ CAResult_t CAHandleRequestResponse()
     return CA_STATUS_OK;
 }
 
-#ifdef __WITH_DTLS__
-
-CAResult_t CASelectCipherSuite(const uint16_t cipher)
+CAResult_t CASelectCipherSuite(const uint16_t cipher, CATransportAdapter_t adapter)
 {
-    OIC_LOG_V(DEBUG, TAG, "CASelectCipherSuite");
-
-    return CADtlsSelectCipherSuite(cipher);
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+    OIC_LOG_V(DEBUG, TAG, "cipher : %d , CATransportAdapter : %d", cipher, adapter);
+    CAResult_t res = CA_STATUS_FAILED;
+#if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
+    res = CAsetTlsCipherSuite(cipher);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to CAsetTlsCipherSuite : %d", res);
+    }
+#else
+    OIC_LOG(ERROR, TAG, "Method not supported");
+#endif
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return res;
 }
 
 CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
 {
     OIC_LOG_V(DEBUG, TAG, "CAEnableAnonECDHCipherSuite");
-
-    return CADtlsEnableAnonECDHCipherSuite(enable);
+    CAResult_t res = CA_STATUS_FAILED;
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+    // TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256    0xFF00 replaces 0xC018
+    res = CAsetTlsCipherSuite(enable ? 0xFF00 : 0x00);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to CAsetTlsCipherSuite : %d", res);
+    }
+#else
+    OIC_LOG(ERROR, TAG, "Method not supported");
+#endif
+    OIC_LOG_V(ERROR, TAG, "Out %s", __func__);
+    return res;
 }
 
 CAResult_t CAGenerateOwnerPSK(const CAEndpoint_t* endpoint,
                     const uint8_t* label, const size_t labelLen,
                     const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
                     const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
-                    uint8_t* ownerPSK, const size_t ownerPSKSize)
+                    uint8_t* ownerPSK, const size_t ownerPskSize)
 {
     OIC_LOG_V(DEBUG, TAG, "IN : CAGenerateOwnerPSK");
-
-    CAResult_t res = CA_STATUS_OK;
-
+    CAResult_t res = CA_STATUS_FAILED;
+#if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
     //newOwnerLabel and prevOwnerLabe can be NULL
-    if (!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPSKSize)
+    if (!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPskSize)
     {
         return CA_STATUS_INVALID_PARAM;
     }
 
-    res = CADtlsGenerateOwnerPSK(endpoint, label, labelLen,
-                                  rsrcServerDeviceID, rsrcServerDeviceIDLen,
-                                  provServerDeviceID, provServerDeviceIDLen,
-                                  ownerPSK, ownerPSKSize);
+    res = CAsslGenerateOwnerPsk(endpoint, label, labelLen,
+                                      rsrcServerDeviceID, rsrcServerDeviceIDLen,
+                                      provServerDeviceID, provServerDeviceIDLen,
+                                      ownerPSK, ownerPskSize);
     if (CA_STATUS_OK != res)
     {
         OIC_LOG_V(ERROR, TAG, "Failed to CAGenerateOwnerPSK : %d", res);
     }
-
+#else
+    OIC_LOG(ERROR, TAG, "Method not supported");
+#endif
     OIC_LOG_V(DEBUG, TAG, "OUT : CAGenerateOwnerPSK");
-
     return res;
 }
 
 CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint)
 {
     OIC_LOG_V(DEBUG, TAG, "IN : CAInitiateHandshake");
-    CAResult_t res = CA_STATUS_OK;
-
+    CAResult_t res = CA_STATUS_FAILED;
+#if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
     if (!endpoint)
     {
         return CA_STATUS_INVALID_PARAM;
     }
 
-    res = CADtlsInitiateHandshake(endpoint);
+    res = CAinitiateSslHandshake(endpoint);
     if (CA_STATUS_OK != res)
     {
-        OIC_LOG_V(ERROR, TAG, "Failed to CADtlsInitiateHandshake : %d", res);
+        OIC_LOG_V(ERROR, TAG, "Failed to CAinitiateSslHandshake : %d", res);
     }
-
+#else
+        OIC_LOG(ERROR, TAG, "Method not supported");
+#endif
     OIC_LOG_V(DEBUG, TAG, "OUT : CAInitiateHandshake");
-
     return res;
 }
 
-CAResult_t CACloseDtlsSession(const CAEndpoint_t *endpoint)
+CAResult_t CAcloseSslSession(const CAEndpoint_t *endpoint)
 {
-    OIC_LOG_V(DEBUG, TAG, "IN : CACloseDtlsSession");
-    CAResult_t res = CA_STATUS_OK;
-
+    OIC_LOG_V(DEBUG, TAG, "IN : CAcloseSslSession");
+    CAResult_t res = CA_STATUS_FAILED;
+#if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
     if (!endpoint)
     {
         return CA_STATUS_INVALID_PARAM;
     }
 
-    res = CADtlsClose(endpoint);
+    res = CAcloseSslConnection(endpoint);
     if (CA_STATUS_OK != res)
     {
-        OIC_LOG_V(ERROR, TAG, "Failed to CADtlsClose : %d", res);
+        OIC_LOG_V(ERROR, TAG, "Failed to CAsslClose : %d", res);
     }
-
-    OIC_LOG_V(DEBUG, TAG, "OUT : CACloseDtlsSession");
-
+#else
+    OIC_LOG(ERROR, TAG, "Method not supported");
+#endif
+    OIC_LOG_V(DEBUG, TAG, "OUT : CAcloseSslSession");
     return res;
 }
 
-#endif /* __WITH_DTLS__ */
+#ifdef TCP_ADAPTER
+void CARegisterKeepAliveHandler(CAKeepAliveConnectionCallback ConnHandler)
+{
+    CATCPSetKeepAliveCallbacks(ConnHandler);
+}
+#endif