Commit 134d7027 authored by Sachin Agrawal's avatar Sachin Agrawal

Refactor PSK Credential retrieval interface

When CA requests PSK credentials during DTLS handshake, SRM retrieves
credential for all devices and provides it to CA. This is un-necessary
and is in-efficient approach. Updated code to only provide credential
which has been requested by tinydtls.

Change-Id: Ie9bdc0ff1236b9f1f198215d211a682df416e731
Signed-off-by: default avatarSachin Agrawal <sachin.agrawal@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/3009Reviewed-by: default avatarJon A. Cruz <jonc@osg.samsung.com>
Tested-by: default avatarjenkins-iotivity <jenkins-iotivity@opendaylight.org>
parent e733fd89
......@@ -31,13 +31,7 @@
* Connectivity Abstraction Interface APIs.
*/
#include "cacommon.h"
#ifdef __WITH_DTLS__
#include "ocsecurityconfig.h"
#endif
#ifdef __WITH_X509__
#include "pki.h"
#endif //__WITH_X509__
#include "casecurityinterface.h"
#ifdef __cplusplus
extern "C"
......@@ -93,66 +87,6 @@ typedef struct
#endif //RA_ADAPTER
#ifdef __WITH_DTLS__
/**
* Binary blob containing device identity and the credentials for all devices
* trusted by this device.
*/
typedef struct
{
unsigned char identity[DTLS_PSK_ID_LEN]; /** identity of self. */
uint32_t num; /** number of credentials in this blob. */
OCDtlsPskCreds *creds; /** list of credentials. Size of this
array is determined by 'num' variable. */
} CADtlsPskCredsBlob_t;
/**
* Callback function type for getting DTLS credentials.
* @param[out] credInfo DTLS credentials info. Handler has to allocate new memory for.
* both credInfo and credInfo->creds which is then freed by CA.
*/
typedef void (*CAGetDTLSCredentialsHandler)(CADtlsPskCredsBlob_t **credInfo);
#endif //__WITH_DTLS__
#ifdef __WITH_X509__
/**
* Binary structure containing certificate chain and certificate credentials
* for this device.
*/
typedef struct
{
// certificate message for DTLS
unsigned char certificateChain[MAX_CERT_MESSAGE_LEN];
// length of the certificate message
uint32_t certificateChainLen;
// number of certificates in certificate message
uint8_t chainLen;
// x component of EC public key
uint8_t rootPublicKeyX[PUBLIC_KEY_SIZE / 2];
// y component of EC public key
uint8_t rootPublicKeyY[PUBLIC_KEY_SIZE / 2];
// EC private key
uint8_t devicePrivateKey[PRIVATE_KEY_SIZE];
} CADtlsX509Creds_t;
/**
* @brief Callback function type for getting certificate credentials.
* @param credInfo [OUT] Certificate credentials info. Handler has to allocate new memory for
* credInfo which is then freed by CA
* @return NONE
*/
typedef int (*CAGetDTLSX509CredentialsHandler)(CADtlsX509Creds_t *credInfo);
/**
* @brief Callback function type for getting CRL.
* @param crlInfo [OUT] Certificate credentials info. Handler has to allocate new memory for
* credInfo which is then freed by CA
* @return NONE
*/
typedef void (*CAGetDTLSCrlHandler)(ByteArray crlInfo);
#endif //__WITH_X509__
/**
* Initialize the connectivity abstraction module.
* It will initialize adapters, thread pool and other modules based on the platform
......@@ -196,30 +130,6 @@ CAResult_t CAStartDiscoveryServer();
void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
CAErrorCallback ErrorHandler);
#ifdef __WITH_DTLS__
/**
* Register callback to get DTLS PSK credentials.
* @param[in] GetDTLSCredentials GetDTLS Credetials callback.
* @return ::CA_STATUS_OK
*/
CAResult_t CARegisterDTLSCredentialsHandler(CAGetDTLSCredentialsHandler GetDTLSCredentials);
#endif //__WITH_DTLS__
#ifdef __WITH_X509__
/**
* @brief Register callback to get DTLS Cert credentials.
* @param GetCertCredentials [IN] GetCert Credetials callback
* @return #CA_STATUS_OK
*/
CAResult_t CARegisterDTLSX509CredentialsHandler(CAGetDTLSX509CredentialsHandler GetX509Credentials);
/**
* @brief Register callback to get CRL.
* @param GetCrl [IN] GetCrl callback
* @return #CA_STATUS_OK
*/
CAResult_t CARegisterDTLSCrlHandler(CAGetDTLSCrlHandler GetCrl);
#endif //__WITH_X509__
/**
* Create an endpoint description.
* @param[in] flags how the adapter should be used.
......@@ -330,83 +240,6 @@ CAResult_t CASetRAInfo(const CARAInfo_t *caraInfo);
#endif
#ifdef __WITH_DTLS__
/**
* Select the cipher suite for dtls handshake.
*
* @param[in] cipher cipher suite (Note : Make sure endianness).
* 0xC018 : TLS_ECDH_anon_WITH_AES_128_CBC_SHA
* 0xC0A8 : TLS_PSK_WITH_AES_128_CCM_8
* 0xC0AE : TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
*
* @retval ::CA_STATUS_OK Successful.
* @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments.
* @retval ::CA_STATUS_FAILED Operation failed.
*/
CAResult_t CASelectCipherSuite(const uint16_t cipher);
/**
* Enable TLS_ECDH_anon_WITH_AES_128_CBC_SHA cipher suite in dtls.
*
* @param[in] enable TRUE/FALSE enables/disables anonymous cipher suite.
*
* @retval ::CA_STATUS_OK Successful.
* @retval ::CA_STATUS_FAILED Operation failed.
*
* @note anonymous cipher suite should only be enabled for 'JustWorks' provisioning.
*/
CAResult_t CAEnableAnonECDHCipherSuite(const bool enable);
/**
* Generate ownerPSK using PRF.
* OwnerPSK = TLS-PRF('master key' , 'oic.sec.doxm.jw',
* 'ID of new device(Resource Server)',
* 'ID of owner smart-phone(Provisioning Server)')
*
* @param[in] endpoint information of network address.
* @param[in] label Ownership transfer method e.g)"oic.sec.doxm.jw".
* @param[in] labelLen Byte length of label.
* @param[in] rsrcServerDeviceID ID of new device(Resource Server).
* @param[in] rsrcServerDeviceIDLen Byte length of rsrcServerDeviceID.
* @param[in] provServerDeviceID label of previous owner.
* @param[in] provServerDeviceIDLen byte length of provServerDeviceID.
* @param[in,out] ownerPSK Output buffer for owner PSK.
* @param[in] ownerPSKSize Byte length of the ownerPSK to be generated.
*
* @retval ::CA_STATUS_OK Successful.
* @retval ::CA_STATUS_FAILED Operation failed.
*/
CAResult_t CAGenerateOwnerPSK(const CAEndpoint_t *endpoint,
const uint8_t* label, const size_t labelLen,
const uint8_t* rsrcServerDeviceID,
const size_t rsrcServerDeviceIDLen,
const uint8_t* provServerDeviceID,
const size_t provServerDeviceIDLen,
uint8_t* ownerPSK, const size_t ownerPSKSize);
/**
* Initiate DTLS handshake with selected cipher suite.
*
* @param[in] endpoint information of network address.
*
* @retval ::CA_STATUS_OK Successful.
* @retval ::CA_STATUS_FAILED Operation failed.
*/
CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint);
/**
* Close the DTLS session.
*
* @param[in] endpoint information of network address.
*
* @retval ::CA_STATUS_OK Successful.
* @retval ::CA_STATUS_FAILED Operation failed.
*/
CAResult_t CACloseDtlsSession(const CAEndpoint_t *endpoint);
#endif /* __WITH_DTLS__ */
#ifdef __cplusplus
} /* extern "C" */
......
/* *****************************************************************
*
* 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.
*
******************************************************************/
/**
* @file
*
* This file contains the Security APIs for Resource Model to use.
*/
#ifndef CA_SECURITY_INTERFACE_H_
#define CA_SECURITY_INTERFACE_H_
#ifdef __WITH_X509__
#include "pki.h"
#endif //__WITH_X509__
#ifdef __cplusplus
extern "C"
{
#endif
#ifdef __WITH_DTLS__
/**
* @enum CADtlsPskCredType_t
* Type of PSK credential required during DTLS handshake
* It does not make much sense in bringing in all definitions from dtls.h into here.
* Therefore, redefining them here.
*/
typedef enum
{
CA_DTLS_PSK_HINT,
CA_DTLS_PSK_IDENTITY,
CA_DTLS_PSK_KEY
} CADtlsPskCredType_t;
/**
* This internal callback is used by CA layer to
* retrieve PSK credentials from SRM.
*
* @param[in] type type of PSK data required by CA layer during DTLS handshake set.
* @param[in] desc Additional request information.
* @param[in] desc_len The actual length of desc.
* @param[out] result Must be filled with the requested information.
* @param[in] result_length Maximum size of @p result.
*
* @return The number of bytes written to @p result or a value
* less than zero on error.
*/
typedef int (*CAGetDTLSPskCredentialsHandler)( CADtlsPskCredType_t type,
const unsigned char *desc, size_t desc_len,
unsigned char *result, size_t result_length);
/**
* Register callback to get DTLS PSK credentials.
* @param[in] GetDTLSCredentials GetDTLS Credetials callback.
* @return ::CA_STATUS_OK
*/
CAResult_t CARegisterDTLSCredentialsHandler(CAGetDTLSPskCredentialsHandler GetDTLSCredentials);
#endif //__WITH_DTLS__
#ifdef __WITH_X509__
/**
* Binary structure containing certificate chain and certificate credentials
* for this device.
*/
typedef struct
{
// certificate message for DTLS
unsigned char certificateChain[MAX_CERT_MESSAGE_LEN];
// length of the certificate message
uint32_t certificateChainLen;
// number of certificates in certificate message
uint8_t chainLen;
// x component of EC public key
uint8_t rootPublicKeyX[PUBLIC_KEY_SIZE / 2];
// y component of EC public key
uint8_t rootPublicKeyY[PUBLIC_KEY_SIZE / 2];
// EC private key
uint8_t devicePrivateKey[PRIVATE_KEY_SIZE];
} CADtlsX509Creds_t;
/**
* @brief Callback function type for getting certificate credentials.
* @param credInfo [OUT] Certificate credentials info. Handler has to allocate new memory for
* credInfo which is then freed by CA
* @return NONE
*/
typedef int (*CAGetDTLSX509CredentialsHandler)(CADtlsX509Creds_t *credInfo);
/**
* @brief Callback function type for getting CRL.
* @param crlInfo [OUT] Certificate credentials info. Handler has to allocate new memory for
* credInfo which is then freed by CA
* @return NONE
*/
typedef void (*CAGetDTLSCrlHandler)(ByteArray crlInfo);
/**
* @brief Register callback to get DTLS Cert credentials.
* @param GetCertCredentials [IN] GetCert Credetials callback
* @return #CA_STATUS_OK
*/
CAResult_t CARegisterDTLSX509CredentialsHandler(CAGetDTLSX509CredentialsHandler GetX509Credentials);
/**
* @brief Register callback to get CRL.
* @param GetCrl [IN] GetCrl callback
* @return #CA_STATUS_OK
*/
CAResult_t CARegisterDTLSCrlHandler(CAGetDTLSCrlHandler GetCrl);
#endif //__WITH_X509__
#ifdef __WITH_DTLS__
/**
* Select the cipher suite for dtls handshake.
*
* @param[in] cipher cipher suite (Note : Make sure endianness).
* 0xC018 : TLS_ECDH_anon_WITH_AES_128_CBC_SHA
* 0xC0A8 : TLS_PSK_WITH_AES_128_CCM_8
* 0xC0AE : TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
*
* @retval ::CA_STATUS_OK Successful.
* @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments.
* @retval ::CA_STATUS_FAILED Operation failed.
*/
CAResult_t CASelectCipherSuite(const uint16_t cipher);
/**
* Enable TLS_ECDH_anon_WITH_AES_128_CBC_SHA cipher suite in dtls.
*
* @param[in] enable TRUE/FALSE enables/disables anonymous cipher suite.
*
* @retval ::CA_STATUS_OK Successful.
* @retval ::CA_STATUS_FAILED Operation failed.
*
* @note anonymous cipher suite should only be enabled for 'JustWorks' provisioning.
*/
CAResult_t CAEnableAnonECDHCipherSuite(const bool enable);
/**
* Generate ownerPSK using PRF.
* OwnerPSK = TLS-PRF('master key' , 'oic.sec.doxm.jw',
* 'ID of new device(Resource Server)',
* 'ID of owner smart-phone(Provisioning Server)')
*
* @param[in] endpoint information of network address.
* @param[in] label Ownership transfer method e.g)"oic.sec.doxm.jw".
* @param[in] labelLen Byte length of label.
* @param[in] rsrcServerDeviceID ID of new device(Resource Server).
* @param[in] rsrcServerDeviceIDLen Byte length of rsrcServerDeviceID.
* @param[in] provServerDeviceID label of previous owner.
* @param[in] provServerDeviceIDLen byte length of provServerDeviceID.
* @param[in,out] ownerPSK Output buffer for owner PSK.
* @param[in] ownerPSKSize Byte length of the ownerPSK to be generated.
*
* @retval ::CA_STATUS_OK Successful.
* @retval ::CA_STATUS_FAILED Operation failed.
*/
CAResult_t CAGenerateOwnerPSK(const CAEndpoint_t *endpoint,
const uint8_t* label, const size_t labelLen,
const uint8_t* rsrcServerDeviceID,
const size_t rsrcServerDeviceIDLen,
const uint8_t* provServerDeviceID,
const size_t provServerDeviceIDLen,
uint8_t* ownerPSK, const size_t ownerPSKSize);
/**
* Initiate DTLS handshake with selected cipher suite.
*
* @param[in] endpoint information of network address.
*
* @retval ::CA_STATUS_OK Successful.
* @retval ::CA_STATUS_FAILED Operation failed.
*/
CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint);
/**
* Close the DTLS session.
*
* @param[in] endpoint information of network address.
*
* @retval ::CA_STATUS_OK Successful.
* @retval ::CA_STATUS_FAILED Operation failed.
*/
CAResult_t CACloseDtlsSession(const CAEndpoint_t *endpoint);
#endif /* __WITH_DTLS__ */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* CA_SECURITY_INTERFACE_H_ */
......@@ -52,6 +52,7 @@ cp -rf %{ROOTDIR}/con/inc/caipadapter.h* %{DEST_INC_DIR}/
cp -rf %{ROOTDIR}/con/inc/caedradapter.h* %{DEST_INC_DIR}/
cp -rf %{ROOTDIR}/con/inc/caleadapter.h* %{DEST_INC_DIR}/
cp -rf %{ROOTDIR}/con/api/cainterface.h* %{DEST_INC_DIR}/
cp -rf %{ROOTDIR}/con/api/casecurityinterface.h* %{DEST_INC_DIR}/
cp -rf %{ROOTDIR}/com.oic.ca.pc %{DEST_LIB_DIR}/pkgconfig/
......
//*******************************************************************
//
// Copyright 2014 Intel Mobile Communications GmbH 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.
//
//
//******************************************************************
/**
* @file
*
* This file contains all the constants which can be configured/modified as
* per platform or security specific product usage scenarios.
*/
#ifndef OC_SECURITY_CONFIG_H
#define OC_SECURITY_CONFIG_H
#include <stdint.h>
#define DTLS_PSK_ID_LEN 16
#define DTLS_PSK_PSK_LEN 16
#define DtlsPskCredsBlobVer_1 1 /**< Credentials stored in plaintext */
#define DtlsPskCredsBlobVer_CurrentVersion DtlsPskCredsBlobVer_1
/**
* Credentials for a device. Includes identity and the associated PSK.
*/
typedef struct
{
unsigned char id[DTLS_PSK_ID_LEN];
unsigned char psk[DTLS_PSK_PSK_LEN];
} OCDtlsPskCreds;
/**
* Binary blob containing device identity and the credentials for all devices
* trusted by this device.
*/
typedef struct
{
unsigned char identity[DTLS_PSK_ID_LEN]; /** identity of self */
uint32_t num; /** number of credentials in this blob */
OCDtlsPskCreds creds[1]; /** list of credentials. Size of this
array is determined by 'num' variable. */
} OCDtlsPskCredsBlob;
#endif //OC_SECURITY_CONFIG_H
......@@ -24,7 +24,6 @@
#include "uarraylist.h"
#include "camutex.h"
#include "caadapterutils.h"
#include "ocsecurityconfig.h"
#include "cainterface.h"
#include "cacommon.h"
......@@ -33,11 +32,6 @@
*/
#define MAX_SUPPORTED_ADAPTERS 2
/**
* The implementation will be provided by OIC RI layer.
*/
extern void OCGetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo);
typedef void (*CAPacketReceivedCallback)(const CASecureEndpoint_t *sep,
const void *data, uint32_t dataLength);
......@@ -130,9 +124,9 @@ void CADTLSSetAdapterCallbacks(CAPacketReceivedCallback recvCallback,
/**
* Register callback to get DTLS PSK credentials.
* @param[in] credCallback callback to get DTLS credentials.
* @param[in] credCallback callback to get DTLS PSK credentials.
*/
void CADTLSSetCredentialsCallback(CAGetDTLSCredentialsHandler credCallback);
void CADTLSSetCredentialsCallback(CAGetDTLSPskCredentialsHandler credCallback);
/**
* Select the cipher suite for dtls handshake
......
......@@ -17,15 +17,11 @@
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
/**
* @def RS_IDENTITY
* @brief
*/
#define IDENTITY ("1111111111111111")
/* @def RS_CLIENT_PSK
* @brief
*/
#define RS_CLIENT_PSK ("AAAAAAAAAAAAAAAA")
// Iotivity Device Identity.
const unsigned char IDENTITY[] = ("1111111111111111");
// PSK between this device and peer device.
const unsigned char RS_CLIENT_PSK[] = ("AAAAAAAAAAAAAAAA");
#define PORT_LENGTH 5
#define SECURE_DEFAULT_PORT 5684
......@@ -104,80 +100,61 @@ Java_org_iotivity_ca_service_RMInterface_setNativeResponseListener(JNIEnv *env,
}
#ifdef __WITH_DTLS__
static CADtlsPskCredsBlob_t *pskCredsBlob = NULL;
void clearDtlsCredentialInfo()
{
LOGI("clearDtlsCredentialInfo IN");
if (pskCredsBlob)
{
// Initialize sensitive data to zeroes before freeing.
if (NULL != pskCredsBlob->creds)
{
memset(pskCredsBlob->creds, 0, sizeof(OCDtlsPskCreds)*(pskCredsBlob->num));
free(pskCredsBlob->creds);
}
memset(pskCredsBlob, 0, sizeof(CADtlsPskCredsBlob_t));
free(pskCredsBlob);
pskCredsBlob = NULL;
}
LOGI("clearDtlsCredentialInfo OUT");
}
// Internal API. Invoked by OC stack to retrieve credentials from this module
void CAGetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo)
int32_t CAGetDtlsPskCredentials( CADtlsPskCredType_t type,
const unsigned char *desc, size_t desc_len,
unsigned char *result, size_t result_length)
{
LOGI("CAGetDtlsPskCredentials IN");
*credInfo = (CADtlsPskCredsBlob_t *) malloc(sizeof(CADtlsPskCredsBlob_t));
if (NULL == *credInfo)
int32_t ret = -1;
if (NULL == result)
{
LOGE("Failed to allocate credential blob.");
return;
return ret;
}
int16_t credLen = sizeof(OCDtlsPskCreds) * (pskCredsBlob->num);
(*credInfo)->creds = (OCDtlsPskCreds *) malloc(credLen);
if (NULL == (*credInfo)->creds)
switch (type)
{
LOGE("Failed to allocate crentials.");
free(*credInfo);
*credInfo = NULL;
return;
}
case CA_DTLS_PSK_HINT:
case CA_DTLS_PSK_IDENTITY:
memcpy((*credInfo)->identity, pskCredsBlob->identity, DTLS_PSK_ID_LEN);
(*credInfo)->num = pskCredsBlob->num;
memcpy((*credInfo)->creds, pskCredsBlob->creds, credLen);
if (result_length < sizeof(IDENTITY))
{
LOGE("ERROR : Wrong value for result for storing IDENTITY");
return ret;
}
LOGI("CAGetDtlsPskCredentials OUT");
}
memcpy(result, IDENTITY, sizeof(IDENTITY));
ret = sizeof(IDENTITY);
break;
CAResult_t SetCredentials()
{
LOGI("SetCredentials IN");
pskCredsBlob = (CADtlsPskCredsBlob_t *)malloc(sizeof(CADtlsPskCredsBlob_t));
if (NULL == pskCredsBlob)
{
LOGE("Memory allocation failed!");
return CA_MEMORY_ALLOC_FAILED;
}
memcpy(pskCredsBlob->identity, IDENTITY, DTLS_PSK_ID_LEN);
case CA_DTLS_PSK_KEY:
pskCredsBlob->num = 1;
if ((desc_len == sizeof(IDENTITY)) &&
memcmp(desc, IDENTITY, sizeof(IDENTITY)) == 0)
{
if (result_length < sizeof(RS_CLIENT_PSK))
{