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 <chuls.lee@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/5341
Reviewed-by: Randeep Singh <randeep.s@samsung.com>
Tested-by: Randeep Singh <randeep.s@samsung.com>
*/
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
}
*/
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
}
*/
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);
- }
}
}
}
{
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)
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)
#include "iotvticalendar.h"
#include "ocserverrequest.h"
+#ifdef __WITH_DTLS__
+#include "global.h"
+#endif //__WITH_DTLS__
+
#ifdef WITH_ARDUINO
#include <string.h>
#else
(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)
}
#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);
#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);
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;
}
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;
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:
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
{
#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;
}
//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;\r
+ ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
}
return ret;
#include "cJSON.h"
#include "resourcemanager.h"
#include "doxmresource.h"
+#include "pstatresource.h"
#include "psinterface.h"
#include "utlist.h"
#include "srmresourcestrings.h"
*/
caRes = CARegisterDTLSCredentialsHandler(GetDtlsPskForRandomPinOxm);
VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
-
ehRet = OC_EH_OK;
}
else
//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))
{
{
gDoxm->owned = true;
// Update new state in persistent storage
- if (true == UpdatePersistentStorage(gDoxm))
+ if (UpdatePersistentStorage(gDoxm))
{
ehRet = OC_EH_OK;
}
"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
{
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)
{
}
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");
+ }
+ }
+}
#include "cJSON.h"
#include "resourcemanager.h"
#include "pstatresource.h"
+#include "doxmresource.h"
#include "psinterface.h"
#include "utlist.h"
#include "base64.h"
&gSm, // OicSecDpom_t *sm
0, // uint16_t commitHash
};
+
static OicSecPstat_t *gPstat = NULL;
+
static OCResourceHandle gPstatHandle = NULL;
void DeletePstatBinData(OicSecPstat_t* pstat)
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.
*/
}
}
// 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))
{
{
gPstat = GetPstatDefault();
}
+
// Instantiate 'oic.sec.pstat'
ret = CreatePstatResource();
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");
+ }
+ }
+}