Commit b2a6955c authored by Kevin Kane's avatar Kevin Kane Committed by Greg Zaverucha

[IOT-1785] Implement roles from symmetric pair-wise keys

Implement roleId property of an oic.sec.cred object.

Fix error path bugs in CRED<->CBOR code to fail properly if
certain serialization subroutines fail; error codes were
being ignored. Fix error path memory leaks.

Also fix the ACL/ACL2<->CBOR code to use the correct JSON
field names per the schema. Fix error path memory leaks.

Change-Id: Ie9aa8baba5903c482acb3adc6ef617a1ced7db31
Signed-off-by: default avatarKevin Kane <kkane@microsoft.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/18463Reviewed-by: default avatarAlex Kelley <alexke@microsoft.com>
Tested-by: default avatarjenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: default avatarDave Thaler <dthaler@microsoft.com>
Reviewed-by: default avatarGreg Zaverucha <gregz@microsoft.com>
parent a99cd2f0
......@@ -53,6 +53,16 @@ OCStackResult InitRolesResource();
*/
OCStackResult DeInitRolesResource();
/**
* Register the PSK credential being used for authentication. This is used by the cred resource
* to inform the roles resource a symmetric PSK has a particular role associated with it.
*
* @param[in] cred PSK credential to register
*
* @return OC_STACK_OK if role credential is successfully registered; error otherwise.
*/
OCStackResult RegisterSymmetricCredentialRole(const OicSecCred_t *cred);
/**
* Retrieve the roles asserted by a given endpoint with certificates.
*
......
......@@ -135,6 +135,17 @@ bool SRMIsSecurityResourceURI(const char* uri);
*/
OicSecSvrType_t GetSvrTypeFromUri(const char* uri);
extern const OicSecRole_t EMPTY_ROLE;
/**
* Determine if a role is non-empty.
*
* @param[in] role Role to check
*
* @return true if role is non-empty, false if role is empty
*/
bool IsNonEmptyRole(const OicSecRole_t *role);
#ifdef __cplusplus
}
#endif
......
......@@ -126,7 +126,8 @@ extern const char * OIC_JSON_OXM_TYPE_NAME;
extern const char * OIC_JSON_OXM_SEL_NAME;
extern const char * OIC_JSON_DEVICE_ID_FORMAT_NAME;
extern const char * OIC_JSON_CREDID_NAME;
extern const char * OIC_JSON_ROLEIDS_NAME;
extern const char * OIC_JSON_ROLEID_NAME;
extern const char * OIC_JSON_ROLE_NAME;
extern const char * OIC_JSON_AUTHORITY_NAME;
extern const char * OIC_JSON_CREDTYPE_NAME;
extern const char * OIC_JSON_PUBLICDATA_NAME;
......
......@@ -528,10 +528,8 @@ struct OicSecCred
// <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
uint16_t credId; // 0:R:S:Y:UINT16
OicUuid_t subject; // 1:R:S:Y:oic.uuid
//Note: Need further clarification on roleID data type
//NOTE: Need further clarification on roleId datatype.
//size_t roleIdsLen; // the number of elts in RoleIds
//OicSecRole_t *roleIds; // 2:R:M:N:oic.sec.role
// If roleId.id is all zeroes, this property is not set.
OicSecRole_t roleId; // 2:R:M:N:oic.sec.roletype
OicSecCredType_t credType; // 3:R:S:Y:oic.sec.credtype
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
OicSecKey_t publicData; // own cerificate chain
......
......@@ -36,6 +36,8 @@ extern "C" {
* @param[in] ptDeviceId Device ID of provisioning tool.
* @param[in] firstDeviceId DeviceID of the first device.
* @param[in] secondDeviceId DeviceID of the second device.
* @param[in] firstRole Role to grant firstDeviceId when communicating with secondDeviceId; NULL for none
* @param[in] secondRole Role to grant secondDeviceId when communicating with firstDeviceId; NULL for none
* @param[out] firstCred Generated credential for first device.
* @param[out] secondCred Generated credential for second device.
* @return OC_STACK_OK on success
......@@ -44,6 +46,8 @@ OCStackResult PMGeneratePairWiseCredentials(OicSecCredType_t type, size_t keySiz
const OicUuid_t *ptDeviceId,
const OicUuid_t *firstDeviceId,
const OicUuid_t *secondDeviceId,
const OicSecRole_t *firstRole,
const OicSecRole_t *secondRole,
OicSecCred_t **firstCred,
OicSecCred_t **secondCred);
......
......@@ -227,10 +227,17 @@ OCStackResult SRPProvisionDirectPairing(void *ctx, const OCProvisionDev_t *selec
* @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, respresenting resource to be provsioned.
* @param[in] pDev2 Pointer to PMOwnedDeviceInfo_t instance, respresenting resource to be provsioned.
* @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.
* Use NULL to indicate the local device.
* @param[in] pemCert When provisioning a certificate (type is SIGNED_ASYMMETRIC_KEY), this is the
* certificate, encoded as PEM.
* @param[in] role1 When provisioning a PSK (type is SYMMETRIC_PAIR_WISE_KEY), this is the role which
* the device indicated by pDev1 will also have when communicating with pDev2. Use NULL
* to associate no role with this credential.
* @param[in] role2 When provisioning a PSK (type is SYMMETRIC_PAIR_WISE_KEY), this is the role which
* the device indicated by pDev1 will also have when communicating with pDev2. Use NULL
* to associate no role with this credential.
* @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.
......@@ -239,6 +246,8 @@ OCStackResult SRPProvisionCredentials(void *ctx,OicSecCredType_t type, size_t ke
const OCProvisionDev_t *pDev1,
const OCProvisionDev_t *pDev2,
const char* pemCert,
const OicSecRole_t *role1,
const OicSecRole_t *role2,
OCProvisionResultCB resultCallback);
/**
......
......@@ -344,8 +344,8 @@ OCStackResult OCProvisionDirectPairing(void* ctx, const OCProvisionDev_t *select
* @param[in] ctx Application context returned in the 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 OCProvisionDev_t instance,respresenting resource to be provsioned.
@param[in] pDev2 Pointer to OCProvisionDev_t instance,respresenting resource to be provsioned.
* @param[in] pDev1 Pointer to OCProvisionDev_t instance, representing the resource to be provisioned.
* @param[in] pDev2 Pointer to OCProvisionDev_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.
......@@ -355,6 +355,30 @@ OCStackResult OCProvisionCredentials(void *ctx, OicSecCredType_t type, size_t ke
const OCProvisionDev_t *pDev2,
OCProvisionResultCB resultCallback);
/**
* API to provision symmetric pair-wise key credentials to devices that grant a role.
*
* @param[in] ctx Application context returned in the 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 OCProvisionDev_t instance, representing the resource to be provisioned.
* @param[in] pDev2 Pointer to OCProvisionDev_t instance, representing the resource to be provisioned.
* Use NULL to indicate the local device.
* @param[in] role1 The role which the device indicated by pDev1 will have when communicating with pDev2.
* Use NULL to associate no role with this credential.
* @param[in] role2 The role which the device indicated by pDev2 will have when communicating with pDev1.
* Use NULL to associate no role with this credential.
* @param[in] resultCallback callback provided by API user, callback will be called when
* provisioning request receives a response from first resource server.
* @return OC_STACK_OK in case of success and other value otherwise.
*/
OCStackResult OCProvisionSymmetricRoleCredentials(void *ctx, OicSecCredType_t type, size_t keySize,
const OCProvisionDev_t *pDev1,
const OCProvisionDev_t *pDev2,
const OicSecRole_t *role1,
const OicSecRole_t *role2,
OCProvisionResultCB resultCallback);
/**
* API to provision a certificate to a device.
*
......
......@@ -1571,6 +1571,136 @@ exit:
return ret;
}
static int provisionSymmetricRoleCred(int dev_num)
{
OicSecRole_t role;
memset(&role, 0, sizeof(role));
OICStrcpy(role.id, sizeof(role.id), TEST_CERT_ROLE1);
// call |OCProvisionCredentials| API
// calling this API with callback actually acts like blocking
// for error checking, the return value saved and printed
g_doneCB = false;
OCStackResult rst =
OCProvisionSymmetricRoleCredentials((void*) g_ctx,
SYMMETRIC_PAIR_WISE_KEY, OWNER_PSK_LENGTH_128,
getDevInst((const OCProvisionDev_t*) g_own_list, dev_num),
NULL, NULL, &role,
provisionCredCB);
if (OC_STACK_OK != rst)
{
OIC_LOG_V(ERROR, TAG, "OCProvisionCredentials API error: %d", rst);
return -1;
}
if (waitCallbackRet()) // input |g_doneCB| flag implicitly
{
OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
return -1;
}
return 0;
}
static int testSymmetricRoleUse(int dev_num)
{
const char* uri = "/a/led";
OicSecAcl_t* acl = NULL;
// Make sure we own at least one device to provision
if (!g_own_list || (g_own_cnt == 0))
{
OIC_LOG(ERROR, TAG, "Owned device list empty, must discover unowned devices first");
return -1; // Error, we should have registered unowned devices already
}
/* Create and provision a role-based ACL allowing ROLE1 to access '/a/led'. */
int ret = createLedAcl(&acl, TEST_CERT_ROLE1, NULL);
if (ret != 0)
{
OIC_LOG_V(ERROR, TAG, "%s failed to create led ACL", __func__);
return ret;
}
ret = provisionAcl(dev_num, acl);
if (ret != 0)
{
OIC_LOG_V(ERROR, TAG, "%s failed to provision led ACL", __func__);
goto exit;
}
/* Create and provision an ACL to allow anyone access to the roles resource. Since all actions
* on the roles resource first requires authentication by public key, this is effectively "any
* authenticated" access.
* @todo: This should be done by default and not be necessary here (IOT-1950).
*/
OCDeleteACLList(acl);
acl = NULL;
ret = createRolesAcl(&acl);
if (ret != 0)
{
OIC_LOG_V(ERROR, TAG, "%s failed to create roles ACL", __func__);
goto exit;
}
ret = provisionAcl(dev_num, acl);
if (ret != 0)
{
OIC_LOG_V(ERROR, TAG, "%s failed to provision roles ACL", __func__);
goto exit;
}
/* Remove the owner credential so that we don't use it when asserting role certs. */
OCStackResult res = OCRemoveCredential(&g_uuidDev1);
if (res != OC_STACK_RESOURCE_DELETED)
{
OIC_LOG_V(ERROR, TAG, "%s failed to remove owner credential for subject UUID: ", __func__);
OIC_LOG_BUFFER(DEBUG, TAG, g_uuidDev1.id, UUID_LENGTH);
ret = -1;
goto exit;
}
/* The server has an owner PSK associated with our GUID. Change our GUID to something else,
* which will both be used to generate the role credential and for the later connection.
*/
const OCUUIdentity newIdentity = { .id = { 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46 } };
if (OC_STACK_OK != OCSetDeviceId(&newIdentity))
{
OIC_LOG_V(ERROR, TAG, "%s failed to set device ID", __func__);
ret = -1;
goto exit;
}
/* Create a new symmetric credential with the role. */
ret = provisionSymmetricRoleCred(dev_num);
if (ret != 0)
{
OIC_LOG_V(ERROR, TAG, "%s failed to provision symmetric role pair-wise keys", __func__);
goto exit;
}
/* Close all secure sessions */
if (closeAllSessions() != 0)
{
OIC_LOG_V(ERROR, TAG, "%s Failed to close sessions", __func__);
ret = -1;
goto exit;
}
/* Try a get request, expect success */
ret = doGetRequest(uri, dev_num);
if (ret != 0)
{
OIC_LOG_V(ERROR, TAG, "%s Get request to %s failed, but should have succeeded", __func__, uri);
goto exit;
}
exit:
OCDeleteACLList(acl);
return ret;
}
/* Get a specific device from the provided device list. The devices in the list
* are numbered starting from 1.
*/
......@@ -1905,6 +2035,32 @@ exit:
return ret;
}
int TestSymmetricRoleUse()
{
int ret = -1;
OIC_LOG_V(ERROR, TAG, "Running %s", __func__);
if (initDiscoverRegisterAllDevices())
{
OIC_LOG_V(ERROR, TAG, "%s: Failed to discover and provision devices", __func__);
goto exit;
}
/* There should be one owned device with number 1. */
if (testSymmetricRoleUse(1))
{
OIC_LOG(ERROR, TAG, "Failed to use symmetric key role");
goto exit;
}
exit:
shutdownProvisionClient();
return ret;
}
// main function for provisioning client using C-level provisioning API
int main(int argc, char** argv)
{
......@@ -1927,6 +2083,8 @@ int main(int argc, char** argv)
return TestRoleProvisioning();
case 5:
return TestRoleAssertionAndUse();
case 6:
return TestSymmetricRoleUse();
default:
printf("%s: Invalid test number\n", argv[0]);
return 1;
......
......@@ -42,7 +42,7 @@ def print_environment():
### main ###
# Number of unit tests in autoprovisioningclient
NUM_TESTS = 5
NUM_TESTS = 6
usage = '''
Run end-to-end certificate tests between autoprovisioningclient and sampleserver_justworks
......
......@@ -34,7 +34,9 @@
OCStackResult PMGeneratePairWiseCredentials(OicSecCredType_t type, size_t keySize,
const OicUuid_t *ptDeviceId, const OicUuid_t *firstDeviceId,
const OicUuid_t *secondDeviceId, OicSecCred_t **firstCred, OicSecCred_t **secondCred)
const OicUuid_t *secondDeviceId,
const OicSecRole_t *firstRole, const OicSecRole_t *secondRole,
OicSecCred_t **firstCred, OicSecCred_t **secondCred)
{
if (NULL == ptDeviceId || NULL == firstDeviceId || NULL == firstCred || NULL != *firstCred || \
NULL == secondDeviceId || NULL == secondCred || NULL != *secondCred)
......@@ -77,6 +79,18 @@ OCStackResult PMGeneratePairWiseCredentials(OicSecCredType_t type, size_t keySiz
tempSecondCred = GenerateCredential(firstDeviceId, type, NULL, &privKey, ptDeviceId, NULL);
VERIFY_NOT_NULL(TAG, tempSecondCred, ERROR);
// firstRole and secondRole are the roles granted to the client when authenticating with this credential;
// therefore, the role to be granted has to be stored on the corresponding server. This is why secondRole
// is assigned to tempFirstCred and vice versa.
if (NULL != secondRole)
{
tempFirstCred->roleId = *secondRole;
}
if (NULL != firstRole)
{
tempSecondCred->roleId = *firstRole;
}
*firstCred = tempFirstCred;
*secondCred = tempSecondCred;
res = OC_STACK_OK;
......
......@@ -478,8 +478,34 @@ OCStackResult OCProvisionCredentials(void *ctx, OicSecCredType_t type, size_t ke
OCProvisionResultCB resultCallback)
{
return SRPProvisionCredentials(ctx, type, keySize,
pDev1, pDev2, NULL, resultCallback);
pDev1, pDev2, NULL, NULL, NULL, resultCallback);
}
/**
* API to provision symmetric pair-wise key credentials to devices that grant a role.
*
* @param[in] ctx Application context returned in the 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 OCProvisionDev_t instance, representing the resource to be provisioned.
* @param[in] pDev2 Pointer to OCProvisionDev_t instance, representing the resource to be provisioned.
* Use NULL to indicate the local device.
* @param[in] role1 The role which the device indicated by pDev1 will have when communicating with pDev2.
* Use NULL to associate no role with this credential.
* @param[in] role2 The role which the device indicated by pDev2 will have when communicating with pDev1.
* Use NULL to associate no role with this credential.
* @param[in] resultCallback callback provided by API user, callback will be called when
* provisioning request receives a response from first resource server.
* @return OC_STACK_OK in case of success and other value otherwise.
*/
OCStackResult OCProvisionSymmetricRoleCredentials(void *ctx, OicSecCredType_t type, size_t keySize,
const OCProvisionDev_t *pDev1,
const OCProvisionDev_t *pDev2,
const OicSecRole_t *role1,
const OicSecRole_t *role2,
OCProvisionResultCB resultCallback)
{
return SRPProvisionCredentials(ctx, type, keySize, pDev1, pDev2, NULL, role1, role2, resultCallback);
}
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
......@@ -499,7 +525,7 @@ OCStackResult OCProvisionCertificate(void *ctx,
OCProvisionResultCB resultCallback)
{
return SRPProvisionCredentials(ctx, SIGNED_ASYMMETRIC_KEY, 0,
pDev, NULL, pemCert, resultCallback);
pDev, NULL, pemCert, NULL, NULL, resultCallback);
}
#endif
......@@ -1245,7 +1271,7 @@ OCStackResult OCProvisionPairwiseDevices(void* ctx, OicSecCredType_t type, size_
link->currentCountResults = 0;
link->resArr = (OCProvisionResult_t*) OICMalloc(sizeof(OCProvisionResult_t)*noOfResults);
res = SRPProvisionCredentials(link, type, keySize,
pDev1, pDev2, NULL, &ProvisionCredsCB);
pDev1, pDev2, NULL, NULL, NULL, &ProvisionCredsCB);
if (res != OC_STACK_OK)
{
OICFree(link->resArr);
......
......@@ -175,27 +175,47 @@ struct RemoveData {
/**
* Function prototype
*/
static OCStackResult provisionCredentials(const OicSecCred_t *cred,
static OCStackResult provisionCredentials(OicSecCred_t *cred,
const OCProvisionDev_t *deviceInfo, CredentialData_t *credData,
OCClientResponseHandler responseHandler);
typedef enum {
DEVICE_1_FINISHED,
DEVICE_2_FINISHED,
DEVICE_LOCAL_FINISHED
} CredProvisioningResultCause_t;
/**
* Internal function to update result in result array.
*/
static void registerResultForCredProvisioning(CredentialData_t *credData,
OCStackResult stackresult, int cause)
OCStackResult stackresult, CredProvisioningResultCause_t cause)
{
OCStackResult res = OC_STACK_ERROR;
OIC_LOG_V(INFO,TAG,"value of credData->numOfResults is %d",credData->numOfResults);
if(1 == cause)
switch (cause)
{
case DEVICE_1_FINISHED:
memcpy(credData->resArr[(credData->numOfResults)].deviceId.id,
credData->deviceInfo1->doxm->deviceID.id,UUID_LENGTH);
}
else
{
break;
case DEVICE_2_FINISHED:
memcpy(credData->resArr[(credData->numOfResults)].deviceId.id,
credData->deviceInfo2->doxm->deviceID.id,UUID_LENGTH);
break;
case DEVICE_LOCAL_FINISHED:
res = GetDoxmDeviceID(&credData->resArr[(credData->numOfResults)].deviceId);
if (OC_STACK_OK != res)
{
OIC_LOG_V(WARNING, TAG, "%s: Could not retrieve own device ID to populate result for cred provisioning: %d", __func__, res);
memset(credData->resArr[(credData->numOfResults)].deviceId.id, 0, UUID_LENGTH);
}
break;
default:
assert(!"Unknown value for cause");
OIC_LOG_V(ERROR, TAG, "%s: unknown value of cause: %d", __func__, cause);
memset(credData->resArr[(credData->numOfResults)].deviceId.id, 0, UUID_LENGTH);
break;
}
credData->resArr[(credData->numOfResults)].res = stackresult;
++(credData->numOfResults);
......@@ -223,7 +243,7 @@ static OCStackApplicationResult provisionCredentialCB2(void *ctx, OCDoHandle UNU
{
if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
{
registerResultForCredProvisioning(credData, OC_STACK_RESOURCE_CHANGED, 2);
registerResultForCredProvisioning(credData, OC_STACK_RESOURCE_CHANGED, DEVICE_2_FINISHED);
OCStackResult res = PDMLinkDevices(&credData->deviceInfo1->doxm->deviceID,
&credData->deviceInfo2->doxm->deviceID);
if (OC_STACK_OK != res)
......@@ -243,7 +263,7 @@ static OCStackApplicationResult provisionCredentialCB2(void *ctx, OCDoHandle UNU
}
OIC_LOG(INFO, TAG, "provisionCredentialCB2 received Null clientResponse");
registerResultForCredProvisioning(credData, OC_STACK_ERROR, 2);
registerResultForCredProvisioning(credData, OC_STACK_ERROR, DEVICE_2_FINISHED);
((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults,
credData->resArr,
true);
......@@ -276,10 +296,16 @@ static OCStackApplicationResult provisionCredentialCB1(void *ctx, OCDoHandle UNU
if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
{
// send credentials to second device
registerResultForCredProvisioning(credData, OC_STACK_RESOURCE_CHANGED,1);
registerResultForCredProvisioning(credData, OC_STACK_RESOURCE_CHANGED, DEVICE_1_FINISHED);
OCStackResult res = provisionCredentials(credInfo, deviceInfo, credData,
provisionCredentialCB2);
DeleteCredList(credInfo);
// 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);
......@@ -293,7 +319,7 @@ static OCStackApplicationResult provisionCredentialCB1(void *ctx, OCDoHandle UNU
}
else
{
registerResultForCredProvisioning(credData, OC_STACK_ERROR,1);
registerResultForCredProvisioning(credData, OC_STACK_ERROR, DEVICE_1_FINISHED);
((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults,
credData->resArr,
true);
......@@ -305,7 +331,7 @@ static OCStackApplicationResult provisionCredentialCB1(void *ctx, OCDoHandle UNU
else
{
OIC_LOG(INFO, TAG, "provisionCredentialCB received Null clientResponse for first device");
registerResultForCredProvisioning(credData, OC_STACK_ERROR,1);
registerResultForCredProvisioning(credData, OC_STACK_ERROR, DEVICE_1_FINISHED);
((OCProvisionResultCB)(resultCallback))(credData->ctx, credData->numOfResults,
credData->resArr,
true);
......@@ -325,58 +351,73 @@ 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(const OicSecCred_t *cred,
static OCStackResult provisionCredentials(OicSecCred_t *cred,
const OCProvisionDev_t *deviceInfo, CredentialData_t *credData,
OCClientResponseHandler responseHandler)
{
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;
OCStackResult 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;
}
OCStackResult res = OC_STACK_OK;
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))
if (NULL != deviceInfo)
{
OIC_LOG(ERROR, TAG, "DeviceDiscoveryHandler : Failed to generate query");
OCPayloadDestroy((OCPayload *)secPayload);
return OC_STACK_ERROR;
}
OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
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;
}
OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
cbData.cb = responseHandler;
cbData.context = (void *) credData;
cbData.cd = NULL;
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))
{