X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fsecurity%2Fsrc%2Fcredresource.c;h=f73e4d64e48075c8e9c467d4a9802ee86199c34b;hb=a4b7de0a5bc42ef0428d3c6a544d5047fb952b1b;hp=68f0eb0a2b4781224b243db74b768ab63713b4de;hpb=45c364268c4f5d575d98f4cd88b571b536c6cb17;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/security/src/credresource.c b/resource/csdk/security/src/credresource.c index 68f0eb0..f73e4d6 100644 --- a/resource/csdk/security/src/credresource.c +++ b/resource/csdk/security/src/credresource.c @@ -19,23 +19,8 @@ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #define __STDC_LIMIT_MACROS -#include "ocstack.h" -#include "logger.h" -#include "oic_malloc.h" -#include "cJSON.h" -#include "resourcemanager.h" -#include "psinterface.h" -#include "utlist.h" -#include "srmresourcestrings.h" -#include "credresource.h" -#include "ocrandom.h" -#include "doxmresource.h" -#include "base64.h" -#include "srmutility.h" -#include "cainterface.h" -#include "pbkdf2.h" + #include -#include "iotvticalendar.h" #ifdef WITH_ARDUINO #include #else @@ -43,8 +28,43 @@ #endif #include +#include "cainterface.h" +#include "payload_logging.h" +#include "ocstack.h" +#include "ocrandom.h" +#include "base64.h" +#include "ocserverrequest.h" +#include "oic_malloc.h" +#include "ocpayload.h" +#include "utlist.h" +#include "credresource.h" +#include "doxmresource.h" +#include "pstatresource.h" +#include "iotvticalendar.h" +#include "pbkdf2.h" +#include "resourcemanager.h" +#include "srmresourcestrings.h" +#include "srmutility.h" +#include "psinterface.h" +#include "pinoxmcommon.h" + +#ifdef __WITH_DTLS__ +#include "global.h" +#endif + #define TAG "SRM-CREDL" +/** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory. + * The value of payload size is increased until reaching belox max cbor size. */ +static const uint16_t CBOR_SIZE = 2048; + +/** Max cbor size payload. */ +static const uint16_t CBOR_MAX_SIZE = 4400; + +/** CRED size - Number of mandatory items. */ +static const uint8_t CRED_ROOT_MAP_SIZE = 2; +static const uint8_t CRED_MAP_SIZE = 3; + static OicSecCred_t *gCred = NULL; static OCResourceHandle gCredHandle = NULL; @@ -56,7 +76,7 @@ static void FreeCred(OicSecCred_t *cred) { if(NULL == cred) { - OIC_LOG (ERROR, TAG, "Invalid Parameter"); + OIC_LOG(ERROR, TAG, "Invalid Parameter"); return; } //Note: Need further clarification on roleID data type @@ -66,7 +86,9 @@ static void FreeCred(OicSecCred_t *cred) #endif //Clean PublicData +#ifdef __WITH_X509__ OICFree(cred->publicData.data); +#endif //Clean PrivateData OICFree(cred->privateData.data); @@ -74,9 +96,6 @@ static void FreeCred(OicSecCred_t *cred) //Clean Period OICFree(cred->period); - //Clean Owners - OICFree(cred->owners); - //Clean Cred node itself OICFree(cred); } @@ -94,341 +113,498 @@ void DeleteCredList(OicSecCred_t* cred) } } -/** - * This function converts credential data into JSON format. - * Caller needs to invoke 'free' when done using - * returned string. - * @param cred pointer to instance of OicSecCred_t structure. - * - * @retval - * pointer to JSON credential representation - if credential for subjectId found - * NULL - if credential for subjectId not found - */ -char * BinToCredJSON(const OicSecCred_t * cred) +static size_t OicSecCredCount(const OicSecCred_t *secCred) { - cJSON *jsonRoot = NULL; - char *jsonStr = NULL; + size_t size = 0; + for (const OicSecCred_t *cred = secCred; cred; cred = cred->next) + { + size++; + } + return size; +} - if (cred) +OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload, + size_t *cborSize, int secureFlag) +{ + if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize) { - char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {}; - uint32_t outLen = 0; - B64Result b64Ret = B64_OK; + return OC_STACK_INVALID_PARAM; + } - jsonRoot = cJSON_CreateObject(); - VERIFY_NON_NULL(TAG, jsonRoot, ERROR); + OCStackResult ret = OC_STACK_ERROR; - cJSON *jsonCredArray = NULL; - cJSON_AddItemToObject(jsonRoot, OIC_JSON_CRED_NAME, - jsonCredArray = cJSON_CreateArray()); - VERIFY_NON_NULL(TAG, jsonCredArray, ERROR); + CborError cborEncoderResult = CborNoError; + uint8_t *outPayload = NULL; + size_t cborLen = *cborSize; + *cborSize = 0; + *cborPayload = NULL; + const OicSecCred_t *cred = credS; + CborEncoder encoder; + CborEncoder credArray; + CborEncoder credRootMap; + + if (0 == cborLen) + { + cborLen = CBOR_SIZE; + } - while(cred) - { - cJSON *jsonCred = cJSON_CreateObject(); - VERIFY_NON_NULL(TAG, jsonCred, ERROR); + outPayload = (uint8_t *)OICCalloc(1, cborLen); + VERIFY_NON_NULL(TAG, outPayload, ERROR); + cbor_encoder_init(&encoder, outPayload, cborLen, 0); - //CredID -- Mandatory - cJSON_AddNumberToObject(jsonCred, OIC_JSON_CREDID_NAME, (int)cred->credId); + // Create CRED Root Map (creds, rownerid) + cborEncoderResult = cbor_encoder_create_map(&encoder, &credRootMap, CRED_ROOT_MAP_SIZE); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Root Map"); - //Subject -- Mandatory - outLen = 0; - memset(base64Buff, 0, sizeof(base64Buff)); - b64Ret = b64Encode(cred->subject.id, sizeof(cred->subject.id), base64Buff, - sizeof(base64Buff), &outLen); - VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR); - cJSON_AddStringToObject(jsonCred, OIC_JSON_SUBJECT_NAME, base64Buff); + // creds + cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_CREDS_NAME, + strlen(OIC_JSON_CREDS_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding creds Name Tag."); - //Note: Need further clarification on roleID data type -#if 0 - //RoleId -- Not Mandatory - if(cred->roleIdsLen > 0) - { - cJSON *jsonRoleIdsArray = NULL; - cJSON_AddItemToObject (jsonCred, OIC_JSON_ROLEIDS_NAME, - jsonRoleIdsArray = cJSON_CreateArray()); - VERIFY_NON_NULL(TAG, jsonRoleIdsArray, ERROR); - for (size_t i = 0; i < cred->roleIdsLen; i++) - { - cJSON_AddItemToArray (jsonRoleIdsArray, - cJSON_CreateString((char *)cred->roleIds[i].id)); - } - } -#endif + // creds array + cborEncoderResult = cbor_encoder_create_array(&credRootMap, &credArray, OicSecCredCount(cred)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Array."); - //CredType -- Mandatory - cJSON_AddNumberToObject(jsonCred, OIC_JSON_CREDTYPE_NAME,(int)cred->credType); + while (cred) + { + CborEncoder credMap; + size_t mapSize = CRED_MAP_SIZE; + char *subject = NULL; + if (cred->period) + { + mapSize++; + } +#ifdef __WITH_X509__ + if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data) + { + mapSize++; + } +#endif /* __WITH_X509__ */ + if (!secureFlag && cred->privateData.data) + { + mapSize++; + } + cborEncoderResult = cbor_encoder_create_map(&credArray, &credMap, mapSize); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Map"); + + //CredID -- Mandatory + cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME, + strlen(OIC_JSON_CREDID_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. "); + cborEncoderResult = cbor_encode_int(&credMap, cred->credId); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Value."); + + //Subject -- Mandatory + cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME, + strlen(OIC_JSON_SUBJECTID_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag."); + ret = ConvertUuidToStr(&cred->subject, &subject); + VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR); + cborEncoderResult = cbor_encode_text_string(&credMap, subject, strlen(subject)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id Value."); + OICFree(subject); + + //CredType -- Mandatory + cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME, + strlen(OIC_JSON_CREDTYPE_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag."); + cborEncoderResult = cbor_encode_int(&credMap, cred->credType); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value."); #ifdef __WITH_X509__ - //PublicData -- Not Mandatory - if(cred->publicData.data) - { - if (SIGNED_ASYMMETRIC_KEY == cred->credType) - { - cJSON_AddItemToObject(jsonCred, OIC_JSON_PUBLICDATA_NAME, - cJSON_Parse(cred->publicData.data)); - } - else - { - cJSON_AddStringToObject(jsonCred, OIC_JSON_PUBLICDATA_NAME, cred->publicData.data); - } - } + //PublicData -- Not Mandatory + if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data) + { + CborEncoder publicMap; + const size_t publicMapSize = 2; + + cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PUBLICDATA_NAME, + strlen(OIC_JSON_PUBLICDATA_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Tag."); + + cborEncoderResult = cbor_encoder_create_map(&credMap, &publicMap, publicMapSize); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Map"); + + cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_DATA_NAME, + strlen(OIC_JSON_DATA_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Data Tag."); + cborEncoderResult = cbor_encode_byte_string(&publicMap, cred->publicData.data, + cred->publicData.len); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Value."); + + // TODO: Need to data strucure modification for OicSecCert_t. + cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_ENCODING_NAME, + strlen(OIC_JSON_ENCODING_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Tag."); + cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_SEC_ENCODING_RAW, + strlen(OIC_SEC_ENCODING_RAW)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Value."); + + cborEncoderResult = cbor_encoder_close_container(&credMap, &publicMap); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PublicData Map."); + } #endif /*__WITH_X509__*/ - //PrivateData -- Not Mandatory - if(cred->privateData.data) - { -#ifdef __WITH_X509__ - if (SIGNED_ASYMMETRIC_KEY == cred->credType) - { - cJSON_AddItemToObject(jsonCred, OIC_JSON_PRIVATEDATA_NAME, - cJSON_Parse(cred->privateData.data)); - } - else - { - cJSON_AddStringToObject(jsonCred, OIC_JSON_PRIVATEDATA_NAME, cred->privateData.data); - } -#else - cJSON_AddStringToObject(jsonCred, OIC_JSON_PRIVATEDATA_NAME, cred->privateData.data); -#endif - } + //PrivateData -- Not Mandatory + if(!secureFlag && cred->privateData.data) + { + CborEncoder privateMap; + const size_t privateMapSize = 2; + + cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PRIVATEDATA_NAME, + strlen(OIC_JSON_PRIVATEDATA_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag."); + + cborEncoderResult = cbor_encoder_create_map(&credMap, &privateMap, privateMapSize); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Map"); + + cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME, + strlen(OIC_JSON_DATA_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag."); + cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data, + cred->privateData.len); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value."); + + // TODO: Need to data strucure modification for OicSecKey_t. + cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME, + strlen(OIC_JSON_ENCODING_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag."); + cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_RAW, + strlen(OIC_SEC_ENCODING_RAW)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value."); + + cborEncoderResult = cbor_encoder_close_container(&credMap, &privateMap); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PrivateData Map."); + } - //Period -- Not Mandatory - if(cred->period) - { - cJSON_AddStringToObject(jsonCred, OIC_JSON_PERIOD_NAME, - cred->period); - } + //Period -- Not Mandatory + if(cred->period) + { + cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME, + strlen(OIC_JSON_PERIOD_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Tag."); + cborEncoderResult = cbor_encode_text_string(&credMap, cred->period, + strlen(cred->period)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value."); + } - //Owners -- Mandatory - cJSON *jsonOwnrArray = NULL; - cJSON_AddItemToObject (jsonCred, OIC_JSON_OWNERS_NAME, - jsonOwnrArray = cJSON_CreateArray()); - VERIFY_NON_NULL(TAG, jsonOwnrArray, ERROR); - for (size_t i = 0; i < cred->ownersLen; i++) - { - outLen = 0; - memset(base64Buff, 0, sizeof(base64Buff)); - b64Ret = b64Encode(cred->owners[i].id, sizeof(cred->owners[i].id), - base64Buff, sizeof(base64Buff), &outLen); - VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR); - cJSON_AddItemToArray (jsonOwnrArray, - cJSON_CreateString((char *)(base64Buff))); - } - /* Attach current cred node to cred Array */ - cJSON_AddItemToArray(jsonCredArray, jsonCred); - cred = cred->next; - } + cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Map."); - jsonStr = cJSON_PrintUnformatted(jsonRoot); + cred = cred->next; } + cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array."); -exit: - if (jsonRoot) + cred = credS; + + // Rownerid { - cJSON_Delete(jsonRoot); + char *rowner = NULL; + cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_ROWNERID_NAME, + strlen(OIC_JSON_ROWNERID_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name."); + ret = ConvertUuidToStr(&cred->rownerID, &rowner); + VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR); + cborEncoderResult = cbor_encode_text_string(&credRootMap, rowner, strlen(rowner)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value."); + OICFree(rowner); } - return jsonStr; -} -/* - * This internal method converts JSON cred into binary cred. - */ -OicSecCred_t * JSONToCredBin(const char * jsonStr) -{ - OCStackResult ret = OC_STACK_ERROR; - OicSecCred_t * headCred = NULL; - OicSecCred_t * prevCred = NULL; - cJSON *jsonCredArray = NULL; + // Close CRED Root Map + cborEncoderResult = cbor_encoder_close_container(&encoder, &credRootMap); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing CRED Root Map."); - cJSON *jsonRoot = cJSON_Parse(jsonStr); - VERIFY_NON_NULL(TAG, jsonRoot, ERROR); + if (CborNoError == cborEncoderResult) + { + OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed"); + *cborPayload = outPayload; + *cborSize = encoder.ptr - outPayload; + ret = OC_STACK_OK; + } + OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT"); +exit: + if (CborErrorOutOfMemory == cborEncoderResult) + { + OIC_LOG(DEBUG, TAG, "CredToCBORPayload:CborErrorOutOfMemory : retry with more memory"); + // reallocate and try again! + OICFree(outPayload); + // Since the allocated initial memory failed, double the memory. + cborLen += encoder.ptr - encoder.end; + cborEncoderResult = CborNoError; + ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag); + *cborSize = cborLen; + } - jsonCredArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRED_NAME); - VERIFY_NON_NULL(TAG, jsonCredArray, ERROR); - if (cJSON_Array == jsonCredArray->type) + if (CborNoError != cborEncoderResult) { - int numCred = cJSON_GetArraySize(jsonCredArray); - int idx = 0; + OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload"); + OICFree(outPayload); + outPayload = NULL; + *cborSize = 0; + *cborPayload = NULL; + ret = OC_STACK_ERROR; + } - unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {}; - uint32_t outLen = 0; - B64Result b64Ret = B64_OK; + return ret; +} - VERIFY_SUCCESS(TAG, numCred > 0, ERROR); - do - { - cJSON *jsonCred = cJSON_GetArrayItem(jsonCredArray, idx); - VERIFY_NON_NULL(TAG, jsonCred, ERROR); +OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size, + OicSecCred_t **secCred) +{ + if (NULL == cborPayload || NULL == secCred || NULL != *secCred || 0 == size) + { + return OC_STACK_INVALID_PARAM; + } - OicSecCred_t *cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t)); - VERIFY_NON_NULL(TAG, cred, ERROR); + OCStackResult ret = OC_STACK_ERROR; + CborValue credCbor = { .parser = NULL }; + CborParser parser = { .end = NULL }; + CborError cborFindResult = CborNoError; + cbor_parser_init(cborPayload, size, 0, &parser, &credCbor); - headCred = (headCred) ? headCred : cred; - if (prevCred) - { - prevCred->next = cred; - } - size_t jsonObjLen = 0; - cJSON *jsonObj = NULL; + OicSecCred_t *headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t)); - //CredId -- Mandatory - jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_CREDID_NAME); - if(jsonObj) - { - VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR); - cred->credId = jsonObj->valueint; - } + // Enter CRED Root Map + CborValue CredRootMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 }; + cborFindResult = cbor_value_enter_container(&credCbor, &CredRootMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering CRED Root Map."); - //subject -- Mandatory - jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_SUBJECT_NAME); - VERIFY_NON_NULL(TAG, jsonObj, ERROR); - VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR); - outLen = 0; - memset(base64Buff, 0, sizeof(base64Buff)); - b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), - base64Buff, sizeof(base64Buff), &outLen); - VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(cred->subject.id)), - ERROR); - memcpy(cred->subject.id, base64Buff, outLen); - - //CredType -- Mandatory - jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_CREDTYPE_NAME); - VERIFY_NON_NULL(TAG, jsonObj, ERROR); - VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR); - cred->credType = (OicSecCredType_t)jsonObj->valueint; - - //PrivateData is mandatory for some of the credential types listed below. - jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PRIVATEDATA_NAME); - if ((cred->credType & SYMMETRIC_PAIR_WISE_KEY) || - (cred->credType & SYMMETRIC_GROUP_KEY) || - (cred->credType & PIN_PASSWORD)) - { - VERIFY_NON_NULL(TAG, jsonObj, ERROR); - VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR); - } -#ifdef __WITH_X509__ - else if (cred->credType & SIGNED_ASYMMETRIC_KEY) - { - VERIFY_NON_NULL(TAG, jsonObj, ERROR); - VERIFY_SUCCESS(TAG, cJSON_Object == jsonObj->type, ERROR); - } -#endif // __WITH_X509__ - if (NULL != jsonObj) + while (cbor_value_is_valid(&CredRootMap)) + { + char* tagName = NULL; + size_t len = 0; + CborType type = cbor_value_get_type(&CredRootMap); + if (type == CborTextStringType) + { + cborFindResult = cbor_value_dup_text_string(&CredRootMap, &tagName, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Root Map."); + cborFindResult = cbor_value_advance(&CredRootMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Root Map."); + } + if(tagName) + { + if (strcmp(tagName, OIC_JSON_CREDS_NAME) == 0) { - if (cJSON_String == jsonObj->type) - { - jsonObjLen = strlen(jsonObj->valuestring) + 1; - cred->privateData.data = (char *)OICMalloc(jsonObjLen); - VERIFY_NON_NULL(TAG, (cred->privateData.data), ERROR); - strncpy((char *)cred->privateData.data, (char *)jsonObj->valuestring, jsonObjLen); - } -#ifdef __WITH_X509__ - else if (SIGNED_ASYMMETRIC_KEY == cred->credType && cJSON_Object == jsonObj->type) + // Enter CREDS Array + size_t len = 0; + int credCount = 0; + CborValue credArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 }; + cborFindResult = cbor_value_enter_container(&CredRootMap, &credArray); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Array."); + + while (cbor_value_is_valid(&credArray)) { - cred->privateData.data = cJSON_PrintUnformatted(jsonObj); - VERIFY_NON_NULL(TAG, (cred->privateData.data), ERROR); - } -#endif // __WITH_X509__ - } + credCount++; + //CredId -- Mandatory + CborValue credMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 }; + cborFindResult = cbor_value_enter_container(&credArray, &credMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Map."); + OicSecCred_t *cred = NULL; + + if(1 == credCount) + { + cred = headCred; + } + else + { + cred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t)); + OicSecCred_t *temp = headCred; + while (temp->next) + { + temp = temp->next; + } + temp->next = cred; + } - //PublicData is mandatory only for SIGNED_ASYMMETRIC_KEY credentials type. - jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PUBLICDATA_NAME); -#ifdef __WITH_X509__ - if (cred->credType & SIGNED_ASYMMETRIC_KEY) - { - VERIFY_NON_NULL(TAG, jsonObj, ERROR); - VERIFY_SUCCESS(TAG, cJSON_Object == jsonObj->type, ERROR); - } -#endif // __WITH_X509__ - if (NULL != jsonObj) - { - if (cJSON_String == jsonObj->type) - { - jsonObjLen = strlen(jsonObj->valuestring) + 1; - cred->publicData.data = (char *)OICMalloc(jsonObjLen); - VERIFY_NON_NULL(TAG, (cred->publicData.data), ERROR); - strncpy((char *)cred->publicData.data, (char *)jsonObj->valuestring, jsonObjLen); - } + VERIFY_NON_NULL(TAG, cred, ERROR); + + while(cbor_value_is_valid(&credMap)) + { + char* name = NULL; + CborType type = cbor_value_get_type(&credMap); + if (type == CborTextStringType) + { + cborFindResult = cbor_value_dup_text_string(&credMap, &name, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Map."); + cborFindResult = cbor_value_advance(&credMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Map."); + } + if(name) + { + //credid + if (strcmp(name, OIC_JSON_CREDID_NAME) == 0) + { + cborFindResult = cbor_value_get_uint64(&credMap, (uint64_t *) &cred->credId); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId."); + } + // subjectid + if (strcmp(name, OIC_JSON_SUBJECTID_NAME) == 0) + { + char *subjectid = NULL; + cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subjectid Value."); + ret = ConvertStrToUuid(subjectid, &cred->subject); + VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR); + OICFree(subjectid); + } + // credtype + if (strcmp(name, OIC_JSON_CREDTYPE_NAME) == 0) + { + cborFindResult = cbor_value_get_uint64(&credMap, (uint64_t *) &cred->credType); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType."); + } + // privatedata + if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME) == 0) + { + CborValue privateMap = { .parser = NULL }; + cborFindResult = cbor_value_enter_container(&credMap, &privateMap); + + while (cbor_value_is_valid(&privateMap)) + { + char* privname = NULL; + CborType type = cbor_value_get_type(&privateMap); + if (type == CborTextStringType) + { + cborFindResult = cbor_value_dup_text_string(&privateMap, &privname, + &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text"); + cborFindResult = cbor_value_advance(&privateMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value"); + } + if (privname) + { + // PrivateData::privdata -- Mandatory + if (strcmp(privname, OIC_JSON_DATA_NAME) == 0) + { + cborFindResult = cbor_value_dup_byte_string(&privateMap, &cred->privateData.data, + &cred->privateData.len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData."); + } + // PrivateData::encoding -- Mandatory + if (strcmp(privname, OIC_JSON_ENCODING_NAME) == 0) + { + // TODO: Need to update data structure, just ignore encoding value now. + } + } + if (cbor_value_is_valid(&privateMap)) + { + cborFindResult = cbor_value_advance(&privateMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing privatedata Map."); + } + OICFree(privname); + } + + } #ifdef __WITH_X509__ - else if (SIGNED_ASYMMETRIC_KEY == cred->credType && cJSON_Object == jsonObj->type) - { - cred->publicData.data = cJSON_PrintUnformatted(jsonObj); - VERIFY_NON_NULL(TAG, (cred->publicData.data), ERROR); + if (strcmp(name, OIC_JSON_PUBLICDATA_NAME) == 0) + { + CborValue pubMap = { .parser = NULL }; + cborFindResult = cbor_value_enter_container(&credMap, &pubMap); + + while (cbor_value_is_valid(&pubMap)) + { + char* pubname = NULL; + CborType type = cbor_value_get_type(&pubMap); + if (type == CborTextStringType) + { + cborFindResult = cbor_value_dup_text_string(&pubMap, &pubname, + &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text"); + cborFindResult = cbor_value_advance(&pubMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value"); + } + if (pubname) + { + // PrivateData::privdata -- Mandatory + if (strcmp(pubname, OIC_JSON_DATA_NAME) == 0) + { + cborFindResult = cbor_value_dup_byte_string(&pubMap, &cred->publicData.data, + &cred->publicData.len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PubData."); + } + // PublicData::encoding -- Mandatory + if (strcmp(pubname, OIC_JSON_ENCODING_NAME) == 0) + { + // TODO: Need to update data structure, just ignore encoding value now. + } + } + if (cbor_value_is_valid(&pubMap)) + { + cborFindResult = cbor_value_advance(&pubMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing publicdata Map."); + } + OICFree(pubname); + } + } +#endif //__WITH_X509__ + + if (0 == strcmp(OIC_JSON_PERIOD_NAME, name)) + { + cborFindResult = cbor_value_dup_text_string(&credMap, &cred->period, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period."); + } + + if (cbor_value_is_valid(&credMap)) + { + cborFindResult = cbor_value_advance(&credMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Map."); + } + OICFree(name); + } + } + cred->next = NULL; + if (cbor_value_is_valid(&credArray)) + { + cborFindResult = cbor_value_advance(&credArray); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Array."); + } } -#endif // __WITH_X509__ } - //Period -- Not Mandatory - jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PERIOD_NAME); - if(jsonObj && cJSON_String == jsonObj->type) + //ROwner -- Mandatory + if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0) { - jsonObjLen = strlen(jsonObj->valuestring) + 1; - cred->period = (char *)OICMalloc(jsonObjLen); - VERIFY_NON_NULL(TAG, cred->period, ERROR); - strncpy(cred->period, jsonObj->valuestring, jsonObjLen); - } + char *stRowner = NULL; + cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value."); - //Owners -- Mandatory - jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_OWNERS_NAME); - VERIFY_NON_NULL(TAG, jsonObj, ERROR); - VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR); - cred->ownersLen = cJSON_GetArraySize(jsonObj); - VERIFY_SUCCESS(TAG, cred->ownersLen > 0, ERROR); - cred->owners = (OicUuid_t*)OICCalloc(cred->ownersLen, sizeof(OicUuid_t)); - VERIFY_NON_NULL(TAG, (cred->owners), ERROR); - for(size_t i = 0; i < cred->ownersLen; i++) - { - cJSON *jsonOwnr = cJSON_GetArrayItem(jsonObj, i); - VERIFY_NON_NULL(TAG, jsonOwnr, ERROR); - VERIFY_SUCCESS(TAG, cJSON_String == jsonOwnr->type, ERROR); - outLen = 0; - memset(base64Buff, 0, sizeof(base64Buff)); - b64Ret = b64Decode(jsonOwnr->valuestring, strlen(jsonOwnr->valuestring), - base64Buff, sizeof(base64Buff), &outLen); - VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && - outLen <= sizeof(cred->owners[i].id)), ERROR); - memcpy(cred->owners[i].id, base64Buff, outLen); + ret = ConvertStrToUuid(stRowner, &headCred->rownerID); + VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR); + OICFree(stRowner); } - prevCred = cred; - } while( ++idx < numCred); + OICFree(tagName); + } + if (cbor_value_is_valid(&CredRootMap)) + { + cborFindResult = cbor_value_advance(&CredRootMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Root Map."); + } } + *secCred = headCred; ret = OC_STACK_OK; exit: - cJSON_Delete(jsonRoot); - if (OC_STACK_OK != ret) + if (CborNoError != cborFindResult) { DeleteCredList(headCred); headCred = NULL; + *secCred = NULL; + ret = OC_STACK_ERROR; } - return headCred; + + return ret; } -/** - * This function generates the bin credential data. - * - * @param subject pointer to subject of this credential. - * @param credType credential type. - * @param publicData public data such as public key. - * @param privateData private data such as private key. - * The privateData is expected in base64 encoded format. - * @param ownersLen length of owners array - * @param owners array of owners. - * - * @retval - * pointer to instance of OicSecCred_t - success - * NULL - error - */ OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType, - const char * publicData, const char * privateData, - size_t ownersLen, const OicUuid_t * owners) + const OicSecCert_t * publicData, const OicSecKey_t* privateData, + const OicUuid_t * rownerID) { (void)publicData; OCStackResult ret = OC_STACK_ERROR; - OicSecCred_t *cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t)); + OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred)); VERIFY_NON_NULL(TAG, cred, ERROR); //CredId is assigned before appending new cred to the existing @@ -443,30 +619,25 @@ OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t cr cred->credType = credType; #ifdef __WITH_X509__ - if(publicData) + if (publicData && publicData->data) { - cred->publicData.data = (char *)OICMalloc(strlen(publicData)+1); + cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len); VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR); - strncpy((char *)cred->publicData.data, publicData, strlen(publicData)+1); + memcpy(cred->publicData.data, publicData->data, publicData->len); + cred->publicData.len = publicData->len; } #endif // __WITH_X509__ - if(privateData) + if (privateData && privateData->data) { - cred->privateData.data = (char *)OICMalloc(strlen(privateData)+1); + cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len); VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR); - strncpy((char *)cred->privateData.data, privateData, strlen(privateData)+1); + memcpy(cred->privateData.data, privateData->data, privateData->len); + cred->privateData.len = privateData->len; } - VERIFY_SUCCESS(TAG, ownersLen > 0, ERROR); - cred->ownersLen = ownersLen; - - cred->owners = (OicUuid_t*)OICCalloc(cred->ownersLen, sizeof(OicUuid_t)); - VERIFY_NON_NULL(TAG, cred->owners, ERROR); - for(size_t i = 0; i < cred->ownersLen; i++) - { - memcpy(cred->owners[i].id, owners[i].id, sizeof(cred->owners[i].id)); - } + VERIFY_NON_NULL(TAG, rownerID, ERROR); + memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t)); ret = OC_STACK_OK; exit: @@ -483,22 +654,24 @@ static bool UpdatePersistentStorage(const OicSecCred_t *cred) bool ret = false; // Convert Cred data into JSON for update to persistent storage - char *jsonStr = BinToCredJSON(cred); - if (jsonStr) + if (cred) { - cJSON *jsonCred = cJSON_Parse(jsonStr); - OICFree(jsonStr); - - if ((jsonCred) && - (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_CRED_NAME, jsonCred))) + uint8_t *payload = NULL; + size_t size = 0; + int secureFlag = 0; + OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag); + if ((OC_STACK_OK == res) && payload) { - ret = true; + if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size)) + { + ret = true; + } + OICFree(payload); } - cJSON_Delete(jsonCred ); } else //Empty cred list { - if (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_CRED_NAME, NULL)) + if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0)) { ret = true; } @@ -507,23 +680,22 @@ static bool UpdatePersistentStorage(const OicSecCred_t *cred) } /** - * Compare function used LL_SORT for sorting credentials + * Compare function used LL_SORT for sorting credentials. * - * @param first pointer to OicSecCred_t struct - * @param second pointer to OicSecCred_t struct + * @param first pointer to OicSecCred_t struct. + * @param second pointer to OicSecCred_t struct. * - *@retval - * -1 if credId of first is less than credId of second - * 0 if credId of first is equal to credId of second - * 1 if credId of first is greater than credId of second + *@return -1, if credId of first is less than credId of second. + * 0, if credId of first is equal to credId of second. + * 1, if credId of first is greater than credId of second. */ static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second) { - if(first->credId < second->credId) + if (first->credId < second->credId) { return -1; } - else if(first->credId > second->credId) + else if (first->credId > second->credId) { return 1; } @@ -537,23 +709,19 @@ static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second) * available due deletion of OicSecCred_t object or one more than * credId of last credential in the list. * - * @retval - * next available credId - success - * 0 - error + * @return next available credId if successful, else 0 for error. */ - static uint16_t GetCredId() { //Sorts credential list in incremental order of credId LL_SORT(gCred, CmpCredId); - OicSecCred_t *currentCred = NULL, *credTmp = NULL; uint16_t nextCredId = 1; LL_FOREACH_SAFE(gCred, currentCred, credTmp) { - if(currentCred->credId == nextCredId) + if (currentCred->credId == nextCredId) { nextCredId += 1; } @@ -571,38 +739,29 @@ exit: } /** - * Get the default value - * @retval NULL for now. Update it when we finalize the default info. + * Get the default value. + * + * @return NULL for now. */ static OicSecCred_t* GetCredDefault() { + // TODO:Update it when we finalize the default info. return NULL; } -/** - * This function adds the new cred to the credential list. - * - * @param cred pointer to new credential. - * - * @retval - * OC_STACK_OK - cred not NULL and persistent storage gets updated - * OC_STACK_ERROR - cred is NULL or fails to update persistent storage - */ OCStackResult AddCredential(OicSecCred_t * newCred) { OCStackResult ret = OC_STACK_ERROR; - VERIFY_SUCCESS(TAG, NULL != newCred, ERROR); //Assigning credId to the newCred newCred->credId = GetCredId(); - VERIFY_SUCCESS(TAG, newCred->credId != 0, ERROR); //Append the new Cred to existing list LL_APPEND(gCred, newCred); - if(UpdatePersistentStorage(gCred)) + if (UpdatePersistentStorage(gCred)) { ret = OC_STACK_OK; } @@ -620,7 +779,7 @@ OCStackResult RemoveCredential(const OicUuid_t *subject) LL_FOREACH_SAFE(gCred, cred, tempCred) { - if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0) + if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0) { LL_DELETE(gCred, cred); FreeCred(cred); @@ -628,9 +787,9 @@ OCStackResult RemoveCredential(const OicUuid_t *subject) } } - if(deleteFlag) + if (deleteFlag) { - if(UpdatePersistentStorage(gCred)) + if (UpdatePersistentStorage(gCred)) { ret = OC_STACK_RESOURCE_DELETED; } @@ -651,21 +810,247 @@ OCStackResult RemoveAllCredentials(void) DeleteCredList(gCred); gCred = GetCredDefault(); - if(!UpdatePersistentStorage(gCred)) + if (!UpdatePersistentStorage(gCred)) { return OC_STACK_ERROR; } return OC_STACK_OK; } -static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest) +#ifdef __WITH_DTLS__ +/** + * Internal function to fill private data of owner PSK. + * + * @param receviedCred recevied owner credential from OBT(PT) + * @param ownerAdd address of OBT(PT) + * @param doxm current device's doxm resource + * + * @return + * true successfully done and valid ower psk information + * false Invalid owner psk information or failed to owner psk generation + */ +static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr, + const OicSecDoxm_t* doxm) +{ + //Derive OwnerPSK locally + const char* oxmLabel = GetOxmString(doxm->oxmSel); + VERIFY_NON_NULL(TAG, oxmLabel, ERROR); + + uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0}; + CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr, + (uint8_t*)oxmLabel, strlen(oxmLabel), + doxm->owner.id, sizeof(doxm->owner.id), + doxm->deviceID.id, sizeof(doxm->deviceID.id), + ownerPSK, OWNER_PSK_LENGTH_128); + VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR); + + OIC_LOG(DEBUG, TAG, "OwnerPSK dump :"); + OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128); + + //Generate owner credential based on recevied credential information + receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128); + VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR); + receviedCred->privateData.len = OWNER_PSK_LENGTH_128; + memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128); + + OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully"); + + //Verify OwnerPSK information + return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 && + receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY); +exit: + //receviedCred->privateData.data will be deallocated when deleting credential. + return false; +} + +#endif //__WITH_DTLS__ + +static OCEntityHandlerResult HandlePutRequest(const OCEntityHandlerRequest * ehRequest) { OCEntityHandlerResult ret = OC_EH_ERROR; + OIC_LOG(DEBUG, TAG, "HandleCREDPutRequest IN"); + + //Get binary representation of cbor + OicSecCred_t *cred = NULL; + uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData); + size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize); + OCStackResult res = CBORPayloadToCred(payload, size, &cred); + if (res == OC_STACK_OK) + { +#ifdef __WITH_DTLS__ + OicUuid_t emptyUuid = {.id={0}}; + const OicSecDoxm_t* doxm = GetDoxmResourceData(); + if(false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0) + { + //in case of owner PSK + switch(cred->credType) + { + case SYMMETRIC_PAIR_WISE_KEY: + { + OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle; + if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm)) + { + if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject)) + { + OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!"); + } + + OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully."); + if(OC_STACK_OK == AddCredential(cred)) + { + ret = OC_EH_RESOURCE_CREATED; + } + else + { + OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource"); + ret = OC_EH_ERROR; + } + } + else + { + OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS."); + ret = OC_EH_ERROR; + } - //Get binary representation of json - OicSecCred_t * cred = JSONToCredBin(((OCSecurityPayload*)ehRequest->payload)->securityData); + if(OC_EH_RESOURCE_CREATED == ret) + { + /** + * in case of random PIN based OxM, + * revert get_psk_info callback of tinyDTLS to use owner credential. + */ + if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel) + { + OicUuid_t emptyUuid = { .id={0}}; + SetUuidForRandomPinOxm(&emptyUuid); + + if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials)) + { + OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler."); + ret = OC_EH_ERROR; + break; + } + } + + //Select cipher suite to use owner PSK + if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false)) + { + OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite"); + ret = OC_EH_ERROR; + } + else + { + OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED"); + } - if(cred) + if(CA_STATUS_OK != + CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256)) + { + OIC_LOG(ERROR, TAG, "Failed to select cipher suite"); + ret = OC_EH_ERROR; + } + } + + break; + } + case SYMMETRIC_GROUP_KEY: + case ASYMMETRIC_KEY: + case SIGNED_ASYMMETRIC_KEY: + case PIN_PASSWORD: + case ASYMMETRIC_ENCRYPTION_KEY: + { + OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential."); + ret = OC_EH_ERROR; + break; + } + default: + { + OIC_LOG(WARNING, TAG, "Unknow credential type for owner credential."); + ret = OC_EH_ERROR; + break; + } + } + + if(OC_EH_RESOURCE_CREATED != ret) + { + /* + * If some error is occured while ownership transfer, + * ownership transfer related resource should be revert back to initial status. + */ + RestoreDoxmToInitState(); + RestorePstatToInitState(); + } + } + else + { + /* + * If the post request credential has credId, it will be + * discarded and the next available credId will be assigned + * to it before getting appended to the existing credential + * list and updating svr database. + */ + ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR; + } +#else //not __WITH_DTLS__ + /* + * If the post request credential has credId, it will be + * discarded and the next available credId will be assigned + * to it before getting appended to the existing credential + * list and updating svr database. + */ + ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR; +#endif//__WITH_DTLS__ + } + + if (OC_EH_RESOURCE_CREATED != ret) + { + if(OC_STACK_OK != RemoveCredential(&cred->subject)) + { + OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential"); + } + FreeCred(cred); + } + OIC_LOG(DEBUG, TAG, "HandleCREDPutRequest OUT"); + return ret; +} + +/** + * The entity handler determines how to process a GET request. + */ +static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest) +{ + OIC_LOG(INFO, TAG, "HandleGetRequest processing GET request"); + + // Convert Cred data into CBOR for transmission + size_t size = 0; + uint8_t *payload = NULL; + int secureFlag = 1; + + const OicSecCred_t *cred = gCred; + OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag); + + // A device should always have a default cred. Therefore, payload should never be NULL. + OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR; + + // Send response payload to request originator + if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size)) + { + ehRet = OC_EH_ERROR; + OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePstatGetRequest"); + } + OICFree(payload); + return ehRet; +} + +static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest) +{ + OCEntityHandlerResult ret = OC_EH_ERROR; + + //Get binary representation of CBOR + OicSecCred_t *cred = NULL; + uint8_t *payload = ((OCSecurityPayload*)ehRequest->payload)->securityData; + size_t size = ((OCSecurityPayload*)ehRequest->payload)->payloadSize; + OCStackResult res = CBORPayloadToCred(payload, size, &cred); + if ((OC_STACK_OK == res) && cred) { //If the Post request credential has credId, it will be //discarded and the next available credId will be assigned @@ -673,6 +1058,7 @@ static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * eh //list and updating svr database. ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR; } + return ret; } @@ -682,54 +1068,43 @@ static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *e OCEntityHandlerResult ehRet = OC_EH_ERROR; - if(NULL == ehRequest->query) - { - return ehRet; - } - - OicParseQueryIter_t parseIter = {.attrPos=NULL}; - OicUuid_t subject = {.id={0}}; - - //Parsing REST query to get the subject - ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter); - while(GetNextQuery(&parseIter)) - { - if(strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECT_NAME, - parseIter.attrLen) == 0) - { - unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {}; - uint32_t outLen = 0; - B64Result b64Ret = B64_OK; - - b64Ret = b64Decode((char *)parseIter.valPos, parseIter.valLen, - base64Buff, sizeof(base64Buff), &outLen); - - VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(subject.id)), ERROR); - memcpy(subject.id, base64Buff, outLen); - } - } - - if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject)) - { - ehRet = OC_EH_RESOURCE_DELETED; - } + if (NULL == ehRequest->query) + { + return ehRet; + } + + OicParseQueryIter_t parseIter = { .attrPos=NULL }; + OicUuid_t subject = {.id={0}}; + + //Parsing REST query to get the subject + ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter); + while (GetNextQuery(&parseIter)) + { + if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME, + parseIter.attrLen) == 0) + { + OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject); + VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR); + } + } + + if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject)) + { + ehRet = OC_EH_RESOURCE_DELETED; + } exit: return ehRet; } -/* - * This internal method is the entity handler for Cred resources - * to handle REST request (PUT/POST/DEL) - */ -OCEntityHandlerResult CredEntityHandler (OCEntityHandlerFlag flag, +OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest, void* callbackParameter) { (void)callbackParameter; OCEntityHandlerResult ret = OC_EH_ERROR; - if(!ehRequest) + if (!ehRequest) { return OC_EH_ERROR; } @@ -737,10 +1112,13 @@ OCEntityHandlerResult CredEntityHandler (OCEntityHandlerFlag flag, { OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG"); //TODO : Handle PUT/DEL methods - switch(ehRequest->method) + switch (ehRequest->method) { case OC_REST_GET: - ret = OC_EH_FORBIDDEN; + ret = HandleGetRequest(ehRequest);; + break; + case OC_REST_PUT: + ret = HandlePutRequest(ehRequest); break; case OC_REST_POST: ret = HandlePostRequest(ehRequest); @@ -755,26 +1133,21 @@ OCEntityHandlerResult CredEntityHandler (OCEntityHandlerFlag flag, } //Send payload to request originator - ret = (SendSRMResponse(ehRequest, ret, NULL) == OC_STACK_OK ? - ret : OC_EH_ERROR); + ret = (SendSRMResponse(ehRequest, ret, NULL, 0) == OC_STACK_OK) ? + ret : OC_EH_ERROR; return ret; } -/* - * This internal method is used to create '/oic/sec/Cred' resource. - */ OCStackResult CreateCredResource() { - OCStackResult ret; - - ret = OCCreateResource(&gCredHandle, - OIC_RSRC_TYPE_SEC_CRED, - OIC_MI_DEF, - OIC_RSRC_CRED_URI, - CredEntityHandler, - NULL, - OC_RES_PROP_NONE); + OCStackResult ret = OCCreateResource(&gCredHandle, + OIC_RSRC_TYPE_SEC_CRED, + OIC_MI_DEF, + OIC_RSRC_CRED_URI, + CredEntityHandler, + NULL, + OC_RES_PROP_NONE); if (OC_STACK_OK != ret) { @@ -784,49 +1157,40 @@ OCStackResult CreateCredResource() return ret; } -/** - * Initialize Cred resource by loading data from persistent storage. - * - * @retval - * OC_STACK_OK - no errors - * OC_STACK_ERROR - stack process error - */ OCStackResult InitCredResource() { OCStackResult ret = OC_STACK_ERROR; //Read Cred resource from PS - char* jsonSVRDatabase = GetSVRDatabase(); - - if (jsonSVRDatabase) + uint8_t *data = NULL; + size_t size = 0; + ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size); + // If database read failed + if (ret != OC_STACK_OK) { - //Convert JSON Cred into binary format - gCred = JSONToCredBin(jsonSVRDatabase); + OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed"); } + if (data) + { + // Read ACL resource from PS + ret = CBORPayloadToCred(data, size, &gCred); + } + /* * If SVR database in persistent storage got corrupted or * is not available for some reason, a default Cred is created * which allows user to initiate Cred provisioning again. */ - if (!jsonSVRDatabase || !gCred) + if (ret != OC_STACK_OK || !data || !gCred) { gCred = GetCredDefault(); } //Instantiate 'oic.sec.cred' ret = CreateCredResource(); - OICFree(jsonSVRDatabase); + OICFree(data); return ret; } -/** - * Perform cleanup for Cred resources. - * - * @return - * OC_STACK_OK - no errors - * OC_STACK_ERROR - stack process error - * OC_STACK_NO_RESOURCE - resource not found - * OC_STACK_INVALID_PARAM - invalid param - */ OCStackResult DeInitCredResource() { OCStackResult result = OCDeleteResource(gCredHandle); @@ -835,15 +1199,6 @@ OCStackResult DeInitCredResource() return result; } -/** - * This method is used by tinydtls/SRM to retrieve credential for given Subject. - * - * @param subject - subject for which credential is required. - * - * @retval - * reference to OicSecCred_t - if credential is found - * NULL - if credential not found - */ const OicSecCred_t* GetCredResourceData(const OicUuid_t* subject) { OicSecCred_t *cred = NULL; @@ -865,22 +1220,9 @@ const OicSecCred_t* GetCredResourceData(const OicUuid_t* subject) #if defined(__WITH_DTLS__) -/** - * This internal callback is used by lower stack (i.e. CA layer) to - * retrieve PSK credentials from RI security layer. - * - * @param[in] type type of PSK data required by tinyDTLS layer during DTLS handshake. - * @param[in] desc Additional request information. - * @param[in] desc_len The actual length of desc. - * @param[out] result Must be filled with the requested information. - * @param[in] result_length Maximum size of @p result. - * - * @return The number of bytes written to @p result or a value - * less than zero on error. - */ -int32_t GetDtlsPskCredentials( CADtlsPskCredType_t type, - const unsigned char *desc, size_t desc_len, - unsigned char *result, size_t result_length) +int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type, + const uint8_t *desc, size_t desc_len, + uint8_t *result, size_t result_length) { int32_t ret = -1; @@ -939,18 +1281,10 @@ int32_t GetDtlsPskCredentials( CADtlsPskCredType_t type, } } - // Convert PSK from Base64 encoding to binary before copying - uint32_t outLen = 0; - B64Result b64Ret = b64Decode(cred->privateData.data, - strlen(cred->privateData.data), result, - result_length, &outLen); - if (B64_OK != b64Ret) - { - OIC_LOG (ERROR, TAG, "Base64 decoding failed."); - ret = -1; - return ret; - } - return outLen; + // Copy PSK. + result_length = cred->privateData.len; + memcpy(result, cred->privateData.data, result_length); + return result_length; } } } @@ -974,37 +1308,33 @@ int32_t GetDtlsPskCredentials( CADtlsPskCredType_t type, * @param[in] credType Type of credential to be added * @param[in] pin numeric characters * @param[in] pinSize length of 'pin' - * @param[in] ownersLen Number of owners - * @param[in] owners Array of owners + * @param[in] rownerID Resource owner's UUID * @param[out] tmpCredSubject Generated credential's subject. * * @return OC_STACK_OK for success and errorcode otherwise. */ OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType, const char * pin, size_t pinSize, - size_t ownersLen, const OicUuid_t * owners, OicUuid_t* tmpCredSubject) + const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject) { OCStackResult ret = OC_STACK_ERROR; + OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN"); - if(tmpSubject == NULL || pin == NULL || pinSize == 0 || tmpCredSubject == NULL) + if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject) { return OC_STACK_INVALID_PARAM; } uint8_t privData[OWNER_PSK_LENGTH_128] = {0,}; - int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, owners->id, + OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128}; + OicSecCred_t* cred = NULL; + int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id, UUID_LENGTH, PBKDF_ITERATIONS, OWNER_PSK_LENGTH_128, privData); - VERIFY_SUCCESS(TAG, (dtlsRes == 0) , ERROR); - - uint32_t outLen = 0; - char base64Buff[B64ENCODE_OUT_SAFESIZE(OWNER_PSK_LENGTH_128) + 1] = {}; - B64Result b64Ret = b64Encode(privData, OWNER_PSK_LENGTH_128, base64Buff, - sizeof(base64Buff), &outLen); - VERIFY_SUCCESS(TAG, (B64_OK == b64Ret), ERROR); + VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR); - OicSecCred_t* cred = GenerateCredential(tmpSubject, credType, NULL, - base64Buff, ownersLen, owners); + cred = GenerateCredential(tmpSubject, credType, NULL, + &privKey, rownerID); if(NULL == cred) { OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential"); @@ -1016,8 +1346,10 @@ OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t cre ret = AddCredential(cred); if( OC_STACK_OK != ret) { + RemoveCredential(tmpSubject); OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential"); } + OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT"); exit: return ret; @@ -1032,21 +1364,12 @@ exit: #define CERTIFICATE ("x5c") #define PRIVATE_KEY ("d") - -static void WriteCertPrefix(uint8_t *prefix, uint32_t certLen) -{ - for (size_t i = 0; i < CERT_LEN_PREFIX; ++i) - { - prefix[i] = (certLen >> (BYTE_SIZE * (CERT_LEN_PREFIX - 1 - i))) & 0xFF; - } -} - -static uint32_t ParseCertPrefix(uint8_t *prefix) +static uint32_t parseCertPrefix(uint8_t *prefix) { uint32_t res = 0; - if(NULL != prefix) + if (NULL != prefix) { - for(int i=0; i < CERT_LEN_PREFIX; ++i) + for (int i = 0; i < CERT_LEN_PREFIX; ++i) { res |= (((uint32_t) prefix[i]) << ((CERT_LEN_PREFIX - 1 -i) * BYTE_SIZE)); } @@ -1054,34 +1377,16 @@ static uint32_t ParseCertPrefix(uint8_t *prefix) return res; } -static uint32_t appendCert2Chain(uint8_t *appendPoint, char *cert, uint32_t max_len) +static OCStackResult GetCAPublicKeyData(CADtlsX509Creds_t *credInfo) { - uint32_t ret = 0; - VERIFY_NON_NULL(TAG, appendPoint, ERROR); - VERIFY_NON_NULL(TAG, cert, ERROR); - - uint32_t certLen; - VERIFY_SUCCESS(TAG, B64_OK == b64Decode(cert, strlen(cert), appendPoint + CERT_LEN_PREFIX, - max_len - CERT_LEN_PREFIX, &certLen), ERROR); - WriteCertPrefix(appendPoint, certLen); - - ret = certLen + CERT_LEN_PREFIX; -exit: - return ret; -} - -static OCStackResult GetCAPublicKeyData(CADtlsX509Creds_t *credInfo){ OCStackResult ret = OC_STACK_ERROR; uint8_t *ccPtr = credInfo->certificateChain; - for(uint32_t i =0; i < credInfo->chainLen - 1; ++i) + for (uint8_t i = 0; i < credInfo->chainLen - 1; ++i) { - ccPtr += CERT_LEN_PREFIX + ParseCertPrefix(ccPtr); + ccPtr += CERT_LEN_PREFIX + parseCertPrefix(ccPtr); } - ByteArray cert = { - .data = ccPtr + CERT_LEN_PREFIX, - .len = ParseCertPrefix(ccPtr) - }; + ByteArray cert = { .data = ccPtr + CERT_LEN_PREFIX, .len = parseCertPrefix(ccPtr) }; CertificateX509 certStruct; VERIFY_SUCCESS(TAG, PKI_SUCCESS == DecodeCertificate(cert, &certStruct), ERROR); @@ -1096,86 +1401,83 @@ static OCStackResult GetCAPublicKeyData(CADtlsX509Creds_t *credInfo){ return ret; } -static OCStackResult GetCertCredPublicData(CADtlsX509Creds_t *credInfo, OicSecCred_t *cred) +int GetDtlsX509Credentials(CADtlsX509Creds_t *credInfo) { - OCStackResult ret = OC_STACK_ERROR; + int ret = 1; VERIFY_NON_NULL(TAG, credInfo, ERROR); - VERIFY_NON_NULL(TAG, cred, ERROR); - VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR); - //VERIFY_SUCCESS(TAG, NULL == credInfo->certificateChain.data, ERROR); - cJSON *jsonRoot = cJSON_Parse(cred->publicData.data); - VERIFY_NON_NULL(TAG, jsonRoot, ERROR); - - //Get certificate chain - cJSON *jsonObj = cJSON_GetObjectItem(jsonRoot, CERTIFICATE);//TODO define field names constants - VERIFY_SUCCESS(TAG, NULL != jsonObj && cJSON_Array == jsonObj->type, ERROR); + if (NULL == gCred) + { + VERIFY_SUCCESS(TAG, OC_STACK_OK == InitCredResource(), ERROR); + } - size_t certChainLen = cJSON_GetArraySize(jsonObj); - credInfo->chainLen = certChainLen; - VERIFY_SUCCESS(TAG, MAX_CHAIN_LEN >= certChainLen, ERROR); + OicSecCred_t *cred = NULL; + LL_SEARCH_SCALAR(gCred, cred, credType, SIGNED_ASYMMETRIC_KEY); + VERIFY_NON_NULL(TAG, cred, ERROR); - uint32_t len = 0; - for (size_t i = 0; i < certChainLen; ++i) + if (cred->publicData.len > MAX_CERT_MESSAGE_LEN || cred->privateData.len > PRIVATE_KEY_SIZE) { - cJSON *item = cJSON_GetArrayItem(jsonObj, i); - VERIFY_SUCCESS(TAG, cJSON_String == item->type, ERROR); - uint32_t appendedLen = appendCert2Chain(credInfo->certificateChain + len, item->valuestring, - MAX_CERT_MESSAGE_LEN - len); - VERIFY_SUCCESS(TAG, 0 != appendedLen, ERROR); - len += appendedLen; + goto exit; } - credInfo->certificateChainLen = len; - VERIFY_SUCCESS(TAG, OC_STACK_OK == GetCAPublicKeyData(credInfo), ERROR); - ret = OC_STACK_OK; + credInfo->chainLen = 2; + memcpy(credInfo->certificateChain, cred->publicData.data, cred->publicData.len); + memcpy(credInfo->devicePrivateKey, cred->privateData.data, cred->privateData.len); + credInfo->certificateChainLen = cred->publicData.len; + GetCAPublicKeyData(credInfo); + ret = 0; + exit: - cJSON_Delete(jsonRoot); + return ret; } +#undef CERT_LEN_PREFIX +#endif /* __WITH_X509__ */ -static OCStackResult GetCertCredPrivateData(CADtlsX509Creds_t *credInfo, OicSecCred_t *cred) +OCStackResult SetCredRownerId(const OicUuid_t* newROwner) { OCStackResult ret = OC_STACK_ERROR; - VERIFY_NON_NULL(TAG, credInfo, ERROR); - VERIFY_NON_NULL(TAG, cred, ERROR); - VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR); - cJSON *jsonRoot = cJSON_Parse(cred->privateData.data); - VERIFY_NON_NULL(TAG, jsonRoot, ERROR); + uint8_t *cborPayload = NULL; + size_t size = 0; + int secureFlag = 0; + OicUuid_t prevId = {.id={0}}; + + if(NULL == newROwner) + { + ret = OC_STACK_INVALID_PARAM; + } + if(NULL == gCred) + { + ret = OC_STACK_NO_RESOURCE; + } - cJSON *jsonObj = cJSON_GetObjectItem(jsonRoot, PRIVATE_KEY);//TODO define field names constants - VERIFY_SUCCESS(TAG, NULL != jsonObj && cJSON_String == jsonObj->type, ERROR); + if(newROwner && gCred) + { + memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id)); + memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id)); - uint32_t read = 0u; - VERIFY_SUCCESS(TAG, B64_OK == b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), - credInfo->devicePrivateKey, PRIVATE_KEY_SIZE, &read) - && PRIVATE_KEY_SIZE == read, ERROR); + ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag); + VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR); - ret = OC_STACK_OK; + ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size); + VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR); + + OICFree(cborPayload); + } + + return ret; exit: - cJSON_Delete(jsonRoot); + OICFree(cborPayload); + memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id)); return ret; } -int GetDtlsX509Credentials(CADtlsX509Creds_t *credInfo) +OCStackResult GetCredRownerId(OicUuid_t *rowneruuid) { - int ret = 1; - VERIFY_NON_NULL(TAG, credInfo, ERROR); - if (NULL == gCred) + OCStackResult retVal = OC_STACK_ERROR; + if (gCred) { - VERIFY_SUCCESS(TAG, OC_STACK_OK == InitCredResource(), ERROR); + *rowneruuid = gCred->rownerID; + retVal = OC_STACK_OK; } - - OicSecCred_t *cred = NULL; - LL_SEARCH_SCALAR(gCred, cred, credType, SIGNED_ASYMMETRIC_KEY); - VERIFY_NON_NULL(TAG, cred, ERROR); - - VERIFY_SUCCESS(TAG, OC_STACK_OK == GetCertCredPrivateData(credInfo, cred), ERROR); - VERIFY_SUCCESS(TAG, OC_STACK_OK == GetCertCredPublicData(credInfo, cred), ERROR); - - ret = 0; -exit: - - return ret; + return retVal; } -#undef CERT_LEN_PREFIX -#endif /* __WITH_X509__ */