Merge branch 'master' into simulator
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / sample / provisioningclient.c
old mode 100755 (executable)
new mode 100644 (file)
index 2284155..ee16b58
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
-#include <getopt.h>
+
 #include "logger.h"
 #include "oic_malloc.h"
 #include "utlist.h"
-#include "securevirtualresourcetypes.h"
-#include "provisioningmanager.h"
+#include "ocprovisioningmanager.h"
+#include "secureresourceprovider.h"
+#include "oxmjustworks.h"
+#include "oxmrandompin.h"
+#include "pinoxmcommon.h"
+#include "oic_string.h"
 
 #define MAX_URI_LENGTH (64)
 #define MAX_PERMISSION_LENGTH (5)
-#define MAX_INPUT_ID_LENGTH (16)
-#define PREDEFINED_TIMEOUT (10)
 #define CREATE (1)
 #define READ (2)
 #define UPDATE (4)
 #define DELETE (8)
 #define NOTIFY (16)
 #define DASH '-'
+#define PREDEFINED_TIMEOUT (10)
+#define MAX_OWNED_DEVICE (10)
 #define TAG  "provisioningclient"
 
-static OicSecAcl_t        *gAcl = NULL;
-static char CRED_FILE[] = "oic_svr_db.json";
+static char CRED_FILE[] = "oic_svr_db_client.json";
+static OicSecAcl_t        *gAcl1 = NULL;
+static OicSecAcl_t        *gAcl2 = NULL;
+static int gOwnershipState = 0;
+
+typedef enum
+{
+    ownershipDone = 1 << 1,
+    finalizeDone = 1 << 2,
+    provisionCredDone = 1 << 3,
+    provisionAclDone = 1 << 4
+} StateManager;
+
 
 /**
- * Perform cleanup for ACL list
- *
- * @param[in]    ACL list
+ * Perform cleanup for ACL
+ * @param[in]    ACL
  */
-static void DeleteACLList(OicSecAcl_t *acl)
+static void deleteACL(OicSecAcl_t *acl)
 {
     if (acl)
     {
-        OicSecAcl_t *aclTmp1 = NULL;
-        OicSecAcl_t *aclTmp2 = NULL;
-        LL_FOREACH_SAFE(acl, aclTmp1, aclTmp2)
+        /* Clean Resources */
+        for (size_t i = 0; i < (acl)->resourcesLen; i++)
         {
-            LL_DELETE(acl, aclTmp1);
+            OICFree((acl)->resources[i]);
+        }
+        OICFree((acl)->resources);
 
-            /* Clean Resources */
-            for (int i = 0; i < aclTmp1->resourcesLen; i++)
-            {
-                OICFree(aclTmp1->resources[i]);
-            }
-            OICFree(aclTmp1->resources);
+        /* Clean Owners */
+        OICFree((acl)->owners);
 
-            /* Clean Owners */
-            OICFree(aclTmp1->owners);
+        /* Clean ACL node itself */
+        OICFree((acl));
 
-            /* Clean ACL node itself */
-            OICFree(aclTmp1);
-        }
         acl = NULL;
     }
 }
@@ -80,17 +88,15 @@ static void DeleteACLList(OicSecAcl_t *acl)
  *
  * @param[in] temp_psm    Input data of ACL permission string
  * @param[in,out] pms    The pointer of ACL permission value
- * @return  0 on success otherwise a positive error value
- * @retval  SP_RESULT_SUCCESS    Successful
- * @retval  SP_RESULT_INVALID_PARAM    Invaild input arguments
+ * @return  0 on success otherwise -1.
  */
