Merge branch 'master' into notification-service
[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
187     int64_t cborEncoderResult = CborNoError;
188     OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
189     if (dbData && dbSize)
190     {
191         size_t aclCborLen = 0;
192         size_t pstatCborLen = 0;
193         size_t doxmCborLen = 0;
194         size_t amaclCborLen = 0;
195         size_t svcCborLen = 0;
196         size_t credCborLen = 0;
197         size_t pconfCborLen = 0;
198         size_t resetPfCborLen = 0;
199
200         // Gets each secure virtual resource from persistent storage
201         // this local scoping intended, for destroying large cbor instances after use
202         {
203             CborParser parser;  // will be initialized in |cbor_parser_init|
204             CborValue cbor;     // will be initialized in |cbor_parser_init|
205             cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
206             CborValue curVal = {0};
207             CborError cborFindResult = CborNoError;
208
209             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
210             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
211             {
212                 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
213                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
214             }
215             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
216             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
217             {
218                 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
219                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
220             }
221             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
222             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
223             {
224                 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
225                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult,  "Failed Finding DOXM Name Value.");
226             }
227             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_AMACL_NAME, &curVal);
228             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
229             {
230                 cborFindResult = cbor_value_dup_byte_string(&curVal, &amaclCbor, &amaclCborLen, NULL);
231                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding AMACL Name Value.");
232             }
233             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_SVC_NAME, &curVal);
234             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
235             {
236                 cborFindResult = cbor_value_dup_byte_string(&curVal, &svcCbor, &svcCborLen, NULL);
237                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SVC Name Value.");
238             }
239             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
240             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
241             {
242                 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
243                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value.");
244             }
245             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PCONF_NAME, &curVal);
246             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
247             {
248                 cborFindResult = cbor_value_dup_byte_string(&curVal, &pconfCbor, &pconfCborLen, NULL);
249                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PCONF Name Value.");
250             }
251             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
252             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
253             {
254                 cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL);
255                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value.");
256             }
257         }
258
259         // Updates the added |psPayload| with the existing secure virtual resource(s)
260         // this local scoping intended, for destroying large cbor instances after use
261         {
262             size_t size = aclCborLen + pstatCborLen + doxmCborLen + amaclCborLen
263                         + svcCborLen + credCborLen + pconfCborLen + resetPfCborLen
264                         + psSize + 255;
265             // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
266
267             outPayload = (uint8_t *) OICCalloc(1, size);
268             VERIFY_NON_NULL(TAG, outPayload, ERROR);
269             CborEncoder encoder;  // will be initialized in |cbor_parser_init|
270             cbor_encoder_init(&encoder, outPayload, size, 0);
271             CborEncoder secRsrc;  // will be initialized in |cbor_encoder_create_map|
272             cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
273             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
274
275             if (psPayload && psSize)
276             {
277                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
278                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
279                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
280                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
281             }
282             if (strcmp(OIC_JSON_ACL_NAME, rsrcName) && aclCborLen)
283             {
284                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
285                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
286                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
287                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
288             }
289             if (strcmp(OIC_JSON_PSTAT_NAME, rsrcName) && pstatCborLen)
290             {
291                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
292                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
293                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
294                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
295             }
296             if (strcmp(OIC_JSON_DOXM_NAME, rsrcName) && doxmCborLen)
297             {
298                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
299                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
300                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
301                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
302             }
303             if (strcmp(OIC_JSON_AMACL_NAME, rsrcName) && amaclCborLen)
304             {
305                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_AMACL_NAME, strlen(OIC_JSON_AMACL_NAME));
306                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Name.");
307                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, amaclCbor, amaclCborLen);
308                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Value.");
309             }
310             if (strcmp(OIC_JSON_SVC_NAME, rsrcName) && svcCborLen)
311             {
312                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_SVC_NAME, strlen(OIC_JSON_SVC_NAME));
313                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Name.");
314                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, svcCbor, svcCborLen);
315                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Value.");
316             }
317             if (strcmp(OIC_JSON_CRED_NAME, rsrcName) && credCborLen)
318             {
319                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
320                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Name.");
321                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
322                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Value.");
323             }
324             if (strcmp(OIC_JSON_PCONF_NAME, rsrcName) && pconfCborLen)
325             {
326                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PCONF_NAME, strlen(OIC_JSON_PCONF_NAME));
327                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Name.");
328                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pconfCbor, pconfCborLen);
329                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Value.");
330             }
331             if (strcmp(OIC_JSON_RESET_PF_NAME, rsrcName) && resetPfCborLen)
332             {
333                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_RESET_PF_NAME, strlen(OIC_JSON_RESET_PF_NAME));
334                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Name.");
335                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, resetPfCbor, resetPfCborLen);
336                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Value.");
337             }
338
339             cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
340             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
341             outSize = encoder.ptr - outPayload;
342         }
343     }
344     else if (psPayload && psSize)
345     {
346         size_t size = psSize + 255;
347         // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
348
349         outPayload = (uint8_t *) OICCalloc(1, size);
350         VERIFY_NON_NULL(TAG, outPayload, ERROR);
351         CborEncoder encoder;  // will be initialized in |cbor_parser_init|
352         cbor_encoder_init(&encoder, outPayload, size, 0);
353         CborEncoder secRsrc;  // will be initialized in |cbor_encoder_create_map|
354         cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
355         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
356
357         cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
358         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
359         cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
360         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
361
362         cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
363         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
364         outSize = encoder.ptr - outPayload;
365     }
366
367     if (outPayload && outSize)
368     {
369         OIC_LOG_V(DEBUG, TAG, "Writing in the file: %zu", outSize);
370         OCPersistentStorage* ps = SRMGetPersistentStorageHandler();
371         if (ps)
372         {
373             FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb");
374             if (fp)
375             {
376                 size_t numberItems = ps->write(outPayload, 1, outSize, fp);
377                 if (outSize == numberItems)
378                 {
379                     OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", outSize);
380                     ret = OC_STACK_OK;
381                 }
382                 else
383                 {
384                     OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", numberItems);
385                 }
386                 ps->close(fp);
387             }
388             else
389             {
390                 OIC_LOG(ERROR, TAG, "File open failed.");
391             }
392         }
393     }
394
395     OIC_LOG(DEBUG, TAG, "UpdateSecureResourceInPS OUT");
396
397 exit:
398     OICFree(dbData);
399     OICFree(outPayload);
400     OICFree(aclCbor);
401     OICFree(pstatCbor);
402     OICFree(doxmCbor);
403     OICFree(amaclCbor);
404     OICFree(svcCbor);
405     OICFree(credCbor);
406     OICFree(pconfCbor);
407     OICFree(resetPfCbor);
408     return ret;
409 }
410
411 /**
412  * Resets the Secure Virtual Resource(s).
413  * This function reads the Reset Profile
414  * and resets the secure virtual resources accordingly.
415  *
416  * @return OCStackResult - result of updating Secure Virtual Resource(s)
417  */
418 OCStackResult ResetSecureResourceInPS(void)
419 {
420     OIC_LOG(DEBUG, TAG, "ResetSecureResourceInPS IN");
421
422     size_t dbSize = 0;
423     size_t outSize = 0;
424     uint8_t *dbData = NULL;
425     uint8_t *outPayload = NULL;
426
427     uint8_t *aclCbor = NULL;
428     uint8_t *pstatCbor = NULL;
429     uint8_t *doxmCbor = NULL;
430     uint8_t *resetPfCbor = NULL;
431
432     int64_t cborEncoderResult = CborNoError;
433     OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
434
435     if(dbData && dbSize)
436     {
437         size_t aclCborLen = 0;
438         size_t pstatCborLen = 0;
439         size_t doxmCborLen = 0;
440         size_t resetPfCborLen = 0;
441
442         // Gets the reset profile from persistent storage
443         {
444             CborParser parser;  // will be initialized in |cbor_parser_init|
445             CborValue cbor;     // will be initialized in |cbor_parser_init|
446             cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
447             CborValue curVal = {0};
448             CborError cborFindResult = CborNoError;
449             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
450             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
451             {
452                 cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL);
453                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value.");
454             }
455         }
456
457         // Gets each secure virtual resource from the reset profile
458         {
459             CborParser parser;  // will be initialized in |cbor_parser_init|
460             CborValue cbor;     // will be initialized in |cbor_parser_init|
461             cbor_parser_init(resetPfCbor, resetPfCborLen, 0, &parser, &cbor);
462             CborValue curVal = {0};
463             CborError cborFindResult = CborNoError;
464             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
465             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
466             {
467                 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
468                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
469             }
470             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
471             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
472             {
473                 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
474                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
475             }
476             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
477             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
478             {
479                 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
480                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value.");
481             }
482         }
483
484         {
485             size_t size = aclCborLen + pstatCborLen + doxmCborLen + resetPfCborLen + 255;
486             // This added '255' is arbitrary value added to cover the name of the resource, map addition, and ending
487
488             outPayload = (uint8_t *) OICCalloc(1, size);
489             VERIFY_NON_NULL(TAG, outPayload, ERROR);
490             CborEncoder encoder;
491             cbor_encoder_init(&encoder, outPayload, size, 0);
492             CborEncoder secRsrc;
493             cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
494
495             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
496             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
497             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
498             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
499
500             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
501             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
502             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
503             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
504
505             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
506             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Name.");
507             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
508             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Value.");
509
510             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_RESET_PF_NAME, strlen(OIC_JSON_RESET_PF_NAME));
511             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Name.");
512             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, resetPfCbor, resetPfCborLen);
513             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Value.");
514
515             cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
516             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
517             outSize = encoder.ptr - outPayload;
518         }
519
520         if (outPayload && outSize)
521         {
522             OIC_LOG_V(DEBUG, TAG, "Writing in the file: %zu", outSize);
523             OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
524             if (ps)
525             {
526                 FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb");
527                 if (fp)
528                 {
529                     size_t numberItems = ps->write(outPayload, 1, outSize, fp);
530                     if (outSize == numberItems)
531                     {
532                         OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", outSize);
533                         ret= OC_STACK_OK;
534                     }
535                     else
536                     {
537                         OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", numberItems);
538                     }
539                     ps->close(fp);
540                 }
541                 else
542                 {
543                     OIC_LOG(ERROR, TAG, "File open failed.");
544                 }
545
546             }
547         }
548     }
549
550     SRMDeInitSecureResources();
551     InitSecureResources();
552     OIC_LOG(DEBUG, TAG, "ResetSecureResourceINPS OUT");
553
554 exit:
555     OICFree(dbData);
556     OICFree(outPayload);
557     OICFree(aclCbor);
558     OICFree(pstatCbor);
559     OICFree(doxmCbor);
560     OICFree(resetPfCbor);
561     return ret;
562 }
563
564 /**
565  * Creates Reset Profile from the initial secure virtual resources.
566  * This function copies the secure resources
567  * and creates the Reset Profile in the Persistent Storage.
568  * Device ID in doxm and pstat are left empty as it will be renewed after reset.
569  *
570  * @return OCStackResult - result of updating Secure Virtual Resource(s)
571  */
572 OCStackResult CreateResetProfile(void)
573 {
574     OIC_LOG(DEBUG, TAG, "CreateResetProfile IN");
575
576     size_t dbSize = 0;
577     uint8_t *dbData = NULL;
578
579     uint8_t *aclCbor = NULL;
580     uint8_t *pstatCbor = NULL;
581     uint8_t *doxmCbor = NULL;
582     uint8_t *resetPfCbor = NULL;
583
584     OCStackResult ret = OC_STACK_ERROR;
585     int64_t cborEncoderResult = CborNoError;
586     ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
587     if (dbData && dbSize)
588     {
589         size_t aclCborLen = 0;
590         size_t pstatCborLen = 0;
591         size_t doxmCborLen = 0;
592         size_t resetPfCborLen = 0;
593
594         {
595             CborParser parser;
596             CborValue cbor;
597             cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
598             CborValue curVal = {0};
599             CborError cborFindResult = CborNoError;
600             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
601             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
602             {
603                 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
604                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
605             }
606             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
607             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
608             {
609                 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
610                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
611             }
612             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
613             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
614             {
615                 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
616                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult,  "Failed Finding DOXM Name Value.");
617             }
618         }
619
620         // Set the Device ID in doxm and pstat to empty
621         if (pstatCbor)
622         {
623             OicSecPstat_t *pstat = NULL;
624             ret = CBORPayloadToPstat(pstatCbor, pstatCborLen, &pstat);
625             OICFree(pstatCbor);
626             pstatCbor = NULL;
627             pstatCborLen = 0;
628
629             OicUuid_t emptyUuid = {.id = {0} };
630             memcpy(&pstat->deviceID, &emptyUuid, sizeof(OicUuid_t));
631             memcpy(&pstat->rownerID, &emptyUuid, sizeof(OicUuid_t));
632
633             ret = PstatToCBORPayload(pstat, &pstatCbor, &pstatCborLen, false);
634             OICFree(pstat);
635         }
636         if (doxmCbor)
637         {
638             OicSecDoxm_t *doxm = NULL;
639             ret = CBORPayloadToDoxm(doxmCbor, doxmCborLen, &doxm);
640             OICFree(doxmCbor);
641             doxmCbor = NULL;
642             doxmCborLen = 0;
643
644             OicUuid_t emptyUuid = {.id = {0} };
645             memcpy(&doxm->deviceID, &emptyUuid, sizeof(OicUuid_t));
646             memcpy(&doxm->rownerID, &emptyUuid, sizeof(OicUuid_t));
647
648             ret = DoxmToCBORPayload(doxm, &doxmCbor, &doxmCborLen, false);
649             OICFree(doxm);
650         }
651
652         {
653             size_t size = aclCborLen + pstatCborLen + doxmCborLen + 255;
654             resetPfCbor = (uint8_t *) OICCalloc(1, size);
655             VERIFY_NON_NULL(TAG, resetPfCbor, ERROR);
656             CborEncoder encoder;  // will be initialized in |cbor_parser_init|
657             cbor_encoder_init(&encoder, resetPfCbor, size, 0);
658             CborEncoder secRsrc;  // will be initialized in |cbor_encoder_create_map|
659             cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
660
661             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
662             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
663             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
664             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
665
666             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
667             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
668             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
669             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
670
671             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
672             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
673             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
674             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
675
676             cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
677             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
678             resetPfCborLen = encoder.ptr - resetPfCbor;
679         }
680
681         UpdateSecureResourceInPS(OIC_JSON_RESET_PF_NAME, resetPfCbor, resetPfCborLen);
682
683     }
684     OIC_LOG(DEBUG, TAG, "CreateResetProfile OUT");
685
686 exit:
687     OICFree(dbData);
688     OICFree(aclCbor);
689     OICFree(pstatCbor);
690     OICFree(doxmCbor);
691     OICFree(resetPfCbor);
692     return ret;
693 }