5838a83e85c001c934519cb4d599f5147d5db7fa
[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 "cawifiinterface.h"
23 #include "dtls.h"
24 #include "oic_malloc.h"
25
26 /**
27  * @def NET_DTLS_TAG
28  * @brief Logging tag for module name
29  */
30 #define NET_DTLS_TAG "NET_DTLS"
31
32 /**
33  * @var g_caDtlsContext
34  * @brief global context which holds dtls context and cache list information.
35  */
36 static stCADtlsContext_t *g_caDtlsContext = NULL;
37
38 /**
39  * @var g_dtlsContextMutex
40  * @brief Mutex to synchronize access to g_caDtlsContext.
41  */
42 static u_mutex g_dtlsContextMutex = NULL;
43
44 /**
45  * @var g_dtlsListMutex
46  * @brief Mutex to synchronize access to DTLS Cache.
47  */
48 static u_mutex g_dtlsListMutex = NULL;
49
50 /**
51  * @var g_getCredentialsCallback
52  * @brief callback to get DTLS credentials
53  */
54 static CAGetDTLSCredentialsHandler g_getCredentialsCallback = NULL;
55
56 static eDtlsRet_t CAAdapterNetDtlsEncryptInternal(const stCADtlsAddrInfo_t *dstSession,
57         uint8_t *data, uint32_t dataLen)
58 {
59     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
60
61     VERIFY_NON_NULL_RET(dstSession, NET_DTLS_TAG, "Param dstSession is NULL" , DTLS_FAIL);
62     VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL" , DTLS_FAIL);
63
64     if (0 == dataLen)
65     {
66         OIC_LOG(ERROR, NET_DTLS_TAG, "Given Packet length is equal to zero.");
67         return DTLS_FAIL;
68     }
69
70     u_mutex_lock(g_dtlsContextMutex);
71     if (NULL == g_caDtlsContext)
72     {
73         OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
74         u_mutex_unlock(g_dtlsContextMutex);
75         return DTLS_FAIL;
76     }
77
78     int retLen = dtls_write(g_caDtlsContext->dtlsContext, (session_t *)dstSession, data,
79                                 dataLen);
80     OIC_LOG_V(DEBUG, NET_DTLS_TAG, "dtls_write retun len [%d]", retLen);
81     u_mutex_unlock(g_dtlsContextMutex);
82
83     if (0 == retLen)
84     {
85         // A new DTLS session was initiated by tinyDTLS library and wait for callback.
86         return DTLS_SESSION_INITIATED;
87     }
88     else if (dataLen == retLen)
89     {
90         OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
91         return DTLS_OK;
92     }
93     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
94     return DTLS_FAIL;
95 }
96
97 static eDtlsRet_t CAAdapterNetDtlsDecryptInternal(const stCADtlsAddrInfo_t *srcSession,
98         uint8_t *buf, uint32_t bufLen)
99 {
100     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
101
102     VERIFY_NON_NULL_RET(srcSession, NET_DTLS_TAG, "Param srcSession is NULL", DTLS_FAIL);
103     VERIFY_NON_NULL_RET(buf, NET_DTLS_TAG, "Param buf is NULL", DTLS_FAIL);
104
105     if (0 == bufLen)
106     {
107         OIC_LOG(ERROR, NET_DTLS_TAG, "Given Packet length is equal to zero.");
108         return DTLS_FAIL;
109     }
110
111     eDtlsRet_t ret = DTLS_FAIL;
112
113     ///  TODO: how to protect g_caDtlsContext as dtls_handle_message is blocking call
114     if (dtls_handle_message(g_caDtlsContext->dtlsContext, (session_t *)srcSession, buf, bufLen) == 0)
115     {
116         OIC_LOG(DEBUG, NET_DTLS_TAG, "dtls_handle_message success");
117         ret = DTLS_OK;
118     }
119
120     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
121     return ret;
122 }
123
124 static void CAFreeCacheMsg(stCACacheMessage_t *msg)
125 {
126     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
127     VERIFY_NON_NULL_VOID(msg, NET_DTLS_TAG, "msg");
128
129     OICFree(msg->destSession);
130     OICFree(msg->data);
131     OICFree(msg);
132
133     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
134 }
135
136 static void CAClearCacheList()
137 {
138     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
139     uint32_t list_index = 0;
140     uint32_t list_length = 0;
141     u_mutex_lock(g_dtlsListMutex);
142     if (NULL == g_caDtlsContext)
143     {
144         OIC_LOG(ERROR, NET_DTLS_TAG, "Dtls Context is NULL");
145         u_mutex_unlock(g_dtlsListMutex);
146         return;
147     }
148     list_length = u_arraylist_length(g_caDtlsContext->cacheList);
149     for (list_index = 0; list_index < list_length; list_index++)
150     {
151         stCACacheMessage_t *msg = (stCACacheMessage_t *)u_arraylist_get(g_caDtlsContext->cacheList,
152                                   list_index);
153         if (msg != NULL)
154         {
155             CAFreeCacheMsg(msg);
156         }
157     }
158     u_arraylist_free(&g_caDtlsContext->cacheList);
159     g_caDtlsContext->cacheList = NULL;
160     u_mutex_unlock(g_dtlsListMutex);
161     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
162 }
163
164 static CAResult_t CADtlsCacheMsg(stCACacheMessage_t *msg)
165 {
166     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
167
168     u_mutex_lock(g_dtlsListMutex);
169     if (NULL == g_caDtlsContext)
170     {
171         OIC_LOG(ERROR, NET_DTLS_TAG, "Dtls Context is NULL");
172         u_mutex_unlock(g_dtlsListMutex);
173         return CA_STATUS_FAILED;
174     }
175
176     CAResult_t result = u_arraylist_add(g_caDtlsContext->cacheList, (void *)msg);
177     if (CA_STATUS_OK != result)
178     {
179         OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_add failed!");
180     }
181     u_mutex_unlock(g_dtlsListMutex);
182
183     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
184     return result;
185 }
186
187
188 static bool CAIsAddressMatching(const stCADtlsAddrInfo_t *a,  const stCADtlsAddrInfo_t *b)
189 {
190     return (a->size == b->size) &&
191            (a->addr.sa.sa_family == b->addr.sa.sa_family) &&
192            (a->addr.sin.sin_port == b->addr.sin.sin_port) &&
193            memcmp(&a->addr.sin.sin_addr, &b->addr.sin.sin_addr, sizeof(struct in_addr)) == 0;
194 }
195
196 static void CASendCachedMsg(const stCADtlsAddrInfo_t *dstSession)
197 {
198     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
199     VERIFY_NON_NULL_VOID(dstSession, NET_DTLS_TAG, "Param dstSession is NULL");
200
201     uint32_t list_index = 0;
202     uint32_t list_length = 0;
203     u_mutex_lock(g_dtlsListMutex);
204     list_length = u_arraylist_length(g_caDtlsContext->cacheList);
205     for (list_index = 0; list_index < list_length;)
206     {
207         stCACacheMessage_t *msg = (stCACacheMessage_t *)u_arraylist_get(g_caDtlsContext->cacheList,
208                                   list_index);
209         if ((NULL != msg) && (true == CAIsAddressMatching(msg->destSession, dstSession)))
210         {
211             eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(msg->destSession,
212                              msg->data, msg->dataLen);
213             if (ret == DTLS_OK)
214             {
215                 OIC_LOG(DEBUG, NET_DTLS_TAG, "CAAdapterNetDtlsEncryptInternal success");
216             }
217             else
218             {
219                 OIC_LOG(ERROR, NET_DTLS_TAG, "CAAdapterNetDtlsEncryptInternal failed.");
220             }
221
222             if (u_arraylist_remove(g_caDtlsContext->cacheList, list_index))
223             {
224                 CAFreeCacheMsg(msg);
225                 // Reduce list length by 1 as we removed one element.
226                 list_length--;
227             }
228             else
229             {
230                 OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_remove failed.");
231                 break;
232             }
233         }
234         else
235         {
236             // Move to the next element
237             ++list_index;
238         }
239     }
240     u_mutex_unlock(g_dtlsListMutex);
241
242     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
243 }
244
245 static int32_t CAReadDecryptedPayload(dtls_context_t *dtlsContext,
246                                       session_t *session,
247                                       uint8_t *buf,
248                                       size_t bufLen )
249 {
250     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
251
252     VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", 0);
253     OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Decrypted buf len [%d]", bufLen);
254
255     stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
256
257     char *remoteAddress = inet_ntoa(addrInfo->addr.sin.sin_addr);
258     uint32_t port = ntohs(addrInfo->addr.sin.sin_port);
259     eDtlsAdapterType_t type = (eDtlsAdapterType_t)addrInfo->ifIndex;
260
261     u_mutex_lock(g_dtlsContextMutex);
262     if (NULL == g_caDtlsContext)
263     {
264         OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
265         u_mutex_unlock(g_dtlsContextMutex);
266         return 0;
267     }
268
269     if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type) &&
270         (NULL != g_caDtlsContext->adapterCallbacks[type].recvCallback))
271     {
272         g_caDtlsContext->adapterCallbacks[type].recvCallback(remoteAddress, port,
273                 buf,  bufLen, true);
274     }
275     else
276     {
277         OIC_LOG_V(DEBUG, NET_DTLS_TAG, "recvCallback Callback or adapter type is wrong [%d]", type);
278     }
279     u_mutex_unlock(g_dtlsContextMutex);
280
281     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
282     return 0;
283 }
284
285 static int32_t CASendSecureData(dtls_context_t *dtlsContext,
286                                 session_t *session,
287                                 uint8_t *buf,
288                                 size_t bufLen)
289 {
290     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
291
292     VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", -1);
293     VERIFY_NON_NULL_RET(buf, NET_DTLS_TAG, "Param buf is NULL", -1);
294
295     if (0 == bufLen)
296     {
297         OIC_LOG(ERROR, NET_DTLS_TAG, "Encrypted Buffer length is equal to zero");
298         return 0;
299     }
300
301     stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
302
303     char *remoteAddress = inet_ntoa(addrInfo->addr.sin.sin_addr);
304     uint16_t port = ntohs(addrInfo->addr.sin.sin_port);
305     eDtlsAdapterType_t type = (eDtlsAdapterType_t)addrInfo->ifIndex;
306
307     //Mutex is not required for g_caDtlsContext. It will be called in same thread.
308     int32_t sentLen = 0;
309     if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type) &&
310         (NULL != g_caDtlsContext->adapterCallbacks[type].sendCallback))
311     {
312         sentLen = g_caDtlsContext->adapterCallbacks[type].sendCallback(remoteAddress, port,
313                   buf,  bufLen);
314     }
315     else
316     {
317         OIC_LOG_V(DEBUG, NET_DTLS_TAG, "send Callback or adapter type is wrong [%d]", type );
318     }
319
320     OIC_LOG_V(DEBUG, NET_DTLS_TAG, "sent buffer length [%d]", sentLen);
321
322     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
323     return sentLen;
324 }
325
326
327 static int32_t CAHandleSecureEvent(dtls_context_t *dtlsContext,
328                                    session_t *session,
329                                    dtls_alert_level_t level,
330                                    unsigned short code)
331 {
332     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
333
334     VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", 0);
335
336     OIC_LOG_V(DEBUG, NET_DTLS_TAG, "level [%d] code [%u]", level, code);
337
338     if (!level && (code == DTLS_EVENT_CONNECTED))
339     {
340         OIC_LOG(DEBUG, NET_DTLS_TAG, "Received DTLS_EVENT_CONNECTED. Sending Cached data");
341         CASendCachedMsg((stCADtlsAddrInfo_t *)session);
342     }
343
344     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
345     return 0;
346 }
347
348
349 static int32_t CAGetPskCredentials(dtls_context_t *ctx,
350                                    const session_t *session,
351                                    dtls_credentials_type_t type,
352                                    const unsigned char *desc, size_t descLen,
353                                    unsigned char *result, size_t resultLen)
354 {
355     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
356
357     int32_t ret  = -1;
358
359     VERIFY_NON_NULL_RET(g_getCredentialsCallback, NET_DTLS_TAG, "GetCredential callback", -1);
360     VERIFY_NON_NULL_RET(result, NET_DTLS_TAG, "result", -1);
361
362     OCDtlsPskCredsBlob *credInfo = NULL;
363
364     // Retrieve the credentials blob from security module
365     // OCGetDtlsPskCredentials(&credInfo);
366     g_getCredentialsCallback(&credInfo);
367
368     VERIFY_NON_NULL_RET(credInfo, NET_DTLS_TAG, "CAGetDtlsPskCredentials credInfo is NULL", -1);
369
370     if ((type == DTLS_PSK_HINT) || (type == DTLS_PSK_IDENTITY))
371     {
372         if (DTLS_PSK_ID_LEN <= resultLen)
373         {
374             memcpy(result, credInfo->identity, DTLS_PSK_ID_LEN);
375             ret = DTLS_PSK_ID_LEN;
376         }
377     }
378
379     if ((type == DTLS_PSK_KEY) && (desc) && (descLen == DTLS_PSK_PSK_LEN))
380     {
381         //Check if we have the credentials for the device with which we
382         //are trying to perform a handshake
383         int index = 0;
384         for (index = 0; index < credInfo->num; index++)
385         {
386             if (memcmp(desc, credInfo->creds[index].id, DTLS_PSK_ID_LEN) == 0)
387             {
388                 memcpy(result, credInfo->creds[index].psk, DTLS_PSK_PSK_LEN);
389                 ret = DTLS_PSK_PSK_LEN;
390             }
391         }
392     }
393
394     return ret;
395 }
396
397 void CADTLSSetAdapterCallbacks(CAPacketReceivedCallback recvCallback,
398                                CAPacketSendCallback sendCallback, eDtlsAdapterType_t type)
399 {
400     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
401     u_mutex_lock(g_dtlsContextMutex);
402     if (NULL == g_caDtlsContext)
403     {
404         OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
405         u_mutex_unlock(g_dtlsContextMutex);
406         return;
407     }
408
409     if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type))
410     {
411         g_caDtlsContext->adapterCallbacks[type].recvCallback = recvCallback;
412         g_caDtlsContext->adapterCallbacks[type].sendCallback = sendCallback;
413     }
414
415     u_mutex_unlock(g_dtlsContextMutex);
416
417     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
418 }
419
420 void CADTLSSetCredentialsCallback(CAGetDTLSCredentialsHandler credCallback)
421 {
422     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
423     g_getCredentialsCallback = credCallback;
424     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
425 }
426
427 CAResult_t CAAdapterNetDtlsInit()
428 {
429     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
430
431     if (NULL == g_dtlsContextMutex)
432     {
433         g_dtlsContextMutex = u_mutex_new();
434         VERIFY_NON_NULL_RET(g_dtlsContextMutex, NET_DTLS_TAG, "malloc failed",
435             CA_MEMORY_ALLOC_FAILED);
436     }
437     else
438     {
439         OIC_LOG(ERROR, NET_DTLS_TAG, "CAAdapterNetDtlsInit done already!");
440         return CA_STATUS_OK;
441     }
442
443     if (NULL == g_dtlsListMutex)
444     {
445         g_dtlsListMutex = u_mutex_new();
446         if (NULL == g_dtlsListMutex)
447         {
448             OIC_LOG(ERROR, NET_DTLS_TAG, "g_dtlsListMutex malloc failed");
449             u_mutex_free(g_dtlsContextMutex);
450             return CA_MEMORY_ALLOC_FAILED;
451         }
452     }
453
454     u_mutex_lock(g_dtlsContextMutex);
455     g_caDtlsContext = (stCADtlsContext_t *)OICCalloc(1, sizeof(stCADtlsContext_t));
456
457     if (NULL == g_caDtlsContext)
458     {
459         OIC_LOG(ERROR, NET_DTLS_TAG, "Context malloc failed");
460         u_mutex_free(g_dtlsListMutex);
461         u_mutex_unlock(g_dtlsContextMutex);
462         u_mutex_free(g_dtlsContextMutex);
463         return CA_MEMORY_ALLOC_FAILED;
464     }
465
466     u_mutex_lock(g_dtlsListMutex);
467     g_caDtlsContext->cacheList = u_arraylist_create();
468
469     if (NULL == g_caDtlsContext->cacheList)
470     {
471         OIC_LOG(ERROR, NET_DTLS_TAG, "cacheList initialization failed!");
472         u_mutex_unlock(g_dtlsListMutex);
473         u_mutex_free(g_dtlsListMutex);
474         u_mutex_unlock(g_dtlsContextMutex);
475         u_mutex_free(g_dtlsContextMutex);
476         OICFree(g_caDtlsContext);
477         g_caDtlsContext = NULL;
478         return CA_STATUS_FAILED;
479     }
480     u_mutex_unlock(g_dtlsListMutex);
481     // Initialize clock, crypto and other global vars in tinyDTLS library
482     dtls_init();
483
484     g_caDtlsContext->dtlsContext = dtls_new_context(g_caDtlsContext);
485
486     if (NULL ==  g_caDtlsContext->dtlsContext)
487     {
488         OIC_LOG(ERROR, NET_DTLS_TAG, "dtls_new_context failed");
489         u_mutex_unlock(g_dtlsContextMutex);
490         CAAdapterNetDtlsDeInit();
491         return CA_STATUS_FAILED;
492     }
493
494     g_caDtlsContext->callbacks.write = CASendSecureData;
495     g_caDtlsContext->callbacks.read  = CAReadDecryptedPayload;
496     g_caDtlsContext->callbacks.event = CAHandleSecureEvent;
497     g_caDtlsContext->callbacks.get_psk_info = CAGetPskCredentials;
498
499     dtls_set_handler(g_caDtlsContext->dtlsContext, &(g_caDtlsContext->callbacks));
500     u_mutex_unlock(g_dtlsContextMutex);
501     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
502     return CA_STATUS_OK;
503 }
504
505 void CAAdapterNetDtlsDeInit()
506 {
507     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
508
509     VERIFY_NON_NULL_VOID(g_caDtlsContext, NET_DTLS_TAG, "context is NULL");
510
511     u_mutex_lock(g_dtlsContextMutex);
512     CAClearCacheList();
513     dtls_free_context(g_caDtlsContext->dtlsContext);
514     g_caDtlsContext->dtlsContext = NULL;
515     OICFree(g_caDtlsContext);
516     g_caDtlsContext = NULL;
517     u_mutex_unlock(g_dtlsContextMutex);
518
519     u_mutex_free(g_dtlsContextMutex);
520     g_dtlsContextMutex = NULL;
521     u_mutex_free(g_dtlsListMutex);
522     g_dtlsListMutex = NULL;
523     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
524 }
525
526 CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress,
527                                    const uint16_t port,
528                                    void *data,
529                                    uint32_t dataLen,
530                                    uint8_t *cacheFlag,
531                                    eDtlsAdapterType_t adapterType)
532 {
533
534     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
535
536     VERIFY_NON_NULL_RET(remoteAddress, NET_DTLS_TAG,"Param remoteAddress is NULL",CA_STATUS_FAILED);
537
538     VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL" , CA_STATUS_FAILED);
539
540     if (0 == dataLen)
541     {
542         OIC_LOG_V(ERROR, NET_DTLS_TAG, "dataLen is less than or equal zero [%d]", dataLen);
543         return CA_STATUS_FAILED;
544     }
545
546     OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Data to be encrypted dataLen [%d]", dataLen);
547
548     stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)OICCalloc(1, sizeof(stCADtlsAddrInfo_t));
549
550     VERIFY_NON_NULL_RET(addrInfo, NET_DTLS_TAG, "malloc failed" , CA_MEMORY_ALLOC_FAILED);
551
552     addrInfo->addr.sin.sin_family = AF_INET;
553     addrInfo->addr.sin.sin_port = htons(port);
554     // Conversion from ASCII format to Network format
555     if (inet_aton(remoteAddress, &addrInfo->addr.sin.sin_addr) == 0)
556     {
557         OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to convert from ASCII to Network Address");
558         OICFree(addrInfo);
559         return CA_STATUS_FAILED;
560     }
561     addrInfo->size = sizeof(addrInfo->addr);
562     addrInfo->ifIndex = adapterType;
563
564     eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(addrInfo, data, dataLen);
565     if (ret == DTLS_SESSION_INITIATED)
566     {
567         stCACacheMessage_t *message = (stCACacheMessage_t *)OICCalloc(1, sizeof(stCACacheMessage_t));
568         if (NULL == message)
569         {
570             OIC_LOG(ERROR, NET_DTLS_TAG, "calloc failed!");
571             OICFree(addrInfo);
572             return CA_MEMORY_ALLOC_FAILED;
573         }
574
575         message->data = (uint8_t *)OICCalloc(dataLen + 1, sizeof(uint8_t));
576         if (NULL == message->data)
577         {
578             OIC_LOG(ERROR, NET_DTLS_TAG, "calloc failed!");
579             OICFree(addrInfo);
580             OICFree(message);
581             return CA_MEMORY_ALLOC_FAILED;
582         }
583         memcpy(message->data, data, dataLen);
584         message->dataLen = dataLen;
585         message->destSession = addrInfo;
586
587         CAResult_t result = CADtlsCacheMsg(message);
588         if (CA_STATUS_OK == result)
589         {
590             if (cacheFlag)
591             {
592                 *cacheFlag = 1;
593             }
594         }
595         else
596         {
597             OIC_LOG(DEBUG, NET_DTLS_TAG, "CADtlsCacheMsg failed!");
598             CAFreeCacheMsg(message);
599         }
600         OIC_LOG_V(DEBUG, NET_DTLS_TAG, "OUT Initiating Dtls session [%d]", result);
601         return result;
602     }
603
604     OICFree(addrInfo);
605
606     if (ret == DTLS_OK)
607     {
608         OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
609         return CA_STATUS_OK;
610     }
611
612     OIC_LOG(ERROR, NET_DTLS_TAG, "OUT FAILURE");
613     return CA_STATUS_FAILED;
614 }
615
616
617 CAResult_t CAAdapterNetDtlsDecrypt(const char *remoteAddress,
618                                    const uint16_t port,
619                                    uint8_t *data,
620                                    uint32_t dataLen,
621                                    eDtlsAdapterType_t adapterType)
622 {
623     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
624
625     stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)OICCalloc(1, sizeof(stCADtlsAddrInfo_t));
626
627     VERIFY_NON_NULL_RET(addrInfo, NET_DTLS_TAG, "calloc failed" , CA_MEMORY_ALLOC_FAILED);
628
629     addrInfo->addr.sin.sin_family = AF_INET;
630     addrInfo->addr.sin.sin_port = htons(port);
631
632     // Conversion from ASCII format to Network format
633     if (inet_aton(remoteAddress, &addrInfo->addr.sin.sin_addr) == 0)
634     {
635         OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to convert from ASCII to Network Address");
636         OICFree(addrInfo);
637         return CA_STATUS_FAILED;
638     }
639     addrInfo->size = sizeof(addrInfo->addr);
640     addrInfo->ifIndex = adapterType;
641
642     eDtlsRet_t ret = CAAdapterNetDtlsDecryptInternal(addrInfo, data, dataLen);
643
644     OICFree(addrInfo);
645     if (DTLS_OK == ret || DTLS_HS_MSG == ret)
646     {
647         OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Successfully Decrypted or Handshake msg recvd [%d]", ret);
648         OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
649         return CA_STATUS_OK;
650     }
651
652     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
653     return CA_STATUS_FAILED;
654 }
655
656