-static SPResult CalculateAclPermission(const char *temp_pms, uint16_t *pms)
+static int CalculateAclPermission(const char *temp_pms, uint16_t *pms)
 {
     int i = 0;
 
     if (NULL == temp_pms || NULL == pms)
     {
-        return SP_RESULT_INVALID_PARAM;
+        return -1;
     }
     *pms = 0;
     while (temp_pms[i] != '\0')
@@ -134,25 +140,23 @@ static SPResult CalculateAclPermission(const char *temp_pms, uint16_t *pms)
                 }
             default:
                 {
-                    return SP_RESULT_INVALID_PARAM;
+                    return -1;
                 }
         }
     }
-    return SP_RESULT_SUCCESS;
+    return 0;
 }
 
 /**
  * Get the ACL property from user
  *
  * @param[in]    ACL Datastructure to save user inputs
- * @return  0 on success otherwise a positive error value
- * @retval  SP_RESULT_SUCCESS    Successful
- * @retval  SP_RESULT_MEM_ALLOCATION_FAIL    Memmory allocation failure
+ * @return  0 on success otherwise -1.
  */
-static SPResult InputACL(OicSecAcl_t *acl)
+static int InputACL(OicSecAcl_t *acl)
 {
-    int unused __attribute__((unused));
-    char temp_id [MAX_INPUT_ID_LENGTH + 4] = {0,};
+    int ret;
+    char temp_id [UUID_LENGTH + 4] = {0,};
     char temp_rsc[MAX_URI_LENGTH + 1] = {0,};
     char temp_pms[MAX_PERMISSION_LENGTH + 1] = {0,};
     printf("******************************************************************************\n");
@@ -162,37 +166,65 @@ static SPResult InputACL(OicSecAcl_t *acl)
     printf("-URN identifying the subject\n");
     printf("ex) 1111-1111-1111-1111 (16 Numbers except to '-')\n");
     printf("Subject : ");
-    unused = scanf("%19s", temp_id);
+    char *ptr = NULL;
+    ret = scanf("%19ms", &ptr);
+    if(1==ret)
+    {
+        OICStrcpy(temp_id, sizeof(temp_id), ptr);
+        OICFree(ptr);
+    }
+    else
+    {
+         printf("Error while input\n");
+         return -1;
+    }
     int j = 0;
     for (int i = 0; temp_id[i] != '\0'; i++)
     {
         if (DASH != temp_id[i])
+        {
+            if(j>UUID_LENGTH)
+            {
+                printf("Invalid input\n");
+                return -1;
+            }
             acl->subject.id[j++] = temp_id[i];
+        }
     }
 
     //Set Resource.
-    printf("Num. of Resource : ");
-    unused = scanf("%zu", &acl->resourcesLen);
+    printf("Num. of Resource : \n");
+    ret = scanf("%zu", &acl->resourcesLen);
     printf("-URI of resource\n");
     printf("ex)/oic/sh/temp/0 (Max_URI_Length: 64 Byte )\n");
-    acl->resources = (char **)OICMalloc(acl->resourcesLen * sizeof(char *));
+    acl->resources = (char **)OICCalloc(acl->resourcesLen, sizeof(char *));
     if (NULL == acl->resources)
     {
         OC_LOG(ERROR, TAG, "Error while memory allocation");
-        return SP_RESULT_MEM_ALLOCATION_FAIL;
+        return -1;
     }
-    for (int i = 0; i < acl->resourcesLen; i++)
+    for (size_t i = 0; i < acl->resourcesLen; i++)
     {
-        printf("[%d]Resource : ", i + 1);
-        unused = scanf("%64s", temp_rsc);
-        acl->resources[i] = (char *)OICMalloc((strlen(temp_rsc) + 1) * sizeof(char));
+        printf("[%zu]Resource : ", i + 1);
+        char *ptr_tempRsc = NULL;
+        ret = scanf("%64ms", &ptr_tempRsc);
+        if (1==ret)
+        {
+            OICStrcpy(temp_rsc, sizeof(temp_rsc), ptr_tempRsc);
+            OICFree(ptr_tempRsc);
+        }
+        else
+        {
+            printf("Error while input\n");
+            return -1;
+        }
+        acl->resources[i] = OICStrdup(temp_rsc);
+
         if (NULL == acl->resources[i])
         {
             OC_LOG(ERROR, TAG, "Error while memory allocation");
-            return SP_RESULT_MEM_ALLOCATION_FAIL;
+            return -1;
         }
-        strncpy(acl->resources[i], temp_rsc, strlen(temp_rsc));
-        acl->resources[i][strlen(temp_rsc)] = '\0';
     }
     // Set Permission
     do
@@ -200,24 +232,47 @@ static SPResult InputACL(OicSecAcl_t *acl)
         printf("-Set the permission(C,R,U,D,N)\n");
         printf("ex) CRUDN, CRU_N,..(5 Charaters)\n");
         printf("Permission : ");
-        unused = scanf("%5s", temp_pms);
+        char *ptr_temp_pms = NULL;
+        ret = scanf("%5ms", &ptr_temp_pms);
+        if(1 == ret)
+        {
+            OICStrcpy(temp_pms, sizeof(temp_pms), ptr_temp_pms);
+            OICFree(ptr_temp_pms);
+
+        }
+        else
+        {
+            printf("Error while input\n");
+            return -1;
+        }
     }
