From c6d712a4477956c5533f6789bcb0b17b65b50b99 Mon Sep 17 00:00:00 2001 From: Jongmin Choi Date: Thu, 23 Jun 2016 15:46:27 +0900 Subject: [PATCH] Remote Reset Create Reset Profile and Remote Reset by Provisioning Tool Patch #2: Changes according to Ashwini's Comments Patch #3: RemoveACE prototype added to header file Change-Id: I6f4c443e8b54c5e0640da868cf7f2c5fbd4db78d Signed-off-by: Jongmin Choi Reviewed-on: https://gerrit.iotivity.org/gerrit/8915 Tested-by: jenkins-iotivity Reviewed-by: Randeep Singh --- .../csdk/security/include/internal/aclresource.h | 13 + .../csdk/security/include/internal/psinterface.h | 17 + .../security/include/internal/srmresourcestrings.h | 3 + .../include/internal/secureresourceprovider.h | 33 ++ .../provisioning/sample/provisioningclient.c | 80 +++- .../provisioning/src/ocprovisioningmanager.c | 47 ++ .../provisioning/src/secureresourceprovider.c | 515 +++++++++++++++++++++ resource/csdk/security/src/aclresource.c | 2 +- resource/csdk/security/src/psinterface.c | 307 +++++++++++- resource/csdk/security/src/pstatresource.c | 24 +- resource/csdk/security/src/srmresourcestrings.c | 3 + resource/csdk/stack/src/ocstack.c | 2 + 12 files changed, 1039 insertions(+), 7 deletions(-) diff --git a/resource/csdk/security/include/internal/aclresource.h b/resource/csdk/security/include/internal/aclresource.h index 2b83f81..7daf51f 100644 --- a/resource/csdk/security/include/internal/aclresource.h +++ b/resource/csdk/security/include/internal/aclresource.h @@ -63,6 +63,19 @@ const OicSecAce_t* GetACLResourceData(const OicUuid_t* subjectId, OicSecAce_t ** OCStackResult AclToCBORPayload(const OicSecAcl_t * acl, uint8_t **outPayload, size_t *size); /** + * This method removes ACE for the subject and resource from the ACL + * + * @param subject of the ACE + * @param resource of the ACE + * + * @return + * ::OC_STACK_RESOURCE_DELETED on success + * ::OC_STACK_NO_RESOURCE on failure to find the appropriate ACE + * ::OC_STACK_INVALID_PARAM on invalid parameter + */ +OCStackResult RemoveACE(const OicUuid_t * subject, const char * resource); + +/** * This function deletes ACL data. * * @param acl instance of @ref OicSecAcl_t structure to be deleted. diff --git a/resource/csdk/security/include/internal/psinterface.h b/resource/csdk/security/include/internal/psinterface.h index 34a7822..493690a 100644 --- a/resource/csdk/security/include/internal/psinterface.h +++ b/resource/csdk/security/include/internal/psinterface.h @@ -71,4 +71,21 @@ OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **dat */ OCStackResult UpdateSecureResourceInPS(const char* rsrcName, uint8_t* cborPayload, size_t size); +/** + * This method resets the secure resources according to the reset profile. + * + * @return ::OC_STACK_OK for Success, otherwise some error value + */ +OCStackResult ResetSecureResourceInPS(void); + +/** + * This method creates the reset profile from the persistent storage. + * The reset profile is the copy of the initial state of SVR resources + * when secure resources are initiated at first. + * In remote reset, the SVR will be reset according to the reset profile. + * + * @return ::OC_STACK_OK for Success, otherwise some error value + */ +OCStackResult CreateResetProfile(void); + #endif //IOTVT_SRM_PSI_H diff --git a/resource/csdk/security/include/internal/srmresourcestrings.h b/resource/csdk/security/include/internal/srmresourcestrings.h index 7e84a76..d9e8de8 100644 --- a/resource/csdk/security/include/internal/srmresourcestrings.h +++ b/resource/csdk/security/include/internal/srmresourcestrings.h @@ -89,6 +89,9 @@ extern const char * OIC_RSRC_TYPE_SEC_VER; extern const char * OIC_RSRC_VER_URI; extern const char * OIC_JSON_VER_NAME; +//reset profile +extern const char * OIC_JSON_RESET_PF_NAME; + extern const char * OIC_JSON_SUBJECT_NAME; extern const char * OIC_JSON_SUBJECTID_NAME; extern const char * OIC_JSON_RESOURCES_NAME; diff --git a/resource/csdk/security/provisioning/include/internal/secureresourceprovider.h b/resource/csdk/security/provisioning/include/internal/secureresourceprovider.h index fe4e546..5fbc284 100644 --- a/resource/csdk/security/provisioning/include/internal/secureresourceprovider.h +++ b/resource/csdk/security/provisioning/include/internal/secureresourceprovider.h @@ -152,6 +152,39 @@ OCStackResult SRPRemoveDevice(void* ctx, const OCProvisionDev_t* pTargetDev, OCProvisionResultCB resultCallback); +/* + * Function to sync-up credential and ACL of the target device. + * This function will remove credential and ACL of target device from all devices in subnet. + * + * @param[in] ctx Application context would be returned in result callback + * @param[in] waitTimeForOwnedDeviceDiscovery Maximum wait time for owned device discovery.(seconds) + * @param[in] pTargetDev Device information to be revoked. + * @param[in] resultCallback callback provided by API user, callback will be called when + * credential revocation is finished. + * when there is an error, this user callback is called immediately. + * @return OC_STACK_OK in case of success and other value otherwise. + * If OC_STACK_OK is returned, the caller of this API should wait for callback. + * OC_STACK_CONTINUE means operation is success but no request is need to be initiated. + */ +OCStackResult SRPSyncDevice(void* ctx, unsigned short waitTimeForOwnedDeviceDiscovery, + const OCProvisionDev_t* pTargetDev, OCProvisionResultCB resultCallback); + +/* + * Function for remote reset + * This function will send pstat POST(modify) message to the target device + * to change current mode to reset state in order to initiate remote reset. + * + * @param[in] pTargetDev Device information to be revoked. + * @param[in] resultCallback callback provided by API user, callback will be called when + * credential revocation is finished. + * when there is an error, this user callback is called immediately. + * @return OC_STACK_OK in case of success and other value otherwise. + * If OC_STACK_OK is returned, the caller of this API should wait for callback. + * OC_STACK_CONTINUE means operation is success but no request is need to be initiated. + */ +OCStackResult SRPResetDevice(const OCProvisionDev_t* pTargetDev, + OCProvisionResultCB resultCallback); + #ifdef __cplusplus } #endif diff --git a/resource/csdk/security/provisioning/sample/provisioningclient.c b/resource/csdk/security/provisioning/sample/provisioningclient.c index a22e393..a2dc06c 100644 --- a/resource/csdk/security/provisioning/sample/provisioningclient.c +++ b/resource/csdk/security/provisioning/sample/provisioningclient.c @@ -50,11 +50,12 @@ extern "C" #define _30_PROVIS_PAIR_DEVS_ 30 #define _31_PROVIS_CRED_ 31 #define _32_PROVIS_ACL_ 32 -#define _33_PROVIS_DP_ 33 +#define _33_PROVIS_DP_ 33 #define _34_CHECK_LINK_STATUS_ 34 #define _40_UNLINK_PAIR_DEVS_ 40 #define _50_REMOVE_SELEC_DEV_ 50 -#define _60_GET_CRED_ 60 +#define _51_RESET_SELEC_DEV_ 51 +#define _60_GET_CRED_ 60 #define _61_GET_ACL_ 61 #define _99_EXIT_PRVN_CLT_ 99 @@ -226,6 +227,20 @@ static void removeDeviceCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool g_doneCB = true; } +static void syncDeviceCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError) +{ + if(!hasError) + { + OIC_LOG_V(INFO, TAG, "Sync Device SUCCEEDED - ctx: %s", (char*) ctx); + } + else + { + OIC_LOG_V(ERROR, TAG, "Sync Device FAILED - ctx: %s", (char*) ctx); + printResultList((const OCProvisionResult_t*) arr, nOfRes); + } + g_doneCB = true; +} + static void inputPinCB(char* pin, size_t len) { if(!pin || OXM_RANDOM_PIN_SIZE>=len) @@ -1031,6 +1046,58 @@ static int removeDevice(void) return 0; } +static int resetDevice(void) +{ + // check |own_list| for removing device + if (!g_own_list || 1 > g_own_cnt) + { + printf(" > Owned Device List, to Reset Device, is Empty\n"); + printf(" > Please Register Unowned Devices first, with [20] Menu\n"); + return 0; + } + + // select device for removing it + int dev_num = 0; + for ( ; ; ) + { + printf(" > Enter Device Number, for Resetting Device: "); + for (int ret = 0; 1 != ret; ) + { + ret = scanf("%d", &dev_num); + for ( ; 0x20 <= getchar() ; ); // for removing overflow garbages + // '0x20 <= code' is character region + } + if (0 < dev_num && g_own_cnt >= dev_num) + { + break; + } + printf(" Entered Wrong Number. Please Enter Again\n"); + } + + g_doneCB = false; + printf(" Resetting Selected Owned Device..\n"); + + OCStackResult rst = OCResetDevice((void *) g_ctx, DISCOVERY_TIMEOUT, + getDevInst((const OCProvisionDev_t *) g_own_list, dev_num), syncDeviceCB); + if (OC_STACK_OK != rst) + { + OIC_LOG_V(ERROR, TAG, "OCResetDevice API error: %d", rst); + return -1; + } + + if (waitCallbackRet()) // input |g_doneCB| flag implicitly + { + OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error"); + return -1; + } + + // display the removed result + printf(" > Reset Selected Owned Device SUCCEEDED\n"); + printf(" > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n"); + + return 0; +} + static OicSecAcl_t* createAcl(const int dev_num) { if(0>=dev_num || g_own_cntdoxm->deviceID, &subID); + if(OC_STACK_OK != ret) + { + OIC_LOG(ERROR, TAG, "SendDeleteACLRequest : Failed to canonical UUID encoding"); + return OC_STACK_ERROR; + } + + char reqBuf[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0}; + int snRet = 0; + //coaps://0.0.0.0:5684/oic/sec/acl?subjectuuid=(Canonical ENCODED UUID) + snRet = snprintf(reqBuf, sizeof(reqBuf), SRP_FORM_DELETE_CREDENTIAL, destDev->endpoint.addr, + destDev->securePort, OIC_RSRC_ACL_URI, OIC_JSON_SUBJECTID_NAME, subID); + OICFree(subID); + if (snRet < 0) + { + OIC_LOG_V(ERROR, TAG, "SendDeleteACLRequest : Error (snprintf) %d\n", snRet); + return OC_STACK_ERROR; + } + else if ((size_t)snRet >= sizeof(reqBuf)) + { + OIC_LOG_V(ERROR, TAG, "SendDeleteACLRequest : Truncated (snprintf) %d\n", snRet); + return OC_STACK_ERROR; + } + + OCCallbackData cbData; + memset(&cbData, 0, sizeof(cbData)); + cbData.context = ctx; + cbData.cb = respHandler; + cbData.cd = NULL; + OIC_LOG_V(INFO, TAG, "URI: %s",reqBuf); + + OIC_LOG(DEBUG, TAG, "Sending remove ACL request to resource server"); + + ret = OCDoResource(NULL, OC_REST_DELETE, reqBuf, + &destDev->endpoint, NULL, + CT_ADAPTER_IP, OC_HIGH_QOS, &cbData, NULL, 0); + if (OC_STACK_OK != ret) + { + OIC_LOG_V(ERROR, TAG, "SendDeleteACLRequest : Error in OCDoResource %d", ret); + } + OIC_LOG(DEBUG, TAG, "OUT SendDeleteACLRequest"); + + return ret; +} + /** * Callback handler of unlink second device. * @@ -1450,6 +1508,34 @@ static void registerResultForRemoveDevice(RemoveData_t *removeData, OicUuid_t *p } } +static void registerResultForResetDevice(RemoveData_t *removeData, OicUuid_t *pLinkedDevId, + OCStackResult stackresult, bool hasError) +{ + OIC_LOG_V(INFO, TAG, "Inside registerResultForResetDevice removeData->numOfResults is %zu\n", + removeData->numOfResults + 1); + if (pLinkedDevId) + { + memcpy(removeData->removeRes[(removeData->numOfResults)].deviceId.id, + &pLinkedDevId->id, sizeof(pLinkedDevId->id)); + } + else + { + memset(removeData->removeRes[(removeData->numOfResults)].deviceId.id, + 0, sizeof(pLinkedDevId->id) ); + } + removeData->removeRes[(removeData->numOfResults)].res = stackresult; + removeData->hasError = hasError; + ++(removeData->numOfResults); + + // If we get suffcient result from linked devices, we have to call user callback and do free + if (removeData->sizeOfResArray == removeData->numOfResults) + { + removeData->resultCallback(removeData->ctx, removeData->numOfResults, removeData->removeRes, + removeData->hasError); + DeleteRemoveData_t(removeData); + } +} + /** * Callback handler of unlink first device. * @@ -1529,6 +1615,171 @@ static OCStackApplicationResult SRPRemoveDeviceCB(void *delDevCtx, OCDoHandle ha return OC_STACK_DELETE_TRANSACTION; } +/** + * Callback handler of reset device. + * + * @param[in] ctx ctx value passed to callback from calling function. + * @param[in] handle handle to an invocation + * @param[in] clientResponse Response from queries to remote servers. + * @return OC_STACK_DELETE_TRANSACTION to delete the transaction + * and OC_STACK_KEEP_TRANSACTION to keep it. + */ +static OCStackApplicationResult SRPSyncDeviceCredCB(void *delDevCtx, OCDoHandle handle, + OCClientResponse *clientResponse) +{ + //Update the delete credential into delete device context + //Save the deleted status in delDevCtx + (void)handle; + OIC_LOG_V(INFO, TAG, "Inside SRPSyncDeviceCredCB."); + VERIFY_NON_NULL(TAG, delDevCtx, ERROR, OC_STACK_DELETE_TRANSACTION); + OCStackResult res = OC_STACK_ERROR; + + RemoveData_t* removeData = (RemoveData_t*)delDevCtx; + OCProvisionDev_t * pTargetDev = PMCloneOCProvisionDev(removeData->revokeTargetDev); + OCProvisionResultCB resultCallback = removeData->resultCallback; + if (clientResponse) + { + OicUuid_t revDevUuid = {.id={0}}; + if(UUID_LENGTH == clientResponse->identity.id_length) + { + memcpy(revDevUuid.id, clientResponse->identity.id, sizeof(revDevUuid.id)); + if (OC_STACK_RESOURCE_DELETED == clientResponse->result) + { + res = PDMUnlinkDevices(&removeData->revokeTargetDev->doxm->deviceID, &revDevUuid); + if (OC_STACK_OK != res) + { + OIC_LOG(ERROR, TAG, "PDMSetLinkStale() FAIL: PDB is an obsolete one."); + registerResultForResetDevice(removeData, &revDevUuid, + OC_STACK_INCONSISTENT_DB, true); + + return OC_STACK_DELETE_TRANSACTION; + } + + registerResultForResetDevice(removeData, &revDevUuid, + OC_STACK_RESOURCE_DELETED, false); + } + else + { + registerResultForResetDevice(removeData, &revDevUuid, + clientResponse->result, false); + OIC_LOG(ERROR, TAG, "Unexpected result from DELETE credential request!"); + } + } + else + { + OIC_LOG_V(WARNING, TAG, "Incorrect length of device UUID was sent from %s:%d", + clientResponse->devAddr.addr, clientResponse->devAddr.port); + + if (OC_STACK_RESOURCE_DELETED == clientResponse->result) + { + /** + * Since server's credential was deleted, + * register result as OC_STACK_INCONSISTENT_DB with NULL UUID. + */ + OIC_LOG_V(ERROR, TAG, "But server's credential was deleted."); + registerResultForResetDevice(removeData, NULL, OC_STACK_INCONSISTENT_DB, true); + } + else + { + registerResultForResetDevice(removeData, NULL, clientResponse->result, true); + } + } + } + else + { + registerResultForResetDevice(removeData, NULL, OC_STACK_ERROR, true); + OIC_LOG(ERROR, TAG, "SRPSyncDevice received Null clientResponse"); + } + + SRPResetDevice(pTargetDev, resultCallback); + + return OC_STACK_DELETE_TRANSACTION; +} + +/** + * Callback handler of reset device sync-up + * + * @param[in] ctx ctx value passed to callback from calling function. + * @param[in] handle handle to an invocation + * @param[in] clientResponse Response from queries to remote servers. + * @return OC_STACK_DELETE_TRANSACTION to delete the transaction + * and OC_STACK_KEEP_TRANSACTION to keep it. + */ +static OCStackApplicationResult SRPSyncDeviceACLCB(void *ctx, OCDoHandle handle, + OCClientResponse *clientResponse) +{ + return OC_STACK_DELETE_TRANSACTION; +} + +/** + * Callback handler of device remote reset. + * + * @param[in] ctx ctx value passed to callback from calling function. + * @param[in] handle handle to an invocation + * @param[in] clientResponse Response from queries to remote servers. + * @return OC_STACK_DELETE_TRANSACTION to delete the transaction + * and OC_STACK_KEEP_TRANSACTION to keep it. + */ +static OCStackApplicationResult SRPResetDeviceCB(void *ctx, OCDoHandle handle, + OCClientResponse *clientResponse) +{ + OIC_LOG(DEBUG, TAG, "IN SRPResetDeviceCB"); + if(OC_STACK_OK == clientResponse->result) + { + OIC_LOG(DEBUG, TAG, "Change Target Device Pstat Cm SUCCEEDED"); + } + + // Delete Cred and ACL related to the target device. + const OicSecCred_t *cred = NULL; + OCProvisionDev_t * pTargetDev = (OCProvisionDev_t *)ctx; + cred = GetCredResourceData(&pTargetDev->doxm->deviceID); + if (cred == NULL) + { + OIC_LOG(ERROR, TAG, "OCResetDevice : Failed to get credential of target device."); + goto error; + } + + OCStackResult res = RemoveCredential(&cred->subject); + if (res != OC_STACK_RESOURCE_DELETED && res != OC_STACK_NO_RESOURCE) + { + OIC_LOG(ERROR, TAG, "OCResetDevice : Failed to remove credential."); + goto error; + } + + res = RemoveACE(&cred->subject, NULL); + if (res != OC_STACK_RESOURCE_DELETED && res != OC_STACK_NO_RESOURCE) + { + OIC_LOG(ERROR, TAG, "OCResetDevice : Failed to remove ACL."); + goto error; + } + if (OC_STACK_OK != PDMDeleteDevice(&pTargetDev->doxm->deviceID)) + { + OIC_LOG(ERROR, TAG, "OCResetDevice : Failed to delete device from PDM"); + } + + //Close the DTLS session of the reset device. + CAEndpoint_t* endpoint = (CAEndpoint_t *)&clientResponse->devAddr; + CAResult_t caResult = CACloseDtlsSession(endpoint); + if(CA_STATUS_OK != caResult) + { + OIC_LOG_V(WARNING, TAG, "OCResetDevice : Failed to close DTLS session : %d", caResult); + } + + /** + * If there is no linked device, PM does not send any request. + * So we should directly invoke the result callback to inform the result of OCResetDevice. + */ + if(OC_STACK_NO_RESOURCE == res) + { + res = OC_STACK_OK; + } + +error: + OICFree(pTargetDev); + return OC_STACK_DELETE_TRANSACTION; + +} + static OCStackResult GetListofDevToReqDeleteCred(const OCProvisionDev_t* pRevokeTargetDev, OCProvisionDev_t* pOwnedDevList, OCUuidList_t* pLinkedUuidList, @@ -1728,6 +1979,270 @@ error: return res; } +/* + * Function to sync-up credential and ACL of the target device. + * This function will remove credential and ACL of target device from all devices in subnet. + * + * @param[in] ctx Application context would be returned in result callback + * @param[in] waitTimeForOwnedDeviceDiscovery Maximum wait time for owned device discovery.(seconds) + * @param[in] pTargetDev Device information to be revoked. + * @param[in] resultCallback callback provided by API user, callback will be called when + * credential revocation is finished. + * when there is an error, this user callback is called immediately. + * @return OC_STACK_OK in case of success and other value otherwise. + * If OC_STACK_OK is returned, the caller of this API should wait for callback. + * OC_STACK_CONTINUE means operation is success but no request is need to be initiated. + */ +OCStackResult SRPSyncDevice(void* ctx, unsigned short waitTimeForOwnedDeviceDiscovery, + const OCProvisionDev_t* pTargetDev, OCProvisionResultCB resultCallback) +{ + OIC_LOG(INFO, TAG, "IN SRPSyncDevice"); + if (!pTargetDev || 0 == waitTimeForOwnedDeviceDiscovery) + { + OIC_LOG(INFO, TAG, "SRPSyncDevice : NULL parameters"); + return OC_STACK_INVALID_PARAM; + } + if (!resultCallback) + { + OIC_LOG(INFO, TAG, "SRPSyncDevice : NULL Callback"); + return OC_STACK_INVALID_CALLBACK; + } + + // Declare variables in here to handle error cases with goto statement. + OCProvisionDev_t* pOwnedDevList = NULL; + OCProvisionDev_t* pLinkedDevList = NULL; + RemoveData_t* removeData = NULL; + + //1. Find all devices that has a credential of the revoked device + OCUuidList_t* pLinkedUuidList = NULL; + size_t numOfDevices = 0; + OCStackResult res = OC_STACK_ERROR; + res = PDMGetLinkedDevices(&pTargetDev->doxm->deviceID, &pLinkedUuidList, &numOfDevices); + if (OC_STACK_OK != res) + { + OIC_LOG(ERROR, TAG, "SRPSyncDevice : Failed to get linked devices information"); + return res; + } + // if there is no related device, we can skip further process. + if (0 == numOfDevices) + { + OIC_LOG(DEBUG, TAG, "SRPSyncDevice : No linked device found."); + res = OC_STACK_CONTINUE; + goto error; + } + + //2. Find owned device from the network + res = PMDeviceDiscovery(waitTimeForOwnedDeviceDiscovery, true, &pOwnedDevList); + if (OC_STACK_OK != res) + { + OIC_LOG(ERROR, TAG, "SRPSyncDevice : Failed to PMDeviceDiscovery"); + goto error; + } + + //3. Make a list of devices to send DELETE credential request + // by comparing owned devices from provisioning database with mutlicast discovery result. + size_t numOfLinkedDev = 0; + res = GetListofDevToReqDeleteCred(pTargetDev, pOwnedDevList, pLinkedUuidList, + &pLinkedDevList, &numOfLinkedDev); + if (OC_STACK_OK != res) + { + OIC_LOG(ERROR, TAG, "SRPSyncDevice : GetListofDevToReqDeleteCred() failed"); + goto error; + } + if (0 == numOfLinkedDev) // This case means, there is linked device but it's not alive now. + { // So we don't have to send request message. + OIC_LOG(DEBUG, TAG, "SRPSyncDevice : No alived & linked device found."); + res = OC_STACK_CONTINUE; + goto error; + } + + // 4. Prepare RemoveData Context data. + removeData = (RemoveData_t*)OICCalloc(1, sizeof(RemoveData_t)); + if (!removeData) + { + OIC_LOG(ERROR, TAG, "SRPSyncDevice : Failed to memory allocation"); + res = OC_STACK_NO_MEMORY; + goto error; + } + + removeData->revokeTargetDev = PMCloneOCProvisionDev(pTargetDev); + if (!removeData->revokeTargetDev) + { + OIC_LOG(ERROR, TAG, "SRPSyncDevice : PMCloneOCProvisionDev Failed"); + res = OC_STACK_NO_MEMORY; + goto error; + } + + removeData->removeRes = + (OCProvisionResult_t*)OICCalloc(numOfLinkedDev, sizeof(OCProvisionResult_t)); + if (!removeData->removeRes) + { + OIC_LOG(ERROR, TAG, "SRPSyncDevice : Failed to allocate memory"); + res = OC_STACK_NO_MEMORY; + goto error; + } + + removeData->ctx = ctx; + removeData->linkedDevList = pLinkedDevList; + removeData->resultCallback = resultCallback; + removeData->numOfResults = 0; + removeData->sizeOfResArray = numOfLinkedDev; + removeData->hasError = false; + + // 5. Send DELETE credential request to linked devices. + OCProvisionDev_t *curDev = NULL, *tmpDev = NULL; + OCStackResult totalRes = OC_STACK_ERROR; /* variable for checking request is sent or not */ + LL_FOREACH_SAFE(pLinkedDevList, curDev, tmpDev) + { + res = SendDeleteACLRequest((void*)removeData, &SRPSyncDeviceACLCB, + removeData->revokeTargetDev, curDev); + if (OC_STACK_OK != res) + { + OIC_LOG_V(ERROR, TAG, "SRPSyncDevice : Fail to send the DELETE ACL request to\ + %s:%u", curDev->endpoint.addr, curDev->endpoint.port); + goto error; + } + res = SendDeleteCredentialRequest((void*)removeData, &SRPSyncDeviceCredCB, + removeData->revokeTargetDev, curDev); + if (OC_STACK_OK != res) + { + OIC_LOG_V(ERROR, TAG, "SRPSyncDevice : Fail to send the DELETE credential request to\ + %s:%u", curDev->endpoint.addr, curDev->endpoint.port); + totalRes = OC_STACK_ERROR; + } + else + { + totalRes = OC_STACK_OK; // This means at least one request is successfully sent. + } + } + + PDMDestoryOicUuidLinkList(pLinkedUuidList); //TODO: Modify API name to have unified convention. + PMDeleteDeviceList(pOwnedDevList); + OIC_LOG(INFO, TAG, "OUT SRPSyncDevice"); + + return totalRes; // Caller of this API should wait callback if totalRes == OC_STACK_OK. + +error: + PDMDestoryOicUuidLinkList(pLinkedUuidList); + PMDeleteDeviceList(pOwnedDevList); + PMDeleteDeviceList(pLinkedDevList); + if (removeData) + { + OICFree(removeData->revokeTargetDev); + OICFree(removeData->removeRes); + OICFree(removeData); + } + OIC_LOG(INFO, TAG, "OUT ERROR case SRPSyncDevice"); + return res; +} + +/* + * Function for remote reset + * This function will send pstat PUT message to the target device to initiate remote reset. + * + * @param[in] pTargetDev Device information to be revoked. + * @param[in] resultCallback callback provided by API user, callback will be called when + * credential revocation is finished. + * when there is an error, this user callback is called immediately. + * @return OC_STACK_OK in case of success and other value otherwise. + * If OC_STACK_OK is returned, the caller of this API should wait for callback. + * OC_STACK_CONTINUE means operation is success but no request is need to be initiated. + */ +OCStackResult SRPResetDevice(const OCProvisionDev_t* pTargetDev, + OCProvisionResultCB resultCallback) +{ + OIC_LOG(INFO, TAG, "IN SRPResetDevice"); + if (!pTargetDev) + { + OIC_LOG(INFO, TAG, "SRPResetDevice : NULL parameters"); + return OC_STACK_INVALID_PARAM; + } + if (!resultCallback) + { + OIC_LOG(INFO, TAG, "SRPResetDevice : NULL Callback"); + return OC_STACK_INVALID_CALLBACK; + } + + OCStackResult res = OC_STACK_ERROR; + OicSecPstat_t * pstat = (OicSecPstat_t *) OICCalloc(1, sizeof(OicSecPstat_t)); + if (!pstat) + { + OIC_LOG(ERROR, TAG, "Failed to allocate memory"); + return OC_STACK_NO_MEMORY; + } + + pstat->cm = (OicSecDpm_t) 1; + pstat->isOp = 0; + memcpy(pstat->deviceID.id, pTargetDev->doxm->deviceID.id, sizeof(OicUuid_t)); + pstat->tm = (OicSecDpm_t) 2; + pstat->om = (OicSecDpom_t) 0; + pstat->smLen = 1; + pstat->sm = (OicSecDpom_t *) OICCalloc(pstat->smLen, sizeof(OicSecDpom_t)); + if (NULL == pstat->sm) + { + OIC_LOG(ERROR, TAG, "Failed to allocate memory"); + OICFree(pstat); + return OC_STACK_NO_MEMORY; + } + pstat->sm[0] = (OicSecDpom_t) 3; + + OCSecurityPayload * secPayload = (OCSecurityPayload *) OICCalloc(1, sizeof(OCSecurityPayload)); + if (!secPayload) + { + OIC_LOG(ERROR, TAG, "Failed to allocate memory"); + res = OC_STACK_NO_MEMORY; + goto error; + } + secPayload->base.type = PAYLOAD_TYPE_SECURITY; + + if (OC_STACK_OK != PstatToCBORPayload(pstat, &(secPayload->securityData), + &(secPayload->payloadSize))) + { + OCPayloadDestroy((OCPayload *) secPayload); + OIC_LOG(ERROR, TAG, "Failed to PstatToCBORPayload"); + res = OC_STACK_NO_MEMORY; + goto error; + } + OIC_LOG(DEBUG, TAG, "Created payload for pstat set"); + OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize); + + char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0}; + if (!PMGenerateQuery(true, + pTargetDev->endpoint.addr, + pTargetDev->securePort, + pTargetDev->connType, + query, sizeof(query), OIC_RSRC_PSTAT_URI)) + { + OIC_LOG(ERROR, TAG, "SRPResetDevice : Failed to generate query"); + OCPayloadDestroy((OCPayload *) secPayload); + res = OC_STACK_ERROR; + goto error; + } + OIC_LOG_V(DEBUG, TAG, "Query=%s", query); + + OCProvisionDev_t * targetDev = PMCloneOCProvisionDev(pTargetDev); + OCCallbackData cbData = { .context = NULL, .cb = NULL, .cd = NULL }; + cbData.cb = &SRPResetDeviceCB; + cbData.context = (void *) targetDev; + cbData.cd = NULL; + OCMethod method = OC_REST_POST; + OCDoHandle handle = NULL; + OIC_LOG(DEBUG, TAG, "Sending PSTAT info to resource server"); + res = OCDoResource(&handle, method, query, + &targetDev->endpoint, (OCPayload *)secPayload, + targetDev->connType, OC_LOW_QOS, &cbData, NULL, 0);\ + if (OC_STACK_OK != res) + { + OIC_LOG(ERROR, TAG, "OCStack resource error"); + } + +error: + OICFree(pstat->sm); + OICFree(pstat); + OIC_LOG(INFO, TAG, "OUT SRPResetDevice"); + return res; +} + /** * Internal Function to store results in result array during GetCredResourceCB. */ diff --git a/resource/csdk/security/src/aclresource.c b/resource/csdk/security/src/aclresource.c index 9537efc..e3aef30 100644 --- a/resource/csdk/security/src/aclresource.c +++ b/resource/csdk/security/src/aclresource.c @@ -949,7 +949,7 @@ exit: * ::OC_STACK_NO_RESOURCE on failure to find the appropriate ACE * ::OC_STACK_INVALID_PARAM on invalid parameter */ -static OCStackResult RemoveACE(const OicUuid_t * subject, const char * resource) +OCStackResult RemoveACE(const OicUuid_t * subject, const char * resource) { OIC_LOG(DEBUG, TAG, "IN RemoveACE"); diff --git a/resource/csdk/security/src/psinterface.c b/resource/csdk/security/src/psinterface.c index d263892..7043f81 100644 --- a/resource/csdk/security/src/psinterface.c +++ b/resource/csdk/security/src/psinterface.c @@ -36,6 +36,8 @@ #include "secureresourcemanager.h" #include "srmresourcestrings.h" #include "srmutility.h" +#include "pstatresource.h" +#include "doxmresource.h" #define TAG "SRM-PSI" @@ -180,6 +182,7 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa uint8_t *svcCbor = NULL; uint8_t *credCbor = NULL; uint8_t *pconfCbor = NULL; + uint8_t *resetPfCbor = NULL; int64_t cborEncoderResult = CborNoError; OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize); @@ -192,6 +195,7 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa size_t svcCborLen = 0; size_t credCborLen = 0; size_t pconfCborLen = 0; + size_t resetPfCborLen = 0; // Gets each secure virtual resource from persistent storage // this local scoping intended, for destroying large cbor instances after use @@ -244,13 +248,20 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa cborFindResult = cbor_value_dup_byte_string(&curVal, &pconfCbor, &pconfCborLen, NULL); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PCONF Name Value."); } + cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal); + if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal)) + { + cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value."); + } } // Updates the added |psPayload| with the existing secure virtual resource(s) // this local scoping intended, for destroying large cbor instances after use { size_t size = aclCborLen + pstatCborLen + doxmCborLen + amaclCborLen - + svcCborLen + credCborLen + pconfCborLen + psSize + 255; + + svcCborLen + credCborLen + pconfCborLen + resetPfCborLen + + psSize + 255; // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending outPayload = (uint8_t *) OICCalloc(1, size); @@ -317,6 +328,13 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pconfCbor, pconfCborLen); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Value."); } + if (strcmp(OIC_JSON_RESET_PF_NAME, rsrcName) && resetPfCborLen) + { + cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_RESET_PF_NAME, strlen(OIC_JSON_RESET_PF_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Name."); + cborEncoderResult |= cbor_encode_byte_string(&secRsrc, resetPfCbor, resetPfCborLen); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Value."); + } cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array."); @@ -348,7 +366,7 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa if (outPayload && outSize) { - OIC_LOG_V(DEBUG, TAG, "Writting in the file: %zu", outSize); + OIC_LOG_V(DEBUG, TAG, "Writing in the file: %zu", outSize); OCPersistentStorage* ps = SRMGetPersistentStorageHandler(); if (ps) { @@ -386,5 +404,290 @@ exit: OICFree(svcCbor); OICFree(credCbor); OICFree(pconfCbor); + OICFree(resetPfCbor); + return ret; +} + +/** + * Resets the Secure Virtual Resource(s). + * This function reads the Reset Profile + * and resets the secure virtual resources accordingly. + * + * @return OCStackResult - result of updating Secure Virtual Resource(s) + */ +OCStackResult ResetSecureResourceInPS(void) +{ + OIC_LOG(DEBUG, TAG, "ResetSecureResourceInPS IN"); + + size_t dbSize = 0; + size_t outSize = 0; + uint8_t *dbData = NULL; + uint8_t *outPayload = NULL; + + uint8_t *aclCbor = NULL; + uint8_t *pstatCbor = NULL; + uint8_t *doxmCbor = NULL; + uint8_t *resetPfCbor = NULL; + + int64_t cborEncoderResult = CborNoError; + OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize); + + if(dbData && dbSize) + { + size_t aclCborLen = 0; + size_t pstatCborLen = 0; + size_t doxmCborLen = 0; + size_t resetPfCborLen = 0; + + // Gets the reset profile from persistent storage + { + CborParser parser; // will be initialized in |cbor_parser_init| + CborValue cbor; // will be initialized in |cbor_parser_init| + cbor_parser_init(dbData, dbSize, 0, &parser, &cbor); + CborValue curVal = {0}; + CborError cborFindResult = CborNoError; + cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal); + if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal)) + { + cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value."); + } + } + + // Gets each secure virtual resource from the reset profile + { + CborParser parser; // will be initialized in |cbor_parser_init| + CborValue cbor; // will be initialized in |cbor_parser_init| + cbor_parser_init(resetPfCbor, resetPfCborLen, 0, &parser, &cbor); + CborValue curVal = {0}; + CborError cborFindResult = CborNoError; + cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal); + if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal)) + { + cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value."); + } + cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal); + if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal)) + { + cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value."); + } + cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal); + if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal)) + { + cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value."); + } + } + + { + size_t size = aclCborLen + pstatCborLen + doxmCborLen + resetPfCborLen + 255; + // This added '255' is arbitrary value added to cover the name of the resource, map addition, and ending + + outPayload = (uint8_t *) OICCalloc(1, size); + VERIFY_NON_NULL(TAG, outPayload, ERROR); + CborEncoder encoder; + cbor_encoder_init(&encoder, outPayload, size, 0); + CborEncoder secRsrc; + cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength); + + cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name."); + cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value."); + + cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name."); + cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value."); + + cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Name."); + cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Value."); + + cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_RESET_PF_NAME, strlen(OIC_JSON_RESET_PF_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Name."); + cborEncoderResult |= cbor_encode_byte_string(&secRsrc, resetPfCbor, resetPfCborLen); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Value."); + + cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array."); + outSize = encoder.ptr - outPayload; + } + + if (outPayload && outSize) + { + OIC_LOG_V(DEBUG, TAG, "Writing in the file: %zu", outSize); + OCPersistentStorage *ps = SRMGetPersistentStorageHandler(); + if (ps) + { + FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb"); + if (fp) + { + size_t numberItems = ps->write(outPayload, 1, outSize, fp); + if (outSize == numberItems) + { + OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", outSize); + ret= OC_STACK_OK; + } + else + { + OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", numberItems); + } + ps->close(fp); + } + else + { + OIC_LOG(ERROR, TAG, "File open failed."); + } + + } + } + } + + SRMDeInitSecureResources(); + InitSecureResources(); + OIC_LOG(DEBUG, TAG, "ResetSecureResourceINPS OUT"); + +exit: + OICFree(dbData); + OICFree(outPayload); + OICFree(aclCbor); + OICFree(pstatCbor); + OICFree(doxmCbor); + OICFree(resetPfCbor); +} + +/** + * Creates Reset Profile from the initial secure virtual resources. + * This function copies the secure resources + * and creates the Reset Profile in the Persistent Storage. + * Device ID in doxm and pstat are left empty as it will be renewed after reset. + * + * @return OCStackResult - result of updating Secure Virtual Resource(s) + */ +OCStackResult CreateResetProfile(void) +{ + OIC_LOG(DEBUG, TAG, "CreateResetProfile IN"); + + size_t dbSize = 0; + uint8_t *dbData = NULL; + + uint8_t *aclCbor = NULL; + uint8_t *pstatCbor = NULL; + uint8_t *doxmCbor = NULL; + uint8_t *resetPfCbor = NULL; + + OCStackResult ret = OC_STACK_ERROR; + int64_t cborEncoderResult = CborNoError; + ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize); + if (dbData && dbSize) + { + size_t aclCborLen = 0; + size_t pstatCborLen = 0; + size_t doxmCborLen = 0; + size_t resetPfCborLen = 0; + + { + CborParser parser; + CborValue cbor; + cbor_parser_init(dbData, dbSize, 0, &parser, &cbor); + CborValue curVal = {0}; + CborError cborFindResult = CborNoError; + cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal); + if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal)) + { + cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value."); + } + cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal); + if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal)) + { + cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value."); + } + cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal); + if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal)) + { + cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value."); + } + } + + // Set the Device ID in doxm and pstat to empty + if (pstatCbor) + { + OicSecPstat_t *pstat = NULL; + ret = CBORPayloadToPstat(pstatCbor, pstatCborLen, &pstat); + OICFree(pstatCbor); + pstatCbor = NULL; + pstatCborLen = 0; + + OicUuid_t emptyUuid = {.id = {0} }; + memcpy(&pstat->deviceID, &emptyUuid, sizeof(OicUuid_t)); + memcpy(&pstat->rownerID, &emptyUuid, sizeof(OicUuid_t)); + + ret = PstatToCBORPayload(pstat, &pstatCbor, &pstatCborLen); + OICFree(pstat); + } + if (doxmCbor) + { + OicSecDoxm_t *doxm = NULL; + ret = CBORPayloadToDoxm(doxmCbor, doxmCborLen, &doxm); + OICFree(doxmCbor); + doxmCbor = NULL; + doxmCborLen = 0; + + OicUuid_t emptyUuid = {.id = {0} }; + memcpy(&doxm->deviceID, &emptyUuid, sizeof(OicUuid_t)); + memcpy(&doxm->rownerID, &emptyUuid, sizeof(OicUuid_t)); + + ret = DoxmToCBORPayload(doxm, &doxmCbor, &doxmCborLen); + OICFree(doxm); + } + + { + size_t size = aclCborLen + pstatCborLen + doxmCborLen + 255; + resetPfCbor = (uint8_t *) OICCalloc(1, size); + VERIFY_NON_NULL(TAG, resetPfCbor, ERROR); + CborEncoder encoder; // will be initialized in |cbor_parser_init| + cbor_encoder_init(&encoder, resetPfCbor, size, 0); + CborEncoder secRsrc; // will be initialized in |cbor_encoder_create_map| + cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength); + + cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name."); + cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value."); + + cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name."); + cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value."); + + cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name."); + cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value."); + + cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array."); + resetPfCborLen = encoder.ptr - resetPfCbor; + } + + UpdateSecureResourceInPS(OIC_JSON_RESET_PF_NAME, resetPfCbor, resetPfCborLen); + + } + OIC_LOG(DEBUG, TAG, "CreateResetProfile OUT"); + +exit: + OICFree(dbData); + OICFree(aclCbor); + OICFree(pstatCbor); + OICFree(doxmCbor); + OICFree(resetPfCbor); return ret; } + diff --git a/resource/csdk/security/src/pstatresource.c b/resource/csdk/security/src/pstatresource.c index 050c497..3d49a4b 100644 --- a/resource/csdk/security/src/pstatresource.c +++ b/resource/csdk/security/src/pstatresource.c @@ -448,7 +448,12 @@ static OCEntityHandlerResult HandlePstatPostRequest(const OCEntityHandlerRequest VERIFY_NON_NULL(TAG, pstat, ERROR); if (OC_STACK_OK == ret) { - if (false == (pstat->cm & TAKE_OWNER) && false == pstat->isOp) + if (true == (pstat->cm & RESET) && false == pstat->isOp) + { + gPstat->cm = pstat->cm; + OIC_LOG(INFO, TAG, "State changed to Ready for Reset"); + } + else if (false == (pstat->cm & TAKE_OWNER) && false == pstat->isOp) { gPstat->cm = pstat->cm; OIC_LOG (INFO, TAG, "State changed to Ready for Provisioning"); @@ -482,6 +487,23 @@ static OCEntityHandlerResult HandlePstatPostRequest(const OCEntityHandlerRequest { ehRet = OC_EH_OK; } + if (true == (pstat->cm & RESET)) + { + if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0)) + { + ehRet = OC_EH_ERROR; + OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePstatPostRequest"); + DeletePstatBinData(pstat); + return ehRet; + } + ret = ResetSecureResourceInPS(); + if (OC_STACK_OK == ret) + { + ehRet = OC_EH_OK; + } + DeletePstatBinData(pstat); + return ehRet; + } } } exit: diff --git a/resource/csdk/security/src/srmresourcestrings.c b/resource/csdk/security/src/srmresourcestrings.c index 5414ef6..20f54bf 100644 --- a/resource/csdk/security/src/srmresourcestrings.c +++ b/resource/csdk/security/src/srmresourcestrings.c @@ -83,6 +83,9 @@ const char * OIC_RSRC_TYPE_SEC_VER = "oic.r.ver"; const char * OIC_RSRC_VER_URI = "/oic/sec/ver"; const char * OIC_JSON_VER_NAME = "ver"; +//reset profile +const char * OIC_JSON_RESET_PF_NAME = "resetpf"; + const char * OIC_JSON_SUBJECT_NAME = "subject"; const char * OIC_JSON_RESOURCES_NAME = "resources"; const char * OIC_JSON_AMSS_NAME = "amss"; diff --git a/resource/csdk/stack/src/ocstack.c b/resource/csdk/stack/src/ocstack.c index 963c6aa..bcd6f44 100644 --- a/resource/csdk/stack/src/ocstack.c +++ b/resource/csdk/stack/src/ocstack.c @@ -51,6 +51,7 @@ #include "logger.h" #include "ocserverrequest.h" #include "secureresourcemanager.h" +#include "psinterface.h" #include "doxmresource.h" #include "cacommon.h" #include "cainterface.h" @@ -4150,6 +4151,7 @@ OCStackResult initResources() if(result == OC_STACK_OK) { + CreateResetProfile(); result = OCCreateResource(&deviceResource, OC_RSRVD_RESOURCE_TYPE_DEVICE, OC_RSRVD_INTERFACE_DEFAULT, -- 2.7.4