//CredType -- Mandatory
cJSON_AddNumberToObject(jsonCred, OIC_JSON_CREDTYPE_NAME,(int)cred->credType);
-#if 0
+#ifdef __WITH_X509__
//PublicData -- Not Mandatory
if(cred->publicData.data)
{
+ if (SIGNED_ASYMMETRIC_KEY == cred->credType)
+ {
+ cJSON_AddItemToObject(jsonCred, OIC_JSON_PUBLICDATA_NAME,
+ cJSON_Parse(cred->publicData.data));
+ }
+ else
+ {
cJSON_AddStringToObject(jsonCred, OIC_JSON_PUBLICDATA_NAME, cred->publicData.data);
+ }
}
-#endif
+#endif /*__WITH_X509__*/
//PrivateData -- Not Mandatory
if(cred->privateData.data)
{
+#ifdef __WITH_X509__
+ if (SIGNED_ASYMMETRIC_KEY == cred->credType)
+ {
+ cJSON_AddItemToObject(jsonCred, OIC_JSON_PRIVATEDATA_NAME,
+ cJSON_Parse(cred->privateData.data));
+ }
+ else
+ {
+ cJSON_AddStringToObject(jsonCred, OIC_JSON_PRIVATEDATA_NAME, cred->privateData.data);
+ }
+#else
cJSON_AddStringToObject(jsonCred, OIC_JSON_PRIVATEDATA_NAME, cred->privateData.data);
+#endif
}
//Period -- Not Mandatory
VERIFY_NON_NULL(TAG, jsonObj, ERROR);
VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
}
- if(jsonObj && cJSON_String == jsonObj->type)
+#ifdef __WITH_X509__
+ else if (cred->credType & SIGNED_ASYMMETRIC_KEY)
{
- jsonObjLen = strlen(jsonObj->valuestring) + 1;
- cred->privateData.data = (char *)OICMalloc(jsonObjLen);
- VERIFY_NON_NULL(TAG, (cred->privateData.data), ERROR);
- strncpy((char *)cred->privateData.data, (char *)jsonObj->valuestring, jsonObjLen);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_Object == jsonObj->type, ERROR);
+ }
+#endif // __WITH_X509__
+ if (NULL != jsonObj)
+ {
+ if (cJSON_String == jsonObj->type)
+ {
+ jsonObjLen = strlen(jsonObj->valuestring) + 1;
+ cred->privateData.data = (char *)OICMalloc(jsonObjLen);
+ VERIFY_NON_NULL(TAG, (cred->privateData.data), ERROR);
+ strncpy((char *)cred->privateData.data, (char *)jsonObj->valuestring, jsonObjLen);
+ }
+#ifdef __WITH_X509__
+ else if (SIGNED_ASYMMETRIC_KEY == cred->credType && cJSON_Object == jsonObj->type)
+ {
+ cred->privateData.data = cJSON_PrintUnformatted(jsonObj);
+ VERIFY_NON_NULL(TAG, (cred->privateData.data), ERROR);
+ }
+#endif // __WITH_X509__
+ }
+
+ //PublicData is mandatory only for SIGNED_ASYMMETRIC_KEY credentials type.
+ jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PUBLICDATA_NAME);
+#ifdef __WITH_X509__
+ if (cred->credType & SIGNED_ASYMMETRIC_KEY)
+ {
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_Object == jsonObj->type, ERROR);
+ }
+#endif // __WITH_X509__
+ if (NULL != jsonObj)
+ {
+ if (cJSON_String == jsonObj->type)
+ {
+ jsonObjLen = strlen(jsonObj->valuestring) + 1;
+ cred->publicData.data = (char *)OICMalloc(jsonObjLen);
+ VERIFY_NON_NULL(TAG, (cred->publicData.data), ERROR);
+ strncpy((char *)cred->publicData.data, (char *)jsonObj->valuestring, jsonObjLen);
+ }
+#ifdef __WITH_X509__
+ else if (SIGNED_ASYMMETRIC_KEY == cred->credType && cJSON_Object == jsonObj->type)
+ {
+ cred->publicData.data = cJSON_PrintUnformatted(jsonObj);
+ VERIFY_NON_NULL(TAG, (cred->publicData.data), ERROR);
+ }
+#endif // __WITH_X509__
}
//Period -- Not Mandatory
SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
cred->credType = credType;
-#if 0
+#ifdef __WITH_X509__
if(publicData)
{
cred->publicData.data = (char *)OICMalloc(strlen(publicData)+1);
VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
strncpy((char *)cred->publicData.data, publicData, strlen(publicData)+1);
}
-#endif
+#endif // __WITH_X509__
if(privateData)
{
//list and updating svr database.
ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
}
-
return ret;
}
return ehRet;
}
-
/*
* This internal method is the entity handler for Cred resources
* to handle REST request (PUT/POST/DEL)
}
#endif /* __WITH_DTLS__ */
+#ifdef __WITH_X509__
+#define CERT_LEN_PREFIX (3)
+#define BYTE_SIZE (8) //bits
+#define PUB_KEY_X_COORD ("x")
+#define PUB_KEY_Y_COORD ("y")
+#define CERTIFICATE ("x5c")
+#define PRIVATE_KEY ("d")
+
+
+static void WriteCertPrefix(uint8_t *prefix, uint32_t certLen)
+{
+ for (size_t i = 0; i < CERT_LEN_PREFIX; ++i)
+ {
+ prefix[i] = (certLen >> (BYTE_SIZE * (CERT_LEN_PREFIX - 1 - i))) & 0xFF;
+ }
+}
+
+static uint32_t ParseCertPrefix(uint8_t *prefix)
+{
+ uint32_t res = 0;
+ if(NULL != prefix)
+ {
+ for(int i=0; i < CERT_LEN_PREFIX; ++i)
+ {
+ res |= (((uint32_t) prefix[i]) << ((CERT_LEN_PREFIX - 1 -i) * BYTE_SIZE));
+ }
+ }
+ return res;
+}
+
+static uint32_t appendCert2Chain(uint8_t *appendPoint, char *cert, uint32_t max_len)
+{
+ uint32_t ret = 0;
+ VERIFY_NON_NULL(TAG, appendPoint, ERROR);
+ VERIFY_NON_NULL(TAG, cert, ERROR);
+
+ uint32_t certLen;
+ VERIFY_SUCCESS(TAG, B64_OK == b64Decode(cert, strlen(cert), appendPoint + CERT_LEN_PREFIX,
+ max_len - CERT_LEN_PREFIX, &certLen), ERROR);
+ WriteCertPrefix(appendPoint, certLen);
+
+ ret = certLen + CERT_LEN_PREFIX;
+exit:
+ return ret;
+}
+
+static OCStackResult GetCAPublicKeyData(CADtlsCertCreds_t *credInfo){
+ OCStackResult ret = OC_STACK_ERROR;
+ uint8_t *ccPtr = credInfo->certificateChain;
+ for(uint32_t i =0; i < credInfo->chainLen - 1; ++i)
+ {
+ ccPtr += CERT_LEN_PREFIX + ParseCertPrefix(ccPtr);
+ }
+
+ ByteArray cert = {
+ .data = ccPtr + CERT_LEN_PREFIX,
+ .len = ParseCertPrefix(ccPtr)
+ };
+ CertificateX509 certStruct;
+
+ VERIFY_SUCCESS(TAG, PKI_SUCCESS == DecodeCertificate(cert, &certStruct), ERROR);
+
+ INC_BYTE_ARRAY(certStruct.pubKey, 2);
+
+ memcpy(credInfo->rootPublicKeyX, certStruct.pubKey.data, PUBLIC_KEY_SIZE / 2);
+ memcpy(credInfo->rootPublicKeyY, certStruct.pubKey.data + PUBLIC_KEY_SIZE / 2, PUBLIC_KEY_SIZE / 2);
+
+ ret = OC_STACK_OK;
+ exit:
+ return ret;
+}
+
+static OCStackResult GetCertCredPublicData(CADtlsCertCreds_t *credInfo, OicSecCred_t *cred)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+ VERIFY_NON_NULL(TAG, credInfo, ERROR);
+ VERIFY_NON_NULL(TAG, cred, ERROR);
+ VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
+ //VERIFY_SUCCESS(TAG, NULL == credInfo->certificateChain.data, ERROR);
+ cJSON *jsonRoot = cJSON_Parse(cred->publicData.data);
+ VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+
+ //Get certificate chain
+ cJSON *jsonObj = cJSON_GetObjectItem(jsonRoot, CERTIFICATE);//TODO define field names constants
+ VERIFY_SUCCESS(TAG, NULL != jsonObj && cJSON_Array == jsonObj->type, ERROR);
+
+ size_t certChainLen = cJSON_GetArraySize(jsonObj);
+ credInfo->chainLen = certChainLen;
+ VERIFY_SUCCESS(TAG, MAX_CHAIN_LEN >= certChainLen, ERROR);
+
+ uint32_t len = 0;
+ for (size_t i = 0; i < certChainLen; ++i)
+ {
+ cJSON *item = cJSON_GetArrayItem(jsonObj, i);
+ VERIFY_SUCCESS(TAG, cJSON_String == item->type, ERROR);
+ uint32_t appendedLen = appendCert2Chain(credInfo->certificateChain + len, item->valuestring,
+ MAX_REQUEST_LENGTH - len);
+ VERIFY_SUCCESS(TAG, 0 != appendedLen, ERROR);
+ len += appendedLen;
+ }
+ credInfo->certificateChainLen = len;
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == GetCAPublicKeyData(credInfo), ERROR);
+ ret = OC_STACK_OK;
+exit:
+ cJSON_Delete(jsonRoot);
+ return ret;
+}
+
+static OCStackResult GetCertCredPrivateData(CADtlsCertCreds_t *credInfo, OicSecCred_t *cred)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+ VERIFY_NON_NULL(TAG, credInfo, ERROR);
+ VERIFY_NON_NULL(TAG, cred, ERROR);
+ VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
+ cJSON *jsonRoot = cJSON_Parse(cred->privateData.data);
+ VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+
+ cJSON *jsonObj = cJSON_GetObjectItem(jsonRoot, PRIVATE_KEY);//TODO define field names constants
+ VERIFY_SUCCESS(TAG, NULL != jsonObj && cJSON_String == jsonObj->type, ERROR);
+
+ uint32_t read = 0u;
+ VERIFY_SUCCESS(TAG, B64_OK == b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring),
+ credInfo->devicePrivateKey, PRIVATE_KEY_SIZE, &read)
+ && PRIVATE_KEY_SIZE == read, ERROR);
+
+ ret = OC_STACK_OK;
+
+exit:
+ cJSON_Delete(jsonRoot);
+ return ret;
+}
+
+OCStackResult GetDtlsCertCredentials(CADtlsCertCreds_t *credInfo)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+ VERIFY_NON_NULL(TAG, credInfo, ERROR);
+ if (NULL == gCred)
+ {
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == InitCredResource(), ERROR);
+ }
+
+ OicSecCred_t *cred = NULL;
+ LL_SEARCH_SCALAR(gCred, cred, credType, SIGNED_ASYMMETRIC_KEY);
+ VERIFY_NON_NULL(TAG, cred, ERROR);
+
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == GetCertCredPrivateData(credInfo, cred), ERROR);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == GetCertCredPublicData(credInfo, cred), ERROR);
+
+ ret = OC_STACK_OK;
+exit:
+
+ return ret;
+}
+#undef CERT_LEN_PREFIX
+#endif /* __WITH_X509__ */
--- /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 <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 "srmresourcestrings.h"
+#include "doxmresource.h"
+#include "srmutility.h"
+#ifdef __WITH_X509__
+#include "crlresource.h"
+#include "crl.h"
+#include "ckm_info.h"
+#endif /* __WITH_X509__ */
+
+#define TAG PCF("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 CRL_DEFAULT_THIS_UPDATE "150101000000Z"
+#define CRL_DEFAULT_CRL_DATA "-"
+
+static OCResourceHandle gCrlHandle = NULL;
+static OicSecCrl_t *gCrl = NULL;
+
+
+void DeleteCrlBinData(OicSecCrl_t *crl)
+{
+ if (crl)
+ {
+ //Clean ThisUpdate
+ OICFree(crl->ThisUpdate.data);
+
+ //clean CrlData
+ OICFree(crl->CrlData.data);
+
+ //Clean crl itself
+ OICFree(crl);
+ }
+}
+
+char *BinToCrlJSON(const OicSecCrl_t *crl)
+{
+ if (NULL == crl)
+ {
+ return NULL;
+ }
+
+ 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);
+
+ cJSON_AddItemToObject(jsonRoot, OIC_JSON_CRL_NAME, jsonCrl);
+
+ //CRLId -- Mandatory
+ cJSON_AddNumberToObject(jsonCrl, OIC_JSON_CRL_ID, (int)crl->CrlId);
+
+ //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);
+
+ //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);
+
+ jsonStr = cJSON_PrintUnformatted(jsonRoot);
+
+exit:
+ OICFree(base64Buff);
+ if (jsonRoot)
+ {
+ cJSON_Delete(jsonRoot);
+ }
+ return jsonStr;
+}
+
+OicSecCrl_t *JSONToCrlBin(const char * jsonStr)
+{
+ if (NULL == jsonStr)
+ {
+ return NULL;
+ }
+
+ OCStackResult ret = OC_STACK_ERROR;
+ OicSecCrl_t *crl = NULL;
+ cJSON *jsonCrl = NULL;
+ cJSON *jsonObj = NULL;
+
+ unsigned char *base64Buff = NULL;
+ uint32_t base64CRLLen = 0;
+ uint32_t outLen = 0;
+ B64Result b64Ret = B64_OK;
+
+ cJSON *jsonRoot = cJSON_Parse(jsonStr);
+ VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+
+ 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)
+ {
+ VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+ crl->CrlId = (uint16_t)jsonObj->valueint;
+ }
+ else // PUT/POST JSON may not have CRLId so set it to the gCRList->CRLId
+ {
+ VERIFY_NON_NULL(TAG, gCrl, ERROR);
+ crl->CrlId = gCrl->CrlId;
+ }
+
+ //ThisUpdate -- Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_THIS_UPDATE);
+ if(jsonObj)
+ {
+ VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
+ if(cJSON_String == jsonObj->type)
+ {
+ //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;
+ }
+ }
+ }
+ else // PUT/POST JSON will not have ThisUpdate so set it to the gCRList->ThisUpdate
+ {
+ 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;
+ }
+
+ //CRLData -- Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_DATA);
+ if(jsonObj)
+ {
+ 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])
+ {
+ 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;
+ }
+ }
+ }
+ else // PUT/POST JSON will not have CRLData so set it to the gCRList->CRLData
+ {
+ 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;
+ }
+
+ ret = OC_STACK_OK;
+exit:
+ cJSON_Delete(jsonRoot);
+ OICFree(base64Buff);
+ base64Buff = NULL;
+ if (OC_STACK_OK != ret)
+ {
+ DeleteCrlBinData(crl);
+ crl = NULL;
+ }
+ return crl;
+}
+
+OCStackResult UpdateCRLResource(const OicSecCrl_t *crl)
+{
+ char *jsonStr = NULL;
+ OCStackResult res = OC_STACK_ERROR;
+
+ jsonStr = BinToCrlJSON((OicSecCrl_t *) crl);
+ if (!jsonStr)
+ {
+ return OC_STACK_ERROR;
+ }
+
+ cJSON *jsonObj = cJSON_Parse(jsonStr);
+ OICFree(jsonStr);
+
+ if (jsonObj == NULL)
+ {
+ return OC_STACK_ERROR;
+ }
+
+ res = UpdateSVRDatabase(OIC_JSON_CRL_NAME, jsonObj);
+ cJSON_Delete(jsonObj);
+
+ return res;
+}
+
+static OCEntityHandlerResult HandleCRLPostRequest(const OCEntityHandlerRequest *ehRequest)
+{
+ OCEntityHandlerResult ehRet = OC_EH_ERROR;
+
+ char *jsonCRL = (char *)(((OCSecurityPayload *)ehRequest->payload)->securityData);
+
+ if (jsonCRL)
+ {
+ OC_LOG(INFO, TAG, PCF("UpdateSVRDB..."));
+ OC_LOG_V(INFO, TAG, PCF("crl: \"%s\""), jsonCRL);
+
+ cJSON *jsonObj = cJSON_Parse(jsonCRL);
+ OicSecCrl_t *crl = NULL;
+ crl = JSONToCrlBin(jsonCRL);
+ if (!crl)
+ {
+ OC_LOG(ERROR, TAG, PCF("Error JSONToCrlBin"));
+ }
+
+ gCrl->CrlId = crl->CrlId;
+
+ 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;
+
+ 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;
+
+ if (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_CRL_NAME, jsonObj))
+ {
+ OC_LOG(INFO, TAG, PCF("UpdateSVRDB == OK"));
+ ehRet = OC_EH_RESOURCE_CREATED;
+ }
+
+ DeleteCrlBinData(crl);
+ cJSON_Delete(jsonObj);
+
+ }
+
+ // Send payload to request originator
+ SendSRMResponse(ehRequest, ehRet, NULL);
+
+ OC_LOG_V(INFO, TAG, PCF("%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)
+{
+ OCEntityHandlerResult ehRet = OC_EH_ERROR;
+ (void)callbackParameter;
+
+ if (!ehRequest)
+ {
+ return ehRet;
+ }
+
+ OC_LOG(INFO, TAG, PCF("Handle CRL resource"));
+
+ if (flag & OC_REQUEST_FLAG)
+ {
+ // TODO : Handle PUT and DEL methods
+ OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
+ switch (ehRequest->method)
+ {
+ case OC_REST_GET:
+ OC_LOG (INFO, TAG, PCF("Not implemented request method."));
+ //ehRet = HandleCRLGetRequest(ehRequest);
+ break;
+
+ case OC_REST_POST:
+ ehRet = HandleCRLPostRequest(ehRequest);
+ break;
+
+ default:
+ ehRet = OC_EH_ERROR;
+ SendSRMResponse(ehRequest, ehRet, NULL);
+ }
+ }
+
+ return ehRet;
+}
+
+/*
+ * This internal method is used to create '/oic/sec/crl' resource.
+ */
+OCStackResult CreateCRLResource()
+{
+ OCStackResult ret;
+ ret = OCCreateResource(&gCrlHandle,
+ OIC_RSRC_TYPE_SEC_CRL,
+ OIC_MI_DEF,
+ OIC_RSRC_CRL_URI,
+ CRLEntityHandler,
+ NULL,
+ OC_OBSERVABLE);
+
+ if (OC_STACK_OK != ret)
+ {
+ OC_LOG(FATAL, TAG, PCF("Unable to instantiate CRL resource"));
+ DeInitCRLResource();
+ }
+ return ret;
+}
+
+/**
+ * Get the default value
+ * @retval NULL for now. Update it when we finalize the default info.
+ */
+static OicSecCrl_t *GetCrlDefault()
+{
+ OicSecCrl_t *defaultCrl = NULL;
+ defaultCrl = (OicSecCrl_t *)OICCalloc(1, sizeof(OicSecCrl_t));
+
+ defaultCrl->CrlId = CRL_DEFAULT_CRL_ID;
+
+ 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);
+
+ 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);
+
+ return defaultCrl;
+}
+
+/**
+ * Initialize CRL resource by loading data from persistent storage.
+ *
+ * @retval
+ * OC_STACK_OK - no errors
+ * OC_STACK_ERROR - stack process error
+ */
+OCStackResult InitCRLResource()
+{
+ OCStackResult ret = OC_STACK_ERROR;
+ char* jsonSVRDatabase;
+
+ //Read CRL resource from PS
+ jsonSVRDatabase = GetSVRDatabase();
+
+ if (jsonSVRDatabase)
+ {
+ //Convert JSON CRL into binary format
+ gCrl = JSONToCrlBin(jsonSVRDatabase);
+ }
+ /*
+ * 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)
+ {
+ gCrl = GetCrlDefault();
+ }
+
+ ret = CreateCRLResource();
+ OICFree(jsonSVRDatabase);
+ return ret;
+}
+
+/**
+ * Perform cleanup for ACL resources.
+ */
+void DeInitCRLResource()
+{
+ OCDeleteResource(gCrlHandle);
+ gCrlHandle = NULL;
+ DeleteCrlBinData(gCrl);
+ gCrl = NULL;
+}
+
+OicSecCrl_t *GetCRLResource()
+{
+ OicSecCrl_t *crl = NULL;
+
+ //Read CRL resource from PS
+ char* jsonSVRDatabase = GetSVRDatabase();
+
+ if (jsonSVRDatabase)
+ {
+ //Convert JSON CRL into binary format
+ crl = JSONToCrlBin(jsonSVRDatabase);
+ }
+ /*
+ * 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)
+ {
+ crl = GetCrlDefault();
+ }
+ OICFree(jsonSVRDatabase);
+
+ return crl;
+}
+
+char *GetBase64CRL()
+{
+ cJSON *jsonCrl = NULL;
+ cJSON *jsonObj = NULL;
+ char *jsonSVRDatabase = GetSVRDatabase();
+ char* ret = NULL;
+
+ cJSON *jsonRoot = cJSON_Parse(jsonSVRDatabase);
+ VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+
+ jsonCrl = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRL_NAME);
+ VERIFY_NON_NULL(TAG, jsonCrl, ERROR);
+
+ //CRLData -- Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_DATA);
+ if(jsonObj)
+ {
+ 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;
+ }
+ }
+ }
+exit:
+ OICFree(jsonSVRDatabase);
+ cJSON_Delete(jsonRoot);
+ return ret;
+}