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 "oic_string.h"
32 #include "securevirtualresourcetypes.h"
34 #include "ck_manager.h"
36 #include "crlresource.h"
38 #define MAX_URI_LENGTH (64)
39 #define MAX_PERMISSION_LENGTH (5)
40 #define MAX_ACL_LENGTH 100
47 #define PREDEFINED_TIMEOUT (10)
48 #define MAX_OWNED_DEVICE (10)
49 #define DATE_LENGTH (14)
50 #define TAG "provisioningclient"
52 static OicSecAcl_t *gAcl = NULL;
53 static OicSecCrl_t *gCrl = NULL;
54 static char PROV_TOOL_DB_FILE[] = "oic_svr_db_pt.dat";
55 static const char* PRVN_DB_FILE_NAME = "oic_prvn_mng.db";
56 static int gOwnershipState = 0;
60 ownershipDone = 1 << 1,
61 finalizeDone = 1 << 2,
62 provisionAclDone = 1 << 3,
63 provisionCert1Done = 1 << 4,
64 provisionCert2Done = 1 << 5,
65 provisionCrlDone = 1 << 6
70 * Perform cleanup for ACL
73 static void deleteACL(OicSecAcl_t *acl)
75 if (acl && MAX_ACL_LENGTH > acl->resourcesLen)
78 for (size_t i = 0; i < (acl)->resourcesLen; i++)
80 OICFree((acl)->resources[i]);
82 OICFree((acl)->resources);
84 /* Clean ACL node itself */
91 void deleteCrl(OicSecCrl_t *crl)
96 OICFree(crl->ThisUpdate.data);
99 OICFree(crl->CrlData.data);
107 * Calculate ACL permission from string to bit
109 * @param[in] temp_psm Input data of ACL permission string
110 * @param[in,out] pms The pointer of ACL permission value
111 * @return 0 on success otherwise -1.
113 static int CalculateAclPermission(const char *temp_pms, uint16_t *pms)
117 if (NULL == temp_pms || NULL == pms)
122 while (temp_pms[i] != '\0')
171 * Get the ACL property from user
173 * @param[in] ACL Datastructure to save user inputs
174 * @return 0 on success otherwise -1.
176 static int InputACL(OicSecAcl_t *acl)
179 char temp_id [UUID_LENGTH + 4] = {0,};
180 char temp_rsc[MAX_URI_LENGTH + 1] = {0,};
181 char temp_pms[MAX_PERMISSION_LENGTH + 1] = {0,};
182 printf("******************************************************************************\n");
183 printf("-Set ACL policy for target device\n");
184 printf("******************************************************************************\n");
186 printf("-URN identifying the subject\n");
187 printf("ex) doorDeviceUUID00 (16 Numbers except to '-')\n");
188 printf("Subject : ");
190 ret = scanf("%19ms", &ptr);
193 OICStrcpy(temp_id, sizeof(temp_id), ptr);
198 printf("Error while input\n");
202 for (int i = 0; temp_id[i] != '\0'; i++)
204 if (DASH != temp_id[i])
208 printf("Invalid input\n");
211 acl->subject.id[j++] = temp_id[i];
216 printf("Num. of Resource : \n");
217 ret = scanf("%zu", &acl->resourcesLen);
218 if(-1 == ret || MAX_ACL_LENGTH < acl->resourcesLen)
220 printf("Error while input\n");
223 printf("-URI of resource\n");
224 printf("ex) /a/light (Max_URI_Length: 64 Byte )\n");
225 acl->resources = (char **)OICCalloc(acl->resourcesLen, sizeof(char *));
226 if (NULL == acl->resources)
228 OIC_LOG(ERROR, TAG, "Error while memory allocation");
231 for (size_t i = 0; i < acl->resourcesLen; i++)
233 printf("[%zu]Resource : ", i + 1);
234 char *ptr_tempRsc = NULL;
235 ret = scanf("%64ms", &ptr_tempRsc);
238 OICStrcpy(temp_rsc, sizeof(temp_rsc), ptr_tempRsc);
239 OICFree(ptr_tempRsc);
243 printf("Error while input\n");
246 acl->resources[i] = OICStrdup(temp_rsc);
248 if (NULL == acl->resources[i])
250 OIC_LOG(ERROR, TAG, "Error while memory allocation");
257 printf("-Set the permission(C,R,U,D,N)\n");
258 printf("ex) CRUDN, CRU_N,..(5 Charaters)\n");
259 printf("Permission : ");
260 char *ptr_temp_pms = NULL;
261 ret = scanf("%5ms", &ptr_temp_pms);
264 OICStrcpy(temp_pms, sizeof(temp_pms), ptr_temp_pms);
265 OICFree(ptr_temp_pms);
270 printf("Error while input\n");
274 while (0 != CalculateAclPermission(temp_pms, &(acl->permission)) );
276 printf("-URN identifying the rowner\n");
277 printf("ex) lightDeviceUUID0 (16 Numbers except to '-')\n");
280 char *ptr_temp_id = NULL;
281 ret = scanf("%19ms", &ptr_temp_id);
284 OICStrcpy(temp_id, sizeof(temp_id), ptr_temp_id);
285 OICFree(ptr_temp_id);
289 printf("Error while input\n");
293 for (int k = 0; temp_id[k] != '\0'; k++)
295 if (DASH != temp_id[k])
297 acl->rownerID.id[j++] = temp_id[k];
304 //FILE *client_fopen(const char *path, const char *mode)
305 FILE *client_fopen(const char* UNUSED_PARAM , const char *mode)
308 return fopen(PROV_TOOL_DB_FILE, mode);
311 void PrintfResult(const char* procName, void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
313 printf("-----------------------------------------------------------\n");
316 printf("%s was successfully done.\n", procName);
320 for(int i = 0; i < nOfRes; i++)
323 for(int j = 0; j < UUID_LENGTH; j++)
325 printf("%c", arr[i].deviceId.id[j]);
328 printf("Result=%d\n", arr[i].res);
334 printf("Context is %s\n", (char*)ctx);
336 printf("-----------------------------------------------------------\n");
339 void ProvisionCertCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
344 PrintfResult("Provision Credential", ctx, nOfRes, arr, hasError);
346 else printf("Cert provisioning error\n-----------------------------------------");
349 void ProvisionAclCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
354 PrintfResult("Provision ACL", ctx, nOfRes, arr, hasError);
358 void ProvisionCrlCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
363 PrintfResult("Provision CRL", ctx, nOfRes, arr, hasError);
369 void OwnershipTransferCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
374 PrintfResult("Ownership transfer", ctx, nOfRes, arr, hasError);
378 static short IsCKMInfoFileExists()
380 FILE *ckmInf = fopen(CA_STORAGE_FILE, "r");
389 static PKIError InitCA()
393 if (IsCKMInfoFileExists())
395 CHECK_CALL(InitCKMInfo);
399 ByteArray rootName = BYTE_ARRAY_INITIALIZER;
400 ByteArray CAPubKey = BYTE_ARRAY_INITIALIZER;
401 ByteArray CAPrivKey = BYTE_ARRAY_INITIALIZER;
402 ByteArray rootCert = BYTE_ARRAY_INITIALIZER;
405 uint8_t rootCertData[ISSUER_MAX_CERT_SIZE];
406 uint8_t CAPubKeyData[PUBLIC_KEY_SIZE];
407 uint8_t CAPrivKeyData[PRIVATE_KEY_SIZE];
408 const char rootNameStr[] = "Sample_Root";
410 CAPubKey.data = CAPubKeyData;
411 CAPubKey.len = PUBLIC_KEY_SIZE;
412 CAPrivKey.data = CAPrivKeyData;
413 CAPrivKey.len = PRIVATE_KEY_SIZE;
414 rootCert.data = rootCertData;
415 rootCert.len = ISSUER_MAX_CERT_SIZE;
416 rootName.data = (uint8_t *)rootNameStr;
417 rootName.len = strlen(rootNameStr);
419 CHECK_CALL(SetRootName, rootName);
420 CHECK_CALL(GenerateCAKeyPair, &CAPrivKey, &CAPubKey);
421 CHECK_CALL(SetSerialNumber, 1);
422 CHECK_CALL(CKMIssueRootCertificate, NULL, NULL, &rootCert);
423 CHECK_CALL(SetCACertificate, &rootCert);
429 static int InputCRL(OicSecCrl_t *crlRes)
432 ByteArray crl = BYTE_ARRAY_INITIALIZER;
435 const int MAX_Revoked_NUMBER = 9;
436 uint8_t uint8ThisUpdateTime[DATE_LENGTH] = "130101000005Z";
437 uint32_t revokedNumbers[MAX_Revoked_NUMBER];
438 const uint8_t* revocationDates[MAX_Revoked_NUMBER];
439 // const uint8_t revocationDatesContent[MAX_Revoked_NUMBER][DATE_LENGTH];
440 uint32_t nuberOfRevoked = 0;
441 printf("Enter number of Revoked certificates(1..%d)\n", MAX_Revoked_NUMBER);
443 ret = scanf("%u", &nuberOfRevoked);
446 printf("Error while input\n");
447 return PKI_UNKNOWN_ERROR;
450 if((uint32_t)MAX_Revoked_NUMBER < nuberOfRevoked)
452 OIC_LOG(ERROR, TAG, "Wrong revoked certificate number");
453 return PKI_UNKNOWN_ERROR;
456 for (size_t i = 0; i < nuberOfRevoked; ++i)
458 printf("Revoked certificate %d:", i);
459 printf("Serial number (E. g.: 100):");
460 ret = scanf("%u", &revokedNumbers[i]);
463 printf("Error while input\n");
464 return PKI_UNKNOWN_ERROR;
467 revocationDates[i] = (const uint8_t*)"130101000005Z";
470 crl.len = CRL_MIN_SIZE + nuberOfRevoked * (sizeof(CertificateRevocationInfo_t) + 4)/* + 1000*/;
471 crl.data = (uint8_t *)OICCalloc(1, crl.len);
473 if (NULL == crl.data)
475 OIC_LOG(ERROR, TAG, "Error while memory allocation");
476 return PKI_MEMORY_ALLOC_FAILED;
479 CHECK_CALL(CKMIssueCRL, uint8ThisUpdateTime, nuberOfRevoked, revokedNumbers,
480 revocationDates, &crl);
481 PRINT_BYTE_ARRAY("CRL:\n",crl);
482 CHECK_CALL(SetCertificateRevocationList, &crl);
483 crlRes->CrlData = crl;
484 crlRes->ThisUpdate.data = uint8ThisUpdateTime;
485 crlRes->ThisUpdate.len = DATE_LENGTH;
496 * Provisioning client sample using ProvisioningAPI
500 OCStackResult res = OC_STACK_OK;
501 OCProvisionDev_t* pDeviceList = NULL;
502 OCProvisionDev_t *pOwnedList = NULL;
504 // Initialize Persistent Storage for SVR database
505 OCPersistentStorage ps = { .open = client_fopen,
511 OCRegisterPersistentStorageHandler(&ps);
513 if (OC_STACK_OK != OCInit(NULL, 0, OC_CLIENT_SERVER))
515 OIC_LOG(ERROR, TAG, "OCStack init error");
518 if(OC_STACK_OK != OCInitPM(PRVN_DB_FILE_NAME))
520 OIC_LOG(ERROR, TAG, "OC_PM init error");
524 res = OCDiscoverUnownedDevices(PREDEFINED_TIMEOUT, &pDeviceList);
525 if(OC_STACK_OK != res)
527 OIC_LOG_V(ERROR, TAG, "Failed to PMDeviceDiscovery : %d", res);
531 OCProvisionDev_t* pCurDev = pDeviceList;
533 while(pCurDev !=NULL)
535 for(i = 0; i < UUID_LENGTH; i++)
537 printf("%c", pCurDev->doxm->deviceID.id[i]);
540 pCurDev = pCurDev->next;
543 //Register callback function to each OxM
544 OTMCallbackData_t justWorksCBData = {.loadSecretCB=NULL,
545 .createSecureSessionCB=NULL,
546 .createSelectOxmPayloadCB=NULL,
547 .createOwnerTransferPayloadCB=NULL};
548 justWorksCBData.loadSecretCB = LoadSecretJustWorksCallback;
549 justWorksCBData.createSecureSessionCB = CreateSecureSessionJustWorksCallback;
550 justWorksCBData.createSelectOxmPayloadCB = CreateJustWorksSelectOxmPayload;
551 justWorksCBData.createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
552 OTMSetOwnershipTransferCallbackData(OIC_JUST_WORKS, &justWorksCBData);
554 char* myContext = "OTM Context";
555 //Perform ownership transfer
556 res = OCDoOwnershipTransfer((void*)myContext, pDeviceList, OwnershipTransferCB);
557 if(OC_STACK_OK == res)
559 OIC_LOG(INFO, TAG, "Request for ownership transfer is sent successfully.");
563 OIC_LOG_V(ERROR, TAG, "Failed to OCDoOwnershipTransfer : %d", res);
567 while (gOwnershipState == 0)
569 if (OCProcess() != OC_STACK_OK)
571 OIC_LOG(ERROR, TAG, "OCStack process error");
577 // Credential & ACL provisioning between two devices.
579 OCProvisionDev_t *pOwnedDevices [MAX_OWNED_DEVICE] = {0,};
580 int nOwnedDevice = 0;
582 res = OCDiscoverOwnedDevices(PREDEFINED_TIMEOUT, &pOwnedList);
583 if (OC_STACK_OK == res)
585 printf("################## Owned Device List #######################\n");
586 while (pOwnedList != NULL)
589 printf(" %d : ", nOwnedDevice);
590 for (int i = 0; i < UUID_LENGTH; i++)
592 printf("%c", pOwnedList->doxm->deviceID.id[i]);
595 pOwnedDevices[nOwnedDevice] = pOwnedList;
596 pOwnedList = pOwnedList->next;
601 OIC_LOG(ERROR, TAG, "Error while Owned Device Discovery");
608 printf("Select 2 devices for Credential & ACL provisioning\n");
609 printf("Device 1: ");
610 ret = scanf("%d", &Device1);
613 printf("Error while input\n");
617 printf("Device 2: ");
618 ret = scanf("%d", &Device2);
621 printf("Error while input\n");
625 if( 0 > Device1 || 0 > Device2 || Device1 > nOwnedDevice || Device2 > nOwnedDevice)
627 OIC_LOG(ERROR, TAG, "Wrong devices number");
631 gAcl = (OicSecAcl_t *)OICCalloc(1,sizeof(OicSecAcl_t));
634 OIC_LOG(ERROR, TAG, "Error while memory allocation");
638 if (PKI_SUCCESS != InitCA())
640 OIC_LOG(ERROR, TAG, "CA init error");
647 res = OCProvisionCredentials(ctx, SIGNED_ASYMMETRIC_KEY, 0, pOwnedDevices[Device1],
648 NULL, ProvisionCertCB);
649 if (OC_STACK_OK != res) OIC_LOG_V(ERROR, TAG, "Failed to provision Device 1 : %d", res);
651 while ( gOwnershipState == 0 )
653 if (OCProcess() != OC_STACK_OK)
655 OIC_LOG(ERROR, TAG, "OCStack process error");
661 res = OCProvisionCredentials(ctx, SIGNED_ASYMMETRIC_KEY, 0, pOwnedDevices[Device2],
662 NULL, ProvisionCertCB);
663 if (OC_STACK_OK != res)
665 OIC_LOG_V(ERROR, TAG, "Failed to provision Device 2 : %d", res);
669 while (gOwnershipState == 0)
671 if (OCProcess() != OC_STACK_OK)
673 OIC_LOG(ERROR, TAG, "OCStack process error");
679 printf("Input ACL for Device2\n");
680 if (0 == InputACL(gAcl))
682 printf("Success Input ACL\n");
686 OIC_LOG(ERROR, TAG, "InputACL error");
689 res = OCProvisionACL(ctx, pOwnedDevices[Device2], gAcl, &ProvisionAclCB);
690 if (OC_STACK_OK != res)
692 OIC_LOG_V(ERROR, TAG, "Failed to ACL provision Device 2 : %d", res);
696 while (gOwnershipState == 0)
698 if (OCProcess() != OC_STACK_OK)
700 OIC_LOG(ERROR, TAG, "OCStack process error");
705 gCrl = (OicSecCrl_t *)OICMalloc(sizeof(OicSecCrl_t));
709 OIC_LOG(ERROR, TAG, "Error while memory allocation");
713 if (PKI_SUCCESS != InputCRL(gCrl))
715 OIC_LOG(ERROR, TAG, "CA init error");
719 PRINT_BYTE_ARRAY("gCrl = \n", gCrl->CrlData);
721 res = OCProvisionCRL(ctx, pOwnedDevices[Device2], gCrl, &ProvisionCrlCB);
722 if (OC_STACK_OK != res) OIC_LOG_V(ERROR, TAG, "Failed to CRL provision Device 2 : %d", res);
725 while (gOwnershipState == 0)
727 if (OCProcess() != OC_STACK_OK)
729 OIC_LOG(ERROR, TAG, "OCStack process error");
735 if (OCStop() != OC_STACK_OK)
737 OIC_LOG(ERROR, TAG, "OCStack process error");
743 OCDeleteDiscoveredDevices(pDeviceList);
744 OCDeleteDiscoveredDevices(pOwnedList);