replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / security / src / oxmpincommon.c
index 569b7d1..ad70a43 100644 (file)
@@ -18,7 +18,9 @@
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
+#ifndef __TIZENRT__
 #include <memory.h>
+#endif
 
 #include "ocstack.h"
 #include "ocrandom.h"
 #include "doxmresource.h"
 #include "credresource.h"
 #include "cainterface.h"
+#include "oic_string.h"
 
-#define TAG "PIN_OXM_COMMON"
+#define TAG "OIC_PIN_OXM_COMMON"
+
+#define NUMBER_OF_PINNUM (10)
+#define NUMBER_OF_ALPHABET (26)
 
 static GeneratePinCallback gGenPinCallback = NULL;
 static InputPinCallback gInputPinCallback = NULL;
+static ClosePinDisplayCallback gClosePinDispalyCallback = NULL;
 
 typedef struct PinOxmData {
-    uint8_t pinData[OXM_RANDOM_PIN_SIZE + 1];
+    uint8_t pinData[OXM_RANDOM_PIN_MAX_SIZE + 1];
+    size_t pinSize;
+    OicSecPinType_t pinType;
     OicUuid_t newDevice;
 }PinOxmData_t;
 
-static PinOxmData_t g_PinOxmData;
+static PinOxmData_t g_PinOxmData = {
+        .pinData={0},
+        .pinSize = OXM_RANDOM_PIN_DEFAULT_SIZE,
+        .pinType = (OicSecPinType_t)(OXM_RANDOM_PIN_DEFAULT_PIN_TYPE),
+    };
 
+/**
+ * Internal function to check pinType
+ */
+static bool IsValidPinType(OicSecPinType_t pinType)
+{
+    return ((NUM_PIN & pinType) ||
+            (LOWERCASE_CHAR_PIN & pinType) ||
+            (UPPERCASE_CHAR_PIN & pinType));
+}
+
+OCStackResult SetRandomPinPolicy(size_t pinSize, OicSecPinType_t pinType)
+{
+    if(OXM_RANDOM_PIN_MIN_SIZE > pinSize)
+    {
+        OIC_LOG(ERROR, TAG, "PIN size is too small");
+        return OC_STACK_INVALID_PARAM;
+    }
+    if(OXM_RANDOM_PIN_MAX_SIZE < pinSize)
+    {
+        OIC_LOG_V(ERROR, TAG, "PIN size can not exceed %d bytes", OXM_RANDOM_PIN_MAX_SIZE);
+        return OC_STACK_INVALID_PARAM;
+    }
+    if(false == IsValidPinType(pinType))
+    {
+        OIC_LOG(ERROR, TAG, "Invalid PIN type.");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    g_PinOxmData.pinSize = pinSize;
+    g_PinOxmData.pinType = pinType;
+
+    return OC_STACK_OK;
+}
 
 void SetInputPinCB(InputPinCallback pinCB)
 {
@@ -67,6 +113,86 @@ void SetGeneratePinCB(GeneratePinCallback pinCB)
     gGenPinCallback = pinCB;
 }
 
+void SetClosePinDisplayCB(ClosePinDisplayCallback closeCB)
+{
+    if (NULL == closeCB)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to set a callback for closing a pin.");
+        return;
+    }
+
+    gClosePinDispalyCallback = closeCB;
+}
+
+
+void UnsetInputPinCB()
+{
+    gInputPinCallback = NULL;
+}
+
+void UnsetGeneratePinCB()
+{
+    gGenPinCallback = NULL;
+}
+
+void UnsetClosePinDisplayCB()
+{
+    gClosePinDispalyCallback = NULL;
+}
+
+void ClosePinDisplay()
+{
+    if (gClosePinDispalyCallback)
+    {
+        gClosePinDispalyCallback();
+    }
+}
+
+/**
+ * Internal function to generate PIN element according to pinType.
+ * This function assumes the pinType is valid.
+ * In case of invalid pinType, '0' will be returned as default vaule.
+ */
+static char GenerateRandomPinElement(OicSecPinType_t pinType)
+{
+    const char defaultRetValue = '0';
+    char allowedCharacters[NUMBER_OF_PINNUM + NUMBER_OF_ALPHABET * 2];
+    size_t curIndex = 0;
+
+    if(NUM_PIN & pinType)
+    {
+        for(char pinEle = '0'; pinEle <= '9'; pinEle++)
+        {
+            allowedCharacters[curIndex++] = pinEle;
+        }
+    }
+    if(UPPERCASE_CHAR_PIN & pinType)
+    {
+        for(char pinEle = 'A'; pinEle <= 'Z'; pinEle++)
+        {
+            allowedCharacters[curIndex++] = pinEle;
+        }
+    }
+    if(LOWERCASE_CHAR_PIN & pinType)
+    {
+        for(char pinEle = 'a'; pinEle <= 'z'; pinEle++)
+        {
+            allowedCharacters[curIndex++] = pinEle;
+        }
+    }
+
+    if(0 == curIndex)
+    {
+        return defaultRetValue;
+    }
+    else
+    {
+        curIndex -= 1;
+    }
+
+    return allowedCharacters[OCGetRandomRange(0, curIndex)];
+}
+
 OCStackResult GeneratePin(char* pinBuffer, size_t bufferSize)
 {
     if(!pinBuffer)
@@ -74,22 +200,30 @@ OCStackResult GeneratePin(char* pinBuffer, size_t bufferSize)
         OIC_LOG(ERROR, TAG, "PIN buffer is NULL");
         return OC_STACK_INVALID_PARAM;
     }
