1 //******************************************************************
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
25 #include "oic_malloc.h"
28 #include "resourcemanager.h"
29 #include "psinterface.h"
31 #include "srmresourcestrings.h"
32 #include "doxmresource.h"
33 #include "srmutility.h"
35 #include "crlresource.h"
38 #endif /* __WITH_X509__ */
40 #define TAG PCF("SRM-CRL")
43 #define SEPARATOR_LEN (1)
44 #define JSON_CRL_NAME "\"CRL\""
45 #define JSON_CRL_NAME_LEN (5)
46 #define OIC_JSON_CRL_NAME "crl"
47 #define OIC_JSON_CRL_ID "CRLId"
48 #define OIC_JSON_CRL_THIS_UPDATE "ThisUpdate"
49 #define OIC_JSON_CRL_DATA "CRLData"
50 #define CRL_DEFAULT_CRL_ID 1
51 #define CRL_DEFAULT_THIS_UPDATE "150101000000Z"
52 #define CRL_DEFAULT_CRL_DATA "-"
54 static OCResourceHandle gCrlHandle = NULL;
55 static OicSecCrl_t *gCrl = NULL;
58 void DeleteCrlBinData(OicSecCrl_t *crl)
63 OICFree(crl->ThisUpdate.data);
66 OICFree(crl->CrlData.data);
73 char *BinToCrlJSON(const OicSecCrl_t *crl)
80 char *base64Buff = NULL;
82 uint32_t base64CRLLen = 0;
83 B64Result b64Ret = B64_OK;
85 cJSON *jsonRoot = cJSON_CreateObject();
86 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
87 cJSON *jsonCrl = cJSON_CreateObject();
88 VERIFY_NON_NULL(TAG, jsonCrl, ERROR);
90 cJSON_AddItemToObject(jsonRoot, OIC_JSON_CRL_NAME, jsonCrl);
93 cJSON_AddNumberToObject(jsonCrl, OIC_JSON_CRL_ID, (int)crl->CrlId);
95 //ThisUpdate -- Mandatory
97 base64CRLLen = B64ENCODE_OUT_SAFESIZE(crl->ThisUpdate.len);
98 base64Buff = OICMalloc(base64CRLLen);
99 b64Ret = b64Encode(crl->ThisUpdate.data, crl->ThisUpdate.len, base64Buff,
100 base64CRLLen, &outLen);
101 VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
102 cJSON_AddStringToObject(jsonCrl, OIC_JSON_CRL_THIS_UPDATE, base64Buff);
105 //CRLData -- Mandatory
107 base64CRLLen = B64ENCODE_OUT_SAFESIZE(crl->CrlData.len);
108 base64Buff = OICMalloc(base64CRLLen);
109 b64Ret = b64Encode(crl->CrlData.data, crl->CrlData.len, base64Buff,
110 base64CRLLen, &outLen);
111 VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
112 cJSON_AddStringToObject(jsonCrl, OIC_JSON_CRL_DATA, base64Buff);
114 jsonStr = cJSON_PrintUnformatted(jsonRoot);
120 cJSON_Delete(jsonRoot);
125 OicSecCrl_t *JSONToCrlBin(const char * jsonStr)
132 OCStackResult ret = OC_STACK_ERROR;
133 OicSecCrl_t *crl = NULL;
134 cJSON *jsonCrl = NULL;
135 cJSON *jsonObj = NULL;
137 unsigned char *base64Buff = NULL;
138 uint32_t base64CRLLen = 0;
140 B64Result b64Ret = B64_OK;
142 cJSON *jsonRoot = cJSON_Parse(jsonStr);
143 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
145 jsonCrl = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRL_NAME);
146 VERIFY_NON_NULL(TAG, jsonCrl, ERROR);
147 crl = (OicSecCrl_t *)OICCalloc(1, sizeof(OicSecCrl_t));
148 VERIFY_NON_NULL(TAG, crl, ERROR);
151 jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_ID);
154 VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
155 crl->CrlId = (uint16_t)jsonObj->valueint;
157 else // PUT/POST JSON may not have CRLId so set it to the gCRList->CRLId
159 VERIFY_NON_NULL(TAG, gCrl, ERROR);
160 crl->CrlId = gCrl->CrlId;
163 //ThisUpdate -- Mandatory
164 jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_THIS_UPDATE);
167 VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
168 if(cJSON_String == jsonObj->type)
170 //Check for empty string, in case ThisUpdate field has not been set yet
171 if (jsonObj->valuestring[0])
173 base64CRLLen = B64ENCODE_OUT_SAFESIZE(strlen(jsonObj->valuestring));
174 base64Buff = OICMalloc(base64CRLLen);
175 b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
176 base64CRLLen, &outLen);
177 VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= base64CRLLen),
179 crl->ThisUpdate.data = OICMalloc(outLen + 1);
180 memcpy(crl->ThisUpdate.data, base64Buff, outLen);
181 crl->ThisUpdate.len = outLen;
187 else // PUT/POST JSON will not have ThisUpdate so set it to the gCRList->ThisUpdate
189 VERIFY_NON_NULL(TAG, gCrl, ERROR);
190 outLen = gCrl->ThisUpdate.len;
191 crl->ThisUpdate.data = OICMalloc(outLen + 1);
192 memcpy(crl->ThisUpdate.data, gCrl->ThisUpdate.data, outLen);
193 crl->ThisUpdate.len = outLen;
196 //CRLData -- Mandatory
197 jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_DATA);
200 VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
201 if(cJSON_String == jsonObj->type)
203 //Check for empty string, in case CRLData field has not been set yet
204 if (jsonObj->valuestring[0])
207 base64CRLLen = B64ENCODE_OUT_SAFESIZE(strlen(jsonObj->valuestring));
208 base64Buff = OICMalloc(base64CRLLen);
209 b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
210 base64CRLLen, &outLen);
211 VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= base64CRLLen),
213 crl->CrlData.data = OICMalloc(outLen + 1);
214 memcpy(crl->CrlData.data, base64Buff, outLen);
215 crl->CrlData.len = outLen;
221 else // PUT/POST JSON will not have CRLData so set it to the gCRList->CRLData
223 VERIFY_NON_NULL(TAG, gCrl, ERROR);
224 outLen = gCrl->CrlData.len;
225 crl->CrlData.data = OICMalloc(outLen + 1);
226 memcpy(crl->CrlData.data, gCrl->CrlData.data, outLen);
227 crl->CrlData.len = outLen;
232 cJSON_Delete(jsonRoot);
235 if (OC_STACK_OK != ret)
237 DeleteCrlBinData(crl);
243 OCStackResult UpdateCRLResource(const OicSecCrl_t *crl)
245 char *jsonStr = NULL;
246 OCStackResult res = OC_STACK_ERROR;
248 jsonStr = BinToCrlJSON((OicSecCrl_t *) crl);
251 return OC_STACK_ERROR;
254 cJSON *jsonObj = cJSON_Parse(jsonStr);
259 return OC_STACK_ERROR;
262 res = UpdateSVRDatabase(OIC_JSON_CRL_NAME, jsonObj);
263 cJSON_Delete(jsonObj);
268 static OCEntityHandlerResult HandleCRLPostRequest(const OCEntityHandlerRequest *ehRequest)
270 OCEntityHandlerResult ehRet = OC_EH_ERROR;
272 char *jsonCRL = (char *)(((OCSecurityPayload *)ehRequest->payload)->securityData);
276 OC_LOG(INFO, TAG, PCF("UpdateSVRDB..."));
277 OC_LOG_V(INFO, TAG, PCF("crl: \"%s\""), jsonCRL);
279 cJSON *jsonObj = cJSON_Parse(jsonCRL);
280 OicSecCrl_t *crl = NULL;
281 crl = JSONToCrlBin(jsonCRL);
284 OC_LOG(ERROR, TAG, PCF("Error JSONToCrlBin"));
287 gCrl->CrlId = crl->CrlId;
289 OICFree(gCrl->ThisUpdate.data);
290 gCrl->ThisUpdate.data = NULL;
291 gCrl->ThisUpdate.data = OICMalloc(crl->ThisUpdate.len);
292 memcpy(gCrl->ThisUpdate.data, crl->ThisUpdate.data, crl->ThisUpdate.len);
293 gCrl->ThisUpdate.len = crl->ThisUpdate.len;
295 OICFree(gCrl->CrlData.data);
296 gCrl->CrlData.data = NULL;
297 gCrl->CrlData.data = OICMalloc(crl->CrlData.len);
298 memcpy(gCrl->CrlData.data, crl->CrlData.data, crl->CrlData.len);
299 gCrl->CrlData.len = crl->CrlData.len;
301 if (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_CRL_NAME, jsonObj))
303 OC_LOG(INFO, TAG, PCF("UpdateSVRDB == OK"));
304 ehRet = OC_EH_RESOURCE_CREATED;
307 DeleteCrlBinData(crl);
308 cJSON_Delete(jsonObj);
312 // Send payload to request originator
313 SendSRMResponse(ehRequest, ehRet, NULL);
315 OC_LOG_V(INFO, TAG, PCF("%s RetVal %d"), __func__, ehRet);
321 * This internal method is the entity handler for CRL resource and
322 * will handle REST request (GET/PUT/POST/DEL) for them.
324 OCEntityHandlerResult CRLEntityHandler(OCEntityHandlerFlag flag,
325 OCEntityHandlerRequest *ehRequest,
326 void *callbackParameter)
328 OCEntityHandlerResult ehRet = OC_EH_ERROR;
329 (void)callbackParameter;
336 OC_LOG(INFO, TAG, PCF("Handle CRL resource"));
338 if (flag & OC_REQUEST_FLAG)
340 // TODO : Handle PUT and DEL methods
341 OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
342 switch (ehRequest->method)
345 OC_LOG (INFO, TAG, PCF("Not implemented request method."));
346 //ehRet = HandleCRLGetRequest(ehRequest);
350 ehRet = HandleCRLPostRequest(ehRequest);
355 SendSRMResponse(ehRequest, ehRet, NULL);
363 * This internal method is used to create '/oic/sec/crl' resource.
365 OCStackResult CreateCRLResource()
368 ret = OCCreateResource(&gCrlHandle,
369 OIC_RSRC_TYPE_SEC_CRL,
376 if (OC_STACK_OK != ret)
378 OC_LOG(FATAL, TAG, PCF("Unable to instantiate CRL resource"));
385 * Get the default value
386 * @retval NULL for now. Update it when we finalize the default info.
388 static OicSecCrl_t *GetCrlDefault()
390 OicSecCrl_t *defaultCrl = NULL;
391 defaultCrl = (OicSecCrl_t *)OICCalloc(1, sizeof(OicSecCrl_t));
393 defaultCrl->CrlId = CRL_DEFAULT_CRL_ID;
395 defaultCrl->CrlData.len = strlen(CRL_DEFAULT_CRL_DATA);
396 defaultCrl->CrlData.data = OICMalloc(defaultCrl->CrlData.len);
397 memcpy(defaultCrl->CrlData.data, CRL_DEFAULT_CRL_DATA, defaultCrl->CrlData.len);
399 defaultCrl->ThisUpdate.len = strlen(CRL_DEFAULT_THIS_UPDATE);
400 defaultCrl->ThisUpdate.data = OICMalloc(defaultCrl->ThisUpdate.len);
401 memcpy(defaultCrl->ThisUpdate.data, CRL_DEFAULT_THIS_UPDATE, defaultCrl->ThisUpdate.len);
407 * Initialize CRL resource by loading data from persistent storage.
410 * OC_STACK_OK - no errors
411 * OC_STACK_ERROR - stack process error
413 OCStackResult InitCRLResource()
415 OCStackResult ret = OC_STACK_ERROR;
416 char* jsonSVRDatabase;
418 //Read CRL resource from PS
419 jsonSVRDatabase = GetSVRDatabase();
423 //Convert JSON CRL into binary format
424 gCrl = JSONToCrlBin(jsonSVRDatabase);
427 * If SVR database in persistent storage got corrupted or
428 * is not available for some reason, a default CrlResource is created
429 * which allows user to initiate CrlResource provisioning again.
431 if (!jsonSVRDatabase || !gCrl)
433 gCrl = GetCrlDefault();
436 ret = CreateCRLResource();
437 OICFree(jsonSVRDatabase);
442 * Perform cleanup for ACL resources.
444 void DeInitCRLResource()
446 OCDeleteResource(gCrlHandle);
448 DeleteCrlBinData(gCrl);
452 OicSecCrl_t *GetCRLResource()
454 OicSecCrl_t *crl = NULL;
456 //Read CRL resource from PS
457 char* jsonSVRDatabase = GetSVRDatabase();
461 //Convert JSON CRL into binary format
462 crl = JSONToCrlBin(jsonSVRDatabase);
465 * If SVR database in persistent storage got corrupted or
466 * is not available for some reason, a default CrlResource is created
467 * which allows user to initiate CrlResource provisioning again.
469 if (!jsonSVRDatabase || !crl)
471 crl = GetCrlDefault();
473 OICFree(jsonSVRDatabase);
480 cJSON *jsonCrl = NULL;
481 cJSON *jsonObj = NULL;
482 char *jsonSVRDatabase = GetSVRDatabase();
485 cJSON *jsonRoot = cJSON_Parse(jsonSVRDatabase);
486 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
488 jsonCrl = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRL_NAME);
489 VERIFY_NON_NULL(TAG, jsonCrl, ERROR);
491 //CRLData -- Mandatory
492 jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_DATA);
495 VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
496 if(cJSON_String == jsonObj->type)
498 //Check for empty string, in case CRLData field has not been set yet
499 if (jsonObj->valuestring[0])
501 ret = jsonObj->valuestring;
506 OICFree(jsonSVRDatabase);
507 cJSON_Delete(jsonRoot);