1 /* *****************************************************************
3 * Copyright 2016 Samsung Electronics All Rights Reserved.
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 * *****************************************************************/
29 #include "oic_malloc.h"
30 #include "oic_string.h"
32 #include "payload_logging.h"
33 #include "ocpayload.h"
34 #include "cainterface.h"
35 #include "ocserverrequest.h"
36 #include "resourcemanager.h"
37 #include "verresource.h"
38 #include "doxmresource.h"
39 #include "psinterface.h"
40 #include "srmresourcestrings.h"
41 #include "securevirtualresourcetypes.h"
42 #include "srmutility.h"
46 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
47 * The value of payload size is increased until reaching belox max cbor size. */
48 static const uint8_t CBOR_SIZE = 255;
50 /** Max cbor size payload. */
51 static const uint16_t CBOR_MAX_SIZE = 4400;
53 /** VER Map size - Number of mandatory items. */
54 static const uint8_t VER_MAP_SIZE = 2;
56 static OCResourceHandle gVerHandle = NULL;
58 /** Security version is mapped with iotivity release version */
59 const char* SECURITY_VERSION = IOTIVITY_VERSION;
61 static OicSecVer_t gVer =
64 {.id = {0}}, /* OicUuid_t deviceID */
67 void DeleteVerBinData(OicSecVer_t* ver)
76 OCStackResult VerToCBORPayload(const OicSecVer_t *ver, uint8_t **payload, size_t *size)
78 if (NULL == ver || NULL == payload || NULL != *payload || NULL == size)
80 return OC_STACK_INVALID_PARAM;
82 size_t cborLen = *size;
90 OCStackResult ret = OC_STACK_ERROR;
95 int64_t cborEncoderResult = CborNoError;
96 uint8_t mapSize = VER_MAP_SIZE;
99 uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
100 VERIFY_NON_NULL(TAG, outPayload, ERROR);
101 cbor_encoder_init(&encoder, outPayload, cborLen, 0);
103 cborEncoderResult |= cbor_encoder_create_map(&encoder, &verMap, mapSize);
104 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Ver Map.");
107 cborEncoderResult |= cbor_encode_text_string(&verMap, OIC_JSON_SEC_V_NAME,
108 strlen(OIC_JSON_SEC_V_NAME));
109 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SecV Tag.");
110 cborEncoderResult |= cbor_encode_text_string(&verMap, ver->secv, strlen(ver->secv));
111 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SecV Value.");
113 //DeviceId -- Mandatory
114 cborEncoderResult = cbor_encode_text_string(&verMap, OIC_JSON_DEVICE_ID_NAME,
115 strlen(OIC_JSON_DEVICE_ID_NAME));
116 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Tag.");
117 ret = ConvertUuidToStr(&ver->deviceID, &strUuid);
118 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
119 cborEncoderResult = cbor_encode_text_string(&verMap, strUuid, strlen(strUuid));
120 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Value.");
125 // Close ver(first) container
126 cborEncoderResult |= cbor_encoder_close_container(&encoder, &verMap);
127 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing VerMap.");
129 if (CborNoError == cborEncoderResult)
131 *size = encoder.ptr - outPayload;
132 *payload = outPayload;
136 if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
138 OIC_LOG(DEBUG, TAG, "Memory getting reallocated.");
139 // reallocate and try again!
141 // Since the allocated initial memory failed, double the memory.
142 cborLen += encoder.ptr - encoder.end;
143 OIC_LOG_V(DEBUG, TAG, "Ver reallocation size : %zd.", cborLen);
144 cborEncoderResult = CborNoError;
145 ret = VerToCBORPayload(ver, payload, &cborLen);
149 if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
155 ret = OC_STACK_ERROR;
161 OCStackResult CBORPayloadToVer(const uint8_t *cborPayload, size_t size,
162 OicSecVer_t **secVer)
164 if (NULL == cborPayload || NULL == secVer || NULL != *secVer || 0 == size)
166 return OC_STACK_INVALID_PARAM;
169 OCStackResult ret = OC_STACK_ERROR;
171 char *strUuid = NULL;
173 CborParser parser = { .end = NULL};
174 CborError cborFindResult = CborNoError;
176 CborValue verCbor = { .parser = NULL };
177 cbor_parser_init(cborPayload, size, 0, &parser, &verCbor);
178 CborValue verMap = { .parser = NULL };
179 OicSecVer_t *ver = (OicSecVer_t *)OICCalloc(1, sizeof(OicSecVer_t));
180 VERIFY_NON_NULL(TAG, ver, ERROR);
183 cborFindResult = cbor_value_map_find_value(&verCbor, OIC_JSON_SEC_V_NAME, &verMap);
184 if (CborNoError == cborFindResult && cbor_value_is_text_string(&verMap))
186 char *version = NULL;
187 cborFindResult = cbor_value_dup_text_string(&verMap, &version, &len, NULL);
188 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Security Version Value.");
189 memcpy(ver->secv, version, len);
193 cborFindResult = cbor_value_map_find_value(&verCbor, OIC_JSON_DEVICE_ID_NAME, &verMap);
194 if (CborNoError == cborFindResult && cbor_value_is_text_string(&verMap))
196 cborFindResult = cbor_value_dup_text_string(&verMap, &strUuid , &len, NULL);
197 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Device Id Value.");
198 ret = ConvertStrToUuid(strUuid , &ver->deviceID);
199 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
208 if (CborNoError != cborFindResult)
210 OIC_LOG (ERROR, TAG, "CBORPayloadToVer failed!!!");
211 DeleteVerBinData(ver);
212 ret = OC_STACK_ERROR;
217 static OCEntityHandlerResult HandleVerGetRequest (const OCEntityHandlerRequest * ehRequest)
219 OCEntityHandlerResult ehRet = OC_EH_OK;
221 OIC_LOG(DEBUG, TAG, "Ver EntityHandle processing GET request");
224 * For GET request return ver resource CBOR payload.
225 * For non-valid query return NULL json payload.
226 * The version is static built-in information, so VerToCBORPayload will
227 * return valid ver resource json.
229 uint8_t *payload = NULL;
231 if (OC_STACK_OK != VerToCBORPayload(&gVer, &payload, &size))
236 // Send response payload to request originator
237 if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size))
240 OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleVerGetRequest");
248 OCEntityHandlerResult VerEntityHandler(OCEntityHandlerFlag flag,
249 OCEntityHandlerRequest * ehRequest,
253 OCEntityHandlerResult ehRet = OC_EH_ERROR;
255 if(NULL == ehRequest)
260 if (flag & OC_REQUEST_FLAG)
262 OIC_LOG(DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
264 switch (ehRequest->method)
267 ehRet = HandleVerGetRequest(ehRequest);
272 SendSRMResponse(ehRequest, ehRet, NULL, 0);
280 OCStackResult CreateVerResource()
282 OCStackResult ret = OCCreateResource(&gVerHandle,
283 OIC_RSRC_TYPE_SEC_VER,
290 if (OC_STACK_OK != ret)
292 OIC_LOG (FATAL, TAG, "Unable to instantiate Ver resource");
299 * Get the security version.
301 * @return the version string of security.
303 const char* GetSecVersion()
305 OIC_LOG(DEBUG, TAG, "GetSecVersion");
309 const OicSecVer_t* GetVerResourceData()
314 OCStackResult InitVerResource()
316 OCStackResult ret = OC_STACK_ERROR;
318 OICStrcpy(gVer.secv, strlen(SECURITY_VERSION)+1, SECURITY_VERSION);
320 //Read device id from doxm
321 OicUuid_t deviceID = {.id={0}};
322 ret = GetDoxmDeviceID(&deviceID);
323 if (OC_STACK_OK != ret)
325 OIC_LOG(ERROR, TAG, "Error while retrieving doxm device ID");
328 memcpy(&gVer.deviceID, &deviceID, sizeof(OicUuid_t));
330 //Instantiate 'oic.sec.ver'
331 ret = CreateVerResource();
332 if (OC_STACK_OK != ret)
334 OIC_LOG(ERROR, TAG, "Error while creating VER resource");
340 OCStackResult DeInitVerResource()
342 OCStackResult ret = OCDeleteResource(gVerHandle);
344 memset(&gVer, 0, sizeof(gVer));
346 if (OC_STACK_OK == ret)
352 return OC_STACK_ERROR;