1 /* *****************************************************************
3 * Copyright 2015 Samsung Electronics All Rights Reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * *****************************************************************/
22 #include "srmutility.h"
24 #include "OCProvisioningManager.hpp"
28 OCStackResult OCSecure::provisionInit(const std::string& dbPath)
31 auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
35 std::lock_guard<std::recursive_mutex> lock(*cLock);
36 result = OCInitPM(dbPath.c_str());
40 oclog() <<"Mutex not found";
41 result = OC_STACK_ERROR;
47 OCStackResult OCSecure::discoverUnownedDevices(unsigned short timeout,
51 OCProvisionDev_t *pDevList = nullptr, *pCurDev = nullptr, *tmp = nullptr;
52 auto csdkLock = OCPlatform_impl::Instance().csdkLock();
53 auto cLock = csdkLock.lock();
57 std::lock_guard<std::recursive_mutex> lock(*cLock);
58 result = OCDiscoverUnownedDevices(timeout, &pDevList);
59 if (result == OC_STACK_OK)
61 // Create DeviceList of OCSecureResource's
66 list.push_back(std::shared_ptr<OCSecureResource>(
67 new OCSecureResource(csdkLock, pCurDev)));
68 pCurDev = pCurDev->next;
74 oclog() <<"Unowned device discovery failed!";
79 oclog() <<"Mutex not found";
80 result = OC_STACK_ERROR;
86 OCStackResult OCSecure::discoverOwnedDevices(unsigned short timeout,
90 OCProvisionDev_t *pDevList = nullptr, *pCurDev = nullptr, *tmp = nullptr;
91 auto csdkLock = OCPlatform_impl::Instance().csdkLock();
92 auto cLock = csdkLock.lock();
96 std::lock_guard<std::recursive_mutex> lock(*cLock);
97 result = OCDiscoverOwnedDevices(timeout, &pDevList);
98 if (result == OC_STACK_OK)
104 list.push_back(std::shared_ptr<OCSecureResource>(
105 new OCSecureResource(csdkLock, pCurDev)));
106 pCurDev = pCurDev->next;
112 oclog() <<"Owned device discovery failed!";
117 oclog() <<"Mutex not found";
118 result = OC_STACK_ERROR;
124 OCStackResult OCSecure::discoverSingleDevice(unsigned short timeout,
125 const OicUuid_t* deviceID,
126 std::shared_ptr<OCSecureResource> &foundDevice)
128 OCStackResult result;
129 OCProvisionDev_t *pDev = nullptr;
130 auto csdkLock = OCPlatform_impl::Instance().csdkLock();
131 auto cLock = csdkLock.lock();
135 std::lock_guard<std::recursive_mutex> lock(*cLock);
136 result = OCDiscoverSingleDevice(timeout, deviceID, &pDev);
137 if (result == OC_STACK_OK)
141 foundDevice.reset(new OCSecureResource(csdkLock, pDev));
145 oclog() <<"Not found Secure resource!";
151 oclog() <<"Secure resource discovery failed!";
156 oclog() <<"Mutex not found";
157 result = OC_STACK_ERROR;
163 OCStackResult OCSecure::setOwnerTransferCallbackData(OicSecOxm_t oxm,
164 OTMCallbackData_t* callbackData, InputPinCallback inputPin)
166 if (NULL == callbackData || oxm >= OIC_OXM_COUNT)
168 oclog() <<"Invalid callbackData or OXM type";
169 return OC_STACK_INVALID_PARAM;
172 if ((OIC_RANDOM_DEVICE_PIN == oxm) && !inputPin)
174 oclog() <<"for OXM type DEVICE_PIN, inputPin callback can't be null";
175 return OC_STACK_INVALID_PARAM;
178 OCStackResult result;
179 auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
183 std::lock_guard<std::recursive_mutex> lock(*cLock);
184 result = OCSetOwnerTransferCallbackData(oxm, callbackData);
185 if (result == OC_STACK_OK && (OIC_RANDOM_DEVICE_PIN == oxm))
187 SetInputPinCB(inputPin);
192 oclog() <<"Mutex not found";
193 result = OC_STACK_ERROR;
200 OCStackResult OCSecure::getDevInfoFromNetwork(unsigned short timeout,
201 DeviceList_t &ownedDevList,
202 DeviceList_t &unownedDevList)
204 OCStackResult result = OC_STACK_OK;
205 OCProvisionDev_t *owned = nullptr, *unowned = nullptr, *tmp = nullptr, *dev = nullptr;
206 auto csdkLock = OCPlatform_impl::Instance().csdkLock();
207 auto cLock = csdkLock.lock();
211 std::lock_guard<std::recursive_mutex> lock(*cLock);
213 result = OCGetDevInfoFromNetwork(timeout, &owned, &unowned);
215 if (result == OC_STACK_OK)
221 ownedDevList.push_back(std::shared_ptr<OCSecureResource>(
222 new OCSecureResource(csdkLock, dev)));
231 unownedDevList.push_back(std::shared_ptr<OCSecureResource>(
232 new OCSecureResource(csdkLock, dev)));
240 oclog() <<"Mutex not found";
241 result = OC_STACK_ERROR;
247 OCStackResult OCSecure::setDisplayPinCB(GeneratePinCallback displayPin)
251 oclog() <<"displayPin can't be null";
252 return OC_STACK_INVALID_PARAM;
255 OCStackResult result = OC_STACK_OK;
256 auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
260 std::lock_guard<std::recursive_mutex> lock(*cLock);
261 SetGeneratePinCB(displayPin);
265 oclog() <<"Mutex not found";
266 result = OC_STACK_ERROR;
272 OCStackResult OCSecure::removeDeviceWithUuid(unsigned short waitTimeForOwnedDeviceDiscovery,
274 ResultCallBack resultCallback)
278 oclog() << "Result calback can't be null";
279 return OC_STACK_INVALID_CALLBACK;
282 OCStackResult result;
283 auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
287 ProvisionContext* context = new ProvisionContext(resultCallback);
289 std::lock_guard<std::recursive_mutex> lock(*cLock);
292 result = ConvertStrToUuid(uuid.c_str(), &targetDev);
293 if(OC_STACK_OK == result)
295 result = OCRemoveDeviceWithUuid(static_cast<void*>(context), waitTimeForOwnedDeviceDiscovery,
296 &targetDev, &OCSecureResource::callbackWrapper);
300 oclog() <<"Can not convert struuid to uuid";
305 oclog() <<"Mutex not found";
306 result = OC_STACK_ERROR;
311 OCStackResult OCSecure::saveACL(const OicSecAcl_t* acl)
315 oclog() <<"ACL can't be null";
316 return OC_STACK_INVALID_PARAM;
319 OCStackResult result;
320 auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
324 std::lock_guard<std::recursive_mutex> lock(*cLock);
325 result = OCSaveACL(const_cast<OicSecAcl_t*>(acl));
329 oclog() <<"Mutex not found";
330 result = OC_STACK_ERROR;
335 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
336 OCStackResult OCSecure::saveTrustCertChain(uint8_t *trustCertChain, size_t chainSize,
337 OicEncodingType_t encodingType, uint16_t *credId)
341 oclog() <<"trustCertChain can't be null";
342 return OC_STACK_INVALID_PARAM;
346 oclog() <<"cred ID can not be null";
347 return OC_STACK_INVALID_PARAM;
350 OCStackResult result;
351 auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
355 std::lock_guard<std::recursive_mutex> lock(*cLock);
356 result = OCSaveTrustCertChain(trustCertChain, chainSize, encodingType, credId );
360 oclog() <<"Mutex not found";
361 result = OC_STACK_ERROR;
366 OCStackResult OCSecure::readTrustCertChain(uint16_t credId, uint8_t **trustCertChain,
369 OCStackResult result;
370 auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
374 std::lock_guard<std::recursive_mutex> lock(*cLock);
375 result = OCReadTrustCertChain(credId, trustCertChain, chainSize);
379 oclog() <<"Mutex not found";
380 result = OC_STACK_ERROR;
385 void OCSecure::certCallbackWrapper(void* ctx, uint16_t credId, uint8_t *trustCertChain,
388 TrustCertChainContext* context = static_cast<TrustCertChainContext*>(ctx);
389 uint8_t *certChain = new uint8_t[chainSize];
390 memcpy(certChain, trustCertChain, chainSize);
391 std::thread exec(context->callback, credId, certChain, chainSize);
396 OCStackResult OCSecure::registerTrustCertChangeNotifier(CertChainCallBack callback)
400 oclog() <<"callback can not be null";
401 return OC_STACK_INVALID_CALLBACK;
404 OCStackResult result;
405 auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
409 TrustCertChainContext* context = new TrustCertChainContext(callback);
410 std::lock_guard<std::recursive_mutex> lock(*cLock);
411 result = OCRegisterTrustCertChainNotifier(static_cast<void*>(context),
412 &OCSecure::certCallbackWrapper);
416 oclog() <<"Mutex not found";
417 result = OC_STACK_ERROR;
423 OCStackResult OCSecure::removeTrustCertChangeNotifier()
425 OCStackResult result;
426 auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
430 std::lock_guard<std::recursive_mutex> lock(*cLock);
431 OCRemoveTrustCertChainNotifier();
432 result = OC_STACK_OK;
436 oclog() <<"Mutex not found";
437 result = OC_STACK_ERROR;
441 #endif // __WITH_DTLS__ || __WITH_TLS__
443 void OCSecureResource::callbackWrapper(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
445 PMResultList_t *results = nullptr;
446 ProvisionContext* context = static_cast<ProvisionContext*>(ctx);
450 results = new PMResultList_t;
452 catch (std::bad_alloc& e)
454 oclog() <<"Bad alloc exception";
458 for (int i = 0; i < nOfRes; i++)
460 results->push_back(arr[i]);
463 std::thread exec(context->callback, results, hasError);
469 OCSecureResource::OCSecureResource(): m_csdkLock(std::weak_ptr<std::recursive_mutex>()),
474 OCSecureResource::OCSecureResource(std::weak_ptr<std::recursive_mutex> csdkLock,
475 OCProvisionDev_t *dPtr)
476 :m_csdkLock(csdkLock), devPtr(dPtr)
480 OCSecureResource::~OCSecureResource()
484 OCDeleteDiscoveredDevices(devPtr);
488 OCStackResult OCSecureResource::doOwnershipTransfer(ResultCallBack resultCallback)
492 oclog() <<"Result callback can't be null";
493 return OC_STACK_INVALID_CALLBACK;
496 OCStackResult result;
497 auto cLock = m_csdkLock.lock();
501 ProvisionContext* context = new ProvisionContext(resultCallback);
503 std::lock_guard<std::recursive_mutex> lock(*cLock);
504 result = OCDoOwnershipTransfer(static_cast<void*>(context),
505 devPtr, &OCSecureResource::callbackWrapper);
509 oclog() <<"Mutex not found";
510 result = OC_STACK_ERROR;
515 OCStackResult OCSecureResource::provisionACL( const OicSecAcl_t* acl,
516 ResultCallBack resultCallback)
520 oclog() <<"ACL can't be null";
521 return OC_STACK_INVALID_PARAM;
525 oclog() <<"result callback can not be null";
526 return OC_STACK_INVALID_CALLBACK;
529 OCStackResult result;
530 auto cLock = m_csdkLock.lock();
534 ProvisionContext* context = new ProvisionContext(resultCallback);
536 std::lock_guard<std::recursive_mutex> lock(*cLock);
537 result = OCProvisionACL(static_cast<void*>(context),
538 devPtr, const_cast<OicSecAcl_t*>(acl),
539 &OCSecureResource::callbackWrapper);
543 oclog() <<"Mutex not found";
544 result = OC_STACK_ERROR;
549 OCStackResult OCSecureResource::provisionCredentials(const Credential &cred,
550 const OCSecureResource &device2, ResultCallBack resultCallback)
554 oclog() << "Result calback can't be null";
555 return OC_STACK_INVALID_CALLBACK;
558 OCStackResult result;
559 auto cLock = m_csdkLock.lock();
563 ProvisionContext* context = new ProvisionContext(resultCallback);
565 std::lock_guard<std::recursive_mutex> lock(*cLock);
566 result = OCProvisionCredentials(static_cast<void*>(context),
567 cred.getCredentialType(),
568 cred.getCredentialKeySize(),
569 devPtr, device2.getDevPtr(),
570 &OCSecureResource::callbackWrapper);
574 oclog() <<"Mutex not found";
575 result = OC_STACK_ERROR;
580 OCStackResult OCSecureResource::provisionPairwiseDevices(const Credential &cred,
581 const OicSecAcl_t* acl1, const OCSecureResource &device2, const OicSecAcl_t* acl2,
582 ResultCallBack resultCallback)
586 oclog() << "Result callback can not be null";
587 return OC_STACK_INVALID_CALLBACK;
590 OCStackResult result;
591 auto cLock = m_csdkLock.lock();
595 ProvisionContext* context = new ProvisionContext(resultCallback);
597 std::lock_guard<std::recursive_mutex> lock(*cLock);
598 result = OCProvisionPairwiseDevices(static_cast<void*>(context),
599 cred.getCredentialType(),
600 cred.getCredentialKeySize(),
601 devPtr, const_cast<OicSecAcl_t*>(acl1),
602 device2.getDevPtr(), const_cast<OicSecAcl_t*>(acl2),
603 &OCSecureResource::callbackWrapper);
607 oclog() <<"Mutex not found";
608 result = OC_STACK_ERROR;
613 OCStackResult OCSecureResource::unlinkDevices(const OCSecureResource &device2,
614 ResultCallBack resultCallback)
618 oclog() << "Result calback can't be null";
619 return OC_STACK_INVALID_CALLBACK;
622 OCStackResult result;
623 auto cLock = m_csdkLock.lock();
627 ProvisionContext* context = new ProvisionContext(resultCallback);
629 std::lock_guard<std::recursive_mutex> lock(*cLock);
631 result = OCUnlinkDevices(static_cast<void*>(context),
632 devPtr, device2.getDevPtr(), &OCSecureResource::callbackWrapper);
636 oclog() <<"Mutex not found";
637 result = OC_STACK_ERROR;
642 OCStackResult OCSecureResource::removeDevice(unsigned short waitTimeForOwnedDeviceDiscovery,
643 ResultCallBack resultCallback)
647 oclog() << "Result calback can't be null";
648 return OC_STACK_INVALID_CALLBACK;
651 OCStackResult result;
652 auto cLock = m_csdkLock.lock();
656 ProvisionContext* context = new ProvisionContext(resultCallback);
658 std::lock_guard<std::recursive_mutex> lock(*cLock);
660 result = OCRemoveDevice(static_cast<void*>(context), waitTimeForOwnedDeviceDiscovery,
661 devPtr, &OCSecureResource::callbackWrapper);
665 oclog() <<"Mutex not found";
666 result = OC_STACK_ERROR;
671 OCStackResult OCSecureResource::getLinkedDevices(UuidList_t &uuidList)
673 OCStackResult result;
674 size_t numOfDevices = -1;
675 auto devUuid = devPtr->doxm->deviceID;
676 auto cLock = m_csdkLock.lock();
680 std::lock_guard<std::recursive_mutex> lock(*cLock);
682 OCUuidList_t* linkedDevs = nullptr, *tmp = nullptr;
683 result = OCGetLinkedStatus(&devUuid, &linkedDevs, &numOfDevices);
684 if (result == OC_STACK_OK)
686 for (tmp = linkedDevs; tmp; tmp = tmp->next)
688 uuidList.push_back(tmp->dev);
690 OCDeleteUuidList(linkedDevs);
695 oclog() <<"Mutex not found";
696 result = OC_STACK_ERROR;
701 OCStackResult OCSecureResource::provisionDirectPairing( const OicSecPconf_t* pconf,
702 ResultCallBack resultCallback)
706 oclog() <<"PCONF can't be null";
707 return OC_STACK_INVALID_PARAM;
711 oclog() <<"result callback can not be null";
712 return OC_STACK_INVALID_CALLBACK;
715 OCStackResult result;
716 auto cLock = m_csdkLock.lock();
720 ProvisionContext* context = new ProvisionContext(resultCallback);
722 std::lock_guard<std::recursive_mutex> lock(*cLock);
723 result = OCProvisionDirectPairing(static_cast<void*>(context),
724 devPtr, const_cast<OicSecPconf_t*>(pconf),
725 &OCSecureResource::callbackWrapper);
729 oclog() <<"Mutex not found";
730 result = OC_STACK_ERROR;
735 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
736 OCStackResult OCSecureResource::provisionTrustCertChain(OicSecCredType_t type, uint16_t credId,
737 ResultCallBack resultCallback)
739 if (SIGNED_ASYMMETRIC_KEY != type)
741 oclog() <<"Invalid key type";
742 return OC_STACK_INVALID_PARAM;
746 oclog() <<"result callback can not be null";
747 return OC_STACK_INVALID_CALLBACK;
750 OCStackResult result;
751 auto cLock = m_csdkLock.lock();
755 ProvisionContext* context = new ProvisionContext(resultCallback);
757 std::lock_guard<std::recursive_mutex> lock(*cLock);
758 result = OCProvisionTrustCertChain(static_cast<void*>(context),
759 type, credId, devPtr,
760 &OCSecureResource::callbackWrapper);
764 oclog() <<"Mutex not found";
765 result = OC_STACK_ERROR;
769 #endif // __WITH_DTLS__ or __WITH_TLS__
771 std::string OCSecureResource::getDeviceID()
773 std::ostringstream deviceId("");
774 char *devID = nullptr;
776 validateSecureResource();
778 if (OC_STACK_OK == ConvertUuidToStr(&(devPtr->doxm->deviceID), &devID))
785 oclog() <<"Can not convert uuid to struuid";
787 return deviceId.str();
790 OCProvisionDev_t* OCSecureResource::getDevPtr() const
795 std::string OCSecureResource::getDevAddr()
797 validateSecureResource();
798 std::string ipAddr(devPtr->endpoint.addr);
802 int OCSecureResource::getDeviceStatus()
804 validateSecureResource();
805 return (int)devPtr->devStatus;
808 bool OCSecureResource::getOwnedStatus()
810 validateSecureResource();
811 return devPtr->doxm->owned;
814 void OCSecureResource::validateSecureResource()
818 throw OCException("Incomplete secure resource", OC_STACK_RESOURCE_ERROR);