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");
217 OIC_LOG(ERROR, TAG, "ps->open() Failed");
218 return OC_STACK_ERROR;
221 if (fileSize != ps->read(plaintext, 1, fileSize, fp))
223 OIC_LOG_V(ERROR, TAG, "ps->read() Failed");
224 ret = OC_STACK_ERROR;
232 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
244 static OCStackResult OTEncrypt(const OCPersistentStorage *psForPlain,
245 const OCPersistentStorage *psForEncrypted)
247 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
249 uint8_t *plaintext = NULL;
251 OCStackResult ret = getPlaintextFromDB(psForPlain, &plaintext, &pt_len);
252 if (OC_STACK_OK != ret)
254 OIC_LOG(ERROR, TAG, "getPlaintextFromDB() Failed");
259 uint8_t *ciphertext = NULL;
261 if (0 != psForEncrypted->encrypt(plaintext, pt_len, &ciphertext, &ct_len))
263 OIC_LOG(ERROR, TAG, "psForEncrypted->encrypt() Failed");
265 return OC_STACK_ERROR;
270 FILE *fp2 = psForEncrypted->open(SVR_DB_DAT_FILE_NAME, "wb");
273 OIC_LOG(ERROR, TAG, "psForEncrypted->open() Failed");
275 return OC_STACK_ERROR;
278 if (ct_len != psForEncrypted->write(ciphertext, 1, ct_len, fp2))
280 OIC_LOG(ERROR, TAG, "psForEncrypted->write() Failed");
282 return OC_STACK_ERROR;
284 psForEncrypted->close(fp2);
287 if (psForPlain->unlink)
289 psForPlain->unlink(SVR_DB_DAT_FILE_NAME);
293 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
298 OCStackResult setSecurePSI(const unsigned char *key, const OCPersistentStorage *psPlain,
299 const OCPersistentStorage *psEnc, const OCPersistentStorage *psRescue)
301 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
305 OIC_LOG_V(ERROR, TAG, "%s: %s is NULL", __func__, !key ? "key" : "psEnc");
306 return OC_STACK_INVALID_PARAM;
308 if (!(psEnc->encrypt && psEnc->decrypt))
310 OIC_LOG(ERROR, TAG, "psEnc->encrypt && psEnc->decrypt should be set");
311 return OC_STACK_INVALID_PARAM;
313 if (psPlain && !(psPlain->open && psPlain->read && psPlain->close
316 OIC_LOG(ERROR, TAG, "open/read/close/unlink funcion for plain should be set");
317 return OC_STACK_INVALID_PARAM;
319 if (psRescue && !(psRescue->open && psRescue->read && psRescue->close))
321 OIC_LOG(ERROR, TAG, "open/read/close funcion for rescue should be set");
322 return OC_STACK_INVALID_PARAM;
326 ret = psiSetKey(key);
327 if (OC_STACK_OK != ret)
329 OIC_LOG(ERROR, TAG, "psiSetKey() Failed");
332 OIC_LOG(DEBUG, TAG, "key is set");
334 // if there is new plain db
336 if (psPlain && (fp = psPlain->open(SVR_DB_DAT_FILE_NAME, "rb")))
341 ret = OTEncrypt(psPlain, psEnc);
342 if (OC_STACK_OK != ret)
344 OIC_LOG(ERROR, TAG, "OTEncrypt() Failed");
352 ret = CheckPersistentStorage((OCPersistentStorage*)psEnc);
353 if (OC_STACK_OK != ret)
355 fp = psRescue->open(SVR_DB_DAT_FILE_NAME, "rb");
358 OIC_LOG(ERROR, TAG, "psRescue->open() Failed");
359 return OC_STACK_ERROR;
364 ret = OTEncrypt(psRescue, psEnc);
365 if (OC_STACK_OK != ret)
367 OIC_LOG_V(ERROR, TAG, "ps is currupted but NOT rescued(%d)", ret);
370 OIC_LOG(INFO, TAG, "ps is currupted and rescued");
374 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
379 #endif // __SECURE_PSI__
382 * Write the Persistent Storage
384 * @param payload - pointer of payload
385 * @param psize - size of payload
387 * @return OCStackResult - OC_STACK_OK sucsess, other - OC_STACK_ERROR
389 OCStackResult WritePSIDatabase(const uint8_t *payload, size_t size)
391 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
393 if (!payload || !size || !g_mutexDb)
395 OIC_LOG_V(ERROR, TAG, "%s: %s is NULL",
396 __func__, !payload ? "payload" : !size ? "size" : "mutex");
397 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
398 return OC_STACK_INVALID_PARAM;
401 OCPersistentStorage *ps = NULL;
403 OCStackResult ret = OC_STACK_SVR_DB_NOT_EXIST;
405 ps = SRMGetPersistentStorageHandler();
406 VERIFY_NON_NULL(TAG, ps, ERROR);
408 #ifdef __SECURE_PSI__
409 if (psiIsKeySet() && ps->encrypt && ps->decrypt)
411 OIC_LOG(DEBUG, TAG, "ps->encrypt !");
413 uint8_t *ciphertext = NULL;
416 if (0 != ps->encrypt(payload, size, &ciphertext, &ct_len))
418 OIC_LOG(ERROR, TAG, "ps->encrypt() Failed");
419 ret = OC_STACK_ERROR;
423 payload = ciphertext;
426 #endif // __SECURE_PSI__
428 OIC_LOG_V(INFO, TAG, "Writing in the file: %zu", size);
430 fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb");
431 VERIFY_NON_NULL(TAG, fp, ERROR);
433 oc_mutex_lock(g_mutexDb);
434 g_svrDbFileSize = ps->write(payload, 1, size, fp);
436 oc_mutex_unlock(g_mutexDb);
438 #ifdef __SECURE_PSI__
439 if (psiIsKeySet() && ps->encrypt && ps->decrypt)
441 OICFree((uint8_t*)payload);
443 #endif // __SECURE_PSI__
444 if (size == g_svrDbFileSize)
446 OIC_LOG_V(INFO, TAG, "Written %zu bytes into SVR database file", size);
451 OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", g_svrDbFileSize);
455 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
460 * Gets the Secure Virtual Database from the Persistent Storage
462 * @param ps - Persistent Storage handler
463 * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
464 * @param data - pointer of the returned Secure Virtual Resource(s)
465 * @param size - pointer of the returned size of Secure Virtual Resource(s)
467 * @return OCStackResult - result of getting Secure Virtual Resource(s)
469 OCStackResult GetSecureVirtualDatabaseFromPS2(OCPersistentStorage* ps, const char *rsrcName, uint8_t **data, size_t *size)
471 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
473 if (!data || *data || !size || !ps)
475 OIC_LOG_V(ERROR, TAG, "%s: %s is NULL",
476 __func__, !data || *data ? "data" : !size ? "size" : "ps");
477 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
478 return OC_STACK_INVALID_PARAM;
482 uint8_t *fsData = NULL;
484 OCStackResult ret = OC_STACK_ERROR;
486 fileSize = GetPSIDatabaseSizeWithoutCaching(ps);
487 OIC_LOG_V(INFO, TAG, "File Read Size: %zu", fileSize);
490 fsData = (uint8_t *) OICCalloc(1, fileSize + 1);
491 VERIFY_NON_NULL(TAG, fsData, ERROR);
493 fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
494 VERIFY_NON_NULL(TAG, fp, ERROR);
495 if (ps->read(fsData, 1, fileSize, fp) == fileSize)
497 #ifdef __SECURE_PSI__
498 if (psiIsKeySet() && ps->encrypt && ps->decrypt)
500 OIC_LOG(DEBUG, TAG, "ps->decrypt !");
502 unsigned char *plainData = NULL;
503 size_t plainSize = 0;
505 if (0 != ps->decrypt(fsData, fileSize, &plainData, &plainSize))
507 OIC_LOG(ERROR, TAG, "ps->decrypt() Failed");
508 ret = OC_STACK_ERROR;
513 fileSize = plainSize;
515 #endif // __SECURE_PSI__
518 CborParser parser; // will be initialized in |cbor_parser_init|
519 CborValue cbor; // will be initialized in |cbor_parser_init|
520 cbor_parser_init(fsData, fileSize, 0, &parser, &cbor);
521 CborValue cborValue = {0};
522 CborError cborFindResult = cbor_value_map_find_value(&cbor, rsrcName, &cborValue);
523 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&cborValue))
525 cborFindResult = cbor_value_dup_byte_string(&cborValue, data, size, NULL);
526 VERIFY_SUCCESS(TAG, CborNoError==cborFindResult, ERROR);
529 // in case of |else (...)|, svr_data not found
531 // return everything in case rsrcName is NULL
535 *data = (uint8_t *) OICCalloc(1, fileSize);
536 VERIFY_NON_NULL(TAG, *data, ERROR);
537 memcpy(*data, fsData, fileSize);
542 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
554 * Gets the Secure Virtual Database from the Persistent Storage
556 * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
557 * @param data - pointer of the returned Secure Virtual Resource(s)
558 * @param size - pointer of the returned size of Secure Virtual Resource(s)
560 * @return OCStackResult - result of getting Secure Virtual Resource(s)
562 OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **data, size_t *size)
564 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
566 // Logs for Persistent Storage status
569 if (!data || *data || !size || !g_mutexDb)
571 OIC_LOG_V(ERROR, TAG, "%s: %s is NULL",
572 __func__, !data || *data ? "data" : !size ? "size" : "mutex");
573 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
574 return OC_STACK_INVALID_PARAM;
578 uint8_t *fsData = NULL;
580 OCStackResult ret = OC_STACK_ERROR;
582 OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
583 VERIFY_NON_NULL(TAG, ps, ERROR);
585 fileSize = GetPSIDatabaseSize(ps);
586 OIC_LOG_V(INFO, TAG, "File Read Size: %zu", fileSize);
589 fsData = (uint8_t *) OICCalloc(1, fileSize);
590 VERIFY_NON_NULL(TAG, fsData, ERROR);
592 fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
593 VERIFY_NON_NULL(TAG, fp, ERROR);
594 if (ps->read(fsData, 1, fileSize, fp) == fileSize)
596 #ifdef __SECURE_PSI__
597 if (psiIsKeySet() && ps->encrypt && ps->decrypt)
599 OIC_LOG(DEBUG, TAG, "ps->decrypt !");
601 unsigned char *plainData = NULL;
602 size_t plainSize = 0;
604 if (0 != ps->decrypt(fsData, fileSize, &plainData, &plainSize))
606 OIC_LOG(ERROR, TAG, "ps->decrypt() Failed");
607 ret = OC_STACK_ERROR;
612 fileSize = plainSize;
614 #endif // __SECURE_PSI__
617 CborParser parser; // will be initialized in |cbor_parser_init|
618 CborValue cbor; // will be initialized in |cbor_parser_init|
619 cbor_parser_init(fsData, fileSize, 0, &parser, &cbor);
620 CborValue cborValue = {0};
621 CborError cborFindResult = cbor_value_map_find_value(&cbor, rsrcName, &cborValue);
622 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&cborValue))
624 cborFindResult = cbor_value_dup_byte_string(&cborValue, data, size, NULL);
625 VERIFY_SUCCESS(TAG, CborNoError==cborFindResult, ERROR);
628 // in case of |else (...)|, svr_data not found
630 // return everything in case rsrcName is NULL
634 *data = (uint8_t *) OICCalloc(1, fileSize);
635 VERIFY_NON_NULL(TAG, *data, ERROR);
636 memcpy(*data, fsData, fileSize);
641 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
653 * Updates the Secure Virtual Resource(s) into the Persistent Storage.
654 * This function stores cbor-payload of each resource by appending resource name,
655 * and empty payload implies deleting the value
657 * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
658 * @param psPayload - pointer of the updated Secure Virtual Resource(s)
659 * @param psSize - the updated size of Secure Virtual Resource(s)
661 * @return OCStackResult - result of updating Secure Virtual Resource(s)
663 OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPayload, size_t psSize)
665 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
669 return OC_STACK_INVALID_PARAM;
674 uint8_t *dbData = NULL;
675 uint8_t *outPayload = NULL;
677 uint8_t *aclCbor = NULL;
678 uint8_t *pstatCbor = NULL;
679 uint8_t *doxmCbor = NULL;
680 uint8_t *amaclCbor = NULL;
681 uint8_t *credCbor = NULL;
682 uint8_t *pconfCbor = NULL;
683 uint8_t *resetPfCbor = NULL;
684 uint8_t *crlCbor = NULL;
686 int64_t cborEncoderResult = CborNoError;
687 OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
688 if (OC_STACK_OK != ret)
690 OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ret);
692 if (dbData && dbSize)
694 size_t aclCborLen = 0;
695 size_t pstatCborLen = 0;
696 size_t doxmCborLen = 0;
697 size_t amaclCborLen = 0;
698 size_t credCborLen = 0;
699 size_t pconfCborLen = 0;
700 size_t resetPfCborLen = 0;
701 size_t crlCborLen = 0;
703 ret = OC_STACK_ERROR;
705 // Gets each secure virtual resource from persistent storage
706 // this local scoping intended, for destroying large cbor instances after use
708 CborParser parser; // will be initialized in |cbor_parser_init|
709 CborValue cbor; // will be initialized in |cbor_parser_init|
710 cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
711 CborValue curVal = {0};
712 CborError cborFindResult = CborNoError;
714 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
715 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
717 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
718 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
720 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
721 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
723 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
724 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
726 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
727 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
729 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
730 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value.");
732 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_AMACL_NAME, &curVal);
733 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
735 cborFindResult = cbor_value_dup_byte_string(&curVal, &amaclCbor, &amaclCborLen, NULL);
736 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding AMACL Name Value.");
739 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
740 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
742 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
743 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value.");
745 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PCONF_NAME, &curVal);
746 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
748 cborFindResult = cbor_value_dup_byte_string(&curVal, &pconfCbor, &pconfCborLen, NULL);
749 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PCONF Name Value.");
751 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
752 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
754 cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL);
755 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value.");
757 int64_t cborFindCrlResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRL_NAME, &curVal);
758 if (CborNoError == cborFindCrlResult && cbor_value_is_byte_string(&curVal))
760 cborFindCrlResult = cbor_value_dup_byte_string(&curVal, &crlCbor, &crlCborLen, NULL);
761 if (CborNoError != cborFindCrlResult && CborErrorOutOfMemory != cborFindCrlResult)
763 OIC_LOG(ERROR, TAG, "Failed Finding optional CRL Name Value.");
767 OIC_LOG(INFO, TAG, "Successfully Finding optional CRL Name Value.");
772 // Updates the added |psPayload| with the existing secure virtual resource(s)
773 // this local scoping intended, for destroying large cbor instances after use
775 size_t size = aclCborLen + pstatCborLen + doxmCborLen + amaclCborLen
776 + credCborLen + pconfCborLen + resetPfCborLen + crlCborLen
778 // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
780 outPayload = (uint8_t *) OICCalloc(1, size);
781 VERIFY_NON_NULL(TAG, outPayload, ERROR);
782 CborEncoder encoder; // will be initialized in |cbor_parser_init|
783 cbor_encoder_init(&encoder, outPayload, size, 0);
784 CborEncoder secRsrc; // will be initialized in |cbor_encoder_create_map|
785 cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
786 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
788 if (psPayload && psSize)
790 cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
791 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
792 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
793 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
795 if (strcmp(OIC_JSON_ACL_NAME, rsrcName) && aclCborLen)
797 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
798 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
799 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
800 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
802 if (strcmp(OIC_JSON_PSTAT_NAME, rsrcName) && pstatCborLen)
804 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
805 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
806 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
807 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
809 if (strcmp(OIC_JSON_DOXM_NAME, rsrcName) && doxmCborLen)
811 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
812 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
813 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
814 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
816 if (strcmp(OIC_JSON_AMACL_NAME, rsrcName) && amaclCborLen)
818 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_AMACL_NAME, strlen(OIC_JSON_AMACL_NAME));
819 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Name.");
820 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, amaclCbor, amaclCborLen);
821 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Value.");
823 if (strcmp(OIC_JSON_CRED_NAME, rsrcName) && credCborLen)
825 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
826 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Name.");
827 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
828 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Value.");
830 if (strcmp(OIC_JSON_PCONF_NAME, rsrcName) && pconfCborLen)
832 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PCONF_NAME, strlen(OIC_JSON_PCONF_NAME));
833 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Name.");
834 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pconfCbor, pconfCborLen);
835 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Value.");
837 if (strcmp(OIC_JSON_RESET_PF_NAME, rsrcName) && resetPfCborLen)
839 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_RESET_PF_NAME, strlen(OIC_JSON_RESET_PF_NAME));
840 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Name.");
841 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, resetPfCbor, resetPfCborLen);
842 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Value.");
844 if (strcmp(OIC_JSON_CRL_NAME, rsrcName) && crlCborLen)
846 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRL_NAME, strlen(OIC_JSON_CRL_NAME));
847 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Crl Name.");
848 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, crlCbor, crlCborLen);
849 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Crl Value.");
852 cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
853 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
854 outSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
857 else if (psPayload && psSize)
859 size_t size = psSize + 255;
860 // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
862 outPayload = (uint8_t *) OICCalloc(1, size);
863 VERIFY_NON_NULL(TAG, outPayload, ERROR);
864 CborEncoder encoder; // will be initialized in |cbor_parser_init|
865 cbor_encoder_init(&encoder, outPayload, size, 0);
866 CborEncoder secRsrc; // will be initialized in |cbor_encoder_create_map|
867 cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
868 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
870 cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
871 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
872 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
873 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
875 cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
876 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
877 outSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
880 ret = WritePSIDatabase(outPayload, outSize);
881 if (OC_STACK_OK != ret)
883 OIC_LOG_V(ERROR, TAG, "WritePSIDatabase() is failed(%d)", ret);
885 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
896 OICFree(resetPfCbor);
902 * Resets the Secure Virtual Resource(s).
903 * This function reads the Reset Profile
904 * and resets the secure virtual resources accordingly.
906 * @return OCStackResult - result of updating Secure Virtual Resource(s)
908 OCStackResult ResetSecureResourceInPS(void)
910 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
914 uint8_t *dbData = NULL;
915 uint8_t *outPayload = NULL;
917 uint8_t *aclCbor = NULL;
918 uint8_t *credCbor = NULL;
919 uint8_t *pstatCbor = NULL;
920 uint8_t *doxmCbor = NULL;
921 uint8_t *resetPfCbor = NULL;
923 int64_t cborEncoderResult = CborNoError;
924 OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
925 if (OC_STACK_OK != ret)
927 OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ret);
931 size_t aclCborLen = 0;
932 size_t credCborLen = 0;
933 size_t pstatCborLen = 0;
934 size_t doxmCborLen = 0;
935 size_t resetPfCborLen = 0;
937 ret = OC_STACK_ERROR;
939 // Gets the reset profile from persistent storage
941 CborParser parser; // will be initialized in |cbor_parser_init|
942 CborValue cbor; // will be initialized in |cbor_parser_init|
943 cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
944 CborValue curVal = {0};
945 CborError cborFindResult = CborNoError;
946 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
947 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
949 cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL);
950 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value.");
952 else if (CborNoError == cborFindResult && CborInvalidType == curVal.type)
954 OIC_LOG(ERROR, TAG, "resetpf is not found");
959 OIC_LOG_V(ERROR, TAG, "cbor_value_map_find_value() Failed(%d)",
965 // Gets each secure virtual resource from the reset profile
967 CborParser parser; // will be initialized in |cbor_parser_init|
968 CborValue cbor; // will be initialized in |cbor_parser_init|
969 cbor_parser_init(resetPfCbor, resetPfCborLen, 0, &parser, &cbor);
970 CborValue curVal = {0};
971 CborError cborFindResult = CborNoError;
972 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
973 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
975 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
976 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
978 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
979 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
981 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
982 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
984 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
985 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
987 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
988 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
990 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
991 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
993 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
994 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value.");
999 size_t size = aclCborLen + credCborLen + pstatCborLen + doxmCborLen + resetPfCborLen + 255;
1000 // This added '255' is arbitrary value added to cover the name of the resource, map addition, and ending
1002 outPayload = (uint8_t *) OICCalloc(1, size);
1003 VERIFY_NON_NULL(TAG, outPayload, ERROR);
1004 CborEncoder encoder;
1005 cbor_encoder_init(&encoder, outPayload, size, 0);
1006 CborEncoder secRsrc;
1007 cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
1009 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
1010 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
1011 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
1012 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
1016 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
1017 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Name.");
1018 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
1019 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Value.");
1022 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
1023 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
1024 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
1025 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
1027 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
1028 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Name.");
1029 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
1030 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Value.");
1032 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_RESET_PF_NAME, strlen(OIC_JSON_RESET_PF_NAME));
1033 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Name.");
1034 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, resetPfCbor, resetPfCborLen);
1035 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Value.");
1037 cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
1038 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
1039 outSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
1042 ret = WritePSIDatabase(outPayload, outSize);
1043 if (OC_STACK_OK != ret)
1045 OIC_LOG_V(ERROR, TAG, "WritePSIDatabase() is failed(%d)", ret);
1049 SRMDeInitSecureResources();
1050 InitSecureResources();
1051 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1055 OICFree(outPayload);
1060 OICFree(resetPfCbor);
1065 * Creates Reset Profile from the initial secure virtual resources.
1066 * This function copies the secure resources
1067 * and creates the Reset Profile in the Persistent Storage.
1068 * Device ID in doxm and pstat remains as same after reset.
1070 * @return OCStackResult - result of updating Secure Virtual Resource(s)
1072 OCStackResult CreateResetProfile(void)
1074 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
1077 uint8_t *dbData = NULL;
1079 uint8_t *aclCbor = NULL;
1080 uint8_t *credCbor = NULL;
1081 uint8_t *pstatCbor = NULL;
1082 uint8_t *doxmCbor = NULL;
1083 uint8_t *resetPfCbor = NULL;
1085 OCStackResult ret = OC_STACK_ERROR;
1086 int64_t cborEncoderResult = CborNoError;
1087 ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
1088 if (OC_STACK_OK != ret)
1090 OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ret);
1092 if (dbData && dbSize)
1094 size_t aclCborLen = 0;
1095 size_t credCborLen = 0;
1096 size_t pstatCborLen = 0;
1097 size_t doxmCborLen = 0;
1098 size_t resetPfCborLen = 0;
1100 ret = OC_STACK_ERROR;
1104 cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
1105 CborValue curVal = {0};
1106 CborError cborFindResult = CborNoError;
1108 // abort if reset profile exists
1109 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
1110 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1112 OIC_LOG(DEBUG, TAG, "Reset Profile already exists!!");
1117 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
1118 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1120 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
1121 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
1123 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
1124 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1126 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
1127 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value.");
1129 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
1130 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1132 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
1133 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
1135 cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
1136 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
1138 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
1139 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value.");
1144 size_t size = aclCborLen + credCborLen + pstatCborLen + doxmCborLen + 255;
1145 resetPfCbor = (uint8_t *) OICCalloc(1, size);
1146 VERIFY_NON_NULL(TAG, resetPfCbor, ERROR);
1147 CborEncoder encoder; // will be initialized in |cbor_parser_init|
1148 cbor_encoder_init(&encoder, resetPfCbor, size, 0);
1149 CborEncoder secRsrc; // will be initialized in |cbor_encoder_create_map|
1150 cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
1152 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
1153 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
1154 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
1155 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
1159 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
1160 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Name.");
1161 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
1162 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Value.");
1165 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
1166 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
1167 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
1168 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
1170 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
1171 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
1172 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
1173 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
1175 cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
1176 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
1177 resetPfCborLen = cbor_encoder_get_buffer_size(&encoder, resetPfCbor);
1180 ret = UpdateSecureResourceInPS(OIC_JSON_RESET_PF_NAME, resetPfCbor, resetPfCborLen);
1181 if (OC_STACK_OK != ret)
1183 OIC_LOG(ERROR, TAG, "Error in UpdateSecureResourceInPS");
1187 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1195 OICFree(resetPfCbor);
1199 void SetPSStatus(PSStatus_t status)
1201 g_psStatus = status;
1204 void PrintPSStatus(void)
1209 OIC_LOG(INFO, TAG, "PS Status: Normal - using external DB");
1212 OIC_LOG(INFO, TAG, "PS Status: Failed to open external DB! - using default DB");
1215 OIC_LOG(INFO, TAG, "PS Status: Failed to CBOR parse external DB! - using default DB");
1218 OIC_LOG(INFO, TAG, "PS Status: No external DB set - using internal memory");