[IOT-1801] Implement OCF Security CR1339
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / caconnectivitymanager.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
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdint.h>
24 #include <stdbool.h>
25
26 #include "ocrandom.h"
27 #include "cainterface.h"
28 #include "caremotehandler.h"
29 #include "camessagehandler.h"
30 #include "caprotocolmessage.h"
31 #include "canetworkconfigurator.h"
32 #include "cainterfacecontroller.h"
33 #include "logger.h"
34
35 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
36 #include "ca_adapter_net_ssl.h"
37 #endif // __WITH_DTLS__ or __WITH_TLS__
38
39 #ifdef TCP_ADAPTER
40 #include "catcpadapter.h"
41 #endif
42
43 CAGlobals_t caglobals = { .clientFlags = 0,
44                           .serverFlags = 0, };
45
46 #define TAG "OIC_CA_CONN_MGR"
47
48 static bool g_isInitialized = false;
49
50 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
51 // Taking callback all the way through adapters not the right approach, hence calling here.
52 extern void CAsetPkixInfoCallback(CAgetPkixInfoHandler infCallback);
53 extern void CAsetPskCredentialsCallback(CAgetPskCredentialsHandler credCallback);
54 extern void CAsetCredentialTypesCallback(CAgetCredentialTypesHandler credCallback);
55 #endif // __WITH_DTLS__ or __WITH_TLS__
56
57
58 CAResult_t CAInitialize(CATransportAdapter_t transportType)
59 {
60     OIC_LOG_V(DEBUG, TAG, "IoTivity version is v%s", IOTIVITY_VERSION);
61     OIC_LOG_V(DEBUG, TAG, "CAInitialize type : %d", transportType);
62
63     if (!g_isInitialized)
64     {
65         CAResult_t res = CAInitializeMessageHandler(transportType);
66         if (res != CA_STATUS_OK)
67         {
68             OIC_LOG(ERROR, TAG, "CAInitialize has failed");
69             CATerminateMessageHandler();
70             return res;
71         }
72         g_isInitialized = true;
73     }
74
75     return CA_STATUS_OK;
76 }
77
78 void CATerminate()
79 {
80     OIC_LOG(DEBUG, TAG, "CATerminate");
81
82     if (g_isInitialized)
83     {
84         CATerminateMessageHandler();
85         CATerminateNetworkType();
86
87         g_isInitialized = false;
88     }
89 }
90
91 CAResult_t CAStartListeningServer()
92 {
93     OIC_LOG(DEBUG, TAG, "CAStartListeningServer");
94
95     if (!g_isInitialized)
96     {
97         return CA_STATUS_NOT_INITIALIZED;
98     }
99
100     return CAStartListeningServerAdapters();
101 }
102
103 CAResult_t CAStopListeningServer()
104 {
105     OIC_LOG(DEBUG, TAG, "CAStopListeningServer");
106
107     if (!g_isInitialized)
108     {
109         return CA_STATUS_NOT_INITIALIZED;
110     }
111
112     return CAStopListeningServerAdapters();
113 }
114
115 CAResult_t CAStartDiscoveryServer()
116 {
117     OIC_LOG(DEBUG, TAG, "CAStartDiscoveryServer");
118
119     if (!g_isInitialized)
120     {
121         return CA_STATUS_NOT_INITIALIZED;
122     }
123
124     return CAStartDiscoveryServerAdapters();
125 }
126
127 void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
128                        CAErrorCallback ErrorHandler)
129 {
130     OIC_LOG(DEBUG, TAG, "CARegisterHandler");
131
132     if (!g_isInitialized)
133     {
134         OIC_LOG(DEBUG, TAG, "CA is not initialized");
135         return;
136     }
137
138     CASetInterfaceCallbacks(ReqHandler, RespHandler, ErrorHandler);
139 }
140
141 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
142 #ifdef MULTIPLE_OWNER
143 const CASecureEndpoint_t *CAGetSecureEndpointData(const CAEndpoint_t *peer)
144 {
145     OIC_LOG(DEBUG, TAG, "IN CAGetSecurePeerInfo");
146
147     if (!g_isInitialized)
148     {
149         OIC_LOG(DEBUG, TAG, "CA is not initialized");
150         return NULL;
151     }
152
153     OIC_LOG(DEBUG, TAG, "OUT CAGetSecurePeerInfo");
154     return GetCASecureEndpointData(peer);
155 }
156 #endif //MULTIPLE_OWNER
157
158 bool CASetSecureEndpointAttribute(const CAEndpoint_t* peer, uint32_t attribute)
159 {
160     bool success = false;
161     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
162
163     if (!g_isInitialized)
164     {
165         OIC_LOG(DEBUG, TAG, "CA is not initialized");
166     }
167     else
168     {
169         success = SetCASecureEndpointAttribute(peer, attribute);
170     }
171
172     OIC_LOG_V(DEBUG, TAG, "Out %s -> %u", __func__, (uint32_t)success);
173     return success;
174 }
175
176 bool CAGetSecureEndpointAttributes(const CAEndpoint_t* peer, uint32_t* attributes)
177 {
178     bool success = false;
179     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
180
181     if (!g_isInitialized)
182     {
183         OIC_LOG(DEBUG, TAG, "CA is not initialized");
184     }
185     else
186     {
187         success = GetCASecureEndpointAttributes(peer, attributes);
188     }
189
190     OIC_LOG_V(DEBUG, TAG, "Out %s -> %u", __func__, (uint32_t)success);
191     return success;
192 }
193
194 CAResult_t CAregisterSslHandshakeCallback(CAErrorCallback tlsHandshakeCallback)
195 {
196     OIC_LOG(DEBUG, TAG, "CAregisterSslHandshakeCallback");
197
198     if(!g_isInitialized)
199     {
200         return CA_STATUS_NOT_INITIALIZED;
201     }
202
203     CAsetSslHandshakeCallback(tlsHandshakeCallback);
204     return CA_STATUS_OK;
205 }
206
207 CAResult_t CAregisterPskCredentialsHandler(CAgetPskCredentialsHandler getTlsCredentialsHandler)
208 {
209     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
210
211     if (!g_isInitialized)
212     {
213         return CA_STATUS_NOT_INITIALIZED;
214     }
215     CAsetPskCredentialsCallback(getTlsCredentialsHandler);
216     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
217     return CA_STATUS_OK;
218 }
219
220 CAResult_t CAregisterPkixInfoHandler(CAgetPkixInfoHandler getPkixInfoHandler)
221 {
222     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
223
224     if (!g_isInitialized)
225     {
226         return CA_STATUS_NOT_INITIALIZED;
227     }
228     CAsetPkixInfoCallback(getPkixInfoHandler);
229     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
230     return CA_STATUS_OK;
231 }
232
233 CAResult_t CAregisterGetCredentialTypesHandler(CAgetCredentialTypesHandler getCredTypesHandler)
234 {
235     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
236
237     if (!g_isInitialized)
238     {
239         return CA_STATUS_NOT_INITIALIZED;
240     }
241     CAsetCredentialTypesCallback(getCredTypesHandler);
242     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
243     return CA_STATUS_OK;
244 }
245 #endif // __WITH_DTLS__ or __WITH_TLS__
246
247 CAResult_t CACreateEndpoint(CATransportFlags_t flags,
248                             CATransportAdapter_t adapter,
249                             const char *addr,
250                             uint16_t port,
251                             CAEndpoint_t **object)
252 {
253     if (!object)
254     {
255         OIC_LOG(ERROR, TAG, "Invalid Parameter");
256         return CA_STATUS_INVALID_PARAM;
257     }
258
259     CAEndpoint_t *endpoint = CACreateEndpointObject(flags, adapter, addr, port);
260     if (!endpoint)
261     {
262         return CA_STATUS_FAILED;
263     }
264     *object = endpoint;
265     return CA_STATUS_OK;
266 }
267
268 void CADestroyEndpoint(CAEndpoint_t *rep)
269 {
270     OIC_LOG(DEBUG, TAG, "CADestroyEndpoint");
271
272     CAFreeEndpoint(rep);
273 }
274
275 CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength)
276 {
277     OIC_LOG(DEBUG, TAG, "CAGenerateToken");
278
279     return CAGenerateTokenInternal(token, tokenLength);
280 }
281
282 void CADestroyToken(CAToken_t token)
283 {
284     OIC_LOG(DEBUG, TAG, "CADestroyToken");
285
286     CADestroyTokenInternal(token);
287
288     OIC_LOG(DEBUG, TAG, "OUT");
289 }
290
291 CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, uint32_t *size)
292 {
293     OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
294
295     if (!g_isInitialized)
296     {
297         return CA_STATUS_NOT_INITIALIZED;
298     }
299
300     return CAGetNetworkInformationInternal(info, size);
301 }
302
303 static CAResult_t CASendMessageMultiAdapter(const CAEndpoint_t *object, const void *sendMsg,
304                                             CADataType_t dataType)
305 {
306     OIC_LOG(DEBUG, TAG, "CASendMessageMultipleAdapter");
307
308     CATransportAdapter_t connTypes[] = {
309             CA_ADAPTER_IP
310 #ifdef LE_ADAPTER
311             ,CA_ADAPTER_GATT_BTLE
312 #endif
313 #ifdef EDR_ADAPTER
314             ,CA_ADAPTER_RFCOMM_BTEDR
315 #endif
316 #ifdef NFC_ADAPTER
317             ,CA_ADAPTER_NFC
318 #endif
319 #ifdef RA_ADAPTER
320             ,CA_ADAPTER_REMOTE_ACCESS
321 #endif
322 #ifdef TCP_ADAPTER
323             ,CA_ADAPTER_TCP
324 #endif
325         };
326
327     CAEndpoint_t *cloneEp = CACloneEndpoint(object);
328     if (!cloneEp)
329     {
330         OIC_LOG(ERROR, TAG, "Failed to clone CAEndpoint");
331         return CA_MEMORY_ALLOC_FAILED;
332     }
333
334     CAResult_t ret = CA_STATUS_OK;
335     size_t numConnTypes = sizeof(connTypes) / sizeof(connTypes[0]);
336
337     for (size_t i = 0; i < numConnTypes && ret == CA_STATUS_OK; i++)
338     {
339         cloneEp->adapter = connTypes[i];
340         ret = CADetachSendMessage(cloneEp, sendMsg, dataType);
341     }
342     CAFreeEndpoint(cloneEp);
343     return ret;
344 }
345
346 CAResult_t CASendRequest(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
347 {
348     OIC_LOG(DEBUG, TAG, "CASendRequest");
349
350     if (!g_isInitialized)
351     {
352         return CA_STATUS_NOT_INITIALIZED;
353     }
354
355     if (requestInfo && requestInfo->isMulticast &&
356             (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
357     {
358         return CASendMessageMultiAdapter(object, requestInfo, CA_REQUEST_DATA);
359     }
360     else
361     {
362         return CADetachSendMessage(object, requestInfo, CA_REQUEST_DATA);
363     }
364 }
365
366 CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
367 {
368     OIC_LOG(DEBUG, TAG, "CASendResponse");
369
370     if (!g_isInitialized)
371     {
372         return CA_STATUS_NOT_INITIALIZED;
373     }
374
375     if (!responseInfo || !object)
376     {
377         return CA_STATUS_INVALID_PARAM;
378     }
379
380     if (responseInfo->isMulticast &&
381             (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
382     {
383         return CASendMessageMultiAdapter(object, responseInfo, responseInfo->info.dataType);
384     }
385     else
386     {
387         return CADetachSendMessage(object, responseInfo, responseInfo->info.dataType);
388     }
389 }
390
391 CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
392 {
393     if (!g_isInitialized)
394     {
395         return CA_STATUS_NOT_INITIALIZED;
396     }
397
398     CAResult_t res = CA_STATUS_OK;
399
400     if (interestedNetwork & CA_ADAPTER_IP)
401     {
402         res = CAAddNetworkType(CA_ADAPTER_IP);
403         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_IP_ADAPTER) function returns result: %d", res);
404     }
405     else if (interestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
406     {
407         res = CAAddNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
408         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
409     }
410     else if (interestedNetwork & CA_ADAPTER_GATT_BTLE)
411     {
412         res = CAAddNetworkType(CA_ADAPTER_GATT_BTLE);
413         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
414     }
415
416 #ifdef RA_ADAPTER
417     else if (interestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
418     {
419         res = CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS);
420         OIC_LOG_V(DEBUG, TAG,
421                   "CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d", res);
422     }
423 #endif
424
425 #ifdef TCP_ADAPTER
426     else if (interestedNetwork & CA_ADAPTER_TCP)
427     {
428         res = CAAddNetworkType(CA_ADAPTER_TCP);
429         OIC_LOG_V(DEBUG, TAG,
430                   "CAAddNetworkType(CA_ADAPTER_TCP) function returns result : %d", res);
431     }
432 #endif
433     else if (interestedNetwork & CA_ADAPTER_NFC)
434     {
435         res = CAAddNetworkType(CA_ADAPTER_NFC);
436         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_ADAPTER_NFC) function returns result : %d", res);
437     }
438     else
439     {
440         res = CA_NOT_SUPPORTED;
441     }
442     return res;
443 }
444
445 CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork)
446 {
447     OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
448
449     if (!g_isInitialized)
450     {
451         return CA_STATUS_NOT_INITIALIZED;
452     }
453
454     CAResult_t res = CA_STATUS_OK;
455
456     if (nonInterestedNetwork & CA_ADAPTER_IP)
457     {
458         res = CARemoveNetworkType(CA_ADAPTER_IP);
459         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_IP_ADAPTER) function returns result : %d", res);
460     }
461     else if (nonInterestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
462     {
463         res = CARemoveNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
464         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
465     }
466     else if (nonInterestedNetwork & CA_ADAPTER_GATT_BTLE)
467     {
468         res = CARemoveNetworkType(CA_ADAPTER_GATT_BTLE);
469         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
470     }
471 #ifdef RA_ADAPTER
472     else if (nonInterestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
473     {
474         res = CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS);
475         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d",
476                   res);
477     }
478 #endif
479
480
481 #ifdef TCP_ADAPTER
482     else if (nonInterestedNetwork & CA_ADAPTER_TCP)
483     {
484         res = CARemoveNetworkType(CA_ADAPTER_TCP);
485         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_TCP) function returns result : %d",
486                   res);
487     }
488 #endif
489
490     else
491     {
492         res = CA_STATUS_FAILED;
493     }
494     return res;
495 }
496
497 CAResult_t CAHandleRequestResponse()
498 {
499     if (!g_isInitialized)
500     {
501         OIC_LOG(ERROR, TAG, "not initialized");
502         return CA_STATUS_NOT_INITIALIZED;
503     }
504
505     CAHandleRequestResponseCallbacks();
506
507     return CA_STATUS_OK;
508 }
509
510 CAResult_t CASelectCipherSuite(const uint16_t cipher, CATransportAdapter_t adapter)
511 {
512     (void)(adapter); // prevent unused-parameter warning when building release variant
513     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
514     OIC_LOG_V(DEBUG, TAG, "cipher : %d , CATransportAdapter : %d", cipher, adapter);
515     CAResult_t res = CA_STATUS_FAILED;
516 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
517     res = CAsetTlsCipherSuite(cipher);
518     if (CA_STATUS_OK != res)
519     {
520         OIC_LOG_V(ERROR, TAG, "Failed to CAsetTlsCipherSuite : %d", res);
521     }
522 #else
523     (void)(cipher); // prevent unused-parameter warning
524     OIC_LOG(ERROR, TAG, "Method not supported");
525 #endif
526     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
527     return res;
528 }
529
530 CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
531 {
532     OIC_LOG_V(DEBUG, TAG, "CAEnableAnonECDHCipherSuite");
533     CAResult_t res = CA_STATUS_FAILED;
534 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
535     // TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256    0xFF00 replaces 0xC018
536     res = CAsetTlsCipherSuite(enable ? 0xFF00 : 0x00);
537     if (CA_STATUS_OK != res)
538     {
539         OIC_LOG_V(ERROR, TAG, "Failed to CAsetTlsCipherSuite : %d", res);
540     }
541 #else
542     (void)(enable); // prevent unused-parameter compiler warning
543     OIC_LOG(ERROR, TAG, "Method not supported");
544 #endif
545     OIC_LOG_V(ERROR, TAG, "Out %s", __func__);
546     return res;
547 }
548
549 CAResult_t CAGenerateOwnerPSK(const CAEndpoint_t* endpoint,
550                     const uint8_t* label, const size_t labelLen,
551                     const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
552                     const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
553                     uint8_t* ownerPSK, const size_t ownerPskSize)
554 {
555     OIC_LOG_V(DEBUG, TAG, "IN : CAGenerateOwnerPSK");
556     CAResult_t res = CA_STATUS_FAILED;
557 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
558     //newOwnerLabel and prevOwnerLabe can be NULL
559     if (!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPskSize)
560     {
561         return CA_STATUS_INVALID_PARAM;
562     }
563
564     res = CAsslGenerateOwnerPsk(endpoint, label, labelLen,
565                                       rsrcServerDeviceID, rsrcServerDeviceIDLen,
566                                       provServerDeviceID, provServerDeviceIDLen,
567                                       ownerPSK, ownerPskSize);
568     if (CA_STATUS_OK != res)
569     {
570         OIC_LOG_V(ERROR, TAG, "Failed to CAGenerateOwnerPSK : %d", res);
571     }
572 #else
573     (void)(endpoint); // prevent unused-parameter compiler warnings
574     (void)(label);
575     (void)(labelLen);
576     (void)(rsrcServerDeviceID);
577     (void)(rsrcServerDeviceIDLen);
578     (void)(provServerDeviceID);
579     (void)(provServerDeviceIDLen);
580     (void)(ownerPSK);
581     (void)(ownerPskSize);
582     OIC_LOG(ERROR, TAG, "Method not supported");
583 #endif
584     OIC_LOG_V(DEBUG, TAG, "OUT : CAGenerateOwnerPSK");
585     return res;
586 }
587
588 CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint)
589 {
590     OIC_LOG_V(DEBUG, TAG, "IN : CAInitiateHandshake");
591     CAResult_t res = CA_STATUS_FAILED;
592 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
593     if (!endpoint)
594     {
595         return CA_STATUS_INVALID_PARAM;
596     }
597
598     res = CAinitiateSslHandshake(endpoint);
599     if (CA_STATUS_OK != res)
600     {
601         OIC_LOG_V(ERROR, TAG, "Failed to CAinitiateSslHandshake : %d", res);
602     }
603 #else
604     (void)(endpoint); // prevent unused-parameter compiler warning
605     OIC_LOG(ERROR, TAG, "Method not supported");
606 #endif
607     OIC_LOG_V(DEBUG, TAG, "OUT : CAInitiateHandshake");
608     return res;
609 }
610
611 CAResult_t CAcloseSslSession(const CAEndpoint_t *endpoint)
612 {
613     OIC_LOG_V(DEBUG, TAG, "IN : CAcloseSslSession");
614     CAResult_t res = CA_STATUS_FAILED;
615 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
616     if (!endpoint)
617     {
618         return CA_STATUS_INVALID_PARAM;
619     }
620
621     res = CAcloseSslConnection(endpoint);
622     if (CA_STATUS_OK != res)
623     {
624         OIC_LOG_V(ERROR, TAG, "Failed to CAsslClose : %d", res);
625     }
626 #else
627     (void)(endpoint); // prevent unused-parameter compiler warning
628     OIC_LOG(ERROR, TAG, "Method not supported");
629 #endif
630     OIC_LOG_V(DEBUG, TAG, "OUT : CAcloseSslSession");
631     return res;
632 }
633
634 #ifdef TCP_ADAPTER
635 void CARegisterKeepAliveHandler(CAKeepAliveConnectionCallback ConnHandler)
636 {
637     CATCPSetKeepAliveCallbacks(ConnHandler);
638 }
639 #endif