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.");
226 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PCONF_NAME, &curVal);
227 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
229 cborFindResult = cbor_value_dup_byte_string(&curVal, &pconfCbor, &pconfCborLen, NULL);
230 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PCONF Name Value.");
236 size_t size = aclCborLen + pstatCborLen + doxmCborLen + amaclCborLen + svcCborLen
237 + credCborLen + pconfCborLen + psSize;
238 // This is arbitrary value that is added to cover the name of the resource, map addition and ending.
241 outPayload = (uint8_t *)OICCalloc(1, size);
242 VERIFY_NON_NULL(TAG, outPayload, ERROR);
243 cbor_encoder_init(&encoder, outPayload, size, 0);
246 cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
247 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
251 cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
252 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
253 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
254 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
257 if (0 != strcmp(OIC_JSON_ACL_NAME, rsrcName) && aclCborLen > 0)
259 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
260 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
261 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
262 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
264 if (0 != strcmp(OIC_JSON_PSTAT_NAME, rsrcName) && pstatCborLen > 0)
266 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
267 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
268 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
269 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
271 if (0 != strcmp(OIC_JSON_DOXM_NAME, rsrcName) && doxmCborLen > 0)
273 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
274 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
275 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
276 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
278 if (0 != strcmp(OIC_JSON_AMACL_NAME, rsrcName) && amaclCborLen > 0)
280 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_AMACL_NAME, strlen(OIC_JSON_AMACL_NAME));
281 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Name.");
282 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, amaclCbor, amaclCborLen);
283 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Value.");
285 if (0 != strcmp(OIC_JSON_SVC_NAME, rsrcName) && svcCborLen > 0)
287 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_SVC_NAME, strlen(OIC_JSON_SVC_NAME));
288 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Name.");
289 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, svcCbor, svcCborLen);
290 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Value.");
292 if (0 != strcmp(OIC_JSON_CRED_NAME, rsrcName) && credCborLen > 0)
294 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
295 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Name.");
296 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
297 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Value.");
299 if (0 != strcmp(OIC_JSON_PCONF_NAME, rsrcName) && pconfCborLen > 0)
301 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PCONF_NAME, strlen(OIC_JSON_PCONF_NAME));
302 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Name.");
303 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pconfCbor, pconfCborLen);
304 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Value.");
307 cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
308 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
310 cborSize = encoder.ptr - outPayload;
315 size_t size = psSize + 255;
316 outPayload = (uint8_t *)OICCalloc(1, size);
317 VERIFY_NON_NULL(TAG, outPayload, ERROR);
319 cbor_encoder_init(&encoder, outPayload, size, 0);
321 CborEncoder secRsrc ;
322 cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
323 cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
324 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
325 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
326 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
327 cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
328 cborSize = encoder.ptr - outPayload;
331 if (outPayload && cborSize > 0)
333 OIC_LOG_V(DEBUG, TAG, "Writting in the file. %zd", cborSize);
334 OCPersistentStorage* ps = SRMGetPersistentStorageHandler();
337 FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "w+");
340 size_t numberItems = ps->write(outPayload, 1, cborSize, fp);
341 if (cborSize == numberItems)
343 OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", cborSize);
348 OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", numberItems);
354 OIC_LOG(ERROR, TAG, "File open failed.");
358 OIC_LOG_V(DEBUG, TAG, "Writing in the file . %zd", cborSize);
361 OIC_LOG(DEBUG, TAG, "Exiting UpdateSecureResourceInPS OUT");