Commit f6443b93 authored by leechul's avatar leechul Committed by Sachin Agrawal

Add PIN based OxM for security provisioning

  1. Implement PIN based OxM according to OTM(Ownership Transfer Manager) callbacks.
  2. Add pbkdf2 implementation
  3. Modify doxmresource.c and credresource.c to support PIN based OxM.

NOTE1:This patch will include several compile warning and work around codes.
        It can be removed after the refactored PM and ECDHE_PSK cipher suite of tinydtls is merged
        into security-basecamp branch.
NOTE2:This patch will not working. Please code review only.

[Patch #1] Initial upload.
[Patch #2] Update codes according to comments.
[Patch #3] Update codes according to Mr.Shim's comments.
[Patch #4] Update codes according to Sakthivel's comment.
[Patch #5] Updated to remove arduino build failure
[Patch #6~8] Update code and scons script according to review comments.
[Patch #9] Delete unnecessary codes.
[Patch #10] Rebase
[Patch #11] Rebase
[Patch #12] Merge with refactored PM.
[Patch #13] Remove build error.
[Patch #14] Delete unnecessary files.
[Patch #15] Update according to comments.
            Remove the removable warnings.
[Patch #16] Update according to Shilpa's comments.
[Patch #18] Update according to Shilpa's comments.
[Patch #19] Refresh for rebuild.
[Patch #20] Refresh for rebuild since Jenkins Server issue is Fixed.

Change-Id: I1328db852a4a7e8225737719061b6c61c37a2f9c
Signed-off-by: default avatarleechul <chuls.lee@samsung.com>
Signed-off-by: Randeep's avatarRandeep Singh <randeep.s@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/1989Tested-by: default avatarjenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: default avatarSachin Agrawal <sachin.agrawal@intel.com>
parent 6fb335eb
......@@ -40,7 +40,7 @@ if target_os == 'arduino':
######################################################################
libocsrm_env.PrependUnique(CPPPATH = [
'../../../extlibs/cjson/',
# '../../../extlibs/tinydtls/',
'../../../extlibs/tinydtls/',
'../logger/include',
'../ocrandom/include',
'../stack/include',
......@@ -82,22 +82,44 @@ if not env.get('RELEASE'):
# Source files and Targets
######################################################################
OCSRM_SRC = 'src/'
libocsrm_src = [
OCSRM_SRC + 'secureresourcemanager.c',
OCSRM_SRC + 'resourcemanager.c',
OCSRM_SRC + 'aclresource.c',
OCSRM_SRC + 'amaclresource.c',
OCSRM_SRC + 'pstatresource.c',
OCSRM_SRC + 'doxmresource.c',
OCSRM_SRC + 'credresource.c',
OCSRM_SRC + 'svcresource.c',
OCSRM_SRC + 'policyengine.c',
OCSRM_SRC + 'psinterface.c',
OCSRM_SRC + 'srmresourcestrings.c',
OCSRM_SRC + 'srmutility.c',
OCSRM_SRC + 'iotvticalendar.c',
OCSRM_SRC + 'base64.c'
]
if env.get('SECURED') == '1':
libocsrm_src = [
OCSRM_SRC + 'secureresourcemanager.c',
OCSRM_SRC + 'resourcemanager.c',
OCSRM_SRC + 'aclresource.c',
OCSRM_SRC + 'amaclresource.c',
OCSRM_SRC + 'pstatresource.c',
OCSRM_SRC + 'doxmresource.c',
OCSRM_SRC + 'credresource.c',
OCSRM_SRC + 'svcresource.c',
OCSRM_SRC + 'policyengine.c',
OCSRM_SRC + 'psinterface.c',
OCSRM_SRC + 'srmresourcestrings.c',
OCSRM_SRC + 'srmutility.c',
OCSRM_SRC + 'iotvticalendar.c',
OCSRM_SRC + 'oxmpincommon.c',
OCSRM_SRC + 'base64.c',
#pbkdf2.c is required to PIN based OxM only.
#But we did not use a separate build options to prevent the build command becomes complicated.
OCSRM_SRC + 'pbkdf2.c'
]
else:
libocsrm_src = [
OCSRM_SRC + 'secureresourcemanager.c',
OCSRM_SRC + 'resourcemanager.c',
OCSRM_SRC + 'aclresource.c',
OCSRM_SRC + 'amaclresource.c',
OCSRM_SRC + 'pstatresource.c',
OCSRM_SRC + 'doxmresource.c',
OCSRM_SRC + 'credresource.c',
OCSRM_SRC + 'svcresource.c',
OCSRM_SRC + 'policyengine.c',
OCSRM_SRC + 'psinterface.c',
OCSRM_SRC + 'srmresourcestrings.c',
OCSRM_SRC + 'srmutility.c',
OCSRM_SRC + 'iotvticalendar.c',
OCSRM_SRC + 'base64.c'
]
libocsrm = libocsrm_env.StaticLibrary('libocsrm', libocsrm_src)
......
......@@ -100,6 +100,15 @@ OicSecCred_t * GenerateCredential(const OicUuid_t* subject, OicSecCredType_t cre
*/
OCStackResult AddCredential(OicSecCred_t * cred);
/**
* Function to remove the credential from SVR DB.
*
* @param credId Credential ID to be deleted.
*
* @return OC_STACK_OK for success and errorcode otherwise.
*/
OCStackResult RemoveCredential(const OicUuid_t* credId);
#if defined(__WITH_DTLS__)
/**
* This internal callback is used by lower stack (i.e. CA layer) to
......@@ -114,6 +123,24 @@ OCStackResult AddCredential(OicSecCred_t * cred);
* @retval none
*/
void GetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo);
/**
* 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);
#endif /* __WITH_DTLS__ */
/**
......
/* *****************************************************************
*
* Copyright 2015 Samsung Electronics All Rights Reserved.
*
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* *****************************************************************/
#ifndef _PBKDF2_H
#define _PBKDF2_H
#include <stdio.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
/**
* The number of iterations desired to derived key.
* (Recommened by RFC 2898)
*/
#define PBKDF_ITERATIONS 1000
/**
* Function to derive cryptographic key from the password. (RFC 2898)
* In this implementation, HMAC with SHA2 is considered as a pseudorandom function
*
* @param[in] passwd is the master password from which a derived key is generated.
* @param[in] pLen is the byte size of the passwd.
* @param[in] salt is a cryptographic salt.
* @param[in] saltlen is the byte size of the salt.
* @param[in] iteration is the number of iterations desired.
* @param[in] keyLen is the desired byte size of the derived key. (should be the same as
* derivedKey size)
* @param[out] derivedKey is the generated derived key
*
* @return 0 on success
*/
int DeriveCryptoKeyFromPassword(const unsigned char* passwd, size_t pLen,
const uint8_t* salt, const size_t saltLen,
const size_t iterations,
const size_t keyLen, uint8_t* derivedKey);
#ifdef __cplusplus
}
#endif
#endif // _PBKDF2_H
/* *****************************************************************
*
* Copyright 2015 Samsung Electronics All Rights Reserved.
*
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* *****************************************************************/
#ifndef PIN_CALLBACK_DEF_H_
#define PIN_CALLBACK_DEF_H_
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#define OXM_RANDOM_PIN_SIZE 8
/**
* Function pointer to print pin code
*/
typedef void (*GeneratePinCallback)(char* pinData, size_t pinSize);
/**
* Function pointer to input pin code
*/
typedef void (*InputPinCallback)(char* pinBuf, size_t bufSize);
/**
* Function to setting generate PIN callback from user
*
* @param[in] pinCB implementation of generate PIN callback
*/
void SetGeneratePinCB(GeneratePinCallback pinCB);
/**
* Function to setting input PIN callback from user
*
* @param[in] pinCB implementation of input PIN callback
*/
void SetInputPinCB(InputPinCallback pinCB);
/**
* Function to generate random PIN.
* This function will send generated PIN to user via callback.
*
* @param[in,out] pinBuffer Buffer to store the generated PIN data.
* @param[in] bufferSize Size of buffer
* @return OC_STACK_SUCCESS in case of success and other value otherwise.
*/
OCStackResult GeneratePin(char* pinBuffer, size_t bufferSize);
/**
* Function to input PIN callback via input callback
*
* @param[in,out] pinBuffer Buffer to store the inputed PIN data.
* @param[in] bufferSize Size of buffer
* @return OC_STACK_SUCCESS in case of success and other value otherwise.
*/
OCStackResult InputPin(char* pinBuffer, size_t bufferSize);
#ifdef __cplusplus
}
#endif
#endif //PIN_CALLBACK_DEF_H_
......@@ -64,8 +64,8 @@ struct OicParseQueryIter
* @note Invoking function must define "exit:" label for goto functionality to work correctly.
*
*/
#define VERIFY_SUCCESS(tag, op, logLevel) { if (!(op)) \
{OC_LOG((logLevel), tag, PCF(#op " failed!!")); goto exit;} }
#define VERIFY_SUCCESS(tag, op, logLevel) do{ if (!(op)) \
{OC_LOG((logLevel), tag, PCF(#op " failed!!")); goto exit; } }while(0)
/**
* @def VERIFY_NON_NULL
......@@ -74,8 +74,8 @@ struct OicParseQueryIter
* @note Invoking function must define "exit:" label for goto functionality to work correctly.
*
*/
#define VERIFY_NON_NULL(tag, arg, logLevel) { if (NULL == (arg)) \
{ OC_LOG((logLevel), tag, PCF(#arg " is NULL")); goto exit; } }
#define VERIFY_NON_NULL(tag, arg, logLevel) do{ if (NULL == (arg)) \
{ OC_LOG((logLevel), tag, PCF(#arg " is NULL")); goto exit; } }while(0)
/**
* This method initializes the OicParseQueryIter_t struct
......
......@@ -42,6 +42,7 @@ provisioning_env.AppendUnique(CPPPATH = [
'../../connectivity/inc',
'../../connectivity/external/inc',
'../../connectivity/common/inc',
'../../connectivity/lib/libcoap-4.1.1',
'../../connectivity/api',
'../include',
'../include/internal'
......@@ -80,11 +81,12 @@ if target_os in ['darwin', 'ios']:
######################################################################
provisioning_src = [
'src/pmutility.c',
'src/credentialgenerator.c',
'src/ownershiptransfermanager.c',
'src/secureresourceprovider.c',
'src/ocprovisioningmanager.c',
'src/oxmjustworks.c' ]
'src/credentialgenerator.c',
'src/ownershiptransfermanager.c',
'src/secureresourceprovider.c',
'src/ocprovisioningmanager.c',
'src/oxmjustworks.c',
'src/oxmrandompin.c' ]
provisioningserver = provisioning_env.StaticLibrary('ocpmapi', provisioning_src)
provisioning_env.InstallTarget(provisioningserver, 'libocpmapi')
......
......@@ -39,7 +39,7 @@ extern "C" {
typedef struct OTMContext{
void* userCtx; /**< Context for user**/
OCProvisionDev_t* selectedDeviceInfo; /**< Selected device info for OT */
uint16_t tempCredId;
OicUuid_t tempCredId;
}OTMContext_t;
/**
......
/* *****************************************************************
*
* Copyright 2015 Samsung Electronics All Rights Reserved.
*
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* *****************************************************************/
#ifndef OXM_RANDOM_PIN_H_
#define OXM_RANDOM_PIN_H_
#include "ocstack.h"
#include "securevirtualresourcetypes.h"
#include "ownershiptransfermanager.h"
#include "pmtypes.h"
#include "pinoxmcommon.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#define OXM_PBKDF2_ITERATIONS 1000
/**
* Callback implementation to input the PIN code from user.
*
* @otmCtx Context of OTM, It includes current device infomation.
* @return OC_STACK_SUCCESS in case of success and other value otherwise.
*/
OCStackResult InputPinCodeCallback(OTMContext_t* otmCtx);
/**
* Callback implemenration to establish a secure channel with PSK cipher suite
*
* @param[in] selectedDeviceInfo Selected device infomation
* @return OC_STACK_SUCCESS in case of success and other value otherwise.
*/
OCStackResult CreateSecureSessionRandomPinCallbak(OTMContext_t* otmCtx);
/**
* Generate payload for select OxM request.
*
* @param[in] selectedDeviceInfo Selected device infomation
* @return DOXM JSON payload including the selected OxM.
* NOTE : Returned memory should be deallocated by caller.
*/
char* CreatePinBasedSelectOxmPayload(OTMContext_t* otmCtx);
/**
* Generate payload for owner transfer request.
*
* @param[in] selectedDeviceInfo Selected device infomation
* @return DOXM JSON payload including the owner information.
* NOTE : Returned memory should be deallocated by caller.
*/
char* CreatePinBasedOwnerTransferPayload(OTMContext_t* otmCtx);
#ifdef __cplusplus
}
#endif
#endif //OXM_RANDOM_PIN_H_
\ No newline at end of file
......@@ -37,21 +37,6 @@ extern "C"
#define COAPS_QUERY "coaps://%s:%d%s"
#define COAP_QUERY "coap://%s:%d%s"
/**
* Macro to verify argument is not equal to NULL.
* eg: VERIFY_NON_NULL(TAG, ptrData, ERROR,OC_STACK_ERROR);
*/
#define VERIFY_NON_NULL(tag, arg, logLevel, retValue) { if (NULL == (arg)) \
{ OC_LOG((logLevel), tag, (#arg " is NULL")); return retValue; } }
/**
* Macro to verify success of operation.
* eg: VERIFY_SUCCESS(TAG, OC_STACK_OK == foo(), ERROR, OC_STACK_ERROR);
*/
#define VERIFY_SUCCESS(tag, op, logLevel, retValue) { if (!(op)) \
{OC_LOG((logLevel), tag, (#op " failed!!")); return retValue;} }
/**
* Discover owned/unowned devices in the same IP subnet. .
*
......
......@@ -65,8 +65,9 @@ provisioning_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
provisioningclient = provisioning_env.Program('provisioningclient', 'provisioningclient.c')
sampleserver_justworks = provisioning_env.Program('sampleserver_justworks', 'sampleserver_justworks.cpp')
sampleserver_randompin = provisioning_env.Program('sampleserver_randompin', 'sampleserver_randompin.cpp')
Alias("samples", [provisioningclient, sampleserver_justworks])
Alias("samples", [provisioningclient, sampleserver_justworks, sampleserver_randompin])
provisioning_env.AppendTarget('samples')
......@@ -78,4 +79,5 @@ provisioning_env.Alias("install", provisioning_env.Install( sec_provisioning_bui
sec_provisioning_src_dir + 'oic_svr_db_client.json'))
provisioning_env.Alias("install", provisioning_env.Install( sec_provisioning_build_dir,
sec_provisioning_src_dir + 'oic_svr_db_server_justworks.json'))
provisioning_env.Alias("install", provisioning_env.Install( sec_provisioning_build_dir,
sec_provisioning_src_dir + 'oic_svr_db_server_randompin.json'))
{
"acl": [
{
"sub": "Kg==",
"rsrc": [
"/oic/res",
"/oic/res/d",
"/oic/res/types/d",
"/oic/presence"
],
"perms": 2,
"ownrs" : [
"cmFuZG9tUGluRGV2VVVJRA=="
]
},
{
"sub": "Kg==",
"rsrc": [
"/oic/sec/doxm",
"/oic/sec/pstat",
"/oic/sec/acl",
"/oic/sec/cred"
],
"perms": 6,
"ownrs" : [
"cmFuZG9tUGluRGV2VVVJRA=="
]
}
],
"pstat": {
"isop": false,
"deviceid": "cmFuZG9tUGluRGV2VVVJRA==",
"commithash": 0,
"cm": 0,
"tm": 0,
"om": 3,
"sm": [3]
},
"doxm": {
"oxm": [0,2],
"oxmsel": 0,
"owned": false,
"deviceid": "cmFuZG9tUGluRGV2VVVJRA=="
}
}
......@@ -28,8 +28,8 @@
#include "ocprovisioningmanager.h"
#include "secureresourceprovider.h"
#include "oxmjustworks.h"
// TODO: PIN based OxM implementation is required.
//#include "oxmrandompin.h"
#include "oxmrandompin.h"
#include "pinoxmcommon.h"
#include "oic_string.h"
#define MAX_URI_LENGTH (64)
......@@ -67,7 +67,7 @@ static void deleteACL(OicSecAcl_t *acl)
if (acl)
{
/* Clean Resources */
for (int i = 0; i < (acl)->resourcesLen; i++)
for (size_t i = 0; i < (acl)->resourcesLen; i++)
{
OICFree((acl)->resources[i]);
}
......@@ -185,9 +185,9 @@ static int InputACL(OicSecAcl_t *acl)
OC_LOG(ERROR, TAG, "Error while memory allocation");
return -1;
}
for (int i = 0; i < acl->resourcesLen; i++)
for (size_t i = 0; i < acl->resourcesLen; i++)
{
printf("[%d]Resource : ", i + 1);
printf("[%zu]Resource : ", i + 1);
unused = scanf("%64s", temp_rsc);
acl->resources[i] = OICStrdup(temp_rsc);
......@@ -219,9 +219,9 @@ static int InputACL(OicSecAcl_t *acl)
OC_LOG(ERROR, TAG, "Error while memory allocation");
return -1;
}
for (int i = 0; i < acl->ownersLen; i++)
for (size_t i = 0; i < acl->ownersLen; i++)
{
printf("[%d]Rowner : ", i + 1);
printf("[%zu]Rowner : ", i + 1);
unused = scanf("%19s", temp_id);
j = 0;
for (int k = 0; temp_id[k] != '\0'; k++)
......@@ -237,17 +237,45 @@ static int InputACL(OicSecAcl_t *acl)
//FILE *client_fopen(const char *path, const char *mode)
FILE *client_fopen(const char *path, const char *mode)
FILE *client_fopen(const char *UNUSED_PARAM, const char *mode)
{
return fopen(CRED_FILE, mode);
}
void PrintfResult(const char* procName, void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
{
printf("-----------------------------------------------------------\n");
if(!hasError)
{
printf("%s was successfully done.\n", procName);
}
else
{
for(int i = 0; i < nOfRes; i++)
{
printf("UUID : ");
for(int j = 0; j < UUID_LENGTH; i++)
{
printf("%c", arr[i].deviceId.id[j]);
}
printf("\t");
printf("Result=%d\n", arr[i].res);
}
}
if(ctx)
{
printf("Context is %s\n", (char*)ctx);
}
printf("-----------------------------------------------------------\n");
}
void ProvisionCredCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
{
if(!hasError)
{
OC_LOG(INFO, TAG, "Provision Credential IS DONE~~!!");
gOwnershipState = 1;
PrintfResult("Provision Credential", ctx, nOfRes, arr, hasError);
}
}
......@@ -255,8 +283,8 @@ void ProvisionAclCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasErr
{
if(!hasError)
{
OC_LOG(INFO, TAG, "Provision Acl IS DONE~~!!");
gOwnershipState = 1;
PrintfResult("Provision ACL", ctx, nOfRes, arr, hasError);
}
}
......@@ -264,9 +292,8 @@ void ProvisionPairwiseCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool h
{
if(!hasError)
{
OC_LOG_V(INFO, TAG, "Context is %s", (char*)ctx);
OC_LOG(INFO, TAG, "Provision Pairwise IS DONE~~!!");
gOwnershipState = 1;
PrintfResult("Provision Pairwise Credential", ctx, nOfRes, arr, hasError);
}
}
......@@ -274,9 +301,8 @@ void OwnershipTransferCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool h
{
if(!hasError)
{
OC_LOG_V(INFO, TAG, "Context is %s", (char*)ctx);
OC_LOG(INFO, TAG, "OWNERSHIP TRANSFER IS DONE~~!!");
gOwnershipState = 1;
PrintfResult("Ownership transfer", ctx, nOfRes, arr, hasError);
}
}
......@@ -284,7 +310,8 @@ void InputPinCB(char* pinBuf, size_t bufSize)
{
if(pinBuf)
{
scanf("%s", pinBuf);
printf("INPUT PIN : ");
int unused = scanf("%s", pinBuf);
pinBuf[bufSize - 1] = '\0';
}
}
......@@ -305,7 +332,11 @@ int main(int argc, char **argv)
}
// Initialize Persistent Storage for SVR database
OCPersistentStorage ps = {};
OCPersistentStorage ps = { .open = NULL,
.read = NULL,
.write = NULL,
.close = NULL,
.unlink = NULL };
ps.open = client_fopen;
ps.read = fread;
ps.write = fwrite;
......@@ -338,20 +369,27 @@ int main(int argc, char **argv)
}
//Register callback function to each OxM
OTMCallbackData_t justWorksCBData = {};
OTMCallbackData_t justWorksCBData = {.loadSecretCB=NULL,