1 /******************************************************************
3 * Copyright 2015 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
26 #include "oic_malloc.h"
28 #include "ocprovisioningmanager.h"
29 #include "secureresourceprovider.h"
30 #include "oxmjustworks.h"
31 #include "oxmrandompin.h"
32 #include "pinoxmcommon.h"
33 #include "oic_string.h"
35 #define MAX_URI_LENGTH (64)
36 #define MAX_PERMISSION_LENGTH (5)
43 #define PREDEFINED_TIMEOUT (10)
44 #define MAX_OWNED_DEVICE (10)
45 #define TAG "provisioningclient"
47 static char CRED_FILE[] = "oic_svr_db_client.json";
48 static OicSecAcl_t *gAcl1 = NULL;
49 static OicSecAcl_t *gAcl2 = NULL;
50 static int gOwnershipState = 0;
54 ownershipDone = 1 << 1,
55 finalizeDone = 1 << 2,
56 provisionCredDone = 1 << 3,
57 provisionAclDone = 1 << 4
62 * Perform cleanup for ACL
65 static void deleteACL(OicSecAcl_t *acl)
70 for (size_t i = 0; i < (acl)->resourcesLen; i++)
72 OICFree((acl)->resources[i]);
74 OICFree((acl)->resources);
77 OICFree((acl)->owners);
79 /* Clean ACL node itself */
87 * Calculate ACL permission from string to bit
89 * @param[in] temp_psm Input data of ACL permission string
90 * @param[in,out] pms The pointer of ACL permission value
91 * @return 0 on success otherwise -1.
93 static int CalculateAclPermission(const char *temp_pms, uint16_t *pms)
97 if (NULL == temp_pms || NULL == pms)
102 while (temp_pms[i] != '\0')
151 * Get the ACL property from user
153 * @param[in] ACL Datastructure to save user inputs
154 * @return 0 on success otherwise -1.
156 static int InputACL(OicSecAcl_t *acl)
159 char temp_id [UUID_LENGTH + 4] = {0,};
160 char temp_rsc[MAX_URI_LENGTH + 1] = {0,};
161 char temp_pms[MAX_PERMISSION_LENGTH + 1] = {0,};
162 printf("******************************************************************************\n");
163 printf("-Set ACL policy for target device\n");
164 printf("******************************************************************************\n");
166 printf("-URN identifying the subject\n");
167 printf("ex) 1111-1111-1111-1111 (16 Numbers except to '-')\n");
168 printf("Subject : ");
170 ret = scanf("%19ms", &ptr);
173 OICStrcpy(temp_id, sizeof(temp_id), ptr);
178 printf("Error while input\n");
182 for (int i = 0; temp_id[i] != '\0'; i++)
184 if (DASH != temp_id[i])
188 printf("Invalid input\n");
191 acl->subject.id[j++] = temp_id[i];
196 printf("Num. of Resource : \n");
197 ret = scanf("%zu", &acl->resourcesLen);
198 printf("-URI of resource\n");
199 printf("ex)/oic/sh/temp/0 (Max_URI_Length: 64 Byte )\n");
200 acl->resources = (char **)OICCalloc(acl->resourcesLen, sizeof(char *));
201 if (NULL == acl->resources)
203 OC_LOG(ERROR, TAG, "Error while memory allocation");
206 for (size_t i = 0; i < acl->resourcesLen; i++)
208 printf("[%zu]Resource : ", i + 1);
209 char *ptr_tempRsc = NULL;
210 ret = scanf("%64ms", &ptr_tempRsc);
213 OICStrcpy(temp_rsc, sizeof(temp_rsc), ptr_tempRsc);
214 OICFree(ptr_tempRsc);
218 printf("Error while input\n");
221 acl->resources[i] = OICStrdup(temp_rsc);
223 if (NULL == acl->resources[i])
225 OC_LOG(ERROR, TAG, "Error while memory allocation");
232 printf("-Set the permission(C,R,U,D,N)\n");
233 printf("ex) CRUDN, CRU_N,..(5 Charaters)\n");
234 printf("Permission : ");
235 char *ptr_temp_pms = NULL;
236 ret = scanf("%5ms", &ptr_temp_pms);
239 OICStrcpy(temp_pms, sizeof(temp_pms), ptr_temp_pms);
240 OICFree(ptr_temp_pms);
245 printf("Error while input\n");
249 while (0 != CalculateAclPermission(temp_pms, &(acl->permission)) );
251 printf("Num. of Rowner : ");
252 ret = scanf("%zu", &acl->ownersLen);
253 printf("-URN identifying the rowner\n");
254 printf("ex) 1111-1111-1111-1111 (16 Numbers except to '-')\n");
255 acl->owners = (OicUuid_t *)OICCalloc(acl->ownersLen, sizeof(OicUuid_t));
256 if (NULL == acl->owners)
258 OC_LOG(ERROR, TAG, "Error while memory allocation");
261 for (size_t i = 0; i < acl->ownersLen; i++)
263 printf("[%zu]Rowner : ", i + 1);
264 char *ptr_temp_id = NULL;
265 ret = scanf("%19ms", &ptr_temp_id);
268 OICStrcpy(temp_id, sizeof(temp_id), ptr_temp_id);
269 OICFree(ptr_temp_id);
273 printf("Error while input\n");
277 for (int k = 0; temp_id[k] != '\0'; k++)
279 if (DASH != temp_id[k])
281 acl->owners[i].id[j++] = temp_id[k];
289 //FILE *client_fopen(const char *path, const char *mode)
290 FILE *client_fopen(const char* UNUSED_PARAM , const char *mode)
293 return fopen(CRED_FILE, mode);
296 void PrintfResult(const char* procName, void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
298 printf("-----------------------------------------------------------\n");
301 printf("%s was successfully done.\n", procName);
305 for(int i = 0; i < nOfRes; i++)
308 for(int j = 0; j < UUID_LENGTH; i++)
310 printf("%c", arr[i].deviceId.id[j]);
313 printf("Result=%d\n", arr[i].res);
319 printf("Context is %s\n", (char*)ctx);
321 printf("-----------------------------------------------------------\n");
324 void ProvisionCredCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
329 PrintfResult("Provision Credential", ctx, nOfRes, arr, hasError);
333 void ProvisionAclCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
338 PrintfResult("Provision ACL", ctx, nOfRes, arr, hasError);
342 void ProvisionPairwiseCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
347 PrintfResult("Provision Pairwise Credential", ctx, nOfRes, arr, hasError);
351 void OwnershipTransferCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
356 PrintfResult("Ownership transfer", ctx, nOfRes, arr, hasError);
360 void InputPinCB(char* pinBuf, size_t bufSize)
364 printf("INPUT PIN : ");
366 int ret = scanf("%ms", &ptr);
369 OICStrcpy(pinBuf, bufSize, ptr);
374 printf("Error in input\n");
381 * Provisioning client sample using ProvisioningAPI
385 OCStackResult res = OC_STACK_OK;
389 // Initialize Persistent Storage for SVR database
390 OCPersistentStorage ps = { .open = NULL,
395 ps.open = client_fopen;
400 OCRegisterPersistentStorageHandler(&ps);
402 if (OC_STACK_OK != OCInit(NULL, 0, OC_CLIENT_SERVER))
404 OC_LOG(ERROR, TAG, "OCStack init error");
408 OCProvisionDev_t* pDeviceList = NULL;
409 res = OCDiscoverUnownedDevices(PREDEFINED_TIMEOUT, &pDeviceList);
410 if(OC_STACK_OK != res)
412 OC_LOG_V(ERROR, TAG, "Failed to PMDeviceDiscovery : %d", res);
416 OCProvisionDev_t* pCurDev = pDeviceList;
418 while(pCurDev !=NULL)
420 for(i = 0; i < UUID_LENGTH; i++)
421 printf("%c", pCurDev->doxm->deviceID.id[i]);
423 pCurDev = pCurDev->next;
426 //Register callback function to each OxM
427 OTMCallbackData_t justWorksCBData = {.loadSecretCB=NULL,
428 .createSecureSessionCB=NULL,
429 .createSelectOxmPayloadCB=NULL,
430 .createOwnerTransferPayloadCB=NULL};
431 justWorksCBData.loadSecretCB = LoadSecretJustWorksCallback;
432 justWorksCBData.createSecureSessionCB = CreateSecureSessionJustWorksCallback;
433 justWorksCBData.createSelectOxmPayloadCB = CreateJustWorksSelectOxmPayload;
434 justWorksCBData.createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
435 OTMSetOwnershipTransferCallbackData(OIC_JUST_WORKS, &justWorksCBData);
437 OTMCallbackData_t pinBasedCBData = {.loadSecretCB=NULL,
438 .createSecureSessionCB=NULL,
439 .createSelectOxmPayloadCB=NULL,
440 .createOwnerTransferPayloadCB=NULL};
441 pinBasedCBData.loadSecretCB = InputPinCodeCallback;
442 pinBasedCBData.createSecureSessionCB = CreateSecureSessionRandomPinCallbak;
443 pinBasedCBData.createSelectOxmPayloadCB = CreatePinBasedSelectOxmPayload;
444 pinBasedCBData.createOwnerTransferPayloadCB = CreatePinBasedOwnerTransferPayload;
445 OTMSetOwnershipTransferCallbackData(OIC_RANDOM_DEVICE_PIN, &pinBasedCBData);
447 SetInputPinCB(&InputPinCB);
449 char* myContext = "OTM Context";
450 //Perform ownership transfer
451 res = OCDoOwnershipTransfer((void*)myContext, pDeviceList, OwnershipTransferCB);
452 if(OC_STACK_OK == res)
454 OC_LOG(INFO, TAG, "Request for ownership transfer is sent successfully.");
458 OC_LOG_V(ERROR, TAG, "Failed to OCDoOwnershipTransfer : %d", res);
462 while ( gOwnershipState == 0 )
464 if (OCProcess() != OC_STACK_OK)
466 OC_LOG(ERROR, TAG, "OCStack process error");
472 // Credential & ACL provisioning between two devices.
474 OCProvisionDev_t *pOwnedList = NULL;
475 OCProvisionDev_t *pOwnedDevices [MAX_OWNED_DEVICE] = {0,};
476 int nOwnedDevice = 0;
478 res = OCDiscoverOwnedDevices(PREDEFINED_TIMEOUT, &pOwnedList);
479 if (OC_STACK_OK == res)
481 printf("################## Owned Device List #######################\n");
482 while (pOwnedList != NULL)
485 printf(" %d : ", nOwnedDevice);
486 for (int i = 0; i < UUID_LENGTH; i++)
488 printf("%c", pOwnedList->doxm->deviceID.id[i]);
491 pOwnedDevices[nOwnedDevice] = pOwnedList;
492 pOwnedList = pOwnedList->next;
497 OC_LOG(ERROR, TAG, "Error while Owned Device Discovery");
503 printf("Select 2 devices for Credential & ACL provisioning\n");
504 printf("Device 1: ");
505 unused = scanf("%d", &Device1);
506 printf("Device 2: ");
507 unused = scanf("%d", &Device2);
510 gAcl1 = (OicSecAcl_t *)OICCalloc(1,sizeof(OicSecAcl_t));
513 OC_LOG(ERROR, TAG, "Error while memory allocation");
517 gAcl2 = (OicSecAcl_t *)OICCalloc(1,sizeof(OicSecAcl_t));
520 OC_LOG(ERROR, TAG, "Error while memory allocation");
524 printf("Input ACL for Device1\n");
525 if ( 0 == InputACL(gAcl1))
527 printf("Success Input ACL\n");
531 OC_LOG(ERROR, TAG, "InputACL error");
535 printf("Input ACL for Device2\n");
536 if (0 == InputACL(gAcl2))
538 printf("Success Input ACL\n");
542 OC_LOG(ERROR, TAG, "InputACL error");
546 OCProvisionPairwiseDevices(ctx,SYMMETRIC_PAIR_WISE_KEY, OWNER_PSK_LENGTH_128, pOwnedDevices[Device1],
547 gAcl1, pOwnedDevices[Device2], gAcl2, ProvisionPairwiseCB);
550 while ( gOwnershipState == 0 )
552 if (OCProcess() != OC_STACK_OK)
554 OC_LOG(ERROR, TAG, "OCStack process error");
560 if (OCStop() != OC_STACK_OK)
562 OC_LOG(ERROR, TAG, "OCStack process error");
569 OCDeleteDiscoveredDevices(&pDeviceList);
570 OCDeleteDiscoveredDevices(&pOwnedList);