replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / src / oxmrandompin.c
index e10f343..314e5b7 100644 (file)
 #include "oic_malloc.h"
 #include "logger.h"
 #include "pbkdf2.h"
-#include "global.h"
 #include "base64.h"
 #include "oxmrandompin.h"
 #include "ownershiptransfermanager.h"
 #include "pinoxmcommon.h"
+#include "oxmverifycommon.h"
 
-#define TAG "OXM_RandomPIN"
+#define TAG "OIC_OXM_RandomPIN"
 
-char* CreatePinBasedSelectOxmPayload(OTMContext_t* otmCtx)
+typedef enum PinState{
+    PIN_INPUT_READY = 0,
+    PIN_INPUT_WAIT = 1,
+    PIN_INPUT_SUCCESS = 2,
+    PIN_INPUT_FAIL = 3
+} PinState_t;
+
+static PinState_t gPinState = PIN_INPUT_READY;
+
+OCStackResult CreatePinBasedSelectOxmPayload(OTMContext_t* otmCtx, uint8_t **payload, size_t *size)
 {
-    if(!otmCtx || !otmCtx->selectedDeviceInfo)
+    if(!otmCtx || !otmCtx->selectedDeviceInfo || !payload || *payload || !size)
     {
-        return NULL;
+        return OC_STACK_INVALID_PARAM;
     }
 
     otmCtx->selectedDeviceInfo->doxm->oxmSel = OIC_RANDOM_DEVICE_PIN;
 
-    return BinToDoxmJSON(otmCtx->selectedDeviceInfo->doxm);
+    return DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm, payload, size, true);
 }
 
-char* CreatePinBasedOwnerTransferPayload(OTMContext_t* otmCtx)
+OCStackResult CreatePinBasedOwnerTransferPayload(OTMContext_t* otmCtx, uint8_t **payload, size_t *size)
 {
-    if(!otmCtx || !otmCtx->selectedDeviceInfo)
+    if(!otmCtx || !otmCtx->selectedDeviceInfo || !payload || *payload || !size)
     {
-        return NULL;
+        return OC_STACK_INVALID_PARAM;
     }
 
     OicUuid_t uuidPT = {.id={0}};
+    *payload = NULL;
+    *size = 0;
 
     if (OC_STACK_OK != GetDoxmDeviceID(&uuidPT))
     {
         OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
-        return NULL;
+        return OC_STACK_ERROR;
     }
     memcpy(otmCtx->selectedDeviceInfo->doxm->owner.id, uuidPT.id , UUID_LENGTH);
 
-    return BinToDoxmJSON(otmCtx->selectedDeviceInfo->doxm);
+    return DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm, payload, size, true);
 }
 
-OCStackResult InputPinCodeCallback(OTMContext_totmCtx)
+OCStackResult InputPinCodeCallback(OTMContext_t *otmCtx)
 {
-    if(!otmCtx || !otmCtx->selectedDeviceInfo)
+    if (!otmCtx || !otmCtx->selectedDeviceInfo)
     {
         return OC_STACK_INVALID_PARAM;
     }
 
-    uint8_t pinData[OXM_RANDOM_PIN_SIZE + 1];
+    uint8_t pinData[OXM_RANDOM_PIN_MAX_SIZE + 1] = {0};
+    OCStackResult res = OC_STACK_ERROR;
+
+    if (PIN_INPUT_WAIT == gPinState)
+    {
+        OIC_LOG(ERROR, TAG, "Pin input callback invoked already");
+        NotifyInputState();
+        SetResult(otmCtx, res);
+        return OC_STACK_NOT_ACCEPTABLE;
+    }
+
+    gPinState = PIN_INPUT_WAIT;
 
-    OCStackResult res = InputPin((char*)pinData, OXM_RANDOM_PIN_SIZE + 1);
-    if(OC_STACK_OK != res)
+    res = InputPin((char*)pinData, sizeof(pinData));
+    if (OC_STACK_OK != res)
     {
         OIC_LOG(ERROR, TAG, "Failed to input PIN");
+        gPinState = PIN_INPUT_FAIL;
+        SetResult(otmCtx, res);
         return res;
     }
+    gPinState = PIN_INPUT_SUCCESS;
 
     /**
      * Since PSK will be used directly while PIN based ownership transfer,
      * Credential should not be saved into SVR.
      * For this reason, We will use a temporary get_psk_info callback to random PIN OxM.
      */
-    if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskForRandomPinOxm))
+    //in case of OTM
+    if(!(otmCtx->selectedDeviceInfo->doxm->owned))
     {
-        OIC_LOG(ERROR, TAG, "Failed to register DTLS credentials handler for random PIN OxM.");
-        res = OC_STACK_ERROR;
+        if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskForRandomPinOxm))
+        {
+            OIC_LOG(ERROR, TAG, "Failed to register DTLS credentials handler for random PIN OxM.");
+            res = OC_STACK_ERROR;
+        }
     }
