Skip to content
This repository has been archived by the owner on Sep 1, 2022. It is now read-only.

Rely on a library for TLS and SSL. #3

Closed
anonimal opened this issue Nov 17, 2015 · 15 comments
Closed

Rely on a library for TLS and SSL. #3

anonimal opened this issue Nov 17, 2015 · 15 comments

Comments

@anonimal
Copy link
Collaborator

The current implementation is questionable and not realistic. We need to look at library options.

@fluffypony
Copy link
Contributor

Here are the three options, as I see them:

  • mbed TLS (was previously called PolarSSL)
  • LibreSSL
  • Botan

From a licensing perspective, mbed TLS may be problematic as it's Apache / GPLv2+ dual licensed (and some commercial license as well). LibreSSL is much less icky. Botany is the least icky, as it's a very permissive simplified BSD license (2-clause).

@anonimal
Copy link
Collaborator Author

Is there a particular reason not to use Boost.asio's OpenSSL implementation (since we're already using Boost)? We only need SSL for reseed but Java I2P has SSL support for I2CP and I think that functionality should be extended to Kovri (apps could then connect to Kovri via SSL or HTTPS, for example). I'm fine with LibreSSL or Botan but I need more time review what else we could use from Botan since SSL alone may be overkill.

@fluffypony
Copy link
Contributor

