X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fsecurity%2Fprovisioning%2Fsrc%2Fownershiptransfermanager.c;h=92836d5eb2edfc7a14bdac87030af88895e74ca3;hb=refs%2Ftags%2Fsubmit%2Ftizen%2F20180118.072546;hp=5a06faf22d047b2cb0baecca0c3c476e76d55f9f;hpb=531eb849bb6cd36510ecd83194268a1f304e85a9;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/security/provisioning/src/ownershiptransfermanager.c b/resource/csdk/security/provisioning/src/ownershiptransfermanager.c index 5a06faf..92836d5 100644 --- a/resource/csdk/security/provisioning/src/ownershiptransfermanager.c +++ b/resource/csdk/security/provisioning/src/ownershiptransfermanager.c @@ -42,6 +42,8 @@ #endif #include #include +#include +#include #include "logger.h" #include "oic_malloc.h" @@ -49,8 +51,11 @@ #include "cacommon.h" #include "cainterface.h" #include "base64.h" +#if defined (__TIZENRT__) +#include +#else #include "cJSON.h" -#include "global.h" +#endif #include "utlist.h" #include "srmresourcestrings.h" #include "doxmresource.h" @@ -62,9 +67,11 @@ #include "oxmjustworks.h" #include "oxmrandompin.h" #include "oxmmanufacturercert.h" -#ifdef _ENABLE_MULTIPLE_OWNER_ +#include "secureresourceprovider.h" + +#ifdef MULTIPLE_OWNER #include "oxmpreconfpin.h" -#endif //_ENABLE_MULTIPLE_OWNER_ +#endif //MULTIPLE_OWNER #include "otmcontextlist.h" #include "pmtypes.h" #include "pmutility.h" @@ -73,6 +80,8 @@ #include "ocpayload.h" #include "payload_logging.h" #include "pkix_interface.h" +#include "oxmverifycommon.h" +#include "psinterface.h" #define TAG "OIC_OTM" @@ -84,12 +93,14 @@ * List of allowed oxm list. * All oxm methods are allowed as default. */ -static uint8_t g_OxmAllowStatus[OIC_OXM_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM, NOT_ALLOWED_OXM}; - -/** - * Variables for pointing the OTMContext to be used in the DTLS handshake result callback. - */ -static OTMContext_t* g_otmCtx = NULL; +#ifdef MULTIPLE_OWNER +static uint8_t g_OxmAllowStatus[OXM_IDX_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM, + ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM, + NOT_ALLOWED_OXM}; +#else +static uint8_t g_OxmAllowStatus[OXM_IDX_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM, + ALLOWED_OXM, ALLOWED_OXM, NOT_ALLOWED_OXM}; +#endif OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks) { @@ -98,11 +109,13 @@ OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks) OIC_LOG(INFO, TAG, "IN OTMSetOTCallback"); VERIFY_NON_NULL(TAG, callbacks, ERROR); -#ifdef _ENABLE_MULTIPLE_OWNER_ - VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_PRECONFIG_PIN == oxm), ERROR); + +#ifdef MULTIPLE_OWNER + VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_PRECONFIG_PIN == oxm || OIC_MV_JUST_WORKS == oxm + || OIC_CON_MFG_CERT == oxm), ERROR); #else - VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm), ERROR); -#endif //_ENABLE_MULTIPLE_OWNER_ + VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_MV_JUST_WORKS == oxm || OIC_CON_MFG_CERT == oxm), ERROR); +#endif // MULTIPLE_OWNER switch(oxm) { @@ -127,14 +140,26 @@ OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks) case OIC_DECENTRALIZED_PUBLIC_KEY: OIC_LOG(ERROR, TAG, "OIC_DECENTRALIZED_PUBLIC_KEY not supported yet."); return OC_STACK_INVALID_METHOD; -#ifdef _ENABLE_MULTIPLE_OWNER_ +#ifdef MULTIPLE_OWNER case OIC_PRECONFIG_PIN: callbacks->loadSecretCB = LoadPreconfigPinCodeCallback; callbacks->createSecureSessionCB = CreateSecureSessionPreconfigPinCallback; callbacks->createSelectOxmPayloadCB = CreatePreconfigPinBasedSelectOxmPayload; callbacks->createOwnerTransferPayloadCB = CreatePreconfigPinBasedOwnerTransferPayload; break; -#endif //_ENABLE_MULTIPLE_OWNER_ +#endif //MULTIPLE_OWNER + case OIC_MV_JUST_WORKS: + callbacks->loadSecretCB = LoadSecretJustWorksCallback; + callbacks->createSecureSessionCB = CreateSecureSessionJustWorksCallback; + callbacks->createSelectOxmPayloadCB = CreateMVJustWorksSelectOxmPayload; + callbacks->createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload; + break; + case OIC_CON_MFG_CERT: + callbacks->loadSecretCB = PrepareMCertificateCallback; + callbacks->createSecureSessionCB = CreateSecureSessionMCertificateCallback; + callbacks->createSelectOxmPayloadCB = CreateConMCertificateBasedSelectOxmPayload; + callbacks->createOwnerTransferPayloadCB = CreateMCertificateBasedOwnerTransferPayload; + break; default: OIC_LOG_V(ERROR, TAG, "Unknown OxM : %d", (int)oxm); return OC_STACK_INVALID_PARAM; @@ -148,50 +173,119 @@ exit: } /** + * Internal API to convert OxM value to index of oxm allow table. + */ +static OxmAllowTableIdx_t GetOxmAllowTableIdx(OicSecOxm_t oxm) +{ + switch(oxm) + { + case OIC_JUST_WORKS: + return OXM_IDX_JUST_WORKS; + case OIC_RANDOM_DEVICE_PIN: + return OXM_IDX_RANDOM_DEVICE_PIN; + case OIC_MANUFACTURER_CERTIFICATE: + return OXM_IDX_MANUFACTURER_CERTIFICATE; + case OIC_DECENTRALIZED_PUBLIC_KEY: + return OXM_IDX_DECENTRALIZED_PUBLIC_KEY; + case OIC_MV_JUST_WORKS: + return OXM_IDX_MV_JUST_WORKS; + case OIC_CON_MFG_CERT: + return OXM_IDX_CON_MFG_CERT; +#ifdef MULTIPLE_OWNER + case OIC_PRECONFIG_PIN: + return OXM_IDX_PRECONFIG_PIN; +#endif + default: + return OXM_IDX_UNKNOWN; + } +} + +/** * Function to select appropriate provisioning method. * * @param[in] supportedMethods Array of supported methods * @param[in] numberOfMethods number of supported methods * @param[out] selectedMethod Selected methods + * @param[in] ownerType type of owner device (SUPER_OWNER or SUB_OWNER) * @return OC_STACK_OK on success */ -static OCStackResult SelectProvisioningMethod(const OicSecOxm_t *supportedMethods, - size_t numberOfMethods, OicSecOxm_t *selectedMethod) +OCStackResult OTMSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMethods, + size_t numberOfMethods, OicSecOxm_t *selectedMethod, OwnerType_t ownerType) { bool isOxmSelected = false; + OxmAllowTableIdx_t selectedOxmIdx = OXM_IDX_UNKNOWN; OIC_LOG(DEBUG, TAG, "IN SelectProvisioningMethod"); - if(numberOfMethods == 0 || !supportedMethods) + if (numberOfMethods == 0 || !supportedMethods) { OIC_LOG(WARNING, TAG, "Could not find a supported OxM."); return OC_STACK_ERROR; } - for(size_t i = 0; i < numberOfMethods; i++) + switch(ownerType) { - if(ALLOWED_OXM == g_OxmAllowStatus[supportedMethods[i]]) + case SUPER_OWNER: { - *selectedMethod = supportedMethods[i]; - isOxmSelected = true; - break; + for (size_t i = 0; i < numberOfMethods; i++) + { + selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]); + if (OXM_IDX_COUNT <= selectedOxmIdx) + { + OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table"); + continue; + } + +#ifdef MULTIPLE_OWNER + if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] && + OXM_IDX_PRECONFIG_PIN != selectedOxmIdx) +#else + if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx]) +#endif //MULTIPLE_OWNER + { + *selectedMethod = supportedMethods[i]; + isOxmSelected = true; + } + } + } + break; +#ifdef MULTIPLE_OWNER + case SUB_OWNER: + { + for (size_t i = 0; i < numberOfMethods; i++) + { + selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]); + if (OXM_IDX_COUNT <= selectedOxmIdx) + { + OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table"); + continue; + } + + //in case of MOT, only Random PIN & Preconfigured PIN based OxM is allowed + if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] && + (OXM_IDX_RANDOM_DEVICE_PIN == selectedOxmIdx || + OXM_IDX_PRECONFIG_PIN == selectedOxmIdx)) + { + *selectedMethod = supportedMethods[i]; + isOxmSelected = true; + } + } + } + break; +#endif + default: + { + OIC_LOG_V(ERROR, TAG, "Unknown owner type or Not supported owner type : %d", ownerType); + return OC_STACK_INVALID_PARAM; } } - if(!isOxmSelected) + + if (!isOxmSelected) { OIC_LOG(ERROR, TAG, "Can not find the allowed OxM."); return OC_STACK_NOT_ALLOWED_OXM; } - for(size_t i = 0; i < numberOfMethods; i++) - { - if(*selectedMethod < supportedMethods[i] && - ALLOWED_OXM == g_OxmAllowStatus[supportedMethods[i]]) - { - *selectedMethod = supportedMethods[i]; - } - } - OIC_LOG(DEBUG, TAG, "OUT SelectProvisioningMethod"); return OC_STACK_OK; @@ -223,6 +317,14 @@ static void SelectOperationMode(const OCProvisionDev_t *selectedDeviceInfo, */ static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice); +/* + * Internal function to setup & cleanup PDM to performing provisioning. + * + * @param[in] selectedDevice selected device information to performing provisioning. + * @return OC_STACK_OK on success + */ +static OCStackResult SetupPDM(const OCProvisionDev_t* selectedDevice); + /** * Function to update owner transfer mode * @@ -323,11 +425,12 @@ static bool IsComplete(OTMContext_t* otmCtx) * @param[in,out] otmCtx Context value of ownership transfer. * @param[in] res result of provisioning */ -static void SetResult(OTMContext_t* otmCtx, const OCStackResult res) +void SetResult(OTMContext_t* otmCtx, const OCStackResult res) { OIC_LOG_V(DEBUG, TAG, "IN SetResult : %d ", res); - if(NULL == otmCtx || NULL == otmCtx->selectedDeviceInfo) + if(NULL == otmCtx || NULL == otmCtx->selectedDeviceInfo + || NULL == otmCtx->selectedDeviceInfo->doxm) { OIC_LOG(WARNING, TAG, "OTMContext is NULL"); return; @@ -338,7 +441,6 @@ static void SetResult(OTMContext_t* otmCtx, const OCStackResult res) otmCtx->selectedDeviceInfo->securePort)) { OIC_LOG(WARNING, TAG, "Current OTM Process has already ended."); - return; } //Revert psk_info callback and new deivce uuid in case of random PIN OxM @@ -351,7 +453,8 @@ static void SetResult(OTMContext_t* otmCtx, const OCStackResult res) OicUuid_t emptyUuid = { .id={0}}; SetUuidForPinBasedOxm(&emptyUuid); } - else if(OIC_MANUFACTURER_CERTIFICATE == otmCtx->selectedDeviceInfo->doxm->oxmSel) + else if(OIC_MANUFACTURER_CERTIFICATE == otmCtx->selectedDeviceInfo->doxm->oxmSel || + OIC_CON_MFG_CERT == otmCtx->selectedDeviceInfo->doxm->oxmSel) { //Revert back certificate related callbacks. if(CA_STATUS_OK != CAregisterPkixInfoHandler(GetPkixInfo)) @@ -373,6 +476,17 @@ static void SetResult(OTMContext_t* otmCtx, const OCStackResult res) if(OC_STACK_OK != res && OC_STACK_CONTINUE != res && OC_STACK_DUPLICATE_REQUEST != res) { otmCtx->ctxHasError = true; + if (OC_STACK_OK != PDMDeleteDevice(&otmCtx->ctxResultArray[i].deviceId)) + { + OIC_LOG(WARNING, TAG, "Internal error in PDMDeleteDevice"); + } + CAEndpoint_t endpoint; + memcpy(&endpoint, &(otmCtx->selectedDeviceInfo->endpoint), sizeof(CAEndpoint_t)); + endpoint.port = otmCtx->selectedDeviceInfo->securePort; + if (CA_STATUS_OK != CAcloseSslConnection(&endpoint)) + { + OIC_LOG(WARNING, TAG, "Failed to close Secure session"); + } } } } @@ -404,6 +518,23 @@ static void SetResult(OTMContext_t* otmCtx, const OCStackResult res) //If all OTM process is complete, invoke the user callback. if(IsComplete(otmCtx)) { + if(OC_STACK_OK != res && OC_STACK_CONTINUE != res && OC_STACK_DUPLICATE_REQUEST != res) + { + // Reset doxm and pstat properties to pre-Ownership Transfer state + OIC_LOG(DEBUG, TAG, "Resetting doxm and pstat properties"); + if(otmCtx->selectedDeviceInfo->doxm) + { + OicUuid_t emptyUuid = {.id = {0}}; + memcpy(&(otmCtx->selectedDeviceInfo->doxm->owner), &emptyUuid, sizeof(OicUuid_t)); + otmCtx->selectedDeviceInfo->doxm->owned = false; + } + if(otmCtx->selectedDeviceInfo->pstat) + { + otmCtx->selectedDeviceInfo->pstat->isOp = false; + otmCtx->selectedDeviceInfo->pstat->cm |= TAKE_OWNER; + } + } + otmCtx->ctxResultCallback(otmCtx->userCtx, otmCtx->ctxResultArraySize, otmCtx->ctxResultArray, otmCtx->ctxHasError); OICFree(otmCtx->ctxResultArray); @@ -430,6 +561,7 @@ static void SetResult(OTMContext_t* otmCtx, const OCStackResult res) */ void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info) { + OIC_LOG(DEBUG, TAG, "IN DTLSHandshakeCB"); if(NULL != endpoint && NULL != info) { OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d", @@ -456,6 +588,59 @@ void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info) false == newDevDoxm->owned && memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) == 0) { + //In case of Mutual Verified Just-Works, display mutualVerifNum + if (OIC_MV_JUST_WORKS == newDevDoxm->oxmSel) + { + uint8_t preMutualVerifNum[OWNER_PSK_LENGTH_128] = {0}; + uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN] = {0}; + OicUuid_t deviceID = {.id = {0}}; + + //Generate mutualVerifNum + char label[LABEL_LEN] = {0}; + snprintf(label, LABEL_LEN, "%s%s", MUTUAL_VERIF_NUM, OXM_MV_JUST_WORKS); + res = GetDoxmDeviceID(&deviceID); + if (OC_STACK_OK != res) + { + OIC_LOG(ERROR, TAG, "Error while retrieving Owner's device ID"); + SetResult(otmCtx, res); + return; + } + + CAResult_t pskRet = CAGenerateOwnerPSK(endpoint, + (uint8_t *)label, + strlen(label), + deviceID.id, sizeof(deviceID.id), + newDevDoxm->deviceID.id, sizeof(newDevDoxm->deviceID.id), + preMutualVerifNum, OWNER_PSK_LENGTH_128); + if (CA_STATUS_OK != pskRet) + { + OIC_LOG(WARNING, TAG, "Failed to remove the invaild owner credential"); + SetResult(otmCtx, OC_STACK_ERROR); + return; + } + + memcpy(mutualVerifNum, preMutualVerifNum + OWNER_PSK_LENGTH_128 - sizeof(mutualVerifNum), + sizeof(mutualVerifNum)); + res = VerifyOwnershipTransfer(mutualVerifNum, DISPLAY_NUM); + if (OC_STACK_OK != res) + { + OIC_LOG(ERROR, TAG, "Error while displaying mutualVerifNum"); + SetResult(otmCtx, res); + return; + } + } + //In case of confirmed manufacturer cert, display message + else if (OIC_MANUFACTURER_CERTIFICATE == newDevDoxm->oxmSel || OIC_CON_MFG_CERT == newDevDoxm->oxmSel) + { + res = VerifyOwnershipTransfer(NULL, DISPLAY_NUM); + if (OC_STACK_OK != res) + { + OIC_LOG(ERROR, TAG, "Error while displaying message"); + SetResult(otmCtx, res); + return; + } + } + //Send request : POST /oic/sec/doxm [{... , "devowner":"PT's UUID"}] res = PostOwnerUuid(otmCtx); if(OC_STACK_OK != res) @@ -488,19 +673,32 @@ void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info) newDevDoxm->owned = false; otmCtx->attemptCnt++; - if(WRONG_PIN_MAX_ATTEMP > otmCtx->attemptCnt) + RemoveOTMContext(otmCtx->selectedDeviceInfo->endpoint.addr, + otmCtx->selectedDeviceInfo->securePort); + + // In order to re-start ownership transfer, device information should be deleted from PDM. + res = PDMDeleteDevice(&(otmCtx->selectedDeviceInfo->doxm->deviceID)); + if (OC_STACK_OK != res) { - res = StartOwnershipTransfer(otmCtx, otmCtx->selectedDeviceInfo); - if(OC_STACK_OK != res) - { - SetResult(otmCtx, res); - OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer"); - } + SetResult(otmCtx, res); + OIC_LOG(ERROR, TAG, "Failed to PDMDeleteDevice"); } else { - OIC_LOG(ERROR, TAG, "User has exceeded the number of authentication attempts."); - SetResult(otmCtx, OC_STACK_AUTHENTICATION_FAILURE); + if(WRONG_PIN_MAX_ATTEMP > otmCtx->attemptCnt) + { + res = StartOwnershipTransfer(otmCtx, otmCtx->selectedDeviceInfo); + if(OC_STACK_OK != res) + { + SetResult(otmCtx, res); + OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer"); + } + } + else + { + OIC_LOG(ERROR, TAG, "User has exceeded the number of authentication attempts."); + SetResult(otmCtx, OC_STACK_AUTHENTICATION_FAILURE); + } } } else @@ -517,6 +715,7 @@ void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info) OIC_LOG(ERROR, TAG, "Can not find the OTM Context."); } } + OIC_LOG(DEBUG, TAG, "OUT DTLSHandshakeCB"); } /** @@ -546,7 +745,7 @@ static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo) } uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0}; - OicSecKey_t ownerKey = {ownerPSK, OWNER_PSK_LENGTH_128}; + OicSecKey_t ownerKey = {.data=ownerPSK, .len=OWNER_PSK_LENGTH_128, .encoding=OIC_ENCODING_RAW}; //Generating OwnerPSK CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint, @@ -567,14 +766,9 @@ static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo) OICClearMemory(ownerPSK, sizeof(ownerPSK)); VERIFY_NON_NULL(TAG, cred, ERROR); - // TODO: Added as workaround. Will be replaced soon. - cred->privateData.encoding = OIC_ENCODING_RAW; - -#if 1 - // NOTE: Test codes to use BASE64 encoded owner PSK. uint32_t outSize = 0; size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1)); - char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize); + char* b64Buf = (char *)OICCalloc(1, b64BufSize); VERIFY_NON_NULL(TAG, b64Buf, ERROR); b64Encode(cred->privateData.data, cred->privateData.len, b64Buf, b64BufSize, &outSize); @@ -582,16 +776,15 @@ static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo) cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1); VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR); - strncpy(cred->privateData.data, b64Buf, outSize); + strncpy((char*)(cred->privateData.data), b64Buf, outSize); cred->privateData.data[outSize] = '\0'; cred->privateData.encoding = OIC_ENCODING_BASE64; cred->privateData.len = outSize; OICFree(b64Buf); -#endif //End of Test codes //Finding previous ownerPSK. const OicSecCred_t* credList = GetCredList(); - OicSecCred_t* prevCred = NULL; + const OicSecCred_t* prevCred = NULL; uint16_t credId = 0; LL_FOREACH(credList, prevCred) { @@ -762,6 +955,13 @@ exit: return OC_STACK_DELETE_TRANSACTION; } +static void deleteCallback(void *ctx) +{ + OC_UNUSED(ctx); + OIC_LOG_V(DEBUG, TAG, "%s: otm context deleted", __func__); +} + + /** * Response handler for update owner uuid request. * @@ -787,6 +987,22 @@ static OCStackApplicationResult OwnerUuidUpdateHandler(void *ctx, OCDoHandle UNU { if(otmCtx && otmCtx->selectedDeviceInfo) { + //In case of Mutual Verified Just-Works, wait for user confirmation + if (OIC_MV_JUST_WORKS == otmCtx->selectedDeviceInfo->doxm->oxmSel) + { + res = VerifyOwnershipTransfer(NULL, USER_CONFIRM); + if (OC_STACK_OK != res) + { + if (OC_STACK_OK != SRPResetDevice(otmCtx->selectedDeviceInfo, deleteCallback)) + { + OIC_LOG(WARNING, TAG, "OwnerUuidUpdateHandler : SRPResetDevice error"); + } + OIC_LOG(ERROR, TAG, "OwnerUuidUpdateHandler:Failed to verify user confirm"); + SetResult(otmCtx, res); + return OC_STACK_DELETE_TRANSACTION; + } + } + res = SaveOwnerPSK(otmCtx->selectedDeviceInfo); if(OC_STACK_OK != res) { @@ -808,8 +1024,25 @@ static OCStackApplicationResult OwnerUuidUpdateHandler(void *ctx, OCDoHandle UNU } else { - res = clientResponse->result; - OIC_LOG_V(ERROR, TAG, "OwnerUuidHandler : Unexpected result %d", res); + if (((OIC_MANUFACTURER_CERTIFICATE == otmCtx->selectedDeviceInfo->doxm->oxmSel) || + (OIC_CON_MFG_CERT == otmCtx->selectedDeviceInfo->doxm->oxmSel)) && + OC_STACK_NOT_ACCEPTABLE == clientResponse->result) + { + res = OC_STACK_USER_DENIED_REQ; + OIC_LOG_V(ERROR, TAG, + "OwnerUuidUpdateHandler : Denied Request(%d)", res); + } + else if (OC_STACK_GATEWAY_TIMEOUT == clientResponse->result) + { + res = clientResponse->result; + OIC_LOG_V(ERROR, TAG, + "OwnerUuidUpdateHandler : Timeout:No Response Received(%d)", res); + } + else + { + res = clientResponse->result; + OIC_LOG_V(ERROR, TAG, "OwnerUuidUpdateHandler : Unexpected result(%d)", res); + } SetResult(otmCtx, res); } @@ -819,6 +1052,49 @@ exit: return OC_STACK_DELETE_TRANSACTION; } +/* + * Invokes Callback to load Random PIN + */ +void *LoadRandomPin(void *ctx) +{ + OIC_LOG_V(DEBUG, TAG, "IN %s", __func__); + OTMContext_t* otmCtx = (OTMContext_t*)ctx; + OCStackResult res = OC_STACK_ERROR; + res = otmCtx->otmCallback.loadSecretCB(otmCtx); + + if(OC_STACK_OK != res) + { + OIC_LOG_V(ERROR, TAG, "%s : Failed to load secret", __func__); + SetResult(otmCtx, res); + OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__); + return NULL; + } + + //Save the current context instance to use on the dtls handshake callback + if(OC_STACK_OK != AddOTMContext(otmCtx, + otmCtx->selectedDeviceInfo->endpoint.addr, + otmCtx->selectedDeviceInfo->securePort)) + { + OIC_LOG_V(ERROR, TAG, "%s : Failed to add OTM Context into OTM List.", __func__); + SetResult(otmCtx, res); + OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__); + return NULL; + } + + //Try DTLS handshake to generate secure session + if(otmCtx->otmCallback.createSecureSessionCB) + { + res = otmCtx->otmCallback.createSecureSessionCB(otmCtx); + if(OC_STACK_OK != res) + { + OIC_LOG_V(ERROR, TAG, "%s : Failed to create DTLS session", __func__); + SetResult(otmCtx, res); + } + } + OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__); + return NULL; +} + /** * Response handler for update operation mode. * @@ -847,34 +1123,50 @@ static OCStackApplicationResult OperationModeUpdateHandler(void *ctx, OCDoHandle //Load secret for temporal secure session. if(otmCtx->otmCallback.loadSecretCB) { - res = otmCtx->otmCallback.loadSecretCB(otmCtx); - if(OC_STACK_OK != res) + if (OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel) { - OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to load secret"); - SetResult(otmCtx, res); - return OC_STACK_DELETE_TRANSACTION; + pthread_t p_thread; + int thr_result; + thr_result = pthread_create(&p_thread, NULL, LoadRandomPin, (void *) otmCtx); + if (0 != thr_result) + { + OIC_LOG_V(ERROR, TAG, "pthread_create Error with code %d", thr_result); + SetResult(otmCtx, res); + return OC_STACK_DELETE_TRANSACTION; + } + OIC_LOG(INFO, TAG, "Random Pin loadSecretCB Thread Created"); } - } + else + { + res = otmCtx->otmCallback.loadSecretCB(otmCtx); + if(OC_STACK_OK != res) + { + OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to load secret"); + SetResult(otmCtx, res); + return OC_STACK_DELETE_TRANSACTION; + } - //Save the current context instance to use on the dtls handshake callback - if(OC_STACK_OK != AddOTMContext(otmCtx, - otmCtx->selectedDeviceInfo->endpoint.addr, - otmCtx->selectedDeviceInfo->securePort)) - { - OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to add OTM Context into OTM List."); - SetResult(otmCtx, res); - return OC_STACK_DELETE_TRANSACTION; - } + //Save the current context instance to use on the dtls handshake callback + if(OC_STACK_OK != AddOTMContext(otmCtx, + otmCtx->selectedDeviceInfo->endpoint.addr, + otmCtx->selectedDeviceInfo->securePort)) + { + OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to add OTM Context into OTM List."); + SetResult(otmCtx, res); + return OC_STACK_DELETE_TRANSACTION; + } - //Try DTLS handshake to generate secure session - if(otmCtx->otmCallback.createSecureSessionCB) - { - res = otmCtx->otmCallback.createSecureSessionCB(otmCtx); - if(OC_STACK_OK != res) - { - OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to create DTLS session"); - SetResult(otmCtx, res); - return OC_STACK_DELETE_TRANSACTION; + //Try DTLS handshake to generate secure session + if(otmCtx->otmCallback.createSecureSessionCB) + { + res = otmCtx->otmCallback.createSecureSessionCB(otmCtx); + if(OC_STACK_OK != res) + { + OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to create DTLS session"); + SetResult(otmCtx, res); + return OC_STACK_DELETE_TRANSACTION; + } + } } } } @@ -934,7 +1226,6 @@ static OCStackApplicationResult OwnerCredentialHandler(void *ctx, OCDoHandle UNU */ // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 = 0xC037, /**< see RFC 5489 */ caResult = CASelectCipherSuite(0xC037, endpoint->adapter); - if(CA_STATUS_OK != caResult) { OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL"); @@ -1228,12 +1519,13 @@ static OCStackResult PostOwnerCredential(OTMContext_t* otmCtx) memcpy(&(newCredential.subject), &credSubjectId, sizeof(OicUuid_t)); //Fill private data as empty string - newCredential.privateData.data = ""; + newCredential.privateData.data = (uint8_t*)""; newCredential.privateData.len = 0; newCredential.privateData.encoding = ownerCredential->privateData.encoding; newCredential.publicData.data = NULL; newCredential.publicData.len = 0; + newCredential.publicData.encoding = ownerCredential->publicData.encoding; int secureFlag = 0; //Send owner credential to new device : POST /oic/sec/cred [ owner credential ] @@ -1694,92 +1986,151 @@ static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx) return res; } -static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice) +static OCStackResult SetupPDM(const OCProvisionDev_t* selectedDevice) { - OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer"); - OCStackResult res = OC_STACK_INVALID_PARAM; + OIC_LOG_V(DEBUG, TAG, "IN %s", __func__); - VERIFY_NON_NULL(TAG, selectedDevice, ERROR); - VERIFY_NON_NULL(TAG, selectedDevice->doxm, ERROR); + PdmDeviceState_t pdmState = PDM_DEVICE_UNKNOWN; + OCStackResult res = PDMGetDeviceState(&selectedDevice->doxm->deviceID, &pdmState); + if (OC_STACK_OK != res) + { + OIC_LOG_V(ERROR, TAG, "Internal error in PDMGetDeviceState : %d", res); + return res; + } - OTMContext_t* otmCtx = (OTMContext_t*)ctx; - otmCtx->selectedDeviceInfo = selectedDevice; + char* strUuid = NULL; + bool removeCredReq = false; + if (OC_STACK_OK != ConvertUuidToStr(&selectedDevice->doxm->deviceID, &strUuid)) + { + OIC_LOG(WARNING, TAG, "Failed to covert uuid to string"); + return OC_STACK_NO_MEMORY; + } + + if (PDM_DEVICE_UNKNOWN == pdmState && !selectedDevice->doxm->owned) + { + removeCredReq = true; + } + else if (PDM_DEVICE_ACTIVE == pdmState && !selectedDevice->doxm->owned) + { + OIC_LOG_V(WARNING, TAG, "Unowned device[%s] dectected from PDM.", strUuid); + OIC_LOG_V(WARNING, TAG, "[%s] will be removed from PDM.", strUuid); + res = PDMDeleteDevice(&selectedDevice->doxm->deviceID); + if(OC_STACK_OK != res) + { + OIC_LOG_V(ERROR, TAG, "Failed to remove [%s] information from PDM.", strUuid); + goto exit; + } + + removeCredReq = true; + } + + if (removeCredReq) + { + OIC_LOG_V(WARNING, TAG, "[%s]'s credential will be removed.", strUuid); + res = RemoveCredential(&selectedDevice->doxm->deviceID); + if (OC_STACK_RESOURCE_DELETED != res) + { + OIC_LOG_V(WARNING, TAG, "Can not find [%s]'s credential.", strUuid); + } + } //Checking duplication of Device ID. bool isDuplicate = true; res = PDMIsDuplicateDevice(&selectedDevice->doxm->deviceID, &isDuplicate); if (OC_STACK_OK != res) { - OIC_LOG(ERROR, TAG, "Internal error in PDMIsDuplicateDevice"); - return res; + OIC_LOG_V(ERROR, TAG, "Internal error in PDMIsDuplicateDevice : %d", res); + goto exit; } + if (isDuplicate) { - PdmDeviceState_t state = PDM_DEVICE_UNKNOWN; - res = PDMGetDeviceState(&selectedDevice->doxm->deviceID, &state); - if(OC_STACK_OK != res) - { - OIC_LOG(ERROR, TAG, "Internal error in PDMGetDeviceState"); - SetResult(otmCtx, res); - return res; - } - char* strUuid = NULL; res = ConvertUuidToStr(&selectedDevice->doxm->deviceID, &strUuid); - if(OC_STACK_OK != res) + if (OC_STACK_OK != res) { - OIC_LOG(ERROR, TAG, "Failed to convert UUID to str"); - SetResult(otmCtx, res); - return res; + OIC_LOG_V(ERROR, TAG, "Failed to convert UUID to str : %d", res); + goto exit; } - if(PDM_DEVICE_STALE == state) + if (PDM_DEVICE_STALE == pdmState) { OIC_LOG(INFO, TAG, "Detected duplicated UUID in stale status, " "device status will revert back to initial status."); res = PDMSetDeviceState(&selectedDevice->doxm->deviceID, PDM_DEVICE_INIT); - if(OC_STACK_OK != res) + if (OC_STACK_OK != res) { - OIC_LOG(ERROR, TAG, "Internal error in PDMSetDeviceState"); - OICFree(strUuid); - SetResult(otmCtx, res); - return res; + OIC_LOG_V(ERROR, TAG, "Internal error in PDMSetDeviceState : %d", res); + goto exit; } } - else if(PDM_DEVICE_INIT == state) + else if (PDM_DEVICE_INIT == pdmState) { OIC_LOG_V(ERROR, TAG, "[%s]'s ownership transfer process is already started.", strUuid); OICFree(strUuid); - SetResult(otmCtx, OC_STACK_DUPLICATE_REQUEST); - return OC_STACK_OK; + res = OC_STACK_DUPLICATE_REQUEST; + goto exit; } else { OIC_LOG(ERROR, TAG, "Unknow device status while OTM."); OICFree(strUuid); - SetResult(otmCtx, OC_STACK_ERROR); - return OC_STACK_ERROR; + res = OC_STACK_ERROR; + goto exit; } } else { res = PDMAddDevice(&selectedDevice->doxm->deviceID); - if(OC_STACK_OK != res) + if (OC_STACK_OK != res) { - OIC_LOG(ERROR, TAG, "Internal error in PDMAddDevice"); - SetResult(otmCtx, res); - return res; + OIC_LOG_V(ERROR, TAG, "Internal error in PDMAddDevice : %d", res); + goto exit; } } +exit: + OICFree(strUuid); + OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__); + return res; +} + +static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice) +{ + OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer"); + OCStackResult res = OC_STACK_INVALID_PARAM; + OicUuid_t emptyOwner = {.id = {0} }; - //Set to the lowest level OxM, and then find more higher level OxM. - res = SelectProvisioningMethod(selectedDevice->doxm->oxm, - selectedDevice->doxm->oxmLen, - &selectedDevice->doxm->oxmSel); + VERIFY_NON_NULL(TAG, selectedDevice, ERROR); + VERIFY_NON_NULL(TAG, selectedDevice->doxm, ERROR); + + OTMContext_t* otmCtx = (OTMContext_t*)ctx; + otmCtx->selectedDeviceInfo = selectedDevice; + + //If devowneruuid of selectedDevice is not emtry, PostOwnerUuid does not triggered in DTLSHandshakeCB + if (memcmp(&(selectedDevice->doxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0) + { + OIC_LOG(DEBUG, TAG, "Set devowneruuid of selectedDevice to empty for OwnershipTransfer"); + memcpy(&(selectedDevice->doxm->owner), &emptyOwner, sizeof(OicUuid_t)); + } + + //Setup PDM to perform the OTM, PDM will be cleanup if necessary. + res = SetupPDM(selectedDevice); if(OC_STACK_OK != res) { - OIC_LOG(ERROR, TAG, "Failed to select the provisioning method"); + OIC_LOG_V(ERROR, TAG, "SetupPDM error : %d", res); + SetResult(otmCtx, res); + return res; + } + + //Select the OxM to performing ownership transfer + res = OTMSelectOwnershipTransferMethod(selectedDevice->doxm->oxm, + selectedDevice->doxm->oxmLen, + &selectedDevice->doxm->oxmSel, + SUPER_OWNER); + if(OC_STACK_OK != res) + { + OIC_LOG_V(ERROR, TAG, "Failed to select the provisioning method : %d", res); SetResult(otmCtx, res); return res; } @@ -1796,7 +2147,7 @@ static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selecte res = PostOwnerTransferModeToResource(otmCtx); if(OC_STACK_OK != res) { - OIC_LOG(WARNING, TAG, "Failed to select the provisioning method"); + OIC_LOG_V(WARNING, TAG, "Failed to select the provisioning method : %d", res); SetResult(otmCtx, res); return res; } @@ -1814,6 +2165,60 @@ exit: return res; } +static OCStackResult StartCustomOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice,const OicSecOxm_t method) +{ + OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer"); + OCStackResult res = OC_STACK_INVALID_PARAM; + + VERIFY_NON_NULL(TAG, selectedDevice, ERROR); + VERIFY_NON_NULL(TAG, selectedDevice->doxm, ERROR); + + OTMContext_t* otmCtx = (OTMContext_t*)ctx; + otmCtx->selectedDeviceInfo = selectedDevice; + + //Setup PDM to perform the OTM, PDM will be cleanup if necessary. + res = SetupPDM(selectedDevice); + if(OC_STACK_OK != res) + { + OIC_LOG_V(ERROR, TAG, "SetupPDM error : %d", res); + SetResult(otmCtx, res); + return res; + } + + //Select the OxM to performing ownership transfer + selectedDevice->doxm->oxmSel = method; + OIC_LOG_V(DEBUG, TAG, "Selected provisoning method = %d", selectedDevice->doxm->oxmSel); + + res = OTMSetOTCallback(selectedDevice->doxm->oxmSel, &otmCtx->otmCallback); + if(OC_STACK_OK != res) + { + OIC_LOG_V(ERROR, TAG, "Error in OTMSetOTCallback : %d", res); + return res; + } + +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + //Register TLS event handler, to catch the TLS handshake event + if(CA_STATUS_OK != CAregisterSslHandshakeCallback(DTLSHandshakeCB)) + { + OIC_LOG(WARNING, TAG, "StartOwnershipTransfer : Failed to register TLS handshake callback."); + } +#endif // __WITH_DTLS__ or __WITH_TLS__ + + //Send Req: POST /oic/sec/doxm [{..."OxmSel" :g_OTMCbDatas[Index of Selected OxM].OXMString,...}] + res = PostOwnerTransferModeToResource(otmCtx); + if(OC_STACK_OK != res) + { + OIC_LOG_V(WARNING, TAG, "Failed to select the provisioning method : %d", res); + SetResult(otmCtx, res); + return res; + } + + OIC_LOG(INFO, TAG, "OUT StartOwnershipTransfer"); + +exit: + return res; +} + OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxmType, OTMCallbackData_t* data) { OIC_LOG(DEBUG, TAG, "IN OTMSetOwnerTransferCallbackData"); @@ -1836,6 +2241,58 @@ OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxmType, OTMCallba return OC_STACK_OK; } +OCStackResult OTMDoCustomOwnershipTransfer(void* ctx, + OCProvisionDev_t *selectedDevice, + OCProvisionResultCB resultCallback, + const OicSecOxm_t method) +{ + OIC_LOG(DEBUG, TAG, "IN OTMDoCustomOwnershipTransfer"); + + if (NULL == selectedDevice) + { + return OC_STACK_INVALID_PARAM; + } + if (NULL == resultCallback) + { + return OC_STACK_INVALID_CALLBACK; + } + + OTMContext_t* otmCtx = (OTMContext_t*)OICCalloc(1,sizeof(OTMContext_t)); + if(!otmCtx) + { + OIC_LOG(ERROR, TAG, "Failed to create OTM Context"); + return OC_STACK_NO_MEMORY; + } + + otmCtx->ctxResultCallback = resultCallback; + otmCtx->ctxHasError = false; + otmCtx->userCtx = ctx; + + //Setting number of selected device. + otmCtx->ctxResultArraySize = 1; + + otmCtx->ctxResultArray = + (OCProvisionResult_t*)OICCalloc(otmCtx->ctxResultArraySize, sizeof(OCProvisionResult_t)); + if(NULL == otmCtx->ctxResultArray) + { + OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Failed to memory allocation"); + OICFree(otmCtx); + return OC_STACK_NO_MEMORY; + } + + //Fill the device UUID for result array. + memcpy(otmCtx->ctxResultArray[0].deviceId.id, + selectedDevice->doxm->deviceID.id, + UUID_LENGTH); + otmCtx->ctxResultArray[0].res = OC_STACK_CONTINUE; + + OCStackResult res = StartCustomOwnershipTransfer(otmCtx, selectedDevice, method); + + OIC_LOG(DEBUG, TAG, "OUT OTMDoCustomOwnershipTransfer"); + + return res; +} + /** * NOTE : Unowned discovery should be done before performing OTMDoOwnershipTransfer */ @@ -1883,7 +2340,6 @@ OCStackResult OTMDoOwnershipTransfer(void* ctx, } pCurDev = selectedDevicelist; - OCStackResult res = OC_STACK_OK; //Fill the device UUID for result array. for(size_t devIdx = 0; devIdx < otmCtx->ctxResultArraySize; devIdx++) { @@ -1894,14 +2350,10 @@ OCStackResult OTMDoOwnershipTransfer(void* ctx, pCurDev = pCurDev->next; } - StartOwnershipTransfer(otmCtx, selectedDevicelist); + OCStackResult res = StartOwnershipTransfer(otmCtx, selectedDevicelist); OIC_LOG(DEBUG, TAG, "OUT OTMDoOwnershipTransfer"); - return OC_STACK_OK; -error: - OICFree(otmCtx->ctxResultArray); - OICFree(otmCtx); return res; } @@ -1910,12 +2362,22 @@ OCStackResult OTMSetOxmAllowStatus(const OicSecOxm_t oxm, const bool allowStatus OIC_LOG_V(INFO, TAG, "IN %s : oxm=%d, allow status=%s", __func__, oxm, (allowStatus ? "true" : "false")); - if(OIC_OXM_COUNT <= oxm) +#ifdef MULTIPLE_OWNER + if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_PRECONFIG_PIN != oxm && OIC_CON_MFG_CERT != oxm) +#else + if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_CON_MFG_CERT != oxm) +#endif { return OC_STACK_INVALID_PARAM; } - g_OxmAllowStatus[oxm] = (allowStatus ? ALLOWED_OXM : NOT_ALLOWED_OXM); + OxmAllowTableIdx_t oxmIdx = GetOxmAllowTableIdx(oxm); + if(OXM_IDX_COUNT <= oxmIdx) + { + OIC_LOG(ERROR, TAG, "Invalid oxm index to access oxm allow table."); + return OC_STACK_ERROR; + } + g_OxmAllowStatus[oxmIdx] = (allowStatus ? ALLOWED_OXM : NOT_ALLOWED_OXM); OIC_LOG_V(INFO, TAG, "OUT %s", __func__); @@ -2037,3 +2499,97 @@ OCStackResult PostNormalOperationStatus(OTMContext_t* otmCtx) return ret; } + +OCStackResult ConfigSelfOwnership(void) +{ + OIC_LOG(INFO, TAG, "IN ConfigSelfOwnership"); + + bool isDeviceOwned = true; + if (OC_STACK_OK != GetDoxmIsOwned(&isDeviceOwned)) + { + OIC_LOG (ERROR, TAG, "Unable to retrieve doxm owned state"); + return OC_STACK_ERROR; + } + if( (true == isDeviceOwned) ||(true == GetPstatIsop()) ) + { + OIC_LOG(ERROR, TAG, "The state of device is not Ready for Ownership transfer."); + return OC_STACK_ERROR; + } + OicUuid_t deviceID = {.id={0}}; + if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) ) + { + OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID"); + return OC_STACK_ERROR; + } + + OCStackResult ret = OC_STACK_OK; + //Update the pstat resource as Normal Operation. + ret = SetPstatSelfOwnership(&deviceID); + if(OC_STACK_OK != ret) + { + OIC_LOG (ERROR, TAG, "Unable to update pstat resource as Normal Operation"); + goto exit; + } + //Update the doxm resource as Normal Operation. + ret = SetDoxmSelfOwnership(&deviceID); + if(OC_STACK_OK != ret) + { + OIC_LOG (ERROR, TAG, "Unable to update doxm resource as Normal Operation"); + goto exit; + } + //Update default ACE of security resource to prevent anonymous user access. + ret = UpdateDefaultSecProvACE(); + if(OC_STACK_OK != ret) + { + OIC_LOG (ERROR, TAG, "Unable to update default ace in ConfigSelfOwnership"); + goto exit; + } + //Update the acl resource owner as owner device. + ret = SetAclRownerId(&deviceID); + if(OC_STACK_OK != ret) + { + OIC_LOG (ERROR, TAG, "Unable to update acl resource in ConfigSelfOwnership"); + goto exit; + } + //Update the cred resource owner as owner device. + ret = SetCredRownerId(&deviceID); + if(OC_STACK_OK != ret) + { + // Cred resouce may be empty in Ready for Ownership transfer state. + if (OC_STACK_NO_RESOURCE == ret) + { + OIC_LOG (INFO, TAG, "Cred resource is empty"); + ret = OC_STACK_OK; + goto exit; + } + OIC_LOG (ERROR, TAG, "Unable to update cred resource in ConfigSelfOwnership"); + } + +exit: + if(OC_STACK_OK != ret) + { + /* + * If some error is occured while configure self-ownership, + * ownership related resource should be revert back to initial status. + */ + ResetSecureResourceInPS(); + } + + return ret; +} + + +void OTMTerminate() +{ + OIC_LOG_V(DEBUG, TAG, "In %s", __func__); + DeleteOTMContextList(); + +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + if(CA_STATUS_OK != CAregisterSslHandshakeCallback(NULL)) + { + OIC_LOG(WARNING, TAG, "Failed to register (D)TLS handshake callback."); + } +#endif // __WITH_DTLS__ or __WITH_TLS__ + + OIC_LOG_V(DEBUG, TAG, "Out %s", __func__); +}