* @param cred is the pointer to instance of OicSecCred_t structure.
* @param cborPayload is the CBOR converted value.
* @param cborSize is the size of the CBOR.
+ * @param secureFlag shows fill or not private key.
*
* @return ::OC_STACK_OK if conversion is successful, else ::OC_STACK_ERROR if unsuccessful.
*/
OCStackResult CredToCBORPayload(const OicSecCred_t* cred, uint8_t **cborPayload,
- size_t *cborSize);
+ size_t *cborSize, int secureFlag);
/**
* This function generates the bin credential data.
*/
OCStackResult SRPProvisionACL(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
OicSecAcl_t *acl, OCProvisionResultCB resultCallback);
-
+
+/**
+ * API to request CRED information to resource.
+ *
+ * @param[in] selectedDeviceInfo Selected target device.
+ * @param[in] resultCallback callback provided by API user, callback will be called when
+ * provisioning request recieves a response from resource server.
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult SRPGetCredResource(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
+ OCProvisionResultCB resultCallback);
+
#ifdef __WITH_X509__
/**
* API to send CRL information to resource.
OCProvisionResultCB resultCallback);\r
\r
/**\r
+ * this function requests CRED information to resource.\r
+ *
+ * @param[in] ctx Application context would be returned in result callback.
+ * @param[in] selectedDeviceInfo Selected target device.\r
+ * @param[in] resultCallback callback provided by API user, callback will be called when provisioning
+ request recieves a response from resource server.
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult OCGetCredResource(void* ctx, const OCProvisionDev_t *selectedDeviceInfo,\r
+ OCProvisionResultCB resultCallback);\r
+\r
+/**\r
* this function sends Direct-Pairing Configuration to a device.\r
*\r
* @param[in] ctx Application context would be returned in result callback.\r
#define _34_CHECK_LINK_STATUS_ 34
#define _40_UNLINK_PAIR_DEVS_ 40
#define _50_REMOVE_SELEC_DEV_ 50
+#define _60_GET_CRED_ 60
#define _99_EXIT_PRVN_CLT_ 99
#define ACL_RESRC_MAX_NUM 16
g_doneCB = true;
}
+static void getCredCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
+{
+ if(!hasError)
+ {
+ OIC_LOG_V(INFO, TAG, "getCredCB SUCCEEDED - ctx: %s", (char*) ctx);
+ }
+ else
+ {
+ OIC_LOG_V(ERROR, TAG, "getCredCB FAILED - ctx: %s", (char*) ctx);
+ printResultList((const OCProvisionResult_t*) arr, nOfRes);
+ }
+ g_doneCB = true;
+}
+
static void provisionDPCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
{
if(!hasError)
return -1;
}
+static int getCred(void)
+{
+ // check |own_list| for checking selected link status on PRVN DB
+ if(!g_own_list || 1>g_own_cnt)
+ {
+ printf(" > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
+ printf(" > Please Register Unowned Devices first, with [20] Menu\n");
+ return 0; // normal case
+ }
+
+ // select device for checking selected link status on PRVN DB
+ int dev_num = 0;
+ for( ; ; )
+ {
+ printf(" > Enter Device Number, for Checking Linked Status on PRVN DB: ");
+ for(int ret=0; 1!=ret; )
+ {
+ ret = scanf("%d", &dev_num);
+ for( ; 0x20<=getchar(); ); // for removing overflow garbages
+ // '0x20<=code' is character region
+ }
+ if(0<dev_num && g_own_cnt>=dev_num)
+ {
+ break;
+ }
+ printf(" Entered Wrong Number. Please Enter Again\n");
+ }
+
+ // call |getDevInst| API actually
+ // calling this API with callback actually acts like blocking
+ // for error checking, the return value saved and printed
+ g_doneCB = false;
+ OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
+ if(!dev)
+ {
+ OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
+ goto PVACL_ERROR;
+ }
+ OCStackResult rst = OCGetCredResource((void*) g_ctx, dev, getCredCB);
+ if(OC_STACK_OK != rst)
+ {
+ OIC_LOG_V(ERROR, TAG, "OCGetCred API error: %d", rst);
+ goto PVACL_ERROR;
+ }
+ if(waitCallbackRet()) // input |g_doneCB| flag implicitly
+ {
+ OIC_LOG(ERROR, TAG, "OCGetCredResource callback error");
+ goto PVACL_ERROR;
+ }
+
+ // display the result of get credential
+ printf(" > Get Cred SUCCEEDED\n");
+
+ return 0;
+
+PVACL_ERROR:
+ return -1;
+}
+
static int unlinkPairwise(void)
{
// check |own_list| for unlinking pairwise devices
printf("** [E] REMOVE THE SELECTED DEVICE\n");
printf("** 50. Remove the Selected Device\n\n");
+ printf("** [F] GET SECURITY RESOURCE FOR DEBUGGING ONLY\n");
+ printf("** 60. Get the Credential resources of the Selected Device\n\n");
+
printf("** [F] EXIT PROVISIONING CLIENT\n");
printf("** 99. Exit Provisionong Client\n\n");
OIC_LOG(ERROR, TAG, "_50_REMOVE_SELEC_DEV_: error");
}
break;
+ case _60_GET_CRED_:
+ if(getCred())
+ {
+ OIC_LOG(ERROR, TAG, "_60_GET_CRED_: error");
+ }
+ break;
case _99_EXIT_PRVN_CLT_:
goto PMCLT_ERROR;
default:
}
/**
+ * this function requests CRED information to resource.
+ *
+ * @param[in] ctx Application context would be returned in result callback.
+ * @param[in] selectedDeviceInfo Selected target device.
+ * @param[in] resultCallback callback provided by API user, callback will be called when provisioning
+ request recieves a response from resource server.
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult OCGetCredResource(void* ctx, const OCProvisionDev_t *selectedDeviceInfo,
+ OCProvisionResultCB resultCallback)
+{
+ return SRPGetCredResource(ctx, selectedDeviceInfo, resultCallback);
+}
+
+/**
* function to provision credential to devices.
*
* @param[in] ctx Application context would be returned in result callback.
newCredential.publicData.data = NULL;
newCredential.publicData.len = 0;
#endif
-
+ int secureFlag = 0;
//Send owner credential to new device : PUT /oic/sec/cred [ owner credential ]
- if (OC_STACK_OK != CredToCBORPayload(&newCredential, &secPayload->securityData, &secPayload->payloadSize))
+ if (OC_STACK_OK != CredToCBORPayload(&newCredential, &secPayload->securityData,
+ &secPayload->payloadSize, secureFlag))
{
OICFree(secPayload);
OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
int numOfResults; /**< Number of results in result array.**/
};
+// Structure to carry get security resource APIs data to callback.
+typedef struct GetSecData GetSecData_t;
+struct GetSecData {
+ void *ctx;
+ const OCProvisionDev_t *deviceInfo; /**< Pointer to PMDevInfo_t.**/
+ OCProvisionResultCB resultCallback; /**< Pointer to result callback.**/
+ OCProvisionResult_t *resArr; /**< Result array.**/
+ int numOfResults; /**< Number of results in result array.**/
+};
+
/**
* Structure to carry PCONF provision API data to callback.
*/
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
- OCStackResult res = CredToCBORPayload(cred, &secPayload->securityData, &secPayload->payloadSize);
+ int secureFlag = 0;
+ OCStackResult res = CredToCBORPayload(cred, &secPayload->securityData,
+ &secPayload->payloadSize, secureFlag);
if((OC_STACK_OK != res) && (NULL == secPayload->securityData))
{
OCPayloadDestroy((OCPayload *)secPayload);
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
+ int secureFlag = 0;
OCStackResult res = CredToCBORPayload(cred, &secPayload->securityData,
- &secPayload->payloadSize);
+ &secPayload->payloadSize, secureFlag);
if ((OC_STACK_OK != res) || (NULL == secPayload->securityData))
{
OIC_LOG(INFO, TAG, "OUT ERROR case SRPRemoveDevice");
return res;
}
+
+/**
+ * Internal Function to store results in result array during GetCredResourceCB.
+ */
+static void registerResultForGetCredResourceCB(GetSecData_t *GetSecData,
+ OCStackResult stackresult)
+{
+ OIC_LOG_V(INFO, TAG, "Inside registerResultForGetCredResourceCB "
+ "GetSecData->numOfResults is %d\n", GetSecData->numOfResults);
+ memcpy(GetSecData->resArr[(GetSecData->numOfResults)].deviceId.id,
+ GetSecData->deviceInfo->doxm->deviceID.id, UUID_LENGTH);
+ GetSecData->resArr[(GetSecData->numOfResults)].res = stackresult;
+ ++(GetSecData->numOfResults);
+}
+
+/**
+ * Callback handler of SRPGetCredResource.
+ *
+ * @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 SRPGetCredResourceCB(void *ctx, OCDoHandle UNUSED,
+ OCClientResponse *clientResponse)
+{
+ OIC_LOG_V(INFO, TAG, "Inside SRPGetCredResourceCB.");
+ (void)UNUSED;
+ VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+ GetSecData_t *GetSecData = (GetSecData_t*)ctx;
+ OCProvisionResultCB resultCallback = GetSecData->resultCallback;
+
+ if (clientResponse)
+ {
+ if(OC_STACK_OK == clientResponse->result)
+ {
+ uint8_t *payload = ((OCSecurityPayload*)clientResponse->payload)->securityData;
+ size_t size = ((OCSecurityPayload*)clientResponse->payload)->payloadSize;
+
+ OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
+
+ registerResultForGetCredResourceCB(GetSecData, OC_STACK_OK);
+ ((OCProvisionResultCB)(resultCallback))(GetSecData->ctx, GetSecData->numOfResults,
+ GetSecData->resArr,
+ false);
+ OICFree(GetSecData->resArr);
+ OICFree(GetSecData);
+
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ }
+ registerResultForGetCredResourceCB(GetSecData, OC_STACK_OK);
+ ((OCProvisionResultCB)(resultCallback))(GetSecData->ctx, GetSecData->numOfResults,
+ GetSecData->resArr,
+ false);
+ OIC_LOG_V(ERROR, TAG, "SRPGetCredResourceCB received Null clientResponse");
+ OICFree(GetSecData->resArr);
+ OICFree(GetSecData);
+
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+
+OCStackResult SRPGetCredResource(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
+ OCProvisionResultCB resultCallback)
+{
+ VERIFY_NON_NULL(TAG, selectedDeviceInfo, ERROR, OC_STACK_INVALID_PARAM);
+ VERIFY_NON_NULL(TAG, resultCallback, ERROR, OC_STACK_INVALID_CALLBACK);
+
+ char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+ if(!PMGenerateQuery(true,
+ selectedDeviceInfo->endpoint.addr,
+ selectedDeviceInfo->securePort,
+ selectedDeviceInfo->connType,
+ query, sizeof(query), OIC_RSRC_CRED_URI))
+ {
+ OIC_LOG(ERROR, TAG, "SRPGetCredResource : 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 = &SRPGetCredResourceCB;
+ GetSecData_t* GetSecData = (GetSecData_t*)OICCalloc(1, sizeof(GetSecData_t));
+ if (NULL == GetSecData)
+ {
+ OIC_LOG(ERROR, TAG, "Unable to allocate memory");
+ return OC_STACK_NO_MEMORY;
+ }
+ GetSecData->deviceInfo = selectedDeviceInfo;
+ GetSecData->resultCallback = resultCallback;
+ GetSecData->numOfResults=0;
+ GetSecData->ctx = ctx;
+
+ int noOfRiCalls = 1;
+ GetSecData->resArr = (OCProvisionResult_t*)OICCalloc(noOfRiCalls, sizeof(OCProvisionResult_t));
+ if (NULL == GetSecData->resArr)
+ {
+ OICFree(GetSecData);
+ OIC_LOG(ERROR, TAG, "Unable to allocate memory");
+ return OC_STACK_NO_MEMORY;
+ }
+ cbData.context = (void *)GetSecData;
+ cbData.cd = NULL;
+ OCMethod method = OC_REST_GET;
+ OCDoHandle handle = NULL;
+ OIC_LOG(DEBUG, TAG, "Sending Get Cred to resource server");
+ OCStackResult ret = OCDoResource(&handle, method, query, NULL, NULL,
+ selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG(ERROR, TAG, "OCStack resource error");
+ OICFree(GetSecData->resArr);
+ OICFree(GetSecData);
+ }
+ VERIFY_SUCCESS(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
+ OIC_LOG(DEBUG, TAG, "OUT SRPGetCredResource");
+
+ return OC_STACK_OK;
+}
+
+
}
OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
- size_t *cborSize)
+ size_t *cborSize, int secureFlag)
{
if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
{
mapSize++;
}
#endif /* __WITH_X509__ */
- if (cred->privateData.data)
+ if (!secureFlag && cred->privateData.data)
{
mapSize++;
}
}
#endif /*__WITH_X509__*/
//PrivateData -- Not Mandatory
- if(cred->privateData.data)
+ if(!secureFlag && cred->privateData.data)
{
CborEncoder privateMap;
const size_t privateMapSize = 2;
// Since the allocated initial memory failed, double the memory.
cborLen += encoder.ptr - encoder.end;
cborEncoderResult = CborNoError;
- ret = CredToCBORPayload(credS, cborPayload, &cborLen);
+ ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
*cborSize = cborLen;
}
{
uint8_t *payload = NULL;
size_t size = 0;
- OCStackResult res = CredToCBORPayload(cred, &payload, &size);
+ int secureFlag = 0;
+ OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
if ((OC_STACK_OK == res) && payload)
{
if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
return ret;
}
+/**
+ * The entity handler determines how to process a GET request.
+ */
+static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
+{
+ OIC_LOG(INFO, TAG, "HandleGetRequest processing GET request");
+
+ // Convert Cred data into CBOR for transmission
+ size_t size = 0;
+ uint8_t *payload = NULL;
+ int secureFlag = 1;
+
+ const OicSecCred_t *cred = gCred;
+ OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
+
+ // A device should always have a default cred. Therefore, payload should never be NULL.
+ OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
+
+ // Send response payload to request originator
+ if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size))
+ {
+ ehRet = OC_EH_ERROR;
+ OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePstatGetRequest");
+ }
+ OICFree(payload);
+ return ehRet;
+}
+
static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
{
OCEntityHandlerResult ret = OC_EH_ERROR;
switch (ehRequest->method)
{
case OC_REST_GET:
- ret = OC_EH_FORBIDDEN;
+ ret = HandleGetRequest(ehRequest);;
break;
case OC_REST_PUT:
ret = HandlePutRequest(ehRequest);
OCStackResult ret = OC_STACK_ERROR;
uint8_t *cborPayload = NULL;
size_t size = 0;
+ int secureFlag = 0;
OicUuid_t prevId = {.id={0}};
if(NULL == newROwner)
memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
- ret = CredToCBORPayload(gCred, &cborPayload, &size);
+ ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRED_NAME);
//printf("CRED json : \n%s\n", cJSON_PrintUnformatted(value));
size_t credCborSize = 0;
+ int secureFlag = 0;
if (NULL != value)
{
OicSecCred_t *cred = JSONToCredBin(jsonStr);
VERIFY_NON_NULL(TAG, cred, FATAL);
- ret = CredToCBORPayload(cred, &credCbor, &credCborSize);
+ ret = CredToCBORPayload(cred, &credCbor, &credCborSize, secureFlag);
if(OC_STACK_OK != ret)
{
OIC_LOG (ERROR, TAG, "Failed converting Cred to Cbor Payload");
ASSERT_TRUE(NULL != cred);
uint8_t *payload = NULL;
size_t size = 0;
- EXPECT_EQ(OC_STACK_OK, CredToCBORPayload(cred, &payload, &size));
+ int secureFlag = 0;
+ EXPECT_EQ(OC_STACK_OK, CredToCBORPayload(cred, &payload, &size, secureFlag));
if (!payload)
{
DeleteCredList(cred);
TEST(CredResourceTest, CredToCBORPayloadNULL)
{
+ int secureFlag = 0;
OicSecCred_t *cred = getCredList();
- EXPECT_EQ(OC_STACK_INVALID_PARAM, CredToCBORPayload(NULL, NULL, 0));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CredToCBORPayload(NULL, NULL, 0, secureFlag));
size_t size = 0;
uint8_t *cborPayload = (uint8_t *) OICCalloc(1, 10);
if (!cborPayload)
DeleteCredList(cred);
}
ASSERT_TRUE(NULL != cborPayload);
- EXPECT_EQ(OC_STACK_INVALID_PARAM, CredToCBORPayload(cred, &cborPayload, &size));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CredToCBORPayload(cred, &cborPayload, &size, secureFlag));
OICFree(cborPayload);
cborPayload = NULL;
- EXPECT_EQ(OC_STACK_INVALID_PARAM, CredToCBORPayload(NULL, &cborPayload, &size));
- EXPECT_EQ(OC_STACK_INVALID_PARAM, CredToCBORPayload(cred, &cborPayload, 0));
- EXPECT_EQ(OC_STACK_INVALID_PARAM, CredToCBORPayload(cred, NULL, &size));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CredToCBORPayload(NULL, &cborPayload, &size,secureFlag));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CredToCBORPayload(cred, &cborPayload, 0, secureFlag));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CredToCBORPayload(cred, NULL, &size, secureFlag));
DeleteCredList(cred);
}
{
uint8_t* payload = NULL;
size_t size = 0;
+ int secureFlag = 0;
OicSecCred_t *cred = getCredList();
- EXPECT_EQ(OC_STACK_OK, CredToCBORPayload(cred, &payload, &size));
+ EXPECT_EQ(OC_STACK_OK, CredToCBORPayload(cred, &payload, &size, secureFlag));
if (!payload)
{
DeleteCredList(cred);
uint8_t *payload = NULL;
size_t size = 0;
- EXPECT_EQ(OC_STACK_OK, CredToCBORPayload(cred1, &payload, &size));
+ int secureFlag = 0;
+ EXPECT_EQ(OC_STACK_OK, CredToCBORPayload(cred1, &payload, &size, secureFlag));
DeleteCredList(cred1);
ASSERT_TRUE(NULL != payload);
DeleteCredList(cred2);
}
+TEST(CredResourceTest, CBORPayloadToCredSecureVALID)
+{
+ OicSecCred_t *cred1 = getCredList();
+ ASSERT_TRUE(NULL != cred1);
+ cred1->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
+ ASSERT_TRUE(NULL != cred1->privateData.data);
+ cred1->privateData.len = OWNER_PSK_LENGTH_128;
+
+ uint8_t *payload = NULL;
+ size_t size = 0;
+ int secureFlag = 1;
+ EXPECT_EQ(OC_STACK_OK, CredToCBORPayload(cred1, &payload, &size, secureFlag));
+
+ ASSERT_TRUE(NULL != payload);
+
+ OicSecCred_t *cred2 = NULL;
+ EXPECT_EQ(OC_STACK_OK, CBORPayloadToCred(payload, size, &cred2));
+ ASSERT_TRUE(cred2 != NULL);
+ ASSERT_TRUE(NULL == cred2->privateData.data);
+ ASSERT_TRUE(0 == cred2->privateData.len);
+
+ OICFree(payload);
+
+ DeleteCredList(cred1);
+ DeleteCredList(cred2);
+}
+
TEST(CredResourceTest, CBORPayloadToCredNULL)
{
OicSecCred_t *cred = NULL;