bc2dbd0bcee7cf9f6171ff6b290db696806d21cb
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / adapter_util / caadapternetdtls.c
1 /******************************************************************
2  *
3  * Copyright 2014 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  ******************************************************************/
20 #include "caadapternetdtls.h"
21 #include "cacommon.h"
22 #include "caipinterface.h"
23 #include "dtls.h"
24 #include "oic_malloc.h"
25 #include "oic_string.h"
26 #include "global.h"
27 #include <netdb.h>
28
29 #ifdef __WITH_X509__
30 #include "pki.h"
31 #include "cainterface.h"
32 #include "credresource.h"
33 #undef VERIFY_SUCCESS
34 #define VERIFY_SUCCESS(op, successCode) { if ((op) != (successCode)) \
35             {OIC_LOG_V(FATAL, NET_DTLS_TAG, "%s failed!!", #op); goto exit;} }
36 #endif
37
38 /**
39  * @def NET_DTLS_TAG
40  * @brief Logging tag for module name
41  */
42 #define NET_DTLS_TAG "NET_DTLS"
43
44 /**
45  * @var g_caDtlsContext
46  * @brief global context which holds dtls context and cache list information.
47  */
48 static stCADtlsContext_t *g_caDtlsContext = NULL;
49
50 /**
51  * @var g_dtlsContextMutex
52  * @brief Mutex to synchronize access to g_caDtlsContext.
53  */
54 static ca_mutex g_dtlsContextMutex = NULL;
55
56 /**
57  * @var g_getCredentialsCallback
58  * @brief callback to get DTLS credentials
59  */
60 static CAGetDTLSCredentialsHandler g_getCredentialsCallback = NULL;
61
62 static CASecureEndpoint_t *GetPeerInfo(const CAEndpoint_t *peer)
63 {
64     uint32_t list_index = 0;
65     uint32_t list_length = 0;
66
67     if(NULL == peer)
68     {
69         OIC_LOG(ERROR, NET_DTLS_TAG, "CAPeerInfoListContains invalid parameters");
70         return NULL;
71     }
72
73     CASecureEndpoint_t *peerInfo = NULL;
74     list_length = u_arraylist_length(g_caDtlsContext->peerInfoList);
75     for (list_index = 0; list_index < list_length; list_index++)
76     {
77         peerInfo = (CASecureEndpoint_t *)u_arraylist_get(g_caDtlsContext->peerInfoList, list_index);
78         if (NULL == peerInfo)
79         {
80             continue;
81         }
82
83         if((0 == strncmp(peer->addr, peerInfo->endpoint.addr, MAX_ADDR_STR_SIZE_CA)) &&
84                 (peer->port == peerInfo->endpoint.port))
85         {
86             return peerInfo;
87         }
88     }
89     return NULL;
90 }
91
92 static CAResult_t CAAddIdToPeerInfoList(const char *peerAddr, uint32_t port,
93         const unsigned char *id, uint16_t id_length)
94 {
95     if(NULL == peerAddr
96        || NULL == id
97        || 0 == port
98        || 0 == id_length
99        || CA_MAX_ENDPOINT_IDENTITY_LEN < id_length)
100     {
101         OIC_LOG(ERROR, NET_DTLS_TAG, "CAAddIdToPeerInfoList invalid parameters");
102         return CA_STATUS_INVALID_PARAM;
103     }
104
105     CASecureEndpoint_t *peer = (CASecureEndpoint_t *)OICCalloc(1, sizeof (CASecureEndpoint_t));
106     if (NULL == peer)
107     {
108         OIC_LOG(ERROR, NET_DTLS_TAG, "peerInfo malloc failed!");
109         return CA_MEMORY_ALLOC_FAILED;
110     }
111
112     OICStrcpy(peer->endpoint.addr, sizeof(peer->endpoint.addr), peerAddr);
113     peer->endpoint.port = port;
114
115     memcpy(peer->identity.id, id, id_length);
116     peer->identity.id_length = id_length;
117
118     if (NULL != GetPeerInfo(&peer->endpoint))
119     {
120         OIC_LOG(ERROR, NET_DTLS_TAG, "CAAddIdToPeerInfoList peer already exist");
121         OICFree(peer);
122         return CA_STATUS_FAILED;
123     }
124
125     bool result = u_arraylist_add(g_caDtlsContext->peerInfoList, (void *)peer);
126     if (!result)
127     {
128         OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_add failed!");
129         OICFree(peer);
130         return CA_STATUS_FAILED;
131     }
132
133     return CA_STATUS_OK;
134 }
135
136 static void CAFreePeerInfoList()
137 {
138     uint32_t list_length = u_arraylist_length(g_caDtlsContext->peerInfoList);
139     for (uint32_t list_index = 0; list_index < list_length; list_index++)
140     {
141         CAEndpoint_t *peerInfo = (CAEndpoint_t *)u_arraylist_get(
142                                      g_caDtlsContext->peerInfoList, list_index);
143         OICFree(peerInfo);
144     }
145     u_arraylist_free(&(g_caDtlsContext->peerInfoList));
146     g_caDtlsContext->peerInfoList = NULL;
147 }
148
149 static void CARemovePeerFromPeerInfoList(const char * addr, uint16_t port)
150 {
151     if (NULL == addr || 0 >= port)
152     {
153         OIC_LOG(ERROR, NET_DTLS_TAG, "CADTLSGetPeerPSKId invalid parameters");
154         return;
155     }
156
157     uint32_t list_length = u_arraylist_length(g_caDtlsContext->peerInfoList);
158     for (uint32_t list_index = 0; list_index < list_length; list_index++)
159     {
160         CAEndpoint_t *peerInfo = (CAEndpoint_t *)u_arraylist_get(
161                                 g_caDtlsContext->peerInfoList,list_index);
162         if (NULL == peerInfo)
163         {
164             continue;
165         }
166         if((0 == strncmp(addr, peerInfo->addr, MAX_ADDR_STR_SIZE_CA)) &&
167                 (port == peerInfo->port))
168         {
169             OICFree(u_arraylist_remove(g_caDtlsContext->peerInfoList, list_index));
170             return;
171         }
172     }
173 }
174
175 static int CASizeOfAddrInfo(stCADtlsAddrInfo_t *addrInfo)
176 {
177     VERIFY_NON_NULL_RET(addrInfo, NET_DTLS_TAG, "addrInfo is NULL" , DTLS_FAIL);
178
179     switch (addrInfo->addr.st.ss_family)
180     {
181     case AF_INET:
182         {
183             return sizeof (struct sockaddr_in);
184         }
185     case AF_INET6:
186         {
187             return sizeof (struct sockaddr_in6);
188         }
189     default:
190         {
191             break;
192         }
193     }
194     return sizeof (struct sockaddr_storage);
195 }
196
197 static eDtlsRet_t CAAdapterNetDtlsEncryptInternal(const stCADtlsAddrInfo_t *dstSession,
198         uint8_t *data, uint32_t dataLen)
199 {
200     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
201
202     VERIFY_NON_NULL_RET(dstSession, NET_DTLS_TAG, "Param dstSession is NULL" , DTLS_FAIL);
203     VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL" , DTLS_FAIL);
204
205     if (0 == dataLen)
206     {
207         OIC_LOG(ERROR, NET_DTLS_TAG, "Given Packet length is equal to zero.");
208         return DTLS_FAIL;
209     }
210
211     if (NULL == g_caDtlsContext)
212     {
213         OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
214         return DTLS_FAIL;
215     }
216
217     int retLen = dtls_write(g_caDtlsContext->dtlsContext, (session_t *)dstSession, data,
218                                 dataLen);
219     OIC_LOG_V(DEBUG, NET_DTLS_TAG, "dtls_write retun len [%d]", retLen);
220     if (retLen < 0)
221     {
222         OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
223         return DTLS_FAIL;
224     }
225     if (0 == retLen)
226     {
227         // A new DTLS session was initiated by tinyDTLS library and wait for callback.
228         return DTLS_SESSION_INITIATED;
229     }
230     else if (dataLen != (uint32_t)retLen)
231     {
232         OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
233         return DTLS_FAIL;
234     }
235     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
236     return DTLS_OK;
237 }
238
239 static eDtlsRet_t CAAdapterNetDtlsDecryptInternal(const stCADtlsAddrInfo_t *srcSession,
240         uint8_t *buf, uint32_t bufLen)
241 {
242     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
243
244     VERIFY_NON_NULL_RET(srcSession, NET_DTLS_TAG, "Param srcSession is NULL", DTLS_FAIL);
245     VERIFY_NON_NULL_RET(buf, NET_DTLS_TAG, "Param buf is NULL", DTLS_FAIL);
246
247     if (0 == bufLen)
248     {
249         OIC_LOG(ERROR, NET_DTLS_TAG, "Given Packet length is equal to zero.");
250         return DTLS_FAIL;
251     }
252
253     eDtlsRet_t ret = DTLS_FAIL;
254
255     if (dtls_handle_message(g_caDtlsContext->dtlsContext, (session_t *)srcSession, buf, bufLen) == 0)
256     {
257         OIC_LOG(DEBUG, NET_DTLS_TAG, "dtls_handle_message success");
258         ret = DTLS_OK;
259     }
260
261     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
262     return ret;
263 }
264
265 static void CAFreeCacheMsg(stCACacheMessage_t *msg)
266 {
267     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
268     VERIFY_NON_NULL_VOID(msg, NET_DTLS_TAG, "msg");
269
270     OICFree(msg->data);
271     OICFree(msg);
272
273     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
274 }
275
276 static void CAClearCacheList()
277 {
278     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
279     uint32_t list_index = 0;
280     uint32_t list_length = 0;
281     if (NULL == g_caDtlsContext)
282     {
283         OIC_LOG(ERROR, NET_DTLS_TAG, "Dtls Context is NULL");
284         return;
285     }
286     list_length = u_arraylist_length(g_caDtlsContext->cacheList);
287     for (list_index = 0; list_index < list_length; list_index++)
288     {
289         stCACacheMessage_t *msg = (stCACacheMessage_t *)u_arraylist_get(g_caDtlsContext->cacheList,
290                                   list_index);
291         if (msg != NULL)
292         {
293             CAFreeCacheMsg(msg);
294         }
295     }
296     u_arraylist_free(&g_caDtlsContext->cacheList);
297     g_caDtlsContext->cacheList = NULL;
298     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
299 }
300
301 static CAResult_t CADtlsCacheMsg(stCACacheMessage_t *msg)
302 {
303     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
304
305     if (NULL == g_caDtlsContext)
306     {
307         OIC_LOG(ERROR, NET_DTLS_TAG, "Dtls Context is NULL");
308         return CA_STATUS_FAILED;
309     }
310
311     bool result = u_arraylist_add(g_caDtlsContext->cacheList, (void *)msg);
312     if (!result)
313     {
314         OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_add failed!");
315         return CA_STATUS_FAILED;
316     }
317
318     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
319     return CA_STATUS_OK;
320 }
321
322
323 static bool CAIsAddressMatching(const stCADtlsAddrInfo_t *a,  const stCADtlsAddrInfo_t *b)
324 {
325     if (a->size != b->size)
326     {
327         return false;
328     }
329     if (memcmp(&a->addr, &b->addr, a->size))
330     {
331         return false;
332     }
333     return true;
334 }
335
336 static void CASendCachedMsg(const stCADtlsAddrInfo_t *dstSession)
337 {
338     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
339     VERIFY_NON_NULL_VOID(dstSession, NET_DTLS_TAG, "Param dstSession is NULL");
340
341     uint32_t list_index = 0;
342     uint32_t list_length = 0;
343     list_length = u_arraylist_length(g_caDtlsContext->cacheList);
344     for (list_index = 0; list_index < list_length;)
345     {
346         stCACacheMessage_t *msg = (stCACacheMessage_t *)u_arraylist_get(g_caDtlsContext->cacheList,
347                                   list_index);
348         if ((NULL != msg) && (true == CAIsAddressMatching(&(msg->destSession), dstSession)))
349         {
350             eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(&(msg->destSession),
351                              msg->data, msg->dataLen);
352             if (ret == DTLS_OK)
353             {
354                 OIC_LOG(DEBUG, NET_DTLS_TAG, "CAAdapterNetDtlsEncryptInternal success");
355             }
356             else
357             {
358                 OIC_LOG(ERROR, NET_DTLS_TAG, "CAAdapterNetDtlsEncryptInternal failed.");
359             }
360
361             if (u_arraylist_remove(g_caDtlsContext->cacheList, list_index))
362             {
363                 CAFreeCacheMsg(msg);
364                 // Reduce list length by 1 as we removed one element.
365                 list_length--;
366             }
367             else
368             {
369                 OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_remove failed.");
370                 break;
371             }
372         }
373         else
374         {
375             // Move to the next element
376             ++list_index;
377         }
378     }
379
380     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
381 }
382
383 static int32_t CAReadDecryptedPayload(dtls_context_t *context,
384                                       session_t *session,
385                                       uint8_t *buf,
386                                       size_t bufLen )
387 {
388     (void)context;
389     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
390
391     VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", 0);
392     OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Decrypted buf len [%d]", bufLen);
393
394     stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
395
396     CASecureEndpoint_t sep =
397     { .endpoint =
398     { .adapter = CA_ADAPTER_IP, .flags =
399             ((addrInfo->addr.st.ss_family == AF_INET) ? CA_IPV4 : CA_IPV6) | CA_SECURE, .port = 0 },
400             .identity =
401             { 0 } };
402     CAConvertAddrToName(&(addrInfo->addr.st), sep.endpoint.addr, &sep.endpoint.port);
403
404     if (NULL == g_caDtlsContext)
405     {
406         OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
407         return 0;
408     }
409
410     int type = 0;
411     if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type) &&
412         (NULL != g_caDtlsContext->adapterCallbacks[type].recvCallback))
413     {
414         // Get identity of the source of packet
415         CASecureEndpoint_t *peerInfo = GetPeerInfo(&sep.endpoint);
416         if (peerInfo)
417         {
418             sep.identity = peerInfo->identity;
419         }
420
421         g_caDtlsContext->adapterCallbacks[type].recvCallback(&sep, buf, bufLen);
422     }
423     else
424     {
425         OIC_LOG_V(DEBUG, NET_DTLS_TAG, "recvCallback Callback or adapter type is wrong [%d]", type);
426     }
427
428     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
429     return 0;
430 }
431
432 static int32_t CASendSecureData(dtls_context_t *context,
433                                 session_t *session,
434                                 uint8_t *buf,
435                                 size_t bufLen)
436 {
437     (void)context;
438     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
439
440     VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", -1);
441     VERIFY_NON_NULL_RET(buf, NET_DTLS_TAG, "Param buf is NULL", -1);
442
443     if (0 == bufLen)
444     {
445         OIC_LOG(ERROR, NET_DTLS_TAG, "Encrypted Buffer length is equal to zero");
446         return 0;
447     }
448
449     stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
450
451     CAEndpoint_t endpoint = {.adapter = CA_DEFAULT_ADAPTER};
452
453     CAConvertAddrToName(&(addrInfo->addr.st), endpoint.addr, &endpoint.port);
454     endpoint.flags = addrInfo->addr.st.ss_family == AF_INET ? CA_IPV4 : CA_IPV6;
455     endpoint.flags |= CA_SECURE;
456     endpoint.adapter = CA_ADAPTER_IP;
457     endpoint.interface = session->ifindex;
458     int type = 0;
459
460     //Mutex is not required for g_caDtlsContext. It will be called in same thread.
461     if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type) &&
462         (NULL != g_caDtlsContext->adapterCallbacks[type].sendCallback))
463     {
464         g_caDtlsContext->adapterCallbacks[type].sendCallback(&endpoint, buf, bufLen);
465     }
466     else
467     {
468         OIC_LOG_V(DEBUG, NET_DTLS_TAG, "send Callback or adapter type is wrong [%d]", type );
469     }
470
471     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
472     return bufLen;
473 }
474
475 static int32_t CAHandleSecureEvent(dtls_context_t *context,
476                                    session_t *session,
477                                    dtls_alert_level_t level,
478                                    unsigned short code)
479 {
480     (void)context;
481     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
482
483     VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", 0);
484
485     OIC_LOG_V(DEBUG, NET_DTLS_TAG, "level [%d] code [%u]", level, code);
486
487     if (!level && (code == DTLS_EVENT_CONNECTED))
488     {
489         OIC_LOG(DEBUG, NET_DTLS_TAG, "Received DTLS_EVENT_CONNECTED. Sending Cached data");
490         CASendCachedMsg((stCADtlsAddrInfo_t *)session);
491     }
492
493     if(DTLS_ALERT_LEVEL_FATAL == level && DTLS_ALERT_CLOSE_NOTIFY == code)
494     {
495         OIC_LOG(INFO, NET_DTLS_TAG, "Peer closing connection");
496
497         stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
498         char peerAddr[MAX_ADDR_STR_SIZE_CA] = { 0 };
499         uint16_t port = 0;
500         CAConvertAddrToName(&(addrInfo->addr.st), peerAddr, &port);
501         CARemovePeerFromPeerInfoList(peerAddr, port);
502     }
503
504     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
505     return 0;
506 }
507
508
509 static int32_t CAGetPskCredentials(dtls_context_t *ctx,
510                                    const session_t *session,
511                                    dtls_credentials_type_t type,
512                                    const unsigned char *desc, size_t descLen,
513                                    unsigned char *result, size_t resultLen)
514 {
515     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
516
517     int32_t ret  = -1;
518     if(NULL == ctx || NULL == session || NULL == result)
519     {
520         OIC_LOG(ERROR, NET_DTLS_TAG, "CAGetPskCredentials invalid parameters");
521         return ret;
522     }
523
524     VERIFY_NON_NULL_RET(g_getCredentialsCallback, NET_DTLS_TAG, "GetCredential callback", -1);
525     VERIFY_NON_NULL_RET(result, NET_DTLS_TAG, "result", -1);
526
527     CADtlsPskCredsBlob_t *credInfo = NULL;
528
529     // Retrieve the credentials blob from security module
530     g_getCredentialsCallback(&credInfo);
531
532     VERIFY_NON_NULL_RET(credInfo, NET_DTLS_TAG, "credInfo is NULL", -1);
533     if(NULL == credInfo->creds)
534     {
535         OIC_LOG(DEBUG, NET_DTLS_TAG, "credentials are NULL");
536         memset(credInfo, 0, sizeof(CADtlsPskCredsBlob_t));
537         OICFree(credInfo);
538         return -1;
539     }
540
541     if ((type == DTLS_PSK_HINT) || (type == DTLS_PSK_IDENTITY))
542     {
543         if (DTLS_PSK_ID_LEN <= resultLen)
544         {
545             memcpy(result, credInfo->identity, DTLS_PSK_ID_LEN);
546             ret = DTLS_PSK_ID_LEN;
547         }
548     }
549
550     if ((type == DTLS_PSK_KEY) && (desc) && (descLen == DTLS_PSK_PSK_LEN))
551     {
552         // Check if we have the credentials for the device with which we
553         // are trying to perform a handshake
554         for (uint32_t index = 0; index < credInfo->num; index++)
555         {
556             if (memcmp(desc, credInfo->creds[index].id, DTLS_PSK_ID_LEN) == 0)
557             {
558                 if(NULL != ctx->peers && DTLS_SERVER == ctx->peers->role )
559                 {
560                     // TODO SRM needs identity of the remote end-point with every data packet to
561                     // perform access control management. tinyDTLS 'frees' the handshake parameters
562                     // data structure when handshake completes. Therefore, currently this is a
563                     // workaround to cache remote end-point identity when tinyDTLS asks for PSK.
564                     stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
565                     char peerAddr[MAX_ADDR_STR_SIZE_CA] = { 0 };
566                     uint16_t port = 0;
567                     CAConvertAddrToName(&(addrInfo->addr.st), peerAddr, &port);
568
569                     CAResult_t result = CAAddIdToPeerInfoList(peerAddr, port, desc, descLen);
570                     if(CA_STATUS_OK != result )
571                     {
572                         OIC_LOG(ERROR, NET_DTLS_TAG, "Fail to add peer id to gDtlsPeerInfoList");
573                     }
574                 }
575                 memcpy(result, credInfo->creds[index].psk, DTLS_PSK_PSK_LEN);
576                 ret = DTLS_PSK_PSK_LEN;
577             }
578         }
579     }
580
581     // Erase sensitive data before freeing.
582     memset(credInfo->creds, 0, sizeof(OCDtlsPskCreds) * (credInfo->num));
583     OICFree(credInfo->creds);
584
585     memset(credInfo, 0, sizeof(CADtlsPskCredsBlob_t));
586     OICFree(credInfo);
587     credInfo = NULL;
588
589     return ret;
590 }
591
592 void CADTLSSetAdapterCallbacks(CAPacketReceivedCallback recvCallback,
593                                CAPacketSendCallback sendCallback,
594                                CATransportAdapter_t type)
595 {
596     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
597     ca_mutex_lock(g_dtlsContextMutex);
598     if (NULL == g_caDtlsContext)
599     {
600         OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
601         ca_mutex_unlock(g_dtlsContextMutex);
602         return;
603     }
604
605     if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type))
606     {
607         // TODO: change the zeros to better values.
608         g_caDtlsContext->adapterCallbacks[0].recvCallback = recvCallback;
609         g_caDtlsContext->adapterCallbacks[0].sendCallback = sendCallback;
610     }
611
612     ca_mutex_unlock(g_dtlsContextMutex);
613
614     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
615 }
616
617 void CADTLSSetCredentialsCallback(CAGetDTLSCredentialsHandler credCallback)
618 {
619     // TODO Does this method needs protection of DtlsContextMutex ?
620     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
621     g_getCredentialsCallback = credCallback;
622     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
623 }
624
625 CAResult_t CADtlsSelectCipherSuite(const dtls_cipher_t cipher)
626 {
627     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsSelectCipherSuite");
628
629     ca_mutex_lock(g_dtlsContextMutex);
630     if (NULL == g_caDtlsContext)
631     {
632         OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
633         ca_mutex_unlock(g_dtlsContextMutex);
634         return CA_STATUS_FAILED;
635     }
636     dtls_select_cipher(g_caDtlsContext->dtlsContext, cipher);
637     ca_mutex_unlock(g_dtlsContextMutex);
638
639     OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Selected cipher suite is 0x%02X%02X\n",
640         ((uint8_t*)(&cipher))[1], ((uint8_t*)(&cipher))[0]);
641     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsSelectCipherSuite");
642
643     return CA_STATUS_OK ;
644 }
645
646 CAResult_t CADtlsEnableAnonECDHCipherSuite(const bool enable)
647 {
648     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsEnablesAnonEcdh");
649
650     ca_mutex_lock(g_dtlsContextMutex);
651     if (NULL == g_caDtlsContext)
652     {
653         OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
654         ca_mutex_unlock(g_dtlsContextMutex);
655         return CA_STATUS_FAILED;
656     }
657     dtls_enables_anon_ecdh(g_caDtlsContext->dtlsContext,
658         enable == true ? DTLS_CIPHER_ENABLE : DTLS_CIPHER_DISABLE);
659     ca_mutex_unlock(g_dtlsContextMutex);
660     OIC_LOG_V(DEBUG, NET_DTLS_TAG, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256  is %s",
661         enable ? "enabled" : "disabled");
662
663     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsEnablesAnonEcdh");
664
665     return CA_STATUS_OK ;
666 }
667
668 CAResult_t CADtlsInitiateHandshake(const CAEndpoint_t *endpoint)
669 {
670     stCADtlsAddrInfo_t dst = { 0 };
671
672     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsInitiateHandshake");
673
674     if(!endpoint)
675     {
676         return CA_STATUS_INVALID_PARAM;
677     }
678
679     CAConvertNameToAddr(endpoint->addr, endpoint->port, &(dst.addr.st));
680     dst.ifIndex = 0;
681     dst.size = CASizeOfAddrInfo(&dst);
682
683     ca_mutex_lock(g_dtlsContextMutex);
684     if(NULL == g_caDtlsContext)
685     {
686         OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
687         ca_mutex_unlock(g_dtlsContextMutex);
688         return CA_STATUS_FAILED;
689     }
690
691     if(0 > dtls_connect(g_caDtlsContext->dtlsContext, (session_t*)(&dst)))
692     {
693         OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to connect");
694         ca_mutex_unlock(g_dtlsContextMutex);
695         return CA_STATUS_FAILED;
696     }
697
698     ca_mutex_unlock(g_dtlsContextMutex);
699
700     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsInitiateHandshake");
701
702     return CA_STATUS_OK;
703 }
704
705 CAResult_t CADtlsClose(const CAEndpoint_t *endpoint)
706 {
707     stCADtlsAddrInfo_t dst = { 0 };
708
709     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsDisconnect");
710
711     if(!endpoint)
712     {
713         return CA_STATUS_INVALID_PARAM;
714     }
715
716     CAConvertNameToAddr(endpoint->addr, endpoint->port, &(dst.addr.st));
717     dst.ifIndex = 0;
718     dst.size = CASizeOfAddrInfo(&dst);
719
720     ca_mutex_lock(g_dtlsContextMutex);
721     if (NULL == g_caDtlsContext)
722     {
723         OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
724         ca_mutex_unlock(g_dtlsContextMutex);
725         return CA_STATUS_FAILED;
726     }
727
728     if (0 > dtls_close(g_caDtlsContext->dtlsContext, (session_t*)(&dst)))
729     {
730         OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to close the session");
731         ca_mutex_unlock(g_dtlsContextMutex);
732         return CA_STATUS_FAILED;
733     }
734
735     ca_mutex_unlock(g_dtlsContextMutex);
736
737     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsDisconnect");
738
739     return CA_STATUS_OK;
740 }
741
742 CAResult_t CADtlsGenerateOwnerPSK(const CAEndpoint_t *endpoint,
743                     const uint8_t* label, const size_t labelLen,
744                     const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
745                     const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
746                     uint8_t* ownerPSK, const size_t ownerPSKSize)
747 {
748     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CADtlsGenerateOwnerPSK");
749
750     if(!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPSKSize)
751     {
752         return CA_STATUS_INVALID_PARAM;
753     }
754
755     stCADtlsAddrInfo_t dst = { 0 };
756
757     CAConvertNameToAddr(endpoint->addr, endpoint->port, &(dst.addr.st));
758     dst.ifIndex = 0;
759     dst.size = CASizeOfAddrInfo(&dst);
760
761     ca_mutex_lock(g_dtlsContextMutex);
762     if (NULL == g_caDtlsContext)
763     {
764         OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
765         ca_mutex_unlock(g_dtlsContextMutex);
766         return CA_STATUS_FAILED;
767     }
768
769     if( 0 == dtls_prf_with_current_keyblock(g_caDtlsContext->dtlsContext, (session_t*)(&dst),
770                  label, labelLen, rsrcServerDeviceID, rsrcServerDeviceIDLen,
771                  provServerDeviceID, provServerDeviceIDLen, ownerPSK, ownerPSKSize))
772     {
773         OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to DTLS PRF");
774         ca_mutex_unlock(g_dtlsContextMutex);
775         return CA_STATUS_FAILED;
776     }
777     ca_mutex_unlock(g_dtlsContextMutex);
778
779     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsGenerateOwnerPSK");
780
781     return CA_STATUS_OK;
782 }
783
784 #ifdef __WITH_X509__
785 static CADtlsCertCreds_t g_X509Cred = {{0}, 0, 0, {0}, {0}, {0}};
786
787 static int g_IsX509Init = 0;
788
789 int CAInitX509()
790 {
791     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN CAInitX509");
792     g_IsX509Init = (OC_STACK_OK == GetDtlsCertCredentials(&g_X509Cred));
793
794     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CAInitX509");
795     return !g_IsX509Init;
796 }
797
798
799 void CADeInitX509()
800 {
801     g_IsX509Init = 0;
802 }
803
804
805 static int CAIsX509Active(struct dtls_context_t *ctx)
806 {
807     (void)ctx;
808     return 0;
809 }
810
811 static int CAGetDeviceKey(struct dtls_context_t *ctx,
812                        const session_t *session,
813                        const dtls_ecc_key_t **result)
814 {
815     OIC_LOG(DEBUG, NET_DTLS_TAG, "CAGetDeviceKey");
816     static dtls_ecc_key_t ecdsa_key = {DTLS_ECDH_CURVE_SECP256R1, NULL, NULL, NULL};
817
818     int ret = 1;
819     if (!g_IsX509Init)
820     {
821         VERIFY_SUCCESS(CAInitX509(), 0);
822     }
823
824     ecdsa_key.priv_key = g_X509Cred.devicePrivateKey;
825     *result = &ecdsa_key;
826
827     ret = 0;
828 exit:
829     return ret;
830 }
831
832 static int
833 CAGetDeviceCertificate(struct dtls_context_t *ctx,
834                     const session_t *session,
835                     const unsigned char **cert,
836                     size_t *cert_size)
837 {
838     OIC_LOG(DEBUG, NET_DTLS_TAG, "CAGetDeviceCertificate");
839     int ret = 1;
840     if (!g_IsX509Init)
841     {
842         VERIFY_SUCCESS(CAInitX509(), 0);
843     }
844     *cert = g_X509Cred.certificateChain;
845     *cert_size = g_X509Cred.certificateChainLen;
846 #ifdef X509_DEBUG
847     ByteArray ownCert = {g_X509Cred.certificateChain, g_X509Cred.certificateChainLen};
848     PRINT_BYTE_ARRAY("OWN CERT: \n", ownCert);
849 #endif
850
851     ret = 0;
852 exit:
853     return ret;
854 }
855 /**
856  * @fn  CAGetRootKey
857  * @brief  Gets x and y components of Root Certificate Autority public key
858  *
859  * @return  0 on success otherwise a positive error value.
860  *
861  */
862 static int CAGetRootKey(const unsigned char **ca_pub_x, const unsigned char **ca_pub_y)
863 {
864     OIC_LOG(DEBUG, NET_DTLS_TAG, "CAGetRootKey");
865     int ret = 1;
866     if (!g_IsX509Init)
867     {
868         VERIFY_SUCCESS(CAInitX509(), 0);
869     }
870     *ca_pub_x = g_X509Cred.rootPublicKeyX;
871     *ca_pub_y = g_X509Cred.rootPublicKeyY;
872
873     ret = 0;
874 exit:
875     return ret;
876 }
877
878
879 static int CAVerifyCertificate(struct dtls_context_t *ctx, const session_t *session,
880                                const unsigned char *cert, size_t certLen,
881                                const unsigned char *x, size_t xLen,
882                                const unsigned char *y, size_t yLen)
883 {
884     OIC_LOG(DEBUG, NET_DTLS_TAG, "Verify Certificate");
885
886     ByteArray crtChainDer[MAX_CHAIN_LEN];
887     CertificateX509 crtChain[MAX_CHAIN_LEN];
888
889     uint8_t chainLength;
890
891     int ret;
892     const unsigned char *ca_pub_x;
893     const unsigned char *ca_pub_y;
894     ByteArray certDerCode = BYTE_ARRAY_INITIALIZER;
895     ByteArray caPubKey = BYTE_ARRAY_INITIALIZER;
896     unsigned char ca_pub_key[PUBLIC_KEY_SIZE];
897
898     CAGetRootKey (&ca_pub_x, &ca_pub_y);
899
900     certDerCode.data = (uint8_t *)cert;
901     certDerCode.len = certLen;
902
903 #ifdef X509_DEBUG
904     PRINT_BYTE_ARRAY("CERT :\n", certDerCode);
905 #endif
906
907
908     caPubKey.len = PUBLIC_KEY_SIZE;
909     caPubKey.data = ca_pub_key;
910
911     memcpy(caPubKey.data, ca_pub_x, PUBLIC_KEY_SIZE / 2);
912     memcpy(caPubKey.data + PUBLIC_KEY_SIZE / 2, ca_pub_y, PUBLIC_KEY_SIZE / 2);
913
914     ret = (int)  LoadCertificateChain (certDerCode, crtChainDer, &chainLength);
915     VERIFY_SUCCESS(ret, PKI_SUCCESS);
916     ret = (int)  ParseCertificateChain (crtChainDer, crtChain, chainLength );
917     VERIFY_SUCCESS(ret, PKI_SUCCESS);
918     ret = (int)  CheckCertificateChain (crtChain, chainLength, caPubKey);
919     VERIFY_SUCCESS(ret, PKI_SUCCESS);
920
921     INC_BYTE_ARRAY(crtChain[0].pubKey, 2);
922
923     memcpy(x, crtChain[0].pubKey.data, xLen);
924     memcpy(y, crtChain[0].pubKey.data + PUBLIC_KEY_SIZE / 2, yLen);
925
926
927     if (NULL != ctx->peers && DTLS_SERVER == ctx->peers->role )
928     {
929         stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
930         char peerAddr[MAX_ADDR_STR_SIZE_CA] = { 0 };
931         uint16_t port = 0;
932         CAConvertAddrToName(&(addrInfo->addr.st), peerAddr, &port);
933
934         CAResult_t result = CAAddIdToPeerInfoList(peerAddr, port,
935         crtChain[0].subject.data + crtChain[0].subject.len - sizeof(OicUuid_t), sizeof(OicUuid_t));
936         if (CA_STATUS_OK != result )
937         {
938             OIC_LOG(ERROR, NET_DTLS_TAG, "Fail to add peer id to gDtlsPeerInfoList");
939         }
940     }
941
942
943 exit:
944     if (ret != 0) OIC_LOG(DEBUG, NET_DTLS_TAG, "Certificate verification FAILED\n");
945     else OIC_LOG(DEBUG, NET_DTLS_TAG, "Certificate verification SUCCESS\n");
946     return -ret;
947 }
948
949 #endif
950
951
952
953
954 CAResult_t CAAdapterNetDtlsInit()
955 {
956     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
957
958     // Initialize mutex for DtlsContext
959     if (NULL == g_dtlsContextMutex)
960     {
961         g_dtlsContextMutex = ca_mutex_new();
962         VERIFY_NON_NULL_RET(g_dtlsContextMutex, NET_DTLS_TAG, "malloc failed",
963             CA_MEMORY_ALLOC_FAILED);
964     }
965     else
966     {
967         OIC_LOG(ERROR, NET_DTLS_TAG, "CAAdapterNetDtlsInit done already!");
968         return CA_STATUS_OK;
969     }
970
971     // Lock DtlsContext mutex and create DtlsContext
972     ca_mutex_lock(g_dtlsContextMutex);
973     g_caDtlsContext = (stCADtlsContext_t *)OICCalloc(1, sizeof(stCADtlsContext_t));
974
975     if (NULL == g_caDtlsContext)
976     {
977         OIC_LOG(ERROR, NET_DTLS_TAG, "Context malloc failed");
978         ca_mutex_unlock(g_dtlsContextMutex);
979         ca_mutex_free(g_dtlsContextMutex);
980         return CA_MEMORY_ALLOC_FAILED;
981     }
982
983
984     // Create PeerInfoList and CacheList
985     g_caDtlsContext->peerInfoList = u_arraylist_create();
986     g_caDtlsContext->cacheList = u_arraylist_create();
987
988     if( (NULL == g_caDtlsContext->peerInfoList) ||
989         (NULL == g_caDtlsContext->cacheList))
990     {
991     OIC_LOG(ERROR, NET_DTLS_TAG, "peerInfoList or cacheList initialization failed!");
992         CAClearCacheList();
993         CAFreePeerInfoList();
994         OICFree(g_caDtlsContext);
995         g_caDtlsContext = NULL;
996         ca_mutex_unlock(g_dtlsContextMutex);
997         ca_mutex_free(g_dtlsContextMutex);
998         return CA_STATUS_FAILED;
999     }
1000
1001     // Initialize clock, crypto and other global vars in tinyDTLS library
1002     dtls_init();
1003
1004     // Create tinydtls Context
1005     g_caDtlsContext->dtlsContext = dtls_new_context(g_caDtlsContext);
1006
1007     if (NULL ==  g_caDtlsContext->dtlsContext)
1008     {
1009         OIC_LOG(ERROR, NET_DTLS_TAG, "dtls_new_context failed");
1010         ca_mutex_unlock(g_dtlsContextMutex);
1011         CAAdapterNetDtlsDeInit();
1012         return CA_STATUS_FAILED;
1013     }
1014
1015     g_caDtlsContext->callbacks.write = CASendSecureData;
1016     g_caDtlsContext->callbacks.read  = CAReadDecryptedPayload;
1017     g_caDtlsContext->callbacks.event = CAHandleSecureEvent;
1018
1019 #ifdef __WITH_X509__
1020     CAInitX509();
1021     if (g_IsX509Init == 0)
1022 #endif //__WITH_X509__
1023     g_caDtlsContext->callbacks.get_psk_info = CAGetPskCredentials;
1024 #ifdef __WITH_X509__
1025     g_caDtlsContext->callbacks.get_x509_key = CAGetDeviceKey;
1026     g_caDtlsContext->callbacks.verify_x509_cert = CAVerifyCertificate;
1027     g_caDtlsContext->callbacks.get_x509_cert = CAGetDeviceCertificate;
1028     g_caDtlsContext->callbacks.is_x509_active = CAIsX509Active;
1029 #endif //__WITH_X509__*
1030     dtls_set_handler(g_caDtlsContext->dtlsContext, &(g_caDtlsContext->callbacks));
1031     ca_mutex_unlock(g_dtlsContextMutex);
1032     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
1033     return CA_STATUS_OK;
1034 }
1035
1036 void CAAdapterNetDtlsDeInit()
1037 {
1038     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
1039
1040     VERIFY_NON_NULL_VOID(g_caDtlsContext, NET_DTLS_TAG, "context is NULL");
1041     VERIFY_NON_NULL_VOID(g_dtlsContextMutex, NET_DTLS_TAG, "context mutex is NULL");
1042
1043     //Lock DtlsContext mutex
1044     ca_mutex_lock(g_dtlsContextMutex);
1045
1046     // Clear all lists
1047     CAFreePeerInfoList();
1048     CAClearCacheList();
1049
1050     // De-initialize tinydtls context
1051     dtls_free_context(g_caDtlsContext->dtlsContext);
1052     g_caDtlsContext->dtlsContext = NULL;
1053
1054     // De-initialize DtlsContext
1055     OICFree(g_caDtlsContext);
1056     g_caDtlsContext = NULL;
1057
1058     // Unlock DtlsContext mutex and de-initialize it
1059     ca_mutex_unlock(g_dtlsContextMutex);
1060     ca_mutex_free(g_dtlsContextMutex);
1061     g_dtlsContextMutex = NULL;
1062
1063     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
1064 }
1065
1066 CAResult_t CAAdapterNetDtlsEncrypt(const CAEndpoint_t *endpoint,
1067                                    void *data, uint32_t dataLen)
1068 {
1069
1070     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
1071
1072     VERIFY_NON_NULL_RET(endpoint, NET_DTLS_TAG,"Param remoteAddress is NULL",
1073                         CA_STATUS_INVALID_PARAM);
1074     VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL" ,
1075                         CA_STATUS_INVALID_PARAM);
1076
1077     if (0 == dataLen)
1078     {
1079         OIC_LOG_V(ERROR, NET_DTLS_TAG, "dataLen is less than or equal zero [%d]", dataLen);
1080         return CA_STATUS_FAILED;
1081     }
1082
1083     OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Data to be encrypted dataLen [%d]", dataLen);
1084
1085     stCADtlsAddrInfo_t addrInfo = { 0 };
1086
1087     CAConvertNameToAddr(endpoint->addr, endpoint->port, &(addrInfo.addr.st));
1088     addrInfo.ifIndex = 0;
1089     addrInfo.size = CASizeOfAddrInfo(&addrInfo);
1090
1091     ca_mutex_lock(g_dtlsContextMutex);
1092     if(NULL == g_caDtlsContext)
1093     {
1094         OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
1095         ca_mutex_unlock(g_dtlsContextMutex);
1096         return CA_STATUS_FAILED;
1097     }
1098
1099     eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(&addrInfo, data, dataLen);
1100     if (ret == DTLS_SESSION_INITIATED)
1101     {
1102         stCACacheMessage_t *message = (stCACacheMessage_t *)OICCalloc(1, sizeof(stCACacheMessage_t));
1103         if (NULL == message)
1104         {
1105             OIC_LOG(ERROR, NET_DTLS_TAG, "calloc failed!");
1106             ca_mutex_unlock(g_dtlsContextMutex);
1107             return CA_MEMORY_ALLOC_FAILED;
1108         }
1109
1110         message->data = (uint8_t *)OICCalloc(dataLen + 1, sizeof(uint8_t));
1111         if (NULL == message->data)
1112         {
1113             OIC_LOG(ERROR, NET_DTLS_TAG, "calloc failed!");
1114             OICFree(message);
1115             ca_mutex_unlock(g_dtlsContextMutex);
1116             return CA_MEMORY_ALLOC_FAILED;
1117         }
1118         memcpy(message->data, data, dataLen);
1119         message->dataLen = dataLen;
1120         message->destSession = addrInfo;
1121
1122         CAResult_t result = CADtlsCacheMsg(message);
1123         if (CA_STATUS_OK != result)
1124         {
1125             OIC_LOG(DEBUG, NET_DTLS_TAG, "CADtlsCacheMsg failed!");
1126             CAFreeCacheMsg(message);
1127         }
1128         OIC_LOG_V(DEBUG, NET_DTLS_TAG, "OUT Initiating Dtls session [%d]", result);
1129         ca_mutex_unlock(g_dtlsContextMutex);
1130         return result;
1131     }
1132
1133     ca_mutex_unlock(g_dtlsContextMutex);
1134
1135     if (ret != DTLS_OK)
1136     {
1137         OIC_LOG(ERROR, NET_DTLS_TAG, "OUT FAILURE");
1138         return CA_STATUS_FAILED;
1139     }
1140
1141     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
1142     return CA_STATUS_OK;
1143 }
1144
1145 CAResult_t CAAdapterNetDtlsDecrypt(const CASecureEndpoint_t *sep,
1146                                    uint8_t *data, uint32_t dataLen)
1147 {
1148     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
1149     VERIFY_NON_NULL_RET(sep, NET_DTLS_TAG, "endpoint is NULL" , CA_STATUS_INVALID_PARAM);
1150
1151     stCADtlsAddrInfo_t addrInfo = { 0 };
1152
1153     CAConvertNameToAddr(sep->endpoint.addr, sep->endpoint.port, &(addrInfo.addr.st));
1154     addrInfo.ifIndex = 0;
1155     addrInfo.size = CASizeOfAddrInfo(&addrInfo);
1156
1157     ca_mutex_lock(g_dtlsContextMutex);
1158     if (NULL == g_caDtlsContext)
1159     {
1160         OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
1161         ca_mutex_unlock(g_dtlsContextMutex);
1162         return CA_STATUS_FAILED;
1163     }
1164
1165     eDtlsRet_t ret = CAAdapterNetDtlsDecryptInternal(&addrInfo, data, dataLen);
1166     ca_mutex_unlock(g_dtlsContextMutex);
1167
1168     if (DTLS_OK == ret || DTLS_HS_MSG == ret)
1169     {
1170         OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Successfully Decrypted or Handshake msg recvd [%d]", ret);
1171         OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
1172         return CA_STATUS_OK;
1173     }
1174
1175     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
1176     return CA_STATUS_FAILED;
1177 }
1178