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.73k stars 440 forks source link

Certificate Revocation List #206

Closed Hardcorian closed 2 years ago

Hardcorian commented 4 years ago

Hello,

I installed and configured a Linux intermediate CA from a Windows Root CA, and working perfectly thanks to your documentation. It is a CentOS 7 version 1708.

When I revoke actively a certificate, I am not able to find the CRL or place where the revoked certificates are listed.

The goal of this is to have the revoked certificates by the Linux intCA in the same CRL as the Windows intCA, to work with only a unified CRL. In fact, in the Linux intCA certificate, I see that the CRL distribution point is the same as the Windows intCA.

Thanks so much.

hslatman commented 2 years ago

@DonOtuseGH: PostgreSQL support was added in the latest release of step-ca. The documentation at https://smallstep.com/docs/step-ca/configuration/#databases has not yet been updated, but the PR for it is done. Some example configurations can be found here: https://github.com/smallstep/certificates/issues/854.

Unfortunately, the PostgreSQL support currently is also only a simple K/V store 😅

charltonstanley commented 2 years ago

Not sure if I should create a new issue for this or post it here instead, but here it goes.

https://smallstep.com/docs/step-ca/certificate-authority-server-production#enable-active-revocation-on-your-intermediate-ca

I'm trying to follow the steps at the link above to create a CRL signed by my root ca. How do i sign the CRL if my keys are in aws kms?

hslatman commented 2 years ago

Copying over (parts of) my answer on Discord for posterity:

I don't think we have something readily available for that at in our open source offering at the moment. We have support for automatic CRL generation in our product now, though.

It may still be possible to use other tools, like openssl, to sign the CRL with a key in AWS KMS. https://github.com/JackOfMostTrades/aws-kms-pkcs11 provides a way for OpenSSL to communicate with AWS KMS through PKCS11. From the looks of it you should be able to configure the ID of your private key and use that to perform signing operations.

maraino commented 2 years ago

@charltonstanley My objective at some point is to be able to use step to sign data using the KMSs that we support on step-ca, and we already support AWS KMS. So to do it programmatically using Go, you can use our awskms.CreateSigner as the signer in Go's x509.CreateRevocationList.

charltonstanley commented 2 years ago

@hslatman and @mmalone thank you! It would indeed be slick to at some point be able to use step to do this in the future :)

logopk commented 2 years ago

I don't think we have something readily available for that at in our open source offering at the moment. We have support for automatic CRL generation in our product now, though.

@hslatman That's good to know, however I don't see any documentation on that!?

Mind to share how to use it?

Hardcorian commented 2 years ago

I don't think we have something readily available for that at in our open source offering at the moment. We have support for automatic CRL generation in our product now, though.

@hslatman That's good to know, however I don't see any documentation on that!?

Mind to share how to use it?

Hello,

I do not know if there is documentation, but this is the related thread:

https://github.com/smallstep/certificates/pull/731

As the creator of this issue, thanks to all the team.

hslatman commented 2 years ago

@logopk: regarding the functionality in the product: we're currently building the parts to make it self-serve. At this time it requires a manual setup through customer support.

Apart from that, there's indeed the work underway that @Hardcorian linked, which would allow users of step-ca to create their own CRL. Then there's also @charltonstanley's use case of being able to sign a CRL (and perhaps other data) created outside of of step using keys configured in step, which isn't currently supported, but may be in the future, as @maraino mentioned.

tmartincpp commented 1 year ago

@logopk @maraino : sorry to bother you.

Any chance to help me with this issue ?

$ go run listcerts.go db/ 2>&1 ; echo $?
# github.com/golang/glog/internal/logsink
/home/thomas/go/src/github.com/golang/glog/internal/logsink/logsink.go:123:41: undefined: any
/home/thomas/go/src/github.com/golang/glog/internal/logsink/logsink.go:172:67: undefined: any
/home/thomas/go/src/github.com/golang/glog/internal/logsink/logsink.go:305:45: undefined: any
/home/thomas/go/src/github.com/golang/glog/internal/logsink/logsink.go:385:75: undefined: any
# github.com/klauspost/compress/huff0
/home/thomas/go/src/github.com/klauspost/compress/huff0/decompress.go:774:20: cannot convert out (type []byte) to type *[256]byte
/home/thomas/go/src/github.com/klauspost/compress/huff0/decompress.go:775:20: cannot convert out[dstEvery:] (type []byte) to type *[256]byte
/home/thomas/go/src/github.com/klauspost/compress/huff0/decompress.go:776:20: cannot convert out[dstEvery * 2:] (type []byte) to type *[256]byte
/home/thomas/go/src/github.com/klauspost/compress/huff0/decompress.go:777:20: cannot convert out[dstEvery * 3:] (type []byte) to type *[256]byte
/home/thomas/go/src/github.com/klauspost/compress/huff0/decompress.go:1013:20: cannot convert out (type []byte) to type *[256]byte
/home/thomas/go/src/github.com/klauspost/compress/huff0/decompress.go:1014:20: cannot convert out[dstEvery:] (type []byte) to type *[256]byte
/home/thomas/go/src/github.com/klauspost/compress/huff0/decompress.go:1015:20: cannot convert out[dstEvery * 2:] (type []byte) to type *[256]byte
/home/thomas/go/src/github.com/klauspost/compress/huff0/decompress.go:1016:20: cannot convert out[dstEvery * 3:] (type []byte) to type *[256]byte
# golang.org/x/sys/unix
/home/thomas/go/src/golang.org/x/sys/unix/syscall.go:83:16: undefined: unsafe.Slice
/home/thomas/go/src/golang.org/x/sys/unix/syscall_linux.go:1018:20: undefined: unsafe.Slice
/home/thomas/go/src/golang.org/x/sys/unix/syscall_linux.go:2289:9: undefined: unsafe.Slice
/home/thomas/go/src/golang.org/x/sys/unix/syscall_unix.go:118:7: undefined: unsafe.Slice
/home/thomas/go/src/golang.org/x/sys/unix/sysvshm_unix.go:33:7: undefined: unsafe.Slice
2

