Support HPKP #55

Closed
opened 2025-12-29 00:23:38 +01:00 by adam · 20 comments
Owner

Originally created by @basbebe on GitHub (Feb 10, 2016).

I would be a great addition if this script also pu out something which could be used in HKPK headers, e.g. with hooks.
For an example see
https://calomel.org/lets_encrypt_client.html

Originally created by @basbebe on GitHub (Feb 10, 2016). I would be a great addition if this script also pu out something which could be used in HKPK headers, e.g. with hooks. For an example see https://calomel.org/lets_encrypt_client.html
adam closed this issue 2025-12-29 00:23:38 +01:00
Author
Owner

@lukas2511 commented on GitHub (Feb 10, 2016):

You should be able to do that inside the deploy_cert hook. I don't really see any benefit of having this directly inside of this script.

@lukas2511 commented on GitHub (Feb 10, 2016): You should be able to do that inside the deploy_cert hook. I don't really see any benefit of having this directly inside of this script.
Author
Owner

@basbebe commented on GitHub (Feb 10, 2016):

Accepted.
I'll try to learn how to do this.

@basbebe commented on GitHub (Feb 10, 2016): Accepted. I'll try to learn how to do this.
Author
Owner

@basbebe commented on GitHub (Feb 11, 2016):

This is what I'm trying out at the moment.
I have yet to find out how to automatically replace the parts in my server config though…

#!/bin/bash

function deploy_cert {
    local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" CHAINFILE="${4}"
    hpkp="$(openssl rsa -in ${BASEDIR}/certs/${DOMAIN}/privkey.pem -outform der -pubout 2>/dev/null | openssl dgst -sha256 -binary | openssl enc -base64)"
  printf "\nHTTP Key Pinning\n   pin-sha256=\"$hpkp\";\n"
}

HANDLER=$1; shift; $HANDLER $@
@basbebe commented on GitHub (Feb 11, 2016): This is what I'm trying out at the moment. I have yet to find out how to automatically replace the parts in my server config though… ``` #!/bin/bash function deploy_cert { local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" CHAINFILE="${4}" hpkp="$(openssl rsa -in ${BASEDIR}/certs/${DOMAIN}/privkey.pem -outform der -pubout 2>/dev/null | openssl dgst -sha256 -binary | openssl enc -base64)" printf "\nHTTP Key Pinning\n pin-sha256=\"$hpkp\";\n" } HANDLER=$1; shift; $HANDLER $@ ```
Author
Owner

@germeier commented on GitHub (Feb 11, 2016):

Shouldn't an include directive do the trick? This way you only need to generate a file with the HKPK config.

@germeier commented on GitHub (Feb 11, 2016): Shouldn't an include directive do the trick? This way you only need to generate a file with the HKPK config.
Author
Owner

@basbebe commented on GitHub (Feb 11, 2016):

yes, that might be a good idea!
https://github.com/lukas2511/letsencrypt.sh/issues/131

@basbebe commented on GitHub (Feb 11, 2016): yes, that might be a good idea! https://github.com/lukas2511/letsencrypt.sh/issues/131
Author
Owner

@basbebe commented on GitHub (Feb 18, 2016):

How about having an option in the config and making this a part of lets encrypt.sh?
add a file with the HKPK hash for embedding it somewhere with a hook!

@basbebe commented on GitHub (Feb 18, 2016): How about having an option in the config and making this a part of lets encrypt.sh? add a file with the HKPK hash for embedding it somewhere with a hook!
Author
Owner

@lukas2511 commented on GitHub (Feb 18, 2016):

And create that file in every config format for every webserver out there? No thanks.

@lukas2511 commented on GitHub (Feb 18, 2016): And create that file in every config format for every webserver out there? No thanks.
Author
Owner

@basbebe commented on GitHub (Feb 18, 2016):

The hash is the same, it is just different for RSA and ECDSA certificates.
https://calomel.org/http_public_key_pinning_hpkp.html
Then the hash can be opened and handled by the users.
No need to adapt to any webservers.

@basbebe commented on GitHub (Feb 18, 2016): The hash is the same, it is just different for RSA and ECDSA certificates. https://calomel.org/http_public_key_pinning_hpkp.html Then the hash can be opened and handled by the users. No need to adapt to any webservers.
Author
Owner

@lukas2511 commented on GitHub (Feb 18, 2016):

The config file format for every webserver out there is different.
If this would be a feature I'd either have to decide on which servers to support or support them all.
A few config-syntax examples are listed in the url you posted in the first message of this conversation:

