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 CAEndpoint_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 CAEndpoint_t *peerInfo;
65 list_length = u_arraylist_length(g_caDtlsContext->peerInfoList);
66 for (list_index = 0; list_index < list_length; list_index++)
68 peerInfo = (CAEndpoint_t *)u_arraylist_get(g_caDtlsContext->peerInfoList, list_index);
74 if((0 == strncmp(peer->addr, peerInfo->addr, MAX_ADDR_STR_SIZE_CA)) &&
75 (peer->port == peerInfo->port))
83 static CAResult_t CAAddIdToPeerInfoList(const char *peerAddr, uint16_t port,
84 const unsigned char *id, uint16_t id_length, CATransportFlags_t flag)
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 CAEndpoint_t *peer = (CAEndpoint_t *)OICCalloc(1, sizeof (CAEndpoint_t));
99 OIC_LOG(ERROR, NET_DTLS_TAG, "peerInfo malloc failed!");
100 return CA_MEMORY_ALLOC_FAILED;
103 OICStrcpy(peer->addr, sizeof(peer->addr), peerAddr);
106 peer->flags |= CA_SECURE;
107 peer->adapter = CA_ADAPTER_IP;
109 memcpy(peer->identity.id, id, id_length);
110 peer->identity.id_length = id_length;
112 if(NULL != GetPeerInfo(peer))
114 OIC_LOG(ERROR, NET_DTLS_TAG, "CAAddIdToPeerInfoList peer already exist");
116 return CA_STATUS_FAILED;
119 CAResult_t result = u_arraylist_add(g_caDtlsContext->peerInfoList, (void *)peer);
120 if (CA_STATUS_OK != result)
122 OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_add failed!");
129 static void CAFreePeerInfoList()
131 uint32_t list_length = u_arraylist_length(g_caDtlsContext->peerInfoList);
132 for (uint32_t list_index = 0; list_index < list_length; list_index++)
134 CAEndpoint_t *peerInfo = (CAEndpoint_t *)u_arraylist_get(
135 g_caDtlsContext->peerInfoList, list_index);
138 u_arraylist_free(&(g_caDtlsContext->peerInfoList));
139 g_caDtlsContext->peerInfoList = NULL;
142 static void CARemovePeerFromPeerInfoList(const char * addr, uint16_t port)
144 if (NULL == addr || 0 >= port)
146 OIC_LOG(ERROR, NET_DTLS_TAG, "CADTLSGetPeerPSKId invalid parameters");
150 uint32_t list_length = u_arraylist_length(g_caDtlsContext->peerInfoList);
151 for (uint32_t list_index = 0; list_index < list_length; list_index++)
153 CAEndpoint_t *peerInfo = (CAEndpoint_t *)u_arraylist_get(
154 g_caDtlsContext->peerInfoList,list_index);
155 if (NULL == peerInfo)
159 if((0 == strncmp(addr, peerInfo->addr, MAX_ADDR_STR_SIZE_CA)) &&
160 (port == peerInfo->port))
162 OICFree(u_arraylist_remove(g_caDtlsContext->peerInfoList, list_index));
168 static int CASizeOfAddrInfo(stCADtlsAddrInfo_t *addrInfo)
170 VERIFY_NON_NULL_RET(addrInfo, NET_DTLS_TAG, "addrInfo is NULL" , DTLS_FAIL);
172 switch (addrInfo->addr.st.ss_family)
176 return sizeof (struct sockaddr_in);
180 return sizeof (struct sockaddr_in6);
187 return sizeof (struct sockaddr_storage);
190 static eDtlsRet_t CAAdapterNetDtlsEncryptInternal(const stCADtlsAddrInfo_t *dstSession,
191 uint8_t *data, uint32_t dataLen)
193 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
195 VERIFY_NON_NULL_RET(dstSession, NET_DTLS_TAG, "Param dstSession is NULL" , DTLS_FAIL);
196 VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL" , DTLS_FAIL);
200 OIC_LOG(ERROR, NET_DTLS_TAG, "Given Packet length is equal to zero.");
204 if (NULL == g_caDtlsContext)
206 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
210 int retLen = dtls_write(g_caDtlsContext->dtlsContext, (session_t *)dstSession, data,
212 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "dtls_write retun len [%d]", retLen);
215 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
220 // A new DTLS session was initiated by tinyDTLS library and wait for callback.
221 return DTLS_SESSION_INITIATED;
223 else if (dataLen != (uint32_t)retLen)
225 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
228 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
232 static eDtlsRet_t CAAdapterNetDtlsDecryptInternal(const stCADtlsAddrInfo_t *srcSession,
233 uint8_t *buf, uint32_t bufLen)
235 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
237 VERIFY_NON_NULL_RET(srcSession, NET_DTLS_TAG, "Param srcSession is NULL", DTLS_FAIL);
238 VERIFY_NON_NULL_RET(buf, NET_DTLS_TAG, "Param buf is NULL", DTLS_FAIL);
242 OIC_LOG(ERROR, NET_DTLS_TAG, "Given Packet length is equal to zero.");
246 eDtlsRet_t ret = DTLS_FAIL;
248 if (dtls_handle_message(g_caDtlsContext->dtlsContext, (session_t *)srcSession, buf, bufLen) == 0)
250 OIC_LOG(DEBUG, NET_DTLS_TAG, "dtls_handle_message success");
254 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
258 static void CAFreeCacheMsg(stCACacheMessage_t *msg)
260 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
261 VERIFY_NON_NULL_VOID(msg, NET_DTLS_TAG, "msg");
266 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
269 static void CAClearCacheList()
271 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
272 uint32_t list_index = 0;
273 uint32_t list_length = 0;
274 if (NULL == g_caDtlsContext)
276 OIC_LOG(ERROR, NET_DTLS_TAG, "Dtls Context is NULL");
279 list_length = u_arraylist_length(g_caDtlsContext->cacheList);
280 for (list_index = 0; list_index < list_length; list_index++)
282 stCACacheMessage_t *msg = (stCACacheMessage_t *)u_arraylist_get(g_caDtlsContext->cacheList,
289 u_arraylist_free(&g_caDtlsContext->cacheList);
290 g_caDtlsContext->cacheList = NULL;
291 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
294 static CAResult_t CADtlsCacheMsg(stCACacheMessage_t *msg)
296 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
298 if (NULL == g_caDtlsContext)
300 OIC_LOG(ERROR, NET_DTLS_TAG, "Dtls Context is NULL");
301 return CA_STATUS_FAILED;
304 CAResult_t result = u_arraylist_add(g_caDtlsContext->cacheList, (void *)msg);
305 if (CA_STATUS_OK != result)
307 OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_add failed!");
310 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
315 static bool CAIsAddressMatching(const stCADtlsAddrInfo_t *a, const stCADtlsAddrInfo_t *b)
317 if (a->size != b->size)
321 if (memcmp(&a->addr, &b->addr, a->size))
328 static void CASendCachedMsg(const stCADtlsAddrInfo_t *dstSession)
330 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
331 VERIFY_NON_NULL_VOID(dstSession, NET_DTLS_TAG, "Param dstSession is NULL");
333 uint32_t list_index = 0;
334 uint32_t list_length = 0;
335 list_length = u_arraylist_length(g_caDtlsContext->cacheList);
336 for (list_index = 0; list_index < list_length;)
338 stCACacheMessage_t *msg = (stCACacheMessage_t *)u_arraylist_get(g_caDtlsContext->cacheList,
340 if ((NULL != msg) && (true == CAIsAddressMatching(&(msg->destSession), dstSession)))
342 eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(&(msg->destSession),
343 msg->data, msg->dataLen);
346 OIC_LOG(DEBUG, NET_DTLS_TAG, "CAAdapterNetDtlsEncryptInternal success");
350 OIC_LOG(ERROR, NET_DTLS_TAG, "CAAdapterNetDtlsEncryptInternal failed.");
353 if (u_arraylist_remove(g_caDtlsContext->cacheList, list_index))
356 // Reduce list length by 1 as we removed one element.
361 OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_remove failed.");
367 // Move to the next element
372 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
375 static int32_t CAReadDecryptedPayload(dtls_context_t *context,
381 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
383 VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", 0);
384 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Decrypted buf len [%d]", bufLen);
386 stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
388 CAEndpoint_t endpoint = { 0 };
389 CAConvertAddrToName(&(addrInfo->addr.st), endpoint.addr, &endpoint.port);
390 endpoint.flags = addrInfo->addr.st.ss_family == AF_INET ? CA_IPV4 : CA_IPV6;
391 endpoint.flags |= CA_SECURE;
392 endpoint.adapter = CA_ADAPTER_IP;
395 if (NULL == g_caDtlsContext)
397 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
401 if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type) &&
402 (NULL != g_caDtlsContext->adapterCallbacks[type].recvCallback))
404 // Get identity of the source of packet
405 CAEndpoint_t *peerInfo = GetPeerInfo(&endpoint);
408 endpoint.identity = peerInfo->identity;
411 g_caDtlsContext->adapterCallbacks[type].recvCallback(&endpoint, buf, bufLen);
415 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "recvCallback Callback or adapter type is wrong [%d]", type);
418 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
422 static int32_t CASendSecureData(dtls_context_t *context,
428 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
430 VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", -1);
431 VERIFY_NON_NULL_RET(buf, NET_DTLS_TAG, "Param buf is NULL", -1);
435 OIC_LOG(ERROR, NET_DTLS_TAG, "Encrypted Buffer length is equal to zero");
439 stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
441 CAEndpoint_t endpoint;
442 CAConvertAddrToName(&(addrInfo->addr.st), endpoint.addr, &endpoint.port);
443 endpoint.flags = addrInfo->addr.st.ss_family == AF_INET ? CA_IPV4 : CA_IPV6;
444 endpoint.flags |= CA_SECURE;
445 endpoint.adapter = CA_ADAPTER_IP;
448 //Mutex is not required for g_caDtlsContext. It will be called in same thread.
449 if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type) &&
450 (NULL != g_caDtlsContext->adapterCallbacks[type].sendCallback))
452 g_caDtlsContext->adapterCallbacks[type].sendCallback(&endpoint, buf, bufLen);
456 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "send Callback or adapter type is wrong [%d]", type );
459 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
463 static int32_t CAHandleSecureEvent(dtls_context_t *context,
465 dtls_alert_level_t level,
469 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
471 VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", 0);
473 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "level [%d] code [%u]", level, code);
475 if (!level && (code == DTLS_EVENT_CONNECTED))
477 OIC_LOG(DEBUG, NET_DTLS_TAG, "Received DTLS_EVENT_CONNECTED. Sending Cached data");
478 CASendCachedMsg((stCADtlsAddrInfo_t *)session);
481 if(DTLS_ALERT_LEVEL_FATAL == level && DTLS_ALERT_CLOSE_NOTIFY == code)
483 OIC_LOG(INFO, NET_DTLS_TAG, "Peer closing connection");
485 stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
486 char peerAddr[MAX_ADDR_STR_SIZE_CA] = {0};
488 CAConvertAddrToName(&(addrInfo->addr.st), peerAddr, &port);
489 CARemovePeerFromPeerInfoList(peerAddr, port);
492 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
497 static int32_t CAGetPskCredentials(dtls_context_t *ctx,
498 const session_t *session,
499 dtls_credentials_type_t type,
500 const unsigned char *desc, size_t descLen,
501 unsigned char *result, size_t resultLen)
503 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
506 if(NULL == ctx || NULL == session || NULL == result)
508 OIC_LOG(ERROR, NET_DTLS_TAG, "CAGetPskCredentials invalid parameters");
512 VERIFY_NON_NULL_RET(g_getCredentialsCallback, NET_DTLS_TAG, "GetCredential callback", -1);
513 VERIFY_NON_NULL_RET(result, NET_DTLS_TAG, "result", -1);
515 CADtlsPskCredsBlob_t *credInfo = NULL;
517 // Retrieve the credentials blob from security module
518 g_getCredentialsCallback(&credInfo);
520 VERIFY_NON_NULL_RET(credInfo, NET_DTLS_TAG, "credInfo is NULL", -1);
521 if(NULL == credInfo->creds)
523 OIC_LOG(DEBUG, NET_DTLS_TAG, "credentials are NULL");
524 memset(credInfo, 0, sizeof(CADtlsPskCredsBlob_t));
529 if ((type == DTLS_PSK_HINT) || (type == DTLS_PSK_IDENTITY))
531 if (DTLS_PSK_ID_LEN <= resultLen)
533 memcpy(result, credInfo->identity, DTLS_PSK_ID_LEN);
534 ret = DTLS_PSK_ID_LEN;
538 if ((type == DTLS_PSK_KEY) && (desc) && (descLen == DTLS_PSK_PSK_LEN))
540 // Check if we have the credentials for the device with which we
541 // are trying to perform a handshake
542 for (uint32_t index = 0; index < credInfo->num; index++)
544 if (memcmp(desc, credInfo->creds[index].id, DTLS_PSK_ID_LEN) == 0)
546 if(NULL != ctx->peers && DTLS_SERVER == ctx->peers->role )
548 // TODO SRM needs identity of the remote end-point with every data packet to
549 // perform access control management. tinyDTLS 'frees' the handshake parameters
550 // data structure when handshake completes. Therefore, currently this is a
551 // workaround to cache remote end-point identity when tinyDTLS asks for PSK.
552 stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
553 char peerAddress[MAX_ADDR_STR_SIZE_CA] = {0};
555 CAConvertAddrToName(&(addrInfo->addr.st), peerAddress, &port);
557 CATransportFlags_t flag =
558 addrInfo->addr.st.ss_family == AF_INET ? CA_IPV4 : CA_IPV6;
560 CAResult_t result = CAAddIdToPeerInfoList(peerAddress,
561 port, desc, descLen, flag);
562 if(CA_STATUS_OK != result )
564 OIC_LOG(ERROR, NET_DTLS_TAG, "Fail to add peer id to gDtlsPeerInfoList");
567 memcpy(result, credInfo->creds[index].psk, DTLS_PSK_PSK_LEN);
568 ret = DTLS_PSK_PSK_LEN;
573 // Erase sensitive data before freeing.
574 memset(credInfo->creds, 0, sizeof(OCDtlsPskCreds) * (credInfo->num));
575 OICFree(credInfo->creds);
577 memset(credInfo, 0, sizeof(CADtlsPskCredsBlob_t));
584 void CADTLSSetAdapterCallbacks(CAPacketReceivedCallback recvCallback,
585 CAPacketSendCallback sendCallback,
586 CATransportAdapter_t type)
588 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
589 ca_mutex_lock(g_dtlsContextMutex);
590 if (NULL == g_caDtlsContext)
592 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
593 ca_mutex_unlock(g_dtlsContextMutex);
597 if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type))
599 // TODO: change the zeros to better values.
600 g_caDtlsContext->adapterCallbacks[0].recvCallback = recvCallback;
601 g_caDtlsContext->adapterCallbacks[0].sendCallback = sendCallback;
604 ca_mutex_unlock(g_dtlsContextMutex);
606 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
609 void CADTLSSetCredentialsCallback(CAGetDTLSCredentialsHandler credCallback)
611 // TODO Does this method needs protection of DtlsContextMutex ?
612 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
613 g_getCredentialsCallback = credCallback;
614 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
617 CAResult_t CADtlsSelectCipherSuite(const dtls_cipher_t cipher)
619 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsSelectCipherSuite");
621 ca_mutex_lock(g_dtlsContextMutex);
622 if (NULL == g_caDtlsContext)
624 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
625 ca_mutex_unlock(g_dtlsContextMutex);
626 return CA_STATUS_FAILED;
628 dtls_select_cipher(g_caDtlsContext->dtlsContext, cipher);
629 ca_mutex_unlock(g_dtlsContextMutex);
631 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Selected cipher suite is 0x%02X%02X\n",
632 ((uint8_t*)(&cipher))[1], ((uint8_t*)(&cipher))[0]);
633 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsSelectCipherSuite");
635 return CA_STATUS_OK ;
638 CAResult_t CADtlsEnableAnonECDHCipherSuite(const bool enable)
640 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsEnablesAnonEcdh");
642 ca_mutex_lock(g_dtlsContextMutex);
643 if (NULL == g_caDtlsContext)
645 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
646 ca_mutex_unlock(g_dtlsContextMutex);
647 return CA_STATUS_FAILED;
649 dtls_enables_anon_ecdh(g_caDtlsContext->dtlsContext,
650 enable == true ? DTLS_CIPHER_ENABLE : DTLS_CIPHER_DISABLE);
651 ca_mutex_unlock(g_dtlsContextMutex);
652 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 is %s",
653 enable ? "enabled" : "disabled");
655 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsEnablesAnonEcdh");
657 return CA_STATUS_OK ;
660 CAResult_t CADtlsInitiateHandshake(const CAEndpoint_t *endpoint)
662 stCADtlsAddrInfo_t dst = { 0 };
664 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsInitiateHandshake");
668 return CA_STATUS_INVALID_PARAM;
671 CAConvertNameToAddr(endpoint->addr, endpoint->port, &(dst.addr.st));
673 dst.size = CASizeOfAddrInfo(&dst);
675 ca_mutex_lock(g_dtlsContextMutex);
676 if(NULL == g_caDtlsContext)
678 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
679 ca_mutex_unlock(g_dtlsContextMutex);
680 return CA_STATUS_FAILED;
683 if(0 > dtls_connect(g_caDtlsContext->dtlsContext, (session_t*)(&dst)))
685 OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to connect");
686 ca_mutex_unlock(g_dtlsContextMutex);
687 return CA_STATUS_FAILED;
690 ca_mutex_unlock(g_dtlsContextMutex);
692 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsInitiateHandshake");
697 CAResult_t CADtlsClose(const CAEndpoint_t *endpoint)
699 stCADtlsAddrInfo_t dst = { 0 };
701 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsDisconnect");
705 return CA_STATUS_INVALID_PARAM;
708 CAConvertNameToAddr(endpoint->addr, endpoint->port, &(dst.addr.st));
710 dst.size = CASizeOfAddrInfo(&dst);
712 ca_mutex_lock(g_dtlsContextMutex);
713 if (NULL == g_caDtlsContext)
715 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
716 ca_mutex_unlock(g_dtlsContextMutex);
717 return CA_STATUS_FAILED;
720 if (0 > dtls_close(g_caDtlsContext->dtlsContext, (session_t*)(&dst)))
722 OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to close the session");
723 ca_mutex_unlock(g_dtlsContextMutex);
724 return CA_STATUS_FAILED;
727 ca_mutex_unlock(g_dtlsContextMutex);
729 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsDisconnect");
734 CAResult_t CADtlsGenerateOwnerPSK(const CAEndpoint_t *endpoint,
735 const uint8_t* label, const size_t labelLen,
736 const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
737 const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
738 uint8_t* ownerPSK, const size_t ownerPSKSize)
740 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsGenerateOwnerPSK");
742 if(!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPSKSize)
744 return CA_STATUS_INVALID_PARAM;
747 stCADtlsAddrInfo_t dst = { 0 };
749 CAConvertNameToAddr(endpoint->addr, endpoint->port, &(dst.addr.st));
751 dst.size = CASizeOfAddrInfo(&dst);
753 ca_mutex_lock(g_dtlsContextMutex);
754 if (NULL == g_caDtlsContext)
756 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
757 ca_mutex_unlock(g_dtlsContextMutex);
758 return CA_STATUS_FAILED;
761 if( 0 == dtls_prf_with_current_keyblock(g_caDtlsContext->dtlsContext, (session_t*)(&dst),
762 label, labelLen, rsrcServerDeviceID, rsrcServerDeviceIDLen,
763 provServerDeviceID, provServerDeviceIDLen, ownerPSK, ownerPSKSize))
765 OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to DTLS PRF");
766 ca_mutex_unlock(g_dtlsContextMutex);
767 return CA_STATUS_FAILED;
769 ca_mutex_unlock(g_dtlsContextMutex);
771 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsGenerateOwnerPSK");
776 CAResult_t CAAdapterNetDtlsInit()
778 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
780 // Initialize mutex for DtlsContext
781 if (NULL == g_dtlsContextMutex)
783 g_dtlsContextMutex = ca_mutex_new();
784 VERIFY_NON_NULL_RET(g_dtlsContextMutex, NET_DTLS_TAG, "malloc failed",
785 CA_MEMORY_ALLOC_FAILED);
789 OIC_LOG(ERROR, NET_DTLS_TAG, "CAAdapterNetDtlsInit done already!");
793 // Lock DtlsContext mutex and create DtlsContext
794 ca_mutex_lock(g_dtlsContextMutex);
795 g_caDtlsContext = (stCADtlsContext_t *)OICCalloc(1, sizeof(stCADtlsContext_t));
797 if (NULL == g_caDtlsContext)
799 OIC_LOG(ERROR, NET_DTLS_TAG, "Context malloc failed");
800 ca_mutex_unlock(g_dtlsContextMutex);
801 ca_mutex_free(g_dtlsContextMutex);
802 return CA_MEMORY_ALLOC_FAILED;
806 // Create PeerInfoList and CacheList
807 g_caDtlsContext->peerInfoList = u_arraylist_create();
808 g_caDtlsContext->cacheList = u_arraylist_create();
810 if( (NULL == g_caDtlsContext->peerInfoList) ||
811 (NULL == g_caDtlsContext->cacheList))
813 OIC_LOG(ERROR, NET_DTLS_TAG, "peerInfoList or cacheList initialization failed!");
815 CAFreePeerInfoList();
816 OICFree(g_caDtlsContext);
817 g_caDtlsContext = NULL;
818 ca_mutex_unlock(g_dtlsContextMutex);
819 ca_mutex_free(g_dtlsContextMutex);
820 return CA_STATUS_FAILED;
823 // Initialize clock, crypto and other global vars in tinyDTLS library
826 // Create tinydtls Context
827 g_caDtlsContext->dtlsContext = dtls_new_context(g_caDtlsContext);
829 if (NULL == g_caDtlsContext->dtlsContext)
831 OIC_LOG(ERROR, NET_DTLS_TAG, "dtls_new_context failed");
832 ca_mutex_unlock(g_dtlsContextMutex);
833 CAAdapterNetDtlsDeInit();
834 return CA_STATUS_FAILED;
837 g_caDtlsContext->callbacks.write = CASendSecureData;
838 g_caDtlsContext->callbacks.read = CAReadDecryptedPayload;
839 g_caDtlsContext->callbacks.event = CAHandleSecureEvent;
840 g_caDtlsContext->callbacks.get_psk_info = CAGetPskCredentials;
842 dtls_set_handler(g_caDtlsContext->dtlsContext, &(g_caDtlsContext->callbacks));
843 ca_mutex_unlock(g_dtlsContextMutex);
844 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
848 void CAAdapterNetDtlsDeInit()
850 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
852 VERIFY_NON_NULL_VOID(g_caDtlsContext, NET_DTLS_TAG, "context is NULL");
853 VERIFY_NON_NULL_VOID(g_dtlsContextMutex, NET_DTLS_TAG, "context mutex is NULL");
855 //Lock DtlsContext mutex
856 ca_mutex_lock(g_dtlsContextMutex);
859 CAFreePeerInfoList();
862 // De-initialize tinydtls context
863 dtls_free_context(g_caDtlsContext->dtlsContext);
864 g_caDtlsContext->dtlsContext = NULL;
866 // De-initialize DtlsContext
867 OICFree(g_caDtlsContext);
868 g_caDtlsContext = NULL;
870 // Unlock DtlsContext mutex and de-initialize it
871 ca_mutex_unlock(g_dtlsContextMutex);
872 ca_mutex_free(g_dtlsContextMutex);
873 g_dtlsContextMutex = NULL;
875 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
878 CAResult_t CAAdapterNetDtlsEncrypt(const CAEndpoint_t *endpoint,
879 void *data, uint32_t dataLen)
882 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
884 VERIFY_NON_NULL_RET(endpoint, NET_DTLS_TAG,"Param remoteAddress is NULL",
885 CA_STATUS_INVALID_PARAM);
886 VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL" ,
887 CA_STATUS_INVALID_PARAM);
891 OIC_LOG_V(ERROR, NET_DTLS_TAG, "dataLen is less than or equal zero [%d]", dataLen);
892 return CA_STATUS_FAILED;
895 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Data to be encrypted dataLen [%d]", dataLen);
897 stCADtlsAddrInfo_t addrInfo = { 0 };
899 CAConvertNameToAddr(endpoint->addr, endpoint->port, &(addrInfo.addr.st));
900 addrInfo.ifIndex = 0;
901 addrInfo.size = CASizeOfAddrInfo(&addrInfo);
903 ca_mutex_lock(g_dtlsContextMutex);
904 if(NULL == g_caDtlsContext)
906 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
907 ca_mutex_unlock(g_dtlsContextMutex);
908 return CA_STATUS_FAILED;
911 eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(&addrInfo, data, dataLen);
912 if (ret == DTLS_SESSION_INITIATED)
914 stCACacheMessage_t *message = (stCACacheMessage_t *)OICCalloc(1, sizeof(stCACacheMessage_t));
917 OIC_LOG(ERROR, NET_DTLS_TAG, "calloc failed!");
918 ca_mutex_unlock(g_dtlsContextMutex);
919 return CA_MEMORY_ALLOC_FAILED;
922 message->data = (uint8_t *)OICCalloc(dataLen + 1, sizeof(uint8_t));
923 if (NULL == message->data)
925 OIC_LOG(ERROR, NET_DTLS_TAG, "calloc failed!");
927 ca_mutex_unlock(g_dtlsContextMutex);
928 return CA_MEMORY_ALLOC_FAILED;
930 memcpy(message->data, data, dataLen);
931 message->dataLen = dataLen;
932 message->destSession = addrInfo;
934 CAResult_t result = CADtlsCacheMsg(message);
935 if (CA_STATUS_OK != result)
937 OIC_LOG(DEBUG, NET_DTLS_TAG, "CADtlsCacheMsg failed!");
938 CAFreeCacheMsg(message);
940 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "OUT Initiating Dtls session [%d]", result);
941 ca_mutex_unlock(g_dtlsContextMutex);
945 ca_mutex_unlock(g_dtlsContextMutex);
949 OIC_LOG(ERROR, NET_DTLS_TAG, "OUT FAILURE");
950 return CA_STATUS_FAILED;
953 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
957 CAResult_t CAAdapterNetDtlsDecrypt(const CAEndpoint_t *endpoint,
958 uint8_t *data, uint32_t dataLen)
960 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
961 VERIFY_NON_NULL_RET(endpoint, NET_DTLS_TAG, "endpoint is NULL" , CA_STATUS_INVALID_PARAM);
963 stCADtlsAddrInfo_t addrInfo = { 0 };
965 CAConvertNameToAddr(endpoint->addr, endpoint->port, &(addrInfo.addr.st));
966 addrInfo.ifIndex = 0;
967 addrInfo.size = CASizeOfAddrInfo(&addrInfo);
969 ca_mutex_lock(g_dtlsContextMutex);
970 if (NULL == g_caDtlsContext)
972 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
973 ca_mutex_unlock(g_dtlsContextMutex);
974 return CA_STATUS_FAILED;
977 eDtlsRet_t ret = CAAdapterNetDtlsDecryptInternal(&addrInfo, data, dataLen);
978 ca_mutex_unlock(g_dtlsContextMutex);
980 if (DTLS_OK == ret || DTLS_HS_MSG == ret)
982 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Successfully Decrypted or Handshake msg recvd [%d]", ret);
983 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
987 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
988 return CA_STATUS_FAILED;