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 "RemoteEnrolleeResource.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< RemoteEnrolleeResource > remoteEnrolleeResource,
51 std::string secDbPath)
53 m_enrolleeSecState = EnrolleeSecState::ES_SEC_UNKNOWN;
54 m_remoteEnrolleeResource = remoteEnrolleeResource;
56 //Initializing the provisioning client stack using the db path provided by the
58 // Note : If the path is NULL or empty, the PDM.db should be present in the same path.
59 OCStackResult result = OCSecure::provisionInit(secDbPath);
61 if (result != OC_STACK_OK)
63 throw ESPlatformException(result);
67 ESResult EnrolleeSecurity::registerCallbackHandler(EnrolleeSecStatusCb enrolleeSecStatusCb,
68 SecurityPinCb securityPinCb, SecProvisioningDbPathCb secProvisioningDbPathCb)
71 m_enrolleeSecStatusCb = enrolleeSecStatusCb;
72 m_securityPinCb = securityPinCb;
73 m_secProvisioningDbPathCb = secProvisioningDbPathCb;
78 std::shared_ptr< OC::OCSecureResource > EnrolleeSecurity::findEnrollee(std::string host,
81 for (unsigned int i = 0; i < list.size(); i++)
83 OC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Device %d ID %s ", i + 1,
84 list[i]->getDeviceID().c_str());
85 OC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "From IP :%s", list[i]->getDevAddr().c_str());
87 if (list[i]->getDevAddr() == host)
96 void EnrolleeSecurity::convertUUIDToString(OicUuid_t uuid, std::string& uuidString)
98 char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*) 0)->id)) + 1] =
101 B64Result b64Ret = B64_OK;
102 std::ostringstream deviceId("");
104 b64Ret = b64Encode(uuid.id, sizeof(uuid.id),
105 base64Buff, sizeof(base64Buff), &outLen);
107 if (B64_OK == b64Ret)
109 deviceId << base64Buff;
111 uuidString = deviceId.str();
114 void EnrolleeSecurity::ownershipTransferCb(OC::PMResultList_t *result, int hasError)
118 OC_LOG(ERROR, ENROLEE_SECURITY_TAG,"Error!!! in OwnershipTransfer");
120 std::shared_ptr< SecProvisioningResult > securityProvisioningStatus = nullptr;
122 convertUUIDToString(result->at(0).deviceId, uuid);
123 securityProvisioningStatus = std::make_shared< SecProvisioningResult >(uuid,
126 m_enrolleeSecStatusCb(securityProvisioningStatus);
131 OC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "ownershipTransferCb : Received provisioning results: ");
132 for (unsigned int i = 0; i < result->size(); i++)
134 OC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Result is = %d for device",result->at(i).res);
136 convertUUIDToString(result->at(0).deviceId, uuid);
138 OC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "UUID : %s",uuid.c_str());
139 std::shared_ptr< SecProvisioningResult > securityProvisioningStatus = nullptr;
140 securityProvisioningStatus = std::make_shared< SecProvisioningResult >(uuid,
143 m_enrolleeSecStatusCb(securityProvisioningStatus);
151 EasySetupState EnrolleeSecurity::performOwnershipTransfer()
153 EasySetupState ownershipStatus = DEVICE_NOT_OWNED;
155 OC::DeviceList_t pUnownedDevList, pOwnedDevList;
157 pOwnedDevList.clear();
158 pUnownedDevList.clear();
160 OCStackResult result;
162 //Developer note : Always test the mediator and enrollee applications on different devices. Running
163 // Mediator and Enrollee in same device will result in returning the same device as already owned.
164 result = OCSecure::discoverOwnedDevices(ES_SEC_DISCOVERY_TIMEOUT,
166 if (result != OC_STACK_OK)
168 OC_LOG(ERROR, ENROLEE_SECURITY_TAG, "Owned Discovery failed.");
169 ownershipStatus = DEVICE_NOT_OWNED;
171 throw ESPlatformException(result);
172 return ownershipStatus;
174 else if (pOwnedDevList.size())
176 OC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Found owned devices. Count =%d",
177 pOwnedDevList.size());
178 std::shared_ptr< OC::OCSecureResource > ownedDevice =
181 m_remoteEnrolleeResource->m_enrolleeNWProvInfo.netAddressInfo.WIFI.ipAddress),
185 ownershipStatus = DEVICE_OWNED;
186 return ownershipStatus;
191 OC_LOG(ERROR, ENROLEE_SECURITY_TAG, "No owned devices found.");
192 ownershipStatus = DEVICE_NOT_OWNED;
195 result = OCSecure::discoverUnownedDevices(ES_SEC_DISCOVERY_TIMEOUT, pUnownedDevList);
196 if (result != OC_STACK_OK)
198 OC_LOG(ERROR, ENROLEE_SECURITY_TAG, "UnOwned Discovery failed.");
199 ownershipStatus = DEVICE_NOT_OWNED;
201 throw ESPlatformException(result);
202 return ownershipStatus;
204 else if (pUnownedDevList.size())
206 OC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Found Unowned devices. Count =%d",
207 pUnownedDevList.size());
211 m_remoteEnrolleeResource->m_enrolleeNWProvInfo.netAddressInfo.WIFI.ipAddress,
215 OTMCallbackData_t justWorksCBData;
216 justWorksCBData.loadSecretCB = LoadSecretJustWorksCallback;
217 justWorksCBData.createSecureSessionCB = CreateSecureSessionJustWorksCallback;
218 justWorksCBData.createSelectOxmPayloadCB = CreateJustWorksSelectOxmPayload;
219 justWorksCBData.createOwnerTransferPayloadCB =
220 CreateJustWorksOwnerTransferPayload;
221 OCSecure::setOwnerTransferCallbackData(OIC_JUST_WORKS, &justWorksCBData, NULL);
223 OC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Transfering ownership for : %s ",
224 m_unownedDevice->getDeviceID().c_str());
226 OC::ResultCallBack ownershipTransferCb = std::bind(
227 &EnrolleeSecurity::ownershipTransferCb, this, std::placeholders::_1,
228 std::placeholders::_2);
230 if (m_unownedDevice->doOwnershipTransfer(ownershipTransferCb) != OC_STACK_OK)
232 OC_LOG(ERROR, ENROLEE_SECURITY_TAG, "OwnershipTransferCallback is failed");
233 ownershipStatus = DEVICE_NOT_OWNED;
235 throw ESPlatformException(result);
237 ownershipStatus = DEVICE_NOT_OWNED;
242 OC_LOG(ERROR, ENROLEE_SECURITY_TAG, "No unSecure devices found.");
243 ownershipStatus = DEVICE_NOT_OWNED;
245 return ownershipStatus;
248 return ownershipStatus;