SetGeneratePinCB
SetInputPinCB
+SetRandomPinPolicy
\ No newline at end of file
extern "C" {
#endif // __cplusplus
-#define OXM_RANDOM_PIN_SIZE (8)
-#define OXM_PRECONFIG_PIN_SIZE (OXM_RANDOM_PIN_SIZE)
+#define OXM_RANDOM_PIN_DEFAULT_SIZE (8)
+#define OXM_RANDOM_PIN_DEFAULT_PIN_TYPE (NUM_PIN | LOWERCASE_CHAR_PIN | UPPERCASE_CHAR_PIN)
+#define OXM_RANDOM_PIN_MIN_SIZE (4)
+#define OXM_RANDOM_PIN_MAX_SIZE (32)
+#define OXM_PRECONFIG_PIN_MAX_SIZE (OXM_RANDOM_PIN_MAX_SIZE)
+/** Number of PIN type */
+#define OXM_PIN_TYPE_COUNT 3
+
+/**
+ * PIN type definition.
+ * This type supports multiple bit set.
+ * e.g.) NUM_PIN | UPPERCASE_CHAR_PIN
+ */
+typedef enum OicSecPinType{
+ NUM_PIN = (0x1 << 0), //Numeric PIN
+ UPPERCASE_CHAR_PIN = (0x1 << 1), //uppercase character PIN
+ LOWERCASE_CHAR_PIN = (0x1 << 2) //lowercase character PIN
+}OicSecPinType_t;
/**
* Function pointer to print pin code.
* @param pinBuffer is the reference to the buffer to store the generated PIN data.
* @param bufferSize is the size of buffer.
*
- * @return ::OC_STACK_SUCCESS in case of success or other value in case of error.
+ * @return ::OC_STACK_OK in case of success or other value in case of error.
*/
OCStackResult GeneratePin(char* pinBuffer, size_t bufferSize);
* @param[in,out] pinBuffer is the reference to the buffer to store the inputed PIN data.
* @param[in] bufferSize is the size of buffer.
*
- * @return ::OC_STACK_SUCCESS in case of success or other value in ccase of error.
+ * @return ::OC_STACK_OK in case of success or other value in ccase of error.
*/
OCStackResult InputPin(char* pinBuffer, size_t bufferSize);
-
#ifdef _ENABLE_MULTIPLE_OWNER_
/**
* Function to save the Pre-configured PIN.
OCStackResult GetPreconfigPin(char* pinBuffer, size_t bufferSize);
#endif
+/**
+ * Function to setting the policy for random PIN generation
+ *
+ * @param[in] pinSize Byte length of random PIN
+ * @param[in] pinType Type of random PIN (ref OicSecPinType)
+ *
+ * @return ::OC_STACK_OK in case of success or other value in case of error.
+ */
+OCStackResult SetRandomPinPolicy(size_t pinSize, OicSecPinType_t pinType);
+
#ifdef __WITH_DTLS__
/**
static void inputPinCB(char* pin, size_t len)
{
- if(!pin || OXM_RANDOM_PIN_SIZE>=len)
+ if(!pin || OXM_RANDOM_PIN_MIN_SIZE > len)
{
OIC_LOG(ERROR, TAG, "inputPinCB invalid parameters");
return;
printf(" > INPUT PIN: ");
for(int ret=0; 1!=ret; )
{
- ret = scanf("%8s", pin);
+ ret = scanf("%32s", pin);
for( ; 0x20<=getchar(); ); // for removing overflow garbages
// '0x20<=code' is character region
}
*/
SetGeneratePinCB(GeneratePinCB);
+ /**
+ * Random PIN generation policy can be changed through SetRandomPinPolicy() API.
+ * first param : byte length of random PIN ( 4 <= first param <= 32)
+ * second param : PIN type (This is bitmask)
+ */
+ if(OC_STACK_OK != SetRandomPinPolicy(8, NUM_PIN))
+ {
+ OIC_LOG(ERROR, TAG, "Failed to setting PIN policy");
+ return 0;
+ }
+
/*
* Declare and create the example resource: LED
*/
char in = getchar();
if('G' == in || 'g' == in)
{
- char ranPin[OXM_RANDOM_PIN_SIZE + 1] = {0};
- GeneratePin(ranPin, OXM_RANDOM_PIN_SIZE + 1);
+ char ranPin[OXM_RANDOM_PIN_MAX_SIZE + 1] = {0};
+ GeneratePin(ranPin, sizeof(ranPin));
}
if('E' == in || 'e' == in)
{
static void inputPinCB(char* pin, size_t len)
{
- if(!pin || OXM_RANDOM_PIN_SIZE>=len)
+ if(!pin || OXM_RANDOM_PIN_MAX_SIZE>=len)
{
OIC_LOG(ERROR, TAG, "inputPinCB invalid parameters");
return;
printf(" > INPUT PIN: ");
for(int ret=0; 1!=ret; )
{
- ret = scanf("%8s", pin);
+ ret = scanf("%32s", pin);
for( ; 0x20<=getchar(); ); // for removing overflow garbages
// '0x20<=code' is character region
}
if(OIC_PRECONFIG_PIN == dev->doxm->oxmSel)
{
//Pre-Configured PIN initialization
- if(OC_STACK_OK != OCAddPreconfigPIN(dev, "12341234", OXM_PRECONFIG_PIN_SIZE))
+ const char* testPreconfPin = "12341234";
+ if(OC_STACK_OK != OCAddPreconfigPIN(dev, testPreconfPin, strlen(testPreconfPin)))
{
printf("\n\n\n*** %60s ***\n", "WARNNING : Failed to save the pre-configured PIN");
printf("*** %60s ***\n\n\n", "WARNNING : You can't use the pre-configured PIN OxM for MOT");
VERIFY_NON_NULL(TAG, targetDeviceInfo, ERROR);
VERIFY_NON_NULL(TAG, preconfPIN, ERROR);
VERIFY_SUCCESS(TAG, (0 != preconfPINLen), ERROR);
- VERIFY_SUCCESS(TAG, (0 != preconfPINLen && OXM_PRECONFIG_PIN_SIZE >= preconfPINLen), ERROR);
+ VERIFY_SUCCESS(TAG, (0 != preconfPINLen && OXM_PRECONFIG_PIN_MAX_SIZE >= preconfPINLen), ERROR);
postCredRes = OC_STACK_NO_MEMORY;
//Generate PIN based credential
VERIFY_NON_NULL(TAG, targetDeviceInfo, ERROR);
VERIFY_NON_NULL(TAG, preconfPIN, ERROR);
VERIFY_SUCCESS(TAG, (0 != preconfPINLen), ERROR);
- VERIFY_SUCCESS(TAG, (0 != preconfPINLen && OXM_PRECONFIG_PIN_SIZE >= preconfPINLen), ERROR);
+ VERIFY_SUCCESS(TAG, (0 != preconfPINLen && OXM_PRECONFIG_PIN_MAX_SIZE >= preconfPINLen), ERROR);
OicSecCred_t* prevCred = GetCredResourceData(&targetDeviceInfo->doxm->deviceID);
if(NULL != prevCred)
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 = InputPin((char*)pinData, OXM_RANDOM_PIN_SIZE + 1);
+ OCStackResult res = InputPin((char*)pinData, sizeof(pinData));
if (OC_STACK_OK != res)
{
OIC_LOG(ERROR, TAG, "Failed to input PIN");
ehRequest->devAddr.adapter);
VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
- char ranPin[OXM_RANDOM_PIN_SIZE + 1] = {0,};
+ char ranPin[OXM_RANDOM_PIN_MAX_SIZE + 1] = {0};
//TODO ehRequest->messageID for copa over TCP always is null. Find reason why.
if(ehRequest->devAddr.adapter == OC_ADAPTER_IP && previousMsgId != ehRequest->messageID)
{
- if(OC_STACK_OK == GeneratePin(ranPin, OXM_RANDOM_PIN_SIZE + 1))
+ if(OC_STACK_OK == GeneratePin(ranPin, sizeof(ranPin)))
{
//Set the device id to derive temporal PSK
SetUuidForPinBasedOxm(&gDoxm->deviceID);
}
else if(previousMsgId != ehRequest->messageID)
{
- if(OC_STACK_OK == GeneratePin(ranPin, OXM_RANDOM_PIN_SIZE + 1))
+ if(OC_STACK_OK == GeneratePin(ranPin, sizeof(ranPin)))
{
//Set the device id to derive temporal PSK
SetUuidForPinBasedOxm(&gDoxm->deviceID);
#define TAG "PIN_OXM_COMMON"
+#define NUMBER_OF_PINNUM (10)
+#define NUMBER_OF_ALPHABET (26)
+
static GeneratePinCallback gGenPinCallback = NULL;
static InputPinCallback gInputPinCallback = 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)
{
gGenPinCallback = NULL;
}
+/**
+ * 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;
+ }
+
+ return allowedCharacters[OCGetRandomRange(0, curIndex)];
+}
+
OCStackResult GeneratePin(char* pinBuffer, size_t bufferSize)
{
if(!pinBuffer)
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))
{
- pinBuffer[i] = OCGetRandomRange((uint32_t)'0', (uint32_t)'9');
+ 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] = 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
{
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;
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(g_PinOxmData.pinData, OXM_RANDOM_PIN_MAX_SIZE + 1, pinBuffer);
+ g_PinOxmData.pinSize = strlen(g_PinOxmData.pinData);
}
else
{
#ifdef _ENABLE_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;
}
{
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);