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)
79 char *base64Buff = NULL;
81 uint32_t base64CRLLen = 0;
82 B64Result b64Ret = B64_OK;
84 cJSON *jsonRoot = cJSON_CreateObject();
85 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
86 cJSON *jsonCrl = cJSON_CreateObject();
87 VERIFY_NON_NULL(TAG, jsonCrl, ERROR);
89 cJSON_AddItemToObject(jsonRoot, OIC_JSON_CRL_NAME, jsonCrl);
92 cJSON_AddNumberToObject(jsonCrl, OIC_JSON_CRL_ID, (int)crl->CrlId);
94 //ThisUpdate -- Mandatory
96 base64CRLLen = (uint32_t)B64ENCODE_OUT_SAFESIZE(crl->ThisUpdate.len);
97 base64Buff = OICMalloc(base64CRLLen);
98 b64Ret = b64Encode(crl->ThisUpdate.data, crl->ThisUpdate.len, base64Buff,
99 base64CRLLen, &outLen);
100 VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
101 cJSON_AddStringToObject(jsonCrl, OIC_JSON_CRL_THIS_UPDATE, base64Buff);
104 //CRLData -- Mandatory
106 base64CRLLen = (uint32_t)B64ENCODE_OUT_SAFESIZE(crl->CrlData.len);
107 base64Buff = OICMalloc(base64CRLLen);
108 b64Ret = b64Encode(crl->CrlData.data, crl->CrlData.len, base64Buff,
109 base64CRLLen, &outLen);
110 VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
111 cJSON_AddStringToObject(jsonCrl, OIC_JSON_CRL_DATA, base64Buff);
113 jsonStr = cJSON_PrintUnformatted(jsonRoot);
119 cJSON_Delete(jsonRoot);
124 OicSecCrl_t *JSONToCrlBin(const char * jsonStr)
131 OCStackResult ret = OC_STACK_ERROR;
132 OicSecCrl_t *crl = NULL;
133 cJSON *jsonCrl = NULL;
134 cJSON *jsonObj = NULL;
136 unsigned char *base64Buff = NULL;
137 uint32_t base64CRLLen = 0;
139 B64Result b64Ret = B64_OK;
141 cJSON *jsonRoot = cJSON_Parse(jsonStr);
142 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
144 jsonCrl = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRL_NAME);
145 VERIFY_NON_NULL(TAG, jsonCrl, ERROR);
146 crl = (OicSecCrl_t *)OICCalloc(1, sizeof(OicSecCrl_t));
147 VERIFY_NON_NULL(TAG, crl, ERROR);
150 jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_ID);
153 VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
154 crl->CrlId = (uint16_t)jsonObj->valueint;
156 else // PUT/POST JSON may not have CRLId so set it to the gCRList->CRLId
158 VERIFY_NON_NULL(TAG, gCrl, ERROR);
159 crl->CrlId = gCrl->CrlId;
162 //ThisUpdate -- Mandatory
163 jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_THIS_UPDATE);
166 VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
167 if(cJSON_String == jsonObj->type)
169 //Check for empty string, in case ThisUpdate field has not been set yet
170 if (jsonObj->valuestring[0])
172 base64CRLLen = B64ENCODE_OUT_SAFESIZE(strlen(jsonObj->valuestring));
173 base64Buff = OICMalloc(base64CRLLen);
174 b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
175 base64CRLLen, &outLen);
176 VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= base64CRLLen),
178 crl->ThisUpdate.data = OICMalloc(outLen + 1);
179 memcpy(crl->ThisUpdate.data, base64Buff, outLen);
180 crl->ThisUpdate.len = outLen;
186 else // PUT/POST JSON will not have ThisUpdate so set it to the gCRList->ThisUpdate
188 VERIFY_NON_NULL(TAG, gCrl, ERROR);
189 outLen = (uint32_t)gCrl->ThisUpdate.len;
190 crl->ThisUpdate.data = OICMalloc(outLen + 1);
191 memcpy(crl->ThisUpdate.data, gCrl->ThisUpdate.data, outLen);
192 crl->ThisUpdate.len = outLen;
195 //CRLData -- Mandatory
196 jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_DATA);
199 VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
200 if(cJSON_String == jsonObj->type)
202 //Check for empty string, in case CRLData field has not been set yet
203 if (jsonObj->valuestring[0])
206 base64CRLLen = B64ENCODE_OUT_SAFESIZE(strlen(jsonObj->valuestring));
207 base64Buff = OICMalloc(base64CRLLen);
208 b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
209 base64CRLLen, &outLen);
210 VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= base64CRLLen),
212 crl->CrlData.data = OICMalloc(outLen + 1);
213 memcpy(crl->CrlData.data, base64Buff, outLen);
214 crl->CrlData.len = outLen;
220 else // PUT/POST JSON will not have CRLData so set it to the gCRList->CRLData
222 VERIFY_NON_NULL(TAG, gCrl, ERROR);
223 outLen = (uint32_t)gCrl->CrlData.len;
224 crl->CrlData.data = OICMalloc(outLen + 1);
225 memcpy(crl->CrlData.data, gCrl->CrlData.data, outLen);
226 crl->CrlData.len = outLen;
231 cJSON_Delete(jsonRoot);
234 if (OC_STACK_OK != ret)
236 DeleteCrlBinData(crl);
242 OCStackResult UpdateCRLResource(const OicSecCrl_t *crl)
244 char *jsonStr = NULL;
245 OCStackResult res = OC_STACK_ERROR;
247 jsonStr = BinToCrlJSON((OicSecCrl_t *) crl);
250 return OC_STACK_ERROR;
253 cJSON *jsonObj = cJSON_Parse(jsonStr);
258 return OC_STACK_ERROR;
261 res = UpdateSVRDatabase(OIC_JSON_CRL_NAME, jsonObj);
262 cJSON_Delete(jsonObj);
267 static OCEntityHandlerResult HandleCRLPostRequest(const OCEntityHandlerRequest *ehRequest)
269 OCEntityHandlerResult ehRet = OC_EH_ERROR;
271 char *jsonCRL = (char *)(((OCSecurityPayload *)ehRequest->payload)->securityData);
275 OIC_LOG(INFO, TAG, "UpdateSVRDB...");
276 OIC_LOG_V(INFO, TAG, "crl: \"%s\"", jsonCRL);
278 cJSON *jsonObj = cJSON_Parse(jsonCRL);
279 OicSecCrl_t *crl = NULL;
280 crl = JSONToCrlBin(jsonCRL);
281 VERIFY_NON_NULL(TAG, crl, ERROR);
283 gCrl->CrlId = crl->CrlId;
285 OICFree(gCrl->ThisUpdate.data);
286 gCrl->ThisUpdate.data = NULL;
287 gCrl->ThisUpdate.data = OICMalloc(crl->ThisUpdate.len);
288 memcpy(gCrl->ThisUpdate.data, crl->ThisUpdate.data, crl->ThisUpdate.len);
289 gCrl->ThisUpdate.len = crl->ThisUpdate.len;
291 OICFree(gCrl->CrlData.data);
292 gCrl->CrlData.data = NULL;
293 gCrl->CrlData.data = OICMalloc(crl->CrlData.len);
294 memcpy(gCrl->CrlData.data, crl->CrlData.data, crl->CrlData.len);
295 gCrl->CrlData.len = crl->CrlData.len;
297 if (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_CRL_NAME, jsonObj))
299 OIC_LOG(INFO, TAG, "UpdateSVRDB == OK");
300 ehRet = OC_EH_RESOURCE_CREATED;
303 DeleteCrlBinData(crl);
306 cJSON_Delete(jsonObj);
309 // Send payload to request originator
310 SendSRMResponse(ehRequest, ehRet, NULL);
312 OIC_LOG_V(INFO, TAG, "%s RetVal %d", __func__, ehRet);
318 * This internal method is the entity handler for CRL resource and
319 * will handle REST request (GET/PUT/POST/DEL) for them.
321 OCEntityHandlerResult CRLEntityHandler(OCEntityHandlerFlag flag,
322 OCEntityHandlerRequest *ehRequest,
323 void *callbackParameter)
325 OCEntityHandlerResult ehRet = OC_EH_ERROR;
326 (void)callbackParameter;
333 OIC_LOG(INFO, TAG, "Handle CRL resource");
335 if (flag & OC_REQUEST_FLAG)
337 // TODO : Handle PUT and DEL methods
338 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
339 switch (ehRequest->method)
342 OIC_LOG (INFO, TAG, "Not implemented request method.");
343 //ehRet = HandleCRLGetRequest(ehRequest);
347 ehRet = HandleCRLPostRequest(ehRequest);
352 SendSRMResponse(ehRequest, ehRet, NULL);
360 * This internal method is used to create '/oic/sec/crl' resource.
362 OCStackResult CreateCRLResource()
365 ret = OCCreateResource(&gCrlHandle,
366 OIC_RSRC_TYPE_SEC_CRL,
373 if (OC_STACK_OK != ret)
375 OIC_LOG(FATAL, TAG, "Unable to instantiate CRL resource");
382 * Get the default value
383 * @retval NULL for now. Update it when we finalize the default info.
385 static OicSecCrl_t *GetCrlDefault()
387 OicSecCrl_t *defaultCrl = NULL;
388 defaultCrl = (OicSecCrl_t *)OICCalloc(1, sizeof(OicSecCrl_t));
390 defaultCrl->CrlId = CRL_DEFAULT_CRL_ID;
392 defaultCrl->CrlData.len = strlen(CRL_DEFAULT_CRL_DATA);
393 defaultCrl->CrlData.data = OICMalloc(defaultCrl->CrlData.len);
394 memcpy(defaultCrl->CrlData.data, CRL_DEFAULT_CRL_DATA, defaultCrl->CrlData.len);
396 defaultCrl->ThisUpdate.len = strlen(CRL_DEFAULT_THIS_UPDATE);
397 defaultCrl->ThisUpdate.data = OICMalloc(defaultCrl->ThisUpdate.len);
398 memcpy(defaultCrl->ThisUpdate.data, CRL_DEFAULT_THIS_UPDATE, defaultCrl->ThisUpdate.len);
404 * Initialize CRL resource by loading data from persistent storage.
407 * OC_STACK_OK - no errors
408 * OC_STACK_ERROR - stack process error
410 OCStackResult InitCRLResource()
412 OCStackResult ret = OC_STACK_ERROR;
413 char* jsonSVRDatabase;
415 //Read CRL resource from PS
416 jsonSVRDatabase = GetSVRDatabase();
420 //Convert JSON CRL into binary format
421 gCrl = JSONToCrlBin(jsonSVRDatabase);
424 * If SVR database in persistent storage got corrupted or
425 * is not available for some reason, a default CrlResource is created
426 * which allows user to initiate CrlResource provisioning again.
428 if (!jsonSVRDatabase || !gCrl)
430 gCrl = GetCrlDefault();
433 ret = CreateCRLResource();
434 OICFree(jsonSVRDatabase);
439 * Perform cleanup for ACL resources.
441 void DeInitCRLResource()
443 OCDeleteResource(gCrlHandle);
445 DeleteCrlBinData(gCrl);
449 OicSecCrl_t *GetCRLResource()
451 OicSecCrl_t *crl = NULL;
453 //Read CRL resource from PS
454 char* jsonSVRDatabase = GetSVRDatabase();
458 //Convert JSON CRL into binary format
459 crl = JSONToCrlBin(jsonSVRDatabase);
462 * If SVR database in persistent storage got corrupted or
463 * is not available for some reason, a default CrlResource is created
464 * which allows user to initiate CrlResource provisioning again.
466 if (!jsonSVRDatabase || !crl)
468 crl = GetCrlDefault();
470 OICFree(jsonSVRDatabase);
477 cJSON *jsonCrl = NULL;
478 cJSON *jsonObj = NULL;
479 char *jsonSVRDatabase = GetSVRDatabase();
482 cJSON *jsonRoot = cJSON_Parse(jsonSVRDatabase);
483 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
485 jsonCrl = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRL_NAME);
486 VERIFY_NON_NULL(TAG, jsonCrl, ERROR);
488 //CRLData -- Mandatory
489 jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_DATA);
492 VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
493 if(cJSON_String == jsonObj->type)
495 //Check for empty string, in case CRLData field has not been set yet
496 if (jsonObj->valuestring[0])
498 ret = jsonObj->valuestring;
503 OICFree(jsonSVRDatabase);
504 cJSON_Delete(jsonRoot);
508 void GetDerCrl(ByteArray crlArray)
510 OicSecCrl_t * crlRes = GetCRLResource();
511 if (crlRes && crlRes->CrlData.len <= crlArray.len)
513 memcpy(crlArray.data, crlRes->CrlData.data, crlRes->CrlData.len);
514 crlArray.len = crlRes->CrlData.len;
520 DeleteCrlBinData(crlRes);