Open PallHaraldsson opened 2 years ago
mbedTLS
?libssh2
https://github.com/JuliaLang/julia/blob/f4801ff2b50594568f0bb66a1b4d8ee9181d76bf/deps/libssh2.mk#L20
libssh2
can use one of the following cryptography libraries:
libgit2
We choose to use mbedTLS
for Linux or FreeBSD.
https://github.com/JuliaLang/julia/blob/f4801ff2b50594568f0bb66a1b4d8ee9181d76bf/deps/libgit2.mk#L33
curl
On Linux, we use mbedTLS
https://github.com/JuliaLang/julia/blob/f4801ff2b50594568f0bb66a1b4d8ee9181d76bf/deps/curl.mk#L45
Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is. We don't recommend that third parties depend upon it. Doing so is likely to be frustrating because there are no guarantees of API or ABI stability.
BoringSSL README.md
Pkg.jl
<- (libgit2
<- mbedtls
) <- libssh2
<- mbedtls
;
Pkg.jl
: Standard library for package managementlibgit2
: Provides git-related functionalitylibssh2
: Provides ssh connectionsmbedtls
: Provides encryption operationsLibCURL.jl
<- curl
<- mbedtls
The simplest thing is keeping mbedTLS (but I understood problematic), at least for now (or only for Julia 1.6 LTS). If there's NO problem keeping it (and neither regarding supporting HTTP/3, which we may want to do somehow), then just close the issue. I assumed BoringSSL ok since lsquic uses.
I just wanted to propose an alternative, since I was proposing dropping mbedTLS, and actually OpenSLL is likely back to being the best option (BoringSSL builds on it, may still be an option, quictls, another fork of OpenSLL, may be a better option).
https://www.freshports.org/security/openssl-quictls/
Note, I would prefer shipping no TLS/SSL, and just defer to what the operating system provides, which is likely OpenSLL (at least on Linux) or something built into Windows.
I don't know exactly what we need from these TLS/SLL libraries (only small part of the API? and thus do not need to worry too much about all the CVEs?).
My thinking is, if we have some ancient Julia installed (or PackageCompiler app), is it insecure, even if the operating system is upgraded with its TLS/SLL library, since what the OS provides wouldn't be used? Or vise versa, if the OS is ancient, then if you have more recent Julia (or upgrade), then you might be ok, if you do NOT defer to the OS (but you do on Windows). Could we choose dynamically which is newer, do some projects do that?
https://www.openssl.org/policies/releasestrat.html
- Version 3.0 will be supported until 2026-09-07 (LTS).
- Version 1.1.1 will be supported until 2023-09-11 (LTS).
LibreSLL is no longer supported in Python, and they went back to OpenSLL (and "currently no plans to support BoringSSL"):
https://peps.python.org/pep-0644/#libressl-support
Swift moved to (or was only considering? note, that's an old RFC) BoringSSL: https://forums.swift.org/t/rfc-moving-swiftnio-ssl-to-boringssl/18280
Apple platforms provide no libssl at all, requiring developers who wish to replicate their Linux build environment to go and obtain a copy of libssl. [..] Unfortunately, the absence of libssl on Apple platforms requires developers that want to ship applications that build on both Linux and Apple platforms to either require that their users read an installation guide to obtain their dependencies, or [..] The story for deployment is also tricky when it comes to libssl. This is because the produced application binary depends on having a copy of libssl available to it that is ABI-compatible with the one that it was built against. [..] Applications built on Ubuntu 14.04 against OpenSSL will run on Ubuntu 16.04, but not Ubuntu 18.04. This is an unfortunate, and unnecessary, limitation.
While we are actively using libraries like libssl widely in the Swift Server space, we will never have anywhere near as compelling a deployment story as languages like Go.
I can't quickly see what Go provides. OpenSLL? if anything by default, at least, it's available: https://pkg.go.dev/github.com/spacemonkeygo/openssl#section-readme
https://github.com/golang/go/issues/32204
Of note is an existing attempt at implementing QUIC and HTTP/3 in pure go: https://github.com/lucas-clemente/quic-go.
https://github.com/nodejs/node/pull/38512
This pull request updates the OpenSSL version that is statically linked with Node.js from OpenSSl 1.1.1 to quictls OpenSSL 3.0.0+quic. [..] The question is when does the community think that we should make this switch to OpenSSL 3.0+quic?
mbedtls
with openssl
? YES!libssh2
YES!
https://github.com/JuliaPackaging/Yggdrasil/blob/d66a54d0d6d4dc63d172e65088fe81c41f78473d/L/LibSSH2/build_tarballs.jl#L24
mbedtls
=> WinCNG (native)mbedtls
=> openssl
libgit2
YES!
https://github.com/JuliaPackaging/Yggdrasil/blob/d66a54d0d6d4dc63d172e65088fe81c41f78473d/L/LibGit2/build_tarballs.jl#L31-L42
mbedtls
=> openssl
curl
YES!
https://github.com/JuliaPackaging/Yggdrasil/blob/d66a54d0d6d4dc63d172e65088fe81c41f78473d/L/LibCURL/common.jl#L42-L60
mbedtls
=> openssl
memo:
I don't know exactly what we need from these TLS/SSL libraries.
I'm not completely sure. But my understanding is that in most cases it is possible to use HTTP only, without SSL encryption. The main use cases are: clone git repo, download files.
First we want to decide if/how we want to change TLS/SLL lib, e.g. to which (likely OpenSLL, not ruling out HTTP/3 and QUIC, or to a library supporting that right away?), without thinking of an auto-update mechanish.
As a follow-up (I'm not sure it influences the decision on what to choose), then consider the auto-update issue I opened (I guess it could be implemented first though, with mbedTLS, but might not be worth it, if we want to migrate later/soon).
in most cases it is possible to use HTTP only, without SSL encryption.
I'm not sure that will be possible in the future. HTTP/3 (and HTTP/2 before) drops unencrypted, and (the former TCP). I'm not sure if non-TCP QUIC influences what of/which library we want to migrate to. Still we need to support HTTP/1.1. E.g. for auto-update, you want to send "I'm using Julia 1.6.5, is newer available?", and it's preferable that "dialing in" is in the clear so that people do not get suspicious what's being sent to JuliaLang. I think this can and must still be done with TLS/SLL (just not HTTP/3). Except for such few exceptions, you would want to use encryption always and HTTP/3 (falling back to HTTP/2 or straight to HTTP/1.1, with HTTPS). Certainly encrypted should be the default, and never falling back to unencrytped, that should always be an opt-in (and maybe just not be offered by Julia).
OpenSSL License Compatibility OpenSLL changed to Apache 2.0 in 3.0. While Python did go with OpenSLL 1.1.1, we might want 3.0, at least by the time we implement this. Older Ubuntu with 1.1.1 (if we choose to defer to the OS), will soon be EOL.
Rustls also seems like a good choice (robustness and portability), however at the moment it looks like only Curl supports using it as a TLS backend (https://daniel.haxx.se/blog/2021/02/09/curl-supports-rustls/).
Rustls is a modern TLS library written in Rust. It uses ring for cryptography and webpki for certificate verification.
ring
Most of the C and assembly language code in ring comes from BoringSSL, and BoringSSL is derived from OpenSSL. ring merges changes from BoringSSL regularly. Also, several changes that were developed for ring have been contributed to and integrated into BoringSSL. —— https://github.com/briansmith/ring
Interesting findings: Rustls -> ring -> BoringSSL
I think that @inkydragon's plan to switch to a mix of native SSL and OpenSSL as laid out in this comment is the way to go. The license situation is that recent OpenSSL is Apache v2, which is incompatible with GPLv2 but compatible with GPLv3+. Fortunately, we don't seem to only have any dependencies in Julia that are incompatible with Apache v2. Indeed, since mbedTLS is also Apache v2, switching to OpenSSL doesn't actually change the license situation at all.
Regarding ABI, there may be some packages out there that rely on Julia shipping mbedTLS, but they really shouldn't and there is an mbedTLS JLL, which is how they should be depending on it.
A pkgeval should catch that, and switching to the JLL should be quite easy.
recent OpenSSL is Apache v2, which is incompatible with GPLv2
As you say, it's not a license change (from MbedTLS), but this would still be a problem for some users... (GPLv2-only vs GPLv2-or-later) unless you depend on OpenSSL of the system (which most or all provide?), the system library GPL exception:
https://www.gnu.org/licenses/gpl-faq.html#SystemLibraryException
So it's important, is the plan to ship Julia and bundling OpenSSL? An alternative would be e.g. Rustls, if you need to bundle anything..., which is MIT (and Apache).
Intriguingly Rustls is the 14th and latest TLS supported by curl:
curl has a range of such alternative backends for various features:
- International Domain Names
- Name resolving
- TLS
- SSH
- HTTP/3
- HTTP content encoding
- HTTP
Is the plan to support (of those) only 3. TLS (plus what Julia already needs), or also 5. HTTP/3? Going forward, could the stuff bundled with Julia only support what's needed for Julia (i.e. Pkg) itself, and could it use HTTP/3, and drop TCP support?
Pkg.jl <- Downloads.jl <- LibCURL.jl <- LibCURL_jll
could the stuff bundled with Julia only support what's needed for Julia (i.e. Pkg) itself
Technically this is possible, but we may need to create two new packages, LibCurl4Julia_jll.jl and LibCurl4Julia.jl, in order to include only the functionality needed by julia.
But will there be a shared library conflict or symbol conflict if one loads both LibCurl4Julia.jl and LibCURL.jl?
I understand mbedTLS is problematic, and since this HTTP/3 (and QUIC) library (which we likely want to support anyway) uses BoringSSL, I think it might be a good replacement:
https://github.com/litespeedtech/lsquic
Actually I think BoringSSL should be in an external JLL package, will not be needed by Julia (only Pkg), so the main message is dropping mbedTLS (that's also an unneeded dependency).
[Note, HTTP/3 is already a standard, and the standard to support, much faster, doesn't use TCP. Might also be very helpful for Pkg? Is when downloading many streams.]