Skip to content

Allow reuse of private keys#4610

Closed
schoen wants to merge 3 commits intomasterfrom
key-path
Closed

Allow reuse of private keys#4610
schoen wants to merge 3 commits intomasterfrom
key-path

Conversation

@schoen
Copy link
Contributor

@schoen schoen commented May 3, 2017

This PR adds an option to allow the reuse of a specified existing private key when requesting a new certificate (other than via CSR, which is already an alternative which can achieve this function with or without direct access to the private key material).

Fixes #3788 and #3709.

@schoen
Copy link
Contributor Author

schoen commented May 3, 2017

This does currently work to reuse a private key.

Four remaining problems or issues with this code (mostly all CLI design matters):

  • Super-confusingly, there is already an option called --key-path which does something totally different! Hence I have called this one --privkey-path. Will this forever mire users in hopeless confusion between the two options? Any way out? Should we make --privkey-path have either meaning (even though they're quite different) depending on the context?

  • Currently the CLI default None overrides the renewal config but it should not. Hence the option disappears on a subsequent renewal. I need to fix the lineage reconstitution to prevent this from happening.

  • There nonetheless needs to be a way to intentionally turn this off, which should override the renewal config and cause reuse_key to be removed from the renewal config. Should this be called --no-privkey-path or --new-key or --new-privkey? I assume we shouldn't try to get the parser to recognize the special string None as the Python value None, which would be ugly and confusing.

  • It turns out that this functionality is still a bit confusing if you want to make a new key on first run but then reuse it afterward (for renewals). The reason is that the key-to-reuse doesn't exist yet on first run! So right now if you wanted to pin a key, you would either need to make it yourself with openssl genrsa and then keep your non-lineage copy around indefinitely, or you would need to make a new lineage and then immediately renew it with --force-renew --privkey-path /etc/letsencrypt/live/example.com/privkey.pem to give the renewal privkey_path something specific to refer to. Although some users who want to pin keys do have an existing copy of the key they want to pin, some people would prefer for Certbot to create the key on first run and then reuse it on renewal, and I'm not exactly sure what the UI for that common use case should look like.

@bmw
Copy link
Member

bmw commented May 5, 2017

Super-confusingly, there is already an option called --key-path which does something totally different! Hence I have called this one --privkey-path. Will this forever mire users in hopeless confusion between the two options? Any way out? Should we make --privkey-path have either meaning (even though they're quite different) depending on the context?

Do you think we could get away with just reusing --key-path here? Currently, the help for --key-path says:

  --key-path KEY_PATH   Path to private key for cert installation or
                        revocation (if account key is missing) (default: None)

Looking at the code, this seems accurate. This means the flag is only currently used for the install and revoke subcommands. The way you're using --privkey-path only affects the certonly, run, and renew subcommands. Since these different usages don't interact, I think we could get away with a single flag if we wanted. I personally like that approach better as it prevents people from accidentally using the wrong flag.

Currently the CLI default None overrides the renewal config but it should not. Hence the option disappears on a subsequent renewal. I need to fix the lineage reconstitution to prevent this from happening.

Briefly playing with this, it didn't happen to me. Keep in mind that renew is the only subcommand that reuses values from a renewal configuration file. If you obtain a new cert using certonly, the renewal conf file is completely ignored and overwritten with the values used to obtain the cert you just got with certonly.

There nonetheless needs to be a way to intentionally turn this off, which should override the renewal config and cause reuse_key to be removed from the renewal config. Should this be called --no-privkey-path or --new-key or --new-privkey? I assume we shouldn't try to get the parser to recognize the special string None as the Python value None, which would be ugly and confusing.

For better or worse, we already treat None specially. The user can also work around this problem by just deleting the line from their renewal conf file.

Looking at the values we currently save in a renewal config, we have the problem with some of these as well. While this isn't the best UX, we can improve it in the future with a common approach to flags like this. My preference is to not add a --no-* flag and stick with the current approach for now.

It turns out that this functionality is still a bit confusing if you want to make a new key on first run but then reuse it afterward (for renewals). The reason is that the key-to-reuse doesn't exist yet on first run! So right now if you wanted to pin a key, you would either need to make it yourself with openssl genrsa and then keep your non-lineage copy around indefinitely, or you would need to make a new lineage and then immediately renew it with --force-renew --privkey-path /etc/letsencrypt/live/example.com/privkey.pem to give the renewal privkey_path something specific to refer to. Although some users who want to pin keys do have an existing copy of the key they want to pin, some people would prefer for Certbot to create the key on first run and then reuse it on renewal, and I'm not exactly sure what the UI for that common use case should look like.

This is similar to the argument I initially made for --reuse-key here. As I stated there, the user can also manually edit their renewal conf file to get this effect. While I agree it's not the best UX, I don't think we need to block this PR on that functionality. We can add it in the future as/if it's requested by users.

@bmw
Copy link
Member

bmw commented Jun 30, 2017

@schoen, are you still planning on working on this?

@schoen
Copy link
Contributor Author

schoen commented Jun 30, 2017

@bmw, yes, I am. Thanks for the reminder.

@Kraeutergarten
Copy link

Any update?

@voidzero
Copy link

@schoen could you please let us know how far along this is? I'd like to reuse my private key when renewing one of my certificates.

@jschlyter
Copy link

@schoen, any updates on this issue?

@schoen
Copy link
Contributor Author

schoen commented Apr 26, 2018

Planning to replace this with #5901, which does use a simpler approach different from what I talked about with @bmw last year (just --reuse-key rather than specifying --key-path). @ohemorange and I concluded that users will be much more confused by specifying --key-path from /etc/letsencrypt/live for this purpose if they don't already know what that is.

@schoen
Copy link
Contributor Author

schoen commented May 3, 2018

Please merge #5901 instead of this PR. However, we should eventually also provide a way to use an existing non-Certbot-created key while also enrolling a cert for renewal (as even with the current version #5901, the only way to do that is with --csr, which doesn't enroll for renewal).

@schoen schoen closed this May 3, 2018
@zoracon zoracon deleted the key-path branch February 28, 2022 20:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants