static OTMContext_t* g_otmCtx = NULL;
/**
- * Function to getting string of ownership transfer method
- */
-static const char* GetOxmString(OicSecOxm_t oxmType)
-{
- switch(oxmType)
- {
- case OIC_JUST_WORKS:
- return OXM_JUST_WORKS;
- case OIC_RANDOM_DEVICE_PIN:
- return OXM_RANDOM_DEVICE_PIN;
- case OIC_MANUFACTURER_CERTIFICATE:
- return OXM_MANUFACTURER_CERTIFICATE;
- default:
- return NULL;
- }
-}
-
-/**
* Function to select appropriate provisioning method.
*
* @param[in] supportedMethods Array of supported methods
break;
}
}
+ OIC_LOG_V(DEBUG, TAG, "Selected Operation Mode = %d", *selectedMode);
+
OIC_LOG(DEBUG, TAG, "OUT SelectOperationMode");
}
/**
+ * Function to start ownership transfer.
+ * This function will send the first request for provisioning,
+ * The next request message is sent from the response handler for this request.
+ *
+ * @param[in] ctx context value passed to callback from calling function.
+ * @param[in] selectedDevice selected device information to performing provisioning.
+ * @return OC_STACK_OK on success
+ */
+static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice);
+
+/**
* Function to update owner transfer mode
*
* @param[in] otmCtx Context value of ownership transfer.
/**
- * Function to send ownerShip info. This function would update Owned as true and
- * owner as UUID for provisioning tool
+ * Function to send uuid of owner device to new device.
+ * This function would update 'owner of doxm' as UUID for provisioning tool.
*
* @param[in] otmCtx Context value of ownership transfer.
* @return OC_STACK_OK on success
*/
-static OCStackResult PutOwnershipInformation(OTMContext_t* otmCtx);
+static OCStackResult PutOwnerUuid(OTMContext_t* otmCtx);
/**
* Function to update the operation mode. As per the spec. Operation mode in client driven
* single service provisioning it will be updated to 0x3
*
* @param[in] otmCtx Context value of ownership transfer.
+ * @return OC_STACK_OK on success
+ */
+static OCStackResult PutUpdateOperationMode(OTMContext_t* otmCtx);
+
+/**
+ * Function to update the owner credential to new device
+ *
+ * @param[in] otmCtx Context value of ownership transfer.
* @param[in] selectedOperationMode selected operation mode
* @return OC_STACK_OK on success
*/
-static OCStackResult PutUpdateOperationMode(OTMContext_t* otmCtx,
- OicSecDpom_t selectedOperationMode);
+static OCStackResult PutOwnerCredential(OTMContext_t* otmCtx);
/**
- * Function to start ownership transfer.
- * This function will send the first request for provisioning,
- * The next request message is sent from the response handler for this request.
+ * Function to send ownerShip info.
+ * This function would update 'owned of doxm' as true.
+ *
+ * @param[in] otmCtx Context value of ownership transfer.
+ * @return OC_STACK_OK on success
+ */
+static OCStackResult PutOwnershipInformation(OTMContext_t* otmCtx);
+
+/**
+ * Function to update pstat when finalize provisioning.
+ * This function would update 'cm' as bx0011,1100 and 'tm' as bx0000,0000.
*
* @param[in] ctx context value passed to callback from calling function.
* @param[in] selectedDevice selected device information to performing provisioning.
* @return OC_STACK_OK on success
*/
-static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice);
+static OCStackResult PutProvisioningStatus(OTMContext_t* otmCtx);
/*
* Function to finalize provisioning.
*/
static OCStackResult FinalizeProvisioning(OTMContext_t* otmCtx);
+
static bool IsComplete(OTMContext_t* otmCtx)
{
for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
if(otmCtx->selectedDeviceInfo)
{
+ //Revert psk_info callback and new deivce uuid in case of random PIN OxM
+ if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
+ {
+ if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials))
+ {
+ OIC_LOG(WARNING, TAG, "Failed to revert is DTLS credential handler.");
+ }
+ OicUuid_t emptyUuid = { .id={0}};
+ SetUuidForRandomPinOxm(&emptyUuid);
+ }
+
for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
{
if(memcmp(otmCtx->selectedDeviceInfo->doxm->deviceID.id,
sizeof(endpoint->addr)) == 0 &&
g_otmCtx->selectedDeviceInfo->securePort == endpoint->port)
{
- OCStackResult res;
-
- CARegisterDTLSHandshakeCallback(NULL);
+ OCStackResult res = OC_STACK_ERROR;
//In case of success, send next coaps request.
if(CA_STATUS_OK == info->result)
{
- //Send request : PUT /oic/sec/doxm [{"Owned":"True", .. , "Owner":"PT's UUID"}]
- res = PutOwnershipInformation(g_otmCtx);
+ //Send request : PUT /oic/sec/doxm [{... , "devowner":"PT's UUID"}]
+ res = PutOwnerUuid(g_otmCtx);
if(OC_STACK_OK != res)
{
OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to send owner information");
if(g_otmCtx->selectedDeviceInfo->doxm->oxmSel == OIC_RANDOM_DEVICE_PIN)
{
+ /*
res = RemoveCredential(&g_otmCtx->subIdForPinOxm);
if(OC_STACK_RESOURCE_DELETED != res)
{
OIC_LOG_V(ERROR, TAG, "Failed to remove temporal PSK : %d", res);
SetResult(g_otmCtx, res);
return;
- }
+ }*/
if(WRONG_PIN_MAX_ATTEMP > g_otmCtx->attemptCnt)
{
//Generating OwnerPSK
CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint,
(uint8_t *)GetOxmString(selectedDeviceInfo->doxm->oxmSel),
- strlen(GetOxmString(selectedDeviceInfo->doxm->oxmSel)), ptDeviceID.id,
- sizeof(ptDeviceID.id), selectedDeviceInfo->doxm->deviceID.id,
- sizeof(selectedDeviceInfo->doxm->deviceID.id), ownerPSK,
- OWNER_PSK_LENGTH_128);
+ strlen(GetOxmString(selectedDeviceInfo->doxm->oxmSel)),
+ ptDeviceID.id, sizeof(ptDeviceID.id),
+ selectedDeviceInfo->doxm->deviceID.id, sizeof(selectedDeviceInfo->doxm->deviceID.id),
+ ownerPSK, OWNER_PSK_LENGTH_128);
if (CA_STATUS_OK == pskRet)
{
otmCtx->selectedDeviceInfo->pstat = pstat;
//Select operation mode (Currently supported SINGLE_SERVICE_CLIENT_DRIVEN only)
- OicSecDpom_t selectedOperationMode;
- SelectOperationMode(otmCtx->selectedDeviceInfo, &selectedOperationMode);
+ SelectOperationMode(otmCtx->selectedDeviceInfo, &(otmCtx->selectedDeviceInfo->pstat->om));
- //Send request : PUT /oic/sec/pstat [{"OM":"0x11", .. }]
- OCStackResult res = PutUpdateOperationMode(otmCtx, selectedOperationMode);
+ //Send request : PUT /oic/sec/pstat [{"om":"bx11", .. }]
+ OCStackResult res = PutUpdateOperationMode(otmCtx);
if (OC_STACK_OK != res)
{
OIC_LOG(ERROR, TAG, "Error while updating operation mode.");
}
/**
- * Callback handler for OwnershipInformationHandler API.
+ * Response handler for update owner uuid request.
*
* @param[in] ctx ctx value passed to callback from calling function.
* @param[in] UNUSED handle to an invocation
* @return OC_STACK_DELETE_TRANSACTION to delete the transaction
* and OC_STACK_KEEP_TRANSACTION to keep it.
*/
-static OCStackApplicationResult OwnershipInformationHandler(void *ctx, OCDoHandle UNUSED,
+static OCStackApplicationResult OwnerUuidUpdateHandler(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse)
{
VERIFY_NON_NULL(TAG, clientResponse, WARNING);
VERIFY_NON_NULL(TAG, ctx, WARNING);
- OIC_LOG(DEBUG, TAG, "IN OwnershipInformationHandler");
+ OIC_LOG(DEBUG, TAG, "IN OwnerUuidUpdateHandler");
(void)UNUSED;
OCStackResult res = OC_STACK_OK;
OTMContext_t* otmCtx = (OTMContext_t*)ctx;
{
if(otmCtx && otmCtx->selectedDeviceInfo)
{
- if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
- {
- res = RemoveCredential(&otmCtx->subIdForPinOxm);
- if(OC_STACK_RESOURCE_DELETED != res)
- {
- OIC_LOG_V(ERROR, TAG, "Failed to remove temporal PSK : %d", res);
- return OC_STACK_DELETE_TRANSACTION;
- }
- }
-
res = SaveOwnerPSK(otmCtx->selectedDeviceInfo);
if(OC_STACK_OK != res)
{
- OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to owner PSK generation");
+ OIC_LOG(ERROR, TAG, "OwnerUuidUpdateHandler:Failed to owner PSK generation");
SetResult(otmCtx, res);
return OC_STACK_DELETE_TRANSACTION;
}
- CAEndpoint_t* endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint;
- endpoint->port = otmCtx->selectedDeviceInfo->securePort;
- CAResult_t caResult = CACloseDtlsSession(endpoint);
- if(CA_STATUS_OK != caResult)
- {
- OIC_LOG(ERROR, TAG, "Failed to close DTLS session");
- SetResult(otmCtx, caResult);
- return OC_STACK_DELETE_TRANSACTION;
- }
-
- /**
- * If we select NULL cipher,
- * client will select appropriate cipher suite according to server's cipher-suite list.
- */
- caResult = CASelectCipherSuite(TLS_NULL_WITH_NULL_NULL);
- if(CA_STATUS_OK != caResult)
- {
- OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");
- SetResult(otmCtx, caResult);
- return OC_STACK_DELETE_TRANSACTION;
- }
-
- OIC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
- OIC_LOG(INFO, TAG, "Start defualt ACL & commit-hash provisioning.");
-
- res = FinalizeProvisioning(otmCtx);
+ //PUT owner credential to new device according to security spec B.
+ res = PutOwnerCredential(otmCtx);
if(OC_STACK_OK != res)
{
+ OIC_LOG(ERROR, TAG,
+ "OwnerUuidUpdateHandler:Failed to send PUT request for onwer credential");
SetResult(otmCtx, res);
+ return OC_STACK_DELETE_TRANSACTION;
}
}
}
else
{
res = clientResponse->result;
- OIC_LOG_V(ERROR, TAG, "OwnershipInformationHandler : Unexpected result %d", res);
+ OIC_LOG_V(ERROR, TAG, "OwnerUuidHandler : Unexpected result %d", res);
SetResult(otmCtx, res);
}
- OIC_LOG(DEBUG, TAG, "OUT OwnershipInformationHandler");
+ OIC_LOG(DEBUG, TAG, "OUT OwnerUuidUpdateHandler");
exit:
return OC_STACK_DELETE_TRANSACTION;
return OC_STACK_DELETE_TRANSACTION;
}
+/**
+ * Response handler for update owner crendetial request.
+ *
+ * @param[in] ctx ctx value passed to callback from calling function.
+ * @param[in] UNUSED handle to an invocation
+ * @param[in] clientResponse Response from queries to remote servers.
+ * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
+ * and OC_STACK_KEEP_TRANSACTION to keep it.
+ */
+static OCStackApplicationResult OwnerCredentialHandler(void *ctx, OCDoHandle UNUSED,
+ OCClientResponse *clientResponse)
+{
+ VERIFY_NON_NULL(TAG, clientResponse, WARNING);
+ VERIFY_NON_NULL(TAG, ctx, WARNING);
+
+ OIC_LOG(DEBUG, TAG, "IN OwnerCredentialHandler");
+ (void)UNUSED;
+ OCStackResult res = OC_STACK_OK;
+ OTMContext_t* otmCtx = (OTMContext_t*)ctx;
+
+ if(OC_STACK_RESOURCE_CREATED == clientResponse->result)
+ {
+ if(otmCtx && otmCtx->selectedDeviceInfo)
+ {
+ //PUT /oic/sec/doxm [{ ..., "owned":"TRUE" }]
+ res = PutOwnershipInformation(otmCtx);
+ if(OC_STACK_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to put ownership information to new device");
+ SetResult(otmCtx, res);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ }
+ }
+ else
+ {
+ res = clientResponse->result;
+ OIC_LOG_V(ERROR, TAG, "OwnerCredentialHandler : Unexpected result %d", res);
+ SetResult(otmCtx, res);
+ }
+
+ OIC_LOG(DEBUG, TAG, "OUT OwnerCredentialHandler");
+
+exit:
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+
+/**
+ * Response handler for update owner information request.
+ *
+ * @param[in] ctx ctx value passed to callback from calling function.
+ * @param[in] UNUSED handle to an invocation
+ * @param[in] clientResponse Response from queries to remote servers.
+ * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
+ * and OC_STACK_KEEP_TRANSACTION to keep it.
+ */
+static OCStackApplicationResult OwnershipInformationHandler(void *ctx, OCDoHandle UNUSED,
+ OCClientResponse *clientResponse)
+{
+ VERIFY_NON_NULL(TAG, clientResponse, WARNING);
+ VERIFY_NON_NULL(TAG, ctx, WARNING);
+
+ OIC_LOG(DEBUG, TAG, "IN OwnershipInformationHandler");
+ (void)UNUSED;
+ OCStackResult res = OC_STACK_OK;
+ OTMContext_t* otmCtx = (OTMContext_t*)ctx;
+
+ if(OC_STACK_OK == clientResponse->result)
+ {
+ if(otmCtx && otmCtx->selectedDeviceInfo)
+ {
+ OIC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
+ OIC_LOG(INFO, TAG, "Start defualt ACL & commit-hash provisioning.");
+
+ res = PutProvisioningStatus(otmCtx);
+ if(OC_STACK_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to update pstat");
+ SetResult(otmCtx, res);
+ }
+ }
+ }
+ else
+ {
+ res = clientResponse->result;
+ OIC_LOG_V(ERROR, TAG, "OwnershipInformationHandler : Unexpected result %d", res);
+ SetResult(otmCtx, res);
+ }
+
+ OIC_LOG(DEBUG, TAG, "OUT OwnershipInformationHandler");
+
+exit:
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+/**
+ * Response handler of update provisioning status.
+ *
+ * @param[in] ctx ctx value passed to callback from calling function.
+ * @param[in] UNUSED handle to an invocation
+ * @param[in] clientResponse Response from queries to remote servers.
+ * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
+ * and OC_STACK_KEEP_TRANSACTION to keep it.
+ */
+static OCStackApplicationResult ProvisioningStatusHandler(void *ctx, OCDoHandle UNUSED,
+ OCClientResponse *clientResponse)
+{
+ OIC_LOG_V(INFO, TAG, "IN ProvisioningStatusHandler.");
+
+ VERIFY_NON_NULL(TAG, clientResponse, ERROR);
+ VERIFY_NON_NULL(TAG, ctx, ERROR);
+
+ OTMContext_t* otmCtx = (OTMContext_t*)ctx;
+ (void)UNUSED;
+ if(OC_STACK_OK == clientResponse->result)
+ {
+ OCStackResult res = FinalizeProvisioning(otmCtx);
+ if (OC_STACK_OK != res)
+ {
+ OIC_LOG_V(INFO, TAG, "Failed to finalize provisioning.");
+ SetResult(otmCtx, res);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ }
+
+exit:
+ OIC_LOG_V(INFO, TAG, "OUT ProvisioningStatusHandler.");
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+/**
+ * Callback handler of finalize provisioning.
+ *
+ * @param[in] ctx ctx value passed to callback from calling function.
+ * @param[in] UNUSED handle to an invocation
+ * @param[in] clientResponse Response from queries to remote servers.
+ * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
+ * and OC_STACK_KEEP_TRANSACTION to keep it.
+ */
+static OCStackApplicationResult FinalizeProvisioningCB(void *ctx, OCDoHandle UNUSED,
+ OCClientResponse *clientResponse)
+{
+ OIC_LOG_V(INFO, TAG, "IN ProvisionDefaultACLCB.");
+
+ VERIFY_NON_NULL(TAG, clientResponse, ERROR);
+ VERIFY_NON_NULL(TAG, ctx, ERROR);
+
+ OTMContext_t* otmCtx = (OTMContext_t*) ctx;
+ (void)UNUSED;
+
+ if (OC_STACK_RESOURCE_CREATED == clientResponse->result)
+ {
+ OCStackResult res = PDMAddDevice(&otmCtx->selectedDeviceInfo->doxm->deviceID);
+ if (OC_STACK_OK == res)
+ {
+ OIC_LOG_V(INFO, TAG, "Add device's UUID in PDM_DB");
+ SetResult(otmCtx, OC_STACK_OK);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "Ownership transfer is complete but adding information to DB is failed.");
+ }
+ }
+ else
+ {
+ OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
+ clientResponse->result);
+ SetResult(otmCtx, clientResponse->result);
+ }
+exit:
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+static OCStackResult PutOwnerCredential(OTMContext_t* otmCtx)
+{
+ OIC_LOG(DEBUG, TAG, "IN PutOwnerCredential");
+
+ if(!otmCtx || !otmCtx->selectedDeviceInfo)
+ {
+ OIC_LOG(ERROR, TAG, "Invalid parameters");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
+ char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+
+ if(!PMGenerateQuery(true,
+ deviceInfo->endpoint.addr, deviceInfo->securePort,
+ deviceInfo->connType,
+ query, sizeof(query), OIC_RSRC_CRED_URI))
+ {
+ OIC_LOG(ERROR, TAG, "PutOwnerCredential : Failed to generate query");
+ return OC_STACK_ERROR;
+ }
+ OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+ OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
+ if(!secPayload)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to memory allocation");
+ return OC_STACK_NO_MEMORY;
+ }
+
+ //Generate owner credential for new device
+ secPayload->base.type = PAYLOAD_TYPE_SECURITY;
+ OicSecCred_t* ownerCredential =
+ GetCredResourceData(&(deviceInfo->doxm->deviceID));
+ if(!ownerCredential)
+ {
+ OIC_LOG(ERROR, TAG, "Can not find OwnerPSK.");
+ return OC_STACK_NO_RESOURCE;
+ }
+
+ OicUuid_t credSubjectId = {.id={0}};
+ if(OC_STACK_OK == GetDoxmDeviceID(&credSubjectId))
+ {
+ OicSecCred_t newCredential;
+ memcpy(&newCredential, ownerCredential, sizeof(OicSecCred_t));
+ newCredential.next = NULL;
+ memcpy(&(newCredential.subject), &credSubjectId, sizeof(OicUuid_t));
+
+ //Send owner credential to new device : PUT /oic/sec/cred [ owner credential ]
+ secPayload->securityData = BinToCredJSON(&newCredential);
+ if (NULL == secPayload->securityData)
+ {
+ OICFree(secPayload);
+ OIC_LOG(ERROR, TAG, "Error while converting bin to json");
+ return OC_STACK_ERROR;
+ }
+ OIC_LOG_V(DEBUG, TAG, "Payload : %s", secPayload->securityData);
+
+ OCCallbackData cbData;
+ cbData.cb = &OwnerCredentialHandler;
+ cbData.context = (void *)otmCtx;
+ cbData.cd = NULL;
+ OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query,
+ &deviceInfo->endpoint, (OCPayload*)secPayload,
+ deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
+ if (res != OC_STACK_OK)
+ {
+ OIC_LOG(ERROR, TAG, "OCStack resource error");
+ }
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "Failed to read DOXM device ID.");
+ return OC_STACK_NO_RESOURCE;
+ }
+
+ OIC_LOG(DEBUG, TAG, "OUT PutOwnerCredential");
+
+ return OC_STACK_OK;
+}
static OCStackResult PutOwnerTransferModeToResource(OTMContext_t* otmCtx)
{
OIC_LOG(ERROR, TAG, "Error while converting bin to json");
return OC_STACK_ERROR;
}
- OIC_LOG_V(DEBUG, TAG, "Payload : %s", secPayload->securityData);
OCCallbackData cbData;
cbData.cb = &OwnerTransferModeHandler;
return res;
}
+static OCStackResult PutOwnerUuid(OTMContext_t* otmCtx)
+{
+ OIC_LOG(DEBUG, TAG, "IN PutOwnerUuid");
+
+ if(!otmCtx || !otmCtx->selectedDeviceInfo)
+ {
+ OIC_LOG(ERROR, TAG, "Invailed parameters");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
+ char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+ if(!PMGenerateQuery(true,
+ deviceInfo->endpoint.addr, deviceInfo->securePort,
+ deviceInfo->connType,
+ query, sizeof(query), OIC_RSRC_DOXM_URI))
+ {
+ OIC_LOG(ERROR, TAG, "PutOwnershipInformation : Failed to generate query");
+ return OC_STACK_ERROR;
+ }
+ OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+ //PUT PT's uuid to new device
+ OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
+ if(!secPayload)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to memory allocation");
+ return OC_STACK_NO_MEMORY;
+ }
+ secPayload->base.type = PAYLOAD_TYPE_SECURITY;
+ secPayload->securityData =
+ g_OTMDatas[deviceInfo->doxm->oxmSel].createOwnerTransferPayloadCB(otmCtx);
+ if (NULL == secPayload->securityData)
+ {
+ OICFree(secPayload);
+ OIC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
+ return OC_STACK_INVALID_PARAM;
+ }
+ OIC_LOG_V(DEBUG, TAG, "Payload : %s", secPayload->securityData);
+
+ OCCallbackData cbData;
+ cbData.cb = &OwnerUuidUpdateHandler;
+ cbData.context = (void *)otmCtx;
+ cbData.cd = NULL;
+
+ OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
+ deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
+ if (res != OC_STACK_OK)
+ {
+ OIC_LOG(ERROR, TAG, "OCStack resource error");
+ }
+
+ OIC_LOG(DEBUG, TAG, "OUT PutOwnerUuid");
+
+ return res;
+}
static OCStackResult PutOwnershipInformation(OTMContext_t* otmCtx)
{
OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
//OwnershipInformationHandler
- OicSecOxm_t selOxm = deviceInfo->doxm->oxmSel;
OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
if(!secPayload)
{
OIC_LOG(ERROR, TAG, "Failed to memory allocation");
return OC_STACK_NO_MEMORY;
}
- secPayload->base.type = PAYLOAD_TYPE_SECURITY;
- secPayload->securityData = g_OTMDatas[selOxm].createOwnerTransferPayloadCB(otmCtx);
+
+ otmCtx->selectedDeviceInfo->doxm->owned = true;
+ secPayload->securityData = BinToDoxmJSON(otmCtx->selectedDeviceInfo->doxm);
if (NULL == secPayload->securityData)
{
OICFree(secPayload);
OIC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
return OC_STACK_INVALID_PARAM;
}
+ secPayload->base.type = PAYLOAD_TYPE_SECURITY;
OCCallbackData cbData;
cbData.cb = &OwnershipInformationHandler;
return res;
}
-static OCStackResult PutUpdateOperationMode(OTMContext_t* otmCtx,
- OicSecDpom_t selectedOperationMode)
+static OCStackResult PutUpdateOperationMode(OTMContext_t* otmCtx)
{
OIC_LOG(DEBUG, TAG, "IN PutUpdateOperationMode");
}
OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
- deviceInfo->pstat->om = selectedOperationMode;
-
OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
if(!secPayload)
{
}
-/**
- * Callback handler of SRPFinalizeProvisioning.
- *
- * @param[in] ctx ctx value passed to callback from calling function.
- * @param[in] UNUSED handle to an invocation
- * @param[in] clientResponse Response from queries to remote servers.
- * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
- * and OC_STACK_KEEP_TRANSACTION to keep it.
- */
-static OCStackApplicationResult FinalizeProvisioningCB(void *ctx, OCDoHandle UNUSED,
- OCClientResponse *clientResponse)
+OCStackResult PutProvisioningStatus(OTMContext_t* otmCtx)
{
- OIC_LOG_V(INFO, TAG, "IN FinalizeProvisioningCB.");
-
- VERIFY_NON_NULL(TAG, clientResponse, ERROR);
- VERIFY_NON_NULL(TAG, ctx, ERROR);
+ OIC_LOG(INFO, TAG, "IN PutProvisioningStatus");
- OTMContext_t* otmCtx = (OTMContext_t*)ctx;
- (void)UNUSED;
- if(OC_STACK_OK == clientResponse->result)
+ if(!otmCtx)
{
- OCStackResult res = PDMAddDevice(&otmCtx->selectedDeviceInfo->doxm->deviceID);
-
- if (OC_STACK_OK == res)
- {
- OIC_LOG_V(INFO, TAG, "Add device's UUID in PDM_DB");
- SetResult(otmCtx, OC_STACK_OK);
- return OC_STACK_DELETE_TRANSACTION;
- }
- else
- {
- OIC_LOG(ERROR, TAG, "Ownership transfer is complete but adding information to DB is failed.");
- }
+ OIC_LOG(ERROR, TAG, "OTMContext is NULL");
+ return OC_STACK_INVALID_PARAM;
+ }
+ if(!otmCtx->selectedDeviceInfo)
+ {
+ OIC_LOG(ERROR, TAG, "Can't find device information in OTMContext");
+ OICFree(otmCtx);
+ return OC_STACK_INVALID_PARAM;
}
-exit:
- return OC_STACK_DELETE_TRANSACTION;
-}
-
-/**
- * Callback handler of default ACL provisioning.
- *
- * @param[in] ctx ctx value passed to callback from calling function.
- * @param[in] UNUSED handle to an invocation
- * @param[in] clientResponse Response from queries to remote servers.
- * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
- * and OC_STACK_KEEP_TRANSACTION to keep it.
- */
-static OCStackApplicationResult ProvisionDefaultACLCB(void *ctx, OCDoHandle UNUSED,
- OCClientResponse *clientResponse)
-{
- OIC_LOG_V(INFO, TAG, "IN ProvisionDefaultACLCB.");
-
- VERIFY_NON_NULL(TAG, clientResponse, ERROR);
- VERIFY_NON_NULL(TAG, ctx, ERROR);
-
- OTMContext_t* otmCtx = (OTMContext_t*) ctx;
- (void)UNUSED;
- if (OC_STACK_RESOURCE_CREATED == clientResponse->result)
+ otmCtx->selectedDeviceInfo->pstat->tm = NORMAL;
+ otmCtx->selectedDeviceInfo->pstat->cm = PROVISION_ACLS | PROVISION_CREDENTIALS |
+ SECURITY_MANAGEMENT_SERVICES | BOOTSTRAP_SERVICE;
+ OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
+ if(!secPayload)
{
- OIC_LOG_V(INFO, TAG, "Staring commit hash task.");
- // TODO hash currently have fixed value 0.
- uint16_t aclHash = 0;
- otmCtx->selectedDeviceInfo->pstat->commitHash = aclHash;
- otmCtx->selectedDeviceInfo->pstat->tm = NORMAL;
- OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
- if(!secPayload)
- {
- OIC_LOG(ERROR, TAG, "Failed to memory allocation");
- return OC_STACK_NO_MEMORY;
- }
- secPayload->base.type = PAYLOAD_TYPE_SECURITY;
- secPayload->securityData = BinToPstatJSON(otmCtx->selectedDeviceInfo->pstat);
- if (NULL == secPayload->securityData)
- {
- OICFree(secPayload);
- SetResult(otmCtx, OC_STACK_INVALID_JSON);
- return OC_STACK_DELETE_TRANSACTION;
- }
- OIC_LOG_V(INFO, TAG, "Created payload for commit hash: %s",secPayload->securityData);
-
- char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
- if(!PMGenerateQuery(true,
- otmCtx->selectedDeviceInfo->endpoint.addr,
- otmCtx->selectedDeviceInfo->securePort,
- otmCtx->selectedDeviceInfo->connType,
- query, sizeof(query), OIC_RSRC_PSTAT_URI))
- {
- OIC_LOG(ERROR, TAG, "ProvisionDefaultACLCB : Failed to generate query");
- return OC_STACK_ERROR;
- }
- OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+ OIC_LOG(ERROR, TAG, "Failed to memory allocation");
+ return OC_STACK_NO_MEMORY;
+ }
+ secPayload->base.type = PAYLOAD_TYPE_SECURITY;
+ secPayload->securityData = BinToPstatJSON(otmCtx->selectedDeviceInfo->pstat);
+ if (NULL == secPayload->securityData)
+ {
+ OICFree(secPayload);
+ SetResult(otmCtx, OC_STACK_INVALID_JSON);
+ return OC_STACK_INVALID_JSON;
+ }
+ OIC_LOG_V(INFO, TAG, "Created payload for commit hash: %s",secPayload->securityData);
- OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
- cbData.cb = &FinalizeProvisioningCB;
- cbData.context = (void*)otmCtx;
- cbData.cd = NULL;
- OCStackResult ret = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
- otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
- OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
- if (ret != OC_STACK_OK)
- {
- OIC_LOG(ERROR, TAG, "OCStack resource error");
- SetResult(otmCtx, ret);
- }
+ char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+ if(!PMGenerateQuery(true,
+ otmCtx->selectedDeviceInfo->endpoint.addr,
+ otmCtx->selectedDeviceInfo->securePort,
+ otmCtx->selectedDeviceInfo->connType,
+ query, sizeof(query), OIC_RSRC_PSTAT_URI))
+ {
+ OIC_LOG(ERROR, TAG, "PutProvisioningStatus : Failed to generate query");
+ return OC_STACK_ERROR;
}
- else
+ OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+ OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
+ cbData.cb = &ProvisioningStatusHandler;
+ cbData.context = (void*)otmCtx;
+ cbData.cd = NULL;
+ OCStackResult ret = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
+ otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
+ OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
+ if (ret != OC_STACK_OK)
{
- OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
- clientResponse->result);
- SetResult(otmCtx, clientResponse->result);
+ OIC_LOG(ERROR, TAG, "OCStack resource error");
+ SetResult(otmCtx, ret);
}
-exit:
- return OC_STACK_DELETE_TRANSACTION;
-}
+ OIC_LOG(INFO, TAG, "OUT PutProvisioningStatus");
+
+ return ret;
+}
OCStackResult FinalizeProvisioning(OTMContext_t* otmCtx)
{
OIC_LOG_V(INFO, TAG, "Request URI for Provisioning default ACL : %s", query);
OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
- cbData.cb = &ProvisionDefaultACLCB;
+ cbData.cb = &FinalizeProvisioningCB;
cbData.context = (void *)otmCtx;
cbData.cd = NULL;
OCStackResult ret = OCDoResource(NULL, OC_REST_POST, query,
#include "pbkdf2.h"
#include <stdlib.h>
#include "iotvticalendar.h"
+#include "ocserverrequest.h"
+
#ifdef WITH_ARDUINO
#include <string.h>
#else
return OC_STACK_OK;
}
+#ifdef __WITH_DTLS__
+/**
+ * Internal function to verify recevied owner PSK.
+ *
+ * @param receviedCred recevied Owner Credential from OBT(PT)
+ * @param ownerAdd address of OBT(PT)
+ * @param doxm current device's doxm resource
+ *
+ * @retval
+ * true valid ower psk
+ * false Invalid owner psk or failed to owner psk verification
+ */
+static bool isValidOwnerPSK(const OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
+ const OicSecDoxm_t* doxm)
+{
+ //Decode received PSK to verify OwnerPSKs match
+ uint32_t privLen = strlen(receviedCred->privateData.data);
+ size_t b64BufSize = B64DECODE_OUT_SAFESIZE((privLen + 1) * sizeof(char));
+ uint8_t* decodeBuff = OICMalloc(b64BufSize);
+ VERIFY_NON_NULL(TAG, decodeBuff, ERROR);
+ uint32_t decodedSize = 0;
+ B64Result b64Ret = b64Decode(receviedCred->privateData.data, privLen,
+ decodeBuff, b64BufSize, &decodedSize);
+ VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+
+ //Derive OwnerPSK locally
+ const char* oxmLabel = GetOxmString(doxm->oxmSel);
+ VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
+
+ uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
+ CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
+ (uint8_t*)oxmLabel, strlen(oxmLabel),
+ doxm->owner.id, sizeof(doxm->owner.id),
+ doxm->deviceID.id, sizeof(doxm->deviceID.id),
+ ownerPSK, OWNER_PSK_LENGTH_128);
+ VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
+
+ OIC_LOG_V(DEBUG, TAG, "Oxm Label = %s", oxmLabel);
+ OIC_LOG_V(DEBUG, TAG, "PSK size compare : %s",
+ OWNER_PSK_LENGTH_128 == decodedSize ? "TRUE" : "FALSE");
+ OIC_LOG_V(DEBUG, TAG, "SubjectID compare = %s",
+ memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 ?
+ "TRUE" : "FALSE");
+ OIC_LOG_V(DEBUG, TAG, "Owner PSK compare = %s",
+ memcmp(ownerPSK, decodeBuff, OWNER_PSK_LENGTH_128) == 0 ? "TRUE" : "FALSE");
+
+ //Verify OwnerPSKs match
+ return (OWNER_PSK_LENGTH_128 == decodedSize &&
+ memcmp(ownerPSK, decodeBuff, OWNER_PSK_LENGTH_128) == 0 &&
+ memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0);
+exit:
+ return false;
+}
+
+#endif //__WITH_DTLS__
+
+static OCEntityHandlerResult HandlePutRequest(const OCEntityHandlerRequest * ehRequest)
+{
+ OCEntityHandlerResult ret = OC_EH_ERROR;
+
+ //Get binary representation of json
+ OicSecCred_t * cred = JSONToCredBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
+
+ if(cred)
+ {
+#ifdef __WITH_DTLS__
+ OicUuid_t emptyUuid = {.id={0}};
+ const OicSecDoxm_t* doxm = GetDoxmResourceData();
+ if(false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
+ {
+ //in case of owner PSK
+ switch(cred->credType)
+ {
+ case SYMMETRIC_PAIR_WISE_KEY:
+ {
+ OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
+ if(isValidOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
+ {
+ OIC_LOG(ERROR, TAG, "OwnerPKS is matched");
+ if(OC_STACK_OK == AddCredential(cred))
+ {
+ ret = OC_EH_RESOURCE_CREATED;
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
+ ret = OC_EH_ERROR;
+ }
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
+ ret = OC_EH_ERROR;
+ }
+
+ break;
+ }
+ case SYMMETRIC_GROUP_KEY:
+ case ASYMMETRIC_KEY:
+ case SIGNED_ASYMMETRIC_KEY:
+ case PIN_PASSWORD:
+ case ASYMMETRIC_ENCRYPTION_KEY:
+ {
+ OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
+ ret = OC_EH_ERROR;
+ break;
+ }
+ default:
+ {
+ OIC_LOG(WARNING, TAG, "Unknow credential type for owner credential.");
+ ret = OC_EH_ERROR;
+ break;
+ }
+ }
+ }
+ else
+ {
+ /*
+ * If the post request credential has credId, it will be
+ * discarded and the next available credId will be assigned
+ * to it before getting appended to the existing credential
+ * list and updating svr database.
+ */
+ ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
+ }
+#else //not __WITH_DTLS__
+ /*
+ * If the post request credential has credId, it will be
+ * discarded and the next available credId will be assigned
+ * to it before getting appended to the existing credential
+ * list and updating svr database.
+ */
+ ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
+#endif//__WITH_DTLS__
+ }
+
+ return ret;
+}
+
static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
{
OCEntityHandlerResult ret = OC_EH_ERROR;
//discarded and the next available credId will be assigned
//to it before getting appended to the existing credential
//list and updating svr database.
- ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
+ ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;\r
}
+
return ret;
}
case OC_REST_GET:
ret = OC_EH_FORBIDDEN;
break;
+ case OC_REST_PUT:
+ ret = HandlePutRequest(ehRequest);
+ break;
case OC_REST_POST:
ret = HandlePostRequest(ehRequest);
break;
return ret;
}
-/**
- * Add temporal PSK to PIN based OxM
- *
- * @param[in] tmpSubject UUID of target device
- * @param[in] credType Type of credential to be added
- * @param[in] pin numeric characters
- * @param[in] pinSize length of 'pin'
- * @param[in] ownersLen Number of owners
- * @param[in] owners Array of owners
- * @param[out] tmpCredSubject Generated credential's subject.
- *
- * @return OC_STACK_OK for success and errorcode otherwise.
- */
-OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
- const char * pin, size_t pinSize,
- size_t ownersLen, const OicUuid_t * owners, OicUuid_t* tmpCredSubject)
-{
- OCStackResult ret = OC_STACK_ERROR;
-
- if(tmpSubject == NULL || pin == NULL || pinSize == 0 || tmpCredSubject == NULL)
- {
- return OC_STACK_INVALID_PARAM;
- }
-
- uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
- int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, owners->id,
- UUID_LENGTH, PBKDF_ITERATIONS,
- OWNER_PSK_LENGTH_128, privData);
- VERIFY_SUCCESS(TAG, (dtlsRes == 0) , ERROR);
-
- uint32_t outLen = 0;
- char base64Buff[B64ENCODE_OUT_SAFESIZE(OWNER_PSK_LENGTH_128) + 1] = {};
- B64Result b64Ret = b64Encode(privData, OWNER_PSK_LENGTH_128, base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, (B64_OK == b64Ret), ERROR);
-
- OicSecCred_t* cred = GenerateCredential(tmpSubject, credType, NULL,
- base64Buff, ownersLen, owners);
- if(NULL == cred)
- {
- OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
- return OC_STACK_ERROR;
- }
-
- memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
-
- ret = AddCredential(cred);
- if( OC_STACK_OK != ret)
- {
- OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
- }
-
-exit:
- return ret;
-}
-
#endif /* __WITH_DTLS__ */
#ifdef __WITH_X509__
#define CERT_LEN_PREFIX (3)
return ehRet;
}
-#ifdef __WITH_DTLS__
-/*
- * Generating new credential for provisioning tool
- *
- * PSK generated by
- */
-static OCEntityHandlerResult AddOwnerPSK(const CAEndpoint_t* endpoint,
- OicSecDoxm_t* ptDoxm,
- const uint8_t* label, const size_t labelLen)
-{
- size_t ownLen = 1;
- uint32_t outLen = 0;
- OicSecCred_t *cred = NULL;
- uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {};
-
- CAResult_t pskRet = CAGenerateOwnerPSK(endpoint,
- label, labelLen,
- ptDoxm->owner.id, sizeof(ptDoxm->owner.id),
- gDoxm->deviceID.id, sizeof(gDoxm->deviceID.id),
- ownerPSK, OWNER_PSK_LENGTH_128);
-
- VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
-
- char base64Buff[B64ENCODE_OUT_SAFESIZE(OWNER_PSK_LENGTH_128) + 1] = {};
- B64Result b64Ret = b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
-
- OIC_LOG (DEBUG, TAG, "Doxm EntityHandle generating Credential");
- cred = GenerateCredential(&ptDoxm->owner, SYMMETRIC_PAIR_WISE_KEY,
- NULL, base64Buff, ownLen, &ptDoxm->owner);
- VERIFY_NON_NULL(TAG, cred, ERROR);
-
- //Adding provisioning tool credential to cred Resource.
- VERIFY_SUCCESS(TAG, OC_STACK_OK == AddCredential(cred), ERROR);
-
- gDoxm->owned = true;
- gDoxm->oxmSel = ptDoxm->oxmSel;
- memcpy(&(gDoxm->owner), &(ptDoxm->owner), sizeof(OicUuid_t));
-
- return OC_EH_OK;
-
-exit:
- return OC_EH_ERROR;
-}
-#endif //__WITH_DTLS__
-
static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest * ehRequest)
{
OIC_LOG (DEBUG, TAG, "Doxm EntityHandle processing PUT request");
// Iotivity SRM ONLY supports OIC_JUST_WORKS now
if (OIC_JUST_WORKS == newDoxm->oxmSel)
{
- /*
- * 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.
- */
if ((false == gDoxm->owned) && (false == newDoxm->owned))
{
- OIC_LOG (INFO, TAG, "Doxm EntityHandle enabling AnonECDHCipherSuite");
-#ifdef __WITH_DTLS__
- ehRet = (CAEnableAnonECDHCipherSuite(true) == CA_STATUS_OK) ? OC_EH_OK : OC_EH_ERROR;
-#endif //__WITH_DTLS__
- goto exit;
- }
-
- /*
- * When current state of the device is un-owned and Provisioning
- * Tool is attempting to change the state to 'Owned' with a
- * qualified value for the field 'Owner'
- */
- if ((false == gDoxm->owned) && (true == newDoxm->owned) &&
- (memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0))
- {
/*
- * Generate OwnerPSK and create credential for Provisioning
- * tool with the generated OwnerPSK.
- * Update persistent storage and disable anonymous ECDH cipher
- *
+ * 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.
*/
-#ifdef __WITH_DTLS__
- OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
-
- //Generating OwnerPSK
- OIC_LOG (INFO, TAG, "Doxm EntityHandle generating OwnerPSK");
-
- //Generate new credential for provisioning tool
- ehRet = AddOwnerPSK((CAEndpoint_t *)&request->devAddr, newDoxm,
- (uint8_t*) OXM_JUST_WORKS, strlen(OXM_JUST_WORKS));
-
- VERIFY_SUCCESS(TAG, OC_EH_OK == ehRet, ERROR);
-
- // Update new state in persistent storage
- if (true == UpdatePersistentStorage(gDoxm))
+ if(memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) == 0)
{
- ehRet = OC_EH_OK;
+ OIC_LOG (INFO, TAG, "Doxm EntityHandle enabling AnonECDHCipherSuite");
+#ifdef __WITH_DTLS__
+ ehRet = (CAEnableAnonECDHCipherSuite(true) == CA_STATUS_OK) ? OC_EH_OK : OC_EH_ERROR;
+#endif //__WITH_DTLS__
+ goto exit;
}
else
{
- ehRet = OC_EH_ERROR;
+#ifdef __WITH_DTLS__
+ //Save the owner's UUID to derive owner credential
+ memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t));
+
+// OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
+// //Generating OwnerPSK
+// OIC_LOG (INFO, TAG, "Doxm EntityHandle generating OwnerPSK");
+// //Generate new credential for provisioning tool
+// ehRet = AddOwnerPSK((CAEndpoint_t *)&request->devAddr, newDoxm,
+// (uint8_t*) OXM_JUST_WORKS, strlen(OXM_JUST_WORKS));
+// VERIFY_SUCCESS(TAG, OC_EH_OK == ehRet, ERROR);
+
+ // Update new state in persistent storage
+ if (true == UpdatePersistentStorage(gDoxm))
+ {
+ ehRet = OC_EH_OK;
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "Failed to update DOXM in persistent storage");
+ ehRet = OC_EH_ERROR;
+ }
/*
- * If persistent storage update failed, revert back the state
- * for global variable.
+ * Disable anonymous ECDH cipher in tinyDTLS since device is now
+ * in owned state.
*/
- gDoxm->owned = false;
- gDoxm->oxmSel = 0;
- memset(&(gDoxm->owner), 0, sizeof(OicUuid_t));
- }
-
- /*
- * Disable anonymous ECDH cipher in tinyDTLS since device is now
- * in owned state.
- */
- CAEnableAnonECDHCipherSuite(false);
+ CAEnableAnonECDHCipherSuite(false);
#ifdef __WITH_X509__
#define TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE
- CASelectCipherSuite(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
+ CASelectCipherSuite(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
#endif //__WITH_X509__
#endif //__WITH_DTLS__
+ }
}
}
else if(OIC_RANDOM_DEVICE_PIN == newDoxm->oxmSel)
{
-#ifdef __WITH_DTLS__
- //this temp Credential ID is used to track temporal Cred Id
- static OicUuid_t tmpCredId = {.id={0}};
- static bool tmpCredGenFlag = false;
-#endif //__WITH_DTLS__
-
if ((false == gDoxm->owned) && (false == newDoxm->owned))
{
-#ifdef __WITH_DTLS__
- CAEnableAnonECDHCipherSuite(false);
- OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
- CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256);
-
- char ranPin[OXM_RANDOM_PIN_SIZE + 1] = {0,};
- if(OC_STACK_OK == GeneratePin(ranPin, OXM_RANDOM_PIN_SIZE + 1))
+ /*
+ * 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.
+ */
+ if(memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) == 0)
{
- if(tmpCredGenFlag)
+ gDoxm->oxmSel = newDoxm->oxmSel;
+ //Update new state in persistent storage
+ if((UpdatePersistentStorage(gDoxm) == true))
{
- OIC_LOG(INFO, TAG, "Corrupted PSK is detected!!!");
- VERIFY_SUCCESS(TAG,
- OC_STACK_RESOURCE_DELETED == RemoveCredential(&tmpCredId),
- ERROR);
+ ehRet = OC_EH_OK;
+ }
+ else
+ {
+ OIC_LOG(WARNING, TAG, "Failed to update DOXM in persistent storage");
+ ehRet = OC_EH_ERROR;
}
- OCStackResult res = AddTmpPskWithPIN( &(newDoxm->owner), SYMMETRIC_PAIR_WISE_KEY,
- ranPin, OXM_RANDOM_PIN_SIZE, 1, &(newDoxm->owner), &tmpCredId);
- VERIFY_SUCCESS(TAG, res == OC_STACK_OK, ERROR);
- tmpCredGenFlag = true;
- ehRet = OC_EH_OK;
- }
- else
- {
- OIC_LOG(ERROR, TAG, "Failed to generate random PIN");
- ehRet = OC_EH_ERROR;
- }
-
-#endif //__WITH_DTLS__
- }
-
- /*
- * When current state of the device is un-owned and Provisioning
- * Tool is attempting to change the state to 'Owned' with a
- * qualified value for the field 'Owner'
- */
- if ((false == gDoxm->owned) && (true == newDoxm->owned) &&
- (memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0))
- {
#ifdef __WITH_DTLS__
- OCServerRequest * request = (OCServerRequest *)ehRequest->requestHandle;
+ CAResult_t caRes = CA_STATUS_OK;
- //Remove Temporal Credential resource
- if(tmpCredGenFlag)
- {
- VERIFY_SUCCESS(TAG,
- OC_STACK_RESOURCE_DELETED == RemoveCredential(&tmpCredId),
- ERROR);
- tmpCredGenFlag = false;
- }
+ caRes = CAEnableAnonECDHCipherSuite(false);
+ VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
+ OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
- //Generate new credential for provisioning tool
- ehRet = AddOwnerPSK((CAEndpoint_t*)(&request->devAddr), newDoxm,
- (uint8_t*)OXM_RANDOM_DEVICE_PIN, strlen(OXM_RANDOM_DEVICE_PIN));
- VERIFY_SUCCESS(TAG, OC_EH_OK == ehRet, ERROR);
+ caRes = CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256);
+ VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
- //Update new state in persistent storage
- if((UpdatePersistentStorage(gDoxm) == true))
- {
- ehRet = OC_EH_OK;
+ char ranPin[OXM_RANDOM_PIN_SIZE + 1] = {0,};
+ if(OC_STACK_OK == GeneratePin(ranPin, OXM_RANDOM_PIN_SIZE + 1))
+ {
+ //Set the device id to derive temporal PSK
+ SetUuidForRandomPinOxm(&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 = CARegisterDTLSCredentialsHandler(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__
}
else
{
- /*
- * If persistent storage update failed, revert back the state
- * for global variable.
- */
- gDoxm->owned = false;
- gDoxm->oxmSel = 0;
- memset(&(gDoxm->owner), 0, sizeof(OicUuid_t));
- ehRet = OC_EH_ERROR;
+#ifdef __WITH_DTLS__
+ //Save the owner's UUID to derive owner credential
+ memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t));
- }
+// OCServerRequest * request = (OCServerRequest *)ehRequest->requestHandle;
+// //Generate new credential for provisioning tool
+// ehRet = AddOwnerPSK((CAEndpoint_t*)(&request->devAddr), newDoxm,
+// (uint8_t*)OXM_RANDOM_DEVICE_PIN, strlen(OXM_RANDOM_DEVICE_PIN));
+// VERIFY_SUCCESS(TAG, OC_EH_OK == ehRet, ERROR);
+
+ //Update new state in persistent storage
+ if((UpdatePersistentStorage(gDoxm) == true))
+ {
+ ehRet = OC_EH_OK;
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "Failed to update DOXM in persistent storage");
+ ehRet = OC_EH_ERROR;
+ }
#endif
- }
+ }
+ }
+ }
+
+ /*
+ * When current state of the device is un-owned and Provisioning
+ * Tool is attempting to change the state to 'Owned' with a
+ * qualified value for the field 'Owner'
+ */
+ if ((false == gDoxm->owned) && (true == newDoxm->owned) &&
+ (memcmp(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t)) == 0))
+ {
+ gDoxm->owned = true;
+ // Update new state in persistent storage
+ if (true == UpdatePersistentStorage(gDoxm))
+ {
+ ehRet = OC_EH_OK;
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "Failed to update DOXM in persistent storage");
+ ehRet = OC_EH_ERROR;
+ }
}
}
exit:
+ if(OC_EH_OK != ehRet)
+ {
+ OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request,"\
+ "DOXM will be reverted.");
+
+ /*
+ * If persistent storage update failed, revert back the state
+ * for global variable.
+ */
+ gDoxm->owned = false;
+ gDoxm->oxmSel = OIC_JUST_WORKS;
+ memset(&(gDoxm->owner), 0, sizeof(OicUuid_t));
+
+ if(!UpdatePersistentStorage(gDoxm))
+ {
+ OIC_LOG(ERROR, TAG, "Failed to revert DOXM in persistent storage");
+ }
+ }
//Send payload to request originator
if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL))