//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#include "iotivity_config.h"
+#include "iotivity_debug.h"
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#endif
-#ifdef __WITH_DTLS__
-#include "global.h"
-#endif
-
#include "ocstack.h"
#include "oic_malloc.h"
#include "payload_logging.h"
#include "resourcemanager.h"
#include "doxmresource.h"
#include "pstatresource.h"
+#include "deviceonboardingstate.h"
#include "aclresource.h"
#include "amaclresource.h"
#include "pconfresource.h"
#include "srmutility.h"
#include "pinoxmcommon.h"
#include "oxmverifycommon.h"
-
#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+#include <mbedtls/ssl_ciphersuites.h>
+#include <mbedtls/md.h>
#include "pkix_interface.h"
#endif
/** Max cbor size payload. */
static const uint16_t CBOR_MAX_SIZE = 4400;
+#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+/** MAX uuid seed size */
+#define MAX_UUID_SEED_SIZE (64)
+/** MIN uuid seed size */
+#define MIN_UUID_SEED_SIZE (8)
+
+/** Buffer to save the seed of device UUID */
+static uint8_t gUuidSeed[MAX_UUID_SEED_SIZE];
+static size_t gUuidSeedSize = 0;
+#endif
+
static OicSecDoxm_t *gDoxm = NULL;
static OCResourceHandle gDoxmHandle = NULL;
-static OicSecOxm_t gOicSecDoxmJustWorks = OIC_JUST_WORKS;
+static OicSecOxm_t gDoxmDefaultOxm = OIC_RANDOM_DEVICE_PIN;
static OicSecDoxm_t gDefaultDoxm =
{
NULL, /* OicUrn_t *oxmType */
0, /* size_t oxmTypeLen */
- &gOicSecDoxmJustWorks, /* uint16_t *oxm */
+ &gDoxmDefaultOxm, /* uint16_t *oxm */
1, /* size_t oxmLen */
- OIC_JUST_WORKS, /* uint16_t oxmSel */
+ OIC_RANDOM_DEVICE_PIN, /* uint16_t oxmSel */
SYMMETRIC_PAIR_WISE_KEY,/* OicSecCredType_t sct */
false, /* bool owned */
{.id = {0}}, /* OicUuid_t deviceID */
{.id = {0}}, /* OicUuid_t rownerID */
};
+#define R PERMISSION_READ
+#define W PERMISSION_WRITE
+#define RW PERMISSION_READ | PERMISSION_WRITE
+
+// NOTE that this table must match the DoxmProperty_t enum in doxmresource.h
+static const uint8_t gDoxmPropertyAccessModes[DOXM_PROPERTY_COUNT][DOS_STATE_COUNT] =
+{ // RESET RFOTM RFPRO RFNOP SRESET
+ { R, R, R, R, R }, // .oxmtype TODO [IOT-2105]
+ { R, R, R, R, R }, // .oxms
+ { R, RW, R, R, R }, // .oxmsel
+ { R, R, R, R, R }, // .sct
+ { R, RW, R, R, R }, // .owned
+#ifdef MULTIPLE_OWNER
+ { RW, RW, RW, RW, RW }, // .subowner
+ { RW, RW, RW, RW, RW }, // .mom
+#endif // MULTIPLE_OWNER
+ { R, RW, R, R, R }, // .deviceuuid
+ { R, RW, R, R, R }, // .devowneruuid
+ { R, RW, R, R, RW } // .rowneruuid
+};
+
+#undef R
+#undef W
+#undef RW
+
+static bool IsPropertyReadOnly(DoxmProperty_t p,
+ OicSecDeviceOnboardingState_t s)
+{
+ bool ret = false;
+
+ if (PERMISSION_READ == gDoxmPropertyAccessModes[p][s])
+ {
+ OIC_LOG_V(DEBUG, TAG, "%s: property %d is read-only in state %d.",
+ __func__, p, s);
+ ret = true;
+ }
+
+ return ret;
+}
+
/**
- * This method is internal method.
- * the param roParsed is optionally used to know whether cborPayload has
- * at least read only property value or not.
- */
+ * Internal method converts CBOR into DOXM data, and determines if a read-only
+ * Property was parsed in the CBOR payload.
+ *
+ * @param[in] cborPayload The doxm data in cbor format.
+ * @param[in] size Size of the cborPayload. In case 0 is provided it assigns CBOR_SIZE (255) value.
+ * @param[out] doxm Pointer to @ref OicSecDoxm_t.
+ * @param[out] roParsed Ptr to bool marked "true" iff a read-only Property is parsed
+ * @param[in] stateForReadOnlyCheck The state to use when determining if a Property is
+ * read-only.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
+*/
static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t size,
- OicSecDoxm_t **doxm, bool *roParsed);
+ OicSecDoxm_t **doxm, bool *roParsed,
+ OicSecDeviceOnboardingState_t stateForReadOnlyCheck);
void DeleteDoxmBinData(OicSecDoxm_t* doxm)
{
}
}
-OCStackResult DoxmToCBORPayload(const OicSecDoxm_t *doxm, uint8_t **payload, size_t *size,
- bool rwOnly)
+OCStackResult DoxmToCBORPayloadPartial(const OicSecDoxm_t *doxm,
+ uint8_t **payload, size_t *size, const bool *propertiesToInclude)
{
if (NULL == doxm || NULL == payload || NULL != *payload || NULL == size)
{
int64_t cborEncoderResult = CborNoError;
uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
- VERIFY_NON_NULL(TAG, outPayload, ERROR);
+ VERIFY_NOT_NULL_RETURN(TAG, outPayload, ERROR, OC_STACK_ERROR);
+
cbor_encoder_init(&encoder, outPayload, cborLen, 0);
cborEncoderResult = cbor_encoder_create_map(&encoder, &doxmMap, CborIndefiniteLength);
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Map.");
- //OxmType -- Not Mandatory
- if (doxm->oxmTypeLen > 0)
+ // oxmtype
+ // TODO [IOT-2105]: resolve "oxmtype" undocumented tag/value
+ if (propertiesToInclude[DOXM_OXMTYPE] && doxm->oxmTypeLen > 0)
{
+ OIC_LOG_V(DEBUG, TAG, "%s: including %s.", __func__, OIC_JSON_OXM_TYPE_NAME);
CborEncoder oxmType;
cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_OXM_TYPE_NAME,
strlen(OIC_JSON_OXM_TYPE_NAME));
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmType Tag.");
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmtype Tag.");
cborEncoderResult = cbor_encoder_create_array(&doxmMap, &oxmType, doxm->oxmTypeLen);
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmType Array.");
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmtype Array.");
for (size_t i = 0; i < doxm->oxmTypeLen; i++)
{
cborEncoderResult = cbor_encode_text_string(&oxmType, doxm->oxmType[i],
strlen(doxm->oxmType[i]));
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmType Value.");
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmtype Value.");
}
cborEncoderResult = cbor_encoder_close_container(&doxmMap, &oxmType);
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing oxmType.");
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing oxmtype.");
}
- //Oxm -- Not Mandatory
- if (doxm->oxmLen > 0 && false == rwOnly)
+ // oxms Property
+ if (propertiesToInclude[DOXM_OXMS] && doxm->oxmLen > 0)
{
+ OIC_LOG_V(DEBUG, TAG, "%s: including %s Property.", __func__, OIC_JSON_OXMS_NAME);
CborEncoder oxm;
cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_OXMS_NAME,
strlen(OIC_JSON_OXMS_NAME));
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmName Tag.");
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxms Tag.");
cborEncoderResult = cbor_encoder_create_array(&doxmMap, &oxm, doxm->oxmLen);
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmName Array.");
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxms Array.");
for (size_t i = 0; i < doxm->oxmLen; i++)
{
cborEncoderResult = cbor_encode_int(&oxm, doxm->oxm[i]);
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmName Value");
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxms Value");
}
cborEncoderResult = cbor_encoder_close_container(&doxmMap, &oxm);
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing oxmName.");
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing oxms.");
}
- //OxmSel -- Mandatory
- cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_OXM_SEL_NAME,
- strlen(OIC_JSON_OXM_SEL_NAME));
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Sel Tag.");
- cborEncoderResult = cbor_encode_int(&doxmMap, doxm->oxmSel);
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Sel Value.");
+ // oxmsel Property
+ if (propertiesToInclude[DOXM_OXMSEL] && doxm->oxmLen > 0)
+ {
+ OIC_LOG_V(DEBUG, TAG, "%s: including %s Property.", __func__, OIC_JSON_OXM_SEL_NAME);
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_OXM_SEL_NAME,
+ strlen(OIC_JSON_OXM_SEL_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmsel Tag.");
+ cborEncoderResult = cbor_encode_int(&doxmMap, doxm->oxmSel);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmsel Value.");
+ }
- //sct -- Mandatory
- if (false == rwOnly)
+ // sct Property
+ if (propertiesToInclude[DOXM_SCT])
{
+ OIC_LOG_V(DEBUG, TAG, "%s: including %s Property.", __func__, OIC_JSON_SUPPORTED_CRED_TYPE_NAME);
cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_SUPPORTED_CRED_TYPE_NAME,
strlen(OIC_JSON_SUPPORTED_CRED_TYPE_NAME));
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag");
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding sct Tag");
cborEncoderResult = cbor_encode_int(&doxmMap, doxm->sct);
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding sct Value.");
}
- //Owned -- Mandatory
- cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_OWNED_NAME,
- strlen(OIC_JSON_OWNED_NAME));
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Owned Tag.");
- cborEncoderResult = cbor_encode_boolean(&doxmMap, doxm->owned);
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Owned Value.");
+ // owned Property
+ if (propertiesToInclude[DOXM_OWNED])
+ {
+ OIC_LOG_V(DEBUG, TAG, "%s: including %s Property.", __func__, OIC_JSON_OWNED_NAME);
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_OWNED_NAME,
+ strlen(OIC_JSON_OWNED_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding owned Tag.");
+ cborEncoderResult = cbor_encode_boolean(&doxmMap, doxm->owned);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding owned Value.");
+ }
- if (false == rwOnly)
+ // deviceuuid Property
+ if (propertiesToInclude[DOXM_DEVICEUUID])
{
- //DeviceId -- Mandatory
+ OIC_LOG_V(DEBUG, TAG, "%s: including %s Property.", __func__, OIC_JSON_DEVICE_ID_NAME);
cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_DEVICE_ID_NAME,
strlen(OIC_JSON_DEVICE_ID_NAME));
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Tag.");
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding deviceuuid Tag.");
ret = ConvertUuidToStr(&doxm->deviceID, &strUuid);
VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
cborEncoderResult = cbor_encode_text_string(&doxmMap, strUuid, strlen(strUuid));
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Value.");
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding deviceuuid Value.");
OICFree(strUuid);
strUuid = NULL;
}
#ifdef MULTIPLE_OWNER
//Device SubOwnerID -- Not Mandatory
- if(doxm->subOwners)
+ if(propertiesToInclude[DOXM_SUBOWNER] && doxm->subOwners)
{
+ OIC_LOG_V(DEBUG, TAG, "%s: including %s Property.", __func__, OIC_JSON_SUBOWNERID_NAME);
size_t subOwnerLen = 0;
OicSecSubOwner_t* subOwner = NULL;
LL_FOREACH(doxm->subOwners, subOwner)
subOwner = NULL;
LL_FOREACH(doxm->subOwners, subOwner)
{
- char* strUuid = NULL;
- ret = ConvertUuidToStr(&subOwner->uuid, &strUuid);
+ char* strSubOwnerUuid = NULL;
+ ret = ConvertUuidToStr(&subOwner->uuid, &strSubOwnerUuid);
VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
- cborEncoderResult = cbor_encode_text_string(&subOwners, strUuid, strlen(strUuid));
- OICFree(strUuid);
+ cborEncoderResult = cbor_encode_text_string(&subOwners, strSubOwnerUuid, strlen(strSubOwnerUuid));
+ OICFree(strSubOwnerUuid);
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SubOwnerId Value");
}
cborEncoderResult = cbor_encoder_close_container(&doxmMap, &subOwners);
}
//Multiple Owner Mode -- Not Mandatory
- if(doxm->mom)
+ if(propertiesToInclude[DOXM_MOM] && doxm->mom)
{
+ OIC_LOG_V(DEBUG, TAG, "%s: including %s Property.", __func__, OIC_JSON_MOM_NAME);
cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_MOM_NAME,
strlen(OIC_JSON_MOM_NAME));
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding mom Tag");
}
#endif //MULTIPLE_OWNER
- //devownerid -- Mandatory
- cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_DEVOWNERID_NAME,
- strlen(OIC_JSON_DEVOWNERID_NAME));
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Owner Id Tag.");
- ret = ConvertUuidToStr(&doxm->owner, &strUuid);
- VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
- cborEncoderResult = cbor_encode_text_string(&doxmMap, strUuid, strlen(strUuid));
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Owner Id Value.");
- OICFree(strUuid);
- strUuid = NULL;
-
- //ROwner -- Mandatory
- cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_ROWNERID_NAME,
- strlen(OIC_JSON_ROWNERID_NAME));
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ROwner Id Tag.");
- ret = ConvertUuidToStr(&doxm->rownerID, &strUuid);
- VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
- cborEncoderResult = cbor_encode_text_string(&doxmMap, strUuid, strlen(strUuid));
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ROwner Id Value.");
- OICFree(strUuid);
- strUuid = NULL;
+ // devowneruuid Property
+ if (propertiesToInclude[DOXM_DEVOWNERUUID])
+ {
+ OIC_LOG_V(DEBUG, TAG, "%s: including %s Property.", __func__, OIC_JSON_DEVOWNERID_NAME);
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_DEVOWNERID_NAME,
+ strlen(OIC_JSON_DEVOWNERID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding devowneruuid Tag.");
+ ret = ConvertUuidToStr(&doxm->owner, &strUuid);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, strUuid, strlen(strUuid));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding devowneruuid Value.");
+ OICFree(strUuid);
+ strUuid = NULL;
+ }
+
+ // rowneruuid Property
+ if (propertiesToInclude[DOXM_ROWNERUUID])
+ {
+ OIC_LOG_V(DEBUG, TAG, "%s: including %s Property.", __func__, OIC_JSON_ROWNERID_NAME);
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_ROWNERID_NAME,
+ strlen(OIC_JSON_ROWNERID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rowneruuid Tag.");
+ ret = ConvertUuidToStr(&doxm->rownerID, &strUuid);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, strUuid, strlen(strUuid));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rowneruuid Value.");
+ OICFree(strUuid);
+ strUuid = NULL;
+ }
//RT -- Mandatory
CborEncoder rtArray;
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");
//IF-- Mandatory
- CborEncoder ifArray;
- cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_IF_NAME,
- strlen(OIC_JSON_IF_NAME));
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
- cborEncoderResult = cbor_encoder_create_array(&doxmMap, &ifArray, 1);
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
+ CborEncoder ifArray;
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_IF_NAME,
+ strlen(OIC_JSON_IF_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
+ cborEncoderResult = cbor_encoder_create_array(&doxmMap, &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,
OIC_LOG(DEBUG, TAG, "Memory getting reallocated.");
// reallocate and try again!
OICFree(outPayload);
+ outPayload = NULL;
// Since the allocated initial memory failed, double the memory.
cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
OIC_LOG_V(DEBUG, TAG, "Doxm reallocation size : %zd.", cborLen);
cborEncoderResult = CborNoError;
- ret = DoxmToCBORPayload(doxm, payload, &cborLen, rwOnly);
+ ret = DoxmToCBORPayloadPartial(doxm, payload, &cborLen, propertiesToInclude);
*size = cborLen;
}
return ret;
}
+OCStackResult DoxmToCBORPayload(const OicSecDoxm_t *doxm,
+ uint8_t **payload, size_t *size)
+{
+ bool allProps[DOXM_PROPERTY_COUNT];
+
+ for (int i = 0; i < DOXM_PROPERTY_COUNT; i++)
+ {
+ allProps[i] = true;
+ }
+
+ allProps[DOXM_OXMTYPE] = false; // TODO [IOT-2105]: resolve "oxmtype" undocumented tag/value
+
+ return DoxmToCBORPayloadPartial(doxm, payload, size, allProps);
+}
+
OCStackResult CBORPayloadToDoxm(const uint8_t *cborPayload, size_t size,
OicSecDoxm_t **secDoxm)
{
- return CBORPayloadToDoxmBin(cborPayload, size, secDoxm, NULL);
+ return CBORPayloadToDoxmBin(cborPayload, size, secDoxm, NULL, DOS_RESET);
}
static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t size,
- OicSecDoxm_t **secDoxm, bool *roParsed)
+ OicSecDoxm_t **secDoxm, bool *roParsed,
+ OicSecDeviceOnboardingState_t stateForReadOnlyCheck)
{
if (NULL == cborPayload || NULL == secDoxm || NULL != *secDoxm || 0 == size)
{
cbor_parser_init(cborPayload, size, 0, &parser, &doxmCbor);
CborValue doxmMap;
OicSecDoxm_t *doxm = (OicSecDoxm_t *)OICCalloc(1, sizeof(*doxm));
- VERIFY_NON_NULL(TAG, doxm, ERROR);
+ VERIFY_NOT_NULL(TAG, doxm, ERROR);
cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_OXM_TYPE_NAME, &doxmMap);
- //OxmType -- not Mandatory
+ // OxmType
+ // TODO [IOT-2105]: resolve "oxmtype" undocumented tag/value
if (CborNoError == cborFindResult && cbor_value_is_array(&doxmMap))
{
+ OIC_LOG(DEBUG, TAG, "Found doxm.oxmtype tag in doxmMap.");
+
CborValue oxmType;
cborFindResult = cbor_value_get_array_length(&doxmMap, &doxm->oxmTypeLen);
VERIFY_SUCCESS(TAG, doxm->oxmTypeLen != 0, ERROR);
doxm->oxmType = (OicUrn_t *)OICCalloc(doxm->oxmTypeLen, sizeof(*doxm->oxmType));
- VERIFY_NON_NULL(TAG, doxm->oxmType, ERROR);
+ VERIFY_NOT_NULL(TAG, doxm->oxmType, ERROR);
cborFindResult = cbor_value_enter_container(&doxmMap, &oxmType);
VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering oxmType Array.")
int i = 0;
- size_t len = 0;
+ size_t oxmTypeStrlen = 0;
while (cbor_value_is_valid(&oxmType) && cbor_value_is_text_string(&oxmType))
{
+ OIC_LOG_V(DEBUG, TAG, "Read doxm.oxmtype value = %s", oxmType);
cborFindResult = cbor_value_dup_text_string(&oxmType, &doxm->oxmType[i++],
- &len, NULL);
+ &oxmTypeStrlen, NULL);
VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding omxType text string.");
cborFindResult = cbor_value_advance(&oxmType);
VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing oxmType.");
}
cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_OXMS_NAME, &doxmMap);
- //Oxm -- not Mandatory
+
+ // oxms
if (CborNoError == cborFindResult && cbor_value_is_array(&doxmMap))
{
+ OIC_LOG(DEBUG, TAG, "Found doxm.oxms tag in doxmMap.");
CborValue oxm;
cborFindResult = cbor_value_get_array_length(&doxmMap, &doxm->oxmLen);
- VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding oxmName array Length.");
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding oxms array Length.");
VERIFY_SUCCESS(TAG, doxm->oxmLen != 0, ERROR);
doxm->oxm = (OicSecOxm_t *)OICCalloc(doxm->oxmLen, sizeof(*doxm->oxm));
- VERIFY_NON_NULL(TAG, doxm->oxm, ERROR);
+ VERIFY_NOT_NULL(TAG, doxm->oxm, ERROR);
cborFindResult = cbor_value_enter_container(&doxmMap, &oxm);
- VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering oxmName Array.")
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering oxms Array.")
int i = 0;
while (cbor_value_is_valid(&oxm) && cbor_value_is_integer(&oxm))
int tmp;
cborFindResult = cbor_value_get_int(&oxm, &tmp);
- VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding oxmName Value")
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding oxms Value")
+ OIC_LOG_V(DEBUG, TAG, "Read doxm.oxms value = %d", tmp);
doxm->oxm[i++] = (OicSecOxm_t)tmp;
cborFindResult = cbor_value_advance(&oxm);
- VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing oxmName.")
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing oxms.")
}
if (roParsed)
{
- *roParsed = true;
+ if (IsPropertyReadOnly(DOXM_OXMS, stateForReadOnlyCheck))
+ {
+ *roParsed = true;
+ }
}
}
else
{
- VERIFY_NON_NULL(TAG, gDoxm, ERROR);
+ VERIFY_NOT_NULL(TAG, gDoxm, ERROR);
doxm->oxm = (OicSecOxm_t *) OICCalloc(gDoxm->oxmLen, sizeof(*doxm->oxm));
- VERIFY_NON_NULL(TAG, doxm->oxm, ERROR);
+ VERIFY_NOT_NULL(TAG, doxm->oxm, ERROR);
doxm->oxmLen = gDoxm->oxmLen;
for (size_t i = 0; i < gDoxm->oxmLen; i++)
{
}
}
+ // oxmsel
cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_OXM_SEL_NAME, &doxmMap);
if (CborNoError == cborFindResult && cbor_value_is_integer(&doxmMap))
{
+ OIC_LOG(DEBUG, TAG, "Found doxm.oxmsel tag in doxmMap.");
+
int oxmSel;
cborFindResult = cbor_value_get_int(&doxmMap, &oxmSel);
VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Sel Name Value.")
+ OIC_LOG_V(DEBUG, TAG, "Read doxm.oxmsel value = %d", oxmSel);
doxm->oxmSel = (OicSecOxm_t)oxmSel;
+ if (roParsed)
+ {
+ if (IsPropertyReadOnly(DOXM_OXMSEL, stateForReadOnlyCheck))
+ {
+ *roParsed = true;
+ }
+ }
}
else // PUT/POST JSON may not have oxmsel so set it to the gDoxm->oxmSel
{
- VERIFY_NON_NULL(TAG, gDoxm, ERROR);
+ VERIFY_NOT_NULL(TAG, gDoxm, ERROR);
doxm->oxmSel = gDoxm->oxmSel;
}
+ // sct
cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_SUPPORTED_CRED_TYPE_NAME, &doxmMap);
if (CborNoError == cborFindResult && cbor_value_is_integer(&doxmMap))
{
+ OIC_LOG(DEBUG, TAG, "Found doxm.oxmsel tag in doxmMap.");
int sct;
cborFindResult = cbor_value_get_int(&doxmMap, &sct);
VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Sct Name Value.")
+ OIC_LOG_V(DEBUG, TAG, "Read doxm.sct value = %d", sct);
doxm->sct = (OicSecCredType_t)sct;
if (roParsed)
{
- *roParsed = true;
+ if (IsPropertyReadOnly(DOXM_SCT, stateForReadOnlyCheck))
+ {
+ *roParsed = true;
+ }
}
}
else // PUT/POST JSON may not have sct so set it to the gDoxm->sct
{
- VERIFY_NON_NULL(TAG, gDoxm, ERROR);
+ VERIFY_NOT_NULL(TAG, gDoxm, ERROR);
doxm->sct = gDoxm->sct;
}
+ // owned
cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_OWNED_NAME, &doxmMap);
if (CborNoError == cborFindResult && cbor_value_is_boolean(&doxmMap))
{
+ OIC_LOG(DEBUG, TAG, "Found doxm.owned tag in doxmMap.");
cborFindResult = cbor_value_get_boolean(&doxmMap, &doxm->owned);
VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Owned Value.")
+ OIC_LOG_V(DEBUG, TAG, "Read doxm.owned value = %s", doxm->owned?"true":"false");
+
+ if (roParsed)
+ {
+ if (IsPropertyReadOnly(DOXM_OWNED, stateForReadOnlyCheck))
+ {
+ *roParsed = true;
+ }
+ }
}
else // PUT/POST JSON may not have owned so set it to the gDomx->owned
{
- VERIFY_NON_NULL(TAG, gDoxm, ERROR);
+ VERIFY_NOT_NULL(TAG, gDoxm, ERROR);
doxm->owned = gDoxm->owned;
}
+ // deviceuuid
cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_DEVICE_ID_NAME, &doxmMap);
if (CborNoError == cborFindResult && cbor_value_is_text_string(&doxmMap))
{
+ OIC_LOG(DEBUG, TAG, "Found doxm.deviceuuid tag in doxmMap.");
cborFindResult = cbor_value_dup_text_string(&doxmMap, &strUuid , &len, NULL);
VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Device Id Value.");
- ret = ConvertStrToUuid(strUuid , &doxm->deviceID);
+ OIC_LOG_V(DEBUG, TAG, "Read doxm.deviceuuid value = %s", strUuid);
+ ret = ConvertStrToUuid(strUuid, &doxm->deviceID);
VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
OICFree(strUuid);
strUuid = NULL;
+
+ if (roParsed)
+ {
+ if (IsPropertyReadOnly(DOXM_DEVICEUUID, stateForReadOnlyCheck))
+ {
+ *roParsed = true;
+ }
+ }
}
else
{
- VERIFY_NON_NULL(TAG, gDoxm, ERROR);
+ VERIFY_NOT_NULL(TAG, gDoxm, ERROR);
memcpy(doxm->deviceID.id, &gDoxm->deviceID.id, sizeof(doxm->deviceID.id));
}
+ // devowneruuid
cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_DEVOWNERID_NAME, &doxmMap);
if (CborNoError == cborFindResult && cbor_value_is_text_string(&doxmMap))
{
+ OIC_LOG(DEBUG, TAG, "Found doxm.devowneruuid tag in doxmMap.");
cborFindResult = cbor_value_dup_text_string(&doxmMap, &strUuid , &len, NULL);
- VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Owner Value.");
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding devowneruuid Value.");
+ OIC_LOG_V(DEBUG, TAG, "Read doxm.devowneruuid value = %s", strUuid);
ret = ConvertStrToUuid(strUuid , &doxm->owner);
VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
OICFree(strUuid);
strUuid = NULL;
+
+ if (roParsed)
+ {
+ if (IsPropertyReadOnly(DOXM_DEVOWNERUUID, stateForReadOnlyCheck))
+ {
+ *roParsed = true;
+ }
+ }
}
else
{
- VERIFY_NON_NULL(TAG, gDoxm, ERROR);
+ VERIFY_NOT_NULL(TAG, gDoxm, ERROR);
memcpy(doxm->owner.id, gDoxm->owner.id, sizeof(doxm->owner.id));
}
cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_MOM_NAME, &doxmMap);
if(CborNoError == cborFindResult && cbor_value_is_integer(&doxmMap))
{
+ OIC_LOG(DEBUG, TAG, "Found doxm.mom tag in doxmMap.");
int mode = 0;
cborFindResult = cbor_value_get_int(&doxmMap, &mode);
VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding mom Name Value.")
if(NULL == doxm->mom)
{
doxm->mom = (OicSecMom_t*)OICCalloc(1, sizeof(OicSecMom_t));
- VERIFY_NON_NULL(TAG, doxm->mom, ERROR);
+ VERIFY_NOT_NULL(TAG, doxm->mom, ERROR);
}
doxm->mom->mode = (OicSecMomType_t)mode;
+ if (roParsed)
+ {
+ if (IsPropertyReadOnly(DOXM_MOM, stateForReadOnlyCheck))
+ {
+ *roParsed = true;
+ }
+ }
}
else if(NULL != gDoxm && NULL != gDoxm->mom)
{
if(NULL == doxm->mom)
{
doxm->mom = (OicSecMom_t*)OICCalloc(1, sizeof(OicSecMom_t));
- VERIFY_NON_NULL(TAG, doxm->mom, ERROR);
+ VERIFY_NOT_NULL(TAG, doxm->mom, ERROR);
}
doxm->mom->mode = gDoxm->mom->mode;
}
cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_SUBOWNERID_NAME, &doxmMap);
if(CborNoError == cborFindResult && cbor_value_is_array(&doxmMap))
{
+ OIC_LOG(DEBUG, TAG, "Found doxm.subowner tag in doxmMap.");
size_t subOwnerLen = 0;
CborValue subOwnerCbor;
cborFindResult = cbor_value_get_array_length(&doxmMap, &subOwnerLen);
{
OCStackResult convertRes = OC_STACK_ERROR;
OicSecSubOwner_t* subOwner = NULL;
- char* strUuid = NULL;
+ char* strSubOwnerUuid = NULL;
size_t uuidLen = 0;
- cborFindResult = cbor_value_dup_text_string(&subOwnerCbor, &strUuid, &uuidLen, NULL);
+ cborFindResult = cbor_value_dup_text_string(&subOwnerCbor, &strSubOwnerUuid, &uuidLen, NULL);
VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SubOwnerId Value");
subOwner = (OicSecSubOwner_t*)OICCalloc(1, sizeof(OicSecSubOwner_t));
- VERIFY_NON_NULL(TAG, subOwner, ERROR);
+ VERIFY_NOT_NULL(TAG, subOwner, ERROR);
- convertRes = ConvertStrToUuid(strUuid, &subOwner->uuid);
+ convertRes = ConvertStrToUuid(strSubOwnerUuid, &subOwner->uuid);
VERIFY_SUCCESS(TAG, OC_STACK_OK == convertRes, ERROR);
subOwner->status = MOT_STATUS_DONE;
LL_APPEND(doxm->subOwners, subOwner);
cborFindResult = cbor_value_advance(&subOwnerCbor);
VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing SubOwnerId.")
}
+ if (roParsed)
+ {
+ if (IsPropertyReadOnly(DOXM_SUBOWNER, stateForReadOnlyCheck))
+ {
+ *roParsed = true;
+ }
+ }
}
else if(NULL != gDoxm && NULL != gDoxm->subOwners)
{
LL_FOREACH(gDoxm->subOwners, subOwnerItor)
{
OicSecSubOwner_t* subOwnerId = (OicSecSubOwner_t*)OICCalloc(1, sizeof(OicSecSubOwner_t));
- VERIFY_NON_NULL(TAG, subOwnerId, ERROR);
+ VERIFY_NOT_NULL(TAG, subOwnerId, ERROR);
memcpy(&subOwnerId->uuid, &subOwnerItor->uuid, sizeof(OicUuid_t));
subOwnerId->status = MOT_STATUS_DONE;
}
#endif //MULTIPLE_OWNER
+ // rowneruuid
cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_ROWNERID_NAME, &doxmMap);
if (CborNoError == cborFindResult && cbor_value_is_text_string(&doxmMap))
{
+ OIC_LOG(DEBUG, TAG, "Found doxm.rowneruuid tag in doxmMap.");
cborFindResult = cbor_value_dup_text_string(&doxmMap, &strUuid , &len, NULL);
- VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ROwner Value.");
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding rowneruuid Value.");
+ OIC_LOG_V(DEBUG, TAG, "Read doxm.rowneruuid value = %s", strUuid);
ret = ConvertStrToUuid(strUuid , &doxm->rownerID);
VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
OICFree(strUuid);
strUuid = NULL;
+
+ if (roParsed)
+ {
+ if (IsPropertyReadOnly(DOXM_ROWNERUUID, stateForReadOnlyCheck))
+ {
+ *roParsed = true;
+ }
+ }
}
else
{
- VERIFY_NON_NULL(TAG, gDoxm, ERROR);
+ VERIFY_NOT_NULL(TAG, gDoxm, ERROR);
memcpy(doxm->rownerID.id, gDoxm->rownerID.id, sizeof(doxm->rownerID.id));
}
// Convert Doxm data into CBOR for update to persistent storage
uint8_t *payload = NULL;
size_t size = 0;
- OCStackResult res = DoxmToCBORPayload(doxm, &payload, &size, false);
+ OCStackResult res = DoxmToCBORPayload(doxm, &payload, &size);
if (payload && (OC_STACK_OK == res)
&& (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_DOXM_NAME, payload, size)))
{
bool bOwnedQry = false; // does querystring contains 'owned' query ?
bool bOwnedMatch = false; // does 'owned' query value matches with doxm.owned status?
- bool bDeviceIDQry = false; // does querystring contains 'deviceid' query ?
- bool bDeviceIDMatch = false; // does 'deviceid' query matches with doxm.deviceid ?
+ bool bDeviceIDQry = false; // does querystring contains 'deviceuuid' query ?
+ bool bDeviceIDMatch = false; // does 'deviceuuid' query matches with doxm.deviceuuid ?
bool bInterfaceQry = false; // does querystring contains 'if' query ?
bool bInterfaceMatch = false; // does 'if' query matches with oic.if.baseline ?
#ifdef MULTIPLE_OWNER
- bool bMotQry = false; // does querystring contains 'mom' and 'owned' query ?
bool bMotMatch = false; // does 'mom' query value is not '0' && does query value matches with doxm.owned status?
#endif //MULTIPLE_OWNER
#ifdef MULTIPLE_OWNER
if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_MOM_NAME, strlen(OIC_JSON_MOM_NAME)) == 0)
{
- bMotQry = true;
OicSecMomType_t momMode = (OicSecMomType_t)(parseIter.valPos[0] - CHAR_ZERO);
if(NULL != gDoxm->mom && momMode != gDoxm->mom->mode)
{
bDeviceIDQry = true;
OicUuid_t subject = {.id={0}};
+ if (sizeof(subject.id) < parseIter.valLen)
+ {
+ OIC_LOG (ERROR, TAG, "Subject ID length is too long");
+ return false;
+ }
memcpy(subject.id, parseIter.valPos, parseIter.valLen);
if (0 == memcmp(&gDoxm->deviceID.id, &subject.id, sizeof(gDoxm->deviceID.id)))
{
}
}
-#ifdef MULTIPLE_OWNER
- return ((bOwnedQry ? bOwnedMatch : true) &&
- (bDeviceIDQry ? bDeviceIDMatch : true) &&
- (bMotQry ? bMotMatch : true));
-#else
return ((bOwnedQry ? bOwnedMatch : true) &&
(bDeviceIDQry ? bDeviceIDMatch : true));
-#endif //MULTIPLE_OWNER
}
static OCEntityHandlerResult HandleDoxmGetRequest (const OCEntityHandlerRequest * ehRequest)
if (ehRet == OC_EH_OK)
{
- if (OC_STACK_OK != DoxmToCBORPayload(gDoxm, &payload, &size, false))
+ if (OC_STACK_OK != DoxmToCBORPayload(gDoxm, &payload, &size))
{
OIC_LOG(WARNING, TAG, "DoxmToCBORPayload failed in HandleDoxmGetRequest");
}
return ehRet;
}
-static void updateWriteableProperty(const OicSecDoxm_t* src, OicSecDoxm_t* dst)
+OCStackResult DoxmUpdateWriteableProperty(const OicSecDoxm_t* src, OicSecDoxm_t* dst)
{
+ OCStackResult result = OC_STACK_OK;
+
if(src && dst)
- {
- // update oxmsel
+ {
+ // Update oxmsel
dst->oxmSel = src->oxmSel;
- //update owner
+ // Update owner
memcpy(&(dst->owner), &(src->owner), sizeof(OicUuid_t));
- //update rowner
+ // Update rowner
memcpy(&(dst->rownerID), &(src->rownerID), sizeof(OicUuid_t));
- //update deviceuuid
+ // Update deviceuuid
memcpy(&(dst->deviceID), &(src->deviceID), sizeof(OicUuid_t));
- //Update owned status
+ // Update owned status
if(dst->owned != src->owned)
{
dst->owned = src->owned;
#ifdef MULTIPLE_OWNER
if(src->mom)
{
- OIC_LOG(DEBUG, TAG, "dectected 'mom' property");
+ OIC_LOG(DEBUG, TAG, "Detected 'mom' property");
if(NULL == dst->mom)
{
dst->mom = (OicSecMom_t*)OICCalloc(1, sizeof(OicSecMom_t));
- if(NULL != dst->mom)
+ if (NULL == dst->mom)
{
- dst->mom->mode = src->mom->mode;
+ result = OC_STACK_NO_MEMORY;
}
}
+
+ if (NULL != dst->mom)
+ {
+ dst->mom->mode = src->mom->mode;
+ }
}
#endif //MULTIPLE_OWNER
}
+
+ return result;
}
#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
if(CA_STATUS_OK == errorInfo->result)
{
- const CASecureEndpoint_t* authenticatedSubOwnerInfo = CAGetSecureEndpointData(object);
- if(authenticatedSubOwnerInfo)
+ CASecureEndpoint_t authenticationSubOwnerInfo;
+ CAResult_t caRes = CAGetSecureEndpointData(object, &authenticationSubOwnerInfo);
+ if (CA_STATUS_OK == caRes)
{
- if (0 == memcmp(authenticatedSubOwnerInfo->identity.id, gDoxm->owner.id,
- authenticatedSubOwnerInfo->identity.id_length))
+ if (0 == memcmp(authenticationSubOwnerInfo.identity.id, gDoxm->owner.id,
+ authenticationSubOwnerInfo.identity.id_length))
{
OIC_LOG(WARNING, TAG, "Super owner tried MOT, this request will be ignored.");
return;
LL_FOREACH(gDoxm->subOwners, subOwnerInst)
{
if(0 == memcmp(subOwnerInst->uuid.id,
- authenticatedSubOwnerInfo->identity.id,
- authenticatedSubOwnerInfo->identity.id_length))
+ authenticationSubOwnerInfo.identity.id,
+ authenticationSubOwnerInfo.identity.id_length))
{
break;
}
if(subOwnerInst)
{
char* strUuid = NULL;
- memcpy(subOwnerInst->uuid.id, authenticatedSubOwnerInfo->identity.id,
- authenticatedSubOwnerInfo->identity.id_length);
+ if (sizeof(subOwnerInst->uuid.id) < authenticationSubOwnerInfo.identity.id_length)
+ {
+ OIC_LOG(ERROR, TAG, "Identity id is too long");
+ return;
+ }
+ memcpy(subOwnerInst->uuid.id, authenticationSubOwnerInfo.identity.id,
+ authenticationSubOwnerInfo.identity.id_length);
if(OC_STACK_OK != ConvertUuidToStr(&subOwnerInst->uuid, &strUuid))
{
OIC_LOG(ERROR, TAG, "Failed to allocate memory.");
}
}
}
+ else
+ {
+ OIC_LOG_V(ERROR, TAG, "Could not CAGetSecureEndpointData: %d", caRes);
+ }
}
if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
return isValidOxmsel;
}
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+static void DoxmDTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
+{
+ OIC_LOG_V(DEBUG, TAG, "In %s(%p, %p)", __func__, endpoint, info);
+
+ if ((NULL != endpoint) && (NULL != info) && (CA_STATUS_OK == info->result))
+ {
+ /*
+ * Allow this OBT endpoint to bypass ACE checks for SVRs, while this
+ * device is not yet owned.
+ */
+ OC_VERIFY(CASetSecureEndpointAttribute(endpoint,
+ CA_SECURE_ENDPOINT_ATTRIBUTE_ADMINISTRATOR));
+ }
+
+ OIC_LOG_V(DEBUG, TAG, "Out %s(%p, %p)", __func__, endpoint, info);
+}
+
+static void RegisterOTMSslHandshakeCallback(CAErrorCallback callback)
+{
+ OC_VERIFY(CA_STATUS_OK == CAregisterSslHandshakeCallback(callback));
+}
+#endif // __WITH_DTLS__ or __WITH_TLS__
+
static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRequest)
{
OIC_LOG (DEBUG, TAG, "Doxm EntityHandle processing POST request");
- OCEntityHandlerResult ehRet = OC_EH_ERROR;
+ OCEntityHandlerResult ehRet = OC_EH_INTERNAL_SERVER_ERROR;
OicUuid_t emptyOwner = {.id = {0} };
static uint16_t previousMsgId = 0;
+ bool isDuplicatedMsg = false;
/*
* Convert CBOR Doxm data into binary. This will also validate
uint8_t *payload = ((OCSecurityPayload *)ehRequest->payload)->securityData;
size_t size = ((OCSecurityPayload *)ehRequest->payload)->payloadSize;
bool roParsed = false;
- OCStackResult res = CBORPayloadToDoxmBin(payload, size, &newDoxm, &roParsed);
+ OicSecDostype_t onboardingState;
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDos(&onboardingState), ERROR);
+ OCStackResult res = CBORPayloadToDoxmBin(payload, size, &newDoxm, &roParsed,
+ onboardingState.state);
if (newDoxm && OC_STACK_OK == res)
{
+ /*
+ * message ID is supported for CoAP over UDP only according to RFC 7252
+ * So we should check message ID to prevent duplicate request handling in case of OC_ADAPTER_IP.
+ * In case of other transport adapter, duplicate message check is not required.
+ */
+ if (OC_ADAPTER_IP == ehRequest->devAddr.adapter &&
+ previousMsgId == ehRequest->messageID)
+ {
+ isDuplicatedMsg = true;
+ }
+
// Check request on RO property
if (true == roParsed)
{
- OIC_LOG(ERROR, TAG, "Not acceptable request because of read-only propertys");
+ OIC_LOG(ERROR, TAG, "Not acceptable request because of read-only properties");
ehRet = OC_EH_NOT_ACCEPTABLE;
goto exit;
}
// in owned state
if (true == gDoxm->owned)
{
- //Update gDoxm based on newDoxm
- updateWriteableProperty(newDoxm, gDoxm);
+ if (false == ValidateOxmsel(gDoxm->oxm, gDoxm->oxmLen, &newDoxm->oxmSel))
+ {
+ OIC_LOG(ERROR, TAG, "Not acceptable request because oxmsel is not supported on Server");
+ ehRet = OC_EH_NOT_ACCEPTABLE;
+ goto exit;
+ }
+
+ // Update gDoxm based on newDoxm
+ res = DoxmUpdateWriteableProperty(newDoxm, gDoxm);
+ if (OC_STACK_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "gDoxm properties were not able to be updated so we cannot handle the request.");
+ ehRet = OC_EH_ERROR;
+ goto exit;
+ }
#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
#ifdef MULTIPLE_OWNER
VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
- caRes = CASelectCipherSuite((uint16_t)TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, ehRequest->devAddr.adapter);
+ RegisterOTMSslHandshakeCallback(DoxmDTLSHandshakeCB);
+ caRes = CASelectCipherSuite((uint16_t)MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, ehRequest->devAddr.adapter);
VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
OIC_LOG(INFO, TAG, "ECDHE_PSK CipherSuite will be used for MOT");
ehRet = OC_EH_ERROR;
goto exit;
}
- OIC_LOG (INFO, TAG, "Doxm EntityHandle enabling AnonECDHCipherSuite");
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+ RegisterOTMSslHandshakeCallback(DoxmDTLSHandshakeCB);
+ OIC_LOG(INFO, TAG, "Doxm EntityHandle enabling AnonECDHCipherSuite");
ehRet = (CAEnableAnonECDHCipherSuite(true) == CA_STATUS_OK) ? OC_EH_OK : OC_EH_ERROR;
#endif // __WITH_DTLS__ or __WITH_TLS__
goto exit;
* Disable anonymous ECDH cipher in tinyDTLS since device is now
* in owned state.
*/
+ RegisterOTMSslHandshakeCallback(NULL);
CAResult_t caRes = CA_STATUS_OK;
caRes = CAEnableAnonECDHCipherSuite(false);
VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
//In case of Mutual Verified Just-Works, verify mutualVerifNum
if (OIC_MV_JUST_WORKS == newDoxm->oxmSel && false == newDoxm->owned &&
- previousMsgId != ehRequest->messageID)
+ false == isDuplicatedMsg)
{
uint8_t preMutualVerifNum[OWNER_PSK_LENGTH_128] = {0};
uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN] = {0};
{
/*
* If current state of the device is un-owned, enable
- * anonymous ECDH cipher in tinyDTLS so that Provisioning
- * tool can initiate JUST_WORKS ownership transfer process.
+ * ECDHE_PSK cipher so that the Provisioning tool can
+ * initiate the ownership transfer.
*/
if(memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) == 0)
{
}
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
- CAResult_t caRes = CA_STATUS_OK;
-
- caRes = CAEnableAnonECDHCipherSuite(false);
+ CAResult_t caRes = CAEnableAnonECDHCipherSuite(false);
VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
- caRes = CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256,
+ RegisterOTMSslHandshakeCallback(DoxmDTLSHandshakeCB);
+ caRes = CASelectCipherSuite(MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
ehRequest->devAddr.adapter);
VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
- char ranPin[OXM_RANDOM_PIN_MAX_SIZE + 1] = {0};
- //TODO ehRequest->messageID for copa over TCP always is null. Find reason why.
- if(ehRequest->devAddr.adapter == OC_ADAPTER_IP && previousMsgId != ehRequest->messageID)
+ if (!isDuplicatedMsg)
{
- if(OC_STACK_OK == GeneratePin(ranPin, sizeof(ranPin)))
+ char ranPin[OXM_RANDOM_PIN_MAX_SIZE + 1] = {0};
+ if (OC_STACK_OK == GeneratePin(ranPin, sizeof(ranPin)))
{
//Set the device id to derive temporal PSK
SetUuidForPinBasedOxm(&gDoxm->deviceID);
ehRet = OC_EH_ERROR;
}
}
- else if(OC_ADAPTER_TCP == ehRequest->devAddr.adapter)
- {
- if(OC_STACK_OK == GeneratePin(ranPin, sizeof(ranPin)))
- {
- //Set the device id to derive temporal PSK
- SetUuidForPinBasedOxm(&gDoxm->deviceID);
-
- /**
- * Since PSK will be used directly by DTLS layer while PIN based ownership transfer,
- * Credential should not be saved into SVR.
- * For this reason, use a temporary get_psk_info callback to random PIN OxM.
- */
- caRes = CAregisterPskCredentialsHandler(GetDtlsPskForRandomPinOxm);
- VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
- ehRet = OC_EH_OK;
- }
- else
- {
- OIC_LOG(ERROR, TAG, "Failed to generate random PIN");
- ehRet = OC_EH_ERROR;
- }
-
- }
#endif // __WITH_DTLS__ or __WITH_TLS__
}
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
//Save the owner's UUID to derive owner credential
memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t));
+ // In case of random-pin based OTM, close the PIN display if callback is registered.
+ if (!isDuplicatedMsg)
+ {
+ ClosePinDisplay();
+ }
+
//Update new state in persistent storage
if (UpdatePersistentStorage(gDoxm) == true)
{
#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
else if (OIC_MANUFACTURER_CERTIFICATE == newDoxm->oxmSel || OIC_CON_MFG_CERT == newDoxm->oxmSel)
{
+ //In case of Confirm Manufacturer Cert, get user confirmation
+ if (OIC_CON_MFG_CERT == newDoxm->oxmSel && false == newDoxm->owned &&
+ false == isDuplicatedMsg &&
+ memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0)
+ {
+ if (OC_STACK_OK != VerifyOwnershipTransfer(NULL, USER_CONFIRM))
+ {
+ ehRet = OC_EH_NOT_ACCEPTABLE;
+ goto exit;
+ }
+ else
+ {
+ ehRet = OC_EH_OK;
+ }
+ }
+
//Save the owner's UUID to derive owner credential
memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t));
gDoxm->oxmSel = newDoxm->oxmSel;
OIC_LOG(WARNING, TAG, "Failed to update DOXM in persistent storage");
ehRet = OC_EH_ERROR;
}
+
+ RegisterOTMSslHandshakeCallback(NULL);
CAResult_t caRes = CAEnableAnonECDHCipherSuite(false);
VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
+ //Unset pre-selected ciphersuite, if any
+ caRes = CASelectCipherSuite(0, ehRequest->devAddr.adapter);
+ VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
+ OIC_LOG(DEBUG, TAG, "No ciphersuite preferred");
+
VERIFY_SUCCESS(TAG, CA_STATUS_OK == CAregisterPkixInfoHandler(GetManufacturerPkixInfo), ERROR);
VERIFY_SUCCESS(TAG, CA_STATUS_OK == CAregisterGetCredentialTypesHandler(InitManufacturerCipherSuiteList), ERROR);
-
- //In case of Confirm Manufacturer Cert, get user confirmation
- if (OIC_CON_MFG_CERT == newDoxm->oxmSel && false == newDoxm->owned &&
- previousMsgId != ehRequest->messageID &&
- memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0)
- {
- if (OC_STACK_OK != VerifyOwnershipTransfer(NULL, USER_CONFIRM))
- {
- ehRet = OC_EH_NOT_ACCEPTABLE;
- }
- else
- {
- ehRet = OC_EH_OK;
- }
- }
-
-
}
#endif // __WITH_DTLS__ or __WITH_TLS__
}
* Tool is attempting to change the state to 'Owned' with a
* qualified value for the field 'Owner'
*/
+ // TODO [IOT-2107] reconcile POST handler behavior with Specification
if ((false == gDoxm->owned) && (true == newDoxm->owned) &&
(memcmp(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t)) == 0))
{
ehRet = OC_EH_ERROR;
goto exit;
}
- ownerRes = SetAmaclRownerId(&gDoxm->owner);
- if(OC_STACK_OK != ownerRes && OC_STACK_NO_RESOURCE != ownerRes)
- {
- ehRet = OC_EH_ERROR;
- goto exit;
- }
ownerRes = SetCredRownerId(&gDoxm->owner);
if(OC_STACK_OK != ownerRes && OC_STACK_NO_RESOURCE != ownerRes)
{
{
OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request");
- if((OC_ADAPTER_IP == ehRequest->devAddr.adapter && previousMsgId != ehRequest->messageID)
- || OC_ADAPTER_TCP == ehRequest->devAddr.adapter)
+ if (!isDuplicatedMsg)
{
RestoreDoxmToInitState();
RestorePstatToInitState();
}
else
{
- previousMsgId = ehRequest->messageID++;
+ previousMsgId = ehRequest->messageID;
}
//Send payload to request originator
OIC_RSRC_DOXM_URI,
DoxmEntityHandler,
NULL,
- OC_SECURE |
+ OC_SECURE | OC_NONSECURE |
OC_DISCOVERABLE);
if (OC_STACK_OK != ret)
{
OCStackResult ret = OC_STACK_ERROR;
bool validId = false;
+
for (uint8_t i = 0; i < UUID_LENGTH; i++)
{
if (gDoxm->deviceID.id[i] != 0)
if (!validId)
{
+ char* strUuid = NULL;
+#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+ //If seed value is exists, generate UUID using seed with SHA256
+ if (0 != gUuidSeedSize)
+ {
+ uint8_t hashVal[MBEDTLS_MD_MAX_SIZE] = {0};
+ int mbedret = 0;
+
+ OIC_LOG(DEBUG, TAG, "UUID will be generated using seed w/ SHA256");
+ OIC_LOG(DEBUG, TAG, "Seed value : ");
+ OIC_LOG_BUFFER(DEBUG, TAG, gUuidSeed, gUuidSeedSize);
+
+ mbedret = mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
+ gUuidSeed, gUuidSeedSize, hashVal);
+ if(0 == mbedret)
+ {
+ memcpy(gDoxm->deviceID.id, hashVal, sizeof(gDoxm->deviceID.id));
+ ret = OC_STACK_OK;
+ }
+ else
+ {
+ OIC_LOG_V(ERROR, TAG, "mbedtls_md error : %d", mbedret);
+ ret = OC_STACK_ERROR;
+ }
+ }
+ else
+ {
+ if (!OCGenerateUuid(gDoxm->deviceID.id))
+ {
+ OIC_LOG(FATAL, TAG, "Generate UUID for Server Instance failed!");
+ ret = OC_STACK_ERROR;
+ }
+ else
+ {
+ ret = OC_STACK_OK;
+ }
+ }
+#else
if (!OCGenerateUuid(gDoxm->deviceID.id))
{
OIC_LOG(FATAL, TAG, "Generate UUID for Server Instance failed!");
- return OC_STACK_ERROR;
+ ret = OC_STACK_ERROR;
}
- ret = OC_STACK_OK;
+ else
+ {
+ ret = OC_STACK_OK;
+ }
+#endif
+
+ if (OC_STACK_OK == ConvertUuidToStr(&gDoxm->deviceID, &strUuid))
+ {
+ OIC_LOG_V(DEBUG, TAG, "Generated device UUID is [%s]", strUuid);
+ OICFree(strUuid);
+ }
+ else
+ {
+ OIC_LOG(WARNING, TAG, "Failed to convert UUID to string");
+ }
+
if (!UpdatePersistentStorage(gDoxm))
{
{
ret = OC_STACK_OK;
}
+
return ret;
}
static void PrepareMOT(const OicSecDoxm_t* doxm)
{
OIC_LOG(INFO, TAG, "IN PrepareMOT");
- VERIFY_NON_NULL(TAG, doxm, ERROR);
+ VERIFY_NOT_NULL(TAG, doxm, ERROR);
if(true == doxm->owned && NULL != doxm->mom && OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode)
{
VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
- caRes = CASelectCipherSuite((uint16_t)TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, CA_ADAPTER_IP);
+ RegisterOTMSslHandshakeCallback(DoxmDTLSHandshakeCB);
+ caRes = CASelectCipherSuite((uint16_t)MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CA_ADAPTER_IP);
VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
#ifdef __WITH_TLS__
- caRes = CASelectCipherSuite((uint16_t)TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, CA_ADAPTER_TCP);
+ caRes = CASelectCipherSuite((uint16_t)MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CA_ADAPTER_TCP);
VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
#endif
OIC_LOG(INFO, TAG, "ECDHE_PSK CipherSuite will be used for MOT");
}
//In case of the server is shut down unintentionally, we should initialize the owner
- if(false == gDoxm->owned)
+ if(gDoxm && (false == gDoxm->owned))
{
OicUuid_t emptyUuid = {.id={0}};
memcpy(&gDoxm->owner, &emptyUuid, sizeof(OicUuid_t));
}
}
-OCStackResult GetDoxmDeviceID(OicUuid_t *deviceID)
+#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+OCStackResult SetDoxmDeviceIDSeed(const uint8_t* seed, size_t seedSize)
{
- if (deviceID && gDoxm)
+ OIC_LOG_V(INFO, TAG, "In %s", __func__);
+
+ if (NULL == seed)
{
- *deviceID = gDoxm->deviceID;
- return OC_STACK_OK;
+ return OC_STACK_INVALID_PARAM;
}
- return OC_STACK_ERROR;
+ if (MAX_UUID_SEED_SIZE < seedSize)
+ {
+ OIC_LOG_V(ERROR, TAG, "Seed size is too long (MAX size is %d bytes)", MAX_UUID_SEED_SIZE);
+ return OC_STACK_INVALID_PARAM;
+ }
+ if (MIN_UUID_SEED_SIZE > seedSize)
+ {
+ OIC_LOG_V(ERROR, TAG, "Seed size is too small (MIN size is %d bytes)", MIN_UUID_SEED_SIZE);
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ memset(gUuidSeed, 0x00, sizeof(gUuidSeed));
+ memcpy(gUuidSeed, seed, seedSize);
+ gUuidSeedSize = seedSize;
+
+ OIC_LOG_V(INFO, TAG, "Out %s", __func__);
+
+ return OC_STACK_OK;
}
+#endif
-OCStackResult GetDoxmIsOwned(bool *isOwned)
+OCStackResult GetDoxmDeviceID(OicUuid_t *deviceuuid)
{
- if (isOwned && gDoxm)
+ if (deviceuuid && gDoxm)
{
- *isOwned = gDoxm->owned;
+ *deviceuuid = gDoxm->deviceID;
return OC_STACK_OK;
}
return OC_STACK_ERROR;
}
-OCStackResult SetDoxmDeviceID(const OicUuid_t *deviceID)
+OCStackResult SetDoxmDeviceID(const OicUuid_t *deviceuuid)
{
- bool isPT = false;
-
- if(NULL == deviceID)
+ bool isOwnerUpdated = false;
+ bool isRownerUpdated = false;
+ if (NULL == deviceuuid)
{
return OC_STACK_INVALID_PARAM;
}
- if(NULL == gDoxm)
+ if (NULL == gDoxm)
{
OIC_LOG(ERROR, TAG, "Doxm resource is not initialized.");
return OC_STACK_NO_RESOURCE;
}
- //Check the device's OTM state
-
#ifdef __WITH_DTLS__
//for normal device.
- if(true == gDoxm->owned &&
- memcmp(gDoxm->deviceID.id, gDoxm->owner.id, sizeof(gDoxm->owner.id)) != 0)
+ if (true == gDoxm->owned &&
+ memcmp(gDoxm->deviceID.id, gDoxm->owner.id, sizeof(gDoxm->owner.id)) != 0)
{
OIC_LOG(ERROR, TAG, "This device owned by owner's device.");
OIC_LOG(ERROR, TAG, "Device UUID cannot be changed to guarantee the reliability of the connection.");
#endif //__WITH_DTLS
//Save the previous UUID
- OicUuid_t tempUuid;
- memcpy(tempUuid.id, gDoxm->deviceID.id, sizeof(tempUuid.id));
+ OicUuid_t prevUuid;
+ memcpy(prevUuid.id, gDoxm->deviceID.id, sizeof(prevUuid.id));
+
+ //Change the device UUID
+ memcpy(gDoxm->deviceID.id, deviceuuid->id, sizeof(gDoxm->deviceID.id));
- //Change the UUID
- memcpy(gDoxm->deviceID.id, deviceID->id, sizeof(deviceID->id));
- if(isPT)
+ //Change the owner ID if necessary
+ if (memcmp(gDoxm->owner.id, prevUuid.id, sizeof(prevUuid.id)) == 0)
{
- memcpy(gDoxm->owner.id, deviceID->id, sizeof(deviceID->id));
- memcpy(gDoxm->rownerID.id, deviceID->id, sizeof(deviceID->id));
+ memcpy(gDoxm->owner.id, deviceuuid->id, sizeof(gDoxm->owner.id));
+ isOwnerUpdated = true;
+ }
+ //Change the resource owner ID if necessary
+ // TODO [IOT-2023] change this behavior and upate the usage of this function
+ // so that rowneruuid for each resource is set by OBT
+ if (memcmp(gDoxm->rownerID.id, prevUuid.id, sizeof(prevUuid.id)) == 0)
+ {
+ memcpy(gDoxm->rownerID.id, deviceuuid->id, sizeof(gDoxm->rownerID.id));
+ isRownerUpdated = true;
}
//Update PS
- if(!UpdatePersistentStorage(gDoxm))
+ if (!UpdatePersistentStorage(gDoxm))
{
- //revert UUID in case of update error
- memcpy(gDoxm->deviceID.id, tempUuid.id, sizeof(tempUuid.id));
- if(isPT)
+ //revert UUID in case of PSI error
+ memcpy(gDoxm->deviceID.id, prevUuid.id, sizeof(gDoxm->deviceID.id));
+ if (isOwnerUpdated)
{
- memcpy(gDoxm->owner.id, tempUuid.id, sizeof(tempUuid.id));
- memcpy(gDoxm->rownerID.id, tempUuid.id, sizeof(tempUuid.id));
+ memcpy(gDoxm->owner.id, prevUuid.id, sizeof(gDoxm->owner.id));
+ }
+ if (isRownerUpdated)
+ {
+ memcpy(gDoxm->rownerID.id, prevUuid.id, sizeof(gDoxm->rownerID.id));
}
OIC_LOG(ERROR, TAG, "Failed to update persistent storage");
return OC_STACK_OK;
}
-OCStackResult GetDoxmDevOwnerId(OicUuid_t *devownerid)
+OCStackResult GetDoxmDevOwnerId(OicUuid_t *devowneruuid)
+{
+ if (gDoxm && devowneruuid)
+ {
+ memcpy(&(devowneruuid->id), &(gDoxm->owner.id), sizeof(devowneruuid->id));
+ return OC_STACK_OK;
+ }
+ return OC_STACK_ERROR;
+}
+
+OCStackResult SetDoxmDevOwnerId(const OicUuid_t *devowneruuid)
+{
+ if (gDoxm && devowneruuid)
+ {
+ memcpy(&(gDoxm->owner.id), &(devowneruuid->id), sizeof(gDoxm->owner.id));
+ return OC_STACK_OK;
+ }
+ return OC_STACK_ERROR;
+}
+
+OCStackResult GetDoxmIsOwned(bool *isowned)
+{
+ if (isowned && gDoxm)
+ {
+ *isowned = gDoxm->owned;
+ return OC_STACK_OK;
+ }
+ return OC_STACK_ERROR;
+}
+
+OCStackResult SetDoxmIsOwned(const bool isowned)
{
- OCStackResult retVal = OC_STACK_ERROR;
if (gDoxm)
{
- OIC_LOG_V(DEBUG, TAG, "GetDoxmDevOwnerId(): gDoxm owned = %d.", \
- gDoxm->owned);
- if (gDoxm->owned)
- {
- *devownerid = gDoxm->owner;
- retVal = OC_STACK_OK;
- }
+ gDoxm->owned = isowned;
+ return OC_STACK_OK;
}
- return retVal;
+ return OC_STACK_ERROR;
}
OCStackResult GetDoxmRownerId(OicUuid_t *rowneruuid)
{
- OCStackResult retVal = OC_STACK_ERROR;
- if (gDoxm)
+ if (gDoxm && rowneruuid)
{
- if( gDoxm->owned )
- {
- *rowneruuid = gDoxm->rownerID;
- retVal = OC_STACK_OK;
- }
+ memcpy(&(rowneruuid->id), &(gDoxm->rownerID.id), sizeof(rowneruuid->id));
+ return OC_STACK_OK;
}
- return retVal;
+ return OC_STACK_ERROR;
+}
+
+OCStackResult SetDoxmRownerId(const OicUuid_t *rowneruuid)
+{
+ if (gDoxm && rowneruuid)
+ {
+ memcpy(&(gDoxm->rownerID.id), &(rowneruuid->id), sizeof(gDoxm->rownerID.id));
+ return OC_STACK_OK;
+ }
+ return OC_STACK_ERROR;
}
#ifdef MULTIPLE_OWNER
}
return retVal;
}
+
+OCStackResult SetMOTStatus(bool enable)
+{
+ OCStackResult ret = OC_STACK_NO_MEMORY;
+ uint8_t *cborPayload = NULL;
+ size_t size = 0;
+ bool isDeallocateRequired = false;
+
+ OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+ if (NULL == gDoxm->mom && !enable)
+ {
+ OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+ return OC_STACK_OK;
+ }
+
+ if (NULL == gDoxm->mom)
+ {
+ gDoxm->mom = (OicSecMom_t*)OICCalloc(1, sizeof(OicSecMom_t));
+ VERIFY_NOT_NULL(TAG, gDoxm->mom, ERROR);
+ isDeallocateRequired = true;
+ }
+
+ gDoxm->mom->mode = (enable ? OIC_MULTIPLE_OWNER_ENABLE : OIC_MULTIPLE_OWNER_DISABLE);
+
+ ret = DoxmToCBORPayload(gDoxm, &cborPayload, &size);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ ret = UpdateSecureResourceInPS(OIC_JSON_DOXM_NAME, cborPayload, size);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ isDeallocateRequired = false;
+
+exit:
+ if (isDeallocateRequired)
+ {
+ OICFree(gDoxm->mom);
+ }
+ OICFree(cborPayload);
+ OIC_LOG_V(DEBUG, TAG, "Out %s : %d", __func__, ret);
+ return ret;
+}
+
#endif //MULTIPLE_OWNER
/**
memcpy(gDoxm->owner.id, newROwner->id, sizeof(newROwner->id));
memcpy(gDoxm->rownerID.id, newROwner->id, sizeof(newROwner->id));
- ret = DoxmToCBORPayload(gDoxm, &cborPayload, &size, false);
+ ret = DoxmToCBORPayload(gDoxm, &cborPayload, &size);
VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
ret = UpdateSecureResourceInPS(OIC_JSON_DOXM_NAME, cborPayload, size);
return ret;
}
+#ifdef MULTIPLE_OWNER
+/** This function checks if two sets of /oic/sec/doxm MOT-specific properties are identical.
+ *
+ * @param doxm1 is a pointer to the first @ref OicSecDoxm_t data.
+ * @param doxm2 is a pointer to the second @ref OicSecDoxm_t data.
+ *
+ * @return true if all of the properties are identical, else false.
+ */
+static bool AreDoxmBinMOTPropertyValuesEqual(OicSecDoxm_t* doxm1, OicSecDoxm_t* doxm2)
+{
+ //Compare the subOwners lists.
+ OicSecSubOwner_t* subOwner1 = doxm1->subOwners;
+ OicSecSubOwner_t* subOwner2 = doxm2->subOwners;
+
+ for (;;)
+ {
+ if ((NULL == subOwner1) && (NULL == subOwner2))
+ {
+ //Reached the end of both lists, so the two lists were identical.
+ break;
+ }
+
+ if ((NULL != subOwner1) && (NULL != subOwner2))
+ {
+ if (0 != memcmp(&subOwner1->uuid, &subOwner2->uuid, sizeof(subOwner1->uuid)))
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: subOwner uuid mismatch", __func__);
+ return false;
+ }
+
+ if (subOwner1->status != subOwner2->status)
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: subOwner status mismatch: (%u, %u)",
+ __func__, (uint32_t)subOwner1->status, (uint32_t)subOwner2->status);
+ return false;
+ }
+
+ //Go to the next elements from the two lists.
+ subOwner1 = subOwner1->next;
+ subOwner2 = subOwner2->next;
+ continue;
+ }
+
+ OIC_LOG_V(ERROR, TAG, "%s: subOwner list length mismatch", __func__);
+ return false;
+ }
+
+ // Compare the mom values.
+ if (NULL == doxm1->mom)
+ {
+ if (NULL != doxm2->mom)
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: doxm1->mom is NULL", __func__);
+ return false;
+ }
+
+ return true;
+ }
+
+ if (NULL == doxm2->mom)
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: doxm2->mom is NULL", __func__);
+ return false;
+ }
+
+ if (doxm1->mom->mode != doxm2->mom->mode)
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: mom->mode mismatch: (%u, %u)",
+ __func__, (uint32_t)doxm1->mom->mode, (uint32_t)doxm2->mom->mode);
+ return false;
+ }
+
+ return true;
+}
+#endif //#ifdef MULTIPLE_OWNER
+
+bool AreDoxmBinPropertyValuesEqual(OicSecDoxm_t* doxm1, OicSecDoxm_t* doxm2)
+{
+ if (NULL == doxm1 || NULL == doxm2)
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: unxpected NULL doxm pointer", __func__);
+ return false;
+ }
+
+ //Compare the contents of the oxmType array and its length oxmTypeLen.
+ size_t arrayLength = doxm1->oxmTypeLen;
+
+ if (arrayLength != doxm2->oxmTypeLen)
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: oxmTypeLen mismatch: (%" PRIuPTR ", %" PRIuPTR ")",
+ __func__, arrayLength, doxm2->oxmTypeLen);
+ return false;
+ }
+
+ for (size_t i = 0; i < arrayLength; i++)
+ {
+ if (NULL == doxm1->oxmType[i] || NULL == doxm2->oxmType[i])
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: unexpected NULL found in the oxmType array",
+ __func__);
+ return false;
+ }
+
+ if (0 != strcmp(doxm1->oxmType[i], doxm2->oxmType[i]))
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: oxmType mismatch: (%s, %s)",
+ __func__, doxm1->oxmType[i], doxm2->oxmType[i]);
+ return false;
+ }
+ }
+
+ //Compare the contents of the oxm array and its length oxmLen.
+ arrayLength = doxm1->oxmLen;
+
+ if (arrayLength != doxm2->oxmLen)
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: oxmLen mismatch: (%" PRIuPTR ", %" PRIuPTR ")",
+ __func__, arrayLength, doxm2->oxmLen);
+ return false;
+ }
+
+ for (size_t i = 0; i < arrayLength; i++)
+ {
+ if (doxm1->oxm[i] != doxm2->oxm[i])
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: oxmType mismatch: (%u, %u)",
+ __func__, (uint32_t)doxm1->oxm[i], (uint32_t)doxm2->oxm[i]);
+ return false;
+ }
+ }
+
+ //Compare the remaining property values.
+ if (doxm1->oxmSel != doxm2->oxmSel)
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: oxmSel mismatch: (%u, %u)",
+ __func__, (uint32_t)doxm1->oxmSel, (uint32_t)doxm2->oxmSel);
+ return false;
+ }
+
+ if (doxm1->sct != doxm2->sct)
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: sct mismatch: (%u, %u)",
+ __func__, (uint32_t)doxm1->sct, (uint32_t)doxm2->sct);
+ return false;
+ }
+
+ if (doxm1->owned != doxm2->owned)
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: owned mismatch: (%u, %u)",
+ __func__, (uint32_t)doxm1->owned, (uint32_t)doxm2->owned);
+ return false;
+ }
+
+ if (0 != memcmp(&doxm1->deviceID, &doxm2->deviceID, sizeof(doxm1->deviceID)))
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: deviceID mismatch", __func__);
+ return false;
+ }
+
+ if (doxm1->dpc != doxm2->dpc)
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: dpc mismatch: (%u, %u)",
+ __func__, (uint32_t)doxm1->dpc, (uint32_t)doxm2->dpc);
+ return false;
+ }
+
+ if (0 != memcmp(&doxm1->owner, &doxm2->owner, sizeof(doxm1->owner)))
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: owner mismatch", __func__);
+ return false;
+ }
+
+ if (0 != memcmp(&doxm1->rownerID, &doxm2->rownerID, sizeof(doxm1->rownerID)))
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: rownerID mismatch", __func__);
+ return false;
+ }
+
+#ifdef MULTIPLE_OWNER
+ return AreDoxmBinMOTPropertyValuesEqual(doxm1, doxm2);
+#else
+ return true;
+#endif
+}