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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 #define __STDC_LIMIT_MACROS
28 #include "oic_malloc.h"
29 #include "ocpayload.h"
30 #include "ocpayloadcbor.h"
31 #include "payload_logging.h"
32 #include "cainterface.h"
33 #include "secureresourcemanager.h"
34 #include "resourcemanager.h"
35 #include "srmresourcestrings.h"
36 #include "srmutility.h"
40 //SVR database buffer block size
41 const size_t DB_FILE_SIZE_BLOCK = 1023;
44 * Gets the Secure Virtual Database size.
46 * @param ps pointer of OCPersistentStorage for the SVR name ("acl", "cred", "pstat" etc).
48 * @return total size of the SVR database.
50 static size_t GetSVRDatabaseSize(const OCPersistentStorage* ps)
58 char buffer[DB_FILE_SIZE_BLOCK];
59 FILE* fp = ps->open(SVR_DB_DAT_FILE_NAME, "r");
64 bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
66 } while (bytesRead > 0);
72 OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **data, size_t *size)
76 return OC_STACK_INVALID_PARAM;
78 OCStackResult ret = OC_STACK_ERROR;
83 uint8_t *fsData = NULL;
85 OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
86 VERIFY_NON_NULL(TAG, ps, ERROR);
88 fileSize = GetSVRDatabaseSize(ps);
91 OIC_LOG_V(DEBUG, TAG, "File Read Size: %zu", fileSize);
92 fsData = (uint8_t *)OICCalloc(1, fileSize);
93 VERIFY_NON_NULL(TAG, fsData, ERROR);
95 FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
96 VERIFY_NON_NULL(TAG, fp, ERROR);
97 size_t itemsRead = ps->read(fsData, 1, fileSize, fp);
98 if (itemsRead == fileSize)
100 VERIFY_NON_NULL(TAG, fsData, ERROR);
101 if (rsrcName != NULL)
103 CborParser parser = { .end = NULL };
104 CborValue cbor = { .parser = NULL };
105 cbor_parser_init(fsData, fileSize, 0, &parser, &cbor);
106 CborValue cborValue = { .parser = NULL };
107 // CborError cborFindResult = cbor_value_enter_container(&cbor, &cborValue);
108 CborError cborFindResult = cbor_value_map_find_value(&cbor, rsrcName, &cborValue);
109 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&cborValue))
111 cborFindResult = cbor_value_dup_byte_string(&cborValue, data, size, NULL);
112 VERIFY_SUCCESS(TAG, cborFindResult == CborNoError, ERROR);
117 // return everything in case rsrcName is NULL
121 *data = (uint8_t *)OICCalloc(1, fileSize);
122 VERIFY_NON_NULL(TAG, *data, ERROR);
123 memcpy(*data, fsData, fileSize);
137 OCStackResult UpdateSecureResourceInPS(const char* rsrcName, const uint8_t* psPayload, size_t psSize)
139 OIC_LOG(DEBUG, TAG, "Entering UpdateSecureResourceInPS IN");
141 * This function stores cbor payload of each resource by appending resource name.
143 // Empty payload implies deleting the value
146 return OC_STACK_INVALID_PARAM;
149 OCStackResult ret = OC_STACK_ERROR;
151 uint8_t *dbData = NULL;
154 uint8_t *outPayload = NULL;
155 uint8_t *aclCbor = NULL;
156 uint8_t *pstatCbor = NULL;
157 uint8_t *amaclCbor = NULL;
158 uint8_t *doxmCbor = NULL;
159 uint8_t *svcCbor = NULL;
160 uint8_t *credCbor = NULL;
161 uint8_t *pconfCbor = NULL;
163 int64_t cborEncoderResult = CborNoError;
166 ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
167 if (dbData && dbSize != 0)
169 size_t aclCborLen = 0;
170 size_t pstatCborLen = 0;
171 size_t doxmCborLen = 0;
172 size_t amaclCborLen = 0;
173 size_t svcCborLen = 0;
174 size_t credCborLen = 0;
175 size_t pconfCborLen = 0;
180 cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
181 CborError cborFindResult = CborNoError;
184 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
185 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
187 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
188 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
191 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
192 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
194 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
195 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value.");
198 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
199 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
201 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
202 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
205 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_AMACL_NAME, &curVal);
206 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
208 cborFindResult = cbor_value_dup_byte_string(&curVal, &amaclCbor, &amaclCborLen, NULL);
209 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding AMACL Name Value.");
212 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_SVC_NAME, &curVal);
213 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
215 cborFindResult = cbor_value_dup_byte_string(&curVal, &svcCbor, &svcCborLen, NULL);
216 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SVC Name Value.");
219 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
220 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
222 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
223 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value.");
225 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PCONF_NAME, &curVal);
226 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
228 cborFindResult = cbor_value_dup_byte_string(&curVal, &pconfCbor, &pconfCborLen, NULL);
229 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PCONF Name Value.");
235 size_t size = aclCborLen + pstatCborLen + doxmCborLen + amaclCborLen + svcCborLen
236 + credCborLen + pconfCborLen +psSize;
237 // This is arbitrary value that is added to cover the name of the resource, map addition and ending.
240 outPayload = (uint8_t *)OICCalloc(1, size);
241 VERIFY_NON_NULL(TAG, outPayload, ERROR);
242 cbor_encoder_init(&encoder, outPayload, size, 0);
245 cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
246 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
250 cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
251 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
252 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
253 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
256 if (0 != strcmp(OIC_JSON_ACL_NAME, rsrcName) && aclCborLen > 0)
258 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
259 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
260 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
261 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
263 if (0 != strcmp(OIC_JSON_PSTAT_NAME, rsrcName) && pstatCborLen > 0)
265 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
266 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
267 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
268 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
270 if (0 != strcmp(OIC_JSON_DOXM_NAME, rsrcName) && doxmCborLen > 0)
272 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
273 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
274 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
275 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
277 if (0 != strcmp(OIC_JSON_AMACL_NAME, rsrcName) && amaclCborLen > 0)
279 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_AMACL_NAME, strlen(OIC_JSON_AMACL_NAME));
280 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Name.");
281 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, amaclCbor, amaclCborLen);
282 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Value.");
284 if (0 != strcmp(OIC_JSON_SVC_NAME, rsrcName) && svcCborLen > 0)
286 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_SVC_NAME, strlen(OIC_JSON_SVC_NAME));
287 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Name.");
288 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, svcCbor, svcCborLen);
289 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Value.");
291 if (0 != strcmp(OIC_JSON_CRED_NAME, rsrcName) && credCborLen > 0)
293 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
294 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Name.");
295 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
296 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Value.");
298 if (0 != strcmp(OIC_JSON_PCONF_NAME, rsrcName) && pconfCborLen > 0)
300 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PCONF_NAME, strlen(OIC_JSON_PCONF_NAME));
301 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Name.");
302 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pconfCbor, pconfCborLen);
303 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Value.");
306 cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
307 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
309 cborSize = encoder.ptr - outPayload;
314 size_t size = psSize + 255;
315 outPayload = (uint8_t *)OICCalloc(1, size);
316 VERIFY_NON_NULL(TAG, outPayload, ERROR);
318 cbor_encoder_init(&encoder, outPayload, size, 0);
320 CborEncoder secRsrc ;
321 cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
322 cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
323 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
324 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
325 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
326 cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
327 cborSize = encoder.ptr - outPayload;
330 if (outPayload && cborSize > 0)
332 OIC_LOG_V(DEBUG, TAG, "Writting in the file. %zd", cborSize);
333 OCPersistentStorage* ps = SRMGetPersistentStorageHandler();
336 FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "w+");
339 size_t numberItems = ps->write(outPayload, 1, cborSize, fp);
340 if (cborSize == numberItems)
342 OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", cborSize);
347 OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", numberItems);
353 OIC_LOG(ERROR, TAG, "File open failed.");
357 OIC_LOG_V(DEBUG, TAG, "Writing in the file . %zd", cborSize);
360 OIC_LOG(DEBUG, TAG, "Exiting UpdateSecureResourceInPS OUT");