[IOT-2463] Fix CTT failure for Get /oic/sec/roles
authorIbrahim Esmat <iesmat@microsoft.com>
Tue, 1 Aug 2017 22:47:29 +0000 (15:47 -0700)
committerRandeep Singh <randeep.s@samsung.com>
Thu, 3 Aug 2017 06:23:01 +0000 (06:23 +0000)
Currently the GET request to the /oic/sec/roles resource will fail
with a 400 Bad Request code if the client doesn't have a Public Key
(non-certificate auth) or if the Public Key doesn't match any roles
certificates.

However, that is incorrect since the GET request to the
/oic/sec/roles resource was correct, it just doesn't have any roles
associated with it.

Changed the /oic/sec/roles resource to return an empty "roles" array
if the client doesn't have a Public Key or if the Public Key doesn't
match any roles certificates. At minimum, the return should be:

{
  "roles": [ ],
  "rt": ["oic.r.roles"],
  "if": ["oic.if.baseline"]
}

Testcase: CT1.7.9.1 Verify Security Virtual Resources conform to OIC
Schema

Change-Id: Id71c233875a6ef9e251f2adccd48907e5dedb1a1
Signed-off-by: Ibrahim Esmat <iesmat@microsoft.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/21733
Reviewed-by: Kevin Kane <kkane@microsoft.com>
Reviewed-by: Alex Kelley <alexke@microsoft.com>
Tested-by: jenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: Randeep Singh <randeep.s@samsung.com>
resource/csdk/security/src/rolesresource.c

index 7b4315e..95097d0 100644 (file)
@@ -115,8 +115,8 @@ static OCStackResult GetPeerPublicKeyFromEndpoint(const CAEndpoint_t *endpoint,
 
     if ((NULL == sep.publicKey) || (0 == sep.publicKeyLength))
     {
-        OIC_LOG_V(ERROR, TAG, "%s: Peer did not have a public key", __func__);
-        return OC_STACK_INVALID_PARAM;
+        OIC_LOG_V(WARNING, TAG, "%s: Peer did not have a public key", __func__);
+        return OC_STACK_NO_RESOURCE;
     }
 
     *publicKey = OICCalloc(1, sep.publicKeyLength);
@@ -433,7 +433,6 @@ OCStackResult RolesToCBORPayload(const RoleCertChain_t *roles, uint8_t **cborPay
     size_t roleCount = 0;
     const RoleCertChain_t *currChain = NULL;
 
-    VERIFY_NOT_NULL_RETURN(TAG, roles, ERROR, OC_STACK_INVALID_PARAM);
     VERIFY_NOT_NULL_RETURN(TAG, cborPayload, ERROR, OC_STACK_INVALID_PARAM);
     VERIFY_NOT_NULL_RETURN(TAG, cborSize, ERROR, OC_STACK_INVALID_PARAM);
 
@@ -458,6 +457,7 @@ OCStackResult RolesToCBORPayload(const RoleCertChain_t *roles, uint8_t **cborPay
     cborEncoderResult = cbor_encode_text_string(&rolesRootMap, OIC_JSON_ROLES_NAME, strlen(OIC_JSON_ROLES_NAME));
     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding roles name tag");
 
+    // If roles is NULL, the "roles" array will be empty
     for (currChain = roles; NULL != currChain; currChain = currChain->next)
     {
         roleCount++;
@@ -789,30 +789,28 @@ static OCEntityHandlerResult HandleGetRequest(OCEntityHandlerRequest *ehRequest)
     size_t publicKeyLength = 0;
 
     res = GetPeerPublicKey(&ehRequest->devAddr, &publicKey, &publicKeyLength);
-    if (OC_STACK_OK != res)
+    // OC_STACK_NO_RESOURCE means that the Peer doesn't have a Public Key.
+    if ((OC_STACK_OK != res) && (OC_STACK_NO_RESOURCE != res))
     {
         OIC_LOG_V(ERROR, TAG, "Could not get remote peer's public key: %d", res);
         ehRet = OC_EH_ERROR;
         goto exit;
     }
 
-    for (const RolesEntry_t *entry = gRoles; NULL != entry; entry = entry->next)
+    if (NULL != publicKey)
     {
-        if ((entry->publicKeyLength == publicKeyLength) &&
-            (0 == memcmp(entry->publicKey, publicKey, publicKeyLength)))
+        for (const RolesEntry_t *entry = gRoles; NULL != entry; entry = entry->next)
         {
-            roles = entry->chains;
-            break;
+            if ((entry->publicKeyLength == publicKeyLength) &&
+                (0 == memcmp(entry->publicKey, publicKey, publicKeyLength)))
+            {
+                roles = entry->chains;
+                break;
+            }
         }
     }
 
-    if (NULL == roles)
-    {
-        OIC_LOG(ERROR, TAG, "Could not find a roles list for this peer");
-        ehRet = OC_EH_ERROR;
-        goto exit;
-    }
-
+    // If roles is NULL, we will return success with an empty "roles" array
     res = RolesToCBORPayload(roles, &payload, &size);
     ehRet = (OC_STACK_OK == res) ? OC_EH_OK : OC_EH_ERROR;