1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
20 #include "caadapternetdtls.h"
22 #include "caipinterface.h"
24 #include "oic_malloc.h"
25 #include "oic_string.h"
31 * @brief Logging tag for module name
33 #define NET_DTLS_TAG "NET_DTLS"
36 * @var g_caDtlsContext
37 * @brief global context which holds dtls context and cache list information.
39 static stCADtlsContext_t *g_caDtlsContext = NULL;
42 * @var g_dtlsContextMutex
43 * @brief Mutex to synchronize access to g_caDtlsContext.
45 static ca_mutex g_dtlsContextMutex = NULL;
48 * @var g_getCredentialsCallback
49 * @brief callback to get DTLS credentials
51 static CAGetDTLSCredentialsHandler g_getCredentialsCallback = NULL;
53 static CASecureEndpoint_t *GetPeerInfo(const CAEndpoint_t *peer)
55 uint32_t list_index = 0;
56 uint32_t list_length = 0;
60 OIC_LOG(ERROR, NET_DTLS_TAG, "CAPeerInfoListContains invalid parameters");
64 CASecureEndpoint_t *peerInfo = NULL;
65 list_length = u_arraylist_length(g_caDtlsContext->peerInfoList);
66 for (list_index = 0; list_index < list_length; list_index++)
68 peerInfo = (CASecureEndpoint_t *)u_arraylist_get(g_caDtlsContext->peerInfoList, list_index);
74 if((0 == strncmp(peer->addr, peerInfo->endpoint.addr, MAX_ADDR_STR_SIZE_CA)) &&
75 (peer->port == peerInfo->endpoint.port))
83 static CAResult_t CAAddIdToPeerInfoList(const char *peerAddr, uint32_t port,
84 const unsigned char *id, uint16_t id_length)
90 || CA_MAX_ENDPOINT_IDENTITY_LEN < id_length)
92 OIC_LOG(ERROR, NET_DTLS_TAG, "CAAddIdToPeerInfoList invalid parameters");
93 return CA_STATUS_INVALID_PARAM;
96 CASecureEndpoint_t *peer = (CASecureEndpoint_t *)OICCalloc(1, sizeof (CASecureEndpoint_t));
99 OIC_LOG(ERROR, NET_DTLS_TAG, "peerInfo malloc failed!");
100 return CA_MEMORY_ALLOC_FAILED;
103 OICStrcpy(peer->endpoint.addr, sizeof(peer->endpoint.addr), peerAddr);
104 peer->endpoint.port = port;
106 memcpy(peer->identity.id, id, id_length);
107 peer->identity.id_length = id_length;
109 if (NULL != GetPeerInfo(&peer->endpoint))
111 OIC_LOG(ERROR, NET_DTLS_TAG, "CAAddIdToPeerInfoList peer already exist");
113 return CA_STATUS_FAILED;
116 bool result = u_arraylist_add(g_caDtlsContext->peerInfoList, (void *)peer);
119 OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_add failed!");
121 return CA_STATUS_FAILED;
127 static void CAFreePeerInfoList()
129 uint32_t list_length = u_arraylist_length(g_caDtlsContext->peerInfoList);
130 for (uint32_t list_index = 0; list_index < list_length; list_index++)
132 CAEndpoint_t *peerInfo = (CAEndpoint_t *)u_arraylist_get(
133 g_caDtlsContext->peerInfoList, list_index);
136 u_arraylist_free(&(g_caDtlsContext->peerInfoList));
137 g_caDtlsContext->peerInfoList = NULL;
140 static void CARemovePeerFromPeerInfoList(const char * addr, uint16_t port)
142 if (NULL == addr || 0 >= port)
144 OIC_LOG(ERROR, NET_DTLS_TAG, "CADTLSGetPeerPSKId invalid parameters");
148 uint32_t list_length = u_arraylist_length(g_caDtlsContext->peerInfoList);
149 for (uint32_t list_index = 0; list_index < list_length; list_index++)
151 CAEndpoint_t *peerInfo = (CAEndpoint_t *)u_arraylist_get(
152 g_caDtlsContext->peerInfoList,list_index);
153 if (NULL == peerInfo)
157 if((0 == strncmp(addr, peerInfo->addr, MAX_ADDR_STR_SIZE_CA)) &&
158 (port == peerInfo->port))
160 OICFree(u_arraylist_remove(g_caDtlsContext->peerInfoList, list_index));
166 static int CASizeOfAddrInfo(stCADtlsAddrInfo_t *addrInfo)
168 VERIFY_NON_NULL_RET(addrInfo, NET_DTLS_TAG, "addrInfo is NULL" , DTLS_FAIL);
170 switch (addrInfo->addr.st.ss_family)
174 return sizeof (struct sockaddr_in);
178 return sizeof (struct sockaddr_in6);
185 return sizeof (struct sockaddr_storage);
188 static eDtlsRet_t CAAdapterNetDtlsEncryptInternal(const stCADtlsAddrInfo_t *dstSession,
189 uint8_t *data, uint32_t dataLen)
191 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
193 VERIFY_NON_NULL_RET(dstSession, NET_DTLS_TAG, "Param dstSession is NULL" , DTLS_FAIL);
194 VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL" , DTLS_FAIL);
198 OIC_LOG(ERROR, NET_DTLS_TAG, "Given Packet length is equal to zero.");
202 if (NULL == g_caDtlsContext)
204 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
208 int retLen = dtls_write(g_caDtlsContext->dtlsContext, (session_t *)dstSession, data,
210 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "dtls_write retun len [%d]", retLen);
213 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
218 // A new DTLS session was initiated by tinyDTLS library and wait for callback.
219 return DTLS_SESSION_INITIATED;
221 else if (dataLen != (uint32_t)retLen)
223 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
226 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
230 static eDtlsRet_t CAAdapterNetDtlsDecryptInternal(const stCADtlsAddrInfo_t *srcSession,
231 uint8_t *buf, uint32_t bufLen)
233 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
235 VERIFY_NON_NULL_RET(srcSession, NET_DTLS_TAG, "Param srcSession is NULL", DTLS_FAIL);
236 VERIFY_NON_NULL_RET(buf, NET_DTLS_TAG, "Param buf is NULL", DTLS_FAIL);
240 OIC_LOG(ERROR, NET_DTLS_TAG, "Given Packet length is equal to zero.");
244 eDtlsRet_t ret = DTLS_FAIL;
246 if (dtls_handle_message(g_caDtlsContext->dtlsContext, (session_t *)srcSession, buf, bufLen) == 0)
248 OIC_LOG(DEBUG, NET_DTLS_TAG, "dtls_handle_message success");
252 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
256 static void CAFreeCacheMsg(stCACacheMessage_t *msg)
258 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
259 VERIFY_NON_NULL_VOID(msg, NET_DTLS_TAG, "msg");
264 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
267 static void CAClearCacheList()
269 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
270 uint32_t list_index = 0;
271 uint32_t list_length = 0;
272 if (NULL == g_caDtlsContext)
274 OIC_LOG(ERROR, NET_DTLS_TAG, "Dtls Context is NULL");
277 list_length = u_arraylist_length(g_caDtlsContext->cacheList);
278 for (list_index = 0; list_index < list_length; list_index++)
280 stCACacheMessage_t *msg = (stCACacheMessage_t *)u_arraylist_get(g_caDtlsContext->cacheList,
287 u_arraylist_free(&g_caDtlsContext->cacheList);
288 g_caDtlsContext->cacheList = NULL;
289 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
292 static CAResult_t CADtlsCacheMsg(stCACacheMessage_t *msg)
294 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
296 if (NULL == g_caDtlsContext)
298 OIC_LOG(ERROR, NET_DTLS_TAG, "Dtls Context is NULL");
299 return CA_STATUS_FAILED;
302 bool result = u_arraylist_add(g_caDtlsContext->cacheList, (void *)msg);
305 OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_add failed!");
306 return CA_STATUS_FAILED;
309 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
314 static bool CAIsAddressMatching(const stCADtlsAddrInfo_t *a, const stCADtlsAddrInfo_t *b)
316 if (a->size != b->size)
320 if (memcmp(&a->addr, &b->addr, a->size))
327 static void CASendCachedMsg(const stCADtlsAddrInfo_t *dstSession)
329 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
330 VERIFY_NON_NULL_VOID(dstSession, NET_DTLS_TAG, "Param dstSession is NULL");
332 uint32_t list_index = 0;
333 uint32_t list_length = 0;
334 list_length = u_arraylist_length(g_caDtlsContext->cacheList);
335 for (list_index = 0; list_index < list_length;)
337 stCACacheMessage_t *msg = (stCACacheMessage_t *)u_arraylist_get(g_caDtlsContext->cacheList,
339 if ((NULL != msg) && (true == CAIsAddressMatching(&(msg->destSession), dstSession)))
341 eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(&(msg->destSession),
342 msg->data, msg->dataLen);
345 OIC_LOG(DEBUG, NET_DTLS_TAG, "CAAdapterNetDtlsEncryptInternal success");
349 OIC_LOG(ERROR, NET_DTLS_TAG, "CAAdapterNetDtlsEncryptInternal failed.");
352 if (u_arraylist_remove(g_caDtlsContext->cacheList, list_index))
355 // Reduce list length by 1 as we removed one element.
360 OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_remove failed.");
366 // Move to the next element
371 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
374 static int32_t CAReadDecryptedPayload(dtls_context_t *context,
380 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
382 VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", 0);
383 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Decrypted buf len [%d]", bufLen);
385 stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
387 CASecureEndpoint_t sep =
389 { .adapter = CA_ADAPTER_IP, .flags =
390 ((addrInfo->addr.st.ss_family == AF_INET) ? CA_IPV4 : CA_IPV6) | CA_SECURE, .port = 0 },
393 CAConvertAddrToName(&(addrInfo->addr.st), sep.endpoint.addr, &sep.endpoint.port);
395 if (NULL == g_caDtlsContext)
397 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
402 if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type) &&
403 (NULL != g_caDtlsContext->adapterCallbacks[type].recvCallback))
405 // Get identity of the source of packet
406 CASecureEndpoint_t *peerInfo = GetPeerInfo(&sep.endpoint);
409 sep.identity = peerInfo->identity;
412 g_caDtlsContext->adapterCallbacks[type].recvCallback(&sep, buf, bufLen);
416 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "recvCallback Callback or adapter type is wrong [%d]", type);
419 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
423 static int32_t CASendSecureData(dtls_context_t *context,
429 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
431 VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", -1);
432 VERIFY_NON_NULL_RET(buf, NET_DTLS_TAG, "Param buf is NULL", -1);
436 OIC_LOG(ERROR, NET_DTLS_TAG, "Encrypted Buffer length is equal to zero");
440 stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
442 CAEndpoint_t endpoint = {.adapter = CA_DEFAULT_ADAPTER};
444 CAConvertAddrToName(&(addrInfo->addr.st), endpoint.addr, &endpoint.port);
445 endpoint.flags = addrInfo->addr.st.ss_family == AF_INET ? CA_IPV4 : CA_IPV6;
446 endpoint.flags |= CA_SECURE;
447 endpoint.adapter = CA_ADAPTER_IP;
448 endpoint.interface = session->ifindex;
451 //Mutex is not required for g_caDtlsContext. It will be called in same thread.
452 if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type) &&
453 (NULL != g_caDtlsContext->adapterCallbacks[type].sendCallback))
455 g_caDtlsContext->adapterCallbacks[type].sendCallback(&endpoint, buf, bufLen);
459 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "send Callback or adapter type is wrong [%d]", type );
462 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
466 static int32_t CAHandleSecureEvent(dtls_context_t *context,
468 dtls_alert_level_t level,
472 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
474 VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", 0);
476 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "level [%d] code [%u]", level, code);
478 if (!level && (code == DTLS_EVENT_CONNECTED))
480 OIC_LOG(DEBUG, NET_DTLS_TAG, "Received DTLS_EVENT_CONNECTED. Sending Cached data");
481 CASendCachedMsg((stCADtlsAddrInfo_t *)session);
484 if(DTLS_ALERT_LEVEL_FATAL == level && DTLS_ALERT_CLOSE_NOTIFY == code)
486 OIC_LOG(INFO, NET_DTLS_TAG, "Peer closing connection");
488 stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
489 char peerAddr[MAX_ADDR_STR_SIZE_CA] = { 0 };
491 CAConvertAddrToName(&(addrInfo->addr.st), peerAddr, &port);
492 CARemovePeerFromPeerInfoList(peerAddr, port);
495 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
500 static int32_t CAGetPskCredentials(dtls_context_t *ctx,
501 const session_t *session,
502 dtls_credentials_type_t type,
503 const unsigned char *desc, size_t descLen,
504 unsigned char *result, size_t resultLen)
506 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
509 if(NULL == ctx || NULL == session || NULL == result)
511 OIC_LOG(ERROR, NET_DTLS_TAG, "CAGetPskCredentials invalid parameters");
515 VERIFY_NON_NULL_RET(g_getCredentialsCallback, NET_DTLS_TAG, "GetCredential callback", -1);
516 VERIFY_NON_NULL_RET(result, NET_DTLS_TAG, "result", -1);
518 CADtlsPskCredsBlob_t *credInfo = NULL;
520 // Retrieve the credentials blob from security module
521 g_getCredentialsCallback(&credInfo);
523 VERIFY_NON_NULL_RET(credInfo, NET_DTLS_TAG, "credInfo is NULL", -1);
524 if(NULL == credInfo->creds)
526 OIC_LOG(DEBUG, NET_DTLS_TAG, "credentials are NULL");
527 memset(credInfo, 0, sizeof(CADtlsPskCredsBlob_t));
532 if ((type == DTLS_PSK_HINT) || (type == DTLS_PSK_IDENTITY))
534 if (DTLS_PSK_ID_LEN <= resultLen)
536 memcpy(result, credInfo->identity, DTLS_PSK_ID_LEN);
537 ret = DTLS_PSK_ID_LEN;
541 if ((type == DTLS_PSK_KEY) && (desc) && (descLen == DTLS_PSK_PSK_LEN))
543 // Check if we have the credentials for the device with which we
544 // are trying to perform a handshake
545 for (uint32_t index = 0; index < credInfo->num; index++)
547 if (memcmp(desc, credInfo->creds[index].id, DTLS_PSK_ID_LEN) == 0)
549 if(NULL != ctx->peers && DTLS_SERVER == ctx->peers->role )
551 // TODO SRM needs identity of the remote end-point with every data packet to
552 // perform access control management. tinyDTLS 'frees' the handshake parameters
553 // data structure when handshake completes. Therefore, currently this is a
554 // workaround to cache remote end-point identity when tinyDTLS asks for PSK.
555 stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
556 char peerAddr[MAX_ADDR_STR_SIZE_CA] = { 0 };
558 CAConvertAddrToName(&(addrInfo->addr.st), peerAddr, &port);
560 CAResult_t result = CAAddIdToPeerInfoList(peerAddr, port, desc, descLen);
561 if(CA_STATUS_OK != result )
563 OIC_LOG(ERROR, NET_DTLS_TAG, "Fail to add peer id to gDtlsPeerInfoList");
566 memcpy(result, credInfo->creds[index].psk, DTLS_PSK_PSK_LEN);
567 ret = DTLS_PSK_PSK_LEN;
572 // Erase sensitive data before freeing.
573 memset(credInfo->creds, 0, sizeof(OCDtlsPskCreds) * (credInfo->num));
574 OICFree(credInfo->creds);
576 memset(credInfo, 0, sizeof(CADtlsPskCredsBlob_t));
583 void CADTLSSetAdapterCallbacks(CAPacketReceivedCallback recvCallback,
584 CAPacketSendCallback sendCallback,
585 CATransportAdapter_t type)
587 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
588 ca_mutex_lock(g_dtlsContextMutex);
589 if (NULL == g_caDtlsContext)
591 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
592 ca_mutex_unlock(g_dtlsContextMutex);
596 if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type))
598 // TODO: change the zeros to better values.
599 g_caDtlsContext->adapterCallbacks[0].recvCallback = recvCallback;
600 g_caDtlsContext->adapterCallbacks[0].sendCallback = sendCallback;
603 ca_mutex_unlock(g_dtlsContextMutex);
605 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
608 void CADTLSSetCredentialsCallback(CAGetDTLSCredentialsHandler credCallback)
610 // TODO Does this method needs protection of DtlsContextMutex ?
611 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
612 g_getCredentialsCallback = credCallback;
613 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
616 CAResult_t CADtlsSelectCipherSuite(const dtls_cipher_t cipher)
618 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsSelectCipherSuite");
620 ca_mutex_lock(g_dtlsContextMutex);
621 if (NULL == g_caDtlsContext)
623 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
624 ca_mutex_unlock(g_dtlsContextMutex);
625 return CA_STATUS_FAILED;
627 dtls_select_cipher(g_caDtlsContext->dtlsContext, cipher);
628 ca_mutex_unlock(g_dtlsContextMutex);
630 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Selected cipher suite is 0x%02X%02X\n",
631 ((uint8_t*)(&cipher))[1], ((uint8_t*)(&cipher))[0]);
632 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsSelectCipherSuite");
634 return CA_STATUS_OK ;
637 CAResult_t CADtlsEnableAnonECDHCipherSuite(const bool enable)
639 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsEnablesAnonEcdh");
641 ca_mutex_lock(g_dtlsContextMutex);
642 if (NULL == g_caDtlsContext)
644 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
645 ca_mutex_unlock(g_dtlsContextMutex);
646 return CA_STATUS_FAILED;
648 dtls_enables_anon_ecdh(g_caDtlsContext->dtlsContext,
649 enable == true ? DTLS_CIPHER_ENABLE : DTLS_CIPHER_DISABLE);
650 ca_mutex_unlock(g_dtlsContextMutex);
651 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 is %s",
652 enable ? "enabled" : "disabled");
654 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsEnablesAnonEcdh");
656 return CA_STATUS_OK ;
659 CAResult_t CADtlsInitiateHandshake(const CAEndpoint_t *endpoint)
661 stCADtlsAddrInfo_t dst = { 0 };
663 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsInitiateHandshake");
667 return CA_STATUS_INVALID_PARAM;
670 CAConvertNameToAddr(endpoint->addr, endpoint->port, &(dst.addr.st));
672 dst.size = CASizeOfAddrInfo(&dst);
674 ca_mutex_lock(g_dtlsContextMutex);
675 if(NULL == g_caDtlsContext)
677 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
678 ca_mutex_unlock(g_dtlsContextMutex);
679 return CA_STATUS_FAILED;
682 if(0 > dtls_connect(g_caDtlsContext->dtlsContext, (session_t*)(&dst)))
684 OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to connect");
685 ca_mutex_unlock(g_dtlsContextMutex);
686 return CA_STATUS_FAILED;
689 ca_mutex_unlock(g_dtlsContextMutex);
691 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsInitiateHandshake");
696 CAResult_t CADtlsClose(const CAEndpoint_t *endpoint)
698 stCADtlsAddrInfo_t dst = { 0 };
700 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsDisconnect");
704 return CA_STATUS_INVALID_PARAM;
707 CAConvertNameToAddr(endpoint->addr, endpoint->port, &(dst.addr.st));
709 dst.size = CASizeOfAddrInfo(&dst);
711 ca_mutex_lock(g_dtlsContextMutex);
712 if (NULL == g_caDtlsContext)
714 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
715 ca_mutex_unlock(g_dtlsContextMutex);
716 return CA_STATUS_FAILED;
719 if (0 > dtls_close(g_caDtlsContext->dtlsContext, (session_t*)(&dst)))
721 OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to close the session");
722 ca_mutex_unlock(g_dtlsContextMutex);
723 return CA_STATUS_FAILED;
726 ca_mutex_unlock(g_dtlsContextMutex);
728 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsDisconnect");
733 CAResult_t CADtlsGenerateOwnerPSK(const CAEndpoint_t *endpoint,
734 const uint8_t* label, const size_t labelLen,
735 const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
736 const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
737 uint8_t* ownerPSK, const size_t ownerPSKSize)
739 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsGenerateOwnerPSK");
741 if(!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPSKSize)
743 return CA_STATUS_INVALID_PARAM;
746 stCADtlsAddrInfo_t dst = { 0 };
748 CAConvertNameToAddr(endpoint->addr, endpoint->port, &(dst.addr.st));
750 dst.size = CASizeOfAddrInfo(&dst);
752 ca_mutex_lock(g_dtlsContextMutex);
753 if (NULL == g_caDtlsContext)
755 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
756 ca_mutex_unlock(g_dtlsContextMutex);
757 return CA_STATUS_FAILED;
760 if( 0 == dtls_prf_with_current_keyblock(g_caDtlsContext->dtlsContext, (session_t*)(&dst),
761 label, labelLen, rsrcServerDeviceID, rsrcServerDeviceIDLen,
762 provServerDeviceID, provServerDeviceIDLen, ownerPSK, ownerPSKSize))
764 OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to DTLS PRF");
765 ca_mutex_unlock(g_dtlsContextMutex);
766 return CA_STATUS_FAILED;
768 ca_mutex_unlock(g_dtlsContextMutex);
770 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsGenerateOwnerPSK");
775 CAResult_t CAAdapterNetDtlsInit()
777 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
779 // Initialize mutex for DtlsContext
780 if (NULL == g_dtlsContextMutex)
782 g_dtlsContextMutex = ca_mutex_new();
783 VERIFY_NON_NULL_RET(g_dtlsContextMutex, NET_DTLS_TAG, "malloc failed",
784 CA_MEMORY_ALLOC_FAILED);
788 OIC_LOG(ERROR, NET_DTLS_TAG, "CAAdapterNetDtlsInit done already!");
792 // Lock DtlsContext mutex and create DtlsContext
793 ca_mutex_lock(g_dtlsContextMutex);
794 g_caDtlsContext = (stCADtlsContext_t *)OICCalloc(1, sizeof(stCADtlsContext_t));
796 if (NULL == g_caDtlsContext)
798 OIC_LOG(ERROR, NET_DTLS_TAG, "Context malloc failed");
799 ca_mutex_unlock(g_dtlsContextMutex);
800 ca_mutex_free(g_dtlsContextMutex);
801 return CA_MEMORY_ALLOC_FAILED;
805 // Create PeerInfoList and CacheList
806 g_caDtlsContext->peerInfoList = u_arraylist_create();
807 g_caDtlsContext->cacheList = u_arraylist_create();
809 if( (NULL == g_caDtlsContext->peerInfoList) ||
810 (NULL == g_caDtlsContext->cacheList))
812 OIC_LOG(ERROR, NET_DTLS_TAG, "peerInfoList or cacheList initialization failed!");
814 CAFreePeerInfoList();
815 OICFree(g_caDtlsContext);
816 g_caDtlsContext = NULL;
817 ca_mutex_unlock(g_dtlsContextMutex);
818 ca_mutex_free(g_dtlsContextMutex);
819 return CA_STATUS_FAILED;
822 // Initialize clock, crypto and other global vars in tinyDTLS library
825 // Create tinydtls Context
826 g_caDtlsContext->dtlsContext = dtls_new_context(g_caDtlsContext);
828 if (NULL == g_caDtlsContext->dtlsContext)
830 OIC_LOG(ERROR, NET_DTLS_TAG, "dtls_new_context failed");
831 ca_mutex_unlock(g_dtlsContextMutex);
832 CAAdapterNetDtlsDeInit();
833 return CA_STATUS_FAILED;
836 g_caDtlsContext->callbacks.write = CASendSecureData;
837 g_caDtlsContext->callbacks.read = CAReadDecryptedPayload;
838 g_caDtlsContext->callbacks.event = CAHandleSecureEvent;
839 g_caDtlsContext->callbacks.get_psk_info = CAGetPskCredentials;
841 dtls_set_handler(g_caDtlsContext->dtlsContext, &(g_caDtlsContext->callbacks));
842 ca_mutex_unlock(g_dtlsContextMutex);
843 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
847 void CAAdapterNetDtlsDeInit()
849 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
851 VERIFY_NON_NULL_VOID(g_caDtlsContext, NET_DTLS_TAG, "context is NULL");
852 VERIFY_NON_NULL_VOID(g_dtlsContextMutex, NET_DTLS_TAG, "context mutex is NULL");
854 //Lock DtlsContext mutex
855 ca_mutex_lock(g_dtlsContextMutex);
858 CAFreePeerInfoList();
861 // De-initialize tinydtls context
862 dtls_free_context(g_caDtlsContext->dtlsContext);
863 g_caDtlsContext->dtlsContext = NULL;
865 // De-initialize DtlsContext
866 OICFree(g_caDtlsContext);
867 g_caDtlsContext = NULL;
869 // Unlock DtlsContext mutex and de-initialize it
870 ca_mutex_unlock(g_dtlsContextMutex);
871 ca_mutex_free(g_dtlsContextMutex);
872 g_dtlsContextMutex = NULL;
874 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
877 CAResult_t CAAdapterNetDtlsEncrypt(const CAEndpoint_t *endpoint,
878 void *data, uint32_t dataLen)
881 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
883 VERIFY_NON_NULL_RET(endpoint, NET_DTLS_TAG,"Param remoteAddress is NULL",
884 CA_STATUS_INVALID_PARAM);
885 VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL" ,
886 CA_STATUS_INVALID_PARAM);
890 OIC_LOG_V(ERROR, NET_DTLS_TAG, "dataLen is less than or equal zero [%d]", dataLen);
891 return CA_STATUS_FAILED;
894 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Data to be encrypted dataLen [%d]", dataLen);
896 stCADtlsAddrInfo_t addrInfo = { 0 };
898 CAConvertNameToAddr(endpoint->addr, endpoint->port, &(addrInfo.addr.st));
899 addrInfo.ifIndex = 0;
900 addrInfo.size = CASizeOfAddrInfo(&addrInfo);
902 ca_mutex_lock(g_dtlsContextMutex);
903 if(NULL == g_caDtlsContext)
905 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
906 ca_mutex_unlock(g_dtlsContextMutex);
907 return CA_STATUS_FAILED;
910 eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(&addrInfo, data, dataLen);
911 if (ret == DTLS_SESSION_INITIATED)
913 stCACacheMessage_t *message = (stCACacheMessage_t *)OICCalloc(1, sizeof(stCACacheMessage_t));
916 OIC_LOG(ERROR, NET_DTLS_TAG, "calloc failed!");
917 ca_mutex_unlock(g_dtlsContextMutex);
918 return CA_MEMORY_ALLOC_FAILED;
921 message->data = (uint8_t *)OICCalloc(dataLen + 1, sizeof(uint8_t));
922 if (NULL == message->data)
924 OIC_LOG(ERROR, NET_DTLS_TAG, "calloc failed!");
926 ca_mutex_unlock(g_dtlsContextMutex);
927 return CA_MEMORY_ALLOC_FAILED;
929 memcpy(message->data, data, dataLen);
930 message->dataLen = dataLen;
931 message->destSession = addrInfo;
933 CAResult_t result = CADtlsCacheMsg(message);
934 if (CA_STATUS_OK != result)
936 OIC_LOG(DEBUG, NET_DTLS_TAG, "CADtlsCacheMsg failed!");
937 CAFreeCacheMsg(message);
939 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "OUT Initiating Dtls session [%d]", result);
940 ca_mutex_unlock(g_dtlsContextMutex);
944 ca_mutex_unlock(g_dtlsContextMutex);
948 OIC_LOG(ERROR, NET_DTLS_TAG, "OUT FAILURE");
949 return CA_STATUS_FAILED;
952 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
956 CAResult_t CAAdapterNetDtlsDecrypt(const CASecureEndpoint_t *sep,
957 uint8_t *data, uint32_t dataLen)
959 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
960 VERIFY_NON_NULL_RET(sep, NET_DTLS_TAG, "endpoint is NULL" , CA_STATUS_INVALID_PARAM);
962 stCADtlsAddrInfo_t addrInfo = { 0 };
964 CAConvertNameToAddr(sep->endpoint.addr, sep->endpoint.port, &(addrInfo.addr.st));
965 addrInfo.ifIndex = 0;
966 addrInfo.size = CASizeOfAddrInfo(&addrInfo);
968 ca_mutex_lock(g_dtlsContextMutex);
969 if (NULL == g_caDtlsContext)
971 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
972 ca_mutex_unlock(g_dtlsContextMutex);
973 return CA_STATUS_FAILED;
976 eDtlsRet_t ret = CAAdapterNetDtlsDecryptInternal(&addrInfo, data, dataLen);
977 ca_mutex_unlock(g_dtlsContextMutex);
979 if (DTLS_OK == ret || DTLS_HS_MSG == ret)
981 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Successfully Decrypted or Handshake msg recvd [%d]", ret);
982 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
986 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
987 return CA_STATUS_FAILED;