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"
37 #endif /* __WITH_X509__ */
42 #define SEPARATOR_LEN (1)
43 #define JSON_CRL_NAME "\"CRL\""
44 #define JSON_CRL_NAME_LEN (5)
45 #define OIC_JSON_CRL_NAME "crl"
46 #define OIC_JSON_CRL_ID "CRLId"
47 #define OIC_JSON_CRL_THIS_UPDATE "ThisUpdate"
48 #define OIC_JSON_CRL_DATA "CRLData"
49 #define CRL_DEFAULT_CRL_ID 1
50 #define CRL_DEFAULT_THIS_UPDATE "150101000000Z"
51 #define CRL_DEFAULT_CRL_DATA "-"
53 static OCResourceHandle gCrlHandle = NULL;
54 static OicSecCrl_t *gCrl = NULL;
57 void DeleteCrlBinData(OicSecCrl_t *crl)
62 OICFree(crl->ThisUpdate.data);
65 OICFree(crl->CrlData.data);
72 char *BinToCrlJSON(const OicSecCrl_t *crl, const bool isIncResName)
79 char *base64Buff = NULL;
81 uint32_t base64CRLLen = 0;
82 B64Result b64Ret = B64_OK;
85 cJSON *jsonRoot = cJSON_CreateObject();
86 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
88 cJSON *jsonCrl = NULL;
91 jsonCrl = cJSON_CreateObject();
92 VERIFY_NON_NULL(TAG, jsonCrl, ERROR);
93 cJSON_AddItemToObject(jsonRoot, OIC_JSON_CRL_NAME, jsonCrl);
101 cJSON_AddNumberToObject(jsonCrl, OIC_JSON_CRL_ID, (int)crl->CrlId);
103 //ThisUpdate -- Mandatory
105 base64CRLLen = B64ENCODE_OUT_SAFESIZE(crl->ThisUpdate.len);
106 base64Buff = OICMalloc(base64CRLLen);
107 b64Ret = b64Encode(crl->ThisUpdate.data, crl->ThisUpdate.len, base64Buff,
108 base64CRLLen, &outLen);
109 VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
110 cJSON_AddStringToObject(jsonCrl, OIC_JSON_CRL_THIS_UPDATE, base64Buff);
113 //CRLData -- Mandatory
115 base64CRLLen = B64ENCODE_OUT_SAFESIZE(crl->CrlData.len);
116 base64Buff = OICMalloc(base64CRLLen);
117 b64Ret = b64Encode(crl->CrlData.data, crl->CrlData.len, base64Buff,
118 base64CRLLen, &outLen);
119 VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
120 cJSON_AddStringToObject(jsonCrl, OIC_JSON_CRL_DATA, base64Buff);
122 jsonStr = cJSON_PrintUnformatted(jsonRoot);
128 cJSON_Delete(jsonRoot);
133 OicSecCrl_t *JSONToCrlBin(const char * jsonStr, const bool isIncResName)
140 OCStackResult ret = OC_STACK_ERROR;
141 OicSecCrl_t *crl = NULL;
142 cJSON *jsonCrl = NULL;
143 cJSON *jsonObj = NULL;
145 unsigned char *base64Buff = NULL;
146 uint32_t base64CRLLen = 0;
148 B64Result b64Ret = B64_OK;
150 cJSON *jsonRoot = cJSON_Parse(jsonStr);
151 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
155 jsonCrl = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRL_NAME);
161 VERIFY_NON_NULL(TAG, jsonCrl, ERROR);
163 crl = (OicSecCrl_t *)OICCalloc(1, sizeof(OicSecCrl_t));
164 VERIFY_NON_NULL(TAG, crl, ERROR);
167 jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_ID);
170 VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
171 crl->CrlId = (uint16_t)jsonObj->valueint;
173 else // PUT/POST JSON may not have CRLId so set it to the gCRList->CRLId
175 VERIFY_NON_NULL(TAG, gCrl, ERROR);
176 crl->CrlId = gCrl->CrlId;
179 //ThisUpdate -- Mandatory
180 jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_THIS_UPDATE);
183 VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
184 if(cJSON_String == jsonObj->type)
186 //Check for empty string, in case ThisUpdate field has not been set yet
187 if (jsonObj->valuestring[0])
189 base64CRLLen = B64ENCODE_OUT_SAFESIZE(strlen(jsonObj->valuestring));
190 base64Buff = OICMalloc(base64CRLLen);
191 b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
192 base64CRLLen, &outLen);
193 VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= base64CRLLen),
195 crl->ThisUpdate.data = OICMalloc(outLen + 1);
196 memcpy(crl->ThisUpdate.data, base64Buff, outLen);
197 crl->ThisUpdate.len = outLen;
203 else // PUT/POST JSON will not have ThisUpdate so set it to the gCRList->ThisUpdate
205 VERIFY_NON_NULL(TAG, gCrl, ERROR);
206 outLen = gCrl->ThisUpdate.len;
207 crl->ThisUpdate.data = OICMalloc(outLen + 1);
208 memcpy(crl->ThisUpdate.data, gCrl->ThisUpdate.data, outLen);
209 crl->ThisUpdate.len = outLen;
212 //CRLData -- Mandatory
213 jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_DATA);
216 VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
217 if(cJSON_String == jsonObj->type)
219 //Check for empty string, in case CRLData field has not been set yet
220 if (jsonObj->valuestring[0])
223 base64CRLLen = B64ENCODE_OUT_SAFESIZE(strlen(jsonObj->valuestring));
224 base64Buff = OICMalloc(base64CRLLen);
225 b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
226 base64CRLLen, &outLen);
227 VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= base64CRLLen),
229 crl->CrlData.data = OICMalloc(outLen + 1);
230 memcpy(crl->CrlData.data, base64Buff, outLen);
231 crl->CrlData.len = outLen;
237 else // PUT/POST JSON will not have CRLData so set it to the gCRList->CRLData
239 VERIFY_NON_NULL(TAG, gCrl, ERROR);
240 outLen = gCrl->CrlData.len;
241 crl->CrlData.data = OICMalloc(outLen + 1);
242 memcpy(crl->CrlData.data, gCrl->CrlData.data, outLen);
243 crl->CrlData.len = outLen;
248 cJSON_Delete(jsonRoot);
251 if (OC_STACK_OK != ret)
253 DeleteCrlBinData(crl);
259 OCStackResult UpdateCRLResource(const OicSecCrl_t *crl)
261 char *jsonStr = NULL;
262 OCStackResult res = OC_STACK_ERROR;
264 jsonStr = BinToCrlJSON((OicSecCrl_t *) crl, true);
267 return OC_STACK_ERROR;
270 cJSON *jsonObj = cJSON_Parse(jsonStr);
275 return OC_STACK_ERROR;
278 res = UpdateSVRDatabase(OIC_JSON_CRL_NAME, jsonObj);
279 cJSON_Delete(jsonObj);
284 static OCEntityHandlerResult HandleCRLPostRequest(const OCEntityHandlerRequest *ehRequest)
286 OCEntityHandlerResult ehRet = OC_EH_ERROR;
288 char *jsonCRL = (char *)(((OCSecurityPayload *)ehRequest->payload)->securityData);
292 OC_LOG(INFO, TAG, "UpdateSVRDB...");
293 OC_LOG_V(INFO, TAG, "crl: \"%s\"", jsonCRL);
295 cJSON *jsonObj = cJSON_Parse(jsonCRL);
296 OicSecCrl_t *crl = NULL;
297 crl = JSONToCrlBin(jsonCRL, false);
300 OC_LOG(ERROR, TAG, "Error JSONToCrlBin");
303 gCrl->CrlId = crl->CrlId;
305 OICFree(gCrl->ThisUpdate.data);
306 gCrl->ThisUpdate.data = NULL;
307 gCrl->ThisUpdate.data = OICMalloc(crl->ThisUpdate.len);
308 memcpy(gCrl->ThisUpdate.data, crl->ThisUpdate.data, crl->ThisUpdate.len);
309 gCrl->ThisUpdate.len = crl->ThisUpdate.len;
311 OICFree(gCrl->CrlData.data);
312 gCrl->CrlData.data = NULL;
313 gCrl->CrlData.data = OICMalloc(crl->CrlData.len);
314 memcpy(gCrl->CrlData.data, crl->CrlData.data, crl->CrlData.len);
315 gCrl->CrlData.len = crl->CrlData.len;
317 if (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_CRL_NAME, jsonObj))
319 OC_LOG(INFO, TAG, "UpdateSVRDB == OK");
320 ehRet = OC_EH_RESOURCE_CREATED;
323 DeleteCrlBinData(crl);
324 cJSON_Delete(jsonObj);
328 // Send payload to request originator
329 SendSRMResponse(ehRequest, ehRet, NULL);
331 OC_LOG_V(INFO, TAG, "%s RetVal %d", __func__, ehRet);
337 * This internal method is the entity handler for CRL resource and
338 * will handle REST request (GET/PUT/POST/DEL) for them.
340 OCEntityHandlerResult CRLEntityHandler(OCEntityHandlerFlag flag,
341 OCEntityHandlerRequest *ehRequest,
342 void *callbackParameter)
344 OCEntityHandlerResult ehRet = OC_EH_ERROR;
345 (void)callbackParameter;
352 OC_LOG(INFO, TAG, "Handle CRL resource");
354 if (flag & OC_REQUEST_FLAG)
356 // TODO : Handle PUT and DEL methods
357 OC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
358 switch (ehRequest->method)
361 OC_LOG (INFO, TAG, "Not implemented request method.");
362 //ehRet = HandleCRLGetRequest(ehRequest);
366 ehRet = HandleCRLPostRequest(ehRequest);
371 SendSRMResponse(ehRequest, ehRet, NULL);
379 * This internal method is used to create '/oic/sec/crl' resource.
381 OCStackResult CreateCRLResource()
384 ret = OCCreateResource(&gCrlHandle,
385 OIC_RSRC_TYPE_SEC_CRL,
392 if (OC_STACK_OK != ret)
394 OC_LOG(FATAL, TAG, "Unable to instantiate CRL resource");
401 * Get the default value
402 * @retval NULL for now. Update it when we finalize the default info.
404 static OicSecCrl_t *GetCrlDefault()
406 OicSecCrl_t *defaultCrl = NULL;
407 defaultCrl = (OicSecCrl_t *)OICCalloc(1, sizeof(OicSecCrl_t));
409 defaultCrl->CrlId = CRL_DEFAULT_CRL_ID;
411 defaultCrl->CrlData.len = strlen(CRL_DEFAULT_CRL_DATA);
412 defaultCrl->CrlData.data = OICMalloc(defaultCrl->CrlData.len);
413 memcpy(defaultCrl->CrlData.data, CRL_DEFAULT_CRL_DATA, defaultCrl->CrlData.len);
415 defaultCrl->ThisUpdate.len = strlen(CRL_DEFAULT_THIS_UPDATE);
416 defaultCrl->ThisUpdate.data = OICMalloc(defaultCrl->ThisUpdate.len);
417 memcpy(defaultCrl->ThisUpdate.data, CRL_DEFAULT_THIS_UPDATE, defaultCrl->ThisUpdate.len);
423 * Initialize CRL resource by loading data from persistent storage.
426 * OC_STACK_OK - no errors
427 * OC_STACK_ERROR - stack process error
429 OCStackResult InitCRLResource()
431 OCStackResult ret = OC_STACK_ERROR;
432 char* jsonSVRDatabase;
434 //Read CRL resource from PS
435 jsonSVRDatabase = GetSVRDatabase();
439 //Convert JSON CRL into binary format
440 gCrl = JSONToCrlBin(jsonSVRDatabase, true);
443 * If SVR database in persistent storage got corrupted or
444 * is not available for some reason, a default CrlResource is created
445 * which allows user to initiate CrlResource provisioning again.
447 if (!jsonSVRDatabase || !gCrl)
449 gCrl = GetCrlDefault();
452 ret = CreateCRLResource();
453 OICFree(jsonSVRDatabase);
458 * Perform cleanup for ACL resources.
460 void DeInitCRLResource()
462 OCDeleteResource(gCrlHandle);
464 DeleteCrlBinData(gCrl);
468 OicSecCrl_t *GetCRLResource()
470 OicSecCrl_t *crl = NULL;
472 //Read CRL resource from PS
473 char* jsonSVRDatabase = GetSVRDatabase();
477 //Convert JSON CRL into binary format
478 crl = JSONToCrlBin(jsonSVRDatabase, true);
481 * If SVR database in persistent storage got corrupted or
482 * is not available for some reason, a default CrlResource is created
483 * which allows user to initiate CrlResource provisioning again.
485 if (!jsonSVRDatabase || !crl)
487 crl = GetCrlDefault();
489 OICFree(jsonSVRDatabase);
496 cJSON *jsonCrl = NULL;
497 cJSON *jsonObj = NULL;
498 char *jsonSVRDatabase = GetSVRDatabase();
501 cJSON *jsonRoot = cJSON_Parse(jsonSVRDatabase);
502 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
504 jsonCrl = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRL_NAME);
505 VERIFY_NON_NULL(TAG, jsonCrl, ERROR);
507 //CRLData -- Mandatory
508 jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_DATA);
511 VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
512 if(cJSON_String == jsonObj->type)
514 //Check for empty string, in case CRLData field has not been set yet
515 if (jsonObj->valuestring[0])
517 ret = jsonObj->valuestring;
522 OICFree(jsonSVRDatabase);
523 cJSON_Delete(jsonRoot);
527 void GetDerCrl(ByteArray crlArray)
529 OicSecCrl_t * crlRes = GetCRLResource();
530 if (crlRes && crlRes->CrlData.len <= crlArray.len)
532 memcpy(crlArray.data, crlRes->CrlData.data, crlRes->CrlData.len);
533 crlArray.len = crlRes->CrlData.len;
539 DeleteCrlBinData(crlRes);