Skip to content

Commit 6b09ac0

Browse files
committed
mbedtls: Set hostname for TURN connections
- New API tlsSessionStartWithHostname can receive optional hostname and set the same - It is recommened to set the hostname and is on by default for mbedtls v3.6.3 and above - Since we receive ICE server credentials via secure API and anyway are use DTLS as WebRTC standard, we could skip this, but let's follow the recommendation as precaution
1 parent f345bf0 commit 6b09ac0

File tree

6 files changed

+95
-6
lines changed

6 files changed

+95
-6
lines changed

src/source/Crypto/Dtls_mbedtls.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,8 @@ VOID dtlsSessionKeyDerivationCallback(PVOID customData, mbedtls_ssl_key_export_t
266266
PDtlsSession pDtlsSession = (PDtlsSession) customData;
267267
PTlsKeys pKeys = &pDtlsSession->tlsKeys;
268268

269-
if (pMasterSecretLen != sizeof(pKeys->masterSecret)) {
270-
DLOGE("Length check failed, pMasterSecretLen = %d, sizeof(pKeys->masterSecret) = %d\n", pMasterSecretLen, sizeof(pKeys->masterSecret));
269+
if (pMasterSecretLen != SIZEOF(pKeys->masterSecret)) {
270+
DLOGE("Length check failed, pMasterSecretLen = %d, sizeof(pKeys->masterSecret) = %d", pMasterSecretLen, SIZEOF(pKeys->masterSecret));
271271
}
272272

273273
MEMCPY(pKeys->masterSecret, pMasterSecret, pMasterSecretLen);

src/source/Crypto/Tls.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ INT32 tlsSessionCertificateVerifyCallback(INT32, X509_STORE_CTX*);
119119
// a callback signature.
120120
INT32 tlsSessionSendCallback(PVOID, const unsigned char*, ULONG);
121121
INT32 tlsSessionReceiveCallback(PVOID, unsigned char*, ULONG);
122+
123+
// Add hostname parameter for mbedTLS 3.x compatibility
124+
STATUS tlsSessionStartWithHostname(PTlsSession, BOOL, PCHAR);
122125
#else
123126
#error "A Crypto implementation is required."
124127
#endif

src/source/Crypto/Tls_mbedtls.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ INT32 tlsSessionReceiveCallback(PVOID customData, unsigned char* buf, ULONG len)
100100
return STATUS_FAILED(retStatus) ? -retStatus : readBytes;
101101
}
102102

103-
STATUS tlsSessionStart(PTlsSession pTlsSession, BOOL isServer)
103+
STATUS tlsSessionStartWithHostname(PTlsSession pTlsSession, BOOL isServer, PCHAR hostname)
104104
{
105105
ENTERS();
106106
STATUS retStatus = STATUS_SUCCESS;
@@ -114,9 +114,25 @@ STATUS tlsSessionStart(PTlsSession pTlsSession, BOOL isServer)
114114
STATUS_CREATE_SSL_FAILED);
115115

116116
mbedtls_ssl_conf_ca_chain(&pTlsSession->sslCtxConfig, &pTlsSession->cacert, NULL);
117-
mbedtls_ssl_conf_authmode(&pTlsSession->sslCtxConfig, MBEDTLS_SSL_VERIFY_REQUIRED);
117+
118+
// For mbedTLS 3.x, use appropriate verification mode
119+
if (hostname != NULL) {
120+
// If a hostname is provided, use strict verification
121+
mbedtls_ssl_conf_authmode(&pTlsSession->sslCtxConfig, MBEDTLS_SSL_VERIFY_REQUIRED);
122+
} else {
123+
// Otherwise, use optional verification for IP-based connections
124+
mbedtls_ssl_conf_authmode(&pTlsSession->sslCtxConfig, MBEDTLS_SSL_VERIFY_OPTIONAL);
125+
}
126+
118127
mbedtls_ssl_conf_rng(&pTlsSession->sslCtxConfig, mbedtls_ctr_drbg_random, &pTlsSession->ctrDrbg);
119128
CHK(mbedtls_ssl_setup(&pTlsSession->sslCtx, &pTlsSession->sslCtxConfig) == 0, STATUS_SSL_CTX_CREATION_FAILED);
129+
130+
// Set the hostname for certificate verification (for mbedTLS 3.x compatibility)
131+
if (!isServer && hostname != NULL) {
132+
// Use the provided hostname for certificate verification
133+
CHK(mbedtls_ssl_set_hostname(&pTlsSession->sslCtx, hostname) == 0, STATUS_SSL_CTX_CREATION_FAILED);
134+
}
135+
120136
mbedtls_ssl_set_mtu(&pTlsSession->sslCtx, DEFAULT_MTU_SIZE_BYTES);
121137
mbedtls_ssl_set_bio(&pTlsSession->sslCtx, pTlsSession, tlsSessionSendCallback, tlsSessionReceiveCallback, NULL);
122138

@@ -134,6 +150,11 @@ STATUS tlsSessionStart(PTlsSession pTlsSession, BOOL isServer)
134150
return retStatus;
135151
}
136152

