1 //******************************************************************
3 // Copyright 2015 Intel Mobile Communications GmbH 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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
24 #include "ocpayload.h"
25 #include "oic_malloc.h"
27 #include "payload_logging.h"
28 #include "resourcemanager.h"
29 #include "psinterface.h"
30 #include "svcresource.h"
31 #include "srmresourcestrings.h"
32 #include "srmutility.h"
34 #include "security_internals.h"
38 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
39 * The value of payload size is increased until reaching belox max cbor size. */
40 static const uint8_t CBOR_SIZE = 255;
42 /** Max cbor size payload. */
43 static const uint16_t CBOR_MAX_SIZE = 4400;
45 /** SVC Map size - Number of mandatory items. */
46 static const uint8_t SVC_MAP_SIZE = 3;
48 static OicSecSvc_t *gSvc = NULL;
49 static OCResourceHandle gSvcHandle = NULL;
51 void DeleteSVCList(OicSecSvc_t* svc)
55 OicSecSvc_t *svcTmp1 = NULL, *svcTmp2 = NULL;
56 LL_FOREACH_SAFE(svc, svcTmp1, svcTmp2)
58 LL_DELETE(svc, svcTmp1);
61 OICFree(svcTmp1->owners);
63 // Clean SVC node itself
69 static size_t svcElementsCount(const OicSecSvc_t *secSvc)
72 for (const OicSecSvc_t *svc = secSvc; svc; svc = svc->next)
79 OCStackResult SVCToCBORPayload(const OicSecSvc_t *svc, uint8_t **cborPayload,
82 if (NULL == svc || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
84 return OC_STACK_INVALID_PARAM;
87 size_t cborLen = *cborSize;
95 CborError cborEncoderResult = CborNoError;
96 OCStackResult ret = OC_STACK_ERROR;
97 CborEncoder encoder = { {.ptr = NULL }, .end = 0 };
98 CborEncoder svcArray = { {.ptr = NULL }, .end = 0 };
100 uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
101 VERIFY_NON_NULL(TAG, outPayload, ERROR);
103 cbor_encoder_init(&encoder, outPayload, cborLen, 0);
106 cborEncoderResult = cbor_encoder_create_array(&encoder, &svcArray,
107 svcElementsCount(svc));
108 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Create SVC Array.");
112 CborEncoder svcMap = { {.ptr = NULL }, .end = 0};
113 cborEncoderResult = cbor_encoder_create_map(&svcArray, &svcMap, SVC_MAP_SIZE);
114 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Create SVC Map.");
116 // Service Device Identity
117 cborEncoderResult = cbor_encode_text_string(&svcMap, OIC_JSON_SERVICE_DEVICE_ID,
118 strlen(OIC_JSON_SERVICE_DEVICE_ID));
119 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Device Id.");
120 cborEncoderResult = cbor_encode_byte_string(&svcMap, (uint8_t *)svc->svcdid.id,
121 sizeof(svc->svcdid.id));
122 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to ");
125 cborEncoderResult = cbor_encode_text_string(&svcMap, OIC_JSON_SERVICE_TYPE,
126 strlen(OIC_JSON_SERVICE_TYPE));
127 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Serv Type Tag.");
128 cborEncoderResult = cbor_encode_int(&svcMap, svc->svct);
129 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Serv Type Value.");
132 cborEncoderResult = cbor_encode_text_string(&svcMap, OIC_JSON_OWNERS_NAME,
133 strlen(OIC_JSON_OWNERS_NAME));
134 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Owners Tag.");
135 CborEncoder owners = { {.ptr = NULL }, .end = 0 };
136 cborEncoderResult = cbor_encoder_create_array(&svcMap, &owners, svc->ownersLen);
137 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Array.");
138 for (size_t i = 0; i < svc->ownersLen; i++)
140 cborEncoderResult = cbor_encode_byte_string(&owners, (uint8_t *)svc->owners[i].id,
141 sizeof(svc->owners[i].id));
142 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Owners Value.");
144 cborEncoderResult = cbor_encoder_close_container(&svcMap, &owners);
145 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Close SVC Array.");
147 cborEncoderResult = cbor_encoder_close_container(&svcArray, &svcMap);
148 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Close SVC Map.");
153 cborEncoderResult = cbor_encoder_close_container(&encoder, &svcArray);
154 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Close SVC Array.");
156 *cborPayload = outPayload;
157 *cborSize = encoder.ptr - outPayload;
161 if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
163 // reallocate and try again!
166 // Since the allocated initial memory failed, double the memory.
167 cborLen += encoder.ptr - encoder.end;
168 cborEncoderResult = CborNoError;
169 ret = SVCToCBORPayload(svc, cborPayload, &cborLen);
172 if (CborNoError != cborEncoderResult)
178 ret = OC_STACK_ERROR;
184 OCStackResult CBORPayloadToSVC(const uint8_t *cborPayload, size_t size,
185 OicSecSvc_t **secSvc)
187 if (NULL == cborPayload || NULL == secSvc || NULL != *secSvc)
189 return OC_STACK_INVALID_PARAM;
194 OCStackResult ret = OC_STACK_ERROR;
196 CborValue svcCbor = { .parser = NULL };
197 CborParser parser = { .end = NULL };
198 CborError cborFindResult = CborNoError;
204 cbor_parser_init(cborPayload, cborLen, 0, &parser, &svcCbor);
206 OicSecSvc_t *headSvc = NULL;
208 CborValue svcArray = { .parser = NULL };
209 cborFindResult = cbor_value_enter_container(&svcCbor, &svcArray);
210 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Enter SVC Array.");
212 while (cbor_value_is_valid(&svcArray))
214 CborValue svcMap = { .parser = NULL };
215 cborFindResult = cbor_value_enter_container(&svcArray, &svcMap);
216 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Enter SVC Map.");
218 OicSecSvc_t *svc = (OicSecSvc_t *) OICCalloc(1, sizeof(OicSecSvc_t));
219 VERIFY_NON_NULL(TAG, svc, ERROR);
221 while (cbor_value_is_valid(&svcMap))
225 cborFindResult = cbor_value_dup_text_string(&svcMap, &name, &len, NULL);
226 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find Name.");
227 cborFindResult = cbor_value_advance(&svcMap);
228 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Advance.");
230 CborType type = cbor_value_get_type(&svcMap);
232 // Service Device Identity
233 if (0 == strcmp(OIC_JSON_SERVICE_DEVICE_ID, name))
235 uint8_t *subjectId = NULL;
236 cborFindResult = cbor_value_dup_byte_string(&svcMap, &subjectId, &len, NULL);
237 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find SubjectId.");
238 memcpy(svc->svcdid.id, subjectId, len);
242 if (0 == strcmp(OIC_JSON_SERVICE_TYPE, name))
244 cborFindResult = cbor_value_get_int(&svcMap, (int *) &svc->svct);
245 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find SVCT.");
248 // Owners -- Mandatory
249 if (0 == strcmp(OIC_JSON_OWNERS_NAME, name))
251 CborValue owners = { .parser = NULL };
252 cborFindResult = cbor_value_get_array_length(&svcMap, &svc->ownersLen);
253 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find Owner Len.");
254 cborFindResult = cbor_value_enter_container(&svcMap, &owners);
255 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Enter Owner Array.");
257 svc->owners = (OicUuid_t *)OICCalloc(svc->ownersLen, sizeof(*svc->owners));
258 VERIFY_NON_NULL(TAG, svc->owners, ERROR);
259 while (cbor_value_is_valid(&owners))
261 uint8_t *owner = NULL;
262 cborFindResult = cbor_value_dup_byte_string(&owners, &owner, &len, NULL);
263 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find Owner Array Value.");
264 cborFindResult = cbor_value_advance(&owners);
265 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Advance Owner Array.");
266 memcpy(svc->owners[i].id, owner, len);
270 if (CborMapType != type && cbor_value_is_valid(&svcMap))
272 cborFindResult = cbor_value_advance(&svcMap);
273 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Advance SVC.");
285 OicSecSvc_t *temp = headSvc;
292 if (cbor_value_is_valid(&svcArray))
294 cborFindResult = cbor_value_advance(&svcArray);
295 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find Name.");
302 if (CborNoError != cborFindResult)
304 DeleteSVCList(headSvc);
306 ret = OC_STACK_ERROR;
311 static OCEntityHandlerResult HandleSVCGetRequest (const OCEntityHandlerRequest * ehRequest)
313 // Convert SVC data into JSON for transmission
315 uint8_t *cborSvc = NULL;
316 OCStackResult res = SVCToCBORPayload(gSvc, &cborSvc, &size);
317 OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
319 // Send response payload to request originator
320 SendSRMCBORResponse(ehRequest, ehRet, cborSvc);
324 OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
328 static OCEntityHandlerResult HandleSVCPostRequest (const OCEntityHandlerRequest * ehRequest)
330 OCEntityHandlerResult ehRet = OC_EH_ERROR;
331 uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData1;;
334 // Convert CBOR SVC data into SVC. This will also validate the SVC data received.
335 OicSecSvc_t *newSvc = NULL;
336 OCStackResult res = CBORPayloadToSVC(payload, CBOR_SIZE, &newSvc);
337 if (newSvc && res == OC_STACK_OK)
339 // Append the new SVC to existing SVC
340 LL_APPEND(gSvc, newSvc);
342 // Convert SVC data into JSON for update to persistent storage
344 uint8_t *cborPayload = NULL;
345 res = SVCToCBORPayload(gSvc, &cborPayload, &size);
346 if (cborPayload && OC_STACK_OK == res &&
347 UpdateSecureResourceInPS(OIC_JSON_SVC_NAME, cborPayload, size) == OC_STACK_OK)
349 ehRet = OC_EH_RESOURCE_CREATED;
351 OICFree(cborPayload);
355 // Send payload to request originator
356 SendSRMCBORResponse(ehRequest, ehRet, NULL);
358 OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
363 * This internal method is the entity handler for SVC resources and
364 * will handle REST request (GET/PUT/POST/DEL) for them.
366 OCEntityHandlerResult SVCEntityHandler (OCEntityHandlerFlag flag,
367 OCEntityHandlerRequest * ehRequest,
368 void* callbackParameter)
370 (void) callbackParameter;
371 OCEntityHandlerResult ehRet = OC_EH_ERROR;
378 if (flag & OC_REQUEST_FLAG)
380 switch (ehRequest->method)
383 ehRet = HandleSVCGetRequest(ehRequest);
387 ehRet = HandleSVCPostRequest(ehRequest);
392 SendSRMCBORResponse(ehRequest, ehRet, NULL);
400 * This internal method is used to create '/oic/sec/svc' resource.
402 OCStackResult CreateSVCResource()
406 ret = OCCreateResource(&gSvcHandle,
407 OIC_RSRC_TYPE_SEC_SVC,
414 if (OC_STACK_OK != ret)
416 OIC_LOG(FATAL, TAG, "Unable to instantiate SVC resource");
423 OCStackResult InitSVCResource()
425 OIC_LOG_V (DEBUG, TAG, "Begin %s ", __func__ );
426 OCStackResult ret = OC_STACK_ERROR;
428 uint8_t *data = NULL;
430 ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_SVC_NAME, &data, &size);
431 // If database read failed
432 if (ret != OC_STACK_OK)
434 OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
439 // Convert JSON SVC into binary format
440 ret = CBORPayloadToSVC(data, size, &gSvc);
444 // Instantiate 'oic.sec.svc'
445 ret = CreateSVCResource();
447 if (OC_STACK_OK != ret)
452 OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ret);
457 * Perform cleanup for SVC resources.
461 void DeInitSVCResource()
463 OCDeleteResource(gSvcHandle);