## apache configuration
Header set public-key-pins "pin-sha256=\"FdFOH8lP8ipUaas4cnj92Ifk81feECxL/RGDps3otfw=\"; pin-sha256=\"LeSTjTfnibfKHJmDfIGoWrE7JwFWMUy/+3Ft55sBTGs=\"; max-age=604800; includeSubDomains"

## nginx configuration
add_header public-key-pins 'pin-sha256="FdFOH8lP8ipUaas4cnj92Ifk81feECxL/RGDps3otfw="; pin-sha256="LeSTjTfnibfKHJmDfIGoWrE7JwFWMUy/+3Ft55sBTGs="; max-age=604800; includeSubDomains';

## h2o configuration
header.add: "public-key-pins: pin-sha256=\"FdFOH8lP8ipUaas4cnj92Ifk81feECxL/RGDps3otfw=\"; pin-sha256=\"LeSTjTfnibfKHJmDfIGoWrE7JwFWMUy/+3Ft55sBTGs=\"; max-age=604800; includeSubDomains"

You should easily be able to do that for your specific webserver configuration in a hook script, but this will never be a feature of this script.

@lukas2511 commented on GitHub (Feb 18, 2016): The config file format for every webserver out there is different. If this would be a feature I'd either have to decide on which servers to support or support them all. A few config-syntax examples are listed in the url you posted in the first message of this conversation: ``` ## apache configuration Header set public-key-pins "pin-sha256=\"FdFOH8lP8ipUaas4cnj92Ifk81feECxL/RGDps3otfw=\"; pin-sha256=\"LeSTjTfnibfKHJmDfIGoWrE7JwFWMUy/+3Ft55sBTGs=\"; max-age=604800; includeSubDomains" ## nginx configuration add_header public-key-pins 'pin-sha256="FdFOH8lP8ipUaas4cnj92Ifk81feECxL/RGDps3otfw="; pin-sha256="LeSTjTfnibfKHJmDfIGoWrE7JwFWMUy/+3Ft55sBTGs="; max-age=604800; includeSubDomains'; ## h2o configuration header.add: "public-key-pins: pin-sha256=\"FdFOH8lP8ipUaas4cnj92Ifk81feECxL/RGDps3otfw=\"; pin-sha256=\"LeSTjTfnibfKHJmDfIGoWrE7JwFWMUy/+3Ft55sBTGs=\"; max-age=604800; includeSubDomains" ``` You should easily be able to do that for your specific webserver configuration in a hook script, but this will never be a feature of this script.
Author
Owner

@basbebe commented on GitHub (Feb 18, 2016):

I thought just about the hash, not the whole header implementation.
FdFOH8lP8ipUaas4cnj92Ifk81feECxL/RGDps3otfw=
Then it could be included in the server config dynamically or manipulated with a script.

@basbebe commented on GitHub (Feb 18, 2016): I thought just about the hash, not the whole header implementation. `FdFOH8lP8ipUaas4cnj92Ifk81feECxL/RGDps3otfw=` Then it could be included in the server config dynamically or manipulated with a script.
Author
Owner

@lukas2511 commented on GitHub (Feb 18, 2016):

Just use hook scripts... doing it this way just makes everything a lot more complicated.

@lukas2511 commented on GitHub (Feb 18, 2016): Just use hook scripts... doing it this way just makes everything a lot more complicated.
Author
Owner

@basbebe commented on GitHub (Feb 18, 2016):

OK.
I just thought it would be nice to have a file symlinking to the latest version, just like the keys and the certificates. Thought it might be helpful for others as well.

@basbebe commented on GitHub (Feb 18, 2016): OK. I just thought it would be nice to have a file symlinking to the latest version, just like the keys and the certificates. Thought it might be helpful for others as well.
Author
Owner

@basbebe commented on GitHub (Feb 26, 2016):

I'm still pursuing this.

I would need to have ${KEY_ALGO} and ${timestamp} passed to the hook for this to work.
Or it could become integrated into letsencrypt.sh and become an option.

Depending on which option you would prefer I would try to make a pull request.

This is what I have so far:

echo " + Generating HPKP information..."

case "${KEY_ALGO}" in
      rsa) hpkp="$(_openssl rsa -in ${KEYFILE} -outform der -pubout 2>/dev/null | openssl dgst -sha256 -binary | openssl enc -base64)";;
      prime256v1|secp384r1) hpkp="$(_openssl ec -in ${KEYFILE} -outform der -pubout 2>/dev/null | openssl dgst -sha256 -binary | openssl enc -base64)";;
    esac

