Add security version resource
authorjs126.lee <js126.lee@samsung.com>
Thu, 24 Mar 2016 11:38:07 +0000 (20:38 +0900)
committerRandeep Singh <randeep.s@samsung.com>
Thu, 24 Mar 2016 15:43:52 +0000 (15:43 +0000)
-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>
17 files changed:
resource/csdk/security/SConscript
resource/csdk/security/include/internal/srmresourcestrings.h [changed mode: 0755->0644]
resource/csdk/security/include/internal/verresource.h [new file with mode: 0644]
resource/csdk/security/include/securevirtualresourcetypes.h
resource/csdk/security/provisioning/include/ocprovisioningmanager.h
resource/csdk/security/provisioning/include/pmtypes.h
resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.dat
resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.json
resource/csdk/security/provisioning/sample/oic_svr_db_server_randompin.dat
resource/csdk/security/provisioning/sample/oic_svr_db_server_randompin.json
resource/csdk/security/provisioning/src/ocprovisioningmanager.c
resource/csdk/security/provisioning/src/pmutility.c
resource/csdk/security/src/resourcemanager.c
resource/csdk/security/src/secureresourcemanager.c
resource/csdk/security/src/srmresourcestrings.c
resource/csdk/security/src/verresource.c [new file with mode: 0644]
resource/include/OCProvisioningManager.h [changed mode: 0755->0644]

index f5d2616..ccfcda0 100644 (file)
@@ -100,6 +100,7 @@ if env.get('SECURED') == '1':
                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',
@@ -126,6 +127,7 @@ else:
                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',
old mode 100755 (executable)
new mode 100644 (file)
index 6c47d87..cbc8e82
@@ -81,6 +81,11 @@ extern const char * OIC_RSRC_TYPE_SEC_DPAIRING;
 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;
@@ -135,6 +140,7 @@ extern const char * OIC_JSON_IF_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;
 
diff --git a/resource/csdk/security/include/internal/verresource.h b/resource/csdk/security/include/internal/verresource.h
new file mode 100644 (file)
index 0000000..18fa03d
--- /dev/null
@@ -0,0 +1,98 @@
+/* *****************************************************************
+ *
+ * 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
index fee8d0d..816b53a 100644 (file)
@@ -551,6 +551,23 @@ struct OicSecDpairing
     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
index 54a5267..7f3dbf6 100644 (file)
@@ -47,7 +47,7 @@ OCStackResult OCInitPM(const char* dbPath);
  * 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
@@ -79,7 +79,7 @@ OCStackResult OCSetOwnerTransferCallbackData(OicSecOxm_t oxm, OTMCallbackData_t*
  * 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
index 2f23125..eede02d 100644 (file)
@@ -67,6 +67,7 @@ typedef struct OCProvisionDev
     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;
index 97393e9..097a938 100644 (file)
Binary files a/resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.dat and b/resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.dat differ
index 7f19ee7..c7e20f1 100644 (file)
@@ -1,5 +1,5 @@
 {\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
index 344f2c4..ef473a3 100644 (file)
Binary files a/resource/csdk/security/provisioning/sample/oic_svr_db_server_randompin.dat and b/resource/csdk/security/provisioning/sample/oic_svr_db_server_randompin.dat differ
index 7c6156f..7191503 100644 (file)
@@ -1,5 +1,5 @@
 {\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
+}
index d50fc36..b5d4bed 100644 (file)
@@ -70,7 +70,7 @@ OCStackResult OCInitPM(const char* dbPath)
  * 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.
  */
@@ -89,7 +89,7 @@ OCStackResult OCDiscoverUnownedDevices(unsigned short timeout, OCProvisionDev_t
  * 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.
  */
index 648ca05..c03d4ce 100644 (file)
@@ -38,6 +38,7 @@
 #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"
@@ -51,6 +52,65 @@ typedef struct _DiscoveryInfo{
     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.
  *
@@ -119,6 +179,7 @@ OCStackResult AddDevice(OCProvisionDev_t **ppDevicesList, const char* addr, cons
         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);
     }
@@ -153,6 +214,37 @@ OCStackResult UpdateSecurePortOfDevice(OCProvisionDev_t **ppDevicesList, const c
 }
 
 /**
+ * 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.
@@ -210,6 +302,15 @@ OCProvisionDev_t* PMCloneOCProvisionDev(const OCProvisionDev_t* src)
         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;
@@ -384,16 +485,80 @@ bool PMGenerateQuery(bool isSecure,
     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)
 {
@@ -431,15 +596,22 @@ static OCStackApplicationResult SecurePortDiscoveryHandler(void *ctx, OCDoHandle
             }
 
             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.");
         }
 
@@ -449,18 +621,10 @@ static OCStackApplicationResult SecurePortDiscoveryHandler(void *ctx, OCDoHandle
     {
         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)
 {
@@ -537,42 +701,15 @@ static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNU
                     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.");
             }
 
@@ -664,6 +801,100 @@ OCStackResult PMDeviceDiscovery(unsigned short waittime, bool isOwned, OCProvisi
     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.
  *
index 90a4583..14f586d 100644 (file)
@@ -36,6 +36,7 @@
 #include "pconfresource.h"
 #include "dpairingresource.h"
 //#endif // DIRECT_PAIRING
+#include "verresource.h"
 
 #define TAG "SRM-RM"
 
@@ -137,6 +138,10 @@ OCStackResult InitSecureResources( )
         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
@@ -160,6 +165,7 @@ OCStackResult DestroySecureResources( )
     DeInitPconfResource();
     DeInitDpairingResource();
 //#endif // DIRECT_PAIRING
+    DeInitVerResource();
 
     return OC_STACK_OK;
 }
index 6e2feb2..26a9277 100644 (file)
@@ -362,6 +362,7 @@ bool SRMIsSecurityResourceURI(const char* uri)
         OIC_RSRC_PSTAT_URI,
         OIC_RSRC_PCONF_URI,
         OIC_RSRC_DPAIRING_URI,
+        OIC_RSRC_VER_URI,
     };
 
     // Remove query from Uri for resource string comparison
index 611f6bb..e8b8165 100644 (file)
@@ -78,6 +78,10 @@ const char * OIC_RSRC_TYPE_SEC_DPAIRING = "oic.sec.dpairing";
 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";
@@ -133,6 +137,7 @@ const char * OIC_JSON_IF_NAME = "if";
 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 = "";
 
diff --git a/resource/csdk/security/src/verresource.c b/resource/csdk/security/src/verresource.c
new file mode 100644 (file)
index 0000000..4f0b2d8
--- /dev/null
@@ -0,0 +1,354 @@
+/* *****************************************************************
+ *
+ * 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;
+    }
+}
old mode 100755 (executable)
new mode 100644 (file)
index aecee19..0a949e3
@@ -124,7 +124,7 @@ namespace OC
              * 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.
              */
@@ -136,7 +136,7 @@ namespace OC
              * 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.
              */