1 //******************************************************************
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
22 #define __STDC_LIMIT_MACROS
29 #include "cainterface.h"
31 #include "ocpayload.h"
32 #include "ocpayloadcbor.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"
42 #include "psinterface.h"
43 #include "doxmresource.h"
46 #define TAG "OIC_SRM_PSI"
48 // SVR database buffer block size
50 #define DB_FILE_SIZE_BLOCK 1023
52 const size_t DB_FILE_SIZE_BLOCK = 1023;
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;
59 // Persistent Storage status
60 static PSStatus_t g_psStatus = PS_NO_EXTERNAL_DB_SET;
62 static resetSVRDBCB_t g_resetSVRDBCB = {0};
64 resetSVRDBCB_t* const GetResetSVRDBCB(void)
66 return &g_resetSVRDBCB;
69 * Update the Persistent Storage Database size.
71 void UpdateSizePSI(size_t size)
73 oc_mutex_lock(g_mutexDb);
74 g_svrDbFileSize = size;
75 oc_mutex_unlock(g_mutexDb);
78 * Init the Persistent Storage Database.
80 OCStackResult InitPersistentStorageInterface(void)
84 g_mutexDb = oc_mutex_new();
87 return OC_STACK_ERROR;
97 * DeInit the Persistent Storage Database.
99 void DeinitPersistentStorageInterface(void)
102 oc_mutex_free(g_mutexDb);
107 * Gets the database size
109 * @param ps is a pointer to OCPersistentStorage for the Virtual Resource(s).
111 * @return size_t - total size of the database
113 static size_t GetPSIDatabaseSizeWithoutCaching(const OCPersistentStorage *ps)
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");
125 size_t bytesRead = 0;
128 bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
138 * Gets the the Persistent Storage Database size
140 * @param ps - pointer of OCPersistentStorage for the Secure Virtual Resource(s)
142 * @return size_t - total size of the SVR database
144 static size_t GetPSIDatabaseSize(const OCPersistentStorage *ps)
146 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
153 if (!g_svrDbFileSize)
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");
161 size_t bytesRead = 0;
164 bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
171 OIC_LOG_V(ERROR, TAG, "%s: File open failed.", __func__);
178 OIC_LOG_V(INFO, TAG, "%s get size from cache", __func__);
181 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
183 return g_svrDbFileSize;
186 #ifdef __SECURE_PSI__
187 static OCStackResult getPlaintextFromDB(const OCPersistentStorage *ps, uint8_t **pt,
190 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
191 OCStackResult ret = OC_STACK_ERROR;
193 uint8_t *plaintext = NULL;
196 fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
199 OIC_LOG(ERROR, TAG, "ps->open() Failed");
200 return OC_STACK_ERROR;
203 // Get fileSize of plaintext
204 char buffer[DB_FILE_SIZE_BLOCK];
205 size_t bytesRead = 0;
209 bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
210 fileSize += bytesRead;
214 ret = OC_STACK_NO_MEMORY;
215 plaintext = (uint8_t*)OICCalloc(1, fileSize);
216 VERIFY_NON_NULL(TAG, plaintext, ERROR);
219 fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
223 OIC_LOG(ERROR, TAG, "ps->open() Failed");
224 return OC_STACK_ERROR;
227 if (fileSize != ps->read(plaintext, 1, fileSize, fp))
229 OIC_LOG_V(ERROR, TAG, "ps->read() Failed");
230 ret = OC_STACK_ERROR;
238 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
250 static OCStackResult OTEncrypt(const OCPersistentStorage *psForPlain,
251 const OCPersistentStorage *psForEncrypted)
253 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
255 uint8_t *plaintext = NULL;
257 OCStackResult ret = getPlaintextFromDB(psForPlain, &plaintext, &pt_len);
258 if (OC_STACK_OK != ret)
260 OIC_LOG(ERROR, TAG, "getPlaintextFromDB() Failed");
265 uint8_t *ciphertext = NULL;
267 if (0 != psForEncrypted->encrypt(plaintext, pt_len, &ciphertext, &ct_len))
269 OIC_LOG(ERROR, TAG, "psForEncrypted->encrypt() Failed");
271 return OC_STACK_ERROR;
276 FILE *fp2 = psForEncrypted->open(SVR_DB_DAT_FILE_NAME, "wb");
279 OIC_LOG(ERROR, TAG, "psForEncrypted->open() Failed");
281 return OC_STACK_ERROR;
284 if (ct_len != psForEncrypted->write(ciphertext, 1, ct_len, fp2))
286 OIC_LOG(ERROR, TAG, "psForEncrypted->write() Failed");
288 return OC_STACK_ERROR;
290 psForEncrypted->close(fp2);
293 if (psForPlain->unlink)
295 psForPlain->unlink(SVR_DB_DAT_FILE_NAME);
299 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
304 OCStackResult setSecurePSI(const unsigned char *key, const OCPersistentStorage *psPlain,
305 const OCPersistentStorage *psEnc, const OCPersistentStorage *psRescue)
307 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
311 OIC_LOG_V(ERROR, TAG, "%s: %s is NULL", __func__, !key ? "key" : "psEnc");
312 return OC_STACK_INVALID_PARAM;
314 if (!(psEnc->encrypt && psEnc->decrypt))
316 OIC_LOG(ERROR, TAG, "psEnc->encrypt && psEnc->decrypt should be set");
317 return OC_STACK_INVALID_PARAM;
319 if (psPlain && !(psPlain->open && psPlain->read && psPlain->close
322 OIC_LOG(ERROR, TAG, "open/read/close/unlink funcion for plain should be set");
323 return OC_STACK_INVALID_PARAM;
325 if (psRescue && !(psRescue->open && psRescue->read && psRescue->close))
327 OIC_LOG(ERROR, TAG, "open/read/close funcion for rescue should be set");
328 return OC_STACK_INVALID_PARAM;
332 ret = psiSetKey(key);
333 if (OC_STACK_OK != ret)
335 OIC_LOG(ERROR, TAG, "psiSetKey() Failed");
338 OIC_LOG(DEBUG, TAG, "key is set");
340 // if there is new plain db
342 if (psPlain && (fp = psPlain->open(SVR_DB_DAT_FILE_NAME, "rb")))
347 ret = OTEncrypt(psPlain, psEnc);
348 if (OC_STACK_OK != ret)
350 OIC_LOG(ERROR, TAG, "OTEncrypt() Failed");
358 ret = CheckPersistentStorage((OCPersistentStorage*)psEnc);
359 if (OC_STACK_OK != ret)
361 fp = psRescue->open(SVR_DB_DAT_FILE_NAME, "rb");
364 OIC_LOG(ERROR, TAG, "psRescue->open() Failed");
365 return OC_STACK_ERROR;
370 ret = OTEncrypt(psRescue, psEnc);
371 if (OC_STACK_OK != ret)
373 OIC_LOG_V(ERROR, TAG, "ps is currupted but NOT rescued(%d)", ret);
376 OIC_LOG(INFO, TAG, "ps is currupted and rescued");
380 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
385 #endif // __SECURE_PSI__
388 * Write the Persistent Storage
390 * @param payload - pointer of payload
391 * @param psize - size of payload
393 * @return OCStackResult - OC_STACK_OK sucsess, other - OC_STACK_ERROR
395 OCStackResult WritePSIDatabase(const uint8_t *payload, size_t size)
397 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
399 if (!payload || !size || !g_mutexDb)
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;
407 OCPersistentStorage *ps = NULL;
409 OCStackResult ret = OC_STACK_SVR_DB_NOT_EXIST;
411 ps = SRMGetPersistentStorageHandler();
412 VERIFY_NON_NULL(TAG, ps, ERROR);
414 #ifdef __SECURE_PSI__
415 if (psiIsKeySet() && ps->encrypt && ps->decrypt)
417 OIC_LOG(DEBUG, TAG, "ps->encrypt !");
419 uint8_t *ciphertext = NULL;
422 if (0 != ps->encrypt(payload, size, &ciphertext, &ct_len))
424 OIC_LOG(ERROR, TAG, "ps->encrypt() Failed");
425 ret = OC_STACK_ERROR;
429 payload = ciphertext;
432 #endif // __SECURE_PSI__
434 OIC_LOG_V(INFO, TAG, "Writing in the file: %zu", size);
436 fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb");
437 VERIFY_NON_NULL(TAG, fp, ERROR);
439 oc_mutex_lock(g_mutexDb);
440 g_svrDbFileSize = ps->write(payload, 1, size, fp);
442 oc_mutex_unlock(g_mutexDb);
444 #ifdef __SECURE_PSI__
445 if (psiIsKeySet() && ps->encrypt && ps->decrypt)
447 OICFree((uint8_t*)payload);
449 #endif // __SECURE_PSI__
450 if (size == g_svrDbFileSize)
452 OIC_LOG_V(INFO, TAG, "Written %zu bytes into SVR database file", size);
457 OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", g_svrDbFileSize);
461 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
466 * Gets the Secure Virtual Database from the Persistent Storage
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)
473 * @return OCStackResult - result of getting Secure Virtual Resource(s)
475 OCStackResult GetSecureVirtualDatabaseFromPS2(OCPersistentStorage* ps, const char *rsrcName, uint8_t **data, size_t *size)
477 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
479 if (!data || *data || !size || !ps)
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;
488 uint8_t *fsData = NULL;
490 OCStackResult ret = OC_STACK_ERROR;
492 fileSize = GetPSIDatabaseSizeWithoutCaching(ps);
493 OIC_LOG_V(INFO, TAG, "File Read Size: %zu", fileSize);
496 fsData = (uint8_t *) OICCalloc(1, fileSize + 1);
497 VERIFY_NON_NULL(TAG, fsData, ERROR);
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)
503 #ifdef __SECURE_PSI__
504 if (psiIsKeySet() && ps->encrypt && ps->decrypt)
506 OIC_LOG(DEBUG, TAG, "ps->decrypt !");
508 unsigned char *plainData = NULL;
509 size_t plainSize = 0;
511 if (0 != ps->decrypt(fsData, fileSize, &plainData, &plainSize))
513 OIC_LOG(ERROR, TAG, "ps->decrypt() Failed");
514 ret = OC_STACK_ERROR;
519 fileSize = plainSize;
521 #endif // __SECURE_PSI__
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))
531 cborFindResult = cbor_value_dup_byte_string(&cborValue, data, size, NULL);
532 VERIFY_SUCCESS(TAG, CborNoError==cborFindResult, ERROR);
535 // in case of |else (...)|, svr_data not found
537 // return everything in case rsrcName is NULL
541 *data = (uint8_t *) OICCalloc(1, fileSize);
542 VERIFY_NON_NULL(TAG, *data, ERROR);
543 memcpy(*data, fsData, fileSize);
548 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
560 * Gets the Secure Virtual Database from the Persistent Storage
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)
566 * @return OCStackResult - result of getting Secure Virtual Resource(s)
568 OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **data, size_t *size)
570 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
572 // Logs for Persistent Storage status
575 if (!data || *data || !size || !g_mutexDb)
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;
584 uint8_t *fsData = NULL;
586 OCStackResult ret = OC_STACK_ERROR;
588 OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
589 VERIFY_NON_NULL(TAG, ps, ERROR);
591 fileSize = GetPSIDatabaseSize(ps);
592 OIC_LOG_V(INFO, TAG, "File Read Size: %zu", fileSize);
595 fsData = (uint8_t *) OICCalloc(1, fileSize);
596 VERIFY_NON_NULL(TAG, fsData, ERROR);
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)
602 #ifdef __SECURE_PSI__
603 if (psiIsKeySet() && ps->encrypt && ps->decrypt)
605 OIC_LOG(DEBUG, TAG, "ps->decrypt !");
607 unsigned char *plainData = NULL;
608 size_t plainSize = 0;
610 if (0 != ps->decrypt(fsData, fileSize, &plainData, &plainSize))
612 OIC_LOG(ERROR, TAG, "ps->decrypt() Failed");
613 ret = OC_STACK_ERROR;
618 fileSize = plainSize;
620 #endif // __SECURE_PSI__
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))
630 cborFindResult = cbor_value_dup_byte_string(&cborValue, data, size, NULL);
631 VERIFY_SUCCESS(TAG, CborNoError==cborFindResult, ERROR);
634 // in case of |else (...)|, svr_data not found
636 // return everything in case rsrcName is NULL
640 *data = (uint8_t *) OICCalloc(1, fileSize);
641 VERIFY_NON_NULL(TAG, *data, ERROR);
642 memcpy(*data, fsData, fileSize);
647 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
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
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)
667 * @return OCStackResult - result of updating Secure Virtual Resource(s)
669 OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPayload, size_t psSize)
671 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
675 return OC_STACK_INVALID_PARAM;
680 uint8_t *dbData = NULL;
681 uint8_t *outPayload = NULL;
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;
692 int64_t cborEncoderResult = CborNoError;
693 OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
694 if (OC_STACK_OK != ret)
696 OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ret);
698 if (dbData && dbSize)
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;
709 ret = OC_STACK_ERROR;
711 // Gets each secure virtual resource from persistent storage
712 // this local scoping intended, for destroying large cbor instances after use
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;
720 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
721 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
723 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
724 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
726 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
727 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
729 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
730 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
732 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
733 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
735 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
736 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value.");
738 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_AMACL_NAME, &curVal);
739 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
741 cborFindResult = cbor_value_dup_byte_string(&curVal, &amaclCbor, &amaclCborLen, NULL);
742 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding AMACL Name Value.");
745 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
746 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
748 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
749 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value.");
751 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PCONF_NAME, &curVal);
752 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
754 cborFindResult = cbor_value_dup_byte_string(&curVal, &pconfCbor, &pconfCborLen, NULL);
755 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PCONF Name Value.");
757 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
758 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
760 cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL);
761 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value.");
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))
766 cborFindCrlResult = cbor_value_dup_byte_string(&curVal, &crlCbor, &crlCborLen, NULL);
767 if (CborNoError != cborFindCrlResult && CborErrorOutOfMemory != cborFindCrlResult)
769 OIC_LOG(ERROR, TAG, "Failed Finding optional CRL Name Value.");
773 OIC_LOG(INFO, TAG, "Successfully Finding optional CRL Name Value.");
778 // Updates the added |psPayload| with the existing secure virtual resource(s)
779 // this local scoping intended, for destroying large cbor instances after use
781 size_t size = aclCborLen + pstatCborLen + doxmCborLen + amaclCborLen
782 + credCborLen + pconfCborLen + resetPfCborLen + crlCborLen
784 // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
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.");
794 if (psPayload && psSize)
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.");
801 if (strcmp(OIC_JSON_ACL_NAME, rsrcName) && aclCborLen)
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.");
808 if (strcmp(OIC_JSON_PSTAT_NAME, rsrcName) && pstatCborLen)
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.");
815 if (strcmp(OIC_JSON_DOXM_NAME, rsrcName) && doxmCborLen)
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.");
822 if (strcmp(OIC_JSON_AMACL_NAME, rsrcName) && amaclCborLen)
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.");
829 if (strcmp(OIC_JSON_CRED_NAME, rsrcName) && credCborLen)
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.");
836 if (strcmp(OIC_JSON_PCONF_NAME, rsrcName) && pconfCborLen)
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.");
843 if (strcmp(OIC_JSON_RESET_PF_NAME, rsrcName) && resetPfCborLen)
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.");
850 if (strcmp(OIC_JSON_CRL_NAME, rsrcName) && crlCborLen)
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.");
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);
863 else if (psPayload && psSize)
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
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.");
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.");
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);
886 ret = WritePSIDatabase(outPayload, outSize);
887 if (OC_STACK_OK != ret)
889 OIC_LOG_V(ERROR, TAG, "WritePSIDatabase() is failed(%d)", ret);
891 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
902 OICFree(resetPfCbor);
908 * Resets the Secure Virtual Resource(s).
909 * This function reads the Reset Profile
910 * and resets the secure virtual resources accordingly.
912 * @return OCStackResult - result of updating Secure Virtual Resource(s)
914 OCStackResult ResetSecureResourceInPS(void)
916 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
920 uint8_t *dbData = NULL;
921 uint8_t *outPayload = NULL;
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;
929 int64_t cborEncoderResult = CborNoError;
930 OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
931 if (OC_STACK_OK != ret)
933 OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ret);
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;
943 ret = OC_STACK_ERROR;
945 // Gets the reset profile from persistent storage
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))
955 cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL);
956 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value.");
958 else if (CborNoError == cborFindResult && CborInvalidType == curVal.type)
960 OIC_LOG(ERROR, TAG, "resetpf is not found");
965 OIC_LOG_V(ERROR, TAG, "cbor_value_map_find_value() Failed(%d)",
971 // Gets each secure virtual resource from the reset profile
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))
981 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
982 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
984 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
985 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
987 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
988 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
990 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
991 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
993 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
994 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
996 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
997 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
999 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
1000 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value.");
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
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);
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.");
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.");
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.");
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.");
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.");
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);
1048 ret = WritePSIDatabase(outPayload, outSize);
1049 if (OC_STACK_OK != ret)
1051 OIC_LOG_V(ERROR, TAG, "WritePSIDatabase() is failed(%d)", ret);
1055 SRMDeInitSecureResources();
1056 InitSecureResources();
1057 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1061 OICFree(outPayload);
1066 OICFree(resetPfCbor);
1068 if (NULL != g_resetSVRDBCB.callback)
1070 g_resetSVRDBCB.callback(ret);
1074 OIC_LOG_V(DEBUG, TAG, "%s - Notifier resetSVRDB callback isn't registered.", __func__);
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.
1086 * @return OCStackResult - result of updating Secure Virtual Resource(s)
1088 OCStackResult CreateResetProfile(void)
1090 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
1093 uint8_t *dbData = NULL;
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;
1101 OCStackResult ret = OC_STACK_ERROR;
1102 int64_t cborEncoderResult = CborNoError;
1103 ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
1104 if (OC_STACK_OK != ret)
1106 OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ret);
1108 if (dbData && dbSize)
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;
1116 ret = OC_STACK_ERROR;
1120 cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
1121 CborValue curVal = {0};
1122 CborError cborFindResult = CborNoError;
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))
1128 OIC_LOG(DEBUG, TAG, "Reset Profile already exists!!");
1133 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
1134 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1136 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
1137 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
1139 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
1140 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1142 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
1143 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value.");
1145 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
1146 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1148 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
1149 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
1151 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
1152 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1154 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
1155 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value.");
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);
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.");
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.");
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.");
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.");
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);
1196 ret = UpdateSecureResourceInPS(OIC_JSON_RESET_PF_NAME, resetPfCbor, resetPfCborLen);
1197 if (OC_STACK_OK != ret)
1199 OIC_LOG(ERROR, TAG, "Error in UpdateSecureResourceInPS");
1203 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1211 OICFree(resetPfCbor);
1215 void SetPSStatus(PSStatus_t status)
1217 g_psStatus = status;
1220 void PrintPSStatus(void)
1225 OIC_LOG(INFO, TAG, "PS Status: Normal - using external DB");
1228 OIC_LOG(INFO, TAG, "PS Status: Failed to open external DB! - using default DB");
1231 OIC_LOG(INFO, TAG, "PS Status: Failed to CBOR parse external DB! - using default DB");
1234 OIC_LOG(INFO, TAG, "PS Status: No external DB set - using internal memory");