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

Figure out what to do about pinning #58

Closed
hlandau opened this issue Jan 7, 2016 · 13 comments
Closed

Figure out what to do about pinning #58

hlandau opened this issue Jan 7, 2016 · 13 comments
Assignees

Comments

@hlandau
Copy link
Owner

hlandau commented Jan 7, 2016

Currently, a new private key is always generated for each new certificate. This causes issues if using HPKP to pin end entity certificates rather than CA certificates. Should probably find a workable solution for that for people that want to use HPKP.

@hlandau hlandau self-assigned this Jan 7, 2016
@apollo13
Copy link

apollo13 commented Jan 7, 2016

Nothing imo. Pinning (non-CA)Certs is not something you should do. You cannot easily roll over HPKP pinnings with a new cert, you'd need to include the new cert in the old pinning setup and ensure that the user actually visits that site before you roll out the new cert, otherwise the old pin with (only) the old cert will prevent further connections. This sounds especially dangerous with short lived certs and users that do not visit often (ie you carefully have to adjust pin times with cert lifetimes etc…).

@rugk
Copy link

rugk commented Jan 20, 2016

Obviously we talk about HPKP. Static pinning the leaf certs would not be a good idea if you use Let's Encrypt. But you may of course pin the intermediate or root cert.
So here is a guide about how to pin the root.
As I doubt you want to implement pinning of the root (which would just require adding one single header) I'd suggest changing the title of this issue to "Figure out what to do about HTTP Public Key Pinning" or something similar.

Here is a guide by @ScottHelme where he just disables the generation of a new cert at renewals. This is one way to go.

The best thing would be if the client could generate 3 certs the first time you set it up:

  • The first cert is the backup one. The user should place it securely somewhere outside of it's server. (So after this is done it may be deleted from the server)
  • The second cert is for the current use. You can validate it like you already do.
  • The third-cert is stored for renewal later.

So when the (second) cert is singed by the CA and obviously - the user chooses/wants to use HPKP (don't forget to add a scary warning as HPKP can be very bad if something fails or a cert is lost and so on...) - a HPKP header should be added with all hashes of the three certs. The max-age should be set to 60 days.
After 60d the client should remove the second cert and use the pre-generated third one. As it was already included in the header all old users accept it and because of max-age no users get locked out if they have not visited your site for a long time.

Have a look at this visualisation with more information:
table(https://github.com/rugk/ACME_LE_HPKP_Theory/blob/master/screenshot.png)

I think this is a solid concept.

@hlandau
Copy link
Owner Author

hlandau commented Jan 20, 2016

You're conflating certificates and keys here. HPKP pins keys, not certificates. You can pin an end key and reuse it for each renewal. (Currently acmetool always generates a new key, but this could be changed.)

@rugk
Copy link

rugk commented Jan 21, 2016

Yes you can do so. But why not cycle through the keys and certs and use HPKP? (That's the idea behind my comment before)

As I already said Scott explains how you can just disable key regeneration and reuse the key for all certs. However you may still want to use new keys every 90 days as there are also some positive aspects of doing so.

@rugk
Copy link

rugk commented Jan 21, 2016

Although I obviously have to add one thing: To benefit from the security aspects of a key regeneration you might also need to regenerate your backup key from time to time.
But as your backup key might be secured in a better way (not on a productive server) the time may be a bit longer. (What about 120days?)
As this is a manual step you can only say the user should set up a reminder.

@ScottHelme
Copy link

The biggest problem is how to automate this. You would need to generate a new backup key at each renewal to create the pin but then remove the key from the production server for safe storage until the next renewal when it would need to be brought back. I can't see a safe way to automate this. In my example where generating a new key is disabled, you can renew the private key at any interval you wish, as you would have done previously in a manual fashion.

@rugk
Copy link

rugk commented Jan 21, 2016

Yes if you want to store a backup key you usually do not find a way around it.
But if you ignore this backup key and take the thing I've described before you have at least a way to automate this all. If an attacker gains access to your server and deletes all your private keys (or just "takes them away") you of course have a problem.
But possibly you might (manually) do a backup every 60days when the next cert is generated (and pinned).

@ScottHelme
Copy link

I might be getting confused but the backups need to be done ahead of time and included in the header at least the value of max-age before they are used in production. This means you can't generate a new key right away and pin against it, otherwise how would clients who have previously received the PKP header and cached it know about the current private key?

@joneskoo
Copy link
Contributor

Could one use a hook to copy backup of keys to a secure non-local location?
E.g. HTTPS POST to a write-only collector.

Alternatively, I think in multi-server use it makes sense to generate keys
in one place and then distribute keys to servers that need it. DNS
challenge may help here?

Anyway the implementation should not be made complex without good reason;
the point of LE is the long tail of users who previously didn't do TLS, so
logically this is also most important target user group.

If hooks enable complex cases, I suggest a simple, easy-to-understand
implementation + if you like a case example for HKPK for complex case, not
something that complicates tool documentation.
On to 21. tammikuuta 2016 at 23.39, Scott Helme notifications@github.com
wrote:

I might be getting confused but the backups need to be done ahead of time
and included in the header at least the value of max-age before they are
used in production. This means you can't generate a new key right away and
pin against it, otherwise how would clients who have previously received
the PKP header and cached it know about the current private key?


Reply to this email directly or view it on GitHub
#58 (comment).

@rugk
Copy link

rugk commented Jan 22, 2016

@ScottHelme Yes, I know. Of course clients have to generate them before using them. Have a look at my previous comment again where I explained in detail how this might be done.

@joneskoo

the point of LE is the long tail of users who previously didn't do TLS, so logically this is also most important target user group.

As for HPKP this should certainly not be the target group. Because HPKP can be risky and break "everything" if you use it in the wrong way it should only be used by users who know what HPKP is and how it works.

Could one use a hook to copy backup of keys to a secure non-local location? E.g. HTTPS POST to a write-only collector.

If you send your private keys (for HTTPS) over a HTTPS connection which does not use key pinning you do not gain any security advantage with HPKP... 😐

@thomaskonrad
Copy link

Just filed a new issue and didn't see this one, so here's the link for reference. Being able to specify a custom CSR would give the admin the possibility to pin public keys, but of course not in a fully automated way.

@hlandau
Copy link
Owner Author

hlandau commented Jan 25, 2016

I was thinking something more like being able to specify a key in a targetfile.

request:
  key:
    id: [key-id]

This would reuse the existing key with the given ID rather than generating a new one.

@hlandau
Copy link
Owner Author

hlandau commented Jan 30, 2016

With #91 now implemented, I think acmetool does everything it reasonably can in this regard. Closing.

@hlandau hlandau closed this as completed Jan 30, 2016
@hlandau hlandau removed the thinking label Jan 30, 2016
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

6 participants