* @param[in] peer remote peer
*/
#define SSL_RES(peer, status) \
-if (g_sslCallback) \
+do \
{ \
- CAErrorInfo_t errorInfo; \
- errorInfo.result = (status); \
- g_sslCallback(&(peer)->sep.endpoint, &errorInfo); \
-}
+ oc_mutex_assert_owner(g_sslContextMutex, true); \
+ if (g_sslCallback) \
+ { \
+ CAErrorInfo_t errorInfo; \
+ errorInfo.result = (status); \
+ g_sslCallback(&(peer)->sep.endpoint, &errorInfo); \
+ } \
+} while(false)
/* OCF-defined EKU value indicating an identity certificate, that can be used for
* TLS client and server authentication. This is the DER encoding of the OID
/**
* @var g_dtlsContextMutex
- * @brief Mutex to synchronize access to g_caSslContext.
+ * @brief Mutex to synchronize access to g_caSslContext and g_sslCallback.
*/
static oc_mutex g_sslContextMutex = NULL;
size_t listIndex = 0;
size_t listLength = 0;
OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+
+ oc_mutex_assert_owner(g_sslContextMutex, true);
+
VERIFY_NON_NULL_RET(peer, NET_SSL_TAG, "TLS peer is NULL", NULL);
VERIFY_NON_NULL_RET(g_caSslContext, NET_SSL_TAG, "SSL Context is NULL", NULL);
{
OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
- oc_mutex_assert_owner(g_sslContextMutex, false);
oc_mutex_lock(g_sslContextMutex);
+
if (NULL == g_caSslContext)
{
OIC_LOG(ERROR, NET_SSL_TAG, "Context is NULL");
}
SslEndPoint_t* sslPeer = GetSslPeer(peer);
- if(sslPeer)
+ if (sslPeer)
{
- OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+ // sslPeer could be destroyed after releasing the lock, so make a copy
+ // of the endpoint information before releasing the lock.
memcpy(sep, &sslPeer->sep, sizeof(sslPeer->sep));
oc_mutex_unlock(g_sslContextMutex);
+
+ OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
return CA_STATUS_OK;
}
- OIC_LOG(DEBUG, NET_SSL_TAG, "Return NULL");
- OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
oc_mutex_unlock(g_sslContextMutex);
+
+ OIC_LOG(DEBUG, NET_SSL_TAG, "GetSslPeer returned NULL");
+ OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
return CA_STATUS_INVALID_PARAM;
}
OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s(peer = %s:%u, attribute = %#x)", __func__,
peer->addr, (uint32_t)peer->port, newAttribute);
- // Acquiring g_sslContextMutex recursively here is not supported, so assert
- // that the caller already owns this mutex. IOT-1876 tracks a possible
- // refactoring of the code that is using g_sslContextMutex, to address these
- // API quirks.
+ // In the current implementation, the caller already owns g_sslContextMutex.
oc_mutex_assert_owner(g_sslContextMutex, true);
if (NULL == g_caSslContext)
OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s(peer = %s:%u)", __func__,
peer->addr, (uint32_t)peer->port);
+ // In the current implementation, the caller doesn't own g_sslContextMutex.
+ oc_mutex_assert_owner(g_sslContextMutex, false);
oc_mutex_lock(g_sslContextMutex);
if (NULL == g_caSslContext)
*/
static void RemovePeerFromList(CAEndpoint_t * endpoint)
{
+ oc_mutex_assert_owner(g_sslContextMutex, true);
+
VERIFY_NON_NULL_VOID(g_caSslContext, NET_SSL_TAG, "SSL Context is NULL");
VERIFY_NON_NULL_VOID(endpoint, NET_SSL_TAG, "endpoint");
+
size_t listLength = u_arraylist_length(g_caSslContext->peerList);
for (size_t listIndex = 0; listIndex < listLength; listIndex++)
{
unsigned char msg)
{
OC_UNUSED(str);
+ OC_UNUSED(msg);
if ((0 != ret) &&
(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY != ret) &&
(MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL != ret))
{
OIC_LOG_V(ERROR, NET_SSL_TAG, "%s: -0x%x", (str), -ret);
- (void)msg;
+ oc_mutex_lock(g_sslContextMutex);
if (MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO != ret)
{
}
RemovePeerFromList(&(peer)->sep.endpoint);
+
+ oc_mutex_unlock(g_sslContextMutex);
return false;
}
*/
static void DeletePeerList()
{
+ oc_mutex_assert_owner(g_sslContextMutex, true);
+
VERIFY_NON_NULL_VOID(g_caSslContext, NET_SSL_TAG, "SSL Context is NULL");
size_t listLength = u_arraylist_length(g_caSslContext->peerList);
//Load allowed SVR suites from SVR DB
SetupCipher(config, endpoint->adapter, endpoint->remoteId);
+ oc_mutex_lock(g_sslContextMutex);
ret = u_arraylist_add(g_caSslContext->peerList, (void *) tep);
if (!ret)
{
+ oc_mutex_unlock(g_sslContextMutex);
OIC_LOG(ERROR, NET_SSL_TAG, "u_arraylist_add failed!");
DeleteSslEndPoint(tep);
return NULL;
{
OIC_LOG(ERROR, NET_SSL_TAG, "Handshake failed due to socket error");
RemovePeerFromList(&tep->sep.endpoint);
+ oc_mutex_unlock(g_sslContextMutex);
return NULL;
}
if (!checkSslOperation(tep,
"Handshake error",
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE))
{
+ oc_mutex_unlock(g_sslContextMutex);
OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
DeleteSslEndPoint(tep);
return NULL;
}
}
+
+ oc_mutex_unlock(g_sslContextMutex);
OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
return tep;
}
// Initialize mutex for tlsContext
if (NULL == g_sslContextMutex)
{
- g_sslContextMutex = oc_mutex_new();
- VERIFY_NON_NULL_RET(g_sslContextMutex, NET_SSL_TAG, "malloc failed", CA_MEMORY_ALLOC_FAILED);
+ g_sslContextMutex = oc_mutex_new_recursive();
+ VERIFY_NON_NULL_RET(g_sslContextMutex, NET_SSL_TAG, "oc_mutex_new_recursive failed",
+ CA_MEMORY_ALLOC_FAILED);
}
else
{
return CA_STATUS_OK;
}
-SslCacheMessage_t * NewCacheMessage(uint8_t * data, size_t dataLen)
+SslCacheMessage_t *NewCacheMessage(uint8_t * data, size_t dataLen)
{
OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
VERIFY_NON_NULL_RET(data, NET_SSL_TAG, "Param data is NULL" , NULL);
static void SendCacheMessages(SslEndPoint_t * tep)
{
OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+
+ // The mutex protects the access to tep.
+ oc_mutex_assert_owner(g_sslContextMutex, true);
+
VERIFY_NON_NULL_VOID(tep, NET_SSL_TAG, "Param tep is NULL");
size_t listIndex = 0;
void CAsetSslHandshakeCallback(CAErrorCallback tlsHandshakeCallback)
{
OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s(%p)", __func__, tlsHandshakeCallback);
+
+ oc_mutex_lock(g_sslContextMutex);
g_sslCallback = tlsHandshakeCallback;
+ oc_mutex_unlock(g_sslContextMutex);
+
OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s(%p)", __func__, tlsHandshakeCallback);
}
CAResult_t CAsetTlsCipherSuite(const uint32_t cipher)
{
OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
- VERIFY_NON_NULL_RET(g_caSslContext, NET_SSL_TAG, "SSL context is not initialized." , CA_STATUS_NOT_INITIALIZED);
+ oc_mutex_lock(g_sslContextMutex);
+
+ if (NULL == g_caSslContext)
+ {
+ OIC_LOG(ERROR, NET_SSL_TAG, "SSL context is not initialized.");
+ oc_mutex_unlock(g_sslContextMutex);
+ return CA_STATUS_NOT_INITIALIZED;
+ }
SslCipher_t index = GetCipherIndex(cipher);
if (SSL_CIPHER_MAX == index)
}
g_caSslContext->cipher = index;
+ oc_mutex_unlock(g_sslContextMutex);
OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
return CA_STATUS_OK;
}
CAResult_t res = CA_STATUS_OK;
OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
VERIFY_NON_NULL_RET(endpoint, NET_SSL_TAG, "Param endpoint is NULL" , CA_STATUS_INVALID_PARAM);
+ oc_mutex_lock(g_sslContextMutex);
if (NULL != GetSslPeer(endpoint))
{
}
}
- oc_mutex_lock(g_sslContextMutex);
if (NULL == InitiateTlsHandshake(endpoint))
{
OIC_LOG(ERROR, NET_SSL_TAG, "TLS handshake failed");
res = CA_STATUS_FAILED;
}
+
oc_mutex_unlock(g_sslContextMutex);
OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
return res;