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;
63 * Update the Persistent Storage Database size.
65 void UpdateSizePSI(size_t size)
67 oc_mutex_lock(g_mutexDb);
68 g_svrDbFileSize = size;
69 oc_mutex_unlock(g_mutexDb);
72 * Init the Persistent Storage Database.
74 OCStackResult InitPersistentStorageInterface(void)
78 g_mutexDb = oc_mutex_new();
81 return OC_STACK_ERROR;
91 * DeInit the Persistent Storage Database.
93 void DeinitPersistentStorageInterface(void)
96 oc_mutex_free(g_mutexDb);
101 * Gets the database size
103 * @param ps is a pointer to OCPersistentStorage for the Virtual Resource(s).
105 * @return size_t - total size of the database
107 static size_t GetPSIDatabaseSizeWithoutCaching(const OCPersistentStorage *ps)
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");
119 size_t bytesRead = 0;
122 bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
132 * Gets the the Persistent Storage Database size
134 * @param ps - pointer of OCPersistentStorage for the Secure Virtual Resource(s)
136 * @return size_t - total size of the SVR database
138 static size_t GetPSIDatabaseSize(const OCPersistentStorage *ps)
140 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
147 if (!g_svrDbFileSize)
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");
155 size_t bytesRead = 0;
158 bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
165 OIC_LOG_V(ERROR, TAG, "%s: File open failed.", __func__);
172 OIC_LOG_V(INFO, TAG, "%s get size from cache", __func__);
175 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
177 return g_svrDbFileSize;
180 #ifdef __SECURE_PSI__
181 static OCStackResult getPlaintextFromDB(const OCPersistentStorage *ps, uint8_t **pt,
184 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
185 OCStackResult ret = OC_STACK_ERROR;
187 uint8_t *plaintext = NULL;
190 fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
193 OIC_LOG(ERROR, TAG, "ps->open() Failed");
194 return OC_STACK_ERROR;
197 // Get fileSize of plaintext
198 char buffer[DB_FILE_SIZE_BLOCK];
199 size_t bytesRead = 0;
203 bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
204 fileSize += bytesRead;
208 ret = OC_STACK_NO_MEMORY;
209 plaintext = (uint8_t*)OICCalloc(1, fileSize);
210 VERIFY_NON_NULL(TAG, plaintext, ERROR);
213 fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
216 OIC_LOG(ERROR, TAG, "ps->open() Failed");
217 return OC_STACK_ERROR;
220 if (fileSize != ps->read(plaintext, 1, fileSize, fp))
222 OIC_LOG_V(ERROR, TAG, "ps->read() Failed");
223 ret = OC_STACK_ERROR;
231 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
243 static OCStackResult OTEncrypt(const OCPersistentStorage *psForPlain,
244 const OCPersistentStorage *psForEncrypted)
246 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
248 uint8_t *plaintext = NULL;
250 OCStackResult ret = getPlaintextFromDB(psForPlain, &plaintext, &pt_len);
251 if (OC_STACK_OK != ret)
253 OIC_LOG(ERROR, TAG, "getPlaintextFromDB() Failed");
258 uint8_t *ciphertext = NULL;
260 if (0 != psForEncrypted->encrypt(plaintext, pt_len, &ciphertext, &ct_len))
262 OIC_LOG(ERROR, TAG, "psForEncrypted->encrypt() Failed");
264 return OC_STACK_ERROR;
269 FILE *fp2 = psForEncrypted->open(SVR_DB_DAT_FILE_NAME, "wb");
272 OIC_LOG(ERROR, TAG, "psForEncrypted->open() Failed");
274 return OC_STACK_ERROR;
277 if (ct_len != psForEncrypted->write(ciphertext, 1, ct_len, fp2))
279 OIC_LOG(ERROR, TAG, "psForEncrypted->write() Failed");
281 return OC_STACK_ERROR;
283 psForEncrypted->close(fp2);
286 if (psForPlain->unlink)
288 psForPlain->unlink(SVR_DB_DAT_FILE_NAME);
292 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
297 OCStackResult setSecurePSI(const unsigned char *key, const OCPersistentStorage *psPlain,
298 const OCPersistentStorage *psEnc, const OCPersistentStorage *psRescue)
300 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
304 OIC_LOG_V(ERROR, TAG, "%s: %s is NULL", __func__, !key ? "key" : "psEnc");
305 return OC_STACK_INVALID_PARAM;
307 if (!(psEnc->encrypt && psEnc->decrypt))
309 OIC_LOG(ERROR, TAG, "psEnc->encrypt && psEnc->decrypt should be set");
310 return OC_STACK_INVALID_PARAM;
312 if (psPlain && !(psPlain->open && psPlain->read && psPlain->close
315 OIC_LOG(ERROR, TAG, "open/read/close/unlink funcion for plain should be set");
316 return OC_STACK_INVALID_PARAM;
318 if (psRescue && !(psRescue->open && psRescue->read && psRescue->close))
320 OIC_LOG(ERROR, TAG, "open/read/close funcion for rescue should be set");
321 return OC_STACK_INVALID_PARAM;
325 ret = psiSetKey(key);
326 if (OC_STACK_OK != ret)
328 OIC_LOG(ERROR, TAG, "psiSetKey() Failed");
331 OIC_LOG(DEBUG, TAG, "key is set");
333 // if there is new plain db
335 if (psPlain && (fp = psPlain->open(SVR_DB_DAT_FILE_NAME, "rb")))
340 ret = OTEncrypt(psPlain, psEnc);
341 if (OC_STACK_OK != ret)
343 OIC_LOG(ERROR, TAG, "OTEncrypt() Failed");
351 ret = CheckPersistentStorage((OCPersistentStorage*)psEnc);
352 if (OC_STACK_OK != ret)
354 fp = psRescue->open(SVR_DB_DAT_FILE_NAME, "rb");
357 OIC_LOG(ERROR, TAG, "psRescue->open() Failed");
358 return OC_STACK_ERROR;
363 ret = OTEncrypt(psRescue, psEnc);
364 if (OC_STACK_OK != ret)
366 OIC_LOG_V(ERROR, TAG, "ps is currupted but NOT rescued(%d)", ret);
369 OIC_LOG(INFO, TAG, "ps is currupted and rescued");
373 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
378 #endif // __SECURE_PSI__
381 * Write the Persistent Storage
383 * @param payload - pointer of payload
384 * @param psize - size of payload
386 * @return OCStackResult - OC_STACK_OK sucsess, other - OC_STACK_ERROR
388 OCStackResult WritePSIDatabase(const uint8_t *payload, size_t size)
390 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
392 if (!payload || !size || !g_mutexDb)
394 OIC_LOG_V(ERROR, TAG, "%s: %s is NULL",
395 __func__, !payload ? "payload" : !size ? "size" : "mutex");
396 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
397 return OC_STACK_INVALID_PARAM;
400 OCPersistentStorage *ps = NULL;
402 OCStackResult ret = OC_STACK_SVR_DB_NOT_EXIST;
404 ps = SRMGetPersistentStorageHandler();
405 VERIFY_NON_NULL(TAG, ps, ERROR);
407 #ifdef __SECURE_PSI__
408 if (psiIsKeySet() && ps->encrypt && ps->decrypt)
410 OIC_LOG(DEBUG, TAG, "ps->encrypt !");
412 uint8_t *ciphertext = NULL;
415 if (0 != ps->encrypt(payload, size, &ciphertext, &ct_len))
417 OIC_LOG(ERROR, TAG, "ps->encrypt() Failed");
418 ret = OC_STACK_ERROR;
422 payload = ciphertext;
425 #endif // __SECURE_PSI__
427 OIC_LOG_V(INFO, TAG, "Writing in the file: %zu", size);
429 fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb");
430 VERIFY_NON_NULL(TAG, fp, ERROR);
432 oc_mutex_lock(g_mutexDb);
433 g_svrDbFileSize = ps->write(payload, 1, size, fp);
435 oc_mutex_unlock(g_mutexDb);
437 #ifdef __SECURE_PSI__
438 if (psiIsKeySet() && ps->encrypt && ps->decrypt)
440 OICFree((uint8_t*)payload);
442 #endif // __SECURE_PSI__
443 if (size == g_svrDbFileSize)
445 OIC_LOG_V(INFO, TAG, "Written %zu bytes into SVR database file", size);
450 OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", g_svrDbFileSize);
454 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
459 * Gets the Secure Virtual Database from the Persistent Storage
461 * @param ps - Persistent Storage handler
462 * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
463 * @param data - pointer of the returned Secure Virtual Resource(s)
464 * @param size - pointer of the returned size of Secure Virtual Resource(s)
466 * @return OCStackResult - result of getting Secure Virtual Resource(s)
468 OCStackResult GetSecureVirtualDatabaseFromPS2(OCPersistentStorage* ps, const char *rsrcName, uint8_t **data, size_t *size)
470 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
472 if (!data || *data || !size || !ps)
474 OIC_LOG_V(ERROR, TAG, "%s: %s is NULL",
475 __func__, !data || *data ? "data" : !size ? "size" : "ps");
476 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
477 return OC_STACK_INVALID_PARAM;
481 uint8_t *fsData = NULL;
483 OCStackResult ret = OC_STACK_ERROR;
485 fileSize = GetPSIDatabaseSizeWithoutCaching(ps);
486 OIC_LOG_V(INFO, TAG, "File Read Size: %zu", fileSize);
489 fsData = (uint8_t *) OICCalloc(1, fileSize + 1);
490 VERIFY_NON_NULL(TAG, fsData, ERROR);
492 fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
493 VERIFY_NON_NULL(TAG, fp, ERROR);
494 if (ps->read(fsData, 1, fileSize, fp) == fileSize)
496 #ifdef __SECURE_PSI__
497 if (psiIsKeySet() && ps->encrypt && ps->decrypt)
499 OIC_LOG(DEBUG, TAG, "ps->decrypt !");
501 unsigned char *plainData = NULL;
502 size_t plainSize = 0;
504 if (0 != ps->decrypt(fsData, fileSize, &plainData, &plainSize))
506 OIC_LOG(ERROR, TAG, "ps->decrypt() Failed");
507 ret = OC_STACK_ERROR;
512 fileSize = plainSize;
514 #endif // __SECURE_PSI__
517 CborParser parser; // will be initialized in |cbor_parser_init|
518 CborValue cbor; // will be initialized in |cbor_parser_init|
519 cbor_parser_init(fsData, fileSize, 0, &parser, &cbor);
520 CborValue cborValue = {0};
521 CborError cborFindResult = cbor_value_map_find_value(&cbor, rsrcName, &cborValue);
522 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&cborValue))
524 cborFindResult = cbor_value_dup_byte_string(&cborValue, data, size, NULL);
525 VERIFY_SUCCESS(TAG, CborNoError==cborFindResult, ERROR);
528 // in case of |else (...)|, svr_data not found
530 // return everything in case rsrcName is NULL
534 *data = (uint8_t *) OICCalloc(1, fileSize);
535 VERIFY_NON_NULL(TAG, *data, ERROR);
536 memcpy(*data, fsData, fileSize);
541 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
553 * Gets the Secure Virtual Database from the Persistent Storage
555 * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
556 * @param data - pointer of the returned Secure Virtual Resource(s)
557 * @param size - pointer of the returned size of Secure Virtual Resource(s)
559 * @return OCStackResult - result of getting Secure Virtual Resource(s)
561 OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **data, size_t *size)
563 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
565 // Logs for Persistent Storage status
568 if (!data || *data || !size || !g_mutexDb)
570 OIC_LOG_V(ERROR, TAG, "%s: %s is NULL",
571 __func__, !data || *data ? "data" : !size ? "size" : "mutex");
572 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
573 return OC_STACK_INVALID_PARAM;
577 uint8_t *fsData = NULL;
579 OCStackResult ret = OC_STACK_ERROR;
581 OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
582 VERIFY_NON_NULL(TAG, ps, ERROR);
584 fileSize = GetPSIDatabaseSize(ps);
585 OIC_LOG_V(INFO, TAG, "File Read Size: %zu", fileSize);
588 fsData = (uint8_t *) OICCalloc(1, fileSize);
589 VERIFY_NON_NULL(TAG, fsData, ERROR);
591 fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
592 VERIFY_NON_NULL(TAG, fp, ERROR);
593 if (ps->read(fsData, 1, fileSize, fp) == fileSize)
595 #ifdef __SECURE_PSI__
596 if (psiIsKeySet() && ps->encrypt && ps->decrypt)
598 OIC_LOG(DEBUG, TAG, "ps->decrypt !");
600 unsigned char *plainData = NULL;
601 size_t plainSize = 0;
603 if (0 != ps->decrypt(fsData, fileSize, &plainData, &plainSize))
605 OIC_LOG(ERROR, TAG, "ps->decrypt() Failed");
606 ret = OC_STACK_ERROR;
611 fileSize = plainSize;
613 #endif // __SECURE_PSI__
616 CborParser parser; // will be initialized in |cbor_parser_init|
617 CborValue cbor; // will be initialized in |cbor_parser_init|
618 cbor_parser_init(fsData, fileSize, 0, &parser, &cbor);
619 CborValue cborValue = {0};
620 CborError cborFindResult = cbor_value_map_find_value(&cbor, rsrcName, &cborValue);
621 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&cborValue))
623 cborFindResult = cbor_value_dup_byte_string(&cborValue, data, size, NULL);
624 VERIFY_SUCCESS(TAG, CborNoError==cborFindResult, ERROR);
627 // in case of |else (...)|, svr_data not found
629 // return everything in case rsrcName is NULL
633 *data = (uint8_t *) OICCalloc(1, fileSize);
634 VERIFY_NON_NULL(TAG, *data, ERROR);
635 memcpy(*data, fsData, fileSize);
640 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
652 * Updates the Secure Virtual Resource(s) into the Persistent Storage.
653 * This function stores cbor-payload of each resource by appending resource name,
654 * and empty payload implies deleting the value
656 * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
657 * @param psPayload - pointer of the updated Secure Virtual Resource(s)
658 * @param psSize - the updated size of Secure Virtual Resource(s)
660 * @return OCStackResult - result of updating Secure Virtual Resource(s)
662 OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPayload, size_t psSize)
664 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
668 return OC_STACK_INVALID_PARAM;
673 uint8_t *dbData = NULL;
674 uint8_t *outPayload = NULL;
676 uint8_t *aclCbor = NULL;
677 uint8_t *pstatCbor = NULL;
678 uint8_t *doxmCbor = NULL;
679 uint8_t *amaclCbor = NULL;
680 uint8_t *credCbor = NULL;
681 uint8_t *pconfCbor = NULL;
682 uint8_t *resetPfCbor = NULL;
683 uint8_t *crlCbor = NULL;
685 int64_t cborEncoderResult = CborNoError;
686 OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
687 if (OC_STACK_OK != ret)
689 OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ret);
691 if (dbData && dbSize)
693 size_t aclCborLen = 0;
694 size_t pstatCborLen = 0;
695 size_t doxmCborLen = 0;
696 size_t amaclCborLen = 0;
697 size_t credCborLen = 0;
698 size_t pconfCborLen = 0;
699 size_t resetPfCborLen = 0;
700 size_t crlCborLen = 0;
702 ret = OC_STACK_ERROR;
704 // Gets each secure virtual resource from persistent storage
705 // this local scoping intended, for destroying large cbor instances after use
707 CborParser parser; // will be initialized in |cbor_parser_init|
708 CborValue cbor; // will be initialized in |cbor_parser_init|
709 cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
710 CborValue curVal = {0};
711 CborError cborFindResult = CborNoError;
713 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
714 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
716 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
717 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
719 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
720 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
722 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
723 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
725 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
726 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
728 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
729 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value.");
731 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_AMACL_NAME, &curVal);
732 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
734 cborFindResult = cbor_value_dup_byte_string(&curVal, &amaclCbor, &amaclCborLen, NULL);
735 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding AMACL Name Value.");
738 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
739 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
741 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
742 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value.");
744 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PCONF_NAME, &curVal);
745 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
747 cborFindResult = cbor_value_dup_byte_string(&curVal, &pconfCbor, &pconfCborLen, NULL);
748 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PCONF Name Value.");
750 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
751 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
753 cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL);
754 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value.");
756 int64_t cborFindCrlResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRL_NAME, &curVal);
757 if (CborNoError == cborFindCrlResult && cbor_value_is_byte_string(&curVal))
759 cborFindCrlResult = cbor_value_dup_byte_string(&curVal, &crlCbor, &crlCborLen, NULL);
760 if (CborNoError != cborFindCrlResult && CborErrorOutOfMemory != cborFindCrlResult)
762 OIC_LOG(ERROR, TAG, "Failed Finding optional CRL Name Value.");
766 OIC_LOG(INFO, TAG, "Successfully Finding optional CRL Name Value.");
771 // Updates the added |psPayload| with the existing secure virtual resource(s)
772 // this local scoping intended, for destroying large cbor instances after use
774 size_t size = aclCborLen + pstatCborLen + doxmCborLen + amaclCborLen
775 + credCborLen + pconfCborLen + resetPfCborLen + crlCborLen
777 // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
779 outPayload = (uint8_t *) OICCalloc(1, size);
780 VERIFY_NON_NULL(TAG, outPayload, ERROR);
781 CborEncoder encoder; // will be initialized in |cbor_parser_init|
782 cbor_encoder_init(&encoder, outPayload, size, 0);
783 CborEncoder secRsrc; // will be initialized in |cbor_encoder_create_map|
784 cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
785 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
787 if (psPayload && psSize)
789 cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
790 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
791 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
792 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
794 if (strcmp(OIC_JSON_ACL_NAME, rsrcName) && aclCborLen)
796 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
797 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
798 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
799 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
801 if (strcmp(OIC_JSON_PSTAT_NAME, rsrcName) && pstatCborLen)
803 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
804 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
805 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
806 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
808 if (strcmp(OIC_JSON_DOXM_NAME, rsrcName) && doxmCborLen)
810 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
811 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
812 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
813 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
815 if (strcmp(OIC_JSON_AMACL_NAME, rsrcName) && amaclCborLen)
817 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_AMACL_NAME, strlen(OIC_JSON_AMACL_NAME));
818 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Name.");
819 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, amaclCbor, amaclCborLen);
820 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Value.");
822 if (strcmp(OIC_JSON_CRED_NAME, rsrcName) && credCborLen)
824 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
825 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Name.");
826 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
827 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Value.");
829 if (strcmp(OIC_JSON_PCONF_NAME, rsrcName) && pconfCborLen)
831 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PCONF_NAME, strlen(OIC_JSON_PCONF_NAME));
832 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Name.");
833 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pconfCbor, pconfCborLen);
834 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Value.");
836 if (strcmp(OIC_JSON_RESET_PF_NAME, rsrcName) && resetPfCborLen)
838 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_RESET_PF_NAME, strlen(OIC_JSON_RESET_PF_NAME));
839 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Name.");
840 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, resetPfCbor, resetPfCborLen);
841 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Value.");
843 if (strcmp(OIC_JSON_CRL_NAME, rsrcName) && crlCborLen)
845 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRL_NAME, strlen(OIC_JSON_CRL_NAME));
846 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Crl Name.");
847 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, crlCbor, crlCborLen);
848 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Crl Value.");
851 cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
852 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
853 outSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
856 else if (psPayload && psSize)
858 size_t size = psSize + 255;
859 // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
861 outPayload = (uint8_t *) OICCalloc(1, size);
862 VERIFY_NON_NULL(TAG, outPayload, ERROR);
863 CborEncoder encoder; // will be initialized in |cbor_parser_init|
864 cbor_encoder_init(&encoder, outPayload, size, 0);
865 CborEncoder secRsrc; // will be initialized in |cbor_encoder_create_map|
866 cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
867 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
869 cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
870 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
871 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
872 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
874 cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
875 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
876 outSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
879 ret = WritePSIDatabase(outPayload, outSize);
880 if (OC_STACK_OK != ret)
882 OIC_LOG_V(ERROR, TAG, "WritePSIDatabase() is failed(%d)", ret);
884 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
895 OICFree(resetPfCbor);
901 * Resets the Secure Virtual Resource(s).
902 * This function reads the Reset Profile
903 * and resets the secure virtual resources accordingly.
905 * @return OCStackResult - result of updating Secure Virtual Resource(s)
907 OCStackResult ResetSecureResourceInPS(void)
909 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
913 uint8_t *dbData = NULL;
914 uint8_t *outPayload = NULL;
916 uint8_t *aclCbor = NULL;
917 uint8_t *credCbor = NULL;
918 uint8_t *pstatCbor = NULL;
919 uint8_t *doxmCbor = NULL;
920 uint8_t *resetPfCbor = NULL;
922 int64_t cborEncoderResult = CborNoError;
923 OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
924 if (OC_STACK_OK != ret)
926 OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ret);
930 size_t aclCborLen = 0;
931 size_t credCborLen = 0;
932 size_t pstatCborLen = 0;
933 size_t doxmCborLen = 0;
934 size_t resetPfCborLen = 0;
936 ret = OC_STACK_ERROR;
938 // Gets the reset profile from persistent storage
940 CborParser parser; // will be initialized in |cbor_parser_init|
941 CborValue cbor; // will be initialized in |cbor_parser_init|
942 cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
943 CborValue curVal = {0};
944 CborError cborFindResult = CborNoError;
945 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
946 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
948 cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL);
949 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value.");
951 else if (CborNoError == cborFindResult && CborInvalidType == curVal.type)
953 OIC_LOG(ERROR, TAG, "resetpf is not found");
958 OIC_LOG_V(ERROR, TAG, "cbor_value_map_find_value() Failed(%d)",
964 // Gets each secure virtual resource from the reset profile
966 CborParser parser; // will be initialized in |cbor_parser_init|
967 CborValue cbor; // will be initialized in |cbor_parser_init|
968 cbor_parser_init(resetPfCbor, resetPfCborLen, 0, &parser, &cbor);
969 CborValue curVal = {0};
970 CborError cborFindResult = CborNoError;
971 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
972 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
974 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
975 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
977 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
978 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
980 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
981 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
983 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
984 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
986 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
987 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
989 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
990 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
992 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
993 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value.");
998 size_t size = aclCborLen + credCborLen + pstatCborLen + doxmCborLen + resetPfCborLen + 255;
999 // This added '255' is arbitrary value added to cover the name of the resource, map addition, and ending
1001 outPayload = (uint8_t *) OICCalloc(1, size);
1002 VERIFY_NON_NULL(TAG, outPayload, ERROR);
1003 CborEncoder encoder;
1004 cbor_encoder_init(&encoder, outPayload, size, 0);
1005 CborEncoder secRsrc;
1006 cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
1008 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
1009 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
1010 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
1011 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
1015 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
1016 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Name.");
1017 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
1018 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Value.");
1021 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
1022 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
1023 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
1024 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
1026 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
1027 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Name.");
1028 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
1029 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Value.");
1031 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_RESET_PF_NAME, strlen(OIC_JSON_RESET_PF_NAME));
1032 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Name.");
1033 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, resetPfCbor, resetPfCborLen);
1034 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Value.");
1036 cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
1037 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
1038 outSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
1041 ret = WritePSIDatabase(outPayload, outSize);
1042 if (OC_STACK_OK != ret)
1044 OIC_LOG_V(ERROR, TAG, "WritePSIDatabase() is failed(%d)", ret);
1048 SRMDeInitSecureResources();
1049 InitSecureResources();
1050 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1054 OICFree(outPayload);
1059 OICFree(resetPfCbor);
1064 * Creates Reset Profile from the initial secure virtual resources.
1065 * This function copies the secure resources
1066 * and creates the Reset Profile in the Persistent Storage.
1067 * Device ID in doxm and pstat remains as same after reset.
1069 * @return OCStackResult - result of updating Secure Virtual Resource(s)
1071 OCStackResult CreateResetProfile(void)
1073 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
1076 uint8_t *dbData = NULL;
1078 uint8_t *aclCbor = NULL;
1079 uint8_t *credCbor = NULL;
1080 uint8_t *pstatCbor = NULL;
1081 uint8_t *doxmCbor = NULL;
1082 uint8_t *resetPfCbor = NULL;
1084 OCStackResult ret = OC_STACK_ERROR;
1085 int64_t cborEncoderResult = CborNoError;
1086 ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
1087 if (OC_STACK_OK != ret)
1089 OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ret);
1091 if (dbData && dbSize)
1093 size_t aclCborLen = 0;
1094 size_t credCborLen = 0;
1095 size_t pstatCborLen = 0;
1096 size_t doxmCborLen = 0;
1097 size_t resetPfCborLen = 0;
1099 ret = OC_STACK_ERROR;
1103 cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
1104 CborValue curVal = {0};
1105 CborError cborFindResult = CborNoError;
1107 // abort if reset profile exists
1108 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
1109 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1111 OIC_LOG(DEBUG, TAG, "Reset Profile already exists!!");
1116 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
1117 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1119 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
1120 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
1122 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
1123 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1125 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
1126 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value.");
1128 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
1129 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1131 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
1132 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
1134 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
1135 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1137 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
1138 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value.");
1143 size_t size = aclCborLen + credCborLen + pstatCborLen + doxmCborLen + 255;
1144 resetPfCbor = (uint8_t *) OICCalloc(1, size);
1145 VERIFY_NON_NULL(TAG, resetPfCbor, ERROR);
1146 CborEncoder encoder; // will be initialized in |cbor_parser_init|
1147 cbor_encoder_init(&encoder, resetPfCbor, size, 0);
1148 CborEncoder secRsrc; // will be initialized in |cbor_encoder_create_map|
1149 cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
1151 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
1152 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
1153 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
1154 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
1158 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
1159 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Name.");
1160 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
1161 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Value.");
1164 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
1165 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
1166 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
1167 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
1169 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
1170 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
1171 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
1172 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
1174 cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
1175 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
1176 resetPfCborLen = cbor_encoder_get_buffer_size(&encoder, resetPfCbor);
1179 ret = UpdateSecureResourceInPS(OIC_JSON_RESET_PF_NAME, resetPfCbor, resetPfCborLen);
1180 if (OC_STACK_OK != ret)
1182 OIC_LOG(ERROR, TAG, "Error in UpdateSecureResourceInPS");
1186 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1194 OICFree(resetPfCbor);
1198 void SetPSStatus(PSStatus_t status)
1200 g_psStatus = status;
1203 void PrintPSStatus(void)
1208 OIC_LOG(INFO, TAG, "PS Status: Normal - using external DB");
1211 OIC_LOG(INFO, TAG, "PS Status: Failed to open external DB! - using default DB");
1214 OIC_LOG(INFO, TAG, "PS Status: Failed to CBOR parse external DB! - using default DB");
1217 OIC_LOG(INFO, TAG, "PS Status: No external DB set - using internal memory");