[IOT-1936] Allow a device's Preconfigured Pin to be changed
authorAlex Kelley <alexke@microsoft.com>
Fri, 21 Apr 2017 00:02:37 +0000 (17:02 -0700)
committerKevin Kane <kkane@microsoft.com>
Tue, 9 May 2017 17:29:03 +0000 (17:29 +0000)
These changes do the following:
 1. Pass additional information in the request to add a Preconfigured
    Pin to identify it as an update to a Preconfigured Pin credential.
 2. Add additional checks to determine if the credential being updated
    is a Preconfigured Pin credential.
 3. Remove an existing Preconfigured Pin credential (if it exists)
    before adding a new one.

Change-Id: I75bfc8a55e25a2da0ec366fa6628e98430c29d00
Signed-off-by: Alex Kelley <alexke@microsoft.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/19537
Reviewed-by: Kevin Kane <kkane@microsoft.com>
Tested-by: jenkins-iotivity <jenkins@iotivity.org>
resource/csdk/security/include/internal/srmresourcestrings.h
resource/csdk/security/provisioning/src/multipleownershiptransfermanager.c
resource/csdk/security/src/credresource.c
resource/csdk/security/src/srmresourcestrings.c

index 4afaef6..f8c7532 100644 (file)
@@ -219,6 +219,11 @@ extern char OIC_SEC_REST_QUERY_DELIMETER;
 //Security Version
 extern const char * DEFAULT_SEC_VERSION;
 
+// Preconfigured Pin credential usage
+#ifdef MULTIPLE_OWNER
+extern const char * PRECONFIG_PIN_CRED;
+#endif //MULTIPLE_OWNER
+
 #ifdef __cplusplus
 }
 #endif
index 6996a98..55b2267 100644 (file)
@@ -423,6 +423,10 @@ OCStackResult MOTProvisionPreconfigPIN(void *ctx, const OCProvisionDev_t *target
     pinCred->credType = PIN_PASSWORD;
     memcpy(&pinCred->subject, &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t));
 
+    pinCred->credUsage = (char*)OICCalloc(1, (strlen(PRECONFIG_PIN_CRED) + 1));
+    VERIFY_NOT_NULL(TAG, pinCred->credUsage, ERROR);
+    OICStrcpy(pinCred->credUsage, (strlen(PRECONFIG_PIN_CRED) + 1), PRECONFIG_PIN_CRED);
+
     //Generate the security payload using updated doxm
     secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
     VERIFY_NOT_NULL(TAG, secPayload, ERROR);
@@ -486,7 +490,8 @@ exit:
 
     if(pinCred)
     {
-        OICFree(pinCred->privateData.data);
+        OICFree(pinCred->credUsage);
+        OICFree(pinCred->privateData.data);        
         OICFree(pinCred);
     }
 
index 2da114c..dab263c 100644 (file)
@@ -1731,22 +1731,40 @@ exit:
     return cmpResult;
 }
 
+#if ((defined(__WITH_DTLS__) || defined(__WITH_TLS__)) && defined(MULTIPLE_OWNER))
+static bool IsNewPreconfigPinCredential(OicSecCred_t * oldCred, OicSecCred_t * newCred)
+{
+    if (oldCred->credUsage &&
+        newCred->credUsage &&
+        (0 == strcmp(PRECONFIG_PIN_CRED, oldCred->credUsage)) &&
+        (0 == strcmp(PRECONFIG_PIN_CRED, newCred->credUsage)))
+    {
+        return true;
+    }
+
+    return false;
+}
+#endif //(__WITH_DTLS__ or __WITH_TLS__) and MULTIPLE_OWNER
+
 OCStackResult AddCredential(OicSecCred_t * newCred)
 {
     OCStackResult ret = OC_STACK_ERROR;
     OicSecCred_t * temp = NULL;
     bool validFlag = true;
     OicUuid_t emptyOwner = { .id = {0} };
+#if ((defined(__WITH_DTLS__) || defined(__WITH_TLS__)) && defined(MULTIPLE_OWNER))
+    uint16_t staleCredId = 0;
+#endif //(__WITH_DTLS__ or __WITH_TLS__) and MULTIPLE_OWNER  
 
     OIC_LOG(DEBUG, TAG, "IN AddCredential");
 
     VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
-    //Assigning credId to the newCred
+
+    // Assigning credId to the newCred
     newCred->credId = GetCredId();
     VERIFY_SUCCESS(TAG, true == IsValidCredential(newCred), ERROR);
 
-    //the newCred is not valid if it is empty
-
+    // The newCred is not valid if it is empty
     if (memcmp(&(newCred->subject), &emptyOwner, sizeof(OicUuid_t)) == 0)
     {
         validFlag = false;
@@ -1773,12 +1791,35 @@ OCStackResult AddCredential(OicSecCred_t * newCred)
                 validFlag = false;
                 break;
             }
+
+#if ((defined(__WITH_DTLS__) || defined(__WITH_TLS__)) && defined(MULTIPLE_OWNER))
+            // Devices can only have one Preconfigured Pin credential at any given time. Check
+            // to see if the new credential is an update to an existing Preconfigured Pin
+            // credential so that we can remove it later.
+            if (IsNewPreconfigPinCredential(temp, newCred))
+            {
+                staleCredId = temp->credId;
+            }
+#endif //(__WITH_DTLS__ or __WITH_TLS__) and MULTIPLE_OWNER
         }
     }
 
-    //Append the new Cred to existing list if new Cred is valid
+    // Append the new Cred to existing list if new Cred is valid
     if (validFlag)
     {
+#if ((defined(__WITH_DTLS__) || defined(__WITH_TLS__)) && defined(MULTIPLE_OWNER))
+        // Remove the existing Preconfigured Pin credential if it exists
+        if (0 != staleCredId)
+        {
+            ret = RemoveCredentialByCredId(staleCredId);
+            if (OC_STACK_RESOURCE_DELETED == ret)
+            {
+                // Use the old Preconfigured Pin cred id so that this acts as an update
+                newCred->credId = staleCredId;
+            }
+        }
+#endif //(__WITH_DTLS__ or __WITH_TLS__) and MULTIPLE_OWNER
+
         LL_APPEND(gCred, newCred);
     }
     if (memcmp(&(newCred->rownerID), &emptyOwner, sizeof(OicUuid_t)) != 0)
index 1a5c2d1..3e62a62 100644 (file)
@@ -216,3 +216,7 @@ char OIC_SEC_REST_QUERY_DELIMETER = '=';
 //Security Version
 const char * DEFAULT_SEC_VERSION = "0.0.0";
 
+//Preconfigured Pin credential identifier
+#ifdef MULTIPLE_OWNER
+const char * PRECONFIG_PIN_CRED = "x.org.iotivity.sec.cred.pcp";
+#endif //MULTIPLE_OWNER