CreateJustWorksOwnerTransferPayload
CreateJustWorksSelectOxmPayload
+CreateMVJustWorksSelectOxmPayload
+CreateConMCertificateBasedSelectOxmPayload
CreatePinBasedSelectOxmPayload
CreatePinBasedOwnerTransferPayload
CreateSecureSessionJustWorksCallback
SetGeneratePinCB
SetInputPinCB
SetRandomPinPolicy
+SetDisplayNumCB
+UnsetDisplayNumCB
+SetUserConfirmCB
+UnsetUserConfirmCB
+SetVerifyOption
+VerifyOwnershipTransfer
registerTimer
unregisterTimer
if libocsrm_env.get('SECURED') == '1':
libocsrm_src = libocsrm_src + [OCSRM_SRC + 'oxmpincommon.c', OCSRM_SRC + 'pbkdf2.c']
- libocsrm_src = libocsrm_src + [OCSRM_SRC + 'crlresource.c', OCSRM_SRC + 'pkix_interface.c']
+ libocsrm_src = libocsrm_src + [OCSRM_SRC + 'crlresource.c', OCSRM_SRC + 'pkix_interface.c']
+ libocsrm_src = libocsrm_src + [OCSRM_SRC + 'oxmverifycommon.c']
if target_os in ['windows', 'msys_nt']:
libocsrm_src = libocsrm_src + [OCSRM_SRC + 'strptime.c']
#ifdef MULTIPLE_OWNER
extern const char * OXM_PRECONF_PIN;
#endif //MULTIPLE_OWNER
+extern const char * OXM_MV_JUST_WORKS;
+extern const char * OXM_CON_MFG_CERT;
+
+//Mutual Verified Just-Works Message Prefix
+extern const char * MUTUAL_VERIF_NUM;
extern const char * OIC_SEC_ENCODING_BASE64;
extern const char * OIC_SEC_ENCODING_RAW;
--- /dev/null
+//******************************************************************
+//
+// Copyright 2016 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_VERIFY_COMMON_
+#define _OXM_VERIFY_COMMON_
+
+#include "securevirtualresourcetypes.h"
+#include "casecurityinterface.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif // __cplusplus
+
+/** Verification Number Length */
+#define MUTUAL_VERIF_NUM_LEN (3)
+
+/** Label Length */
+#define LABEL_LEN (30)
+
+/* Verification Method Option definition
+ * This type supports multiple bit set.
+ */
+ typedef enum VerifyOptionBitmask
+{
+ NOT_APPLICABLE = 0x0,
+ DISPLAY_NUM = (0x1 << 0),
+ USER_CONFIRM = (0x1 << 1)
+} VerifyOptionBitmask_t;
+
+/**
+ * Function pointer to display verification PIN
+ */
+typedef OCStackResult (*DisplayNumCallback)(void * ctx, uint8_t verifNum[MUTUAL_VERIF_NUM_LEN]);
+
+/*
+ * Function pointer to get user confirmation
+ */
+typedef OCStackResult (*UserConfirmCallback)(void * ctx);
+
+/**
+ * Context for displaying verification PIN
+ */
+typedef struct DisplayNumContext
+{
+ DisplayNumCallback callback;
+ void * context;
+} DisplayNumContext_t;
+
+/**
+ * Context for getting user confirmation
+ */
+typedef struct UserConfirmContext
+{
+ UserConfirmCallback callback;
+ void * context;
+} UserConfirmContext_t;
+
+/*
+ * Set Callback for displaying verification PIN
+ */
+void SetDisplayNumCB(void * ptr, DisplayNumCallback displayNumCB);
+
+/*
+ * Unset Callback for displaying verification PIN
+ */
+void UnsetDisplayNumCB();
+
+/*
+ * Set Callback for getting user confirmation
+ */
+void SetUserConfirmCB(void * ptr, UserConfirmCallback userConfirmCB);
+
+/*
+ * Unset Callback for getting user confirmation
+ */
+void UnsetUserConfirmCB();
+
+/*
+ * Set verification method option.
+ * The default is both display PIN and get user confirmation.
+ */
+void SetVerifyOption(VerifyOptionBitmask_t verifyOption);
+
+/*
+ * Call the Callback for Verifying Ownership Transfer process.
+ */
+OCStackResult VerifyOwnershipTransfer(uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN],
+ VerifyOptionBitmask_t verifyOption);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
#ifdef MULTIPLE_OWNER
OIC_PRECONFIG_PIN = 0xFF00,
#endif //MULTIPLE_OWNER
+ OIC_MV_JUST_WORKS = 0xFF01,
+ OIC_CON_MFG_CERT = 0xFF02,
}OicSecOxm_t;
typedef enum
typedef struct OTMCallbackData OTMCallbackData_t;\r
typedef struct OTMContext OTMContext_t;\r
\r
+\r
+typedef enum OxmAllowTableIdx {\r
+ OXM_IDX_JUST_WORKS = 0,\r
+ OXM_IDX_MV_JUST_WORKS,\r
+#ifdef MULTIPLE_OWNER\r
+ OXM_IDX_PRECONFIG_PIN,\r
+#endif\r
+ OXM_IDX_RANDOM_DEVICE_PIN,\r
+ OXM_IDX_MANUFACTURER_CERTIFICATE,\r
+ OXM_IDX_CON_MFG_CERT,\r
+ OXM_IDX_DECENTRALIZED_PUBLIC_KEY,\r
+ OXM_IDX_COUNT,\r
+ OXM_IDX_UNKNOWN\r
+}OxmAllowTableIdx_t;\r
+\r
/**\r
* Do ownership transfer for the unowned devices.\r
*\r
*/
OCStackResult CreateJustWorksOwnerTransferPayload(OTMContext_t *otmCtx, uint8_t **cborPayload,
size_t *cborSize);
+
+/**
+ * Generate payload for select OxM request for Mutual Verified Just-Works.
+ *
+ * @param otmCtx Context of OTM, It includes current device information.
+ * @param cborPayload is the DOXM CBOR payload including the selected OxM.
+ * @note Returned memory should be deallocated by caller.
+ * @param cborSize is the size of the cborPayload.
+ *
+ * @return ::OC_STACK_SUCCESS in case of success and other value otherwise.
+ */
+OCStackResult CreateMVJustWorksSelectOxmPayload(OTMContext_t *otmCtx, uint8_t **cborPayload,
+ size_t *cborSize);
+
#ifdef __cplusplus
}
#endif
size_t *cborSize);
/**
+ * Generate payload for select OxM request for confirmed manufactrer certificate method.
+ *
+ * @param otmCtx Context of OTM, It includes current device information.
+ * @param cborPayload is the DOXM CBOR payload including the selected OxM.
+ * @note Returned memory should be deallocated by caller.
+ * @param cborSize is the size of the cborPayload.
+ *
+ * @return ::OC_STACK_SUCCESS in case of success and other value otherwise.
+ */
+OCStackResult CreateConMCertificateBasedSelectOxmPayload(OTMContext_t *otmCtx, uint8_t **cborPayload,
+ size_t *cborSize);
+
+/**
* Generate payload for owner transfer request.
*
* @param otmCtx Context of OTM, It includes current device information.
sampleserver_justworks = provisioning_env.Program('sampleserver_justworks', 'sampleserver_justworks.cpp')
sampleserver_randompin = provisioning_env.Program('sampleserver_randompin', 'sampleserver_randompin.cpp')
sampleserver_mfg = provisioning_env.Program('sampleserver_mfg', 'sampleserver_mfg.cpp')
+sampleserver_mvjustworks = provisioning_env.Program('sampleserver_mvjustworks', 'sampleserver_mvjustworks.cpp')
if provisioning_env.get('MULTIPLE_OWNER') == '1':
subownerclient = provisioning_env.Program('subownerclient', 'subownerclient.c')
sec_provisioning_src_dir+ 'oic_svr_db_server_mfg.dat')
randompin_with_emptyuuid_dat = provisioning_env.Install(sec_provisioning_build_dir,
sec_provisioning_src_dir+ 'oic_svr_db_randompin_with_empty_deviceid.dat')
+mvjustworksdat = provisioning_env.Install(sec_provisioning_build_dir,
+ sec_provisioning_src_dir + 'oic_svr_db_server_mvjustworks.dat')
if provisioning_env.get('MULTIPLE_OWNER') == '1':
subownerclientdat = provisioning_env.Install(sec_provisioning_build_dir,
Alias("samples", [
provisioningclient, subownerclient,
sampleserver_justworks, sampleserver_randompin, sampleserver_mfg,
- clientdat, subownerclientdat,
- justworksdat, randompindat, mfgdat, randompin_with_emptyuuid_dat
+ sampleserver_preconfpin,
+ clientdat, subownerclientdat, preconfserverdat,
+ justworksdat, randompindat, mfgdat, randompin_with_emptyuuid_dat,
+ mvjustworksdat
])
else:
Alias("samples", [
provisioningclient,
sampleserver_justworks, sampleserver_randompin, sampleserver_mfg,
clientdat,
- justworksdat, randompindat, mfgdat, randompin_with_emptyuuid_dat
+ justworksdat, randompindat, mfgdat, randompin_with_emptyuuid_dat,
+ mvjustworksdat
])
provisioning_env.AppendTarget('samples')
--- /dev/null
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": ["oic.wk.res"],\r
+ "if": ["oic.if.ll"]\r
+ },{\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": ["oic.wk.d"],\r
+ "if": ["oic.if.baseline", "oic.if.r"]\r
+ },{\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": ["oic.wk.p"],\r
+ "if": ["oic.if.baseline", "oic.if.r"]\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": ["oic.r.doxm"],\r
+ "if": ["oic.if.baseline"]\r
+ },\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": ["oic.r.pstat"],\r
+ "if": ["oic.if.baseline"]\r
+ },\r
+ {\r
+ "href": "/oic/sec/acl",\r
+ "rel": "",\r
+ "rt": ["oic.r.acl"],\r
+ "if": ["oic.if.baseline"]\r
+ },\r
+ {\r
+ "href": "/oic/sec/cred",\r
+ "rel": "",\r
+ "rt": ["oic.r.cred"],\r
+ "if": ["oic.if.baseline"]\r
+ }\r
+ ],\r
+ "permission": 6\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "6D766A75-7374-776F-726B-735575696430"\r
+ },\r
+ "pstat": {\r
+ "isop": false,\r
+ "deviceuuid": "6D766A75-7374-776F-726B-735575696430",\r
+ "rowneruuid": "6D766A75-7374-776F-726B-735575696430",\r
+ "cm": 2,\r
+ "tm": 0,\r
+ "om": 4,\r
+ "sm": 4\r
+ },\r
+ "doxm": {\r
+ "oxms": [0, 65281],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": false,\r
+ "deviceuuid": "6D766A75-7374-776F-726B-735575696430",\r
+ "devowneruuid": "",\r
+ "rowneruuid": "6D766A75-7374-776F-726B-735575696430"\r
+ }\r
+}\r
#include "securevirtualresourcetypes.h"
#include "srmutility.h"
#include "pmtypes.h"
+#include "oxmverifycommon.h"
#ifdef __cplusplus
extern "C"
#define _72_MOT_OXM_SEL_ 72
#endif //MULTIPLE_OWNER
#define _80_SELECT_PROTOCOL_ 80
+#define _81_SELECT_VERIF_METHOD_ 81
#define _99_EXIT_PRVN_CLT_ 99
#define ACL_RESRC_MAX_NUM 16
return 0;
}
+OCStackResult displayNumCB(void * ctx, uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN])
+{
+ OIC_LOG(INFO, TAG, "IN displayMutualVerifNumCB");
+ if (NULL != mutualVerifNum)
+ {
+ OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
+ OIC_LOG_BUFFER(INFO, TAG, mutualVerifNum, MUTUAL_VERIF_NUM_LEN);
+ OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
+ OIC_LOG(INFO, TAG, "OUT displayMutualVerifNumCB");
+ }
+ else
+ {
+ OIC_LOG(INFO, TAG, "############ Confirm on the Server side ############");
+ }
+ return OC_STACK_OK;
+}
+
+OCStackResult confirmNumCB(void * ctx)
+{
+ for (;;)
+ {
+ int userConfirm;
+
+ printf(" > Press 1 if the mutual verification numbers are the same\n");
+ printf(" > Press 0 if the mutual verification numbers are not the same\n");
+
+ for (int ret=0; 1!=ret; )
+ {
+ ret = scanf("%d", &userConfirm);
+ for (; 0x20<=getchar(); ); // for removing overflow garbage
+ // '0x20<=code' is character region
+ }
+ if (1 == userConfirm)
+ {
+ break;
+ }
+ else if (0 == userConfirm)
+ {
+ return OC_STACK_USER_DENIED_REQ;
+ }
+ printf(" Entered Wrong Number. Please Enter Again\n");
+ }
+ return OC_STACK_OK;
+}
+
#ifdef MULTIPLE_OWNER
static int changeMultipleOwnershipTrnasferMode(void)
{
}
#endif
+static void selectVerifMethod()
+{
+ int option;
+ printf(" Select verification method for ownership transfer\n");
+ printf(" 0 - No verification\n");
+ printf(" 1 - Display only\n");
+ printf(" 2 - Confirm only\n");
+ printf(" 3 - Both Display and Confirm\n");
+
+ for(int ret=0; 1!=ret; )
+ {
+ ret = scanf("%d",&option);
+ for( ; 0x20<=getchar(); ); // for removing overflow garbages
+ // '0x20<=code' is character region
+ }
+
+ if(0 > option || 3 < option)
+ {
+ printf("Invalid option!");
+ }
+ SetVerifyOption((VerifyOptionBitmask_t) option);
+ printf("Option %d chosen!", option);
+}
+
static void printMenu(void)
{
printf("************************************************************\n");
#endif //MULTIPLE_OWNER
#ifdef __WITH_TLS__
- printf("** [H] SELECT SECURE PROTOCOL DTLS/TLS\n");
- printf("** 80. Select secure protocol(default DTLS)\n\n");
-
- printf("** [I] EXIT PROVISIONING CLIENT\n");
+ printf("** [H] SELECT SECURE PROTOCOL DTLS/TLS AND OTHERS\n");
+ printf("** 80. Select secure protocol(default DTLS)\n");
+ printf("** 81. Select verification method\n\n");
#else
- printf("** [H] EXIT PROVISIONING CLIENT\n");
+ printf("** [H] SELECT VERIFICATION OPTION\n");
+ printf("** 81. Select verification method\n\n");
#endif
+ printf("** [I] EXIT PROVISIONING CLIENT\n");
printf("** 99. Exit Provisionong Client\n\n");
OIC_LOG(WARNING, TAG, "Failed to disable OIC_DECENTRALIZED_PUBLIC_KEY OxM");
}
+ // set callbacks for verification options
+ SetDisplayNumCB(NULL, displayNumCB);
+ SetUserConfirmCB(NULL, confirmNumCB);
+
#ifdef MULTIPLE_OWNER
SetPreconfigPin("12341234", 8);
#endif //MULTIPLE_OWNER
selectSecureProtocol();
break;
#endif
+ case _81_SELECT_VERIF_METHOD_:
+ selectVerifMethod();
+ break;
case _99_EXIT_PRVN_CLT_:
goto PMCLT_ERROR;
default:
--- /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 "iotivity_config.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+#include <signal.h>
+#include "ocstack.h"
+#include "ocpayload.h"
+#include "pinoxmcommon.h"
+#include "oxmverifycommon.h"
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+/** @todo stop-gap for naming issue. Windows.h does not like us to use ERROR */
+#ifdef ERROR
+#undef ERROR
+#endif //ERROR
+#endif //HAVE_WINDOWS_H
+#include "platform_features.h"
+#include "logger.h"
+
+
+#define TAG "SAMPLE_MV_JUSTWORKS"
+
+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_mvjustworks.dat";
+
+/* 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)
+ {
+ OIC_LOG(ERROR, TAG, "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)
+ {
+ OIC_LOG(ERROR, TAG, "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))
+ {
+ OIC_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
+ {
+ OIC_LOG_V (INFO, TAG, "Payload was NULL");
+ ehResult = OC_EH_ERROR;
+ }
+
+ return ehResult;
+}
+
+OCEntityHandlerResult
+OCEntityHandlerCb (OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest *entityHandlerRequest,
+ void* callbackParam)
+{
+ OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
+ (void)callbackParam;
+ OCEntityHandlerResult ehResult = OC_EH_ERROR;
+
+ OCEntityHandlerResponse response;
+ memset(&response, 0, sizeof(response));
+
+ // Validate pointer
+ if (!entityHandlerRequest)
+ {
+ OIC_LOG (ERROR, TAG, "Invalid request pointer");
+ return OC_EH_ERROR;
+ }
+
+ OCRepPayload* payload = NULL;
+
+ if (flag & OC_REQUEST_FLAG)
+ {
+ OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
+ if (entityHandlerRequest)
+ {
+ if (OC_REST_GET == entityHandlerRequest->method)
+ {
+ OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
+ ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
+ }
+ else if (OC_REST_PUT == entityHandlerRequest->method)
+ {
+ OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
+ ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
+ }
+ else if (OC_REST_POST == entityHandlerRequest->method)
+ {
+ OIC_LOG (INFO, TAG, "Received OC_REST_POST from client");
+ ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
+ }
+ else
+ {
+ OIC_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)
+ {
+ OIC_LOG(ERROR, TAG, "Error sending response");
+ ehResult = OC_EH_ERROR;
+ }
+ }
+ }
+ }
+
+ OCPayloadDestroy(response.payload);
+ return ehResult;
+}
+
+OCStackResult displayNumCB(void * ctx, uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN])
+{
+ OIC_LOG(INFO, TAG, "IN displayNumCB");
+ OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
+ OIC_LOG_BUFFER(INFO, TAG, mutualVerifNum, MUTUAL_VERIF_NUM_LEN);
+ OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
+ OIC_LOG(INFO, TAG, "OUT displayNumCB");
+ return OC_STACK_OK;
+}
+
+OCStackResult confirmNumCB(void * ctx)
+{
+ for (;;)
+ {
+ int userConfirm;
+
+ printf(" > Press 1 for confirmation\n");
+ printf(" > Press 0 otherwise\n");
+
+ for (int ret=0; 1!=ret; )
+ {
+ ret = scanf("%d", &userConfirm);
+ for (; 0x20<=getchar(); ); // for removing overflow garbage
+ // '0x20<=code' is character region
+ }
+ if (1 == userConfirm)
+ {
+ break;
+ }
+ else if (0 == userConfirm)
+ {
+ return OC_STACK_ERROR;
+ }
+ printf(" Entered Wrong Number. Please Enter Again\n");
+ }
+ return OC_STACK_OK;
+}
+
+/* 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);
+}
+
+int main()
+{
+ struct timespec timeout;
+
+ OIC_LOG(DEBUG, TAG, "OCServer is starting...");
+
+ // Set callbacks for verification
+ SetDisplayNumCB(NULL, displayNumCB);
+ SetUserConfirmCB(NULL, confirmNumCB);
+
+ // Set Verification Option for ownership transfer
+ // Currently, BOTH display AND confirm
+ SetVerifyOption((VerifyOptionBitmask_t)(DISPLAY_NUM | USER_CONFIRM));
+
+ // Initialize Persistent Storage for SVR database
+ OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
+
+ OCRegisterPersistentStorageHandler(&ps);
+
+ if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
+ {
+ OIC_LOG(ERROR, TAG, "OCStack init error");
+ return 0;
+ }
+
+ /*
+ * 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
+ OIC_LOG(INFO, TAG, "Entering ocserver main loop...");
+ signal(SIGINT, handleSigInt);
+ while (!gQuitFlag)
+ {
+ if (OCProcess() != OC_STACK_OK)
+ {
+ OIC_LOG(ERROR, TAG, "OCStack process error");
+ return 0;
+ }
+ nanosleep(&timeout, NULL);
+ }
+
+ OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");
+
+ if (OCStop() != OC_STACK_OK)
+ {
+ OIC_LOG(ERROR, TAG, "OCStack process error");
+ }
+
+ return 0;
+}
+
+int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower)
+{
+ if (!uri)
+ {
+ OIC_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);
+ OIC_LOG_V(INFO, TAG, "Created LED resource with result: %s", getResult(res));
+
+ return 0;
+}
#include "ocpayload.h"
#include "payload_logging.h"
#include "pkix_interface.h"
+#include "oxmverifycommon.h"
#define TAG "OIC_OTM"
* List of allowed oxm list.
* All oxm methods are allowed as default.
*/
-static uint8_t g_OxmAllowStatus[OIC_OXM_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM, NOT_ALLOWED_OXM};
+#ifdef MULTIPLE_OWNER
+static uint8_t g_OxmAllowStatus[OXM_IDX_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
+ ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
+ NOT_ALLOWED_OXM};
+#else
+static uint8_t g_OxmAllowStatus[OXM_IDX_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
+ ALLOWED_OXM, ALLOWED_OXM, NOT_ALLOWED_OXM};
+#endif
/**
* Variables for pointing the OTMContext to be used in the DTLS handshake result callback.
OIC_LOG(INFO, TAG, "IN OTMSetOTCallback");
VERIFY_NON_NULL(TAG, callbacks, ERROR);
+
#ifdef MULTIPLE_OWNER
- VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_PRECONFIG_PIN == oxm), ERROR);
+ VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_PRECONFIG_PIN == oxm || OIC_MV_JUST_WORKS == oxm
+ || OIC_CON_MFG_CERT == oxm), ERROR);
#else
- VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm), ERROR);
-#endif //MULTIPLE_OWNER
+ VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_MV_JUST_WORKS == oxm || OIC_CON_MFG_CERT == oxm), ERROR);
+#endif // MULTIPLE_OWNER
switch(oxm)
{
callbacks->createOwnerTransferPayloadCB = CreatePreconfigPinBasedOwnerTransferPayload;
break;
#endif //MULTIPLE_OWNER
+ case OIC_MV_JUST_WORKS:
+ callbacks->loadSecretCB = LoadSecretJustWorksCallback;
+ callbacks->createSecureSessionCB = CreateSecureSessionJustWorksCallback;
+ callbacks->createSelectOxmPayloadCB = CreateMVJustWorksSelectOxmPayload;
+ callbacks->createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
+ break;
+ case OIC_CON_MFG_CERT:
+ callbacks->loadSecretCB = PrepareMCertificateCallback;
+ callbacks->createSecureSessionCB = CreateSecureSessionMCertificateCallback;
+ callbacks->createSelectOxmPayloadCB = CreateConMCertificateBasedSelectOxmPayload;
+ callbacks->createOwnerTransferPayloadCB = CreateMCertificateBasedOwnerTransferPayload;
+ break;
default:
OIC_LOG_V(ERROR, TAG, "Unknown OxM : %d", (int)oxm);
return OC_STACK_INVALID_PARAM;
}
/**
+ * Internal API to convert OxM value to index of oxm allow table.
+ */
+static OxmAllowTableIdx_t GetOxmAllowTableIdx(OicSecOxm_t oxm)
+{
+ switch(oxm)
+ {
+ case OIC_JUST_WORKS:
+ return OXM_IDX_JUST_WORKS;
+ case OIC_RANDOM_DEVICE_PIN:
+ return OXM_IDX_RANDOM_DEVICE_PIN;
+ case OIC_MANUFACTURER_CERTIFICATE:
+ return OXM_IDX_MANUFACTURER_CERTIFICATE;
+ case OIC_DECENTRALIZED_PUBLIC_KEY:
+ return OXM_IDX_DECENTRALIZED_PUBLIC_KEY;
+ case OIC_MV_JUST_WORKS:
+ return OXM_IDX_MV_JUST_WORKS;
+ case OIC_CON_MFG_CERT:
+ return OXM_IDX_CON_MFG_CERT;
+#ifdef MULTIPLE_OWNER
+ case OIC_PRECONFIG_PIN:
+ return OXM_IDX_PRECONFIG_PIN;
+#endif
+ default:
+ return OXM_IDX_UNKNOWN;
+ }
+}
+
+/**
* Function to select appropriate provisioning method.
*
* @param[in] supportedMethods Array of supported methods
size_t numberOfMethods, OicSecOxm_t *selectedMethod)
{
bool isOxmSelected = false;
+ OxmAllowTableIdx_t oxmIdx = OXM_IDX_UNKNOWN;
+ OxmAllowTableIdx_t selectedOxmIdx = OXM_IDX_UNKNOWN;
OIC_LOG(DEBUG, TAG, "IN SelectProvisioningMethod");
for(size_t i = 0; i < numberOfMethods; i++)
{
- if(ALLOWED_OXM == g_OxmAllowStatus[supportedMethods[i]])
+ selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]);
+ if(OXM_IDX_COUNT <= selectedOxmIdx)
+ {
+ OIC_LOG(ERROR, TAG, "Invalid oxm index to access OxM allow table");
+ return OC_STACK_ERROR;
+ }
+
+#ifdef MULTIPLE_OWNER
+ if(ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
+ OXM_IDX_PRECONFIG_PIN != selectedOxmIdx)
+#else
+ if(ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx])
+#endif //MULTIPLE_OWNER
{
*selectedMethod = supportedMethods[i];
isOxmSelected = true;
- break;
}
}
if(!isOxmSelected)
return OC_STACK_NOT_ALLOWED_OXM;
}
- for(size_t i = 0; i < numberOfMethods; i++)
- {
- if(*selectedMethod < supportedMethods[i] &&
- ALLOWED_OXM == g_OxmAllowStatus[supportedMethods[i]])
- {
- *selectedMethod = supportedMethods[i];
- }
- }
-
OIC_LOG(DEBUG, TAG, "OUT SelectProvisioningMethod");
return OC_STACK_OK;
}
+
/**
* Function to select operation mode.This function will return most secure common operation mode.
*
false == newDevDoxm->owned &&
memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) == 0)
{
+ //In case of Mutual Verified Just-Works, display mutualVerifNum
+ if (OIC_MV_JUST_WORKS == newDevDoxm->oxmSel)
+ {
+ uint8_t preMutualVerifNum[OWNER_PSK_LENGTH_128] = {0};
+ uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN] = {0};
+ OicUuid_t deviceID = {.id = {0}};
+
+ //Generate mutualVerifNum
+ char label[LABEL_LEN] = {0};
+ snprintf(label, LABEL_LEN, "%s%s", MUTUAL_VERIF_NUM, OXM_MV_JUST_WORKS);
+ if (OC_STACK_OK != GetDoxmDeviceID(&deviceID))
+ {
+ OIC_LOG(ERROR, TAG, "Error while retrieving Owner's device ID");
+ return;
+ }
+
+ CAResult_t pskRet = CAGenerateOwnerPSK(endpoint,
+ (uint8_t *)label,
+ strlen(label),
+ deviceID.id, sizeof(deviceID.id),
+ newDevDoxm->deviceID.id, sizeof(newDevDoxm->deviceID.id),
+ preMutualVerifNum, OWNER_PSK_LENGTH_128);
+ if (CA_STATUS_OK != pskRet)
+ {
+ OIC_LOG(WARNING, TAG, "Failed to remove the invaild owner credential");
+ return;
+ }
+
+ memcpy(mutualVerifNum, preMutualVerifNum + OWNER_PSK_LENGTH_128 - sizeof(mutualVerifNum),
+ sizeof(mutualVerifNum));
+ if (OC_STACK_OK != VerifyOwnershipTransfer(mutualVerifNum, DISPLAY_NUM))
+ {
+ OIC_LOG(ERROR, TAG, "Error while displaying mutualVerifNum");
+ return;
+ }
+ }
+ //In case of confirmed manufacturer cert, display message
+ else if (OIC_CON_MFG_CERT == newDevDoxm->oxmSel)
+ {
+ if (OC_STACK_OK != VerifyOwnershipTransfer(NULL, DISPLAY_NUM))
+ {
+ OIC_LOG(ERROR, TAG, "Error while displaying message");
+ return;
+ }
+ }
+
//Send request : POST /oic/sec/doxm [{... , "devowner":"PT's UUID"}]
res = PostOwnerUuid(otmCtx);
if(OC_STACK_OK != res)
{
if(otmCtx && otmCtx->selectedDeviceInfo)
{
+ //In case of Mutual Verified Just-Works, wait for user confirmation
+ if (OIC_MV_JUST_WORKS == otmCtx->selectedDeviceInfo->doxm->oxmSel)
+ {
+ res = VerifyOwnershipTransfer(NULL, USER_CONFIRM);
+ if (OC_STACK_OK != res)
+ {
+ SRPResetDevice(otmCtx->selectedDeviceInfo, otmCtx->ctxResultCallback);
+ }
+ }
+
res = SaveOwnerPSK(otmCtx->selectedDeviceInfo);
if(OC_STACK_OK != res)
{
OIC_LOG_V(INFO, TAG, "IN %s : oxm=%d, allow status=%s",
__func__, oxm, (allowStatus ? "true" : "false"));
- if(OIC_OXM_COUNT <= oxm)
+#ifdef MULTIPLE_OWNER
+ if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_PRECONFIG_PIN != oxm && OIC_CON_MFG_CERT != oxm)
+#else
+ if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_CON_MFG_CERT != oxm)
+#endif
{
return OC_STACK_INVALID_PARAM;
}
- g_OxmAllowStatus[oxm] = (allowStatus ? ALLOWED_OXM : NOT_ALLOWED_OXM);
+ OxmAllowTableIdx_t oxmIdx = GetOxmAllowTableIdx(oxm);
+ if(OXM_IDX_COUNT <= oxmIdx)
+ {
+ OIC_LOG(ERROR, TAG, "Invalid oxm index to access oxm allow table.");
+ return OC_STACK_ERROR;
+ }
+ g_OxmAllowStatus[oxmIdx] = (allowStatus ? ALLOWED_OXM : NOT_ALLOWED_OXM);
OIC_LOG_V(INFO, TAG, "OUT %s", __func__);
OIC_LOG(INFO, TAG, "OUT CreateSecureSessionJustWorksCallback");
return OC_STACK_OK;
}
+
+OCStackResult CreateMVJustWorksSelectOxmPayload(OTMContext_t *otmCtx, uint8_t **cborPayload,
+ size_t *cborSize)
+{
+ if (!otmCtx || !otmCtx->selectedDeviceInfo || !cborPayload || *cborPayload || !cborSize)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ otmCtx->selectedDeviceInfo->doxm->oxmSel = OIC_MV_JUST_WORKS;
+ *cborPayload = NULL;
+ *cborSize = 0;
+
+ return DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm, cborPayload, cborSize, true);
+}
+
return DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm, payload, size, true);
}
+OCStackResult CreateConMCertificateBasedSelectOxmPayload(OTMContext_t* otmCtx, uint8_t **payload, size_t *size)
+{
+ if (!otmCtx || !otmCtx->selectedDeviceInfo || !payload || *payload || !size)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ otmCtx->selectedDeviceInfo->doxm->oxmSel = OIC_CON_MFG_CERT;
+
+ return DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm, payload, size, true);
+}
+
OCStackResult CreateMCertificateBasedOwnerTransferPayload(OTMContext_t* otmCtx, uint8_t **payload, size_t *size)
{
if (!otmCtx || !otmCtx->selectedDeviceInfo || !payload || *payload || !size)
#include "credresource.h"
#include "srmutility.h"
#include "pinoxmcommon.h"
+#include "oxmverifycommon.h"
#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
#include "pkix_interface.h"
goto exit;
}
- if (OIC_JUST_WORKS == newDoxm->oxmSel)
+ if (OIC_JUST_WORKS == newDoxm->oxmSel || OIC_MV_JUST_WORKS == newDoxm->oxmSel)
{
/*
* If current state of the device is un-owned, enable
*/
if (memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) == 0)
{
+ gDoxm->oxmSel = newDoxm->oxmSel;
+ //Update new state in persistent storage
+ if ((UpdatePersistentStorage(gDoxm) == true))
+ {
+ ehRet = OC_EH_OK;
+ }
+ else
+ {
+ OIC_LOG(WARNING, TAG, "Failed to update DOXM in persistent storage");
+ ehRet = OC_EH_ERROR;
+ }
OIC_LOG (INFO, TAG, "Doxm EntityHandle enabling AnonECDHCipherSuite");
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
ehRet = (CAEnableAnonECDHCipherSuite(true) == CA_STATUS_OK) ? OC_EH_OK : OC_EH_ERROR;
VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
+ //In case of Mutual Verified Just-Works, verify mutualVerifNum
+ if (OIC_MV_JUST_WORKS == newDoxm->oxmSel && false == newDoxm->owned &&
+ previousMsgId != ehRequest->messageID)
+ {
+ uint8_t preMutualVerifNum[OWNER_PSK_LENGTH_128] = {0};
+ uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN] = {0};
+ OicUuid_t deviceID = {.id = {0}};
+
+ //Generate mutualVerifNum
+ OCServerRequest * request = GetServerRequestUsingHandle(ehRequest->requestHandle);
+
+ char label[LABEL_LEN] = {0};
+ snprintf(label, LABEL_LEN, "%s%s", MUTUAL_VERIF_NUM, OXM_MV_JUST_WORKS);
+ if (OC_STACK_OK != GetDoxmDeviceID(&deviceID))
+ {
+ OIC_LOG(ERROR, TAG, "Error while retrieving Owner's device ID");
+ ehRet = OC_EH_ERROR;
+ goto exit;
+
+ }
+
+ CAResult_t pskRet = CAGenerateOwnerPSK((CAEndpoint_t *)&request->devAddr,
+ (uint8_t *)label,
+ strlen(label),
+ gDoxm->owner.id, sizeof(gDoxm->owner.id),
+ gDoxm->deviceID.id, sizeof(gDoxm->deviceID.id),
+ preMutualVerifNum, OWNER_PSK_LENGTH_128);
+ if (CA_STATUS_OK != pskRet)
+ {
+ OIC_LOG(WARNING, TAG, "Failed to remove the invaild owner credential");
+ ehRet = OC_EH_ERROR;
+ goto exit;
+
+ }
+
+ memcpy(mutualVerifNum, preMutualVerifNum + OWNER_PSK_LENGTH_128 - sizeof(mutualVerifNum),
+ sizeof(mutualVerifNum));
+
+ //Wait for user confirmation
+ if (OC_STACK_OK != VerifyOwnershipTransfer(mutualVerifNum, DISPLAY_NUM | USER_CONFIRM))
+ {
+ ehRet = OC_EH_NOT_ACCEPTABLE;
+ }
+ else
+ {
+ ehRet = OC_EH_OK;
+ }
+ }
+
#endif // __WITH_DTLS__ or __WITH_TLS__
}
}
#endif // __WITH_DTLS__ or __WITH_TLS__
}
#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
- else if (OIC_MANUFACTURER_CERTIFICATE == newDoxm->oxmSel)
+ else if (OIC_MANUFACTURER_CERTIFICATE == newDoxm->oxmSel || OIC_CON_MFG_CERT == newDoxm->oxmSel)
{
- //Save the owner's UUID to derive owner credential
- memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t));
- gDoxm->oxmSel = newDoxm->oxmSel;
- //Update new state in persistent storage
- if (UpdatePersistentStorage(gDoxm))
+ if (memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) == 0)
{
- ehRet = OC_EH_OK;
+ //Save the owner's UUID to derive owner credential
+ memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t));
+ gDoxm->oxmSel = newDoxm->oxmSel;
+ //Update new state in persistent storage
+ if (UpdatePersistentStorage(gDoxm))
+ {
+ ehRet = OC_EH_OK;
+ }
+ else
+ {
+ OIC_LOG(WARNING, TAG, "Failed to update DOXM in persistent storage");
+ ehRet = OC_EH_ERROR;
+ }
+ CAResult_t caRes = CAEnableAnonECDHCipherSuite(false);
+ VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
+ OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
+
+ VERIFY_SUCCESS(TAG, CA_STATUS_OK == CAregisterPkixInfoHandler(GetManufacturerPkixInfo), ERROR);
+ VERIFY_SUCCESS(TAG, CA_STATUS_OK == CAregisterGetCredentialTypesHandler(InitManufacturerCipherSuiteList), ERROR);
}
else
{
- OIC_LOG(WARNING, TAG, "Failed to update DOXM in persistent storage");
- ehRet = OC_EH_ERROR;
+ //In case of Confirm Manufacturer Cert, get user confirmation
+ if (OIC_CON_MFG_CERT == newDoxm->oxmSel && false == newDoxm->owned &&
+ previousMsgId != ehRequest->messageID)
+ {
+ if (OC_STACK_OK != VerifyOwnershipTransfer(NULL, USER_CONFIRM))
+ {
+ ehRet = OC_EH_NOT_ACCEPTABLE;
+ }
+ else
+ {
+ ehRet = OC_EH_OK;
+ }
+ }
}
- CAResult_t caRes = CAEnableAnonECDHCipherSuite(false);
- VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
- OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
- VERIFY_SUCCESS(TAG, CA_STATUS_OK == CAregisterPkixInfoHandler(GetManufacturerPkixInfo), ERROR);
- VERIFY_SUCCESS(TAG, CA_STATUS_OK == CAregisterGetCredentialTypesHandler(InitManufacturerCipherSuiteList), ERROR);
}
#endif // __WITH_DTLS__ or __WITH_TLS__
}
--- /dev/null
+//******************************************************************
+//
+// Copyright 2016 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 "logger.h"
+#include "base64.h"
+#include "securevirtualresourcetypes.h"
+#include "srmresourcestrings.h"
+#include "cainterface.h"
+#include "oxmverifycommon.h"
+
+#define TAG "OIC_VERIFY_COMMON"
+
+static VerifyOptionBitmask_t gVerifyOption = (DISPLAY_NUM | USER_CONFIRM);
+
+static DisplayNumContext_t gDisplayNumContext = { .callback = NULL, .context = NULL };
+static UserConfirmContext_t gUserConfirmContext = { .callback = NULL, .context = NULL };
+
+void SetDisplayNumCB(void * ptr, DisplayNumCallback displayNumCB)
+{
+ if (NULL == displayNumCB)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to set callback for displaying mutualVerifNum");
+ return;
+ }
+ gDisplayNumContext.callback = displayNumCB;
+ gDisplayNumContext.context = ptr;
+}
+
+void UnsetDisplayNumCB()
+{
+ gDisplayNumContext.callback = NULL;
+}
+
+void SetUserConfirmCB(void * ptr, UserConfirmCallback userConfirmCB)
+{
+ if (NULL == userConfirmCB)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to set callback to confirm mutualVerifNum");
+ return;
+ }
+ gUserConfirmContext.callback = userConfirmCB;
+ gUserConfirmContext.context = ptr;
+}
+
+void UnsetUserConfirmCB()
+{
+ gUserConfirmContext.callback = NULL;
+}
+
+void SetVerifyOption(VerifyOptionBitmask_t verifyOption)
+{
+ gVerifyOption = verifyOption;
+}
+
+OCStackResult VerifyOwnershipTransfer(uint8_t mutualVerifNum [MUTUAL_VERIF_NUM_LEN],
+ VerifyOptionBitmask_t verifyOption)
+{
+ verifyOption = (VerifyOptionBitmask_t)(verifyOption & gVerifyOption);
+ if (verifyOption & DISPLAY_NUM)
+ {
+ if (!gDisplayNumContext.callback)
+ {
+ OIC_LOG(ERROR, TAG, "Callback for displaying verification PIN not registered");
+ return OC_STACK_ERROR;
+ }
+ if (OC_STACK_OK != gDisplayNumContext.callback(gDisplayNumContext.context, mutualVerifNum))
+ {
+ OIC_LOG(ERROR, TAG, "Failed to display verification PIN");
+ return OC_STACK_ERROR;
+ }
+ }
+ if (verifyOption & USER_CONFIRM)
+ {
+ if (!gUserConfirmContext.callback)
+ {
+ OIC_LOG(ERROR, TAG, "Callback to get user confirmation not registered");
+ return OC_STACK_ERROR;
+ }
+ if (OC_STACK_OK != gUserConfirmContext.callback(gUserConfirmContext.context))
+ {
+ OIC_LOG(ERROR, TAG, "Failed to get user confirmation");
+ return OC_STACK_USER_DENIED_REQ;
+ }
+ }
+ return OC_STACK_OK;
+}
const char * OXM_RANDOM_DEVICE_PIN = "oic.sec.doxm.rdp";
const char * OXM_MANUFACTURER_CERTIFICATE = "oic.sec.doxm.mfgcert";
#ifdef MULTIPLE_OWNER
-const char * OXM_PRECONF_PIN = "oic.sec..doxm.pcp";
+const char * OXM_PRECONF_PIN = "oic.sec.doxm.pcp";
#endif //MULTIPLE_OWNER
+const char * OXM_MV_JUST_WORKS = "oic.sec.doxm.mvjw";
+const char * OXM_CON_MFG_CERT = "oic.sec.doxm.conmfgcert";
+
+//Mutual Verified Just-Works Message Prefix
+const char * MUTUAL_VERIF_NUM = "mutualVerifNum";
//Credential data encoding methods
const char * OIC_SEC_ENCODING_BASE64 = "oic.sec.encoding.base64";
case OIC_PRECONFIG_PIN:
return OXM_PRECONF_PIN;
#endif //MULTIPLE_OWNER
+ case OIC_MV_JUST_WORKS:
+ return OXM_MV_JUST_WORKS;
+ case OIC_CON_MFG_CERT:
+ return OXM_CON_MFG_CERT;
default:
return NULL;
}
OC_STACK_PRESENCE_DO_NOT_HANDLE,
#endif
+ /** Request is denied by the user*/
+ OC_STACK_USER_DENIED_REQ,
+
/** ERROR code from server */
OC_STACK_FORBIDDEN_REQ, /** 403*/
OC_STACK_INTERNAL_SERVER_ERROR, /** 500*/
static const char INCONSISTENT_DB[] = "Data in provisioning DB is inconsistent";
static const char AUTHENTICATION_FAILURE[] = "Authentication failure";
static const char NOT_ALLOWED_OXM[] = "Not allowed ownership transfer method";
+ static const char USER_DENIED_REQ[] = "Request denied by User";
static const char PUBLISH_RESOURCE_FAILED[] = "Publish Resource failure";
static const char FORBIDDEN_REQ[] = "Forbidden request";
static const char INTERNAL_SERVER_ERROR[] = "Internal server error";
return OC::Exception::AUTHENTICATION_FAILURE;
case OC_STACK_NOT_ALLOWED_OXM:
return OC::Exception::NOT_ALLOWED_OXM;
+ case OC_STACK_USER_DENIED_REQ:
+ return OC::Exception::USER_DENIED_REQ;
case OC_STACK_FORBIDDEN_REQ:
return OC::Exception::FORBIDDEN_REQ;
case OC_STACK_INTERNAL_SERVER_ERROR:
OC_STACK_INCONSISTENT_DB,
OC_STACK_AUTHENTICATION_FAILURE,
OC_STACK_NOT_ALLOWED_OXM,
+ OC_STACK_USER_DENIED_REQ,
OC_STACK_FORBIDDEN_REQ,
OC_STACK_INTERNAL_SERVER_ERROR
};
OC::Exception::INCONSISTENT_DB,
OC::Exception::AUTHENTICATION_FAILURE,
OC::Exception::NOT_ALLOWED_OXM,
+ OC::Exception::USER_DENIED_REQ,
OC::Exception::FORBIDDEN_REQ,
OC::Exception::INTERNAL_SERVER_ERROR
};