Update snapshot(2018-01-04)
[platform/upstream/iotivity.git] / resource / provisioning / src / OCProvisioningManager.cpp
1 /* *****************************************************************
2  *
3  * Copyright 2015 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 "ocstack.h"
22 #include "srmutility.h"
23 #include "base64.h"
24 #include "OCProvisioningManager.hpp"
25 #include "mbedtls/x509_crt.h"
26
27
28 namespace OC
29 {
30     OCStackResult OCSecure::provisionInit(const std::string& dbPath)
31     {
32         OCStackResult result;
33         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
34
35         if (cLock)
36         {
37             std::lock_guard<std::recursive_mutex> lock(*cLock);
38             result = OCInitPM(dbPath.c_str());
39         }
40         else
41         {
42             oclog() <<"Mutex not found";
43             result = OC_STACK_ERROR;
44         }
45
46         return result;
47     }
48
49     OCStackResult OCSecure::terminatePM()
50     {
51         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
52
53         if (cLock)
54         {
55             std::lock_guard<std::recursive_mutex> lock(*cLock);
56             OCTerminatePM();
57             return OC_STACK_OK;
58         }
59         else
60         {
61             oclog() <<"Mutex not found";
62             return OC_STACK_ERROR;
63         }
64     }
65
66     OCStackResult OCSecure::discoverUnownedDevices(unsigned short timeout,
67             DeviceList_t &list)
68     {
69         OCStackResult result;
70         OCProvisionDev_t *pDevList = nullptr, *pCurDev = nullptr, *tmp = nullptr;
71         auto csdkLock = OCPlatform_impl::Instance().csdkLock();
72         auto cLock = csdkLock.lock();
73
74         if (cLock)
75         {
76             std::lock_guard<std::recursive_mutex> lock(*cLock);
77             result = OCDiscoverUnownedDevices(timeout, &pDevList);
78             if (result == OC_STACK_OK)
79             {
80                 // Create DeviceList of OCSecureResource's
81                 pCurDev = pDevList;
82                 while (pCurDev)
83                 {
84                     tmp = pCurDev;
85                     list.push_back(std::shared_ptr<OCSecureResource>(
86                                 new OCSecureResource(csdkLock, pCurDev)));
87                     pCurDev = pCurDev->next;
88                     tmp->next = nullptr;
89                 }
90             }
91             else
92             {
93                 oclog() <<"Unowned device discovery failed!";
94             }
95         }
96         else
97         {
98             oclog() <<"Mutex not found";
99             result = OC_STACK_ERROR;
100         }
101
102         return result;
103     }
104
105     OCStackResult OCSecure::discoverOwnedDevices(unsigned short timeout,
106             DeviceList_t &list)
107     {
108         OCStackResult result;
109         OCProvisionDev_t *pDevList = nullptr, *pCurDev = nullptr, *tmp = nullptr;
110         auto csdkLock = OCPlatform_impl::Instance().csdkLock();
111         auto cLock = csdkLock.lock();
112
113         if (cLock)
114         {
115             std::lock_guard<std::recursive_mutex> lock(*cLock);
116             result = OCDiscoverOwnedDevices(timeout, &pDevList);
117             if (result == OC_STACK_OK)
118             {
119                 pCurDev = pDevList;
120                 while (pCurDev)
121                 {
122                     tmp = pCurDev;
123                     list.push_back(std::shared_ptr<OCSecureResource>(
124                                 new OCSecureResource(csdkLock, pCurDev)));
125                     pCurDev = pCurDev->next;
126                     tmp->next = nullptr;
127                 }
128             }
129             else
130             {
131                 oclog() <<"Owned device discovery failed!";
132             }
133         }
134         else
135         {
136             oclog() <<"Mutex not found";
137             result = OC_STACK_ERROR;
138         }
139
140         return result;
141     }
142
143     OCStackResult OCSecure::discoverSingleDevice(unsigned short timeout,
144             const OicUuid_t* deviceID,
145             std::shared_ptr<OCSecureResource> &foundDevice)
146     {
147         OCStackResult result;
148         OCProvisionDev_t *pDev = nullptr;
149         auto csdkLock = OCPlatform_impl::Instance().csdkLock();
150         auto cLock = csdkLock.lock();
151
152         if (cLock)
153         {
154             std::lock_guard<std::recursive_mutex> lock(*cLock);
155             result = OCDiscoverSingleDevice(timeout, deviceID, &pDev);
156             if (result == OC_STACK_OK)
157             {
158                 if (pDev)
159                 {
160                     foundDevice.reset(new OCSecureResource(csdkLock, pDev));
161                 }
162                 else
163                 {
164                     oclog() <<"Not found Secure resource!";
165                     foundDevice.reset();
166                 }
167             }
168             else
169             {
170                 oclog() <<"Secure resource discovery failed!";
171             }
172         }
173         else
174         {
175             oclog() <<"Mutex not found";
176             result = OC_STACK_ERROR;
177         }
178
179         return result;
180     }
181
182     OCStackResult OCSecure::discoverSingleDeviceInUnicast(unsigned short timeout,
183             const OicUuid_t* deviceID,
184             const std::string& hostAddress,
185             OCConnectivityType connType,
186             std::shared_ptr<OCSecureResource> &foundDevice)
187     {
188         OCStackResult result = OC_STACK_ERROR;
189         OCProvisionDev_t *pDev = nullptr;
190         auto csdkLock = OCPlatform_impl::Instance().csdkLock();
191         auto cLock = csdkLock.lock();
192
193         if (cLock)
194         {
195             std::lock_guard<std::recursive_mutex> lock(*cLock);
196             result = OCDiscoverSingleDeviceInUnicast(timeout, deviceID, hostAddress.c_str(),
197                             connType, &pDev);
198
199             if (result == OC_STACK_OK)
200             {
201                 if (pDev)
202                 {
203                     foundDevice.reset(new OCSecureResource(csdkLock, pDev));
204                 }
205                 else
206                 {
207                     oclog() <<"Not found Secure resource!";
208                     foundDevice.reset();
209                 }
210             }
211             else
212             {
213                 oclog() <<"Secure resource discovery failed!";
214             }
215         }
216         else
217         {
218             oclog() <<"Mutex not found";
219             result = OC_STACK_ERROR;
220         }
221
222         return result;
223     }
224
225 #ifdef MULTIPLE_OWNER
226     OCStackResult OCSecure::discoverMultipleOwnerEnabledDevices(unsigned short timeout,
227             DeviceList_t &list)
228     {
229         OCStackResult result;
230         OCProvisionDev_t *pDevList = nullptr, *pCurDev = nullptr, *tmp = nullptr;
231         auto csdkLock = OCPlatform_impl::Instance().csdkLock();
232         auto cLock = csdkLock.lock();
233
234         if (cLock)
235         {
236             std::lock_guard<std::recursive_mutex> lock(*cLock);
237             result = OCDiscoverMultipleOwnerEnabledDevices(timeout, &pDevList);
238             if (result == OC_STACK_OK)
239             {
240                 pCurDev = pDevList;
241                 while (pCurDev)
242                 {
243                     tmp = pCurDev;
244                     list.push_back(std::shared_ptr<OCSecureResource>(
245                                 new OCSecureResource(csdkLock, pCurDev)));
246                     pCurDev = pCurDev->next;
247                     tmp->next = nullptr;
248                 }
249             }
250             else
251             {
252                 oclog() <<"MultipleOwner Enabled device discovery failed!";
253             }
254         }
255         else
256         {
257             oclog() <<"Mutex not found";
258             result = OC_STACK_ERROR;
259         }
260
261         return result;
262     }
263
264     OCStackResult OCSecure::discoverMultipleOwnedDevices(unsigned short timeout,
265             DeviceList_t &list)
266     {
267         OCStackResult result;
268         OCProvisionDev_t *pDevList = nullptr, *pCurDev = nullptr, *tmp = nullptr;
269         auto csdkLock = OCPlatform_impl::Instance().csdkLock();
270         auto cLock = csdkLock.lock();
271
272         if (cLock)
273         {
274             std::lock_guard<std::recursive_mutex> lock(*cLock);
275             result = OCDiscoverMultipleOwnedDevices(timeout, &pDevList);
276             if (result == OC_STACK_OK)
277             {
278                 pCurDev = pDevList;
279                 while (pCurDev)
280                 {
281                     tmp = pCurDev;
282                     list.push_back(std::shared_ptr<OCSecureResource>(
283                                 new OCSecureResource(csdkLock, pCurDev)));
284                     pCurDev = pCurDev->next;
285                     tmp->next = nullptr;
286                 }
287             }
288             else
289             {
290                 oclog() <<"Multiple Owned device discovery failed!";
291             }
292         }
293         else
294         {
295             oclog() <<"Mutex not found";
296             result = OC_STACK_ERROR;
297         }
298
299         return result;
300     }
301
302 #endif
303     OCStackResult OCSecure::setInputPinCallback(InputPinCallback inputPin)
304     {
305         OCStackResult result;
306         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
307
308         if (cLock)
309         {
310             std::lock_guard<std::recursive_mutex> lock(*cLock);
311             SetInputPinCB(inputPin);
312             result = OC_STACK_OK;
313         }
314         else
315         {
316             oclog() <<"Mutex not found";
317             result = OC_STACK_ERROR;
318         }
319
320         return result;
321     }
322
323
324     OCStackResult OCSecure::unsetInputPinCallback()
325     {
326         OCStackResult result;
327         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
328
329         if (cLock)
330         {
331             std::lock_guard<std::recursive_mutex> lock(*cLock);
332             UnsetInputPinCB();
333             result = OC_STACK_OK;
334         }
335         else
336         {
337             oclog() <<"Mutex not found";
338             result = OC_STACK_ERROR;
339         }
340
341         return result;
342     }
343
344     OCStackResult OCSecure::setRandomPinPolicy(size_t pinSize, OicSecPinType_t pinType)
345     {
346         OCStackResult result;
347         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
348
349         if (cLock)
350         {
351             std::lock_guard<std::recursive_mutex> lock(*cLock);
352             result = SetRandomPinPolicy(pinSize, pinType);
353         }
354         else
355         {
356             oclog() <<"Mutex not found";
357             result = OC_STACK_ERROR;
358         }
359         return result;
360     }
361
362     OCStackResult OCSecure::getDevInfoFromNetwork(unsigned short timeout,
363             DeviceList_t &ownedDevList,
364             DeviceList_t &unownedDevList)
365     {
366         OCStackResult result = OC_STACK_OK;
367         OCProvisionDev_t *owned = nullptr, *unowned = nullptr, *tmp = nullptr, *dev = nullptr;
368         auto csdkLock = OCPlatform_impl::Instance().csdkLock();
369         auto cLock = csdkLock.lock();
370
371         if (cLock)
372         {
373             std::lock_guard<std::recursive_mutex> lock(*cLock);
374
375             result = OCGetDevInfoFromNetwork(timeout, &owned, &unowned);
376
377             if (result == OC_STACK_OK)
378             {
379                 dev = owned;
380                 while (dev)
381                 {
382                     tmp = dev;
383                     ownedDevList.push_back(std::shared_ptr<OCSecureResource>(
384                                 new OCSecureResource(csdkLock, dev)));
385                     dev = dev->next;
386                     tmp->next = nullptr;
387                 }
388
389                 dev = unowned;
390                 while (dev)
391                 {
392                     tmp = dev;
393                     unownedDevList.push_back(std::shared_ptr<OCSecureResource>(
394                                 new OCSecureResource(csdkLock,  dev)));
395                     dev = dev->next;
396                     tmp->next = nullptr;
397                 }
398             }
399         }
400         else
401         {
402             oclog() <<"Mutex not found";
403             result = OC_STACK_ERROR;
404         }
405
406         return result;
407     }
408
409     OCStackResult OCSecure::setDisplayPinCB(GeneratePinCallback displayPin)
410     {
411         if (!displayPin)
412         {
413             oclog() <<"displayPin can't be null";
414             return OC_STACK_INVALID_PARAM;
415         }
416
417         OCStackResult result = OC_STACK_OK;
418         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
419
420         if (cLock)
421         {
422             std::lock_guard<std::recursive_mutex> lock(*cLock);
423             SetGeneratePinCB(displayPin);
424         }
425         else
426         {
427             oclog() <<"Mutex not found";
428             result = OC_STACK_ERROR;
429         }
430
431         return result;
432     }
433
434     OCStackResult OCSecure::removeDeviceWithUuid(unsigned short waitTimeForOwnedDeviceDiscovery,
435             std::string uuid,
436             ResultCallBack resultCallback)
437     {
438         if (!resultCallback)
439         {
440             oclog() << "Result calback can't be null";
441             return OC_STACK_INVALID_CALLBACK;
442         }
443
444         OCStackResult result;
445         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
446
447         if (cLock)
448         {
449             ProvisionContext* context = new ProvisionContext(resultCallback);
450
451             std::lock_guard<std::recursive_mutex> lock(*cLock);
452
453             OicUuid_t targetDev;
454             result = ConvertStrToUuid(uuid.c_str(), &targetDev);
455             if(OC_STACK_OK == result)
456             {
457                 result = OCRemoveDeviceWithUuid(static_cast<void*>(context), waitTimeForOwnedDeviceDiscovery,
458                         &targetDev, &OCSecureResource::callbackWrapper);
459             }
460             else
461             {
462                 oclog() <<"Can not convert struuid to uuid";
463             }
464         }
465         else
466         {
467             oclog() <<"Mutex not found";
468             result = OC_STACK_ERROR;
469         }
470         return result;
471     }
472
473     OCStackResult OCSecure::saveACL(const OicSecAcl_t* acl)
474     {
475         if (!acl)
476         {
477             oclog() <<"ACL can't be null";
478             return OC_STACK_INVALID_PARAM;
479         }
480
481         OCStackResult result;
482         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
483
484         if (cLock)
485         {
486             std::lock_guard<std::recursive_mutex> lock(*cLock);
487             result = OCSaveACL(const_cast<OicSecAcl_t*>(acl));
488         }
489         else
490         {
491             oclog() <<"Mutex not found";
492             result = OC_STACK_ERROR;
493         }
494         return result;
495     }
496
497     OCStackResult OCSecure::displayNumCallbackWrapper(void* ctx,
498             uint8_t verifNum[MUTUAL_VERIF_NUM_LEN])
499     {
500         uint8_t *number = NULL;
501
502         DisplayNumContext* context = static_cast<DisplayNumContext*>(ctx);
503         if (!context)
504         {
505             oclog() << "Invalid context";
506             return OC_STACK_INVALID_PARAM;
507         }
508
509         if (NULL != verifNum) {
510             number = new uint8_t[MUTUAL_VERIF_NUM_LEN];
511             memcpy(number, verifNum, MUTUAL_VERIF_NUM_LEN);
512         }
513
514         return context->callback(number);
515     }
516
517     OCStackResult OCSecure::registerDisplayNumCallback(DisplayNumCB displayNumCB)
518     {
519         if(!displayNumCB)
520         {
521             oclog() << "Failed to register callback for display.";
522             return OC_STACK_INVALID_CALLBACK;
523         }
524
525         OCStackResult result = OCSecure::deregisterDisplayNumCallback();
526         if (OC_STACK_OK != result)
527         {
528             oclog() << "Failed to de-register callback for display."<<std::endl;
529             return result;
530         }
531
532         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
533         if (cLock)
534         {
535             DisplayNumContext* context = new DisplayNumContext(displayNumCB);
536             std::lock_guard<std::recursive_mutex> lock(*cLock);
537             SetDisplayNumCB(static_cast<void*>(context), &OCSecure::displayNumCallbackWrapper);
538             result = OC_STACK_OK;
539         }
540         else
541         {
542             oclog() <<"Mutex not found";
543             result = OC_STACK_ERROR;
544         }
545         return result;
546     }
547
548     OCStackResult OCSecure::deregisterDisplayNumCallback()
549     {
550         OCStackResult result;
551         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
552
553         if (cLock)
554         {
555             std::lock_guard<std::recursive_mutex> lock(*cLock);
556             DisplayNumContext* context = static_cast<DisplayNumContext*>(UnsetDisplayNumCB());
557             if (context)
558             {
559                 oclog() << "Delete registered display num context"<<std::endl;
560                 delete context;
561             }
562             result = OC_STACK_OK;
563         }
564         else
565         {
566             oclog() <<"Mutex not found";
567             result = OC_STACK_ERROR;
568         }
569         return result;
570     }
571
572     OCStackResult OCSecure::confirmUserCallbackWrapper(void* ctx)
573     {
574         UserConfirmNumContext* context = static_cast<UserConfirmNumContext*>(ctx);
575         if (!context)
576         {
577             oclog() << "Invalid context";
578             return OC_STACK_INVALID_PARAM;
579         }
580
581         return context->callback();
582     }
583
584     OCStackResult OCSecure::registerUserConfirmCallback(UserConfirmNumCB userConfirmCB)
585     {
586         if(!userConfirmCB)
587         {
588             oclog() << "Failed to set callback for confirming verifying callback.";
589             return OC_STACK_INVALID_CALLBACK;
590         }
591
592         OCStackResult result = OCSecure::deregisterUserConfirmCallback();
593         if (OC_STACK_OK != result)
594         {
595             oclog() << "Failed to de-register callback for comfirm."<<std::endl;
596             return result;
597         }
598
599         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
600         if (cLock)
601         {
602             UserConfirmNumContext* context = new UserConfirmNumContext(userConfirmCB);
603             std::lock_guard<std::recursive_mutex> lock(*cLock);
604             SetUserConfirmCB(static_cast<void*>(context), &OCSecure::confirmUserCallbackWrapper);
605             result = OC_STACK_OK;
606         }
607         else
608         {
609             oclog() <<"Mutex not found";
610             result = OC_STACK_ERROR;
611         }
612         return result;
613     }
614
615     OCStackResult OCSecure::deregisterUserConfirmCallback()
616     {
617         OCStackResult result;
618         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
619
620         if (cLock)
621         {
622             std::lock_guard<std::recursive_mutex> lock(*cLock);
623             UserConfirmNumContext* context = static_cast<UserConfirmNumContext*>(UnsetUserConfirmCB());
624             if (context)
625             {
626                 oclog() << "Delete registered user confirm context"<<std::endl;
627                 delete context;
628             }
629             result = OC_STACK_OK;
630         }
631         else
632         {
633             oclog() <<"Mutex not found";
634             result = OC_STACK_ERROR;
635         }
636         return result;
637     }
638
639     OCStackResult OCSecure::setVerifyOptionMask(VerifyOptionBitmask_t optionMask)
640     {
641         OCStackResult result;
642         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
643         if (cLock)
644         {
645             std::lock_guard<std::recursive_mutex> lock(*cLock);
646             SetVerifyOption(optionMask);
647             result = OC_STACK_OK;
648         }
649         else
650         {
651             oclog() <<"Mutex not found";
652             result = OC_STACK_ERROR;
653         }
654         return result;
655     }
656
657     OCStackResult OCSecure::pdmCleanupForTimeout()
658     {
659         OCStackResult result;
660         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
661         if (cLock)
662         {
663             result = OCPDMCleanupForTimeout();
664         }
665         else
666         {
667             oclog() <<"Mutex not found";
668             result = OC_STACK_ERROR;
669         }
670         return result;
671     }
672
673     OCStackResult OCSecure::configSelfOwnership()
674     {
675         OCStackResult result;
676         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
677         if (cLock)
678         {
679             std::lock_guard<std::recursive_mutex> lock(*cLock);
680             result = OCConfigSelfOwnership();
681         }
682         else
683         {
684             oclog() <<"Mutex not found";
685             result = OC_STACK_ERROR;
686         }
687         return result;
688     }
689
690 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
691     OCStackResult OCSecure::saveTrustCertChain(uint8_t *trustCertChain, size_t chainSize,
692                                         OicEncodingType_t encodingType, uint16_t *credId)
693     {
694         if (!trustCertChain)
695         {
696             oclog() <<"trustCertChain can't be null";
697             return OC_STACK_INVALID_PARAM;
698         }
699         if (!credId)
700         {
701             oclog() <<"cred ID can not be null";
702             return OC_STACK_INVALID_PARAM;
703         }
704
705         OCStackResult result;
706         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
707
708         if (cLock)
709         {
710             std::lock_guard<std::recursive_mutex> lock(*cLock);
711             result = OCSaveTrustCertChain(trustCertChain, chainSize, encodingType, credId );
712         }
713         else
714         {
715             oclog() <<"Mutex not found";
716             result = OC_STACK_ERROR;
717         }
718         return result;
719     }
720
721     OCStackResult OCSecure::readTrustCertChain(uint16_t credId, uint8_t **trustCertChain,
722             size_t *chainSize)
723     {
724         OCStackResult result;
725         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
726
727         if (cLock)
728         {
729             std::lock_guard<std::recursive_mutex> lock(*cLock);
730             result = OCReadTrustCertChain(credId, trustCertChain, chainSize);
731         }
732         else
733         {
734             oclog() <<"Mutex not found";
735             result = OC_STACK_ERROR;
736         }
737         return result;
738     }
739
740     void OCSecure::certCallbackWrapper(void* ctx, uint16_t credId, uint8_t *trustCertChain,
741             size_t chainSize)
742     {
743         TrustCertChainContext* context = static_cast<TrustCertChainContext*>(ctx);
744         uint8_t *certChain = new uint8_t[chainSize];
745         memcpy(certChain, trustCertChain, chainSize);
746         std::thread exec(context->callback, credId, certChain, chainSize);
747         exec.detach();
748         delete context;
749     }
750
751     OCStackResult OCSecure::registerTrustCertChangeNotifier(CertChainCallBack callback)
752     {
753         if (!callback)
754         {
755             oclog() <<"callback can not be null";
756             return OC_STACK_INVALID_CALLBACK;
757         }
758
759         OCStackResult result;
760         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
761
762         if (cLock)
763         {
764             TrustCertChainContext* context = new TrustCertChainContext(callback);
765             std::lock_guard<std::recursive_mutex> lock(*cLock);
766             result = OCRegisterTrustCertChainNotifier(static_cast<void*>(context),
767                     &OCSecure::certCallbackWrapper);
768         }
769         else
770         {
771             oclog() <<"Mutex not found";
772             result = OC_STACK_ERROR;
773         }
774         return result;
775     }
776
777
778     OCStackResult OCSecure::removeTrustCertChangeNotifier()
779     {
780         OCStackResult result;
781         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
782
783         if (cLock)
784         {
785             std::lock_guard<std::recursive_mutex> lock(*cLock);
786             OCRemoveTrustCertChainNotifier();
787             result = OC_STACK_OK;
788         }
789         else
790         {
791             oclog() <<"Mutex not found";
792             result = OC_STACK_ERROR;
793         }
794         return result;
795     }
796
797     OCStackResult OCSecure::setDeviceIdSeed(const uint8_t* seed, size_t seedSize)
798     {
799         if (!seed)
800         {
801             oclog() <<"seed can not be null";
802             return OC_STACK_INVALID_PARAM;
803         }
804
805         return SetDeviceIdSeed(seed, seedSize);
806     }
807
808     int OCSecure::peerCertCallbackWrapper(void *ctx, const mbedtls_x509_crt *cert,
809             int depth)
810     {
811         OCStackResult ret = OC_STACK_ERROR;
812
813         PeerCertContext *context = static_cast<PeerCertContext*>(ctx);
814         if (NULL == context)
815         {
816             oclog() << "Invalid Context";
817             return 1;
818         }
819
820         if (context->callback)
821         {
822             ret = context->callback(cert, depth);
823         }
824
825         return (OC_STACK_OK == ret)? 0 : 1;
826     }
827
828     OCStackResult OCSecure::setPeerCertCallback(PeerCertCB peerCertCallback)
829     {
830         OCStackResult result;
831         // UNSET cb
832         if (NULL == peerCertCallback)
833         {
834             result = OCSetPeerCertCallback(NULL, NULL);
835             if (OC_STACK_OK != result)
836             {
837                 oclog() << "OCSetPeerCertCallback() Failed";
838             }
839             return result;
840         }
841
842         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
843
844         if (cLock)
845         {
846             PeerCertContext *context = new PeerCertContext(peerCertCallback);
847
848             std::lock_guard<std::recursive_mutex> lock(*cLock);
849             result = OCSetPeerCertCallback(static_cast<void*>(context),
850                     &OCSecure::peerCertCallbackWrapper);
851             if (OC_STACK_OK != result)
852             {
853                 oclog() << "OCSetPeerCertCallback() Failed";
854             }
855         }
856         else
857         {
858             oclog() << "Mutex not found";
859             result = OC_STACK_ERROR;
860         }
861         return result;
862     }
863
864 #endif // __WITH_DTLS__ || __WITH_TLS__
865
866     void OCSecureResource::callbackWrapper(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
867     {
868         PMResultList_t *results = nullptr;
869         ProvisionContext* context = static_cast<ProvisionContext*>(ctx);
870
871         try
872         {
873             results = new PMResultList_t;
874         }
875         catch (std::bad_alloc& e)
876         {
877             oclog() <<"Bad alloc exception";
878             return;
879         }
880
881         for (int i = 0; i < nOfRes; i++)
882         {
883             results->push_back(arr[i]);
884         }
885
886         std::thread exec(context->callback, results, hasError);
887         exec.detach();
888
889         delete context;
890     }
891
892     OCSecureResource::OCSecureResource(): m_csdkLock(std::weak_ptr<std::recursive_mutex>()),
893                                         devPtr(nullptr)
894     {
895     }
896
897     OCSecureResource::OCSecureResource(std::weak_ptr<std::recursive_mutex> csdkLock,
898             OCProvisionDev_t *dPtr)
899         :m_csdkLock(csdkLock), devPtr(dPtr)
900     {
901     }
902
903     OCSecureResource::~OCSecureResource()
904     {
905         if (devPtr)
906         {
907             OCDeleteDiscoveredDevices(devPtr);
908         }
909     }
910
911     OCStackResult OCSecureResource::doOwnershipTransfer(ResultCallBack resultCallback)
912     {
913         if (!resultCallback)
914         {
915             oclog() <<"Result callback can't be null";
916             return OC_STACK_INVALID_CALLBACK;
917         }
918
919         OCStackResult result;
920         auto cLock = m_csdkLock.lock();
921
922         if (cLock)
923         {
924             ProvisionContext* context = new ProvisionContext(resultCallback);
925
926             std::lock_guard<std::recursive_mutex> lock(*cLock);
927             result = OCDoOwnershipTransfer(static_cast<void*>(context),
928                     devPtr, &OCSecureResource::callbackWrapper);
929         }
930         else
931         {
932             oclog() <<"Mutex not found";
933             result = OC_STACK_ERROR;
934         }
935         return result;
936     }
937
938 #ifdef MULTIPLE_OWNER
939     OCStackResult OCSecureResource::doMultipleOwnershipTransfer(ResultCallBack resultCallback)
940     {
941         if (!resultCallback)
942         {
943             oclog() <<"Result callback can't be null";
944             return OC_STACK_INVALID_CALLBACK;
945         }
946
947         OCStackResult result;
948         auto cLock = m_csdkLock.lock();
949
950         if (cLock)
951         {
952             ProvisionContext* context = new ProvisionContext(resultCallback);
953
954             std::lock_guard<std::recursive_mutex> lock(*cLock);
955             result = OCDoMultipleOwnershipTransfer(static_cast<void*>(context),
956                     devPtr, &OCSecureResource::callbackWrapper);
957         }
958         else
959         {
960             oclog() <<"Mutex not found";
961             result = OC_STACK_ERROR;
962         }
963         return result;
964     }
965
966     OCStackResult OCSecureResource::getSubOwnerList(UuidList_t &uuidList)
967     {
968         validateSecureResource();
969         OicSecSubOwner_t* tmp = NULL;
970         for (tmp = devPtr->doxm->subOwners; tmp; tmp = tmp->next)
971         {
972             uuidList.push_back(tmp->uuid);
973         }
974         return OC_STACK_OK;
975     }
976
977 #endif
978     OCStackResult OCSecureResource::provisionACL( const OicSecAcl_t* acl,
979             ResultCallBack resultCallback)
980     {
981         if (!acl)
982         {
983             oclog() <<"ACL can't be null";
984             return OC_STACK_INVALID_PARAM;
985         }
986         if (!resultCallback)
987         {
988             oclog() <<"result callback can not be null";
989             return OC_STACK_INVALID_CALLBACK;
990         }
991
992         OCStackResult result;
993         auto cLock = m_csdkLock.lock();
994
995         if (cLock)
996         {
997             ProvisionContext* context = new ProvisionContext(resultCallback);
998
999             std::lock_guard<std::recursive_mutex> lock(*cLock);
1000             result = OCProvisionACL(static_cast<void*>(context),
1001                     devPtr, const_cast<OicSecAcl_t*>(acl),
1002                     &OCSecureResource::callbackWrapper);
1003         }
1004         else
1005         {
1006             oclog() <<"Mutex not found";
1007             result = OC_STACK_ERROR;
1008         }
1009         return result;
1010     }
1011
1012     OCStackResult OCSecureResource::provisionCredentials(const Credential &cred,
1013             const OCSecureResource &device2, ResultCallBack resultCallback)
1014     {
1015         if (!resultCallback)
1016         {
1017             oclog() << "Result calback can't be null";
1018             return OC_STACK_INVALID_CALLBACK;
1019         }
1020
1021         OCStackResult result;
1022         auto cLock = m_csdkLock.lock();
1023
1024         if (cLock)
1025         {
1026             ProvisionContext* context = new ProvisionContext(resultCallback);
1027
1028             std::lock_guard<std::recursive_mutex> lock(*cLock);
1029             result = OCProvisionCredentials(static_cast<void*>(context),
1030                     cred.getCredentialType(),
1031                     cred.getCredentialKeySize(),
1032                     devPtr, device2.getDevPtr(),
1033                     &OCSecureResource::callbackWrapper);
1034         }
1035         else
1036         {
1037             oclog() <<"Mutex not found";
1038             result = OC_STACK_ERROR;
1039         }
1040         return result;
1041     }
1042
1043     OCStackResult OCSecureResource::provisionPairwiseDevices(const Credential &cred,
1044             const OicSecAcl_t* acl1, const OCSecureResource &device2, const OicSecAcl_t* acl2,
1045             ResultCallBack resultCallback)
1046     {
1047         if (!resultCallback)
1048         {
1049             oclog() << "Result callback can not be null";
1050             return OC_STACK_INVALID_CALLBACK;
1051         }
1052
1053         OCStackResult result;
1054         auto cLock = m_csdkLock.lock();
1055
1056         if (cLock)
1057         {
1058             ProvisionContext* context = new ProvisionContext(resultCallback);
1059
1060             std::lock_guard<std::recursive_mutex> lock(*cLock);
1061             result = OCProvisionPairwiseDevices(static_cast<void*>(context),
1062                     cred.getCredentialType(),
1063                     cred.getCredentialKeySize(),
1064                     devPtr, const_cast<OicSecAcl_t*>(acl1),
1065                     device2.getDevPtr(), const_cast<OicSecAcl_t*>(acl2),
1066                     &OCSecureResource::callbackWrapper);
1067         }
1068         else
1069         {
1070             oclog() <<"Mutex not found";
1071             result = OC_STACK_ERROR;
1072         }
1073         return result;
1074     }
1075
1076     OCStackResult OCSecureResource::unlinkDevices(const OCSecureResource &device2,
1077             ResultCallBack resultCallback)
1078     {
1079         if (!resultCallback)
1080         {
1081             oclog() << "Result calback can't be null";
1082             return OC_STACK_INVALID_CALLBACK;
1083         }
1084
1085         OCStackResult result;
1086         auto cLock = m_csdkLock.lock();
1087
1088         if (cLock)
1089         {
1090             ProvisionContext* context = new ProvisionContext(resultCallback);
1091
1092             std::lock_guard<std::recursive_mutex> lock(*cLock);
1093
1094             result = OCUnlinkDevices(static_cast<void*>(context),
1095                     devPtr, device2.getDevPtr(), &OCSecureResource::callbackWrapper);
1096         }
1097         else
1098         {
1099             oclog() <<"Mutex not found";
1100             result = OC_STACK_ERROR;
1101         }
1102         return result;
1103     }
1104
1105     OCStackResult OCSecureResource::removeDevice(unsigned short waitTimeForOwnedDeviceDiscovery,
1106             ResultCallBack resultCallback)
1107     {
1108         if (!resultCallback)
1109         {
1110             oclog() << "Result calback can't be null";
1111             return OC_STACK_INVALID_CALLBACK;
1112         }
1113
1114         OCStackResult result;
1115         auto cLock = m_csdkLock.lock();
1116
1117         if (cLock)
1118         {
1119             ProvisionContext* context = new ProvisionContext(resultCallback);
1120
1121             std::lock_guard<std::recursive_mutex> lock(*cLock);
1122
1123             result = OCRemoveDevice(static_cast<void*>(context), waitTimeForOwnedDeviceDiscovery,
1124                     devPtr, &OCSecureResource::callbackWrapper);
1125         }
1126         else
1127         {
1128             oclog() <<"Mutex not found";
1129             result = OC_STACK_ERROR;
1130         }
1131         return result;
1132     }
1133
1134     OCStackResult OCSecureResource::getLinkedDevices(UuidList_t &uuidList)
1135     {
1136         OCStackResult result;
1137         size_t numOfDevices = -1;
1138         auto devUuid = devPtr->doxm->deviceID;
1139         auto cLock = m_csdkLock.lock();
1140
1141         if (cLock)
1142         {
1143             std::lock_guard<std::recursive_mutex> lock(*cLock);
1144
1145             OCUuidList_t* linkedDevs = nullptr, *tmp = nullptr;
1146             result = OCGetLinkedStatus(&devUuid, &linkedDevs, &numOfDevices);
1147             if (result == OC_STACK_OK)
1148             {
1149                 for (tmp = linkedDevs; tmp; tmp = tmp->next)
1150                 {
1151                     uuidList.push_back(tmp->dev);
1152                 }
1153                 OCDeleteUuidList(linkedDevs);
1154             }
1155         }
1156         else
1157         {
1158             oclog() <<"Mutex not found";
1159             result = OC_STACK_ERROR;
1160         }
1161         return result;
1162     }
1163
1164     OCStackResult OCSecureResource::provisionDirectPairing( const OicSecPconf_t* pconf,
1165             ResultCallBack resultCallback)
1166     {
1167         if (!pconf)
1168         {
1169             oclog() <<"PCONF can't be null";
1170             return OC_STACK_INVALID_PARAM;
1171         }
1172         if (!resultCallback)
1173         {
1174             oclog() <<"result callback can not be null";
1175             return OC_STACK_INVALID_CALLBACK;
1176         }
1177
1178         OCStackResult result;
1179         auto cLock = m_csdkLock.lock();
1180
1181         if (cLock)
1182         {
1183             ProvisionContext* context = new ProvisionContext(resultCallback);
1184
1185             std::lock_guard<std::recursive_mutex> lock(*cLock);
1186             result = OCProvisionDirectPairing(static_cast<void*>(context),
1187                     devPtr, const_cast<OicSecPconf_t*>(pconf),
1188                     &OCSecureResource::callbackWrapper);
1189         }
1190         else
1191         {
1192             oclog() <<"Mutex not found";
1193             result = OC_STACK_ERROR;
1194         }
1195         return result;
1196     }
1197
1198 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1199     OCStackResult OCSecureResource::provisionTrustCertChain(OicSecCredType_t type, uint16_t credId,
1200                     ResultCallBack resultCallback)
1201     {
1202         if (SIGNED_ASYMMETRIC_KEY != type)
1203         {
1204             oclog() <<"Invalid key type";
1205             return OC_STACK_INVALID_PARAM;
1206         }
1207         if (!resultCallback)
1208         {
1209             oclog() <<"result callback can not be null";
1210             return OC_STACK_INVALID_CALLBACK;
1211         }
1212
1213         OCStackResult result;
1214         auto cLock = m_csdkLock.lock();
1215
1216         if (cLock)
1217         {
1218             ProvisionContext* context = new ProvisionContext(resultCallback);
1219
1220             std::lock_guard<std::recursive_mutex> lock(*cLock);
1221             result = OCProvisionTrustCertChain(static_cast<void*>(context),
1222                     type, credId, devPtr,
1223                     &OCSecureResource::callbackWrapper);
1224         }
1225         else
1226         {
1227             oclog() <<"Mutex not found";
1228             result = OC_STACK_ERROR;
1229         }
1230         return result;
1231     }
1232 #endif // __WITH_DTLS__ or __WITH_TLS__
1233
1234     std::string OCSecureResource::getDeviceID()
1235     {
1236         std::ostringstream deviceId("");
1237         char *devID = nullptr;
1238
1239         validateSecureResource();
1240
1241         if (OC_STACK_OK == ConvertUuidToStr(&(devPtr->doxm->deviceID), &devID))
1242         {
1243             deviceId << devID;
1244             free(devID);
1245         }
1246         else
1247         {
1248             oclog() <<"Can not convert uuid to struuid";
1249         }
1250         return deviceId.str();
1251     }
1252
1253     OCProvisionDev_t* OCSecureResource::getDevPtr() const
1254     {
1255         return devPtr;
1256     }
1257
1258     std::string OCSecureResource::getDevAddr()
1259     {
1260         validateSecureResource();
1261         std::string ipAddr(devPtr->endpoint.addr);
1262         return ipAddr;
1263     }
1264
1265     int OCSecureResource::getDeviceStatus()
1266     {
1267         validateSecureResource();
1268         return (int)devPtr->devStatus;
1269     }
1270
1271     bool OCSecureResource::getOwnedStatus()
1272     {
1273         validateSecureResource();
1274         return devPtr->doxm->owned;
1275     }
1276
1277     void OCSecureResource::validateSecureResource()
1278     {
1279         if (!devPtr)
1280         {
1281             throw OCException("Incomplete secure resource", OC_STACK_RESOURCE_ERROR);
1282         }
1283     }
1284
1285     OCStackResult OCSecureResource::getOTMethod(OicSecOxm_t* oxm)
1286     {
1287         if(!oxm)
1288         {
1289             oclog() << "Null param";
1290             return OC_STACK_INVALID_PARAM;
1291         }
1292
1293         OCStackResult result = OC_STACK_ERROR;
1294         auto cLock = m_csdkLock.lock();
1295         if (cLock)
1296         {
1297             std::lock_guard<std::recursive_mutex> lock(*cLock);
1298             if(devPtr && devPtr->doxm)
1299             {
1300                 result = OCSelectOwnershipTransferMethod(devPtr->doxm->oxm, devPtr->doxm->oxmLen,
1301                                                   oxm, SUPER_OWNER);
1302             }
1303         }
1304         else
1305         {
1306             oclog() <<"Mutex not found";
1307         }
1308         return result;
1309     }
1310
1311
1312 #ifdef MULTIPLE_OWNER
1313     OCStackResult OCSecureResource::getMOTMethod( OicSecOxm_t* oxm)
1314     {
1315         if (!oxm)
1316         {
1317             oclog() << "Null param";
1318             return OC_STACK_INVALID_PARAM;
1319         }
1320
1321         OCStackResult result = OC_STACK_ERROR;
1322         auto cLock = m_csdkLock.lock();
1323         if (cLock)
1324         {
1325             std::lock_guard<std::recursive_mutex> lock(*cLock);
1326             if (devPtr && devPtr->doxm)
1327             {
1328                 result = OCSelectOwnershipTransferMethod(devPtr->doxm->oxm, devPtr->doxm->oxmLen,
1329                                                   oxm, SUB_OWNER);
1330             }
1331         }
1332         else
1333         {
1334             oclog() <<"Mutex not found";
1335         }
1336         return result;
1337     }
1338
1339     bool OCSecureResource::isMOTSupported()
1340     {
1341         if (devPtr && devPtr->doxm)
1342         {
1343             return (devPtr->doxm->mom ? true : false);
1344         }
1345         return false;
1346     }
1347
1348     bool OCSecureResource::isMOTEnabled()
1349     {
1350         if (devPtr && devPtr->doxm && devPtr->doxm->mom)
1351         {
1352             if (OIC_MULTIPLE_OWNER_DISABLE != devPtr->doxm->mom->mode)
1353             {
1354                 return true;
1355             }
1356         }
1357         return false;
1358     }
1359
1360     OCStackResult OCSecureResource::selectMOTMethod( const OicSecOxm_t oxmSelVal,
1361             ResultCallBack resultCallback)
1362     {
1363         if (!resultCallback)
1364         {
1365             oclog() <<"result callback can not be null";
1366             return OC_STACK_INVALID_CALLBACK;
1367         }
1368
1369         OCStackResult result;
1370         auto cLock = m_csdkLock.lock();
1371
1372         if (cLock)
1373         {
1374             ProvisionContext* context = new ProvisionContext(resultCallback);
1375
1376             std::lock_guard<std::recursive_mutex> lock(*cLock);
1377             result = OCSelectMOTMethod(static_cast<void*>(context),
1378                     devPtr, oxmSelVal,
1379                     &OCSecureResource::callbackWrapper);
1380         }
1381         else
1382         {
1383             oclog() <<"Mutex not found";
1384             result = OC_STACK_ERROR;
1385         }
1386         return result;
1387     }
1388
1389     OCStackResult OCSecureResource::changeMOTMode( const OicSecMomType_t momType,
1390             ResultCallBack resultCallback)
1391     {
1392         if (!resultCallback)
1393         {
1394             oclog() <<"result callback can not be null";
1395             return OC_STACK_INVALID_CALLBACK;
1396         }
1397
1398         OCStackResult result;
1399         auto cLock = m_csdkLock.lock();
1400
1401         if (cLock)
1402         {
1403             ProvisionContext* context = new ProvisionContext(resultCallback);
1404
1405             std::lock_guard<std::recursive_mutex> lock(*cLock);
1406             result = OCChangeMOTMode(static_cast<void*>(context),
1407                     devPtr, momType,
1408                     &OCSecureResource::callbackWrapper);
1409         }
1410         else
1411         {
1412             oclog() <<"Mutex not found";
1413             result = OC_STACK_ERROR;
1414         }
1415         return result;
1416     }
1417
1418
1419     OCStackResult OCSecureResource::addPreconfigPIN(const char* preconfPIN,
1420             size_t preconfPINLength)
1421     {
1422         if (!preconfPIN)
1423         {
1424             oclog() <<"pre config pin can not be null";
1425             return OC_STACK_INVALID_PARAM;
1426         }
1427         if (preconfPINLength <= 0)
1428         {
1429             oclog() <<"pre config pin length can not be zero or less";
1430             return OC_STACK_INVALID_PARAM;
1431         }
1432         OCStackResult result;
1433         auto cLock = m_csdkLock.lock();
1434
1435         if (cLock)
1436         {
1437             std::lock_guard<std::recursive_mutex> lock(*cLock);
1438             result = OCAddPreconfigPin(devPtr, preconfPIN,
1439                     preconfPINLength);
1440         }
1441         else
1442         {
1443             oclog() <<"Mutex not found";
1444             result = OC_STACK_ERROR;
1445         }
1446         return result;
1447     }
1448
1449     OCStackResult OCSecureResource::provisionPreconfPin(const char * preconfPin,
1450             size_t preconfPinLength, ResultCallBack resultCallback)
1451     {
1452         if (!resultCallback)
1453         {
1454             oclog() <<"result callback can not be null";
1455             return OC_STACK_INVALID_CALLBACK;
1456         }
1457         if (!preconfPin)
1458         {
1459             oclog() <<"pre config pin can not be null";
1460             return OC_STACK_INVALID_PARAM;
1461         }
1462         if (preconfPinLength <= 0)
1463         {
1464             oclog() <<"pre config pin length can not be zero or less";
1465             return OC_STACK_INVALID_PARAM;
1466         }
1467
1468         OCStackResult result;
1469         auto cLock = m_csdkLock.lock();
1470
1471         if (cLock)
1472         {
1473             ProvisionContext* context = new ProvisionContext(resultCallback);
1474
1475             std::lock_guard<std::recursive_mutex> lock(*cLock);
1476             result = OCProvisionPreconfigPin(static_cast<void*>(context),
1477                     devPtr, preconfPin, preconfPinLength,
1478                     &OCSecureResource::callbackWrapper);
1479         }
1480         else
1481         {
1482             oclog() <<"Mutex not found";
1483             result = OC_STACK_ERROR;
1484         }
1485         return result;
1486     }
1487
1488     OCStackResult OCSecureResource::removeSubOwner(const OicUuid_t* subOwnerId, ResultCallBack resultCallback)
1489     {
1490         validateSecureResource();
1491         OCStackResult result;
1492         auto cLock = m_csdkLock.lock();
1493         if (cLock)
1494         {
1495             ProvisionContext* context = new ProvisionContext(resultCallback);
1496             result = OCRemoveSubOwner(static_cast<void*>(context),
1497                 devPtr, subOwnerId, &OCSecureResource::callbackWrapper);
1498         }
1499         else
1500         {
1501             oclog() << "Mutex not found";
1502             result = OC_STACK_ERROR;
1503         }
1504         return result;
1505     }
1506
1507     OCStackResult OCSecureResource::removeAllSubOwner(ResultCallBack resultCallback)
1508     {
1509         validateSecureResource();
1510         OCStackResult result;
1511         auto cLock = m_csdkLock.lock();
1512         if (cLock)
1513         {
1514             ProvisionContext* context = new ProvisionContext(resultCallback);
1515             result =OCRemoveAllSubOwner(static_cast<void*>(context),
1516                 devPtr, &OCSecureResource::callbackWrapper);
1517         }
1518         else
1519         {
1520             oclog() << "Mutex not found";
1521             result = OC_STACK_ERROR;
1522         }
1523         return result;
1524     }
1525
1526 #endif // MULTIPLE_OWNER
1527 }