Skip to content

Commit a3dfa88

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 a3dfa88

File tree

5 files changed

+87
-4
lines changed

5 files changed

+87
-4
lines changed

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: 12 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,10 @@ STATUS freeSocketConnection(PSocketConnection* ppSocketConnection)
105106
freeTlsSession(&pSocketConnection->pTlsSession);
106107
}
107108

109+
if (pSocketConnection->hostname != NULL) {
110+
MEMFREE(pSocketConnection->hostname);
111+
}
112+
108113
getIpAddrStr(&pSocketConnection->hostIpAddr, ipAddr, ARRAY_SIZE(ipAddr));
109114
DLOGD("close socket with ip: %s:%u. family:%d", ipAddr, (UINT16) getInt16(pSocketConnection->hostIpAddr.port),
110115
pSocketConnection->hostIpAddr.family);
@@ -186,7 +191,14 @@ STATUS socketConnectionInitSecureConnection(PSocketConnection pSocketConnection,
186191
callbacks.stateChangeFn = socketConnectionTlsSessionOnStateChange;
187192

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

192204
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: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,38 @@
77
extern StateMachineState TURN_CONNECTION_STATE_MACHINE_STATES[];
88
extern UINT32 TURN_CONNECTION_STATE_MACHINE_STATE_COUNT;
99

10+
static STATUS getHostnameFromUrl(PCHAR url, PCHAR* ppHostname)
11+
{
12+
ENTERS();
13+
STATUS retStatus = STATUS_SUCCESS;
14+
PCHAR urlStart = NULL;
15+
PCHAR urlEnd = NULL;
16+
UINT32 hostnameLen = 0;
17+
18+
CHK(url != NULL && ppHostname != NULL, STATUS_NULL_ARG);
19+
20+
// Skip protocol prefix (turn: or turns:)
21+
urlStart = STRSTR(url, "://");
22+
if (urlStart != NULL) {
23+
urlStart += 3; // Skip "://"
24+
urlEnd = STRCHR(urlStart, ':');
25+
if (urlEnd != NULL) {
26+
hostnameLen = urlEnd - urlStart;
27+
} else {
28+
// If no port is specified, use the entire string after "://"
29+
hostnameLen = STRLEN(urlStart);
30+
}
31+
32+
*ppHostname = MEMCALLOC(1, hostnameLen + 1);
33+
CHK(*ppHostname != NULL, STATUS_NOT_ENOUGH_MEMORY);
34+
STRNCPY(*ppHostname, urlStart, hostnameLen);
35+
}
36+
37+
CleanUp:
38+
LEAVES();
39+
return retStatus;
40+
}
41+
1042
STATUS createTurnConnection(PIceServer pTurnServer, TIMER_QUEUE_HANDLE timerQueueHandle, TURN_CONNECTION_DATA_TRANSFER_MODE dataTransferMode,
1143
KVS_SOCKET_PROTOCOL protocol, PTurnConnectionCallbacks pTurnConnectionCallbacks, PSocketConnection pTurnSocket,
1244
PConnectionListener pConnectionListener, PTurnConnection* ppTurnConnection)
@@ -23,6 +55,13 @@ STATUS createTurnConnection(PIceServer pTurnServer, TIMER_QUEUE_HANDLE timerQueu
2355
!IS_EMPTY_STRING(pTurnServer->username),
2456
STATUS_INVALID_ARG);
2557

58+
// Set the TURN server hostname in the socket connection for TLS hostname verification
59+
if (pTurnServer->url != NULL) {
60+
PCHAR hostname = NULL;
61+
CHK_STATUS(getHostnameFromUrl(pTurnServer->url, &hostname));
62+
pTurnSocket->hostname = hostname;
63+
}
64+
2665
pTurnConnection = (PTurnConnection) MEMCALLOC(
2766
1, SIZEOF(TurnConnection) + DEFAULT_TURN_MESSAGE_RECV_CHANNEL_DATA_BUFFER_LEN * 2 + DEFAULT_TURN_MESSAGE_SEND_CHANNEL_DATA_BUFFER_LEN);
2867
CHK(pTurnConnection != NULL, STATUS_NOT_ENOUGH_MEMORY);
@@ -70,8 +109,13 @@ STATUS createTurnConnection(PIceServer pTurnServer, TIMER_QUEUE_HANDLE timerQueu
70109

71110
CHK_LOG_ERR(retStatus);
72111

73-
if (STATUS_FAILED(retStatus) && pTurnConnection != NULL) {
74-
freeTurnConnection(&pTurnConnection);
112+
if (STATUS_FAILED(retStatus)) {
113+
if (pTurnConnection != NULL) {
114+
freeTurnConnection(&pTurnConnection);
115+
}
116+
if (pTurnSocket != NULL) {
117+
SAFE_MEMFREE(pTurnSocket->hostname);
118+
}
75119
}
76120

77121
if (ppTurnConnection != NULL) {

0 commit comments

Comments
 (0)