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