Merge tizen_5.0 codes into tizen_4.0
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / src / ownershiptransfermanager.c
index fc7946b..a483e7a 100644 (file)
@@ -66,6 +66,7 @@
 #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;
@@ -112,9 +116,9 @@ OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks)
 
 #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)
@@ -160,6 +164,12 @@ OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks)
         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;
@@ -172,6 +182,18 @@ exit:
     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.
  */
@@ -189,6 +211,8 @@ static OxmAllowTableIdx_t GetOxmAllowTableIdx(OicSecOxm_t oxm)
             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
@@ -227,6 +251,11 @@ OCStackResult OTMSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMetho
     {
         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]);
@@ -235,19 +264,45 @@ OCStackResult OTMSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMetho
                     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:
@@ -955,6 +1010,13 @@ exit:
     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.
  *
@@ -986,7 +1048,7 @@ static OCStackApplicationResult OwnerUuidUpdateHandler(void *ctx, OCDoHandle UNU
                 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");
                     }
@@ -2127,7 +2189,7 @@ static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selecte
         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)
@@ -2158,6 +2220,60 @@ exit:
     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");
@@ -2180,6 +2296,58 @@ OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxmType, OTMCallba
     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
  */