Imported Upstream version 0.9.1
[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
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 ca_mutex g_dtlsContextMutex = NULL;
43
44 /**
45  * @var g_dtlsListMutex
46  * @brief Mutex to synchronize access to DTLS Cache.
47  */
48 static ca_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     ca_mutex_lock(g_dtlsContextMutex);
71     if (NULL == g_caDtlsContext)
72     {
73         OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
74         ca_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     ca_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     ca_mutex_lock(g_dtlsListMutex);
142     if (NULL == g_caDtlsContext)
143     {
144         OIC_LOG(ERROR, NET_DTLS_TAG, "Dtls Context is NULL");
145         ca_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     ca_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     ca_mutex_lock(g_dtlsListMutex);
169     if (NULL == g_caDtlsContext)
170     {
171         OIC_LOG(ERROR, NET_DTLS_TAG, "Dtls Context is NULL");
172         ca_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     ca_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     ca_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     ca_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     ca_mutex_lock(g_dtlsContextMutex);
262     if (NULL == g_caDtlsContext)
263     {
264         OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
265         ca_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     ca_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     CADtlsPskCredsBlob_t *credInfo = NULL;
363
364     // Retrieve the credentials blob from security module
365     g_getCredentialsCallback(&credInfo);
366
367     VERIFY_NON_NULL_RET(credInfo, NET_DTLS_TAG, "credInfo is NULL", -1);
368     if(NULL == credInfo->creds)
369     {
370         OIC_LOG(DEBUG, NET_DTLS_TAG, "credentials are NULL");
371         memset(credInfo, 0, sizeof(CADtlsPskCredsBlob_t));
372         OICFree(credInfo);
373         return -1;
374     }
375
376     if ((type == DTLS_PSK_HINT) || (type == DTLS_PSK_IDENTITY))
377     {
378         if (DTLS_PSK_ID_LEN <= resultLen)
379         {
380             memcpy(result, credInfo->identity, DTLS_PSK_ID_LEN);
381             ret = DTLS_PSK_ID_LEN;
382         }
383     }
384
385     if ((type == DTLS_PSK_KEY) && (desc) && (descLen == DTLS_PSK_PSK_LEN))
386     {
387         // Check if we have the credentials for the device with which we
388         // are trying to perform a handshake
389         int index = 0;
390         for (index = 0; index < credInfo->num; index++)
391         {
392             if (memcmp(desc, credInfo->creds[index].id, DTLS_PSK_ID_LEN) == 0)
393             {
394                 memcpy(result, credInfo->creds[index].psk, DTLS_PSK_PSK_LEN);
395                 ret = DTLS_PSK_PSK_LEN;
396             }
397         }
398     }
399
400     // Erase sensitive data before freeing.
401     memset(credInfo->creds, 0, sizeof(OCDtlsPskCreds) * (credInfo->num));
402     OICFree(credInfo->creds);
403
404     memset(credInfo, 0, sizeof(CADtlsPskCredsBlob_t));
405     OICFree(credInfo);
406     credInfo = NULL;
407
408     return ret;
409 }
410
411 void CADTLSSetAdapterCallbacks(CAPacketReceivedCallback recvCallback,
412                                CAPacketSendCallback sendCallback, eDtlsAdapterType_t type)
413 {
414     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
415     ca_mutex_lock(g_dtlsContextMutex);
416     if (NULL == g_caDtlsContext)
417     {
418         OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
419         ca_mutex_unlock(g_dtlsContextMutex);
420         return;
421     }
422
423     if ((0 <= type) && (MAX_SUPPORTED_ADAPTERS > type))
424     {
425         g_caDtlsContext->adapterCallbacks[type].recvCallback = recvCallback;
426         g_caDtlsContext->adapterCallbacks[type].sendCallback = sendCallback;
427     }
428
429     ca_mutex_unlock(g_dtlsContextMutex);
430
431     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
432 }
433
434 void CADTLSSetCredentialsCallback(CAGetDTLSCredentialsHandler credCallback)
435 {
436     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
437     g_getCredentialsCallback = credCallback;
438     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
439 }
440
441 CAResult_t CAAdapterNetDtlsInit()
442 {
443     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
444
445     if (NULL == g_dtlsContextMutex)
446     {
447         g_dtlsContextMutex = ca_mutex_new();
448         VERIFY_NON_NULL_RET(g_dtlsContextMutex, NET_DTLS_TAG, "malloc failed",
449             CA_MEMORY_ALLOC_FAILED);
450     }
451     else
452     {
453         OIC_LOG(ERROR, NET_DTLS_TAG, "CAAdapterNetDtlsInit done already!");
454         return CA_STATUS_OK;
455     }
456
457     if (NULL == g_dtlsListMutex)
458     {
459         g_dtlsListMutex = ca_mutex_new();
460         if (NULL == g_dtlsListMutex)
461         {
462             OIC_LOG(ERROR, NET_DTLS_TAG, "g_dtlsListMutex malloc failed");
463             ca_mutex_free(g_dtlsContextMutex);
464             return CA_MEMORY_ALLOC_FAILED;
465         }
466     }
467
468     ca_mutex_lock(g_dtlsContextMutex);
469     g_caDtlsContext = (stCADtlsContext_t *)OICCalloc(1, sizeof(stCADtlsContext_t));
470
471     if (NULL == g_caDtlsContext)
472     {
473         OIC_LOG(ERROR, NET_DTLS_TAG, "Context malloc failed");
474         ca_mutex_free(g_dtlsListMutex);
475         ca_mutex_unlock(g_dtlsContextMutex);
476         ca_mutex_free(g_dtlsContextMutex);
477         return CA_MEMORY_ALLOC_FAILED;
478     }
479
480     ca_mutex_lock(g_dtlsListMutex);
481     g_caDtlsContext->cacheList = u_arraylist_create();
482
483     if (NULL == g_caDtlsContext->cacheList)
484     {
485         OIC_LOG(ERROR, NET_DTLS_TAG, "cacheList initialization failed!");
486         ca_mutex_unlock(g_dtlsListMutex);
487         ca_mutex_free(g_dtlsListMutex);
488         ca_mutex_unlock(g_dtlsContextMutex);
489         ca_mutex_free(g_dtlsContextMutex);
490         OICFree(g_caDtlsContext);
491         g_caDtlsContext = NULL;
492         return CA_STATUS_FAILED;
493     }
494     ca_mutex_unlock(g_dtlsListMutex);
495     // Initialize clock, crypto and other global vars in tinyDTLS library
496     dtls_init();
497
498     g_caDtlsContext->dtlsContext = dtls_new_context(g_caDtlsContext);
499
500     if (NULL ==  g_caDtlsContext->dtlsContext)
501     {
502         OIC_LOG(ERROR, NET_DTLS_TAG, "dtls_new_context failed");
503         ca_mutex_unlock(g_dtlsContextMutex);
504         CAAdapterNetDtlsDeInit();
505         return CA_STATUS_FAILED;
506     }
507
508     g_caDtlsContext->callbacks.write = CASendSecureData;
509     g_caDtlsContext->callbacks.read  = CAReadDecryptedPayload;
510     g_caDtlsContext->callbacks.event = CAHandleSecureEvent;
511     g_caDtlsContext->callbacks.get_psk_info = CAGetPskCredentials;
512
513     dtls_set_handler(g_caDtlsContext->dtlsContext, &(g_caDtlsContext->callbacks));
514     ca_mutex_unlock(g_dtlsContextMutex);
515     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
516     return CA_STATUS_OK;
517 }
518
519 void CAAdapterNetDtlsDeInit()
520 {
521     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
522
523     VERIFY_NON_NULL_VOID(g_caDtlsContext, NET_DTLS_TAG, "context is NULL");
524
525     ca_mutex_lock(g_dtlsContextMutex);
526     CAClearCacheList();
527     dtls_free_context(g_caDtlsContext->dtlsContext);
528     g_caDtlsContext->dtlsContext = NULL;
529     OICFree(g_caDtlsContext);
530     g_caDtlsContext = NULL;
531     ca_mutex_unlock(g_dtlsContextMutex);
532
533     ca_mutex_free(g_dtlsContextMutex);
534     g_dtlsContextMutex = NULL;
535     ca_mutex_free(g_dtlsListMutex);
536     g_dtlsListMutex = NULL;
537     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
538 }
539
540 CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress,
541                                    const uint16_t port,
542                                    void *data,
543                                    uint32_t dataLen,
544                                    uint8_t *cacheFlag,
545                                    eDtlsAdapterType_t adapterType)
546 {
547
548     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
549
550     VERIFY_NON_NULL_RET(remoteAddress, NET_DTLS_TAG,"Param remoteAddress is NULL",CA_STATUS_FAILED);
551
552     VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL" , CA_STATUS_FAILED);
553
554     if (0 == dataLen)
555     {
556         OIC_LOG_V(ERROR, NET_DTLS_TAG, "dataLen is less than or equal zero [%d]", dataLen);
557         return CA_STATUS_FAILED;
558     }
559
560     OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Data to be encrypted dataLen [%d]", dataLen);
561
562     stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)OICCalloc(1, sizeof(stCADtlsAddrInfo_t));
563
564     VERIFY_NON_NULL_RET(addrInfo, NET_DTLS_TAG, "malloc failed" , CA_MEMORY_ALLOC_FAILED);
565
566     addrInfo->addr.sin.sin_family = AF_INET;
567     addrInfo->addr.sin.sin_port = htons(port);
568     // Conversion from ASCII format to Network format
569     if (inet_aton(remoteAddress, &addrInfo->addr.sin.sin_addr) == 0)
570     {
571         OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to convert from ASCII to Network Address");
572         OICFree(addrInfo);
573         return CA_STATUS_FAILED;
574     }
575     addrInfo->size = sizeof(addrInfo->addr);
576     addrInfo->ifIndex = adapterType;
577
578     eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(addrInfo, data, dataLen);
579     if (ret == DTLS_SESSION_INITIATED)
580     {
581         stCACacheMessage_t *message = (stCACacheMessage_t *)OICCalloc(1, sizeof(stCACacheMessage_t));
582         if (NULL == message)
583         {
584             OIC_LOG(ERROR, NET_DTLS_TAG, "calloc failed!");
585             OICFree(addrInfo);
586             return CA_MEMORY_ALLOC_FAILED;
587         }
588
589         message->data = (uint8_t *)OICCalloc(dataLen + 1, sizeof(uint8_t));
590         if (NULL == message->data)
591         {
592             OIC_LOG(ERROR, NET_DTLS_TAG, "calloc failed!");
593             OICFree(addrInfo);
594             OICFree(message);
595             return CA_MEMORY_ALLOC_FAILED;
596         }
597         memcpy(message->data, data, dataLen);
598         message->dataLen = dataLen;
599         message->destSession = addrInfo;
600
601         CAResult_t result = CADtlsCacheMsg(message);
602         if (CA_STATUS_OK == result)
603         {
604             if (cacheFlag)
605             {
606                 *cacheFlag = 1;
607             }
608         }
609         else
610         {
611             OIC_LOG(DEBUG, NET_DTLS_TAG, "CADtlsCacheMsg failed!");
612             CAFreeCacheMsg(message);
613         }
614         OIC_LOG_V(DEBUG, NET_DTLS_TAG, "OUT Initiating Dtls session [%d]", result);
615         return result;
616     }
617
618     OICFree(addrInfo);
619
620     if (ret == DTLS_OK)
621     {
622         OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
623         return CA_STATUS_OK;
624     }
625
626     OIC_LOG(ERROR, NET_DTLS_TAG, "OUT FAILURE");
627     return CA_STATUS_FAILED;
628 }
629
630
631 CAResult_t CAAdapterNetDtlsDecrypt(const char *remoteAddress,
632                                    const uint16_t port,
633                                    uint8_t *data,
634                                    uint32_t dataLen,
635                                    eDtlsAdapterType_t adapterType)
636 {
637     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
638
639     stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)OICCalloc(1, sizeof(stCADtlsAddrInfo_t));
640
641     VERIFY_NON_NULL_RET(addrInfo, NET_DTLS_TAG, "calloc failed" , CA_MEMORY_ALLOC_FAILED);
642
643     addrInfo->addr.sin.sin_family = AF_INET;
644     addrInfo->addr.sin.sin_port = htons(port);
645
646     // Conversion from ASCII format to Network format
647     if (inet_aton(remoteAddress, &addrInfo->addr.sin.sin_addr) == 0)
648     {
649         OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to convert from ASCII to Network Address");
650         OICFree(addrInfo);
651         return CA_STATUS_FAILED;
652     }
653     addrInfo->size = sizeof(addrInfo->addr);
654     addrInfo->ifIndex = adapterType;
655
656     eDtlsRet_t ret = CAAdapterNetDtlsDecryptInternal(addrInfo, data, dataLen);
657
658     OICFree(addrInfo);
659     if (DTLS_OK == ret || DTLS_HS_MSG == ret)
660     {
661         OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Successfully Decrypted or Handshake msg recvd [%d]", ret);
662         OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
663         return CA_STATUS_OK;
664     }
665
666     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
667     return CA_STATUS_FAILED;
668 }
669
670