-Patch 1: To check security version, oic.sec.ver is created.
-Patch 2: Add commit description
-Patch 3.4: Apply Randeep's comment
-Patch 5: Rebase
-Patch 6-7: Fixed build error on Arduino
-Patch 8: Modify version data type of provisioningmanager
-Patch 9: Rebase
-Patch 10: Update device type
-Patch 11: 1) Modify to start version discovery in succession after secure port discovery
2) Separate each discovery(secureport, version) process as internal function.
-Patch 12: Add null check and remove unnecessary local variables.
-Patch 13: Modify the API description according to patch 11.
-Patch 14: Update according to SVACE report
-Patch 15: Rebase
It is clone https://gerrit.iotivity.org/gerrit/#/c/6059/ of
security-cbor-conv-1.1 branch after resolved conflict.
Change-Id: I0de72d8cc35acb048acfb7136769f3c84c72c152
Signed-off-by: Jongsung Lee <js126.lee@samsung.com>
Signed-off-by: Chul Lee <chuls.lee@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/6105
Reviewed-by: Yonggoo Kang <ygace.kang@samsung.com>
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Randeep Singh <randeep.s@samsung.com>
OCSRM_SRC + 'svcresource.c',
OCSRM_SRC + 'pconfresource.c',
OCSRM_SRC + 'dpairingresource.c',
+ OCSRM_SRC + 'verresource.c',
OCSRM_SRC + 'policyengine.c',
OCSRM_SRC + 'psinterface.c',
OCSRM_SRC + 'srmresourcestrings.c',
OCSRM_SRC + 'pconfresource.c',
OCSRM_SRC + 'dpairingresource.c',
OCSRM_SRC + 'policyengine.c',
+ OCSRM_SRC + 'verresource.c',
OCSRM_SRC + 'psinterface.c',
OCSRM_SRC + 'srmresourcestrings.c',
OCSRM_SRC + 'srmutility.c',
extern const char * OIC_RSRC_DPAIRING_URI;
extern const char * OIC_JSON_DPAIRING_NAME;
+//version
+extern const char * OIC_RSRC_TYPE_SEC_VER;
+extern const char * OIC_RSRC_VER_URI;
+extern const char * OIC_JSON_VER_NAME;
+
extern const char * OIC_JSON_SUBJECT_NAME;
extern const char * OIC_JSON_SUBJECTID_NAME;
extern const char * OIC_JSON_RESOURCES_NAME;
extern const char * OIC_JSON_ROWNERID_NAME;
extern const char * OIC_JSON_ENCODING_NAME;
extern const char * OIC_JSON_DATA_NAME;
+extern const char * OIC_JSON_SEC_V_NAME;
extern const char * OIC_JSON_EMPTY_STRING;
--- /dev/null
+/* *****************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * *****************************************************************/
+
+#ifndef IOTVT_SRM_VER_H
+#define IOTVT_SRM_VER_H
+
+#include "octypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initialize VER resource by loading data from persistent storage.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
+ */
+OCStackResult InitVerResource();
+
+/**
+ * Perform cleanup for VER resources.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
+ */
+OCStackResult DeInitVerResource();
+
+/**
+ * This method is used by SRM to retrieve VER resource data..
+ *
+ * @return reference to @ref OicSecDoxm_t, binary format of Doxm resource data.
+ */
+const OicSecVer_t* GetVerResourceData();
+
+/**
+ * This method converts CBOR VER into binary VER.
+ * The CBOR VER can be from persistent database or
+ * or received as PUT/POST request.
+ *
+ * @param cborPayload is a ver data in cbor.
+ * @note Caller needs to invoke OCFree after done using the return pointer.
+ * @param doxm is the pointer to @ref OicSecVer_t.
+ * @param size of the cborPayload. In case value is 0, CBOR_SIZE value is assigned.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
+ */
+OCStackResult CBORPayloadToVer(const uint8_t *cborPayload, size_t size,
+ OicSecVer_t **ver);
+
+/**
+ * This method converts VER data into CBOR format.
+ * Caller needs to invoke 'free' when finished done using
+ * return string.
+ *
+ * @param ver Pointer to @ref OicSecVer_t.
+ * @note Caller needs to invoke OCFree after done using the return pointer.
+ * @param cborPayload is the payload of the cbor.
+ * @param cborSize is the size of the cbor payload. Passed parameter should not be NULL.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
+ */
+OCStackResult VerToCBORPayload(const OicSecVer_t * ver, uint8_t **cborPayload,
+ size_t *cborSize);
+
+/**
+ * Get the security version.
+ *
+ * @return the version string of security.
+ */
+const char* GetSecVersion();
+
+/** This function deallocates the memory for OicSecVer_t .
+ *
+ * @param ver is the pointer to @ref OicSecVer_t.
+ */
+void DeleteVerBinData(OicSecVer_t* ver);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //IOTVT_SRM_VER_H
\ No newline at end of file
OicUuid_t rowner; // 2:R:S:Y:oic.uuid
};
+#define MAX_VERSION_LEN 16 // Security Version length. i.e., 00.00.000 + reserved space
+
+/**
+ * @brief security version data type
+ */
+typedef struct OicSecVer OicSecVer_t;
+
+/**
+ * @brief /oic/sec/ver (Security Version) data type
+ */
+struct OicSecVer
+{
+ // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
+ char secv[MAX_VERSION_LEN]; // 0:R:S:Y:String
+ OicUuid_t deviceID; // 1:R:S:Y:oic.uuid
+};
+
#ifdef __cplusplus
}
#endif
* OCMode.\r
*\r
* @param[in] timeout Timeout in seconds, value till which function will listen to responses from\r
- * client before returning the list of devices.\r
+ * server before returning the list of devices.\r
* @param[out] ppList List of candidate devices to be provisioned\r
* @return OTM_SUCCESS in case of success and other value otherwise.\r
*/\r
* all the device in subnet which are owned by calling provisioning client.\r
*\r
* @param[in] timeout Timeout in seconds, value till which function will listen to responses from\r
- * client before returning the list of devices.\r
+ * server before returning the list of devices.\r
* @param[out] ppList List of device owned by provisioning tool.\r
* @return OTM_SUCCESS in case of success and other value otherwise.\r
*/\r
OicSecDoxm_t *doxm; /**< Pointer to target's doxm resource. **/
OCConnectivityType connType; /**< Connectivity type of endpoint */
uint16_t securePort; /**< secure port **/
+ char secVer[MAX_VERSION_LEN]; /**< security version **/
DeviceStatus devStatus; /**< status of device **/
struct OCProvisionDev *next; /**< Next pointer. **/
}OCProvisionDev_t;
{\r
- "acl": {\r
+ "acl": {
"aclist": {\r
"aces": [\r
{\r
}\r
],\r
"permission": 6\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/ver",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
}\r
]\r
},\r
{\r
- "acl": {\r
+ "acl": {
"aclist": {\r
"aces": [\r
{\r
}\r
],\r
"permission": 6\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/ver",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
}\r
]\r
},\r
"rowneruuid": "72616E64-5069-6E44-6576-557569643030",\r
"dpc": true\r
}\r
-}
\ No newline at end of file
+}
* OCMode.
*
* @param[in] timeout Timeout in seconds, value till which function will listen to responses from
- * client before returning the list of devices.
+ * server before returning the list of devices.
* @param[out] ppList List of candidate devices to be provisioned
* @return OTM_SUCCESS in case of success and other value otherwise.
*/
* all the device in subnet which are owned by calling provisioning client.
*
* @param[in] timeout Timeout in seconds, value till which function will listen to responses from
- * client before returning the list of devices.
+ * server before returning the list of devices.
* @param[out] ppList List of device owned by provisioning tool.
* @return OTM_SUCCESS in case of success and other value otherwise.
*/
#include "srmresourcestrings.h" //@note: SRM's internal header
#include "doxmresource.h" //@note: SRM's internal header
#include "pstatresource.h" //@note: SRM's internal header
+#include "verresource.h" //@note: SRM's internal header
#include "pmtypes.h"
#include "pmutility.h"
bool isOwnedDiscovery;
} DiscoveryInfo;
+/*
+ * Function to discover secre port information through unicast
+ *
+ * @param[in] discoveryInfo The pointer of discovery information to matain result of discovery
+ * @param[in] clientResponse Response information(It will contain payload)
+ *
+ * @return OC_STACK_OK on success otherwise error.
+ */
+static OCStackResult SecurePortDiscovery(DiscoveryInfo* discoveryInfo,
+ const OCClientResponse *clientResponse);
+
+/*
+ * Function to discover security version information through unicast
+ *
+ * @param[in] discoveryInfo The pointer of discovery information to matain result of discovery
+ * @param[in] clientResponse Response information(It will contain payload)
+ *
+ * @return OC_STACK_OK on success otherwise error.
+ */
+static OCStackResult SecurityVersionDiscovery(DiscoveryInfo* discoveryInfo,
+ const OCClientResponse *clientResponse);
+
+/**
+ * Callback handler for PMDeviceDiscovery API.
+ *
+ * @param[in] ctx User context
+ * @param[in] handle Handler for response
+ * @param[in] clientResponse Response information (It will contain payload)
+ * @return OC_STACK_KEEP_TRANSACTION to keep transaction and
+ * OC_STACK_DELETE_TRANSACTION to delete it.
+ */
+static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
+ OCClientResponse *clientResponse);
+
+/**
+ * Callback handler for getting secure port information using /oic/res discovery.
+ *
+ * @param[in] ctx user context
+ * @param[in] handle Handle for response
+ * @param[in] clientResponse Response information(It will contain payload)
+ *
+ * @return OC_STACK_KEEP_TRANSACTION to keep transaction and
+ * OC_STACK_DELETE_TRANSACTION to delete it.
+ */
+static OCStackApplicationResult SecurePortDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
+ OCClientResponse *clientResponse);
+
+/**
+ * Callback handler for security version discovery.
+ *
+ * @param[in] ctx User context
+ * @param[in] handle Handler for response
+ * @param[in] clientResponse Response information (It will contain payload)
+ * @return OC_STACK_KEEP_TRANSACTION to keep transaction and
+ * OC_STACK_DELETE_TRANSACTION to delete it.
+ */
+static OCStackApplicationResult SecVersionDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
+ OCClientResponse *clientResponse);
+
/**
* Function to search node in linked list that matches given IP and port.
*
ptr->next = NULL;
ptr->connType = connType;
ptr->devStatus = DEV_STATUS_ON; //AddDevice is called when discovery(=alive)
+ OICStrcpy(ptr->secVer, strlen("0.0.0"), "0.0.0"); // version initialization
LL_PREPEND(*ppDevicesList, ptr);
}
}
/**
+ * Function to set security version information from the given list of devices.
+ *
+ * @param[in] pList List of OCProvisionDev_t.
+ * @param[in] addr address of target device.
+ * @param[in] port port of remote server.
+ * @param[in] secVer security version information.
+ *
+ * @return OC_STACK_OK for success and errorcode otherwise.
+ */
+OCStackResult UpdateSecVersionOfDevice(OCProvisionDev_t **ppDevicesList, const char *addr,
+ uint16_t port, const char* secVer)
+{
+ if (NULL == secVer)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OCProvisionDev_t *ptr = GetDevice(ppDevicesList, addr, port);
+
+ if(!ptr)
+ {
+ OIC_LOG(ERROR, TAG, "Can not find device information in the discovery device list");
+ return OC_STACK_ERROR;
+ }
+
+ OICStrcpy(ptr->secVer, strlen(secVer), secVer);
+
+ return OC_STACK_OK;
+}
+
+/**
* This function deletes list of provision target devices
*
* @param[in] pDevicesList List of OCProvisionDev_t.
newDev->doxm->oxm = NULL;
}
+ if (0 == strlen(src->secVer))
+ {
+ OICStrcpy(newDev->secVer, strlen("0.0.0"), "0.0.0");
+ }
+ else
+ {
+ OICStrcpy(newDev->secVer, strlen(src->secVer), src->secVer);
+ }
+
newDev->securePort = src->securePort;
newDev->devStatus = src->devStatus;
newDev->connType = src->connType;
return true;
}
-/**
- * Callback handler for getting secure port information using /oic/res discovery.
- *
- * @param[in] ctx user context
- * @param[in] handle Handle for response
- * @param[in] clientResponse Response information(It will contain payload)
- *
- * @return OC_STACK_KEEP_TRANSACTION to keep transaction and
- * OC_STACK_DELETE_TRANSACTION to delete it.
- */
+static OCStackApplicationResult SecurityVersionDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
+ OCClientResponse *clientResponse)
+{
+ if (ctx == NULL)
+ {
+ OIC_LOG(ERROR, TAG, "Lost List of device information");
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+ (void)UNUSED;
+ if (clientResponse)
+ {
+ if (NULL == clientResponse->payload)
+ {
+ OIC_LOG(INFO, TAG, "Skiping Null payload");
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+ if (OC_STACK_OK != clientResponse->result)
+ {
+ OIC_LOG(INFO, TAG, "Error in response");
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+ else
+ {
+ if (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)
+ {
+ OIC_LOG(INFO, TAG, "Unknown payload type");
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ OicSecVer_t *ptrVer = NULL;
+ uint8_t *payload = ((OCSecurityPayload*)clientResponse->payload)->securityData1;
+ size_t size = ((OCSecurityPayload*)clientResponse->payload)->payloadSize;
+ OCStackResult res = CBORPayloadToVer(payload, size, &ptrVer);
+ if ((NULL == ptrVer) && (OC_STACK_OK != res))
+ {
+ OIC_LOG(INFO, TAG, "Ignoring malformed CBOR");
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+ else
+ {
+ OIC_LOG(DEBUG, TAG, "Successfully converted ver cbor to bin.");
+
+ //If this is owend device discovery we have to filter out the responses.
+ DiscoveryInfo* pDInfo = (DiscoveryInfo*)ctx;
+ res = UpdateSecVersionOfDevice(pDInfo->ppDevicesList, clientResponse->devAddr.addr,
+ clientResponse->devAddr.port, ptrVer->secv);
+ if (OC_STACK_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "Error while getting security version.");
+ DeleteVerBinData(ptrVer);
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ OIC_LOG(INFO, TAG, "= Discovered security version =");
+ OIC_LOG_V(DEBUG, TAG, "IP %s", clientResponse->devAddr.addr);
+ OIC_LOG_V(DEBUG, TAG, "PORT %d", clientResponse->devAddr.port);
+ OIC_LOG_V(DEBUG, TAG, "VERSION %s", ptrVer->secv);
+
+ OIC_LOG(INFO, TAG, "Exiting SecVersionDiscoveryHandler.");
+ DeleteVerBinData(ptrVer);
+ }
+
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+ }
+ else
+ {
+ OIC_LOG(INFO, TAG, "Skiping Null response");
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
static OCStackApplicationResult SecurePortDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse)
{
}
DiscoveryInfo* pDInfo = (DiscoveryInfo*)ctx;
- OCProvisionDev_t **ppDevicesList = pDInfo->ppDevicesList;
-
- OCStackResult res = UpdateSecurePortOfDevice(ppDevicesList, clientResponse->devAddr.addr,
+ OCStackResult res = UpdateSecurePortOfDevice(pDInfo->ppDevicesList,
+ clientResponse->devAddr.addr,
clientResponse->devAddr.port, securePort);
if (OC_STACK_OK != res)
{
OIC_LOG(ERROR, TAG, "Error while getting secure port.");
return OC_STACK_DELETE_TRANSACTION;
}
+
+ res = SecurityVersionDiscovery(pDInfo, clientResponse);
+ if(OC_STACK_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to SecurityVersionDiscovery");
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
OIC_LOG(INFO, TAG, "Exiting SecurePortDiscoveryHandler.");
}
{
OIC_LOG(INFO, TAG, "Skiping Null response");
}
+
return OC_STACK_DELETE_TRANSACTION;
}
-/**
- * Callback handler for PMDeviceDiscovery API.
- *
- * @param[in] ctx User context
- * @param[in] handle Handler for response
- * @param[in] clientResponse Response information (It will contain payload)
- * @return OC_STACK_KEEP_TRANSACTION to keep transaction and
- * OC_STACK_DELETE_TRANSACTION to delete it.
- */
static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse)
{
DeleteDoxmBinData(ptrDoxm);
return OC_STACK_KEEP_TRANSACTION;
}
- char rsrc_uri[MAX_URI_LENGTH+1] = {0};
- int wr_len = snprintf(rsrc_uri, sizeof(rsrc_uri), "%s?%s=%s",
- OC_RSRVD_WELL_KNOWN_URI, OC_RSRVD_RESOURCE_TYPE, OIC_RSRC_TYPE_SEC_DOXM);
- if(wr_len <= 0 || (size_t)wr_len >= sizeof(rsrc_uri))
- {
- OIC_LOG(ERROR, TAG, "rsrc_uri_string_print failed");
- return OC_STACK_ERROR;
- }
- //Try to the unicast discovery to getting secure port
- char query[MAX_URI_LENGTH+MAX_QUERY_LENGTH+1] = {0};
- if(!PMGenerateQuery(false,
- clientResponse->devAddr.addr, clientResponse->devAddr.port,
- clientResponse->connType,
- query, sizeof(query), rsrc_uri))
- {
- OIC_LOG(ERROR, TAG, "DeviceDiscoveryHandler : Failed to generate query");
- return OC_STACK_KEEP_TRANSACTION;
- }
- OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
-
- OCCallbackData cbData;
- cbData.cb = &SecurePortDiscoveryHandler;
- cbData.context = ctx;
- cbData.cd = NULL;
- OCStackResult ret = OCDoResource(NULL, OC_REST_DISCOVER, query, 0, 0,
- clientResponse->connType, OC_LOW_QOS, &cbData, NULL, 0);
- // TODO: Should we use the default secure port in case of error?
- if(OC_STACK_OK != ret)
+
+ res = SecurePortDiscovery(pDInfo, clientResponse);
+ if(OC_STACK_OK != res)
{
- OIC_LOG(ERROR, TAG, "Failed to Secure Port Discovery");
+ OIC_LOG(ERROR, TAG, "Failed to SecurePortDiscovery");
+ DeleteDoxmBinData(ptrDoxm);
return OC_STACK_KEEP_TRANSACTION;
}
- else
- {
- OIC_LOG_V(INFO, TAG, "OCDoResource with [%s] Success", query);
- }
+
OIC_LOG(INFO, TAG, "Exiting ProvisionDiscoveryHandler.");
}
return res;
}
+static OCStackResult SecurePortDiscovery(DiscoveryInfo* discoveryInfo,
+ const OCClientResponse *clientResponse)
+{
+ OIC_LOG(DEBUG, TAG, "IN SecurePortDiscovery");
+
+ if(NULL == discoveryInfo || NULL == clientResponse)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ char rsrc_uri[MAX_URI_LENGTH+1] = {0};
+ int wr_len = snprintf(rsrc_uri, sizeof(rsrc_uri), "%s?%s=%s",
+ OC_RSRVD_WELL_KNOWN_URI, OC_RSRVD_RESOURCE_TYPE, OIC_RSRC_TYPE_SEC_DOXM);
+ if(wr_len <= 0 || (size_t)wr_len >= sizeof(rsrc_uri))
+ {
+ OIC_LOG(ERROR, TAG, "rsrc_uri_string_print failed");
+ return OC_STACK_ERROR;
+ }
+ //Try to the unicast discovery to getting secure port
+ char query[MAX_URI_LENGTH+MAX_QUERY_LENGTH+1] = {0};
+ if(!PMGenerateQuery(false,
+ clientResponse->devAddr.addr, clientResponse->devAddr.port,
+ clientResponse->connType,
+ query, sizeof(query), rsrc_uri))
+ {
+ OIC_LOG(ERROR, TAG, "SecurePortDiscovery : Failed to generate query");
+ return OC_STACK_ERROR;
+ }
+ OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+ OCCallbackData cbData;
+ cbData.cb = &SecurePortDiscoveryHandler;
+ cbData.context = (void*)discoveryInfo;
+ cbData.cd = NULL;
+ OCStackResult ret = OCDoResource(NULL, OC_REST_DISCOVER, query, 0, 0,
+ clientResponse->connType, OC_LOW_QOS, &cbData, NULL, 0);
+ if(OC_STACK_OK != ret)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to Secure Port Discovery");
+ return ret;
+ }
+ else
+ {
+ OIC_LOG_V(INFO, TAG, "OCDoResource with [%s] Success", query);
+ }
+
+ OIC_LOG(DEBUG, TAG, "OUT SecurePortDiscovery");
+
+ return ret;
+}
+
+static OCStackResult SecurityVersionDiscovery(DiscoveryInfo* discoveryInfo,
+ const OCClientResponse *clientResponse)
+{
+ OIC_LOG(DEBUG, TAG, "IN SecurityVersionDiscovery");
+
+ if(NULL == discoveryInfo || NULL == clientResponse)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ //Try to the unicast discovery to getting security version
+ char query[MAX_URI_LENGTH+MAX_QUERY_LENGTH+1] = {0};
+ if(!PMGenerateQuery(false,
+ clientResponse->devAddr.addr, clientResponse->devAddr.port,
+ clientResponse->connType,
+ query, sizeof(query), OIC_RSRC_VER_URI))
+ {
+ OIC_LOG(ERROR, TAG, "SecurityVersionDiscovery : Failed to generate query");
+ return OC_STACK_ERROR;
+ }
+ OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+ OCCallbackData cbData;
+ cbData.cb = &SecurityVersionDiscoveryHandler;
+ cbData.context = (void*)discoveryInfo;
+ cbData.cd = NULL;
+ OCStackResult ret = OCDoResource(NULL, OC_REST_DISCOVER, query, 0, 0,
+ clientResponse->connType, OC_LOW_QOS, &cbData, NULL, 0);
+ if(OC_STACK_OK != ret)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to Security Version Discovery");
+ return ret;
+ }
+ else
+ {
+ OIC_LOG_V(INFO, TAG, "OCDoResource with [%s] Success", query);
+ }
+
+ OIC_LOG(DEBUG, TAG, "OUT SecurityVersionDiscovery");
+
+ return ret;
+}
+
/**
* Function to print OCProvisionDev_t for debug purpose.
*
#include "pconfresource.h"
#include "dpairingresource.h"
//#endif // DIRECT_PAIRING
+#include "verresource.h"
#define TAG "SRM-RM"
ret = InitDpairingResource();
}
//#endif // DIRECT_PAIRING
+ if(OC_STACK_OK == ret)
+ {
+ ret = InitVerResource();
+ }
if(OC_STACK_OK != ret)
{
//TODO: Update the default behavior if one of the SVR fails
DeInitPconfResource();
DeInitDpairingResource();
//#endif // DIRECT_PAIRING
+ DeInitVerResource();
return OC_STACK_OK;
}
OIC_RSRC_PSTAT_URI,
OIC_RSRC_PCONF_URI,
OIC_RSRC_DPAIRING_URI,
+ OIC_RSRC_VER_URI,
};
// Remove query from Uri for resource string comparison
const char * OIC_RSRC_DPAIRING_URI = "/oic/sec/dpairing";
const char * OIC_JSON_DPAIRING_NAME = "dpairing";
+//version
+const char * OIC_RSRC_TYPE_SEC_VER = "oic.sec.ver";
+const char * OIC_RSRC_VER_URI = "/oic/sec/ver";
+const char * OIC_JSON_VER_NAME = "ver";
const char * OIC_JSON_SUBJECT_NAME = "subject";
const char * OIC_JSON_RESOURCES_NAME = "resources";
const char * OIC_JSON_ROWNERID_NAME = "rowneruuid";
const char * OIC_JSON_ENCODING_NAME = "encoding";
const char * OIC_JSON_DATA_NAME = "data";
+const char * OIC_JSON_SEC_V_NAME = "secv";
const char * OIC_JSON_EMPTY_STRING = "";
--- /dev/null
+/* *****************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * *****************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#include "ocstack.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "logger.h"
+#include "payload_logging.h"
+#include "ocpayload.h"
+#include "cainterface.h"
+#include "ocserverrequest.h"
+#include "resourcemanager.h"
+#include "verresource.h"
+#include "doxmresource.h"
+#include "psinterface.h"
+#include "srmresourcestrings.h"
+#include "securevirtualresourcetypes.h"
+#include "srmutility.h"
+
+#define TAG "SEC-VER"
+
+/** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
+ * The value of payload size is increased until reaching belox max cbor size. */
+static const uint8_t CBOR_SIZE = 255;
+
+/** Max cbor size payload. */
+static const uint16_t CBOR_MAX_SIZE = 4400;
+
+/** VER Map size - Number of mandatory items. */
+static const uint8_t VER_MAP_SIZE = 2;
+
+static OCResourceHandle gVerHandle = NULL;
+
+/** Security version is mapped with iotivity release version */
+const char* SECURITY_VERSION = IOTIVITY_VERSION;
+
+static OicSecVer_t gVer =
+{
+ {0}, /* char *secv */
+ {.id = {0}}, /* OicUuid_t deviceID */
+};
+
+void DeleteVerBinData(OicSecVer_t* ver)
+{
+ if (ver)
+ {
+ //Clean ver itself
+ OICFree(ver);
+ }
+}
+
+OCStackResult VerToCBORPayload(const OicSecVer_t *ver, uint8_t **payload, size_t *size)
+{
+ if (NULL == ver || NULL == payload || NULL != *payload || NULL == size)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+ size_t cborLen = *size;
+ if (0 == cborLen)
+ {
+ cborLen = CBOR_SIZE;
+ }
+ *payload = NULL;
+ *size = 0;
+
+ OCStackResult ret = OC_STACK_ERROR;
+
+ CborEncoder encoder = { {.ptr = NULL }, .end = 0 };
+ CborEncoder verMap = { {.ptr = NULL }, .end = 0 };
+
+ int64_t cborEncoderResult = CborNoError;
+ uint8_t mapSize = VER_MAP_SIZE;
+ char* strUuid = NULL;
+
+ uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
+ VERIFY_NON_NULL(TAG, outPayload, ERROR);
+ cbor_encoder_init(&encoder, outPayload, cborLen, 0);
+
+ cborEncoderResult |= cbor_encoder_create_map(&encoder, &verMap, mapSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Ver Map.");
+
+ //SecV -- Mandatory
+ cborEncoderResult |= cbor_encode_text_string(&verMap, OIC_JSON_SEC_V_NAME,
+ strlen(OIC_JSON_SEC_V_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SecV Tag.");
+ cborEncoderResult |= cbor_encode_text_string(&verMap, ver->secv, strlen(ver->secv));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SecV Value.");
+
+ //DeviceId -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&verMap, OIC_JSON_DEVICE_ID_NAME,
+ strlen(OIC_JSON_DEVICE_ID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Tag.");
+ ret = ConvertUuidToStr(&ver->deviceID, &strUuid);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
+ cborEncoderResult = cbor_encode_text_string(&verMap, strUuid, strlen(strUuid));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Value.");
+ OICFree(strUuid);
+ strUuid = NULL;
+
+
+ // Close ver(first) container
+ cborEncoderResult |= cbor_encoder_close_container(&encoder, &verMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing VerMap.");
+
+ if (CborNoError == cborEncoderResult)
+ {
+ *size = encoder.ptr - outPayload;
+ *payload = outPayload;
+ ret = OC_STACK_OK;
+ }
+exit:
+ if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
+ {
+ OIC_LOG(DEBUG, TAG, "Memory getting reallocated.");
+ // reallocate and try again!
+ OICFree(outPayload);
+ // Since the allocated initial memory failed, double the memory.
+ cborLen += encoder.ptr - encoder.end;
+ OIC_LOG_V(DEBUG, TAG, "Ver reallocation size : %zd.", cborLen);
+ cborEncoderResult = CborNoError;
+ ret = VerToCBORPayload(ver, payload, &cborLen);
+ *size = cborLen;
+ }
+
+ if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
+ {
+ OICFree(outPayload);
+ outPayload = NULL;
+ *payload = NULL;
+ *size = 0;
+ ret = OC_STACK_ERROR;
+ }
+
+ return ret;
+}
+
+OCStackResult CBORPayloadToVer(const uint8_t *cborPayload, size_t size,
+ OicSecVer_t **secVer)
+{
+ if (NULL == cborPayload || NULL == secVer || NULL != *secVer)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OCStackResult ret = OC_STACK_ERROR;
+ *secVer = NULL;
+ char *strUuid = NULL;
+
+ CborParser parser = { .end = NULL};
+ CborError cborFindResult = CborNoError;
+ int cborLen = (size == 0) ? CBOR_SIZE : size;
+ size_t len = 0;
+ CborValue verCbor = { .parser = NULL };
+ cbor_parser_init(cborPayload, cborLen, 0, &parser, &verCbor);
+ CborValue verMap = { .parser = NULL };
+ OicSecVer_t *ver = (OicSecVer_t *)OICCalloc(1, sizeof(OicSecVer_t));
+ VERIFY_NON_NULL(TAG, ver, ERROR);
+
+
+ cborFindResult = cbor_value_map_find_value(&verCbor, OIC_JSON_SEC_V_NAME, &verMap);
+ if (CborNoError == cborFindResult && cbor_value_is_text_string(&verMap))
+ {
+ char *version = NULL;
+ cborFindResult = cbor_value_dup_text_string(&verMap, &version, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Security Version Value.");
+ memcpy(ver->secv, version, len);
+ OICFree(version);
+ }
+
+ cborFindResult = cbor_value_map_find_value(&verCbor, OIC_JSON_DEVICE_ID_NAME, &verMap);
+ if (CborNoError == cborFindResult && cbor_value_is_text_string(&verMap))
+ {
+ cborFindResult = cbor_value_dup_text_string(&verMap, &strUuid , &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Device Id Value.");
+ ret = ConvertStrToUuid(strUuid , &ver->deviceID);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+ OICFree(strUuid );
+ strUuid = NULL;
+ }
+
+ *secVer = ver;
+ ret = OC_STACK_OK;
+
+exit:
+ if (CborNoError != cborFindResult)
+ {
+ OIC_LOG (ERROR, TAG, "CBORPayloadToVer failed!!!");
+ DeleteVerBinData(ver);
+ ret = OC_STACK_ERROR;
+ }
+ return ret;
+}
+
+static OCEntityHandlerResult HandleVerGetRequest (const OCEntityHandlerRequest * ehRequest)
+{
+ OCEntityHandlerResult ehRet = OC_EH_OK;
+
+ OIC_LOG(DEBUG, TAG, "Ver EntityHandle processing GET request");
+
+ /*
+ * For GET request return ver resource CBOR payload.
+ * For non-valid query return NULL json payload.
+ * The version is static built-in information, so VerToCBORPayload will
+ * return valid ver resource json.
+ */
+ uint8_t *payload = NULL;
+ size_t size = 0;
+ if (OC_STACK_OK != VerToCBORPayload(&gVer, &payload, &size))
+ {
+ payload = NULL;
+ }
+
+ // Send response payload to request originator
+ if (OC_STACK_OK != SendSRMCBORResponse(ehRequest, ehRet, payload, size))
+ {
+ OIC_LOG(ERROR, TAG, "SendSRMCBORResponse failed in HandleVerGetRequest");
+ }
+
+ OICFree(payload);
+
+ return ehRet;
+}
+
+OCEntityHandlerResult VerEntityHandler(OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest * ehRequest,
+ void* callbackParam)
+{
+ (void)callbackParam;
+ OCEntityHandlerResult ehRet = OC_EH_ERROR;
+
+ if(NULL == ehRequest)
+ {
+ return ehRet;
+ }
+
+ if (flag & OC_REQUEST_FLAG)
+ {
+ OIC_LOG(DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
+
+ switch (ehRequest->method)
+ {
+ case OC_REST_GET:
+ ehRet = HandleVerGetRequest(ehRequest);
+ break;
+
+ default:
+ ehRet = OC_EH_ERROR;
+ SendSRMCBORResponse(ehRequest, ehRet, NULL, 0);
+ break;
+ }
+ }
+
+ return ehRet;
+}
+
+OCStackResult CreateVerResource()
+{
+ OCStackResult ret = OCCreateResource(&gVerHandle,
+ OIC_RSRC_TYPE_SEC_VER,
+ OIC_MI_DEF,
+ OIC_RSRC_VER_URI,
+ VerEntityHandler,
+ NULL,
+ OC_SECURE);
+
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG (FATAL, TAG, "Unable to instantiate Ver resource");
+ DeInitVerResource();
+ }
+ return ret;
+}
+
+/**
+ * Get the security version.
+ *
+ * @return the version string of security.
+ */
+const char* GetSecVersion()
+{
+ OIC_LOG(DEBUG, TAG, "GetSecVersion");
+ return gVer.secv;
+}
+
+const OicSecVer_t* GetVerResourceData()
+{
+ return &gVer;
+}
+
+OCStackResult InitVerResource()
+{
+ OCStackResult ret = OC_STACK_ERROR;
+
+ OICStrcpy(gVer.secv, strlen(SECURITY_VERSION)+1, SECURITY_VERSION);
+
+ //Read device id from doxm
+ OicUuid_t deviceID = {.id={0}};
+ ret = GetDoxmDeviceID(&deviceID);
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG(ERROR, TAG, "Error while retrieving doxm device ID");
+ return ret;
+ }
+ memcpy(&gVer.deviceID, &deviceID, sizeof(OicUuid_t));
+
+ //Instantiate 'oic.sec.ver'
+ ret = CreateVerResource();
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG(ERROR, TAG, "Error while creating VER resource");
+ }
+
+ return ret;
+}
+
+OCStackResult DeInitVerResource()
+{
+ OCStackResult ret = OCDeleteResource(gVerHandle);
+
+ memset(&gVer, 0, sizeof(gVer));
+
+ if (OC_STACK_OK == ret)
+ {
+ return OC_STACK_OK;
+ }
+ else
+ {
+ return OC_STACK_ERROR;
+ }
+}
* all the device in subnet which are not yet owned.
*
* @param timeout Timeout in seconds, time until which function will listen to
- * responses from client before returning the list of devices.
+ * responses from server before returning the list of devices.
* @param list List of candidate devices to be provisioned.
* @return ::OC_STACK_OK in case of success and other value otherwise.
*/
* all the device in subnet which are already owned by calling provisioning client.
*
* @param timeout Timeout in seconds, time until which function will listen to
- * responses from client before returning the list of devices.
+ * responses from server before returning the list of devices.
* @param list List of owned devices.
* @return ::OC_STACK_OK in case of success and other value otherwise.
*/