Enable generating credId sequentially
authorShilpa Sodani <shilpa.a.sodani@intel.com>
Thu, 7 May 2015 04:02:03 +0000 (21:02 -0700)
committerSachin Agrawal <sachin.agrawal@intel.com>
Mon, 22 Jun 2015 19:12:59 +0000 (19:12 +0000)
Added code to generate credId sequentially and disregard
the credId in POST credentail request.

Change-Id: I6da7343eb29817ead3a195c6b262738499d08472
Signed-off-by: Shilpa Sodani <shilpa.a.sodani@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/1284
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Sachin Agrawal <sachin.agrawal@intel.com>
resource/csdk/security/src/credresource.c
resource/csdk/security/unittest/credentialresource.cpp

index 56c0927..1ceb2d9 100755 (executable)
@@ -18,6 +18,7 @@
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
+#define __STDC_LIMIT_MACROS
 #include "ocstack.h"
 #include "logger.h"
 #include "oic_malloc.h"
@@ -34,6 +35,8 @@
 #include "cainterface.h"
 #include <stdlib.h>
 #include <string.h>
+#include <stdint.h>
+
 
 #define TAG  PCF("SRM-CREDL")
 
@@ -233,14 +236,16 @@ OicSecCred_t * JSONToCredBin(const char * jsonStr)
 
             //CredId -- Mandatory
             jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_CREDID_NAME);
-            VERIFY_NON_NULL(TAG, jsonObj, ERROR);
-            VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR)
-            cred->credId = jsonObj->valueint;
+            if(jsonObj)
+            {
+                VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+                cred->credId = jsonObj->valueint;
+            }
 
             //subject -- Mandatory
             jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_SUBJECT_NAME);
             VERIFY_NON_NULL(TAG, jsonObj, ERROR);
-            VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR)
+            VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
             outLen = 0;
             memset(base64Buff, 0, sizeof(base64Buff));
             b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring),
@@ -252,7 +257,7 @@ OicSecCred_t * JSONToCredBin(const char * jsonStr)
             //CredType -- Mandatory
             jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_CREDTYPE_NAME);
             VERIFY_NON_NULL(TAG, jsonObj, ERROR);
-            VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR)
+            VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
             cred->credType = jsonObj->valueint;
 
             //PrivateData is mandatory for some of the credential types listed below.
@@ -326,6 +331,7 @@ exit:
  * @param credType credential type.
  * @param publicData public data such as public key.
  * @param privateData private data such as private key.
+ *        The privateData is expected in base64 encoded format.
  * @param ownersLen length of owners array
  * @param owners array of owners.
  *
@@ -342,13 +348,15 @@ OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t cr
     OicSecCred_t *cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
     VERIFY_NON_NULL(TAG, cred, ERROR);
 
-    //TODO:Need more clarification on credId
-    OCFillRandomMem((uint8_t*)&cred->credId, sizeof(cred->credId));
+    //CredId is assigned before appending new cred to the existing
+    //credential list and updating svr database in AddCredential().
+    cred->credId = 0;
 
     VERIFY_NON_NULL(TAG, subject, ERROR);
     memcpy(cred->subject.id, subject->id , sizeof(cred->subject.id));
 
