Commit 690545bb authored by Oleksii Beketov's avatar Oleksii Beketov Committed by Randeep

[IOT-2632] Callback to check peer's CN

Added callback to check peer's certificate Common Name field.

Change-Id: Idb316438a76d70fcc7a91a2e119aadd0c771bde6
Signed-off-by: default avatarakk0rd <v.riznyk@samsung.com>
Signed-off-by: default avatarOleksii Beketov <ol.beketov@samsung.com>
parent 367287a4
...@@ -124,6 +124,28 @@ typedef struct ...@@ -124,6 +124,28 @@ typedef struct
ByteArray_t crl; /**< trusted CRLs as binary-encoded DER */ ByteArray_t crl; /**< trusted CRLs as binary-encoded DER */
} PkiInfo_t; } PkiInfo_t;
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
/**
* Callback is used by application layer to check peer's certificate CN field.
* If set, this callback will be invoked during handshake after certificate verification.
*
* @param[out] cn peer's certificate Common Name field.
* If common name was not found, cn will be set to NULL.
* @param[out] cnLen peer's certificate Common Name field length.
* If CN was not found, cnLen will be set to 0.
*
* @return CA_STATUS_OK or CA_STATUS_FAIL. In case CA_STATUS_FAIL is returned,
* handshake will be dropped.
*/
typedef CAResult_t (*PeerCNVerifyCallback)(const unsigned char *cn, size_t cnLen);
/**
* API to set callback that checks peer's certificate Common Name field
* @param[in] cb callback to utilize certificate Common Name field
*/
void CAsetPeerCNVerifyCallback(PeerCNVerifyCallback cb);
#endif
/** /**
* Register callback to get types of TLS suites. * Register callback to get types of TLS suites.
* @param[in] getCredTypesHandler Get types of TLS suites callback. * @param[in] getCredTypesHandler Get types of TLS suites callback.
......
...@@ -418,6 +418,13 @@ static oc_mutex g_sslContextMutex = NULL; ...@@ -418,6 +418,13 @@ static oc_mutex g_sslContextMutex = NULL;
*/ */
static CAHandshakeErrorCallback g_sslCallback = NULL; static CAHandshakeErrorCallback g_sslCallback = NULL;
/**
* @var g_peerCNVerifyCallback
*
* @brief callback to utilize peer certificate information
*/
static PeerCNVerifyCallback g_peerCNVerifyCallback = NULL;
/** /**
* Data structure for holding the data to be received. * Data structure for holding the data to be received.
*/ */
...@@ -458,6 +465,7 @@ void CAsetPkixInfoCallback(CAgetPkixInfoHandler infoCallback) ...@@ -458,6 +465,7 @@ void CAsetPkixInfoCallback(CAgetPkixInfoHandler infoCallback)
g_getPkixInfoCallback = infoCallback; g_getPkixInfoCallback = infoCallback;
OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__); OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
} }
void CAsetCredentialTypesCallback(CAgetCredentialTypesHandler credTypesCallback) void CAsetCredentialTypesCallback(CAgetCredentialTypesHandler credTypesCallback)
{ {
OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__); OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
...@@ -465,6 +473,17 @@ void CAsetCredentialTypesCallback(CAgetCredentialTypesHandler credTypesCallback) ...@@ -465,6 +473,17 @@ void CAsetCredentialTypesCallback(CAgetCredentialTypesHandler credTypesCallback)
OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__); OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
} }
void CAsetPeerCNVerifyCallback(PeerCNVerifyCallback cb)
{
OIC_LOG_V(DEBUG, NET_SSL_TAG, "IN %s", __func__);
if (NULL == cb)
{
OIC_LOG(DEBUG, NET_SSL_TAG, "UNSET peerCNVerifyCallback");
}
g_peerCNVerifyCallback = cb;
OIC_LOG_V(DEBUG, NET_SSL_TAG, "OUT %s", __func__);
}
/** /**
* Sets SSL result for callback. * Sets SSL result for callback.
* *
...@@ -483,6 +502,43 @@ static CAResult_t notifySubscriber(SslEndPoint_t* peer, CAResult_t status) ...@@ -483,6 +502,43 @@ static CAResult_t notifySubscriber(SslEndPoint_t* peer, CAResult_t status)
return result; return result;
} }
static CAResult_t PeerCertExtractCN(const mbedtls_x509_crt *peerCert)
{
OIC_LOG_V(DEBUG, NET_SSL_TAG, "IN %s", __func__);
CAResult_t res = CA_STATUS_OK;
mbedtls_asn1_named_data *subject = (mbedtls_asn1_named_data *)&(peerCert->subject);
while (NULL != subject)
{
if (0 == MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &(subject->oid)))
{
break;
}
subject = subject->next;
}
if (NULL != g_peerCNVerifyCallback)
{
if (NULL != subject)
{
res = g_peerCNVerifyCallback(subject->val.p, subject->val.len);
}
else
{
OIC_LOG(DEBUG, NET_SSL_TAG, "Common Name not found");
res = g_peerCNVerifyCallback(NULL, 0);
}
}
else
{
OIC_LOG(DEBUG, NET_SSL_TAG, "g_peerCNVerifyCallback is not set");
}
OIC_LOG_V(DEBUG, NET_SSL_TAG, "OUT %s", __func__);
return res;
}
static int GetAdapterIndex(CATransportAdapter_t adapter) static int GetAdapterIndex(CATransportAdapter_t adapter)
{ {
switch (adapter) switch (adapter)
...@@ -2038,7 +2094,6 @@ CAResult_t CAdecryptSsl(const CASecureEndpoint_t *sep, uint8_t *data, size_t dat ...@@ -2038,7 +2094,6 @@ CAResult_t CAdecryptSsl(const CASecureEndpoint_t *sep, uint8_t *data, size_t dat
return CA_STATUS_FAILED; return CA_STATUS_FAILED;
} }
SslEndPoint_t * peer = GetSslPeer(&sep->endpoint); SslEndPoint_t * peer = GetSslPeer(&sep->endpoint);
if (NULL == peer) if (NULL == peer)
{ {
...@@ -2109,6 +2164,23 @@ CAResult_t CAdecryptSsl(const CASecureEndpoint_t *sep, uint8_t *data, size_t dat ...@@ -2109,6 +2164,23 @@ CAResult_t CAdecryptSsl(const CASecureEndpoint_t *sep, uint8_t *data, size_t dat
OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__); OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
return CA_STATUS_FAILED; return CA_STATUS_FAILED;
} }
if (MBEDTLS_SSL_CERTIFICATE_VERIFY == peer->ssl.state)
{
mbedtls_x509_crt *peerCert = peer->ssl.session_negotiate->peer_cert;
if (NULL != peerCert)
{
ret = PeerCertExtractCN(peerCert);
if (CA_STATUS_OK != ret)
{
oc_mutex_unlock(g_sslContextMutex);
OIC_LOG_V(ERROR, NET_SSL_TAG, "ProcessPeerCert failed with %d", ret);
OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
return CA_STATUS_FAILED;
}
}
}
if (MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC == peer->ssl.state) if (MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC == peer->ssl.state)
{ {
memcpy(peer->master, peer->ssl.session_negotiate->master, sizeof(peer->master)); memcpy(peer->master, peer->ssl.session_negotiate->master, sizeof(peer->master));
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#define GetCASecureEndpointData GetCASecureEndpointDataTest #define GetCASecureEndpointData GetCASecureEndpointDataTest
#define SetCASecureEndpointAttribute SetCASecureEndpointAttributeTest #define SetCASecureEndpointAttribute SetCASecureEndpointAttributeTest
#define GetCASecureEndpointAttributes GetCASecureEndpointAttributesTest #define GetCASecureEndpointAttributes GetCASecureEndpointAttributesTest
#define CAsetPeerCNVerifyCallback CAsetPeerCNVerifyCallbackTest
#include "../src/adapter_util/ca_adapter_net_ssl.c" #include "../src/adapter_util/ca_adapter_net_ssl.c"
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "octypes.h" #include "octypes.h"
#include "pmtypes.h" #include "pmtypes.h"
#include "casecurityinterface.h"
#include "ownershiptransfermanager.h" #include "ownershiptransfermanager.h"
#ifdef MULTIPLE_OWNER #ifdef MULTIPLE_OWNER
#include "experimental/securevirtualresourcetypes.h" #include "experimental/securevirtualresourcetypes.h"
...@@ -690,6 +691,18 @@ OCStackResult OC_CALL OCReadTrustCertChain(uint16_t credId, uint8_t **trustCertC ...@@ -690,6 +691,18 @@ OCStackResult OC_CALL OCReadTrustCertChain(uint16_t credId, uint8_t **trustCertC
OCStackResult OC_CALL OCSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMethods, OCStackResult OC_CALL OCSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMethods,
size_t numberOfMethods, OicSecOxm_t *selectedMethod, OwnerType_t ownerType); size_t numberOfMethods, OicSecOxm_t *selectedMethod, OwnerType_t ownerType);
/**
* Function to set callback to check peer's Common Name field.
*
* @param[in] cb callback to utilize peer's certificate Common Name information.
* If set, callback is invoked during handshake after certificate
* verification. It takes peer's certificate CN field and provides
* it to application level. Application is to decide whether CN is
* valid or not. In case CA_STATUS_FAIL is returned, handshake will
* be dropped.
*/
void OC_CALL OCSetPeerCNVerifyCallback(PeerCNVerifyCallback cb);
#endif // __WITH_DTLS__ || __WITH_TLS__ #endif // __WITH_DTLS__ || __WITH_TLS__
......
...@@ -2509,6 +2509,20 @@ static FILE* fopen_prvnMng(const char* path, const char* mode) ...@@ -2509,6 +2509,20 @@ static FILE* fopen_prvnMng(const char* path, const char* mode)
} }
} }
static CAResult_t peerCNVerifyCallback(const unsigned char *cn, size_t cnLen)
{
if (NULL != cn && 0 != cnLen)
{
OIC_LOG(INFO, TAG, "peer certificate CN: ");
OIC_LOG_BUFFER(INFO, TAG, cn, cnLen);
return CA_STATUS_OK;
}
else
{
return CA_STATUS_FAILED;
}
}
static int waitCallbackRet(void) static int waitCallbackRet(void)
{ {
for (int i = 0; !g_doneCB && (CALLBACK_TIMEOUT > i); ++i) for (int i = 0; !g_doneCB && (CALLBACK_TIMEOUT > i); ++i)
...@@ -2742,6 +2756,9 @@ int main() ...@@ -2742,6 +2756,9 @@ int main()
SetDisplayNumCB(NULL, displayNumCB); SetDisplayNumCB(NULL, displayNumCB);
SetUserConfirmCB(NULL, confirmNumCB); SetUserConfirmCB(NULL, confirmNumCB);
// set callback for checking peer certificate information
OCSetPeerCNVerifyCallback(peerCNVerifyCallback);
#ifdef MULTIPLE_OWNER #ifdef MULTIPLE_OWNER
SetPreconfigPin("12341234", 8); SetPreconfigPin("12341234", 8);
#endif //MULTIPLE_OWNER #endif //MULTIPLE_OWNER
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <signal.h> #include <signal.h>
#include "ocstack.h" #include "ocstack.h"
#include "ocpayload.h" #include "ocpayload.h"
#include "ocprovisioningmanager.h"
#ifdef HAVE_WINDOWS_H #ifdef HAVE_WINDOWS_H
#include <windows.h> #include <windows.h>
...@@ -416,6 +417,20 @@ FILE* server_fopen(const char *path, const char *mode) ...@@ -416,6 +417,20 @@ FILE* server_fopen(const char *path, const char *mode)
} }
} }
static CAResult_t peerCNVerifyCallback(const unsigned char *cn, size_t cnLen)
{
if (NULL != cn && 0 != cnLen)
{
OIC_LOG(INFO, TAG, "peer certificate CN: ");
OIC_LOG_BUFFER(INFO, TAG, cn, cnLen);
return CA_STATUS_OK;
}
else
{
return CA_STATUS_FAILED;
}
}
int main() int main()
{ {
struct timespec timeout; struct timespec timeout;
...@@ -427,6 +442,9 @@ int main() ...@@ -427,6 +442,9 @@ int main()
OCRegisterPersistentStorageHandler(&ps); OCRegisterPersistentStorageHandler(&ps);
// set callback for checking peer certificate information
OCSetPeerCNVerifyCallback(peerCNVerifyCallback);
if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK) if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
{ {
OIC_LOG(ERROR, TAG, "OCStack init error"); OIC_LOG(ERROR, TAG, "OCStack init error");
......
...@@ -1581,5 +1581,15 @@ void OC_CALL OCRemoveTrustCertChainNotifier() ...@@ -1581,5 +1581,15 @@ void OC_CALL OCRemoveTrustCertChainNotifier()
{ {
SRPRemoveTrustCertChainNotifier(); SRPRemoveTrustCertChainNotifier();
} }
/**
* Function to set the callback to utilize peer certificate Common Name field
*/
void OC_CALL OCSetPeerCNVerifyCallback(PeerCNVerifyCallback cb)
{
OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
CAsetPeerCNVerifyCallback(cb);
OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
}
#endif // __WITH_DTLS__ || __WITH_TLS__ #endif // __WITH_DTLS__ || __WITH_TLS__
...@@ -51,6 +51,7 @@ OCSelectOwnershipTransferMethod ...@@ -51,6 +51,7 @@ OCSelectOwnershipTransferMethod
OCSaveOwnRoleCert OCSaveOwnRoleCert
OCSetOwnerTransferCallbackData OCSetOwnerTransferCallbackData
OCSetOxmAllowStatus OCSetOxmAllowStatus
OCSetPeerCNVerifyCallback
OCUnlinkDevices OCUnlinkDevices
OCVerifyCSRSignature OCVerifyCSRSignature
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment