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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
22 #define __STDC_LIMIT_MACROS
28 #include "cainterface.h"
30 #include "ocpayload.h"
31 #include "ocpayloadcbor.h"
33 #include "oic_malloc.h"
34 #include "payload_logging.h"
35 #include "resourcemanager.h"
36 #include "secureresourcemanager.h"
37 #include "srmresourcestrings.h"
38 #include "srmutility.h"
42 //SVR database buffer block size
43 const size_t DB_FILE_SIZE_BLOCK = 1023;
46 * Gets the Secure Virtual Database size
48 * @param ps - pointer of OCPersistentStorage for the Secure Virtual Resource(s)
50 * @return size_t - total size of the SVR database
52 static size_t GetSVRDatabaseSize(const OCPersistentStorage *ps)
59 char buffer[DB_FILE_SIZE_BLOCK]; // can not initialize with declaration
60 // but maybe not needed to initialize
61 FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
67 bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
76 * Gets the Secure Virtual Database from the Persistent Storage
78 * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
79 * @param data - pointer of the returned Secure Virtual Resource(s)
80 * @param size - pointer of the returned size of Secure Virtual Resource(s)
82 * @return OCStackResult - result of getting Secure Virtual Resource(s)
84 OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **data, size_t *size)
86 OIC_LOG(DEBUG, TAG, "GetSecureVirtualDatabaseFromPS IN");
87 if (!data || *data || !size)
89 return OC_STACK_INVALID_PARAM;
93 uint8_t *fsData = NULL;
95 OCStackResult ret = OC_STACK_ERROR;
97 OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
98 VERIFY_NON_NULL(TAG, ps, ERROR);
100 fileSize = GetSVRDatabaseSize(ps);
101 OIC_LOG_V(DEBUG, TAG, "File Read Size: %zu", fileSize);
104 fsData = (uint8_t *) OICCalloc(1, fileSize);
105 VERIFY_NON_NULL(TAG, fsData, ERROR);
107 fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
108 VERIFY_NON_NULL(TAG, fp, ERROR);
109 if (ps->read(fsData, 1, fileSize, fp) == fileSize)
113 CborParser parser; // will be initialized in |cbor_parser_init|
114 CborValue cbor; // will be initialized in |cbor_parser_init|
115 cbor_parser_init(fsData, fileSize, 0, &parser, &cbor);
116 CborValue cborValue = {0};
117 CborError cborFindResult = cbor_value_map_find_value(&cbor, rsrcName, &cborValue);
118 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&cborValue))
120 cborFindResult = cbor_value_dup_byte_string(&cborValue, data, size, NULL);
121 VERIFY_SUCCESS(TAG, CborNoError==cborFindResult, ERROR);
124 // in case of |else (...)|, svr_data not found
126 // return everything in case rsrcName is NULL
130 *data = (uint8_t *) OICCalloc(1, fileSize);
131 VERIFY_NON_NULL(TAG, *data, ERROR);
132 memcpy(*data, fsData, fileSize);
137 OIC_LOG(DEBUG, TAG, "GetSecureVirtualDatabaseFromPS OUT");
149 * Updates the Secure Virtual Resource(s) into the Persistent Storage.
150 * This function stores cbor-payload of each resource by appending resource name,
151 * and empty payload implies deleting the value
153 * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
154 * @param psPayload - pointer of the updated Secure Virtual Resource(s)
155 * @param psSize - the updated size of Secure Virtual Resource(s)
157 * @return OCStackResult - result of updating Secure Virtual Resource(s)
159 OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPayload, size_t psSize)
161 OIC_LOG(DEBUG, TAG, "UpdateSecureResourceInPS IN");
164 return OC_STACK_INVALID_PARAM;
169 uint8_t *dbData = NULL;
170 uint8_t *outPayload = NULL;
172 uint8_t *aclCbor = NULL;
173 uint8_t *pstatCbor = NULL;
174 uint8_t *doxmCbor = NULL;
175 uint8_t *amaclCbor = NULL;
176 uint8_t *svcCbor = NULL;
177 uint8_t *credCbor = NULL;
178 uint8_t *pconfCbor = NULL;
180 int64_t cborEncoderResult = CborNoError;
181 OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
182 if (dbData && dbSize)
184 size_t aclCborLen = 0;
185 size_t pstatCborLen = 0;
186 size_t doxmCborLen = 0;
187 size_t amaclCborLen = 0;
188 size_t svcCborLen = 0;
189 size_t credCborLen = 0;
190 size_t pconfCborLen = 0;
192 // Gets each secure virtual resource from persistent storage
193 // this local scoping intended, for destroying large cbor instances after use
195 CborParser parser; // will be initialized in |cbor_parser_init|
196 CborValue cbor; // will be initialized in |cbor_parser_init|
197 cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
198 CborValue curVal = {0};
199 CborError cborFindResult = CborNoError;
201 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
202 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
204 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
205 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
207 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
208 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
210 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
211 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
213 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
214 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
216 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
217 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value.");
219 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_AMACL_NAME, &curVal);
220 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
222 cborFindResult = cbor_value_dup_byte_string(&curVal, &amaclCbor, &amaclCborLen, NULL);
223 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding AMACL Name Value.");
225 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_SVC_NAME, &curVal);
226 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
228 cborFindResult = cbor_value_dup_byte_string(&curVal, &svcCbor, &svcCborLen, NULL);
229 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SVC Name Value.");
231 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
232 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
234 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
235 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value.");
237 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PCONF_NAME, &curVal);
238 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
240 cborFindResult = cbor_value_dup_byte_string(&curVal, &pconfCbor, &pconfCborLen, NULL);
241 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PCONF Name Value.");
245 // Updates the added |psPayload| with the existing secure virtual resource(s)
246 // this local scoping intended, for destroying large cbor instances after use
248 size_t size = aclCborLen + pstatCborLen + doxmCborLen + amaclCborLen
249 + svcCborLen + credCborLen + pconfCborLen + psSize + 255;
250 // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
252 outPayload = (uint8_t *) OICCalloc(1, size);
253 VERIFY_NON_NULL(TAG, outPayload, ERROR);
254 CborEncoder encoder; // will be initialized in |cbor_parser_init|
255 cbor_encoder_init(&encoder, outPayload, size, 0);
256 CborEncoder secRsrc; // will be initialized in |cbor_encoder_create_map|
257 cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
258 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
260 if (psPayload && psSize)
262 cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
263 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
264 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
265 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
267 if (strcmp(OIC_JSON_ACL_NAME, rsrcName) && aclCborLen)
269 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
270 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
271 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
272 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
274 if (strcmp(OIC_JSON_PSTAT_NAME, rsrcName) && pstatCborLen)
276 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
277 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
278 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
279 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
281 if (strcmp(OIC_JSON_DOXM_NAME, rsrcName) && doxmCborLen)
283 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
284 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
285 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
286 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
288 if (strcmp(OIC_JSON_AMACL_NAME, rsrcName) && amaclCborLen)
290 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_AMACL_NAME, strlen(OIC_JSON_AMACL_NAME));
291 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Name.");
292 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, amaclCbor, amaclCborLen);
293 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Value.");
295 if (strcmp(OIC_JSON_SVC_NAME, rsrcName) && svcCborLen)
297 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_SVC_NAME, strlen(OIC_JSON_SVC_NAME));
298 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Name.");
299 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, svcCbor, svcCborLen);
300 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Value.");
302 if (strcmp(OIC_JSON_CRED_NAME, rsrcName) && credCborLen)
304 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
305 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Name.");
306 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
307 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Value.");
309 if (strcmp(OIC_JSON_PCONF_NAME, rsrcName) && pconfCborLen)
311 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PCONF_NAME, strlen(OIC_JSON_PCONF_NAME));
312 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Name.");
313 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pconfCbor, pconfCborLen);
314 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Value.");
317 cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
318 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
319 outSize = encoder.ptr - outPayload;
322 else if (psPayload && psSize)
324 size_t size = psSize + 255;
325 // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
327 outPayload = (uint8_t *) OICCalloc(1, size);
328 VERIFY_NON_NULL(TAG, outPayload, ERROR);
329 CborEncoder encoder; // will be initialized in |cbor_parser_init|
330 cbor_encoder_init(&encoder, outPayload, size, 0);
331 CborEncoder secRsrc; // will be initialized in |cbor_encoder_create_map|
332 cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
333 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
335 cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
336 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
337 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
338 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
340 cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
341 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
342 outSize = encoder.ptr - outPayload;
345 if (outPayload && outSize)
347 OIC_LOG_V(DEBUG, TAG, "Writting in the file: %zu", outSize);
348 OCPersistentStorage* ps = SRMGetPersistentStorageHandler();
351 FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb");
354 size_t numberItems = ps->write(outPayload, 1, outSize, fp);
355 if (outSize == numberItems)
357 OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", outSize);
362 OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", numberItems);
368 OIC_LOG(ERROR, TAG, "File open failed.");
373 OIC_LOG(DEBUG, TAG, "UpdateSecureResourceInPS OUT");