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