Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Technically constrain root CA #75

Open
ghost opened this issue Aug 21, 2016 · 16 comments
Open

Technically constrain root CA #75

ghost opened this issue Aug 21, 2016 · 16 comments

Comments

@ghost
Copy link

ghost commented Aug 21, 2016

In the current form (from what I understand anyway) is that the root CA could be used to MITM HTTPS and other TLS connections that use the system certificate store (e.g. Google Chrome, iOS Safari) transparently if the box were to get popped (or your friend isn't one).

If the root were technically constrained there'd be less of a possibility to do damage to stacks that support the constraints if the private key were obtained.

Here's a selection of the constraints that could possibly be used but I'm sure I've missed or used some incorrectly:

  • Basic Constraints, pathlen:0 - This prevents a subordinate/intermediate CA from being created under the root CA
  • Name Constraints: This could be used to only allow issuance to the IP address of the server (permit: IP:<server>) This would probably affect client certificate issuance too but a randomly generated reserved "DNS name" might work for the permit side such as DNS:<uuid4> allowing <client name>.<uuid4> to be valid
  • Extended Key Usage: serverAuth, clientAuth, OCSPSigning(?)
@ghost ghost mentioned this issue Aug 21, 2016
@ghost
Copy link
Author

ghost commented Aug 21, 2016

On macOS it looks like you can manually mark the root CA as not trusted and still have it work for the VPN connection (deleting the CA stops the connection from proceeding as expected)

In Keychain Access.app I opened the root and set Trust -> When using this certificate: to Never Trust. Unfortunately, iOS and presumably other platforms don't expose this setting or may refuse to connect if set

@ghost
Copy link
Author

ghost commented Aug 21, 2016

Looks like macOS and iOS (general release, haven't verified betas) don't implement nameConstraints 😠

OpenSSL 1.0+ and Firefox seem to. Don't have anything else to test with

@dguido dguido added the bounty label Nov 25, 2016
@dguido
Copy link
Member

dguido commented Nov 25, 2016

$500 bounty! Submit a pull request and email dan@trailofbits.com to claim it. Partial solutions may be rewarded.

@FiloSottile
Copy link

Wouldn't it be a simple, bare minimum mitigation to password-protect the CA private key? Or even better offer a mode in which it never touches the disk and then is destroyed?

The former doesn't help if the attacker waits for a users update, and neither help if a third party sets up a server for you, but this is a pretty big exposure increase. For instance, me myself I'd rather use a public wifi w/o VPN than allow a server to MitM my TLS connections.

@FiloSottile
Copy link

The more I think about it the more I believe this warrants a pretty visible disclaimer. The threat model of who routes my traffic is directly informed by my trust in TLS verification.

@dakami
Copy link

dakami commented Dec 12, 2016

There's some deprecated EKU's around IPSec.

The following purposes have been included in a predecessor draft of RFC 3280 and
therefore continue to be registrated by this implementation:

ipsecEndSystem (1.3.6.1.5.5.7.3.5) -- IP security end system
ipsecTunnel (1.3.6.1.5.5.7.3.6) -- IP security tunnel termination
ipsecUser (1.3.6.1.5.5.7.3.7) -- IP security user

Note that these three key usages are deprecated by the PKIX profile for IKE. Instead the
iKEIntermediate extended key usage (1.3.6.1.5.5.8.2.2) may be used in a certificate for
an IPsec end entity. However, iKEIntermediate was also only specified by an internet
draft (draft-ietf-ipsec-pki-req-05.txt) which has not become an RFC. Nevertheless
iKEIntermediate may be required by an IpSec service.

I admit to being a bit confused though, I wasn't under the impression a VPN server needed to also be a trusted root. Or, even if it does (for various deployability purposes), does the private key need to persist? It's not a problem for the client to trust a root cert that only exists to validate one specific leaf.

@dakami
Copy link

dakami commented Dec 12, 2016

Splitting roots between user->server and server->user, where the former lacks ServerAuth and the latter is ephemeral, might work. Even if two roots is banned, one root that's ephemeral, with two intermediates that otherwise meet this design, almost has to work (unless, you know, leaf nodes don't inherit EKU constraints of parent nodes, which I'm sure somebody screwed up).

@dguido
Copy link
Member

dguido commented Dec 12, 2016

Constraining the CA key in a cross-platform way is likely a dead end (https://twitter.com/sleevi_/status/808374227074105344).

There are 2 "easy" solutions available:

  1. Rather than store the CA privkey online on the server to aid in ease of use and maintenance, we can generate the certificates on the client building the Algo server and leave the privkey there. This means you now have a hot potato to either store or delete on your local desktop.

  2. We can keep everything as-is with one additional question for the user: Do you want to ever update the users on the server? If yes, keep the CA privkey. If no, delete the CA privkey. With appropriate warnings of course.

I think #1 is the right long term solution, and I think #2 is the right hot-patch we can do today.

@dguido
Copy link
Member

dguido commented Dec 12, 2016

@gunph1ld I think the simplest immediate "fix" for this issue is to generate a random password for the CA privkey during the install process and print it to standard out. The update script will have to be changed to accept a password too.

I'll file a new ticket for generating the keys on the client, rather than the server.

@dguido
Copy link
Member

dguido commented Jan 2, 2017

Hey all, just a note to catch everyone up on our efforts to resolve this issue.

#75 merged in a randomly generated password for the CA private key. For a user that never runs update-users or otherwise decrypts the CA key after deployment, the key is no longer available for VPS company employees to potentially snoop on. This was committed to master, so this has been the case for every Algo VPN server deployed since mid-December.

#169 moves the CA generation process to the client, but it has not been merged yet because we're looking for more reviewers. We plan to make ephemeral generation the default and only store the CA private key when specifically requested (if a deployer intends to update the user list later).

@dguido dguido added this to the 1.0 milestone Jan 2, 2017
@dguido
Copy link
Member

dguido commented Feb 6, 2017

The local certificate generation branch was merged into master (#169). All new users of Algo have their certificates generated on the client and, by default, the private key for the root CA is discarded after the server is deployed.

So, you still have to install a root CA with all privileges, however, the private key for it is only available on your client during the installation process. In order to steal it, an attacker would have needed code execution on your client during the installation process. If that were true, then you're situation is unchanged by the installation of an Algo CA -- you are completely hosed.

There are some minor improvements that we can make, like generating the keys in a tmpfs, but an attacker with code exec on your client is likely to find a way around that anyway. We will continue to look for opportunities to take advantage of BasicConstraints as the support for those restrictions gains support on more client platforms (in particular, iOS/macOS).

@dguido dguido removed this from the 1.0 milestone Feb 6, 2017
@dguido
Copy link
Member

dguido commented Apr 1, 2017

Note: Apple may have added a new feature on iOS that allows you to distrust the root CA. See #294.

@ghost
Copy link
Author

ghost commented Apr 1, 2017

Ooh! Nice. I heard but didn't have time to verify that name constraint support was added to the latest iOS and macOS as well

@dguido
Copy link
Member

dguido commented Apr 1, 2017

I may have dialed up the heads of a few departments at Apple to complain immediately after you filed this ticket :-P

@zbeekman
Copy link

It sounds like this issue is resolved with #169, no? Or am I missing something?

@dguido
Copy link
Member

dguido commented Apr 14, 2017

It is mitigated, but the root cause has not been addressed on non-Apple devices.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants