obs-outputs: Add mbedTLS support to libRTMP#1360
obs-outputs: Add mbedTLS support to libRTMP#1360compiler-errors wants to merge 9 commits intoobsproject:masterfrom
Conversation
|
The commit messages are a tiny bit different than what we'd usually use. Although you're modifying the librtmp library, the module being modified for the first two is technically obs-outputs. The commit messages are typically 50 character titles (minus prefix), blank line, then the commit description, which is word-wrapped at 72 columns. So for your commits, I'd probably suggest something more along the lines of: You'll notice they're wrapped at 72 characters, and the titles are a bit shorter and more concise. Now, for the https://gist.github.com/jp9000/ed5b96a52bd7e8bbc515f69bca216c30 This would allow us to easily package mbedtls as part of the dependencies zip on windows. You may have to change Last issue is the custom send callback, |
This diff adds mbedTLS support. PolarSSL and mbedTLS have grown so different between 2015-or-so when libRTMP was written and now that it's no longer feasible to just use the USE_POLARSSL flag that is present in libRTMP already. I kept the old PolarSSL flag, but now there's USE_MBEDTLS instead which uses the library more responsibly due to the introduction of a bunch of _init and _free functions, etc. Right now we're statically linking, meaning that the dependency on mbedTLS on the client machine is not necessary and which alleviates concerns of shipping OBS with this flag on by default.
CMake rule for mbedTLS should work correctly with the build system on Linux, MacOS, and Windows.
|
@jp9000, I fixed my commit messages and addressed the new Windows networking stack I adjusted that cmake file you provided in the gist with some OS-specific peculiarities I had found. I've commented them in the FindMbedtls cmake file pretty well, but I also wanted to mention them here:
A lot of these issues are due to the fact that (as far as I understand), we want to statically link mbedtls into the obs-outputs plugin. |
|
Note: Also, anyone who has checked out these sources, I |
| mbedtls_ssl_init(s);\ | ||
| mbedtls_ssl_setup(s, &ctx->conf);\ | ||
| mbedtls_ssl_config_defaults(&ctx->conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);\ | ||
| mbedtls_ssl_conf_authmode(&ctx->conf, MBEDTLS_SSL_VERIFY_NONE);\ |
There was a problem hiding this comment.
Could this be set to MBEDTLS_SSL_VERIFY_REQUIRED? Disabling certificate verification negates the security of an RTMPS connection. I'm not entirely sure how mbed TLS handles root certs, I suppose we'd need to ship a CA bundle?
There was a problem hiding this comment.
I'm going to try the PR with that param. Hopefully @compiler-errors can make some time verify this.
There was a problem hiding this comment.
I tested the MBEDTLS_SSL_VERIFY_REQUIRED param and it seemed to work -- @compiler-errors may want to also confirm whether this is alright.
There was a problem hiding this comment.
I tested VERIFY_REQUIRED and it doesn't seem to work out-of-the-box. Did you add anything to the client init code to load root certs from the OS?
(tested on MacOS, maybe Linux or Windows know where to look by default?)
There was a problem hiding this comment.
Oh, I'm sorry. What I meant is that it appears to stream. I did get a disconnect my first time I tried it, but I'm unsure if it was due to the cert code change.
There was a problem hiding this comment.
So I tested on Linux, and it works there. I tested on MacOS, and it works after I manually load the root certs at /etc/ssl/cert.pem. I'm about to commit an OS-specific case to load this on MacOS, and I'd like to see what @notr1ch thinks.
| ret = RTMPSockBuf_Send(&stream->rtmp.m_sb, | ||
| (const char *)stream->write_buf, | ||
| (int)send_len, 0); | ||
| (int)send_len); |
There was a problem hiding this comment.
We may want to disable low latency mode if using RTMPS. I'm not entirely sure how mbed TLS handles sizing of records, but writing lots of small chunks may result in a high TLS record overhead.
There was a problem hiding this comment.
@notr1ch I noticed this comment seemed unresolved. Is this still a concern?
|
Hey there @compiler-errors -- when you have time could you take a look at the comments on this pull request? |
| project(obs-outputs) | ||
|
|
||
| option(USE_SSL "Enable rtmps support with OpenSSL" OFF) | ||
| option(WITH_RTMPS "Enable rtmps support with mbedTLS" OFF) |
There was a problem hiding this comment.
I think this may be better if the default is ON for this option. Facebook won't function without it if it's set to rtmps anyway.
* Enables WITH_RTMPS option by default in CMakeLists * Enables `MBEDTLS_SSL_VERIFY_REQUIRED` so certificates are always checked
|
Edit: Read new update below A few things: Even though I've enabled WITH_RTMPS, the continuous-integration platforms are essentially skipping over the option since they haven't been configured to have the modified build environment (i.e. one that provides mbedTLS static libs). This should get fixed so CI would catch RTMPS-specific bugs. Commit caec9ab seems like a quick fix to a bigger cert problem in MacOS. The general philosophical issue here is that MacOS uses its own keystores to store all of its encryption info. Luckily, when I load the certs included in I'll test Windows RTMPS functionality with the VERIFY_REQUIRED option enabled tonight, but I wanted to get this message out sooner than later since I've pushed a commit without much explanation. I'd like to hear what both of y'all think, @jp9000 @notr1ch. |
On MacOS, root certificates aren't located in `/etc/ssl/certs/*`, but instead in their own keychain API which can be programatically loaded via Apple's Security framework. On MacOS, this change loads a cert chain so that we can properly authenticate servers when connecting via RTMPS. On Windows, we do the same thing with the Crypt32 library. Currently, this is broken. There are a few bugs that I have been unable to find, but I'm committing this so we can at least get an initial review out.
|
Hey y'all, Sorry for all the updates. I actually went ahead and wrote a dedicated I've never worked with the windows On another note, for some reason the |
Added hostname verification, fix root CA verification on Windows, add friendlier error message if cert verification fails.
On Windows, we need to add `crypt32`. On MacOS, we need Security framework (but only if we have WITH_RTMPS on).
|
Works on Linux and MacOS. |
|
CMake logic should be corrected imo. It claims user has requested WITH_RTMPS when user has not. It does not fail when user manually specifies WITH_RTMPS but the required libraries are not found, and instead disables RTMPS support (this should be done when a user does not specify anything). findMbedTLS appears to attempt to hijack the library names to inject linker flags. This is not supported and should not be used. There are walls of deprecation warnings when compiling against mbedtls 2.8.0, I'm not sure what version of Ubuntu is being targeting with the upcoming release but if these deprecated functions and include locations can be avoided I recommend you do.
|
|
Compiles when built against mbedtls 2.12.0 with fPIC enabled. And connects and streams successfully to an rtmps endpoint. |
|
I successfully tested this on Windows 10 64-bit with a 64-bit build of OBS Studio (both Debug and RelWithDebInfo). Seemed to work as expected once I got around some confusion over building mbedTLS. |
|
I also confirmed it works without the About the CMake logic, @jp9000 suggested that WITH_RTMPS should be on by default. See the comments on The "fall back and disable crypto if SSL is missing" logic was already present in OBS when it was using OpenSSL before my changes. I have made it explicitly an error so the builder is aware that they're intending to build with RTMPS and cmake unable to find the correct dependencies. These options (WITH_RTMPS and MBEDTLS_STATIC) will need to be enabled on the official build flow: the intention that I have discussed with @jp9000 is to ship OBS with RTMPS and mbedTLS enabled by default, since otherwise RTMPS-only targets won't be able to connect on officially-packaged versions of the OBS binary. Statically, too, since we don't want to introduce a extra dependency on the client machine either. |
|
Sorry if there is a bit of misunderstanding, I don't think building with RTMPS should be disabled by default. Basically if the user requests with/without RTMPS it should be respected and an error if it cannot be. If the user doesnt request anything build by default but dont fail if its not found. |
|
Okay! In that case, I'll try to amend it with the default/explicit behavior that you described above. Thanks. |
|
Amended WITH_RTMPS option to take a tri-state (AUTO|ON|OFF) value instead of just boolean ON/OFF, as to emulate the functionality that @kkartaltepe suggested. |
* WITH_RTMPS can take three values (AUTO [default], ON, OFF):
- AUTO: Will build RTMPS if it finds mbedTLS, and otherwise silently
disable the feature if we cannot find mbedTLS, so no catastrophic
failure.
- ON: Will enforce that RTMPS is built; if we cannot find mbedTLS,
then fail explicitly with a fatal error. This is to ensure that the
builder knows that they have a mis-configured build environment.
- OFF: Will not build RTMPS support even if mbedTLS is present.
* Adds STATIC_MBEDTLS option to specify that we want to statically link
mbedTLS on unix-like machines.
|
(forgot to support the AUTO option everywhere, fixed in 06f288b) |
|
I'm probably going to squash some of these commits, then merge shortly. Additionally, there's also a bug where if the user was already using Facebook in their settings, it would still use the non-secure URL. I'm going to fix that up myself after. |
|
Actually before merging to the repository I may have to submit an email to the BIS due to shipping (or more technically "exporting") mbedTLS. May be a bit before that's finished up, just want to make sure I do it correctly. |
|
mbedTLS can be exported without a license. Ref: https://tls.mbed.org/kb/generic/export-control-eccn-number-for-mbedtls |
|
In incorporating mbedTLS obs becomes it's own encryption tool which falls
under export law. Like mbedTLS it will likely fall under the Open Source
exemption, but it still needs to be reported.
From note 2:
https://www.bis.doc.gov/index.php/policy-guidance/encryption/1-encryption-items-not-subject-to-the-ear
…On Thu, Aug 2, 2018, 09:40 Richard Stanway ***@***.***> wrote:
mbedTLS can be exported without a license.
Ref:
https://tls.mbed.org/kb/generic/export-control-eccn-number-for-mbedtls
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1360 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAgIU7YKmF7pdDnZrOTdCd3WPSUazoIDks5uMyuJgaJpZM4VIGm5>
.
|
|
I've filed a Self Classification Report just to be sure then. The code can safely be used under the mass market exception. |
|
Okay, everything looks good, tested it and everything seems to be working smoothly. Going to squash this myself, and fix up a code styling issue or two. Merging shortly, you should see something like "closed from [commit]". |
|
Additionally, there was a bug where if the user was set to the old server, it would get stuck on that server and would not use RTMPS. I made a fix for that here: be8ddc0 |
This diff adds mbedTLS support to the obs-outputs plugin. PolarSSL and mbedTLS have grown so different between 2015-or-so when libRTMP was written, and now it's no longer feasible to just use the USE_POLARSSL flag. This commit adds a WITH_RTMPS tri-state CMake variable (auto/on/off), set to "Auto" by default. "Auto" will use RTMPS if mbedTLS is found, otherwise will disable RTMPS. "On" will make it require mbedTLS, otherwise fails configuration, and "Off" disables RTMPS support altogether. Closes obsproject#1360
|
@compiler-errors |
|
Right now there isn't a simple way to build with another SSL library (e.g. GnuTLS). It would be possible to modify the CMake logic to allow that to happen, but I wanted to keep it simple. Before this PR, the CMake logic also only allowed OpenSSL, so I don't think OBS ever let you choose your SSL library easily. |
|
@compiler-errors |
When compiled with the flag
-DWITH_RTMPS=ON, Cmake will look for mbedTLS (specifically, the static libs). This should compile with any modern version of mbedTLS.Works out-of-box with macOS. Needs
mbedtlsinstalled with brew just for building/linking, but should statically link after built.To build on Linux, mbedTLS needs to be built from scratch with
-fPICand with the dynamic linking flags off so it generates*.afiles. Same as above, this is just needed for building. Alternatively, dynamically linking with the mbedTLS*.sofiles included in any common linux package manager and adding mbedTLS dependency on Linux is also an option.To build on Windows,
mbedtls.libneeds to be built using the visual studio project that comes with the mbedTLS sources. Once that's done, you can just throw thembedtls.libfile and theinclude/directory into the same DepsPath that already consolidates all of the windows dependencies.Finally, I also changed the Facebook stream URL to point to the RTMPS url instead of the RTMP url.