echo $hpkp >> "${BASEDIR}/certs/${DOMAIN}/hpkp-${timestamp}.txt"
ln -sf "${BASEDIR}/certs/${DOMAIN}/hpkp-${timestamp}.txt" "${BASEDIR}/certs/${DOMAIN}/hpkp.txt"
@basbebe commented on GitHub (Feb 26, 2016): I'm still pursuing this. I would need to have `${KEY_ALGO}` and `${timestamp}` passed to the hook for this to work. Or it could become integrated into letsencrypt.sh and become an option. Depending on which option you would prefer I would try to make a pull request. This is what I have so far: ``` echo " + Generating HPKP information..." case "${KEY_ALGO}" in rsa) hpkp="$(_openssl rsa -in ${KEYFILE} -outform der -pubout 2>/dev/null | openssl dgst -sha256 -binary | openssl enc -base64)";; prime256v1|secp384r1) hpkp="$(_openssl ec -in ${KEYFILE} -outform der -pubout 2>/dev/null | openssl dgst -sha256 -binary | openssl enc -base64)";; esac echo $hpkp >> "${BASEDIR}/certs/${DOMAIN}/hpkp-${timestamp}.txt" ln -sf "${BASEDIR}/certs/${DOMAIN}/hpkp-${timestamp}.txt" "${BASEDIR}/certs/${DOMAIN}/hpkp.txt" ```
Author
Owner

@lukas2511 commented on GitHub (Feb 29, 2016):

creating a textfile like this would be okay.

on the deploy_cert hook i'd then like to just have the timestamp added, so that it can be used for future features and we don't need to add more options all the time.

@lukas2511 commented on GitHub (Feb 29, 2016): creating a textfile like this would be okay. on the deploy_cert hook i'd then like to just have the timestamp added, so that it can be used for future features and we don't need to add more options all the time.
Author
Owner

@lukas2511 commented on GitHub (Jan 29, 2017):

This should be doable in the deploy_cert hook by now, everything that is needed for generating those config entries is exported and there even is support for key rollover now, making this actually useful.

@lukas2511 commented on GitHub (Jan 29, 2017): This should be doable in the `deploy_cert` hook by now, everything that is needed for generating those config entries is exported and there even is support for key rollover now, making this actually useful.
Author
Owner

@vi commented on GitHub (Feb 7, 2017):

Maybe there should be a mode with fixed private key and CSR to have a permanent pin?

Like with --signcsr mode, but employing /var/lib/dehydrated/certs/ structure (with privkey.pem and cert.csr as regular files, not symlinks)?

Maybe the PRIVATE_KEY_RENEW config options should be better advertised/documented?

@vi commented on GitHub (Feb 7, 2017): <s>Maybe there should be a mode with fixed private key and CSR to have a permanent pin? Like with `--signcsr` mode, but employing `/var/lib/dehydrated/certs/` structure (with `privkey.pem` and `cert.csr` as regular files, not symlinks)? </s> Maybe the `PRIVATE_KEY_RENEW` config options should be better advertised/documented?
Author
Owner

@txr13 commented on GitHub (Feb 7, 2017):

@vi Was having that option written up in the config file (which is linked to from the readme) not sufficient?

@txr13 commented on GitHub (Feb 7, 2017): @vi Was having that option written up in the `config` file (which is linked to from the readme) not sufficient?
Author
Owner

@vi commented on GitHub (Feb 7, 2017):

I don't see it in the README.

I discovered it from the source code after already deploying --signcsr-based scheme.

And finally only now I found this.

Also Debian's default /etc/dehydrated/config looks much shorter...

@vi commented on GitHub (Feb 7, 2017): I don't see it in the [README](https://github.com/lukas2511/dehydrated/blob/master/README.md). I discovered it from the source code after already deploying `--signcsr`-based scheme. And finally only now I found [this](https://github.com/lukas2511/dehydrated/blob/master/docs/examples/config). Also Debian's default `/etc/dehydrated/config` looks much shorter...
Author
Owner

@txr13 commented on GitHub (Feb 7, 2017):

From README.md:

Have a look at docs/examples/config to get started, copy it to e.g. /etc/dehydrated/config and edit it to fit your needs.

From docs/examples/config:

#Regenerate private keys instead of just signing new certificates on renewal (default: yes)
#PRIVATE_KEY_RENEW="yes"

@txr13 commented on GitHub (Feb 7, 2017): From `README.md`: > Have a look at docs/examples/config to get started, copy it to e.g. /etc/dehydrated/config and edit it to fit your needs. From `docs/examples/config`: >#Regenerate private keys instead of just signing new certificates on renewal (default: yes) >#PRIVATE_KEY_RENEW="yes"
Author
Owner

@vi commented on GitHub (Feb 7, 2017):

Yes, now I found.

@vi commented on GitHub (Feb 7, 2017): Yes, now I found.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/dehydrated#55