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!");
126 static void CAFreePeerInfoList()
128 uint32_t list_length = u_arraylist_length(g_caDtlsContext->peerInfoList);
129 for (uint32_t list_index = 0; list_index < list_length; list_index++)
131 CAEndpoint_t *peerInfo = (CAEndpoint_t *)u_arraylist_get(
132 g_caDtlsContext->peerInfoList, list_index);
135 u_arraylist_free(&(g_caDtlsContext->peerInfoList));
136 g_caDtlsContext->peerInfoList = NULL;
139 static void CARemovePeerFromPeerInfoList(const char * addr, uint16_t port)
141 if (NULL == addr || 0 >= port)
143 OIC_LOG(ERROR, NET_DTLS_TAG, "CADTLSGetPeerPSKId invalid parameters");
147 uint32_t list_length = u_arraylist_length(g_caDtlsContext->peerInfoList);
148 for (uint32_t list_index = 0; list_index < list_length; list_index++)
150 CAEndpoint_t *peerInfo = (CAEndpoint_t *)u_arraylist_get(
151 g_caDtlsContext->peerInfoList,list_index);
152 if (NULL == peerInfo)
156 if((0 == strncmp(addr, peerInfo->addr, MAX_ADDR_STR_SIZE_CA)) &&
157 (port == peerInfo->port))
159 OICFree(u_arraylist_remove(g_caDtlsContext->peerInfoList, list_index));
165 static int CASizeOfAddrInfo(stCADtlsAddrInfo_t *addrInfo)
167 VERIFY_NON_NULL_RET(addrInfo, NET_DTLS_TAG, "addrInfo is NULL" , DTLS_FAIL);
169 switch (addrInfo->addr.st.ss_family)
173 return sizeof (struct sockaddr_in);
177 return sizeof (struct sockaddr_in6);
184 return sizeof (struct sockaddr_storage);
187 static eDtlsRet_t CAAdapterNetDtlsEncryptInternal(const stCADtlsAddrInfo_t *dstSession,
188 uint8_t *data, uint32_t dataLen)
190 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
192 VERIFY_NON_NULL_RET(dstSession, NET_DTLS_TAG, "Param dstSession is NULL" , DTLS_FAIL);
193 VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL" , DTLS_FAIL);
197 OIC_LOG(ERROR, NET_DTLS_TAG, "Given Packet length is equal to zero.");
201 if (NULL == g_caDtlsContext)
203 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
207 int retLen = dtls_write(g_caDtlsContext->dtlsContext, (session_t *)dstSession, data,
209 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "dtls_write retun len [%d]", retLen);
212 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
217 // A new DTLS session was initiated by tinyDTLS library and wait for callback.
218 return DTLS_SESSION_INITIATED;
220 else if (dataLen != (uint32_t)retLen)
222 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
225 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
229 static eDtlsRet_t CAAdapterNetDtlsDecryptInternal(const stCADtlsAddrInfo_t *srcSession,
230 uint8_t *buf, uint32_t bufLen)
232 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
234 VERIFY_NON_NULL_RET(srcSession, NET_DTLS_TAG, "Param srcSession is NULL", DTLS_FAIL);
235 VERIFY_NON_NULL_RET(buf, NET_DTLS_TAG, "Param buf is NULL", DTLS_FAIL);
239 OIC_LOG(ERROR, NET_DTLS_TAG, "Given Packet length is equal to zero.");
243 eDtlsRet_t ret = DTLS_FAIL;
245 if (dtls_handle_message(g_caDtlsContext->dtlsContext, (session_t *)srcSession, buf, bufLen) == 0)
247 OIC_LOG(DEBUG, NET_DTLS_TAG, "dtls_handle_message success");
251 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
255 static void CAFreeCacheMsg(stCACacheMessage_t *msg)
257 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
258 VERIFY_NON_NULL_VOID(msg, NET_DTLS_TAG, "msg");
263 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
266 static void CAClearCacheList()
268 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
269 uint32_t list_index = 0;
270 uint32_t list_length = 0;
271 if (NULL == g_caDtlsContext)
273 OIC_LOG(ERROR, NET_DTLS_TAG, "Dtls Context is NULL");
276 list_length = u_arraylist_length(g_caDtlsContext->cacheList);
277 for (list_index = 0; list_index < list_length; list_index++)
279 stCACacheMessage_t *msg = (stCACacheMessage_t *)u_arraylist_get(g_caDtlsContext->cacheList,
286 u_arraylist_free(&g_caDtlsContext->cacheList);
287 g_caDtlsContext->cacheList = NULL;
288 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
291 static CAResult_t CADtlsCacheMsg(stCACacheMessage_t *msg)
293 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
295 if (NULL == g_caDtlsContext)
297 OIC_LOG(ERROR, NET_DTLS_TAG, "Dtls Context is NULL");
298 return CA_STATUS_FAILED;
301 bool result = u_arraylist_add(g_caDtlsContext->cacheList, (void *)msg);
304 OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_add failed!");
307 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
312 static bool CAIsAddressMatching(const stCADtlsAddrInfo_t *a, const stCADtlsAddrInfo_t *b)
314 if (a->size != b->size)
318 if (memcmp(&a->addr, &b->addr, a->size))
325 static void CASendCachedMsg(const stCADtlsAddrInfo_t *dstSession)
327 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
328 VERIFY_NON_NULL_VOID(dstSession, NET_DTLS_TAG, "Param dstSession is NULL");
330 uint32_t list_index = 0;
331 uint32_t list_length = 0;
332 list_length = u_arraylist_length(g_caDtlsContext->cacheList);
333 for (list_index = 0; list_index < list_length;)
335 stCACacheMessage_t *msg = (stCACacheMessage_t *)u_arraylist_get(g_caDtlsContext->cacheList,
337 if ((NULL != msg) && (true == CAIsAddressMatching(&(msg->destSession), dstSession)))
339 eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(&(msg->destSession),
340 msg->data, msg->dataLen);
343 OIC_LOG(DEBUG, NET_DTLS_TAG, "CAAdapterNetDtlsEncryptInternal success");
347 OIC_LOG(ERROR, NET_DTLS_TAG, "CAAdapterNetDtlsEncryptInternal failed.");
350 if (u_arraylist_remove(g_caDtlsContext->cacheList, list_index))
353 // Reduce list length by 1 as we removed one element.
358 OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_remove failed.");
364 // Move to the next element
369 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
372 static int32_t CAReadDecryptedPayload(dtls_context_t *context,
378 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
380 VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", 0);
381 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Decrypted buf len [%d]", bufLen);
383 stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
385 CASecureEndpoint_t sep =
387 { .adapter = CA_ADAPTER_IP, .flags =
388 ((addrInfo->addr.st.ss_family == AF_INET) ? CA_IPV4 : CA_IPV6) | CA_SECURE, .port = 0 },
391 CAConvertAddrToName(&(addrInfo->addr.st), sep.endpoint.addr, &sep.endpoint.port);
393 if (NULL == g_caDtlsContext)
395 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
400 if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type) &&
401 (NULL != g_caDtlsContext->adapterCallbacks[type].recvCallback))
403 // Get identity of the source of packet
404 CASecureEndpoint_t *peerInfo = GetPeerInfo(&sep.endpoint);
407 sep.identity = peerInfo->identity;
410 g_caDtlsContext->adapterCallbacks[type].recvCallback(&sep, buf, bufLen);
414 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "recvCallback Callback or adapter type is wrong [%d]", type);
417 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
421 static int32_t CASendSecureData(dtls_context_t *context,
427 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
429 VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", -1);
430 VERIFY_NON_NULL_RET(buf, NET_DTLS_TAG, "Param buf is NULL", -1);
434 OIC_LOG(ERROR, NET_DTLS_TAG, "Encrypted Buffer length is equal to zero");
438 stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
440 CAEndpoint_t endpoint;
441 CAConvertAddrToName(&(addrInfo->addr.st), endpoint.addr, &endpoint.port);
442 endpoint.flags = addrInfo->addr.st.ss_family == AF_INET ? CA_IPV4 : CA_IPV6;
443 endpoint.flags |= CA_SECURE;
444 endpoint.adapter = CA_ADAPTER_IP;
447 //Mutex is not required for g_caDtlsContext. It will be called in same thread.
448 if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type) &&
449 (NULL != g_caDtlsContext->adapterCallbacks[type].sendCallback))
451 g_caDtlsContext->adapterCallbacks[type].sendCallback(&endpoint, buf, bufLen);
455 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "send Callback or adapter type is wrong [%d]", type );
458 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
462 static int32_t CAHandleSecureEvent(dtls_context_t *context,
464 dtls_alert_level_t level,
468 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
470 VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", 0);
472 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "level [%d] code [%u]", level, code);
474 if (!level && (code == DTLS_EVENT_CONNECTED))
476 OIC_LOG(DEBUG, NET_DTLS_TAG, "Received DTLS_EVENT_CONNECTED. Sending Cached data");
477 CASendCachedMsg((stCADtlsAddrInfo_t *)session);
480 if(DTLS_ALERT_LEVEL_FATAL == level && DTLS_ALERT_CLOSE_NOTIFY == code)
482 OIC_LOG(INFO, NET_DTLS_TAG, "Peer closing connection");
484 stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
485 char peerAddr[MAX_ADDR_STR_SIZE_CA] = { 0 };
487 CAConvertAddrToName(&(addrInfo->addr.st), peerAddr, &port);
488 CARemovePeerFromPeerInfoList(peerAddr, port);
491 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
496 static int32_t CAGetPskCredentials(dtls_context_t *ctx,
497 const session_t *session,
498 dtls_credentials_type_t type,
499 const unsigned char *desc, size_t descLen,
500 unsigned char *result, size_t resultLen)
502 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
505 if(NULL == ctx || NULL == session || NULL == result)
507 OIC_LOG(ERROR, NET_DTLS_TAG, "CAGetPskCredentials invalid parameters");
511 VERIFY_NON_NULL_RET(g_getCredentialsCallback, NET_DTLS_TAG, "GetCredential callback", -1);
512 VERIFY_NON_NULL_RET(result, NET_DTLS_TAG, "result", -1);
514 CADtlsPskCredsBlob_t *credInfo = NULL;
516 // Retrieve the credentials blob from security module
517 g_getCredentialsCallback(&credInfo);
519 VERIFY_NON_NULL_RET(credInfo, NET_DTLS_TAG, "credInfo is NULL", -1);
520 if(NULL == credInfo->creds)
522 OIC_LOG(DEBUG, NET_DTLS_TAG, "credentials are NULL");
523 memset(credInfo, 0, sizeof(CADtlsPskCredsBlob_t));
528 if ((type == DTLS_PSK_HINT) || (type == DTLS_PSK_IDENTITY))
530 if (DTLS_PSK_ID_LEN <= resultLen)
532 memcpy(result, credInfo->identity, DTLS_PSK_ID_LEN);
533 ret = DTLS_PSK_ID_LEN;
537 if ((type == DTLS_PSK_KEY) && (desc) && (descLen == DTLS_PSK_PSK_LEN))
539 // Check if we have the credentials for the device with which we
540 // are trying to perform a handshake
541 for (uint32_t index = 0; index < credInfo->num; index++)
543 if (memcmp(desc, credInfo->creds[index].id, DTLS_PSK_ID_LEN) == 0)
545 if(NULL != ctx->peers && DTLS_SERVER == ctx->peers->role )
547 // TODO SRM needs identity of the remote end-point with every data packet to
548 // perform access control management. tinyDTLS 'frees' the handshake parameters
549 // data structure when handshake completes. Therefore, currently this is a
550 // workaround to cache remote end-point identity when tinyDTLS asks for PSK.
551 stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
552 char peerAddr[MAX_ADDR_STR_SIZE_CA] = { 0 };
554 CAConvertAddrToName(&(addrInfo->addr.st), peerAddr, &port);
556 CAResult_t result = CAAddIdToPeerInfoList(peerAddr, port, desc, descLen);
557 if(CA_STATUS_OK != result )
559 OIC_LOG(ERROR, NET_DTLS_TAG, "Fail to add peer id to gDtlsPeerInfoList");
562 memcpy(result, credInfo->creds[index].psk, DTLS_PSK_PSK_LEN);
563 ret = DTLS_PSK_PSK_LEN;
568 // Erase sensitive data before freeing.
569 memset(credInfo->creds, 0, sizeof(OCDtlsPskCreds) * (credInfo->num));
570 OICFree(credInfo->creds);
572 memset(credInfo, 0, sizeof(CADtlsPskCredsBlob_t));
579 void CADTLSSetAdapterCallbacks(CAPacketReceivedCallback recvCallback,
580 CAPacketSendCallback sendCallback,
581 CATransportAdapter_t type)
583 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
584 ca_mutex_lock(g_dtlsContextMutex);
585 if (NULL == g_caDtlsContext)
587 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
588 ca_mutex_unlock(g_dtlsContextMutex);
592 if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type))
594 // TODO: change the zeros to better values.
595 g_caDtlsContext->adapterCallbacks[0].recvCallback = recvCallback;
596 g_caDtlsContext->adapterCallbacks[0].sendCallback = sendCallback;
599 ca_mutex_unlock(g_dtlsContextMutex);
601 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
604 void CADTLSSetCredentialsCallback(CAGetDTLSCredentialsHandler credCallback)
606 // TODO Does this method needs protection of DtlsContextMutex ?
607 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
608 g_getCredentialsCallback = credCallback;
609 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
612 CAResult_t CADtlsSelectCipherSuite(const dtls_cipher_t cipher)
614 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsSelectCipherSuite");
616 ca_mutex_lock(g_dtlsContextMutex);
617 if (NULL == g_caDtlsContext)
619 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
620 ca_mutex_unlock(g_dtlsContextMutex);
621 return CA_STATUS_FAILED;
623 dtls_select_cipher(g_caDtlsContext->dtlsContext, cipher);
624 ca_mutex_unlock(g_dtlsContextMutex);
626 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Selected cipher suite is 0x%02X%02X\n",
627 ((uint8_t*)(&cipher))[1], ((uint8_t*)(&cipher))[0]);
628 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsSelectCipherSuite");
630 return CA_STATUS_OK ;
633 CAResult_t CADtlsEnableAnonECDHCipherSuite(const bool enable)
635 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsEnablesAnonEcdh");
637 ca_mutex_lock(g_dtlsContextMutex);
638 if (NULL == g_caDtlsContext)
640 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
641 ca_mutex_unlock(g_dtlsContextMutex);
642 return CA_STATUS_FAILED;
644 dtls_enables_anon_ecdh(g_caDtlsContext->dtlsContext,
645 enable == true ? DTLS_CIPHER_ENABLE : DTLS_CIPHER_DISABLE);
646 ca_mutex_unlock(g_dtlsContextMutex);
647 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 is %s",
648 enable ? "enabled" : "disabled");
650 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsEnablesAnonEcdh");
652 return CA_STATUS_OK ;
655 CAResult_t CADtlsInitiateHandshake(const CAEndpoint_t *endpoint)
657 stCADtlsAddrInfo_t dst = { 0 };
659 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsInitiateHandshake");
663 return CA_STATUS_INVALID_PARAM;
666 CAConvertNameToAddr(endpoint->addr, endpoint->port, &(dst.addr.st));
668 dst.size = CASizeOfAddrInfo(&dst);
670 ca_mutex_lock(g_dtlsContextMutex);
671 if(NULL == g_caDtlsContext)
673 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
674 ca_mutex_unlock(g_dtlsContextMutex);
675 return CA_STATUS_FAILED;
678 if(0 > dtls_connect(g_caDtlsContext->dtlsContext, (session_t*)(&dst)))
680 OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to connect");
681 ca_mutex_unlock(g_dtlsContextMutex);
682 return CA_STATUS_FAILED;
685 ca_mutex_unlock(g_dtlsContextMutex);
687 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsInitiateHandshake");
692 CAResult_t CADtlsClose(const CAEndpoint_t *endpoint)
694 stCADtlsAddrInfo_t dst = { 0 };
696 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsDisconnect");
700 return CA_STATUS_INVALID_PARAM;
703 CAConvertNameToAddr(endpoint->addr, endpoint->port, &(dst.addr.st));
705 dst.size = CASizeOfAddrInfo(&dst);
707 ca_mutex_lock(g_dtlsContextMutex);
708 if (NULL == g_caDtlsContext)
710 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
711 ca_mutex_unlock(g_dtlsContextMutex);
712 return CA_STATUS_FAILED;
715 if (0 > dtls_close(g_caDtlsContext->dtlsContext, (session_t*)(&dst)))
717 OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to close the session");
718 ca_mutex_unlock(g_dtlsContextMutex);
719 return CA_STATUS_FAILED;
722 ca_mutex_unlock(g_dtlsContextMutex);
724 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsDisconnect");
729 CAResult_t CADtlsGenerateOwnerPSK(const CAEndpoint_t *endpoint,
730 const uint8_t* label, const size_t labelLen,
731 const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
732 const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
733 uint8_t* ownerPSK, const size_t ownerPSKSize)
735 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsGenerateOwnerPSK");
737 if(!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPSKSize)
739 return CA_STATUS_INVALID_PARAM;
742 stCADtlsAddrInfo_t dst = { 0 };
744 CAConvertNameToAddr(endpoint->addr, endpoint->port, &(dst.addr.st));
746 dst.size = CASizeOfAddrInfo(&dst);
748 ca_mutex_lock(g_dtlsContextMutex);
749 if (NULL == g_caDtlsContext)
751 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
752 ca_mutex_unlock(g_dtlsContextMutex);
753 return CA_STATUS_FAILED;
756 if( 0 == dtls_prf_with_current_keyblock(g_caDtlsContext->dtlsContext, (session_t*)(&dst),
757 label, labelLen, rsrcServerDeviceID, rsrcServerDeviceIDLen,
758 provServerDeviceID, provServerDeviceIDLen, ownerPSK, ownerPSKSize))
760 OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to DTLS PRF");
761 ca_mutex_unlock(g_dtlsContextMutex);
762 return CA_STATUS_FAILED;
764 ca_mutex_unlock(g_dtlsContextMutex);
766 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsGenerateOwnerPSK");
771 CAResult_t CAAdapterNetDtlsInit()
773 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
775 // Initialize mutex for DtlsContext
776 if (NULL == g_dtlsContextMutex)
778 g_dtlsContextMutex = ca_mutex_new();
779 VERIFY_NON_NULL_RET(g_dtlsContextMutex, NET_DTLS_TAG, "malloc failed",
780 CA_MEMORY_ALLOC_FAILED);
784 OIC_LOG(ERROR, NET_DTLS_TAG, "CAAdapterNetDtlsInit done already!");
788 // Lock DtlsContext mutex and create DtlsContext
789 ca_mutex_lock(g_dtlsContextMutex);
790 g_caDtlsContext = (stCADtlsContext_t *)OICCalloc(1, sizeof(stCADtlsContext_t));
792 if (NULL == g_caDtlsContext)
794 OIC_LOG(ERROR, NET_DTLS_TAG, "Context malloc failed");
795 ca_mutex_unlock(g_dtlsContextMutex);
796 ca_mutex_free(g_dtlsContextMutex);
797 return CA_MEMORY_ALLOC_FAILED;
801 // Create PeerInfoList and CacheList
802 g_caDtlsContext->peerInfoList = u_arraylist_create();
803 g_caDtlsContext->cacheList = u_arraylist_create();
805 if( (NULL == g_caDtlsContext->peerInfoList) ||
806 (NULL == g_caDtlsContext->cacheList))
808 OIC_LOG(ERROR, NET_DTLS_TAG, "peerInfoList or cacheList initialization failed!");
810 CAFreePeerInfoList();
811 OICFree(g_caDtlsContext);
812 g_caDtlsContext = NULL;
813 ca_mutex_unlock(g_dtlsContextMutex);
814 ca_mutex_free(g_dtlsContextMutex);
815 return CA_STATUS_FAILED;
818 // Initialize clock, crypto and other global vars in tinyDTLS library
821 // Create tinydtls Context
822 g_caDtlsContext->dtlsContext = dtls_new_context(g_caDtlsContext);
824 if (NULL == g_caDtlsContext->dtlsContext)
826 OIC_LOG(ERROR, NET_DTLS_TAG, "dtls_new_context failed");
827 ca_mutex_unlock(g_dtlsContextMutex);
828 CAAdapterNetDtlsDeInit();
829 return CA_STATUS_FAILED;
832 g_caDtlsContext->callbacks.write = CASendSecureData;
833 g_caDtlsContext->callbacks.read = CAReadDecryptedPayload;
834 g_caDtlsContext->callbacks.event = CAHandleSecureEvent;
835 g_caDtlsContext->callbacks.get_psk_info = CAGetPskCredentials;
837 dtls_set_handler(g_caDtlsContext->dtlsContext, &(g_caDtlsContext->callbacks));
838 ca_mutex_unlock(g_dtlsContextMutex);
839 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
843 void CAAdapterNetDtlsDeInit()
845 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
847 VERIFY_NON_NULL_VOID(g_caDtlsContext, NET_DTLS_TAG, "context is NULL");
848 VERIFY_NON_NULL_VOID(g_dtlsContextMutex, NET_DTLS_TAG, "context mutex is NULL");
850 //Lock DtlsContext mutex
851 ca_mutex_lock(g_dtlsContextMutex);
854 CAFreePeerInfoList();
857 // De-initialize tinydtls context
858 dtls_free_context(g_caDtlsContext->dtlsContext);
859 g_caDtlsContext->dtlsContext = NULL;
861 // De-initialize DtlsContext
862 OICFree(g_caDtlsContext);
863 g_caDtlsContext = NULL;
865 // Unlock DtlsContext mutex and de-initialize it
866 ca_mutex_unlock(g_dtlsContextMutex);
867 ca_mutex_free(g_dtlsContextMutex);
868 g_dtlsContextMutex = NULL;
870 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
873 CAResult_t CAAdapterNetDtlsEncrypt(const CAEndpoint_t *endpoint,
874 void *data, uint32_t dataLen)
877 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
879 VERIFY_NON_NULL_RET(endpoint, NET_DTLS_TAG,"Param remoteAddress is NULL",
880 CA_STATUS_INVALID_PARAM);
881 VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL" ,
882 CA_STATUS_INVALID_PARAM);
886 OIC_LOG_V(ERROR, NET_DTLS_TAG, "dataLen is less than or equal zero [%d]", dataLen);
887 return CA_STATUS_FAILED;
890 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Data to be encrypted dataLen [%d]", dataLen);
892 stCADtlsAddrInfo_t addrInfo = { 0 };
894 CAConvertNameToAddr(endpoint->addr, endpoint->port, &(addrInfo.addr.st));
895 addrInfo.ifIndex = 0;
896 addrInfo.size = CASizeOfAddrInfo(&addrInfo);
898 ca_mutex_lock(g_dtlsContextMutex);
899 if(NULL == g_caDtlsContext)
901 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
902 ca_mutex_unlock(g_dtlsContextMutex);
903 return CA_STATUS_FAILED;
906 eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(&addrInfo, data, dataLen);
907 if (ret == DTLS_SESSION_INITIATED)
909 stCACacheMessage_t *message = (stCACacheMessage_t *)OICCalloc(1, sizeof(stCACacheMessage_t));
912 OIC_LOG(ERROR, NET_DTLS_TAG, "calloc failed!");
913 ca_mutex_unlock(g_dtlsContextMutex);
914 return CA_MEMORY_ALLOC_FAILED;
917 message->data = (uint8_t *)OICCalloc(dataLen + 1, sizeof(uint8_t));
918 if (NULL == message->data)
920 OIC_LOG(ERROR, NET_DTLS_TAG, "calloc failed!");
922 ca_mutex_unlock(g_dtlsContextMutex);
923 return CA_MEMORY_ALLOC_FAILED;
925 memcpy(message->data, data, dataLen);
926 message->dataLen = dataLen;
927 message->destSession = addrInfo;
929 CAResult_t result = CADtlsCacheMsg(message);
930 if (CA_STATUS_OK != result)
932 OIC_LOG(DEBUG, NET_DTLS_TAG, "CADtlsCacheMsg failed!");
933 CAFreeCacheMsg(message);
935 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "OUT Initiating Dtls session [%d]", result);
936 ca_mutex_unlock(g_dtlsContextMutex);
940 ca_mutex_unlock(g_dtlsContextMutex);
944 OIC_LOG(ERROR, NET_DTLS_TAG, "OUT FAILURE");
945 return CA_STATUS_FAILED;
948 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
952 CAResult_t CAAdapterNetDtlsDecrypt(const CASecureEndpoint_t *sep,
953 uint8_t *data, uint32_t dataLen)
955 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
956 VERIFY_NON_NULL_RET(sep, NET_DTLS_TAG, "endpoint is NULL" , CA_STATUS_INVALID_PARAM);
958 stCADtlsAddrInfo_t addrInfo = { 0 };
960 CAConvertNameToAddr(sep->endpoint.addr, sep->endpoint.port, &(addrInfo.addr.st));
961 addrInfo.ifIndex = 0;
962 addrInfo.size = CASizeOfAddrInfo(&addrInfo);
964 ca_mutex_lock(g_dtlsContextMutex);
965 if (NULL == g_caDtlsContext)
967 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
968 ca_mutex_unlock(g_dtlsContextMutex);
969 return CA_STATUS_FAILED;
972 eDtlsRet_t ret = CAAdapterNetDtlsDecryptInternal(&addrInfo, data, dataLen);
973 ca_mutex_unlock(g_dtlsContextMutex);
975 if (DTLS_OK == ret || DTLS_HS_MSG == ret)
977 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Successfully Decrypted or Handshake msg recvd [%d]", ret);
978 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
982 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
983 return CA_STATUS_FAILED;