-    while (SP_RESULT_SUCCESS != CalculateAclPermission(temp_pms, &(acl->permission)) );
+    while (0 != CalculateAclPermission(temp_pms, &(acl->permission)) );
     // Set Rowner
     printf("Num. of Rowner : ");
-    unused = scanf("%zu", &acl->ownersLen);
+    ret = scanf("%zu", &acl->ownersLen);
     printf("-URN identifying the rowner\n");
     printf("ex) 1111-1111-1111-1111 (16 Numbers except to '-')\n");
     acl->owners = (OicUuid_t *)OICCalloc(acl->ownersLen, sizeof(OicUuid_t));
     if (NULL == acl->owners)
     {
         OC_LOG(ERROR, TAG, "Error while memory allocation");
-        return SP_RESULT_MEM_ALLOCATION_FAIL;
+        return -1;
     }
-    for (int i = 0; i < acl->ownersLen; i++)
+    for (size_t i = 0; i < acl->ownersLen; i++)
     {
-        printf("[%d]Rowner : ", i + 1);
-        unused = scanf("%19s", temp_id);
+        printf("[%zu]Rowner : ", i + 1);
+        char *ptr_temp_id = NULL;
+        ret = scanf("%19ms", &ptr_temp_id);
+        if (1 == ret)
+        {
+            OICStrcpy(temp_id, sizeof(temp_id), ptr_temp_id);
+            OICFree(ptr_temp_id);
+        }
+        else
+        {
+            printf("Error while input\n");
+            return -1;
+        }
         j = 0;
         for (int k = 0; temp_id[k] != '\0'; k++)
         {
@@ -227,27 +282,116 @@ static SPResult InputACL(OicSecAcl_t *acl)
             }
         }
     }
-    return SP_RESULT_SUCCESS;
+    return 0;
 }
 
-FILE* client_fopen(const char *path, const char *mode)
+
+//FILE *client_fopen(const char *path, const char *mode)
+FILE *client_fopen(const char* UNUSED_PARAM , const char *mode)
 {
-    (void)path;
+    (void)UNUSED_PARAM;
     return fopen(CRED_FILE, mode);
 }
 
