+ OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "provisionPreconfPin is called.");
+ if(OC_STACK_OK != m_securedResource->provisionPreconfPin(
+ pin.c_str(), pin.length(), preconfigPinProvCB))
+ {
+ OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "provisionPreconfPin API error");
+ res = ESResult:: ES_PRE_CONFIG_PIN_PROVISIONING_FAILURE;
+ return res;
+ }
+
+ std::unique_lock<std::mutex> lck(m_mtx);
+ m_cond.wait(lck);
+
+ if(!preConfigPinProvResult)
+ {
+ OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "provisionPreconfPin is failed.");
+ res = ESResult:: ES_PRE_CONFIG_PIN_PROVISIONING_FAILURE;
+ return res;
+ }
+
+ return ESResult::ES_OK;
+ }
+
+ ESResult EnrolleeSecurity::requestSetMOTMethod(const ESOwnershipTransferData& MOTData)
+ {
+ OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "requestSetMOTMethod IN");
+
+ ESResult res = ESResult::ES_ERROR;
+
+ OC::ResultCallBack selectMOTMethodCB = std::bind(
+ &EnrolleeSecurity::onEnrolleeSecuritySafetyCB,
+ std::placeholders::_1, std::placeholders::_2,
+ static_cast<ESSecurityCb>(std::bind(&EnrolleeSecurity::selectMOTMethodCB,
+ this, std::placeholders::_1, std::placeholders::_2)),
+ shared_from_this());
+
+ OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "selectMOTMethod is called.");
+ if(OC_STACK_OK != m_securedResource->selectMOTMethod(
+ MOTData.getMOTMethod(),
+ selectMOTMethodCB))
+ {
+ OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "selectMOTMethod API error");
+ res = ESResult:: ES_MOT_METHOD_SELECTION_FAILURE;
+ return res;
+ }
+
+ std::unique_lock<std::mutex> lck(m_mtx);
+ m_cond.wait(lck);
+
+ if(!motMethodProvResult)
+ {
+ OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "selectMOTMethod is failed.");
+ res = ESResult:: ES_MOT_METHOD_SELECTION_FAILURE;
+ return res;
+ }
+
+ return ESResult::ES_OK;
+ }
+
+ ESResult EnrolleeSecurity::requestEnableMOTMode()
+ {
+ OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "requestEnableMOTMode IN");
+ ESResult res = ESResult:: ES_ERROR;
+
+ OC::ResultCallBack changeMOTMethodCB = std::bind(
+ &EnrolleeSecurity::onEnrolleeSecuritySafetyCB,
+ std::placeholders::_1, std::placeholders::_2,
+ static_cast<ESSecurityCb>(std::bind(&EnrolleeSecurity::changeMOTMethodCB,
+ this, std::placeholders::_1, std::placeholders::_2)),
+ shared_from_this());
+
+ if(OC_STACK_OK !=
+ m_securedResource->changeMOTMode(OIC_MULTIPLE_OWNER_ENABLE, changeMOTMethodCB))
+ {
+ OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "changeMOTMode is failed.");
+ return ESResult:: ES_MOT_ENABLING_FAILURE;
+ }
+
+ std::unique_lock<std::mutex> lck(m_mtx);
+ m_cond.wait(lck);
+
+ if(!enableMOTModeResult)
+ {
+ OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "requestEnableMOTMode is failed.");
+ res = ESResult:: ES_MOT_ENABLING_FAILURE;
+ return res;
+ }
+
+ return ESResult::ES_OK;
+ }
+
+ ESResult EnrolleeSecurity::provisionMOTConfig(const ESOwnershipTransferData& MOTData)
+ {
+ OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "provisionMOTConfig IN");
+ ESResult res = ESResult:: ES_ERROR;
+
+ if(!m_securedResource->isMOTEnabled())
+ {
+ res = requestEnableMOTMode();
+ if(res != ESResult::ES_OK)
+ {
+ OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "requestEnableMOTMode is failed.");
+ return res;
+ }
+ }
+
+ if( OIC_PRECONFIG_PIN == MOTData.getMOTMethod() &&
+ !MOTData.getPreConfiguredPin().empty())
+ {
+ res = requestSetPreconfPinData(MOTData);
+
+ if(res != ESResult::ES_OK)
+ {
+ OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "RequestSetPreconfPinData is failed.");
+ return res;
+ }
+ }
+ if(OIC_PRECONFIG_PIN == MOTData.getMOTMethod() ||
+ OIC_RANDOM_DEVICE_PIN == MOTData.getMOTMethod())
+ {
+ res = requestSetMOTMethod(MOTData);
+
+ if(res != ESResult::ES_OK)
+ {
+ OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "RequestSetMOTMethod is failed.");
+ return res;
+ }
+ }
+ return res;
+ }
+#endif
+
+ void EnrolleeSecurity::ownershipTransferCb(OC::PMResultList_t *result, int hasError
+ , ESResult& res)
+ {
+ OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "ownershipTransferCb IN");
+
+ otmResult = false;
+
+ if (hasError)
+ {
+ for (unsigned int i = 0; i < result->size(); i++)
+ {
+ std::string uuid;
+ convertUUIDToString(result->at(i).deviceId.id, uuid);
+
+ if(m_ocResource != NULL && m_ocResource->sid() == uuid)
+ {
+ if(OC_STACK_USER_DENIED_REQ == result->at(i).res)
+ {
+ res = ESResult::ES_USER_DENIED_CONFIRMATION_REQ;
+ }
+ else if(OC_STACK_AUTHENTICATION_FAILURE == result->at(i).res)
+ {
+ OicSecOxm_t oxm = OIC_OXM_COUNT;
+ if(OC_STACK_OK != m_securedResource->getOTMethod(&oxm))
+ {
+ otmResult = false;
+ return;
+ }
+
+ if(OIC_MANUFACTURER_CERTIFICATE == oxm)
+ {
+ res = ESResult::ES_AUTHENTICATION_FAILURE_WITH_WRONG_CERT;
+ }
+ else if(OIC_CON_MFG_CERT == oxm)
+ {
+ res = ESResult::ES_AUTHENTICATION_FAILURE_WITH_WRONG_CERT;
+ }
+ else if(OIC_RANDOM_DEVICE_PIN == oxm)
+ {
+ res = ESResult::ES_AUTHENTICATION_FAILURE_WITH_WRONG_PIN;
+ }
+ }
+ else if(OC_STACK_COMM_ERROR == result->at(i).res)
+ {
+ OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,
+ "OwnershipTransfer is failed with OC_STACK_COMM_ERROR");
+ res = ESResult::ES_COMMUNICATION_ERROR;
+ }
+ else if(OC_STACK_TIMEOUT == result->at(i).res)
+ {
+ OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,
+ "OwnershipTransfer is failed with OC_STACK_TIMEOUT");
+ res = ESResult::ES_COMMUNICATION_ERROR;
+ }
+ else if(OC_STACK_GATEWAY_TIMEOUT== result->at(i).res)
+ {
+ OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,
+ "OwnershipTransfer is failed with OC_STACK_GATEWAY_TIMEOUT");
+ res = ESResult::ES_COMMUNICATION_ERROR;
+ }
+ }
+ }
+ OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG, "OwnershipTransfer is failed with ESResult(%d)", res);
+
+ otmResult = false;
+ }
+ else
+ {
+ for (unsigned int i = 0; i < result->size(); i++)
+ {
+ std::string uuid;
+ convertUUIDToString(result->at(i).deviceId.id, uuid);
+
+ if(m_ocResource != NULL && m_ocResource->sid() == uuid)
+ {
+ if( OC_STACK_OK == result->at(i).res )
+ {
+ OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "OwnershipTransfer is succeeded");
+ OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Result is = %d", result->at(i).res);
+ OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "device uuid : %s", uuid.c_str());
+
+ otmResult = true;
+ }
+ else
+ {
+ OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG, "OwnershipTransfer is failed with code(%d)", hasError);
+ otmResult = false;
+ }
+ }
+ }
+ }
+
+ delete result;
+ m_cond.notify_all();
+ }
+
+ ESResult EnrolleeSecurity::discoverTargetSecureResource()
+ {
+ OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "discoverTargetSecureResource IN");
+
+ OCStackResult result = OC_STACK_ERROR;
+
+ OicUuid_t uuid;
+ if(OC_STACK_OK != ConvertStrToUuid(m_ocResource->sid().c_str(), &uuid))
+ {
+ OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Convert to uuid from deviceID failed.");
+ return ES_ERROR;
+ }
+
+ // If a discovered resource uses BLE transport, unicast for secure resource discovery is
+ // used.
+ if( m_ocResource->connectivityType() & CT_ADAPTER_GATT_BTLE )
+ {
+ std::string GattAddress = getResourceDeviceAddress(m_ocResource->host());
+ if(!GattAddress.empty())
+ {
+ result = OCSecure::discoverSingleDeviceInUnicast(ES_SEC_DISCOVERY_TIMEOUT,
+ &uuid,
+ GattAddress,
+ m_ocResource->connectivityType(),
+ m_securedResource);
+ if(result != OC_STACK_OK)
+ {
+ return ES_SECURE_RESOURCE_DISCOVERY_FAILURE;
+ }
+ }
+ else
+ {
+ OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "GATT BTLE address format is wrong.");
+ return ES_ERROR;
+ }
+ }
+ else
+ {
+ result = OCSecure::discoverSingleDevice(ES_SEC_DISCOVERY_TIMEOUT,
+ &uuid,
+ m_securedResource);
+ if(result != OC_STACK_OK)
+ {
+ return ES_SECURE_RESOURCE_DISCOVERY_FAILURE;
+ }
+ }
+
+ OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Secured resource is found.");
+ OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "HOST: %s", m_securedResource->getDevAddr().c_str());
+ OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "SID: %s", m_securedResource->getDeviceID().c_str());
+ OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Owned status: %d", m_securedResource->getOwnedStatus());
+
+ OicSecOxm_t selectedOTMethod = OIC_OXM_COUNT;
+ if( OC_STACK_OK != m_securedResource->getOTMethod(&selectedOTMethod) )
+ {
+ selectedOTMethod = OIC_OXM_COUNT; // Out-of-range
+ }
+ OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Selected OT Method: %d", (int)(selectedOTMethod));
+#ifdef MULTIPLE_OWNER
+ OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "MOT Supported: %d", (int)(m_securedResource->isMOTSupported()));
+ OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "MOT Enabled: %d", (int)(m_securedResource->isMOTEnabled()));
+#endif
+ if(m_securedResource->getOwnedStatus())
+ {
+ char uuidString[UUID_STRING_SIZE] = {};
+ if(RAND_UUID_OK == OCConvertUuidToString(m_securedResource->getDevPtr()->doxm->owner.id, uuidString))
+ {
+ OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "Owner ID: %s", uuidString);
+ }
+ else
+ {
+ OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "OCConvertUuidToString is failed");
+ }
+ }
+
+ return ES_OK;
+ }
+
+ ESOwnershipTransferData EnrolleeSecurity::getOwnershipTransferDataFromUser
+ (SecurityProvStatusCbWithOption callback)
+ {
+ OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "getOwnershipTransferDataFromUser IN");
+ ESOwnershipTransferData ownershipTransferData;
+
+ std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
+ std::make_shared< SecProvisioningStatus >
+ (m_securedResource,
+ ESResult::ES_SECURE_RESOURCE_IS_DISCOVERED);
+ ownershipTransferData = callback(securityProvisioningStatus);
+#ifdef MULTIPLE_OWNER
+ if(OIC_RANDOM_DEVICE_PIN == ownershipTransferData.getMOTMethod())
+ {
+ OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Selected MOT Method: OIC_RANDOM_DEVICE_PIN");
+ }
+ else if(OIC_PRECONFIG_PIN == ownershipTransferData.getMOTMethod())
+ {
+ OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Selected MOT Method: OIC_PRECONFIG_PIN");
+ OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "Pre-configured PIN: %s",
+ ownershipTransferData.getPreConfiguredPin().c_str());
+ }
+#endif
+ return ownershipTransferData;
+ }
+
+ ESResult EnrolleeSecurity::syncUpWithMediatorDB()
+ {
+ OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "syncUpWithMediatorDB IN");
+
+ OCStackResult result = OC_STACK_ERROR;
+ ESResult res = ESResult::ES_ERROR;
+
+ OC::ResultCallBack removeDeviceWithUuidCB = std::bind(
+ &EnrolleeSecurity::onEnrolleeSecuritySafetyCB,
+ std::placeholders::_1, std::placeholders::_2,
+ static_cast<ESSecurityCb>(std::bind(&EnrolleeSecurity::removeDeviceWithUuidCB,
+ this, std::placeholders::_1, std::placeholders::_2)),
+ shared_from_this());
+
+ result = OCSecure::removeDeviceWithUuid(ES_SEC_DISCOVERY_TIMEOUT,
+ m_ocResource->sid(),
+ removeDeviceWithUuidCB);
+ if(result != OC_STACK_OK)
+ {
+ OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG, "removeDeviceWithUuid failed. (%d)", result);
+ res = ESResult::ES_OWNERSHIP_IS_NOT_SYNCHRONIZED;
+ return res;
+ }
+
+ std::unique_lock<std::mutex> lck(m_mtx);
+ m_cond.wait_for(lck, std::chrono::seconds(ES_SEC_DISCOVERY_TIMEOUT));
+
+ if(!removeDeviceResult)
+ {
+ OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "Removing device is failed.");
+ res = ESResult::ES_OWNERSHIP_IS_NOT_SYNCHRONIZED;
+ return res;
+ }
+ return ESResult::ES_OK;
+ }
+
+ std::string EnrolleeSecurity::getMediatorDevID()
+ {
+ OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "getMediatorDevID IN");
+ OCUUIdentity* mediatorDevId = (OCUUIdentity* )OICMalloc(sizeof(OCUUIdentity));
+ if(!mediatorDevId)
+ {
+ OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "provisionOwnership: OICMalloc error return");
+ return {};
+ }
+
+ if(OC::OCPlatform::getDeviceId(mediatorDevId) != OC_STACK_OK)
+ {
+ OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "getDeviceId is failed.");
+ OICFree(mediatorDevId);
+ return {};
+ }
+
+ char uuidString[UUID_STRING_SIZE] = {};
+ if(RAND_UUID_OK == OCConvertUuidToString(mediatorDevId->id, uuidString))