Commit 7d7fe55e authored by Greg Zaverucha's avatar Greg Zaverucha Committed by Nathan Heldt-Sheller

[IOT-1952] Assert roles automatically

- Change OCDoRequest to assert role certificates before the first
secure request to a server.

- Move role assertion code out of provisioning to security, so that
ocstack can call it without including all provisioning code. Create
a public API for asserting role certificates OCAssertRoles. Role
assertion code is in new files ocsecurity.c/h

- Revise scenario tests accordingly.

Other changes in this commit:
- Rename a macro "OPTIONAL" in cloud samples since this is defined
in a standard Windows header and causing a build break.

- Fix the --onetest command line option to provisioningTest.py

Change-Id: I915d321bfff0bfd00add3298b07865b0963d9f14
Signed-off-by: default avatarGreg Zaverucha <gregz@microsoft.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/18833Tested-by: default avatarjenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: default avatarKevin Kane <kkane@microsoft.com>
Reviewed-by: default avatarDan Mihai <Daniel.Mihai@microsoft.com>
Reviewed-by: Nathan Heldt-Sheller's avatarNathan Heldt-Sheller <nathan.heldt-sheller@intel.com>
parent e1dbe04e
......@@ -67,9 +67,9 @@ typedef int (*CAgetPskCredentialsHandler)(CADtlsPskCredType_t type,
uint8_t *result, size_t result_length);
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
#ifdef MULTIPLE_OWNER
/**
* API to get a secure connected peer information
* API to get security information about a connected peer
*
* @param[in] peer peer information includs IP address and port.
* @param[out] sep copy of secure endpoint info
......@@ -77,7 +77,6 @@ typedef int (*CAgetPskCredentialsHandler)(CADtlsPskCredType_t type,
* @return CA_STATUS_OK on success; other error otherwise
*/
CAResult_t CAGetSecureEndpointData(const CAEndpoint_t *peer, CASecureEndpoint_t *sep);
#endif //MULTIPLE_OWNER
/**
* Adds a bit to the attributes field of a secure endpoint.
......
......@@ -138,7 +138,7 @@ void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHand
}
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
#ifdef MULTIPLE_OWNER
CAResult_t CAGetSecureEndpointData(const CAEndpoint_t *peer, CASecureEndpoint_t *sep)
{
OIC_LOG(DEBUG, TAG, "IN CAGetSecurePeerInfo");
......@@ -152,7 +152,6 @@ CAResult_t CAGetSecureEndpointData(const CAEndpoint_t *peer, CASecureEndpoint_t
OIC_LOG(DEBUG, TAG, "OUT CAGetSecurePeerInfo");
return GetCASecureEndpointData(peer, sep);
}
#endif //MULTIPLE_OWNER
bool CASetSecureEndpointAttribute(const CAEndpoint_t* peer, uint32_t attribute)
{
......
......@@ -128,6 +128,7 @@ if libocsrm_env.get('SECURED') == '1':
libocsrm_src = libocsrm_src + [OCSRM_SRC + 'certhelpers.c', OCSRM_SRC + 'occertutility.c']
libocsrm_src = libocsrm_src + [OCSRM_SRC + 'csrresource.c']
libocsrm_src = libocsrm_src + [OCSRM_SRC + 'rolesresource.c']
libocsrm_src = libocsrm_src + [OCSRM_SRC + 'ocsecurity.c']
if target_os in ['windows', 'msys_nt']:
libocsrm_src = libocsrm_src + [OCSRM_SRC + 'strptime.c']
......
//******************************************************************
//
// Copyright 2017 Microsoft
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//******************************************************************
#if defined(__WITH_TLS__) || defined(__WITH_DTLS__)
#ifndef OCSECURITY_H_
#define OCSECURITY_H_
#include "cacommon.h"
#include "octypes.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Callback function used when calling OCAssertRoles
*
* @param[in] ctx Context string used by callback in debug output
* @param[out] hasError Set to true if the asserting roles succeeded
*/
typedef void(*OCAssertRolesCB)(void* ctx, bool hasError);
/**
* 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 to resultCallback
* @param[in] devAddr 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. If no role certificates
* are installed, the error code OC_STACK_INCONSISTENT_DB is returned.
*
* @note The port field of the devAddr parameter MUST contain the secure port of the peer.
*
*/
OCStackResult OCAssertRoles(void *ctx, const OCDevAddr *devAddr, OCAssertRolesCB resultCallback);
#ifdef __cplusplus
}
#endif
#endif /* OCSECURITY_H_ */
#endif /* defined(__WITH_TLS__) || defined(__WITH_DTLS__) */
\ No newline at end of file
......@@ -168,19 +168,6 @@ OCStackResult SRPSaveOwnCertChain(OicSecKey_t * cert, OicSecKey_t * key, uint16_
*/
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.
*
......
......@@ -48,11 +48,10 @@
#include "pmtypes.h"
#include "oxmverifycommon.h"
#include "occertutility.h"
#include "ocsecurity.h"
#include "ocstackinternal.h"
#include "pmutility.h"
#include "secureresourceprovider.h" /* @todo: For SRPAssertRoles. Remove once IOT-1952 is resolved. */
#ifdef _MSC_VER
#include <io.h>
......@@ -284,17 +283,18 @@ static void provisionAclCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, b
g_doneCB = true;
}
static void assertRolesCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
static void assertRolesCB(void* ctx, bool hasError)
{
OC_UNUSED(ctx); // unused in release builds
if (!hasError)
{
OIC_LOG_V(INFO, TAG, "Asserting roles SUCCEEDED - ctx: %s", (char*)ctx);
OIC_LOG_V(INFO, TAG, "%s: Asserting roles SUCCEEDED - ctx: %s", __func__, (char*)ctx);
g_successCB = true;
}
else
{
OIC_LOG_V(ERROR, TAG, "Asserting roles FAILED - ctx: %s", (char*)ctx);
printResultList((const OCProvisionResult_t*)arr, nOfRes);
OIC_LOG_V(DEBUG, TAG, "%s: Asserting roles FAILED - ctx: %s", __func__, (char*)ctx);
g_successCB = false;
}
g_doneCB = true;
......@@ -1104,7 +1104,7 @@ static int testCertUse(int dev_num)
OicSecAcl_t* acl = NULL;
// Make sure we own at least one device to provision
if (!g_own_list || g_own_cnt == 0)
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
......@@ -1235,7 +1235,7 @@ static int testRoleProvisioning(int dev_num)
char* roleCert = NULL;
// Make sure we own at least one device to provision
if (!g_own_list || g_own_cnt == 0)
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
......@@ -1306,16 +1306,15 @@ exit:
return ret;
}
static int testRoleAssertionAndUse(int dev_num)
static int testRoleAssertion(int dev_num)
{
char* csr = NULL;
char* idCert = NULL;
char* roleCert = NULL;
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)
/* 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
......@@ -1367,7 +1366,7 @@ static int testRoleAssertionAndUse(int dev_num)
* us out. Using another UUID makes us appear as another device on the network.
*/
OicUuid_t notOurUuid;
(void) OCGenerateUuid(notOurUuid.id);
(void)OCGenerateUuid(notOurUuid.id);
ret = setupOwnCert(&notOurUuid);
if (ret != 0)
{
......@@ -1393,9 +1392,9 @@ static int testRoleAssertionAndUse(int dev_num)
}
/*
* Work around bug IOT-1927
* @todo: When that bug is resolved, remove this call and the function workAroundBug
*/
* Work around bug IOT-1927
* @todo: When that bug is resolved, remove this call and the function workAroundBug
*/
if (workAroundBug() != 0)
{
OIC_LOG_V(ERROR, TAG, "%s bug workaround failed: ", __func__);
......@@ -1403,7 +1402,7 @@ static int testRoleAssertionAndUse(int dev_num)
goto exit;
}
/* Close all secure sessions*/
/* Close all secure sessions */
if (closeAllSessions() != 0)
{
OIC_LOG_V(ERROR, TAG, "%s Failed to close sessions", __func__);
......@@ -1411,42 +1410,152 @@ static int testRoleAssertionAndUse(int dev_num)
goto exit;
}
/* Try a GET request, expect failure, we haven't asserted our role cert yet. */
ret = doGetRequest(uri, dev_num);
if (ret == 0)
/* Assert role certificate */
OCProvisionDev_t *device = NULL;
device = getDevInst(g_own_list, dev_num);
if (!device)
{
OIC_LOG_V(ERROR, TAG, "%s Get request to %s succeeded, but should have failed", __func__, uri);
OIC_LOG(ERROR, TAG, "Selected device does not exist");
ret = -1;
goto exit;
}
/* Assert our role cert. (@todo: This should be done automatically, IOT-1952) */
OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*)g_own_list, dev_num);
if (!dev)
{
OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
return -1;
}
OCDevAddr devAddr = device->endpoint;
devAddr.port = device->securePort;
g_doneCB = false;
res = SRPAssertRoles(g_ctx, dev, &assertRolesCB);
res = OCAssertRoles(g_ctx, &devAddr, assertRolesCB);
if (res != OC_STACK_OK)
{
OIC_LOG_V(ERROR, TAG, "%s Failed assert roles", __func__);
OIC_LOG_V(ERROR, TAG, "OCAssertRoles returned error %d with method", res);
ret = -1;
goto exit;
}
if (waitCallbackRet())
{
OIC_LOG(ERROR, TAG, "SRPAssertRoles callback error");
goto exit;
OIC_LOG_V(ERROR, TAG, "%s callback error", __func__);
}
if (!g_successCB)
{
OIC_LOG_V(ERROR, TAG, "%s callback completed, but failed", __func__);
ret = -1;
goto exit;
}
/* Try a get request, expect success */
exit:
OICFree(csr);
OICFree(idCert);
OICFree(roleCert);
OCDeleteACLList(acl);
return ret;
}
static int testRoleAssertionAndUse(int dev_num)
{
char* csr = NULL;
char* idCert = NULL;
char* roleCert = NULL;
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
}
/* Provision the device with the CA root, and issue it an identity cert. */
if (provisionTrustAnchor(dev_num) != 0)
{
return -1;
}
if (getCsr(dev_num, &csr) != 0)
{
return -1;
}
int ret = createCertFromCSR(g_caKeyPem, g_caCertPem, csr, NULL, NULL, &idCert);
if (ret != 0)
{
OIC_LOG_V(ERROR, TAG, "Failed to create identity certificate", __func__);
goto exit;
}
ret = provisionCert(dev_num, idCert);
if (ret != 0)
{
OIC_LOG_V(ERROR, TAG, "Failed to provision id certificate", __func__);
goto exit;
}
/* Create and provision a role-based ACL allowing ROLE1 to access '/a/led'. */
ret = createLedAcl(&acl, TEST_CERT_ROLE1, NULL);
if (ret != 0)
{
OIC_LOG_V(ERROR, TAG, "%s failed to create led ACL", __func__);
goto exit;
}
ret = provisionAcl(dev_num, acl);
if (ret != 0)
{
OIC_LOG_V(ERROR, TAG, "%s failed to provision led ACL", __func__);
goto exit;
}
/* Provision ourselves an identity and role cert.
* For the identity cert we use a random UUID, since the server has an ACE granting our UUID
* access to everything (as owner). We don't want to remove this ACE because it would lock
* us out. Using another UUID makes us appear as another device on the network.
*/
OicUuid_t notOurUuid;
(void) OCGenerateUuid(notOurUuid.id);
ret = setupOwnCert(&notOurUuid);
if (ret != 0)
{
OIC_LOG_V(ERROR, TAG, "%s Failed to self-provision a key/certificate", __func__);
goto exit;
}
ret = setupOwnRoleCert(NULL, TEST_CERT_ROLE1, NULL);
if (ret != 0)
{
OIC_LOG_V(ERROR, TAG, "%s Failed to self-provision a key/certificate", __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;
}
/*
* Work around bug IOT-1927
* @todo: When that bug is resolved, remove this call and the function workAroundBug
*/
if (workAroundBug() != 0)
{
OIC_LOG_V(ERROR, TAG, "%s bug workaround failed: ", __func__);
ret = -1;
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, role certificate will be automatically asserted */
ret = doGetRequest(uri, dev_num);
if (ret != 0)
{
......@@ -1878,6 +1987,34 @@ exit:
return ret;
}
int TestRoleAssertion()
{
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 (testRoleAssertion(1))
{
OIC_LOG(ERROR, TAG, "Failed to assert roles");
goto exit;
}
ret = 0;
exit:
shutdownProvisionClient();
return ret;
}
int TestRoleAssertionAndUse()
{
int ret = -1;
......@@ -1925,6 +2062,8 @@ int TestSymmetricRoleUse()
goto exit;
}
ret = 0;
exit:
shutdownProvisionClient();
......@@ -1953,8 +2092,10 @@ int main(int argc, char** argv)
case 4:
return TestRoleProvisioning();
case 5:
return TestRoleAssertionAndUse();
return TestRoleAssertion();
case 6:
return TestRoleAssertionAndUse();
case 7:
return TestSymmetricRoleUse();
default:
printf("%s: Invalid test number\n", argv[0]);
......
......@@ -48,7 +48,7 @@
#define INTERFACE_EXAMPLE "oic.if.baseline"
//in case of optional parameters absence should be sent NULL
#define OPTIONAL(str) (str[0] ? str : NULL)
#define OPTIONAL_PARAM(str) (str[0] ? str : NULL)
/**
* Skip special characters from stdin
......@@ -598,7 +598,7 @@ OCStackResult OCWrapperAclCreateGroup(const OCDevAddr *endPoint, OCCloudResponse
readString(gtype, sizeof(gtype), "Group type value", "Public");
readOptionalString(gmid, sizeof(gmid), "group member id value", UUID_EXAMPLE_2);
return OCCloudAclCreateGroup(NULL, gtype, OPTIONAL(gmid), endPoint, callback);
return OCCloudAclCreateGroup(NULL, gtype, OPTIONAL_PARAM(gmid), endPoint, callback);
}
OCStackResult OCWrapperAclFindMyGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
......@@ -607,7 +607,7 @@ OCStackResult OCWrapperAclFindMyGroup(const OCDevAddr *endPoint, OCCloudResponse
readOptionalString(mid, sizeof(mid), "member id value", UUID_EXAMPLE_2);
return OCCloudAclFindMyGroup(NULL, OPTIONAL(mid), endPoint, callback);
return OCCloudAclFindMyGroup(NULL, OPTIONAL_PARAM(mid), endPoint, callback);
}
OCStackResult OCWrapperAclDeleteGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
......@@ -619,7 +619,7 @@ OCStackResult OCWrapperAclDeleteGroup(const OCDevAddr *endPoint, OCCloudResponse
readOptionalString(gmid, sizeof(gmid), "group member id value", UUID_EXAMPLE_2);
return OCCloudAclDeleteGroup(NULL, gid, OPTIONAL(gmid), endPoint, callback);
return OCCloudAclDeleteGroup(NULL, gid, OPTIONAL_PARAM(gmid), endPoint, callback);
}
OCStackResult OCWrapperAclJoinToInvitedGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
......@@ -691,7 +691,7 @@ OCStackResult OCWrapperAclGroupGetInfo(const OCDevAddr *endPoint, OCCloudRespons
readOptionalString(mid, sizeof(mid), "member id value", UUID_EXAMPLE_2);
return OCCloudAclGroupGetInfo(NULL, gid, OPTIONAL(mid), endPoint, callback);
return OCCloudAclGroupGetInfo(NULL, gid, OPTIONAL_PARAM(mid), endPoint, callback);
}
OCStackResult OCWrapperAclInviteUser(const OCDevAddr *endPoint, OCCloudResponseCB callback)
......@@ -707,7 +707,7 @@ OCStackResult OCWrapperAclInviteUser(const OCDevAddr *endPoint, OCCloudResponseC
readStringArray(&midlist, MAX_ID_LENGTH, "member id list", UUID_EXAMPLE_2);
result = OCCloudAclInviteUser(NULL, OPTIONAL(uid), &gidlist, &midlist, endPoint, callback);
result = OCCloudAclInviteUser(NULL, OPTIONAL_PARAM(uid), &gidlist, &midlist, endPoint, callback);
clearStringArray(&midlist);
clearStringArray(&gidlist);
......@@ -721,7 +721,7 @@ OCStackResult OCWrapperAclGetInvitation(const OCDevAddr *endPoint, OCCloudRespon
readOptionalString(uid, sizeof(uid), "user uuid value", UUID_EXAMPLE_2);
return OCCloudAclGetInvitation(NULL, OPTIONAL(uid), endPoint, callback);
return OCCloudAclGetInvitation(NULL, OPTIONAL_PARAM(uid), endPoint, callback);
}
OCStackResult OCWrapperAclDeleteInvitation(const OCDevAddr *endPoint, OCCloudResponseCB callback)
......@@ -732,7 +732,7 @@ OCStackResult OCWrapperAclDeleteInvitation(const OCDevAddr *endPoint, OCCloudRes
readOptionalString(uid, sizeof(uid), "user uuid value", UUID_EXAMPLE_2);
readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
return OCCloudAclDeleteInvitation(NULL, OPTIONAL(uid), gid, endPoint, callback);
return OCCloudAclDeleteInvitation(NULL, OPTIONAL_PARAM(uid), gid, endPoint, callback);
}
OCStackResult OCWrapperAclCancelInvitation(const OCDevAddr *endPoint, OCCloudResponseCB callback)
......@@ -746,7 +746,7 @@ OCStackResult OCWrapperAclCancelInvitation(const OCDevAddr *endPoint, OCCloudRes
readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
readString(mid, sizeof(mid), "member id value", ID_EXAMPLE_1);
return OCCloudAclCancelInvitation(NULL, OPTIONAL(uid), gid, mid, endPoint, callback);
return OCCloudAclCancelInvitation(NULL, OPTIONAL_PARAM(uid), gid, mid, endPoint, callback);
}
OCStackResult OCWrapperAclPolicyCheck(const OCDevAddr *endPoint, OCCloudResponseCB callback)
......
......@@ -42,7 +42,7 @@ def print_environment():
### main ###
# Number of unit tests in autoprovisioningclient
NUM_TESTS = 6
NUM_TESTS = 7
usage = '''
Run end-to-end certificate tests between autoprovisioningclient and sampleserver_justworks
......@@ -63,7 +63,7 @@ parser = argparse.ArgumentParser(
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.')
parser.add_argument('--onetest', nargs='?', help= 'Run a single test, specified by number (1, ..., ' + str(NUM_TESTS) + '). By default all tests are run.')
args = parser.parse_args()
......@@ -90,6 +90,9 @@ num_failures = 0
test_range = range(1, NUM_TESTS + 1) #default to running all tests
if args.onetest:
try:
if int(args.onetest) > NUM_TESTS or int(args.onetest) < 1:
print 'Argument to --onetest out of range'
sys.exit(-1)
test_range = range(int(args.onetest), int(args.onetest) + 1)
except ValueError:
print 'invalid argument to --onetest'
......
......@@ -116,15 +116,6 @@ 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.
*/
......@@ -784,150 +775,6 @@ 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,