Before the go run I did : go get -v . without error.

My goal is to generate an index file to use with openssl ocsp.

Thanks!

logopk commented 1 year ago

@tmartincpp oh I'm not that familiar with go, but to me it does not seem to be caused by the source of listcerts.go (as it does not include any of the mentioned files).

To prevent any such interferences I build the program in a separate docker container (in golang:alpine image).

tmartincpp commented 1 year ago

Thanks @logopk , I might try it out.

edit: it worked!

Here is an example of a Dockerfile to use :

FROM golang:alpine
#
COPY files/listcerts.go /step/
#
RUN cd /step/ && \
    go mod init step && \
    go get github.com/dgraph-io/badger/v2

Then you can call the image with something like : docker run --rm --network none --read-only --security-opt no-new-privileges --tmpfs /tmp:exec -v ~/docker/step_db:/step/db -w /step/ step_listcerts go run listcerts.go db/.

mrexodia commented 1 year ago

In case someone is looking here because of Windows refusing certificates without CRL specified when using step-ca as your self-signed ACME server:

> curl https://cloud.my.lan
curl: (35) schannel: next InitializeSecurityContext failed: Unknown error (0x80092012) - The revocation function was unable to check revocation for the certificate.

You can fix this by enabling CRL in ~/.step/config/ca.json (see here for the relevant code, otherwise undocumented):

        "commonName": "Whatever CA",
        "crl": {
                "enabled": true,
                "generateOnRevoke": true,
                "idpURL": "http://ca.my.lan:8000/crl"
        }

Additionally you need to set up a template (as mentioned in this thread). I had to do this for both my ACME and JWK provisioners:

                        {
                                "type": "ACME",
                                "name": "acme",
                                "claims": {
                                        "maxTLSCertDuration": "4320h0m0s",
                                        "defaultTLSCertDuration": "744h0m0s",
                                        "enableSSHCA": true,
                                        "disableRenewal": false,
                                        "allowRenewalAfterExpiry": false
                                },
                                "options": {
                                        "x509": {
                                                "templateFile": "templates/x509/leaf-crl.tpl"
                                        },
                                        "ssh": {}
                                }
                        },

The template is in ~/.step/templates/x509/leaf-crl.tpl:

{
        "subject": {{ toJson .Subject }},
        "sans": {{ toJson .SANs }},
{{- if typeIs "*rsa.PublicKey" .Insecure.CR.PublicKey }}
        "keyUsage": ["keyEncipherment", "digitalSignature"],
{{- else }}
        "keyUsage": ["digitalSignature"],
{{- end }}
        "extKeyUsage": ["serverAuth", "clientAuth"],
        "crlDistributionPoints": ["http://ca.my.lan:8000/crl"]
}

The CRL will be available under https://ca.my.lan:4443/crl (the same HTTPS endpoint you use as the ACME server). Windows will no accept an HTTPS endpoint, so I did a quick Caddy reverse proxy to enable regular HTTP as well. This is my Caddyfile (I run step-ca on my router and port 80 was already taken, so I use 8000, but any port will work):

{
        http_port 8000
        auto_https off
}

:8000 {
        reverse_proxy https://ca.my.lan:4443 {
                transport http {
                        tls_insecure_skip_verify
                }
        }
}

It's important to change both the crlDistributionPointers in leaf-crl.tpl and the idpURL in config.json to point to the HTTP endpoint http://ca.my.lan:8000/crl. If I figure out how to set up OCSP stapling (just a dummy that returns an acceptable response) I'll post a comment!

hslatman commented 1 year ago

@mrexodia that's a great example configuration, showing all the bits to getting it to work. Thank you! 😄

Yesterday we merged https://github.com/smallstep/certificates/pull/1372, so that the CRL endpoint is now available on the HTTP server too. This should make life easier with Windows in the mix.

mrexodia commented 1 year ago

Thanks @hslatman I'll update when a new version is released! I didn't realize there was also an option to run an insecure server 😅

The updated guide would probably be to replace Caddy with the "insecureAddress": ":8000" setting.

Also wouldn't it be good to default to the insecure endpoint for the CRL's idpURL if it's enabled? Currently you have to manually set it to the HTTP one. Also it would be nice to set the crlDistributionPoints so a template isn't necessary, but I understand there might be some reservations for that...

hslatman commented 1 year ago

We don't advertise the insecure server more than is necessary. It was only used for the SCEP protocol before, because that's designed to run over HTTP. But it makes sense for CRLs too, so that's why I added those endpoints now too. You should indeed be able to run this without Caddy with "insecureAddress": ":8000".

Your suggestions absolutely make sense, but need a bit of thought. The CA can run with multiple DNS names and on multiple IP addresses, so we must be deterministic in which one is chosen (the first one makes sense, of course). It should still be possible to override it in that case. Automatically adding the crlDistributionPoints extension could also be based on that value. Support for CRL generation in open source was a community contribution, and building it out hasn't been a high priority for us so far, so that's why there are parts to it that can be improved.