1 /******************************************************************
3 * Copyright 2017 Microsoft. 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 *****************************************************************/
22 * This file is derived from iotivity\resource\csdk\security\provisioning\sample\provisioningclient.c
23 * That program is interactive, and requires user input to perform provisioning
24 * steps, while this version takes input on the command line and executes a
25 * sequence of provisioning operations automatically, then exists, reporting
26 * whether the sequence succeeded. This is so that we can script provisioning
30 #include "iotivity_config.h"
38 #include "payload_logging.h"
41 #include "oic_malloc.h"
42 #include "oic_string.h"
43 #include "ocprovisioningmanager.h"
44 #include "oxmjustworks.h"
45 #include "oxmrandompin.h"
46 #include "srmutility.h"
48 #include "oxmverifycommon.h"
49 #include "occertutility.h"
50 #include "ocsecurity.h"
51 #include "ocstackinternal.h"
52 #include "pmutility.h"
58 #define access _access_s
66 #define DISCOVERY_TIMEOUT 3 // 3 sec
67 #define CALLBACK_TIMEOUT 60 // 1 min
68 #define TAG "autoprovisioningclient"
70 static const char* SVR_DB_FILE_NAME = "oic_svr_db_client.dat";
71 // '_' for separaing from the same constant variable in |srmresourcestrings.c|
72 static const char* PRVN_DB_FILE_NAME = "oic_autoprvn_mng.db";
74 static const char* TEST_CERT_NOT_BEFORE = "20170101000000"; // Not before field for certificates, in format YYYYMMDDhhmmss
75 static const char* TEST_CERT_NOT_AFTER = "20270101000000"; // + ten years
76 static const char* TEST_CERT_ROLE1 = "IoTivity-test-role1";
77 static const char* TEST_CERT_ROLE2 = "IoTivity-test-role2";
78 static const char* TEST_CERT_AUTHORITY = "IoTivity-test-OBT-authority-name";
80 // |g_ctx| means provision manager application context and
81 // the following, includes |un/own_list|, could be variables, which |g_ctx| has,
82 // for accessing all function(s) for these, they are declared on global domain
83 static char* g_ctx = "Provision Manager Client Application Context";
84 static char* g_svr_fname;
85 static char* g_prvn_fname;
86 static OCProvisionDev_t* g_own_list;
87 static OCProvisionDev_t* g_unown_list;
89 static int g_unown_cnt;
90 static char* g_csr; /* Certificate signing request from device */
91 static OicUuid_t g_uuidDev1;
92 static char* g_idPublicKey = NULL;
94 static volatile bool g_doneCB; /* Set to true by the callback to indicate it completed. */
95 static bool g_successCB; /* Set to true by the callback to indicate success. */
97 // function declaration(s) for calling them before implementing
98 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t*, const int);
99 static int printDevList(const OCProvisionDev_t*);
100 static size_t printResultList(const OCProvisionResult_t*, const size_t);
101 static void printUuid(const OicUuid_t*);
102 static int saveUuid(const OCProvisionResult_t* rslt_lst, const size_t rslt_cnt);
103 static FILE* fopen_prvnMng(const char*, const char*);
104 static int waitCallbackRet(void);
107 * Test CA key and certificate created with
108 * iotivity/resource/csdk/security/scripts/test_cert_generation.sh
110 static const char* g_caCertPem = "-----BEGIN CERTIFICATE-----\n"
111 "MIIBfjCCASSgAwIBAgIJAPQXoGTceaW5MAoGCCqGSM49BAMCMBkxFzAVBgNVBAoM\n"
112 "DklvVGl2aXR5VGVzdENBMB4XDTE3MDMxNTAwNTExOVoXDTMwMTEyMjAwNTExOVow\n"
113 "GTEXMBUGA1UECgwOSW9UaXZpdHlUZXN0Q0EwWTATBgcqhkjOPQIBBggqhkjOPQMB\n"
114 "BwNCAARvYPdt+LjqASlHoc2zrjo3hHGjZsI31c+bg9AwINW5TuRZsE03w/Ejotza\n"
115 "y4VDLImMlDhGP+K/f6OmKD3FNHhKo1UwUzAhBgNVHSUEGjAYBgorBgEEAYLefAEG\n"
116 "BgorBgEEAYLefAEHMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNw+hm69Rxb5\n"
117 "UpclERf5r85g1nwmMAoGCCqGSM49BAMCA0gAMEUCIQDbvNLA3ZkwEzuoH6XUR6JS\n"
118 "UzZTVgsDgnJcOqtqOg0qEAIgUJR2g8XlMxqiuXP7JdwALdtnvCQTlJQbuD1gu+Jy\n"
120 "-----END CERTIFICATE-----\n";
122 static const char* g_caKeyPem = "-----BEGIN EC PRIVATE KEY-----\n"
123 "MHcCAQEEILx9VOHDrMYuan6SXN4CQIHHXNq6SjzanaDFDgIaOaXloAoGCCqGSM49\n"
124 "AwEHoUQDQgAEb2D3bfi46gEpR6HNs646N4Rxo2bCN9XPm4PQMCDVuU7kWbBNN8Px\n"
125 "I6Lc2suFQyyJjJQ4Rj/iv3+jpig9xTR4Sg==\n"
126 "-----END EC PRIVATE KEY-----\n";
129 /* At a few places in this file, warning 4028 is incorrectly produced, disable it for the whole file. */
131 #pragma warning( disable : 4028)
134 // callback function(s) for provisioning client using C-level provisioning API
135 static void ownershipTransferCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
140 OIC_LOG_V(INFO, TAG, "Ownership Transfer SUCCEEDED - ctx: %s", (char*) ctx);
141 if (saveUuid((const OCProvisionResult_t*)arr, nOfRes) == 0)
148 OIC_LOG_V(ERROR, TAG, "Ownership Transfer FAILED - ctx: %s", (char*) ctx);
149 printResultList((const OCProvisionResult_t*) arr, nOfRes);
155 static void provisionCredCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
159 OIC_LOG_V(INFO, TAG, "Provision Credential SUCCEEDED - ctx: %s", (char*) ctx);
164 OIC_LOG_V(ERROR, TAG, "Provision Credential FAILED - ctx: %s", (char*) ctx);
165 printResultList((const OCProvisionResult_t*) arr, nOfRes);
171 /* Function of type OCProvisionResultCB from \resource\csdk\security\provisioning\include\pmtypes.h */
172 void provisionTrustChainCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
176 OIC_LOG_V(INFO, TAG, "Provision Credential SUCCEEDED - ctx: %s", (char*)ctx);
181 OIC_LOG_V(ERROR, TAG, "Provision Credential FAILED - ctx: %s", (char*)ctx);
182 printResultList((const OCProvisionResult_t*)arr, nOfRes);
188 static void getCsrForCertProvCB(void* ctx, size_t nOfRes, OCPMGetCsrResult_t* arr, bool hasError)
196 OIC_LOG_V(ERROR, TAG, "getCsrForCertProvCB FAILED - ctx: %s", (char*)ctx);
200 if (arr[0].encoding == OIC_ENCODING_DER)
202 OCStackResult res = OCConvertDerCSRToPem((char*)arr[0].csr, arr[0].csrLen, &g_csr);
203 if (res != OC_STACK_OK)
205 OIC_LOG_V(ERROR, TAG, "getCsrForCertProvCB FAILED (CSR re-encoding failed) - error: %d, ctx: %s", res, (char*)ctx);
210 else if (arr[0].encoding == OIC_ENCODING_PEM)
212 g_csr = (char*)OICCalloc(1, arr[0].csrLen);
215 OIC_LOG_V(ERROR, TAG, "getCsrForCertProvCB FAILED (memory allocation) - ctx: %s", (char*)ctx);
219 memcpy(g_csr, arr[0].csr, arr[0].csrLen);
221 OIC_LOG(INFO, TAG, "getCsrForCertProvCB success");
226 OIC_LOG_V(ERROR, TAG, "getCsrForCertProvCB FAILED (unknown encoding) - ctx: %s", (char*)ctx);
232 OIC_LOG_V(ERROR, TAG, "getCsrForCertProvCB FAILED - ctx: %s", (char*)ctx);
239 OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle,
240 OCClientResponse* clientResponse)
248 if (clientResponse == NULL)
250 OIC_LOG(ERROR, TAG, "getReqCB received NULL clientResponse");
251 return OC_STACK_DELETE_TRANSACTION;
254 if (clientResponse->result != OC_STACK_OK)
256 OIC_LOG_V(ERROR, TAG, "getReqCB response %d", clientResponse->result);
257 return OC_STACK_DELETE_TRANSACTION;
262 return OC_STACK_DELETE_TRANSACTION;
265 static void provisionAclCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
269 OIC_LOG_V(INFO, TAG, "Provision ACL SUCCEEDED - ctx: %s", (char*)ctx);
274 OIC_LOG_V(ERROR, TAG, "Provision ACL FAILED - ctx: %s", (char*)ctx);
275 printResultList((const OCProvisionResult_t*)arr, nOfRes);
281 static void assertRolesCB(void* ctx, bool hasError)
283 OC_UNUSED(ctx); // unused in release builds
287 OIC_LOG_V(INFO, TAG, "%s: Asserting roles SUCCEEDED - ctx: %s", __func__, (char*)ctx);
292 OIC_LOG_V(DEBUG, TAG, "%s: Asserting roles FAILED - ctx: %s", __func__, (char*)ctx);
298 // function(s) for provisioning client using C-level provisioning API
299 static int initProvisionClient(void)
301 // initialize persistent storage for SVR DB
302 static OCPersistentStorage pstStr =
304 .open = fopen_prvnMng,
310 if (OC_STACK_OK != OCRegisterPersistentStorageHandler(&pstStr))
312 OIC_LOG(ERROR, TAG, "OCRegisterPersistentStorageHandler error");
316 // initialize OC stack and provisioning manager
317 if (OC_STACK_OK != OCInit(NULL, 0, OC_CLIENT_SERVER))
319 OIC_LOG(ERROR, TAG, "OCStack init error");
323 if (access(PRVN_DB_FILE_NAME, F_OK) == 0)
325 printf("************************************************************\n");
326 printf("************Provisioning DB file already exists.************\n");
327 printf("************************************************************\n");
331 printf("*************************************************************\n");
332 printf("************No provisioning DB file, creating new************\n");
333 printf("*************************************************************\n");
336 if (OC_STACK_OK != OCInitPM(PRVN_DB_FILE_NAME))
338 OIC_LOG(ERROR, TAG, "OC_PM init error");
345 /* In some tests we need to close existing sessions after making a change
346 * in order for the effect of the change to take effect. This function shuts
347 * down the OC stack and restarts it.
349 static int closeAllSessions()
351 if (OC_STACK_OK != OCStop())
353 OIC_LOG_V(ERROR, TAG, "%s: OCStack stop error", __func__);
357 if (OC_STACK_OK != OCInit(NULL, 0, OC_CLIENT_SERVER))
359 OIC_LOG_V(ERROR, TAG, "%s: OCStack init error", __func__);
366 static int discoverAllDevices(void)
368 // delete un/owned device lists before updating them
371 OCDeleteDiscoveredDevices(g_own_list);
376 OCDeleteDiscoveredDevices(g_unown_list);
380 // call |OCGetDevInfoFromNetwork| API
381 printf(" Discovering All Un/Owned Devices on Network..\n");
382 if(OC_STACK_OK != OCGetDevInfoFromNetwork(DISCOVERY_TIMEOUT, &g_own_list, &g_unown_list))
384 OIC_LOG(ERROR, TAG, "OCGetDevInfoFromNetwork API error");
388 // display the discovered un/owned lists
389 printf(" > Discovered Owned Devices\n");
390 g_own_cnt = printDevList(g_own_list);
391 printf(" > Discovered Unowned Devices\n");
392 g_unown_cnt = printDevList(g_unown_list);
397 static int registerDevices(void)
399 // check |unown_list| for registering devices
400 if(!g_unown_list || 0>=g_unown_cnt)
402 OIC_LOG(ERROR, TAG, "Unowned device list empty, must discover unowned devices first");
403 return -1; // Error, we should have registered unowned devices already
406 // call |OCDoOwnershipTransfer| API
407 // calling this API with callback actually acts like blocking
408 // for error checking, the return value saved and printed
410 printf(" Registering All Discovered Unowned Devices..\n");
411 OCStackResult rst = OCDoOwnershipTransfer((void*) g_ctx, g_unown_list, ownershipTransferCB);
412 if(OC_STACK_OK != rst)
414 OIC_LOG_V(ERROR, TAG, "OCDoOwnershipTransfer API error: %d", rst);
417 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
419 OIC_LOG(ERROR, TAG, "OCDoOwnershipTransfer callback error");
425 OIC_LOG(ERROR, TAG, "OCDoOwnershipTransfer callback failed");
429 // display the registered result
430 printf(" > Registered Discovered Unowned Devices\n");
435 static int provisionTrustAnchor(int dev_num)
437 OCProvisionDev_t* targetDevice = getDevInst((const OCProvisionDev_t*)g_own_list, dev_num);
438 if(targetDevice == NULL)
440 OIC_LOG(ERROR, TAG, "Error, invalid device %d");
444 // Install the CA trust anchor locally
445 uint16_t caCredId = 0;
446 OCStackResult rst = OCSaveTrustCertChain((const uint8_t*)g_caCertPem, strlen(g_caCertPem) + 1,
447 OIC_ENCODING_PEM, &caCredId);
448 if (OC_STACK_OK != rst)
450 OIC_LOG_V(ERROR, TAG, "OCSaveTrustCertChain error: %d", rst);
454 // Provision the CA root cert to the target device
455 printf(" > Saving root certificate (trust anchor) to selected device..\n");
457 OicSecCredType_t type = SIGNED_ASYMMETRIC_KEY;
459 rst = OCProvisionTrustCertChain((void*)g_ctx, type, caCredId, targetDevice, (OCProvisionResultCB)&provisionTrustChainCB);
460 if(OC_STACK_OK != rst)
462 OIC_LOG_V(ERROR, TAG, "OCProvisionTrustCertChain returned error: %d", rst);
466 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
468 OIC_LOG(ERROR, TAG, "OCProvisionTrustCertChain callback error");
476 printf(" > Provisioned certificate trust anchor\n");
482 /* If csr is not null, a copy will be made, and the caller must free it with OICFree. */
483 static int getCsr(int dev_num, char** csr)
485 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
488 OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
493 OCStackResult rst = OCGetCSRResource((void*) g_ctx, dev, getCsrForCertProvCB);
494 if(OC_STACK_OK != rst)
496 OIC_LOG_V(ERROR, TAG, "OCGetCSRResource API error: %d", rst);
500 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
502 OIC_LOG(ERROR, TAG, "OCGetCSRResource callback error");
510 rst = OCVerifyCSRSignature(g_csr);
511 if(rst != OC_STACK_OK)
513 OIC_LOG(ERROR, TAG, "Failed to validate CSR signature");
514 OICFreeAndSetToNull((void**)&g_csr);
520 *csr = OICStrdup(g_csr);
523 OIC_LOG(ERROR, TAG, "OICStrdup failed");
524 OICFreeAndSetToNull((void**)&g_csr);
529 OICFreeAndSetToNull((void**)&g_csr);
531 printf(" > Get CSR SUCCEEDED\n");
536 printf(" > Get CSR FAILED\n");
540 static int doGetRequest(const char* uri, int dev_num)
543 OCCallbackData cbData;
545 OCProvisionDev_t *device = NULL;
547 device = getDevInst(g_own_list, dev_num);
550 OIC_LOG(ERROR, TAG, "Selected device does not exist");
553 cbData.context = NULL;
555 cbData.cb = &getReqCB;
556 OIC_LOG_V(INFO, TAG, "Performing GET on %s", uri);
559 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = { 0 };
560 if (!PMGenerateQuery(true,
561 device->endpoint.addr,
564 query, sizeof(query), uri))
566 OIC_LOG_V(ERROR, TAG, "%s : Failed to generate query", __func__);
570 res = OCDoRequest(&handle, OC_REST_GET, query, NULL, NULL,
571 device->connType, OC_HIGH_QOS, &cbData, NULL, 0);
573 if (res != OC_STACK_OK)
575 OIC_LOG_V(ERROR, TAG, "OCDoRequest returned error %d with method", res);
577 if (waitCallbackRet()) // input |g_doneCB| flag implicitly
579 OIC_LOG_V(ERROR, TAG, "%s callback error", __func__);
589 static int provisionCert(int dev_num, char* cert)
591 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*)g_own_list, dev_num);
594 OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
598 printf(" > Provisioning certificate credential to selected device..\n");
600 OCStackResult rst = OCProvisionCertificate((void *)g_ctx, dev, cert, provisionCredCB);
601 if (OC_STACK_OK != rst)
603 OIC_LOG_V(ERROR, TAG, "OCProvisionCertificate returned error: %d", rst);
606 if (waitCallbackRet())
608 OIC_LOG_V(ERROR, TAG, "%s failed waiting for callback", __func__);
613 OIC_LOG_V(ERROR, TAG, "%s callback completed, but failed", __func__);
617 printf(" > Provision cert SUCCEEDED\n");
623 * Create a role or identity certificate for a device, based on the information in its CSR.
624 * Assumes the CSR has already been validated wtih OCVerifyCSRSignature.
625 * If role is not NULL, a role certificate is created, otherwise an identity certificate
628 static int createCertFromCSR(const char* caKeyPem, const char* caCertPem, char* csr,
629 const char* role, const char* authority, char** deviceCert)
631 char* publicKey = NULL;
634 OicUuid_t uuid = { 0 };
635 OCStackResult res = OC_STACK_ERROR;
637 res = OCGetUuidFromCSR(csr, &uuid);
638 if (res != OC_STACK_OK)
640 OIC_LOG_V(ERROR, TAG, "Failed to get UUID from CSR, error: %d", res);
643 /* Note: a real OBT must make sure the UUID isn't already in use on the network. */
645 res = OCGetPublicKeyFromCSR(csr, &publicKey);
646 if (res != OC_STACK_OK)
648 OIC_LOG_V(ERROR, TAG, "Failed to get public key from CSR, error: %d", res);
652 res = OCGenerateRandomSerialNumber(&serial, &serialLen);
653 if (res != OC_STACK_OK)
655 OIC_LOG_V(ERROR, TAG, "OCGenerateRandomSerialNumber failed, error: %d", res);
659 size_t deviceCertLen;
662 res = OCGenerateRoleCertificate(
668 TEST_CERT_NOT_BEFORE,
677 res = OCGenerateIdentityCertificate(
683 TEST_CERT_NOT_BEFORE,
688 if (res != OC_STACK_OK)
690 OIC_LOG_V(ERROR, TAG, "Failed generating certificate, error: %d", res);
698 return (res == OC_STACK_OK) ? 0 : -1;
701 static int setupOwnCert(OicUuid_t* inputUuid)
703 OCUUIdentity deviceId = { 0 };
706 size_t serialLen = 0;
707 size_t idPublicKeyLen = 0;
711 size_t idCertLen = 0;
713 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
715 /* Set our own trust anchor so that we trust certs we've issued. */
716 OCStackResult res = OCSaveTrustCertChain((const uint8_t*)g_caCertPem, strlen(g_caCertPem)+1, OIC_ENCODING_PEM, &caCredId);
717 if (OC_STACK_OK != res)
719 OIC_LOG_V(ERROR, TAG, "OCSaveTrustCertChain error: %d", res);
723 /* Create identity certificate for use by the CA. */
724 res = OCGenerateKeyPair(&g_idPublicKey, &idPublicKeyLen, &idKey, &idKeyLen);
725 if (res != OC_STACK_OK)
727 OIC_LOG_V(ERROR, TAG, "OCGenerateKeyPair failed, error: %d", res);
731 res = OCGenerateRandomSerialNumber(&serial, &serialLen);
732 if (res != OC_STACK_OK)
734 OIC_LOG_V(ERROR, TAG, "OCGenerateRandomSerialNumber failed, error: %d", res);
738 OicUuid_t* uuidForCert = inputUuid;
739 OicUuid_t uuid = { 0 };
740 if (inputUuid == NULL)
742 res = OCGetDeviceId(&deviceId);
743 if (res != OC_STACK_OK)
745 OIC_LOG_V(ERROR, TAG, "Failed to get own UUID, error: %d", res);
748 memcpy(uuid.id, deviceId.id, sizeof(uuid.id));
752 OIC_LOG(DEBUG, TAG, "Creating own cert with UUID:");
753 printUuid(uuidForCert);
755 res = OCGenerateIdentityCertificate(
761 TEST_CERT_NOT_BEFORE,
765 if (res != OC_STACK_OK)
767 OIC_LOG_V(ERROR, TAG, "Failed to create identity cert for CA, error: %d", res);
771 uint16_t idCertCredId = 0;
772 res = OCSaveOwnCertChain(idCert, idKey, &idCertCredId);
773 if (res != OC_STACK_OK)
775 OIC_LOG_V(ERROR, TAG, "Failed to save CA's identity cert & key, error: %d", res);
783 OICClearMemory(idKey, idKeyLen);
788 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
790 return (res == OC_STACK_OK) ? 0 : -1;
793 static int setupOwnRoleCert(OicUuid_t* inputUuid, const char* role, const char* authority)
795 OCUUIdentity deviceId = { 0 };
797 size_t serialLen = 0;
798 char* roleCert = NULL;
799 size_t roleCertLen = 0;
801 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
803 if (g_idPublicKey == NULL)
805 OIC_LOG_V(ERROR, TAG, "%s failed because own public key is NULL, has setupOwnCert been called?", __func__);
809 /* Create role certificate. */
810 OCStackResult res = OCGenerateRandomSerialNumber(&serial, &serialLen);
811 if (res != OC_STACK_OK)
813 OIC_LOG_V(ERROR, TAG, "OCGenerateRandomSerialNumber failed, error: %d", res);
817 OicUuid_t* uuidForCert = inputUuid;
818 OicUuid_t uuid = { 0 };
819 if (inputUuid == NULL)
821 res = OCGetDeviceId(&deviceId);
822 if (res != OC_STACK_OK)
824 OIC_LOG_V(ERROR, TAG, "Failed to get own UUID, error: %d", res);
827 memcpy(uuid.id, deviceId.id, sizeof(uuid.id));
831 OIC_LOG(DEBUG, TAG, "Creating own role cert with UUID:");
832 printUuid(uuidForCert);
834 res = OCGenerateRoleCertificate(
840 TEST_CERT_NOT_BEFORE,
846 if (res != OC_STACK_OK)
848 OIC_LOG_V(ERROR, TAG, "Failed to create role cert, error: %d", res);
852 uint16_t roleCertCredId = 0;
853 res = OCSaveOwnRoleCert(roleCert, &roleCertCredId);
854 if (res != OC_STACK_OK)
856 OIC_LOG_V(ERROR, TAG, "Failed to save role cert, error: %d", res);
864 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
866 return (res == OC_STACK_OK) ? 0 : -1;
870 * Create an ACL for the /a/led resource.
871 * Caller must call OCDeleteACLList(newAcl).
872 * The role and authority parameters are optional. If role is not NULL, a
873 * role-based ACL will be created. Otherwise a subject-based ACL is created.
875 static int createLedAcl(OicSecAcl_t** newAcl, const char* role, const char* authority)
878 OCUUIdentity ownUuid = { 0 };
879 OicSecAcl_t* acl = NULL;
880 OicSecAce_t* ace = NULL;
881 OicSecRsrc_t* rsrc = NULL;
882 const char* resource = "/a/led";
883 const char* resource_type = "core.led";
884 const char* resource_interface = "oic.if.baseline";
885 uint16_t perms = PERMISSION_FULL_CONTROL;
887 /* Create an ACL with one ACE */
888 acl = (OicSecAcl_t*)OICCalloc(1, sizeof(OicSecAcl_t));
891 OIC_LOG_V(ERROR, TAG, "%s: OICCalloc failed (acl)", __func__);
894 ace = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
897 OIC_LOG_V(ERROR, TAG, "%s: OICCalloc failed (ace)", __func__);
900 LL_APPEND(acl->aces, ace);
902 if (role != NULL) /* Create a role-based ACL */
904 ace->subjectType = OicSecAceRoleSubject;
905 assert(strlen(role) + 1 < ROLEID_LENGTH);
906 memcpy(ace->subjectRole.id, role, strlen(role) + 1);
908 if (authority != NULL)
910 assert(strlen(authority) + 1 < ROLEAUTHORITY_LENGTH);
911 memcpy(ace->subjectRole.authority, role, strlen(authority) + 1);
913 OIC_LOG_V(DEBUG, TAG, "Creating ACE with role id = %s, authority = %s:", ace->subjectRole.id, ace->subjectRole.authority);
915 else /* Create a subject based ACL */
917 /* Set uuid to our own */
918 OCStackResult res = OCGetDeviceId(&ownUuid);
919 if (res != OC_STACK_OK)
921 OIC_LOG_V(ERROR, TAG, "Failed to get own UUID, error: %d", res);
924 ace->subjectType = OicSecAceUuidSubject;
925 memcpy(ace->subjectuuid.id, ownUuid.id, sizeof(ace->subjectuuid.id));
927 OicUuid_t uuid = { 0 };
928 memcpy(uuid.id, ownUuid.id, sizeof(uuid.id));
929 OIC_LOG(DEBUG, TAG, "Creating ACE with UUID:");
933 /* Add a resource (e.g. '/a/led') to the ACE */
934 rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
937 OIC_LOG_V(ERROR, TAG, "%s: OICCalloc failed (rsrc)", __func__);
940 LL_APPEND(ace->resources, rsrc);
941 rsrc->href = OICStrdup(resource);
943 /* Set resource type, e.g., 'core.led' */
945 rsrc->types = (char**)OICCalloc(rsrc->typeLen, sizeof(char*));
948 OIC_LOG_V(ERROR, TAG, "%s: OICCalloc failed (rsrc->types)", __func__);
951 rsrc->types[0] = OICStrdup(resource_type);
953 /* Set interface, e.g., 'oic.if.baseline' */
954 rsrc->interfaceLen = 1;
955 rsrc->interfaces = (char**)OICCalloc(rsrc->interfaceLen, sizeof(char*));
956 if (!rsrc->interfaces)
958 OIC_LOG_V(ERROR, TAG, "%s: OICCalloc failed (rsrc->interfaces)", __func__);
961 rsrc->interfaces[0] = OICStrdup(resource_interface);
963 if (!rsrc->href || !rsrc->types[0] || !rsrc->interfaces[0])
965 OIC_LOG_V(ERROR, TAG, "%s: OICStrdup failed", __func__);
969 /* Set permission for the ACE */
970 ace->permission = perms;
972 ret = 0; /* success */
980 OCDeleteACLList(acl);
986 static int provisionAcl(int dev_num, OicSecAcl_t* acl)
988 OCStackResult res = OC_STACK_ERROR;
990 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*)g_own_list, dev_num);
993 OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
998 res = OCProvisionACL((void*)g_ctx, dev, acl, provisionAclCB);
999 if (OC_STACK_OK != res)
1001 OIC_LOG_V(ERROR, TAG, "OCProvisionACL API error: %d", res);
1004 if (waitCallbackRet())
1006 OIC_LOG(ERROR, TAG, "OCProvisionACL callback error");
1011 OIC_LOG_V(ERROR, TAG, "%s callback completed, but failed", __func__);
1017 return (res == OC_STACK_OK) ? 0 : -1;
1020 /* Function to work around IOT-1927. The ocrandom.h include is only required for the workaround.
1021 * @todo: when IOT-1927 is resolved remove this function
1023 #include "ocrandom.h"
1026 /* Remove credential for 31313131-3131-3131-3131-313131313131 */
1027 const char* uuidStr = "31313131-3131-3131-3131-313131313131";
1028 OicUuid_t uuid = { 0 };
1029 if (!OCConvertStringToUuid(uuidStr, uuid.id))
1031 OIC_LOG(ERROR, TAG, "UUID conversion failed - caller bug, or the .dat file not longer contains a cred for this UUID. ");
1035 OCStackResult res = OCRemoveCredential(&uuid);
1036 if (res != OC_STACK_RESOURCE_DELETED)
1038 OIC_LOG_V(ERROR, TAG, "%s failed to remove credential for subject UUID: ", __func__);
1039 OIC_LOG_BUFFER(DEBUG, TAG, uuid.id, UUID_LENGTH);
1046 static int testCertUse(int dev_num)
1049 char* deviceCert = NULL;
1050 const char* uri = "/a/led";
1051 OicSecAcl_t* acl = NULL;
1053 // Make sure we own at least one device to provision
1054 if (!g_own_list || (g_own_cnt == 0))
1056 OIC_LOG(ERROR, TAG, "Owned device list empty, must discover unowned devices first");
1057 return -1; // Error, we should have registered unowned devices already
1060 /* Provision the device with the CA root, and issue it a cert. */
1061 if (provisionTrustAnchor(dev_num) != 0)
1066 if (getCsr(dev_num, &csr) != 0)
1071 int ret = createCertFromCSR(g_caKeyPem, g_caCertPem, csr, NULL, NULL, &deviceCert);
1074 OIC_LOG_V(ERROR, TAG, "%s Failed to create identity certificate", __func__);
1078 ret = provisionCert(dev_num, deviceCert);
1081 OIC_LOG_V(ERROR, TAG, "%s Failed to provision certificate", __func__);
1085 /* Try a GET request, expecting success because the owner credential is used.*/
1086 ret = doGetRequest(uri, dev_num);
1089 OIC_LOG_V(ERROR, TAG, "%s failed when requesting %s", __func__, uri);
1093 ret = createLedAcl(&acl, NULL, NULL);
1096 OIC_LOG_V(ERROR, TAG, "%s failed to create ACL", __func__);
1100 /* Provision an ACL on the server, allowing us to access '/a/led' with our cert. */
1101 ret = provisionAcl(dev_num, acl);
1104 OIC_LOG_V(ERROR, TAG, "%s failed to provision ACL", __func__);
1108 /* Remove the owner credential */
1109 OCStackResult res = OCRemoveCredential(&g_uuidDev1);
1110 if (res != OC_STACK_RESOURCE_DELETED)
1112 OIC_LOG_V(ERROR, TAG, "%s failed to remove owner credential for subject UUID: ", __func__);
1113 OIC_LOG_BUFFER(DEBUG, TAG, g_uuidDev1.id, UUID_LENGTH);
1119 * Work around bug IOT-1927
1120 * @todo: When that bug is resolved, remove this call and the function workAroundBug
1122 if (workAroundBug() != 0)
1124 OIC_LOG_V(ERROR, TAG, "%s bug workaround failed: ", __func__);
1129 /* Close all secure sessions, so that we don't re-use a cached session */
1130 if (closeAllSessions() != 0)
1132 OIC_LOG_V(ERROR, TAG, "%s Failed to close sessions", __func__);
1137 /* Try a GET request, expect failure, we don't share a credential. */
1138 ret = doGetRequest(uri, dev_num);
1141 OIC_LOG_V(ERROR, TAG, "%s Get request to %s succeeded, but should have failed", __func__, uri);
1145 /* Provision ourself a valid certificate credential */
1146 ret = setupOwnCert(NULL);
1149 OIC_LOG_V(ERROR, TAG, "%s Failed to self-provision a key/certificate", __func__);
1153 /* Close all secure sessions again */
1154 if (closeAllSessions() != 0)
1156 OIC_LOG_V(ERROR, TAG, "%s Failed to close sessions", __func__);
1161 /* Try a get request, expect success */
1162 ret = doGetRequest(uri, dev_num);
1165 OIC_LOG_V(ERROR, TAG, "%s Get request to %s failed, but should have succeeded", __func__, uri);
1172 OICFree(deviceCert);
1173 OCDeleteACLList(acl);
1178 static int testRoleProvisioning(int dev_num)
1181 char* idCert = NULL;
1182 char* roleCert = NULL;
1184 // Make sure we own at least one device to provision
1185 if (!g_own_list || (g_own_cnt == 0))
1187 OIC_LOG(ERROR, TAG, "Owned device list empty, must discover unowned devices first");
1188 return -1; // Error, we should have registered unowned devices already
1191 /* Provision the device with the CA root, and issue it a role and identity cert. */
1192 if (provisionTrustAnchor(dev_num) != 0)
1197 if (getCsr(dev_num, &csr) != 0)
1202 int ret = createCertFromCSR(g_caKeyPem, g_caCertPem, csr, NULL, NULL, &idCert);
1205 OIC_LOG_V(ERROR, TAG, "%s Failed to create identity certificate", __func__);
1209 ret = provisionCert(dev_num, idCert);
1212 OIC_LOG_V(ERROR, TAG, "%s Failed to provision id certificate", __func__);
1216 /* The first role cert will have no authority field (it's optional) */
1217 ret = createCertFromCSR(g_caKeyPem, g_caCertPem, csr, TEST_CERT_ROLE1, NULL, &roleCert);
1220 OIC_LOG_V(ERROR, TAG, "%s Failed to create role certificate", __func__);
1224 ret = provisionCert(dev_num, roleCert);
1227 OIC_LOG_V(ERROR, TAG, "%s Failed to provision role certificate", __func__);
1230 OICFreeAndSetToNull((void**)&roleCert);
1232 /* The second will have the authority field set */
1233 ret = createCertFromCSR(g_caKeyPem, g_caCertPem, csr, TEST_CERT_ROLE2, TEST_CERT_AUTHORITY, &roleCert);
1236 OIC_LOG_V(ERROR, TAG, "%s Failed to create role certificate", __func__);
1240 ret = provisionCert(dev_num, roleCert);
1243 OIC_LOG_V(ERROR, TAG, "%s Failed to provision role certificate", __func__);
1256 static int testRoleAssertion(int dev_num)
1259 char* idCert = NULL;
1260 char* roleCert = NULL;
1261 OicSecAcl_t* acl = NULL;
1263 /* Make sure we own at least one device to provision */
1264 if (!g_own_list || (g_own_cnt == 0))
1266 OIC_LOG(ERROR, TAG, "Owned device list empty, must discover unowned devices first");
1267 return -1; // Error, we should have registered unowned devices already
1270 /* Provision the device with the CA root, and issue it an identity cert. */
1271 if (provisionTrustAnchor(dev_num) != 0)
1276 if (getCsr(dev_num, &csr) != 0)
1281 int ret = createCertFromCSR(g_caKeyPem, g_caCertPem, csr, NULL, NULL, &idCert);
1284 OIC_LOG_V(ERROR, TAG, "%s Failed to create identity certificate", __func__);
1288 ret = provisionCert(dev_num, idCert);
1291 OIC_LOG_V(ERROR, TAG, "%s Failed to provision id certificate", __func__);
1295 /* Create and provision a role-based ACL allowing ROLE1 to access '/a/led'. */
1296 ret = createLedAcl(&acl, TEST_CERT_ROLE1, NULL);
1299 OIC_LOG_V(ERROR, TAG, "%s failed to create led ACL", __func__);
1303 ret = provisionAcl(dev_num, acl);
1306 OIC_LOG_V(ERROR, TAG, "%s failed to provision led ACL", __func__);
1310 /* Provision ourselves an identity and role cert.
1311 * For the identity cert we use a random UUID, since the server has an ACE granting our UUID
1312 * access to everything (as owner). We don't want to remove this ACE because it would lock
1313 * us out. Using another UUID makes us appear as another device on the network.
1315 OicUuid_t notOurUuid;
1316 (void)OCGenerateUuid(notOurUuid.id);
1317 ret = setupOwnCert(¬OurUuid);
1320 OIC_LOG_V(ERROR, TAG, "%s Failed to self-provision a key/certificate", __func__);
1324 ret = setupOwnRoleCert(NULL, TEST_CERT_ROLE1, NULL);
1327 OIC_LOG_V(ERROR, TAG, "%s Failed to self-provision a key/certificate", __func__);
1331 /* Remove the owner credential so that we don't use it when asserting role certs. */
1332 OCStackResult res = OCRemoveCredential(&g_uuidDev1);
1333 if (res != OC_STACK_RESOURCE_DELETED)
1335 OIC_LOG_V(ERROR, TAG, "%s failed to remove owner credential for subject UUID: ", __func__);
1336 OIC_LOG_BUFFER(DEBUG, TAG, g_uuidDev1.id, UUID_LENGTH);
1342 * Work around bug IOT-1927
1343 * @todo: When that bug is resolved, remove this call and the function workAroundBug
1345 if (workAroundBug() != 0)
1347 OIC_LOG_V(ERROR, TAG, "%s bug workaround failed: ", __func__);
1352 /* Close all secure sessions */
1353 if (closeAllSessions() != 0)
1355 OIC_LOG_V(ERROR, TAG, "%s Failed to close sessions", __func__);
1360 /* Assert role certificate */
1361 OCProvisionDev_t *device = NULL;
1362 device = getDevInst(g_own_list, dev_num);
1365 OIC_LOG(ERROR, TAG, "Selected device does not exist");
1370 OCDevAddr devAddr = device->endpoint;
1371 devAddr.port = device->securePort;
1374 res = OCAssertRoles(g_ctx, &devAddr, assertRolesCB);
1375 if (res != OC_STACK_OK)
1377 OIC_LOG_V(ERROR, TAG, "OCAssertRoles returned error %d with method", res);
1381 if (waitCallbackRet())
1383 OIC_LOG_V(ERROR, TAG, "%s callback error", __func__);
1395 OCDeleteACLList(acl);
1400 static int testRoleAssertionAndUse(int dev_num)
1403 char* idCert = NULL;
1404 char* roleCert = NULL;
1405 const char* uri = "/a/led";
1406 OicSecAcl_t* acl = NULL;
1408 // Make sure we own at least one device to provision
1409 if (!g_own_list || (g_own_cnt == 0))
1411 OIC_LOG(ERROR, TAG, "Owned device list empty, must discover unowned devices first");
1412 return -1; // Error, we should have registered unowned devices already
1415 /* Provision the device with the CA root, and issue it an identity cert. */
1416 if (provisionTrustAnchor(dev_num) != 0)
1421 if (getCsr(dev_num, &csr) != 0)
1426 int ret = createCertFromCSR(g_caKeyPem, g_caCertPem, csr, NULL, NULL, &idCert);
1429 OIC_LOG_V(ERROR, TAG, "%s Failed to create identity certificate", __func__);
1433 ret = provisionCert(dev_num, idCert);
1436 OIC_LOG_V(ERROR, TAG, "%s Failed to provision id certificate", __func__);
1440 /* Create and provision a role-based ACL allowing ROLE1 to access '/a/led'. */
1441 ret = createLedAcl(&acl, TEST_CERT_ROLE1, NULL);
1444 OIC_LOG_V(ERROR, TAG, "%s failed to create led ACL", __func__);
1448 ret = provisionAcl(dev_num, acl);
1451 OIC_LOG_V(ERROR, TAG, "%s failed to provision led ACL", __func__);
1455 /* Provision ourselves an identity and role cert.
1456 * For the identity cert we use a random UUID, since the server has an ACE granting our UUID
1457 * access to everything (as owner). We don't want to remove this ACE because it would lock
1458 * us out. Using another UUID makes us appear as another device on the network.
1460 OicUuid_t notOurUuid;
1461 (void) OCGenerateUuid(notOurUuid.id);
1462 ret = setupOwnCert(¬OurUuid);
1465 OIC_LOG_V(ERROR, TAG, "%s Failed to self-provision a key/certificate", __func__);
1469 ret = setupOwnRoleCert(NULL, TEST_CERT_ROLE1, NULL);
1472 OIC_LOG_V(ERROR, TAG, "%s Failed to self-provision a key/certificate", __func__);
1476 /* Remove the owner credential so that we don't use it when asserting role certs. */
1477 OCStackResult res = OCRemoveCredential(&g_uuidDev1);
1478 if (res != OC_STACK_RESOURCE_DELETED)
1480 OIC_LOG_V(ERROR, TAG, "%s failed to remove owner credential for subject UUID: ", __func__);
1481 OIC_LOG_BUFFER(DEBUG, TAG, g_uuidDev1.id, UUID_LENGTH);
1487 * Work around bug IOT-1927
1488 * @todo: When that bug is resolved, remove this call and the function workAroundBug
1490 if (workAroundBug() != 0)
1492 OIC_LOG_V(ERROR, TAG, "%s bug workaround failed: ", __func__);
1497 /* Close all secure sessions */
1498 if (closeAllSessions() != 0)
1500 OIC_LOG_V(ERROR, TAG, "%s Failed to close sessions", __func__);
1505 /* Try a get request, expect success, role certificate will be automatically asserted */
1506 ret = doGetRequest(uri, dev_num);
1509 OIC_LOG_V(ERROR, TAG, "%s Get request to %s failed, but should have succeeded", __func__, uri);
1517 OCDeleteACLList(acl);
1522 static int provisionSymmetricRoleCred(int dev_num)
1525 memset(&role, 0, sizeof(role));
1526 OICStrcpy(role.id, sizeof(role.id), TEST_CERT_ROLE1);
1528 // call |OCProvisionCredentials| API
1529 // calling this API with callback actually acts like blocking
1530 // for error checking, the return value saved and printed
1533 OCProvisionSymmetricRoleCredentials((void*) g_ctx,
1534 SYMMETRIC_PAIR_WISE_KEY, OWNER_PSK_LENGTH_128,
1535 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num),
1538 if (OC_STACK_OK != rst)
1540 OIC_LOG_V(ERROR, TAG, "OCProvisionCredentials API error: %d", rst);
1543 if (waitCallbackRet()) // input |g_doneCB| flag implicitly
1545 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
1552 static int testSymmetricRoleUse(int dev_num)
1554 const char* uri = "/a/led";
1555 OicSecAcl_t* acl = NULL;
1557 // Make sure we own at least one device to provision
1558 if (!g_own_list || (g_own_cnt == 0))
1560 OIC_LOG(ERROR, TAG, "Owned device list empty, must discover unowned devices first");
1561 return -1; // Error, we should have registered unowned devices already
1564 /* Create and provision a role-based ACL allowing ROLE1 to access '/a/led'. */
1565 int ret = createLedAcl(&acl, TEST_CERT_ROLE1, NULL);
1568 OIC_LOG_V(ERROR, TAG, "%s failed to create led ACL", __func__);
1572 ret = provisionAcl(dev_num, acl);
1575 OIC_LOG_V(ERROR, TAG, "%s failed to provision led ACL", __func__);
1579 /* Remove the owner credential so that we don't use it when asserting role certs. */
1580 OCStackResult res = OCRemoveCredential(&g_uuidDev1);
1581 if (res != OC_STACK_RESOURCE_DELETED)
1583 OIC_LOG_V(ERROR, TAG, "%s failed to remove owner credential for subject UUID: ", __func__);
1584 OIC_LOG_BUFFER(DEBUG, TAG, g_uuidDev1.id, UUID_LENGTH);
1589 /* The server has an owner PSK associated with our GUID. Change our GUID to something else,
1590 * which will both be used to generate the role credential and for the later connection.
1592 const OCUUIdentity newIdentity = { .id = { 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46 } };
1593 if (OC_STACK_OK != OCSetDeviceId(&newIdentity))
1595 OIC_LOG_V(ERROR, TAG, "%s failed to set device ID", __func__);
1600 /* Create a new symmetric credential with the role. */
1601 ret = provisionSymmetricRoleCred(dev_num);
1604 OIC_LOG_V(ERROR, TAG, "%s failed to provision symmetric role pair-wise keys", __func__);
1608 /* Close all secure sessions */
1609 if (closeAllSessions() != 0)
1611 OIC_LOG_V(ERROR, TAG, "%s Failed to close sessions", __func__);
1616 /* Try a get request, expect success */
1617 ret = doGetRequest(uri, dev_num);
1620 OIC_LOG_V(ERROR, TAG, "%s Get request to %s failed, but should have succeeded", __func__, uri);
1626 OCDeleteACLList(acl);
1631 /* Get a specific device from the provided device list. The devices in the list
1632 * are numbered starting from 1.
1634 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t* dev_lst, const int dev_num)
1636 if (!dev_lst || 0 >= dev_num)
1638 printf(" Device List is Empty..\n");
1642 OCProvisionDev_t* lst = (OCProvisionDev_t*)dev_lst;
1643 for (int i = 0; lst; )
1652 OIC_LOG_V(ERROR, TAG, "%s failed, requested device not found in list (does the device need to be discovered or owned first?)", __func__);
1653 return NULL; // in here |lst| is always |NULL|
1656 static int printDevList(const OCProvisionDev_t* dev_lst)
1660 printf(" Device List is Empty..\n\n");
1664 OCProvisionDev_t* lst = (OCProvisionDev_t*)dev_lst;
1668 printf(" [%d] ", ++lst_cnt);
1669 printUuid((const OicUuid_t*)&lst->doxm->deviceID);
1678 static size_t printResultList(const OCProvisionResult_t* rslt_lst, const size_t rslt_cnt)
1680 if (!rslt_lst || (0 == rslt_cnt))
1682 printf(" Device List is Empty..\n\n");
1687 for (; rslt_cnt > lst_cnt; ++lst_cnt)
1689 printf(" [%" PRIuPTR "] ", lst_cnt + 1);
1690 printUuid((const OicUuid_t*)&rslt_lst[lst_cnt].deviceId);
1691 printf(" - result: %d\n", rslt_lst[lst_cnt].res);
1698 static int saveUuid(const OCProvisionResult_t* rslt_lst, const size_t rslt_cnt)
1700 if (!rslt_lst || (rslt_cnt != 1))
1702 OIC_LOG_V(ERROR, TAG, "%s: expected only one device", __func__);
1706 memcpy(&g_uuidDev1, &rslt_lst[0].deviceId, sizeof(OicUuid_t));
1711 static void printUuid(const OicUuid_t* uid)
1713 for (int i = 0; i<UUID_LENGTH; )
1715 printf("%02X", (*uid).id[i++]);
1716 if (i == 4 || i == 6 || i == 8 || i == 10) // canonical format for UUID has '8-4-4-4-12'
1724 static FILE* fopen_prvnMng(const char* path, const char* mode)
1726 if (0 == strncmp(path, OC_SECURITY_DB_DAT_FILE_NAME, strlen(OC_SECURITY_DB_DAT_FILE_NAME)))
1728 // input |g_svr_db_fname| internally by force, not using |path| parameter
1729 // because |OCPersistentStorage::open| is called |OCPersistentStorage| internally
1730 // with its own |SVR_DB_FILE_NAME|
1731 return fopen(SVR_DB_FILE_NAME, mode);
1735 return fopen(path, mode);
1739 static int waitCallbackRet(void)
1741 for(int i = 0; !g_doneCB; ++i)
1743 if(OC_STACK_OK != OCProcess())
1745 OIC_LOG(ERROR, TAG, "OCStack process error");
1749 if (i == CALLBACK_TIMEOUT)
1760 void shutdownProvisionClient()
1762 if(OC_STACK_OK != OCStop())
1764 OIC_LOG(ERROR, TAG, "OCStack stop error");
1766 OCDeleteDiscoveredDevices(g_own_list); // after here |g_own_list| points to nothing
1767 OCDeleteDiscoveredDevices(g_unown_list); // after here |g_unown_list| points to nothing
1769 OICFreeAndSetToNull((void**)&g_svr_fname);
1770 OICFreeAndSetToNull((void**)&g_prvn_fname);
1773 static int initDiscoverRegisterAllDevices()
1775 if(initProvisionClient())
1777 OIC_LOG_V(ERROR, TAG, "%s: ProvisionClient init error", __func__);
1781 if(discoverAllDevices())
1783 OIC_LOG_V(ERROR, TAG, "%s: Discovery failed", __func__);
1787 if(registerDevices())
1789 OIC_LOG_V(ERROR, TAG, "%s: Failed to onboard devices", __func__);
1793 if(discoverAllDevices())
1795 OIC_LOG_V(ERROR, TAG, "%s: Re-discovery failed after registerDevices", __func__);
1803 int TestTrustAnchorProvisioning()
1807 OIC_LOG_V(ERROR, TAG, "Running %s", __func__);
1809 if(initDiscoverRegisterAllDevices())
1811 OIC_LOG_V(ERROR, TAG, "%s: Failed to discover and provision devices", __func__);
1815 /* There should be one owned device with number 1. */
1816 if(provisionTrustAnchor(1))
1818 OIC_LOG_V(ERROR, TAG, "%s: Failed to provision trust anchor to device", __func__);
1826 shutdownProvisionClient();
1831 int TestCSRResource()
1835 OIC_LOG_V(ERROR, TAG, "Running %s", __func__);
1837 if(initDiscoverRegisterAllDevices())
1839 OIC_LOG_V(ERROR, TAG, "%s: Failed to discover and provision devices", __func__);
1843 /* There should be one owned device with number 1. */
1846 OIC_LOG(ERROR, TAG, "Failed to get CSR from device");
1854 shutdownProvisionClient();
1863 OIC_LOG_V(ERROR, TAG, "Running %s", __func__);
1865 if (initDiscoverRegisterAllDevices())
1867 OIC_LOG_V(ERROR, TAG, "%s: Failed to discover and provision devices", __func__);
1871 /* There should be one owned device with number 1. */
1874 OIC_LOG(ERROR, TAG, "Failed to authenticate to device with certificate");
1882 shutdownProvisionClient();
1887 int TestRoleProvisioning()
1891 OIC_LOG_V(ERROR, TAG, "Running %s", __func__);
1893 if (initDiscoverRegisterAllDevices())
1895 OIC_LOG_V(ERROR, TAG, "%s: Failed to discover and provision devices", __func__);
1899 /* There should be one owned device with number 1. */
1900 if (testRoleProvisioning(1))
1902 OIC_LOG(ERROR, TAG, "Failed to provision roles to device");
1910 shutdownProvisionClient();
1915 int TestRoleAssertion()
1919 OIC_LOG_V(ERROR, TAG, "Running %s", __func__);
1921 if (initDiscoverRegisterAllDevices())
1923 OIC_LOG_V(ERROR, TAG, "%s: Failed to discover and provision devices", __func__);
1927 /* There should be one owned device with number 1. */
1928 if (testRoleAssertion(1))
1930 OIC_LOG(ERROR, TAG, "Failed to assert roles");
1938 shutdownProvisionClient();
1943 int TestRoleAssertionAndUse()
1947 OIC_LOG_V(ERROR, TAG, "Running %s", __func__);
1949 if (initDiscoverRegisterAllDevices())
1951 OIC_LOG_V(ERROR, TAG, "%s: Failed to discover and provision devices", __func__);
1955 /* There should be one owned device with number 1. */
1956 if (testRoleAssertionAndUse(1))
1958 OIC_LOG(ERROR, TAG, "Failed to assert and use roles");
1966 shutdownProvisionClient();
1971 int TestSymmetricRoleUse()
1975 OIC_LOG_V(ERROR, TAG, "Running %s", __func__);
1977 if (initDiscoverRegisterAllDevices())
1979 OIC_LOG_V(ERROR, TAG, "%s: Failed to discover and provision devices", __func__);
1983 /* There should be one owned device with number 1. */
1984 if (testSymmetricRoleUse(1))
1986 OIC_LOG(ERROR, TAG, "Failed to use symmetric key role");
1994 shutdownProvisionClient();
1999 // main function for provisioning client using C-level provisioning API
2000 int main(int argc, char** argv)
2004 printf("%s: No test number provided (argc = %d)\n", argv[0], argc);
2008 unsigned int testNumber = strtoul(argv[1], NULL, 10);
2012 return TestTrustAnchorProvisioning();
2014 return TestCSRResource();
2016 return TestCertUse();
2018 return TestRoleProvisioning();
2020 return TestRoleAssertion();
2022 return TestRoleAssertionAndUse();
2024 return TestSymmetricRoleUse();
2026 printf("%s: Invalid test number\n", argv[0]);
2029 /* Note: when adding a new test, update NUM_TESTS in provisioningTest.py */
2036 #endif //__cplusplus