From 1e16e1da801bd8b623624eca65f8eadd13227f6b Mon Sep 17 00:00:00 2001 From: Jihun Ha Date: Fri, 9 Dec 2016 15:08:54 +0900 Subject: [PATCH] Add an additional callback in security provisioning of easy setup after secure resource is discovered. Right after a target secure resource is discovered, Mediator may need to confirm which ownership tranfer method is used or set a pre-configured pin number for MOT use case. For that, it adds an additional ESResult, ES_SECURE_RESOURCE_IS_DISCOVERED, which indicates the event. And if some user inputs are needed, user can pass its inputs as a form of ESOwnershipTransferData object which can store an ownership transfer method to be used and pre-configured pin to be used for a MOT case. Note that, related APIs for MOT was merged : https://gerrit.iotivity.org/gerrit/#/c/14221/ Change-Id: Ic17f50693a6c4073eb5208da861506230f817f0e Signed-off-by: Jihun Ha Reviewed-on: https://gerrit.iotivity.org/gerrit/15161 Tested-by: jenkins-iotivity Reviewed-by: Uze Choi (cherry picked from commit 80884027f52113cdeb2673877d2a3d338630e371) Reviewed-on: https://gerrit.iotivity.org/gerrit/15467 --- service/easy-setup/inc/escommon.h | 15 + .../easy-setup/mediator/richsdk/inc/ESRichCommon.h | 123 +++++- .../mediator/richsdk/inc/RemoteEnrollee.h | 18 +- .../mediator/richsdk/src/EnrolleeSecurity.cpp | 260 ++++++++++-- .../mediator/richsdk/src/EnrolleeSecurity.h | 12 +- .../mediator/richsdk/src/RemoteEnrollee.cpp | 62 ++- .../sampleapp/enrollee/linux/oic_svr_db_server.dat | Bin 997 -> 2167 bytes .../mediator/linux/richsdk_sample/SConscript | 10 +- .../{mediator_cpp.cpp => mediator.cpp} | 35 +- .../linux/richsdk_sample/oic_svr_db_subclient.dat | Bin 0 -> 1027 bytes .../mediator/linux/richsdk_sample/submediator.cpp | 463 +++++++++++++++++++++ 11 files changed, 951 insertions(+), 47 deletions(-) rename service/easy-setup/sampleapp/mediator/linux/richsdk_sample/{mediator_cpp.cpp => mediator.cpp} (90%) create mode 100644 service/easy-setup/sampleapp/mediator/linux/richsdk_sample/oic_svr_db_subclient.dat create mode 100755 service/easy-setup/sampleapp/mediator/linux/richsdk_sample/submediator.cpp diff --git a/service/easy-setup/inc/escommon.h b/service/easy-setup/inc/escommon.h index c350109..51928b9 100755 --- a/service/easy-setup/inc/escommon.h +++ b/service/easy-setup/inc/escommon.h @@ -136,6 +136,11 @@ typedef enum ES_OK = 0, /** + * Secure resource is discovered. + */ + ES_SECURE_RESOURCE_IS_DISCOVERED = 1, + + /** * Enrollee discovery fails in cloud provisioning */ ES_ENROLLEE_DISCOVERY_FAILURE = 11, @@ -176,6 +181,16 @@ typedef enum ES_CERT_PROVISIONING_FAILURE, /** + * MOT method selection is failed + */ + ES_MOT_METHOD_SELECTION_FAILURE, + + /** + * A provisioning of Pre-configured pin number for MOT is failed + */ + ES_PRE_CONFIG_PIN_PROVISIONING_FAILURE, + + /** * Provisioning fails for some reason. */ ES_ERROR = 255 diff --git a/service/easy-setup/mediator/richsdk/inc/ESRichCommon.h b/service/easy-setup/mediator/richsdk/inc/ESRichCommon.h index 41fc10c..0dac2fb 100755 --- a/service/easy-setup/mediator/richsdk/inc/ESRichCommon.h +++ b/service/easy-setup/mediator/richsdk/inc/ESRichCommon.h @@ -31,6 +31,10 @@ #include "OCPlatform.h" #include "ocstack.h" #include "octypes.h" +#ifdef __WITH_DTLS__ +#include "securevirtualresourcetypes.h" +#include "OCProvisioningManager.hpp" +#endif #include "escommon.h" @@ -454,13 +458,48 @@ namespace OIC SecProvisioningStatus(string deviceUUID, ESResult result) : m_devUUID(deviceUUID), m_result(result) { +#ifdef __WITH_DTLS__ + m_selectedOTMethod = OIC_JUST_WORKS; + m_isMOTEnabled = false; + m_isOwned = false; +#endif + } +#ifdef __WITH_DTLS__ + SecProvisioningStatus(std::shared_ptr resource, ESResult result) : + m_result(result) + { + m_isMOTEnabled = false; + if(resource.get() != nullptr) + { + m_devUUID = resource->getDeviceID(); + m_isOwned = resource->getOwnedStatus(); + + // TODO + // When severAPIs in OCSecureResource for getting a list of supported methods or + // status of MOT support, a code for setting this information will be implemeted. + m_selectedOTMethod = OIC_JUST_WORKS; + } + } + + OicSecOxm_t getSelectedOTMethod() const + { + return m_selectedOTMethod; } - const string getDeviceUUID() + bool isMOTEnabled() const { - return m_devUUID; + return m_isMOTEnabled; } + bool isOwnedDevice() const + { + return m_isOwned; + } +#endif + const std::string getDeviceUUID() + { + return m_devUUID; + } /** * Get a result for about security provisioning is success or not. * @@ -477,6 +516,11 @@ namespace OIC private: string m_devUUID; ESResult m_result; +#ifdef __WITH_DTLS__ + OicSecOxm_t m_selectedOTMethod; + bool m_isMOTEnabled; + bool m_isOwned; +#endif }; /** @@ -854,6 +898,73 @@ namespace OIC ESResult m_result; }; + class ESOwnershipTransferData + { + public: +#ifdef __WITH_DTLS__ + ESOwnershipTransferData() : + m_MOTMethod(OIC_JUST_WORKS), m_preconfiguredPin("") + { + } + + ESOwnershipTransferData(const ESOwnershipTransferData& data) : + m_MOTMethod(data.getMOTMethod()), + m_preconfiguredPin(data.getPreConfiguredPin()) + { + } + + ESResult setMOTMethod(OicSecOxm_t method) + { +#ifdef MULTIPLE_OWNER + if(OIC_RANDOM_DEVICE_PIN != method) + { + return ES_ERROR; + } + + m_MOTMethod = method; + return ES_OK; +#else + (void) method; + + return ES_ERROR; +#endif + } + + ESResult setMOTMethod(OicSecOxm_t method, const std::string& pin) + { +#ifdef MULTIPLE_OWNER + if(OIC_PRECONFIG_PIN != method || pin.empty()) + { + return ES_ERROR; + } + + m_preconfiguredPin = pin; + m_MOTMethod = method; + return ES_OK; +#else + (void) method; + (void) pin; + + return ES_ERROR; +#endif + } + + OicSecOxm_t getMOTMethod() const + { + return m_MOTMethod; + } + + std::string getPreConfiguredPin() const + { + return m_preconfiguredPin; + } + + private: + OicSecOxm_t m_MOTMethod; + std::string m_preconfiguredPin; +#endif + }; + /** * Callback function definition for providing Enrollee status */ @@ -880,6 +991,14 @@ namespace OIC typedef function< void(shared_ptr) > SecurityProvStatusCb; /** + * Callback function definition for providing Enrollee security provisioning status. + * This callback is an overloaded version of SecurityProvStatusCb, which has + * ESOwnershipTransferData as a return value. + */ + typedef function< ESOwnershipTransferData(shared_ptr) > + SecurityProvStatusCbWithOption; + + /** * Callback definition to be invoked when the security stack expects a pin from application */ typedef function< void(string&) > SecurityPinCb; diff --git a/service/easy-setup/mediator/richsdk/inc/RemoteEnrollee.h b/service/easy-setup/mediator/richsdk/inc/RemoteEnrollee.h index 30ef55c..5f1008f 100755 --- a/service/easy-setup/mediator/richsdk/inc/RemoteEnrollee.h +++ b/service/easy-setup/mediator/richsdk/inc/RemoteEnrollee.h @@ -76,7 +76,7 @@ namespace OIC */ void getConfiguration(const GetConfigurationStatusCb callback); - /** + /** * Do security provisioning such as ownership tranfer to Enrollee. * * @param callback will give the result if the security provisioning succeeds or fails for some reasons @@ -88,6 +88,19 @@ namespace OIC void provisionSecurity(const SecurityProvStatusCb callback); /** + * Do security provisioning such as ownership tranfer to Enrollee which may require more + * specific user selections like a type of ownership transfer method or pre-configured + * pin number used to Pre-configured pin-based MOT. + * + * @param callback will give the result if the security provisioning succeeds or fails for some reasons. + * + * @throws ESBadRequestException If RemoteEnrollee device not created prior to this call. + * + * @see SecurityProvStatusCb + */ + void provisionSecurity(const SecurityProvStatusCbWithOption callback); + + /** * Provision WiFi AP information and device configuration to Enrollee * 1. WiFi AP information includes a SSID, password, auth type, and encryption type. * 2. Device configuration includes a language (IETF language tags) and country (ISO 3166-1 Alpha-2) @@ -143,6 +156,8 @@ namespace OIC (const std::shared_ptr< CloudPropProvisioningStatus > status) const; void securityStatusHandler (const std::shared_ptr< SecProvisioningStatus > status) const; + ESOwnershipTransferData securityStatusWithOptionHandler + (const std::shared_ptr< SecProvisioningStatus > status) const; private: std::shared_ptr< OC::OCResource > m_ocResource; @@ -157,6 +172,7 @@ namespace OIC std::condition_variable m_cond; SecurityProvStatusCb m_securityProvStatusCb; + SecurityProvStatusCbWithOption m_securityProvStatusCbWithOption; GetStatusCb m_getStatusCb; GetConfigurationStatusCb m_getConfigurationStatusCb; SecurityPinCb m_securityPinCb; diff --git a/service/easy-setup/mediator/richsdk/src/EnrolleeSecurity.cpp b/service/easy-setup/mediator/richsdk/src/EnrolleeSecurity.cpp index da70c09..fac771a 100755 --- a/service/easy-setup/mediator/richsdk/src/EnrolleeSecurity.cpp +++ b/service/easy-setup/mediator/richsdk/src/EnrolleeSecurity.cpp @@ -65,6 +65,7 @@ namespace OIC { (void) secDbPath; m_ocResource = resource; + m_ownershipTransferData = {}; } void EnrolleeSecurity::convertUUIDToString(const uint8_t uuid[UUID_SIZE], @@ -150,6 +151,69 @@ namespace OIC } } +#ifdef MULTIPLE_OWNER + void EnrolleeSecurity::SelectMOTMethodCB(PMResultList_t *result, int hasError) + { + OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "SelectMOTMethodCB IN"); + if (hasError) + { + OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG, + "selectMOTMethod API is failed with error %d", hasError); + MOTMethodProvResult = false; + } + else + { + OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "selectMOTMethod API is succeeded"); + MOTMethodProvResult = true; + } + + delete result; + m_cond.notify_all(); + } + + void EnrolleeSecurity::PreconfigPinProvCB(PMResultList_t *result, int hasError) + { + OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "PreconfigPinProvCB IN"); + if (hasError) + { + OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG, + "provisionPreconfPin API is failed with error %d", hasError); + PreConfigPinProvResult = false; + } + else + { + OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "provisionPreconfPin API is succeeded"); + PreConfigPinProvResult = true; + } + + delete result; + m_cond.notify_all(); + } + + void EnrolleeSecurity::MultipleOwnershipTransferCb(OC::PMResultList_t *result, int hasError) + { + OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "MultipleOwnershipTransferCb IN"); + if (hasError) + { + OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG, "MultipleOwnershipTransferCb is failed with code(%d)", hasError); + OTMResult = false; + m_cond.notify_all(); + } + else + { + OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "MultipleOwnershipTransfer is succeeded"); + for (unsigned int i = 0; i < result->size(); i++) + { + OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Result is = %d for device", result->at(i).res); + } + + delete result; + OTMResult = true; + m_cond.notify_all(); + } + } +#endif + void EnrolleeSecurity::ownershipTransferCb(OC::PMResultList_t *result, int hasError) { OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "ownershipTransferCb IN"); @@ -165,13 +229,14 @@ namespace OIC { OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Result is = %d for device", result->at(i).res); } - delete result; OTMResult = true; } + + delete result; m_cond.notify_all(); } - ESResult EnrolleeSecurity::provisionOwnership() + ESResult EnrolleeSecurity::provisionOwnership(SecurityProvStatusCbWithOption callback) { OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "provisionOwnership IN"); @@ -225,19 +290,33 @@ namespace OIC OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "SID: %s", m_securedResource->getDeviceID().c_str()); OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Owned status: %d", m_securedResource->getOwnedStatus()); - if (m_securedResource->getOwnedStatus()) // owned check logic + if(callback != NULL) { - if(isOwnedDeviceRegisteredInSVRDB()) + std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus = + std::make_shared< SecProvisioningStatus > + (m_securedResource, + ESResult::ES_SECURE_RESOURCE_IS_DISCOVERED); + m_ownershipTransferData = callback(securityProvisioningStatus); + + if(OIC_RANDOM_DEVICE_PIN == m_ownershipTransferData.getMOTMethod()) { - OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, - "The found device is already owned by Mediator.(SUCCESS)"); - res = ESResult::ES_OK; + OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Selected MOT Method: OIC_RANDOM_DEVICE_PIN"); } - else +#ifdef MULTIPLE_OWNER + else if(OIC_PRECONFIG_PIN == m_ownershipTransferData.getMOTMethod()) { - OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "The found device is not one in SVR DB"); - res = ESResult::ES_ERROR; + OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Selected MOT Method: OIC_PRECONFIG_PIN"); + OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Pre-configured PIN: %s", + m_ownershipTransferData.getPreConfiguredPin().c_str()); } +#endif + } + + if(m_securedResource->getOwnedStatus() && isOwnedDeviceRegisteredInSVRDB()) // owned check logic + { + OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, + "The found device is already owned by Mediator.(SUCCESS)"); + res = ESResult::ES_OK; return res; } else // unowned check logic @@ -273,23 +352,115 @@ namespace OIC OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "Removing device is succeeded."); } - res = performOwnershipTransfer(); - - if(res != ESResult::ES_OK) + if(!m_securedResource->getOwnedStatus()) { - OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG, "Ownership-Transfer failed. (%d)", res); - res = ESResult::ES_OWNERSHIP_TRANSFER_FAILURE; - return res; + res = performOwnershipTransfer(); + + if(res != ESResult::ES_OK) + { + OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG, "Ownership-Transfer failed. (%d)", res); + res = ESResult::ES_OWNERSHIP_TRANSFER_FAILURE; + return res; + } + + std::unique_lock lck(m_mtx); + m_cond.wait(lck); + + if(!OTMResult) + { + OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "Ownership-Transfer failed."); + res = ESResult::ES_OWNERSHIP_TRANSFER_FAILURE; + return res; + } +#ifdef MULTIPLE_OWNER + if( // m_securedResource->isMOTSupported() && //not provided, yet + OIC_PRECONFIG_PIN == m_ownershipTransferData.getMOTMethod() && + !m_ownershipTransferData.getPreConfiguredPin().empty()) + { + OC::ResultCallBack preconfigPinProvCB = std::bind( + &EnrolleeSecurity::PreconfigPinProvCB, this, std::placeholders::_1, + std::placeholders::_2); + + std::string pin = m_ownershipTransferData.getPreConfiguredPin(); + + 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; + } + + 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; + } + } + + if(// m_securedResource->isMOTSupported() && //not provided, yet + OIC_PRECONFIG_PIN == m_ownershipTransferData.getMOTMethod() || + OIC_RANDOM_DEVICE_PIN == m_ownershipTransferData.getMOTMethod()) + { + + OC::ResultCallBack selectMOTMethodCB = std::bind( + &EnrolleeSecurity::SelectMOTMethodCB, this, std::placeholders::_1, + std::placeholders::_2); + + OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "selectMOTMethod is called."); + if(OC_STACK_OK != m_securedResource->selectMOTMethod( + m_ownershipTransferData.getMOTMethod(), + selectMOTMethodCB)) + { + OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "selectMOTMethod API error"); + res = ESResult:: ES_MOT_METHOD_SELECTION_FAILURE; + return res; + } + + m_cond.wait(lck); + + if(!MOTMethodProvResult) + { + OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "selectMOTMethod is failed."); + res = ESResult:: ES_MOT_METHOD_SELECTION_FAILURE; + return res; + } + } +#endif } +#ifdef MULTIPLE_OWNER + else + { + res = performMultipleOwnershipTransfer(); - std::unique_lock lck(m_mtx); - m_cond.wait(lck); + if(res != ESResult::ES_OK) + { + OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG, "Multiple Ownership-Transfer failed. (%d)", res); + res = ESResult::ES_OWNERSHIP_TRANSFER_FAILURE; + return res; + } + + std::unique_lock lck(m_mtx); + m_cond.wait(lck); - if(!OTMResult) + if(!OTMResult) + { + OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "Multiple Ownership-Transfer failed."); + res = ESResult::ES_OWNERSHIP_TRANSFER_FAILURE; + return res; + } + } +#else + else { - OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "Ownership-Transfer failed."); - res = ESResult::ES_OWNERSHIP_TRANSFER_FAILURE; + OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "The found device is already owned by other PT"); + res = ESResult::ES_ERROR; } +#endif } } else @@ -309,14 +480,11 @@ namespace OIC OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Transfering ownership for : %s ", m_securedResource->getDeviceID().c_str()); - //In case of random pin, argument should be inputPinCallback func. - // for justwork, not required(NULL) - OCSecure::setInputPinCallback(NULL); - OC::ResultCallBack ownershipTransferCb = std::bind( &EnrolleeSecurity::ownershipTransferCb, this, std::placeholders::_1, std::placeholders::_2); + OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "doOwnershipTransfer is excuted"); result = m_securedResource->doOwnershipTransfer(ownershipTransferCb); if (result != OC_STACK_OK) { @@ -326,6 +494,48 @@ namespace OIC return ESResult::ES_OK; } +#ifdef MULTIPLE_OWNER + ESResult EnrolleeSecurity::performMultipleOwnershipTransfer() + { + OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "performMultipleOwnershipTransfer IN."); + + OCStackResult result = OC_STACK_ERROR; + + OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Transfering sub-ownership for : %s ", + m_securedResource->getDeviceID().c_str()); + + if( // m_securedResource->isMOTSupported() && //not provided, yet + OIC_PRECONFIG_PIN == m_ownershipTransferData.getMOTMethod() && + !m_ownershipTransferData.getPreConfiguredPin().empty()) + { + std::string pin = m_ownershipTransferData.getPreConfiguredPin(); + + result = m_securedResource->addPreconfigPIN(pin.c_str(), pin.length()); + if(OC_STACK_OK != result) + { + OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "addPreconfigPIN is failed"); + return ESResult::ES_ERROR; + } + + OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Preconfig PIN : %s", pin.c_str()); + } + + OC::ResultCallBack multipleOwnershipTransferCb = std::bind( + &EnrolleeSecurity::MultipleOwnershipTransferCb, this, std::placeholders::_1, + std::placeholders::_2); + + OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "doMultipleOwnershipTransfer is excuted"); + + result = m_securedResource->doMultipleOwnershipTransfer(multipleOwnershipTransferCb); + if(OC_STACK_OK != result) + { + OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "doMultipleOwnershipTransfer is failed"); + return ESResult::ES_ERROR; + } + return ESResult::ES_OK; + } +#endif + void EnrolleeSecurity::removeDeviceWithUuidCB(OC::PMResultList_t *result, int hasError) { OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "removeDeviceWithUuidCB IN"); diff --git a/service/easy-setup/mediator/richsdk/src/EnrolleeSecurity.h b/service/easy-setup/mediator/richsdk/src/EnrolleeSecurity.h index 0c4f8c3..76d0c8e 100755 --- a/service/easy-setup/mediator/richsdk/src/EnrolleeSecurity.h +++ b/service/easy-setup/mediator/richsdk/src/EnrolleeSecurity.h @@ -52,7 +52,7 @@ namespace OIC public: EnrolleeSecurity(std::shared_ptr< OC::OCResource > resource, const std::string secDbPath); - ESResult provisionOwnership(); + ESResult provisionOwnership(SecurityProvStatusCbWithOption callback); std::string getUUID() const; private: @@ -64,15 +64,25 @@ namespace OIC std::mutex m_mtx; std::condition_variable m_cond; std::atomic OTMResult; + std::atomic MOTMethodProvResult; + std::atomic PreConfigPinProvResult; std::atomic removeDeviceResult; std::atomic aclResult; std::atomic certResult; std::shared_ptr< OC::OCSecureResource > m_securedResource; + ESOwnershipTransferData m_ownershipTransferData; + ESResult performOwnershipTransfer(); bool isOwnedDeviceRegisteredInSVRDB(); void removeDeviceWithUuidCB(OC::PMResultList_t *result, int hasError); +#ifdef MULTIPLE_OWNER + ESResult performMultipleOwnershipTransfer(); + void SelectMOTMethodCB(PMResultList_t *result, int hasError); + void PreconfigPinProvCB(PMResultList_t *result, int hasError); + void MultipleOwnershipTransferCb(OC::PMResultList_t *result, int hasError); +#endif void ownershipTransferCb(OC::PMResultList_t *result, int hasError); void convertUUIDToString(const uint8_t uuid[UUID_SIZE], std::string& uuidString); diff --git a/service/easy-setup/mediator/richsdk/src/RemoteEnrollee.cpp b/service/easy-setup/mediator/richsdk/src/RemoteEnrollee.cpp index 15dbf43..c78ed96 100755 --- a/service/easy-setup/mediator/richsdk/src/RemoteEnrollee.cpp +++ b/service/easy-setup/mediator/richsdk/src/RemoteEnrollee.cpp @@ -73,6 +73,17 @@ namespace OIC OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "securityStatusHandlr OUT"); } + ESOwnershipTransferData RemoteEnrollee::securityStatusWithOptionHandler( + const std::shared_ptr< SecProvisioningStatus > status) const + { + OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "securityStatusWithOptionHandler IN"); + OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "UUID = %s, ESResult = %d", + status->getDeviceUUID().c_str(), status->getESResult()); + + OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "securityStatusWithOptionHandler OUT"); + return m_securityProvStatusCbWithOption(status); + } + void RemoteEnrollee::getStatusHandler( const std::shared_ptr< GetEnrolleeStatus > status) const { @@ -238,7 +249,7 @@ namespace OIC m_enrolleeSecurity = std::make_shared (m_ocResource, ""); } - res = m_enrolleeSecurity->provisionOwnership(); + res = m_enrolleeSecurity->provisionOwnership(NULL); std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus = std::make_shared< SecProvisioningStatus >(m_enrolleeSecurity->getUUID(), res); @@ -259,6 +270,48 @@ namespace OIC OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity OUT"); } + void RemoteEnrollee::provisionSecurity(const SecurityProvStatusCbWithOption callback) + { + OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity IN"); +#ifdef __WITH_DTLS__ + ESResult res = ESResult::ES_ERROR; + if(!callback) + { + throw ESInvalidParameterException("Callback is empty"); + } + m_securityProvStatusCbWithOption = callback; + + SecurityProvStatusCbWithOption securityProvStatusCbWithOption = std::bind( + &RemoteEnrollee::securityStatusWithOptionHandler, + this, + std::placeholders::_1); + + if(!m_enrolleeSecurity.get()) + { + m_enrolleeSecurity = std::make_shared (m_ocResource, ""); + } + + res = m_enrolleeSecurity->provisionOwnership(securityProvStatusCbWithOption); + + std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus = + std::make_shared< SecProvisioningStatus >(m_enrolleeSecurity->getUUID(), res); + securityProvStatusCbWithOption(securityProvisioningStatus); + m_enrolleeSecurity.reset(); +#else + OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG,"Mediator is unsecured built."); + + if(!callback) + { + throw ESInvalidParameterException("Callback is empty"); + } + std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus = + std::make_shared< SecProvisioningStatus > + ("", ESResult::ES_SEC_OPERATION_IS_NOT_SUPPORTED); + callback(securityProvisioningStatus); +#endif + OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity OUT"); + } + void RemoteEnrollee::getStatus(const GetStatusCb callback) { OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getStatus IN"); @@ -381,13 +434,6 @@ namespace OIC m_cloudPropProvStatusCb = callback; - if(cloudProp.getAuthCode().empty() || - cloudProp.getAuthProvider().empty() || - cloudProp.getCiServer().empty()) - { - throw ESBadRequestException ("Invalid Cloud Provisiong Info."); - } - try { initCloudResource(); diff --git a/service/easy-setup/sampleapp/enrollee/linux/oic_svr_db_server.dat b/service/easy-setup/sampleapp/enrollee/linux/oic_svr_db_server.dat index 82b4e405784448301d84ff7e1297ab39ee68ff01..ae81a11f75fe30127833e9a6df0434b79e348f9d 100644 GIT binary patch delta 371 zcmaFL{#`(5e@aSzMQ+61{UEBii9z!JWF}@MP16+fBy)4K6x|dfb93Ef!z5!}3&SJ> zU1JNgRI@}20~3oBgXG-&T*k>B%np;onN=nqU{(=JPE5{;WLmN$4M=Aemn=+4OinFs z-YEW*(PD9SacNRkYH~?wX=X~IR%TIZaeiqLP`YtRN=8v?T9JNYGLTnXke``XQmkKA ztZ$H1RMMC*IgwFv@&`t4W~Qv7$v({blXaQ=fc6=J?F?j8QA!7zlv+}d7Rh3^e*o+k Q#2S7e*Ri69k1FGT0My-t;{X5v delta 303 zcmew^@RVJAe{y1SP9&52k~AQlSzNL(B{4a*xM}hOCdthOEN2)Evx@S|^HPgSOEXg{ zRLm01P0fwXO?1u8&C+zujm(mCO-#&8bdDNUZhtP?_vVp2_? zEWo15my(iSksI-HKZq)BoG7G3l)EOzI#>|nq@oJF{GxQd%>0tfvdof7y_ACFuag5g FQ~@f+SE&F1 diff --git a/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/SConscript b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/SConscript index 2f422a2..ccbc795 100644 --- a/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/SConscript +++ b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/SConscript @@ -66,13 +66,17 @@ mediator_env.PrependUnique(LIBS = ['ESMediatorRich', 'oc', 'octbstack', 'oc_logg if env.get('SECURED') == '1': mediator_env.PrependUnique(LIBS = ['ocpmapi', 'ocprovision']) -mediator = mediator_env.Program('mediator_rich', 'mediator_cpp.cpp') +mediator = mediator_env.Program('mediator', 'mediator.cpp') +submediator = mediator_env.Program('submediator', 'submediator.cpp') -i_mediator = mediator_env.Install(env.get('BUILD_DIR'), mediator) +i_mediator = mediator_env.Install(env.get('BUILD_DIR'), [mediator, submediator]) clientdat = mediator_env.Install(env.get('BUILD_DIR') + '/service/easy-setup/sampleapp/mediator/linux/richsdk_sample', env.get('SRC_DIR') + '/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/oic_svr_db_client.dat') +subclientdat = mediator_env.Install(env.get('BUILD_DIR') + '/service/easy-setup/sampleapp/mediator/linux/richsdk_sample', + env.get('SRC_DIR') + '/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/oic_svr_db_subclient.dat') -Alias('mediator_rich', [i_mediator, clientdat]) + +Alias('mediator_rich', [i_mediator, clientdat, subclientdat]) env.AppendTarget('mediator_rich') diff --git a/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator_cpp.cpp b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator.cpp similarity index 90% rename from service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator_cpp.cpp rename to service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator.cpp index 9452a3e..1c7cc1b 100755 --- a/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator_cpp.cpp +++ b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator.cpp @@ -24,6 +24,7 @@ #include "OCPlatform.h" #include "OCApi.h" #include "OCProvisioningManager.hpp" +#include "securevirtualresourcetypes.h" #include "EasySetup.h" #include "ESRichCommon.h" @@ -88,18 +89,38 @@ void printStatus(EnrolleeStatus status) cout << "===========================================" << endl; } -void provisionSecurityStatusCallback(std::shared_ptr secProvisioningStatus) +ESOwnershipTransferData provisionSecurityStatusCallback(std::shared_ptr secProvisioningStatus) { - if(secProvisioningStatus->getESResult() != ES_OK) + cout << "provisionSecurityStatusCallback IN" << endl; + cout << "ESResult : " << secProvisioningStatus->getESResult() << std::endl; + cout << "Device ID : " << secProvisioningStatus->getDeviceUUID() << std::endl; + + if(secProvisioningStatus->getESResult() == ES_SECURE_RESOURCE_IS_DISCOVERED) { - cout << "provisionSecurity is failed." << endl; - return; +#if defined(__WITH_DTLS__) && defined(MULTIPLE_OWNER) + cout << "Owned Status : " << secProvisioningStatus->isOwnedDevice() << std::endl; + cout << "OT Method : " << secProvisioningStatus->getSelectedOTMethod() << std::endl; + + // TEST + ESOwnershipTransferData OTData; + OTData.setMOTMethod(OIC_PRECONFIG_PIN, "12345678"); + + cout << "Enter!" << std::endl; + getchar(); + + return OTData; +#endif + } + else if(secProvisioningStatus->getESResult() == ES_OK) + { + cout << "provisionSecurity is success." << std::endl; } else { - cout << "provisionSecurity is success." << endl; - cout << "uuid : " << secProvisioningStatus->getDeviceUUID()<< endl; + cout << "provisionSecurity is failed." << endl; } + + return {}; } void provisionSecurity() @@ -112,7 +133,7 @@ void provisionSecurity() try { - remoteEnrollee->provisionSecurity(provisionSecurityStatusCallback); + remoteEnrollee->provisionSecurity((SecurityProvStatusCbWithOption)provisionSecurityStatusCallback); } catch (OCException &e) { diff --git a/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/oic_svr_db_subclient.dat b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/oic_svr_db_subclient.dat new file mode 100644 index 0000000000000000000000000000000000000000..ae130bcc4f4e06a3f292ad681485c04c27970329 GIT binary patch literal 1027 zcmbVLL2kk@5TxZRJyl9TggEL?=&gypE)I^J+DV~D=sS9-%B8R16@3b4>UB^QQAHFE z)_Uz7@62YhqbZe-w{KhSqOjE`ODWj*uZ69%9B5V7f~EJufYr6Zn=P9g;Pa6dbmUGm zQ>}Bi50{G&Q^D5)Q^7+isR8-a0JsM*ET13CnJeDtV{w*RkV1jKbYSxbTXwPKd2C*S zDTK8`tJ_{Vn}%KC*;$|?rdLI)$%H<2noenU*r^s<+A6IOyg*SVZ1O(zCHy))s8+n& z!{>cH8g(x%Lsq832=$B)sD@;F)b~c0XKwUTfk9KO?&2tk$z;ldBq0!xIGF^~h|qvM zkeEO+jmFU!8+kvN(D@79aXLxxQ<{BzGhubP&uB5oDz|ho%xp2t8N3P#|L=Ge#d9Bw op$}$1I}CO`;21y-sHN2n;7Hj1VxrP1yKtIUY4d+)zmpG#Uv+VHF#rGn literal 0 HcmV?d00001 diff --git a/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/submediator.cpp b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/submediator.cpp new file mode 100755 index 0000000..7e98942 --- /dev/null +++ b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/submediator.cpp @@ -0,0 +1,463 @@ +//****************************************************************** +// +// Copyright 2015 Samsung Electronics All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#include +#include + +#include "OCPlatform.h" +#include "OCApi.h" +#include "OCProvisioningManager.hpp" +#include "securevirtualresourcetypes.h" + +#include "EasySetup.h" +#include "ESRichCommon.h" + +#define ES_SAMPLE_APP_TAG "ES_SAMPLE_APP_TAG" +#define DECLARE_MENU(FUNC, ...) { #FUNC, FUNC } + +#define JSON_DB_PATH "./oic_svr_db_subclient.dat" + +using namespace OC; +using namespace OIC::Service; + +static std::shared_ptr remoteEnrollee = nullptr; +static std::shared_ptr curResource = nullptr; + +static std::mutex g_discoverymtx; +static std::condition_variable g_cond; + +typedef void (*Runner)(); + +Runner g_currentRun; + +int processUserInput(int min = std::numeric_limits::min(), + int max = std::numeric_limits::max()) +{ + assert(min <= max); + + int input; + + std::cin >> input; + std::cin.ignore(std::numeric_limits::max(), '\n'); + + if (!std::cin.fail() && min <= input && input <= max) return input; + + std::cin.clear(); + std::cin.ignore(std::numeric_limits::max(), '\n'); + + throw std::runtime_error("Invalid Input, please try again"); +} + +void printConfiguration(EnrolleeConf conf) +{ + cout << "===========================================" << endl; + cout << "\tDevice Name : " << conf.getDeviceName() << endl; + cout << "\tModel Number : " << conf.getModelNumber() << endl; + + for(auto it : conf.getWiFiModes()) + { + cout << "\tSupported WiFi modes : " << it << endl; + } + + cout << "\tSupported WiFi freq : " << static_cast(conf.getWiFiFreq()) << endl; + cout << "\tCloud accessibility: " << conf.isCloudAccessible() << endl; + cout << "===========================================" << endl; +} + +void printStatus(EnrolleeStatus status) +{ + cout << "===========================================" << endl; + cout << "\tProvStatus : " << status.getProvStatus() << endl; + cout << "\tLastErrCode : " << status.getLastErrCode() << endl; + cout << "===========================================" << endl; +} + +ESOwnershipTransferData provisionSecurityStatusCallback(std::shared_ptr secProvisioningStatus) +{ + cout << "provisionSecurityStatusCallback IN" << endl; + cout << "ESResult : " << secProvisioningStatus->getESResult() << std::endl; + cout << "Device ID : " << secProvisioningStatus->getDeviceUUID() << std::endl; + + if(secProvisioningStatus->getESResult() == ES_SECURE_RESOURCE_IS_DISCOVERED) + { +#if defined(__WITH_DTLS__) && defined(MULTIPLE_OWNER) + cout << "Owned Status : " << secProvisioningStatus->isOwnedDevice() << std::endl; + cout << "OT Method : " << secProvisioningStatus->getSelectedOTMethod() << std::endl; + + // TEST + ESOwnershipTransferData OTData; + OTData.setMOTMethod(OIC_PRECONFIG_PIN, "12345678"); + + cout << "Enter!" << std::endl; + getchar(); + + return OTData; +#endif + } + else if(secProvisioningStatus->getESResult() == ES_OK) + { + cout << "provisionSecurity is success." << std::endl; + } + else + { + cout << "provisionSecurity is failed." << endl; + } + + return {}; +} + +void provisionSecurity() +{ + if(!remoteEnrollee) + { + std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl; + return; + } + + try + { + remoteEnrollee->provisionSecurity((SecurityProvStatusCbWithOption)provisionSecurityStatusCallback); + } + catch (OCException &e) + { + std::cout << "Exception during provisionSecurity call" << e.reason(); + return; + } +} + +void getStatusCallback(std::shared_ptr< GetEnrolleeStatus > getEnrolleeStatus) +{ + if(getEnrolleeStatus->getESResult() != ES_OK) + { + cout << "getStatus is failed." << endl; + return; + } + else + { + cout << "getStatus is success." << endl; + printStatus(getEnrolleeStatus->getEnrolleeStatus()); + } +} + + +void getStatus() +{ + if(!remoteEnrollee) + { + std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl; + return; + } + + try + { + remoteEnrollee->getStatus(getStatusCallback); + } + catch (OCException &e) + { + std::cout << "Exception during getConfiguration call" << e.reason(); + return; + } +} + +void getConfigurationCallback(std::shared_ptr< GetConfigurationStatus > getConfigurationStatus) +{ + if(getConfigurationStatus->getESResult() != ES_OK) + { + cout << "GetConfigurationStatus is failed." << endl; + return; + } + else + { + cout << "GetConfigurationStatus is success." << endl; + printConfiguration(getConfigurationStatus->getEnrolleeConf()); + } +} + +void getConfiguration() +{ + if(!remoteEnrollee) + { + std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl; + return; + } + + try + { + remoteEnrollee->getConfiguration(getConfigurationCallback); + } + catch (OCException &e) + { + std::cout << "Exception during getConfiguration call" << e.reason(); + return; + } +} + +void deviceProvisioningStatusCallback(std::shared_ptr< DevicePropProvisioningStatus > provStatus) +{ + if(provStatus->getESResult() != ES_OK) + { + cout << "Device Provisioning is failed." << endl; + return; + } + else + { + cout << "Device Provisioning is success." << endl; + } +} + +void provisionDeviceProperty() +{ + if(!remoteEnrollee) + { + std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl; + return; + } + + DeviceProp devProp; + devProp.setWiFiProp("Iotivity_SSID", "Iotivity_PWD", WPA2_PSK, TKIP_AES); + devProp.setDevConfProp("korean", "Korea", "Location"); + + try + { + remoteEnrollee->provisionDeviceProperties(devProp, deviceProvisioningStatusCallback); + } + catch (OCException &e) + { + std::cout << "Exception during provisionDeviceProperties call" << e.reason(); + return; + } +} + +void cloudProvisioningStatusCallback(std::shared_ptr< CloudPropProvisioningStatus > provStatus) +{ + switch (provStatus->getESResult()) + { + case ES_OK: + cout << "Cloud Provisioning is success." << endl; + break; + case ES_SECURE_RESOURCE_DISCOVERY_FAILURE: + cout << "Enrollee is not found in a given network." << endl; + break; + case ES_ACL_PROVISIONING_FAILURE: + cout << "ACL provisioning is failed." << endl; + break; + case ES_CERT_PROVISIONING_FAILURE: + cout << "CERT provisioning is failed." << endl; + break; + default: + cout << "Cloud Provisioning is failed." << endl; + break; + } +} + +void provisionCloudProperty() +{ + if(!remoteEnrollee) + { + std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl; + return; + } + + CloudProp cloudProp; + cloudProp.setCloudProp("authCode", "authProvider", "ciServer"); + cloudProp.setCloudID("f002ae8b-c42c-40d3-8b8d-1927c17bd1b3"); + cloudProp.setCredID(1); + + try + { + remoteEnrollee->provisionCloudProperties(cloudProp, cloudProvisioningStatusCallback); + } + catch (OCException &e) + { + std::cout << "Exception during provisionCloudProperties call" << e.reason(); + return; + } +} + +// Callback to found resources +void foundResource(std::shared_ptr resource) +{ + std::string resourceURI; + std::string hostAddress; + try + { + // Do some operations with resource object. + if(resource && + !curResource && + resource->getResourceTypes().at(0) == OC_RSRVD_ES_RES_TYPE_PROV) + { + std::cout<<"DISCOVERED Resource:"<uri(); + std::cout << "\tURI of the resource: " << resourceURI << std::endl; + + // Get the resource host address + hostAddress = resource->host(); + std::cout << "\tHost address of the resource: " << hostAddress << std::endl; + + // Get the resource types + std::cout << "\tList of resource types: " << std::endl; + for(auto &resourceTypes : resource->getResourceTypes()) + { + std::cout << "\t\t" << resourceTypes << std::endl; + } + + // Get the resource interfaces + std::cout << "\tList of resource interfaces: " << std::endl; + for(auto &resourceInterfaces : resource->getResourceInterfaces()) + { + std::cout << "\t\t" << resourceInterfaces << std::endl; + } + + if(curResource == nullptr) + { + remoteEnrollee = EasySetup::getInstance()->createRemoteEnrollee(resource); + if(!remoteEnrollee) + { + std::cout << "RemoteEnrollee object is failed for some reasons!" << std::endl; + } + else + { + curResource = resource; + std::cout << "RemoteEnrollee object is successfully created!" << std::endl; + g_cond.notify_all(); + } + } + } + } + catch(std::exception& e) + { + std::cerr << "Exception in foundResource: "<< e.what() << std::endl; + } +} + +void discoveryEnrolleeResource() +{ + try + { + std::ostringstream requestURI; + requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=" << OC_RSRVD_ES_RES_TYPE_PROV; + OCPlatform::findResource("", requestURI.str(), CT_DEFAULT, &foundResource); + std::cout<< "Finding Resource... " < lck(g_discoverymtx); + g_cond.wait_for(lck, std::chrono::seconds(5)); + } + catch (OCException& e) + { + std::cout << "Exception in discoveryEnrolleeResource: "<