5d219bd4e60046287da69d4d26ba787f4e6eadc8
[iotivity.git] / resource / csdk / security / src / psinterface.c
1 //******************************************************************
2 //
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
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
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
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.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #ifdef WITH_ARDUINO
22 #define __STDC_LIMIT_MACROS
23 #endif
24
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "cainterface.h"
29 #include "logger.h"
30 #include "ocpayload.h"
31 #include "ocpayloadcbor.h"
32 #include "ocstack.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"
39 #include "pstatresource.h"
40 #include "doxmresource.h"
41
42 #define TAG  "OIC_SRM_PSI"
43
44 //SVR database buffer block size
45 #ifdef _WIN32
46 #define DB_FILE_SIZE_BLOCK 1023
47 #else
48 const size_t DB_FILE_SIZE_BLOCK = 1023;
49 #endif
50
51 /**
52  * Gets the Secure Virtual Database size
53  *
54  * @param ps - pointer of OCPersistentStorage for the Secure Virtual Resource(s)
55  *
56  * @return size_t - total size of the SVR database
57  */
58 static size_t GetSVRDatabaseSize(const OCPersistentStorage *ps)
59 {
60     if (!ps)
61     {
62         return 0;
63     }
64     size_t size = 0;
65     char buffer[DB_FILE_SIZE_BLOCK];  // can not initialize with declaration
66                                       // but maybe not needed to initialize
67     FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
68     if (fp)
69     {
70         size_t bytesRead = 0;
71         do
72         {
73             bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
74             size += bytesRead;
75         } while (bytesRead);
76         ps->close(fp);
77     }
78     return size;
79 }
80
81 /**
82  * Gets the Secure Virtual Database from the Persistent Storage
83  *
84  * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
85  * @param data - pointer of the returned Secure Virtual Resource(s)
86  * @param size - pointer of the returned size of Secure Virtual Resource(s)
87  *
88  * @return OCStackResult - result of getting Secure Virtual Resource(s)
89  */
90 OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **data, size_t *size)
91 {
92     OIC_LOG(DEBUG, TAG, "GetSecureVirtualDatabaseFromPS IN");
93     if (!data || *data || !size)
94     {
95         return OC_STACK_INVALID_PARAM;
96     }
97
98     FILE *fp = NULL;
99     uint8_t *fsData = NULL;
100     size_t fileSize = 0;
101     OCStackResult ret = OC_STACK_ERROR;
102
103     OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
104     VERIFY_NON_NULL(TAG, ps, ERROR);
105
106     fileSize = GetSVRDatabaseSize(ps);
107     OIC_LOG_V(DEBUG, TAG, "File Read Size: %zu", fileSize);
108     if (fileSize)
109     {
110         fsData = (uint8_t *) OICCalloc(1, fileSize);
111         VERIFY_NON_NULL(TAG, fsData, ERROR);
112
113         fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
114         VERIFY_NON_NULL(TAG, fp, ERROR);
115         if (ps->read(fsData, 1, fileSize, fp) == fileSize)
116         {
117             if (rsrcName)
118             {
119                 CborParser parser;  // will be initialized in |cbor_parser_init|
120                 CborValue cbor;     // will be initialized in |cbor_parser_init|
121                 cbor_parser_init(fsData, fileSize, 0, &parser, &cbor);
122                 CborValue cborValue = {0};
123                 CborError cborFindResult = cbor_value_map_find_value(&cbor, rsrcName, &cborValue);
124                 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&cborValue))
125                 {
126                     cborFindResult = cbor_value_dup_byte_string(&cborValue, data, size, NULL);
127                     VERIFY_SUCCESS(TAG, CborNoError==cborFindResult, ERROR);
128                     ret = OC_STACK_OK;
129                 }
130                 // in case of |else (...)|, svr_data not found
131             }
132             // return everything in case rsrcName is NULL
133             else
134             {
135                 *size = fileSize;
136                 *data = (uint8_t *) OICCalloc(1, fileSize);
137                 VERIFY_NON_NULL(TAG, *data, ERROR);
138                 memcpy(*data, fsData, fileSize);
139                 ret = OC_STACK_OK;
140             }
141         }
142     }
143     OIC_LOG(DEBUG, TAG, "GetSecureVirtualDatabaseFromPS OUT");
144
145 exit:
146     if (fp)
147     {
148         ps->close(fp);
149     }
150     OICFree(fsData);
151     return ret;
152 }
153
154 /**
155  * Updates the Secure Virtual Resource(s) into the Persistent Storage.
156  * This function stores cbor-payload of each resource by appending resource name,
157  * and empty payload implies deleting the value
158  *
159  * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
160  * @param psPayload - pointer of the updated Secure Virtual Resource(s)
161  * @param psSize - the updated size of Secure Virtual Resource(s)
162  *
163  * @return OCStackResult - result of updating Secure Virtual Resource(s)
164  */
165 OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPayload, size_t psSize)
166 {
167     OIC_LOG(DEBUG, TAG, "UpdateSecureResourceInPS IN");
168     if (!rsrcName)
169     {
170         return OC_STACK_INVALID_PARAM;
171     }
172
173     size_t dbSize = 0;
174     size_t outSize = 0;
175     uint8_t *dbData = NULL;
176     uint8_t *outPayload = NULL;
177
178     uint8_t *aclCbor = NULL;
179     uint8_t *pstatCbor = NULL;
180     uint8_t *doxmCbor = NULL;
181     uint8_t *amaclCbor = NULL;
182     uint8_t *svcCbor = NULL;
183     uint8_t *credCbor = NULL;
184     uint8_t *pconfCbor = NULL;
185     uint8_t *resetPfCbor = NULL;
186     uint8_t *crlCbor = NULL;
187
188     int64_t cborEncoderResult = CborNoError;
189     OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
190     if (dbData && dbSize)
191     {
192         size_t aclCborLen = 0;
193         size_t pstatCborLen = 0;
194         size_t doxmCborLen = 0;
195         size_t amaclCborLen = 0;
196         size_t svcCborLen = 0;
197         size_t credCborLen = 0;
198         size_t pconfCborLen = 0;
199         size_t resetPfCborLen = 0;
200         size_t crlCborLen = 0;
201
202         // Gets each secure virtual resource from persistent storage
203         // this local scoping intended, for destroying large cbor instances after use
204         {
205             CborParser parser;  // will be initialized in |cbor_parser_init|
206             CborValue cbor;     // will be initialized in |cbor_parser_init|
207             cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
208             CborValue curVal = {0};
209             CborError cborFindResult = CborNoError;
210
211             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
212             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
213             {
214                 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
215                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
216             }
217             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
218             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
219             {
220                 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
221                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
222             }
223             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
224             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
225             {
226                 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
227                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult,  "Failed Finding DOXM Name Value.");
228             }
229             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_AMACL_NAME, &curVal);
230             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
231             {
232                 cborFindResult = cbor_value_dup_byte_string(&curVal, &amaclCbor, &amaclCborLen, NULL);
233                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding AMACL Name Value.");
234             }
235             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_SVC_NAME, &curVal);
236             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
237             {
238                 cborFindResult = cbor_value_dup_byte_string(&curVal, &svcCbor, &svcCborLen, NULL);
239                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SVC Name Value.");
240             }
241             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
242             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
243             {
244                 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
245                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value.");
246             }
247             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PCONF_NAME, &curVal);
248             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
249             {
250                 cborFindResult = cbor_value_dup_byte_string(&curVal, &pconfCbor, &pconfCborLen, NULL);
251                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PCONF Name Value.");
252             }
253             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
254             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
255             {
256                 cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL);
257                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value.");
258             }
259             int64_t cborFindCrlResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRL_NAME, &curVal);
260             if (CborNoError == cborFindCrlResult && cbor_value_is_byte_string(&curVal))
261             {
262                 cborFindCrlResult = cbor_value_dup_byte_string(&curVal, &crlCbor, &crlCborLen, NULL);
263                 if (CborNoError != cborFindCrlResult && CborErrorOutOfMemory != cborFindCrlResult)
264                 {
265                     OIC_LOG(ERROR, TAG, "Failed Finding optional CRL Name Value.");
266                 }
267                 else
268                 {
269                     OIC_LOG(INFO, TAG, "Successfully Finding optional CRL Name Value.");
270                 }
271             }
272         }
273
274         // Updates the added |psPayload| with the existing secure virtual resource(s)
275         // this local scoping intended, for destroying large cbor instances after use
276         {
277             size_t size = aclCborLen + pstatCborLen + doxmCborLen + amaclCborLen
278                         + svcCborLen + credCborLen + pconfCborLen + resetPfCborLen + crlCborLen
279                         + psSize + 255;
280             // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
281
282             outPayload = (uint8_t *) OICCalloc(1, size);
283             VERIFY_NON_NULL(TAG, outPayload, ERROR);
284             CborEncoder encoder;  // will be initialized in |cbor_parser_init|
285             cbor_encoder_init(&encoder, outPayload, size, 0);
286             CborEncoder secRsrc;  // will be initialized in |cbor_encoder_create_map|
287             cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
288             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
289
290             if (psPayload && psSize)
291             {
292                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
293                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
294                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
295                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
296             }
297             if (strcmp(OIC_JSON_ACL_NAME, rsrcName) && aclCborLen)
298             {
299                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
300                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
301                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
302                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
303             }
304             if (strcmp(OIC_JSON_PSTAT_NAME, rsrcName) && pstatCborLen)
305             {
306                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
307                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
308                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
309                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
310             }
311             if (strcmp(OIC_JSON_DOXM_NAME, rsrcName) && doxmCborLen)
312             {
313                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
314                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
315                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
316                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
317             }
318             if (strcmp(OIC_JSON_AMACL_NAME, rsrcName) && amaclCborLen)
319             {
320                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_AMACL_NAME, strlen(OIC_JSON_AMACL_NAME));
321                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Name.");
322                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, amaclCbor, amaclCborLen);
323                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Value.");
324             }
325             if (strcmp(OIC_JSON_SVC_NAME, rsrcName) && svcCborLen)
326             {
327                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_SVC_NAME, strlen(OIC_JSON_SVC_NAME));
328                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Name.");
329                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, svcCbor, svcCborLen);
330                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Value.");
331             }
332             if (strcmp(OIC_JSON_CRED_NAME, rsrcName) && credCborLen)
333             {
334                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
335                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Name.");
336                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
337                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Value.");
338             }
339             if (strcmp(OIC_JSON_PCONF_NAME, rsrcName) && pconfCborLen)
340             {
341                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PCONF_NAME, strlen(OIC_JSON_PCONF_NAME));
342                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Name.");
343                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pconfCbor, pconfCborLen);
344                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Value.");
345             }
346             if (strcmp(OIC_JSON_RESET_PF_NAME, rsrcName) && resetPfCborLen)
347             {
348                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_RESET_PF_NAME, strlen(OIC_JSON_RESET_PF_NAME));
349                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Name.");
350                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, resetPfCbor, resetPfCborLen);
351                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Value.");
352             }
353             if (strcmp(OIC_JSON_CRL_NAME, rsrcName) && crlCborLen)
354             {
355                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRL_NAME, strlen(OIC_JSON_CRL_NAME));
356                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Crl Name.");
357                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, crlCbor, crlCborLen);
358                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Crl Value.");
359             }
360
361             cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
362             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
363             outSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
364         }
365     }
366     else if (psPayload && psSize)
367     {
368         size_t size = psSize + 255;
369         // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
370
371         outPayload = (uint8_t *) OICCalloc(1, size);
372         VERIFY_NON_NULL(TAG, outPayload, ERROR);
373         CborEncoder encoder;  // will be initialized in |cbor_parser_init|
374         cbor_encoder_init(&encoder, outPayload, size, 0);
375         CborEncoder secRsrc;  // will be initialized in |cbor_encoder_create_map|
376         cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
377         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
378
379         cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
380         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
381         cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
382         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
383
384         cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
385         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
386         outSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
387     }
388
389     if (outPayload && outSize)
390     {
391         OIC_LOG_V(DEBUG, TAG, "Writing in the file: %zu", outSize);
392         OCPersistentStorage* ps = SRMGetPersistentStorageHandler();
393         if (ps)
394         {
395             FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb");
396             if (fp)
397             {
398                 size_t numberItems = ps->write(outPayload, 1, outSize, fp);
399                 if (outSize == numberItems)
400                 {
401                     OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", outSize);
402                     ret = OC_STACK_OK;
403                 }
404                 else
405                 {
406                     OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", numberItems);
407                 }
408                 ps->close(fp);
409             }
410             else
411             {
412                 OIC_LOG(ERROR, TAG, "File open failed.");
413             }
414         }
415     }
416
417     OIC_LOG(DEBUG, TAG, "UpdateSecureResourceInPS OUT");
418
419 exit:
420     OICFree(dbData);
421     OICFree(outPayload);
422     OICFree(aclCbor);
423     OICFree(pstatCbor);
424     OICFree(doxmCbor);
425     OICFree(amaclCbor);
426     OICFree(svcCbor);
427     OICFree(credCbor);
428     OICFree(pconfCbor);
429     OICFree(resetPfCbor);
430     OICFree(crlCbor);
431     return ret;
432 }
433
434 /**
435  * Resets the Secure Virtual Resource(s).
436  * This function reads the Reset Profile
437  * and resets the secure virtual resources accordingly.
438  *
439  * @return OCStackResult - result of updating Secure Virtual Resource(s)
440  */
441 OCStackResult ResetSecureResourceInPS(void)
442 {
443     OIC_LOG(DEBUG, TAG, "ResetSecureResourceInPS IN");
444
445     size_t dbSize = 0;
446     size_t outSize = 0;
447     uint8_t *dbData = NULL;
448     uint8_t *outPayload = NULL;
449
450     uint8_t *aclCbor = NULL;
451     uint8_t *credCbor = NULL;
452     uint8_t *pstatCbor = NULL;
453     uint8_t *doxmCbor = NULL;
454     uint8_t *resetPfCbor = NULL;
455
456     int64_t cborEncoderResult = CborNoError;
457     OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
458
459     if(dbData && dbSize)
460     {
461         size_t aclCborLen = 0;
462         size_t credCborLen = 0;
463         size_t pstatCborLen = 0;
464         size_t doxmCborLen = 0;
465         size_t resetPfCborLen = 0;
466
467         // Gets the reset profile from persistent storage
468         {
469             CborParser parser;  // will be initialized in |cbor_parser_init|
470             CborValue cbor;     // will be initialized in |cbor_parser_init|
471             cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
472             CborValue curVal = {0};
473             CborError cborFindResult = CborNoError;
474             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
475             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
476             {
477                 cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL);
478                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value.");
479             }
480         }
481
482         // Gets each secure virtual resource from the reset profile
483         {
484             CborParser parser;  // will be initialized in |cbor_parser_init|
485             CborValue cbor;     // will be initialized in |cbor_parser_init|
486             cbor_parser_init(resetPfCbor, resetPfCborLen, 0, &parser, &cbor);
487             CborValue curVal = {0};
488             CborError cborFindResult = CborNoError;
489             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
490             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
491             {
492                 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
493                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
494             }
495             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
496             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
497             {
498                 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
499                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
500             }
501             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
502             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
503             {
504                 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
505                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
506             }
507             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
508             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
509             {
510                 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
511                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value.");
512             }
513         }
514
515         {
516             size_t size = aclCborLen + credCborLen + pstatCborLen + doxmCborLen + resetPfCborLen + 255;
517             // This added '255' is arbitrary value added to cover the name of the resource, map addition, and ending
518
519             outPayload = (uint8_t *) OICCalloc(1, size);
520             VERIFY_NON_NULL(TAG, outPayload, ERROR);
521             CborEncoder encoder;
522             cbor_encoder_init(&encoder, outPayload, size, 0);
523             CborEncoder secRsrc;
524             cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
525
526             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
527             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
528             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
529             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
530
531             if (credCborLen)
532             {
533                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
534                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Name.");
535                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
536                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Value.");
537             }
538
539             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
540             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
541             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
542             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
543
544             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
545             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Name.");
546             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
547             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Value.");
548
549             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_RESET_PF_NAME, strlen(OIC_JSON_RESET_PF_NAME));
550             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Name.");
551             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, resetPfCbor, resetPfCborLen);
552             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Value.");
553
554             cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
555             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
556             outSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
557         }
558
559         if (outPayload && outSize)
560         {
561             OIC_LOG_V(DEBUG, TAG, "Writing in the file: %zu", outSize);
562             OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
563             if (ps)
564             {
565                 FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb");
566                 if (fp)
567                 {
568                     size_t numberItems = ps->write(outPayload, 1, outSize, fp);
569                     if (outSize == numberItems)
570                     {
571                         OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", outSize);
572                         ret= OC_STACK_OK;
573                     }
574                     else
575                     {
576                         OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", numberItems);
577                     }
578                     ps->close(fp);
579                 }
580                 else
581                 {
582                     OIC_LOG(ERROR, TAG, "File open failed.");
583                 }
584
585             }
586         }
587     }
588
589     SRMDeInitSecureResources();
590     InitSecureResources();
591     OIC_LOG(DEBUG, TAG, "ResetSecureResourceINPS OUT");
592
593 exit:
594     OICFree(dbData);
595     OICFree(outPayload);
596     OICFree(aclCbor);
597     OICFree(credCbor);
598     OICFree(pstatCbor);
599     OICFree(doxmCbor);
600     OICFree(resetPfCbor);
601     return ret;
602 }
603
604 /**
605  * Creates Reset Profile from the initial secure virtual resources.
606  * This function copies the secure resources
607  * and creates the Reset Profile in the Persistent Storage.
608  * Device ID in doxm and pstat remains as same after reset.
609  *
610  * @return OCStackResult - result of updating Secure Virtual Resource(s)
611  */
612 OCStackResult CreateResetProfile(void)
613 {
614     OIC_LOG(DEBUG, TAG, "CreateResetProfile IN");
615
616     size_t dbSize = 0;
617     uint8_t *dbData = NULL;
618
619     uint8_t *aclCbor = NULL;
620     uint8_t *credCbor = NULL;
621     uint8_t *pstatCbor = NULL;
622     uint8_t *doxmCbor = NULL;
623     uint8_t *resetPfCbor = NULL;
624
625     OCStackResult ret = OC_STACK_ERROR;
626     int64_t cborEncoderResult = CborNoError;
627     ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
628     if (dbData && dbSize)
629     {
630         size_t aclCborLen = 0;
631         size_t credCborLen = 0;
632         size_t pstatCborLen = 0;
633         size_t doxmCborLen = 0;
634         size_t resetPfCborLen = 0;
635
636         {
637             CborParser parser;
638             CborValue cbor;
639             cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
640             CborValue curVal = {0};
641             CborError cborFindResult = CborNoError;
642             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
643             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
644             {
645                 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
646                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
647             }
648             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
649             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
650             {
651                 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
652                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value.");
653             }
654             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
655             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
656             {
657                 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
658                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
659             }
660             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
661             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
662             {
663                 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
664                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult,  "Failed Finding DOXM Name Value.");
665             }
666         }
667
668         {
669             size_t size = aclCborLen + credCborLen + pstatCborLen + doxmCborLen + 255;
670             resetPfCbor = (uint8_t *) OICCalloc(1, size);
671             VERIFY_NON_NULL(TAG, resetPfCbor, ERROR);
672             CborEncoder encoder;  // will be initialized in |cbor_parser_init|
673             cbor_encoder_init(&encoder, resetPfCbor, size, 0);
674             CborEncoder secRsrc;  // will be initialized in |cbor_encoder_create_map|
675             cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
676
677             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
678             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
679             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
680             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
681
682             if (credCborLen)
683             {
684                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
685                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Name.");
686                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
687                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Value.");
688             }
689
690             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
691             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
692             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
693             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
694
695             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
696             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
697             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
698             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
699
700             cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
701             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
702             resetPfCborLen = cbor_encoder_get_buffer_size(&encoder, resetPfCbor);
703         }
704
705         UpdateSecureResourceInPS(OIC_JSON_RESET_PF_NAME, resetPfCbor, resetPfCborLen);
706
707     }
708     OIC_LOG(DEBUG, TAG, "CreateResetProfile OUT");
709
710 exit:
711     OICFree(dbData);
712     OICFree(aclCbor);
713     OICFree(credCbor);
714     OICFree(pstatCbor);
715     OICFree(doxmCbor);
716     OICFree(resetPfCbor);
717     return ret;
718 }