+void PrintfResult(const char* procName, void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
+{
+    printf("-----------------------------------------------------------\n");
+    if(!hasError)
+    {
+        printf("%s was successfully done.\n", procName);
+    }
+    else
+    {
+        for(int i = 0; i < nOfRes; i++)
+        {
+            printf("UUID : ");
+            for(int j = 0; j < UUID_LENGTH; i++)
+            {
+                printf("%c", arr[i].deviceId.id[j]);
+            }
+            printf("\t");
+            printf("Result=%d\n", arr[i].res);
+        }
+    }
+
+    if(ctx)
+    {
+        printf("Context is %s\n", (char*)ctx);
+    }
+    printf("-----------------------------------------------------------\n");
+}
+
+void ProvisionCredCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
+{
+    if(!hasError)
+    {
+        gOwnershipState = 1;
+        PrintfResult("Provision Credential", ctx, nOfRes, arr, hasError);
+    }
+}
+
+void ProvisionAclCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
+{
+    if(!hasError)
+    {
+        gOwnershipState = 1;
+        PrintfResult("Provision ACL", ctx, nOfRes, arr, hasError);
+    }
+}
+
+void ProvisionPairwiseCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
+{
+    if(!hasError)
+    {
+        gOwnershipState = 1;
+        PrintfResult("Provision Pairwise Credential", ctx, nOfRes, arr, hasError);
+    }
+}
+
+void OwnershipTransferCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
+{
+    if(!hasError)
+    {
+        gOwnershipState = 1;
+        PrintfResult("Ownership transfer", ctx, nOfRes, arr, hasError);
+    }
+}
+
+void InputPinCB(char* pinBuf, size_t bufSize)
+{
+    if(pinBuf)
+    {
+        printf("INPUT PIN : ");
+        char *ptr = NULL;
+        int ret = scanf("%ms", &ptr);
+        if(1 == ret)
+        {
+            OICStrcpy(pinBuf, bufSize, ptr);
+            OICFree(ptr);
+        }
+        else
+        {
+             printf("Error in input\n");
+             return;
+        }
+    }
+}
+
 /**
- * Provisioning client sample using ProvisioningAPI on provisioningmanager.c
- * To change network type use command line option -w for Wifi and -e for Ethernet
+ * Provisioning client sample using ProvisioningAPI
  */
-int main(int argc, char **argv)
+int main()
 {
-    SPResult res = SP_RESULT_SUCCESS;
-    SPTargetDeviceInfo_t *pDeviceList = NULL;
-    gAcl = (OicSecAcl_t *)OICMalloc(sizeof(OicSecAcl_t));
+    OCStackResult res = OC_STACK_OK;
+    int unused;
+    (void)unused;
 
     // Initialize Persistent Storage for SVR database
-    OCPersistentStorage ps = {};
+    OCPersistentStorage ps = { .open = NULL,
+                               .read = NULL,
+                               .write = NULL,
+                               .close = NULL,
+                               .unlink = NULL };
     ps.open = client_fopen;
     ps.read = fread;
     ps.write = fwrite;
@@ -255,72 +399,175 @@ int main(int argc, char **argv)
     ps.unlink = unlink;
     OCRegisterPersistentStorageHandler(&ps);
 
-    if (OCInit(NULL, 0, OC_CLIENT_SERVER) != OC_STACK_OK)
+    if (OC_STACK_OK != OCInit(NULL, 0, OC_CLIENT_SERVER))
     {
         OC_LOG(ERROR, TAG, "OCStack init error");
-        return 0;
+        goto error;
     }
 
-    if (NULL == gAcl)
+    OCProvisionDev_t* pDeviceList = NULL;
+    res = OCDiscoverUnownedDevices(PREDEFINED_TIMEOUT, &pDeviceList);
+    if(OC_STACK_OK != res)
     {
-        OC_LOG(ERROR, TAG, "Error while memory allocation");
-        return SP_RESULT_MEM_ALLOCATION_FAIL;
+        OC_LOG_V(ERROR, TAG, "Failed to PMDeviceDiscovery : %d", res);
+        goto error;
+    }
+
+    OCProvisionDev_t* pCurDev = pDeviceList;
+    int i;
+    while(pCurDev !=NULL)
+    {
+        for(i = 0; i < UUID_LENGTH; i++)
+            printf("%c", pCurDev->doxm->deviceID.id[i]);
+        printf("\n");
+        pCurDev = pCurDev->next;
+    }
+
+    //Register callback function to each OxM
+    OTMCallbackData_t justWorksCBData = {.loadSecretCB=NULL,
+                                         .createSecureSessionCB=NULL,
+                                         .createSelectOxmPayloadCB=NULL,
+                                         .createOwnerTransferPayloadCB=NULL};
+    justWorksCBData.loadSecretCB = LoadSecretJustWorksCallback;
+    justWorksCBData.createSecureSessionCB = CreateSecureSessionJustWorksCallback;
+    justWorksCBData.createSelectOxmPayloadCB = CreateJustWorksSelectOxmPayload;
+    justWorksCBData.createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
+    OTMSetOwnershipTransferCallbackData(OIC_JUST_WORKS, &justWorksCBData);
+
+    OTMCallbackData_t pinBasedCBData = {.loadSecretCB=NULL,
+                                         .createSecureSessionCB=NULL,
+                                         .createSelectOxmPayloadCB=NULL,
+                                         .createOwnerTransferPayloadCB=NULL};
+    pinBasedCBData.loadSecretCB = InputPinCodeCallback;
+    pinBasedCBData.createSecureSessionCB = CreateSecureSessionRandomPinCallbak;
+    pinBasedCBData.createSelectOxmPayloadCB = CreatePinBasedSelectOxmPayload;
+    pinBasedCBData.createOwnerTransferPayloadCB = CreatePinBasedOwnerTransferPayload;
+    OTMSetOwnershipTransferCallbackData(OIC_RANDOM_DEVICE_PIN, &pinBasedCBData);
+
+    SetInputPinCB(&InputPinCB);
+
+    char* myContext = "OTM Context";
+    //Perform ownership transfer
+    res = OCDoOwnershipTransfer((void*)myContext, pDeviceList, OwnershipTransferCB);
+    if(OC_STACK_OK == res)
+    {
+        OC_LOG(INFO, TAG, "Request for ownership transfer is sent successfully.");
+    }
+    else
+    {
+        OC_LOG_V(ERROR, TAG, "Failed to OCDoOwnershipTransfer : %d", res);
+    }
+
+    gOwnershipState = 0;
+    while ( gOwnershipState == 0 )
+    {
+        if (OCProcess() != OC_STACK_OK)
+        {
+            OC_LOG(ERROR, TAG, "OCStack process error");
+            goto error;
+        }
+        sleep(1);
     }
 
-    res = SPProvisioningDiscovery(PREDEFINED_TIMEOUT, &pDeviceList);
-    if (SP_RESULT_SUCCESS == res)
+// Credential & ACL provisioning between two devices.
+
+    OCProvisionDev_t *pOwnedList = NULL;
+    OCProvisionDev_t *pOwnedDevices [MAX_OWNED_DEVICE] = {0,};
+    int nOwnedDevice = 0;
+
+    res = OCDiscoverOwnedDevices(PREDEFINED_TIMEOUT, &pOwnedList);
+    if (OC_STACK_OK == res)
     {
-        while (pDeviceList != NULL)
+        printf("################## Owned Device List #######################\n");
+        while (pOwnedList != NULL)
         {
-            printf("-Provisioning device ID : ");
-            for (int i = 0; i < MAX_INPUT_ID_LENGTH; i++)
+            nOwnedDevice ++;
+            printf(" %d : ", nOwnedDevice);
+            for (int i = 0; i < UUID_LENGTH; i++)
             {
-                if (pDeviceList->doxm->deviceID.id[i] == '\0')
-                {
-                     break;
-                }
-                printf("%c", pDeviceList->doxm->deviceID.id[i]);
+                printf("%c", pOwnedList->doxm->deviceID.id[i]);
             }
             printf("\n");
-            res = SPInitProvisionContext(PREDEFINED_TIMEOUT, pDeviceList);
-            if (SP_RESULT_SUCCESS != res)
-            {
-                OC_LOG(ERROR, TAG, "Error while init provisioning Context");
-                goto error;
-            }
-            res = InputACL(gAcl);
-            if (SP_RESULT_SUCCESS != res)
-            {
-                OC_LOG(ERROR, TAG, "Error while user ACL input ");
-                goto error;
-            }
-            res = SPProvisionACL(PREDEFINED_TIMEOUT, pDeviceList, gAcl);
-            if (SP_RESULT_SUCCESS != res)
-            {
-                OC_LOG(ERROR, TAG, "Error while provisioning ACL");
-                goto error;
-            }
-            res = SPFinalizeProvisioning(PREDEFINED_TIMEOUT, pDeviceList);
-            if (SP_RESULT_SUCCESS == res)
-            {
-                printf("Provisioning Success~!!\n");
-            }
-            else if (SP_RESULT_SUCCESS != res)
-            {
-                OC_LOG(ERROR, TAG, "Error while Finalize Provisioning");
-                goto error;
-            }
-            pDeviceList = pDeviceList->next;
+            pOwnedDevices[nOwnedDevice] = pOwnedList;
+            pOwnedList = pOwnedList->next;
         }
     }
     else
     {
-        OC_LOG(ERROR, TAG, "Error while Provisioning Discovery");
+        OC_LOG(ERROR, TAG, "Error while Owned Device Discovery");
+    }
+
+    int Device1 = 0;
+    int Device2 = 0;
+
+    printf("Select 2 devices for Credential & ACL provisioning\n");
+    printf("Device 1: ");
+    unused = scanf("%d", &Device1);
+    printf("Device 2: ");
+    unused = scanf("%d", &Device2);
+
+
+    gAcl1 = (OicSecAcl_t *)OICCalloc(1,sizeof(OicSecAcl_t));
+    if (NULL == gAcl1)
+    {
+        OC_LOG(ERROR, TAG, "Error while memory allocation");
+        goto error;
+    }
+
+    gAcl2 = (OicSecAcl_t *)OICCalloc(1,sizeof(OicSecAcl_t));
+    if (NULL == gAcl2)
+    {
+        OC_LOG(ERROR, TAG, "Error while memory allocation");
+        goto error;
+    }
+
+    printf("Input ACL for Device1\n");
+    if ( 0 == InputACL(gAcl1))
+    {
+        printf("Success Input ACL\n");
+    }
+    else
+    {
+        OC_LOG(ERROR, TAG, "InputACL error");
+        goto error;
+    }
+
+    printf("Input ACL for Device2\n");
+    if (0 == InputACL(gAcl2))
+    {
+        printf("Success Input ACL\n");
+    }
+    else
+    {
+        OC_LOG(ERROR, TAG, "InputACL error");
+        goto error;
+    }
+    char *ctx = "DUMMY";
+    OCProvisionPairwiseDevices(ctx,SYMMETRIC_PAIR_WISE_KEY, OWNER_PSK_LENGTH_128, pOwnedDevices[Device1],
+                           gAcl1, pOwnedDevices[Device2], gAcl2, ProvisionPairwiseCB);
+
+    gOwnershipState = 0;
+    while ( gOwnershipState == 0 )
+    {
+        if (OCProcess() != OC_STACK_OK)
+        {
+            OC_LOG(ERROR, TAG, "OCStack process error");
+            goto error;
+        }
+        sleep(1);
+    }
+
+    if (OCStop() != OC_STACK_OK)
+    {
+        OC_LOG(ERROR, TAG, "OCStack process error");
         goto error;
     }
 
 error:
-    DeleteACLList(gAcl);
-    SPTerminateProvisioning();
+    deleteACL(gAcl1);
+    deleteACL(gAcl2);
+    OCDeleteDiscoveredDevices(&pDeviceList);
+    OCDeleteDiscoveredDevices(&pOwnedList);
+
     return 0;
 }