+#ifdef MULTIPLE_OWNER
+    //in case of MOT
+    else if(otmCtx->selectedDeviceInfo->doxm->owned &&
+            otmCtx->selectedDeviceInfo->doxm->mom &&
+            OIC_MULTIPLE_OWNER_DISABLE != otmCtx->selectedDeviceInfo->doxm->mom->mode)
+    {
+        if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskForMotRandomPinOxm))
+        {
+            OIC_LOG(ERROR, TAG, "Failed to register TLS credentials handler for random PIN OxM.");
+            res = OC_STACK_ERROR;
+        }
+    }
+#endif //MULTIPLE_OWNER
 
     //Set the device id to derive temporal PSK
-    SetUuidForRandomPinOxm(&(otmCtx->selectedDeviceInfo->doxm->deviceID));
+    SetUuidForPinBasedOxm(&(otmCtx->selectedDeviceInfo->doxm->deviceID));
 
     return res;
 }
 
-OCStackResult CreateSecureSessionRandomPinCallbak(OTMContext_t* otmCtx)
+OCStackResult CreateSecureSessionRandomPinCallback(OTMContext_t* otmCtx)
 {
     OIC_LOG(INFO, TAG, "IN CreateSecureSessionRandomPinCallbak");
 
-    if(!otmCtx || !otmCtx->selectedDeviceInfo)
+    if (!otmCtx || !otmCtx->selectedDeviceInfo)
     {
         return OC_STACK_INVALID_PARAM;
     }
@@ -119,25 +161,34 @@ OCStackResult CreateSecureSessionRandomPinCallbak(OTMContext_t* otmCtx)
     }
     OIC_LOG(INFO, TAG, "Anonymous cipher suite disabled.");
 
-    caresult  = CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256);
+    caresult  = CASelectCipherSuite(MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, otmCtx->selectedDeviceInfo->endpoint.adapter);
     if (CA_STATUS_OK != caresult)
     {
-        OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256");
+        OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256");
         return OC_STACK_ERROR;
     }
-    OIC_LOG(INFO, TAG, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 cipher suite selected.");
-
+    OIC_LOG(INFO, TAG, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 cipher suite selected.");
 
     OCProvisionDev_t* selDevInfo = otmCtx->selectedDeviceInfo;
-    CAEndpoint_t *endpoint = (CAEndpoint_t *)OICCalloc(1, sizeof (CAEndpoint_t));
-    if(NULL == endpoint)
+    CAEndpoint_t endpoint;
+    memcpy(&endpoint, &selDevInfo->endpoint, sizeof(CAEndpoint_t));
+
+    if(CA_ADAPTER_IP == endpoint.adapter)
     {
-        return OC_STACK_NO_MEMORY;
+        endpoint.port = selDevInfo->securePort;
+        caresult = CAInitiateHandshake(&endpoint);
     }
-    memcpy(endpoint,&selDevInfo->endpoint,sizeof(CAEndpoint_t));
-    endpoint->port = selDevInfo->securePort;
-    caresult = CAInitiateHandshake(endpoint);
-    OICFree(endpoint);
+    else if (CA_ADAPTER_GATT_BTLE == endpoint.adapter)
+    {
+        caresult = CAInitiateHandshake(&endpoint);
+    }
+#ifdef __WITH_TLS__
+    else
+    {
+        endpoint.port = selDevInfo->tcpPort;
+        caresult = CAinitiateSslHandshake(&endpoint);
+    }
+#endif
     if (CA_STATUS_OK != caresult)
     {
         OIC_LOG_V(ERROR, TAG, "DTLS handshake failure.");
@@ -148,4 +199,3 @@ OCStackResult CreateSecureSessionRandomPinCallbak(OTMContext_t* otmCtx)
 
     return OC_STACK_OK;
 }
-