-    if(OXM_RANDOM_PIN_SIZE + 1 > bufferSize)
+    if(g_PinOxmData.pinSize + 1 > bufferSize)
     {
         OIC_LOG(ERROR, TAG, "PIN buffer size is too small");
         return OC_STACK_INVALID_PARAM;
     }
-    for(size_t i = 0; i < OXM_RANDOM_PIN_SIZE; i++)
+    if(false == IsValidPinType(g_PinOxmData.pinType))
+    {
+        OIC_LOG(ERROR, TAG, "Invalid PIN type.");
+        OIC_LOG(ERROR, TAG, "Please set the PIN type using SetRandomPinPolicy API.");
+        return OC_STACK_ERROR;
+    }
+
+    for(size_t i = 0; i < g_PinOxmData.pinSize; i++)
     {
-        pinBuffer[i] = OCGetRandomRange((uint32_t)'0', (uint32_t)'9');
+        pinBuffer[i] = GenerateRandomPinElement(g_PinOxmData.pinType);
         g_PinOxmData.pinData[i] = pinBuffer[i];
     }
-    pinBuffer[OXM_RANDOM_PIN_SIZE] = '\0';
-    g_PinOxmData.pinData[OXM_RANDOM_PIN_SIZE] = '\0';
+
+    pinBuffer[g_PinOxmData.pinSize] = '\0';
+    g_PinOxmData.pinData[g_PinOxmData.pinSize] = '\0';
 
     if(gGenPinCallback)
     {
-        gGenPinCallback(pinBuffer, OXM_RANDOM_PIN_SIZE);
+        gGenPinCallback(pinBuffer, g_PinOxmData.pinSize);
     }
     else
     {
@@ -130,7 +264,7 @@ OCStackResult InputPin(char* pinBuffer, size_t bufferSize)
         OIC_LOG(ERROR, TAG, "PIN buffer is NULL");
         return OC_STACK_INVALID_PARAM;
     }
-    if(OXM_RANDOM_PIN_SIZE + 1 > bufferSize)
+    if(g_PinOxmData.pinSize + 1 > bufferSize)
     {
         OIC_LOG(ERROR, TAG, "PIN buffer size is too small");
         return OC_STACK_INVALID_PARAM;
@@ -138,9 +272,9 @@ OCStackResult InputPin(char* pinBuffer, size_t bufferSize)
 
     if(gInputPinCallback)
     {
-        gInputPinCallback(pinBuffer, OXM_RANDOM_PIN_SIZE + 1);
-        memcpy(g_PinOxmData.pinData, pinBuffer, OXM_RANDOM_PIN_SIZE);
-        g_PinOxmData.pinData[OXM_RANDOM_PIN_SIZE] = '\0';
+        gInputPinCallback(pinBuffer, bufferSize);
+        OICStrcpy((char*)(g_PinOxmData.pinData), OXM_RANDOM_PIN_MAX_SIZE + 1, pinBuffer);
+        g_PinOxmData.pinSize = strlen((char*)(g_PinOxmData.pinData));
     }
     else
     {
@@ -152,10 +286,10 @@ OCStackResult InputPin(char* pinBuffer, size_t bufferSize)
     return OC_STACK_OK;
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
-OCStackResult SetPreconfigPin(const charpinBuffer, size_t pinLength)
+#ifdef MULTIPLE_OWNER
+OCStackResult SetPreconfigPin(const char *pinBuffer, size_t pinLength)
 {
-    if(NULL == pinBuffer || OXM_PRECONFIG_PIN_SIZE < pinLength)
+    if(NULL == pinBuffer || OXM_PRECONFIG_PIN_MAX_SIZE < pinLength)
     {
         return OC_STACK_INVALID_PARAM;
     }
@@ -165,7 +299,7 @@ OCStackResult SetPreconfigPin(const char* pinBuffer, size_t pinLength)
 
     return OC_STACK_OK;
 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 #ifdef __WITH_DTLS__
 
@@ -181,7 +315,7 @@ int DerivePSKUsingPIN(uint8_t* result)
 {
     int dtlsRes = DeriveCryptoKeyFromPassword(
                                               (const unsigned char *)g_PinOxmData.pinData,
-                                              OXM_RANDOM_PIN_SIZE,
+                                              g_PinOxmData.pinSize,
                                               g_PinOxmData.newDevice.id,
                                               UUID_LENGTH, PBKDF_ITERATIONS,
                                               OWNER_PSK_LENGTH_128, result);
@@ -252,7 +386,7 @@ int32_t GetDtlsPskForRandomPinOxm( CADtlsPskCredType_t type,
     return ret;
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 int32_t GetDtlsPskForMotRandomPinOxm( CADtlsPskCredType_t type,
               const unsigned char *UNUSED1, size_t UNUSED2,
               unsigned char *result, size_t result_length)
@@ -515,6 +649,6 @@ int32_t GetDtlsPskForMotPreconfPinOxm( CADtlsPskCredType_t type,
 
     return ret;
 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 #endif //__WITH_DTLS__