replace : iotivity -> iotivity-sec
[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 #include <unistd.h>
28
29 #include "cainterface.h"
30 #include "logger.h"
31 #include "ocpayload.h"
32 #include "ocpayloadcbor.h"
33 #include "ocstack.h"
34 #include "oic_malloc.h"
35 #include "payload_logging.h"
36 #include "resourcemanager.h"
37 #include "secureresourcemanager.h"
38 #include "srmresourcestrings.h"
39 #include "srmutility.h"
40 #include "pstatresource.h"
41 #include "psiutils.h"
42 #include "psinterface.h"
43 #include "doxmresource.h"
44 #include "octhread.h"
45
46 #define TAG  "OIC_SRM_PSI"
47
48 // SVR database buffer block size
49 #ifdef _WIN32
50 #define DB_FILE_SIZE_BLOCK 1023
51 #else
52 const size_t DB_FILE_SIZE_BLOCK = 1023;
53 #endif
54 //the Secure Virtual Database file size
55 static size_t g_svrDbFileSize = 0;
56 //mutex for the Secure Virtual Database
57 static oc_mutex g_mutexDb = NULL;
58
59 // Persistent Storage status
60 static PSStatus_t g_psStatus = PS_NO_EXTERNAL_DB_SET;
61
62 /**
63  * Update the Persistent Storage Database size.
64  */
65 void UpdateSizePSI(size_t size)
66 {
67     oc_mutex_lock(g_mutexDb);
68     g_svrDbFileSize = size;
69     oc_mutex_unlock(g_mutexDb);
70 }
71 /**
72  * Init the Persistent Storage Database.
73  */
74 OCStackResult InitPersistentStorageInterface(void)
75 {
76     if (!g_mutexDb)
77     {
78         g_mutexDb = oc_mutex_new();
79         if(!g_mutexDb)
80         {
81             return OC_STACK_ERROR;
82         }
83     }
84
85     UpdateSizePSI(0);
86
87     return OC_STACK_OK;
88 }
89
90 /**
91  * DeInit the Persistent Storage Database.
92  */
93 void DeinitPersistentStorageInterface(void)
94 {
95     g_svrDbFileSize = 0;
96     oc_mutex_free(g_mutexDb);
97     g_mutexDb = NULL;
98 }
99
100 /**
101  * Gets the database size
102  *
103  * @param ps            is a pointer to OCPersistentStorage for the Virtual Resource(s).
104  *
105  * @return size_t - total size of the database
106  */
107 static size_t GetPSIDatabaseSizeWithoutCaching(const OCPersistentStorage *ps)
108 {
109     if (!ps)
110     {
111         return 0;
112     }
113     size_t size = 0;
114     char buffer[DB_FILE_SIZE_BLOCK];  // can not initialize with declaration
115                                       // but maybe not needed to initialize
116     FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
117     if (fp)
118     {
119         size_t bytesRead = 0;
120         do
121         {
122             bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
123             size += bytesRead;
124         } while (bytesRead);
125         ps->close(fp);
126     }
127     return size;
128 }
129
130
131 /**
132  * Gets the the Persistent Storage Database size
133  *
134  * @param ps - pointer of OCPersistentStorage for the Secure Virtual Resource(s)
135  *
136  * @return size_t - total size of the SVR database
137  */
138 static size_t GetPSIDatabaseSize(const OCPersistentStorage *ps)
139 {
140     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
141
142     if (!ps)
143     {
144         return 0;
145     }
146
147     if (!g_svrDbFileSize)
148     {
149         size_t size = 0;
150         char buffer[DB_FILE_SIZE_BLOCK];  // can not initialize with declaration
151                                           // but maybe not needed to initialize
152         FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
153         if (fp)
154         {
155             size_t bytesRead = 0;
156             do
157             {
158                 bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
159                 size += bytesRead;
160             } while (bytesRead);
161             ps->close(fp);
162         }
163         else
164         {
165             OIC_LOG_V(ERROR, TAG, "%s: File open failed.", __func__);
166         }
167
168         UpdateSizePSI(size);
169     }
170     else
171     {
172         OIC_LOG_V(INFO, TAG, "%s get size from cache", __func__);
173     }
174
175     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
176
177     return g_svrDbFileSize;
178 }
179
180 #ifdef __SECURE_PSI__
181 static OCStackResult getPlaintextFromDB(const OCPersistentStorage *ps, uint8_t **pt,
182         size_t *pt_len)
183 {
184     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
185     OCStackResult ret = OC_STACK_ERROR;
186
187     uint8_t *plaintext = NULL;
188
189     FILE *fp = NULL;
190     fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
191     if (NULL == fp)
192     {
193         OIC_LOG(ERROR, TAG, "ps->open() Failed");
194         return OC_STACK_ERROR;
195     }
196
197     // Get fileSize of plaintext
198     char buffer[DB_FILE_SIZE_BLOCK];
199     size_t bytesRead = 0;
200     size_t fileSize = 0;
201     do
202     {
203         bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
204         fileSize += bytesRead;
205     } while (bytesRead);
206
207     // Get plaintext
208     ret = OC_STACK_NO_MEMORY;
209     plaintext = (uint8_t*)OICCalloc(1, fileSize);
210     VERIFY_NON_NULL(TAG, plaintext, ERROR);
211
212     ps->close(fp);
213     fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
214     if (NULL == fp)
215     {
216         OIC_LOG(ERROR, TAG, "ps->open() Failed");
217         return OC_STACK_ERROR;
218     }
219
220     if (fileSize != ps->read(plaintext, 1, fileSize, fp))
221     {
222         OIC_LOG_V(ERROR, TAG, "ps->read() Failed");
223         ret = OC_STACK_ERROR;
224         goto exit;
225     }
226
227     *pt = plaintext;
228     *pt_len = fileSize;
229     ps->close(fp);
230
231     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
232
233     return OC_STACK_OK;
234 exit:
235     OICFree(plaintext);
236     if (fp)
237     {
238         ps->close(fp);
239     }
240     return ret;
241 }
242
243 static OCStackResult OTEncrypt(const OCPersistentStorage *psForPlain,
244         const OCPersistentStorage *psForEncrypted)
245 {
246     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
247
248     uint8_t *plaintext = NULL;
249     size_t pt_len = 0;
250     OCStackResult ret = getPlaintextFromDB(psForPlain, &plaintext, &pt_len);
251     if (OC_STACK_OK != ret)
252     {
253         OIC_LOG(ERROR, TAG, "getPlaintextFromDB() Failed");
254         return ret;
255     }
256
257     // Encrypt plaintext
258     uint8_t *ciphertext = NULL;
259     size_t ct_len = 0;
260     if (0 != psForEncrypted->encrypt(plaintext, pt_len, &ciphertext, &ct_len))
261     {
262         OIC_LOG(ERROR, TAG, "psForEncrypted->encrypt() Failed");
263         OICFree(plaintext);
264         return OC_STACK_ERROR;
265     }
266     OICFree(plaintext);
267
268     // Write Ciphertext
269     FILE *fp2 = psForEncrypted->open(SVR_DB_DAT_FILE_NAME, "wb");
270     if (NULL == fp2)
271     {
272         OIC_LOG(ERROR, TAG, "psForEncrypted->open() Failed");
273         OICFree(ciphertext);
274         return OC_STACK_ERROR;
275     }
276
277     if (ct_len != psForEncrypted->write(ciphertext, 1, ct_len, fp2))
278     {
279         OIC_LOG(ERROR, TAG, "psForEncrypted->write() Failed");
280         OICFree(ciphertext);
281         return OC_STACK_ERROR;
282     }
283     psForEncrypted->close(fp2);
284
285     // Remove plain DB
286     if (psForPlain->unlink)
287     {
288         psForPlain->unlink(SVR_DB_DAT_FILE_NAME);
289     }
290
291     OICFree(ciphertext);
292     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
293
294     return OC_STACK_OK;
295 }
296
297 OCStackResult setSecurePSI(const unsigned char *key, const OCPersistentStorage *psPlain,
298         const OCPersistentStorage *psEnc, const OCPersistentStorage *psRescue)
299 {
300     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
301
302     if (!key || !psEnc)
303     {
304         OIC_LOG_V(ERROR, TAG, "%s: %s is NULL", __func__, !key ? "key" : "psEnc");
305         return OC_STACK_INVALID_PARAM;
306     }
307     if (!(psEnc->encrypt && psEnc->decrypt))
308     {
309         OIC_LOG(ERROR, TAG, "psEnc->encrypt && psEnc->decrypt should be set");
310         return OC_STACK_INVALID_PARAM;
311     }
312     if (psPlain && !(psPlain->open && psPlain->read && psPlain->close
313                 && psPlain->unlink))
314     {
315         OIC_LOG(ERROR, TAG, "open/read/close/unlink funcion for plain should be set");
316         return OC_STACK_INVALID_PARAM;
317     }
318     if (psRescue && !(psRescue->open && psRescue->read && psRescue->close))
319     {
320         OIC_LOG(ERROR, TAG, "open/read/close funcion for rescue should be set");
321         return OC_STACK_INVALID_PARAM;
322     }
323
324     OCStackResult ret;
325     ret = psiSetKey(key);
326     if (OC_STACK_OK != ret)
327     {
328         OIC_LOG(ERROR, TAG, "psiSetKey() Failed");
329         return ret;
330     }
331     OIC_LOG(DEBUG, TAG, "key is set");
332
333     // if there is new plain db
334     FILE *fp = NULL;
335     if (psPlain && (fp = psPlain->open(SVR_DB_DAT_FILE_NAME, "rb")))
336     {
337         psPlain->close(fp);
338         fp = NULL;
339
340         ret = OTEncrypt(psPlain, psEnc);
341         if (OC_STACK_OK != ret)
342         {
343             OIC_LOG(ERROR, TAG, "OTEncrypt() Failed");
344             return ret;
345         }
346     }
347
348     // check ps & rescue
349     if (psRescue)
350     {
351         ret = CheckPersistentStorage((OCPersistentStorage*)psEnc);
352         if (OC_STACK_OK != ret)
353         {
354             fp = psRescue->open(SVR_DB_DAT_FILE_NAME, "rb");
355             if (NULL == fp)
356             {
357                 OIC_LOG(ERROR, TAG, "psRescue->open() Failed");
358                 return OC_STACK_ERROR;
359             }
360             psRescue->close(fp);
361             fp = NULL;
362
363             ret = OTEncrypt(psRescue, psEnc);
364             if (OC_STACK_OK != ret)
365             {
366                 OIC_LOG_V(ERROR, TAG, "ps is currupted but NOT rescued(%d)", ret);
367                 return ret;
368             }
369             OIC_LOG(INFO, TAG, "ps is currupted and rescued");
370         }
371     }
372
373     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
374
375     return OC_STACK_OK;
376
377 }
378 #endif // __SECURE_PSI__
379
380 /**
381  * Write the Persistent Storage
382  *
383  * @param payload - pointer of payload
384  * @param psize   - size of payload
385  *
386  * @return OCStackResult - OC_STACK_OK sucsess, other - OC_STACK_ERROR
387  */
388 OCStackResult WritePSIDatabase(const uint8_t *payload, size_t size)
389 {
390     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
391
392     if (!payload || !size || !g_mutexDb)
393     {
394         OIC_LOG_V(ERROR, TAG, "%s: %s is NULL",
395                    __func__, !payload ? "payload" : !size ? "size" : "mutex");
396         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
397         return OC_STACK_INVALID_PARAM;
398     }
399
400     OCPersistentStorage *ps = NULL;
401     FILE *fp = NULL;
402     OCStackResult ret = OC_STACK_SVR_DB_NOT_EXIST;
403
404     ps = SRMGetPersistentStorageHandler();
405     VERIFY_NON_NULL(TAG, ps, ERROR);
406
407 #ifdef __SECURE_PSI__
408     if (psiIsKeySet() && ps->encrypt && ps->decrypt)
409     {
410         OIC_LOG(DEBUG, TAG, "ps->encrypt !");
411
412         uint8_t *ciphertext = NULL;
413         size_t ct_len = 0;
414
415         if (0 != ps->encrypt(payload, size, &ciphertext, &ct_len))
416         {
417             OIC_LOG(ERROR, TAG, "ps->encrypt() Failed");
418             ret = OC_STACK_ERROR;
419             goto exit;
420         }
421
422         payload = ciphertext;
423         size = ct_len;
424     }
425 #endif // __SECURE_PSI__
426
427     OIC_LOG_V(INFO, TAG, "Writing in the file: %zu", size);
428
429     fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb");
430     VERIFY_NON_NULL(TAG, fp, ERROR);
431
432     oc_mutex_lock(g_mutexDb);
433     g_svrDbFileSize = ps->write(payload, 1, size, fp);
434     ps->close(fp);
435     oc_mutex_unlock(g_mutexDb);
436
437 #ifdef __SECURE_PSI__
438     if (psiIsKeySet() && ps->encrypt && ps->decrypt)
439     {
440         OICFree((uint8_t*)payload);
441     }
442 #endif // __SECURE_PSI__
443     if (size == g_svrDbFileSize)
444     {
445         OIC_LOG_V(INFO, TAG, "Written %zu bytes into SVR database file", size);
446         ret = OC_STACK_OK;
447     }
448     else
449     {
450         OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", g_svrDbFileSize);
451     }
452
453 exit:
454     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
455     return ret;
456 }
457
458 /**
459  * Gets the Secure Virtual Database from the Persistent Storage
460  *
461  * @param ps - Persistent Storage handler
462  * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
463  * @param data - pointer of the returned Secure Virtual Resource(s)
464  * @param size - pointer of the returned size of Secure Virtual Resource(s)
465  *
466  * @return OCStackResult - result of getting Secure Virtual Resource(s)
467  */
468 OCStackResult GetSecureVirtualDatabaseFromPS2(OCPersistentStorage* ps, const char *rsrcName, uint8_t **data, size_t *size)
469 {
470     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
471
472     if (!data || *data || !size || !ps)
473     {
474         OIC_LOG_V(ERROR, TAG, "%s: %s is NULL",
475                    __func__, !data || *data ? "data" : !size ? "size" : "ps");
476         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
477         return OC_STACK_INVALID_PARAM;
478     }
479
480     FILE *fp = NULL;
481     uint8_t *fsData = NULL;
482     size_t fileSize = 0;
483     OCStackResult ret = OC_STACK_ERROR;
484
485     fileSize = GetPSIDatabaseSizeWithoutCaching(ps);
486     OIC_LOG_V(INFO, TAG, "File Read Size: %zu", fileSize);
487     if (fileSize)
488     {
489         fsData = (uint8_t *) OICCalloc(1, fileSize + 1);
490         VERIFY_NON_NULL(TAG, fsData, ERROR);
491
492         fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
493         VERIFY_NON_NULL(TAG, fp, ERROR);
494         if (ps->read(fsData, 1, fileSize, fp) == fileSize)
495         {
496 #ifdef __SECURE_PSI__
497             if (psiIsKeySet() && ps->encrypt && ps->decrypt)
498             {
499                 OIC_LOG(DEBUG, TAG, "ps->decrypt !");
500
501                 unsigned char *plainData = NULL;
502                 size_t plainSize = 0;
503
504                 if (0 != ps->decrypt(fsData, fileSize, &plainData, &plainSize))
505                 {
506                     OIC_LOG(ERROR, TAG, "ps->decrypt() Failed");
507                     ret = OC_STACK_ERROR;
508                     goto exit;
509                 }
510                 OICFree(fsData);
511                 fsData = plainData;
512                 fileSize = plainSize;
513             }
514 #endif // __SECURE_PSI__
515             if (rsrcName)
516             {
517                 CborParser parser;  // will be initialized in |cbor_parser_init|
518                 CborValue cbor;     // will be initialized in |cbor_parser_init|
519                 cbor_parser_init(fsData, fileSize, 0, &parser, &cbor);
520                 CborValue cborValue = {0};
521                 CborError cborFindResult = cbor_value_map_find_value(&cbor, rsrcName, &cborValue);
522                 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&cborValue))
523                 {
524                     cborFindResult = cbor_value_dup_byte_string(&cborValue, data, size, NULL);
525                     VERIFY_SUCCESS(TAG, CborNoError==cborFindResult, ERROR);
526                     ret = OC_STACK_OK;
527                 }
528                 // in case of |else (...)|, svr_data not found
529             }
530             // return everything in case rsrcName is NULL
531             else
532             {
533                 *size = fileSize;
534                 *data = (uint8_t *) OICCalloc(1, fileSize);
535                 VERIFY_NON_NULL(TAG, *data, ERROR);
536                 memcpy(*data, fsData, fileSize);
537                 ret = OC_STACK_OK;
538             }
539         }
540     }
541     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
542
543 exit:
544     if (fp)
545     {
546         ps->close(fp);
547     }
548     OICFree(fsData);
549     return ret;
550 }
551
552 /**
553  * Gets the Secure Virtual Database from the Persistent Storage
554  *
555  * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
556  * @param data - pointer of the returned Secure Virtual Resource(s)
557  * @param size - pointer of the returned size of Secure Virtual Resource(s)
558  *
559  * @return OCStackResult - result of getting Secure Virtual Resource(s)
560  */
561 OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **data, size_t *size)
562 {
563     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
564
565     // Logs for Persistent Storage status
566     PrintPSStatus();
567
568     if (!data || *data || !size || !g_mutexDb)
569     {
570         OIC_LOG_V(ERROR, TAG, "%s: %s is NULL",
571                    __func__, !data || *data ? "data" : !size ? "size" : "mutex");
572         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
573         return OC_STACK_INVALID_PARAM;
574     }
575
576     FILE *fp = NULL;
577     uint8_t *fsData = NULL;
578     size_t fileSize = 0;
579     OCStackResult ret = OC_STACK_ERROR;
580
581     OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
582     VERIFY_NON_NULL(TAG, ps, ERROR);
583
584     fileSize = GetPSIDatabaseSize(ps);
585     OIC_LOG_V(INFO, TAG, "File Read Size: %zu", fileSize);
586     if (fileSize)
587     {
588         fsData = (uint8_t *) OICCalloc(1, fileSize);
589         VERIFY_NON_NULL(TAG, fsData, ERROR);
590
591         fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
592         VERIFY_NON_NULL(TAG, fp, ERROR);
593         if (ps->read(fsData, 1, fileSize, fp) == fileSize)
594         {
595 #ifdef __SECURE_PSI__
596             if (psiIsKeySet() && ps->encrypt && ps->decrypt)
597             {
598                 OIC_LOG(DEBUG, TAG, "ps->decrypt !");
599
600                 unsigned char *plainData = NULL;
601                 size_t plainSize = 0;
602
603                 if (0 != ps->decrypt(fsData, fileSize, &plainData, &plainSize))
604                 {
605                     OIC_LOG(ERROR, TAG, "ps->decrypt() Failed");
606                     ret = OC_STACK_ERROR;
607                     goto exit;
608                 }
609                 OICFree(fsData);
610                 fsData = plainData;
611                 fileSize = plainSize;
612             }
613 #endif // __SECURE_PSI__
614             if (rsrcName)
615             {
616                 CborParser parser;  // will be initialized in |cbor_parser_init|
617                 CborValue cbor;     // will be initialized in |cbor_parser_init|
618                 cbor_parser_init(fsData, fileSize, 0, &parser, &cbor);
619                 CborValue cborValue = {0};
620                 CborError cborFindResult = cbor_value_map_find_value(&cbor, rsrcName, &cborValue);
621                 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&cborValue))
622                 {
623                     cborFindResult = cbor_value_dup_byte_string(&cborValue, data, size, NULL);
624                     VERIFY_SUCCESS(TAG, CborNoError==cborFindResult, ERROR);
625                     ret = OC_STACK_OK;
626                 }
627                 // in case of |else (...)|, svr_data not found
628             }
629             // return everything in case rsrcName is NULL
630             else
631             {
632                 *size = fileSize;
633                 *data = (uint8_t *) OICCalloc(1, fileSize);
634                 VERIFY_NON_NULL(TAG, *data, ERROR);
635                 memcpy(*data, fsData, fileSize);
636                 ret = OC_STACK_OK;
637             }
638         }
639     }
640     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
641
642 exit:
643     if (fp)
644     {
645         ps->close(fp);
646     }
647     OICFree(fsData);
648     return ret;
649 }
650
651 /**
652  * Updates the Secure Virtual Resource(s) into the Persistent Storage.
653  * This function stores cbor-payload of each resource by appending resource name,
654  * and empty payload implies deleting the value
655  *
656  * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
657  * @param psPayload - pointer of the updated Secure Virtual Resource(s)
658  * @param psSize - the updated size of Secure Virtual Resource(s)
659  *
660  * @return OCStackResult - result of updating Secure Virtual Resource(s)
661  */
662 OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPayload, size_t psSize)
663 {
664     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
665
666     if (!rsrcName)
667     {
668         return OC_STACK_INVALID_PARAM;
669     }
670
671     size_t dbSize = 0;
672     size_t outSize = 0;
673     uint8_t *dbData = NULL;
674     uint8_t *outPayload = NULL;
675
676     uint8_t *aclCbor = NULL;
677     uint8_t *pstatCbor = NULL;
678     uint8_t *doxmCbor = NULL;
679     uint8_t *amaclCbor = NULL;
680     uint8_t *credCbor = NULL;
681     uint8_t *pconfCbor = NULL;
682     uint8_t *resetPfCbor = NULL;
683     uint8_t *crlCbor = NULL;
684
685     int64_t cborEncoderResult = CborNoError;
686     OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
687     if (OC_STACK_OK != ret)
688     {
689         OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ret);
690     }
691     if (dbData && dbSize)
692     {
693         size_t aclCborLen = 0;
694         size_t pstatCborLen = 0;
695         size_t doxmCborLen = 0;
696         size_t amaclCborLen = 0;
697         size_t credCborLen = 0;
698         size_t pconfCborLen = 0;
699         size_t resetPfCborLen = 0;
700         size_t crlCborLen = 0;
701
702         ret = OC_STACK_ERROR;
703
704         // Gets each secure virtual resource from persistent storage
705         // this local scoping intended, for destroying large cbor instances after use
706         {
707             CborParser parser;  // will be initialized in |cbor_parser_init|
708             CborValue cbor;     // will be initialized in |cbor_parser_init|
709             cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
710             CborValue curVal = {0};
711             CborError cborFindResult = CborNoError;
712
713             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
714             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
715             {
716                 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
717                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
718             }
719             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
720             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
721             {
722                 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
723                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
724             }
725             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
726             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
727             {
728                 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
729                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult,  "Failed Finding DOXM Name Value.");
730             }
731             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_AMACL_NAME, &curVal);
732             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
733             {
734                 cborFindResult = cbor_value_dup_byte_string(&curVal, &amaclCbor, &amaclCborLen, NULL);
735                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding AMACL Name Value.");
736             }
737
738             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
739             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
740             {
741                 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
742                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value.");
743             }
744             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PCONF_NAME, &curVal);
745             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
746             {
747                 cborFindResult = cbor_value_dup_byte_string(&curVal, &pconfCbor, &pconfCborLen, NULL);
748                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PCONF Name Value.");
749             }
750             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
751             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
752             {
753                 cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL);
754                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value.");
755             }
756             int64_t cborFindCrlResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRL_NAME, &curVal);
757             if (CborNoError == cborFindCrlResult && cbor_value_is_byte_string(&curVal))
758             {
759                 cborFindCrlResult = cbor_value_dup_byte_string(&curVal, &crlCbor, &crlCborLen, NULL);
760                 if (CborNoError != cborFindCrlResult && CborErrorOutOfMemory != cborFindCrlResult)
761                 {
762                     OIC_LOG(ERROR, TAG, "Failed Finding optional CRL Name Value.");
763                 }
764                 else
765                 {
766                     OIC_LOG(INFO, TAG, "Successfully Finding optional CRL Name Value.");
767                 }
768             }
769         }
770
771         // Updates the added |psPayload| with the existing secure virtual resource(s)
772         // this local scoping intended, for destroying large cbor instances after use
773         {
774             size_t size = aclCborLen + pstatCborLen + doxmCborLen + amaclCborLen
775                         + credCborLen + pconfCborLen + resetPfCborLen + crlCborLen
776                         + psSize + 255;
777             // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
778
779             outPayload = (uint8_t *) OICCalloc(1, size);
780             VERIFY_NON_NULL(TAG, outPayload, ERROR);
781             CborEncoder encoder;  // will be initialized in |cbor_parser_init|
782             cbor_encoder_init(&encoder, outPayload, size, 0);
783             CborEncoder secRsrc;  // will be initialized in |cbor_encoder_create_map|
784             cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
785             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
786
787             if (psPayload && psSize)
788             {
789                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
790                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
791                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
792                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
793             }
794             if (strcmp(OIC_JSON_ACL_NAME, rsrcName) && aclCborLen)
795             {
796                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
797                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
798                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
799                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
800             }
801             if (strcmp(OIC_JSON_PSTAT_NAME, rsrcName) && pstatCborLen)
802             {
803                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
804                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
805                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
806                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
807             }
808             if (strcmp(OIC_JSON_DOXM_NAME, rsrcName) && doxmCborLen)
809             {
810                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
811                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
812                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
813                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
814             }
815             if (strcmp(OIC_JSON_AMACL_NAME, rsrcName) && amaclCborLen)
816             {
817                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_AMACL_NAME, strlen(OIC_JSON_AMACL_NAME));
818                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Name.");
819                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, amaclCbor, amaclCborLen);
820                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Value.");
821             }
822             if (strcmp(OIC_JSON_CRED_NAME, rsrcName) && credCborLen)
823             {
824                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
825                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Name.");
826                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
827                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Value.");
828             }
829             if (strcmp(OIC_JSON_PCONF_NAME, rsrcName) && pconfCborLen)
830             {
831                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PCONF_NAME, strlen(OIC_JSON_PCONF_NAME));
832                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Name.");
833                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pconfCbor, pconfCborLen);
834                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Value.");
835             }
836             if (strcmp(OIC_JSON_RESET_PF_NAME, rsrcName) && resetPfCborLen)
837             {
838                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_RESET_PF_NAME, strlen(OIC_JSON_RESET_PF_NAME));
839                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Name.");
840                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, resetPfCbor, resetPfCborLen);
841                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Value.");
842             }
843             if (strcmp(OIC_JSON_CRL_NAME, rsrcName) && crlCborLen)
844             {
845                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRL_NAME, strlen(OIC_JSON_CRL_NAME));
846                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Crl Name.");
847                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, crlCbor, crlCborLen);
848                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Crl Value.");
849             }
850
851             cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
852             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
853             outSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
854         }
855     }
856     else if (psPayload && psSize)
857     {
858         size_t size = psSize + 255;
859         // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
860
861         outPayload = (uint8_t *) OICCalloc(1, size);
862         VERIFY_NON_NULL(TAG, outPayload, ERROR);
863         CborEncoder encoder;  // will be initialized in |cbor_parser_init|
864         cbor_encoder_init(&encoder, outPayload, size, 0);
865         CborEncoder secRsrc;  // will be initialized in |cbor_encoder_create_map|
866         cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
867         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
868
869         cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
870         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
871         cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
872         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
873
874         cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
875         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
876         outSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
877     }
878
879     ret = WritePSIDatabase(outPayload, outSize);
880     if (OC_STACK_OK != ret)
881     {
882         OIC_LOG_V(ERROR, TAG, "WritePSIDatabase() is failed(%d)", ret);
883     }
884     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
885
886 exit:
887     OICFree(dbData);
888     OICFree(outPayload);
889     OICFree(aclCbor);
890     OICFree(pstatCbor);
891     OICFree(doxmCbor);
892     OICFree(amaclCbor);
893     OICFree(credCbor);
894     OICFree(pconfCbor);
895     OICFree(resetPfCbor);
896     OICFree(crlCbor);
897     return ret;
898 }
899
900 /**
901  * Resets the Secure Virtual Resource(s).
902  * This function reads the Reset Profile
903  * and resets the secure virtual resources accordingly.
904  *
905  * @return OCStackResult - result of updating Secure Virtual Resource(s)
906  */
907 OCStackResult ResetSecureResourceInPS(void)
908 {
909     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
910
911     size_t dbSize = 0;
912     size_t outSize = 0;
913     uint8_t *dbData = NULL;
914     uint8_t *outPayload = NULL;
915
916     uint8_t *aclCbor = NULL;
917     uint8_t *credCbor = NULL;
918     uint8_t *pstatCbor = NULL;
919     uint8_t *doxmCbor = NULL;
920     uint8_t *resetPfCbor = NULL;
921
922     int64_t cborEncoderResult = CborNoError;
923     OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
924     if (OC_STACK_OK != ret)
925     {
926         OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ret);
927     }
928     if(dbData && dbSize)
929     {
930         size_t aclCborLen = 0;
931         size_t credCborLen = 0;
932         size_t pstatCborLen = 0;
933         size_t doxmCborLen = 0;
934         size_t resetPfCborLen = 0;
935
936         ret = OC_STACK_ERROR;
937
938         // Gets the reset profile from persistent storage
939         {
940             CborParser parser;  // will be initialized in |cbor_parser_init|
941             CborValue cbor;     // will be initialized in |cbor_parser_init|
942             cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
943             CborValue curVal = {0};
944             CborError cborFindResult = CborNoError;
945             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
946             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
947             {
948                 cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL);
949                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value.");
950             }
951             else if (CborNoError == cborFindResult && CborInvalidType == curVal.type)
952             {
953                 OIC_LOG(ERROR, TAG, "resetpf is not found");
954                 goto exit;
955             }
956             else
957             {
958                 OIC_LOG_V(ERROR, TAG, "cbor_value_map_find_value() Failed(%d)",
959                         cborFindResult);
960                 goto exit;
961             }
962         }
963
964         // Gets each secure virtual resource from the reset profile
965         {
966             CborParser parser;  // will be initialized in |cbor_parser_init|
967             CborValue cbor;     // will be initialized in |cbor_parser_init|
968             cbor_parser_init(resetPfCbor, resetPfCborLen, 0, &parser, &cbor);
969             CborValue curVal = {0};
970             CborError cborFindResult = CborNoError;
971             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
972             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
973             {
974                 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
975                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
976             }
977             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
978             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
979             {
980                 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
981                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
982             }
983             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
984             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
985             {
986                 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
987                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
988             }
989             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
990             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
991             {
992                 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
993                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value.");
994             }
995         }
996
997         {
998             size_t size = aclCborLen + credCborLen + pstatCborLen + doxmCborLen + resetPfCborLen + 255;
999             // This added '255' is arbitrary value added to cover the name of the resource, map addition, and ending
1000
1001             outPayload = (uint8_t *) OICCalloc(1, size);
1002             VERIFY_NON_NULL(TAG, outPayload, ERROR);
1003             CborEncoder encoder;
1004             cbor_encoder_init(&encoder, outPayload, size, 0);
1005             CborEncoder secRsrc;
1006             cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
1007
1008             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
1009             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
1010             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
1011             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
1012
1013             if (credCborLen)
1014             {
1015                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
1016                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Name.");
1017                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
1018                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Value.");
1019             }
1020
1021             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
1022             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
1023             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
1024             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
1025
1026             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
1027             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Name.");
1028             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
1029             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Value.");
1030
1031             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_RESET_PF_NAME, strlen(OIC_JSON_RESET_PF_NAME));
1032             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Name.");
1033             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, resetPfCbor, resetPfCborLen);
1034             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Value.");
1035
1036             cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
1037             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
1038             outSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
1039         }
1040
1041         ret = WritePSIDatabase(outPayload, outSize);
1042         if (OC_STACK_OK != ret)
1043         {
1044             OIC_LOG_V(ERROR, TAG, "WritePSIDatabase() is failed(%d)", ret);
1045         }
1046     }
1047
1048     SRMDeInitSecureResources();
1049     InitSecureResources();
1050     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1051
1052 exit:
1053     OICFree(dbData);
1054     OICFree(outPayload);
1055     OICFree(aclCbor);
1056     OICFree(credCbor);
1057     OICFree(pstatCbor);
1058     OICFree(doxmCbor);
1059     OICFree(resetPfCbor);
1060     return ret;
1061 }
1062
1063 /**
1064  * Creates Reset Profile from the initial secure virtual resources.
1065  * This function copies the secure resources
1066  * and creates the Reset Profile in the Persistent Storage.
1067  * Device ID in doxm and pstat remains as same after reset.
1068  *
1069  * @return OCStackResult - result of updating Secure Virtual Resource(s)
1070  */
1071 OCStackResult CreateResetProfile(void)
1072 {
1073     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
1074
1075     size_t dbSize = 0;
1076     uint8_t *dbData = NULL;
1077
1078     uint8_t *aclCbor = NULL;
1079     uint8_t *credCbor = NULL;
1080     uint8_t *pstatCbor = NULL;
1081     uint8_t *doxmCbor = NULL;
1082     uint8_t *resetPfCbor = NULL;
1083
1084     OCStackResult ret = OC_STACK_ERROR;
1085     int64_t cborEncoderResult = CborNoError;
1086     ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
1087     if (OC_STACK_OK != ret)
1088     {
1089         OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ret);
1090     }
1091     if (dbData && dbSize)
1092     {
1093         size_t aclCborLen = 0;
1094         size_t credCborLen = 0;
1095         size_t pstatCborLen = 0;
1096         size_t doxmCborLen = 0;
1097         size_t resetPfCborLen = 0;
1098
1099         ret = OC_STACK_ERROR;
1100         {
1101             CborParser parser;
1102             CborValue cbor;
1103             cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
1104             CborValue curVal = {0};
1105             CborError cborFindResult = CborNoError;
1106
1107             // abort if reset profile exists
1108             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
1109             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1110             {
1111                 OIC_LOG(DEBUG, TAG, "Reset Profile already exists!!");
1112                 OICFree(dbData);
1113                 return OC_STACK_OK;
1114             }
1115
1116             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
1117             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1118             {
1119                 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
1120                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
1121             }
1122             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
1123             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1124             {
1125                 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
1126                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value.");
1127             }
1128             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
1129             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1130             {
1131                 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
1132                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
1133             }
1134             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
1135             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1136             {
1137                 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
1138                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult,  "Failed Finding DOXM Name Value.");
1139             }
1140         }
1141
1142         {
1143             size_t size = aclCborLen + credCborLen + pstatCborLen + doxmCborLen + 255;
1144             resetPfCbor = (uint8_t *) OICCalloc(1, size);
1145             VERIFY_NON_NULL(TAG, resetPfCbor, ERROR);
1146             CborEncoder encoder;  // will be initialized in |cbor_parser_init|
1147             cbor_encoder_init(&encoder, resetPfCbor, size, 0);
1148             CborEncoder secRsrc;  // will be initialized in |cbor_encoder_create_map|
1149             cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
1150
1151             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
1152             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
1153             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
1154             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
1155
1156             if (credCborLen)
1157             {
1158                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
1159                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Name.");
1160                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
1161                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Value.");
1162             }
1163
1164             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
1165             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
1166             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
1167             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
1168
1169             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
1170             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
1171             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
1172             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
1173
1174             cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
1175             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
1176             resetPfCborLen = cbor_encoder_get_buffer_size(&encoder, resetPfCbor);
1177         }
1178
1179         ret = UpdateSecureResourceInPS(OIC_JSON_RESET_PF_NAME, resetPfCbor, resetPfCborLen);
1180         if (OC_STACK_OK != ret)
1181         {
1182             OIC_LOG(ERROR, TAG, "Error in UpdateSecureResourceInPS");
1183         }
1184
1185     }
1186     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1187
1188 exit:
1189     OICFree(dbData);
1190     OICFree(aclCbor);
1191     OICFree(credCbor);
1192     OICFree(pstatCbor);
1193     OICFree(doxmCbor);
1194     OICFree(resetPfCbor);
1195     return ret;
1196 }
1197
1198 void SetPSStatus(PSStatus_t status)
1199 {
1200     g_psStatus = status;
1201 }
1202
1203 void PrintPSStatus(void)
1204 {
1205     switch(g_psStatus)
1206     {
1207         case PS_NORMAL:
1208             OIC_LOG(INFO, TAG, "PS Status: Normal - using external DB");
1209             break;
1210         case PS_OPEN_FAIL:
1211             OIC_LOG(INFO, TAG, "PS Status: Failed to open external DB! - using default DB");
1212             break;
1213         case PS_PARSE_FAIL:
1214             OIC_LOG(INFO, TAG, "PS Status: Failed to CBOR parse external DB! - using default DB");
1215             break;
1216         default:
1217             OIC_LOG(INFO, TAG, "PS Status: No external DB set - using internal memory");
1218
1219     }
1220 }