1 From 179ad9e67b74bb8ea8d2c655ce12071c2dd67e81 Mon Sep 17 00:00:00 2001
2 From: tytan652 <tytan652@tytanium.xyz>
3 Date: Tue, 28 Sep 2021 18:26:23 +0200
4 Subject: [PATCH] librtmp: Add mbedtls 3 compatibility
6 Since Mbed TLS 3 doesn't support RC4 algorithm,
7 encrypted RTMP is disabled if OBS is built with
8 the version 3 or later of Mbed TLS.
10 plugins/obs-outputs/librtmp/handshake.h | 54 ++++++++++++++++++++++++-
11 plugins/obs-outputs/librtmp/rtmp.c | 12 ++++--
12 plugins/obs-outputs/librtmp/rtmp.h | 2 +
13 3 files changed, 64 insertions(+), 4 deletions(-)
15 diff --git a/plugins/obs-outputs/librtmp/handshake.h b/plugins/obs-outputs/librtmp/handshake.h
16 index 1827867850a7..7f7825592aad 100644
17 --- a/plugins/obs-outputs/librtmp/handshake.h
18 +++ b/plugins/obs-outputs/librtmp/handshake.h
21 #if defined(USE_MBEDTLS)
22 #include <mbedtls/md.h>
23 +#if MBEDTLS_VERSION_MAJOR < 3
24 #include <mbedtls/arc4.h>
26 #ifndef SHA256_DIGEST_LENGTH
27 #define SHA256_DIGEST_LENGTH 32
29 @@ -38,12 +40,14 @@ typedef mbedtls_md_context_t *HMAC_CTX;
30 #define HMAC_finish(ctx, dig) mbedtls_md_hmac_finish(ctx, dig)
31 #define HMAC_close(ctx) mbedtls_md_free(ctx); free(ctx); ctx = NULL
33 +#if MBEDTLS_VERSION_MAJOR < 3
34 typedef mbedtls_arc4_context* RC4_handle;
35 #define RC4_alloc(h) *h = malloc(sizeof(mbedtls_arc4_context)); mbedtls_arc4_init(*h)
36 #define RC4_setkey(h,l,k) mbedtls_arc4_setup(h,k,l)
37 #define RC4_encrypt(h,l,d) mbedtls_arc4_crypt(h,l,(unsigned char *)d,(unsigned char *)d)
38 #define RC4_encrypt2(h,l,s,d) mbedtls_arc4_crypt(h,l,(unsigned char *)s,(unsigned char *)d)
39 #define RC4_free(h) mbedtls_arc4_free(h); free(h); h = NULL
42 #elif defined(USE_POLARSSL)
43 #include <polarssl/sha2.h>
44 @@ -104,7 +108,9 @@ typedef RC4_KEY * RC4_handle;
48 +#if !defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3
52 static const uint8_t GenuineFMSKey[] =
54 @@ -133,6 +139,7 @@ static const uint8_t GenuineFPKey[] =
58 +#if !defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3
59 static void InitRC4Encryption
62 @@ -173,9 +180,11 @@ static void InitRC4Encryption
64 RC4_setkey(*rc4keyIn, 16, digest);
68 typedef unsigned int (getoff)(uint8_t *buf, unsigned int len);
70 +#if !defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3
72 GetDHOffset2(uint8_t *handshake, unsigned int len)
74 @@ -206,6 +215,7 @@ GetDHOffset2(uint8_t *handshake, unsigned int len)
81 GetDigestOffset2(uint8_t *handshake, unsigned int len)
82 @@ -238,6 +248,7 @@ GetDigestOffset2(uint8_t *handshake, unsigned int len)
86 +#if !defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3
88 GetDHOffset1(uint8_t *handshake, unsigned int len)
90 @@ -268,6 +279,7 @@ GetDHOffset1(uint8_t *handshake, unsigned int len)
97 GetDigestOffset1(uint8_t *handshake, unsigned int len)
98 @@ -302,7 +314,9 @@ GetDigestOffset1(uint8_t *handshake, unsigned int len)
101 static getoff *digoff[] = {GetDigestOffset1, GetDigestOffset2};
102 +#if !defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3
103 static getoff *dhoff[] = {GetDHOffset1, GetDHOffset2};
107 HMACsha256(const uint8_t *message, size_t messageLen, const uint8_t *key,
108 @@ -805,12 +819,16 @@ static int
109 HandShake(RTMP * r, int FP9HandShake)
112 +#if !defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3
115 int digestPosClient = 0;
116 int encrypted = r->Link.protocol & RTMP_FEATURE_ENC;
118 +#if !defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3
119 RC4_handle keyIn = 0;
120 RC4_handle keyOut = 0;
125 @@ -820,15 +838,31 @@ HandShake(RTMP * r, int FP9HandShake)
126 uint8_t clientbuf[RTMP_SIG_SIZE + 4], *clientsig=clientbuf+4;
127 uint8_t serversig[RTMP_SIG_SIZE], client2[RTMP_SIG_SIZE], *reply;
129 - getoff *getdh = NULL, *getdig = NULL;
130 +#if !defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3
131 + getoff *getdh = NULL;
133 + getoff *getdig = NULL;
135 +#if !defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3
136 if (encrypted || r->Link.SWFSize)
139 FP9HandShake = FALSE;
141 r->Link.rc4keyIn = r->Link.rc4keyOut = 0;
145 + RTMP_Log(RTMP_LOGWARNING, "%s: encrypted RTMP is no longer supported with mbedtls 3 and later", __FUNCTION__);
148 + else if (r->Link.SWFSize)
149 + FP9HandShake = TRUE;
151 + FP9HandShake = FALSE;
154 +#if !defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3
157 clientsig[-1] = 0x06; /* 0x08 is RTMPE as well */
158 @@ -836,12 +870,16 @@ HandShake(RTMP * r, int FP9HandShake)
161 clientsig[-1] = 0x03;
163 + clientsig[-1] = 0x03;
166 uptime = htonl(RTMP_GetTime());
167 memcpy(clientsig, &uptime, 4);
171 +#if !defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3
172 /* set version to at least 9.0.115.0 */
175 @@ -853,12 +891,18 @@ HandShake(RTMP * r, int FP9HandShake)
186 RTMP_Log(RTMP_LOGDEBUG, "%s: Client type: %02X", __FUNCTION__, clientsig[-1]);
187 getdig = digoff[offalg];
188 +#if !defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3
189 getdh = dhoff[offalg];
194 @@ -877,6 +921,7 @@ HandShake(RTMP * r, int FP9HandShake)
195 /* set handshake digest */
198 +#if !defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3
201 /* generate Diffie-Hellmann parameters */
202 @@ -904,6 +949,7 @@ HandShake(RTMP * r, int FP9HandShake)
208 digestPosClient = getdig(clientsig, RTMP_SIG_SIZE); /* reuse this value in verification */
209 RTMP_Log(RTMP_LOGDEBUG, "%s: Client digest offset: %d", __FUNCTION__,
210 @@ -966,7 +1012,9 @@ HandShake(RTMP * r, int FP9HandShake)
211 RTMP_Log(RTMP_LOGWARNING, "Trying different position for server digest!");
213 getdig = digoff[offalg];
214 +#if !defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3
215 getdh = dhoff[offalg];
217 digestPosServer = getdig(serversig, RTMP_SIG_SIZE);
219 if (!VerifyDigest(digestPosServer, serversig, GenuineFMSKey, 36))
220 @@ -991,6 +1039,7 @@ HandShake(RTMP * r, int FP9HandShake)
221 (uint8_t *)&r->Link.SWFVerificationResponse[10]);
224 +#if !defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3
225 /* do Diffie-Hellmann Key exchange for encrypted RTMP */
228 @@ -1017,6 +1066,7 @@ HandShake(RTMP * r, int FP9HandShake)
229 (uint8_t *) & clientsig[dhposClient],
236 @@ -1146,6 +1196,7 @@ HandShake(RTMP * r, int FP9HandShake)
237 RTMP_Log(RTMP_LOGDEBUG, "%s: Genuine Adobe Flash Media Server", __FUNCTION__);
240 +#if !defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3
243 char buff[RTMP_SIG_SIZE];
244 @@ -1165,6 +1216,7 @@ HandShake(RTMP * r, int FP9HandShake)
245 RC4_encrypt(r->Link.rc4keyOut, RTMP_SIG_SIZE, (uint8_t *) buff);
252 diff --git a/plugins/obs-outputs/librtmp/rtmp.c b/plugins/obs-outputs/librtmp/rtmp.c
253 index 70e42f7ee636..fbc25c679526 100644
254 --- a/plugins/obs-outputs/librtmp/rtmp.c
255 +++ b/plugins/obs-outputs/librtmp/rtmp.c
256 @@ -954,7 +954,11 @@ RTMP_Connect1(RTMP *r, RTMPPacket *cp)
258 #if defined(USE_MBEDTLS)
259 mbedtls_net_context *server_fd = &r->RTMP_TLS_ctx->net;
260 +#if MBEDTLS_VERSION_NUMBER == 0x03000000
261 + server_fd->MBEDTLS_PRIVATE(fd) = r->m_sb.sb_socket;
263 server_fd->fd = r->m_sb.sb_socket;
265 TLS_setfd(r->m_sb.sb_ssl, server_fd);
267 // make sure we verify the certificate hostname
268 @@ -1540,7 +1544,7 @@ ReadN(RTMP *r, char *buffer, int n)
269 if (r->Link.protocol & RTMP_FEATURE_HTTP)
270 r->m_resplen -= nBytes;
273 +#if defined(CRYPTO) && (!defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3)
274 if (r->Link.rc4keyIn)
276 RC4_encrypt(r->Link.rc4keyIn, nBytes, ptr);
277 @@ -1562,6 +1566,7 @@ WriteN(RTMP *r, const char *buffer, int n)
279 char buf[RTMP_BUFFER_CACHE_SIZE];
281 +#if !defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3
282 if (r->Link.rc4keyOut)
284 if (n > (int)sizeof(buf))
285 @@ -1571,6 +1576,7 @@ WriteN(RTMP *r, const char *buffer, int n)
287 RC4_encrypt2(r->Link.rc4keyOut, n, buffer, ptr);
293 @@ -2607,7 +2613,7 @@ b64enc(const unsigned char *input, int length, char *output, int maxsize)
294 #if defined(USE_MBEDTLS)
295 typedef mbedtls_md5_context MD5_CTX;
297 -#if MBEDTLS_VERSION_NUMBER >= 0x02070000
298 +#if MBEDTLS_VERSION_NUMBER >= 0x02070000 && MBEDTLS_VERSION_MAJOR < 3
299 #define MD5_Init(ctx) mbedtls_md5_init(ctx); mbedtls_md5_starts_ret(ctx)
300 #define MD5_Update(ctx,data,len) mbedtls_md5_update_ret(ctx,(unsigned char *)data,len)
301 #define MD5_Final(dig,ctx) mbedtls_md5_finish_ret(ctx,dig); mbedtls_md5_free(ctx)
302 @@ -4409,7 +4415,7 @@ RTMP_Close(RTMP *r)
303 free(r->Link.tcUrl.av_val);
304 r->Link.tcUrl.av_val = NULL;
306 -#elif defined(CRYPTO)
307 +#elif defined(CRYPTO) && (!defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3)
310 MDH_free(r->Link.dh);
311 diff --git a/plugins/obs-outputs/librtmp/rtmp.h b/plugins/obs-outputs/librtmp/rtmp.h
312 index 5020120ee3ee..45090c3f1b9f 100644
313 --- a/plugins/obs-outputs/librtmp/rtmp.h
314 +++ b/plugins/obs-outputs/librtmp/rtmp.h
315 @@ -342,9 +342,11 @@ extern "C"
318 #define RTMP_SWF_HASHLEN 32
319 +#if !defined(USE_MBEDTLS) || MBEDTLS_VERSION_MAJOR < 3
320 void *dh; /* for encryption */
326 uint8_t SWFHash[RTMP_SWF_HASHLEN];