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"
31 #include "crlresource.h"
33 #endif /* __WITH_X509__ */
38 #define SEPARATOR_LEN (1)
39 #define CBOR_CRL_NAME "\"CRL\""
40 #define CBOR_CRL_NAME_LEN (5)
41 #define OIC_CBOR_CRL_NAME "crl"
42 #define OIC_CBOR_CRL_ID "CRLId"
43 #define OIC_CBOR_CRL_THIS_UPDATE "ThisUpdate"
44 #define OIC_CBOR_CRL_DATA "CRLData"
45 #define CRL_DEFAULT_CRL_ID (1)
46 #define CRL_DEFAULT_THIS_UPDATE "150101000000Z"
47 #define CRL_DEFAULT_CRL_DATA "-"
49 static OCResourceHandle gCrlHandle = NULL;
50 static OicSecCrl_t *gCrl = NULL;
52 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
53 * The value of payload size is increased until reaching below max cbor size. */
54 static const uint16_t CBOR_SIZE = 1024;
56 // Max cbor size payload.
57 static const uint16_t CBOR_MAX_SIZE = 4400;
59 // PSTAT Map size - Number of mandatory items
60 static const uint8_t CRL_MAP_SIZE = 3;
62 void DeleteCrlBinData(OicSecCrl_t *crl)
67 OICFree(crl->ThisUpdate.data);
70 OICFree(crl->CrlData.data);
77 OCStackResult CrlToCBORPayload(const OicSecCrl_t *crl, uint8_t **payload, size_t *size)
79 if (NULL == crl || NULL == payload || NULL != *payload || NULL == size)
81 return OC_STACK_INVALID_PARAM;
84 size_t cborLen = *size;
93 OCStackResult ret = OC_STACK_ERROR;
95 CborEncoder encoder = { {.ptr = NULL }, .end = 0 };
96 CborEncoder crlMap = { {.ptr = NULL }, .end = 0 };
98 CborError cborEncoderResult = CborNoError;
100 uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
101 VERIFY_NON_NULL(TAG, outPayload, ERROR);
102 cbor_encoder_init(&encoder, outPayload, cborLen, 0);
104 cborEncoderResult = cbor_encoder_create_map(&encoder, &crlMap, CRL_MAP_SIZE);
105 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, ERROR);
108 cborEncoderResult = cbor_encode_text_string(&crlMap, OIC_CBOR_CRL_ID,
109 strlen(OIC_CBOR_CRL_ID));
110 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, ERROR);
111 cborEncoderResult = cbor_encode_int(&crlMap, crl->CrlId);
112 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, ERROR);
114 //ThisUpdate -- Mandatory
115 cborEncoderResult = cbor_encode_text_string(&crlMap, OIC_CBOR_CRL_THIS_UPDATE,
116 strlen(OIC_CBOR_CRL_THIS_UPDATE));
117 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, ERROR);
118 cborEncoderResult = cbor_encode_byte_string(&crlMap, crl->ThisUpdate.data,
119 crl->ThisUpdate.len);
120 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, ERROR);
122 //CRLData -- Mandatory
123 cborEncoderResult = cbor_encode_text_string(&crlMap, OIC_CBOR_CRL_DATA,
124 strlen(OIC_CBOR_CRL_DATA));
125 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, ERROR);
126 cborEncoderResult = cbor_encode_byte_string(&crlMap, crl->CrlData.data,
128 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, ERROR);
130 cborEncoderResult = cbor_encoder_close_container(&encoder, &crlMap);
131 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, ERROR);
133 *size = encoder.ptr - outPayload;
134 *payload = outPayload;
138 if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
140 // reallocate and try again!
142 // Since the allocated initial memory failed, double the memory.
143 cborLen += encoder.ptr - encoder.end;
144 cborEncoderResult = CborNoError;
145 ret = CrlToCBORPayload(crl, payload, &cborLen);
148 if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
154 ret = OC_STACK_ERROR;
160 OCStackResult CBORPayloadToCrl(const uint8_t *cborPayload, const size_t size,
161 OicSecCrl_t **secCrl)
163 if (NULL == cborPayload || NULL == secCrl || NULL != *secCrl)
165 return OC_STACK_INVALID_PARAM;
168 OCStackResult ret = OC_STACK_ERROR;
171 CborValue crlCbor = {.parser = NULL};
172 CborParser parser = {.end = NULL};
173 CborError cborFindResult = CborNoError;
174 int cborLen = (size == 0) ? CBOR_SIZE : size;
175 cbor_parser_init(cborPayload, cborLen, 0, &parser, &crlCbor);
176 CborValue crlMap = { .parser = NULL};
177 OicSecCrl_t *crl = NULL;
179 cborFindResult = cbor_value_enter_container(&crlCbor, &crlMap);
180 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, ERROR);
182 crl = (OicSecCrl_t *)OICCalloc(1, sizeof(OicSecCrl_t));
183 VERIFY_NON_NULL(TAG, crl, ERROR);
185 cborFindResult = cbor_value_map_find_value(&crlCbor, OIC_CBOR_CRL_ID, &crlMap);
186 if (CborNoError == cborFindResult && cbor_value_is_integer(&crlMap))
188 cborFindResult = cbor_value_get_int(&crlMap, (int *) &crl->CrlId);
189 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CrlId.");
192 cborFindResult = cbor_value_map_find_value(&crlCbor, OIC_CBOR_CRL_THIS_UPDATE, &crlMap);
193 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&crlMap))
195 cborFindResult = cbor_value_dup_byte_string(&crlMap,
196 &crl->ThisUpdate.data, &crl->ThisUpdate.len, NULL);
197 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Byte Array.");
199 cborFindResult = cbor_value_map_find_value(&crlCbor, OIC_CBOR_CRL_DATA, &crlMap);
200 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&crlMap))
202 cborFindResult = cbor_value_dup_byte_string(&crlMap,
203 &crl->CrlData.data, &crl->CrlData.len, NULL);
204 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Byte Array.");
210 if (CborNoError != cborFindResult)
212 // PUT/POST CBOR may not have mandatory values set default values.
215 OIC_LOG (DEBUG, TAG, "Set default values");
216 crl->CrlId = gCrl->CrlId;
217 if (crl->ThisUpdate.data)
219 OICFree(crl->ThisUpdate.data);
221 outLen = gCrl->ThisUpdate.len;
222 crl->ThisUpdate.data = (uint8_t*) OICMalloc(outLen);
223 if (crl->ThisUpdate.data)
225 memcpy(crl->ThisUpdate.data, gCrl->ThisUpdate.data, outLen);
226 crl->ThisUpdate.len = outLen;
230 crl->ThisUpdate.len = 0;
231 OIC_LOG(ERROR, TAG, "Set default failed");
233 if (crl->CrlData.data)
235 OICFree(crl->CrlData.data);
237 outLen = gCrl->CrlData.len;
238 crl->CrlData.data = (uint8_t*) OICMalloc(outLen);
239 if (crl->CrlData.data && gCrl->CrlData.data)
241 memcpy(crl->CrlData.data, gCrl->CrlData.data, outLen);
242 crl->CrlData.len = outLen;
246 crl->CrlData.len = 0;
247 OIC_LOG (ERROR, TAG, "Set default failed");
255 OIC_LOG (ERROR, TAG, "CBORPayloadToCrl failed");
256 DeleteCrlBinData(crl);
258 ret = OC_STACK_ERROR;
264 OCStackResult UpdateCRLResource(const OicSecCrl_t *crl)
266 uint8_t *payload = NULL;
269 OCStackResult res = CrlToCBORPayload((OicSecCrl_t *) crl, &payload, &size);
270 if (OC_STACK_OK != res)
275 return UpdateSecureResourceInPS(OIC_CBOR_CRL_NAME, payload, size);
278 static OCEntityHandlerResult HandleCRLPostRequest(const OCEntityHandlerRequest *ehRequest)
280 OCEntityHandlerResult ehRet = OC_EH_ERROR;
281 OicSecCrl_t *crl = NULL;
282 uint8_t *payload = ((OCSecurityPayload *)ehRequest->payload)->securityData1;
283 size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
287 OIC_LOG(INFO, TAG, "UpdateSVRDB...");
288 CBORPayloadToCrl(payload, size, &crl);
289 VERIFY_NON_NULL(TAG, crl, ERROR);
291 gCrl->CrlId = crl->CrlId;
293 OICFree(gCrl->ThisUpdate.data);
294 gCrl->ThisUpdate.data = NULL;
295 gCrl->ThisUpdate.data = OICMalloc(crl->ThisUpdate.len);
296 VERIFY_NON_NULL(TAG, gCrl->ThisUpdate.data, ERROR);
297 memcpy(gCrl->ThisUpdate.data, crl->ThisUpdate.data, crl->ThisUpdate.len);
298 gCrl->ThisUpdate.len = crl->ThisUpdate.len;
300 OICFree(gCrl->CrlData.data);
301 gCrl->CrlData.data = OICMalloc(crl->CrlData.len);
302 VERIFY_NON_NULL(TAG, gCrl->CrlData.data, ERROR);
303 memcpy(gCrl->CrlData.data, crl->CrlData.data, crl->CrlData.len);
304 gCrl->CrlData.len = crl->CrlData.len;
306 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_CBOR_CRL_NAME, payload, size))
308 ehRet = OC_EH_RESOURCE_CREATED;
311 DeleteCrlBinData(crl);
316 // Send payload to request originator
317 SendSRMCBORResponse(ehRequest, ehRet, NULL, 0);
319 OIC_LOG_V(INFO, TAG, "%s RetVal %d", __func__, ehRet);
325 * This internal method is the entity handler for CRL resource and
326 * will handle REST request (GET/PUT/POST/DEL) for them.
328 static OCEntityHandlerResult CRLEntityHandler(OCEntityHandlerFlag flag,
329 OCEntityHandlerRequest *ehRequest,
330 void *callbackParameter)
332 OCEntityHandlerResult ehRet = OC_EH_ERROR;
333 (void)callbackParameter;
340 OIC_LOG(INFO, TAG, "Handle CRL resource");
342 if (flag & OC_REQUEST_FLAG)
344 // TODO : Handle PUT and DEL methods
345 OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
346 switch (ehRequest->method)
349 OIC_LOG (INFO, TAG, "Not implemented request method.");
350 //ehRet = HandleCRLGetRequest(ehRequest);
354 ehRet = HandleCRLPostRequest(ehRequest);
359 SendSRMCBORResponse(ehRequest, ehRet, NULL, 0);
367 * This internal method is used to create '/oic/sec/crl' resource.
369 static OCStackResult CreateCRLResource()
371 OCStackResult ret = OCCreateResource(&gCrlHandle,
372 OIC_RSRC_TYPE_SEC_CRL,
379 if (OC_STACK_OK != ret)
381 OIC_LOG(FATAL, TAG, "Unable to instantiate CRL resource");
388 * Get the default value.
389 * @return defaultCrl for now.
391 static OicSecCrl_t *GetCrlDefault()
393 OicSecCrl_t *defaultCrl = (OicSecCrl_t *)OICCalloc(1, sizeof(OicSecCrl_t));
394 if (NULL == defaultCrl)
398 defaultCrl->CrlId = CRL_DEFAULT_CRL_ID;
400 defaultCrl->CrlData.len = strlen(CRL_DEFAULT_CRL_DATA);
401 defaultCrl->CrlData.data = (uint8_t*) OICMalloc(defaultCrl->CrlData.len);
402 if (defaultCrl->CrlData.data)
404 memcpy(defaultCrl->CrlData.data, CRL_DEFAULT_CRL_DATA, defaultCrl->CrlData.len);
408 defaultCrl->CrlData.len = 0;
411 defaultCrl->ThisUpdate.len = strlen(CRL_DEFAULT_THIS_UPDATE);
412 defaultCrl->ThisUpdate.data = (uint8_t*) OICMalloc(defaultCrl->ThisUpdate.len);
413 if (defaultCrl->ThisUpdate.data)
415 memcpy(defaultCrl->ThisUpdate.data, CRL_DEFAULT_THIS_UPDATE, defaultCrl->ThisUpdate.len);
419 defaultCrl->ThisUpdate.len = 0;
426 * Initialize CRL resource by loading data from persistent storage.
429 * OC_STACK_OK - no errors
430 * OC_STACK_ERROR - stack process error
432 OCStackResult InitCRLResource()
434 OCStackResult ret = OC_STACK_ERROR;
435 // Read Crl resource from PS
436 uint8_t *data = NULL;
438 ret = GetSecureVirtualDatabaseFromPS(OIC_CBOR_CRL_NAME, &data, &size);
439 // If database read failed
440 if (OC_STACK_OK != ret)
442 OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
446 // Read ACL resource from PS
447 ret = CBORPayloadToCrl(data, size, &gCrl);
451 * If SVR database in persistent storage got corrupted or
452 * is not available for some reason, a default CrlResource is created
453 * which allows user to initiate CrlResource provisioning again.
455 if ((OC_STACK_OK != ret) || !data || !gCrl)
457 gCrl = GetCrlDefault();
460 ret = CreateCRLResource();
466 * Perform cleanup for ACL resources.
468 void DeInitCRLResource()
470 OCDeleteResource(gCrlHandle);
472 DeleteCrlBinData(gCrl);
476 OicSecCrl_t *GetCRLResource()
478 OicSecCrl_t *crl = NULL;
480 //Read CRL resource from PS
481 uint8_t *data = NULL;
483 OCStackResult ret = GetSecureVirtualDatabaseFromPS(OIC_CBOR_CRL_NAME, &data, &size);
486 //Convert CBOR CRL into binary format
487 ret = CBORPayloadToCrl(data, size, &crl);
490 * If SVR database in persistent storage got corrupted or
491 * is not available for some reason, a default CrlResource is created
492 * which allows user to initiate CrlResource provisioning again.
494 if ((OC_STACK_OK != ret) || !data || !crl)
496 crl = GetCrlDefault();
505 uint8_t *data = NULL;
507 OicSecCrl_t *crl = NULL;
508 if (OC_STACK_OK == GetSecureVirtualDatabaseFromPS(OIC_CBOR_CRL_NAME, &data, &size) && data &&
509 OC_STACK_OK == CBORPayloadToCrl(data, size, &crl))
511 return crl->CrlData.data;
516 void GetDerCrl(ByteArray crlArray)
518 OicSecCrl_t * crlRes = GetCRLResource();
519 if (crlRes && crlRes->CrlData.len <= crlArray.len)
521 memcpy(crlArray.data, crlRes->CrlData.data, crlRes->CrlData.len);
522 crlArray.len = crlRes->CrlData.len;
528 DeleteCrlBinData(crlRes);