1 //******************************************************************
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
23 #include "EnrolleeSecurity.h"
24 #include "oxmjustworks.h"
25 #include "oxmrandompin.h"
26 #include "EnrolleeResource.h"
28 #include "ESException.h"
29 #include "oic_malloc.h"
30 #include "oic_string.h"
36 #define MAX_PERMISSION_LENGTH (5)
44 //TODO : Currently discovery timeout for owned and unowned devices is fixed as 5
45 // The value should be accepted from the application as a parameter during ocplatform
47 #define ES_SEC_DISCOVERY_TIMEOUT 5
49 EnrolleeSecurity::EnrolleeSecurity(
50 std::shared_ptr< OC::OCResource > resource,
51 std::string secDbPath)
53 m_ocResource = resource;
56 void EnrolleeSecurity::registerCallbackHandler(SecurityProvStatusCb securityProvStatusCb,
57 SecurityPinCb securityPinCb, SecProvisioningDbPathCb secProvisioningDbPathCb)
59 m_securityProvStatusCb = securityProvStatusCb;
60 m_securityPinCb = securityPinCb;
61 m_secProvisioningDbPathCb = secProvisioningDbPathCb;
64 std::shared_ptr< OC::OCSecureResource > EnrolleeSecurity::getEnrollee(DeviceList_t &list)
66 for (unsigned int i = 0; i < list.size(); i++)
68 if(m_ocResource->sid() == list[i]->getDeviceID().c_str())
70 OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Device %d ID %s ", i + 1,
71 list[i]->getDeviceID().c_str());
72 OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "From IP :%s", list[i]->getDevAddr().c_str());
75 //Always return the first element of the unOwned devices. This is considering that Mediator is
76 // always connected with only one Enrollee for which ownership transfer is being performed.
77 // Incase of multiple Enrollee devices connected to the Mediator via any OnBoarding method (SoftAp
78 // for example), the Enrollee devices will be provisioned in the first come first serve basis in the order
79 // returned by the security layer.
82 OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,"Error!!! DeviceList_t is NULL");
86 void EnrolleeSecurity::convertUUIDToString(OicUuid_t uuid, std::string& uuidString)
88 char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*) 0)->id)) + 1] =
91 B64Result b64Ret = B64_OK;
92 std::ostringstream deviceId("");
94 b64Ret = b64Encode(uuid.id, sizeof(uuid.id),
95 base64Buff, sizeof(base64Buff), &outLen);
99 deviceId << base64Buff;
101 uuidString = deviceId.str();
104 void EnrolleeSecurity::ownershipTransferCb(OC::PMResultList_t *result, int hasError)
108 OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,"Error!!! in OwnershipTransfer");
111 convertUUIDToString(result->at(0).deviceId, uuid);
112 std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
113 std::make_shared< SecProvisioningStatus >(uuid, ES_ERROR);
114 m_securityProvStatusCb(securityProvisioningStatus);
119 OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "ownershipTransferCb : Received provisioning results: ");
120 for (unsigned int i = 0; i < result->size(); i++)
122 OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Result is = %d for device",result->at(i).res);
124 convertUUIDToString(result->at(0).deviceId, uuid);
126 OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "UUID : %s",uuid.c_str());
127 std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
128 std::make_shared< SecProvisioningStatus >(uuid, ES_OK);
129 m_securityProvStatusCb(securityProvisioningStatus);
137 void EnrolleeSecurity::performOwnershipTransfer()
139 OC::DeviceList_t pUnownedDevList, pOwnedDevList;
141 pOwnedDevList.clear();
142 pUnownedDevList.clear();
144 OCStackResult result;
146 result = OCSecure::discoverOwnedDevices(ES_SEC_DISCOVERY_TIMEOUT,
148 if (result != OC_STACK_OK)
150 OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "Owned Discovery failed.");
152 throw ESPlatformException(result);
154 else if (pOwnedDevList.size())
156 OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Found owned devices. Count =%d",
157 pOwnedDevList.size());
158 std::shared_ptr< OC::OCSecureResource > ownedDevice = getEnrollee(pOwnedDevList);
162 std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
163 std::make_shared< SecProvisioningStatus >(ownedDevice->getDeviceID(), ES_OK);
164 m_securityProvStatusCb(securityProvisioningStatus);
169 result = OCSecure::discoverUnownedDevices(ES_SEC_DISCOVERY_TIMEOUT, pUnownedDevList);
170 if (result != OC_STACK_OK)
172 OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "UnOwned Discovery failed.");
174 throw ESPlatformException(result);
176 else if (pUnownedDevList.size())
178 OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Found Unowned devices. Count =%d",
179 pUnownedDevList.size());
181 m_unownedDevice = getEnrollee(pUnownedDevList);
184 OTMCallbackData_t justWorksCBData;
185 justWorksCBData.loadSecretCB = LoadSecretJustWorksCallback;
186 justWorksCBData.createSecureSessionCB = CreateSecureSessionJustWorksCallback;
187 justWorksCBData.createSelectOxmPayloadCB = CreateJustWorksSelectOxmPayload;
188 justWorksCBData.createOwnerTransferPayloadCB =
189 CreateJustWorksOwnerTransferPayload;
190 OCSecure::setOwnerTransferCallbackData(OIC_JUST_WORKS, &justWorksCBData, NULL);
192 OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Transfering ownership for : %s ",
193 m_unownedDevice->getDeviceID().c_str());
195 OC::ResultCallBack ownershipTransferCb = std::bind(
196 &EnrolleeSecurity::ownershipTransferCb, this, std::placeholders::_1,
197 std::placeholders::_2);
199 result = m_unownedDevice->doOwnershipTransfer(ownershipTransferCb);
200 if (result != OC_STACK_OK)
202 OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "OwnershipTransferCallback is failed");
203 throw ESPlatformException(result);
209 OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "No unOwned devices found.");
210 throw ESException("No unOwned devices found.");