smallstep / certificates

🛡️ A private certificate authority (X.509 & SSH) & ACME server for secure automated certificate management, so you can use TLS everywhere & SSO for SSH.
https://smallstep.com/certificates
Apache License 2.0
6.66k stars 433 forks source link

Customized backdate has no effect on ACME provisioner #927

Open GermanCoding opened 2 years ago

GermanCoding commented 2 years ago

Subject of the issue

Customized backdates seem to have no effect on ACME provisioners. I've attempted to increase the default backdate duration from it's hardcoded value of 1 minute to about 1 hour (like LE does), because there are devices out there that can't always keep their clock accurate to +- 1 minute.

I've therefore set a custom backdate value in ca.json which does get applied when I use my JWK provisioner. However, when requesting certificates via ACME, they're always backdated by 1 minute, not by my value set in ca.json

Your environment

Steps to reproduce

  1. Setup a new smallstep ca with both a JWK and an ACME provisioner
  2. Set a custom backdate value like this:

# ca.json

{
[snip]
        "authority": {
                "provisioners": [
                        {
                                "type": "ACME",
                                "name": "my-acme-provisioner",
                                "forceCN": true,
                               [snip]
                        },
                        {
                                "type": "JWK",
                               [snip]
                        }
                ],
                "template": {},
                "backdate": "1h0s"
        },
[snip]
}
  1. Issue a certificate via the JWK provisioner, do not specify a NotBefore value. Compare the NotBefore on the issued certificate with the current time.
  2. Issue a certificate via ACME provisioner via any ACME client without specifying custom NotBefore values (if the client even supports it). Compare the NotBefore on the issued certificate with the current time.

Expected behaviour

Both certificates are backdated by ~1 hour.

Actual behaviour

The JWK-issued certificate is backdated by ~1 hour, while the ACME-issued certificate is backdated by ~1 minute.

Additional context

The ACME protocol can set customized NotBefore/NotAfter fields in the order. I haven't tested if smallstep supports these. For my tests I was using acme.sh 3.0.4, which to my knowledge does not set NotBefore/NotAfter fields in the ACME order (unlesss explicitly configured to do so), so the ACME order should have used the default backdate specified in ca.json, just like the JWK provisioner.

It looks like the ACME provisioner always uses it's hardcoded backdate value of 1 min and ignores whatever was set in ca.json.

maraino commented 2 years ago

The problem seems to be that the order is always stored with a notBefore and notAfter, even if the client didn't request any, and it has a hardcoded backdate of 1m: https://github.com/smallstep/certificates/blob/ea084d71fb7b2ab8c2e3fc81e20e84ee49f6cc88/acme/api/order.go#L174-L184

Then the Sign operation has those options set, and they are used instead of using the current time minus the configured backdate. https://github.com/smallstep/certificates/blob/ea084d71fb7b2ab8c2e3fc81e20e84ee49f6cc88/acme/order.go#L173-L176

dopey commented 2 years ago

https://github.com/smallstep/certificates/issues/92

icedevml commented 1 year ago

Bump. Could the ACME provisioner use the backdate setting from the global configuration instead of the hardcoded value? I'm using certbot and it's submitting orders without specifying any particular NotBefore date.

For now I've manually changed the hardcoded value in the code - it works well with certbot and all constraints regarding certificate maximal lifetime are still validated correctly.

I'm unfortunately not fluent enough in Go to be able to propose PR on my own here :( Would be really grateful if somebody could fix this.