153+
STATUS tlsSessionStart(PTlsSession pTlsSession, BOOL isServer)
154+
{
155+
return tlsSessionStartWithHostname(pTlsSession, isServer, NULL);
156+
}
157+
137158
STATUS tlsSessionProcessPacket(PTlsSession pTlsSession, PBYTE pData, UINT32 bufferLen, PUINT32 pDataLen)
138159
{
139160
ENTERS();

src/source/Ice/SocketConnection.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ STATUS createSocketConnection(KVS_IP_FAMILY_TYPE familyType, KVS_SOCKET_PROTOCOL
3030

3131
pSocketConnection->secureConnection = FALSE;
3232
pSocketConnection->protocol = protocol;
33+
pSocketConnection->hostname = NULL;
3334
if (protocol == KVS_SOCKET_PROTOCOL_TCP) {
3435
pSocketConnection->peerIpAddr = *pPeerIpAddr;
3536
CHK_STATUS(socketConnect(pPeerIpAddr, pSocketConnection->localSocket));
@@ -105,6 +106,8 @@ STATUS freeSocketConnection(PSocketConnection* ppSocketConnection)
105106
freeTlsSession(&pSocketConnection->pTlsSession);
106107
}
107108

109+
SAFE_MEMFREE(pSocketConnection->hostname);
110+
108111
getIpAddrStr(&pSocketConnection->hostIpAddr, ipAddr, ARRAY_SIZE(ipAddr));
109112
DLOGD("close socket with ip: %s:%u. family:%d", ipAddr, (UINT16) getInt16(pSocketConnection->hostIpAddr.port),
110113
pSocketConnection->hostIpAddr.family);
@@ -186,7 +189,14 @@ STATUS socketConnectionInitSecureConnection(PSocketConnection pSocketConnection,
186189
callbacks.stateChangeFn = socketConnectionTlsSessionOnStateChange;
187190

188191
CHK_STATUS(createTlsSession(&callbacks, &pSocketConnection->pTlsSession));
192+
193+
#if KVS_USE_MBEDTLS
194+
// Setting the hostname is recommended by mbedTLS and is default in mbedTLS 3.0 and above
195+
// https://mbed-tls.readthedocs.io/en/latest/security-advisories/mbedtls-security-advisory-2025-03-1/
196+
CHK_STATUS(tlsSessionStartWithHostname(pSocketConnection->pTlsSession, isServer, pSocketConnection->hostname));
197+
#else
189198
CHK_STATUS(tlsSessionStart(pSocketConnection->pTlsSession, isServer));
199+
#endif
190200
pSocketConnection->secureConnection = TRUE;
191201

192202
CleanUp:

src/source/Ice/SocketConnection.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ struct __SocketConnection {
4444
ConnectionDataAvailableFunc dataAvailableCallbackFn;
4545
UINT64 dataAvailableCallbackCustomData;
4646
UINT64 tlsHandshakeStartTime;
47+
48+
/* Hostname for TLS verification */
49+
PCHAR hostname;
4750
};
4851
typedef struct __SocketConnection* PSocketConnection;
4952

src/source/Ice/TurnConnection.c

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,48 @@
77
extern StateMachineState TURN_CONNECTION_STATE_MACHINE_STATES[];
88
extern UINT32 TURN_CONNECTION_STATE_MACHINE_STATE_COUNT;
99

10+
// On success, ppHostname is allocated and must be freed by the caller
11+
STATUS getHostnameFromUrl(PCHAR url, PCHAR* ppHostname)
12+
{
13+
ENTERS();
14+
STATUS retStatus = STATUS_SUCCESS;
15+
PCHAR urlStart = NULL;
16+
PCHAR urlEnd = NULL;
17+
UINT32 hostnameLen = 0;
18+
19+
CHK(url != NULL && ppHostname != NULL, STATUS_NULL_ARG);
20+
21+
// Skip protocol prefix (turn: or turns:) if present
22+
urlStart = STRSTR(url, "://");
23+
if (urlStart != NULL) {
24+
urlStart += 3; // Skip "://"
25+
} else {
26+
// If no protocol prefix, use the entire URL
27+
urlStart = url;
28+
}
29+
30+
// Find port separator if it exists
31+
urlEnd = STRCHR(urlStart, ':');
32+
if (urlEnd != NULL) {
33+
hostnameLen = urlEnd - urlStart;
34+
} else {
35+
// If no port is specified, use the entire remaining string
36+
hostnameLen = STRLEN(urlStart);
37+
}
38+
39+
CHK(hostnameLen > 0 && hostnameLen <= MAX_ICE_CONFIG_URI_LEN, STATUS_INVALID_ARG);
40+
*ppHostname = MEMCALLOC(1, hostnameLen + 1);
41+
CHK(*ppHostname != NULL, STATUS_NOT_ENOUGH_MEMORY);
42+
STRNCPY(*ppHostname, urlStart, hostnameLen);
43+
44+
CleanUp:
45+
46+
CHK_LOG_ERR(retStatus);
47+
LEAVES();
48+
49+
return retStatus;
50+
}
51+
1052
STATUS createTurnConnection(PIceServer pTurnServer, TIMER_QUEUE_HANDLE timerQueueHandle, TURN_CONNECTION_DATA_TRANSFER_MODE dataTransferMode,
1153
KVS_SOCKET_PROTOCOL protocol, PTurnConnectionCallbacks pTurnConnectionCallbacks, PSocketConnection pTurnSocket,
1254
PConnectionListener pConnectionListener, PTurnConnection* ppTurnConnection)
@@ -23,6 +65,11 @@ STATUS createTurnConnection(PIceServer pTurnServer, TIMER_QUEUE_HANDLE timerQueu
2365
!IS_EMPTY_STRING(pTurnServer->username),
2466
STATUS_INVALID_ARG);
2567

68+
// Set the TURN server hostname in the socket connection for TLS hostname verification
69+
PCHAR hostname = NULL;
70+
CHK_STATUS(getHostnameFromUrl(pTurnServer->url, &hostname));
71+
pTurnSocket->hostname = hostname;
72+
2673
pTurnConnection = (PTurnConnection) MEMCALLOC(
2774
1, SIZEOF(TurnConnection) + DEFAULT_TURN_MESSAGE_RECV_CHANNEL_DATA_BUFFER_LEN * 2 + DEFAULT_TURN_MESSAGE_SEND_CHANNEL_DATA_BUFFER_LEN);
2875
CHK(pTurnConnection != NULL, STATUS_NOT_ENOUGH_MEMORY);
@@ -70,8 +117,13 @@ STATUS createTurnConnection(PIceServer pTurnServer, TIMER_QUEUE_HANDLE timerQueu
70117

71118
CHK_LOG_ERR(retStatus);
72119

73-
if (STATUS_FAILED(retStatus) && pTurnConnection != NULL) {
74-
freeTurnConnection(&pTurnConnection);
120+
if (STATUS_FAILED(retStatus)) {
121+
if (pTurnConnection != NULL) {
122+
freeTurnConnection(&pTurnConnection);
123+
}
124+
if (pTurnSocket != NULL) {
125+
SAFE_MEMFREE(pTurnSocket->hostname);
126+
}
75127
}
76128

77129
if (ppTurnConnection != NULL) {

0 commit comments

Comments
 (0)