From d8daf9060c3ae02978c0358d19433169ccc97447 Mon Sep 17 00:00:00 2001 From: Ibrahim Esmat Date: Tue, 1 Aug 2017 15:47:29 -0700 Subject: [PATCH] [IOT-2463] Fix CTT failure for Get /oic/sec/roles 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 Reviewed-on: https://gerrit.iotivity.org/gerrit/21733 Reviewed-by: Kevin Kane Reviewed-by: Alex Kelley Tested-by: jenkins-iotivity Reviewed-by: Randeep Singh --- resource/csdk/security/src/rolesresource.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/resource/csdk/security/src/rolesresource.c b/resource/csdk/security/src/rolesresource.c index 7b4315e..95097d0 100644 --- a/resource/csdk/security/src/rolesresource.c +++ b/resource/csdk/security/src/rolesresource.c @@ -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; -- 2.7.4