[IOT-1405, IOT-1418] Bug fixes
[platform/upstream/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  "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 = encoder.ptr - 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 = encoder.ptr - 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 *pstatCbor = NULL;
452     uint8_t *doxmCbor = NULL;
453     uint8_t *resetPfCbor = NULL;
454
455     int64_t cborEncoderResult = CborNoError;
456     OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
457
458     if(dbData && dbSize)
459     {
460         size_t aclCborLen = 0;
461         size_t pstatCborLen = 0;
462         size_t doxmCborLen = 0;
463         size_t resetPfCborLen = 0;
464
465         // Gets the reset profile from persistent storage
466         {
467             CborParser parser;  // will be initialized in |cbor_parser_init|
468             CborValue cbor;     // will be initialized in |cbor_parser_init|
469             cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
470             CborValue curVal = {0};
471             CborError cborFindResult = CborNoError;
472             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
473             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
474             {
475                 cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL);
476                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value.");
477             }
478         }
479
480         // Gets each secure virtual resource from the reset profile
481         {
482             CborParser parser;  // will be initialized in |cbor_parser_init|
483             CborValue cbor;     // will be initialized in |cbor_parser_init|
484             cbor_parser_init(resetPfCbor, resetPfCborLen, 0, &parser, &cbor);
485             CborValue curVal = {0};
486             CborError cborFindResult = CborNoError;
487             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
488             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
489             {
490                 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
491                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
492             }
493             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
494             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
495             {
496                 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
497                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
498             }
499             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
500             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
501             {
502                 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
503                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value.");
504             }
505         }
506
507         {
508             size_t size = aclCborLen + pstatCborLen + doxmCborLen + resetPfCborLen + 255;
509             // This added '255' is arbitrary value added to cover the name of the resource, map addition, and ending
510
511             outPayload = (uint8_t *) OICCalloc(1, size);
512             VERIFY_NON_NULL(TAG, outPayload, ERROR);
513             CborEncoder encoder;
514             cbor_encoder_init(&encoder, outPayload, size, 0);
515             CborEncoder secRsrc;
516             cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
517
518             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
519             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
520             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
521             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
522
523             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
524             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
525             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
526             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
527
528             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
529             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Name.");
530             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
531             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Value.");
532
533             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_RESET_PF_NAME, strlen(OIC_JSON_RESET_PF_NAME));
534             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Name.");
535             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, resetPfCbor, resetPfCborLen);
536             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Value.");
537
538             cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
539             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
540             outSize = encoder.ptr - outPayload;
541         }
542
543         if (outPayload && outSize)
544         {
545             OIC_LOG_V(DEBUG, TAG, "Writing in the file: %zu", outSize);
546             OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
547             if (ps)
548             {
549                 FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb");
550                 if (fp)
551                 {
552                     size_t numberItems = ps->write(outPayload, 1, outSize, fp);
553                     if (outSize == numberItems)
554                     {
555                         OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", outSize);
556                         ret= OC_STACK_OK;
557                     }
558                     else
559                     {
560                         OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", numberItems);
561                     }
562                     ps->close(fp);
563                 }
564                 else
565                 {
566                     OIC_LOG(ERROR, TAG, "File open failed.");
567                 }
568
569             }
570         }
571     }
572
573     SRMDeInitSecureResources();
574     InitSecureResources();
575     OIC_LOG(DEBUG, TAG, "ResetSecureResourceINPS OUT");
576
577 exit:
578     OICFree(dbData);
579     OICFree(outPayload);
580     OICFree(aclCbor);
581     OICFree(pstatCbor);
582     OICFree(doxmCbor);
583     OICFree(resetPfCbor);
584     return ret;
585 }
586
587 /**
588  * Creates Reset Profile from the initial secure virtual resources.
589  * This function copies the secure resources
590  * and creates the Reset Profile in the Persistent Storage.
591  * Device ID in doxm and pstat are left empty as it will be renewed after reset.
592  *
593  * @return OCStackResult - result of updating Secure Virtual Resource(s)
594  */
595 OCStackResult CreateResetProfile(void)
596 {
597     OIC_LOG(DEBUG, TAG, "CreateResetProfile IN");
598
599     size_t dbSize = 0;
600     uint8_t *dbData = NULL;
601
602     uint8_t *aclCbor = NULL;
603     uint8_t *pstatCbor = NULL;
604     uint8_t *doxmCbor = NULL;
605     uint8_t *resetPfCbor = NULL;
606
607     OCStackResult ret = OC_STACK_ERROR;
608     int64_t cborEncoderResult = CborNoError;
609     ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
610     if (dbData && dbSize)
611     {
612         size_t aclCborLen = 0;
613         size_t pstatCborLen = 0;
614         size_t doxmCborLen = 0;
615         size_t resetPfCborLen = 0;
616
617         {
618             CborParser parser;
619             CborValue cbor;
620             cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
621             CborValue curVal = {0};
622             CborError cborFindResult = CborNoError;
623             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
624             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
625             {
626                 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
627                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
628             }
629             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
630             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
631             {
632                 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
633                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
634             }
635             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
636             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
637             {
638                 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
639                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult,  "Failed Finding DOXM Name Value.");
640             }
641         }
642
643         // Set the Device ID in doxm and pstat to empty
644         if (pstatCbor)
645         {
646             OicSecPstat_t *pstat = NULL;
647             ret = CBORPayloadToPstat(pstatCbor, pstatCborLen, &pstat);
648             OICFree(pstatCbor);
649             pstatCbor = NULL;
650             pstatCborLen = 0;
651
652             OicUuid_t emptyUuid = {.id = {0} };
653             memcpy(&pstat->deviceID, &emptyUuid, sizeof(OicUuid_t));
654             memcpy(&pstat->rownerID, &emptyUuid, sizeof(OicUuid_t));
655
656             ret = PstatToCBORPayload(pstat, &pstatCbor, &pstatCborLen, false);
657             DeletePstatBinData(pstat);
658         }
659         if (doxmCbor)
660         {
661             OicSecDoxm_t *doxm = NULL;
662             ret = CBORPayloadToDoxm(doxmCbor, doxmCborLen, &doxm);
663             OICFree(doxmCbor);
664             doxmCbor = NULL;
665             doxmCborLen = 0;
666
667             OicUuid_t emptyUuid = {.id = {0} };
668             memcpy(&doxm->deviceID, &emptyUuid, sizeof(OicUuid_t));
669             memcpy(&doxm->rownerID, &emptyUuid, sizeof(OicUuid_t));
670
671             ret = DoxmToCBORPayload(doxm, &doxmCbor, &doxmCborLen, false);
672             DeleteDoxmBinData(doxm);
673         }
674
675         {
676             size_t size = aclCborLen + pstatCborLen + doxmCborLen + 255;
677             resetPfCbor = (uint8_t *) OICCalloc(1, size);
678             VERIFY_NON_NULL(TAG, resetPfCbor, ERROR);
679             CborEncoder encoder;  // will be initialized in |cbor_parser_init|
680             cbor_encoder_init(&encoder, resetPfCbor, size, 0);
681             CborEncoder secRsrc;  // will be initialized in |cbor_encoder_create_map|
682             cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
683
684             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
685             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
686             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
687             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
688
689             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
690             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
691             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
692             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
693
694             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
695             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
696             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
697             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
698
699             cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
700             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
701             resetPfCborLen = encoder.ptr - resetPfCbor;
702         }
703
704         UpdateSecureResourceInPS(OIC_JSON_RESET_PF_NAME, resetPfCbor, resetPfCborLen);
705
706     }
707     OIC_LOG(DEBUG, TAG, "CreateResetProfile OUT");
708
709 exit:
710     OICFree(dbData);
711     OICFree(aclCbor);
712     OICFree(pstatCbor);
713     OICFree(doxmCbor);
714     OICFree(resetPfCbor);
715     return ret;
716 }