-    //TODO: check credType has one of the values {0, 1, 2, 4, 6, 8, 16}
+    VERIFY_SUCCESS(TAG, credType < (NO_SECURITY_MODE | SYMMETRIC_PAIR_WISE_KEY |
+            SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
     cred->credType = credType;
 
 #if 0
@@ -387,6 +395,69 @@ exit:
     return cred;
 }
 
+/*
+ * Compare function used LL_SORT for sorting credentials
+ *
+ * @param first   pointer to OicSecCred_t struct
+ * @param second  pointer to OicSecCred_t struct
+ *
+ *@retval
+ *  -1    if credId of first is less than credId of second
+ *   0    if credId of first is equal to credId of second
+ *   1    if credId of first is greater than credId of second
+ */
+static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
+{
+    if(first->credId < second->credId)
+    {
+        return -1;
+    }
+    else if(first->credId > second->credId)
+    {
+        return 1;
+    }
+    else
+        return 0;
+}
+
+/**
+ * GetCredId goes through the cred list and returns the next
+ * available credId. The next credId could be the credId that is
+ * available due deletion of OicSecCred_t object or one more than
+ * credId of last credential in the list.
+ *
+ * @retval
+ *      next available credId  - success
+ *      0                      - error
+ */
+
+static uint16_t GetCredId()
+{
+    //Sorts credential list in incremental order of credId
+    LL_SORT(gCred, CmpCredId);
+
+
+    OicSecCred_t *currentCred = NULL, *credTmp = NULL;
+    uint16_t nextCredId = 1;
+
+    LL_FOREACH_SAFE(gCred, currentCred, credTmp)
+    {
+        if(currentCred->credId == nextCredId)
+        {
+            nextCredId += 1;
+        }
+        else
+        {
+            break;
+        }
+    }
+
+    VERIFY_SUCCESS(TAG, nextCredId < UINT16_MAX, ERROR);
+    return nextCredId;
+
+exit:
+    return 0;
+}
 /**
  * This function adds the new cred to the credential list.
  *
@@ -399,17 +470,20 @@ exit:
 OCStackResult AddCredential(OicSecCred_t * newCred)
 {
     OCStackResult ret = OC_STACK_ERROR;
+    char * jsonStr = NULL;
 
-    if(NULL == newCred)
-    {
-        return OC_STACK_ERROR;
-    }
+    VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
+
+    //Assigning credId to the newCred
+    newCred->credId = GetCredId();
+
+    VERIFY_SUCCESS(TAG, newCred->credId != 0, ERROR);
 
     //Append the new Cred to existing list
     LL_APPEND(gCred, newCred);
 
     //Convert CredList to JSON and update the persistent Storage
-    char * jsonStr = BinToCredJSON(gCred);
+    jsonStr = BinToCredJSON(gCred);
 
     if(jsonStr)
     {
@@ -423,6 +497,7 @@ OCStackResult AddCredential(OicSecCred_t * newCred)
         cJSON_Delete(jsonCred);
     }
 
+exit:
     return ret;
 }
 
@@ -435,7 +510,10 @@ static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * eh
 
     if(cred)
     {
-        //Append the new Cred to existing list
+        //If the Post request credential has credId, it will be
+        //discarded and the next available credId will be assigned
+        //to it before getting appended to the existing credential
+        //list and updating svr database.
         ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
     }
 
index 31c5b55..13dfb12 100644 (file)
 #include "securevirtualresourcetypes.h"
 #include "credresource.h"
 #include "oic_malloc.h"
+#include "oic_string.h"
+#include "logger.h"
+
+#define TAG PCF("SRM-CRED-UT")
 
 #ifdef __cplusplus
 extern "C" {
@@ -35,6 +39,7 @@ char * BinToCredJSON(const OicSecCred_t * pstat);
 OicSecCred_t * JSONToCredBin(const char * jsonStr);
 void InitSecCredInstance(OicSecCred_t * cred);
 void DeleteCredList(OicSecCred_t* cred);
+const OicSecCred_t* GetCredResourceData(const OicUuid_t* subject);
 #ifdef __cplusplus
 }
 #endif
@@ -43,40 +48,67 @@ OicSecCred_t * getCredList()
 {
     OicSecCred_t * cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
     cred->credId = 1234;
-    strcpy((char *)cred->subject.id, "subject1");
+    OICStrcpy((char *)cred->subject.id, sizeof(cred->subject.id), "subject1");
 
 #if 0
     cred->roleIdsLen = 2;
     cred->roleIds = (OicSecRole_t *)OICCalloc(cred->roleIdsLen, sizeof(OicSecRole_t));
-    strcpy((char *)cred->roleIds[0].id, "role11");
-    strcpy((char *)cred->roleIds[1].id, "role12");
+    OICStrcpy((char *)cred->roleIds[0].id, sizeof(cred->roleIds[0].id), "role11");
+    OICStrcpy((char *)cred->roleIds[1].id, sizeof(cred->roleIds[1].id), "role12");
 #endif
 
     cred->credType = 1;
     cred->ownersLen = 1;
     cred->owners = (OicUuid_t*)OICCalloc(cred->ownersLen, sizeof(OicUuid_t));
-    strcpy((char *)cred->owners[0].id, "ownersId11");
+    OICStrcpy((char *)cred->owners[0].id, sizeof(cred->owners[0].id), "ownersId11");
 
     cred->next = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
     cred->next->credId = 5678;
-    strcpy((char *)cred->next->subject.id, "subject2");
+    OICStrcpy((char *)cred->next->subject.id, sizeof(cred->next->subject.id), "subject2");
 #if 0
     cred->next->roleIdsLen = 0;
 #endif
     cred->next->credType = 1;
     cred->next->privateData.data = (char *)OICCalloc(1, strlen("My private Key21") + 1);
-    strcpy(cred->next->privateData.data, "My private Key21");
+    OICStrcpy(cred->next->privateData.data, sizeof(cred->next->privateData.data),
+            "My private Key21");
 #if 0
     cred->next->publicData.data = (char *)OICCalloc(1, strlen("My Public Key123") + 1);
-    strcpy(cred->next->publicData.data, "My Public Key123");
+    OICStrcpy(cred->next->publicData.data, sizeof(cred->next->publicData.data),"My Public Key123");
 #endif
     cred->next->ownersLen = 2;
     cred->next->owners = (OicUuid_t*)OICCalloc(cred->next->ownersLen, sizeof(OicUuid_t));
-    strcpy((char *)cred->next->owners[0].id, "ownersId21");
-    strcpy((char *)cred->next->owners[1].id, "ownersId22");
+    OICStrcpy((char *)cred->next->owners[0].id, sizeof(cred->next->owners[0].id), "ownersId21");
+    OICStrcpy((char *)cred->next->owners[1].id, sizeof(cred->next->owners[1].id), "ownersId22");
     return cred;
 }
 
+static void printCred(const OicSecCred_t * cred)
+{
+    EXPECT_TRUE(NULL != cred);
+
+    const OicSecCred_t *credTmp1 = NULL;
+    for(credTmp1 = cred; credTmp1; credTmp1 = credTmp1->next)
+    {
+        OC_LOG_V(INFO, TAG, PCF("\ncred->credId = %d"), credTmp1->credId);
+        OC_LOG_V(INFO, TAG, PCF("cred->subject.id = %s"), credTmp1->subject.id);
+        OC_LOG_V(INFO, TAG, PCF("cred->credType = %d"), credTmp1->credType);
+        if(credTmp1->privateData.data)
+        {
+            OC_LOG_V(INFO, TAG, PCF("cred->privateData.data = %s"), credTmp1->privateData.data);
+        }
+        if(credTmp1->publicData.data)
+        {
+           OC_LOG_V(INFO, TAG, PCF("cred->publicData.data = %s"), credTmp1->publicData.data);
+        }
+        OC_LOG_V(INFO, TAG, PCF("cred->ownersLen = %zd"), credTmp1->ownersLen);
+        for(size_t i = 0; i < cred->ownersLen; i++)
+        {
+            OC_LOG_V(INFO, TAG, PCF("cred->owners[%zd].id = %s"), i, credTmp1->owners[i].id);
+        }
+    }
+}
+
  //InitCredResource Tests
 TEST(InitCredResourceTest, InitCredResource)
 {
@@ -162,10 +194,10 @@ TEST(CredGetResourceDataTest, GetCredResourceDataNULLSubject)
 TEST(CredGenerateCredentialTest, GenerateCredentialValidInput)
 {
     OicUuid_t owners[1];
-   strcpy((char *)owners[0].id, "ownersId21");
+    OICStrcpy((char *)owners[0].id, sizeof(owners[0].id), "ownersId21");
 
     OicUuid_t subject = {};
-    strcpy((char *)subject.id, "subject11");
+    OICStrcpy((char *)subject.id, sizeof(subject.id), "subject11");
 
     char privateKey[] = "My private Key11";
 
@@ -173,38 +205,50 @@ TEST(CredGenerateCredentialTest, GenerateCredentialValidInput)
 
     cred = GenerateCredential(&subject, SYMMETRIC_PAIR_WISE_KEY, NULL,
                              privateKey, 1, owners);
-    printf("cred->credId = %d\n", cred->credId);
-    printf("cred->subject.id = %s\n", cred->subject.id);
-    printf("cred->credType = %d\n", cred->credType);
-    printf("cred->privateData.data = %s\n", cred->privateData.data);
-    printf("cred->ownersLen = %zd\n", cred->ownersLen);
-    printf("cred->owners[0].id = %s\n", cred->owners[0].id);
+    printCred(cred);
 
-    EXPECT_TRUE(NULL != cred);
     DeleteCredList(cred);
 }
 
-TEST(CredAddCredentialTest, GenerateCredentialValidInput)
+TEST(GenerateAndAddCredentialTest, GenerateAndAddCredentialValidInput)
 {
     OicUuid_t owners[1];
-    strcpy((char *)owners[0].id, "ownersId21");
+    OICStrcpy((char *)owners[0].id, sizeof(owners[0].id), "ownersId11");
 
     OicUuid_t subject = {};
-    strcpy((char *)subject.id, "subject11");
+    OICStrcpy((char *)subject.id, sizeof(subject.id), "subject11");
 
     char privateKey[] = "My private Key11";
 
-    OicSecCred_t * cred  = NULL;
+    OicSecCred_t * cred1  = NULL;
+    OicSecCred_t * headCred = NULL;
 
-    cred = GenerateCredential(&subject, SYMMETRIC_PAIR_WISE_KEY, NULL,
+    cred1 = GenerateCredential(&subject, SYMMETRIC_PAIR_WISE_KEY, NULL,
                                  privateKey, 1, owners);
-    EXPECT_TRUE(NULL != cred);
 
-    EXPECT_EQ(OC_STACK_ERROR, AddCredential(cred));
+    EXPECT_EQ(OC_STACK_ERROR, AddCredential(cred1));
+    headCred = cred1;
 
-    DeleteCredList(cred);
+    OICStrcpy((char *)owners[0].id, sizeof(owners[0].id), "ownersId22");
+    OICStrcpy((char *)subject.id, sizeof(subject.id), "subject22");
+    cred1 = GenerateCredential(&subject, SYMMETRIC_PAIR_WISE_KEY, NULL,
+                                     privateKey, 1, owners);
+    EXPECT_EQ(OC_STACK_ERROR, AddCredential(cred1));
+
+    OICStrcpy((char *)owners[0].id, sizeof(owners[0].id), "ownersId33");
+    OICStrcpy((char *)subject.id, sizeof(subject.id), "subject33");
+    cred1 = GenerateCredential(&subject, SYMMETRIC_PAIR_WISE_KEY, NULL,
+                                     privateKey, 1, owners);
+    EXPECT_EQ(OC_STACK_ERROR, AddCredential(cred1));
+
+    const OicSecCred_t* credList = GetCredResourceData(&headCred->subject);
+
+    printCred(credList);
+
+    DeleteCredList(headCred);
 
 }
+
 #if 0
 TEST(CredGetResourceDataTest, GetCredResourceDataValidSubject)
 {