TLS support
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / adapter_util / ca_adapter_net_tls.c
1 /******************************************************************
2  *
3  * Copyright 2016 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
21 #define _GNU_SOURCE
22
23 #include <stddef.h>
24 #include "ca_adapter_net_tls.h"
25 #include "cacommon.h"
26 #include "caipinterface.h"
27 #include "oic_malloc.h"
28 #include "pkix/byte_array.h"
29 #include "camutex.h"
30
31 // headers required for mbed TLS
32 #include "mbedtls/platform.h"
33 #include "mbedtls/ssl.h"
34 #include "mbedtls/entropy.h"
35 #include "mbedtls/ctr_drbg.h"
36 #include "mbedtls/pkcs12.h"
37 #include "mbedtls/ssl_internal.h"
38
39 #ifndef NDEBUG
40 #include "mbedtls/debug.h"
41 #include "mbedtls/version.h"
42 #endif
43
44 #ifdef __unix__
45 #include <sys/types.h>
46 #include <sys/stat.h>
47 #include <fcntl.h>
48 #include <unistd.h>
49 #endif
50
51 #include "pkix/byte_array.h"
52
53 /**
54  * @def MBED_TLS_VERSION_LEN
55  * @brief mbedTLS version string length
56  */
57 #define MBED_TLS_VERSION_LEN (16)
58 /**
59  * @def SEED
60  * @brief Seed for initialization RNG
61  */
62 #define SEED "IOTIVITY_RND"
63 /**
64  * @def UUID_PREFIX
65  * @brief uuid prefix in certificate subject field
66  */
67 #define UUID_PREFIX "uuid:"
68
69 /**
70  * @def NET_TLS_TAG
71  * @brief Logging tag for module name
72  */
73 #define NET_TLS_TAG "OIC_CA_NET_TLS"
74 /**
75  * @def MBED_TLS_TAG
76  * @brief Logging tag for mbedTLS library
77  */
78 #define MBED_TLS_TAG "OIC_MBED_TLS"
79 /**
80  * @def MMBED_TLS_DEBUG_LEVEL
81  * @brief Logging level for mbedTLS library
82  */
83 #define MBED_TLS_DEBUG_LEVEL (4) // Verbose
84
85 /**
86  * @def TLS_MSG_BUF_LEN
87  * @brief Buffer size for TLS record. A single TLS record may be up to 16384 octets in length
88  */
89
90 #define TLS_MSG_BUF_LEN (16384)
91 /**
92  * @def PSK_LENGTH
93  * @brief PSK keys max length
94  */
95 #define PSK_LENGTH (256/8)
96 /**
97  * @def UUID_LENGTHPSK_LENGTH
98  * @brief Identity max length
99  */
100 #define UUID_LENGTH (128/8)
101 /**
102  * @def MASTER_SECRET_LEN
103  * @brief TLS master secret length
104  */
105 #define MASTER_SECRET_LEN (48)
106
107 #define TLS_CLOSE_NOTIFY(peer, ret)                                                                \
108 do                                                                                                 \
109 {                                                                                                  \
110     ret = mbedtls_ssl_close_notify(&peer->ssl);                                                    \
111 } while (MBEDTLS_ERR_SSL_WANT_WRITE == ret)
112
113 #define TLS_RET_HANDSHAKE_RES(peer)                                                                \
114 if (g_tlsHandshakeCallback)                                                                        \
115 {                                                                                                  \
116     CAErrorInfo_t errorInfo = {.result = CA_STATUS_FAILED};                                        \
117     g_tlsHandshakeCallback(&peer->sep.endpoint, &errorInfo);                                       \
118 }
119
120 #define TLS_CHECK_HANDSHAKE_FAIL(peer, ret, str, mutex, error)                                     \
121 if (0 != ret && MBEDTLS_ERR_SSL_WANT_READ != ret &&  MBEDTLS_ERR_SSL_WANT_WRITE != ret)            \
122 {                                                                                                  \
123     OIC_LOG_V(ERROR, NET_TLS_TAG, "%s: -0x%x", str, -ret);                                         \
124     TLS_CLOSE_NOTIFY(peer, ret);                                                                   \
125     TLS_RET_HANDSHAKE_RES(peer);                                                                   \
126     removePeerFromList(&peer->sep.endpoint);                                                       \
127     if (mutex)                                                                                     \
128     {                                                                                              \
129         ca_mutex_unlock(g_tlsContextMutex);                                                        \
130     }                                                                                              \
131     return error;                                                                                  \
132 }
133
134 typedef enum
135 {
136     ADAPTER_TLS_RSA_WITH_AES_256_CBC_SHA,
137     ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
138     ADAPTER_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA_256,
139     ADAPTER_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
140     ADAPTER_CIPHER_MAX
141 } AdapterCipher_t;
142
143 typedef enum
144 {
145     ADAPTER_CURVE_SECP256R1,
146     ADAPTER_CURVE_MAX
147 } AdapterCurve_t;
148
149 int tlsCipher[ADAPTER_CIPHER_MAX][2] =
150 {
151     {MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, 0},
152     {MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, 0},
153     {MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256, 0},
154     {MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, 0}
155 };
156
157 mbedtls_ecp_group_id curve[ADAPTER_CURVE_MAX][2] =
158 {
159     {MBEDTLS_ECP_DP_SECP256R1, 0}
160 };
161
162 //TODO add description
163 static PkiInfo_t g_pkiInfo = {{NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}};
164
165 #ifndef NDEBUG
166 /**
167  * Pass a message to the OIC logger.
168  *
169  * @param[in] ctx  opaque context for the callback
170  * @param[in] level  debug level
171  * @param[in] file  file name
172  * @param[in] line  line number
173  * @param[in] str  message
174  */
175 static void debugTls(void *ctx, int level, const char *file, int line, const char *str)
176 {
177     ((void) level);
178     ((void) file);
179     ((void) line);
180
181     OIC_LOG_V(DEBUG, MBED_TLS_TAG, "%s", str);
182     fflush((FILE *) ctx);
183 }
184 #endif
185
186 /**
187  * structure to holds the information of cache message and address info.
188  */
189 typedef ByteArray TlsCacheMessage_t;
190
191
192 /**
193  * Data structure for holding the send and recv callbacks.
194  */
195 typedef struct TlsCallBacks
196 {
197     CAPacketReceivedCallback recvCallback;  /**< Callback used to send data to upper layer. */
198     CAPacketSendCallback sendCallback;      /**< Callback used to send data to socket layer. */
199 } TlsCallbacks_t;
200
201 /**
202  * Data structure for holding the mbedTLS interface related info.
203  */
204 typedef struct TlsContext
205 {
206     u_arraylist_t *peerList;         /**< peer list which holds the mapping between
207                                               peer id, it's n/w address and mbedTLS context. */
208     mbedtls_entropy_context entropy;
209     mbedtls_ctr_drbg_context rnd;
210     mbedtls_x509_crt ca;
211     mbedtls_x509_crt crt;
212     mbedtls_pk_context pkey;
213     mbedtls_ssl_config clientConf;
214     mbedtls_ssl_config serverConf;
215     AdapterCipher_t cipher;
216     TlsCallbacks_t adapterCallbacks[MAX_SUPPORTED_ADAPTERS];
217     mbedtls_x509_crl crl;
218
219 } TlsContext_t;
220
221 /**
222  * @var g_caTlsContext
223  * @brief global context which holds tls context and cache list information.
224  */
225 static TlsContext_t * g_caTlsContext = NULL;
226
227 /**
228  * @var g_getCredentialsCallback
229  * @brief callback to get TLS credentials (same as for DTLS)
230  */
231 static CAGetDTLSPskCredentialsHandler g_getCredentialsCallback = NULL;
232
233 /**
234  * @var g_getPkixInfoCallback
235  *
236  * @brief callback to get X.509-based Public Key Infrastructure
237  */
238 static CAgetPkixInfoHandler g_getPkixInfoCallback = NULL;
239
240 /**
241  * @var g_dtlsContextMutex
242  * @brief Mutex to synchronize access to g_caTlsContext.
243  */
244 static ca_mutex g_tlsContextMutex = NULL;
245
246 /**
247  * @var g_tlsHandshakeCallback
248  * @brief callback to deliver the TLS handshake result
249  */
250 static CAErrorCallback g_tlsHandshakeCallback = NULL;
251
252 /**
253  * Data structure for holding the data to be rceived.
254  */
255 typedef struct TlsRecBuf
256 {
257     uint8_t * buff;
258     size_t len;
259     size_t loaded;
260 } TlsRecBuf_t;
261
262 /**
263  * Data structure for holding the data related to endpoint
264  * and TLS session.
265  */
266 typedef struct TlsEndPoint
267 {
268     mbedtls_ssl_context ssl;
269     CASecureEndpoint_t sep;
270     u_arraylist_t * cacheList;
271     TlsRecBuf_t recBuf;
272     uint8_t master[MASTER_SECRET_LEN];
273 } TlsEndPoint_t;
274
275 void CAsetTlsCredentialsCallback(CAGetDTLSPskCredentialsHandler credCallback)
276 {
277     // TODO Does this method needs protection of tlsContextMutex?
278     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
279     g_getCredentialsCallback = credCallback;
280     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
281 }
282
283 void CAsetPkixInfoCallback(CAgetPkixInfoHandler infoCallback)
284 {
285     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
286     g_getPkixInfoCallback = infoCallback;
287     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
288 }
289 /**
290  * Write callback.
291  *
292  * @param[in]  tep    TLS endpoint
293  * @param[in]  data    message
294  * @param[in]  dataLen    message length
295  *
296  * @return  message length
297  */
298 static int sendTls(void * tep, const unsigned char * data, size_t dataLen)
299 {
300     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
301     VERIFY_NON_NULL_RET(tep, NET_TLS_TAG, "secure endpoint is NULL", 0);
302     VERIFY_NON_NULL_RET(data, NET_TLS_TAG, "data is NULL", 0);
303     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Data len: %zu", dataLen);
304
305     g_caTlsContext->adapterCallbacks[0].sendCallback(&(((TlsEndPoint_t * )tep)->sep.endpoint),
306             (const void *) data, (uint32_t) dataLen);
307     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
308     return dataLen;
309 }
310 /**
311  * Read callback.
312  *
313  * @param[in]  tep    TLS endpoint
314  * @param[in]  data    message
315  * @param[in]  dataLen    message length
316  *
317  * @return  read length
318  */
319 static int recvTls(void * tep, unsigned char * data, size_t dataLen)
320 {
321     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
322     VERIFY_NON_NULL_RET(tep, NET_TLS_TAG, "endpoint is NULL", 0);
323     VERIFY_NON_NULL_RET(data, NET_TLS_TAG, "data is NULL", 0);
324
325     TlsRecBuf_t *recBuf = &((TlsEndPoint_t *)tep)->recBuf;
326     size_t retLen = (recBuf->len > recBuf->loaded ? recBuf->len - recBuf->loaded : 0);
327     retLen = (retLen < dataLen ? retLen : dataLen);
328
329     memcpy(data, recBuf->buff + recBuf->loaded, retLen);
330     recBuf->loaded += retLen;
331
332     OIC_LOG_BUFFER(DEBUG, NET_TLS_TAG, data, retLen);
333     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
334     return (int)retLen;
335 }
336
337 //TODO add description
338 static int parseChain(mbedtls_x509_crt * crt, const unsigned char * buf, int buflen)
339 {
340     VERIFY_NON_NULL_RET(crt, NET_TLS_TAG, "Param crt is NULL" , -1);
341     VERIFY_NON_NULL_RET(buf, NET_TLS_TAG, "Param buf is NULL" , -1);
342
343     int pos = 0;
344     int len = 0;
345     int ret = 0;
346     while (pos < buflen)
347     {
348         if (0x30 == buf[pos] && 0x82 == buf[pos + 1] && pos + 3 < buflen)
349         {
350             len = (((int) buf[pos+2]) << 8) | buf[pos+3];
351             if (pos + len < buflen)
352             {
353                 ret = mbedtls_x509_crt_parse_der(crt, buf+pos, len+4);
354                 if( 0 != ret)
355                 {
356                     OIC_LOG_V(ERROR, NET_TLS_TAG, "mbedtls_x509_crt_parse returned -0x%x", -ret);
357                     return -1;
358                 }
359             }
360             pos += len + 4;
361         }
362         else
363         {
364              OIC_LOG_V(ERROR, NET_TLS_TAG, "mbedtls_x509_crt_parse returned -0x%x", -ret);
365              return -1;
366         }
367     }
368     return 0;
369 }
370 //TODO add description
371 static int loadX509()
372 {
373     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
374     VERIFY_NON_NULL_RET(g_getPkixInfoCallback, NET_TLS_TAG, "PKIX info callback is NULL", -1);
375
376     g_getPkixInfoCallback(&g_pkiInfo);
377
378     int ret = parseChain(&g_caTlsContext->ca, g_pkiInfo.ca.data, g_pkiInfo.ca.len);
379     if(0 != ret)
380     {
381         OIC_LOG(ERROR, NET_TLS_TAG, "CA chain parsing error");
382         OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
383         return -1;
384     }
385     ret = parseChain(&g_caTlsContext->crt, g_pkiInfo.crt.data, g_pkiInfo.crt.len);
386     if(0 != ret)
387     {
388         OIC_LOG(ERROR, NET_TLS_TAG, "Own certificate chain parsing error");
389         OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
390         return -1;
391     }
392
393     ret =  mbedtls_pk_parse_key(&g_caTlsContext->pkey, g_pkiInfo.key.data, g_pkiInfo.key.len,
394                                                                                            NULL, 0);
395     if(0 != ret)
396     {
397         OIC_LOG(ERROR, NET_TLS_TAG, "Key parsing error");
398         OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
399         return -1;
400     }
401     ret = mbedtls_x509_crl_parse_der(&g_caTlsContext->crl, g_pkiInfo.crl.data, g_pkiInfo.crl.len);
402     if(0 != ret)
403     {
404         OIC_LOG(ERROR, NET_TLS_TAG, "CRL parsing error");
405         OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
406         //TODO
407         //return -1;
408     }
409
410     mbedtls_ssl_conf_ca_chain(&g_caTlsContext->clientConf, &g_caTlsContext->ca, NULL);
411     mbedtls_ssl_conf_ca_chain(&g_caTlsContext->serverConf, &g_caTlsContext->ca, NULL);
412
413     ret = mbedtls_ssl_conf_own_cert(&g_caTlsContext->serverConf, &g_caTlsContext->crt,
414                                                                              &g_caTlsContext->pkey);
415     if(0 != ret)
416     {
417         OIC_LOG(ERROR, NET_TLS_TAG, "Certificate parsing error");
418         OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
419         return -1;
420     }
421     ret = mbedtls_ssl_conf_own_cert( &g_caTlsContext->clientConf, &g_caTlsContext->crt,
422                                                                              &g_caTlsContext->pkey);
423     if(0 != ret)
424     {
425         OIC_LOG(ERROR, NET_TLS_TAG, "Certificate parsing error");
426         OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
427         return -1;
428     }
429
430     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
431     return 0;
432 }
433
434 /*
435  * PSK callback.
436  *
437  * @param[in]  notUsed     opaque context
438  * @param[in]  ssl    mbedTLS context
439  * @param[in]  desc    identity
440  * @param[in]  descLen    identity length
441  *
442  * @return  0 on success any other return value will result in a denied PSK identity
443  */
444 static int getTlsCredentialsCallback(void * notUsed, mbedtls_ssl_context * ssl,
445                                      const unsigned char * desc, size_t descLen)
446 {
447     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
448     VERIFY_NON_NULL_RET(g_getCredentialsCallback, NET_TLS_TAG, "Credential callback s NULL", -1);
449     VERIFY_NON_NULL_RET(ssl, NET_TLS_TAG, "ssl pointer is NULL", -1);
450     VERIFY_NON_NULL_RET(desc, NET_TLS_TAG, "desc pointer is NULL", -1);
451     if (descLen > CA_MAX_ENDPOINT_IDENTITY_LEN)
452     {
453         OIC_LOG(ERROR, NET_TLS_TAG, "desc too long!");
454         return -1;
455     }
456     (void) notUsed;
457     uint8_t keyBuf[PSK_LENGTH] = {0};
458
459     // Retrieve the credentials blob from security module
460     int ret = g_getCredentialsCallback(2, desc, descLen, keyBuf, PSK_LENGTH);
461     if (ret > 0)
462     {
463         memcpy(((TlsEndPoint_t *) ssl)->sep.identity.id, desc, descLen);
464         ((TlsEndPoint_t *) ssl)->sep.identity.id_length = descLen;
465
466         OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
467         return(mbedtls_ssl_set_hs_psk(ssl, keyBuf, PSK_LENGTH));
468     }
469     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
470     return -1;
471 }
472 /**
473  * Gets session corresponding for endpoint.
474  *
475  * @param[in]  peer    remote address
476  *
477  * @return  TLS session or NULL
478  */
479 static TlsEndPoint_t *getTlsPeer(const CAEndpoint_t *peer)
480 {
481     uint32_t listIndex = 0;
482     uint32_t listLength = 0;
483     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
484     VERIFY_NON_NULL_RET(peer, NET_TLS_TAG, "TLS peer is NULL", NULL);
485
486     TlsEndPoint_t *tep = NULL;
487     listLength = u_arraylist_length(g_caTlsContext->peerList);
488     for (listIndex = 0; listIndex < listLength; listIndex++)
489     {
490         tep = (TlsEndPoint_t *) u_arraylist_get(g_caTlsContext->peerList, listIndex);
491         if (NULL == tep)
492         {
493             continue;
494         }
495         OIC_LOG_V(DEBUG, NET_TLS_TAG, "Compare [%s] and [%s]", peer->addr, tep->sep.endpoint.addr);
496         if((0 == strncmp(peer->addr, tep->sep.endpoint.addr, MAX_ADDR_STR_SIZE_CA))
497                 && (peer->port == tep->sep.endpoint.port))
498         {
499             OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
500             return tep;
501         }
502     }
503     OIC_LOG(DEBUG, NET_TLS_TAG, "Return NULL");
504     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
505     return NULL;
506 }
507 /**
508  * Deletes cached message.
509  *
510  * @param[in]  msg    message
511  */
512 static void deleteTlsCacheMessage(TlsCacheMessage_t * msg)
513 {
514     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
515     VERIFY_NON_NULL_VOID(msg, NET_TLS_TAG, "msg");
516
517     OICFree(msg->data);
518     OICFree(msg);
519
520     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
521 }
522 /**
523  * Deletes cached message list.
524  *
525  * @param[in] cacheList  list of cached messages
526  */
527 static void deleteCacheList(u_arraylist_t * cacheList)
528 {
529     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
530     VERIFY_NON_NULL_VOID(cacheList, NET_TLS_TAG, "cacheList");
531     uint32_t listIndex = 0;
532     uint32_t listLength = 0;
533
534     listLength = u_arraylist_length(cacheList);
535     for (listIndex = 0; listIndex < listLength; listIndex++)
536     {
537         TlsCacheMessage_t * msg = (TlsCacheMessage_t *) u_arraylist_get(cacheList, listIndex);
538         if (NULL != msg)
539         {
540             deleteTlsCacheMessage(msg);
541         }
542     }
543     u_arraylist_free(&cacheList);
544
545     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
546 }
547 /**
548  * Deletes endpoint with session.
549  *
550  * @param[in]  tep    endpoint with session info
551  */
552 static void deleteTlsEndPoint(TlsEndPoint_t * tep)
553 {
554     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
555     VERIFY_NON_NULL_VOID(tep, NET_TLS_TAG, "tep");
556
557     mbedtls_ssl_free(&tep->ssl);
558     deleteCacheList(tep->cacheList);
559     OICFree(tep);
560     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
561 }
562 /**
563  * Removes endpoint session from list.
564  *
565  * @param[in]  endpoint    remote address
566  */
567 static void removePeerFromList(CAEndpoint_t * endpoint)
568 {
569     uint32_t listLength = u_arraylist_length(g_caTlsContext->peerList);
570     VERIFY_NON_NULL_VOID(endpoint, NET_TLS_TAG, "endpoint");
571     for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
572     {
573         TlsEndPoint_t * tep = (TlsEndPoint_t *)u_arraylist_get(g_caTlsContext->peerList,listIndex);
574         if (NULL == tep)
575         {
576             continue;
577         }
578         if(0 == strncmp(endpoint->addr, tep->sep.endpoint.addr, MAX_ADDR_STR_SIZE_CA)
579                 && (endpoint->port == tep->sep.endpoint.port))
580         {
581             u_arraylist_remove(g_caTlsContext->peerList, listIndex);
582             deleteTlsEndPoint(tep);
583             return;
584         }
585     }
586 }
587 /**
588  * Deletes session list.
589  */
590 static void deletePeerList()
591 {
592     uint32_t listLength = u_arraylist_length(g_caTlsContext->peerList);
593     for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
594     {
595         TlsEndPoint_t * tep = (TlsEndPoint_t *)u_arraylist_get(g_caTlsContext->peerList,listIndex);
596         if (NULL == tep)
597         {
598             continue;
599         }
600         deleteTlsEndPoint(tep);
601     }
602     u_arraylist_free(&g_caTlsContext->peerList);
603 }
604
605 CAResult_t CAcloseTlsConnection(const CAEndpoint_t *endpoint)
606 {
607     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
608     VERIFY_NON_NULL_RET(endpoint, NET_TLS_TAG, "Param endpoint is NULL" , CA_STATUS_INVALID_PARAM);
609
610     ca_mutex_lock(g_tlsContextMutex);
611     if (NULL == g_caTlsContext)
612     {
613         OIC_LOG(ERROR, NET_TLS_TAG, "Context is NULL");
614         ca_mutex_unlock(g_tlsContextMutex);
615         return CA_STATUS_FAILED;
616     }
617     TlsEndPoint_t * tep = getTlsPeer(endpoint);
618     if (NULL == tep)
619     {
620         OIC_LOG(ERROR, NET_TLS_TAG, "Session does not exist");
621         ca_mutex_unlock(g_tlsContextMutex);
622         return CA_STATUS_FAILED;
623     }
624     /* No error checking, the connection might be closed already */
625     int ret = 0;
626     do
627     {
628         ret = mbedtls_ssl_close_notify(&tep->ssl);
629     }
630     while (MBEDTLS_ERR_SSL_WANT_WRITE == ret);
631
632     removePeerFromList(&tep->sep.endpoint);
633     ca_mutex_unlock(g_tlsContextMutex);
634
635     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
636     return CA_STATUS_OK;
637 }
638 /**
639  * Creates session for endpoint.
640  *
641  * @param[in]  endpoint    remote address
642  * @param[in]  config    mbedTLS configuration info
643  *
644  * @return  TLS endpoint or NULL
645  */
646 static TlsEndPoint_t * newTlsEndPoint(const CAEndpoint_t * endpoint, mbedtls_ssl_config * config)
647 {
648     TlsEndPoint_t * tep = NULL;
649     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
650     VERIFY_NON_NULL_RET(endpoint, NET_TLS_TAG, "endpoint", NULL);
651     VERIFY_NON_NULL_RET(config, NET_TLS_TAG, "config", NULL);
652
653     tep = (TlsEndPoint_t *) OICCalloc(1, sizeof (TlsEndPoint_t));
654     if (NULL == tep)
655     {
656         OIC_LOG(ERROR, NET_TLS_TAG, "Malloc failed!");
657         return NULL;
658     }
659
660     tep->sep.endpoint = *endpoint;
661     tep->sep.endpoint.flags |= CA_SECURE;
662
663     if(0 != mbedtls_ssl_setup( &tep->ssl, config))
664     {
665         OIC_LOG(ERROR, NET_TLS_TAG, "Setup failed");
666         OICFree(tep);
667         OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
668         return NULL;
669     }
670
671     mbedtls_ssl_set_bio(&tep->ssl, tep, sendTls, recvTls, NULL);
672
673     tep->cacheList = u_arraylist_create();
674     if (NULL == tep->cacheList)
675     {
676         OIC_LOG(ERROR, NET_TLS_TAG, "cacheList initialization failed!");
677         mbedtls_ssl_free(&tep->ssl);
678         OICFree(tep);
679         OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
680         return NULL;
681     }
682     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
683     return tep;
684 }
685 /**
686  * Initializes PSK identity.
687  *
688  * @param[out]  config    client/server config to be updated
689  *
690  * @return  0 on success or -1 on error
691  */
692 static int initPskIdentity(mbedtls_ssl_config * config)
693 {
694     uint8_t idBuf[UUID_LENGTH] = {0};
695     VERIFY_NON_NULL_RET(config, NET_TLS_TAG, "Param config is NULL" , -1);
696
697     if (0 > g_getCredentialsCallback(CA_DTLS_PSK_IDENTITY, NULL, 0, idBuf, UUID_LENGTH))
698     {
699         OIC_LOG(ERROR, NET_TLS_TAG, "Identity not found");
700         return -1;
701     }
702     if (0 != mbedtls_ssl_conf_psk(config, idBuf, 0, idBuf, UUID_LENGTH))
703     {
704         OIC_LOG(ERROR, NET_TLS_TAG, "Identity initialization failed!");
705         return -1;
706     }
707     return 0;
708 }
709 /**
710  * Initiate TLS handshake with endpoint.
711  *
712  * @param[in]  endpoint    remote address
713  *
714  * @return  TLS endpoint or NULL
715  */
716 static TlsEndPoint_t * initiateTlsHandshake(const CAEndpoint_t *endpoint)
717 {
718     int ret = 0;
719     TlsEndPoint_t * tep = NULL;
720
721     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
722     VERIFY_NON_NULL_RET(endpoint, NET_TLS_TAG, "Param endpoint is NULL" , NULL);
723
724     // Retrieve the credentials blob from security module
725     if (ADAPTER_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 == g_caTlsContext->cipher &&
726             0 != initPskIdentity(&g_caTlsContext->clientConf))
727     {
728         OIC_LOG(ERROR, NET_TLS_TAG, "Client PSK identity initialization failed!");
729         return NULL;
730     }
731
732     tep = newTlsEndPoint(endpoint, &g_caTlsContext->clientConf);
733     if (NULL == tep)
734     {
735         OIC_LOG(ERROR, NET_TLS_TAG, "Malloc failed!");
736         return NULL;
737     }
738
739     if (ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 == g_caTlsContext->cipher ||
740         ADAPTER_TLS_RSA_WITH_AES_256_CBC_SHA == g_caTlsContext->cipher)
741     {
742         ret = loadX509();
743         if (0 != ret)
744         {
745             OIC_LOG(ERROR, NET_TLS_TAG, "Failed to init X.509");
746             deleteTlsEndPoint(tep);
747             return NULL;
748         }
749     }
750
751     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Add %s:%d", tep->sep.endpoint.addr, tep->sep.endpoint.port);
752     ret = u_arraylist_add(g_caTlsContext->peerList, (void *) tep);
753     if (!ret)
754     {
755         OIC_LOG(ERROR, NET_TLS_TAG, "u_arraylist_add failed!");
756         deleteTlsEndPoint(tep);
757         return NULL;
758     }
759
760     while (MBEDTLS_SSL_HANDSHAKE_OVER > tep->ssl.state)
761     {
762         ret = mbedtls_ssl_handshake_step(&tep->ssl);
763         if (MBEDTLS_ERR_SSL_CONN_EOF == ret)
764         {
765             break;
766         }
767         TLS_CHECK_HANDSHAKE_FAIL(tep, ret, "Handshake error", 0, NULL);
768     }
769     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
770     return tep;
771 }
772
773 void CAdeinitTlsAdapter()
774 {
775     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
776
777     VERIFY_NON_NULL_VOID(g_caTlsContext, NET_TLS_TAG, "context is NULL");
778     VERIFY_NON_NULL_VOID(g_tlsContextMutex, NET_TLS_TAG, "context mutex is NULL");
779
780     //Lock tlsContext mutex
781     ca_mutex_lock(g_tlsContextMutex);
782
783     // Clear all lists
784     deletePeerList();
785
786     // De-initialize mbedTLS
787     mbedtls_x509_crt_free(&g_caTlsContext->crt);
788     mbedtls_pk_free(&g_caTlsContext->pkey);
789     mbedtls_ssl_config_free(&g_caTlsContext->clientConf);
790     mbedtls_ssl_config_free(&g_caTlsContext->serverConf);
791     mbedtls_ctr_drbg_free(&g_caTlsContext->rnd);
792     mbedtls_entropy_free(&g_caTlsContext->entropy);
793
794     // De-initialize tls Context
795     OICFree(g_caTlsContext);
796     g_caTlsContext = NULL;
797
798     // Unlock tlsContext mutex and de-initialize it
799     ca_mutex_unlock(g_tlsContextMutex);
800     ca_mutex_free(g_tlsContextMutex);
801     g_tlsContextMutex = NULL;
802
803     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s ", __func__);
804 }
805
806 CAResult_t CAinitTlsAdapter()
807 {
808     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
809
810     // Initialize mutex for tlsContext
811     if (NULL == g_tlsContextMutex)
812     {
813         g_tlsContextMutex = ca_mutex_new();
814         VERIFY_NON_NULL_RET(g_tlsContextMutex, NET_TLS_TAG, "malloc failed",
815                             CA_MEMORY_ALLOC_FAILED);
816     }
817     else
818     {
819         OIC_LOG(ERROR, NET_TLS_TAG, "CAAdapterNettlsInit done already!");
820         return CA_STATUS_OK;
821     }
822
823     // Lock tlsContext mutex and create tlsContext
824     ca_mutex_lock(g_tlsContextMutex);
825     g_caTlsContext = (TlsContext_t *)OICCalloc(1, sizeof(TlsContext_t));
826
827     if (NULL == g_caTlsContext)
828     {
829         OIC_LOG(ERROR, NET_TLS_TAG, "Context malloc failed");
830         ca_mutex_unlock(g_tlsContextMutex);
831         ca_mutex_free(g_tlsContextMutex);
832         g_tlsContextMutex = NULL;
833         return CA_MEMORY_ALLOC_FAILED;
834     }
835
836     // Create peer list
837     g_caTlsContext->peerList = u_arraylist_create();
838
839     if(NULL == g_caTlsContext->peerList)
840     {
841         OIC_LOG(ERROR, NET_TLS_TAG, "peerList initialization failed!");
842         OICFree(g_caTlsContext);
843         g_caTlsContext = NULL;
844         ca_mutex_unlock(g_tlsContextMutex);
845         ca_mutex_free(g_tlsContextMutex);
846         g_tlsContextMutex = NULL;
847         return CA_STATUS_FAILED;
848     }
849
850     /* Initialize TLS library
851      */
852 #ifndef NDEBUG
853     char version[MBED_TLS_VERSION_LEN];
854     mbedtls_version_get_string(version);
855     OIC_LOG_V(INFO, NET_TLS_TAG, "mbed TLS version: %s", version);
856 #endif
857
858     /* Entropy settings
859      */
860     mbedtls_entropy_init(&g_caTlsContext->entropy);
861     mbedtls_ctr_drbg_init(&g_caTlsContext->rnd);
862
863 #ifdef __unix__
864     unsigned char seed[sizeof(SEED)] = {0};
865     int urandomFd = -2;
866     urandomFd = open("/dev/urandom", O_RDONLY);
867     if(urandomFd == -1)
868     {
869         OIC_LOG(ERROR, NET_TLS_TAG, "Fails open /dev/urandom!");
870         ca_mutex_unlock(g_tlsContextMutex);
871         CAdeinitTlsAdapter();
872         return CA_STATUS_FAILED;
873     }
874     if(0 > read(urandomFd, seed, sizeof(seed)))
875     {
876         OIC_LOG(ERROR, NET_TLS_TAG, "Fails read from /dev/urandom!");
877         close(urandomFd);
878         ca_mutex_unlock(g_tlsContextMutex);
879         CAdeinitTlsAdapter();
880         return CA_STATUS_FAILED;
881     }
882     close(urandomFd);
883
884 #else
885     unsigned char * seed = (unsigned char*) SEED;
886 #endif
887     if(0 != mbedtls_ctr_drbg_seed(&g_caTlsContext->rnd, mbedtls_entropy_func,
888                                   &g_caTlsContext->entropy, seed, sizeof(SEED)))
889     {
890         OIC_LOG(ERROR, NET_TLS_TAG, "Seed initialization failed!");
891         ca_mutex_unlock(g_tlsContextMutex);
892         CAdeinitTlsAdapter();
893         return CA_STATUS_FAILED;
894     }
895     mbedtls_ctr_drbg_set_prediction_resistance(&g_caTlsContext->rnd, MBEDTLS_CTR_DRBG_PR_OFF);
896
897     /* Client SSL configuration
898      */
899     mbedtls_ssl_config_init(&g_caTlsContext->clientConf);
900     if (mbedtls_ssl_config_defaults(&g_caTlsContext->clientConf, MBEDTLS_SSL_IS_CLIENT,
901                                     MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) != 0)
902     {
903         OIC_LOG(ERROR, NET_TLS_TAG, "Client config initialization failed!");
904         ca_mutex_unlock(g_tlsContextMutex);
905         CAdeinitTlsAdapter();
906         return CA_STATUS_FAILED;
907     }
908
909     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
910
911     mbedtls_ssl_conf_psk_cb(&g_caTlsContext->clientConf, getTlsCredentialsCallback, NULL);
912     mbedtls_ssl_conf_rng( &g_caTlsContext->clientConf, mbedtls_ctr_drbg_random,
913                           &g_caTlsContext->rnd);
914     mbedtls_ssl_conf_curves(&g_caTlsContext->clientConf, curve[ADAPTER_CURVE_SECP256R1]);
915     mbedtls_ssl_conf_min_version(&g_caTlsContext->clientConf, MBEDTLS_SSL_MAJOR_VERSION_3,
916                                  MBEDTLS_SSL_MINOR_VERSION_1);
917     mbedtls_ssl_conf_renegotiation(&g_caTlsContext->clientConf, MBEDTLS_SSL_RENEGOTIATION_DISABLED);
918
919     mbedtls_ssl_conf_authmode(&g_caTlsContext->clientConf, MBEDTLS_SSL_VERIFY_REQUIRED);
920 #ifndef NDEBUG
921     mbedtls_ssl_conf_dbg( &g_caTlsContext->clientConf, debugTls, NULL);
922 #endif
923
924     /* Server SSL configuration
925      */
926     mbedtls_ssl_config_init(&g_caTlsContext->serverConf);
927     if (mbedtls_ssl_config_defaults(&g_caTlsContext->serverConf, MBEDTLS_SSL_IS_SERVER,
928                                     MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) != 0)
929     {
930         OIC_LOG(ERROR, NET_TLS_TAG, "Server config initialization failed!");
931         ca_mutex_unlock(g_tlsContextMutex);
932         CAdeinitTlsAdapter();
933         return CA_STATUS_FAILED;
934     }
935
936     mbedtls_ssl_conf_psk_cb(&g_caTlsContext->serverConf, getTlsCredentialsCallback, NULL);
937     mbedtls_ssl_conf_rng( &g_caTlsContext->serverConf, mbedtls_ctr_drbg_random,
938                           &g_caTlsContext->rnd);
939     mbedtls_ssl_conf_curves(&g_caTlsContext->serverConf, curve[ADAPTER_CURVE_SECP256R1]);
940     mbedtls_ssl_conf_min_version(&g_caTlsContext->serverConf, MBEDTLS_SSL_MAJOR_VERSION_3,
941                                  MBEDTLS_SSL_MINOR_VERSION_1);
942     mbedtls_ssl_conf_renegotiation(&g_caTlsContext->serverConf, MBEDTLS_SSL_RENEGOTIATION_DISABLED);
943     mbedtls_ssl_conf_authmode(&g_caTlsContext->serverConf, MBEDTLS_SSL_VERIFY_REQUIRED);
944
945 #ifndef NDEBUG
946     mbedtls_ssl_conf_dbg( &g_caTlsContext->serverConf, debugTls, NULL);
947     mbedtls_debug_set_threshold(MBED_TLS_DEBUG_LEVEL);
948 #endif
949
950     // set default cipher to PSK
951     CAsetTlsCipherSuite(MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256);
952
953     // init X.509
954     mbedtls_x509_crt_init(&g_caTlsContext->ca);
955     mbedtls_x509_crt_init(&g_caTlsContext->crt);
956     mbedtls_pk_init(&g_caTlsContext->pkey);
957     mbedtls_x509_crl_init(&g_caTlsContext->crl);
958
959     ca_mutex_unlock(g_tlsContextMutex);
960
961     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
962     return CA_STATUS_OK;
963 }
964 /**
965  * Creates cache message structure and fills with data.
966  *
967  * @param[in]  data    data array
968  * @param[in]  dataLen    data array length
969  *
970  * @return  message or NULL
971  */
972 TlsCacheMessage_t *  newTlsCacheMessage(uint8_t * data, size_t dataLen)
973 {
974     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
975     VERIFY_NON_NULL_RET(data, NET_TLS_TAG, "Param data is NULL" , NULL);
976     if (0 == dataLen)
977     {
978         OIC_LOG(ERROR, NET_TLS_TAG, "dataLen is equal to zero");
979         OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
980         return NULL;
981     }
982     TlsCacheMessage_t * message = (TlsCacheMessage_t *) OICCalloc(1, sizeof(TlsCacheMessage_t));
983     if (NULL == message)
984     {
985         OIC_LOG(ERROR, NET_TLS_TAG, "calloc failed!");
986         OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
987         return NULL;
988     }
989
990     message->data = (uint8_t *)OICCalloc(dataLen, sizeof(uint8_t));
991     if (NULL == message->data)
992     {
993         OIC_LOG(ERROR, NET_TLS_TAG, "calloc failed!");
994         OICFree(message);
995         OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
996         return NULL;
997     }
998     memcpy(message->data, data, dataLen);
999     message->len = dataLen;
1000     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
1001     return message;
1002 }
1003
1004 /* Send data via TLS connection.
1005  */
1006 CAResult_t CAencryptTls(const CAEndpoint_t *endpoint,
1007                         void *data, uint32_t dataLen)
1008 {
1009     int ret = 0;
1010
1011     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s ", __func__);
1012
1013     VERIFY_NON_NULL_RET(endpoint, NET_TLS_TAG,"Remote address is NULL", CA_STATUS_INVALID_PARAM);
1014     VERIFY_NON_NULL_RET(data, NET_TLS_TAG, "Data is NULL", CA_STATUS_INVALID_PARAM);
1015
1016     if (0 == dataLen)
1017     {
1018         OIC_LOG_V(ERROR, NET_TLS_TAG, "dataLen is zero [%d]", dataLen);
1019         return CA_STATUS_FAILED;
1020     }
1021
1022     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Data to be encrypted dataLen [%d]", dataLen);
1023
1024     ca_mutex_lock(g_tlsContextMutex);
1025     if(NULL == g_caTlsContext)
1026     {
1027         OIC_LOG(ERROR, NET_TLS_TAG, "Context is NULL");
1028         ca_mutex_unlock(g_tlsContextMutex);
1029         return CA_STATUS_FAILED;
1030     }
1031
1032     TlsEndPoint_t * tep = getTlsPeer(endpoint);
1033     if (NULL == tep)
1034     {
1035         tep = initiateTlsHandshake(endpoint);
1036     }
1037     if (NULL == tep)
1038     {
1039         OIC_LOG(ERROR, NET_TLS_TAG, "TLS handshake failed");
1040         ca_mutex_unlock(g_tlsContextMutex);
1041         return CA_STATUS_FAILED;
1042     }
1043
1044     if (MBEDTLS_SSL_HANDSHAKE_OVER == tep->ssl.state)
1045     {
1046         ret = mbedtls_ssl_write(&tep->ssl, (unsigned char *) data, dataLen);
1047
1048         if(ret < 0)
1049         {
1050             OIC_LOG_V(ERROR, NET_TLS_TAG, "mbedTLS write returned %d", ret);
1051             if (g_tlsHandshakeCallback)
1052             {
1053                 CAErrorInfo_t errorInfo = {.result = CA_STATUS_FAILED};
1054                 g_tlsHandshakeCallback(&tep->sep.endpoint, &errorInfo);
1055             }
1056             removePeerFromList(&tep->sep.endpoint);
1057             ca_mutex_unlock(g_tlsContextMutex);
1058             return CA_STATUS_FAILED;
1059         }
1060     }
1061     else
1062     {
1063         TlsCacheMessage_t * msg = newTlsCacheMessage(data, dataLen);
1064         if (NULL == msg || !u_arraylist_add(tep->cacheList, (void *) msg))
1065         {
1066             OIC_LOG(ERROR, NET_TLS_TAG, "u_arraylist_add failed!");
1067             ca_mutex_unlock(g_tlsContextMutex);
1068             return CA_STATUS_FAILED;
1069         }
1070     }
1071
1072     ca_mutex_unlock(g_tlsContextMutex);
1073
1074     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
1075     return CA_STATUS_OK;
1076 }
1077 /**
1078  * Sends cached messages via TLS connection.
1079  *
1080  * @param[in]  tep    remote address with session info
1081  */
1082 static void sendCacheMessages(TlsEndPoint_t * tep)
1083 {
1084     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
1085     VERIFY_NON_NULL_VOID(tep, NET_TLS_TAG, "Param tep is NULL");
1086
1087     uint32_t listIndex = 0;
1088     uint32_t listLength = 0;
1089     listLength = u_arraylist_length(tep->cacheList);
1090     for (listIndex = 0; listIndex < listLength;)
1091     {
1092         int ret = 0;
1093         TlsCacheMessage_t * msg = (TlsCacheMessage_t *) u_arraylist_get(tep->cacheList, listIndex);
1094         if (NULL != msg && NULL != msg->data && 0 != msg->len)
1095         {
1096             do
1097             {
1098                 ret = mbedtls_ssl_write(&tep->ssl, (unsigned char *) msg->data, msg->len);
1099             }
1100             while(MBEDTLS_ERR_SSL_WANT_WRITE == ret);
1101
1102             if(ret < 0)
1103             {
1104                 OIC_LOG_V(ERROR, NET_TLS_TAG,"mbedTLS write returned %d", ret );
1105             }
1106             if (u_arraylist_remove(tep->cacheList, listIndex))
1107             {
1108                 deleteTlsCacheMessage(msg);
1109                 // Reduce list length by 1 as we removed one element.
1110                 listLength--;
1111             }
1112             else
1113             {
1114                 OIC_LOG(ERROR, NET_TLS_TAG, "u_arraylist_remove failed.");
1115                 break;
1116             }
1117         }
1118         else
1119         {
1120             // Move to the next element
1121             ++listIndex;
1122         }
1123     }
1124     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
1125 }
1126
1127 void CAsetTlsHandshakeCallback(CAErrorCallback tlsHandshakeCallback)
1128 {
1129     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
1130     g_tlsHandshakeCallback = tlsHandshakeCallback;
1131     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
1132 }
1133 // TODO move ConvertStrToUuid function to common module
1134 /*
1135  * Converts string UUID to CARemoteId_t
1136  *
1137  * @param strUuid Device UUID in string format
1138  * @param uuid converted UUID in CARemoteId_t format
1139  *
1140  * @return 0 for success.
1141  * */
1142 static int ConvertStrToUuid(const char* strUuid, CARemoteId_t* uuid)
1143 {
1144     if(NULL == strUuid || NULL == uuid)
1145     {
1146         OIC_LOG(ERROR, NET_TLS_TAG, "ConvertStrToUuid : Invalid param");
1147         return -1;
1148     }
1149
1150     size_t urnIdx = 0;
1151     size_t uuidIdx = 0;
1152     size_t strUuidLen = 0;
1153     char convertedUuid[UUID_LENGTH * 2] = {0};
1154
1155     strUuidLen = strlen(strUuid);
1156     if(0 == strUuidLen)
1157     {
1158         OIC_LOG(INFO, NET_TLS_TAG, "The empty string detected, The UUID will be converted to "\
1159                            "\"00000000-0000-0000-0000-000000000000\"");
1160     }
1161     else if(UUID_LENGTH * 2 + 4 == strUuidLen)
1162     {
1163         for(uuidIdx=0, urnIdx=0; uuidIdx < UUID_LENGTH ; uuidIdx++, urnIdx+=2)
1164         {
1165             if(*(strUuid + urnIdx) == '-')
1166             {
1167                 urnIdx++;
1168             }
1169             sscanf(strUuid + urnIdx, "%2hhx", &convertedUuid[uuidIdx]);
1170         }
1171     }
1172     else
1173     {
1174         OIC_LOG(ERROR, NET_TLS_TAG, "Invalid string uuid format");
1175         return -1;
1176     }
1177
1178     memcpy(uuid->id, convertedUuid, UUID_LENGTH);
1179     uuid->id_length = UUID_LENGTH;
1180     return 0;
1181 }
1182
1183 /* Read data from TLS connection
1184  */
1185 CAResult_t CAdecryptTls(const CASecureEndpoint_t *sep, uint8_t *data, uint32_t dataLen)
1186 {
1187     int ret = 0;
1188     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
1189     VERIFY_NON_NULL_RET(sep, NET_TLS_TAG, "endpoint is NULL" , CA_STATUS_INVALID_PARAM);
1190     VERIFY_NON_NULL_RET(data, NET_TLS_TAG, "Param data is NULL" , CA_STATUS_INVALID_PARAM);
1191
1192     ca_mutex_lock(g_tlsContextMutex);
1193     if (NULL == g_caTlsContext)
1194     {
1195         OIC_LOG(ERROR, NET_TLS_TAG, "Context is NULL");
1196         ca_mutex_unlock(g_tlsContextMutex);
1197         return CA_STATUS_FAILED;
1198     }
1199
1200     if (ADAPTER_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 == g_caTlsContext->cipher &&
1201             0 != initPskIdentity(&g_caTlsContext->serverConf))
1202     {
1203         ca_mutex_unlock(g_tlsContextMutex);
1204         return CA_STATUS_FAILED;
1205     }
1206
1207     TlsEndPoint_t * peer = getTlsPeer(&sep->endpoint);
1208     if (NULL == peer)
1209     {
1210         peer = newTlsEndPoint(&sep->endpoint, &g_caTlsContext->serverConf);
1211         if (NULL == peer)
1212         {
1213             OIC_LOG(ERROR, NET_TLS_TAG, "Malloc failed!");
1214             ca_mutex_unlock(g_tlsContextMutex);
1215             return CA_STATUS_FAILED;
1216         }
1217
1218         if (ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 == g_caTlsContext->cipher ||
1219             ADAPTER_TLS_RSA_WITH_AES_256_CBC_SHA == g_caTlsContext->cipher)
1220         {
1221             ret = loadX509();
1222             if (0 != ret)
1223             {
1224                 OIC_LOG(ERROR, NET_TLS_TAG, "Failed to init X.509");
1225                 deleteTlsEndPoint(peer);
1226                 ca_mutex_unlock(g_tlsContextMutex);
1227                 return CA_STATUS_FAILED;
1228             }
1229         }
1230
1231         ret = u_arraylist_add(g_caTlsContext->peerList, (void *) peer);
1232         if (!ret)
1233         {
1234             OIC_LOG(ERROR, NET_TLS_TAG, "u_arraylist_add failed!");
1235             OICFree(peer);
1236             ca_mutex_unlock(g_tlsContextMutex);
1237             return CA_STATUS_FAILED;
1238         }
1239     }
1240     OIC_LOG_BUFFER(DEBUG, NET_TLS_TAG, data, dataLen);
1241     peer->recBuf.buff = data;
1242     peer->recBuf.len = dataLen;
1243     peer->recBuf.loaded = 0;
1244
1245     OIC_LOG(DEBUG, NET_TLS_TAG, "Call mbedTLS handshake steps");
1246
1247     while (MBEDTLS_SSL_HANDSHAKE_OVER > peer->ssl.state)
1248     {
1249         ret = mbedtls_ssl_handshake_step(&peer->ssl);
1250         if (MBEDTLS_ERR_SSL_CONN_EOF == ret)
1251         {
1252             break;
1253         }
1254         TLS_CHECK_HANDSHAKE_FAIL(peer, ret, "Handshake error", 1, CA_STATUS_FAILED);
1255         if (MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC == peer->ssl.state)
1256         {
1257             memcpy(peer->master, peer->ssl.session_negotiate->master, sizeof(peer->master));
1258         }
1259
1260         if (MBEDTLS_SSL_HANDSHAKE_OVER == peer->ssl.state)
1261         {
1262             if (MBEDTLS_SSL_IS_CLIENT == peer->ssl.conf->endpoint)
1263             {
1264                 sendCacheMessages(peer);
1265                 if (g_tlsHandshakeCallback)
1266                 {
1267                     CAErrorInfo_t errorInfo = {.result = CA_STATUS_OK};
1268                     g_tlsHandshakeCallback(&peer->sep.endpoint, &errorInfo);
1269                 }
1270             }
1271             else
1272             {
1273                 if (ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 == g_caTlsContext->cipher)
1274                 {
1275                     char uuid[UUID_LENGTH * 2 + 5] = {0};
1276                     void * uuidPos = NULL;
1277                     const mbedtls_x509_crt * peerCert = mbedtls_ssl_get_peer_cert(&peer->ssl);
1278                     ret = (NULL == peerCert ? -1 : 0);
1279                     TLS_CHECK_HANDSHAKE_FAIL(peer, ret, "Failed to retrieve subject",
1280                                                                                1, CA_STATUS_FAILED);
1281                     ret = mbedtls_ssl_get_verify_result(&peer->ssl);
1282                     TLS_CHECK_HANDSHAKE_FAIL(peer, ret, "Failed to retrieve subject",
1283                                                                                1, CA_STATUS_FAILED);
1284                     uuidPos = memmem((void *) peerCert->subject_raw.p, peerCert->subject_raw.len,
1285                                                      (void *) UUID_PREFIX, sizeof(UUID_PREFIX) - 1);
1286
1287                     ret = (NULL == uuidPos ? -1 : 0);
1288                     TLS_CHECK_HANDSHAKE_FAIL(peer, ret, "Failed to retrieve subject",
1289                                                                                1, CA_STATUS_FAILED);
1290
1291                     memcpy(uuid, uuidPos + sizeof(UUID_PREFIX) - 1, UUID_LENGTH * 2 + 4);
1292                     ret = ConvertStrToUuid(uuid, &peer->sep.identity);
1293                     TLS_CHECK_HANDSHAKE_FAIL(peer, ret, "Failed to convert subject",
1294                                                                                1, CA_STATUS_FAILED);
1295                 }
1296             }
1297             ca_mutex_unlock(g_tlsContextMutex);
1298             OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
1299             return CA_STATUS_OK;
1300         }
1301     }
1302
1303     if (MBEDTLS_SSL_HANDSHAKE_OVER == peer->ssl.state)
1304     {
1305         uint8_t decryptBuffer[TLS_MSG_BUF_LEN] = {0};
1306         do
1307         {
1308             ret = mbedtls_ssl_read(&peer->ssl, decryptBuffer, TLS_MSG_BUF_LEN);
1309         } while (MBEDTLS_ERR_SSL_WANT_READ == ret);
1310         if (MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY == ret)
1311         {
1312             OIC_LOG(INFO, NET_TLS_TAG, "Connection was closed gracefully");
1313             removePeerFromList(&peer->sep.endpoint);
1314             ca_mutex_unlock(g_tlsContextMutex);
1315             return CA_STATUS_OK;
1316         }
1317
1318         if (0 >= ret)
1319         {
1320             OIC_LOG_V(ERROR, NET_TLS_TAG, "mbedtls_ssl_read returned -0x%x", -ret);
1321             if (g_tlsHandshakeCallback)
1322             {
1323                 CAErrorInfo_t errorInfo = {.result = CA_STATUS_FAILED};
1324                 g_tlsHandshakeCallback(&peer->sep.endpoint, &errorInfo);
1325             }
1326             removePeerFromList(&peer->sep.endpoint);
1327             ca_mutex_unlock(g_tlsContextMutex);
1328             return CA_STATUS_FAILED;
1329         }
1330
1331         g_caTlsContext->adapterCallbacks[0].recvCallback(&peer->sep, decryptBuffer, ret);
1332     }
1333
1334     ca_mutex_unlock(g_tlsContextMutex);
1335     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
1336     return CA_STATUS_OK;
1337 }
1338
1339 void CAsetTlsAdapterCallbacks(CAPacketReceivedCallback recvCallback,
1340                               CAPacketSendCallback sendCallback,
1341                               CATransportAdapter_t type)
1342 {
1343     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
1344     VERIFY_NON_NULL_VOID(sendCallback, NET_TLS_TAG, "sendCallback is NULL");
1345     VERIFY_NON_NULL_VOID(recvCallback, NET_TLS_TAG, "recvCallback is NULL");
1346     ca_mutex_lock(g_tlsContextMutex);
1347     if (NULL == g_caTlsContext)
1348     {
1349         OIC_LOG(ERROR, NET_TLS_TAG, "Context is NULL");
1350         ca_mutex_unlock(g_tlsContextMutex);
1351         return;
1352     }
1353
1354     if (MAX_SUPPORTED_ADAPTERS > type)
1355     {
1356         // TODO: change the zeros to better values.
1357         g_caTlsContext->adapterCallbacks[0].recvCallback = recvCallback;
1358         g_caTlsContext->adapterCallbacks[0].sendCallback = sendCallback;
1359     }
1360
1361     ca_mutex_unlock(g_tlsContextMutex);
1362     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
1363 }
1364
1365 CAResult_t CAsetTlsCipherSuite(const uint32_t cipher)
1366 {
1367     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
1368     switch(cipher)
1369     {
1370         case MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA:
1371         {
1372             mbedtls_ssl_conf_ciphersuites(&g_caTlsContext->clientConf,
1373                                          tlsCipher[ADAPTER_TLS_RSA_WITH_AES_256_CBC_SHA]);
1374             mbedtls_ssl_conf_ciphersuites(&g_caTlsContext->serverConf,
1375                                          tlsCipher[ADAPTER_TLS_RSA_WITH_AES_256_CBC_SHA]);
1376             g_caTlsContext->cipher = ADAPTER_TLS_RSA_WITH_AES_256_CBC_SHA;
1377             break;
1378         }
1379         case MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
1380         {
1381             mbedtls_ssl_conf_ciphersuites(&g_caTlsContext->clientConf,
1382                                          tlsCipher[ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8]);
1383             mbedtls_ssl_conf_ciphersuites(&g_caTlsContext->serverConf,
1384                                          tlsCipher[ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8]);
1385             g_caTlsContext->cipher = ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
1386             break;
1387         }
1388         case MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256:
1389         {
1390             mbedtls_ssl_conf_ciphersuites(&g_caTlsContext->clientConf,
1391                                          tlsCipher[ADAPTER_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA_256]);
1392             mbedtls_ssl_conf_ciphersuites(&g_caTlsContext->serverConf,
1393                                          tlsCipher[ADAPTER_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA_256]);
1394             g_caTlsContext->cipher = ADAPTER_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA_256;
1395             break;
1396         }
1397         case MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256:
1398         {
1399             mbedtls_ssl_conf_ciphersuites(&g_caTlsContext->clientConf,
1400                                           tlsCipher[ADAPTER_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256]);
1401             mbedtls_ssl_conf_ciphersuites(&g_caTlsContext->serverConf,
1402                                           tlsCipher[ADAPTER_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256]);
1403             g_caTlsContext->cipher = ADAPTER_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256;
1404             break;
1405         }
1406         default:
1407         {
1408             OIC_LOG(ERROR, NET_TLS_TAG, "Unknown cipher");
1409             return CA_STATUS_FAILED;
1410         }
1411     }
1412     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Selected cipher: 0x%x", cipher);
1413     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
1414     return CA_STATUS_OK;
1415 }
1416
1417 CAResult_t CAinitiateTlsHandshake(const CAEndpoint_t *endpoint)
1418 {
1419     CAResult_t res = CA_STATUS_OK;
1420     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
1421     VERIFY_NON_NULL_RET(endpoint, NET_TLS_TAG, "Param endpoint is NULL" , CA_STATUS_INVALID_PARAM);
1422     ca_mutex_lock(g_tlsContextMutex);
1423     if (NULL == initiateTlsHandshake(endpoint))
1424     {
1425         OIC_LOG(ERROR, NET_TLS_TAG, "TLS handshake failed");
1426         res = CA_STATUS_FAILED;
1427     }
1428     ca_mutex_unlock(g_tlsContextMutex);
1429     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
1430     return res;
1431 }
1432
1433 CAResult_t CAtlsGenerateOwnerPSK(const CAEndpoint_t *endpoint,
1434                                  uint8_t* ownerPSK, const size_t ownerPSKSize,
1435                                  const uint8_t* deviceID, const size_t deviceIDLen)
1436 {
1437     OIC_LOG_V(DEBUG, NET_TLS_TAG, "In %s", __func__);
1438
1439     VERIFY_NON_NULL_RET(ownerPSK, NET_TLS_TAG, "ownerPSK is NULL", CA_STATUS_INVALID_PARAM);
1440     VERIFY_NON_NULL_RET(deviceID, NET_TLS_TAG, "rsrcID is NULL", CA_STATUS_INVALID_PARAM);
1441
1442     ca_mutex_lock(g_tlsContextMutex);
1443     if (NULL == g_caTlsContext)
1444     {
1445         OIC_LOG(ERROR, NET_TLS_TAG, "Context is NULL");
1446         ca_mutex_unlock(g_tlsContextMutex);
1447         OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
1448         return CA_STATUS_FAILED;
1449     }
1450     TlsEndPoint_t * tep = getTlsPeer(endpoint);
1451     if (NULL == tep)
1452     {
1453         OIC_LOG(ERROR, NET_TLS_TAG, "Session does not exist");
1454         ca_mutex_unlock(g_tlsContextMutex);
1455         return CA_STATUS_FAILED;
1456     }
1457
1458     if (0 != mbedtls_pkcs12_derivation(ownerPSK, ownerPSKSize,
1459                                        tep->master, sizeof(tep->master),
1460                                        deviceID, deviceIDLen,
1461                                        MBEDTLS_MD_SHA1, MBEDTLS_PKCS12_DERIVE_KEY, 1))
1462     {
1463         OIC_LOG(ERROR, NET_TLS_TAG, "Failed to generate key");
1464         ca_mutex_unlock(g_tlsContextMutex);
1465         OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
1466         return CA_STATUS_FAILED;
1467     }
1468     OIC_LOG_V(DEBUG, NET_TLS_TAG, "PSK: ");
1469     OIC_LOG_BUFFER(DEBUG, NET_TLS_TAG, tep->master, sizeof(tep->master));
1470     ca_mutex_unlock(g_tlsContextMutex);
1471
1472     OIC_LOG_V(DEBUG, NET_TLS_TAG, "Out %s", __func__);
1473     return CA_STATUS_OK;
1474 }