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