From a532ef729f3d4836975615583b2d8c8a9de63c21 Mon Sep 17 00:00:00 2001 From: Dmitriy Zhuravlev Date: Thu, 25 May 2017 15:03:12 +0300 Subject: [PATCH] [IOT-2359][IOT-2360][IOT-2364] Separate provisioning with DOS Restore functions removed in https://gerrit.iotivity.org/gerrit/#/c/19931/ Add NULL checking for pDev2 in SRPProvisionCredentialsDos Change-Id: Icf3397247478c97c7029380aadcaa5dd89b42870 Signed-off-by: Dmitriy Zhuravlev Reviewed-on: https://gerrit.iotivity.org/gerrit/20387 Tested-by: jenkins-iotivity Reviewed-by: dongik Lee Reviewed-by: Uze Choi Reviewed-by: Jongmin Choi Reviewed-by: Randeep Singh --- .../include/internal/secureresourceprovider.h | 16 + .../provisioning/src/ocprovisioningmanager.c | 8 +- .../provisioning/src/secureresourceprovider.c | 419 ++++++++++++++++++--- 3 files changed, 389 insertions(+), 54 deletions(-) diff --git a/resource/csdk/security/provisioning/include/internal/secureresourceprovider.h b/resource/csdk/security/provisioning/include/internal/secureresourceprovider.h index 90d3baf..6768791 100644 --- a/resource/csdk/security/provisioning/include/internal/secureresourceprovider.h +++ b/resource/csdk/security/provisioning/include/internal/secureresourceprovider.h @@ -236,6 +236,22 @@ OCStackResult SRPProvisionCredentials(void *ctx,OicSecCredType_t type, size_t ke const OicSecRole_t *role1, const OicSecRole_t *role2, OCProvisionResultCB resultCallback); + /** + * API to provision credential to devices with DOS. + * + * @param[in] ctx Application context to be returned in result callback. + * @param[in] type Type of credentials to be provisioned to the device. + * @param[in] keySize size of key + * @param[in] pDev1 Pointer to PMOwnedDeviceInfo_t instance, representing the resource to be provisioned. + * @param[in] pDev2 Pointer to PMOwnedDeviceInfo_t instance, representing the resource to be provisioned. + * @param[in] resultCallback callback provided by API user, callback will be called when + * provisioning request recieves a response from first resource server. + * @return OC_STACK_OK in case of success and other value otherwise. + */ +OCStackResult SRPProvisionCredentialsDos(void *ctx,OicSecCredType_t type, size_t keySize, + const OCProvisionDev_t *pDev1, + const OCProvisionDev_t *pDev2, + OCProvisionResultCB resultCallback); /** * Function to unlink devices. diff --git a/resource/csdk/security/provisioning/src/ocprovisioningmanager.c b/resource/csdk/security/provisioning/src/ocprovisioningmanager.c index ddc919e..bca59c8 100644 --- a/resource/csdk/security/provisioning/src/ocprovisioningmanager.c +++ b/resource/csdk/security/provisioning/src/ocprovisioningmanager.c @@ -482,8 +482,8 @@ OCStackResult OCProvisionCredentials(void *ctx, OicSecCredType_t type, size_t ke const OCProvisionDev_t *pDev2, OCProvisionResultCB resultCallback) { - return SRPProvisionCredentials(ctx, type, keySize, - pDev1, pDev2, NULL, NULL, NULL, resultCallback); + return SRPProvisionCredentialsDos(ctx, type, keySize, + pDev1, pDev2, resultCallback); } /** @@ -1275,8 +1275,8 @@ OCStackResult OCProvisionPairwiseDevices(void* ctx, OicSecCredType_t type, size_ link->resultCallback = resultCallback; link->currentCountResults = 0; link->resArr = (OCProvisionResult_t*) OICMalloc(sizeof(OCProvisionResult_t)*noOfResults); - res = SRPProvisionCredentials(link, type, keySize, - pDev1, pDev2, NULL, NULL, NULL, &ProvisionCredsCB); + res = SRPProvisionCredentialsDos(link, type, keySize, + pDev1, pDev2, &ProvisionCredsCB); if (res != OC_STACK_OK) { OICFree(link->resArr); diff --git a/resource/csdk/security/provisioning/src/secureresourceprovider.c b/resource/csdk/security/provisioning/src/secureresourceprovider.c index 625d4cf..f191914 100644 --- a/resource/csdk/security/provisioning/src/secureresourceprovider.c +++ b/resource/csdk/security/provisioning/src/secureresourceprovider.c @@ -202,8 +202,11 @@ struct RemoveData { /** * Function prototypes */ -static OCStackResult provisionCredentials(void *ctx, OicSecCred_t *cred, +static OCStackResult ProvisionCredentialsDos(void *ctx, OicSecCred_t *cred, const OCProvisionDev_t *deviceInfo, OCClientResponseHandler responseHandler); +static OCStackResult provisionCredentials(OicSecCred_t *cred, + const OCProvisionDev_t *deviceInfo, CredentialData_t *credData, + OCClientResponseHandler responseHandler); static OCStackApplicationResult ProvisionPskCB(void *ctx, OCDoHandle UNUSED, OCClientResponse *clientResponse); static OCStackResult SetDOS(const Data_t *data, OicSecDeviceOnboardingState_t dos, @@ -302,6 +305,128 @@ static OCStackApplicationResult provisionCredentialCB2(void *ctx, OCDoHandle UNU OCClientResponse *clientResponse) { VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION); + CredentialData_t *credData = (CredentialData_t *) ctx; + (void)UNUSED; + + OCProvisionResultCB resultCallback = credData->resultCallback; + OIC_LOG(INFO, TAG, "provisionCredentialCB2 called"); + if (clientResponse) + { + if(OC_STACK_RESOURCE_CHANGED == clientResponse->result) + { + registerResultForCredProvisioning(credData, OC_STACK_RESOURCE_CHANGED, DEVICE_2_FINISHED); + OCStackResult res = PDMLinkDevices(&credData->deviceInfo[0]->doxm->deviceID, + &credData->deviceInfo[1]->doxm->deviceID); + if (OC_STACK_OK != res) + { + OIC_LOG(ERROR, TAG, "Error occured on PDMLinkDevices"); + return OC_STACK_DELETE_TRANSACTION; + } + OIC_LOG(INFO, TAG, "Link created successfully"); + + ((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults, + credData->resArr, + false); + OICFree(credData->resArr); + OICFree(credData); + return OC_STACK_DELETE_TRANSACTION; + } + + } + OIC_LOG(INFO, TAG, "provisionCredentialCB2 received Null clientResponse"); + registerResultForCredProvisioning(credData, OC_STACK_ERROR, DEVICE_2_FINISHED); + ((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults, + credData->resArr, + true); + OICFree(credData->resArr); + OICFree(credData); + return OC_STACK_DELETE_TRANSACTION; +} + +/** + * Callback handler for handling callback of provisioning device 1. + * + * @param[in] ctx ctx value passed to callback from calling function. + * @param[in] UNUSED handle to an invocation + * @param[in] clientResponse Response from queries to remote servers. + * @return OC_STACK_DELETE_TRANSACTION to delete the transaction + * and OC_STACK_KEEP_TRANSACTION to keep it. + */ +static OCStackApplicationResult provisionCredentialCB1(void *ctx, OCDoHandle UNUSED, + OCClientResponse *clientResponse) +{ + VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION); + (void)UNUSED; + CredentialData_t* credData = (CredentialData_t*) ctx; + OICFree(credData->credInfo[0]); + const OCProvisionDev_t *deviceInfo = credData->deviceInfo[1]; + OicSecCred_t *credInfo = credData->credInfo[1]; + const OCProvisionResultCB resultCallback = credData->resultCallback; + if (clientResponse) + { + if (OC_STACK_RESOURCE_CHANGED == clientResponse->result) + { + // send credentials to second device + registerResultForCredProvisioning(credData, OC_STACK_RESOURCE_CHANGED, DEVICE_1_FINISHED); + OCStackResult res = provisionCredentials(credInfo, deviceInfo, credData, + provisionCredentialCB2); + // If deviceInfo is NULL, this device is the second device. Don't delete the cred + // because provisionCredentials added it to the local cred store and it now owns + // the memory. + if ((NULL != deviceInfo) || (OC_STACK_OK != res)) + { + DeleteCredList(credInfo); + } + if (OC_STACK_OK != res) + { + registerResultForCredProvisioning(credData, res,2); + ((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults, + credData->resArr, + true); + OICFree(credData->resArr); + OICFree(credData); + credData = NULL; + } + } + else + { + registerResultForCredProvisioning(credData, OC_STACK_ERROR, DEVICE_1_FINISHED); + ((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults, + credData->resArr, + true); + OICFree(credData->resArr); + OICFree(credData); + credData = NULL; + } + } + else + { + OIC_LOG(INFO, TAG, "provisionCredentialCB received Null clientResponse for first device"); + registerResultForCredProvisioning(credData, OC_STACK_ERROR, DEVICE_1_FINISHED); + ((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults, + credData->resArr, + true); + DeleteCredList(credInfo); + OICFree(credData->resArr); + OICFree(credData); + credData = NULL; + } + return OC_STACK_DELETE_TRANSACTION; +} + +/** + * Callback handler for handling callback of provisioning device 2. + * + * @param[in] ctx ctx value passed to callback from calling function. + * @param[in] UNUSED handle to an invocation + * @param[in] clientResponse Response from queries to remote servers. + * @return OC_STACK_DELETE_TRANSACTION to delete the transaction + * and OC_STACK_KEEP_TRANSACTION to keep it. + */ +static OCStackApplicationResult ProvisionCredentialDosCB2(void *ctx, OCDoHandle UNUSED, + OCClientResponse *clientResponse) +{ + VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION); CredentialData_t *credData = (CredentialData_t *) ((Data_t *) ctx)->ctx; (void)UNUSED; @@ -329,7 +454,7 @@ static OCStackApplicationResult provisionCredentialCB2(void *ctx, OCDoHandle UNU } } - OIC_LOG(INFO, TAG, "provisionCredentialCB2 received Null clientResponse"); + OIC_LOG(INFO, TAG, "ProvisionCredentialDosCB2 received Null clientResponse"); registerResultForCredProvisioning(credData, OC_STACK_ERROR, DEVICE_2_FINISHED); ((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults, credData->resArr, @@ -348,7 +473,7 @@ static OCStackApplicationResult provisionCredentialCB2(void *ctx, OCDoHandle UNU * @return OC_STACK_DELETE_TRANSACTION to delete the transaction * and OC_STACK_KEEP_TRANSACTION to keep it. */ -static OCStackApplicationResult provisionCredentialCB1(void *ctx, OCDoHandle UNUSED, +static OCStackApplicationResult ProvisionCredentialDosCB1(void *ctx, OCDoHandle UNUSED, OCClientResponse *clientResponse) { OIC_LOG_V(DEBUG, TAG, "IN %s", __func__); @@ -396,7 +521,83 @@ static OCStackApplicationResult provisionCredentialCB1(void *ctx, OCDoHandle UNU OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__); return OC_STACK_DELETE_TRANSACTION; } +/** + * Internal function for handling credential generation and sending credential to resource server. + * + * @param[in] cred Instance of cred resource. + * @param[in] deviceInfo information about device to which credential is to be provisioned. + * @param[in] responseHandler callbak called by OC stack when request API receives response. + * @return OC_STACK_OK in case of success and other value otherwise. + */ +static OCStackResult provisionCredentials(OicSecCred_t *cred, + const OCProvisionDev_t *deviceInfo, CredentialData_t *credData, + OCClientResponseHandler responseHandler) +{ + OCStackResult res = OC_STACK_OK; + + if (NULL != deviceInfo) + { + OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload)); + if (!secPayload) + { + OIC_LOG(ERROR, TAG, "Failed to allocate memory"); + return OC_STACK_NO_MEMORY; + } + secPayload->base.type = PAYLOAD_TYPE_SECURITY; + int secureFlag = 0; + res = CredToCBORPayload(cred, &secPayload->securityData, &secPayload->payloadSize, secureFlag); + if ((OC_STACK_OK != res) && (NULL == secPayload->securityData)) + { + OCPayloadDestroy((OCPayload *)secPayload); + OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload"); + return OC_STACK_NO_MEMORY; + } + OIC_LOG(DEBUG, TAG, "Created payload for Cred:"); + OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize); + char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = { 0 }; + if (!PMGenerateQuery(true, + deviceInfo->endpoint.addr, + deviceInfo->securePort, + deviceInfo->connType, + query, sizeof(query), OIC_RSRC_CRED_URI)) + { + OIC_LOG(ERROR, TAG, "DeviceDiscoveryHandler : Failed to generate query"); + OCPayloadDestroy((OCPayload *)secPayload); + return OC_STACK_ERROR; + } + OIC_LOG_V(DEBUG, TAG, "Query=%s", query); + + OCCallbackData cbData; + memset(&cbData, 0, sizeof(cbData)); + cbData.cb = responseHandler; + cbData.context = (void *)credData; + cbData.cd = NULL; + + OCDoHandle handle = NULL; + OCMethod method = OC_REST_POST; + res = OCDoResource(&handle, method, query, 0, (OCPayload*)secPayload, + deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0); + OIC_LOG_V(INFO, TAG, "OCDoResource::Credential provisioning returned : %d", res); + if (res != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG, "OCStack resource error"); + return res; + } + return OC_STACK_OK; + } + else + { + /* Provision this credential to the local cred store. On success, the cred resource takes + * ownership of the memory. On failure, provisionCredentialCB1 will delete the cred object. + */ + res = AddCredential(cred); + /* Call the result callback directly. */ + registerResultForCredProvisioning(credData, OC_STACK_RESOURCE_CHANGED, DEVICE_LOCAL_FINISHED); + (credData->resultCallback)(credData->ctx, credData->numOfResults, credData->resArr, false); + return res; + } +} /** * Internal function for handling credential generation and sending credential to resource server. * @@ -405,7 +606,7 @@ static OCStackApplicationResult provisionCredentialCB1(void *ctx, OCDoHandle UNU * @param[in] responseHandler callbak called by OC stack when request API receives response. * @return OC_STACK_OK in case of success and other value otherwise. */ -static OCStackResult provisionCredentials(void *ctx, OicSecCred_t *cred, +static OCStackResult ProvisionCredentialsDos(void *ctx, OicSecCred_t *cred, const OCProvisionDev_t *deviceInfo, OCClientResponseHandler responseHandler) { OCStackResult res = OC_STACK_OK; @@ -464,7 +665,7 @@ static OCStackResult provisionCredentials(void *ctx, OicSecCred_t *cred, else { /* Provision this credential to the local cred store. On success, the cred resource takes - * ownership of the memory. On failure, provisionCredentialCB1 will delete the cred object. + * ownership of the memory. On failure, ProvisionCredentialDosCB1 will delete the cred object. */ res = AddCredential(cred); /* Call the result callback directly. */ @@ -560,11 +761,11 @@ static OCStackApplicationResult SetReadyForNormalOperationCB(void *ctx, OCDoHand if (pskData->currIndex == 0) { pskData->currIndex = 1; - provisionCredentialCB1(ctx, handler, clientResponse); + ProvisionCredentialDosCB1(ctx, handler, clientResponse); } else { - provisionCredentialCB2(ctx, handler, clientResponse); + ProvisionCredentialDosCB2(ctx, handler, clientResponse); } } @@ -741,7 +942,7 @@ static OCStackApplicationResult ProvisionPskCB(void *ctx, OCDoHandle UNUSED, { if (OC_STACK_RESOURCE_CHANGED == clientResponse->result) { - OCStackResult res = provisionCredentials(ctx, cred, device, ProvisionCB); + OCStackResult res = ProvisionCredentialsDos(ctx, cred, device, ProvisionCB); if (OC_STACK_OK != res) { registerResultForCredProvisioning(credData, res, 2); @@ -1186,48 +1387,42 @@ OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t k return OC_STACK_ERROR; } OIC_LOG(INFO, TAG, "retrieved deviceid"); - - CredentialData_t *credData = (CredentialData_t *) OICCalloc(1, sizeof(CredentialData_t)); - Data_t *data = (Data_t *) OICCalloc(1, sizeof(Data_t)); - if (NULL == credData || NULL == data) - { - - OICFree(credData); - OICFree(data); - OIC_LOG(ERROR, TAG, "Memory allocation problem"); - return OC_STACK_NO_MEMORY; - } - - data->ctx = credData; - switch (type) { case SYMMETRIC_PAIR_WISE_KEY: { - data->type = PSK_TYPE; + const OCProvisionDev_t *firstDevice = pDev1; + const OCProvisionDev_t *secondDevice = pDev2; + OicSecCred_t *firstCred = NULL; OicSecCred_t *secondCred = NULL; OCStackResult res = PMGeneratePairWiseCredentials(type, keySize, &provTooldeviceID, - &pDev1->doxm->deviceID, (NULL != pDev2) ? &pDev2->doxm->deviceID : - &provTooldeviceID, - role1, role2, - &firstCred, &secondCred); - VERIFY_SUCCESS_RETURN(TAG, (res == OC_STACK_OK), ERROR, OC_STACK_ERROR); + &firstDevice->doxm->deviceID, (NULL != secondDevice) ? &secondDevice->doxm->deviceID : &provTooldeviceID, + role1, role2, + &firstCred, &secondCred); + VERIFY_SUCCESS_RETURN(TAG, (res==OC_STACK_OK), ERROR, OC_STACK_ERROR); OIC_LOG(INFO, TAG, "Credentials generated successfully"); - - credData->deviceInfo[0] = pDev1; - credData->deviceInfo[1] = pDev2; - credData->credInfo[0] = firstCred; + CredentialData_t *credData = + (CredentialData_t *) OICCalloc(1, sizeof(CredentialData_t)); + if (NULL == credData) + { + OICFree(firstCred); + OICFree(secondCred); + OIC_LOG(ERROR, TAG, "Memory allocation problem"); + return OC_STACK_NO_MEMORY; + } + credData->deviceInfo[0] = firstDevice; + credData->deviceInfo[1] = secondDevice; credData->credInfo[1] = secondCred; credData->ctx = ctx; - credData->currIndex = 0; + credData->credInfo[0] = firstCred; credData->numOfResults = 0; credData->resultCallback = resultCallback; // first call to provision creds to device1. // second call to provision creds to device2. int noOfRiCalls = 2; credData->resArr = - (OCProvisionResult_t *)OICCalloc(noOfRiCalls, sizeof(OCProvisionResult_t)); + (OCProvisionResult_t*)OICCalloc(noOfRiCalls, sizeof(OCProvisionResult_t)); if (NULL == credData->resArr) { OICFree(firstCred); @@ -1236,18 +1431,16 @@ OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t k OIC_LOG(ERROR, TAG, "Memory allocation problem"); return OC_STACK_NO_MEMORY; } - - res = SetDOS(data, DOS_RFPRO, ProvisionPskCB); - + res = provisionCredentials(firstCred, firstDevice, credData, &provisionCredentialCB1); if (OC_STACK_OK != res) { DeleteCredList(firstCred); DeleteCredList(secondCred); - FreeData(data); - OIC_LOG_V(ERROR, TAG, "OUT %s", __func__); - return res; + OICFree(credData->resArr); + OICFree(credData); } - OIC_LOG_V(INFO, TAG, "provisionCredentials returned: %d", res); + OIC_LOG_V(INFO, TAG, "provisionCredentials returned: %d",res); + VERIFY_SUCCESS_RETURN(TAG, (res==OC_STACK_OK), ERROR, OC_STACK_ERROR); return res; } case SIGNED_ASYMMETRIC_KEY: @@ -1258,7 +1451,6 @@ OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t k /* pemCert is the cerficiate to be provisioned */ VERIFY_NOT_NULL_RETURN(TAG, pemCert, ERROR, OC_STACK_INVALID_PARAM); - data->type = CERT_TYPE; OicSecKey_t deviceCert = { 0 }; deviceCert.data = (uint8_t*) pemCert; /* Casting away const is OK here */ deviceCert.len = strlen(pemCert) + 1; @@ -1281,10 +1473,10 @@ OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t k cred->credUsage = OICStrdup(PRIMARY_CERT); } - if (NULL == cred->credUsage) + /* Create credential data (used by the response handler provisionCertificateCB and freed there) */ + CredentialData_t *credData = (CredentialData_t *)OICCalloc(1, sizeof(CredentialData_t)); + if ((NULL == credData) || (NULL == cred->credUsage)) { - OICFree(credData); - OICFree(data); DeleteCredList(cred); OIC_LOG(ERROR, TAG, "Memory allocation problem"); return OC_STACK_NO_MEMORY; @@ -1298,13 +1490,11 @@ OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t k credData->resultCallback = resultCallback; credData->resArr = NULL; - /* Note: the callback is of type OCClientResponseHandler, thin wrapper that calls ResultCallback */ - // TODO update flow with DOS - OCStackResult res = provisionCredentials(ctx, cred, pDev1, &provisionCertificateCB); - if (OC_STACK_OK != res) + /* Note: the callback is of type OCClientResponseHandler, thin wrapper that calls resultCallback */ + OCStackResult res = provisionCredentials(cred, pDev1, credData, &provisionCertificateCB); + if (res != OC_STACK_OK) { OICFree(credData); - OICFree(data); } DeleteCredList(cred); @@ -1317,6 +1507,135 @@ OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t k } } } + +OCStackResult SRPProvisionCredentialsDos(void *ctx, OicSecCredType_t type, size_t keySize, + const OCProvisionDev_t *pDev1, + const OCProvisionDev_t *pDev2, + OCProvisionResultCB resultCallback) +{ + VERIFY_NOT_NULL_RETURN(TAG, pDev1, ERROR, OC_STACK_INVALID_PARAM); + if (!resultCallback) + { + OIC_LOG(INFO, TAG, "SRPProvisionCredentialsDos: NULL Callback"); + return OC_STACK_INVALID_CALLBACK; + } + if ((SYMMETRIC_PAIR_WISE_KEY == type) && + (NULL != pDev2) && + (0 == memcmp(&pDev1->doxm->deviceID, &pDev2->doxm->deviceID, sizeof(OicUuid_t)))) + { + OIC_LOG(INFO, TAG, "SRPProvisionCredentialsDos : Same device ID"); + return OC_STACK_INVALID_PARAM; + } + if (SYMMETRIC_PAIR_WISE_KEY == type && NULL == pDev2) + { + OIC_LOG(INFO, TAG, "SRPProvisionCredentialsDos : NULL device"); + return OC_STACK_INVALID_PARAM; + } + + if (SYMMETRIC_PAIR_WISE_KEY == type && + !(OWNER_PSK_LENGTH_128 == keySize || OWNER_PSK_LENGTH_256 == keySize)) + { + OIC_LOG(INFO, TAG, "Invalid key size"); + return OC_STACK_INVALID_PARAM; + } + + OIC_LOG(INFO, TAG, "In SRPProvisionCredentialsDos"); + + if ((SYMMETRIC_PAIR_WISE_KEY == type) && (NULL != pDev2)) + { + bool linkExisits = true; + OCStackResult res = PDMIsLinkExists(&pDev1->doxm->deviceID, &pDev2->doxm->deviceID, &linkExisits); + + if (res != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG, "Internal error occured"); + return res; + } + if (linkExisits) + { + OIC_LOG(ERROR, TAG, "Link already exists"); + return OC_STACK_INVALID_PARAM; + } + } + + OicUuid_t provTooldeviceID = {{0,}}; + if (OC_STACK_OK != GetDoxmDeviceID(&provTooldeviceID)) + { + OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID"); + return OC_STACK_ERROR; + } + OIC_LOG(INFO, TAG, "retrieved deviceid"); + + CredentialData_t *credData = (CredentialData_t *) OICCalloc(1, sizeof(CredentialData_t)); + Data_t *data = (Data_t *) OICCalloc(1, sizeof(Data_t)); + if (NULL == credData || NULL == data) + { + + OICFree(credData); + OICFree(data); + OIC_LOG(ERROR, TAG, "Memory allocation problem"); + return OC_STACK_NO_MEMORY; + } + + data->ctx = credData; + + switch (type) + { + case SYMMETRIC_PAIR_WISE_KEY: + { + data->type = PSK_TYPE; + OicSecCred_t *firstCred = NULL; + OicSecCred_t *secondCred = NULL; + OCStackResult res = PMGeneratePairWiseCredentials(type, keySize, &provTooldeviceID, + &pDev1->doxm->deviceID, (NULL != pDev2) ? &pDev2->doxm->deviceID : + &provTooldeviceID, + NULL, NULL, + &firstCred, &secondCred); + VERIFY_SUCCESS_RETURN(TAG, (res == OC_STACK_OK), ERROR, OC_STACK_ERROR); + OIC_LOG(INFO, TAG, "Credentials generated successfully"); + + credData->deviceInfo[0] = pDev1; + credData->deviceInfo[1] = pDev2; + credData->credInfo[0] = firstCred; + credData->credInfo[1] = secondCred; + credData->ctx = ctx; + credData->currIndex = 0; + credData->numOfResults = 0; + credData->resultCallback = resultCallback; + // first call to provision creds to device1. + // second call to provision creds to device2. + int noOfRiCalls = 2; + credData->resArr = + (OCProvisionResult_t *)OICCalloc(noOfRiCalls, sizeof(OCProvisionResult_t)); + if (NULL == credData->resArr) + { + OICFree(firstCred); + OICFree(secondCred); + OICFree(credData); + OIC_LOG(ERROR, TAG, "Memory allocation problem"); + return OC_STACK_NO_MEMORY; + } + + res = SetDOS(data, DOS_RFPRO, ProvisionPskCB); + + if (OC_STACK_OK != res) + { + DeleteCredList(firstCred); + DeleteCredList(secondCred); + FreeData(data); + OIC_LOG_V(ERROR, TAG, "OUT %s", __func__); + return res; + } + OIC_LOG_V(INFO, TAG, "provisionCredentials returned: %d", res); + return res; + } + default: + { + OIC_LOG(ERROR, TAG, "Invalid option."); + return OC_STACK_INVALID_PARAM; + } + } +} /** * Callback for ACL provisioning. */ -- 2.7.4