Commit 4541e501 authored by Greg Zaverucha's avatar Greg Zaverucha Committed by Nathan Heldt-Sheller

[IOT-1785] Finish role certs feature

Add end-to-end testing of role certificate scenario:
- provision role certs
- test role-based ACLs provisioning and enforcement
- test assertion of role certificates

Fix bugs and add new functions as necessary. Added the ROLE_CERT
usage to distinguish role certs (which can't be used for TLS)
from identity certs. Previously they were both saved as PRIMARY_CERT.
Some small changes to save and retrieve role certificates locally. Add
functionality to assert roles (POST the certs to /oic/sec/roles).

Change-Id: I9080e0ca6b0809608621eb8b23dd4bbbfbbb176c
Signed-off-by: default avatarGreg Zaverucha <gregz@microsoft.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/18219Reviewed-by: default avatarAlex Kelley <alexke@microsoft.com>
Reviewed-by: default avatarDave Thaler <dthaler@microsoft.com>
Reviewed-by: default avatarKevin Kane <kkane@microsoft.com>
Tested-by: default avatarjenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: Nathan Heldt-Sheller's avatarNathan Heldt-Sheller <nathan.heldt-sheller@intel.com>
parent 9ca54cba
......@@ -24,6 +24,7 @@
#include "cainterface.h"
#include "securevirtualresourcetypes.h"
#include "octypes.h"
#include "rolesresource.h"
#include <cbor.h>
#ifdef __cplusplus
......@@ -221,6 +222,18 @@ OCStackResult GetCredRownerId(OicUuid_t *rowneruuid);
* @param[in] usage credential usage string.
*/
OCStackResult GetPemCaCert(ByteArray_t * crt, const char * usage);
/**
* Get a list of all role certificates. Used when asserting roles.
*
* @param[out] roleCerts list of role certificates
* @return When ::OC_STACK_OK is returned, a list of certificates (roleCerts)
* that must be freed with FreeRoleCertChainList. roleCerts can still
* be NULL in this case, if no role certs are installed. On error, an
* error value is returned and roleCerts is NULL.
*/
OCStackResult GetAllRoleCerts(RoleCertChain_t** roleCerts);
/**
* Used by mbedTLS to retrieve own certificate chain
*
......
......@@ -76,10 +76,24 @@ OCStackResult GetEndpointRoles(const CAEndpoint_t *endpoint, OicSecRole_t **role
* @param[in] size Size of cborPayload
* @param[out] roleCertList Pointer to receive linked list of RoleCertChain_t objects
* On success, caller must call FreeRoleCertChainList on *roleCertList when finished
*
* @return OC_STACK_OK if payload is successfully converted; error code otherwise
*/
OCStackResult CBORPayloadToRoles(const uint8_t *cborPayload, size_t size, RoleCertChain_t **roleCertList);
/**
* This function converts a list of role certificates into a CBOR payload.
* Caller needs to call 'OICFree' on *cborPayload after use.
*
* @param[in] roles Linked list of RoleCertChain_t objects
* @param[out] cborPayload Pointer to receive the CBOR payload
* On success, caller must call OICFree on *cborPayload when finished
* @param[out] size Pointer to receive size of cborPayload
*
* @return OC_STACK_OK if payload is successfully converted; error code otherwise
*/
OCStackResult RolesToCBORPayload(const RoleCertChain_t *roles, uint8_t **cborPayload, size_t *cborSize);
/**
* Free the memory used by a list of RoleCertChain_t objects created by CBORPayloadToRoles.
*
......
......@@ -181,6 +181,7 @@ extern const char * OIC_JSON_EMPTY_STRING;
extern const char * TRUST_CA;
extern const char * PRIMARY_CERT;
extern const char * PRIMARY_KEY;
extern const char * ROLE_CERT;
// Certificates provided by manufacturer
extern const char * MF_TRUST_CA;
......
......@@ -132,7 +132,7 @@ OCStackResult OCGenerateIdentityCertificate(
size_t *certificateLen);
/**
* Generate a certificate for a device's role.
* Generate a role certificate for a device.
*
* @param subjectUuid UUID for the device to use the certificate.
* @param subjectPublicKey Subject's public key in PEM format
......@@ -176,7 +176,7 @@ OCStackResult OCGenerateRoleCertificate(
* @param[in] csr The CSR containing the UUID as null-terminated PEM.
* @param[out] uuid The UUID in the CSR
*
* @return 0 on success, nonzero otherwise
* @return OC_STACK_OK if successful, error code otherwise
*/
OCStackResult OCGetUuidFromCSR(const char* csr, OicUuid_t* uuid);
......@@ -187,7 +187,7 @@ OCStackResult OCGetUuidFromCSR(const char* csr, OicUuid_t* uuid);
* @param[out] publicKey The public key is output here as null-terminated PEM.
* Callers must call OICFree when finished.
*
* @return 0 on success, nonzero otherwise
* @return OC_STACK_OK if successful, error code otherwise
*/
OCStackResult OCGetPublicKeyFromCSR(const char* csr, char** publicKey);
......@@ -196,7 +196,7 @@ OCStackResult OCGetPublicKeyFromCSR(const char* csr, char** publicKey);
*
* @param[in] csr The CSR to check, as null-terminated PEM.
*
* @returns 0 on success, nonzero otherwise
* @return OC_STACK_OK if successful, error code otherwise
*
* @remark Requires that ECDSA with SHA-256 be used for the signature.
*/
......@@ -210,8 +210,8 @@ OCStackResult OCVerifyCSRSignature(const char* csr);
* @param[out] pemCSR The output, PEM encoded, null-terminated CSR. Callers
* call OICFree when finished.
*
* @returns 0 on success, nonzero otherwise
*/
* @return OC_STACK_OK if successful, error code otherwise
*/
OCStackResult OCConvertDerCSRToPem(const char* derCSR, size_t derCSRLen, char** pemCSR);
#ifdef __cplusplus
......
......@@ -293,14 +293,15 @@ enum
OIC_R_AMACL_TYPE,
OIC_R_CRED_TYPE,
OIC_R_CRL_TYPE,
OIC_R_CSR_TYPE,
OIC_R_DOXM_TYPE,
OIC_R_DPAIRING_TYPE,
OIC_R_PCONF_TYPE,
OIC_R_PSTAT_TYPE,
OIC_R_ROLES_TYPE,
OIC_R_SACL_TYPE,
OIC_R_SVC_TYPE,
OIC_R_CSR_TYPE,
OIC_R_ACL2_TYPE,
OIC_R_ROLES_TYPE,
OIC_SEC_SVR_TYPE_COUNT, //define the value to number of SVR
NOT_A_SVR_RESOURCE = 99
};
......
......@@ -156,6 +156,31 @@ OCStackResult SRPSaveTrustCertChain(const uint8_t *trustCertChain, size_t chainS
*/
OCStackResult SRPSaveOwnCertChain(OicSecKey_t * cert, OicSecKey_t * key, uint16_t *credId);
/**
* function to save own role certificate into Cred of SVR.
*
* @param[in] cert Certificate chain to be saved in Cred of SVR
* @param[out] credId CredId of saved trust certificate chain in Cred of SVR.
* @return OC_STACK_OK in case of success and other value otherwise.
*
* @note The certificate public key must be the same as public key in the identity
* certificate (installed by SRPSaveOwnCertChain).
*/
OCStackResult SRPSaveOwnRoleCert(OicSecKey_t * cert, uint16_t *credId);
/**
* Assert all roles to a device. This POSTs all role certificates from the
* local cred resource to /oic/sec/roles.
*
* @param[in] ctx User context to be passed.
* @param[in] device The device to assert the roles to
* @param[in] resultCallback Callback that is called with the response from the device
* @return OC_STACK_OK in case of success and other value otherwise.
*
* @note If no role certificates are installed, this will fail. See GetAllRoleCerts in credresource.h
*/
OCStackResult SRPAssertRoles(void *ctx, const OCProvisionDev_t *device, OCProvisionResultCB resultCallback);
/**
* function to register callback, for getting notification for TrustCertChain change.
*
......
......@@ -627,6 +627,18 @@ OCStackResult OCSaveTrustCertChain(const uint8_t *trustCertChain, size_t chainSi
*/
OCStackResult OCSaveOwnCertChain(const char* cert, const char* key, uint16_t *credId);
/**
* Function to save own role certificate into Cred of SVR.
*
* @param[in] cert Certificate chain to be saved in Cred of SVR, PEM encoded, null terminated
* @param[out] credId CredId of saved trust certificate chain in Cred of SVR.
* @return OC_STACK_OK in case of success and other value otherwise.
*
* @note The certificate public key must be the same as public key in the identity
* certificate (installed by OCSaveOwnCertChain).
*/
OCStackResult OCSaveOwnRoleCert(const char* cert, uint16_t *credId);
/**
* function to register callback, for getting notification for TrustCertChain change.
*
......
......@@ -41,6 +41,9 @@ def print_environment():
### main ###
# Number of unit tests in autoprovisioningclient
NUM_TESTS = 5
usage = '''
Run end-to-end certificate tests between autoprovisioningclient and sampleserver_justworks
Usage Notes
......@@ -58,14 +61,12 @@ parser = argparse.ArgumentParser(
description=usage
)
parser.add_argument('--arch', nargs='?', choices = ['amd64', 'x86', 'arm'], help= 'Architecture, one of x86, amd64 or arm. Defaults to amd64', default='amd64')
parser.add_argument('--build', nargs='?', choices = ['debug', 'release'], help= 'Build type, one of debug or release. Defaults to debug', default='debug')
parser.add_argument('--arch', nargs='?', choices = ['amd64', 'x86', 'arm'], help= 'Architecture, one of x86, amd64 or arm. Defaults to amd64.', default='amd64')
parser.add_argument('--build', nargs='?', choices = ['debug', 'release'], help= 'Build type, one of debug or release. Defaults to debug.', default='debug')
parser.add_argument('--onetest', nargs='?', choices = ['1', '...', str(NUM_TESTS)], help= 'Run a single test, specified by number. By default all tests are run.')
args = parser.parse_args()
# Number of unit tests in autoprovisioningclient
NUM_TESTS = 3
iotivity_base_path = os.getcwd()
os_name = platform.system()
if os_name == 'Windows':
......@@ -85,7 +86,16 @@ os.chdir(exe_path)
output_text = ""
num_failures = 0
for i in range(1, NUM_TESTS + 1):
test_range = range(1, NUM_TESTS + 1) #default to running all tests
if args.onetest:
try:
test_range = range(int(args.onetest), int(args.onetest) + 1)
except ValueError:
print 'invalid argument to --onetest'
sys.exit(-1)
for i in test_range:
print '\nRunning test %d...\n' % i
# Clear state from previous test
......@@ -114,7 +124,7 @@ for i in range(1, NUM_TESTS + 1):
print "\n------------------------------------"
print " Test Results: %d of %d tests passed" % (NUM_TESTS - num_failures, NUM_TESTS)
print " Test Results: %d of %d tests passed" % (len(test_range) - num_failures, len(test_range))
print "------------------------------------"
print output_text
print '\n'
......
......@@ -340,29 +340,49 @@ void OCDeleteDiscoveredDevices(OCProvisionDev_t *pList)
}
/**
* this function sends ACL information to resource.
* This function sends ACL information to resource.
*
* @param[in] ctx Application context would be returned in result callback.
* @param[in] selectedDeviceInfo Selected target device.
* @param[in] acl ACL to provision.
* @param[in] resultCallback callback provided by API user, callback will be called when provisioning
request recieves a response from resource server.
* request receives a response from resource server.
* @return OC_STACK_OK in case of success and other value otherwise.
*/
OCStackResult OCProvisionACL(void* ctx, const OCProvisionDev_t *selectedDeviceInfo, OicSecAcl_t *acl,
OCProvisionResultCB resultCallback)
{
return SRPProvisionACL(ctx, selectedDeviceInfo, acl, OIC_SEC_ACL_V1, resultCallback);
/*
* Determine whether this is a version 1 or version 2 ACL. We can't just always use V2 here
* since we may be provisioning an IoTivity 1.2 device.
*/
OicSecAclVersion_t aclVersion = OIC_SEC_ACL_V1; /* default to v1 */
if (acl->aces != NULL)
{
/* If any of the aces have the role subject, the ACL is v2 */
OicSecAce_t* ace = NULL;
LL_FOREACH(acl->aces, ace)
{
if (ace->subjectType == OicSecAceRoleSubject)
{
aclVersion = OIC_SEC_ACL_V2;
break;
}
}
}
return SRPProvisionACL(ctx, selectedDeviceInfo, acl, aclVersion, resultCallback);
}
/**
* this function sends ACL information to resource.
* This function sends ACL information to resource.
*
* @param[in] ctx Application context would be returned in result callback.
* @param[in] selectedDeviceInfo Selected target device.
* @param[in] acl ACL to provision.
* @param[in] resultCallback callback provided by API user, callback will be called when provisioning
request recieves a response from resource server.
* request recieves a response from resource server.
* @return OC_STACK_OK in case of success and other value otherwise.
*/
OCStackResult OCProvisionACL2(void* ctx, const OCProvisionDev_t *selectedDeviceInfo, OicSecAcl_t *acl,
......@@ -1503,6 +1523,26 @@ OCStackResult OCSaveOwnCertChain(const char* cert, const char* key, uint16_t *cr
return SRPSaveOwnCertChain(&ownCert, &ownKey, credId);
}
/**
* Function to save own role certificate into Cred of SVR.
*
* @param[in] cert own role certificate to be saved in Cred of SVR.
* @param[out] credId CredId of saved trust certificate chain in Cred of SVR.
* @return OC_STACK_OK in case of success and other value otherwise.
*
* @note The certificate public key must be the same as public key in the identity
* certificate (installed by OCSaveOwnCertChain).
*/
OCStackResult OCSaveOwnRoleCert(const char* cert, uint16_t *credId)
{
OicSecKey_t ownCert = { 0 };
ownCert.data = (uint8_t*)cert;
ownCert.len = strlen(cert) + 1;
ownCert.encoding = OIC_ENCODING_PEM;
return SRPSaveOwnRoleCert(&ownCert, credId);
}
/**
* function to register notifier for Trustcertchain change.
*
......
......@@ -49,6 +49,7 @@
#include "utlist.h"
#include "ocpayload.h"
#include "srmutility.h"
#include "certhelpers.h"
#ifdef __WITH_DTLS__
#include "crlresource.h"
......@@ -115,6 +116,15 @@ struct GetRolesData {
size_t numOfResults; /**< Number of results in result array.**/
};
typedef struct AssertRolesData AssertRolesData_t;
struct AssertRolesData {
void *ctx; /**< User-provided context **/
const OCProvisionDev_t *deviceInfo; /**< Pointer to PMDevInfo_t.**/
OCProvisionResultCB resultCallback; /**< Pointer to result callback.**/
OCProvisionResult_t *resArr; /**< Result array.**/
size_t numOfResults; /**< Number of results in result array.**/
};
/**
* Structure to carry PCONF provision API data to callback.
*/
......@@ -322,7 +332,7 @@ static OCStackResult provisionCredentials(const OicSecCred_t *cred,
OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
if (!secPayload)
{
OIC_LOG(ERROR, TAG, "Failed to memory allocation");
OIC_LOG(ERROR, TAG, "Failed to allocate memory");
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
......@@ -460,7 +470,7 @@ static OCStackApplicationResult provisionCertCB(void *ctx, OCDoHandle UNUSED,
return OC_STACK_DELETE_TRANSACTION;
}
static OCStackApplicationResult provisionIdentityCertCB(void *ctx, OCDoHandle UNUSED,
static OCStackApplicationResult provisionCertificateCB(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse)
{
// Just call the callback provided to SRProvisionCredentials
......@@ -514,7 +524,7 @@ OCStackResult SRPProvisionTrustCertChain(void *ctx, OicSecCredType_t type, uint1
if(!secPayload)
{
DeleteCredList(trustCertChainCred);
OIC_LOG(ERROR, TAG, "Failed to memory allocation");
OIC_LOG(ERROR, TAG, "Failed to allocate memory");
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
......@@ -664,8 +674,11 @@ static OCStackResult saveCertChain(OicSecKey_t * cert, OicSecKey_t * key, uint16
OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
VERIFY_NOT_NULL_RETURN(TAG, cert, ERROR, OC_STACK_INVALID_PARAM);
VERIFY_NOT_NULL_RETURN(TAG, cert->data, ERROR, OC_STACK_INVALID_PARAM);
VERIFY_NOT_NULL_RETURN(TAG, key, ERROR, OC_STACK_INVALID_PARAM);
if (key != NULL)
{
/* Key is optional. */
VERIFY_NOT_NULL_RETURN(TAG, key->data, ERROR, OC_STACK_INVALID_PARAM);
}
VERIFY_NOT_NULL_RETURN(TAG, credId, ERROR, OC_STACK_INVALID_PARAM);
VERIFY_NOT_NULL_RETURN(TAG, usage, ERROR, OC_STACK_INVALID_PARAM);
......@@ -679,7 +692,7 @@ static OCStackResult saveCertChain(OicSecKey_t * cert, OicSecKey_t * key, uint16
res = GetDoxmDeviceID(&cred->subject);
if (OC_STACK_OK != res)
{
OIC_LOG(ERROR, TAG, "Cann't get the device id(GetDoxmDeviceID)");
OIC_LOG(ERROR, TAG, "Can't get the device id(GetDoxmDeviceID)");
DeleteCredList(cred);
return res;
}
......@@ -697,12 +710,15 @@ static OCStackResult saveCertChain(OicSecKey_t * cert, OicSecKey_t * key, uint16
publicData->len = cert->len;
publicData->encoding = cert->encoding;
if (key != NULL)
{
OicSecKey_t *privateData = &cred->privateData;
privateData->data = (uint8_t *)OICCalloc(1, key->len);
VERIFY_NOT_NULL_RETURN(TAG, privateData->data, ERROR, OC_STACK_NO_MEMORY);
memcpy(privateData->data, key->data, key->len);
privateData->len = key->len;
privateData->encoding = key->encoding;
}
res = AddCredential(cred);
if(res != OC_STACK_OK)
......@@ -722,6 +738,155 @@ OCStackResult SRPSaveOwnCertChain(OicSecKey_t * cert, OicSecKey_t * key, uint16_
return saveCertChain(cert, key, credId, PRIMARY_CERT);
}
OCStackResult SRPSaveOwnRoleCert(OicSecKey_t * cert, uint16_t *credId)
{
return saveCertChain(cert, NULL, credId, ROLE_CERT);
}
/**
* Callback handler of SRPAssertRoles.
*
* @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 SRPAssertRolesCB(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse)
{
OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
OC_UNUSED(UNUSED);
VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
AssertRolesData_t *assertRolesData = (AssertRolesData_t*)ctx;
OCProvisionResultCB resultCallback = assertRolesData->resultCallback;
bool hasError = true;
if (clientResponse && (OC_STACK_RESOURCE_CHANGED == clientResponse->result))
{
hasError = false;
}
else
{
OIC_LOG_V(ERROR, TAG, "%s : NULL client response, or response indicating failure (%d)", __func__);
}
((OCProvisionResultCB)(resultCallback))(assertRolesData->ctx, assertRolesData->numOfResults,
assertRolesData->resArr,
hasError);
OICFree(assertRolesData->resArr);
OICFree(assertRolesData);
OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
return OC_STACK_DELETE_TRANSACTION;
}
OCStackResult SRPAssertRoles(void *ctx, const OCProvisionDev_t *device, OCProvisionResultCB resultCallback)
{
OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
VERIFY_NOT_NULL_RETURN(TAG, device, ERROR, OC_STACK_INVALID_PARAM);
VERIFY_NOT_NULL_RETURN(TAG, resultCallback, ERROR, OC_STACK_INVALID_CALLBACK);
OC_UNUSED(device);
OC_UNUSED(ctx);
OC_UNUSED(resultCallback);
/* 1. Retrieve all our stored role certificates */
RoleCertChain_t *roles = NULL;
OCStackResult res = GetAllRoleCerts(&roles);
if (res != OC_STACK_OK)
{
OIC_LOG(ERROR, TAG, "Failed to retrieve role certs");
return OC_STACK_ERROR;
}
if (roles == NULL)
{
OIC_LOG(ERROR, TAG, "Can't assert roles, no role certs installed");
return OC_STACK_ERROR;
}
/* 2. Encode them for transfer */
OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
if (!secPayload)
{
OIC_LOG(ERROR, TAG, "Failed to allocate memory");
FreeRoleCertChainList(roles);
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
if(OC_STACK_OK != RolesToCBORPayload(roles, &secPayload->securityData, &secPayload->payloadSize))
{
OCPayloadDestroy((OCPayload *)secPayload);
OIC_LOG(ERROR, TAG, "RolesToCBORPayload failed");
FreeRoleCertChainList(roles);
return OC_STACK_NO_MEMORY;
}
OIC_LOG(DEBUG, TAG, "Created payload for asserting roles:");
OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
FreeRoleCertChainList(roles);
/* 3. Post roles to the roles resource on the server */
char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = { 0 };
if (!PMGenerateQuery(true,
device->endpoint.addr,
device->securePort,
device->connType,
query, sizeof(query), OIC_RSRC_ROLES_URI))
{
OCPayloadDestroy((OCPayload *)secPayload);
OIC_LOG(ERROR, TAG, "DeviceDiscoveryHandler : Failed to generate query");
return OC_STACK_ERROR;
}
OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
OCCallbackData cbData = { .context = NULL,.cb = NULL,.cd = NULL };
cbData.cb = &SRPAssertRolesCB;
AssertRolesData_t *assertRolesData = (AssertRolesData_t *)OICCalloc(1, sizeof(AssertRolesData_t));
if (assertRolesData == NULL)
{
OCPayloadDestroy((OCPayload *)secPayload);
OIC_LOG(ERROR, TAG, "Unable to allocate memory");
return OC_STACK_NO_MEMORY;
}
assertRolesData->deviceInfo = device;
assertRolesData->resultCallback = resultCallback;
assertRolesData->numOfResults = 0;
assertRolesData->ctx = ctx;
int noOfRiCalls = 1;
assertRolesData->resArr = (OCProvisionResult_t*)OICCalloc(noOfRiCalls, sizeof(OCProvisionResult_t));
if (assertRolesData->resArr == NULL)
{
OICFree(assertRolesData);
OCPayloadDestroy((OCPayload *)secPayload);
OIC_LOG(ERROR, TAG, "Unable to allocate memory");
return OC_STACK_NO_MEMORY;
}
cbData.context = (void *)assertRolesData;
cbData.cd = NULL;
OCMethod method = OC_REST_POST;
OCDoHandle handle = NULL;
OIC_LOG(DEBUG, TAG, "Sending roles to server");
OCStackResult ret = OCDoRequest(&handle, method, query,
&device->endpoint, (OCPayload*)secPayload,
device->connType, OC_HIGH_QOS, &cbData, NULL, 0);
if (ret != OC_STACK_OK)
{
OICFree(assertRolesData->resArr);
OICFree(assertRolesData);
OIC_LOG_V(ERROR, TAG, "%s OCDoRequest failed", __func__);
}
OCPayloadDestroy((OCPayload *)secPayload);
OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
VERIFY_SUCCESS_RETURN(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
return ret;
}
#endif // __WITH_DTLS__ || __WITH_TLS__
OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t keySize,
......@@ -855,11 +1020,19 @@ OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t k
VERIFY_NOT_NULL_RETURN(TAG, cred, ERROR, OC_STACK_ERROR);
cred->publicData.encoding = OIC_ENCODING_PEM;
if (OCInternalIsValidRoleCertificate(deviceCert.data, deviceCert.len, NULL, NULL) == OC_STACK_OK)
{
cred->credUsage = OICStrdup(ROLE_CERT);
}
else
{
cred->credUsage = OICStrdup(PRIMARY_CERT);
}
/* Create credential data (used by the response handler provisionIdentityCertCB and freed there) */
/* 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)
if ((NULL == credData) || (NULL == cred->credUsage))
{
DeleteCredList(cred);
OIC_LOG(ERROR, TAG, "Memory allocation problem");
......@@ -874,8 +1047,8 @@ OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t k
credData->resultCallback = resultCallback;
credData->resArr = NULL;
/* Note: the callback of type OCClientResponseHandler, thin wrapper that calls resultCallback */
OCStackResult res = provisionCredentials(cred, pDev1, credData, &provisionIdentityCertCB);
/* 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);
......@@ -990,7 +1163,7 @@ OCStackResult SRPProvisionACL(void *ctx, const OCProvisionDev_t *selectedDeviceI
OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
if(!secPayload)
{
OIC_LOG(ERROR, TAG, "Failed to memory allocation");
OIC_LOG(ERROR, TAG, "Failed to allocate memory");
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
......@@ -1146,7 +1319,7 @@ OCStackResult SRPProvisionDirectPairing(void *ctx, const OCProvisionDev_t *selec
OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
if(!secPayload)
{
OIC_LOG(ERROR, TAG, "Failed to memory allocation");
OIC_LOG(ERROR, TAG, "Failed to allocate memory");
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
......@@ -2074,7 +2247,7 @@ OCStackResult SRPRemoveDevice(void* ctx, unsigned short waitTimeForOwnedDeviceDi
removeData = (RemoveData_t*)OICCalloc(1, sizeof(RemoveData_t));
if (!removeData)