#include <stdlib.h>
#include <string.h>
-#include "ocstack.h"
-#include "logger.h"
#include "oic_malloc.h"
-#include "oic_string.h"
-#include "cJSON.h"
-#include "base64.h"
-#include "resourcemanager.h"
+#include "ocpayload.h"
+#include "payload_logging.h"
#include "psinterface.h"
+#include "resourcemanager.h"
#include "utlist.h"
#include "srmresourcestrings.h"
-#include "amaclresource.h"
#include "srmutility.h"
-#include <stdlib.h>
-#include <string.h>
+#include "amaclresource.h"
#define TAG "SRM-AMACL"
-OicSecAmacl_t *gAmacl = NULL;
+/** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
+ * The value of payload size is increased until reaching belox max cbor size. */
+static const uint8_t CBOR_SIZE = 255;
+
+/* Max cbor size payload. */
+static const uint16_t CBOR_MAX_SIZE = 4400;
+
+/** AMACL Map size - Number of mandatory items. */
+static const uint8_t AMACL_MAP_SIZE = 3;
+
+static OicSecAmacl_t *gAmacl = NULL;
static OCResourceHandle gAmaclHandle = NULL;
void DeleteAmaclList(OicSecAmacl_t* amacl)
}
}
-/*
- * This internal method converts AMACL data into JSON format.
- *
- * Note: Caller needs to invoke 'free' when finished using the return string.
- */
-char * BinToAmaclJSON(const OicSecAmacl_t * amacl)
+static size_t OicSecAmaclCount(const OicSecAmacl_t *secAmacl)
{
- cJSON *jsonRoot = NULL;
- char *jsonStr = NULL;
-
- if (amacl)
+ size_t size = 0;
+ for (const OicSecAmacl_t *amacl = secAmacl; amacl; amacl = amacl->next)
{
- jsonRoot = cJSON_CreateObject();
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+ size++;
+ }
+ return size;
+}
- cJSON *jsonAmaclArray = NULL;
- cJSON_AddItemToObject (jsonRoot, OIC_JSON_AMACL_NAME, jsonAmaclArray = cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonAmaclArray, ERROR);
+OCStackResult AmaclToCBORPayload(const OicSecAmacl_t *amaclS, uint8_t **cborPayload,
+ size_t *cborSize)
+{
+ if (NULL == amaclS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
- while(amacl)
- {
- char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
- uint32_t outLen = 0;
- B64Result b64Ret = B64_OK;
+ OCStackResult ret = OC_STACK_ERROR;
+ size_t cborLen = *cborSize;
+ if (0 == cborLen)
+ {
+ cborLen = CBOR_SIZE;
+ }
- cJSON *jsonAmacl = cJSON_CreateObject();
+ *cborSize = 0;
+ *cborPayload = NULL;
- // Resources -- Mandatory
- cJSON *jsonRsrcArray = NULL;
- cJSON_AddItemToObject(jsonAmacl, OIC_JSON_RESOURCES_NAME, jsonRsrcArray =
- cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonRsrcArray, ERROR);
- for (unsigned int i = 0; i < amacl->resourcesLen; i++)
- {
- cJSON_AddItemToArray(jsonRsrcArray, cJSON_CreateString(amacl->resources[i]));
- }
+ CborEncoder encoder = { {.ptr = NULL }, .end = 0 };
+ CborEncoder amaclArray = { {.ptr = NULL }, .end = 0 };
+ CborError cborEncoderResult = CborNoError;
- // Amss -- Mandatory
- cJSON *jsonAmsArray = NULL;
- cJSON_AddItemToObject(jsonAmacl, OIC_JSON_AMSS_NAME, jsonAmsArray =
- cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonAmsArray, ERROR);
- for (unsigned int i = 0; i < amacl->amssLen; i++)
- {
- outLen = 0;
+ const OicSecAmacl_t *amacl = amaclS;
+ uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
+ VERIFY_NON_NULL(TAG, outPayload, ERROR);
+ cbor_encoder_init(&encoder, outPayload, cborLen, 0);
- b64Ret = b64Encode(amacl->amss[i].id, sizeof(((OicUuid_t*) 0)->id), base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+ // Create AMACL Array
+ cborEncoderResult = cbor_encoder_create_array(&encoder, &amaclArray, OicSecAmaclCount(amacl));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding AMACL Array.");
- cJSON_AddItemToArray(jsonAmsArray, cJSON_CreateString(base64Buff));
- }
+ while (amacl)
+ {
+ CborEncoder amaclMap = { {.ptr = NULL }, .end = 0 };
+ cborEncoderResult = cbor_encoder_create_map(&amaclArray, &amaclMap, AMACL_MAP_SIZE);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding AMACL MAP.");
- // Owners -- Mandatory
- cJSON *jsonOwnrArray = NULL;
- cJSON_AddItemToObject(jsonAmacl, OIC_JSON_OWNERS_NAME, jsonOwnrArray =
- cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonOwnrArray, ERROR);
- for (unsigned int i = 0; i < amacl->ownersLen; i++)
+ // Resources -- Mandatory
+ {
+ CborEncoder resources = { {.ptr = NULL }, .end = 0};
+ cborEncoderResult = cbor_encode_text_string(&amaclMap, OIC_JSON_RESOURCES_NAME,
+ strlen(OIC_JSON_RESOURCES_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Resource Name Tag.");
+ cborEncoderResult = cbor_encoder_create_array(&amaclMap, &resources, amacl->resourcesLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Resource Name Array.");
+ for (size_t i = 0; i < amacl->resourcesLen; i++)
{
- outLen = 0;
-
- b64Ret = b64Encode(amacl->owners[i].id, sizeof(((OicUuid_t*) 0)->id), base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+ cborEncoderResult = cbor_encode_text_string(&resources, amacl->resources[i],
+ strlen(amacl->resources[i]));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Resource Name Value in Array.");
- cJSON_AddItemToArray(jsonOwnrArray, cJSON_CreateString(base64Buff));
}
-
- // Attach current amacl node to Amacl Array
- cJSON_AddItemToArray(jsonAmaclArray, jsonAmacl);
- amacl = amacl->next;
+ cborEncoderResult = cbor_encoder_close_container(&amaclMap, &resources);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Name ");
+ }
+ // Amss -- Mandatory
+ {
+ CborEncoder amss = { {.ptr = NULL }, .end = 0 };
+ cborEncoderResult = cbor_encode_text_string(&amaclMap, OIC_JSON_AMSS_NAME,
+ strlen(OIC_JSON_AMSS_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding AMSS Name Tag.");
+ cborEncoderResult = cbor_encoder_create_array(&amaclMap, &amss, amacl->amssLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding AMSS Name Array.");
+ for (size_t i = 0; i < amacl->amssLen; i++)
+ {
+ cborEncoderResult = cbor_encode_byte_string(&amss, amacl->amss[i].id,
+ sizeof(amacl->amss[i].id));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding AMSS Name Value.");
+ }
+ cborEncoderResult = cbor_encoder_close_container(&amaclMap, &amss);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing AMSS Array.");
+ }
+ // Owners -- Mandatory
+ {
+ cborEncoderResult = cbor_encode_text_string(&amaclMap, OIC_JSON_OWNERS_NAME,
+ strlen(OIC_JSON_OWNERS_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Owners Array Tag.");
+ CborEncoder owners = { {.ptr = NULL }, .end = 0};
+ cborEncoderResult = cbor_encoder_create_array(&amaclMap, &owners, amacl->ownersLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Owners Array.");
+ for (size_t i = 0; i < amacl->ownersLen; i++)
+ {
+ cborEncoderResult = cbor_encode_byte_string(&owners, (uint8_t *)amacl->owners[i].id,
+ sizeof(amacl->owners[i].id));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Owners Array Value.");
+ }
+ cborEncoderResult = cbor_encoder_close_container(&amaclMap, &owners);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Owners Array.");
}
+ cborEncoderResult = cbor_encoder_close_container(&amaclArray, &amaclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing AMACL Map.");
- jsonStr = cJSON_PrintUnformatted(jsonRoot);
+ amacl = amacl->next;
}
+ cborEncoderResult = cbor_encoder_close_container(&encoder, &amaclArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Amacl Array.");
-exit:
- if (jsonRoot)
+ if (CborNoError == cborEncoderResult)
{
- cJSON_Delete(jsonRoot);
+ *cborPayload = outPayload;
+ *cborSize = encoder.ptr - outPayload;
+ ret = OC_STACK_OK;
}
- return jsonStr;
-}
+exit:
+ if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
+ {
+ // reallocate and try again!
+ OICFree(outPayload);
+ outPayload = NULL;
+ // Since the allocated initial memory failed, double the memory.
+ cborLen += encoder.ptr - encoder.end;
+ cborEncoderResult = CborNoError;
+ ret = AmaclToCBORPayload(amaclS, cborPayload, &cborLen);
+ if (OC_STACK_OK == ret)
+ {
+ *cborSize = cborLen;
+ ret = OC_STACK_OK;
+ }
+ }
+ if (CborNoError != cborEncoderResult)
+ {
+ OICFree(outPayload);
+ outPayload = NULL;
+ *cborSize = 0;
+ *cborPayload = NULL;
+ ret = OC_STACK_ERROR;
+ }
+ return ret;
+}
-/*
- * This internal method converts JSON AMACL into binary AMACL.
- */
-OicSecAmacl_t * JSONToAmaclBin(const char * jsonStr)
+OCStackResult CBORPayloadToAmacl(const uint8_t *cborPayload, size_t size,
+ OicSecAmacl_t **secAmacl)
{
- OCStackResult ret = OC_STACK_ERROR;
- OicSecAmacl_t * headAmacl = NULL;
- OicSecAmacl_t * prevAmacl = NULL;
- cJSON *jsonRoot = NULL;
- cJSON *jsonAmaclArray = NULL;
-
- VERIFY_NON_NULL(TAG, jsonStr, ERROR);
+ if (NULL == cborPayload || NULL == secAmacl || NULL != *secAmacl)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
- jsonRoot = cJSON_Parse(jsonStr);
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+ *secAmacl = NULL;
- jsonAmaclArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_AMACL_NAME);
- VERIFY_NON_NULL(TAG, jsonAmaclArray, INFO);
+ OCStackResult ret = OC_STACK_ERROR;
- if (cJSON_Array == jsonAmaclArray->type)
+ CborValue amaclCbor = { .parser = NULL };
+ CborParser parser = { .end = NULL };
+ CborError cborFindResult = CborNoError;
+ int cborLen = size;
+ if (0 == size)
{
- int numAmacl = cJSON_GetArraySize(jsonAmaclArray);
- int idx = 0;
+ cborLen = CBOR_SIZE;
+ }
+ cbor_parser_init(cborPayload, cborLen, 0, &parser, &amaclCbor);
- VERIFY_SUCCESS(TAG, numAmacl > 0, INFO);
- do
- {
- cJSON *jsonAmacl = cJSON_GetArrayItem(jsonAmaclArray, idx);
- VERIFY_NON_NULL(TAG, jsonAmacl, ERROR);
+ OicSecAmacl_t *headAmacl = NULL;
- OicSecAmacl_t *amacl = (OicSecAmacl_t*)OICCalloc(1, sizeof(OicSecAmacl_t));
- VERIFY_NON_NULL(TAG, amacl, ERROR);
+ CborValue amaclArray = { .parser = NULL };
+ cborFindResult = cbor_value_enter_container(&amaclCbor, &amaclArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
- headAmacl = (headAmacl) ? headAmacl : amacl;
- if (prevAmacl)
- {
- prevAmacl->next = amacl;
- }
+ while (cbor_value_is_valid(&amaclArray))
+ {
+ CborValue amaclMap = { .parser = NULL };
+ cborFindResult = cbor_value_enter_container(&amaclArray, &amaclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
- size_t jsonObjLen = 0;
- cJSON *jsonObj = NULL;
+ OicSecAmacl_t *amacl = (OicSecAmacl_t *) OICCalloc(1, sizeof(*amacl));
+ VERIFY_NON_NULL(TAG, amacl, ERROR);
- // Resources -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonAmacl, OIC_JSON_RESOURCES_NAME);
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
+ while (cbor_value_is_valid(&amaclMap))
+ {
+ char *name = NULL;
+ size_t len = 0;
+ cborFindResult = cbor_value_dup_text_string(&amaclMap, &name, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
+ cborFindResult = cbor_value_advance(&amaclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
- amacl->resourcesLen = (size_t)cJSON_GetArraySize(jsonObj);
- VERIFY_SUCCESS(TAG, amacl->resourcesLen > 0, ERROR);
- amacl->resources = (char**)OICCalloc(amacl->resourcesLen, sizeof(char*));
- VERIFY_NON_NULL(TAG, (amacl->resources), ERROR);
+ CborType type = cbor_value_get_type(&amaclMap);
- size_t idxx = 0;
- do
+ // Resources -- Mandatory
+ if (0 == strcmp(OIC_JSON_RESOURCES_NAME, name))
{
- cJSON *jsonRsrc = cJSON_GetArrayItem(jsonObj, idxx);
- VERIFY_NON_NULL(TAG, jsonRsrc, ERROR);
-
- jsonObjLen = strlen(jsonRsrc->valuestring) + 1;
- amacl->resources[idxx] = (char*)OICMalloc(jsonObjLen);
- VERIFY_NON_NULL(TAG, (amacl->resources[idxx]), ERROR);
- OICStrcpy(amacl->resources[idxx], jsonObjLen, jsonRsrc->valuestring);
- } while ( ++idxx < amacl->resourcesLen);
+ CborValue resources = { .parser = NULL };
+ cborFindResult = cbor_value_get_array_length(&amaclMap, &amacl->resourcesLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
+
+ cborFindResult = cbor_value_enter_container(&amaclMap, &resources);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
+
+ amacl->resources = (char **) OICMalloc(amacl->resourcesLen * sizeof(*amacl->resources));
+ VERIFY_NON_NULL(TAG, amacl->resources, ERROR);
+ int i = 0;
+ while (cbor_value_is_text_string(&resources))
+ {
+ cborFindResult = cbor_value_dup_text_string(&resources, &amacl->resources[i++],
+ &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
+ cborFindResult = cbor_value_advance(&resources);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
+ }
+ }
// Amss -- Mandatory
- VERIFY_SUCCESS( TAG, OC_STACK_OK == AddUuidArray(jsonAmacl, OIC_JSON_AMSS_NAME,
- &(amacl->amssLen), &(amacl->amss)), ERROR);
+ if (0 == strcmp(OIC_JSON_AMSS_NAME, name))
+ {
+ CborValue amss = { .parser = NULL };
+ cborFindResult = cbor_value_get_array_length(&amaclMap, &amacl->amssLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
+ cborFindResult = cbor_value_enter_container(&amaclMap, &amss);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
+ int i = 0;
+ amacl->amss = (OicUuid_t *)OICCalloc(amacl->amssLen, sizeof(*amacl->amss));
+ VERIFY_NON_NULL(TAG, amacl->amss, ERROR);
+ while (cbor_value_is_valid(&amss))
+ {
+ uint8_t *amssId = NULL;
+ cborFindResult = cbor_value_dup_byte_string(&amss, &amssId, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
+ cborFindResult = cbor_value_advance(&amss);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
+ memcpy(amacl->amss[i].id, amssId, len);
+ OICFree(amssId);
+ }
+ }
// Owners -- Mandatory
- VERIFY_SUCCESS( TAG, OC_STACK_OK == AddUuidArray(jsonAmacl, OIC_JSON_OWNERS_NAME,
- &(amacl->ownersLen), &(amacl->owners)), ERROR);
+ if (0 == strcmp(OIC_JSON_OWNERS_NAME, name))
+ {
+ CborValue owners = { .parser = NULL };
+ cborFindResult = cbor_value_get_array_length(&amaclMap, &amacl->ownersLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
+ cborFindResult = cbor_value_enter_container(&amaclMap, &owners);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
+ int i = 0;
+ amacl->owners = (OicUuid_t *)OICCalloc(amacl->ownersLen, sizeof(*amacl->owners));
+ VERIFY_NON_NULL(TAG, amacl->owners, ERROR);
+ while (cbor_value_is_valid(&owners))
+ {
+ uint8_t *owner = NULL;
+ cborFindResult = cbor_value_dup_byte_string(&owners, &owner, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
+ cborFindResult = cbor_value_advance(&owners);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
+ memcpy(amacl->owners[i].id, owner, len);
+ OICFree(owner);
+ }
+ }
+ if (CborMapType != type && cbor_value_is_valid(&amaclMap))
+ {
+ cborFindResult = cbor_value_advance(&amaclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
+ }
+ OICFree(name);
+ }
- prevAmacl = amacl;
- } while( ++idx < numAmacl);
+ amacl->next = NULL;
+ if (NULL == headAmacl)
+ {
+ headAmacl = amacl;
+ }
+ else
+ {
+ OicSecAmacl_t *temp = headAmacl;
+ while (temp->next)
+ {
+ temp = temp->next;
+ }
+ temp->next = amacl;
+ }
+ if (cbor_value_is_valid(&amaclArray))
+ {
+ cborFindResult = cbor_value_advance(&amaclArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
+ }
}
-
+ *secAmacl = headAmacl;
ret = OC_STACK_OK;
-
exit:
- cJSON_Delete(jsonRoot);
- if (OC_STACK_OK != ret)
+ if (CborNoError != cborFindResult)
{
DeleteAmaclList(headAmacl);
headAmacl = NULL;
+ ret = OC_STACK_ERROR;
}
- return headAmacl;
+ return ret;
}
static OCEntityHandlerResult HandleAmaclGetRequest (const OCEntityHandlerRequest * ehRequest)
{
// Convert Amacl data into JSON for transmission
- char* jsonStr = BinToAmaclJSON(gAmacl);
+ size_t size = 0;
+ uint8_t *cborPayload = NULL;
+ OCStackResult res = AmaclToCBORPayload(gAmacl, &cborPayload, &size);
- OCEntityHandlerResult ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR);
+ OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
// Send response payload to request originator
- SendSRMResponse(ehRequest, ehRet, jsonStr);
+ SendSRMCBORResponse(ehRequest, ehRet, cborPayload);
- OICFree(jsonStr);
+ OICFree(cborPayload);
OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
return ehRet;
{
OCEntityHandlerResult ehRet = OC_EH_ERROR;
- // Convert JSON Amacl data into binary. This will also validate the Amacl data received.
- OicSecAmacl_t* newAmacl = JSONToAmaclBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
-
- if (newAmacl)
+ // Convert CBOR Amacl data into binary. This will also validate the Amacl data received.
+ uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData1;;
+ if (payload)
{
- // Append the new Amacl to existing Amacl
- LL_APPEND(gAmacl, newAmacl);
-
- // Convert Amacl data into JSON for update to persistent storage
- char *jsonStr = BinToAmaclJSON(gAmacl);
- if (jsonStr)
+ OicSecAmacl_t *newAmacl = NULL;
+ OCStackResult res = CBORPayloadToAmacl(payload, CBOR_SIZE, &newAmacl);
+ if (newAmacl && OC_STACK_OK == res)
{
- cJSON *jsonAmacl = cJSON_Parse(jsonStr);
- OICFree(jsonStr);
-
- if ((jsonAmacl) &&
- (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_AMACL_NAME, jsonAmacl)))
+ // Append the new Amacl to existing Amacl
+ LL_APPEND(gAmacl, newAmacl);
+ size_t size = 0;
+ // Convert Amacl data into JSON for update to persistent storage.
+ uint8_t *cborPayload = NULL;
+ res = AmaclToCBORPayload(gAmacl, &cborPayload, &size);
+ if (cborPayload && (OC_STACK_OK == res) &&
+ (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_AMACL_NAME, cborPayload, size)))
{
ehRet = OC_EH_RESOURCE_CREATED;
}
- cJSON_Delete(jsonAmacl);
+ OICFree(cborPayload);
}
+ OICFree(payload);
}
// Send payload to request originator
- SendSRMResponse(ehRequest, ehRet, NULL);
+ SendSRMCBORResponse(ehRequest, ehRet, NULL);
- OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
+ OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
return ehRet;
}
*/
OCStackResult CreateAmaclResource()
{
- OCStackResult ret;
-
- ret = OCCreateResource(&gAmaclHandle,
- OIC_RSRC_TYPE_SEC_AMACL,
- OIC_MI_DEF,
- OIC_RSRC_AMACL_URI,
- AmaclEntityHandler,
- NULL,
- OC_OBSERVABLE);
+ OCStackResult ret = OCCreateResource(&gAmaclHandle,
+ OIC_RSRC_TYPE_SEC_AMACL,
+ OIC_MI_DEF,
+ OIC_RSRC_AMACL_URI,
+ AmaclEntityHandler,
+ NULL,
+ OC_OBSERVABLE);
if (OC_STACK_OK != ret)
{
{
OCStackResult ret = OC_STACK_ERROR;
- // Read Amacl resource from PS
- char* jsonSVRDatabase = GetSVRDatabase();
+ uint8_t *data = NULL;
+ size_t size = 0;
+ ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_AMACL_NAME, &data, &size);
- if (jsonSVRDatabase)
+ // If database read failed
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG(DEBUG, TAG, "ReadSVDataFromPS failed");
+ }
+ if (data)
{
- // Convert JSON Amacl into binary format
- gAmacl = JSONToAmaclBin(jsonSVRDatabase);
- OICFree(jsonSVRDatabase);
+ // Read AMACL resource from PS
+ ret = CBORPayloadToAmacl(data, size, &gAmacl);
+ OICFree(data);
}
// Instantiate 'oic/sec/amacl' resource
{
for(size_t i = 0; i < amacl->resourcesLen; i++)
{
- if (strncmp((amacl->resources[i]), resource, strlen(amacl->resources[i])) == 0)
+ if (0 == strncmp((amacl->resources[i]), resource, strlen(amacl->resources[i])))
{
//Returning the ID of the first AMS service for the resource
memcpy(amsDeviceId, &amacl->amss[0], sizeof(*amsDeviceId));
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "gtest/gtest.h"
+#include "cainterface.h"
+#include "ocstack.h"
+#include "ocpayload.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "payload_logging.h"
+#include "psinterface.h"
+#include "secureresourcemanager.h"
+#include "securevirtualresourcetypes.h"
+#include "srmresourcestrings.h"
+#include "srmutility.h"
+#include "amaclresource.h"
+#include "security_internals.h"
+
+using namespace std;
+
+#define TAG "SRM-AMACL-UT"
+
+TEST(AMACLResourceTest, CBORAMACLConversion)
+{
+ OicSecAmacl_t *secAmacl = (OicSecAmacl_t *) OICCalloc(1, sizeof(*secAmacl));
+ ASSERT_TRUE(NULL != secAmacl);
+ uint8_t amss[] = {0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
+ 0x35, 0x35, 0x35, 0x35, 0x35, 0x35};
+ uint8_t amss1[] = {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36};
+ secAmacl->amssLen = 2;
+ secAmacl->amss = (OicUuid_t *)OICCalloc(secAmacl->amssLen, sizeof(*secAmacl->amss));
+ if (!secAmacl->amss)
+ {
+ OICFree(secAmacl);
+ }
+ ASSERT_TRUE(NULL != secAmacl->amss);
+ memcpy(secAmacl->amss[0].id, amss, sizeof(amss));
+ memcpy(secAmacl->amss[1].id, amss1, sizeof(amss1));
+
+ const char *rsrc[] = { "/a/led", "/a/fan"};
+ secAmacl->resourcesLen = 2;
+ secAmacl->resources = (char **)OICCalloc(secAmacl->resourcesLen,
+ sizeof(*secAmacl->resources));
+ if (!secAmacl->resources)
+ {
+ OICFree(secAmacl->amss);
+ OICFree(secAmacl);
+ }
+ ASSERT_TRUE(NULL != secAmacl->resources);
+ for (size_t i = 0 ; i < secAmacl->resourcesLen; i++)
+ {
+ secAmacl->resources[i] = OICStrdup(rsrc[i]);
+ ASSERT_TRUE(NULL != secAmacl->resources[i]);
+ }
+ secAmacl->ownersLen = 1;
+ uint8_t ownrs[] = {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
+ 0x32, 0x32, 0x32, 0x32, 0x32, 0x32};
+ secAmacl->owners = (OicUuid_t *)OICCalloc(1, sizeof(*secAmacl->owners));
+ if (!secAmacl->owners)
+ {
+ OICFree(secAmacl->resources);
+ OICFree(secAmacl->amss);
+ OICFree(secAmacl);
+ }
+ ASSERT_TRUE(NULL != secAmacl->owners);
+ memcpy(secAmacl->owners[0].id, ownrs, sizeof(ownrs));
+
+ OicSecAmacl_t *secAmacl1 = (OicSecAmacl_t *) OICCalloc(1, sizeof(*secAmacl1));
+ if (!secAmacl1)
+ {
+ OICFree(secAmacl->owners);
+ OICFree(secAmacl->resources);
+ OICFree(secAmacl->amss);
+ OICFree(secAmacl);
+ }
+ ASSERT_TRUE(NULL != secAmacl1);
+ secAmacl1->amssLen = 2;
+ secAmacl1->amss = (OicUuid_t *)OICCalloc(2, sizeof(*secAmacl1->amss));
+ if (!secAmacl1->amss)
+ {
+ OICFree(secAmacl->owners);
+ OICFree(secAmacl->resources);
+ OICFree(secAmacl->amss);
+ OICFree(secAmacl);
+ OICFree(secAmacl1);
+ }
+ ASSERT_TRUE(NULL != secAmacl1->amss);
+ memcpy(secAmacl1->amss[0].id, amss, sizeof(amss));
+ memcpy(secAmacl1->amss[1].id, amss1, sizeof(amss1));
+
+ const char *rsrc1[] = { "/b/led", "/b/fan"};
+ secAmacl1->resourcesLen = 2;
+ secAmacl1->resources = (char **)OICCalloc(secAmacl1->resourcesLen,
+ sizeof(*secAmacl1->resources));
+ if (!secAmacl1->resources)
+ {
+ OICFree(secAmacl->owners);
+ OICFree(secAmacl->resources);
+ OICFree(secAmacl->amss);
+ OICFree(secAmacl);
+ OICFree(secAmacl1->amss);
+ OICFree(secAmacl1);
+ }
+ ASSERT_TRUE(NULL != secAmacl1->resources);
+ for (size_t i = 0 ; i < secAmacl1->resourcesLen; i++)
+ {
+ secAmacl1->resources[i] = OICStrdup(rsrc1[i]);
+ ASSERT_TRUE(NULL != secAmacl1->resources[i]);
+ }
+ secAmacl1->ownersLen = 1;
+ secAmacl1->owners = (OicUuid_t *)OICCalloc(1, sizeof(*secAmacl1->owners));
+ if (!secAmacl1->owners)
+ {
+ OICFree(secAmacl->owners);
+ OICFree(secAmacl->resources);
+ OICFree(secAmacl->amss);
+ OICFree(secAmacl);
+ OICFree(secAmacl1->resources);
+ OICFree(secAmacl1->amss);
+ OICFree(secAmacl1);
+ }
+ ASSERT_TRUE(NULL != secAmacl1->owners);
+ memcpy(secAmacl1->owners[0].id, ownrs, sizeof(ownrs));
+ secAmacl1->next = NULL;
+ secAmacl->next = secAmacl1;
+
+ size_t size = 0;
+ uint8_t *psStorage = NULL;
+ EXPECT_EQ(OC_STACK_OK, AmaclToCBORPayload(secAmacl, &psStorage, &size));
+ if (!psStorage)
+ {
+ OICFree(secAmacl->owners);
+ OICFree(secAmacl->resources);
+ OICFree(secAmacl->amss);
+ OICFree(secAmacl);
+ OICFree(secAmacl1->owners);
+ OICFree(secAmacl1->resources);
+ OICFree(secAmacl1->amss);
+ OICFree(secAmacl1);
+ }
+ ASSERT_TRUE(NULL != psStorage);
+
+ OicSecAmacl_t *amacl = NULL;
+ EXPECT_EQ(OC_STACK_OK, CBORPayloadToAmacl(psStorage, size, &amacl));
+ if (!amacl)
+ {
+ OICFree(secAmacl->owners);
+ OICFree(secAmacl->resources);
+ OICFree(secAmacl->amss);
+ OICFree(secAmacl);
+ OICFree(secAmacl1->owners);
+ OICFree(secAmacl1->resources);
+ OICFree(secAmacl1->amss);
+ OICFree(secAmacl1);
+ OICFree(psStorage);
+ }
+ ASSERT_TRUE(NULL != amacl);
+
+ EXPECT_EQ(secAmacl->amssLen, amacl->amssLen);
+ EXPECT_EQ(sizeof(secAmacl->amss[0].id), sizeof(amacl->amss[0].id));
+ EXPECT_EQ(sizeof(secAmacl->amss[1].id), sizeof(amacl->amss[1].id));
+ EXPECT_STREQ(secAmacl->resources[0], amacl->resources[0]);
+ EXPECT_STREQ(secAmacl->resources[1], amacl->resources[1]);
+ EXPECT_EQ(secAmacl->resourcesLen, amacl->resourcesLen);
+ EXPECT_EQ(secAmacl->ownersLen, amacl->ownersLen);
+ EXPECT_EQ(*secAmacl->owners[0].id, *amacl->owners[0].id);
+
+ EXPECT_EQ(secAmacl->next->amssLen, amacl->next->amssLen);
+ EXPECT_EQ(sizeof(secAmacl->next->amss[0].id), sizeof(amacl->next->amss[0].id));
+ EXPECT_STREQ(secAmacl->next->resources[0], amacl->next->resources[0]);
+ EXPECT_STREQ(secAmacl->next->resources[1], amacl->next->resources[1]);
+ EXPECT_EQ(secAmacl->next->resourcesLen, amacl->next->resourcesLen);
+ EXPECT_EQ(secAmacl->next->ownersLen, amacl->next->ownersLen);
+ EXPECT_EQ(*secAmacl->next->owners[0].id, *amacl->next->owners[0].id);
+
+ OICFree(secAmacl->owners);
+ OICFree(secAmacl->resources);
+ OICFree(secAmacl->amss);
+ OICFree(secAmacl);
+ OICFree(secAmacl1->owners);
+ OICFree(secAmacl1->resources);
+ OICFree(secAmacl1->amss);
+ OICFree(secAmacl1);
+ OICFree(psStorage);
+ OICFree(amacl);
+}