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