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"
30 * @brief Logging tag for module name
32 #define NET_DTLS_TAG "NET_DTLS"
35 * @var g_caDtlsContext
36 * @brief global context which holds dtls context and cache list information.
38 static stCADtlsContext_t *g_caDtlsContext = NULL;
41 * @var g_dtlsContextMutex
42 * @brief Mutex to synchronize access to g_caDtlsContext.
44 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 stCADtlsPeerInfo_t * GetPeerInfo(const char *peerAddr, uint32_t port)
55 uint32_t list_index = 0;
56 uint32_t list_length = 0;
58 if(NULL == peerAddr || 0 == port)
60 OIC_LOG(ERROR, NET_DTLS_TAG, "CAPeerInfoListContains invalid parameters");
64 stCADtlsPeerInfo_t *peerInfo;
65 list_length = u_arraylist_length(g_caDtlsContext->peerInfoList);
66 for (list_index = 0; list_index < list_length; list_index++)
68 peerInfo = (stCADtlsPeerInfo_t *)u_arraylist_get(g_caDtlsContext->peerInfoList, list_index);
74 if((0 == strncmp(peerAddr, peerInfo->address.IP.ipAddress, CA_IPADDR_SIZE)) &&
75 (port == peerInfo->address.IP.port))
83 static CAResult_t CAAddIdToPeerInfoList(const char *peerAddr, uint32_t port,
84 const unsigned char * id,uint16_t id_length)
86 if(NULL == peerAddr || NULL == id || 0 == port || 0 == id_length)
88 OIC_LOG(ERROR, NET_DTLS_TAG, "CAAddIdToPeerInfoList invalid parameters");
89 return CA_STATUS_INVALID_PARAM;
92 if(NULL != GetPeerInfo(peerAddr, port))
94 OIC_LOG(ERROR, NET_DTLS_TAG, "CAAddIdToPeerInfoList peer already exist");
95 return CA_STATUS_FAILED;
98 stCADtlsPeerInfo_t *peerInfo = (stCADtlsPeerInfo_t *)
99 OICCalloc(1, sizeof(stCADtlsPeerInfo_t));
100 if (NULL == peerInfo)
102 OIC_LOG(ERROR, NET_DTLS_TAG, "peerInfo malloc failed!");
103 return CA_MEMORY_ALLOC_FAILED;
106 OICStrcpy(peerInfo->address.IP.ipAddress, sizeof(peerInfo->address.IP.ipAddress),
108 peerInfo->address.IP.port = port;
109 OICStrcpyPartial(peerInfo->identity.id, sizeof(peerInfo->identity.id), id, id_length);
110 peerInfo->identity.id_length = id_length;
112 CAResult_t result = u_arraylist_add(g_caDtlsContext->peerInfoList, (void *)peerInfo);
114 if (CA_STATUS_OK != result)
116 OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_add failed!");
124 static void CAFreePeerInfoList()
126 uint32_t list_length = u_arraylist_length(g_caDtlsContext->peerInfoList);
127 for (uint32_t list_index = 0; list_index < list_length; list_index++)
129 stCADtlsPeerInfo_t * peerInfo = (stCADtlsPeerInfo_t *)u_arraylist_get(
130 g_caDtlsContext->peerInfoList, list_index);
133 u_arraylist_free(&(g_caDtlsContext->peerInfoList));
134 g_caDtlsContext->peerInfoList = NULL;
137 static void CARemovePeerFromPeerInfoList(const char * addr, uint32_t port)
139 if(NULL == addr || 0 >= port)
141 OIC_LOG(ERROR, NET_DTLS_TAG, "CADTLSGetPeerPSKId invalid parameters");
145 uint32_t list_length = u_arraylist_length(g_caDtlsContext->peerInfoList);
146 for (uint32_t list_index = 0; list_index < list_length; list_index++)
148 stCADtlsPeerInfo_t * peerInfo = (stCADtlsPeerInfo_t *)u_arraylist_get(
149 g_caDtlsContext->peerInfoList,list_index);
150 if (NULL == peerInfo)
154 if((0 == strncmp(addr, peerInfo->address.IP.ipAddress, CA_IPADDR_SIZE)) &&
155 (port == peerInfo->address.IP.port))
157 OICFree(u_arraylist_remove(g_caDtlsContext->peerInfoList, list_index));
163 static eDtlsRet_t CAAdapterNetDtlsEncryptInternal(const stCADtlsAddrInfo_t *dstSession,
164 uint8_t *data, uint32_t dataLen)
166 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
168 VERIFY_NON_NULL_RET(dstSession, NET_DTLS_TAG, "Param dstSession is NULL" , DTLS_FAIL);
169 VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL" , DTLS_FAIL);
173 OIC_LOG(ERROR, NET_DTLS_TAG, "Given Packet length is equal to zero.");
177 if (NULL == g_caDtlsContext)
179 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
183 int retLen = dtls_write(g_caDtlsContext->dtlsContext, (session_t *)dstSession, data,
185 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "dtls_write retun len [%d]", retLen);
188 // A new DTLS session was initiated by tinyDTLS library and wait for callback.
189 return DTLS_SESSION_INITIATED;
191 else if (dataLen == retLen)
193 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
196 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
200 static eDtlsRet_t CAAdapterNetDtlsDecryptInternal(const stCADtlsAddrInfo_t *srcSession,
201 uint8_t *buf, uint32_t bufLen)
203 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
205 VERIFY_NON_NULL_RET(srcSession, NET_DTLS_TAG, "Param srcSession is NULL", DTLS_FAIL);
206 VERIFY_NON_NULL_RET(buf, NET_DTLS_TAG, "Param buf is NULL", DTLS_FAIL);
210 OIC_LOG(ERROR, NET_DTLS_TAG, "Given Packet length is equal to zero.");
214 eDtlsRet_t ret = DTLS_FAIL;
216 if (dtls_handle_message(g_caDtlsContext->dtlsContext, (session_t *)srcSession, buf, bufLen) == 0)
218 OIC_LOG(DEBUG, NET_DTLS_TAG, "dtls_handle_message success");
222 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
226 static void CAFreeCacheMsg(stCACacheMessage_t *msg)
228 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
229 VERIFY_NON_NULL_VOID(msg, NET_DTLS_TAG, "msg");
234 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
237 static void CAClearCacheList()
239 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
240 uint32_t list_index = 0;
241 uint32_t list_length = 0;
242 if (NULL == g_caDtlsContext)
244 OIC_LOG(ERROR, NET_DTLS_TAG, "Dtls Context is NULL");
247 list_length = u_arraylist_length(g_caDtlsContext->cacheList);
248 for (list_index = 0; list_index < list_length; list_index++)
250 stCACacheMessage_t *msg = (stCACacheMessage_t *)u_arraylist_get(g_caDtlsContext->cacheList,
257 u_arraylist_free(&g_caDtlsContext->cacheList);
258 g_caDtlsContext->cacheList = NULL;
259 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
262 static CAResult_t CADtlsCacheMsg(stCACacheMessage_t *msg)
264 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
266 if (NULL == g_caDtlsContext)
268 OIC_LOG(ERROR, NET_DTLS_TAG, "Dtls Context is NULL");
269 return CA_STATUS_FAILED;
272 CAResult_t result = u_arraylist_add(g_caDtlsContext->cacheList, (void *)msg);
273 if (CA_STATUS_OK != result)
275 OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_add failed!");
278 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
283 static bool CAIsAddressMatching(const stCADtlsAddrInfo_t *a, const stCADtlsAddrInfo_t *b)
285 return (a->size == b->size) &&
286 (a->addr.sa.sa_family == b->addr.sa.sa_family) &&
287 (a->addr.sin.sin_port == b->addr.sin.sin_port) &&
288 memcmp(&a->addr.sin.sin_addr, &b->addr.sin.sin_addr, sizeof(struct in_addr)) == 0;
291 static void CASendCachedMsg(const stCADtlsAddrInfo_t *dstSession)
293 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
294 VERIFY_NON_NULL_VOID(dstSession, NET_DTLS_TAG, "Param dstSession is NULL");
296 uint32_t list_index = 0;
297 uint32_t list_length = 0;
298 list_length = u_arraylist_length(g_caDtlsContext->cacheList);
299 for (list_index = 0; list_index < list_length;)
301 stCACacheMessage_t *msg = (stCACacheMessage_t *)u_arraylist_get(g_caDtlsContext->cacheList,
303 if ((NULL != msg) && (true == CAIsAddressMatching(&(msg->destSession), dstSession)))
305 eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(&(msg->destSession),
306 msg->data, msg->dataLen);
309 OIC_LOG(DEBUG, NET_DTLS_TAG, "CAAdapterNetDtlsEncryptInternal success");
313 OIC_LOG(ERROR, NET_DTLS_TAG, "CAAdapterNetDtlsEncryptInternal failed.");
316 if (u_arraylist_remove(g_caDtlsContext->cacheList, list_index))
319 // Reduce list length by 1 as we removed one element.
324 OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_remove failed.");
330 // Move to the next element
335 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
338 static int32_t CAReadDecryptedPayload(dtls_context_t *dtlsContext,
343 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
345 VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", 0);
346 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Decrypted buf len [%d]", bufLen);
348 stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
350 char *remoteAddress = inet_ntoa(addrInfo->addr.sin.sin_addr);
351 uint32_t port = ntohs(addrInfo->addr.sin.sin_port);
352 CATransportType_t type = (CATransportType_t)addrInfo->ifIndex;
354 if (NULL == g_caDtlsContext)
356 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
360 if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type) &&
361 (NULL != g_caDtlsContext->adapterCallbacks[type].recvCallback))
363 // Get identity of sthe source of packet
364 stCADtlsPeerInfo_t * peerInfo = GetPeerInfo(remoteAddress, port);
366 g_caDtlsContext->adapterCallbacks[type].recvCallback(remoteAddress, port,
368 (peerInfo) ? &(peerInfo->identity) : NULL);
372 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "recvCallback Callback or adapter type is wrong [%d]", type);
375 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
379 static int32_t CASendSecureData(dtls_context_t *dtlsContext,
384 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
386 VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", -1);
387 VERIFY_NON_NULL_RET(buf, NET_DTLS_TAG, "Param buf is NULL", -1);
391 OIC_LOG(ERROR, NET_DTLS_TAG, "Encrypted Buffer length is equal to zero");
395 stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
397 char *remoteAddress = inet_ntoa(addrInfo->addr.sin.sin_addr);
398 uint16_t port = ntohs(addrInfo->addr.sin.sin_port);
399 CATransportType_t type = (CATransportType_t)addrInfo->ifIndex;
401 //Mutex is not required for g_caDtlsContext. It will be called in same thread.
403 if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type) &&
404 (NULL != g_caDtlsContext->adapterCallbacks[type].sendCallback))
406 sentLen = g_caDtlsContext->adapterCallbacks[type].sendCallback(remoteAddress, port,
411 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "send Callback or adapter type is wrong [%d]", type );
414 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "sent buffer length [%d]", sentLen);
416 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
421 static int32_t CAHandleSecureEvent(dtls_context_t *dtlsContext,
423 dtls_alert_level_t level,
426 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
428 VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", 0);
430 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "level [%d] code [%u]", level, code);
432 if (!level && (code == DTLS_EVENT_CONNECTED))
434 OIC_LOG(DEBUG, NET_DTLS_TAG, "Received DTLS_EVENT_CONNECTED. Sending Cached data");
435 CASendCachedMsg((stCADtlsAddrInfo_t *)session);
438 if(DTLS_ALERT_LEVEL_FATAL == level && DTLS_ALERT_CLOSE_NOTIFY == code)
440 OIC_LOG(INFO, NET_DTLS_TAG, "Peer closing connection");
442 stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
443 char *peerAddr = inet_ntoa(addrInfo->addr.sin.sin_addr);
444 uint32_t port = ntohs(addrInfo->addr.sin.sin_port);
446 CARemovePeerFromPeerInfoList(peerAddr, port);
449 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
454 static int32_t CAGetPskCredentials(dtls_context_t *ctx,
455 const session_t *session,
456 dtls_credentials_type_t type,
457 const unsigned char *desc, size_t descLen,
458 unsigned char *result, size_t resultLen)
460 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
463 if(NULL == ctx || NULL == session || NULL == result)
465 OIC_LOG(ERROR, NET_DTLS_TAG, "CAGetPskCredentials invalid parameters");
469 VERIFY_NON_NULL_RET(g_getCredentialsCallback, NET_DTLS_TAG, "GetCredential callback", -1);
470 VERIFY_NON_NULL_RET(result, NET_DTLS_TAG, "result", -1);
472 CADtlsPskCredsBlob_t *credInfo = NULL;
474 // Retrieve the credentials blob from security module
475 g_getCredentialsCallback(&credInfo);
477 VERIFY_NON_NULL_RET(credInfo, NET_DTLS_TAG, "credInfo is NULL", -1);
478 if(NULL == credInfo->creds)
480 OIC_LOG(DEBUG, NET_DTLS_TAG, "credentials are NULL");
481 memset(credInfo, 0, sizeof(CADtlsPskCredsBlob_t));
486 if ((type == DTLS_PSK_HINT) || (type == DTLS_PSK_IDENTITY))
488 if (DTLS_PSK_ID_LEN <= resultLen)
490 memcpy(result, credInfo->identity, DTLS_PSK_ID_LEN);
491 ret = DTLS_PSK_ID_LEN;
495 if ((type == DTLS_PSK_KEY) && (desc) && (descLen == DTLS_PSK_PSK_LEN))
497 // Check if we have the credentials for the device with which we
498 // are trying to perform a handshake
500 for (index = 0; index < credInfo->num; index++)
502 if (memcmp(desc, credInfo->creds[index].id, DTLS_PSK_ID_LEN) == 0)
504 if(NULL != ctx->peers && DTLS_SERVER == ctx->peers->role )
506 // TODO SRM needs identity of the remote end-point with every data packet to
507 // perform access control management. tinyDTLS 'frees' the handshake parameters
508 // data structure when handshake completes. Therefore, currently this is a
509 // workaround to cache remote end-point identity when tinyDTLS asks for PSK.
510 stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
511 char *peerAddress = inet_ntoa(addrInfo->addr.sin.sin_addr);
512 uint32_t port = ntohs(addrInfo->addr.sin.sin_port);
514 CAResult_t result = CAAddIdToPeerInfoList(peerAddress, port, desc, descLen);
515 if(CA_STATUS_OK != result )
517 OIC_LOG(ERROR, NET_DTLS_TAG, "Fail to add peer id to gDtlsPeerInfoList");
520 memcpy(result, credInfo->creds[index].psk, DTLS_PSK_PSK_LEN);
521 ret = DTLS_PSK_PSK_LEN;
526 // Erase sensitive data before freeing.
527 memset(credInfo->creds, 0, sizeof(OCDtlsPskCreds) * (credInfo->num));
528 OICFree(credInfo->creds);
530 memset(credInfo, 0, sizeof(CADtlsPskCredsBlob_t));
537 void CADTLSSetAdapterCallbacks(CAPacketReceivedCallback recvCallback,
538 CAPacketSendCallback sendCallback, CATransportType_t type)
540 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
541 ca_mutex_lock(g_dtlsContextMutex);
542 if (NULL == g_caDtlsContext)
544 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
545 ca_mutex_unlock(g_dtlsContextMutex);
549 if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type))
551 g_caDtlsContext->adapterCallbacks[type].recvCallback = recvCallback;
552 g_caDtlsContext->adapterCallbacks[type].sendCallback = sendCallback;
555 ca_mutex_unlock(g_dtlsContextMutex);
557 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
560 void CADTLSSetCredentialsCallback(CAGetDTLSCredentialsHandler credCallback)
562 // TODO Does this method needs protection of DtlsContextMutex ?
563 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
564 g_getCredentialsCallback = credCallback;
565 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
568 CAResult_t CADtlsSelectCipherSuite(const dtls_cipher_t cipher)
570 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsSelectCipherSuite");
572 ca_mutex_lock(g_dtlsContextMutex);
573 if (NULL == g_caDtlsContext)
575 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
576 ca_mutex_unlock(g_dtlsContextMutex);
577 return CA_STATUS_FAILED;
579 dtls_select_cipher(g_caDtlsContext->dtlsContext, cipher);
580 ca_mutex_unlock(g_dtlsContextMutex);
582 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Selected cipher suite is 0x%02X%02X\n",
583 ((uint8_t*)(&cipher))[1], ((uint8_t*)(&cipher))[0]);
584 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsSelectCipherSuite");
586 return CA_STATUS_OK ;
589 CAResult_t CADtlsEnableAnonECDHCipherSuite(const bool enable)
591 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsEnablesAnonEcdh");
593 ca_mutex_lock(g_dtlsContextMutex);
594 if (NULL == g_caDtlsContext)
596 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
597 ca_mutex_unlock(g_dtlsContextMutex);
598 return CA_STATUS_FAILED;
600 dtls_enables_anon_ecdh(g_caDtlsContext->dtlsContext,
601 enable == true ? DTLS_CIPHER_ENABLE : DTLS_CIPHER_DISABLE);
602 ca_mutex_unlock(g_dtlsContextMutex);
603 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA is %s",
604 enable ? "enabled" : "disabled");
606 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsEnablesAnonEcdh");
608 return CA_STATUS_OK ;
611 CAResult_t CADtlsInitiateHandshake(const CAAddress_t* addrInfo,
612 const CATransportType_t transportType)
614 stCADtlsAddrInfo_t dst = {};
616 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsInitiateHandshake");
620 return CA_STATUS_INVALID_PARAM;
623 if(inet_aton(addrInfo->IP.ipAddress, &dst.addr.sin.sin_addr) == 0)
625 OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to convert from ASCII to Network Address");
626 return CA_STATUS_FAILED;
628 dst.addr.sin.sin_family = AF_INET;
629 dst.addr.sin.sin_port = htons(addrInfo->IP.port);
630 dst.size = sizeof(dst.addr);
632 dst.ifIndex = transportType;
634 ca_mutex_lock(g_dtlsContextMutex);
635 if(NULL == g_caDtlsContext)
637 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
638 ca_mutex_unlock(g_dtlsContextMutex);
639 return CA_STATUS_FAILED;
642 if(0 > dtls_connect(g_caDtlsContext->dtlsContext, (session_t*)(&dst)))
644 OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to connect");
645 ca_mutex_unlock(g_dtlsContextMutex);
646 return CA_STATUS_FAILED;
649 ca_mutex_unlock(g_dtlsContextMutex);
651 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsInitiateHandshake");
656 CAResult_t CADtlsClose(const CAAddress_t* addrInfo, const CATransportType_t transportType)
658 stCADtlsAddrInfo_t dst = {};
660 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsDisconnect");
664 return CA_STATUS_INVALID_PARAM;
667 if(inet_aton(addrInfo->IP.ipAddress, &dst.addr.sin.sin_addr) == 0)
669 OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to convert from ASCII to Network Address");
670 return CA_STATUS_FAILED;
672 dst.addr.sin.sin_family = AF_INET;
673 dst.addr.sin.sin_port = htons(addrInfo->IP.port);
674 dst.size = sizeof(dst.addr);
676 dst.ifIndex = transportType;
678 ca_mutex_lock(g_dtlsContextMutex);
679 if(NULL == g_caDtlsContext)
681 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
682 ca_mutex_unlock(g_dtlsContextMutex);
683 return CA_STATUS_FAILED;
686 if(0 > dtls_close(g_caDtlsContext->dtlsContext, (session_t*)(&dst)))
688 OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to close the session");
689 ca_mutex_unlock(g_dtlsContextMutex);
690 return CA_STATUS_FAILED;
693 ca_mutex_unlock(g_dtlsContextMutex);
695 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsDisconnect");
700 CAResult_t CADtlsGenerateOwnerPSK(const CAAddress_t* addrInfo,
701 const CATransportType_t transportType,
702 const uint8_t* label, const size_t labelLen,
703 const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
704 const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
705 uint8_t* ownerPSK, const size_t ownerPSKSize)
707 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsGenerateOwnerPSK");
709 if(!addrInfo || !label || 0 == labelLen || !ownerPSK || 0 == ownerPSKSize)
711 return CA_STATUS_INVALID_PARAM;
714 stCADtlsAddrInfo_t dst = {};
716 if(inet_aton(addrInfo->IP.ipAddress, &dst.addr.sin.sin_addr) == 0)
718 OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to convert from ASCII to Network Address");
719 return CA_STATUS_FAILED;
721 dst.addr.sin.sin_family = AF_INET;
722 dst.addr.sin.sin_port = htons(addrInfo->IP.port);
723 dst.size = sizeof(dst.addr);
725 dst.ifIndex = transportType;
727 ca_mutex_lock(g_dtlsContextMutex);
728 if (NULL == g_caDtlsContext)
730 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
731 ca_mutex_unlock(g_dtlsContextMutex);
732 return CA_STATUS_FAILED;
735 if( 0 == dtls_prf_with_current_keyblock(g_caDtlsContext->dtlsContext, (session_t*)(&dst),
736 label, labelLen, rsrcServerDeviceID, rsrcServerDeviceIDLen,
737 provServerDeviceID, provServerDeviceIDLen, ownerPSK, ownerPSKSize))
739 OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to DTLS PRF");
740 ca_mutex_unlock(g_dtlsContextMutex);
741 return CA_STATUS_FAILED;
743 ca_mutex_unlock(g_dtlsContextMutex);
745 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsGenerateOwnerPSK");
750 CAResult_t CAAdapterNetDtlsInit()
752 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
754 // Initialize mutex for DtlsContext
755 if (NULL == g_dtlsContextMutex)
757 g_dtlsContextMutex = ca_mutex_new();
758 VERIFY_NON_NULL_RET(g_dtlsContextMutex, NET_DTLS_TAG, "malloc failed",
759 CA_MEMORY_ALLOC_FAILED);
763 OIC_LOG(ERROR, NET_DTLS_TAG, "CAAdapterNetDtlsInit done already!");
767 // Lock DtlsContext mutex and create DtlsContext
768 ca_mutex_lock(g_dtlsContextMutex);
769 g_caDtlsContext = (stCADtlsContext_t *)OICCalloc(1, sizeof(stCADtlsContext_t));
771 if (NULL == g_caDtlsContext)
773 OIC_LOG(ERROR, NET_DTLS_TAG, "Context malloc failed");
774 ca_mutex_unlock(g_dtlsContextMutex);
775 ca_mutex_free(g_dtlsContextMutex);
776 return CA_MEMORY_ALLOC_FAILED;
780 // Create PeerInfoList and CacheList
781 g_caDtlsContext->peerInfoList = u_arraylist_create();
782 g_caDtlsContext->cacheList = u_arraylist_create();
784 if( (NULL == g_caDtlsContext->peerInfoList) ||
785 (NULL == g_caDtlsContext->cacheList))
787 OIC_LOG(ERROR, NET_DTLS_TAG, "peerInfoList or cacheList initialization failed!");
789 CAFreePeerInfoList();
790 OICFree(g_caDtlsContext);
791 g_caDtlsContext = NULL;
792 ca_mutex_unlock(g_dtlsContextMutex);
793 ca_mutex_free(g_dtlsContextMutex);
794 return CA_STATUS_FAILED;
797 // Initialize clock, crypto and other global vars in tinyDTLS library
800 // Create tinydtls Context
801 g_caDtlsContext->dtlsContext = dtls_new_context(g_caDtlsContext);
803 if (NULL == g_caDtlsContext->dtlsContext)
805 OIC_LOG(ERROR, NET_DTLS_TAG, "dtls_new_context failed");
806 ca_mutex_unlock(g_dtlsContextMutex);
807 CAAdapterNetDtlsDeInit();
808 return CA_STATUS_FAILED;
811 g_caDtlsContext->callbacks.write = CASendSecureData;
812 g_caDtlsContext->callbacks.read = CAReadDecryptedPayload;
813 g_caDtlsContext->callbacks.event = CAHandleSecureEvent;
814 g_caDtlsContext->callbacks.get_psk_info = CAGetPskCredentials;
816 dtls_set_handler(g_caDtlsContext->dtlsContext, &(g_caDtlsContext->callbacks));
817 ca_mutex_unlock(g_dtlsContextMutex);
818 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
822 void CAAdapterNetDtlsDeInit()
824 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
826 VERIFY_NON_NULL_VOID(g_caDtlsContext, NET_DTLS_TAG, "context is NULL");
827 VERIFY_NON_NULL_VOID(g_dtlsContextMutex, NET_DTLS_TAG, "context mutex is NULL");
829 //Lock DtlsContext mutex
830 ca_mutex_lock(g_dtlsContextMutex);
833 CAFreePeerInfoList();
836 // De-initialize tinydtls context
837 dtls_free_context(g_caDtlsContext->dtlsContext);
838 g_caDtlsContext->dtlsContext = NULL;
840 // De-initialize DtlsContext
841 OICFree(g_caDtlsContext);
842 g_caDtlsContext = NULL;
844 // Unlock DtlsContext mutex and de-initialize it
845 ca_mutex_unlock(g_dtlsContextMutex);
846 ca_mutex_free(g_dtlsContextMutex);
847 g_dtlsContextMutex = NULL;
849 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
852 CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress,
856 CATransportType_t transportType)
859 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
861 VERIFY_NON_NULL_RET(remoteAddress, NET_DTLS_TAG,"Param remoteAddress is NULL",CA_STATUS_FAILED);
863 VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL" , CA_STATUS_FAILED);
867 OIC_LOG_V(ERROR, NET_DTLS_TAG, "dataLen is less than or equal zero [%d]", dataLen);
868 return CA_STATUS_FAILED;
871 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Data to be encrypted dataLen [%d]", dataLen);
873 stCADtlsAddrInfo_t addrInfo = {};
875 addrInfo.addr.sin.sin_family = AF_INET;
876 addrInfo.addr.sin.sin_port = htons(port);
877 // Conversion from ASCII format to Network format
878 if (inet_aton(remoteAddress, &addrInfo.addr.sin.sin_addr) == 0)
880 OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to convert from ASCII to Network Address");
881 return CA_STATUS_FAILED;
883 addrInfo.size = sizeof(addrInfo.addr);
884 addrInfo.ifIndex = transportType;
886 ca_mutex_lock(g_dtlsContextMutex);
887 if(NULL == g_caDtlsContext)
889 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
890 ca_mutex_unlock(g_dtlsContextMutex);
891 return CA_STATUS_FAILED;
894 eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(&addrInfo, data, dataLen);
895 if (ret == DTLS_SESSION_INITIATED)
897 stCACacheMessage_t *message = (stCACacheMessage_t *)OICCalloc(1, sizeof(stCACacheMessage_t));
900 OIC_LOG(ERROR, NET_DTLS_TAG, "calloc failed!");
901 ca_mutex_unlock(g_dtlsContextMutex);
902 return CA_MEMORY_ALLOC_FAILED;
905 message->data = (uint8_t *)OICCalloc(dataLen + 1, sizeof(uint8_t));
906 if (NULL == message->data)
908 OIC_LOG(ERROR, NET_DTLS_TAG, "calloc failed!");
910 ca_mutex_unlock(g_dtlsContextMutex);
911 return CA_MEMORY_ALLOC_FAILED;
913 memcpy(message->data, data, dataLen);
914 message->dataLen = dataLen;
915 message->destSession = addrInfo;
917 CAResult_t result = CADtlsCacheMsg(message);
918 if (CA_STATUS_OK != result)
920 OIC_LOG(DEBUG, NET_DTLS_TAG, "CADtlsCacheMsg failed!");
921 CAFreeCacheMsg(message);
923 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "OUT Initiating Dtls session [%d]", result);
924 ca_mutex_unlock(g_dtlsContextMutex);
928 ca_mutex_unlock(g_dtlsContextMutex);
932 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
936 OIC_LOG(ERROR, NET_DTLS_TAG, "OUT FAILURE");
937 return CA_STATUS_FAILED;
941 CAResult_t CAAdapterNetDtlsDecrypt(const char *remoteAddress,
945 CATransportType_t transportType)
947 OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
949 stCADtlsAddrInfo_t addrInfo = {};
951 addrInfo.addr.sin.sin_family = AF_INET;
952 addrInfo.addr.sin.sin_port = htons(port);
954 // Conversion from ASCII format to Network format
955 if (inet_aton(remoteAddress, &addrInfo.addr.sin.sin_addr) == 0)
957 OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to convert from ASCII to Network Address");
958 return CA_STATUS_FAILED;
960 addrInfo.size = sizeof(addrInfo.addr);
961 addrInfo.ifIndex = transportType;
963 ca_mutex_lock(g_dtlsContextMutex);
964 if(NULL == g_caDtlsContext)
966 OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
967 ca_mutex_unlock(g_dtlsContextMutex);
968 return CA_STATUS_FAILED;
971 eDtlsRet_t ret = CAAdapterNetDtlsDecryptInternal(&addrInfo, data, dataLen);
972 ca_mutex_unlock(g_dtlsContextMutex);
974 if (DTLS_OK == ret || DTLS_HS_MSG == ret)
976 OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Successfully Decrypted or Handshake msg recvd [%d]", ret);
977 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
981 OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
982 return CA_STATUS_FAILED;