@anonimal mostly the security risks attached to OpenSSL. Buuuut LibreSSL is a drop-in replacement (it's forked from OpenSSL) so we should be able to go that route, although Botan is (perhaps) preferable as it is WAY more than just TLS, it's a general purpose crypto library. So we can (possibly) drop the crypto++ dep and switch to Botan, and get TLS for free.

@anonimal
Copy link
Collaborator Author

So we can (possibly) drop the crypto++ dep and switch to Botan, and get TLS for free.

I like Botan. In our first meeting, I believe I mentioned a complete overhaul to Botan but the idea was shot down (by someone else). Dropping Crypto++ in exchange for Botan would be no easy task (with this codebase) but I am up for the challenge. If we decide to do this, I forsee a long weird-spell of having two crypto libs when only one would suffice.

I can't do this alone, but I can at least start working on reseed. Help is wanted and more voices/eyes/input are needed! @majestrate care to get down n' dirty?

@anonimal anonimal added the major label Nov 23, 2015
@anonimal
Copy link
Collaborator Author

If @majestrate can comment with a paste verifying TLS-related memory corruptions, I'll label as critical. Either way, this is borderline critical.

@majestrate
Copy link
Contributor

https://github.com/monero-project/kovri/blob/master/core/Reseed.cpp#L207
https://github.com/monero-project/kovri/blob/master/core/Reseed.cpp#L279
https://github.com/monero-project/kovri/blob/master/core/Reseed.cpp#L395
https://github.com/monero-project/kovri/blob/master/core/Reseed.cpp#L862

4 potential BoF in TLS implementation that are obvious, probably lots more elsewhere.

I want to abstract the crypto parts so that we can change what library is used if someone wanted to without changing the rest of the code.

@anonimal
Copy link
Collaborator Author

Oh, those buggers. Labeling as critical because (at the least) local overruns seem trivial to execute.

@anonimal
Copy link
Collaborator Author

In our most recent meeting (see #47), we decided to go with LibreSSL. What we didn't discuss was the issue of packaging. On Arch (please check your distro) libressl conflicts with openssl; therefore a complete removal of openssl is needed. This may be problematic for users re: packing and satisfying dependencies, especially Tor users.

We need to consider our packaging options or simply bundle libressl (or was it implied that we would be bundling?).

@anonimal
Copy link
Collaborator Author

anonimal commented Dec 2, 2015

2015-12-02 02:21:35     +psi    [01:56:33] boost::asio has libssl support baked in
2015-12-02 02:22:46     &anonimal        I know, I proposed using that long ago. But if we're going to go through the headache of libressl, why not use libtls?...
2015-12-02 02:59:28     &anonimal        And unless we can figure out an easy way to keep libressl updated on peoples' machines, let alone give them a reason to use libressl outside of our app, I'm starting to rethink the benefits over openssl.
2015-12-02 03:00:02     &anonimal        Do we expect people to build their own libressl and keep it updated? AFACT, most package managers do not have libressl.
2015-12-02 03:00:27     &anonimal        And if we bundle, are we expected to release upon every libressl release?
2015-12-02 03:01:31     &anonimal        Most importantly: if we bundle, how can we guarantee that people will stay updated with our app? How dangerous to be using our app with a vulnerable libressl when they expected their package manager to update for them.
2015-12-02 03:03:43     &anonimal        Libressl's openssl api is still vulnerable to developer error; thus the reason for libtls. IMHO, developer error is are biggest threat, not some random 0day.

Even if self-contained within kovri, what I meant about 'staying updated' was that since we don't have a self-updating mechanism, and even if our app is secure; if libressl has a 0day or vuln, our users would still be vulnerable because A) they don't stay up-to-date or B) even after they get the news about a libressl vuln, they forget that we bundle libressl - and thus don't update kovri.

Not staying up-to-date would hurt them regardless, but this extra dependency does not help re: that situation.

So, how should we proceed?

@fluffypony
Copy link
Contributor

For the benefit of anyone else reading this, libtls is LibreSSL, just with a new API. Also, LibreSSL is OpenSSL, but taken by some of the OpenBSD developers and reworked to be more secure and less issue-prone. We can all agree on rejecting OpenSSL because of the security risks, but what to do beyond that remains in question.

There are a few options, such as GnuTLS and mbedTLS (formerly PolarSSL), that have to be rejected outright due to their licensing. We want a permissive license, as we are encouraging integration, and we don't want to prevent that integration from happening in closed-source projects or in projects that are made available on the various app stores (which may impose additional restrictions, thus making them incompatible with the GPL). Incidentally, OpenSSL does not suffer from this problem, as their dual-license has the SSLeay license as an option, which is pretty permissive (similar to the BSD 4-clause).

This really brings us down to two options: libtls (ie. LibreSSL), or Botan, both of which are provided under permissive licenses. In previous discussions we leaned away from Botan because we wanted to use LibreSSL as a drop-in replacement for OpenSSL. However, if we're going the libtls route, then we will be reimplementing anyway, which opens up the Botan discussion again.

Both Botan and LibreSSL provide much of the same functionality, and LibreSSL has the advantage of broader support, it being used as the default TLS provider on OS X since El Capitan (10.11). On the other hand, Botan is C++ not C, and provides things LibreSSL doesn't (like support for Curve25519) so there may be advantage in using it. Either way, there is an over-arching risk factor for both of these libraries: how do we protect our users running bundled binaries?

Obviously the guy that compiles Kovri from scratch and has it dynamically linked is in a better position, as he merely needs to update his installed packages and he's ok. But Bob the Windows User is not so lucky. Additionally, if Kovri is integrated into a bunch of different applications that Bob has installed that all contain a statically linked version of Kovri, he might have all manner of TLS libs scattered on his system. Thus I propose we do the following:

  1. We implement that Kovri-as-a-stub scheme I've spoken about before, whereby any application that instantiates a Kovri router via a library call will either launch a new independent "stub", or will attach to an existing, running stub.
  2. Instead of simply evaluating whether a stub is running or not, the newly instantiated call should determine what version of the stub is running. If the calling application contains a version of Kovri that is older or the same, then simply use that running stub that is already connected to the I2P network. However, if the calling application contains a newer version of Kovri, it should notify the running stub that it is going to take over, and that stub can shut down.
  3. Once the new stub is fully connected to the I2P network, the old stub can notify its callers of the new port / socket / whatever they must use, and then it shuts itself down.

The advantage of this scheme is that Bob the Windows User can run a 5 year old version of an application that has NEVER received updates to its statically linked Kovri, but merely by downloading and running a new version of Kovri Control (a hypothetical application that has a statically linked Kovri library, and provides support for running it as a daemon / service, plus provides the web panel and maybe a system tray icon) he can ensure that his old application is using a "safe" version of Kovri.

Now all we have to do on top of that is have an eepsite that responds with the latest version / release date, and then Kovri Control or similar can irritate him to update his out-of-date application.

@anonimal
Copy link
Collaborator Author

anonimal commented Dec 2, 2015

While we wait for @majestrate's response...

Obviously the guy that compiles Kovri from scratch and has it dynamically linked is in a better position, as he merely needs to update his installed packages and he's ok.

That's part of the problem: libressl is not shipped with most (almost all) distros outside of OSX so one must build it themselves and be responsible for keeping it updated becuase their package managers will be clueless. What a hassle. This also provides opportunities for end-user error.

JFTR: I've never been against openssl, I don't think I've ever said I was (if so, please let me know). In a perfect world, I obviously wouldn't use it, but considering our need for TLS is both very little and rudimentary, I see a greater danger in us spending more time talking about not using openssl (and not focusing on more important issues) than in actually using openssl. This ticket is only marked critical because of the terrible implementation we have now.

We only need TLS for reseed. Connect -> download .su3 -> disconnect. That's it. After that, any use of TLS would be an added bonus and not critical nor a core function of I2P.

We implement that Kovri-as-a-stub scheme I've spoken about before, whereby any application that instantiates a Kovri router via a library call will either launch a new independent "stub", or will attach to an existing, running stub.

Tagging your 'stub' proposal to #34.

Now all we have to do on top of that is have an eepsite that responds with the latest version / release date, and then Kovri Control or similar can irritate him to update his out-of-date application.

Good idea. I think this can be done without a 'stub' approach too. Tagging to #48.

@fluffypony
Copy link
Contributor

Question: is it just the initial bootstrap seed that needs it, and subsequent reseeds can happen from an eepsite?

@anonimal
Copy link
Collaborator Author

anonimal commented Dec 2, 2015

Yes, the initial bootstrap should TLS and, technically, when we run low on peers, we reseed again; but that shouldn't happen very often, or in some cases doesn't happen at all. Bottom-line: we reseed every time the router starts.

As for the 'low-on-peers' scenario, if we tried to reseed via eepsite, AFAICT it may fail because we'd be low on peers to begin with so we would have to clearnet reseed as a backup. More imporantly, we should observe java I2P's defenses for mitigating bootstrap attacks:

  • Changing the reseed task to fetch a subset of RouterInfos from each of several reseed sites rather than using only a single site
  • Creating an out-of-network reseed monitoring service that periodically polls reseed websites and verifies that the data are not stale or inconsistent with other views of the network

@anonimal
Copy link
Collaborator Author

anonimal commented Dec 8, 2015

bc42f4c brings us closer to resolving this ticket.

2015-12-08 13:21:26     &anonimal       Pushed https://github.com/monero-project/kovri/commit/bc42f4c4d3c1c4a26f143bd34dcf463b4cf739b2
2015-12-08 13:21:51     &anonimal       Please $ rm -fr ~/.kovri/ && cd build/ && rm -f CMakeCache.txt && cmake ../ && make
2015-12-08 13:24:16     &anonimal       Refactoring su3 certificate handling opened up a huge can of worms, so I didn't include that in the commit.
2015-12-08 13:24:49     &anonimal       psi: ^ I found myself touching waaaaaaaay too much crypto for that so I wanted to stay clear until I touched base with you.
2015-12-08 13:26:50     &anonimal       Is there any chance you can push crypto_refactor to your fork so I can review what's been done (so I don't play with things that you've already axed)?

@anonimal
Copy link
Collaborator Author

JFTR: for now, we are using OpenSSL where it is needed. See #30 (comment) for a follow-up on my previous comment and why I'm closing this ticket as resolved.

anonimal referenced this issue in anonimal/kovri Jul 14, 2016
anonimal referenced this issue in anonimal/kovri Aug 9, 2016
Style: remove file guidelines from guide. Refs monero-project#280
@moneromooo moneromooo mentioned this issue Oct 2, 2016
1 task
anonimal pushed a commit that referenced this issue Jul 3, 2018
anonimal added a commit that referenced this issue Jul 5, 2018
Build: include Boost before Boost.Python
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants