#include "securevirtualresourcetypes.h"
#include "oxmjustworks.h"
#include "oxmrandompin.h"
+#include "oxmrawpublickey.h"
#include "oxmmanufacturercert.h"
#include "secureresourceprovider.h"
#ifdef MULTIPLE_OWNER
static uint8_t g_OxmAllowStatus[OXM_IDX_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
- NOT_ALLOWED_OXM};
+ ALLOWED_OXM, NOT_ALLOWED_OXM};
#else
static uint8_t g_OxmAllowStatus[OXM_IDX_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
- ALLOWED_OXM, ALLOWED_OXM, NOT_ALLOWED_OXM};
+ ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
+ NOT_ALLOWED_OXM};
#endif
+static OTMSelectMethodCallback g_selectOTMCB = NULL;
+
OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks)
{
OCStackResult res = OC_STACK_INVALID_PARAM;
#ifdef MULTIPLE_OWNER
VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_PRECONFIG_PIN == oxm || OIC_MV_JUST_WORKS == oxm
- || OIC_CON_MFG_CERT == oxm), ERROR);
+ || OIC_CON_MFG_CERT == oxm || OIC_RAW_PUB_KEY == oxm), ERROR);
#else
- VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_MV_JUST_WORKS == oxm || OIC_CON_MFG_CERT == oxm), ERROR);
+ VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_MV_JUST_WORKS == oxm || OIC_CON_MFG_CERT == oxm || OIC_RAW_PUB_KEY == oxm), ERROR);
#endif // MULTIPLE_OWNER
switch(oxm)
callbacks->createSelectOxmPayloadCB = CreateConMCertificateBasedSelectOxmPayload;
callbacks->createOwnerTransferPayloadCB = CreateMCertificateBasedOwnerTransferPayload;
break;
+ case OIC_RAW_PUB_KEY:
+ callbacks->loadSecretCB = GetMasterRPKCallback;
+ callbacks->createSecureSessionCB = CreateSecureSessionRPKCallback;
+ callbacks->createSelectOxmPayloadCB = CreateRPKBasedSelectOxmPayload;
+ callbacks->createOwnerTransferPayloadCB = CreateRPKBasedOwnerTransferPayload;
+ break;
default:
OIC_LOG_V(ERROR, TAG, "Unknown OxM : %d", (int)oxm);
return OC_STACK_INVALID_PARAM;
return res;
}
+void SetSelectOTMCB(OTMSelectMethodCallback selectOTMcb)
+{
+ g_selectOTMCB = selectOTMcb;
+ return;
+}
+
+void UnsetSelectOTMCB()
+{
+ g_selectOTMCB = NULL;
+ return;
+}
+
/**
* Internal API to convert OxM value to index of oxm allow table.
*/
return OXM_IDX_DECENTRALIZED_PUBLIC_KEY;
case OIC_MV_JUST_WORKS:
return OXM_IDX_MV_JUST_WORKS;
+ case OIC_RAW_PUB_KEY:
+ return OXM_IDX_RAW_PUBLIC_KEY;
case OIC_CON_MFG_CERT:
return OXM_IDX_CON_MFG_CERT;
#ifdef MULTIPLE_OWNER
{
case SUPER_OWNER:
{
+ if (g_selectOTMCB)
+ {
+ uint32_t methNum = 0;
+ OicSecOxm_t list[10] = {0};
+
for (size_t i = 0; i < numberOfMethods; i++)
{
selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]);
OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table");
continue;
}
+ #ifdef MULTIPLE_OWNER
+ if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
+ OXM_IDX_PRECONFIG_PIN != selectedOxmIdx)
+ #else
-#ifdef MULTIPLE_OWNER
+ if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx])
+ #endif //MULTIPLE_OWNER
+ {
+ list[methNum] = supportedMethods[i];
+ methNum++;
+ }
+ }
+ *selectedMethod = g_selectOTMCB(list, methNum);
+ isOxmSelected = true;
+ }
+ else
+ {
+ for (size_t i = 0; i < numberOfMethods; i++)
+ {
+ selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]);
+ if (OXM_IDX_COUNT <= selectedOxmIdx)
+ {
+ OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table");
+ continue;
+ }
+ #ifdef MULTIPLE_OWNER
if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
OXM_IDX_PRECONFIG_PIN != selectedOxmIdx)
-#else
+ #else
+
if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx])
-#endif //MULTIPLE_OWNER
+ #endif //MULTIPLE_OWNER
{
*selectedMethod = supportedMethods[i];
isOxmSelected = true;
}
}
}
+ }
break;
#ifdef MULTIPLE_OWNER
case SUB_OWNER:
return OC_STACK_DELETE_TRANSACTION;
}
+static void deleteCallback(void *ctx)
+{
+ OC_UNUSED(ctx);
+ OIC_LOG_V(DEBUG, TAG, "%s: otm context deleted", __func__);
+}
+
+
/**
* Response handler for update owner uuid request.
*
res = VerifyOwnershipTransfer(NULL, USER_CONFIRM);
if (OC_STACK_OK != res)
{
- if (OC_STACK_OK != SRPResetDevice(otmCtx->selectedDeviceInfo, otmCtx->ctxResultCallback))
+ if (OC_STACK_OK != SRPResetDevice(otmCtx->selectedDeviceInfo, deleteCallback))
{
OIC_LOG(WARNING, TAG, "OwnerUuidUpdateHandler : SRPResetDevice error");
}
SetResult(otmCtx, res);
return res;
}
- OIC_LOG_V(DEBUG, TAG, "Selected provisoning method = %d", selectedDevice->doxm->oxmSel);
+ OIC_LOG_V(DEBUG, TAG, "Selected provisioning method = %d", selectedDevice->doxm->oxmSel);
res = OTMSetOTCallback(selectedDevice->doxm->oxmSel, &otmCtx->otmCallback);
if(OC_STACK_OK != res)
return res;
}
+static OCStackResult StartCustomOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice,const OicSecOxm_t method)
+{
+ OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
+ OCStackResult res = OC_STACK_INVALID_PARAM;
+
+ VERIFY_NON_NULL(TAG, selectedDevice, ERROR);
+ VERIFY_NON_NULL(TAG, selectedDevice->doxm, ERROR);
+
+ OTMContext_t* otmCtx = (OTMContext_t*)ctx;
+ otmCtx->selectedDeviceInfo = selectedDevice;
+
+ //Setup PDM to perform the OTM, PDM will be cleanup if necessary.
+ res = SetupPDM(selectedDevice);
+ if(OC_STACK_OK != res)
+ {
+ OIC_LOG_V(ERROR, TAG, "SetupPDM error : %d", res);
+ SetResult(otmCtx, res);
+ return res;
+ }
+
+ //Select the OxM to performing ownership transfer
+ selectedDevice->doxm->oxmSel = method;
+ OIC_LOG_V(DEBUG, TAG, "Selected provisioning method = %d", selectedDevice->doxm->oxmSel);
+
+ res = OTMSetOTCallback(selectedDevice->doxm->oxmSel, &otmCtx->otmCallback);
+ if(OC_STACK_OK != res)
+ {
+ OIC_LOG_V(ERROR, TAG, "Error in OTMSetOTCallback : %d", res);
+ return res;
+ }
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+ //Register TLS event handler, to catch the TLS handshake event
+ if(CA_STATUS_OK != CAregisterSslHandshakeCallback(DTLSHandshakeCB))
+ {
+ OIC_LOG(WARNING, TAG, "StartOwnershipTransfer : Failed to register TLS handshake callback.");
+ }
+#endif // __WITH_DTLS__ or __WITH_TLS__
+
+ //Send Req: POST /oic/sec/doxm [{..."OxmSel" :g_OTMCbDatas[Index of Selected OxM].OXMString,...}]
+ res = PostOwnerTransferModeToResource(otmCtx);
+ if(OC_STACK_OK != res)
+ {
+ OIC_LOG_V(WARNING, TAG, "Failed to select the provisioning method : %d", res);
+ SetResult(otmCtx, res);
+ return res;
+ }
+
+ OIC_LOG(INFO, TAG, "OUT StartOwnershipTransfer");
+
+exit:
+ return res;
+}
+
OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxmType, OTMCallbackData_t* data)
{
OIC_LOG(DEBUG, TAG, "IN OTMSetOwnerTransferCallbackData");
return OC_STACK_OK;
}
+OCStackResult OTMDoCustomOwnershipTransfer(void* ctx,
+ OCProvisionDev_t *selectedDevice,
+ OCProvisionResultCB resultCallback,
+ const OicSecOxm_t method)
+{
+ OIC_LOG(DEBUG, TAG, "IN OTMDoCustomOwnershipTransfer");
+
+ if (NULL == selectedDevice)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+ if (NULL == resultCallback)
+ {
+ return OC_STACK_INVALID_CALLBACK;
+ }
+
+ OTMContext_t* otmCtx = (OTMContext_t*)OICCalloc(1,sizeof(OTMContext_t));
+ if(!otmCtx)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to create OTM Context");
+ return OC_STACK_NO_MEMORY;
+ }
+
+ otmCtx->ctxResultCallback = resultCallback;
+ otmCtx->ctxHasError = false;
+ otmCtx->userCtx = ctx;
+
+ //Setting number of selected device.
+ otmCtx->ctxResultArraySize = 1;
+
+ otmCtx->ctxResultArray =
+ (OCProvisionResult_t*)OICCalloc(otmCtx->ctxResultArraySize, sizeof(OCProvisionResult_t));
+ if(NULL == otmCtx->ctxResultArray)
+ {
+ OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Failed to memory allocation");
+ OICFree(otmCtx);
+ return OC_STACK_NO_MEMORY;
+ }
+
+ //Fill the device UUID for result array.
+ memcpy(otmCtx->ctxResultArray[0].deviceId.id,
+ selectedDevice->doxm->deviceID.id,
+ UUID_LENGTH);
+ otmCtx->ctxResultArray[0].res = OC_STACK_CONTINUE;
+
+ OCStackResult res = StartCustomOwnershipTransfer(otmCtx, selectedDevice, method);
+
+ OIC_LOG(DEBUG, TAG, "OUT OTMDoCustomOwnershipTransfer");
+
+ return res;
+}
+
/**
* NOTE : Unowned discovery should be done before performing OTMDoOwnershipTransfer
*/