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 * *****************************************************************/
21 #include "iotivity_config.h"
30 #include "oic_malloc.h"
31 #include "oic_string.h"
33 #include "payload_logging.h"
34 #include "ocpayload.h"
35 #include "cainterface.h"
36 #include "ocserverrequest.h"
37 #include "resourcemanager.h"
38 #include "verresource.h"
39 #include "doxmresource.h"
40 #include "psinterface.h"
41 #include "srmresourcestrings.h"
42 #include "securevirtualresourcetypes.h"
43 #include "srmutility.h"
47 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
48 * The value of payload size is increased until reaching belox max cbor size. */
49 static const uint8_t CBOR_SIZE = 255;
51 /** Max cbor size payload. */
52 static const uint16_t CBOR_MAX_SIZE = 4400;
54 /** VER Map size - Number of mandatory items. */
55 static const uint8_t VER_MAP_SIZE = 2;
57 static OCResourceHandle gVerHandle = NULL;
59 /** Security version is mapped with iotivity release version */
60 const char* SECURITY_VERSION = IOTIVITY_VERSION;
62 static OicSecVer_t gVer =
65 {.id = {0}}, /* OicUuid_t deviceID */
68 void DeleteVerBinData(OicSecVer_t* ver)
77 OCStackResult VerToCBORPayload(const OicSecVer_t *ver, uint8_t **payload, size_t *size)
79 if (NULL == ver || NULL == payload || NULL != *payload || NULL == size)
81 return OC_STACK_INVALID_PARAM;
83 size_t cborLen = *size;
91 OCStackResult ret = OC_STACK_ERROR;
96 int64_t cborEncoderResult = CborNoError;
97 uint8_t mapSize = VER_MAP_SIZE;
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, &verMap, mapSize);
105 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Ver Map.");
108 cborEncoderResult |= cbor_encode_text_string(&verMap, OIC_JSON_SEC_V_NAME,
109 strlen(OIC_JSON_SEC_V_NAME));
110 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SecV Tag.");
111 cborEncoderResult |= cbor_encode_text_string(&verMap, ver->secv, strlen(ver->secv));
112 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SecV Value.");
114 //DeviceId -- Mandatory
115 cborEncoderResult = cbor_encode_text_string(&verMap, OIC_JSON_DEVICE_ID_NAME,
116 strlen(OIC_JSON_DEVICE_ID_NAME));
117 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Tag.");
118 ret = ConvertUuidToStr(&ver->deviceID, &strUuid);
119 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
120 cborEncoderResult = cbor_encode_text_string(&verMap, strUuid, strlen(strUuid));
121 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Value.");
126 // Close ver(first) container
127 cborEncoderResult |= cbor_encoder_close_container(&encoder, &verMap);
128 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing VerMap.");
130 if (CborNoError == cborEncoderResult)
132 *size = encoder.ptr - outPayload;
133 *payload = outPayload;
137 if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
139 OIC_LOG(DEBUG, TAG, "Memory getting reallocated.");
140 // reallocate and try again!
142 // Since the allocated initial memory failed, double the memory.
143 cborLen += encoder.ptr - encoder.end;
144 OIC_LOG_V(DEBUG, TAG, "Ver reallocation size : %zd.", cborLen);
145 cborEncoderResult = CborNoError;
146 ret = VerToCBORPayload(ver, payload, &cborLen);
150 if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
156 ret = OC_STACK_ERROR;
162 OCStackResult CBORPayloadToVer(const uint8_t *cborPayload, size_t size,
163 OicSecVer_t **secVer)
165 if (NULL == cborPayload || NULL == secVer || NULL != *secVer || 0 == size)
167 return OC_STACK_INVALID_PARAM;
170 OCStackResult ret = OC_STACK_ERROR;
172 char *strUuid = NULL;
174 CborParser parser = { .end = NULL};
175 CborError cborFindResult = CborNoError;
177 CborValue verCbor = { .parser = NULL };
178 cbor_parser_init(cborPayload, size, 0, &parser, &verCbor);
179 CborValue verMap = { .parser = NULL };
180 OicSecVer_t *ver = (OicSecVer_t *)OICCalloc(1, sizeof(OicSecVer_t));
181 VERIFY_NON_NULL(TAG, ver, ERROR);
184 cborFindResult = cbor_value_map_find_value(&verCbor, OIC_JSON_SEC_V_NAME, &verMap);
185 if (CborNoError == cborFindResult && cbor_value_is_text_string(&verMap))
187 char *version = NULL;
188 cborFindResult = cbor_value_dup_text_string(&verMap, &version, &len, NULL);
189 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Security Version Value.");
190 memcpy(ver->secv, version, len);
194 cborFindResult = cbor_value_map_find_value(&verCbor, OIC_JSON_DEVICE_ID_NAME, &verMap);
195 if (CborNoError == cborFindResult && cbor_value_is_text_string(&verMap))
197 cborFindResult = cbor_value_dup_text_string(&verMap, &strUuid , &len, NULL);
198 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Device Id Value.");
199 ret = ConvertStrToUuid(strUuid , &ver->deviceID);
200 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
209 if (CborNoError != cborFindResult)
211 OIC_LOG (ERROR, TAG, "CBORPayloadToVer failed!!!");
212 DeleteVerBinData(ver);
213 ret = OC_STACK_ERROR;
218 static OCEntityHandlerResult HandleVerGetRequest (const OCEntityHandlerRequest * ehRequest)
220 OCEntityHandlerResult ehRet = OC_EH_OK;
222 OIC_LOG(DEBUG, TAG, "Ver EntityHandle processing GET request");
225 * For GET request return ver resource CBOR payload.
226 * For non-valid query return NULL json payload.
227 * The version is static built-in information, so VerToCBORPayload will
228 * return valid ver resource json.
230 uint8_t *payload = NULL;
232 if (OC_STACK_OK != VerToCBORPayload(&gVer, &payload, &size))
237 // Send response payload to request originator
238 if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size))
241 OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleVerGetRequest");
249 OCEntityHandlerResult VerEntityHandler(OCEntityHandlerFlag flag,
250 OCEntityHandlerRequest * ehRequest,
254 OCEntityHandlerResult ehRet = OC_EH_ERROR;
256 if(NULL == ehRequest)
261 if (flag & OC_REQUEST_FLAG)
263 OIC_LOG(DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
265 switch (ehRequest->method)
268 ehRet = HandleVerGetRequest(ehRequest);
273 SendSRMResponse(ehRequest, ehRet, NULL, 0);
281 OCStackResult CreateVerResource()
283 OCStackResult ret = OCCreateResource(&gVerHandle,
284 OIC_RSRC_TYPE_SEC_VER,
285 OC_RSRVD_INTERFACE_DEFAULT,
291 if (OC_STACK_OK != ret)
293 OIC_LOG (FATAL, TAG, "Unable to instantiate Ver resource");
300 * Get the security version.
302 * @return the version string of security.
304 const char* GetSecVersion()
306 OIC_LOG(DEBUG, TAG, "GetSecVersion");
310 const OicSecVer_t* GetVerResourceData()
315 OCStackResult InitVerResource()
317 OCStackResult ret = OC_STACK_ERROR;
319 OICStrcpy(gVer.secv, MAX_VERSION_LEN, SECURITY_VERSION);
321 //Read device id from doxm
322 OicUuid_t deviceID = {.id={0}};
323 ret = GetDoxmDeviceID(&deviceID);
324 if (OC_STACK_OK != ret)
326 OIC_LOG(ERROR, TAG, "Error while retrieving doxm device ID");
329 memcpy(&gVer.deviceID, &deviceID, sizeof(OicUuid_t));
331 //Instantiate 'oic.sec.ver'
332 ret = CreateVerResource();
333 if (OC_STACK_OK != ret)
335 OIC_LOG(ERROR, TAG, "Error while creating VER resource");
341 OCStackResult DeInitVerResource()
343 OCStackResult ret = OCDeleteResource(gVerHandle);
345 memset(&gVer, 0, sizeof(gVer));
347 if (OC_STACK_OK == ret)
353 return OC_STACK_ERROR;