//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#include <stdlib.h>
-#include <string.h>
-#include "ocstack.h"
-#include "logger.h"
-#include "oic_malloc.h"
-#include "cJSON.h"
-#include "base64.h"
-#include "resourcemanager.h"
-#include "psinterface.h"
#include "utlist.h"
+#include "payload_logging.h"
+#include "psinterface.h"
+#include "resourcemanager.h"
#include "srmresourcestrings.h"
-#include "doxmresource.h"
#include "srmutility.h"
-#ifdef __WITH_X509__
+#include "doxmresource.h"
+#include "ocpayload.h"
+#include "ocpayloadcbor.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
#include "crlresource.h"
-#include "crl.h"
-#endif /* __WITH_X509__ */
+#include "ocpayloadcbor.h"
+#include "base64.h"
+#include <time.h>
-#define TAG "SRM-CRL"
+#define TAG "OIC_SRM_CRL"
#define SEPARATOR ":"
#define SEPARATOR_LEN (1)
-#define JSON_CRL_NAME "\"CRL\""
-#define JSON_CRL_NAME_LEN (5)
-#define OIC_JSON_CRL_NAME "crl"
-#define OIC_JSON_CRL_ID "CRLId"
-#define OIC_JSON_CRL_THIS_UPDATE "ThisUpdate"
-#define OIC_JSON_CRL_DATA "CRLData"
-#define CRL_DEFAULT_CRL_ID 1
+#define CBOR_CRL_NAME "\"CRL\""
+#define CBOR_CRL_NAME_LEN (5)
+#define OIC_CBOR_CRL_NAME "crl"
+#define OIC_CBOR_CRL_ID "CRLId"
+#define OIC_CBOR_CRL_THIS_UPDATE "ThisUpdate"
+#define OIC_CBOR_CRL_DATA "CRLData"
+#define CRL_DEFAULT_CRL_ID (1)
#define CRL_DEFAULT_THIS_UPDATE "150101000000Z"
+#define CRL_DEFAULT_LAST_UPDATE "20150701000000"
#define CRL_DEFAULT_CRL_DATA "-"
+#define CRL_MAP_SIZE (3)
static OCResourceHandle gCrlHandle = NULL;
static OicSecCrl_t *gCrl = NULL;
+/** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
+ * The value of payload size is increased until reaching below max cbor size. */
+static const uint16_t CBOR_SIZE = 1024;
-void DeleteCrlBinData(OicSecCrl_t *crl)
+// Max cbor size payload.
+static const uint16_t CBOR_MAX_SIZE = 4400;
+
+void DeleteCrl(OicSecCrl_t *crl)
{
if (crl)
{
}
}
-char *BinToCrlJSON(const OicSecCrl_t *crl)
+void printCrl(const OicSecCrl_t *crl)
{
if (NULL == crl)
{
- return NULL;
+ OIC_LOG(INFO, TAG, "Received NULL CRL");
+ return;
}
- char *base64Buff = NULL;
- uint32_t outLen = 0;
- uint32_t base64CRLLen = 0;
- B64Result b64Ret = B64_OK;
- char *jsonStr = NULL;
- cJSON *jsonRoot = cJSON_CreateObject();
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
- cJSON *jsonCrl = cJSON_CreateObject();
- VERIFY_NON_NULL(TAG, jsonCrl, ERROR);
+ OIC_LOG(INFO, TAG, "Crl object contain:");
+ OIC_LOG_V(INFO, TAG, "id = %d", crl->CrlId);
+ OIC_LOG_V(INFO, TAG, "this update = %s", crl->ThisUpdate.data);
- cJSON_AddItemToObject(jsonRoot, OIC_JSON_CRL_NAME, jsonCrl);
+ OIC_LOG(INFO, TAG, "crl:");
+ OIC_LOG_V(INFO, TAG, "encoding = %d", crl->CrlData.encoding);
+ OIC_LOG_V(INFO, TAG, "data (length = %zu):", crl->CrlData.len);
+ OIC_LOG_BUFFER(INFO, TAG, crl->CrlData.data, crl->CrlData.len);
+}
- //CRLId -- Mandatory
- cJSON_AddNumberToObject(jsonCrl, OIC_JSON_CRL_ID, (int)crl->CrlId);
+static bool copyByteArray(const uint8_t *in, size_t in_len, uint8_t **out, size_t *out_len)
+{
+ OICFree(*out);
+ uint8_t *tmp = OICMalloc(in_len);
+ if (!tmp)
+ {
+ return false;
+ }
+ memcpy(tmp, in, in_len);
+ *out = tmp;
+ *out_len = in_len;
+ return true;
+}
- //ThisUpdate -- Mandatory
- outLen = 0;
- base64CRLLen = B64ENCODE_OUT_SAFESIZE(crl->ThisUpdate.len);
- base64Buff = OICMalloc(base64CRLLen);
- b64Ret = b64Encode(crl->ThisUpdate.data, crl->ThisUpdate.len, base64Buff,
- base64CRLLen, &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
- cJSON_AddStringToObject(jsonCrl, OIC_JSON_CRL_THIS_UPDATE, base64Buff);
- OICFree(base64Buff);
+static bool copyCrl(const OicSecCrl_t *in, OicSecCrl_t *out)
+{
+ bool result = false;
- //CRLData -- Mandatory
- outLen = 0;
- base64CRLLen = B64ENCODE_OUT_SAFESIZE(crl->CrlData.len);
- base64Buff = OICMalloc(base64CRLLen);
- b64Ret = b64Encode(crl->CrlData.data, crl->CrlData.len, base64Buff,
- base64CRLLen, &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
- cJSON_AddStringToObject(jsonCrl, OIC_JSON_CRL_DATA, base64Buff);
+ if (!in || !out)
+ {
+ OIC_LOG(ERROR, TAG, "in or out crl is NULL");
+ return false;
+ }
- jsonStr = cJSON_PrintUnformatted(jsonRoot);
+ out->CrlId = in->CrlId;
-exit:
- OICFree(base64Buff);
- if (jsonRoot)
+ result = copyByteArray(in->ThisUpdate.data, in->ThisUpdate.len, &out->ThisUpdate.data, &out->ThisUpdate.len);
+ if (!result)
{
- cJSON_Delete(jsonRoot);
+ OIC_LOG(ERROR, TAG, "Can't allocate memory for ThisUpdate");
+ return false;
}
- return jsonStr;
+
+ result = copyByteArray(in->CrlData.data, in->CrlData.len, &out->CrlData.data, &out->CrlData.len);
+ if (!result)
+ {
+ OIC_LOG(ERROR, TAG, "Can't allocate memory for CrlData");
+ return false;
+ }
+
+ return result;
}
-OicSecCrl_t *JSONToCrlBin(const char * jsonStr)
+static CborError setPubDataType(CborEncoder *out, const char *name, const OicSecKey_t *value)
{
- if (NULL == jsonStr)
+ if (!out || !name || !value)
{
- return NULL;
+ OIC_LOG_V(ERROR, TAG, "%s: null input params", __func__);
+ return CborErrorInternalError;
}
- OCStackResult ret = OC_STACK_ERROR;
- OicSecCrl_t *crl = NULL;
- cJSON *jsonCrl = NULL;
- cJSON *jsonObj = NULL;
+ CborEncoder map;
- unsigned char *base64Buff = NULL;
- uint32_t base64CRLLen = 0;
- uint32_t outLen = 0;
- B64Result b64Ret = B64_OK;
+ const char *encoding = NULL;
+ bool binary_field = false;
- cJSON *jsonRoot = cJSON_Parse(jsonStr);
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+ size_t mapSize = 0;
- jsonCrl = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRL_NAME);
- VERIFY_NON_NULL(TAG, jsonCrl, ERROR);
- crl = (OicSecCrl_t *)OICCalloc(1, sizeof(OicSecCrl_t));
- VERIFY_NON_NULL(TAG, crl, ERROR);
-
- //CRLId -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_ID);
- if(jsonObj)
+ mapSize++;
+ switch(value->encoding)
{
- VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
- crl->CrlId = (uint16_t)jsonObj->valueint;
+ case OIC_ENCODING_RAW:
+ binary_field = true;
+ encoding = OIC_SEC_ENCODING_RAW;
+ break;
+ case OIC_ENCODING_BASE64:
+ encoding = OIC_SEC_ENCODING_BASE64;
+ break;
+ case OIC_ENCODING_DER:
+ binary_field = true;
+ encoding = OIC_SEC_ENCODING_DER;
+ break;
+ case OIC_ENCODING_PEM:
+ encoding = OIC_SEC_ENCODING_PEM;
+ break;
+ default:
+ OIC_LOG(ERROR, TAG, "Received UNKNOWN encoding, exit!");
+ return CborErrorInternalError;
}
- else // PUT/POST JSON may not have CRLId so set it to the gCRList->CRLId
+
+ if (value->data)
{
- VERIFY_NON_NULL(TAG, gCrl, ERROR);
- crl->CrlId = gCrl->CrlId;
+ mapSize++;
}
- //ThisUpdate -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_THIS_UPDATE);
- if(jsonObj)
+ CborError result = CborNoError;
+ result = cbor_encode_text_string(out, name, strlen(name));
+ VERIFY_CBOR_SUCCESS(TAG, result, "Failed Adding name Tag.");
+
+ result = cbor_encoder_create_map(out, &map, mapSize);
+ VERIFY_CBOR_SUCCESS(TAG, result, "Failed creating name map");
+
+ if (encoding)
{
- VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
- if(cJSON_String == jsonObj->type)
+ result = cbor_encode_text_string(&map, OIC_JSON_ENCODING_NAME,
+ strlen(OIC_JSON_ENCODING_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, result, "Failed to add encoding tag.")
+ result = cbor_encode_text_string(&map, encoding, strlen(encoding));
+ VERIFY_CBOR_SUCCESS(TAG, result, "Failed to add encoding value.");
+ };
+
+ if (value->data)
+ {
+ result = cbor_encode_text_string(&map, OIC_JSON_DATA_NAME, strlen(OIC_JSON_DATA_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, result, "Failed to add data tag.");
+ if (binary_field)
{
- //Check for empty string, in case ThisUpdate field has not been set yet
- if (jsonObj->valuestring[0])
- {
- base64CRLLen = B64ENCODE_OUT_SAFESIZE(strlen(jsonObj->valuestring));
- base64Buff = OICMalloc(base64CRLLen);
- b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
- base64CRLLen, &outLen);
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= base64CRLLen),
- ERROR);
- crl->ThisUpdate.data = OICMalloc(outLen + 1);
- memcpy(crl->ThisUpdate.data, base64Buff, outLen);
- crl->ThisUpdate.len = outLen;
- OICFree(base64Buff);
- base64Buff = NULL;
- }
+ result = cbor_encode_byte_string(&map, value->data, value->len);
}
+ else
+ {
+ result = cbor_encode_text_string(&map, (const char *)value->data, value->len);
+ }
+ VERIFY_CBOR_SUCCESS(TAG, result, "Failed to add data value.");
}
- else // PUT/POST JSON will not have ThisUpdate so set it to the gCRList->ThisUpdate
+
+ result = cbor_encoder_close_container(out, &map);
+ VERIFY_CBOR_SUCCESS(TAG, result, "Failed Closing PrivateData Map.");
+
+exit:
+ return result;
+}
+
+static CborError getPubDataType(CborValue *in, const char *name, OicSecKey_t *value)
+{
+ if (!in || !name || !value)
{
- VERIFY_NON_NULL(TAG, gCrl, ERROR);
- outLen = gCrl->ThisUpdate.len;
- crl->ThisUpdate.data = OICMalloc(outLen + 1);
- memcpy(crl->ThisUpdate.data, gCrl->ThisUpdate.data, outLen);
- crl->ThisUpdate.len = outLen;
+ OIC_LOG_V(ERROR, TAG, "%s: null input params", __func__);
+ return CborErrorInternalError;
}
- //CRLData -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_DATA);
- if(jsonObj)
+ CborError result = CborNoError;
+ char *encoding = NULL;
+
+ CborValue crlNode = { .parser = NULL };
+ result = cbor_value_map_find_value(in, name, &crlNode);
+ if (CborNoError == result && cbor_value_is_map(&crlNode))
{
- VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
- if(cJSON_String == jsonObj->type)
+ CborValue crlMap = { .parser = NULL };
+ result = cbor_value_enter_container(&crlNode, &crlMap);
+
+ while(cbor_value_is_valid(&crlMap) && cbor_value_is_text_string(&crlMap))
{
- //Check for empty string, in case CRLData field has not been set yet
- if (jsonObj->valuestring[0])
+ char *property = NULL;
+ size_t length = 0;
+ result = cbor_value_dup_text_string(&crlMap, &property, &length, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, result, "Failed Get first crl ojbject tag.");
+ result = cbor_value_advance(&crlMap);
+ VERIFY_CBOR_SUCCESS(TAG, result, "Failed to advance crlMap");
+
+ if (0 == strcmp(OIC_JSON_DATA_NAME, property))
+ {
+ if (cbor_value_is_byte_string(&crlMap))
+ {
+ result = cbor_value_dup_byte_string(&crlMap, &value->data, &value->len, NULL);
+ }
+ else if(cbor_value_is_text_string(&crlMap))
+ {
+ char *buffer = NULL;
+ result = cbor_value_dup_text_string(&crlMap, &buffer, &value->len, NULL);
+ value->data = (uint8_t *)buffer;
+ }
+ else
+ {
+ result = CborErrorUnknownType;
+ OIC_LOG(ERROR, TAG, "Unknown type for crl->data.");
+ }
+ VERIFY_CBOR_SUCCESS(TAG, result, "Failed to read crl->data");
+ }
+ else if (0 == strcmp(OIC_JSON_ENCODING_NAME, property))
{
- outLen = 0;
- base64CRLLen = B64ENCODE_OUT_SAFESIZE(strlen(jsonObj->valuestring));
- base64Buff = OICMalloc(base64CRLLen);
- b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
- base64CRLLen, &outLen);
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= base64CRLLen),
- ERROR);
- crl->CrlData.data = OICMalloc(outLen + 1);
- memcpy(crl->CrlData.data, base64Buff, outLen);
- crl->CrlData.len = outLen;
- OICFree(base64Buff);
- base64Buff = NULL;
+ size_t encoding_len = 0;
+ result = cbor_value_dup_text_string(&crlMap, &encoding, &encoding_len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, result, "Failed to read crl->encdoing");
}
+ OICFree(property);
}
}
- else // PUT/POST JSON will not have CRLData so set it to the gCRList->CRLData
+ VERIFY_CBOR_SUCCESS(TAG, result, "Failed to find root node");
+
+ if (encoding)
+ {
+ OicEncodingType_t type = OIC_ENCODING_UNKNOW;
+ if (0 == strcmp(encoding, OIC_SEC_ENCODING_BASE64)) type = OIC_ENCODING_BASE64;
+ else if (0 == strcmp(encoding, OIC_SEC_ENCODING_DER)) type = OIC_ENCODING_DER;
+ else if (0 == strcmp(encoding, OIC_SEC_ENCODING_PEM)) type = OIC_ENCODING_PEM;
+ else if (0 == strcmp(encoding, OIC_SEC_ENCODING_RAW)) type = OIC_ENCODING_RAW;
+
+ value->encoding = type;
+ }
+exit:
+ return result;
+}
+
+OCStackResult CrlToCBORPayload(const OicSecCrl_t *crl, uint8_t **payload, size_t *size, char *lastUpdate)
+{
+ if (NULL == crl || NULL == payload || NULL != *payload || NULL == size)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ size_t cborLen = *size;
+ if (0 == cborLen)
{
- VERIFY_NON_NULL(TAG, gCrl, ERROR);
- outLen = gCrl->CrlData.len;
- crl->CrlData.data = OICMalloc(outLen + 1);
- memcpy(crl->CrlData.data, gCrl->CrlData.data, outLen);
- crl->CrlData.len = outLen;
+ cborLen = CBOR_SIZE;
}
+ *payload = NULL;
+ *size = 0;
+
+ size_t mapSize = CRL_MAP_SIZE;
+ if (lastUpdate)
+ {
+ mapSize++;
+ }
+
+ printCrl(crl);
+
+ OCStackResult ret = OC_STACK_ERROR;
+
+ CborEncoder encoder;
+ CborEncoder crlMap;
+
+ CborError cborEncoderResult = CborNoError;
+
+ uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
+ VERIFY_NON_NULL(TAG, outPayload, ERROR);
+ cbor_encoder_init(&encoder, outPayload, cborLen, 0);
+
+ cborEncoderResult = cbor_encoder_create_map(&encoder, &crlMap, mapSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create CRL Map");
+
+ //CRLId -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&crlMap, OC_RSRVD_CRL_ID,
+ strlen(OC_RSRVD_CRL_ID));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add CRL ID");
+ cborEncoderResult = cbor_encode_int(&crlMap, crl->CrlId);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add CRL Id value");
+
+ //ThisUpdate -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&crlMap, OC_RSRVD_THIS_UPDATE,
+ strlen(OC_RSRVD_THIS_UPDATE));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add Crl update");
+ cborEncoderResult = cbor_encode_text_string(&crlMap, (const char *)crl->ThisUpdate.data,
+ crl->ThisUpdate.len);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add Crl Update value");
+
+ //CRLData -- Mandatory
+ cborEncoderResult = setPubDataType(&crlMap, OC_RSRVD_CRL, &crl->CrlData);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add CRLData object");
+
+ //lastUpdate - internal field
+ if (lastUpdate)
+ {
+ cborEncoderResult = cbor_encode_text_string(&crlMap, OC_RSRVD_LAST_UPDATE,
+ strlen(OC_RSRVD_LAST_UPDATE));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add last Update tag");
+ cborEncoderResult = cbor_encode_text_string(&crlMap, lastUpdate, strlen(lastUpdate));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add last Update value");
+ }
+
+ cborEncoderResult = cbor_encoder_close_container(&encoder, &crlMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add close Crl map");
+
+ *size = cbor_encoder_get_buffer_size(&encoder, outPayload);
+ *payload = outPayload;
ret = OC_STACK_OK;
+
exit:
- cJSON_Delete(jsonRoot);
- OICFree(base64Buff);
- base64Buff = NULL;
- if (OC_STACK_OK != ret)
+ if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
{
- DeleteCrlBinData(crl);
- crl = NULL;
+ OICFree(outPayload);
+ outPayload = NULL;
+ *payload = NULL;
+ *size = 0;
+ ret = OC_STACK_ERROR;
+ if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
+ {
+ // Since the allocated initial memory failed, double the memory.
+ cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
+ cborEncoderResult = CborNoError;
+ ret = CrlToCBORPayload(crl, payload, &cborLen, lastUpdate);
+ }
}
- return crl;
+
+ return ret;
}
-OCStackResult UpdateCRLResource(const OicSecCrl_t *crl)
+OCStackResult CBORPayloadToCrl(const uint8_t *cborPayload, const size_t size,
+ OicSecCrl_t **secCrl)
{
- char *jsonStr = NULL;
- OCStackResult res = OC_STACK_ERROR;
+ if (NULL == cborPayload || NULL == secCrl || NULL != *secCrl || 0 == size)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
- jsonStr = BinToCrlJSON((OicSecCrl_t *) crl);
- if (!jsonStr)
+ OCStackResult ret = OC_STACK_ERROR;
+ OicSecCrl_t *crl = NULL;
+
+ CborValue crlCbor = {.parser = NULL};
+ CborParser parser = {.end = NULL};
+ CborError cborFindResult = CborNoError;
+
+ cbor_parser_init(cborPayload, size, 0, &parser, &crlCbor);
+ CborValue crlMap = { .parser = NULL};
+ cborFindResult = cbor_value_enter_container(&crlCbor, &crlMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter Crl map");
+
+ crl = (OicSecCrl_t *)OICCalloc(1, sizeof(OicSecCrl_t));
+ VERIFY_NON_NULL(TAG, crl, ERROR);
+
+ cborFindResult = cbor_value_map_find_value(&crlCbor, OC_RSRVD_CRL_ID, &crlMap);
+ if (CborNoError == cborFindResult && cbor_value_is_integer(&crlMap))
{
- return OC_STACK_ERROR;
+ int CrlId;
+
+ cborFindResult = cbor_value_get_int(&crlMap, &CrlId);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CrlId.");
+ crl->CrlId = (uint16_t)CrlId;
}
- cJSON *jsonObj = cJSON_Parse(jsonStr);
- OICFree(jsonStr);
+ cborFindResult = cbor_value_map_find_value(&crlCbor, OC_RSRVD_THIS_UPDATE, &crlMap);
+ if (CborNoError == cborFindResult && cbor_value_is_text_string(&crlMap))
+ {
+ cborFindResult = cbor_value_dup_text_string(&crlMap,
+ (char **)&crl->ThisUpdate.data, &crl->ThisUpdate.len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Byte Array.");
+ }
+
+ cborFindResult = getPubDataType(&crlCbor, OC_RSRVD_CRL, &crl->CrlData);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read CRL.");
+
+ printCrl(crl);
- if (jsonObj == NULL)
+ *secCrl = crl;
+ ret = OC_STACK_OK;
+exit:
+ if (CborNoError != cborFindResult)
{
- return OC_STACK_ERROR;
+ // PUT/POST CBOR may not have mandatory values set default values.
+ OIC_LOG (DEBUG, TAG, "Set default values");
+
+ if (copyCrl(gCrl, crl))
+ {
+ *secCrl = crl;
+ ret = OC_STACK_OK;
+ }
+ else
+ {
+ DeleteCrl(crl);
+ crl = NULL;
+ ret = OC_STACK_ERROR;
+ OIC_LOG (ERROR, TAG, "Can't set default crl");
+ }
}
+ return ret;
+}
- res = UpdateSVRDatabase(OIC_JSON_CRL_NAME, jsonObj);
- cJSON_Delete(jsonObj);
+static void getCurrentUTCTime(char *out, size_t len)
+{
+ //TODO: how to implement it in cross-platform way?
+ time_t rawtime;
+ struct tm * timeinfo = NULL;
+
+ time ( &rawtime );
+ timeinfo = localtime ( &rawtime );
- return res;
+ if (NULL == timeinfo)
+ {
+ return;
+ }
+
+ snprintf(out, len, "%04d%02d%02d%02d%02d%02d",
+ timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday,
+ timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
}
-static OCEntityHandlerResult HandleCRLPostRequest(const OCEntityHandlerRequest *ehRequest)
+OCStackResult UpdateCRLResource(OicSecCrl_t *crl)
{
- OCEntityHandlerResult ehRet = OC_EH_ERROR;
+ static uint16_t crlid = 0;
+ uint8_t *payload = NULL;
+ size_t size = 0;
- char *jsonCRL = (char *)(((OCSecurityPayload *)ehRequest->payload)->securityData);
+ crl->CrlId = crlid++;
- if (jsonCRL)
+ if (!copyCrl(crl, gCrl))
{
- OC_LOG(INFO, TAG, "UpdateSVRDB...");
- OC_LOG_V(INFO, TAG, "crl: \"%s\"", jsonCRL);
+ OIC_LOG(ERROR, TAG, "Can't update global crl");
+ return OC_STACK_ERROR;
+ }
- cJSON *jsonObj = cJSON_Parse(jsonCRL);
- OicSecCrl_t *crl = NULL;
- crl = JSONToCrlBin(jsonCRL);
- if (!crl)
- {
- OC_LOG(ERROR, TAG, "Error JSONToCrlBin");
- }
+ char currentTime[32] = {0};
+ getCurrentUTCTime(currentTime, sizeof(currentTime));
- gCrl->CrlId = crl->CrlId;
+ OCStackResult res = CrlToCBORPayload((const OicSecCrl_t *) crl, &payload, &size, currentTime);
+ if (OC_STACK_OK != res)
+ {
+ return res;
+ }
- OICFree(gCrl->ThisUpdate.data);
- gCrl->ThisUpdate.data = NULL;
- gCrl->ThisUpdate.data = OICMalloc(crl->ThisUpdate.len);
- memcpy(gCrl->ThisUpdate.data, crl->ThisUpdate.data, crl->ThisUpdate.len);
- gCrl->ThisUpdate.len = crl->ThisUpdate.len;
+ return UpdateSecureResourceInPS(OIC_CBOR_CRL_NAME, payload, size);
+}
- OICFree(gCrl->CrlData.data);
- gCrl->CrlData.data = NULL;
- gCrl->CrlData.data = OICMalloc(crl->CrlData.len);
- memcpy(gCrl->CrlData.data, crl->CrlData.data, crl->CrlData.len);
- gCrl->CrlData.len = crl->CrlData.len;
+static OCEntityHandlerResult HandleCRLPostRequest(const OCEntityHandlerRequest *ehRequest)
+{
+ OCEntityHandlerResult ehRet = OC_EH_ERROR;
+ OicSecCrl_t *crl = NULL;
+ uint8_t *payload = ((OCSecurityPayload *)ehRequest->payload)->securityData;
+ size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
+
+ if (payload)
+ {
+ OIC_LOG(INFO, TAG, "Update SVR DB...");
+ CBORPayloadToCrl(payload, size, &crl);
+ VERIFY_NON_NULL(TAG, crl, ERROR);
- if (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_CRL_NAME, jsonObj))
+ if (OC_STACK_OK == UpdateCRLResource(crl))
{
- OC_LOG(INFO, TAG, "UpdateSVRDB == OK");
ehRet = OC_EH_RESOURCE_CREATED;
}
- DeleteCrlBinData(crl);
- cJSON_Delete(jsonObj);
-
+ DeleteCrl(crl);
}
+exit:
// Send payload to request originator
- SendSRMResponse(ehRequest, ehRet, NULL);
+ if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
+ {
+ ehRet = OC_EH_ERROR;
+ OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleCRLPostRequest");
+ }
- OC_LOG_V(INFO, TAG, "%s RetVal %d", __func__, ehRet);
+ OIC_LOG_V(INFO, TAG, "%s RetVal %d", __func__, ehRet);
return ehRet;
}
-/*
+/**
* This internal method is the entity handler for CRL resource and
* will handle REST request (GET/PUT/POST/DEL) for them.
*/
-OCEntityHandlerResult CRLEntityHandler(OCEntityHandlerFlag flag,
- OCEntityHandlerRequest *ehRequest,
- void *callbackParameter)
+static OCEntityHandlerResult CRLEntityHandler(OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest *ehRequest,
+ void *callbackParameter)
{
OCEntityHandlerResult ehRet = OC_EH_ERROR;
(void)callbackParameter;
return ehRet;
}
- OC_LOG(INFO, TAG, "Handle CRL resource");
+ OIC_LOG(INFO, TAG, "Handle CRL resource");
if (flag & OC_REQUEST_FLAG)
{
// TODO : Handle PUT and DEL methods
- OC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
+ OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
switch (ehRequest->method)
{
case OC_REST_GET:
- OC_LOG (INFO, TAG, "Not implemented request method.");
+ OIC_LOG (INFO, TAG, "Not implemented request method.");
//ehRet = HandleCRLGetRequest(ehRequest);
break;
default:
ehRet = OC_EH_ERROR;
- SendSRMResponse(ehRequest, ehRet, NULL);
+ SendSRMResponse(ehRequest, ehRet, NULL, 0);
}
}
return ehRet;
}
-/*
+/**
* This internal method is used to create '/oic/sec/crl' resource.
*/
-OCStackResult CreateCRLResource()
+static OCStackResult CreateCRLResource()
{
- OCStackResult ret;
- ret = OCCreateResource(&gCrlHandle,
- OIC_RSRC_TYPE_SEC_CRL,
- OIC_MI_DEF,
- OIC_RSRC_CRL_URI,
- CRLEntityHandler,
- NULL,
- OC_OBSERVABLE);
+ OCStackResult ret = OCCreateResource(&gCrlHandle,
+ OIC_RSRC_TYPE_SEC_CRL,
+ OC_RSRVD_INTERFACE_DEFAULT,
+ OIC_RSRC_CRL_URI,
+ CRLEntityHandler,
+ NULL,
+ OC_OBSERVABLE);
if (OC_STACK_OK != ret)
{
- OC_LOG(FATAL, TAG, "Unable to instantiate CRL resource");
+ OIC_LOG(FATAL, TAG, "Unable to instantiate CRL resource");
DeInitCRLResource();
}
return ret;
}
/**
- * Get the default value
- * @retval NULL for now. Update it when we finalize the default info.
+ * Get the default value.
+ * @return defaultCrl for now.
*/
static OicSecCrl_t *GetCrlDefault()
{
- OicSecCrl_t *defaultCrl = NULL;
- defaultCrl = (OicSecCrl_t *)OICCalloc(1, sizeof(OicSecCrl_t));
+ OicSecCrl_t *defaultCrl = (OicSecCrl_t *)OICCalloc(1, sizeof(OicSecCrl_t));
+ if (NULL == defaultCrl)
+ {
+ return NULL;
+ }
defaultCrl->CrlId = CRL_DEFAULT_CRL_ID;
+ defaultCrl->CrlData.encoding = OIC_ENCODING_DER;
- defaultCrl->CrlData.len = strlen(CRL_DEFAULT_CRL_DATA);
- defaultCrl->CrlData.data = OICMalloc(defaultCrl->CrlData.len);
- memcpy(defaultCrl->CrlData.data, CRL_DEFAULT_CRL_DATA, defaultCrl->CrlData.len);
+ bool result1 = copyByteArray((const uint8_t *)CRL_DEFAULT_CRL_DATA,
+ strlen(CRL_DEFAULT_CRL_DATA),
+ &defaultCrl->CrlData.data,
+ &defaultCrl->CrlData.len);
- defaultCrl->ThisUpdate.len = strlen(CRL_DEFAULT_THIS_UPDATE);
- defaultCrl->ThisUpdate.data = OICMalloc(defaultCrl->ThisUpdate.len);
- memcpy(defaultCrl->ThisUpdate.data, CRL_DEFAULT_THIS_UPDATE, defaultCrl->ThisUpdate.len);
+ bool result2 = copyByteArray((const uint8_t *)CRL_DEFAULT_THIS_UPDATE,
+ strlen(CRL_DEFAULT_THIS_UPDATE),
+ &defaultCrl->ThisUpdate.data,
+ &defaultCrl->ThisUpdate.len);
+
+ if (!result1 || !result2)
+ {
+ DeleteCrl(defaultCrl);
+ return NULL;
+ }
return defaultCrl;
}
OCStackResult InitCRLResource()
{
OCStackResult ret = OC_STACK_ERROR;
- char* jsonSVRDatabase;
-
- //Read CRL resource from PS
- jsonSVRDatabase = GetSVRDatabase();
-
- if (jsonSVRDatabase)
+ // Read Crl resource from PS
+ uint8_t *data = NULL;
+ size_t size = 0;
+ ret = GetSecureVirtualDatabaseFromPS(OIC_CBOR_CRL_NAME, &data, &size);
+ // If database read failed
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
+ }
+ if (data)
{
- //Convert JSON CRL into binary format
- gCrl = JSONToCrlBin(jsonSVRDatabase);
+ // Read ACL resource from PS
+ ret = CBORPayloadToCrl(data, size, &gCrl);
}
+
/*
* If SVR database in persistent storage got corrupted or
* is not available for some reason, a default CrlResource is created
* which allows user to initiate CrlResource provisioning again.
*/
- if (!jsonSVRDatabase || !gCrl)
+ if ((OC_STACK_OK != ret) || !data || !gCrl)
{
gCrl = GetCrlDefault();
}
ret = CreateCRLResource();
- OICFree(jsonSVRDatabase);
+ OICFree(data);
return ret;
}
/**
* Perform cleanup for ACL resources.
*/
-void DeInitCRLResource()
+OCStackResult DeInitCRLResource()
{
- OCDeleteResource(gCrlHandle);
+ OCStackResult result = OCDeleteResource(gCrlHandle);
gCrlHandle = NULL;
- DeleteCrlBinData(gCrl);
+ DeleteCrl(gCrl);
gCrl = NULL;
+ return result;
}
OicSecCrl_t *GetCRLResource()
OicSecCrl_t *crl = NULL;
//Read CRL resource from PS
- char* jsonSVRDatabase = GetSVRDatabase();
-
- if (jsonSVRDatabase)
+ uint8_t *data = NULL;
+ size_t size = 0;
+ OCStackResult ret = GetSecureVirtualDatabaseFromPS(OIC_CBOR_CRL_NAME, &data, &size);
+ if (data)
{
- //Convert JSON CRL into binary format
- crl = JSONToCrlBin(jsonSVRDatabase);
+ //Convert CBOR CRL into binary format
+ ret = CBORPayloadToCrl(data, size, &crl);
}
/*
* If SVR database in persistent storage got corrupted or
* is not available for some reason, a default CrlResource is created
* which allows user to initiate CrlResource provisioning again.
*/
- if (!jsonSVRDatabase || !crl)
+ if ((OC_STACK_OK != ret) || !data || !crl)
{
crl = GetCrlDefault();
}
- OICFree(jsonSVRDatabase);
+ OICFree(data);
return crl;
}
-char *GetBase64CRL()
+OCStackResult getLastUpdateFromDB(char **lastUpdate)
{
- cJSON *jsonCrl = NULL;
- cJSON *jsonObj = NULL;
- char *jsonSVRDatabase = GetSVRDatabase();
- char* ret = NULL;
+ OCStackResult result = OC_STACK_OK;
- cJSON *jsonRoot = cJSON_Parse(jsonSVRDatabase);
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+ OCPayload *payload = NULL;
+ uint8_t *data = NULL;
+ size_t size = 0;
- jsonCrl = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRL_NAME);
- VERIFY_NON_NULL(TAG, jsonCrl, ERROR);
+ if (!lastUpdate)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
- //CRLData -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_DATA);
- if(jsonObj)
+ result = GetSecureVirtualDatabaseFromPS(OIC_CBOR_CRL_NAME, &data, &size);
+ if (result != OC_STACK_OK)
{
- VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
- if(cJSON_String == jsonObj->type)
- {
- //Check for empty string, in case CRLData field has not been set yet
- if (jsonObj->valuestring[0])
- {
- ret = jsonObj->valuestring;
- }
- }
+ OIC_LOG(ERROR, TAG, "Can't get crl data from database");
+ goto exit;
}
+
+ result = OCParsePayload(&payload, PAYLOAD_TYPE_REPRESENTATION, data, size);
+ if (result != OC_STACK_OK)
+ {
+ OIC_LOG(ERROR, TAG, "Can't parse cbor data from DB");
+ goto exit;
+ }
+
+ if (!OCRepPayloadGetPropString((const OCRepPayload*)payload, OC_RSRVD_LAST_UPDATE, lastUpdate))
+ {
+ OIC_LOG_V(ERROR, TAG, "Can't get: %s", OC_RSRVD_LAST_UPDATE);
+ result = OC_STACK_ERROR;
+ }
+
exit:
- OICFree(jsonSVRDatabase);
- cJSON_Delete(jsonRoot);
- return ret;
+ if (result != OC_STACK_OK)
+ {
+ OIC_LOG(DEBUG, TAG, "Assume you are first time get Crl, and it can be absent in database");
+ OIC_LOG_V(DEBUG, TAG, "Return default last update time %s", CRL_DEFAULT_LAST_UPDATE);
+
+ *lastUpdate = OICStrdup(CRL_DEFAULT_LAST_UPDATE);
+ result = OC_STACK_OK;
+ }
+ OCPayloadDestroy((OCPayload *)payload);
+
+ return result;
}
-void GetDerCrl(ByteArray crlArray)
+uint8_t *GetCrl()
{
- OicSecCrl_t * crlRes = GetCRLResource();
- if (crlRes && crlRes->CrlData.len <= crlArray.len)
+ uint8_t *data = NULL;
+ size_t size = 0;
+ OicSecCrl_t *crl = NULL;
+ if (OC_STACK_OK == GetSecureVirtualDatabaseFromPS(OIC_CBOR_CRL_NAME, &data, &size) && data &&
+ OC_STACK_OK == CBORPayloadToCrl(data, size, &crl))
+ {
+ return crl->CrlData.data;
+ }
+ return NULL;
+}
+
+void GetDerCrl(ByteArray_t* out)
+{
+ if(NULL == out)
+ {
+ return;
+ }
+
+ OicSecCrl_t *crlRes = GetCRLResource();
+
+ if(NULL == crlRes)
+ {
+ return;
+ }
+
+ OicSecKey_t *crl = &crlRes->CrlData;
+
+ if (OIC_ENCODING_BASE64 == crl->encoding)
+ {
+ size_t outSize = B64DECODE_OUT_SAFESIZE((crl->len + 1));
+ uint8_t *out = OICCalloc(1, outSize);
+ if (!out)
+ {
+ OIC_LOG(ERROR, TAG, "Can't allocate memory for base64 str");
+ DeleteCrl(crlRes);
+ return;
+ }
+ uint32_t len = 0;
+
+ if(B64_OK == b64Decode((char*)crl->data, crl->len, out, outSize, &len))
+ {
+ memcpy(crl->data, out, len);
+ crl->len = (size_t)len;
+
+ OIC_LOG (ERROR, TAG, "Crl successfully decoded to base64.");
+ }
+ else
+ {
+ OIC_LOG (ERROR, TAG, "Base64 decoding failed.");
+ }
+ OICFree(out);
+ }
+
+ out->len = 0;
+
+ out->data = OICRealloc(out->data, crl->len);
+ if (out->data)
{
- memcpy(crlArray.data, crlRes->CrlData.data, crlRes->CrlData.len);
- crlArray.len = crlRes->CrlData.len;
+ memcpy(out->data, crl->data, crl->len);
+ out->len = crl->len;
}
else
{
- crlArray.len = 0;
+ OIC_LOG(ERROR, TAG, "Can't allocate memory for out->data");
}
- DeleteCrlBinData(crlRes);
+ DeleteCrl(crlRes);
}