+ char* name = NULL;
+ CborType type = cbor_value_get_type(&map);
+ if (type == CborTextStringType && cbor_value_is_text_string(&map))
+ {
+ cborFindResult = cbor_value_dup_text_string(&map, &name, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
+ cborFindResult = cbor_value_advance(&map);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
+ }
+ if (name)
+ {
+ // OptionalData::revstat -- Mandatory
+ if (strcmp(name, OIC_JSON_REVOCATION_STATUS_NAME) == 0)
+ {
+ cborFindResult = cbor_value_get_boolean(&map, &value->revstat);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding revstat Value.")
+ }
+ OicSecKey_t out;
+ VERIFY_CBOR_SUCCESS(TAG, DeserializeEncodingFromCborInternal(&map, name, &out),
+ "Failed to read OicSecKey_t value");
+
+ value->data = out.data;
+ value->encoding = out.encoding;
+ value->len = out.len;
+ }
+ if (cbor_value_is_valid(&map))
+ {
+ cborFindResult = cbor_value_advance(&map);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Map.");
+ }
+ OICFree(name);
+ }
+ exit:
+ return cborFindResult;
+}
+
+OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
+ size_t *cborSize, int secureFlag)
+{
+ if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OCStackResult ret = OC_STACK_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;
+ }
+
+ outPayload = (uint8_t *)OICCalloc(1, cborLen);
+ VERIFY_NON_NULL(TAG, outPayload, ERROR);
+ cbor_encoder_init(&encoder, outPayload, cborLen, 0);
+
+ // 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");
+
+ // 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.");
+
+ // creds array
+ cborEncoderResult = cbor_encoder_create_array(&credRootMap, &credArray, OicSecCredCount(cred));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Array.");
+
+ while (cred)
+ {
+ CborEncoder credMap;
+ size_t mapSize = CRED_MAP_SIZE;
+ size_t inLen = 0;
+ if (cred->period)
+ {
+ mapSize++;
+ }
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+#ifdef MULTIPLE_OWNER
+ if(cred->eownerID)
+ {
+ mapSize++;
+ }
+#endif //MULTIPLE_OWNER
+
+ if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
+ {
+ mapSize++;
+ }
+ if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
+ {
+ mapSize++;
+ }
+ if (cred->credUsage)
+ {
+ mapSize++;
+ }
+#endif /* __WITH_DTLS__ || __WITH_TLS__*/
+ 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.");
+ inLen = (memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0) ?
+ WILDCARD_SUBJECT_ID_LEN : sizeof(OicUuid_t);
+ if(inLen == WILDCARD_SUBJECT_ID_LEN)
+ {
+ cborEncoderResult = cbor_encode_text_string(&credMap, WILDCARD_RESOURCE_URI,
+ strlen(WILDCARD_RESOURCE_URI));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id wildcard Value.");
+ }
+ else
+ {
+ char *subject = NULL;
+ 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.");
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+ //PublicData -- Not Mandatory
+ if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
+ {
+ cborEncoderResult = SerializeEncodingToCbor(&credMap,
+ OIC_JSON_PUBLICDATA_NAME, &cred->publicData);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");
+ }
+ //OptionalData -- Not Mandatory
+ if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
+ {
+ cborEncoderResult = SerializeSecOptToCbor(&credMap,
+ OIC_JSON_OPTDATA_NAME, &cred->optionalData);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Tag.");
+ }
+ //CredUsage -- Not Mandatory
+ if(cred->credUsage)
+ {
+ cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDUSAGE_NAME,
+ strlen(OIC_JSON_CREDUSAGE_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Tag.");
+ cborEncoderResult = cbor_encode_text_string(&credMap, cred->credUsage,
+ strlen(cred->credUsage));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Value.");
+ }
+#endif /* __WITH_DTLS__ || __WITH_TLS__*/
+ //PrivateData -- Not Mandatory
+ if(!secureFlag && cred->privateData.data)
+ {
+ cborEncoderResult = SerializeEncodingToCbor(&credMap,
+ OIC_JSON_PRIVATEDATA_NAME, &cred->privateData);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
+ }
+
+ //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.");
+ }
+
+#ifdef MULTIPLE_OWNER
+ // Eownerid -- Not Mandatory
+ if(cred->eownerID)
+ {
+ char *eowner = NULL;
+ cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_EOWNERID_NAME,
+ strlen(OIC_JSON_EOWNERID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding eownerId Name Tag.");
+ ret = ConvertUuidToStr(cred->eownerID, &eowner);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ cborEncoderResult = cbor_encode_text_string(&credMap, eowner, strlen(eowner));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding eownerId Value.");
+ OICFree(eowner);
+ }
+#endif //MULTIPLE_OWNER
+
+ cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Map.");
+
+ cred = cred->next;
+ }
+ cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array.");
+
+ cred = credS;
+
+ // Rownerid
+ {
+ 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);
+ }
+
+ //RT -- Mandatory
+ CborEncoder rtArray;
+ cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_RT_NAME,
+ strlen(OIC_JSON_RT_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
+ cborEncoderResult = cbor_encoder_create_array(&credRootMap, &rtArray, 1);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
+ for (size_t i = 0; i < 1; i++)
+ {
+ cborEncoderResult = cbor_encode_text_string(&rtArray, OIC_RSRC_TYPE_SEC_CRED,
+ strlen(OIC_RSRC_TYPE_SEC_CRED));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Value.");
+ }
+ cborEncoderResult = cbor_encoder_close_container(&credRootMap, &rtArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");
+
+ //IF-- Mandatory
+ CborEncoder ifArray;
+ cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_IF_NAME,
+ strlen(OIC_JSON_IF_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
+ cborEncoderResult = cbor_encoder_create_array(&credRootMap, &ifArray, 1);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
+ for (size_t i = 0; i < 1; i++)
+ {
+ cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
+ strlen(OC_RSRVD_INTERFACE_DEFAULT));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Value.");
+ }
+ cborEncoderResult = cbor_encoder_close_container(&credRootMap, &ifArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing IF.");
+
+
+ // Close CRED Root Map
+ cborEncoderResult = cbor_encoder_close_container(&encoder, &credRootMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing CRED Root Map.");
+
+ if (CborNoError == cborEncoderResult)
+ {
+ OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed");
+ *cborPayload = outPayload;
+ *cborSize = cbor_encoder_get_buffer_size(&encoder, 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 += cbor_encoder_get_buffer_size(&encoder, encoder.end);
+ cborEncoderResult = CborNoError;
+ ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
+ *cborSize = cborLen;
+ }
+
+ if (CborNoError != cborEncoderResult)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
+ OICFree(outPayload);
+ outPayload = NULL;
+ *cborSize = 0;
+ *cborPayload = NULL;
+ ret = OC_STACK_ERROR;
+ }
+
+ return ret;
+}
+
+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;
+ }
+
+ OCStackResult ret = OC_STACK_ERROR;
+ CborValue credCbor = { .parser = NULL };
+ CborParser parser = { .end = NULL };
+ CborError cborFindResult = CborNoError;
+ cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
+
+ OicSecCred_t *headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
+ VERIFY_NON_NULL(TAG, headCred, ERROR);
+
+ // 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.");
+
+ while (cbor_value_is_valid(&CredRootMap))
+ {
+ char* tagName = NULL;
+ size_t len = 0;
+ CborType type = cbor_value_get_type(&CredRootMap);
+ if (type == CborTextStringType && cbor_value_is_text_string(&CredRootMap))
+ {
+ 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)
+ {
+ // 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))
+ {
+ 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));
+ VERIFY_NON_NULL(TAG, cred, ERROR);
+ OicSecCred_t *temp = headCred;
+ while (temp->next)
+ {
+ temp = temp->next;
+ }
+ temp->next = cred;
+ }
+
+ while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&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)
+ {
+ uint64_t credId = 0;
+ cborFindResult = cbor_value_get_uint64(&credMap, &credId);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId.");
+ cred->credId = (uint16_t)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.");
+ if(strcmp(subjectid, WILDCARD_RESOURCE_URI) == 0)
+ {
+ cred->subject.id[0] = '*';
+ }
+ else
+ {
+ ret = ConvertStrToUuid(subjectid, &cred->subject);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ }
+ OICFree(subjectid);
+ }
+ // credtype
+ if (strcmp(name, OIC_JSON_CREDTYPE_NAME) == 0)
+ {
+#ifdef __TIZENRT__
+ cborFindResult = cbor_value_get_int(&credMap, (int *) &cred->credType);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
+#else
+ uint64_t credType = 0;
+ cborFindResult = cbor_value_get_uint64(&credMap, &credType);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
+ cred->credType = (OicSecCredType_t)credType;
+#endif
+ }
+ // privatedata
+ if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME) == 0)
+ {
+ cborFindResult = DeserializeEncodingFromCbor(&credMap, &cred->privateData);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read privateData structure");
+
+ OicEncodingType_t encoding = cred->privateData.encoding;
+ if (OIC_ENCODING_DER == encoding || OIC_ENCODING_PEM == encoding)
+ {
+ //For unit test
+ cred->privateData.encoding = OIC_ENCODING_RAW;
+ OIC_LOG(WARNING, TAG, "Unknown encoding type detected for private data.");
+ }
+ }
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+ //PublicData -- Not Mandatory
+ if (strcmp(name, OIC_JSON_PUBLICDATA_NAME) == 0)
+ {
+ cborFindResult = DeserializeEncodingFromCbor(&credMap, &cred->publicData);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read publicData structure");
+ }
+ //OptionalData -- Not Mandatory
+ if (strcmp(name, OIC_JSON_OPTDATA_NAME) == 0)
+ {
+ cborFindResult = DeserializeSecOptFromCbor(&credMap, &cred->optionalData);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read optionalData structure");
+ }
+ //Credusage -- Not Mandatory
+ if (0 == strcmp(OIC_JSON_CREDUSAGE_NAME, name))
+ {
+ cborFindResult = cbor_value_dup_text_string(&credMap, &cred->credUsage, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
+ }
+#endif //__WITH_DTLS__ || __WITH_TLS__
+
+ 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.");
+ }
+
+#ifdef MULTIPLE_OWNER
+ // Eowner uuid -- Not Mandatory
+ if (strcmp(OIC_JSON_EOWNERID_NAME, name) == 0 && cbor_value_is_text_string(&credMap))
+ {
+ char *eowner = NULL;
+ cborFindResult = cbor_value_dup_text_string(&credMap, &eowner, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding eownerId Value.");
+ if(NULL == cred->eownerID)
+ {
+ cred->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
+ VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
+ }
+ ret = ConvertStrToUuid(eowner, cred->eownerID);
+ OICFree(eowner);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
+ }
+#endif //MULTIPLE_OWNER
+
+ 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.");
+ }
+ }
+ }
+
+ //ROwner -- Mandatory
+ if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0 && cbor_value_is_text_string(&CredRootMap))
+ {
+ char *stRowner = NULL;
+ cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
+
+ ret = ConvertStrToUuid(stRowner, &headCred->rownerID);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ OICFree(stRowner);
+ }
+ else if (NULL != gCred)
+ {
+ memcpy(&(headCred->rownerID), &(gCred->rownerID), sizeof(OicUuid_t));
+ }
+ 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:
+ if (CborNoError != cborFindResult)
+ {
+ DeleteCredList(headCred);
+ headCred = NULL;
+ *secCred = NULL;
+ ret = OC_STACK_ERROR;
+ }
+
+ return ret;
+}
+
+#ifdef MULTIPLE_OWNER
+bool IsValidCredentialAccessForSubOwner(const OicUuid_t* uuid, const uint8_t *cborPayload, size_t size)
+{
+ OicSecCred_t* cred = NULL;
+ bool isValidCred = false;
+
+ OIC_LOG_BUFFER(DEBUG, TAG, cborPayload, size);
+
+ VERIFY_NON_NULL(TAG, uuid, ERROR);
+ VERIFY_NON_NULL(TAG, cborPayload, ERROR);
+ VERIFY_SUCCESS(TAG, 0 != size, ERROR);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == CBORPayloadToCred(cborPayload, size, &cred), ERROR);
+ VERIFY_NON_NULL(TAG, cred, ERROR);
+ VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
+ VERIFY_SUCCESS(TAG, (memcmp(cred->eownerID->id, uuid->id, sizeof(uuid->id)) == 0), ERROR);
+
+ isValidCred = true;
+
+exit:
+ DeleteCredList(cred);
+
+ return isValidCred;
+
+}
+#endif //MULTIPLE_OWNER
+
+OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
+ const OicSecKey_t * publicData, const OicSecKey_t* privateData,
+ const OicUuid_t * rownerID, const OicUuid_t * eownerID)
+{
+ OIC_LOG(DEBUG, TAG, "IN GenerateCredential");
+
+ (void)publicData;
+ OCStackResult ret = OC_STACK_ERROR;
+
+ 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
+ //credential list and updating svr database in AddCredential().
+ cred->credId = 0;
+
+ VERIFY_NON_NULL(TAG, subject, ERROR);
+ memcpy(cred->subject.id, subject->id , sizeof(cred->subject.id));
+
+ VERIFY_SUCCESS(TAG, credType < (NO_SECURITY_MODE | SYMMETRIC_PAIR_WISE_KEY |
+ SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
+ cred->credType = credType;
+
+#ifdef __WITH_DTLS__
+ if (publicData && publicData->data)
+ {
+ cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
+ VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
+ memcpy(cred->publicData.data, publicData->data, publicData->len);
+ cred->publicData.len = publicData->len;
+ }
+#endif // __WITH_DTLS__
+
+ if (privateData && privateData->data)
+ {
+ cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
+ VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
+ memcpy(cred->privateData.data, privateData->data, privateData->len);
+ cred->privateData.len = privateData->len;
+ cred->privateData.encoding = OIC_ENCODING_RAW;
+ }
+
+ VERIFY_NON_NULL(TAG, rownerID, ERROR);
+ memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
+
+#ifdef MULTIPLE_OWNER
+ if(eownerID)
+ {
+ cred->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
+ VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
+ memcpy(cred->eownerID->id, eownerID->id, sizeof(eownerID->id));
+ }
+#else
+ (void)(eownerID);
+#endif //MULTIPLE_OWNER_
+
+ ret = OC_STACK_OK;
+
+ OIC_LOG_V(DEBUG, TAG, "GenerateCredential : result: %d", ret);
+ OIC_LOG_V(DEBUG, TAG, "GenerateCredential : credId: %d", cred->credId);
+ OIC_LOG_V(DEBUG, TAG, "GenerateCredential : credType: %d", cred->credType);
+ OIC_LOG_BUFFER(DEBUG, TAG, cred->subject.id, sizeof(cred->subject.id));
+ if (cred->privateData.data)
+ {
+ OIC_LOG_V(DEBUG, TAG, "GenerateCredential : privateData len: %zd", cred->privateData.len);
+ OIC_LOG_BUFFER(DEBUG, TAG, cred->privateData.data, cred->privateData.len);
+ }
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+ if(cred->credUsage)
+ {
+ OIC_LOG_V(DEBUG, TAG, "GenerateCredential : credUsage: %s", cred->credUsage);
+ }
+ if (cred->publicData.data)
+ {
+ OIC_LOG_V(DEBUG, TAG, "GenerateCredential : publicData len: %zd", cred->publicData.len);
+ OIC_LOG_BUFFER(DEBUG, TAG, cred->publicData.data, cred->publicData.len);
+
+ }
+ if (cred->optionalData.data)
+ {
+ OIC_LOG_V(DEBUG, TAG, "GenerateCredential : optionalData len: %zd", cred->optionalData.len);
+ OIC_LOG_BUFFER(DEBUG, TAG, cred->optionalData.data, cred->optionalData.len);
+ OIC_LOG_V(DEBUG, TAG, "GenerateCredential : optionalData revstat: %d", cred->optionalData.revstat);
+ }
+#endif //defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+
+exit:
+ if (OC_STACK_OK != ret)
+ {
+ DeleteCredList(cred);
+ cred = NULL;
+ }
+ OIC_LOG(DEBUG, TAG, "OUT GenerateCredential");
+ return cred;
+}
+
+static bool UpdatePersistentStorage(const OicSecCred_t *cred)
+{
+ bool ret = false;
+ OIC_LOG(DEBUG, TAG, "IN Cred UpdatePersistentStorage");
+
+ // Convert Cred data into JSON for update to persistent storage
+ if (cred)
+ {
+ uint8_t *payload = NULL;
+ // This added '512' is arbitrary value that is added to cover the name of the resource, map addition and ending
+ size_t size = GetCredKeyDataSize(cred);
+ size += (512 * OicSecCredCount(cred));
+ OIC_LOG_V(INFO, TAG, "target cred size: %zu - temporal size to make room for encoding", size);
+
+ int secureFlag = 0;
+ OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
+ if ((OC_STACK_OK == res) && payload)
+ {
+ if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
+ {
+ ret = true;
+ }
+ OICClearMemory(payload, size);
+ OICFree(payload);
+ }
+ }
+ else //Empty cred list
+ {
+ if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
+ {
+ ret = true;
+ }
+ }
+ OIC_LOG(DEBUG, TAG, "OUT Cred UpdatePersistentStorage");
+ return ret;
+}
+
+/**
+ * Compare function used LL_SORT for sorting credentials.
+ *
+ * @param first pointer to OicSecCred_t struct.
+ * @param second pointer to OicSecCred_t struct.
+ *
+ *@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)
+ {
+ return -1;
+ }
+ else if (first->credId > second->credId)
+ {
+ return 1;
+ }
+ else
+ return 0;
+}
+
+/**
+ * GetCredId goes through the cred list and returns the next
+ * available credId. The next credId could be the credId that is
+ * available due deletion of OicSecCred_t object or one more than
+ * credId of last credential in the list.
+ *
+ * @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)
+ {
+ nextCredId += 1;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ VERIFY_SUCCESS(TAG, nextCredId < UINT16_MAX, ERROR);
+ return nextCredId;
+
+exit:
+ return 0;
+}
+
+/**
+ * Get the default value.
+ *
+ * @return NULL for now.
+ */
+static OicSecCred_t* GetCredDefault()
+{
+ // TODO:Update it when we finalize the default info.
+ return NULL;
+}
+
+static bool IsSameSecOpt(const OicSecOpt_t* sk1, const OicSecOpt_t* sk2)
+{
+ VERIFY_NON_NULL(TAG, sk1, WARNING);
+ VERIFY_NON_NULL(TAG, sk2, WARNING);
+
+ VERIFY_SUCCESS(TAG, (sk1->len == sk2->len), INFO);
+ VERIFY_SUCCESS(TAG, (sk1->encoding == sk2->encoding), INFO);
+ VERIFY_SUCCESS(TAG, (0 == memcmp(sk1->data, sk2->data, sk1->len)), INFO);
+ return true;
+exit:
+ return false;
+}
+
+static bool IsSameSecKey(const OicSecKey_t* sk1, const OicSecKey_t* sk2)
+{
+ VERIFY_NON_NULL(TAG, sk1, WARNING);
+ VERIFY_NON_NULL(TAG, sk2, WARNING);
+
+ VERIFY_SUCCESS(TAG, (sk1->len == sk2->len), INFO);
+ VERIFY_SUCCESS(TAG, (sk1->encoding == sk2->encoding), INFO);
+ VERIFY_SUCCESS(TAG, (0 == memcmp(sk1->data, sk2->data, sk1->len)), INFO);
+ return true;
+exit:
+ return false;
+}
+
+/**
+ * Compares credential
+ *
+ * @return CRED_CMP_EQUAL if credentials are equal
+ * CRED_CMP_NOT_EQUAL if not equal
+ * otherwise error.
+ */
+
+static CredCompareResult_t CompareCredential(const OicSecCred_t * l, const OicSecCred_t * r)
+{
+ CredCompareResult_t cmpResult = CRED_CMP_ERROR;
+ bool isCompared = false;
+ OIC_LOG(DEBUG, TAG, "IN CompareCredetial");
+
+ VERIFY_NON_NULL(TAG, l, ERROR);
+ VERIFY_NON_NULL(TAG, r, ERROR);
+
+ cmpResult = CRED_CMP_NOT_EQUAL;
+
+ VERIFY_SUCCESS(TAG, (l->credType == r->credType), INFO);
+ VERIFY_SUCCESS(TAG, (0 == memcmp(l->subject.id, r->subject.id, sizeof(l->subject.id))), INFO);
+
+ switch(l->credType)
+ {
+ case SYMMETRIC_PAIR_WISE_KEY:
+ case SYMMETRIC_GROUP_KEY:
+ case PIN_PASSWORD:
+ {
+ if(l->privateData.data && r->privateData.data)
+ {
+ VERIFY_SUCCESS(TAG, IsSameSecKey(&l->privateData, &r->privateData), INFO);
+ isCompared = true;
+ }
+ break;
+ }
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+ case ASYMMETRIC_KEY:
+ case SIGNED_ASYMMETRIC_KEY:
+ {
+ if(l->publicData.data && r->publicData.data)
+ {
+ VERIFY_SUCCESS(TAG, IsSameSecKey(&l->publicData, &r->publicData), INFO);
+ isCompared = true;
+ }
+
+ if(l->optionalData.data && r->optionalData.data)
+ {
+ VERIFY_SUCCESS(TAG, IsSameSecOpt(&l->optionalData, &r->optionalData), INFO);
+ isCompared = true;
+ }
+
+ if(l->credUsage && r->credUsage)
+ {
+ VERIFY_SUCCESS(TAG, (strlen(l->credUsage) == strlen(r->credUsage)), INFO);
+ VERIFY_SUCCESS(TAG, (0 == strncmp(l->credUsage, r->credUsage, strlen(l->credUsage))), INFO);
+ isCompared = true;
+ }
+ break;
+ }
+ case ASYMMETRIC_ENCRYPTION_KEY:
+ {
+ if(l->privateData.data && r->privateData.data)
+ {
+ VERIFY_SUCCESS(TAG, IsSameSecKey(&l->privateData, &r->privateData), INFO);
+ isCompared = true;
+ }
+
+ if(l->publicData.data && r->publicData.data)
+ {
+ VERIFY_SUCCESS(TAG, IsSameSecKey(&l->publicData, &r->publicData), INFO);
+ isCompared = true;
+ }
+
+ if(l->optionalData.data && r->optionalData.data)
+ {
+ VERIFY_SUCCESS(TAG, IsSameSecOpt(&l->optionalData, &r->optionalData), INFO);
+ isCompared = true;
+ }
+
+ break;
+ }
+#endif //__WITH_DTLS__ or __WITH_TLS__
+ default:
+ {
+ OIC_LOG_V(ERROR, TAG, "Invalid CredType(%d)", l->credType);
+ cmpResult = CRED_CMP_ERROR;
+ goto exit;
+ }
+ }
+
+ if(isCompared)
+ {
+ OIC_LOG(DEBUG, TAG, "Same Credentials");
+ cmpResult = CRED_CMP_EQUAL;
+ }
+ else
+ {
+ OIC_LOG(DEBUG, TAG, "Can not find the key data in credential");
+ cmpResult = CRED_CMP_ERROR;
+ }
+exit:
+ OIC_LOG(DEBUG, TAG, "OUT CompareCredetial");
+
+ return cmpResult;
+}
+
+OCStackResult AddCredential(OicSecCred_t * newCred)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+ OicSecCred_t * temp = NULL;
+ bool validFlag = true;
+ OicUuid_t emptyOwner = { .id = {0} };
+
+ OIC_LOG(DEBUG, TAG, "IN AddCredential");
+
+ VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
+ //Assigning credId to the newCred
+ newCred->credId = GetCredId();
+ VERIFY_SUCCESS(TAG, true == IsValidCredential(newCred), ERROR);
+
+ //the newCred is not valid if it is empty
+
+ if (memcmp(&(newCred->subject), &emptyOwner, sizeof(OicUuid_t)) == 0)
+ {
+ validFlag = false;
+ }
+ else
+ {
+ OicSecCred_t *prev = NULL;
+ LL_FOREACH(gCred, temp)
+ {
+ CredCompareResult_t cmpRes = CompareCredential(temp, newCred);
+ if(CRED_CMP_EQUAL == cmpRes)
+ {
+ OIC_LOG_V(WARNING, TAG, "Detected same credential ID(%d)" \
+ "new credential's ID will be replaced.", temp->credId);
+ newCred->credId = temp->credId;
+ newCred->next = temp->next;
+
+ if(NULL == prev)
+ {
+ gCred = newCred;
+ }
+ else
+ {
+ prev->next = newCred;
+ }
+
+ FreeCred(temp);
+ ret = OC_STACK_OK;
+ validFlag = false;
+ break;
+ }
+
+ if (CRED_CMP_ERROR == cmpRes)
+ {
+ OIC_LOG_V(WARNING, TAG, "Credential skipped : %d", cmpRes);
+ ret = OC_STACK_ERROR;
+ validFlag = false;
+ break;
+ }
+
+ prev = temp;
+ }
+ }
+
+ //Append the new Cred to existing list if new Cred is valid
+ if (validFlag)
+ {
+ OIC_LOG(INFO, TAG, "New credentials are added to the cred resource");
+ LL_APPEND(gCred, newCred);
+ }
+ if (memcmp(&(newCred->rownerID), &emptyOwner, sizeof(OicUuid_t)) != 0)
+ {
+ memcpy(&(gCred->rownerID), &(newCred->rownerID), sizeof(OicUuid_t));
+ }
+ if (UpdatePersistentStorage(gCred))
+ {
+ OIC_LOG(DEBUG, TAG, "UpdatePersistentStorage() Success");
+ ret = OC_STACK_OK;
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "UpdatePersistentStorage() Failed");
+ LL_DELETE(gCred, newCred);
+ ret = OC_STACK_INCONSISTENT_DB;
+ }
+exit:
+ OIC_LOG(DEBUG, TAG, "OUT AddCredential");
+ return ret;
+}
+
+OCStackResult RemoveCredential(const OicUuid_t *subject)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+ OicSecCred_t *cred = NULL;
+ OicSecCred_t *tempCred = NULL;
+ bool deleteFlag = false;
+
+ LL_FOREACH_SAFE(gCred, cred, tempCred)
+ {
+ if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
+ {
+ LL_DELETE(gCred, cred);
+ FreeCred(cred);
+ deleteFlag = 1;
+ }