X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fsecurity%2Fsrc%2Fpsinterface.c;h=c24f05aa6de44e324f4e51286fa78fe1a27cee9d;hb=3c093548382bb2542c87a67e6e5fa32552c29cb3;hp=c24ecde5904c74c3116102276bff33d183e385ea;hpb=72344ad0d6bf761dd65f7c9fe44922559b1bed2e;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/security/src/psinterface.c b/resource/csdk/security/src/psinterface.c index c24ecde..c24f05a 100644 --- a/resource/csdk/security/src/psinterface.c +++ b/resource/csdk/security/src/psinterface.c @@ -24,6 +24,7 @@ #include #include +#include #include "cainterface.h" #include "logger.h" @@ -37,25 +38,73 @@ #include "srmresourcestrings.h" #include "srmutility.h" #include "pstatresource.h" +#include "psiutils.h" +#include "psinterface.h" #include "doxmresource.h" +#include "octhread.h" -#define TAG "SRM-PSI" +#define TAG "OIC_SRM_PSI" -//SVR database buffer block size +// SVR database buffer block size #ifdef _WIN32 #define DB_FILE_SIZE_BLOCK 1023 #else const size_t DB_FILE_SIZE_BLOCK = 1023; #endif +//the Secure Virtual Database file size +static size_t g_svrDbFileSize = 0; +//mutex for the Secure Virtual Database +static oc_mutex g_mutexDb = NULL; +// Persistent Storage status +static PSStatus_t g_psStatus = PS_NO_EXTERNAL_DB_SET; + +/** + * Update the Persistent Storage Database size. + */ +void UpdateSizePSI(size_t size) +{ + oc_mutex_lock(g_mutexDb); + g_svrDbFileSize = size; + oc_mutex_unlock(g_mutexDb); +} /** - * Gets the Secure Virtual Database size + * Init the Persistent Storage Database. + */ +OCStackResult InitPersistentStorageInterface(void) +{ + if (!g_mutexDb) + { + g_mutexDb = oc_mutex_new(); + if(!g_mutexDb) + { + return OC_STACK_ERROR; + } + } + + UpdateSizePSI(0); + + return OC_STACK_OK; +} + +/** + * DeInit the Persistent Storage Database. + */ +void DeinitPersistentStorageInterface(void) +{ + g_svrDbFileSize = 0; + oc_mutex_free(g_mutexDb); + g_mutexDb = NULL; +} + +/** + * Gets the database size * - * @param ps - pointer of OCPersistentStorage for the Secure Virtual Resource(s) + * @param ps is a pointer to OCPersistentStorage for the Virtual Resource(s). * - * @return size_t - total size of the SVR database + * @return size_t - total size of the database */ -static size_t GetSVRDatabaseSize(const OCPersistentStorage *ps) +static size_t GetPSIDatabaseSizeWithoutCaching(const OCPersistentStorage *ps) { if (!ps) { @@ -78,6 +127,428 @@ static size_t GetSVRDatabaseSize(const OCPersistentStorage *ps) return size; } + +/** + * Gets the the Persistent Storage Database size + * + * @param ps - pointer of OCPersistentStorage for the Secure Virtual Resource(s) + * + * @return size_t - total size of the SVR database + */ +static size_t GetPSIDatabaseSize(const OCPersistentStorage *ps) +{ + OIC_LOG_V(DEBUG, TAG, "In %s", __func__); + + if (!ps) + { + return 0; + } + + if (!g_svrDbFileSize) + { + size_t size = 0; + char buffer[DB_FILE_SIZE_BLOCK]; // can not initialize with declaration + // but maybe not needed to initialize + FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb"); + if (fp) + { + size_t bytesRead = 0; + do + { + bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp); + size += bytesRead; + } while (bytesRead); + ps->close(fp); + } + else + { + OIC_LOG_V(ERROR, TAG, "%s: File open failed.", __func__); + } + + UpdateSizePSI(size); + } + else + { + OIC_LOG_V(INFO, TAG, "%s get size from cache", __func__); + } + + OIC_LOG_V(DEBUG, TAG, "Out %s", __func__); + + return g_svrDbFileSize; +} + +#ifdef __SECURE_PSI__ +static OCStackResult getPlaintextFromDB(const OCPersistentStorage *ps, uint8_t **pt, + size_t *pt_len) +{ + OIC_LOG_V(DEBUG, TAG, "In %s", __func__); + OCStackResult ret = OC_STACK_ERROR; + + uint8_t *plaintext = NULL; + + FILE *fp = NULL; + fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb"); + if (NULL == fp) + { + OIC_LOG(ERROR, TAG, "ps->open() Failed"); + return OC_STACK_ERROR; + } + + // Get fileSize of plaintext + char buffer[DB_FILE_SIZE_BLOCK]; + size_t bytesRead = 0; + size_t fileSize = 0; + do + { + bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp); + fileSize += bytesRead; + } while (bytesRead); + + // Get plaintext + ret = OC_STACK_NO_MEMORY; + plaintext = (uint8_t*)OICCalloc(1, fileSize); + VERIFY_NON_NULL(TAG, plaintext, ERROR); + + ps->close(fp); + fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb"); + if (NULL == fp) + { + OIC_LOG(ERROR, TAG, "ps->open() Failed"); + return OC_STACK_ERROR; + } + + if (fileSize != ps->read(plaintext, 1, fileSize, fp)) + { + OIC_LOG_V(ERROR, TAG, "ps->read() Failed"); + ret = OC_STACK_ERROR; + goto exit; + } + + *pt = plaintext; + *pt_len = fileSize; + ps->close(fp); + + OIC_LOG_V(DEBUG, TAG, "Out %s", __func__); + + return OC_STACK_OK; +exit: + OICFree(plaintext); + if (fp) + { + ps->close(fp); + } + return ret; +} + +static OCStackResult OTEncrypt(const OCPersistentStorage *psForPlain, + const OCPersistentStorage *psForEncrypted) +{ + OIC_LOG_V(DEBUG, TAG, "In %s", __func__); + + uint8_t *plaintext = NULL; + size_t pt_len = 0; + OCStackResult ret = getPlaintextFromDB(psForPlain, &plaintext, &pt_len); + if (OC_STACK_OK != ret) + { + OIC_LOG(ERROR, TAG, "getPlaintextFromDB() Failed"); + return ret; + } + + // Encrypt plaintext + uint8_t *ciphertext = NULL; + size_t ct_len = 0; + if (0 != psForEncrypted->encrypt(plaintext, pt_len, &ciphertext, &ct_len)) + { + OIC_LOG(ERROR, TAG, "psForEncrypted->encrypt() Failed"); + OICFree(plaintext); + return OC_STACK_ERROR; + } + OICFree(plaintext); + + // Write Ciphertext + FILE *fp2 = psForEncrypted->open(SVR_DB_DAT_FILE_NAME, "wb"); + if (NULL == fp2) + { + OIC_LOG(ERROR, TAG, "psForEncrypted->open() Failed"); + OICFree(ciphertext); + return OC_STACK_ERROR; + } + + if (ct_len != psForEncrypted->write(ciphertext, 1, ct_len, fp2)) + { + OIC_LOG(ERROR, TAG, "psForEncrypted->write() Failed"); + OICFree(ciphertext); + return OC_STACK_ERROR; + } + psForEncrypted->close(fp2); + + // Remove plain DB + if (psForPlain->unlink) + { + psForPlain->unlink(SVR_DB_DAT_FILE_NAME); + } + + OICFree(ciphertext); + OIC_LOG_V(DEBUG, TAG, "Out %s", __func__); + + return OC_STACK_OK; +} + +OCStackResult setSecurePSI(const unsigned char *key, const OCPersistentStorage *psPlain, + const OCPersistentStorage *psEnc, const OCPersistentStorage *psRescue) +{ + OIC_LOG_V(DEBUG, TAG, "In %s", __func__); + + if (!key || !psEnc) + { + OIC_LOG_V(ERROR, TAG, "%s: %s is NULL", __func__, !key ? "key" : "psEnc"); + return OC_STACK_INVALID_PARAM; + } + if (!(psEnc->encrypt && psEnc->decrypt)) + { + OIC_LOG(ERROR, TAG, "psEnc->encrypt && psEnc->decrypt should be set"); + return OC_STACK_INVALID_PARAM; + } + if (psPlain && !(psPlain->open && psPlain->read && psPlain->close + && psPlain->unlink)) + { + OIC_LOG(ERROR, TAG, "open/read/close/unlink funcion for plain should be set"); + return OC_STACK_INVALID_PARAM; + } + if (psRescue && !(psRescue->open && psRescue->read && psRescue->close)) + { + OIC_LOG(ERROR, TAG, "open/read/close funcion for rescue should be set"); + return OC_STACK_INVALID_PARAM; + } + + OCStackResult ret; + ret = psiSetKey(key); + if (OC_STACK_OK != ret) + { + OIC_LOG(ERROR, TAG, "psiSetKey() Failed"); + return ret; + } + OIC_LOG(DEBUG, TAG, "key is set"); + + // if there is new plain db + FILE *fp = NULL; + if (psPlain && (fp = psPlain->open(SVR_DB_DAT_FILE_NAME, "rb"))) + { + psPlain->close(fp); + fp = NULL; + + ret = OTEncrypt(psPlain, psEnc); + if (OC_STACK_OK != ret) + { + OIC_LOG(ERROR, TAG, "OTEncrypt() Failed"); + return ret; + } + } + + // check ps & rescue + if (psRescue) + { + ret = CheckPersistentStorage((OCPersistentStorage*)psEnc); + if (OC_STACK_OK != ret) + { + fp = psRescue->open(SVR_DB_DAT_FILE_NAME, "rb"); + if (NULL == fp) + { + OIC_LOG(ERROR, TAG, "psRescue->open() Failed"); + return OC_STACK_ERROR; + } + psRescue->close(fp); + fp = NULL; + + ret = OTEncrypt(psRescue, psEnc); + if (OC_STACK_OK != ret) + { + OIC_LOG_V(ERROR, TAG, "ps is currupted but NOT rescued(%d)", ret); + return ret; + } + OIC_LOG(INFO, TAG, "ps is currupted and rescued"); + } + } + + OIC_LOG_V(DEBUG, TAG, "Out %s", __func__); + + return OC_STACK_OK; + +} +#endif // __SECURE_PSI__ + +/** + * Write the Persistent Storage + * + * @param payload - pointer of payload + * @param psize - size of payload + * + * @return OCStackResult - OC_STACK_OK sucsess, other - OC_STACK_ERROR + */ +OCStackResult WritePSIDatabase(const uint8_t *payload, size_t size) +{ + OIC_LOG_V(DEBUG, TAG, "In %s", __func__); + + if (!payload || !size || !g_mutexDb) + { + OIC_LOG_V(ERROR, TAG, "%s: %s is NULL", + __func__, !payload ? "payload" : !size ? "size" : "mutex"); + OIC_LOG_V(DEBUG, TAG, "Out %s", __func__); + return OC_STACK_INVALID_PARAM; + } + + OCPersistentStorage *ps = NULL; + FILE *fp = NULL; + OCStackResult ret = OC_STACK_SVR_DB_NOT_EXIST; + + ps = SRMGetPersistentStorageHandler(); + VERIFY_NON_NULL(TAG, ps, ERROR); + +#ifdef __SECURE_PSI__ + if (psiIsKeySet() && ps->encrypt && ps->decrypt) + { + OIC_LOG(DEBUG, TAG, "ps->encrypt !"); + + uint8_t *ciphertext = NULL; + size_t ct_len = 0; + + if (0 != ps->encrypt(payload, size, &ciphertext, &ct_len)) + { + OIC_LOG(ERROR, TAG, "ps->encrypt() Failed"); + ret = OC_STACK_ERROR; + goto exit; + } + + payload = ciphertext; + size = ct_len; + } +#endif // __SECURE_PSI__ + + OIC_LOG_V(INFO, TAG, "Writing in the file: %zu", size); + + fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb"); + VERIFY_NON_NULL(TAG, fp, ERROR); + + oc_mutex_lock(g_mutexDb); + g_svrDbFileSize = ps->write(payload, 1, size, fp); + ps->close(fp); + oc_mutex_unlock(g_mutexDb); + +#ifdef __SECURE_PSI__ + if (psiIsKeySet() && ps->encrypt && ps->decrypt) + { + OICFree((uint8_t*)payload); + } +#endif // __SECURE_PSI__ + if (size == g_svrDbFileSize) + { + OIC_LOG_V(INFO, TAG, "Written %zu bytes into SVR database file", size); + ret = OC_STACK_OK; + } + else + { + OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", g_svrDbFileSize); + } + +exit: + OIC_LOG_V(DEBUG, TAG, "Out %s", __func__); + return ret; +} + +/** + * Gets the Secure Virtual Database from the Persistent Storage + * + * @param ps - Persistent Storage handler + * @param rsrcName - pointer of character string for the SVR name (e.g. "acl") + * @param data - pointer of the returned Secure Virtual Resource(s) + * @param size - pointer of the returned size of Secure Virtual Resource(s) + * + * @return OCStackResult - result of getting Secure Virtual Resource(s) + */ +OCStackResult GetSecureVirtualDatabaseFromPS2(OCPersistentStorage* ps, const char *rsrcName, uint8_t **data, size_t *size) +{ + OIC_LOG_V(DEBUG, TAG, "In %s", __func__); + + if (!data || *data || !size || !ps) + { + OIC_LOG_V(ERROR, TAG, "%s: %s is NULL", + __func__, !data || *data ? "data" : !size ? "size" : "ps"); + OIC_LOG_V(DEBUG, TAG, "Out %s", __func__); + return OC_STACK_INVALID_PARAM; + } + + FILE *fp = NULL; + uint8_t *fsData = NULL; + size_t fileSize = 0; + OCStackResult ret = OC_STACK_ERROR; + + fileSize = GetPSIDatabaseSizeWithoutCaching(ps); + OIC_LOG_V(INFO, TAG, "File Read Size: %zu", fileSize); + if (fileSize) + { + fsData = (uint8_t *) OICCalloc(1, fileSize + 1); + VERIFY_NON_NULL(TAG, fsData, ERROR); + + fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb"); + VERIFY_NON_NULL(TAG, fp, ERROR); + if (ps->read(fsData, 1, fileSize, fp) == fileSize) + { +#ifdef __SECURE_PSI__ + if (psiIsKeySet() && ps->encrypt && ps->decrypt) + { + OIC_LOG(DEBUG, TAG, "ps->decrypt !"); + + unsigned char *plainData = NULL; + size_t plainSize = 0; + + if (0 != ps->decrypt(fsData, fileSize, &plainData, &plainSize)) + { + OIC_LOG(ERROR, TAG, "ps->decrypt() Failed"); + ret = OC_STACK_ERROR; + goto exit; + } + OICFree(fsData); + fsData = plainData; + fileSize = plainSize; + } +#endif // __SECURE_PSI__ + if (rsrcName) + { + CborParser parser; // will be initialized in |cbor_parser_init| + CborValue cbor; // will be initialized in |cbor_parser_init| + cbor_parser_init(fsData, fileSize, 0, &parser, &cbor); + CborValue cborValue = {0}; + CborError cborFindResult = cbor_value_map_find_value(&cbor, rsrcName, &cborValue); + if (CborNoError == cborFindResult && cbor_value_is_byte_string(&cborValue)) + { + cborFindResult = cbor_value_dup_byte_string(&cborValue, data, size, NULL); + VERIFY_SUCCESS(TAG, CborNoError==cborFindResult, ERROR); + ret = OC_STACK_OK; + } + // in case of |else (...)|, svr_data not found + } + // return everything in case rsrcName is NULL + else + { + *size = fileSize; + *data = (uint8_t *) OICCalloc(1, fileSize); + VERIFY_NON_NULL(TAG, *data, ERROR); + memcpy(*data, fsData, fileSize); + ret = OC_STACK_OK; + } + } + } + OIC_LOG_V(DEBUG, TAG, "Out %s", __func__); + +exit: + if (fp) + { + ps->close(fp); + } + OICFree(fsData); + return ret; +} + /** * Gets the Secure Virtual Database from the Persistent Storage * @@ -89,9 +560,16 @@ static size_t GetSVRDatabaseSize(const OCPersistentStorage *ps) */ OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **data, size_t *size) { - OIC_LOG(DEBUG, TAG, "GetSecureVirtualDatabaseFromPS IN"); - if (!data || *data || !size) + OIC_LOG_V(DEBUG, TAG, "In %s", __func__); + + // Logs for Persistent Storage status + PrintPSStatus(); + + if (!data || *data || !size || !g_mutexDb) { + OIC_LOG_V(ERROR, TAG, "%s: %s is NULL", + __func__, !data || *data ? "data" : !size ? "size" : "mutex"); + OIC_LOG_V(DEBUG, TAG, "Out %s", __func__); return OC_STACK_INVALID_PARAM; } @@ -103,8 +581,8 @@ OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **dat OCPersistentStorage *ps = SRMGetPersistentStorageHandler(); VERIFY_NON_NULL(TAG, ps, ERROR); - fileSize = GetSVRDatabaseSize(ps); - OIC_LOG_V(DEBUG, TAG, "File Read Size: %zu", fileSize); + fileSize = GetPSIDatabaseSize(ps); + OIC_LOG_V(INFO, TAG, "File Read Size: %zu", fileSize); if (fileSize) { fsData = (uint8_t *) OICCalloc(1, fileSize); @@ -114,6 +592,25 @@ OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **dat VERIFY_NON_NULL(TAG, fp, ERROR); if (ps->read(fsData, 1, fileSize, fp) == fileSize) { +#ifdef __SECURE_PSI__ + if (psiIsKeySet() && ps->encrypt && ps->decrypt) + { + OIC_LOG(DEBUG, TAG, "ps->decrypt !"); + + unsigned char *plainData = NULL; + size_t plainSize = 0; + + if (0 != ps->decrypt(fsData, fileSize, &plainData, &plainSize)) + { + OIC_LOG(ERROR, TAG, "ps->decrypt() Failed"); + ret = OC_STACK_ERROR; + goto exit; + } + OICFree(fsData); + fsData = plainData; + fileSize = plainSize; + } +#endif // __SECURE_PSI__ if (rsrcName) { CborParser parser; // will be initialized in |cbor_parser_init| @@ -140,7 +637,7 @@ OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **dat } } } - OIC_LOG(DEBUG, TAG, "GetSecureVirtualDatabaseFromPS OUT"); + OIC_LOG_V(DEBUG, TAG, "Out %s", __func__); exit: if (fp) @@ -164,7 +661,8 @@ exit: */ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPayload, size_t psSize) { - OIC_LOG(DEBUG, TAG, "UpdateSecureResourceInPS IN"); + OIC_LOG_V(DEBUG, TAG, "In %s", __func__); + if (!rsrcName) { return OC_STACK_INVALID_PARAM; @@ -179,23 +677,29 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa uint8_t *pstatCbor = NULL; uint8_t *doxmCbor = NULL; uint8_t *amaclCbor = NULL; - uint8_t *svcCbor = NULL; uint8_t *credCbor = NULL; uint8_t *pconfCbor = NULL; uint8_t *resetPfCbor = NULL; + uint8_t *crlCbor = NULL; int64_t cborEncoderResult = CborNoError; OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize); + if (OC_STACK_OK != ret) + { + OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ret); + } if (dbData && dbSize) { size_t aclCborLen = 0; size_t pstatCborLen = 0; size_t doxmCborLen = 0; size_t amaclCborLen = 0; - size_t svcCborLen = 0; size_t credCborLen = 0; size_t pconfCborLen = 0; size_t resetPfCborLen = 0; + size_t crlCborLen = 0; + + ret = OC_STACK_ERROR; // Gets each secure virtual resource from persistent storage // this local scoping intended, for destroying large cbor instances after use @@ -230,12 +734,7 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa cborFindResult = cbor_value_dup_byte_string(&curVal, &amaclCbor, &amaclCborLen, NULL); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding AMACL Name Value."); } - cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_SVC_NAME, &curVal); - if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal)) - { - cborFindResult = cbor_value_dup_byte_string(&curVal, &svcCbor, &svcCborLen, NULL); - VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SVC Name Value."); - } + cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal); if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal)) { @@ -254,13 +753,26 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value."); } + int64_t cborFindCrlResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRL_NAME, &curVal); + if (CborNoError == cborFindCrlResult && cbor_value_is_byte_string(&curVal)) + { + cborFindCrlResult = cbor_value_dup_byte_string(&curVal, &crlCbor, &crlCborLen, NULL); + if (CborNoError != cborFindCrlResult && CborErrorOutOfMemory != cborFindCrlResult) + { + OIC_LOG(ERROR, TAG, "Failed Finding optional CRL Name Value."); + } + else + { + OIC_LOG(INFO, TAG, "Successfully Finding optional CRL Name Value."); + } + } } // Updates the added |psPayload| with the existing secure virtual resource(s) // this local scoping intended, for destroying large cbor instances after use { size_t size = aclCborLen + pstatCborLen + doxmCborLen + amaclCborLen - + svcCborLen + credCborLen + pconfCborLen + resetPfCborLen + + credCborLen + pconfCborLen + resetPfCborLen + crlCborLen + psSize + 255; // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending @@ -307,13 +819,6 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa cborEncoderResult |= cbor_encode_byte_string(&secRsrc, amaclCbor, amaclCborLen); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Value."); } - if (strcmp(OIC_JSON_SVC_NAME, rsrcName) && svcCborLen) - { - cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_SVC_NAME, strlen(OIC_JSON_SVC_NAME)); - VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Name."); - cborEncoderResult |= cbor_encode_byte_string(&secRsrc, svcCbor, svcCborLen); - VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Value."); - } if (strcmp(OIC_JSON_CRED_NAME, rsrcName) && credCborLen) { cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME)); @@ -335,10 +840,17 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa cborEncoderResult |= cbor_encode_byte_string(&secRsrc, resetPfCbor, resetPfCborLen); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Value."); } + if (strcmp(OIC_JSON_CRL_NAME, rsrcName) && crlCborLen) + { + cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRL_NAME, strlen(OIC_JSON_CRL_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Crl Name."); + cborEncoderResult |= cbor_encode_byte_string(&secRsrc, crlCbor, crlCborLen); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Crl Value."); + } cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array."); - outSize = encoder.ptr - outPayload; + outSize = cbor_encoder_get_buffer_size(&encoder, outPayload); } } else if (psPayload && psSize) @@ -361,38 +873,15 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array."); - outSize = encoder.ptr - outPayload; + outSize = cbor_encoder_get_buffer_size(&encoder, outPayload); } - if (outPayload && outSize) + ret = WritePSIDatabase(outPayload, outSize); + if (OC_STACK_OK != ret) { - OIC_LOG_V(DEBUG, TAG, "Writing in the file: %zu", outSize); - OCPersistentStorage* ps = SRMGetPersistentStorageHandler(); - if (ps) - { - FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb"); - if (fp) - { - size_t numberItems = ps->write(outPayload, 1, outSize, fp); - if (outSize == numberItems) - { - OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", outSize); - ret = OC_STACK_OK; - } - else - { - OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", numberItems); - } - ps->close(fp); - } - else - { - OIC_LOG(ERROR, TAG, "File open failed."); - } - } + OIC_LOG_V(ERROR, TAG, "WritePSIDatabase() is failed(%d)", ret); } - - OIC_LOG(DEBUG, TAG, "UpdateSecureResourceInPS OUT"); + OIC_LOG_V(DEBUG, TAG, "Out %s", __func__); exit: OICFree(dbData); @@ -401,10 +890,10 @@ exit: OICFree(pstatCbor); OICFree(doxmCbor); OICFree(amaclCbor); - OICFree(svcCbor); OICFree(credCbor); OICFree(pconfCbor); OICFree(resetPfCbor); + OICFree(crlCbor); return ret; } @@ -417,7 +906,7 @@ exit: */ OCStackResult ResetSecureResourceInPS(void) { - OIC_LOG(DEBUG, TAG, "ResetSecureResourceInPS IN"); + OIC_LOG_V(DEBUG, TAG, "In %s", __func__); size_t dbSize = 0; size_t outSize = 0; @@ -425,20 +914,27 @@ OCStackResult ResetSecureResourceInPS(void) uint8_t *outPayload = NULL; uint8_t *aclCbor = NULL; + uint8_t *credCbor = NULL; uint8_t *pstatCbor = NULL; uint8_t *doxmCbor = NULL; uint8_t *resetPfCbor = NULL; int64_t cborEncoderResult = CborNoError; OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize); - + if (OC_STACK_OK != ret) + { + OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ret); + } if(dbData && dbSize) { size_t aclCborLen = 0; + size_t credCborLen = 0; size_t pstatCborLen = 0; size_t doxmCborLen = 0; size_t resetPfCborLen = 0; + ret = OC_STACK_ERROR; + // Gets the reset profile from persistent storage { CborParser parser; // will be initialized in |cbor_parser_init| @@ -452,6 +948,17 @@ OCStackResult ResetSecureResourceInPS(void) cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value."); } + else if (CborNoError == cborFindResult && CborInvalidType == curVal.type) + { + OIC_LOG(ERROR, TAG, "resetpf is not found"); + goto exit; + } + else + { + OIC_LOG_V(ERROR, TAG, "cbor_value_map_find_value() Failed(%d)", + cborFindResult); + goto exit; + } } // Gets each secure virtual resource from the reset profile @@ -467,6 +974,12 @@ OCStackResult ResetSecureResourceInPS(void) cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value."); } + cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal); + if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal)) + { + cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value."); + } cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal); if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal)) { @@ -482,7 +995,7 @@ OCStackResult ResetSecureResourceInPS(void) } { - size_t size = aclCborLen + pstatCborLen + doxmCborLen + resetPfCborLen + 255; + size_t size = aclCborLen + credCborLen + pstatCborLen + doxmCborLen + resetPfCborLen + 255; // This added '255' is arbitrary value added to cover the name of the resource, map addition, and ending outPayload = (uint8_t *) OICCalloc(1, size); @@ -497,6 +1010,14 @@ OCStackResult ResetSecureResourceInPS(void) cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value."); + if (credCborLen) + { + cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Name."); + cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Value."); + } + cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME)); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name."); cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen); @@ -514,68 +1035,48 @@ OCStackResult ResetSecureResourceInPS(void) cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array."); - outSize = encoder.ptr - outPayload; + outSize = cbor_encoder_get_buffer_size(&encoder, outPayload); } - if (outPayload && outSize) + ret = WritePSIDatabase(outPayload, outSize); + if (OC_STACK_OK != ret) { - OIC_LOG_V(DEBUG, TAG, "Writing in the file: %zu", outSize); - OCPersistentStorage *ps = SRMGetPersistentStorageHandler(); - if (ps) - { - FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb"); - if (fp) - { - size_t numberItems = ps->write(outPayload, 1, outSize, fp); - if (outSize == numberItems) - { - OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", outSize); - ret= OC_STACK_OK; - } - else - { - OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", numberItems); - } - ps->close(fp); - } - else - { - OIC_LOG(ERROR, TAG, "File open failed."); - } - - } + OIC_LOG_V(ERROR, TAG, "WritePSIDatabase() is failed(%d)", ret); } } SRMDeInitSecureResources(); InitSecureResources(); - OIC_LOG(DEBUG, TAG, "ResetSecureResourceINPS OUT"); + OIC_LOG_V(DEBUG, TAG, "Out %s", __func__); exit: OICFree(dbData); OICFree(outPayload); OICFree(aclCbor); + OICFree(credCbor); OICFree(pstatCbor); OICFree(doxmCbor); OICFree(resetPfCbor); + return ret; } /** * Creates Reset Profile from the initial secure virtual resources. * This function copies the secure resources * and creates the Reset Profile in the Persistent Storage. - * Device ID in doxm and pstat are left empty as it will be renewed after reset. + * Device ID in doxm and pstat remains as same after reset. * * @return OCStackResult - result of updating Secure Virtual Resource(s) */ OCStackResult CreateResetProfile(void) { - OIC_LOG(DEBUG, TAG, "CreateResetProfile IN"); + OIC_LOG_V(DEBUG, TAG, "In %s", __func__); size_t dbSize = 0; uint8_t *dbData = NULL; uint8_t *aclCbor = NULL; + uint8_t *credCbor = NULL; uint8_t *pstatCbor = NULL; uint8_t *doxmCbor = NULL; uint8_t *resetPfCbor = NULL; @@ -583,25 +1084,47 @@ OCStackResult CreateResetProfile(void) OCStackResult ret = OC_STACK_ERROR; int64_t cborEncoderResult = CborNoError; ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize); + if (OC_STACK_OK != ret) + { + OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ret); + } if (dbData && dbSize) { size_t aclCborLen = 0; + size_t credCborLen = 0; size_t pstatCborLen = 0; size_t doxmCborLen = 0; size_t resetPfCborLen = 0; + ret = OC_STACK_ERROR; { CborParser parser; CborValue cbor; cbor_parser_init(dbData, dbSize, 0, &parser, &cbor); CborValue curVal = {0}; CborError cborFindResult = CborNoError; + + // abort if reset profile exists + cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal); + if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal)) + { + OIC_LOG(DEBUG, TAG, "Reset Profile already exists!!"); + OICFree(dbData); + return OC_STACK_OK; + } + cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal); if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal)) { cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value."); } + cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal); + if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal)) + { + cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value."); + } cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal); if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal)) { @@ -616,40 +1139,8 @@ OCStackResult CreateResetProfile(void) } } - // Set the Device ID in doxm and pstat to empty - if (pstatCbor) { - OicSecPstat_t *pstat = NULL; - ret = CBORPayloadToPstat(pstatCbor, pstatCborLen, &pstat); - OICFree(pstatCbor); - pstatCbor = NULL; - pstatCborLen = 0; - - OicUuid_t emptyUuid = {.id = {0} }; - memcpy(&pstat->deviceID, &emptyUuid, sizeof(OicUuid_t)); - memcpy(&pstat->rownerID, &emptyUuid, sizeof(OicUuid_t)); - - ret = PstatToCBORPayload(pstat, &pstatCbor, &pstatCborLen, false); - OICFree(pstat); - } - if (doxmCbor) - { - OicSecDoxm_t *doxm = NULL; - ret = CBORPayloadToDoxm(doxmCbor, doxmCborLen, &doxm); - OICFree(doxmCbor); - doxmCbor = NULL; - doxmCborLen = 0; - - OicUuid_t emptyUuid = {.id = {0} }; - memcpy(&doxm->deviceID, &emptyUuid, sizeof(OicUuid_t)); - memcpy(&doxm->rownerID, &emptyUuid, sizeof(OicUuid_t)); - - ret = DoxmToCBORPayload(doxm, &doxmCbor, &doxmCborLen, false); - OICFree(doxm); - } - - { - size_t size = aclCborLen + pstatCborLen + doxmCborLen + 255; + size_t size = aclCborLen + credCborLen + pstatCborLen + doxmCborLen + 255; resetPfCbor = (uint8_t *) OICCalloc(1, size); VERIFY_NON_NULL(TAG, resetPfCbor, ERROR); CborEncoder encoder; // will be initialized in |cbor_parser_init| @@ -662,6 +1153,14 @@ OCStackResult CreateResetProfile(void) cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value."); + if (credCborLen) + { + cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Name."); + cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Value."); + } + cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME)); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name."); cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen); @@ -674,19 +1173,48 @@ OCStackResult CreateResetProfile(void) cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array."); - resetPfCborLen = encoder.ptr - resetPfCbor; + resetPfCborLen = cbor_encoder_get_buffer_size(&encoder, resetPfCbor); } - UpdateSecureResourceInPS(OIC_JSON_RESET_PF_NAME, resetPfCbor, resetPfCborLen); + ret = UpdateSecureResourceInPS(OIC_JSON_RESET_PF_NAME, resetPfCbor, resetPfCborLen); + if (OC_STACK_OK != ret) + { + OIC_LOG(ERROR, TAG, "Error in UpdateSecureResourceInPS"); + } } - OIC_LOG(DEBUG, TAG, "CreateResetProfile OUT"); + OIC_LOG_V(DEBUG, TAG, "Out %s", __func__); exit: OICFree(dbData); OICFree(aclCbor); + OICFree(credCbor); OICFree(pstatCbor); OICFree(doxmCbor); OICFree(resetPfCbor); return ret; } + +void SetPSStatus(PSStatus_t status) +{ + g_psStatus = status; +} + +void PrintPSStatus(void) +{ + switch(g_psStatus) + { + case PS_NORMAL: + OIC_LOG(INFO, TAG, "PS Status: Normal - using external DB"); + break; + case PS_OPEN_FAIL: + OIC_LOG(INFO, TAG, "PS Status: Failed to open external DB! - using default DB"); + break; + case PS_PARSE_FAIL: + OIC_LOG(INFO, TAG, "PS Status: Failed to CBOR parse external DB! - using default DB"); + break; + default: + OIC_LOG(INFO, TAG, "PS Status: No external DB set - using internal memory"); + + } +}