From: leechul Date: Thu, 3 Mar 2016 08:36:08 +0000 (+0900) Subject: Modify OTM & SRM according to spec CR document. X-Git-Tag: 1.2.0+RC1~567 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7315a6b41ed6a0965128f1846af54b7f7285c107;p=platform%2Fupstream%2Fiotivity.git Modify OTM & SRM according to spec CR document. NOTE : This patch is modified based on ownership transfer CR document. Please refer to https://workspace.openinterconnect.org/apps/org/workgroup/security_tg/download.php/4703/STG008_OIC%20CR%20Ownership%20Transfer%20sequence%20diagram%20v2.docx This CR document seems to be applied to next spec. I'd like to apply CR to save time for prepare 1.1.0 release. This patch includes the following modifications : 1. Modify not to include private data when OBT sends owner credential. - Please see the step 19 of CR document. 2. Modify to re-establish secure session using owner credential when owner credential was successfully exchanged. - We can verify owner credential through re-establish secure session. - Please see the step 38,39 of CR docuemnt. 3. Add logic to handle errors that occurred during ownership transfer. [Patch #1] Initial upload. [Patch #2] Add logic to handle errors [Patch #3] Remove the compile errors and warnings. [Patch #4] Retrigger [Patch #5] Retrigger [Patch #6] Rebase [Patch #7] Rebase [Patch #8] Update based on self-review. [Patch #9] Rebase [Patch #10] Retrigger [Patch #11] Modify according to Mr.JongSung Lee's comment. Change-Id: If3d8f21ef686db86dbfcc1b15382eeebaa232a9d Signed-off-by: leechul Reviewed-on: https://gerrit.iotivity.org/gerrit/5341 Reviewed-by: Randeep Singh Tested-by: Randeep Singh --- diff --git a/resource/csdk/security/include/internal/doxmresource.h b/resource/csdk/security/include/internal/doxmresource.h index e0f2fc9e9..237da6437 100644 --- a/resource/csdk/security/include/internal/doxmresource.h +++ b/resource/csdk/security/include/internal/doxmresource.h @@ -94,6 +94,11 @@ OCStackResult GetDoxmDevOwnerId(OicUuid_t *devOwner); */ void DeleteDoxmBinData(OicSecDoxm_t* doxm); +/** + * Function to restore doxm resurce to initial status. + * This function will use in case of error while ownership transfer + */ +void RestoreDoxmToInitState(); #ifdef __cplusplus } diff --git a/resource/csdk/security/include/internal/pstatresource.h b/resource/csdk/security/include/internal/pstatresource.h index 40c41abef..31347884c 100644 --- a/resource/csdk/security/include/internal/pstatresource.h +++ b/resource/csdk/security/include/internal/pstatresource.h @@ -61,6 +61,11 @@ char * BinToPstatJSON(const OicSecPstat_t * pstat); */ void DeletePstatBinData(OicSecPstat_t* pstat); +/** + * Function to restore pstat resurce to initial status. + * This function will use in case of error while ownership transfer + */ +void RestorePstatToInitState(); #ifdef __cplusplus } diff --git a/resource/csdk/security/provisioning/src/ownershiptransfermanager.c b/resource/csdk/security/provisioning/src/ownershiptransfermanager.c index ba284f6d3..5011ea668 100644 --- a/resource/csdk/security/provisioning/src/ownershiptransfermanager.c +++ b/resource/csdk/security/provisioning/src/ownershiptransfermanager.c @@ -323,65 +323,84 @@ static void SetResult(OTMContext_t* otmCtx, const OCStackResult res) */ void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info) { - if(g_otmCtx && endpoint && info) + if(NULL != g_otmCtx && NULL != g_otmCtx->selectedDeviceInfo && + NULL != endpoint && NULL != info) { OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d", endpoint->addr, endpoint->port, info->result); - //Make sure the address matches. - if(strncmp(g_otmCtx->selectedDeviceInfo->endpoint.addr, - endpoint->addr, - sizeof(endpoint->addr)) == 0 && - g_otmCtx->selectedDeviceInfo->securePort == endpoint->port) + OicSecDoxm_t* newDevDoxm = g_otmCtx->selectedDeviceInfo->doxm; + + if(NULL != newDevDoxm) { - OCStackResult res = OC_STACK_ERROR; + OicUuid_t emptyUuid = {.id={0}}; - //In case of success, send next coaps request. - if(CA_STATUS_OK == info->result) + //Make sure the address matches. + if(strncmp(g_otmCtx->selectedDeviceInfo->endpoint.addr, + endpoint->addr, + sizeof(endpoint->addr)) == 0 && + g_otmCtx->selectedDeviceInfo->securePort == endpoint->port) { - //Send request : PUT /oic/sec/doxm [{... , "devowner":"PT's UUID"}] - res = PutOwnerUuid(g_otmCtx); - if(OC_STACK_OK != res) - { - OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to send owner information"); - SetResult(g_otmCtx, res); - } - } - //In case of failure, re-start the ownership transfer in case of PIN OxM - else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result) - { - g_otmCtx->selectedDeviceInfo->doxm->owned = false; - g_otmCtx->attemptCnt++; + OCStackResult res = OC_STACK_ERROR; - if(g_otmCtx->selectedDeviceInfo->doxm->oxmSel == OIC_RANDOM_DEVICE_PIN) + //If temporal secure sesstion established successfully + if(CA_STATUS_OK == info->result && + false == newDevDoxm->owned && + memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) == 0) { - /* - res = RemoveCredential(&g_otmCtx->subIdForPinOxm); - if(OC_STACK_RESOURCE_DELETED != res) + //Send request : PUT /oic/sec/doxm [{... , "devowner":"PT's UUID"}] + res = PutOwnerUuid(g_otmCtx); + if(OC_STACK_OK != res) { - OIC_LOG_V(ERROR, TAG, "Failed to remove temporal PSK : %d", res); + OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to send owner information"); SetResult(g_otmCtx, res); - return; - }*/ + } + } + //In case of authentication failure + else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result) + { + //in case of error from owner credential + if(memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0 && + true == newDevDoxm->owned) + { + OIC_LOG(ERROR, TAG, "The owner credential may incorrect."); - if(WRONG_PIN_MAX_ATTEMP > g_otmCtx->attemptCnt) + if(OC_STACK_OK != RemoveCredential(&(newDevDoxm->deviceID))) + { + OIC_LOG(WARNING, TAG, "Failed to remove the invaild owner credential"); + } + SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE); + } + //in case of error from wrong PIN, re-start the ownership transfer + else if(OIC_RANDOM_DEVICE_PIN == newDevDoxm->oxmSel) { - res = StartOwnershipTransfer(g_otmCtx, g_otmCtx->selectedDeviceInfo); - if(OC_STACK_OK != res) + OIC_LOG(ERROR, TAG, "The PIN number may incorrect."); + + memcpy(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)); + newDevDoxm->owned = false; + g_otmCtx->attemptCnt++; + + if(WRONG_PIN_MAX_ATTEMP > g_otmCtx->attemptCnt) + { + res = StartOwnershipTransfer(g_otmCtx, g_otmCtx->selectedDeviceInfo); + if(OC_STACK_OK != res) + { + SetResult(g_otmCtx, res); + OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer"); + } + } + else { - SetResult(g_otmCtx, res); - OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer"); + OIC_LOG(ERROR, TAG, "User has exceeded the number of authentication attempts."); + SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE); } } else { + OIC_LOG(ERROR, TAG, "Failed to establish secure session."); SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE); } } - else - { - SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE); - } } } } @@ -711,6 +730,46 @@ static OCStackApplicationResult OwnerCredentialHandler(void *ctx, OCDoHandle UNU { if(otmCtx && otmCtx->selectedDeviceInfo) { + //Close the temporal secure session to verify the owner credential + CAEndpoint_t* endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint; + endpoint->port = otmCtx->selectedDeviceInfo->securePort; + CAResult_t caResult = CACloseDtlsSession(endpoint); + if(CA_STATUS_OK != caResult) + { + OIC_LOG(ERROR, TAG, "Failed to close DTLS session"); + SetResult(otmCtx, caResult); + return OC_STACK_DELETE_TRANSACTION; + } + + /** + * If we select NULL cipher, + * client will select appropriate cipher suite according to server's cipher-suite list. + */ + caResult = CASelectCipherSuite(TLS_NULL_WITH_NULL_NULL); + if(CA_STATUS_OK != caResult) + { + OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL"); + SetResult(otmCtx, caResult); + return OC_STACK_DELETE_TRANSACTION; + } + + /** + * in case of random PIN based OxM, + * revert get_psk_info callback of tinyDTLS to use owner credential. + */ + if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel) + { + OicUuid_t emptyUuid = { .id={0}}; + SetUuidForRandomPinOxm(&emptyUuid); + + if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials)) + { + OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler."); + SetResult(otmCtx, OC_STACK_INVALID_CALLBACK); + return OC_STACK_DELETE_TRANSACTION; + } + } + //PUT /oic/sec/doxm [{ ..., "owned":"TRUE" }] res = PutOwnershipInformation(otmCtx); if(OC_STACK_OK != res) @@ -907,8 +966,13 @@ static OCStackResult PutOwnerCredential(OTMContext_t* otmCtx) OicSecCred_t newCredential; memcpy(&newCredential, ownerCredential, sizeof(OicSecCred_t)); newCredential.next = NULL; + + //Set subject ID as PT's ID memcpy(&(newCredential.subject), &credSubjectId, sizeof(OicUuid_t)); + //Fill private data as empty string + newCredential.privateData.data = NULL; + //Send owner credential to new device : PUT /oic/sec/cred [ owner credential ] secPayload->securityData = BinToCredJSON(&newCredential); if (NULL == secPayload->securityData) diff --git a/resource/csdk/security/src/credresource.c b/resource/csdk/security/src/credresource.c index ac172f755..4bc220b73 100644 --- a/resource/csdk/security/src/credresource.c +++ b/resource/csdk/security/src/credresource.c @@ -38,6 +38,10 @@ #include "iotvticalendar.h" #include "ocserverrequest.h" +#ifdef __WITH_DTLS__ +#include "global.h" +#endif //__WITH_DTLS__ + #ifdef WITH_ARDUINO #include #else @@ -306,8 +310,10 @@ OicSecCred_t * JSONToCredBin(const char * jsonStr) (cred->credType & SYMMETRIC_GROUP_KEY) || (cred->credType & PIN_PASSWORD)) { - VERIFY_NON_NULL(TAG, jsonObj, ERROR); - VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR); + if(jsonObj) + { + VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR); + } } #ifdef __WITH_X509__ else if (cred->credType & SIGNED_ASYMMETRIC_KEY) @@ -333,6 +339,10 @@ OicSecCred_t * JSONToCredBin(const char * jsonStr) } #endif // __WITH_X509__ } + else + { + cred->privateData.data = NULL; + } //PublicData is mandatory only for SIGNED_ASYMMETRIC_KEY credentials type. jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PUBLICDATA_NAME); @@ -662,29 +672,19 @@ OCStackResult RemoveAllCredentials(void) #ifdef __WITH_DTLS__ /** - * Internal function to verify recevied owner PSK. + * Internal function to fill private data of owner PSK. * - * @param receviedCred recevied Owner Credential from OBT(PT) + * @param receviedCred recevied owner credential from OBT(PT) * @param ownerAdd address of OBT(PT) * @param doxm current device's doxm resource * * @retval - * true valid ower psk - * false Invalid owner psk or failed to owner psk verification + * true successfully done and valid ower psk information + * false Invalid owner psk information or failed to owner psk generation */ -static bool isValidOwnerPSK(const OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr, +static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr, const OicSecDoxm_t* doxm) { - //Decode received PSK to verify OwnerPSKs match - uint32_t privLen = strlen(receviedCred->privateData.data); - size_t b64BufSize = B64DECODE_OUT_SAFESIZE((privLen + 1) * sizeof(char)); - uint8_t* decodeBuff = OICMalloc(b64BufSize); - VERIFY_NON_NULL(TAG, decodeBuff, ERROR); - uint32_t decodedSize = 0; - B64Result b64Ret = b64Decode(receviedCred->privateData.data, privLen, - decodeBuff, b64BufSize, &decodedSize); - VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR); - //Derive OwnerPSK locally const char* oxmLabel = GetOxmString(doxm->oxmSel); VERIFY_NON_NULL(TAG, oxmLabel, ERROR); @@ -697,20 +697,38 @@ static bool isValidOwnerPSK(const OicSecCred_t* receviedCred, const CAEndpoint_t ownerPSK, OWNER_PSK_LENGTH_128); VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR); - OIC_LOG_V(DEBUG, TAG, "Oxm Label = %s", oxmLabel); - OIC_LOG_V(DEBUG, TAG, "PSK size compare : %s", - OWNER_PSK_LENGTH_128 == decodedSize ? "TRUE" : "FALSE"); - OIC_LOG_V(DEBUG, TAG, "SubjectID compare = %s", - memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 ? - "TRUE" : "FALSE"); - OIC_LOG_V(DEBUG, TAG, "Owner PSK compare = %s", - memcmp(ownerPSK, decodeBuff, OWNER_PSK_LENGTH_128) == 0 ? "TRUE" : "FALSE"); - - //Verify OwnerPSKs match - return (OWNER_PSK_LENGTH_128 == decodedSize && - memcmp(ownerPSK, decodeBuff, OWNER_PSK_LENGTH_128) == 0 && - memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0); + OIC_LOG(DEBUG, TAG, "OwnerPSK dump :"); + OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128); + + //Generate owner credential based on recevied credential information + size_t b64BufSize = B64ENCODE_OUT_SAFESIZE(OWNER_PSK_LENGTH_128 * sizeof(char)); + uint8_t* encodeBuff = OICMalloc((b64BufSize + 1) * sizeof(char)); + VERIFY_NON_NULL(TAG, encodeBuff, ERROR); + uint32_t encodedSize = 0; + B64Result b64Ret = b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, + (char*)encodeBuff, b64BufSize + 1, &encodedSize); + VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR); + encodeBuff[encodedSize] = '\0'; + + //memory re-allocation for private data + OICFree(receviedCred->privateData.data); + receviedCred->privateData.data = (char*)OICMalloc((encodedSize + 1) * sizeof(char)); + VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR); + + //fill the base64 encoded private data + strncpy(receviedCred->privateData.data, (char*)encodeBuff, b64BufSize + 1); + + OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully"); + + //deallocate local memory + OICFree(encodeBuff); + + //Verify OwnerPSK information + return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 && + receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY); exit: + //receviedCred->privateData.data will be deallocated when deleting credential. + OICFree(encodeBuff); return false; } @@ -736,9 +754,14 @@ static OCEntityHandlerResult HandlePutRequest(const OCEntityHandlerRequest * ehR case SYMMETRIC_PAIR_WISE_KEY: { OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle; - if(isValidOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm)) + if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm)) { - OIC_LOG(ERROR, TAG, "OwnerPKS is matched"); + if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject)) + { + OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!"); + } + + OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully."); if(OC_STACK_OK == AddCredential(cred)) { ret = OC_EH_RESOURCE_CREATED; @@ -755,6 +778,44 @@ static OCEntityHandlerResult HandlePutRequest(const OCEntityHandlerRequest * ehR ret = OC_EH_ERROR; } + if(OC_EH_RESOURCE_CREATED == ret) + { + /** + * in case of random PIN based OxM, + * revert get_psk_info callback of tinyDTLS to use owner credential. + */ + if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel) + { + OicUuid_t emptyUuid = { .id={0}}; + SetUuidForRandomPinOxm(&emptyUuid); + + if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials)) + { + OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler."); + ret = OC_EH_ERROR; + break; + } + } + + //Select cipher suite to use owner PSK + if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false)) + { + OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite"); + ret = OC_EH_ERROR; + } + else + { + OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED"); + } + + if(CA_STATUS_OK != + CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256)) + { + OIC_LOG(ERROR, TAG, "Failed to select cipher suite"); + ret = OC_EH_ERROR; + } + } + break; } case SYMMETRIC_GROUP_KEY: @@ -774,6 +835,16 @@ static OCEntityHandlerResult HandlePutRequest(const OCEntityHandlerRequest * ehR break; } } + + if(OC_EH_RESOURCE_CREATED != ret) + { + /* + * If some error is occured while ownership transfer, + * ownership transfer related resource should be revert back to initial status. + */ + RestoreDoxmToInitState(); + RestorePstatToInitState(); + } } else { @@ -796,6 +867,15 @@ static OCEntityHandlerResult HandlePutRequest(const OCEntityHandlerRequest * ehR #endif//__WITH_DTLS__ } + if(OC_EH_RESOURCE_CREATED != ret) + { + if(OC_STACK_OK != RemoveCredential(&cred->subject)) + { + OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential"); + } + FreeCred(cred); + } + return ret; } @@ -812,7 +892,7 @@ static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * eh //discarded and the next available credId will be assigned //to it before getting appended to the existing credential //list and updating svr database. - ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR; + ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR; } return ret; diff --git a/resource/csdk/security/src/doxmresource.c b/resource/csdk/security/src/doxmresource.c index 22688d61a..30d3d9770 100644 --- a/resource/csdk/security/src/doxmresource.c +++ b/resource/csdk/security/src/doxmresource.c @@ -24,6 +24,7 @@ #include "cJSON.h" #include "resourcemanager.h" #include "doxmresource.h" +#include "pstatresource.h" #include "psinterface.h" #include "utlist.h" #include "srmresourcestrings.h" @@ -576,7 +577,6 @@ static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest */ caRes = CARegisterDTLSCredentialsHandler(GetDtlsPskForRandomPinOxm); VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR); - ehRet = OC_EH_OK; } else @@ -592,12 +592,6 @@ static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest //Save the owner's UUID to derive owner credential memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t)); -// OCServerRequest * request = (OCServerRequest *)ehRequest->requestHandle; -// //Generate new credential for provisioning tool -// ehRet = AddOwnerPSK((CAEndpoint_t*)(&request->devAddr), newDoxm, -// (uint8_t*)OXM_RANDOM_DEVICE_PIN, strlen(OXM_RANDOM_DEVICE_PIN)); -// VERIFY_SUCCESS(TAG, OC_EH_OK == ehRet, ERROR); - //Update new state in persistent storage if((UpdatePersistentStorage(gDoxm) == true)) { @@ -623,7 +617,7 @@ static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest { gDoxm->owned = true; // Update new state in persistent storage - if (true == UpdatePersistentStorage(gDoxm)) + if (UpdatePersistentStorage(gDoxm)) { ehRet = OC_EH_OK; } @@ -642,17 +636,11 @@ exit: "DOXM will be reverted."); /* - * If persistent storage update failed, revert back the state - * for global variable. + * If some error is occured while ownership transfer, + * ownership transfer related resource should be revert back to initial status. */ - gDoxm->owned = false; - gDoxm->oxmSel = OIC_JUST_WORKS; - memset(&(gDoxm->owner), 0, sizeof(OicUuid_t)); - - if(!UpdatePersistentStorage(gDoxm)) - { - OIC_LOG(ERROR, TAG, "Failed to revert DOXM in persistent storage"); - } + RestoreDoxmToInitState(); + RestorePstatToInitState(); } //Send payload to request originator @@ -813,6 +801,14 @@ OCStackResult InitDoxmResource() { gDoxm = GetDoxmDefault(); } + + //In case of the server is shut down unintentionally, we should initialize the owner + if(false == gDoxm->owned) + { + OicUuid_t emptyUuid = {.id={0}}; + memcpy(&gDoxm->owner, &emptyUuid, sizeof(OicUuid_t)); + } + ret = CheckDeviceID(); if (ret == OC_STACK_OK) { @@ -887,3 +883,25 @@ OCStackResult GetDoxmDevOwnerId(OicUuid_t *devOwner) } return retVal; } + +/** + * Function to restore doxm resurce to initial status. + * This function will use in case of error while ownership transfer + */ +void RestoreDoxmToInitState() +{ + if(gDoxm) + { + OIC_LOG(INFO, TAG, "DOXM resource will revert back to initial status."); + + OicUuid_t emptyUuid = {.id={0}}; + memcpy(&(gDoxm->owner), &emptyUuid, sizeof(OicUuid_t)); + gDoxm->owned = false; + gDoxm->oxmSel = OIC_JUST_WORKS; + + if(!UpdatePersistentStorage(gDoxm)) + { + OIC_LOG(ERROR, TAG, "Failed to revert DOXM in persistent storage"); + } + } +} diff --git a/resource/csdk/security/src/pstatresource.c b/resource/csdk/security/src/pstatresource.c index f5c47461b..4bada3105 100644 --- a/resource/csdk/security/src/pstatresource.c +++ b/resource/csdk/security/src/pstatresource.c @@ -24,6 +24,7 @@ #include "cJSON.h" #include "resourcemanager.h" #include "pstatresource.h" +#include "doxmresource.h" #include "psinterface.h" #include "utlist.h" #include "base64.h" @@ -48,7 +49,9 @@ static OicSecPstat_t gDefaultPstat = &gSm, // OicSecDpom_t *sm 0, // uint16_t commitHash }; + static OicSecPstat_t *gPstat = NULL; + static OCResourceHandle gPstatHandle = NULL; void DeletePstatBinData(OicSecPstat_t* pstat) @@ -190,6 +193,35 @@ exit: return pstat; } +/** + * Function to update persistent storage + */ +static bool UpdatePersistentStorage(OicSecPstat_t * pstat) +{ + bool bRet = false; + + if (pstat) + { + // Convert pstat data into JSON for update to persistent storage + char *jsonStr = BinToPstatJSON(pstat); + if (jsonStr) + { + cJSON *jsonPstat = cJSON_Parse(jsonStr); + OICFree(jsonStr); + + if (jsonPstat && + (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_PSTAT_NAME, jsonPstat))) + { + bRet = true; + } + cJSON_Delete(jsonPstat); + } + } + + return bRet; +} + + /** * The entity handler determines how to process a GET request. */ @@ -264,18 +296,22 @@ static OCEntityHandlerResult HandlePstatPutRequest(const OCEntityHandlerRequest } } // Convert pstat data into JSON for update to persistent storage - char *jsonStr = BinToPstatJSON(gPstat); - if (jsonStr) + if(UpdatePersistentStorage(gPstat)) { - cJSON *jsonPstat = cJSON_Parse(jsonStr); - OICFree(jsonStr); - if (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_PSTAT_NAME, jsonPstat)) - { - ehRet = OC_EH_OK; - } + ehRet = OC_EH_OK; } } exit: + if(OC_EH_OK != ehRet) + { + /* + * If some error is occured while ownership transfer, + * ownership transfer related resource should be revert back to initial status. + */ + RestoreDoxmToInitState(); + RestorePstatToInitState(); + } + //Send payload to request originator if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL)) { @@ -380,6 +416,7 @@ OCStackResult InitPstatResource() { gPstat = GetPstatDefault(); } + // Instantiate 'oic.sec.pstat' ret = CreatePstatResource(); @@ -402,3 +439,28 @@ OCStackResult DeInitPstatResource() return OCDeleteResource(gPstatHandle); } + +/** + * Function to restore pstat resurce to initial status. + * This function will use in case of error while ownership transfer + */ +void RestorePstatToInitState() +{ + if(gPstat) + { + OIC_LOG(INFO, TAG, "PSTAT resource will revert back to initial status."); + + gPstat->cm = NORMAL; + gPstat->tm = NORMAL; + gPstat->om = SINGLE_SERVICE_CLIENT_DRIVEN; + if(gPstat->sm && 0 < gPstat->smLen) + { + gPstat->sm[0] = SINGLE_SERVICE_CLIENT_DRIVEN; + } + + if(!UpdatePersistentStorage(gPstat)) + { + OIC_LOG(ERROR, TAG, "Failed to revert DOXM in persistent storage"); + } + } +}