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