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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
22 #include "payload_logging.h"
23 #include "psinterface.h"
24 #include "resourcemanager.h"
25 #include "srmresourcestrings.h"
26 #include "srmutility.h"
27 #include "doxmresource.h"
28 #include "ocpayload.h"
29 #include "oic_malloc.h"
30 #include "crlresource.h"
36 #define SEPARATOR_LEN (1)
37 #define CBOR_CRL_NAME "\"CRL\""
38 #define CBOR_CRL_NAME_LEN (5)
39 #define OIC_CBOR_CRL_NAME "crl"
40 #define OIC_CBOR_CRL_ID "CRLId"
41 #define OIC_CBOR_CRL_THIS_UPDATE "ThisUpdate"
42 #define OIC_CBOR_CRL_DATA "CRLData"
43 #define CRL_DEFAULT_CRL_ID (1)
44 #define CRL_DEFAULT_THIS_UPDATE "150101000000Z"
45 #define CRL_DEFAULT_CRL_DATA "-"
47 static OCResourceHandle gCrlHandle = NULL;
48 static OicSecCrl_t *gCrl = NULL;
50 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
51 * The value of payload size is increased until reaching below max cbor size. */
52 static const uint16_t CBOR_SIZE = 1024;
54 // Max cbor size payload.
55 static const uint16_t CBOR_MAX_SIZE = 4400;
57 // PSTAT Map size - Number of mandatory items
58 static const uint8_t CRL_MAP_SIZE = 3;
60 void DeleteCrlBinData(OicSecCrl_t *crl)
65 OICFree(crl->ThisUpdate.data);
68 OICFree(crl->CrlData.data);
75 OCStackResult CrlToCBORPayload(const OicSecCrl_t *crl, uint8_t **payload, size_t *size)
77 if (NULL == crl || NULL == payload || NULL != *payload || NULL == size)
79 return OC_STACK_INVALID_PARAM;
82 size_t cborLen = *size;
91 OCStackResult ret = OC_STACK_ERROR;
96 CborError cborEncoderResult = CborNoError;
98 uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
99 VERIFY_NON_NULL(TAG, outPayload, ERROR);
100 cbor_encoder_init(&encoder, outPayload, cborLen, 0);
102 cborEncoderResult = cbor_encoder_create_map(&encoder, &crlMap, CRL_MAP_SIZE);
103 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create CRL Map");
106 cborEncoderResult = cbor_encode_text_string(&crlMap, OIC_CBOR_CRL_ID,
107 strlen(OIC_CBOR_CRL_ID));
108 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add CRL ID");
109 cborEncoderResult = cbor_encode_int(&crlMap, crl->CrlId);
110 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add CRL Id value");
112 //ThisUpdate -- Mandatory
113 cborEncoderResult = cbor_encode_text_string(&crlMap, OIC_CBOR_CRL_THIS_UPDATE,
114 strlen(OIC_CBOR_CRL_THIS_UPDATE));
115 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add Crl update");
116 cborEncoderResult = cbor_encode_byte_string(&crlMap, crl->ThisUpdate.data,
117 crl->ThisUpdate.len);
118 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add Crl Update value");
120 //CRLData -- Mandatory
121 cborEncoderResult = cbor_encode_text_string(&crlMap, OIC_CBOR_CRL_DATA,
122 strlen(OIC_CBOR_CRL_DATA));
123 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add Crl data name");
124 cborEncoderResult = cbor_encode_byte_string(&crlMap, crl->CrlData.data,
126 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add Crl data value");
128 cborEncoderResult = cbor_encoder_close_container(&encoder, &crlMap);
129 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add close Crl map");
131 *size = encoder.ptr - outPayload;
132 *payload = outPayload;
136 if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
138 // reallocate and try again!
140 // Since the allocated initial memory failed, double the memory.
141 cborLen += encoder.ptr - encoder.end;
142 cborEncoderResult = CborNoError;
143 ret = CrlToCBORPayload(crl, payload, &cborLen);
146 if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
152 ret = OC_STACK_ERROR;
158 OCStackResult CBORPayloadToCrl(const uint8_t *cborPayload, const size_t size,
159 OicSecCrl_t **secCrl)
161 if (NULL == cborPayload || NULL == secCrl || NULL != *secCrl || 0 == size)
163 return OC_STACK_INVALID_PARAM;
166 OCStackResult ret = OC_STACK_ERROR;
169 CborValue crlCbor = {.parser = NULL};
170 CborParser parser = {.end = NULL};
171 CborError cborFindResult = CborNoError;
173 cbor_parser_init(cborPayload, size, 0, &parser, &crlCbor);
174 CborValue crlMap = { .parser = NULL};
175 OicSecCrl_t *crl = NULL;
177 cborFindResult = cbor_value_enter_container(&crlCbor, &crlMap);
178 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter Crl map");
180 crl = (OicSecCrl_t *)OICCalloc(1, sizeof(OicSecCrl_t));
181 VERIFY_NON_NULL(TAG, crl, ERROR);
183 cborFindResult = cbor_value_map_find_value(&crlCbor, OIC_CBOR_CRL_ID, &crlMap);
184 if (CborNoError == cborFindResult && cbor_value_is_integer(&crlMap))
188 cborFindResult = cbor_value_get_int(&crlMap, &CrlId);
189 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CrlId.");
190 crl->CrlId = (uint16_t)CrlId;
193 cborFindResult = cbor_value_map_find_value(&crlCbor, OIC_CBOR_CRL_THIS_UPDATE, &crlMap);
194 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&crlMap))
196 cborFindResult = cbor_value_dup_byte_string(&crlMap,
197 &crl->ThisUpdate.data, &crl->ThisUpdate.len, NULL);
198 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Byte Array.");
200 cborFindResult = cbor_value_map_find_value(&crlCbor, OIC_CBOR_CRL_DATA, &crlMap);
201 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&crlMap))
203 cborFindResult = cbor_value_dup_byte_string(&crlMap,
204 &crl->CrlData.data, &crl->CrlData.len, NULL);
205 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Byte Array.");
211 if (CborNoError != cborFindResult)
213 // PUT/POST CBOR may not have mandatory values set default values.
216 OIC_LOG (DEBUG, TAG, "Set default values");
217 crl->CrlId = gCrl->CrlId;
218 if (crl->ThisUpdate.data)
220 OICFree(crl->ThisUpdate.data);
222 outLen = gCrl->ThisUpdate.len;
223 crl->ThisUpdate.data = (uint8_t*) OICMalloc(outLen);
224 if (crl->ThisUpdate.data)
226 memcpy(crl->ThisUpdate.data, gCrl->ThisUpdate.data, outLen);
227 crl->ThisUpdate.len = outLen;
231 crl->ThisUpdate.len = 0;
232 OIC_LOG(ERROR, TAG, "Set default failed");
234 if (crl->CrlData.data)
236 OICFree(crl->CrlData.data);
238 outLen = gCrl->CrlData.len;
239 crl->CrlData.data = (uint8_t*) OICMalloc(outLen);
240 if (crl->CrlData.data && gCrl->CrlData.data)
242 memcpy(crl->CrlData.data, gCrl->CrlData.data, outLen);
243 crl->CrlData.len = outLen;
247 crl->CrlData.len = 0;
248 OIC_LOG (ERROR, TAG, "Set default failed");
256 OIC_LOG (ERROR, TAG, "CBORPayloadToCrl failed");
257 DeleteCrlBinData(crl);
259 ret = OC_STACK_ERROR;
265 OCStackResult UpdateCRLResource(const OicSecCrl_t *crl)
267 uint8_t *payload = NULL;
270 OCStackResult res = CrlToCBORPayload((OicSecCrl_t *) crl, &payload, &size);
271 if (OC_STACK_OK != res)
276 return UpdateSecureResourceInPS(OIC_CBOR_CRL_NAME, payload, size);
279 static OCEntityHandlerResult HandleCRLPostRequest(const OCEntityHandlerRequest *ehRequest)
281 OCEntityHandlerResult ehRet = OC_EH_ERROR;
282 OicSecCrl_t *crl = NULL;
283 uint8_t *payload = ((OCSecurityPayload *)ehRequest->payload)->securityData;
284 size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
288 OIC_LOG(INFO, TAG, "UpdateSVRDB...");
289 CBORPayloadToCrl(payload, size, &crl);
290 VERIFY_NON_NULL(TAG, crl, ERROR);
292 gCrl->CrlId = crl->CrlId;
294 OICFree(gCrl->ThisUpdate.data);
295 gCrl->ThisUpdate.data = NULL;
296 gCrl->ThisUpdate.data = OICMalloc(crl->ThisUpdate.len);
297 VERIFY_NON_NULL(TAG, gCrl->ThisUpdate.data, ERROR);
298 memcpy(gCrl->ThisUpdate.data, crl->ThisUpdate.data, crl->ThisUpdate.len);
299 gCrl->ThisUpdate.len = crl->ThisUpdate.len;
301 OICFree(gCrl->CrlData.data);
302 gCrl->CrlData.data = OICMalloc(crl->CrlData.len);
303 VERIFY_NON_NULL(TAG, gCrl->CrlData.data, ERROR);
304 memcpy(gCrl->CrlData.data, crl->CrlData.data, crl->CrlData.len);
305 gCrl->CrlData.len = crl->CrlData.len;
307 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_CBOR_CRL_NAME, payload, size))
309 ehRet = OC_EH_RESOURCE_CREATED;
312 DeleteCrlBinData(crl);
316 // Send payload to request originator
317 if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
320 OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleCRLPostRequest");
323 OIC_LOG_V(INFO, TAG, "%s RetVal %d", __func__, ehRet);
329 * This internal method is the entity handler for CRL resource and
330 * will handle REST request (GET/PUT/POST/DEL) for them.
332 static OCEntityHandlerResult CRLEntityHandler(OCEntityHandlerFlag flag,
333 OCEntityHandlerRequest *ehRequest,
334 void *callbackParameter)
336 OCEntityHandlerResult ehRet = OC_EH_ERROR;
337 (void)callbackParameter;
344 OIC_LOG(INFO, TAG, "Handle CRL resource");
346 if (flag & OC_REQUEST_FLAG)
348 // TODO : Handle PUT and DEL methods
349 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
350 switch (ehRequest->method)
353 OIC_LOG (INFO, TAG, "Not implemented request method.");
354 //ehRet = HandleCRLGetRequest(ehRequest);
358 ehRet = HandleCRLPostRequest(ehRequest);
363 SendSRMResponse(ehRequest, ehRet, NULL, 0);
371 * This internal method is used to create '/oic/sec/crl' resource.
373 static OCStackResult CreateCRLResource()
375 OCStackResult ret = OCCreateResource(&gCrlHandle,
376 OIC_RSRC_TYPE_SEC_CRL,
377 OC_RSRVD_INTERFACE_DEFAULT,
383 if (OC_STACK_OK != ret)
385 OIC_LOG(FATAL, TAG, "Unable to instantiate CRL resource");
392 * Get the default value.
393 * @return defaultCrl for now.
395 static OicSecCrl_t *GetCrlDefault()
397 OicSecCrl_t *defaultCrl = (OicSecCrl_t *)OICCalloc(1, sizeof(OicSecCrl_t));
398 if (NULL == defaultCrl)
402 defaultCrl->CrlId = CRL_DEFAULT_CRL_ID;
404 defaultCrl->CrlData.len = strlen(CRL_DEFAULT_CRL_DATA);
405 defaultCrl->CrlData.data = (uint8_t*) OICMalloc(defaultCrl->CrlData.len);
406 if (defaultCrl->CrlData.data)
408 memcpy(defaultCrl->CrlData.data, CRL_DEFAULT_CRL_DATA, defaultCrl->CrlData.len);
412 defaultCrl->CrlData.len = 0;
415 defaultCrl->ThisUpdate.len = strlen(CRL_DEFAULT_THIS_UPDATE);
416 defaultCrl->ThisUpdate.data = (uint8_t*) OICMalloc(defaultCrl->ThisUpdate.len);
417 if (defaultCrl->ThisUpdate.data)
419 memcpy(defaultCrl->ThisUpdate.data, CRL_DEFAULT_THIS_UPDATE, defaultCrl->ThisUpdate.len);
423 defaultCrl->ThisUpdate.len = 0;
430 * Initialize CRL resource by loading data from persistent storage.
433 * OC_STACK_OK - no errors
434 * OC_STACK_ERROR - stack process error
436 OCStackResult InitCRLResource()
438 OCStackResult ret = OC_STACK_ERROR;
439 // Read Crl resource from PS
440 uint8_t *data = NULL;
442 ret = GetSecureVirtualDatabaseFromPS(OIC_CBOR_CRL_NAME, &data, &size);
443 // If database read failed
444 if (OC_STACK_OK != ret)
446 OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
450 // Read ACL resource from PS
451 ret = CBORPayloadToCrl(data, size, &gCrl);
455 * If SVR database in persistent storage got corrupted or
456 * is not available for some reason, a default CrlResource is created
457 * which allows user to initiate CrlResource provisioning again.
459 if ((OC_STACK_OK != ret) || !data || !gCrl)
461 gCrl = GetCrlDefault();
464 ret = CreateCRLResource();
470 * Perform cleanup for ACL resources.
472 OCStackResult DeInitCRLResource()
474 OCStackResult result = OCDeleteResource(gCrlHandle);
476 DeleteCrlBinData(gCrl);
481 OicSecCrl_t *GetCRLResource()
483 OicSecCrl_t *crl = NULL;
485 //Read CRL resource from PS
486 uint8_t *data = NULL;
488 OCStackResult ret = GetSecureVirtualDatabaseFromPS(OIC_CBOR_CRL_NAME, &data, &size);
491 //Convert CBOR CRL into binary format
492 ret = CBORPayloadToCrl(data, size, &crl);
495 * If SVR database in persistent storage got corrupted or
496 * is not available for some reason, a default CrlResource is created
497 * which allows user to initiate CrlResource provisioning again.
499 if ((OC_STACK_OK != ret) || !data || !crl)
501 crl = GetCrlDefault();
510 uint8_t *data = NULL;
512 OicSecCrl_t *crl = NULL;
513 if (OC_STACK_OK == GetSecureVirtualDatabaseFromPS(OIC_CBOR_CRL_NAME, &data, &size) && data &&
514 OC_STACK_OK == CBORPayloadToCrl(data, size, &crl))
516 return crl->CrlData.data;
521 void GetDerCrl(ByteArray* crlArray)
527 OicSecCrl_t * crlRes = GetCRLResource();
528 if (NULL != crlArray->data && NULL != crlRes
529 && NULL !=crlRes->CrlData.data && crlRes->CrlData.len <= crlArray->len)
531 memcpy(crlArray->data, crlRes->CrlData.data, crlRes->CrlData.len);
532 crlArray->len = crlRes->CrlData.len;
538 DeleteCrlBinData(crlRes);