extern const char * OXM_JUST_WORKS;
extern const char * OXM_RANDOM_DEVICE_PIN;
extern const char * OXM_MANUFACTURER_CERTIFICATE;
+extern const char * OXM_RAW_PUBLIC_KEY;
#ifdef MULTIPLE_OWNER
extern const char * OXM_PRECONF_PIN;
#endif //MULTIPLE_OWNER
typedef void (*InputPinCallback)(char* pinBuf, size_t bufSize);
/**
+ * Function pointer for getting peer's public key, own public and private keys and token
+ * for raw public key generation.
+ */
+typedef void (*GetRPKMasterKeyCallback)(char *rpkMasterKey, size_t *rpkMasterKeyLen);
+
+/**
* Function pointer to close the displied PIN.
*/
typedef void (*ClosePinDisplayCallback)(void);
void SetInputPinCB(InputPinCallback pinCB);
/**
+ * Function to setting RPK key callback from user.
+ *
+ * @param rpkCB implementation of RPK parameters callback.
+ */
+void SetGetRPKMasterKeyCB(GetRPKMasterKeyCallback rpkCB);
+
+/**
* Function to set the close PIN callback
* This callback will be invoked when PIN based OTM is finished.
*
#endif //MULTIPLE_OWNER
OIC_MV_JUST_WORKS = 0xFF01,
OIC_CON_MFG_CERT = 0xFF02,
+ OIC_RAW_PUB_KEY = 0xFF03,
}OicSecOxm_t;
typedef enum
'src/ocprovisioningmanager.c',
'src/oxmjustworks.c',
'src/oxmrandompin.c',
+ 'src/oxmrawpublickey.c',
'src/oxmmanufacturercert.c',
'src/provisioningdatabasemanager.c' ]
--- /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_RAW_PUBLIC_KEY_H_
+#define OXM_RAW_PUBLIC_KEY_H_
+
+#include "ocstack.h"
+#include "securevirtualresourcetypes.h"
+#include "ownershiptransfermanager.h"
+#include "pmtypes.h"
+#include "pinoxmcommon.h"
+
+#define OXM_RPK_MASTER_KEY_MAX_SIZE (32)
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+/**
+ * Callback implementation to generate RPK master key.
+ *
+ * @param otmCtx Context of OTM, It includes current device information.
+ *
+ * @return ::OC_STACK_SUCCESS in case of success and other value otherwise.
+ */
+OCStackResult GetMasterRPKCallback(OTMContext_t *otmCtx);
+
+/**
+ * Callback implemenration to establish a secure channel with PSK cipher suite.
+ *
+ * @param otmCtx Context of OTM, It includes current device information.
+ *
+ * @return ::OC_STACK_SUCCESS in case of success and other value otherwise.
+ */
+OCStackResult CreateSecureSessionRPKCallback(OTMContext_t *otmCtx);
+
+/**
+ * Generate payload for select OxM request.
+ *
+ * @param otmCtx Context of OTM, It includes current device information.
+ * @param cborPaylaod 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 CreateRPKBasedSelectOxmPayload(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.
+ * @param cborPaylaod is the DOXM CBOR payload including the owner information.
+ * @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 CreateRPKBasedOwnerTransferPayload(OTMContext_t *otmCtx, uint8_t **cborPayload,
+ size_t *cborSize);
+
+#ifdef __cplusplus
+}
+#endif
+#endif //OXM_RAW_PUBLIC_KEY_H_
#endif
OXM_IDX_RANDOM_DEVICE_PIN,
OXM_IDX_MANUFACTURER_CERTIFICATE,
+ OXM_IDX_RAW_PUBLIC_KEY,
OXM_IDX_CON_MFG_CERT,
OXM_IDX_DECENTRALIZED_PUBLIC_KEY,
OXM_IDX_COUNT,
}
}
+static void InputRPKMasterKeyCB(uint8_t *rpkMasterKey, int *rpkMasterKeyLen)
+{
+ if(!rpkMasterKey || !rpkMasterKeyLen)
+ {
+ OIC_LOG(ERROR, TAG, "InputRPKMasterKeyCB invalid parameters");
+ return;
+ }
+
+ uint8_t rpk[32] = {
+ 0xfd, 0xb5, 0x48, 0xec, 0x9c, 0x16, 0xc9, 0x72,
+ 0xc6, 0xee, 0xaf, 0x42, 0x64, 0x0d, 0xe5, 0xb6,
+ 0x44, 0x78, 0x84, 0x9e, 0xdd, 0x5c, 0x1d, 0x31,
+ 0xcf, 0xd0, 0xf2, 0xe8, 0xb1, 0xa4, 0xad, 0x0f
+ };
+
+ memcpy(rpkMasterKey, rpk, 32);
+ *rpkMasterKeyLen = 32;
+}
+
// function(s) for provisioning client using C-level provisioning API
static int initProvisionClient(void)
{
}
SetInputPinCB(inputPinCB);
+ SetInputRPKMasterKeyCB(InputRPKMasterKeyCB);
return 0;
}
#include "securevirtualresourcetypes.h"
#include "oxmjustworks.h"
#include "oxmrandompin.h"
+#include "oxmrawpublickey.h"
#include "oxmmanufacturercert.h"
#include "secureresourceprovider.h"
#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};
+ 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};
+ ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
+ NOT_ALLOWED_OXM};
#endif
OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks)
#ifdef MULTIPLE_OWNER
VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_PRECONFIG_PIN == oxm || OIC_MV_JUST_WORKS == oxm
- || OIC_CON_MFG_CERT == oxm), ERROR);
+ || OIC_CON_MFG_CERT == oxm || OIC_RAW_PUB_KEY == oxm), ERROR);
#else
- VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_MV_JUST_WORKS == oxm || OIC_CON_MFG_CERT == oxm), ERROR);
+ VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_MV_JUST_WORKS == oxm || OIC_CON_MFG_CERT == oxm || OIC_RAW_PUB_KEY == oxm), ERROR);
#endif // MULTIPLE_OWNER
switch(oxm)
callbacks->createSelectOxmPayloadCB = CreateConMCertificateBasedSelectOxmPayload;
callbacks->createOwnerTransferPayloadCB = CreateMCertificateBasedOwnerTransferPayload;
break;
+ case OIC_RAW_PUB_KEY:
+ callbacks->loadSecretCB = GetMasterRPKCallback;
+ callbacks->createSecureSessionCB = CreateSecureSessionRPKCallback;
+ callbacks->createSelectOxmPayloadCB = CreateRPKBasedSelectOxmPayload;
+ callbacks->createOwnerTransferPayloadCB = CreateRPKBasedOwnerTransferPayload;
+ break;
default:
OIC_LOG_V(ERROR, TAG, "Unknown OxM : %d", (int)oxm);
return OC_STACK_INVALID_PARAM;
return OXM_IDX_DECENTRALIZED_PUBLIC_KEY;
case OIC_MV_JUST_WORKS:
return OXM_IDX_MV_JUST_WORKS;
+ case OIC_RAW_PUB_KEY:
+ return OXM_IDX_RAW_PUBLIC_KEY;
case OIC_CON_MFG_CERT:
return OXM_IDX_CON_MFG_CERT;
#ifdef MULTIPLE_OWNER
OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table");
continue;
}
-
#ifdef MULTIPLE_OWNER
if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
OXM_IDX_PRECONFIG_PIN != selectedOxmIdx)
#else
+
if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx])
#endif //MULTIPLE_OWNER
{
--- /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 "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 "base64.h"
+#include "oxmrawpublickey.h"
+#include "ownershiptransfermanager.h"
+#include "oxmverifycommon.h"
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/ssl_internal.h"
+
+#define TAG "OIC_OXM_RawPubKey"
+
+typedef struct RPKOxmData {
+ char rpkData[OXM_RPK_MASTER_KEY_MAX_SIZE + 1];
+ size_t rpkSize;
+ OicUuid_t newDevice;
+}RPKOxmData_t;
+
+static RPKOxmData_t g_RPKOxmData = {
+ .rpkData={0},
+ .rpkSize = 0,
+ };
+
+static GetRPKMasterKeyCallback gGetRPKMasterKeyCallback = NULL;
+
+void SetInputRPKMasterKeyCB(GetRPKMasterKeyCallback rpkCB)
+{
+ if(NULL == rpkCB)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to set callback for rpk.");
+ return;
+ }
+
+ gGetRPKMasterKeyCallback = rpkCB;
+}
+
+void UnsetRPKMasterKeyCB()
+{
+ gGetRPKMasterKeyCallback = NULL;
+}
+
+OCStackResult CreateRPKBasedSelectOxmPayload(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_RAW_PUB_KEY;
+
+ return DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm, payload, size, true);
+}
+
+OCStackResult CreateRPKBasedOwnerTransferPayload(OTMContext_t* otmCtx, uint8_t **payload, size_t *size)
+{
+ if(!otmCtx || !otmCtx->selectedDeviceInfo || !payload || *payload || !size)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OicUuid_t uuidPT = {.id={0}};
+ *payload = NULL;
+ *size = 0;
+
+ if (OC_STACK_OK != GetDoxmDeviceID(&uuidPT))
+ {
+ OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
+ return OC_STACK_ERROR;
+ }
+ memcpy(otmCtx->selectedDeviceInfo->doxm->owner.id, uuidPT.id , UUID_LENGTH);
+
+ return DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm, payload, size, true);
+}
+
+OCStackResult GetMasterRPK(char* master, size_t* master_len)
+{
+ if(!master || !master_len)
+ {
+ OIC_LOG(ERROR, TAG, "RPK buffer is NULL");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ if(gGetRPKMasterKeyCallback)
+ {
+ gGetRPKMasterKeyCallback(g_RPKOxmData.rpkData, &g_RPKOxmData.rpkSize);
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "Invoke RPK callback failed!");
+ OIC_LOG(ERROR, TAG, "Callback for input RPK should be registered to use Random RPK based OxM.");
+ return OC_STACK_ERROR;
+ }
+
+ return OC_STACK_OK;
+}
+
+void SetUuidForRPKBasedOxm(const OicUuid_t* uuid)
+{
+ if(NULL != uuid)
+ {
+ memcpy(g_RPKOxmData.newDevice.id, uuid->id, UUID_LENGTH);
+ }
+}
+
+int DerivePSKUsingRPK(uint8_t* result)
+{
+ int dtlsRes = DeriveCryptoKeyFromPassword(
+ (const unsigned char *)g_RPKOxmData.rpkData,
+ g_RPKOxmData.rpkSize,
+ g_RPKOxmData.newDevice.id,
+ UUID_LENGTH, PBKDF_ITERATIONS,
+ OWNER_PSK_LENGTH_128, result);
+
+ OIC_LOG_V(DEBUG, TAG, "DeriveCryptoKeyFromPassword Completed (%d)", dtlsRes);
+ OIC_LOG_V(DEBUG, TAG, "RPK : %s", g_RPKOxmData.rpkData);
+ OIC_LOG(DEBUG, TAG, "UUID : ");
+ OIC_LOG_BUFFER(DEBUG, TAG, g_RPKOxmData.newDevice.id, UUID_LENGTH);
+ return dtlsRes;
+}
+
+int32_t GetDtlsPskForRPKOxm( CADtlsPskCredType_t type,
+ const unsigned char *UNUSED1, size_t UNUSED2,
+ unsigned char *result, size_t result_length)
+{
+ int32_t ret = -1;
+
+ (void)UNUSED1;
+ (void)UNUSED2;
+
+ if (NULL == result || result_length < OWNER_PSK_LENGTH_128)
+ {
+ return ret;
+ }
+
+ switch (type)
+ {
+ case CA_DTLS_PSK_HINT:
+ case CA_DTLS_PSK_IDENTITY:
+ {
+ /**
+ * The server will provide PSK hint to identify PSK according to RFC 4589 and RFC 4279.
+ *
+ * At this point, The server generate random hint and
+ * provide it to client through server key exchange message.
+ */
+ OCFillRandomMem(result, result_length);
+ ret = result_length;
+ OIC_LOG(DEBUG, TAG, "PSK HINT : ");
+ OIC_LOG_BUFFER(DEBUG, TAG, result, result_length);
+ }
+ break;
+
+ case CA_DTLS_PSK_KEY:
+ {
+ if(0 == DerivePSKUsingRPK((uint8_t*)result))
+ {
+ ret = OWNER_PSK_LENGTH_128;
+ }
+ else
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from RPK");
+ ret = -1;
+ }
+ }
+ break;
+
+ default:
+ {
+ OIC_LOG (ERROR, TAG, "Wrong value passed for CADtlsPskCredType_t.");
+ ret = -1;
+ }
+ break;
+ }
+ return ret;
+}
+
+OCStackResult GetMasterRPKCallback(OTMContext_t *otmCtx)
+{
+ if (!otmCtx || !otmCtx->selectedDeviceInfo)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ uint8_t rpkData[OXM_RPK_MASTER_KEY_MAX_SIZE + 1] = {0};
+ size_t rpkLen = 0;
+ OCStackResult res = OC_STACK_ERROR;
+
+ res = GetMasterRPK((char*)rpkData, &rpkLen);
+
+ if (OC_STACK_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to generate RPK master key");
+ SetResult(otmCtx, res);
+ return res;
+ }
+
+ /**
+ * Since PSK will be used directly while RPK based ownership transfer,
+ * Credential should not be saved into SVR.
+ * For this reason, We will use a temporary get_psk_info callback to random RPK OxM.
+ */
+ //in case of OTM
+ if(!(otmCtx->selectedDeviceInfo->doxm->owned))
+ {
+ if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskForRPKOxm))
+ {
+ OIC_LOG(ERROR, TAG, "Failed to register DTLS credentials handler for random raw public key OxM.");
+ res = OC_STACK_ERROR;
+ }
+ }
+
+ //Set the device id to derive temporal PSK
+ SetUuidForRPKBasedOxm(&(otmCtx->selectedDeviceInfo->doxm->deviceID));
+
+ return res;
+}
+
+OCStackResult CreateSecureSessionRPKCallback(OTMContext_t* otmCtx)
+{
+ OIC_LOG(INFO, TAG, "IN CreateSecureSessionRPKCallback");
+
+ if (!otmCtx || !otmCtx->selectedDeviceInfo)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ CAResult_t caresult = CAEnableAnonECDHCipherSuite(false);
+ if (CA_STATUS_OK != caresult)
+ {
+ OIC_LOG_V(ERROR, TAG, "Unable to disable anon cipher suite");
+ return OC_STACK_ERROR;
+ }
+ OIC_LOG(INFO, TAG, "Anonymous cipher suite disabled.");
+
+ caresult = CASelectCipherSuite(MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, otmCtx->selectedDeviceInfo->endpoint.adapter);
+ if (CA_STATUS_OK != caresult)
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256");
+ return OC_STACK_ERROR;
+ }
+ OIC_LOG(INFO, TAG, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 cipher suite selected.");
+
+ OCProvisionDev_t* selDevInfo = otmCtx->selectedDeviceInfo;
+ CAEndpoint_t endpoint;
+ memcpy(&endpoint, &selDevInfo->endpoint, sizeof(CAEndpoint_t));
+
+ if(CA_ADAPTER_IP == endpoint.adapter)
+ {
+ endpoint.port = selDevInfo->securePort;
+ caresult = CAInitiateHandshake(&endpoint);
+ }
+ else if (CA_ADAPTER_GATT_BTLE == endpoint.adapter)
+ {
+ caresult = CAInitiateHandshake(&endpoint);
+ }
+#ifdef __WITH_TLS__
+ else
+ {
+ endpoint.port = selDevInfo->tcpPort;
+ caresult = CAinitiateSslHandshake(&endpoint);
+ }
+#endif
+ if (CA_STATUS_OK != caresult)
+ {
+ OIC_LOG_V(ERROR, TAG, "DTLS handshake failure.");
+ return OC_STACK_ERROR;
+ }
+
+ OIC_LOG(INFO, TAG, "OUT CreateSecureSessionRPKCallback");
+
+ return OC_STACK_OK;
+}
OIC_LOG_V(DEBUG, TAG, "PIN : %s", g_PinOxmData.pinData);
OIC_LOG(DEBUG, TAG, "UUID : ");
OIC_LOG_BUFFER(DEBUG, TAG, g_PinOxmData.newDevice.id, UUID_LENGTH);
-
return dtlsRes;
}
*/
OCFillRandomMem(result, result_length);
ret = result_length;
-
OIC_LOG(DEBUG, TAG, "PSK HINT : ");
OIC_LOG_BUFFER(DEBUG, TAG, result, result_length);
}
}
break;
}
-
return ret;
}
const char * OXM_JUST_WORKS = "oic.sec.doxm.jw";
const char * OXM_RANDOM_DEVICE_PIN = "oic.sec.doxm.rdp";
const char * OXM_MANUFACTURER_CERTIFICATE = "oic.sec.doxm.mfgcert";
+const char * OXM_RAW_PUBLIC_KEY = "oic.sec.doxm.rpk";
#ifdef MULTIPLE_OWNER
const char * OXM_PRECONF_PIN = "x.org.iotivity.sec.doxm.pcp";
#endif //MULTIPLE_OWNER
return OXM_RANDOM_DEVICE_PIN;
case OIC_MANUFACTURER_CERTIFICATE:
return OXM_MANUFACTURER_CERTIFICATE;
+ case OIC_RAW_PUB_KEY:
+ return OXM_RAW_PUBLIC_KEY;
#ifdef MULTIPLE_OWNER
case OIC_PRECONFIG_PIN:
return OXM_PRECONF_PIN;
#include "svrdbeditordoxm.h"
#ifdef MULTIPLE_OWNER
-#define DOXM_TYPE_CNT (6)
+#define DOXM_TYPE_CNT (7)
#else
-#define DOXM_TYPE_CNT (5)
+#define DOXM_TYPE_CNT (6)
#endif //MULTIPLE_OWNER
static const char *DOXM_TYPE_STRING[DOXM_TYPE_CNT] =
#ifdef MULTIPLE_OWNER
"PRECONFIG_PIN",
#endif //MULTIPLE_OWNER
- "MV_JUST_WORKS", "CON_MFG_CERT"
+ "MV_JUST_WORKS", "CON_MFG_CERT", "RAW_PUB_KEY"
};
static const unsigned int DOXM_TYPE_NUMBER[DOXM_TYPE_CNT] =
#ifdef MULTIPLE_OWNER
OIC_PRECONFIG_PIN,
#endif //MULTIPLE_OWNER
- OIC_MV_JUST_WORKS, OIC_CON_MFG_CERT
+ OIC_MV_JUST_WORKS, OIC_CON_MFG_CERT, OIC_RAW_PUB_KEY
};
#define DOXM_SCT_CNT (6)