Fix for SVACE issue. (#326)
[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                 delete context;
463                 oclog() <<"Can not convert struuid to uuid";
464             }
465         }
466         else
467         {
468             oclog() <<"Mutex not found";
469             result = OC_STACK_ERROR;
470         }
471         return result;
472     }
473
474     OCStackResult OCSecure::saveACL(const OicSecAcl_t* acl)
475     {
476         if (!acl)
477         {
478             oclog() <<"ACL can't be null";
479             return OC_STACK_INVALID_PARAM;
480         }
481
482         OCStackResult result;
483         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
484
485         if (cLock)
486         {
487             std::lock_guard<std::recursive_mutex> lock(*cLock);
488             result = OCSaveACL(const_cast<OicSecAcl_t*>(acl));
489         }
490         else
491         {
492             oclog() <<"Mutex not found";
493             result = OC_STACK_ERROR;
494         }
495         return result;
496     }
497
498     OCStackResult OCSecure::displayNumCallbackWrapper(void* ctx,
499             uint8_t verifNum[MUTUAL_VERIF_NUM_LEN])
500     {
501         uint8_t *number = NULL;
502
503         DisplayNumContext* context = static_cast<DisplayNumContext*>(ctx);
504         if (!context)
505         {
506             oclog() << "Invalid context";
507             return OC_STACK_INVALID_PARAM;
508         }
509
510         if (NULL != verifNum) {
511             number = new uint8_t[MUTUAL_VERIF_NUM_LEN];
512             memcpy(number, verifNum, MUTUAL_VERIF_NUM_LEN);
513         }
514
515         return context->callback(number);
516     }
517
518     OCStackResult OCSecure::registerDisplayNumCallback(DisplayNumCB displayNumCB)
519     {
520         if(!displayNumCB)
521         {
522             oclog() << "Failed to register callback for display.";
523             return OC_STACK_INVALID_CALLBACK;
524         }
525
526         OCStackResult result = OCSecure::deregisterDisplayNumCallback();
527         if (OC_STACK_OK != result)
528         {
529             oclog() << "Failed to de-register callback for display."<<std::endl;
530             return result;
531         }
532
533         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
534         if (cLock)
535         {
536             DisplayNumContext* context = new DisplayNumContext(displayNumCB);
537             std::lock_guard<std::recursive_mutex> lock(*cLock);
538             SetDisplayNumCB(static_cast<void*>(context), &OCSecure::displayNumCallbackWrapper);
539             result = OC_STACK_OK;
540         }
541         else
542         {
543             oclog() <<"Mutex not found";
544             result = OC_STACK_ERROR;
545         }
546         return result;
547     }
548
549     OCStackResult OCSecure::deregisterDisplayNumCallback()
550     {
551         OCStackResult result;
552         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
553
554         if (cLock)
555         {
556             std::lock_guard<std::recursive_mutex> lock(*cLock);
557             DisplayNumContext* context = static_cast<DisplayNumContext*>(UnsetDisplayNumCB());
558             if (context)
559             {
560                 oclog() << "Delete registered display num context"<<std::endl;
561                 delete context;
562             }
563             result = OC_STACK_OK;
564         }
565         else
566         {
567             oclog() <<"Mutex not found";
568             result = OC_STACK_ERROR;
569         }
570         return result;
571     }
572
573     OCStackResult OCSecure::confirmUserCallbackWrapper(void* ctx)
574     {
575         UserConfirmNumContext* context = static_cast<UserConfirmNumContext*>(ctx);
576         if (!context)
577         {
578             oclog() << "Invalid context";
579             return OC_STACK_INVALID_PARAM;
580         }
581
582         return context->callback();
583     }
584
585     OCStackResult OCSecure::registerUserConfirmCallback(UserConfirmNumCB userConfirmCB)
586     {
587         if(!userConfirmCB)
588         {
589             oclog() << "Failed to set callback for confirming verifying callback.";
590             return OC_STACK_INVALID_CALLBACK;
591         }
592
593         OCStackResult result = OCSecure::deregisterUserConfirmCallback();
594         if (OC_STACK_OK != result)
595         {
596             oclog() << "Failed to de-register callback for comfirm."<<std::endl;
597             return result;
598         }
599
600         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
601         if (cLock)
602         {
603             UserConfirmNumContext* context = new UserConfirmNumContext(userConfirmCB);
604             std::lock_guard<std::recursive_mutex> lock(*cLock);
605             SetUserConfirmCB(static_cast<void*>(context), &OCSecure::confirmUserCallbackWrapper);
606             result = OC_STACK_OK;
607         }
608         else
609         {
610             oclog() <<"Mutex not found";
611             result = OC_STACK_ERROR;
612         }
613         return result;
614     }
615
616     OCStackResult OCSecure::deregisterUserConfirmCallback()
617     {
618         OCStackResult result;
619         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
620
621         if (cLock)
622         {
623             std::lock_guard<std::recursive_mutex> lock(*cLock);
624             UserConfirmNumContext* context = static_cast<UserConfirmNumContext*>(UnsetUserConfirmCB());
625             if (context)
626             {
627                 oclog() << "Delete registered user confirm context"<<std::endl;
628                 delete context;
629             }
630             result = OC_STACK_OK;
631         }
632         else
633         {
634             oclog() <<"Mutex not found";
635             result = OC_STACK_ERROR;
636         }
637         return result;
638     }
639
640     OCStackResult OCSecure::setVerifyOptionMask(VerifyOptionBitmask_t optionMask)
641     {
642         OCStackResult result;
643         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
644         if (cLock)
645         {
646             std::lock_guard<std::recursive_mutex> lock(*cLock);
647             SetVerifyOption(optionMask);
648             result = OC_STACK_OK;
649         }
650         else
651         {
652             oclog() <<"Mutex not found";
653             result = OC_STACK_ERROR;
654         }
655         return result;
656     }
657
658     OCStackResult OCSecure::pdmCleanupForTimeout()
659     {
660         OCStackResult result;
661         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
662         if (cLock)
663         {
664             result = OCPDMCleanupForTimeout();
665         }
666         else
667         {
668             oclog() <<"Mutex not found";
669             result = OC_STACK_ERROR;
670         }
671         return result;
672     }
673
674     OCStackResult OCSecure::configSelfOwnership()
675     {
676         OCStackResult result;
677         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
678         if (cLock)
679         {
680             std::lock_guard<std::recursive_mutex> lock(*cLock);
681             result = OCConfigSelfOwnership();
682         }
683         else
684         {
685             oclog() <<"Mutex not found";
686             result = OC_STACK_ERROR;
687         }
688         return result;
689     }
690
691 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
692     OCStackResult OCSecure::saveTrustCertChain(uint8_t *trustCertChain, size_t chainSize,
693                                         OicEncodingType_t encodingType, uint16_t *credId)
694     {
695         if (!trustCertChain)
696         {
697             oclog() <<"trustCertChain can't be null";
698             return OC_STACK_INVALID_PARAM;
699         }
700         if (!credId)
701         {
702             oclog() <<"cred ID can not be null";
703             return OC_STACK_INVALID_PARAM;
704         }
705
706         OCStackResult result;
707         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
708
709         if (cLock)
710         {
711             std::lock_guard<std::recursive_mutex> lock(*cLock);
712             result = OCSaveTrustCertChain(trustCertChain, chainSize, encodingType, credId );
713         }
714         else
715         {
716             oclog() <<"Mutex not found";
717             result = OC_STACK_ERROR;
718         }
719         return result;
720     }
721
722     OCStackResult OCSecure::readTrustCertChain(uint16_t credId, uint8_t **trustCertChain,
723             size_t *chainSize)
724     {
725         OCStackResult result;
726         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
727
728         if (cLock)
729         {
730             std::lock_guard<std::recursive_mutex> lock(*cLock);
731             result = OCReadTrustCertChain(credId, trustCertChain, chainSize);
732         }
733         else
734         {
735             oclog() <<"Mutex not found";
736             result = OC_STACK_ERROR;
737         }
738         return result;
739     }
740
741     void OCSecure::certCallbackWrapper(void* ctx, uint16_t credId, uint8_t *trustCertChain,
742             size_t chainSize)
743     {
744         TrustCertChainContext* context = static_cast<TrustCertChainContext*>(ctx);
745         uint8_t *certChain = new uint8_t[chainSize];
746         memcpy(certChain, trustCertChain, chainSize);
747         std::thread exec(context->callback, credId, certChain, chainSize);
748         exec.detach();
749         delete context;
750     }
751
752     OCStackResult OCSecure::registerTrustCertChangeNotifier(CertChainCallBack callback)
753     {
754         if (!callback)
755         {
756             oclog() <<"callback can not be null";
757             return OC_STACK_INVALID_CALLBACK;
758         }
759
760         OCStackResult result;
761         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
762
763         if (cLock)
764         {
765             TrustCertChainContext* context = new TrustCertChainContext(callback);
766             std::lock_guard<std::recursive_mutex> lock(*cLock);
767             result = OCRegisterTrustCertChainNotifier(static_cast<void*>(context),
768                     &OCSecure::certCallbackWrapper);
769         }
770         else
771         {
772             oclog() <<"Mutex not found";
773             result = OC_STACK_ERROR;
774         }
775         return result;
776     }
777
778
779     OCStackResult OCSecure::removeTrustCertChangeNotifier()
780     {
781         OCStackResult result;
782         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
783
784         if (cLock)
785         {
786             std::lock_guard<std::recursive_mutex> lock(*cLock);
787             OCRemoveTrustCertChainNotifier();
788             result = OC_STACK_OK;
789         }
790         else
791         {
792             oclog() <<"Mutex not found";
793             result = OC_STACK_ERROR;
794         }
795         return result;
796     }
797
798     OCStackResult OCSecure::setDeviceIdSeed(const uint8_t* seed, size_t seedSize)
799     {
800         if (!seed)
801         {
802             oclog() <<"seed can not be null";
803             return OC_STACK_INVALID_PARAM;
804         }
805
806         return SetDeviceIdSeed(seed, seedSize);
807     }
808
809     int OCSecure::peerCertCallbackWrapper(void *ctx, const mbedtls_x509_crt *cert,
810             int depth)
811     {
812         OCStackResult ret = OC_STACK_ERROR;
813
814         PeerCertContext *context = static_cast<PeerCertContext*>(ctx);
815         if (NULL == context)
816         {
817             oclog() << "Invalid Context";
818             return 1;
819         }
820
821         if (context->callback)
822         {
823             ret = context->callback(cert, depth);
824         }
825
826         return (OC_STACK_OK == ret)? 0 : 1;
827     }
828
829     OCStackResult OCSecure::setPeerCertCallback(PeerCertCB peerCertCallback)
830     {
831         OCStackResult result;
832         // UNSET cb
833         if (NULL == peerCertCallback)
834         {
835             result = OCSetPeerCertCallback(NULL, NULL);
836             if (OC_STACK_OK != result)
837             {
838                 oclog() << "OCSetPeerCertCallback() Failed";
839             }
840             return result;
841         }
842
843         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
844
845         if (cLock)
846         {
847             PeerCertContext *context = new PeerCertContext(peerCertCallback);
848
849             std::lock_guard<std::recursive_mutex> lock(*cLock);
850             result = OCSetPeerCertCallback(static_cast<void*>(context),
851                     &OCSecure::peerCertCallbackWrapper);
852             if (OC_STACK_OK != result)
853             {
854                 oclog() << "OCSetPeerCertCallback() Failed";
855             }
856         }
857         else
858         {
859             oclog() << "Mutex not found";
860             result = OC_STACK_ERROR;
861         }
862         return result;
863     }
864
865 #endif // __WITH_DTLS__ || __WITH_TLS__
866
867     void OCSecureResource::callbackWrapper(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
868     {
869         PMResultList_t *results = nullptr;
870         ProvisionContext* context = static_cast<ProvisionContext*>(ctx);
871
872         try
873         {
874             results = new PMResultList_t;
875         }
876         catch (std::bad_alloc& e)
877         {
878             oclog() <<"Bad alloc exception";
879             return;
880         }
881
882         for (int i = 0; i < nOfRes; i++)
883         {
884             results->push_back(arr[i]);
885         }
886
887         std::thread exec(context->callback, results, hasError);
888         exec.detach();
889
890         delete context;
891     }
892
893     OCSecureResource::OCSecureResource(): m_csdkLock(std::weak_ptr<std::recursive_mutex>()),
894                                         devPtr(nullptr),
895                                         context(nullptr)
896     {
897     }
898
899     OCSecureResource::OCSecureResource(std::weak_ptr<std::recursive_mutex> csdkLock,
900             OCProvisionDev_t *dPtr)
901         :m_csdkLock(csdkLock), devPtr(dPtr), context(nullptr)
902     {
903     }
904
905     OCSecureResource::~OCSecureResource()
906     {
907         if (devPtr)
908         {
909             OCDeleteDiscoveredDevices(devPtr);
910         }
911         if(context)
912         {
913             delete context;
914         }
915     }
916
917     OCStackResult OCSecureResource::doOwnershipTransfer(ResultCallBack resultCallback)
918     {
919         if (!resultCallback)
920         {
921             oclog() <<"Result callback can't be null";
922             return OC_STACK_INVALID_CALLBACK;
923         }
924
925         OCStackResult result;
926         auto cLock = m_csdkLock.lock();
927
928         if (cLock)
929         {
930             ProvisionContext* context = new ProvisionContext(resultCallback);
931             if(context)
932             {
933                 delete context;
934             }
935             context = new ProvisionContext(resultCallback);
936
937             std::lock_guard<std::recursive_mutex> lock(*cLock);
938             result = OCDoOwnershipTransfer(static_cast<void*>(context),
939                     devPtr, &OCSecureResource::callbackWrapper);
940         }
941         else
942         {
943             oclog() <<"Mutex not found";
944             result = OC_STACK_ERROR;
945         }
946         return result;
947     }
948
949     OCStackResult OCSecureResource::doOwnershipTransfer(ResultCallBack resultCallback, const OicSecOxm_t method)
950     {
951         if (!resultCallback)
952         {
953             oclog() <<"Result callback can't be null";
954             return OC_STACK_INVALID_CALLBACK;
955         }
956
957         OCStackResult result;
958         auto cLock = m_csdkLock.lock();
959
960         if (cLock)
961         {
962             if(context)
963             {
964                  delete context;
965             }
966             context = new ProvisionContext(resultCallback);
967
968             std::lock_guard<std::recursive_mutex> lock(*cLock);
969             result = OCDoCustomOwnershipTransfer(static_cast<void*>(context),
970                    devPtr, &OCSecureResource::callbackWrapper, method);
971         }
972         else
973         {
974             oclog() <<"Mutex not found";
975             result = OC_STACK_ERROR;
976         }
977         return result;
978     }
979
980 #ifdef MULTIPLE_OWNER
981     OCStackResult OCSecureResource::doMultipleOwnershipTransfer(ResultCallBack resultCallback)
982     {
983         if (!resultCallback)
984         {
985             oclog() <<"Result callback can't be null";
986             return OC_STACK_INVALID_CALLBACK;
987         }
988
989         OCStackResult result;
990         auto cLock = m_csdkLock.lock();
991
992         if (cLock)
993         {
994             ProvisionContext* context = new ProvisionContext(resultCallback);
995
996             std::lock_guard<std::recursive_mutex> lock(*cLock);
997             result = OCDoMultipleOwnershipTransfer(static_cast<void*>(context),
998                     devPtr, &OCSecureResource::callbackWrapper);
999         }
1000         else
1001         {
1002             oclog() <<"Mutex not found";
1003             result = OC_STACK_ERROR;
1004         }
1005         return result;
1006     }
1007
1008     OCStackResult OCSecureResource::getSubOwnerList(UuidList_t &uuidList)
1009     {
1010         validateSecureResource();
1011         OicSecSubOwner_t* tmp = NULL;
1012         for (tmp = devPtr->doxm->subOwners; tmp; tmp = tmp->next)
1013         {
1014             uuidList.push_back(tmp->uuid);
1015         }
1016         return OC_STACK_OK;
1017     }
1018
1019 #endif
1020     OCStackResult OCSecureResource::provisionACL( const OicSecAcl_t* acl,
1021             ResultCallBack resultCallback)
1022     {
1023         if (!acl)
1024         {
1025             oclog() <<"ACL can't be null";
1026             return OC_STACK_INVALID_PARAM;
1027         }
1028         if (!resultCallback)
1029         {
1030             oclog() <<"result callback can not be null";
1031             return OC_STACK_INVALID_CALLBACK;
1032         }
1033
1034         OCStackResult result;
1035         auto cLock = m_csdkLock.lock();
1036
1037         if (cLock)
1038         {
1039             ProvisionContext* context = new ProvisionContext(resultCallback);
1040
1041             std::lock_guard<std::recursive_mutex> lock(*cLock);
1042             result = OCProvisionACL(static_cast<void*>(context),
1043                     devPtr, const_cast<OicSecAcl_t*>(acl),
1044                     &OCSecureResource::callbackWrapper);
1045         }
1046         else
1047         {
1048             oclog() <<"Mutex not found";
1049             result = OC_STACK_ERROR;
1050         }
1051         return result;
1052     }
1053
1054     OCStackResult OCSecureResource::provisionCredentials(const Credential &cred,
1055             const OCSecureResource &device2, ResultCallBack resultCallback)
1056     {
1057         if (!resultCallback)
1058         {
1059             oclog() << "Result calback can't be null";
1060             return OC_STACK_INVALID_CALLBACK;
1061         }
1062
1063         OCStackResult result;
1064         auto cLock = m_csdkLock.lock();
1065
1066         if (cLock)
1067         {
1068             ProvisionContext* context = new ProvisionContext(resultCallback);
1069
1070             std::lock_guard<std::recursive_mutex> lock(*cLock);
1071             result = OCProvisionCredentials(static_cast<void*>(context),
1072                     cred.getCredentialType(),
1073                     cred.getCredentialKeySize(),
1074                     devPtr, device2.getDevPtr(),
1075                     &OCSecureResource::callbackWrapper);
1076         }
1077         else
1078         {
1079             oclog() <<"Mutex not found";
1080             result = OC_STACK_ERROR;
1081         }
1082         return result;
1083     }
1084
1085     OCStackResult OCSecureResource::provisionPairwiseDevices(const Credential &cred,
1086             const OicSecAcl_t* acl1, const OCSecureResource &device2, const OicSecAcl_t* acl2,
1087             ResultCallBack resultCallback)
1088     {
1089         if (!resultCallback)
1090         {
1091             oclog() << "Result callback can not be null";
1092             return OC_STACK_INVALID_CALLBACK;
1093         }
1094
1095         OCStackResult result;
1096         auto cLock = m_csdkLock.lock();
1097
1098         if (cLock)
1099         {
1100             ProvisionContext* context = new ProvisionContext(resultCallback);
1101
1102             std::lock_guard<std::recursive_mutex> lock(*cLock);
1103             result = OCProvisionPairwiseDevices(static_cast<void*>(context),
1104                     cred.getCredentialType(),
1105                     cred.getCredentialKeySize(),
1106                     devPtr, const_cast<OicSecAcl_t*>(acl1),
1107                     device2.getDevPtr(), const_cast<OicSecAcl_t*>(acl2),
1108                     &OCSecureResource::callbackWrapper);
1109         }
1110         else
1111         {
1112             oclog() <<"Mutex not found";
1113             result = OC_STACK_ERROR;
1114         }
1115         return result;
1116     }
1117
1118     OCStackResult OCSecureResource::unlinkDevices(const OCSecureResource &device2,
1119             ResultCallBack resultCallback)
1120     {
1121         if (!resultCallback)
1122         {
1123             oclog() << "Result calback can't be null";
1124             return OC_STACK_INVALID_CALLBACK;
1125         }
1126
1127         OCStackResult result;
1128         auto cLock = m_csdkLock.lock();
1129
1130         if (cLock)
1131         {
1132             ProvisionContext* context = new ProvisionContext(resultCallback);
1133
1134             std::lock_guard<std::recursive_mutex> lock(*cLock);
1135
1136             result = OCUnlinkDevices(static_cast<void*>(context),
1137                     devPtr, device2.getDevPtr(), &OCSecureResource::callbackWrapper);
1138         }
1139         else
1140         {
1141             oclog() <<"Mutex not found";
1142             result = OC_STACK_ERROR;
1143         }
1144         return result;
1145     }
1146
1147     OCStackResult OCSecureResource::removeDevice(unsigned short waitTimeForOwnedDeviceDiscovery,
1148             ResultCallBack resultCallback)
1149     {
1150         if (!resultCallback)
1151         {
1152             oclog() << "Result calback can't be null";
1153             return OC_STACK_INVALID_CALLBACK;
1154         }
1155
1156         OCStackResult result;
1157         auto cLock = m_csdkLock.lock();
1158
1159         if (cLock)
1160         {
1161             ProvisionContext* context = new ProvisionContext(resultCallback);
1162
1163             std::lock_guard<std::recursive_mutex> lock(*cLock);
1164
1165             result = OCRemoveDevice(static_cast<void*>(context), waitTimeForOwnedDeviceDiscovery,
1166                     devPtr, &OCSecureResource::callbackWrapper);
1167         }
1168         else
1169         {
1170             oclog() <<"Mutex not found";
1171             result = OC_STACK_ERROR;
1172         }
1173         return result;
1174     }
1175
1176     OCStackResult OCSecureResource::getLinkedDevices(UuidList_t &uuidList)
1177     {
1178         OCStackResult result;
1179         size_t numOfDevices = -1;
1180         auto devUuid = devPtr->doxm->deviceID;
1181         auto cLock = m_csdkLock.lock();
1182
1183         if (cLock)
1184         {
1185             std::lock_guard<std::recursive_mutex> lock(*cLock);
1186
1187             OCUuidList_t* linkedDevs = nullptr, *tmp = nullptr;
1188             result = OCGetLinkedStatus(&devUuid, &linkedDevs, &numOfDevices);
1189             if (result == OC_STACK_OK)
1190             {
1191                 for (tmp = linkedDevs; tmp; tmp = tmp->next)
1192                 {
1193                     uuidList.push_back(tmp->dev);
1194                 }
1195                 OCDeleteUuidList(linkedDevs);
1196             }
1197         }
1198         else
1199         {
1200             oclog() <<"Mutex not found";
1201             result = OC_STACK_ERROR;
1202         }
1203         return result;
1204     }
1205
1206     OCStackResult OCSecureResource::provisionDirectPairing( const OicSecPconf_t* pconf,
1207             ResultCallBack resultCallback)
1208     {
1209         if (!pconf)
1210         {
1211             oclog() <<"PCONF can't be null";
1212             return OC_STACK_INVALID_PARAM;
1213         }
1214         if (!resultCallback)
1215         {
1216             oclog() <<"result callback can not be null";
1217             return OC_STACK_INVALID_CALLBACK;
1218         }
1219
1220         OCStackResult result;
1221         auto cLock = m_csdkLock.lock();
1222
1223         if (cLock)
1224         {
1225             ProvisionContext* context = new ProvisionContext(resultCallback);
1226
1227             std::lock_guard<std::recursive_mutex> lock(*cLock);
1228             result = OCProvisionDirectPairing(static_cast<void*>(context),
1229                     devPtr, const_cast<OicSecPconf_t*>(pconf),
1230                     &OCSecureResource::callbackWrapper);
1231         }
1232         else
1233         {
1234             oclog() <<"Mutex not found";
1235             result = OC_STACK_ERROR;
1236         }
1237         return result;
1238     }
1239
1240 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1241     OCStackResult OCSecureResource::provisionTrustCertChain(OicSecCredType_t type, uint16_t credId,
1242                     ResultCallBack resultCallback)
1243     {
1244         if (SIGNED_ASYMMETRIC_KEY != type)
1245         {
1246             oclog() <<"Invalid key type";
1247             return OC_STACK_INVALID_PARAM;
1248         }
1249         if (!resultCallback)
1250         {
1251             oclog() <<"result callback can not be null";
1252             return OC_STACK_INVALID_CALLBACK;
1253         }
1254
1255         OCStackResult result;
1256         auto cLock = m_csdkLock.lock();
1257
1258         if (cLock)
1259         {
1260             ProvisionContext* context = new ProvisionContext(resultCallback);
1261
1262             std::lock_guard<std::recursive_mutex> lock(*cLock);
1263             result = OCProvisionTrustCertChain(static_cast<void*>(context),
1264                     type, credId, devPtr,
1265                     &OCSecureResource::callbackWrapper);
1266         }
1267         else
1268         {
1269             oclog() <<"Mutex not found";
1270             result = OC_STACK_ERROR;
1271         }
1272         return result;
1273     }
1274 #endif // __WITH_DTLS__ or __WITH_TLS__
1275
1276     std::string OCSecureResource::getDeviceID()
1277     {
1278         std::ostringstream deviceId("");
1279         char *devID = nullptr;
1280
1281         validateSecureResource();
1282
1283         if (OC_STACK_OK == ConvertUuidToStr(&(devPtr->doxm->deviceID), &devID))
1284         {
1285             deviceId << devID;
1286             free(devID);
1287         }
1288         else
1289         {
1290             oclog() <<"Can not convert uuid to struuid";
1291         }
1292         return deviceId.str();
1293     }
1294
1295     OCProvisionDev_t* OCSecureResource::getDevPtr() const
1296     {
1297         return devPtr;
1298     }
1299
1300     std::string OCSecureResource::getDevAddr()
1301     {
1302         validateSecureResource();
1303         std::string ipAddr(devPtr->endpoint.addr);
1304         return ipAddr;
1305     }
1306
1307     int OCSecureResource::getDeviceStatus()
1308     {
1309         validateSecureResource();
1310         return (int)devPtr->devStatus;
1311     }
1312
1313     bool OCSecureResource::getOwnedStatus()
1314     {
1315         validateSecureResource();
1316         return devPtr->doxm->owned;
1317     }
1318
1319     void OCSecureResource::validateSecureResource()
1320     {
1321         if (!devPtr)
1322         {
1323             throw OCException("Incomplete secure resource", OC_STACK_RESOURCE_ERROR);
1324         }
1325     }
1326
1327     OCStackResult OCSecureResource::getOTMethod(OicSecOxm_t* oxm)
1328     {
1329         if(!oxm)
1330         {
1331             oclog() << "Null param";
1332             return OC_STACK_INVALID_PARAM;
1333         }
1334
1335         OCStackResult result = OC_STACK_ERROR;
1336         auto cLock = m_csdkLock.lock();
1337         if (cLock)
1338         {
1339             std::lock_guard<std::recursive_mutex> lock(*cLock);
1340             if(devPtr && devPtr->doxm)
1341             {
1342                 result = OCSelectOwnershipTransferMethod(devPtr->doxm->oxm, devPtr->doxm->oxmLen,
1343                                                   oxm, SUPER_OWNER);
1344             }
1345         }
1346         else
1347         {
1348             oclog() <<"Mutex not found";
1349         }
1350         return result;
1351     }
1352
1353
1354 #ifdef MULTIPLE_OWNER
1355     OCStackResult OCSecureResource::getMOTMethod( OicSecOxm_t* oxm)
1356     {
1357         if (!oxm)
1358         {
1359             oclog() << "Null param";
1360             return OC_STACK_INVALID_PARAM;
1361         }
1362
1363         OCStackResult result = OC_STACK_ERROR;
1364         auto cLock = m_csdkLock.lock();
1365         if (cLock)
1366         {
1367             std::lock_guard<std::recursive_mutex> lock(*cLock);
1368             if (devPtr && devPtr->doxm)
1369             {
1370                 result = OCSelectOwnershipTransferMethod(devPtr->doxm->oxm, devPtr->doxm->oxmLen,
1371                                                   oxm, SUB_OWNER);
1372             }
1373         }
1374         else
1375         {
1376             oclog() <<"Mutex not found";
1377         }
1378         return result;
1379     }
1380
1381     bool OCSecureResource::isMOTSupported()
1382     {
1383         if (devPtr && devPtr->doxm)
1384         {
1385             return (devPtr->doxm->mom ? true : false);
1386         }
1387         return false;
1388     }
1389
1390     bool OCSecureResource::isMOTEnabled()
1391     {
1392         if (devPtr && devPtr->doxm && devPtr->doxm->mom)
1393         {
1394             if (OIC_MULTIPLE_OWNER_DISABLE != devPtr->doxm->mom->mode)
1395             {
1396                 return true;
1397             }
1398         }
1399         return false;
1400     }
1401
1402     OCStackResult OCSecureResource::selectMOTMethod( const OicSecOxm_t oxmSelVal,
1403             ResultCallBack resultCallback)
1404     {
1405         if (!resultCallback)
1406         {
1407             oclog() <<"result callback can not be null";
1408             return OC_STACK_INVALID_CALLBACK;
1409         }
1410
1411         OCStackResult result;
1412         auto cLock = m_csdkLock.lock();
1413
1414         if (cLock)
1415         {
1416             ProvisionContext* context = new ProvisionContext(resultCallback);
1417
1418             std::lock_guard<std::recursive_mutex> lock(*cLock);
1419             result = OCSelectMOTMethod(static_cast<void*>(context),
1420                     devPtr, oxmSelVal,
1421                     &OCSecureResource::callbackWrapper);
1422         }
1423         else
1424         {
1425             oclog() <<"Mutex not found";
1426             result = OC_STACK_ERROR;
1427         }
1428         return result;
1429     }
1430
1431     OCStackResult OCSecureResource::changeMOTMode( const OicSecMomType_t momType,
1432             ResultCallBack resultCallback)
1433     {
1434         if (!resultCallback)
1435         {
1436             oclog() <<"result callback can not be null";
1437             return OC_STACK_INVALID_CALLBACK;
1438         }
1439
1440         OCStackResult result;
1441         auto cLock = m_csdkLock.lock();
1442
1443         if (cLock)
1444         {
1445             ProvisionContext* context = new ProvisionContext(resultCallback);
1446
1447             std::lock_guard<std::recursive_mutex> lock(*cLock);
1448             result = OCChangeMOTMode(static_cast<void*>(context),
1449                     devPtr, momType,
1450                     &OCSecureResource::callbackWrapper);
1451         }
1452         else
1453         {
1454             oclog() <<"Mutex not found";
1455             result = OC_STACK_ERROR;
1456         }
1457         return result;
1458     }
1459
1460
1461     OCStackResult OCSecureResource::addPreconfigPIN(const char* preconfPIN,
1462             size_t preconfPINLength)
1463     {
1464         if (!preconfPIN)
1465         {
1466             oclog() <<"pre config pin can not be null";
1467             return OC_STACK_INVALID_PARAM;
1468         }
1469         if (preconfPINLength <= 0)
1470         {
1471             oclog() <<"pre config pin length can not be zero or less";
1472             return OC_STACK_INVALID_PARAM;
1473         }
1474         OCStackResult result;
1475         auto cLock = m_csdkLock.lock();
1476
1477         if (cLock)
1478         {
1479             std::lock_guard<std::recursive_mutex> lock(*cLock);
1480             result = OCAddPreconfigPin(devPtr, preconfPIN,
1481                     preconfPINLength);
1482         }
1483         else
1484         {
1485             oclog() <<"Mutex not found";
1486             result = OC_STACK_ERROR;
1487         }
1488         return result;
1489     }
1490
1491     OCStackResult OCSecureResource::provisionPreconfPin(const char * preconfPin,
1492             size_t preconfPinLength, ResultCallBack resultCallback)
1493     {
1494         if (!resultCallback)
1495         {
1496             oclog() <<"result callback can not be null";
1497             return OC_STACK_INVALID_CALLBACK;
1498         }
1499         if (!preconfPin)
1500         {
1501             oclog() <<"pre config pin can not be null";
1502             return OC_STACK_INVALID_PARAM;
1503         }
1504         if (preconfPinLength <= 0)
1505         {
1506             oclog() <<"pre config pin length can not be zero or less";
1507             return OC_STACK_INVALID_PARAM;
1508         }
1509
1510         OCStackResult result;
1511         auto cLock = m_csdkLock.lock();
1512
1513         if (cLock)
1514         {
1515             ProvisionContext* context = new ProvisionContext(resultCallback);
1516
1517             std::lock_guard<std::recursive_mutex> lock(*cLock);
1518             result = OCProvisionPreconfigPin(static_cast<void*>(context),
1519                     devPtr, preconfPin, preconfPinLength,
1520                     &OCSecureResource::callbackWrapper);
1521         }
1522         else
1523         {
1524             oclog() <<"Mutex not found";
1525             result = OC_STACK_ERROR;
1526         }
1527         return result;
1528     }
1529
1530     OCStackResult OCSecureResource::removeSubOwner(const OicUuid_t* subOwnerId, ResultCallBack resultCallback)
1531     {
1532         validateSecureResource();
1533         OCStackResult result;
1534         auto cLock = m_csdkLock.lock();
1535         if (cLock)
1536         {
1537             ProvisionContext* context = new ProvisionContext(resultCallback);
1538             result = OCRemoveSubOwner(static_cast<void*>(context),
1539                 devPtr, subOwnerId, &OCSecureResource::callbackWrapper);
1540         }
1541         else
1542         {
1543             oclog() << "Mutex not found";
1544             result = OC_STACK_ERROR;
1545         }
1546         return result;
1547     }
1548
1549     OCStackResult OCSecureResource::removeAllSubOwner(ResultCallBack resultCallback)
1550     {
1551         validateSecureResource();
1552         OCStackResult result;
1553         auto cLock = m_csdkLock.lock();
1554         if (cLock)
1555         {
1556             ProvisionContext* context = new ProvisionContext(resultCallback);
1557             result =OCRemoveAllSubOwner(static_cast<void*>(context),
1558                 devPtr, &OCSecureResource::callbackWrapper);
1559         }
1560         else
1561         {
1562             oclog() << "Mutex not found";
1563             result = OC_STACK_ERROR;
1564         }
1565         return result;
1566     }
1567
1568 #endif // MULTIPLE_OWNER
1569 }