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: leechul <chuls.lee@samsung.com>
Signed-off-by: Randeep Singh <randeep.s@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/1989
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Sachin Agrawal <sachin.agrawal@intel.com>
######################################################################
libocsrm_env.PrependUnique(CPPPATH = [
'../../../extlibs/cjson/',
-# '../../../extlibs/tinydtls/',
+ '../../../extlibs/tinydtls/',
'../logger/include',
'../ocrandom/include',
'../stack/include',
# 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)
*/
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
* @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__ */
/**
--- /dev/null
+/* *****************************************************************
+ *
+ * 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
+
--- /dev/null
+/* *****************************************************************
+ *
+ * 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_
* @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
* @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
'../../connectivity/inc',
'../../connectivity/external/inc',
'../../connectivity/common/inc',
+ '../../connectivity/lib/libcoap-4.1.1',
'../../connectivity/api',
'../include',
'../include/internal'
######################################################################
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')
typedef struct OTMContext{\r
void* userCtx; /**< Context for user**/\r
OCProvisionDev_t* selectedDeviceInfo; /**< Selected device info for OT */\r
- uint16_t tempCredId;\r
+ OicUuid_t tempCredId;\r
}OTMContext_t;\r
\r
/**\r
--- /dev/null
+/* *****************************************************************
+ *
+ * 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
#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. .
*
* @param[in] waittime Timeout in seconds.
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')
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'))
--- /dev/null
+{
+ "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=="
+ }
+}
#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)
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]);
}
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);
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++)
//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);
}
}
{
if(!hasError)
{
- OC_LOG(INFO, TAG, "Provision Acl IS DONE~~!!");
gOwnershipState = 1;
+ PrintfResult("Provision ACL", ctx, nOfRes, arr, hasError);
}
}
{
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);
}
}
{
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);
}
}
{
if(pinBuf)
{
- scanf("%s", pinBuf);
+ printf("INPUT PIN : ");
+ int unused = scanf("%s", pinBuf);
pinBuf[bufSize - 1] = '\0';
}
}
}
// 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;
}
//Register callback function to each OxM
- OTMCallbackData_t justWorksCBData = {};
+ OTMCallbackData_t justWorksCBData = {.loadSecretCB=NULL,
+ .createSecureSessionCB=NULL,
+ .createSelectOxmPayloadCB=NULL,
+ .createOwnerTransferPayloadCB=NULL};
justWorksCBData.loadSecretCB = LoadSecretJustWorksCallback;
justWorksCBData.createSecureSessionCB = CreateSecureSessionJustWorksCallback;
justWorksCBData.createSelectOxmPayloadCB = CreateJustWorksSelectOxmPayload;
justWorksCBData.createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
OTMSetOwnershipTransferCallbackData(OIC_JUST_WORKS, &justWorksCBData);
- // TODO: PIN based OxM implementation is required.
- //OTMCallbackData_t pinBasedCBData = {};
- //pinBasedCBData.loadSecretCB = InputPinCodeCallback;
- //pinBasedCBData.createSecureSessionCB = CreateSecureSessionRandomPinCallbak;
- //pinBasedCBData.createSelectOxmPayloadCB = CreatePinBasedSelectOxmPayload;
- //pinBasedCBData.createOwnerTransferPayloadCB = CreatePinBasedOwnerTransferPayload;
- //OTMSetOwnershipTransferCallbackData(OIC_RANDOM_DEVICE_PIN, &pinBasedCBData);
+ OTMCallbackData_t pinBasedCBData = {.loadSecretCB=NULL,
+ .createSecureSessionCB=NULL,
+ .createSelectOxmPayloadCB=NULL,
+ .createOwnerTransferPayloadCB=NULL};
+ pinBasedCBData.loadSecretCB = InputPinCodeCallback;
+ pinBasedCBData.createSecureSessionCB = CreateSecureSessionRandomPinCallbak;
+ pinBasedCBData.createSelectOxmPayloadCB = CreatePinBasedSelectOxmPayload;
+ pinBasedCBData.createOwnerTransferPayloadCB = CreatePinBasedOwnerTransferPayload;
+ OTMSetOwnershipTransferCallbackData(OIC_RANDOM_DEVICE_PIN, &pinBasedCBData);
+
+ SetInputPinCB(&InputPinCB);
char* myContext = "OTM Context";
//Perform ownership transfer
response.ehResult = ehResult;
response.payload = (OCPayload*)(payload);
response.numSendVendorSpecificHeaderOptions = 0;
- memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
+ memset(response.sendVendorSpecificHeaderOptions, 0,
+ sizeof(response.sendVendorSpecificHeaderOptions));
memset(response.resourceUri, 0, sizeof(response.resourceUri));
// Indicate that response is NOT in a persistent buffer
response.persistentBufferFlag = 0;
--- /dev/null
+/******************************************************************
+*
+* 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.
+*
+******************************************************************/
+///////////////////////////////////////////////////////////////////////
+//NOTE : This sample server is generated based on ocserverbasicops.cpp
+///////////////////////////////////////////////////////////////////////
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <pthread.h>
+#include "ocstack.h"
+#include "logger.h"
+#include "ocpayload.h"
+#include "pinoxmcommon.h"
+
+#define TAG "SAMPLE_RANDOMPIN"
+
+int gQuitFlag = 0;
+
+/* Structure to represent a LED resource */
+typedef struct LEDRESOURCE{
+ OCResourceHandle handle;
+ bool state;
+ int power;
+} LEDResource;
+
+static LEDResource LED;
+// This variable determines instance number of the LED resource.
+// Used by POST method to create a new instance of LED resource.
+static int gCurrLedInstance = 0;
+#define SAMPLE_MAX_NUM_POST_INSTANCE 2
+static LEDResource gLedInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
+
+char *gResourceUri= (char *)"/a/led";
+
+//Secure Virtual Resource database for Iotivity Server
+//It contains Server's Identity and the PSK credentials
+//of other devices which the server trusts
+static char CRED_FILE[] = "oic_svr_db_server_randompin.json";
+
+/* Function that creates a new LED resource by calling the
+ * OCCreateResource() method.
+ */
+int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower);
+
+/* This method converts the payload to JSON format */
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest);
+
+/* Following methods process the PUT, GET, POST
+ * requests
+ */
+OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
+ OCRepPayload **payload);
+OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
+ OCRepPayload **payload);
+OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
+ OCEntityHandlerResponse *response,
+ OCRepPayload **payload);
+
+/* Entity Handler callback functions */
+OCEntityHandlerResult
+OCEntityHandlerCb (OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest *entityHandlerRequest,
+ void* callbackParam);
+
+const char *getResult(OCStackResult result) {
+ switch (result) {
+ case OC_STACK_OK:
+ return "OC_STACK_OK";
+ case OC_STACK_RESOURCE_CREATED:
+ return "OC_STACK_RESOURCE_CREATED";
+ case OC_STACK_RESOURCE_DELETED:
+ return "OC_STACK_RESOURCE_DELETED";
+ case OC_STACK_INVALID_URI:
+ return "OC_STACK_INVALID_URI";
+ case OC_STACK_INVALID_QUERY:
+ return "OC_STACK_INVALID_QUERY";
+ case OC_STACK_INVALID_IP:
+ return "OC_STACK_INVALID_IP";
+ case OC_STACK_INVALID_PORT:
+ return "OC_STACK_INVALID_PORT";
+ case OC_STACK_INVALID_CALLBACK:
+ return "OC_STACK_INVALID_CALLBACK";
+ case OC_STACK_INVALID_METHOD:
+ return "OC_STACK_INVALID_METHOD";
+ case OC_STACK_NO_MEMORY:
+ return "OC_STACK_NO_MEMORY";
+ case OC_STACK_COMM_ERROR:
+ return "OC_STACK_COMM_ERROR";
+ case OC_STACK_INVALID_PARAM:
+ return "OC_STACK_INVALID_PARAM";
+ case OC_STACK_NOTIMPL:
+ return "OC_STACK_NOTIMPL";
+ case OC_STACK_NO_RESOURCE:
+ return "OC_STACK_NO_RESOURCE";
+ case OC_STACK_RESOURCE_ERROR:
+ return "OC_STACK_RESOURCE_ERROR";
+ case OC_STACK_SLOW_RESOURCE:
+ return "OC_STACK_SLOW_RESOURCE";
+ case OC_STACK_NO_OBSERVERS:
+ return "OC_STACK_NO_OBSERVERS";
+ #ifdef WITH_PRESENCE
+ case OC_STACK_PRESENCE_STOPPED:
+ return "OC_STACK_PRESENCE_STOPPED";
+ #endif
+ case OC_STACK_ERROR:
+ return "OC_STACK_ERROR";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
+{
+ OCRepPayload* payload = OCRepPayloadCreate();
+ if(!payload)
+ {
+ OC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
+ return NULL;
+ }
+
+ OCRepPayloadSetUri(payload, uri);
+ OCRepPayloadSetPropBool(payload, "state", state);
+ OCRepPayloadSetPropInt(payload, "power", power);
+
+ return payload;
+}
+
+//This function takes the request as an input and returns the response
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest)
+{
+ if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
+ {
+ OC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
+ return NULL;
+ }
+
+ OCRepPayload* input = (OCRepPayload*)(ehRequest->payload);
+
+ LEDResource *currLEDResource = &LED;
+
+ if (ehRequest->resource == gLedInstance[0].handle)
+ {
+ currLEDResource = &gLedInstance[0];
+ gResourceUri = (char *) "/a/led/0";
+ }
+ else if (ehRequest->resource == gLedInstance[1].handle)
+ {
+ currLEDResource = &gLedInstance[1];
+ gResourceUri = (char *) "/a/led/1";
+ }
+
+ if(OC_REST_PUT == ehRequest->method)
+ {
+ // Get pointer to query
+ int64_t pow;
+ if(OCRepPayloadGetPropInt(input, "power", &pow))
+ {
+ currLEDResource->power =pow;
+ }
+
+ bool state;
+ if(OCRepPayloadGetPropBool(input, "state", &state))
+ {
+ currLEDResource->state = state;
+ }
+ }
+
+ return getPayload(gResourceUri, currLEDResource->power, currLEDResource->state);
+}
+
+OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
+ OCRepPayload **payload)
+{
+ OCEntityHandlerResult ehResult;
+
+ OCRepPayload *getResp = constructResponse(ehRequest);
+
+ if(getResp)
+ {
+ *payload = getResp;
+ ehResult = OC_EH_OK;
+ }
+ else
+ {
+ ehResult = OC_EH_ERROR;
+ }
+
+ return ehResult;
+}
+
+OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
+ OCRepPayload **payload)
+{
+ OCEntityHandlerResult ehResult;
+
+ OCRepPayload *putResp = constructResponse(ehRequest);
+
+ if(putResp)
+ {
+ *payload = putResp;
+ ehResult = OC_EH_OK;
+ }
+ else
+ {
+ ehResult = OC_EH_ERROR;
+ }
+
+ return ehResult;
+}
+
+OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
+ OCEntityHandlerResponse *response, OCRepPayload **payload)
+{
+ OCRepPayload *respPLPost_led = NULL;
+ OCEntityHandlerResult ehResult = OC_EH_OK;
+
+ /*
+ * The entity handler determines how to process a POST request.
+ * Per the REST paradigm, POST can also be used to update representation of existing
+ * resource or create a new resource.
+ * In the sample below, if the POST is for /a/led then a new instance of the LED
+ * resource is created with default representation (if representation is included in
+ * POST payload it can be used as initial values) as long as the instance is
+ * lesser than max new instance count. Once max instance count is reached, POST on
+ * /a/led updated the representation of /a/led (just like PUT)
+ */
+
+ if (ehRequest->resource == LED.handle)
+ {
+ if (gCurrLedInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
+ {
+ // Create new LED instance
+ char newLedUri[15] = "/a/led/";
+ int newLedUriLength = strlen(newLedUri);
+ snprintf (newLedUri + newLedUriLength, sizeof(newLedUri)-newLedUriLength, "%d", gCurrLedInstance);
+
+ respPLPost_led = OCRepPayloadCreate();
+ OCRepPayloadSetUri(respPLPost_led, gResourceUri);
+ OCRepPayloadSetPropString(respPLPost_led, "createduri", newLedUri);
+
+ if (0 == createLEDResource (newLedUri, &gLedInstance[gCurrLedInstance], false, 0))
+ {
+ OC_LOG (INFO, TAG, "Created new LED instance");
+ gLedInstance[gCurrLedInstance].state = 0;
+ gLedInstance[gCurrLedInstance].power = 0;
+ gCurrLedInstance++;
+ strncpy ((char *)response->resourceUri, newLedUri, MAX_URI_LENGTH);
+ ehResult = OC_EH_RESOURCE_CREATED;
+ }
+ }
+ else
+ {
+ respPLPost_led = constructResponse(ehRequest);
+ }
+ }
+ else
+ {
+ for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
+ {
+ if (ehRequest->resource == gLedInstance[i].handle)
+ {
+ if (i == 0)
+ {
+ respPLPost_led = constructResponse(ehRequest);
+ break;
+ }
+ else if (i == 1)
+ {
+ respPLPost_led = constructResponse(ehRequest);
+ }
+ }
+ }
+ }
+
+ if (respPLPost_led != NULL)
+ {
+ *payload = respPLPost_led;
+ ehResult = OC_EH_OK;
+ }
+ else
+ {
+ OC_LOG_V (INFO, TAG, "Payload was NULL");
+ ehResult = OC_EH_ERROR;
+ }
+
+ return ehResult;
+}
+
+OCEntityHandlerResult
+OCEntityHandlerCb (OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest *entityHandlerRequest,
+ void* callbackParam)
+{
+ OC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
+
+ OCEntityHandlerResult ehResult = OC_EH_ERROR;
+ OCEntityHandlerResponse response = {};
+
+ // Validate pointer
+ if (!entityHandlerRequest)
+ {
+ OC_LOG (ERROR, TAG, "Invalid request pointer");
+ return OC_EH_ERROR;
+ }
+
+ OCRepPayload* payload = NULL;
+
+ if (flag & OC_REQUEST_FLAG)
+ {
+ OC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
+ if (entityHandlerRequest)
+ {
+ if (OC_REST_GET == entityHandlerRequest->method)
+ {
+ OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
+ ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
+ }
+ else if (OC_REST_PUT == entityHandlerRequest->method)
+ {
+ OC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
+ ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
+ }
+ else if (OC_REST_POST == entityHandlerRequest->method)
+ {
+ OC_LOG (INFO, TAG, "Received OC_REST_POST from client");
+ ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
+ }
+ else
+ {
+ OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
+ entityHandlerRequest->method);
+ ehResult = OC_EH_ERROR;
+ }
+
+ if (ehResult == OC_EH_OK && ehResult != OC_EH_FORBIDDEN)
+ {
+ // Format the response. Note this requires some info about the request
+ response.requestHandle = entityHandlerRequest->requestHandle;
+ response.resourceHandle = entityHandlerRequest->resource;
+ response.ehResult = ehResult;
+ response.payload = (OCPayload*)(payload);
+ response.numSendVendorSpecificHeaderOptions = 0;
+ memset(response.sendVendorSpecificHeaderOptions, 0,
+ sizeof(response.sendVendorSpecificHeaderOptions));
+ memset(response.resourceUri, 0, sizeof(response.resourceUri));
+ // Indicate that response is NOT in a persistent buffer
+ response.persistentBufferFlag = 0;
+
+ // Send the response
+ if (OCDoResponse(&response) != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "Error sending response");
+ ehResult = OC_EH_ERROR;
+ }
+ }
+ }
+ }
+
+ OCPayloadDestroy(response.payload);
+ return ehResult;
+}
+
+/* SIGINT handler: set gQuitFlag to 1 for graceful termination */
+void handleSigInt(int signum)
+{
+ if (signum == SIGINT)
+ {
+ gQuitFlag = 1;
+ }
+}
+
+FILE* server_fopen(const char *path, const char *mode)
+{
+ (void)path;
+ return fopen(CRED_FILE, mode);
+}
+
+void GeneratePinCB(char* pin, size_t pinSize)
+{
+ if(NULL == pin || pinSize <= 0)
+ {
+ OC_LOG(INFO, TAG, "Invalid PIN");
+ return;
+ }
+
+ OC_LOG(INFO, TAG, "============================");
+ OC_LOG_V(INFO, TAG, " PIN CODE : %s", pin);
+ OC_LOG(INFO, TAG, "============================");
+}
+
+int main(int argc, char* argv[])
+{
+ struct timespec timeout;
+
+ OC_LOG(DEBUG, TAG, "OCServer is starting...");
+
+ // Initialize Persistent Storage for SVR database
+ OCPersistentStorage ps = {};
+ ps.open = server_fopen;
+ ps.read = fread;
+ ps.write = fwrite;
+ ps.close = fclose;
+ ps.unlink = unlink;
+ OCRegisterPersistentStorageHandler(&ps);
+
+ if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "OCStack init error");
+ return 0;
+ }
+
+ /**
+ * If server supported random pin based ownership transfer,
+ * callback of print PIN should be registered before runing server.
+ */
+ SetGeneratePinCB(&GeneratePinCB);
+
+ /*
+ * Declare and create the example resource: LED
+ */
+ createLEDResource(gResourceUri, &LED, false, 0);
+
+ timeout.tv_sec = 0;
+ timeout.tv_nsec = 100000000L;
+
+ // Break from loop with Ctrl-C
+ OC_LOG(INFO, TAG, "Entering ocserver main loop...");
+ signal(SIGINT, handleSigInt);
+ while (!gQuitFlag)
+ {
+ if (OCProcess() != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "OCStack process error");
+ return 0;
+ }
+ nanosleep(&timeout, NULL);
+ }
+
+ OC_LOG(INFO, TAG, "Exiting ocserver main loop...");
+
+ if (OCStop() != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "OCStack process error");
+ }
+
+ return 0;
+}
+
+int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower)
+{
+ if (!uri)
+ {
+ OC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
+ return -1;
+ }
+
+ ledResource->state = resourceState;
+ ledResource->power= resourcePower;
+ OCStackResult res = OCCreateResource(&(ledResource->handle),
+ "core.led",
+ OC_RSRVD_INTERFACE_DEFAULT,
+ uri,
+ OCEntityHandlerCb,
+ NULL,
+ OC_DISCOVERABLE|OC_OBSERVABLE | OC_SECURE);
+ OC_LOG_V(INFO, TAG, "Created LED resource with result: %s", getResult(res));
+
+ return 0;
+}
OCProvisionResultCB resultCallback)
{
- VERIFY_NON_NULL(TAG, pDev1, ERROR, OC_STACK_INVALID_PARAM);
- VERIFY_NON_NULL(TAG, pDev2, ERROR, OC_STACK_INVALID_PARAM);
- VERIFY_NON_NULL(TAG, resultCallback, ERROR, OC_STACK_INVALID_CALLBACK);
-
+ if(!pDev1 || !pDev2 || !resultCallback)
+ {
+ OC_LOG(ERROR, TAG, "OCProvisionPairwiseDevices : Invalid parameters");
+ return OC_STACK_INVALID_PARAM;
+ }
if (!(keySize == OWNER_PSK_LENGTH_128 || keySize == OWNER_PSK_LENGTH_256))
{
- OC_LOG(INFO, TAG, "Invalid key size");
+ OC_LOG(INFO, TAG, "OCProvisionPairwiseDevices : Invalid key size");
return OC_STACK_INVALID_PARAM;
}
int noOfResults = 2; // Initial Value
#include "oxmjustworks.h"
#include "pmtypes.h"
#include "pmutility.h"
+#include "srmutility.h"
// TODO: Not yet supported.
//#include "oxmrandompin.h"
OCProvisionResultCB g_resultCallback;
OCProvisionResult_t* g_resultArray = NULL;
-uint32_t g_resultArraySize = 0;
-bool hasError = false;
+size_t g_resultArraySize = 0;
+bool g_hasError = false;
/**
* Possible states of ownership transfer manager module.
* Number of supported provisioning methods
* current version supports only one.
*/
-static int gNumOfProvisioningMethodsPT = 1;
+static size_t gNumOfProvisioningMethodsPT = 1;
/**
* Function to getting string of ownership transfer method
/**
* Function to select appropriate provisioning method.
*
- * @param[in] supportedMethodsList List of supported methods
+ * @param[in] supportedMethods Array of supported methods
+ * @param[in] numberOfMethods number of supported methods
* @param[out] selectedMethod Selected methods
* @return SP_SUCCESS on success
*/
-static OCStackResult SelectProvisioningMethod(const OicSecOxm_t *supportedMethods, size_t numberOfMethods,
+static OCStackResult SelectProvisioningMethod(const OicSecOxm_t *supportedMethods,
+ size_t numberOfMethods,
OicSecOxm_t *selectedMethod)
{
- int i;
OC_LOG(DEBUG, TAG, "IN SelectProvisioningMethod");
if(numberOfMethods == 0 || !supportedMethods)
}
*selectedMethod = supportedMethods[0];
- for(i = 0; i < numberOfMethods; i++)
+ for(size_t i = 0; i < numberOfMethods; i++)
{
if(*selectedMethod < supportedMethods[i])
{
/**
* Function to select operation mode.This function will return most secure common operation mode.
*
+ * @param[in] selectedDeviceInfo selected device information to performing provisioning.
* @param[out] selectedMode selected operation mode
* @return SP_SUCCESS on success
*/
{
OC_LOG(DEBUG, TAG, "IN SelectOperationMode");
- int i = 0;
- int j = 0;
+ size_t i = 0;
+ size_t j = 0;
while (i < gNumOfProvisioningMethodsPT && j < selectedDeviceInfo->pstat->smLen)
{
/**
* Function to update owner transfer mode
*
- * @param[in] deviceInfo Device Info.
+ * @param[in] otmCtx Context value of ownership transfer.
* @return OC_STACK_OK on success
*/
static OCStackResult PutOwnerTransferModeToResource(OTMContext_t* otmCtx);
/**
* Function to send request to resource to get its pstat resource information.
*
- * @param[in] deviceInfo Selected device Info.
- * @param[in] otmCtx address of pointer variable for OTMContext_t
+ * @param[in] otmCtx Context value of ownership transfer.
* @return OC_STACK_OK on success
*/
static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx);
* Function to send ownerShip info. This function would update Owned as true and
* owner as UUID for provisioning tool
*
- * @param[in] deviceInfo Selected device info
- * @param[in] otmCtx address of pointer variable for OTMContext_t
+ * @param[in] otmCtx Context value of ownership transfer.
* @return OC_STACK_OK on success
*/
static OCStackResult PutOwnershipInformation(OTMContext_t* otmCtx);
* Function to update the operation mode. As per the spec. Operation mode in client driven
* single service provisioning it will be updated to 0x3
*
- * @param[in] deviceInfo Selected device Info.
+ * @param[in] otmCtx Context value of ownership transfer.
* @param[in] selectedOperationMode selected operation mode
- * @param[in] otmCtx address of pointer variable for OTMContext_t
* @return OC_STACK_OK on success
*/
static OCStackResult PutUpdateOperationMode(OTMContext_t* otmCtx,
OicSecDpom_t selectedOperationMode);
+/**
+ * Function to start ownership transfer.
+ * This function will send the first request for provisioning,
+ * The next request message is sent from the response handler for this request.
+ *
+ * @param[in] ctx context value passed to callback from calling function.
+ * @param[in] selectedDevice selected device information to performing provisioning.
+ * @return OC_STACK_OK on success
+ */
static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice);
+/*
+ * Function to finalize provisioning.
+ * This function will send default ACL and commit hash.
+ *
+ * @param[in] otmCtx Context value of ownership transfer.
+ * @return OC_STACK_OK on success
+ */
static OCStackResult FinalizeProvisioning(OTMContext_t* otmCtx);
static bool IsComplete()
{
- int i;
- for(i = 0; i < g_resultArraySize; i++)
+ for(size_t i = 0; i < g_resultArraySize; i++)
{
if(OC_STACK_CONTINUE == g_resultArray[i].res)
{
return true;
}
-static void SetResult(OTMContext_t* otmCtx, OCStackResult res)
+/**
+ * Function to save the result of provisioning.
+ *
+ * @param[in,out] otmCtx Context value of ownership transfer.
+ * @param[in] res result of provisioning
+ */
+static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
{
- int i;
-
OC_LOG(DEBUG, TAG, "IN SetResult");
if(!otmCtx)
{
OC_LOG(WARNING, TAG, "OTMContext is NULL");
+ return;
}
if(otmCtx->selectedDeviceInfo)
{
- for(i = 0; i < g_resultArraySize; i++)
+ for(size_t i = 0; i < g_resultArraySize; i++)
{
if(memcmp(otmCtx->selectedDeviceInfo->doxm->deviceID.id,
g_resultArray[i].deviceId.id, UUID_LENGTH) == 0)
g_resultArray[i].res = res;
if(OC_STACK_OK != res)
{
- hasError = true;
+ g_hasError = true;
}
}
}
//If all request is completed, invoke the user callback.
if(IsComplete())
{
- g_resultCallback(otmCtx->userCtx, g_resultArraySize, g_resultArray, hasError);
+ g_resultCallback(otmCtx->userCtx, g_resultArraySize, g_resultArray, g_hasError);
}
else
{
/**
* Function to save ownerPSK at provisioning tool end.
*
+ * @param[in] selectedDeviceInfo selected device information to performing provisioning.
* @return OC_STACK_OK on success
*/
static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
OCStackResult res = OC_STACK_ERROR;
- CAEndpoint_t endpoint = {0};
+ CAEndpoint_t endpoint;
+ memset(&endpoint, 0x00, sizeof(CAEndpoint_t));
OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE_CA, selectedDeviceInfo->endpoint.addr);
endpoint.addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0';
endpoint.port = selectedDeviceInfo->securePort;
- OicUuid_t ptDeviceID = {};
+ OicUuid_t ptDeviceID = {.id={0}};
if (OC_STACK_OK != GetDoxmDeviceID(&ptDeviceID))
{
OC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
return res;
}
- uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {};
+ uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
//Generating OwnerPSK
CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint,
char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(ownerPSK)) + 1] = {};
B64Result b64Ret = b64Encode(ownerPSK, sizeof(ownerPSK), base64Buff, sizeof(base64Buff),
&outLen);
- if (B64_OK == b64Ret)
- {
- OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID,
- SYMMETRIC_PAIR_WISE_KEY, NULL,
- base64Buff, ownLen, &ptDeviceID);
- if (cred)
- {
- //Update the SVR database.
- if (OC_STACK_OK == AddCredential(cred))
- {
- res = OC_STACK_OK;
- }
- else
- {
- OC_LOG(ERROR, TAG, "AddCredential failed");
- }
- }
- else
- {
- OC_LOG(ERROR, TAG, "GenerateCredential failed");
- }
- }
- else
+ VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR);
+
+ OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID,
+ SYMMETRIC_PAIR_WISE_KEY, NULL,
+ base64Buff, ownLen, &ptDeviceID);
+ VERIFY_NON_NULL(TAG, cred, ERROR);
+
+ res = AddCredential(cred);
+ if(res != OC_STACK_OK)
{
- OC_LOG(ERROR, TAG, "b64Encode failed");
+ DeleteCredList(cred);
+ return res;
}
}
else
}
OC_LOG(DEBUG, TAG, "OUT SaveOwnerPSK");
-
+exit:
return res;
}
/**
* Callback handler for OwnerShipTransferModeHandler API.
*
- * @param[in] ctx IP of target device.
- * @param[in] handle port of remote server.
- * @param[in] clientResponse adapter type of endpoint.
- * @param[in] doxm pointer to doxm instance.
- * @return OC_STACK_KEEP_TRANSACTION to keep transaction and
- * OC_STACK_DELETE_TRANSACTION to delete it.
+ * @param[in] ctx ctx value passed to callback from calling function.
+ * @param[in] UNUSED handle to an invocation
+ * @param[in] clientResponse Response from queries to remote servers.
+ * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
+ * and OC_STACK_KEEP_TRANSACTION to keep it.
*/
-static OCStackApplicationResult OwnerTransferModeHandler(void *ctx, OCDoHandle handle,
+static OCStackApplicationResult OwnerTransferModeHandler(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse)
{
- if (clientResponse)
- {
- OC_LOG(DEBUG, TAG, "IN OwnerTransferModeHandler");
+ OC_LOG(DEBUG, TAG, "IN OwnerTransferModeHandler");
- OTMContext_t* otmCtx = (OTMContext_t*)ctx;
- if(!otmCtx)
- {
- OC_LOG(ERROR, TAG, "Can't find OTMContext");
- return OC_STACK_DELETE_TRANSACTION;
- }
+ VERIFY_NON_NULL(TAG, clientResponse, WARNING);
+ VERIFY_NON_NULL(TAG, ctx, WARNING);
- if(clientResponse->result == OC_STACK_OK)
- {
- OC_LOG(INFO, TAG, "OwnerTransferModeHandler : response result = OC_STACK_OK");
- //Send request : GET /oic/sec/pstat
- OCStackResult res = GetProvisioningStatusResource(otmCtx);
- if(OC_STACK_OK != res)
- {
+ OTMContext_t* otmCtx = (OTMContext_t*)ctx;
- OC_LOG(WARNING, TAG, "Failed to getting pstat information");
- SetResult(otmCtx, res);
- return OC_STACK_DELETE_TRANSACTION;
- }
- }
- else
+ if(clientResponse->result == OC_STACK_OK)
+ {
+ OC_LOG(INFO, TAG, "OwnerTransferModeHandler : response result = OC_STACK_OK");
+ //Send request : GET /oic/sec/pstat
+ OCStackResult res = GetProvisioningStatusResource(otmCtx);
+ if(OC_STACK_OK != res)
{
-
- OC_LOG_V(WARNING, TAG, "OwnerTransferModeHandler : Client response is incorrect : %d",
- clientResponse->result);
- SetResult(otmCtx, clientResponse->result);
- return OC_STACK_DELETE_TRANSACTION;
+ OC_LOG(WARNING, TAG, "Failed to get pstat information");
+ SetResult(otmCtx, res);
}
- OC_LOG(DEBUG, TAG, "OUT OwnerTransferModeHandler");
}
+ else
+ {
+ OC_LOG_V(WARNING, TAG, "OwnerTransferModeHandler : Client response is incorrect : %d",
+ clientResponse->result);
+ SetResult(otmCtx, clientResponse->result);
+ }
+
+ OC_LOG(DEBUG, TAG, "OUT OwnerTransferModeHandler");
+exit:
return OC_STACK_DELETE_TRANSACTION;
}
/**
* Callback handler for ProvisioningStatusResouceHandler API.
*
- * @param[in] ctx IP of target device.
- * @param[in] handle port of remote server.
- * @param[in] clientResponse adapter type of endpoint.
- * @param[in] doxm pointer to doxm instance.
- * @return OC_STACK_KEEP_TRANSACTION to keep transaction and
- * OC_STACK_DELETE_TRANSACTION to delete it.
+ * @param[in] ctx ctx value passed to callback from calling function.
+ * @param[in] UNUSED handle to an invocation
+ * @param[in] clientResponse Response from queries to remote servers.
+ * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
+ * and OC_STACK_KEEP_TRANSACTION to keep it.
*/
-static OCStackApplicationResult ListMethodsHandler(void *ctx, OCDoHandle handle,
+static OCStackApplicationResult ListMethodsHandler(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse)
{
- if (clientResponse)
- {
- OC_LOG(DEBUG, TAG, "IN ListMethodsHandler");
+ OC_LOG(DEBUG, TAG, "IN ListMethodsHandler");
+
+ VERIFY_NON_NULL(TAG, clientResponse, WARNING);
+ VERIFY_NON_NULL(TAG, ctx, WARNING);
+
+ OTMContext_t* otmCtx = (OTMContext_t*)ctx;
- OTMContext_t* otmCtx = (OTMContext_t*)ctx;
- if(!otmCtx)
+ if (OC_STACK_OK == clientResponse->result)
+ {
+ if (NULL == clientResponse->payload)
{
- OC_LOG(ERROR, TAG, "Can't find OTMContext");
+ OC_LOG(INFO, TAG, "Skiping Null payload");
+ SetResult(otmCtx, OC_STACK_ERROR);
return OC_STACK_DELETE_TRANSACTION;
}
- if (OC_STACK_OK == clientResponse->result)
+ if (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)
{
- if (NULL == clientResponse->payload)
- {
- OC_LOG(INFO, TAG, "Skiping Null payload");
- SetResult(otmCtx, OC_STACK_ERROR);
- return OC_STACK_DELETE_TRANSACTION;
- }
-
- if (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)
- {
- OC_LOG(INFO, TAG, "Unknown payload type");
- SetResult(otmCtx, OC_STACK_ERROR);
- return OC_STACK_KEEP_TRANSACTION;
- }
-
- OicSecPstat_t* pstat = JSONToPstatBin(
- ((OCSecurityPayload*)clientResponse->payload)->securityData);
- if(NULL == pstat)
- {
- OC_LOG(ERROR, TAG, "Error while converting json to pstat bin");
- SetResult(otmCtx, OC_STACK_ERROR);
- return OC_STACK_DELETE_TRANSACTION;
- }
- otmCtx->selectedDeviceInfo->pstat = pstat;
+ OC_LOG(INFO, TAG, "Unknown payload type");
+ SetResult(otmCtx, OC_STACK_ERROR);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
- //Select operation mode (Currently supported SINGLE_SERVICE_CLIENT_DRIVEN only)
- OicSecDpom_t selectedOperationMode;
- SelectOperationMode(otmCtx->selectedDeviceInfo, &selectedOperationMode);
+ OicSecPstat_t* pstat = JSONToPstatBin(
+ ((OCSecurityPayload*)clientResponse->payload)->securityData);
+ if(NULL == pstat)
+ {
+ OC_LOG(ERROR, TAG, "Error while converting json to pstat bin");
+ SetResult(otmCtx, OC_STACK_ERROR);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ otmCtx->selectedDeviceInfo->pstat = pstat;
- //Send request : PUT /oic/sec/pstat [{"OM":"0x11", .. }]
- OCStackResult res = PutUpdateOperationMode(otmCtx, selectedOperationMode);
- if (OC_STACK_OK != res)
- {
- OC_LOG(ERROR, TAG, "Error while updating operation mode.");
- SetResult(otmCtx, res);
+ //Select operation mode (Currently supported SINGLE_SERVICE_CLIENT_DRIVEN only)
+ OicSecDpom_t selectedOperationMode;
+ SelectOperationMode(otmCtx->selectedDeviceInfo, &selectedOperationMode);
- }
- }
- else
+ //Send request : PUT /oic/sec/pstat [{"OM":"0x11", .. }]
+ OCStackResult res = PutUpdateOperationMode(otmCtx, selectedOperationMode);
+ if (OC_STACK_OK != res)
{
- OC_LOG_V(WARNING, TAG, "ListMethodsHandler : Client response is incorrect : %d",
- clientResponse->result);
- SetResult(otmCtx, clientResponse->result);
+ OC_LOG(ERROR, TAG, "Error while updating operation mode.");
+ SetResult(otmCtx, res);
}
-
- OC_LOG(DEBUG, TAG, "OUT ListMethodsHandler");
+ }
+ else
+ {
+ OC_LOG_V(WARNING, TAG, "ListMethodsHandler : Client response is incorrect : %d",
+ clientResponse->result);
+ SetResult(otmCtx, clientResponse->result);
}
+ OC_LOG(DEBUG, TAG, "OUT ListMethodsHandler");
+exit:
return OC_STACK_DELETE_TRANSACTION;
}
/**
* Callback handler for OwnershipInformationHandler API.
*
- * @param[in] ctx IP of target device.
- * @param[in] handle port of remote server.
- * @param[in] clientResponse adapter type of endpoint.
- * @param[in] doxm pointer to doxm instance.
- * @return OC_STACK_KEEP_TRANSACTION to keep transaction and
- * OC_STACK_DELETE_TRANSACTION to delete it.
+ * @param[in] ctx ctx value passed to callback from calling function.
+ * @param[in] UNUSED handle to an invocation
+ * @param[in] clientResponse Response from queries to remote servers.
+ * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
+ * and OC_STACK_KEEP_TRANSACTION to keep it.
*/
static OCStackApplicationResult OwnershipInformationHandler(void *ctx,
- OCDoHandle handle, OCClientResponse *clientResponse)
+ OCDoHandle UNUSED, OCClientResponse *clientResponse)
{
+ VERIFY_NON_NULL(TAG, clientResponse, WARNING);
+ VERIFY_NON_NULL(TAG, ctx, WARNING);
- if (clientResponse)
- {
- OC_LOG(DEBUG, TAG, "IN OwnershipInformationHandler");
+ OC_LOG(DEBUG, TAG, "IN OwnershipInformationHandler");
- OCStackResult res = OC_STACK_OK;
- OTMContext_t* otmCtx = (OTMContext_t*)ctx;
- if (OC_STACK_OK == clientResponse->result)
+ OCStackResult res = OC_STACK_OK;
+ OTMContext_t* otmCtx = (OTMContext_t*)ctx;
+ if (OC_STACK_OK == clientResponse->result)
+ {
+ if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
{
- res = SaveOwnerPSK(otmCtx->selectedDeviceInfo);
- if(OC_STACK_OK != res)
- {
- OC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to owner PSK generation");
- SetResult(otmCtx, res);
- return OC_STACK_DELETE_TRANSACTION;
- }
-
- CAEndpoint_t* endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint;
- endpoint->port = otmCtx->selectedDeviceInfo->securePort;
- CAResult_t closeRes = CACloseDtlsSession(endpoint);
- if(CA_STATUS_OK != closeRes)
+ res = RemoveCredential(&otmCtx->tempCredId);
+ if(OC_STACK_RESOURCE_DELETED != res)
{
- OC_LOG(ERROR, TAG, "Failed to close DTLS session");
- SetResult(otmCtx, closeRes);
+ OC_LOG_V(ERROR, TAG, "Failed to remove temporal PSK : %d", res);
return OC_STACK_DELETE_TRANSACTION;
}
+ }
- // TODO: PIN based OxM is required.
- /*
- if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
- {
- res = RemoveCredential(otmCtx->tempCredId);
- if(OC_STACK_OK != res)
- {
- OC_LOG_V(ERROR, TAG, "Failed to remove temporal PSK : %d", res);
- return OC_STACK_DELETE_TRANSACTION;
- }
- }
- */
- OC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
- OC_LOG(INFO, TAG, "Start defualt ACL & commit-hash provisioning.");
-
- res = FinalizeProvisioning(otmCtx);
- if(OC_STACK_OK != res)
- {
- SetResult(otmCtx, res);
- return OC_STACK_DELETE_TRANSACTION;
- }
+ res = SaveOwnerPSK(otmCtx->selectedDeviceInfo);
+ if(OC_STACK_OK != res)
+ {
+ OC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to owner PSK generation");
+ SetResult(otmCtx, res);
+ return OC_STACK_DELETE_TRANSACTION;
}
- else
+
+ CAEndpoint_t* endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint;
+ endpoint->port = otmCtx->selectedDeviceInfo->securePort;
+ CAResult_t closeRes = CACloseDtlsSession(endpoint);
+ if(CA_STATUS_OK != closeRes)
{
- res = clientResponse->result;
+ OC_LOG(ERROR, TAG, "Failed to close DTLS session");
+ SetResult(otmCtx, closeRes);
+ return OC_STACK_DELETE_TRANSACTION;
}
- OC_LOG(DEBUG, TAG, "OUT OwnershipInformationHandler");
+ OC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
+ OC_LOG(INFO, TAG, "Start defualt ACL & commit-hash provisioning.");
+
+ res = FinalizeProvisioning(otmCtx);
+ if(OC_STACK_OK != res)
+ {
+ SetResult(otmCtx, res);
+ }
+ }
+ else
+ {
+ res = clientResponse->result;
}
+ OC_LOG(DEBUG, TAG, "OUT OwnershipInformationHandler");
+
+exit:
return OC_STACK_DELETE_TRANSACTION;
}
/**
* Response handler for update operation mode.
*
- * @param[in] object Remote endpoint object
- * @param[in] requestInfo Datastructure containing request information.
+ * @param[in] ctx ctx value passed to callback from calling function.
+ * @param[in] UNUSED handle to an invocation
+ * @param[in] clientResponse Response from queries to remote servers.
+ * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
+ * and OC_STACK_KEEP_TRANSACTION to keep it.
*/
static OCStackApplicationResult OperationModeUpdateHandler(void *ctx,
- OCDoHandle handle, OCClientResponse *clientResponse)
+ OCDoHandle UNUSED, OCClientResponse *clientResponse)
{
- if (clientResponse)
- {
- OC_LOG(DEBUG, TAG, "IN OperationModeUpdateHandler");
+ OC_LOG(DEBUG, TAG, "IN OperationModeUpdateHandler");
- OTMContext_t* otmCtx = (OTMContext_t*)ctx;
- if (OC_STACK_OK == clientResponse->result)
- {
- OCStackResult res = OC_STACK_ERROR;
- OicSecOxm_t selOxm = otmCtx->selectedDeviceInfo->doxm->oxmSel;
- //DTLS Handshake
- //Load secret for temporal secure session.
- if(g_OTMDatas[selOxm].loadSecretCB)
- {
- res = g_OTMDatas[selOxm].loadSecretCB(otmCtx);
- if(OC_STACK_OK != res)
- {
- OC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to load secret");
- SetResult(otmCtx, res);
- return OC_STACK_DELETE_TRANSACTION;
- }
- }
+ VERIFY_NON_NULL(TAG, clientResponse, WARNING);
+ VERIFY_NON_NULL(TAG, ctx, WARNING);
- //Try DTLS handshake to generate secure session
- if(g_OTMDatas[selOxm].createSecureSessionCB)
+ OTMContext_t* otmCtx = (OTMContext_t*)ctx;
+ if (OC_STACK_OK == clientResponse->result)
+ {
+ OCStackResult res = OC_STACK_ERROR;
+ OicSecOxm_t selOxm = otmCtx->selectedDeviceInfo->doxm->oxmSel;
+ //DTLS Handshake
+ //Load secret for temporal secure session.
+ if(g_OTMDatas[selOxm].loadSecretCB)
+ {
+ res = g_OTMDatas[selOxm].loadSecretCB(otmCtx);
+ if(OC_STACK_OK != res)
{
- res = g_OTMDatas[selOxm].createSecureSessionCB(otmCtx);
- if(OC_STACK_OK != res)
- {
- OC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to create DTLS session");
- SetResult(otmCtx, res);
- return OC_STACK_DELETE_TRANSACTION;
- }
+ OC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to load secret");
+ SetResult(otmCtx, res);
+ return OC_STACK_DELETE_TRANSACTION;
}
+ }
- //Send request : PUT /oic/sec/doxm [{"Owned":"True", .. , "Owner":"PT's UUID"}]
- res = PutOwnershipInformation(otmCtx);
+ //Try DTLS handshake to generate secure session
+ if(g_OTMDatas[selOxm].createSecureSessionCB)
+ {
+ res = g_OTMDatas[selOxm].createSecureSessionCB(otmCtx);
if(OC_STACK_OK != res)
{
- OC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to send owner information");
+ OC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to create DTLS session");
SetResult(otmCtx, res);
- return OC_STACK_DELETE_TRANSACTION;
+ return OC_STACK_DELETE_TRANSACTION;
}
}
- else
+
+ //Send request : PUT /oic/sec/doxm [{"Owned":"True", .. , "Owner":"PT's UUID"}]
+ res = PutOwnershipInformation(otmCtx);
+ if(OC_STACK_OK != res)
{
- OC_LOG(ERROR, TAG, "Error while update operation mode");
- SetResult(otmCtx, clientResponse->result);
- return OC_STACK_DELETE_TRANSACTION;
+ OC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to send owner information");
+ SetResult(otmCtx, res);
}
- OC_LOG(DEBUG, TAG, "OUT OperationModeUpdateHandler");
}
+ else
+ {
+ OC_LOG(ERROR, TAG, "Error while update operation mode");
+ SetResult(otmCtx, clientResponse->result);
+ }
+
+ OC_LOG(DEBUG, TAG, "OUT OperationModeUpdateHandler");
+exit:
return OC_STACK_DELETE_TRANSACTION;
}
secPayload->securityData = g_OTMDatas[selectedOxm].createSelectOxmPayloadCB(otmCtx);
if (NULL == secPayload->securityData)
{
+ OICFree(secPayload);
OC_LOG(ERROR, TAG, "Error while converting bin to json");
return OC_STACK_ERROR;
}
return res;
}
-/**
- * Function to send request to resource to get its pstat resource information.
- *
- * @param[in] timeout timeout for operation.
- * @param[in] deviceInfo Device Info.
- * @return OC_STACK_OK on success
- */
static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx)
{
OC_LOG(DEBUG, TAG, "IN GetProvisioningStatusResource");
}
-/**
- * Function to send ownerShip info. This function would update Owned as true and
- * owner as UUID for provisioning tool
- *
- * @param[in] timeout timeout value for the operation.
- * @param[in] deviceInfo provisioning context.
- * @return OC_STACK_OK on success
- */
static OCStackResult PutOwnershipInformation(OTMContext_t* otmCtx)
{
OC_LOG(DEBUG, TAG, "IN PutOwnershipInformation");
secPayload->securityData = g_OTMDatas[selOxm].createOwnerTransferPayloadCB(otmCtx);
if (NULL == secPayload->securityData)
{
+ OICFree(secPayload);
OC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
return OC_STACK_INVALID_PARAM;
}
cbData.cb = &OwnershipInformationHandler;
cbData.context = (void *)otmCtx;
cbData.cd = NULL;
-
// TODO: 6th argument need to be changed, if we have to use CT_FLAG_SECURE
OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
CT_ADAPTER_IP, OC_LOW_QOS, &cbData, NULL, 0);
return res;
}
-/**
- * Function to update the operation mode. As per the spec. Operation mode in client driven
- * single service provisioning it will be updated to 0x3
- *
- * @param[in] timeout timeout for operation.
- * @param[in] deviceInfo Device Info.
- * @return OC_STACK_OK on success
- */
static OCStackResult PutUpdateOperationMode(OTMContext_t* otmCtx,
OicSecDpom_t selectedOperationMode)
{
secPayload->securityData = BinToPstatJSON(deviceInfo->pstat);
if (NULL == secPayload->securityData)
{
+ OICFree(secPayload);
OC_LOG(ERROR, TAG, "Error while converting pstat bin to json");
return OC_STACK_INVALID_PARAM;
}
}
g_resultCallback = resultCallback;
- hasError = false;
+ g_hasError = false;
OCProvisionDev_t* pCurDev = selectedDevicelist;
return OC_STACK_NO_MEMORY;
}
- int devIdx = 0;
pCurDev = selectedDevicelist;
//Fill the device UUID for result array.
- for(devIdx = 0; devIdx < g_resultArraySize; devIdx++)
+ for(size_t devIdx = 0; devIdx < g_resultArraySize; devIdx++)
{
memcpy(g_resultArray[devIdx].deviceId.id,
pCurDev->doxm->deviceID.id,
OC_LOG(DEBUG, TAG, "OUT OTMDoOwnershipTransfer");
- return (hasError ? OC_STACK_ERROR : OC_STACK_OK);
+ return (g_hasError ? OC_STACK_ERROR : OC_STACK_OK);
}
/**
* Callback handler of SRPFinalizeProvisioning.
*
* @param[in] ctx ctx value passed to callback from calling function.
- * @param[in] handle handle to an invocation
+ * @param[in] UNUSED handle to an invocation
* @param[in] clientResponse Response from queries to remote servers.
* @return OC_STACK_DELETE_TRANSACTION to delete the transaction
* and OC_STACK_KEEP_TRANSACTION to keep it.
*/
-static OCStackApplicationResult FinalizeProvisioningCB(void *ctx, OCDoHandle handle,
+static OCStackApplicationResult FinalizeProvisioningCB(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse)
{
- if (clientResponse)
- {
- OC_LOG_V(INFO, TAG, "IN FinalizeProvisioningCB.");
- OTMContext_t* otmCtx = (OTMContext_t*)ctx;
- if(!otmCtx)
- {
- OC_LOG(ERROR, TAG, "OTMContext is NULL");
- return OC_STACK_DELETE_TRANSACTION;
- }
+ OC_LOG_V(INFO, TAG, "IN FinalizeProvisioningCB.");
- if(OC_STACK_OK == clientResponse->result)
- {
- SetResult(otmCtx, OC_STACK_OK);
- return OC_STACK_DELETE_TRANSACTION;
- }
- }
+ VERIFY_NON_NULL(TAG, clientResponse, ERROR);
+ VERIFY_NON_NULL(TAG, ctx, ERROR);
+ OTMContext_t* otmCtx = (OTMContext_t*)ctx;
+
+ if(OC_STACK_OK == clientResponse->result)
+ {
+ SetResult(otmCtx, OC_STACK_OK);
+ }
+exit:
return OC_STACK_DELETE_TRANSACTION;
}
* Callback handler of default ACL provisioning.
*
* @param[in] ctx ctx value passed to callback from calling function.
- * @param[in] handle handle to an invocation
+ * @param[in] UNUSED handle to an invocation
* @param[in] clientResponse Response from queries to remote servers.
* @return OC_STACK_DELETE_TRANSACTION to delete the transaction
* and OC_STACK_KEEP_TRANSACTION to keep it.
*/
-static OCStackApplicationResult ProvisionDefaultACLCB(void *ctx, OCDoHandle handle,
+static OCStackApplicationResult ProvisionDefaultACLCB(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse)
{
OC_LOG_V(INFO, TAG, "IN ProvisionDefaultACLCB.");
- if (clientResponse)
+ VERIFY_NON_NULL(TAG, clientResponse, ERROR);
+ VERIFY_NON_NULL(TAG, ctx, ERROR);
+
+ OTMContext_t* otmCtx = (OTMContext_t*) ctx;
+
+ if (OC_STACK_RESOURCE_CREATED == clientResponse->result)
{
- OTMContext_t* otmCtx = (OTMContext_t*) ctx;
- if(!otmCtx)
+ OC_LOG_V(INFO, TAG, "Staring commit hash task.");
+ // TODO hash currently have fixed value 0.
+ uint16_t aclHash = 0;
+ otmCtx->selectedDeviceInfo->pstat->commitHash = aclHash;
+ otmCtx->selectedDeviceInfo->pstat->tm = NORMAL;
+ OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
+ if(!secPayload)
{
- OC_LOG(ERROR, TAG, "OTMContext is NULL");
- return OC_STACK_DELETE_TRANSACTION;
+ OC_LOG(ERROR, TAG, "Failed to memory allocation");
+ return OC_STACK_NO_MEMORY;
}
-
- if (OC_STACK_RESOURCE_CREATED == clientResponse->result)
+ secPayload->base.type = PAYLOAD_TYPE_SECURITY;
+ secPayload->securityData = BinToPstatJSON(otmCtx->selectedDeviceInfo->pstat);
+ if (NULL == secPayload->securityData)
{
- OC_LOG_V(INFO, TAG, "Staring commit hash task.");
- // TODO hash currently have fixed value 0.
- uint16_t aclHash = 0;
- otmCtx->selectedDeviceInfo->pstat->commitHash = aclHash;
- otmCtx->selectedDeviceInfo->pstat->tm = NORMAL;
- OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
- if(!secPayload)
- {
- OC_LOG(ERROR, TAG, "Failed to memory allocation");
- return OC_STACK_NO_MEMORY;
- }
- secPayload->base.type = PAYLOAD_TYPE_SECURITY;
- secPayload->securityData = BinToPstatJSON(otmCtx->selectedDeviceInfo->pstat);
- if (NULL == secPayload->securityData)
- {
- SetResult(otmCtx, OC_STACK_INVALID_JSON);
- return OC_STACK_DELETE_TRANSACTION;
- }
- OC_LOG_V(INFO, TAG, "Created payload for commit hash: %s",secPayload->securityData);
-
- char uri[MAX_QUERY_LENGTH] = { 0 };
- size_t uriLen = sizeof(uri);
-
- snprintf(uri, uriLen - 1, COAPS_QUERY, otmCtx->selectedDeviceInfo->endpoint.addr,
- otmCtx->selectedDeviceInfo->securePort, OIC_RSRC_PSTAT_URI);
- uri[uriLen - 1] = '\0';
- OCCallbackData cbData = {0,};
- cbData.cb = &FinalizeProvisioningCB;
- cbData.context = (void*)otmCtx; // forward context to SRPFinalizeProvisioningCB
- cbData.cd = NULL;
-
- // TODO change value of CT_ADAPTER_IP with val from discovery
- OCStackResult ret = OCDoResource(NULL, OC_REST_PUT, uri, 0, (OCPayload*)secPayload,
- CT_ADAPTER_IP, OC_HIGH_QOS, &cbData, NULL, 0);
- OC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
- if (ret != OC_STACK_OK)
- {
- OC_LOG(ERROR, TAG, "OCStack resource error");
- SetResult(otmCtx, ret);
- return OC_STACK_DELETE_TRANSACTION;
- }
+ OICFree(secPayload);
+ SetResult(otmCtx, OC_STACK_INVALID_JSON);
return OC_STACK_DELETE_TRANSACTION;
}
- else
+ OC_LOG_V(INFO, TAG, "Created payload for commit hash: %s",secPayload->securityData);
+
+ char uri[MAX_QUERY_LENGTH] = { 0 };
+ size_t uriLen = sizeof(uri);
+
+ snprintf(uri, uriLen - 1, COAPS_QUERY, otmCtx->selectedDeviceInfo->endpoint.addr,
+ otmCtx->selectedDeviceInfo->securePort, OIC_RSRC_PSTAT_URI);
+ uri[uriLen - 1] = '\0';
+ OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
+ cbData.cb = &FinalizeProvisioningCB;
+ cbData.context = (void*)otmCtx; // forward context to SRPFinalizeProvisioningCB
+ cbData.cd = NULL;
+
+ // TODO change value of CT_ADAPTER_IP with val from discovery
+ OCStackResult ret = OCDoResource(NULL, OC_REST_PUT, uri, 0, (OCPayload*)secPayload,
+ CT_ADAPTER_IP, OC_HIGH_QOS, &cbData, NULL, 0);
+ OC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
+ if (ret != OC_STACK_OK)
{
- OC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
- clientResponse->result);
- SetResult(otmCtx, clientResponse->result);
+ OC_LOG(ERROR, TAG, "OCStack resource error");
+ SetResult(otmCtx, ret);
}
}
-
+ else
+ {
+ OC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
+ clientResponse->result);
+ SetResult(otmCtx, clientResponse->result);
+ }
+exit:
return OC_STACK_DELETE_TRANSACTION;
}
}
// Provision Default ACL to device
OicSecAcl_t defaultAcl =
- { {},
+ { {.id={0}},
1,
NULL,
0x001F,
NULL,
};
- OicUuid_t provTooldeviceID = {{0,}};
+ OicUuid_t provTooldeviceID = {.id={0}};
if (OC_STACK_OK != GetDoxmDeviceID(&provTooldeviceID))
{
OC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
OICFree(defaultAcl.owners);
if(!secPayload->securityData)
{
+ OICFree(secPayload);
OC_LOG(INFO, TAG, "FinalizeProvisioning : Failed to BinToAclJSON");
SetResult(otmCtx, OC_STACK_ERROR);
return OC_STACK_ERROR;
uri[uriLen - 1] = '\0';
OC_LOG_V(INFO, TAG, "Request URI for Provisioning default ACL : %s",uri);
- OCCallbackData cbData = {};
+ OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
cbData.cb = &ProvisionDefaultACLCB;
cbData.context = (void *)otmCtx;
cbData.cd = NULL;
return NULL;
}
- OicUuid_t uuidPT = {};
+ OicUuid_t uuidPT = {.id={0}};
if (OC_STACK_OK != GetDoxmDeviceID(&uuidPT))
{
OC_LOG(INFO, TAG, "Anonymous cipher suite Enabled.");
OCProvisionDev_t* selDevInfo = otmCtx->selectedDeviceInfo;
- CAEndpoint_t* endpoint = CACloneEndpoint((CAEndpoint_t *)&selDevInfo->endpoint);
+ CAEndpoint_t *endpoint = (CAEndpoint_t *)OICCalloc(1, sizeof (CAEndpoint_t));
if(NULL == endpoint)
{
return OC_STACK_NO_MEMORY;
}
+ memcpy(endpoint,&selDevInfo->endpoint,sizeof(CAEndpoint_t));
endpoint->port = selDevInfo->securePort;
- caresult = CAInitiateHandshake(endpoint);
+ caresult = CAInitiateHandshake(endpoint);
OICFree(endpoint);
-
if (CA_STATUS_OK != caresult)
{
OC_LOG_V(ERROR, TAG, "DTLS handshake failure.");
OC_LOG(INFO, TAG, "OUT CreateSecureSessionJustWorksCallback");
return OC_STACK_OK;
}
-
--- /dev/null
+/* *****************************************************************
+ *
+ * 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.
+ *
+ * *****************************************************************/
+
+#include <memory.h>
+
+#include "ocstack.h"
+#include "ocsecurityconfig.h"
+#include "securevirtualresourcetypes.h"
+#include "doxmresource.h"
+#include "credresource.h"
+#include "cacommon.h"
+#include "cainterface.h"
+#include "ocrandom.h"
+#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"
+
+#define TAG "OXM_RandomPIN"
+
+char* CreatePinBasedSelectOxmPayload(OTMContext_t* otmCtx)
+{
+ if(!otmCtx || !otmCtx->selectedDeviceInfo)
+ {
+ return NULL;
+ }
+
+ otmCtx->selectedDeviceInfo->doxm->oxmSel = OIC_RANDOM_DEVICE_PIN;
+
+ OicUuid_t uuidPT = {.id={0}};
+ if (OC_STACK_OK != GetDoxmDeviceID(&uuidPT))
+ {
+ OC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
+ return NULL;
+ }
+ memcpy(otmCtx->selectedDeviceInfo->doxm->owner.id, uuidPT.id, UUID_LENGTH);
+
+ return BinToDoxmJSON(otmCtx->selectedDeviceInfo->doxm);
+}
+
+char* CreatePinBasedOwnerTransferPayload(OTMContext_t* otmCtx)
+{
+ if(!otmCtx || !otmCtx->selectedDeviceInfo)
+ {
+ return NULL;
+ }
+
+ OicUuid_t uuidPT = {.id={0}};
+
+ if (OC_STACK_OK != GetDoxmDeviceID(&uuidPT))
+ {
+ OC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
+ return NULL;
+ }
+ memcpy(otmCtx->selectedDeviceInfo->doxm->owner.id, uuidPT.id , UUID_LENGTH);
+ otmCtx->selectedDeviceInfo->doxm->owned = true;
+
+ return BinToDoxmJSON(otmCtx->selectedDeviceInfo->doxm);
+}
+
+OCStackResult InputPinCodeCallback(OTMContext_t* otmCtx)
+{
+ if(!otmCtx || !otmCtx->selectedDeviceInfo)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ uint8_t pinData[OXM_RANDOM_PIN_SIZE + 1];
+
+ OCStackResult res = InputPin((char*)pinData, OXM_RANDOM_PIN_SIZE + 1);
+ if(OC_STACK_OK != res)
+ {
+ OC_LOG(ERROR, TAG, "Failed to input PIN");
+ return res;
+ }
+
+ OicUuid_t deviceUUID = {.id={0}};
+ if (OC_STACK_OK != GetDoxmDeviceID(&deviceUUID))
+ {
+ OC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
+ return OC_STACK_ERROR;
+ }
+
+ res = AddTmpPskWithPIN(&otmCtx->selectedDeviceInfo->doxm->deviceID,
+ SYMMETRIC_PAIR_WISE_KEY,
+ (char*)pinData, OXM_RANDOM_PIN_SIZE,
+ 1, &deviceUUID, &otmCtx->tempCredId);
+ if(res != OC_STACK_OK)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed to save the temporal PSK : %d", res);
+ }
+
+ return res;
+}
+
+OCStackResult CreateSecureSessionRandomPinCallbak(OTMContext_t* otmCtx)
+{
+ OC_LOG(INFO, TAG, "IN CreateSecureSessionRandomPinCallbak");
+
+ if(!otmCtx || !otmCtx->selectedDeviceInfo)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OCProvisionDev_t* selDevInfo = otmCtx->selectedDeviceInfo;
+ CAEndpoint_t *endpoint = (CAEndpoint_t *)OICCalloc(1, sizeof (CAEndpoint_t));
+ if(NULL == endpoint)
+ {
+ return OC_STACK_NO_MEMORY;
+ }
+ memcpy(endpoint,&selDevInfo->endpoint,sizeof(CAEndpoint_t));
+ endpoint->port = selDevInfo->securePort;
+ CAResult_t caresult = CAInitiateHandshake(endpoint);
+ OICFree(endpoint);
+ if (CA_STATUS_OK != caresult)
+ {
+ OC_LOG_V(ERROR, TAG, "DTLS handshake failure.");
+ return OC_STACK_ERROR;
+ }
+
+ OC_LOG(INFO, TAG, "OUT CreateSecureSessionRandomPinCallbak");
+
+ return OC_STACK_OK;
+}
*/
OCStackResult PMTimeout(unsigned short waittime)
{
- struct timespec startTime = {};
- struct timespec currTime = {};
+ struct timespec startTime = {.tv_sec=0, .tv_nsec=0};
+ struct timespec currTime = {.tv_sec=0, .tv_nsec=0};
OCStackResult res = OC_STACK_OK;
#ifdef _POSIX_MONOTONIC_CLOCK
* OC_STACK_DELETE_TRANSACTION to delete it.
*/
static OCStackApplicationResult SecurePortDiscoveryHandler(void *ctx,
- OCDoHandle handle, OCClientResponse *clientResponse)
+ OCDoHandle UNUSED, OCClientResponse *clientResponse)
{
if (ctx == NULL)
{
* OC_STACK_DELETE_TRANSACTION to delete it.
*/
static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx,
- OCDoHandle handle, OCClientResponse *clientResponse)
+ OCDoHandle UNUSED, OCClientResponse *clientResponse)
{
if (ctx == NULL)
{
exit:
return res;
}
-
* limitations under the License.
*
* *****************************************************************/
-
#include <stdio.h>
#include <string.h>
#include <stdint.h>
* Callback handler for handling callback of provisioning device 2.
*
* @param[in] ctx ctx value passed to callback from calling function.
- * @param[in] handle handle to an invocation
+ * @param[in] UNUSED handle to an invocation
* @param[in] clientResponse Response from queries to remote servers.
* @return OC_STACK_DELETE_TRANSACTION to delete the transaction
* and OC_STACK_KEEP_TRANSACTION to keep it.
*/
-static OCStackApplicationResult provisionCredentialCB2(void *ctx, OCDoHandle handle,
+static OCStackApplicationResult provisionCredentialCB2(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse)
{
VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
* Callback handler for handling callback of provisioning device 1.
*
* @param[in] ctx ctx value passed to callback from calling function.
- * @param[in] handle handle to an invocation
+ * @param[in] UNUSED handle to an invocation
* @param[in] clientResponse Response from queries to remote servers.
* @return OC_STACK_DELETE_TRANSACTION to delete the transaction
* and OC_STACK_KEEP_TRANSACTION to keep it.
*/
-static OCStackApplicationResult provisionCredentialCB1(void *ctx, OCDoHandle handle,
+static OCStackApplicationResult provisionCredentialCB1(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse)
{
VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
secPayload->securityData = BinToCredJSON(cred);
- VERIFY_NON_NULL(TAG, secPayload->securityData, ERROR, OC_STACK_NO_MEMORY);
+ if(NULL == secPayload->securityData)
+ {
+ OICFree(secPayload);
+ OC_LOG(ERROR, TAG, "Failed to BinToCredJSON");
+ return OC_STACK_NO_MEMORY;
+ }
+
OC_LOG_V(INFO, TAG, "Credential for provisioning : %s",secPayload->securityData);
char uri[SRP_MAX_URI_LENGTH] = { 0 };
uri[uriLen - 1] = '\0';
OC_LOG_V(INFO, TAG, "URI for Credential provisioning : %s",uri);
- OCCallbackData cbData = { };
+ OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
cbData.cb = responseHandler;
cbData.context = (void *) credData;
cbData.cd = NULL;
OCDoHandle handle = NULL;
OCMethod method = OC_REST_POST;
// TODO replace CT_ADAPTER_IP with value from discovery
- OCStackResult ret = OCDoResource(&handle, method, uri, 0, secPayload,
+ OCStackResult ret = OCDoResource(&handle, method, uri, 0, (OCPayload*)secPayload,
CT_ADAPTER_IP, OC_HIGH_QOS, &cbData, NULL, 0);
OC_LOG_V(INFO, TAG, "OCDoResource::Credential provisioning returned : %d",ret);
if (ret != OC_STACK_OK)
* Callback handler of SRPProvisionACL.
*
* @param[in] ctx ctx value passed to callback from calling function.
- * @param[in] handle handle to an invocation
+ * @param[in] UNUSED handle to an invocation
* @param[in] clientResponse Response from queries to remote servers.
* @return OC_STACK_DELETE_TRANSACTION to delete the transaction
* and OC_STACK_KEEP_TRANSACTION to keep it.
*/
-static OCStackApplicationResult SRPProvisionACLCB(void *ctx, OCDoHandle handle,
+static OCStackApplicationResult SRPProvisionACLCB(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse)
{
OC_LOG_V(INFO, TAG, "Inside SRPProvisionACLCB.");
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
secPayload->securityData = BinToAclJSON(acl);
- VERIFY_NON_NULL(TAG, secPayload->securityData, ERROR, OC_STACK_NO_MEMORY);
+ if(NULL == secPayload->securityData)
+ {
+ OICFree(secPayload);
+ OC_LOG(ERROR, TAG, "Failed to BinToAclJSON");
+ return OC_STACK_NO_MEMORY;
+ }
OC_LOG_V(INFO, TAG, "ACL : %s", secPayload->securityData);
char uri[SRP_MAX_URI_LENGTH] = {0};
uri[uriLen - 1] = '\0';
OC_LOG_V(INFO, TAG, "URI : %s", uri);
- OCCallbackData cbData = {0,};
+ OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
cbData.cb = &SRPProvisionACLCB;
ACLData_t *aclData = (ACLData_t *) OICMalloc(sizeof(ACLData_t));
if (aclData == NULL)
{
+ OICFree(secPayload);
OC_LOG(ERROR, TAG, "Unable to allocate memory");
return OC_STACK_NO_MEMORY;
}
aclData->resArr = (OCProvisionResult_t*)OICMalloc(sizeof(OCProvisionResult_t)*noOfRiCalls);
if (aclData->resArr == NULL)
{
+ OICFree(secPayload);
OC_LOG(ERROR, TAG, "Unable to allocate memory");
return OC_STACK_NO_MEMORY;
}
// TODO replace CT_ADAPTER_IP with value from discovery
OCStackResult ret = OCDoResource(&handle, method, uri,
- &selectedDeviceInfo->endpoint, secPayload,
+ &selectedDeviceInfo->endpoint, (OCPayload*)secPayload,
CT_ADAPTER_IP, OC_HIGH_QOS, &cbData, NULL, 0);
-
if (ret != OC_STACK_OK)
{
OICFree(aclData->resArr);
* *****************************************************************/
#include "gtest/gtest.h"
#include "oxmjustworks.h"
-// TODO: PIN based OxM implementation is required.
-//#include "oxmrandompin.h"
+#include "oxmrandompin.h"
#include "ownershiptransfermanager.h"
#include "ocstack.h"
#include "utlist.h"
EXPECT_TRUE(NULL == payloadRes);
}
-// TODO: PIN based OxM implementation is required
-/*
TEST(RandomPinOxMTest, NullParam)
{
OTMContext_t* otmCtx = NULL;
payloadRes = CreatePinBasedOwnerTransferPayload(&otmCtx2);
EXPECT_TRUE(NULL == payloadRes);
-}*/
-
+}
static OCProvisionDev_t pDev2;
static OicSecCredType_t credType;
-static void provisioningCB (void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
+static void provisioningCB (void* UNUSED1, int UNUSED2,
+ OCProvisionResult_t *UNUSED3, bool UNUSED4)
{
//dummy callback
}
TEST(SRPProvisionCredentialsTest, NullDevice1)
{
- EXPECT_EQ(OC_STACK_INVALID_PARAM, SRPProvisionCredentials(NULL, credType, OWNER_PSK_LENGTH_128, NULL, &pDev2, &provisioningCB));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, SRPProvisionCredentials(NULL, credType,
+ OWNER_PSK_LENGTH_128, NULL,
+ &pDev2, &provisioningCB));
}
TEST(SRPProvisionCredentialsTest, NullCallback)
{
- EXPECT_EQ(OC_STACK_INVALID_CALLBACK, SRPProvisionCredentials(NULL, credType, OWNER_PSK_LENGTH_128, &pDev1, &pDev2, NULL));
+ EXPECT_EQ(OC_STACK_INVALID_CALLBACK, SRPProvisionCredentials(NULL, credType,
+ OWNER_PSK_LENGTH_128,
+ &pDev1, &pDev2, NULL));
}
TEST(SRPProvisionCredentialsTest, InvalidKeySize)
{
- EXPECT_EQ(OC_STACK_INVALID_PARAM, SRPProvisionCredentials(NULL, credType, 0, &pDev1, &pDev2, &provisioningCB));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, SRPProvisionCredentials(NULL, credType,
+ 0, &pDev1, &pDev2,
+ &provisioningCB));
}
\ No newline at end of file
#include "base64.h"
#include "srmutility.h"
#include "cainterface.h"
+#include "pbkdf2.h"
#include <stdlib.h>
#ifdef WITH_ARDUINO
#include <string.h>
//Owners -- Mandatory
jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_OWNERS_NAME);
VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR)
+ VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
cred->ownersLen = cJSON_GetArraySize(jsonObj);
VERIFY_SUCCESS(TAG, cred->ownersLen > 0, ERROR);
cred->owners = (OicUuid_t*)OICCalloc(cred->ownersLen, sizeof(OicUuid_t));
}
OICFree(caBlob);
}
+
+/**
+ * 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)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+
+ if(tmpSubject == NULL || pin == NULL || pinSize == 0 || tmpCredSubject == NULL)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
+ int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, owners->id,
+ UUID_LENGTH, PBKDF_ITERATIONS,
+ OWNER_PSK_LENGTH_128, privData);
+ VERIFY_SUCCESS(TAG, (dtlsRes == 0) , ERROR);
+
+ uint32_t outLen = 0;
+ char base64Buff[B64ENCODE_OUT_SAFESIZE(OWNER_PSK_LENGTH_128) + 1] = {};
+ B64Result b64Ret = b64Encode(privData, OWNER_PSK_LENGTH_128, base64Buff,
+ sizeof(base64Buff), &outLen);
+ VERIFY_SUCCESS(TAG, (B64_OK == b64Ret), ERROR);
+
+ OicSecCred_t* cred = GenerateCredential(tmpSubject, credType, NULL,
+ base64Buff, ownersLen, owners);
+ if(NULL == cred)
+ {
+ OC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
+ return OC_STACK_ERROR;
+ }
+
+ memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
+
+ ret = AddCredential(cred);
+ if( OC_STACK_OK != ret)
+ {
+ OC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
+ }
+
+exit:
+ return ret;
+}
+
#endif /* __WITH_DTLS__ */
#include "credresource.h"
#include "ocserverrequest.h"
#include "srmutility.h"
+#include "pinoxmcommon.h"
+
+#ifdef __WITH_DTLS__
+#include "global.h"
+#endif
+
#include <stdlib.h>
#include <string.h>
jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OXM_SEL_NAME);
if(jsonObj)
{
- VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR)
+ VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
doxm->oxmSel = (OicSecOxm_t)jsonObj->valueint;
}
else // PUT/POST JSON may not have oxmsel so set it to the gDoxm->oxmSel
jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OWNED_NAME);
if(jsonObj)
{
- VERIFY_SUCCESS(TAG, (cJSON_True == jsonObj->type || cJSON_False == jsonObj->type), ERROR)
+ VERIFY_SUCCESS(TAG, (cJSON_True == jsonObj->type || cJSON_False == jsonObj->type), ERROR);
doxm->owned = jsonObj->valueint;
}
else // PUT/POST JSON may not have owned so set it to the gDomx->owned
strncpy((char *)doxm->deviceID.id, (char *)gDoxm->deviceID.id, sizeof(doxm->deviceID.id));
}
- // Owner -- will be empty when device state is unowned.
- if (true == doxm->owned)
+ //Owner -- will be empty when device status is unowned.
+ jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OWNER_NAME);
+ if(true == doxm->owned)
{
- jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OWNER_NAME);
VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR)
- outLen = 0;
+ }
+ if(jsonObj)
+ {
+ VERIFY_SUCCESS(TAG, (cJSON_String == jsonObj->type), ERROR);
+ outLen = 0;
b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(doxm->owner.id)), ERROR);
+ VERIFY_SUCCESS(TAG, ((b64Ret == B64_OK) && (outLen <= sizeof(doxm->owner.id))), ERROR);
memcpy(doxm->owner.id, base64Buff, outLen);
}
return ehRet;
}
+#ifdef __WITH_DTLS__
+/*
+ * Generating new credential for provisioning tool
+ *
+ * PSK generated by
+ */
+static OCEntityHandlerResult AddOwnerPSK(const CAEndpoint_t* endpoint,
+ OicSecDoxm_t* ptDoxm,
+ const uint8_t* label, const size_t labelLen)
+{
+ size_t ownLen = 1;
+ uint32_t outLen = 0;
+ OicSecCred_t *cred = NULL;
+ uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {};
+
+ CAResult_t pskRet = CAGenerateOwnerPSK(endpoint,
+ label, labelLen,
+ ptDoxm->owner.id, sizeof(ptDoxm->owner.id),
+ gDoxm->deviceID.id, sizeof(gDoxm->deviceID.id),
+ ownerPSK, OWNER_PSK_LENGTH_128);
+
+ VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
+
+ char base64Buff[B64ENCODE_OUT_SAFESIZE(OWNER_PSK_LENGTH_128) + 1] = {};
+ B64Result b64Ret = b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, base64Buff,
+ sizeof(base64Buff), &outLen);
+ VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+
+ OC_LOG (INFO, TAG, PCF("Doxm EntityHandle generating Credential"));
+ cred = GenerateCredential(&ptDoxm->owner, SYMMETRIC_PAIR_WISE_KEY,
+ NULL, base64Buff, ownLen, &ptDoxm->owner);
+ VERIFY_NON_NULL(TAG, cred, ERROR);
+
+ //Adding provisioning tool credential to cred Resource.
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == AddCredential(cred), ERROR);
+
+ gDoxm->owned = true;
+ memcpy(&(gDoxm->owner), &(ptDoxm->owner), sizeof(OicUuid_t));
+
+ return OC_EH_OK;
+
+exit:
+ return OC_EH_ERROR;
+}
+#endif //__WITH_DTLS__
static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest * ehRequest)
{
*
*/
#ifdef __WITH_DTLS__
- CAResult_t pskRet;
-
OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
- uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {};
//Generating OwnerPSK
OC_LOG (INFO, TAG, PCF("Doxm EntityHandle generating OwnerPSK"));
- pskRet = CAGenerateOwnerPSK((CAEndpoint_t *)&request->devAddr,
- (uint8_t*) OXM_JUST_WORKS, strlen(OXM_JUST_WORKS),
- newDoxm->owner.id, sizeof(newDoxm->owner.id),
- gDoxm->deviceID.id, sizeof(gDoxm->deviceID.id),
- ownerPSK, OWNER_PSK_LENGTH_128);
-
- VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
-
- //Generating new credential for provisioning tool
- size_t ownLen = 1;
- uint32_t outLen = 0;
- char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(ownerPSK)) + 1] = {};
- B64Result b64Ret = b64Encode(ownerPSK, sizeof(ownerPSK), base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+ //Generate new credential for provisioning tool
+ ehRet = AddOwnerPSK((CAEndpoint_t *)&request->devAddr, newDoxm,
+ (uint8_t*) OXM_JUST_WORKS, strlen(OXM_JUST_WORKS));
- OC_LOG (INFO, TAG, PCF("Doxm EntityHandle generating Credential"));
- OicSecCred_t *cred = GenerateCredential(&newDoxm->owner, SYMMETRIC_PAIR_WISE_KEY,
- NULL, base64Buff, ownLen, &newDoxm->owner);
- VERIFY_NON_NULL(TAG, cred, ERROR);
-
- //Adding provisioning tool credential to cred Resource.
- VERIFY_SUCCESS(TAG, OC_STACK_OK == AddCredential(cred), ERROR);
-
- gDoxm->owned = true;
- memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t));
+ VERIFY_SUCCESS(TAG, ehRet = OC_EH_OK, ERROR);
// Update new state in persistent storage
if (true == UpdatePersistentStorage(gDoxm))
#endif //__WITH_DTLS__
}
}
+ else if(OIC_RANDOM_DEVICE_PIN == newDoxm->oxmSel)
+ {
+ //this temp Credential ID is used to track temporal Cred Id
+ static OicUuid_t tmpCredId = {.id={0}};
+ static bool tmpCredGenFlag = false;
+
+ if ((false == gDoxm->owned) && (false == newDoxm->owned))
+ {
+#ifdef __WITH_DTLS__
+ CAEnableAnonECDHCipherSuite(false);
+ OC_LOG(DEBUG, TAG, "ECDH_ANON CipherSuite is DISABLED");
+ CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256);
+
+ char ranPin[OXM_RANDOM_PIN_SIZE + 1] = {0,};
+ if(OC_STACK_OK == GeneratePin(ranPin, OXM_RANDOM_PIN_SIZE + 1))
+ {
+ if(tmpCredGenFlag)
+ {
+ OC_LOG(DEBUG, TAG, "Corrupted PSK is detected!!!");
+ VERIFY_SUCCESS(TAG,
+ OC_STACK_RESOURCE_DELETED == RemoveCredential(&tmpCredId),
+ ERROR);
+ }
+
+ OCStackResult res = AddTmpPskWithPIN( &(newDoxm->owner), SYMMETRIC_PAIR_WISE_KEY,
+ ranPin, OXM_RANDOM_PIN_SIZE, 1, &(newDoxm->owner), &tmpCredId);
+ VERIFY_SUCCESS(TAG, res == OC_STACK_OK, ERROR);
+ tmpCredGenFlag = true;
+ ehRet = OC_EH_OK;
+ }
+ else
+ {
+ OC_LOG(ERROR, TAG, "Failed to generate random PIN");
+ ehRet = OC_EH_ERROR;
+ }
+
+#endif //__WITH_DTLS__
+ }
+
+ /*
+ * When current state of the device is un-owned and Provisioning
+ * Tool is attempting to change the state to 'Owned' with a
+ * qualified value for the field 'Owner'
+ */
+ if ((false == gDoxm->owned) && (true == newDoxm->owned) &&
+ (memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0))
+ {
+#ifdef __WITH_DTLS__
+ OCServerRequest * request = (OCServerRequest *)ehRequest->requestHandle;
+
+ //Remove Temporal Credential resource
+ if(tmpCredGenFlag)
+ {
+ VERIFY_SUCCESS(TAG,
+ OC_STACK_RESOURCE_DELETED == RemoveCredential(&tmpCredId),
+ ERROR);
+ tmpCredGenFlag = false;
+ }
+
+ //Generate new credential for provisioning tool
+ ehRet = AddOwnerPSK((CAEndpoint_t*)(&request->devAddr), newDoxm,
+ (uint8_t*)OXM_RANDOM_DEVICE_PIN, strlen(OXM_RANDOM_DEVICE_PIN));
+ VERIFY_SUCCESS(TAG, OC_EH_OK == ehRet, ERROR);
+
+ //Update new state in persistent storage
+ ehRet = (UpdatePersistentStorage(gDoxm) == true) ? OC_EH_OK : OC_EH_ERROR;
+#endif
+ }
+ }
}
exit:
--- /dev/null
+/* *****************************************************************
+ *
+ * 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.
+ *
+ * *****************************************************************/
+#include "ocstack.h"
+#include "ocrandom.h"
+#include "logger.h"
+#include "pinoxmcommon.h"
+
+#define TAG PCF("PIN_OXM_COMMON")
+
+static GeneratePinCallback gGenPinCallback = NULL;
+static InputPinCallback gInputPinCallback = NULL;
+
+void SetInputPinCB(InputPinCallback pinCB)
+{
+ if(NULL == pinCB)
+ {
+ OC_LOG(ERROR, TAG, "Failed to set callback for input pin.");
+ return;
+ }
+
+ gInputPinCallback = pinCB;
+}
+
+void SetGeneratePinCB(GeneratePinCallback pinCB)
+{
+ if(NULL == pinCB)
+ {
+ OC_LOG(ERROR, TAG, "Failed to set callback for generate pin.");
+ return;
+ }
+
+ gGenPinCallback = pinCB;
+}
+
+OCStackResult GeneratePin(char* pinBuffer, size_t bufferSize)
+{
+ if(!pinBuffer)
+ {
+ OC_LOG(ERROR, TAG, "PIN buffer is NULL");
+ return OC_STACK_INVALID_PARAM;
+ }
+ if(OXM_RANDOM_PIN_SIZE + 1 > bufferSize)
+ {
+ OC_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++)
+ {
+ pinBuffer[i] = OCGetRandomRange((uint32_t)'0', (uint32_t)'9');
+ }
+ pinBuffer[OXM_RANDOM_PIN_SIZE] = '\0';
+
+ if(gGenPinCallback)
+ {
+ gGenPinCallback(pinBuffer, OXM_RANDOM_PIN_SIZE);
+ }
+ else
+ {
+ OC_LOG(ERROR, TAG, "Invoke PIN callback failed!");
+ OC_LOG(ERROR, TAG, "Callback for genrate PIN should be registered to use PIN based OxM.");
+ return OC_STACK_ERROR;
+ }
+
+ return OC_STACK_OK;
+}
+
+
+OCStackResult InputPin(char* pinBuffer, size_t bufferSize)
+{
+ if(!pinBuffer)
+ {
+ OC_LOG(ERROR, TAG, "PIN buffer is NULL");
+ return OC_STACK_INVALID_PARAM;
+ }
+ if(OXM_RANDOM_PIN_SIZE + 1 > bufferSize)
+ {
+ OC_LOG(ERROR, TAG, "PIN buffer size is too small");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ if(gInputPinCallback)
+ {
+ gInputPinCallback(pinBuffer, OXM_RANDOM_PIN_SIZE + 1);
+ }
+ else
+ {
+ OC_LOG(ERROR, TAG, "Invoke PIN callback failed!");
+ OC_LOG(ERROR, TAG, "Callback for input PIN should be registered to use PIN based OxM.");
+ return OC_STACK_ERROR;
+ }
+
+ return OC_STACK_OK;
+}
--- /dev/null
+/* *****************************************************************
+ *
+ * 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.
+ *
+ * *****************************************************************/
+#include <string.h>
+#include <math.h>
+#include "pbkdf2.h"
+#include "hmac.h"
+#include "debug.h"
+#include "logger.h"
+
+#define TAG "PBDKF2"
+#define XOR_BUF(in, out, bufSize)\
+do{\
+ size_t i=0;\
+ for(i=0; i< (bufSize); i++)\
+ {\
+ (out)[i] = (in)[i] ^ (out)[i];\
+ }\
+}while(0)\
+
+
+static int isLittle()
+{
+ static int a = 1;
+ static int flag = -1;
+ if (flag == -1)
+ {
+ if ( ((uint8_t *)&a)[0] == 0x1) // little
+ flag = 1;
+ else
+ flag = 0;
+ }
+ return flag;
+}
+
+static void GetBigEndianBuf(uint8_t *buf, int num)
+{
+ uint8_t *nBuf = (uint8_t *)#
+ if ( isLittle() == 1 )
+ {
+ int i = 0;
+ for (i = 0; i < sizeof(int); i++)
+ {
+ buf[i] = nBuf[ sizeof(int) - i - 1];
+ }
+ }
+ else
+ {
+ memcpy(buf, nBuf, sizeof(int));
+ }
+}
+
+// TODO: Add comments to explain implementation.
+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)
+{
+ int res = 0;
+ uint8_t buf[DTLS_HMAC_DIGEST_SIZE];
+ uint8_t uBuf[DTLS_HMAC_DIGEST_SIZE];
+
+ size_t nBlocks = 0;
+ size_t nOctetInLastBlock = 0;
+
+ nBlocks = (size_t)ceil ((double)keyLen / (double)DTLS_HMAC_DIGEST_SIZE);
+ nOctetInLastBlock = keyLen - (nBlocks - 1) * DTLS_HMAC_DIGEST_SIZE;
+
+ dtls_hmac_context_t *ctx = NULL;
+ ctx = dtls_hmac_new( (const unsigned char *)passwd, pLen);
+ if (NULL == ctx)
+ {
+ OC_LOG(ERROR, TAG, "DTLS HMAC Context is NULL");
+ goto bail;
+ }
+
+ size_t i = 1;
+ size_t idx = 0; //index for buffer
+ size_t counter = 0;
+ while (i != nBlocks + 1)
+ {
+ counter = 0 ;
+ dtls_hmac_init(ctx, (const unsigned char *)passwd, pLen);
+ while (counter != iterations)
+ {
+ if (counter == 0)
+ {
+ uint8_t intBuf[4] = {0x00, 0x00, 0x00, 0x00};
+ dtls_hmac_update(ctx, salt, saltLen);
+ GetBigEndianBuf(intBuf, i);
+ dtls_hmac_update(ctx, intBuf, 4);
+
+ int len = dtls_hmac_finalize(ctx, buf);
+ if (DTLS_HMAC_DIGEST_SIZE != len)
+ {
+ OC_LOG(ERROR, TAG, "DTLS HMAC is failed");
+ res = -1;
+ }
+ memcpy(uBuf, buf, DTLS_HMAC_DIGEST_SIZE);
+ }
+ else
+ {
+ dtls_hmac_init(ctx, (const unsigned char *)passwd, pLen);
+ dtls_hmac_update(ctx, buf, DTLS_HMAC_DIGEST_SIZE);
+ int len = dtls_hmac_finalize(ctx, buf);
+ if (DTLS_HMAC_DIGEST_SIZE != len)
+ {
+ OC_LOG(ERROR, TAG, "DTLS HMAC is failed");
+ res = -1;
+ }
+ XOR_BUF(buf, uBuf, DTLS_HMAC_DIGEST_SIZE);
+ }
+ counter++;
+ }
+
+
+ if (i == nBlocks)
+ {
+ memcpy(derivedKey + idx, uBuf, nOctetInLastBlock);
+ }
+ else
+ {
+ memcpy(derivedKey + idx, uBuf, DTLS_HMAC_DIGEST_SIZE);
+ idx += DTLS_HMAC_DIGEST_SIZE;
+ }
+ i++;
+ }
+
+bail:
+ dtls_hmac_free(ctx);
+ return res;
+}
+