replace : iotivity -> iotivity-sec
[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         OCStackResult result;
806         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
807
808         if (cLock)
809         {
810             std::lock_guard<std::recursive_mutex> lock(*cLock);
811             result = SetDeviceIdSeed(seed, seedSize);
812         }
813         else
814         {
815             oclog() <<"Mutex not found";
816             result = OC_STACK_ERROR;
817         }
818         return result;
819     }
820
821     int OCSecure::peerCertCallbackWrapper(void *ctx, const mbedtls_x509_crt *cert,
822             int depth)
823     {
824         OCStackResult ret = OC_STACK_ERROR;
825
826         PeerCertContext *context = static_cast<PeerCertContext*>(ctx);
827         if (NULL == context)
828         {
829             oclog() << "Invalid Context";
830             return 1;
831         }
832
833         if (context->callback)
834         {
835             ret = context->callback(cert, depth);
836         }
837
838         if (0 == depth)
839         {
840             delete context;
841         }
842
843         return (OC_STACK_OK == ret)? 0 : 1;
844     }
845
846     OCStackResult OCSecure::setPeerCertCallback(PeerCertCB peerCertCallback)
847     {
848         OCStackResult result;
849         // UNSET cb
850         if (NULL == peerCertCallback)
851         {
852             result = OCSetPeerCertCallback(NULL, NULL);
853             if (OC_STACK_OK != result)
854             {
855                 oclog() << "OCSetPeerCertCallback() Failed";
856                 return result;
857             }
858         }
859
860         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
861
862         if (cLock)
863         {
864             PeerCertContext *context = new PeerCertContext(peerCertCallback);
865
866             std::lock_guard<std::recursive_mutex> lock(*cLock);
867             result = OCSetPeerCertCallback(static_cast<void*>(context),
868                     &OCSecure::peerCertCallbackWrapper);
869             if (OC_STACK_OK != result)
870             {
871                 oclog() << "OCSetPeerCertCallback() Failed";
872             }
873         }
874         else
875         {
876             oclog() << "Mutex not found";
877             result = OC_STACK_ERROR;
878         }
879         return result;
880     }
881
882 #endif // __WITH_DTLS__ || __WITH_TLS__
883
884     void OCSecureResource::callbackWrapper(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
885     {
886         PMResultList_t *results = nullptr;
887         ProvisionContext* context = static_cast<ProvisionContext*>(ctx);
888
889         try
890         {
891             results = new PMResultList_t;
892         }
893         catch (std::bad_alloc& e)
894         {
895             oclog() <<"Bad alloc exception";
896             return;
897         }
898
899         for (int i = 0; i < nOfRes; i++)
900         {
901             results->push_back(arr[i]);
902         }
903
904         std::thread exec(context->callback, results, hasError);
905         exec.detach();
906
907         delete context;
908     }
909
910     OCSecureResource::OCSecureResource(): m_csdkLock(std::weak_ptr<std::recursive_mutex>()),
911                                         devPtr(nullptr)
912     {
913     }
914
915     OCSecureResource::OCSecureResource(std::weak_ptr<std::recursive_mutex> csdkLock,
916             OCProvisionDev_t *dPtr)
917         :m_csdkLock(csdkLock), devPtr(dPtr)
918     {
919     }
920
921     OCSecureResource::~OCSecureResource()
922     {
923         if (devPtr)
924         {
925             OCDeleteDiscoveredDevices(devPtr);
926         }
927     }
928
929     OCStackResult OCSecureResource::doOwnershipTransfer(ResultCallBack resultCallback)
930     {
931         if (!resultCallback)
932         {
933             oclog() <<"Result callback can't be null";
934             return OC_STACK_INVALID_CALLBACK;
935         }
936
937         OCStackResult result;
938         auto cLock = m_csdkLock.lock();
939
940         if (cLock)
941         {
942             ProvisionContext* context = new ProvisionContext(resultCallback);
943
944             std::lock_guard<std::recursive_mutex> lock(*cLock);
945             result = OCDoOwnershipTransfer(static_cast<void*>(context),
946                     devPtr, &OCSecureResource::callbackWrapper);
947         }
948         else
949         {
950             oclog() <<"Mutex not found";
951             result = OC_STACK_ERROR;
952         }
953         return result;
954     }
955
956 #ifdef MULTIPLE_OWNER
957     OCStackResult OCSecureResource::doMultipleOwnershipTransfer(ResultCallBack resultCallback)
958     {
959         if (!resultCallback)
960         {
961             oclog() <<"Result callback can't be null";
962             return OC_STACK_INVALID_CALLBACK;
963         }
964
965         OCStackResult result;
966         auto cLock = m_csdkLock.lock();
967
968         if (cLock)
969         {
970             ProvisionContext* context = new ProvisionContext(resultCallback);
971
972             std::lock_guard<std::recursive_mutex> lock(*cLock);
973             result = OCDoMultipleOwnershipTransfer(static_cast<void*>(context),
974                     devPtr, &OCSecureResource::callbackWrapper);
975         }
976         else
977         {
978             oclog() <<"Mutex not found";
979             result = OC_STACK_ERROR;
980         }
981         return result;
982     }
983
984     OCStackResult OCSecureResource::getSubOwnerList(UuidList_t &uuidList)
985     {
986         validateSecureResource();
987         OicSecSubOwner_t* tmp = NULL;
988         for (tmp = devPtr->doxm->subOwners; tmp; tmp = tmp->next)
989         {
990             uuidList.push_back(tmp->uuid);
991         }
992         return OC_STACK_OK;
993     }
994
995 #endif
996     OCStackResult OCSecureResource::provisionACL( const OicSecAcl_t* acl,
997             ResultCallBack resultCallback)
998     {
999         if (!acl)
1000         {
1001             oclog() <<"ACL can't be null";
1002             return OC_STACK_INVALID_PARAM;
1003         }
1004         if (!resultCallback)
1005         {
1006             oclog() <<"result callback can not be null";
1007             return OC_STACK_INVALID_CALLBACK;
1008         }
1009
1010         OCStackResult result;
1011         auto cLock = m_csdkLock.lock();
1012
1013         if (cLock)
1014         {
1015             ProvisionContext* context = new ProvisionContext(resultCallback);
1016
1017             std::lock_guard<std::recursive_mutex> lock(*cLock);
1018             result = OCProvisionACL(static_cast<void*>(context),
1019                     devPtr, const_cast<OicSecAcl_t*>(acl),
1020                     &OCSecureResource::callbackWrapper);
1021         }
1022         else
1023         {
1024             oclog() <<"Mutex not found";
1025             result = OC_STACK_ERROR;
1026         }
1027         return result;
1028     }
1029
1030     OCStackResult OCSecureResource::provisionCredentials(const Credential &cred,
1031             const OCSecureResource &device2, ResultCallBack resultCallback)
1032     {
1033         if (!resultCallback)
1034         {
1035             oclog() << "Result calback can't be null";
1036             return OC_STACK_INVALID_CALLBACK;
1037         }
1038
1039         OCStackResult result;
1040         auto cLock = m_csdkLock.lock();
1041
1042         if (cLock)
1043         {
1044             ProvisionContext* context = new ProvisionContext(resultCallback);
1045
1046             std::lock_guard<std::recursive_mutex> lock(*cLock);
1047             result = OCProvisionCredentials(static_cast<void*>(context),
1048                     cred.getCredentialType(),
1049                     cred.getCredentialKeySize(),
1050                     devPtr, device2.getDevPtr(),
1051                     &OCSecureResource::callbackWrapper);
1052         }
1053         else
1054         {
1055             oclog() <<"Mutex not found";
1056             result = OC_STACK_ERROR;
1057         }
1058         return result;
1059     }
1060
1061     OCStackResult OCSecureResource::provisionPairwiseDevices(const Credential &cred,
1062             const OicSecAcl_t* acl1, const OCSecureResource &device2, const OicSecAcl_t* acl2,
1063             ResultCallBack resultCallback)
1064     {
1065         if (!resultCallback)
1066         {
1067             oclog() << "Result callback can not be null";
1068             return OC_STACK_INVALID_CALLBACK;
1069         }
1070
1071         OCStackResult result;
1072         auto cLock = m_csdkLock.lock();
1073
1074         if (cLock)
1075         {
1076             ProvisionContext* context = new ProvisionContext(resultCallback);
1077
1078             std::lock_guard<std::recursive_mutex> lock(*cLock);
1079             result = OCProvisionPairwiseDevices(static_cast<void*>(context),
1080                     cred.getCredentialType(),
1081                     cred.getCredentialKeySize(),
1082                     devPtr, const_cast<OicSecAcl_t*>(acl1),
1083                     device2.getDevPtr(), const_cast<OicSecAcl_t*>(acl2),
1084                     &OCSecureResource::callbackWrapper);
1085         }
1086         else
1087         {
1088             oclog() <<"Mutex not found";
1089             result = OC_STACK_ERROR;
1090         }
1091         return result;
1092     }
1093
1094     OCStackResult OCSecureResource::unlinkDevices(const OCSecureResource &device2,
1095             ResultCallBack resultCallback)
1096     {
1097         if (!resultCallback)
1098         {
1099             oclog() << "Result calback can't be null";
1100             return OC_STACK_INVALID_CALLBACK;
1101         }
1102
1103         OCStackResult result;
1104         auto cLock = m_csdkLock.lock();
1105
1106         if (cLock)
1107         {
1108             ProvisionContext* context = new ProvisionContext(resultCallback);
1109
1110             std::lock_guard<std::recursive_mutex> lock(*cLock);
1111
1112             result = OCUnlinkDevices(static_cast<void*>(context),
1113                     devPtr, device2.getDevPtr(), &OCSecureResource::callbackWrapper);
1114         }
1115         else
1116         {
1117             oclog() <<"Mutex not found";
1118             result = OC_STACK_ERROR;
1119         }
1120         return result;
1121     }
1122
1123     OCStackResult OCSecureResource::removeDevice(unsigned short waitTimeForOwnedDeviceDiscovery,
1124             ResultCallBack resultCallback)
1125     {
1126         if (!resultCallback)
1127         {
1128             oclog() << "Result calback can't be null";
1129             return OC_STACK_INVALID_CALLBACK;
1130         }
1131
1132         OCStackResult result;
1133         auto cLock = m_csdkLock.lock();
1134
1135         if (cLock)
1136         {
1137             ProvisionContext* context = new ProvisionContext(resultCallback);
1138
1139             std::lock_guard<std::recursive_mutex> lock(*cLock);
1140
1141             result = OCRemoveDevice(static_cast<void*>(context), waitTimeForOwnedDeviceDiscovery,
1142                     devPtr, &OCSecureResource::callbackWrapper);
1143         }
1144         else
1145         {
1146             oclog() <<"Mutex not found";
1147             result = OC_STACK_ERROR;
1148         }
1149         return result;
1150     }
1151
1152     OCStackResult OCSecureResource::getLinkedDevices(UuidList_t &uuidList)
1153     {
1154         OCStackResult result;
1155         size_t numOfDevices = -1;
1156         auto devUuid = devPtr->doxm->deviceID;
1157         auto cLock = m_csdkLock.lock();
1158
1159         if (cLock)
1160         {
1161             std::lock_guard<std::recursive_mutex> lock(*cLock);
1162
1163             OCUuidList_t* linkedDevs = nullptr, *tmp = nullptr;
1164             result = OCGetLinkedStatus(&devUuid, &linkedDevs, &numOfDevices);
1165             if (result == OC_STACK_OK)
1166             {
1167                 for (tmp = linkedDevs; tmp; tmp = tmp->next)
1168                 {
1169                     uuidList.push_back(tmp->dev);
1170                 }
1171                 OCDeleteUuidList(linkedDevs);
1172             }
1173         }
1174         else
1175         {
1176             oclog() <<"Mutex not found";
1177             result = OC_STACK_ERROR;
1178         }
1179         return result;
1180     }
1181
1182     OCStackResult OCSecureResource::provisionDirectPairing( const OicSecPconf_t* pconf,
1183             ResultCallBack resultCallback)
1184     {
1185         if (!pconf)
1186         {
1187             oclog() <<"PCONF can't be null";
1188             return OC_STACK_INVALID_PARAM;
1189         }
1190         if (!resultCallback)
1191         {
1192             oclog() <<"result callback can not be null";
1193             return OC_STACK_INVALID_CALLBACK;
1194         }
1195
1196         OCStackResult result;
1197         auto cLock = m_csdkLock.lock();
1198
1199         if (cLock)
1200         {
1201             ProvisionContext* context = new ProvisionContext(resultCallback);
1202
1203             std::lock_guard<std::recursive_mutex> lock(*cLock);
1204             result = OCProvisionDirectPairing(static_cast<void*>(context),
1205                     devPtr, const_cast<OicSecPconf_t*>(pconf),
1206                     &OCSecureResource::callbackWrapper);
1207         }
1208         else
1209         {
1210             oclog() <<"Mutex not found";
1211             result = OC_STACK_ERROR;
1212         }
1213         return result;
1214     }
1215
1216 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1217     OCStackResult OCSecureResource::provisionTrustCertChain(OicSecCredType_t type, uint16_t credId,
1218                     ResultCallBack resultCallback)
1219     {
1220         if (SIGNED_ASYMMETRIC_KEY != type)
1221         {
1222             oclog() <<"Invalid key type";
1223             return OC_STACK_INVALID_PARAM;
1224         }
1225         if (!resultCallback)
1226         {
1227             oclog() <<"result callback can not be null";
1228             return OC_STACK_INVALID_CALLBACK;
1229         }
1230
1231         OCStackResult result;
1232         auto cLock = m_csdkLock.lock();
1233
1234         if (cLock)
1235         {
1236             ProvisionContext* context = new ProvisionContext(resultCallback);
1237
1238             std::lock_guard<std::recursive_mutex> lock(*cLock);
1239             result = OCProvisionTrustCertChain(static_cast<void*>(context),
1240                     type, credId, devPtr,
1241                     &OCSecureResource::callbackWrapper);
1242         }
1243         else
1244         {
1245             oclog() <<"Mutex not found";
1246             result = OC_STACK_ERROR;
1247         }
1248         return result;
1249     }
1250 #endif // __WITH_DTLS__ or __WITH_TLS__
1251
1252     std::string OCSecureResource::getDeviceID()
1253     {
1254         std::ostringstream deviceId("");
1255         char *devID = nullptr;
1256
1257         validateSecureResource();
1258
1259         if (OC_STACK_OK == ConvertUuidToStr(&(devPtr->doxm->deviceID), &devID))
1260         {
1261             deviceId << devID;
1262             free(devID);
1263         }
1264         else
1265         {
1266             oclog() <<"Can not convert uuid to struuid";
1267         }
1268         return deviceId.str();
1269     }
1270
1271     OCProvisionDev_t* OCSecureResource::getDevPtr() const
1272     {
1273         return devPtr;
1274     }
1275
1276     std::string OCSecureResource::getDevAddr()
1277     {
1278         validateSecureResource();
1279         std::string ipAddr(devPtr->endpoint.addr);
1280         return ipAddr;
1281     }
1282
1283     int OCSecureResource::getDeviceStatus()
1284     {
1285         validateSecureResource();
1286         return (int)devPtr->devStatus;
1287     }
1288
1289     bool OCSecureResource::getOwnedStatus()
1290     {
1291         validateSecureResource();
1292         return devPtr->doxm->owned;
1293     }
1294
1295     void OCSecureResource::validateSecureResource()
1296     {
1297         if (!devPtr)
1298         {
1299             throw OCException("Incomplete secure resource", OC_STACK_RESOURCE_ERROR);
1300         }
1301     }
1302
1303     OCStackResult OCSecureResource::getOTMethod(OicSecOxm_t* oxm)
1304     {
1305         if(!oxm)
1306         {
1307             oclog() << "Null param";
1308             return OC_STACK_INVALID_PARAM;
1309         }
1310
1311         OCStackResult result = OC_STACK_ERROR;
1312         auto cLock = m_csdkLock.lock();
1313         if (cLock)
1314         {
1315             std::lock_guard<std::recursive_mutex> lock(*cLock);
1316             if(devPtr && devPtr->doxm)
1317             {
1318                 result = OCSelectOwnershipTransferMethod(devPtr->doxm->oxm, devPtr->doxm->oxmLen,
1319                                                   oxm, SUPER_OWNER);
1320             }
1321         }
1322         else
1323         {
1324             oclog() <<"Mutex not found";
1325         }
1326         return result;
1327     }
1328
1329
1330 #ifdef MULTIPLE_OWNER
1331     OCStackResult OCSecureResource::getMOTMethod( OicSecOxm_t* oxm)
1332     {
1333         if (!oxm)
1334         {
1335             oclog() << "Null param";
1336             return OC_STACK_INVALID_PARAM;
1337         }
1338
1339         OCStackResult result = OC_STACK_ERROR;
1340         auto cLock = m_csdkLock.lock();
1341         if (cLock)
1342         {
1343             std::lock_guard<std::recursive_mutex> lock(*cLock);
1344             if (devPtr && devPtr->doxm)
1345             {
1346                 result = OCSelectOwnershipTransferMethod(devPtr->doxm->oxm, devPtr->doxm->oxmLen,
1347                                                   oxm, SUB_OWNER);
1348             }
1349         }
1350         else
1351         {
1352             oclog() <<"Mutex not found";
1353         }
1354         return result;
1355     }
1356
1357     bool OCSecureResource::isMOTSupported()
1358     {
1359         if (devPtr && devPtr->doxm)
1360         {
1361             return (devPtr->doxm->mom ? true : false);
1362         }
1363         return false;
1364     }
1365
1366     bool OCSecureResource::isMOTEnabled()
1367     {
1368         if (devPtr && devPtr->doxm && devPtr->doxm->mom)
1369         {
1370             if (OIC_MULTIPLE_OWNER_DISABLE != devPtr->doxm->mom->mode)
1371             {
1372                 return true;
1373             }
1374         }
1375         return false;
1376     }
1377
1378     OCStackResult OCSecureResource::selectMOTMethod( const OicSecOxm_t oxmSelVal,
1379             ResultCallBack resultCallback)
1380     {
1381         if (!resultCallback)
1382         {
1383             oclog() <<"result callback can not be null";
1384             return OC_STACK_INVALID_CALLBACK;
1385         }
1386
1387         OCStackResult result;
1388         auto cLock = m_csdkLock.lock();
1389
1390         if (cLock)
1391         {
1392             ProvisionContext* context = new ProvisionContext(resultCallback);
1393
1394             std::lock_guard<std::recursive_mutex> lock(*cLock);
1395             result = OCSelectMOTMethod(static_cast<void*>(context),
1396                     devPtr, oxmSelVal,
1397                     &OCSecureResource::callbackWrapper);
1398         }
1399         else
1400         {
1401             oclog() <<"Mutex not found";
1402             result = OC_STACK_ERROR;
1403         }
1404         return result;
1405     }
1406
1407     OCStackResult OCSecureResource::changeMOTMode( const OicSecMomType_t momType,
1408             ResultCallBack resultCallback)
1409     {
1410         if (!resultCallback)
1411         {
1412             oclog() <<"result callback can not be null";
1413             return OC_STACK_INVALID_CALLBACK;
1414         }
1415
1416         OCStackResult result;
1417         auto cLock = m_csdkLock.lock();
1418
1419         if (cLock)
1420         {
1421             ProvisionContext* context = new ProvisionContext(resultCallback);
1422
1423             std::lock_guard<std::recursive_mutex> lock(*cLock);
1424             result = OCChangeMOTMode(static_cast<void*>(context),
1425                     devPtr, momType,
1426                     &OCSecureResource::callbackWrapper);
1427         }
1428         else
1429         {
1430             oclog() <<"Mutex not found";
1431             result = OC_STACK_ERROR;
1432         }
1433         return result;
1434     }
1435
1436
1437     OCStackResult OCSecureResource::addPreconfigPIN(const char* preconfPIN,
1438             size_t preconfPINLength)
1439     {
1440         if (!preconfPIN)
1441         {
1442             oclog() <<"pre config pin can not be null";
1443             return OC_STACK_INVALID_PARAM;
1444         }
1445         if (preconfPINLength <= 0)
1446         {
1447             oclog() <<"pre config pin length can not be zero or less";
1448             return OC_STACK_INVALID_PARAM;
1449         }
1450         OCStackResult result;
1451         auto cLock = m_csdkLock.lock();
1452
1453         if (cLock)
1454         {
1455             std::lock_guard<std::recursive_mutex> lock(*cLock);
1456             result = OCAddPreconfigPin(devPtr, preconfPIN,
1457                     preconfPINLength);
1458         }
1459         else
1460         {
1461             oclog() <<"Mutex not found";
1462             result = OC_STACK_ERROR;
1463         }
1464         return result;
1465     }
1466
1467     OCStackResult OCSecureResource::provisionPreconfPin(const char * preconfPin,
1468             size_t preconfPinLength, ResultCallBack resultCallback)
1469     {
1470         if (!resultCallback)
1471         {
1472             oclog() <<"result callback can not be null";
1473             return OC_STACK_INVALID_CALLBACK;
1474         }
1475         if (!preconfPin)
1476         {
1477             oclog() <<"pre config pin can not be null";
1478             return OC_STACK_INVALID_PARAM;
1479         }
1480         if (preconfPinLength <= 0)
1481         {
1482             oclog() <<"pre config pin length can not be zero or less";
1483             return OC_STACK_INVALID_PARAM;
1484         }
1485
1486         OCStackResult result;
1487         auto cLock = m_csdkLock.lock();
1488
1489         if (cLock)
1490         {
1491             ProvisionContext* context = new ProvisionContext(resultCallback);
1492
1493             std::lock_guard<std::recursive_mutex> lock(*cLock);
1494             result = OCProvisionPreconfigPin(static_cast<void*>(context),
1495                     devPtr, preconfPin, preconfPinLength,
1496                     &OCSecureResource::callbackWrapper);
1497         }
1498         else
1499         {
1500             oclog() <<"Mutex not found";
1501             result = OC_STACK_ERROR;
1502         }
1503         return result;
1504     }
1505
1506     OCStackResult OCSecureResource::removeSubOwner(const OicUuid_t* subOwnerId, ResultCallBack resultCallback)
1507     {
1508         validateSecureResource();
1509         OCStackResult result;
1510         auto cLock = m_csdkLock.lock();
1511         if (cLock)
1512         {
1513             ProvisionContext* context = new ProvisionContext(resultCallback);
1514             result = OCRemoveSubOwner(static_cast<void*>(context),
1515                 devPtr, subOwnerId, &OCSecureResource::callbackWrapper);
1516         }
1517         else
1518         {
1519             oclog() << "Mutex not found";
1520             result = OC_STACK_ERROR;
1521         }
1522         return result;
1523     }
1524
1525     OCStackResult OCSecureResource::removeAllSubOwner(ResultCallBack resultCallback)
1526     {
1527         validateSecureResource();
1528         OCStackResult result;
1529         auto cLock = m_csdkLock.lock();
1530         if (cLock)
1531         {
1532             ProvisionContext* context = new ProvisionContext(resultCallback);
1533             result =OCRemoveAllSubOwner(static_cast<void*>(context),
1534                 devPtr, &OCSecureResource::callbackWrapper);
1535         }
1536         else
1537         {
1538             oclog() << "Mutex not found";
1539             result = OC_STACK_ERROR;
1540         }
1541         return result;
1542     }
1543
1544 #endif // MULTIPLE_OWNER
1545 }