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

Add OCSP and CRL support to certificate verify #1161

Merged
merged 1 commit into from
May 14, 2024

Conversation

redrac
Copy link
Contributor

@redrac redrac commented Apr 23, 2024

Name of feature:

Add OCSP and CRL support to certificate verify

Pain or issue this feature alleviates:

Add args and functionality to certificate verify to check a CRL and OCSP for a certificate based on the extensions. Users can pass flags to enable verification of each (CRL, OCSP). The command will try and get the CRL and OCSP server from the certificate extensions if the endpoints are not provided.

Supporting links/other PRs/issues:

Implements #845

Notes

  • I tested the logic against a valid certificate, invalid OCSP/CRL endpoints, and a revoked certificate
  • I moved some of the functions and structs from crl into its own internal package internal/crlutil so it can be reused
  • Long term if this ever is adressed then a lot of this can be removed in favor of using built in functionality in crypto/x509

@github-actions github-actions bot added the needs triage Waiting for discussion / prioritization by team label Apr 23, 2024
@redrac redrac force-pushed the feature/crl_and_ocsp_inspection branch from 48474d3 to 7c8ddc9 Compare April 28, 2024 20:47
@redrac redrac marked this pull request as ready for review April 28, 2024 20:48
@redrac
Copy link
Contributor Author

redrac commented Apr 28, 2024

Getting a certificate, before revoking:

export STEPPATH=/etc/step
TOKEN=$(step ca token --provisioner-password-file=pass.txt --provisioner=provisioner@acme.com foo.acme.com)

redrac@test-host:~$ step ca certificate --token ${TOKEN} foo.acme.com foo.crt foo.key
✔ CA: https://dev-step-ca.acme.com
✔ Certificate: foo.crt
✔ Private Key: foo.key

$ step certificate inspect foo.crt
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 250957313983734049942497464497330310647 (0xbccc9ede18bfa11b2f8f6de16055cdf7)
    Signature Algorithm: ECDSA-SHA256
        Issuer: ****************************************
        Validity
            Not Before: Apr 28 21:58:41 2024 UTC
            Not After : May 28 21:58:51 2024 UTC
        Subject: CN=foo.acme.com
....
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Extended Key Usage:
                Server Authentication, Client Authentication
            X509v3 Subject Key Identifier:
                E0:A3:9B:7D:AC:AC:98:72:69:4C:C8:70:CC:23:D1:10:8F:46:DF:83
            X509v3 Authority Key Identifier:
                keyid:0B:53:D4:15:2F:90:92:87:93:67:E7:9D:BB:64:B2:B6:D8:E4:AA:67
            Authority Information Access:
                OCSP - URI:http://dev-step-ca.acme.com/ocsp
                CA Issuers - URI:https://dev-step-docs.acme.com/certs/intermediate.crt
            X509v3 Subject Alternative Name:
                DNS:foo.acme.com
                email:provisioner@acme.com
            X509v3 CRL Distribution Points:
                Full Name:
                  URI:http://dev-step-ca.acme.com/crl
            X509v3 Step Provisioner:
                Type: JWK
                Name: provisioner@acme.com
                CredentialID: LhmOBZ3rNZfv49GHM9bLuCq2px2KV03-9REcHaa5ikw
...

Revoking:

redrac@test-host:~$ step ca revoke --cert foo.crt --key foo.key
✔ CA: https://dev-step-ca.acme.com
Certificate with Serial Number 250957313983734049942497464497330310647 has been revoked.

$ step crl inspect --insecure foo_crl
Certificate Revocation List (CRL):
    Data:
        Valid: false
        Version: 656 (0x290)
    Signature algorithm: ECDSA-SHA256
        Issuer:
        Last Update: 2024-04-28 21:59:50 +0000 UTC
        Next Update: 2024-04-29 21:59:50 +0000 UTC
        CRL Extensions:
            X509v3 Authority Key Identifier:
                keyid:0B:53:D4:15:2F:90:92:87:93:67:E7:9D:BB:64:B2:B6:D8:E4:AA:67
            X509v3 CRL Number:
                656
            X509v3 Issuing Distribution Point: critical
                Full Name:
                    URI:http://dev-step-ca.acme.com/crl
                Only User Certificates
        Revoked Certificates:
            Serial Number: 250957313983734049942497464497330310647 (0xBCCC9EDE18BFA11B2F8F6DE16055CDF7)
                Revocation Date: 2024-04-28 21:59:50 +0000 UTC
...

Verifying with step certificate verify:

$ ./step certificate verify foo.crt --roots foo_roots.crt --ca foo_issuer.crt  --verify-verbose
certificate validated against roots
certficiate is valid
$ echo $?
0

$ ./step certificate verify foo.crt --roots foo_roots.crt --ca foo_issuer.crt  --verify-crl --verify-verbose
certificate marked as revoked in CRL
$ echo $?
1

$ ./step certificate verify foo.crt --roots foo_roots.crt --ca foo_issuer.crt --verify-ocsp  --verify-verbose
certificate has been revoked according to OCSP
$ echo $?
1

@redrac
Copy link
Contributor Author

redrac commented Apr 28, 2024

And a non-revoked cert:

$ ./step certificate verify ./certificate.pem --roots /etc/ssl/certs/ --ca ./intermediate.pem  --verify-crl --verify-ocsp  --verify-verbose
certificate validated against roots
certificate not revoked in CRL
certificate status shows good in OCSP
certficiate is valid
$ echo $?
0

@redrac redrac force-pushed the feature/crl_and_ocsp_inspection branch from 7c8ddc9 to 0642c10 Compare April 28, 2024 22:24
@redrac
Copy link
Contributor Author

redrac commented Apr 28, 2024

Existing CRL functionality works still..

$ ./step crl inspect --ca foo_issuer.pem http://dev-step-ca.acme.com/crl
Certificate Revocation List (CRL):
    Data:
        Valid: false
        Version: 656 (0x290)
    Signature algorithm: ECDSA-SHA256
        Issuer:
        Last Update: 2024-04-28 21:59:50 +0000 UTC
        Next Update: 2024-04-29 21:59:50 +0000 UTC
        CRL Extensions:
            X509v3 Authority Key Identifier:
                keyid:0B:53:D4:15:2F:90:92:87:93:67:E7:9D:BB:64:B2:B6:D8:E4:AA:67
            X509v3 CRL Number:
                656
            X509v3 Issuing Distribution Point: critical
                Full Name:
                    URI:http://dev-step-ca.acme.com/crl
                Only User Certificates
        Revoked Certificates:
            Serial Number: 250957313983734049942497464497330310647 (0xBCCC9EDE18BFA11B2F8F6DE16055CDF7)
                Revocation Date: 2024-04-28 21:59:50 +0000 UTC
..

And JSON:

$ ./step crl inspect --ca foo_issuer.pem http://dev-step-ca.acme.com/crl --format json
{
  "version": 657,
  "signature_algorithm": {
    "name": "ECDSA-SHA256",
    "oid": "1.2.840.10045.4.3.2"
  },
  "issuer": {
    "organization": [

@redrac redrac force-pushed the feature/crl_and_ocsp_inspection branch 2 times, most recently from 72e08bc to 2cbe6d8 Compare April 28, 2024 23:23
@redrac
Copy link
Contributor Author

redrac commented Apr 28, 2024

Try verifying a cert against a user provided CRL

$ ./step certificate verify foo.crt --roots foo_roots.crt --ca foo_issuer.crt  --verify-verbose --verify-crl --crl-endpoint http://dev-step-ca.acme.com/crl
certificate marked as revoked in CRL http://dev-step-ca.acme.com/crl

Try verifying a cert against a user provided CRL for a different CA

$ ./step certificate verify foo.crt --roots foo_roots.crt --ca foo_issuer.crt  --verify-verbose --verify-crl --crl-endpoint http://step-ca.acme.com/crl
error validating the CRL against the CA issuer: x509: ECDSA verification failure

Try verifying a cert against a user provided OCSP server

$ ./step certificate verify foo.crt --roots foo_roots.crt --ca foo_issuer.crt  --verify-verbose --verify-ocsp --ocsp-endpoint http://dev-step-ca.acme.com/ocsp
certificate has been revoked according to OCSP http://dev-step-ca.acme.com/ocsp

Try verifying a cert against an OCSP for a different CA

$ ./step certificate verify foo.crt --roots foo_roots.crt --ca foo_issuer.crt  --verify-verbose --verify-ocsp --ocsp-endpoint http://step-ca.acme.com/ocsp
error parsing repsonse from OCSP server: http://step-ca.acme.com/ocsp

@redrac redrac force-pushed the feature/crl_and_ocsp_inspection branch 4 times, most recently from 5ff3603 to 2049858 Compare April 28, 2024 23:46
@maraino maraino self-requested a review May 6, 2024 21:41
@redrac
Copy link
Contributor Author

redrac commented May 6, 2024

Linting fixed @maraino

@redrac redrac force-pushed the feature/crl_and_ocsp_inspection branch from 2049858 to 9b45f50 Compare May 8, 2024 20:20
Copy link
Collaborator

@maraino maraino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In most cases, if the certificate passed as a parameter contains an intermediate certificate, we can assume this is the issuer if the --ca flag is not provided.

command/certificate/verify.go Outdated Show resolved Hide resolved
command/certificate/verify.go Outdated Show resolved Hide resolved
command/certificate/verify.go Outdated Show resolved Hide resolved
command/certificate/verify.go Outdated Show resolved Hide resolved
command/certificate/verify.go Outdated Show resolved Hide resolved
command/certificate/verify.go Outdated Show resolved Hide resolved
@redrac redrac force-pushed the feature/crl_and_ocsp_inspection branch 5 times, most recently from 80b1b7c to 2a074ff Compare May 11, 2024 17:26
@redrac redrac requested a review from maraino May 11, 2024 17:28
@redrac
Copy link
Contributor Author

redrac commented May 11, 2024

Updated to

  • get issuing CA from issuer URL
  • loop through CRL endpoints
  • loop through OCSP endpoints

For the CRL & OCSP endpoints, as long as we get a valid response from a CRL or OCSP we break the loop; whether the response indicates the certificate is good or revoked or unknown makes no difference to breaking the loop.

@redrac
Copy link
Contributor Author

redrac commented May 11, 2024

Running against a public website

# ./step certificate verify --verify-crl --verify-ocsp --verify-verbose https://google.com
certificate validated against roots
certificate not revoked in CRL http://c.pki.goog/wr2/GSyT1N4PBrg.crl
certificate status is good according OCSP http://o.pki.goog/wr2
certficiate is valid

Running against internal website with private CA

$ ./step certificate verify foo.crt --roots foo_roots.crt --verify-verbose --verify-crl --verify-ocsp
certificate validated against roots
certificate not revoked in CRL http://dev-step-ca.acme.com/crl
certificate status is good according OCSP http://dev-step-ca.acme.com/ocsp
certficiate is valid

Running against internal website with private CA after revoking

$ ./step certificate verify foo.crt --roots foo_roots.crt --verify-verbose --verify-ocsp
certificate has been revoked according to OCSP http://dev-step-ca.acme.com/ocsp

$ ./step certificate verify foo.crt --roots foo_roots.crt --verify-verbose --verify-crl
certificate marked as revoked in CRL http://dev-step-ca.acme.com/crl

@redrac redrac force-pushed the feature/crl_and_ocsp_inspection branch from 2a074ff to c369d92 Compare May 11, 2024 17:36
Copy link
Collaborator

@maraino maraino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @redrac, I've added suggestion that I think solves all the linter errors, and renames the verbose flag to --verbose, I can apply those and merge, unless you see something wrong with my changes.

command/certificate/verify.go Outdated Show resolved Hide resolved
command/certificate/verify.go Outdated Show resolved Hide resolved
command/certificate/verify.go Outdated Show resolved Hide resolved
command/certificate/verify.go Outdated Show resolved Hide resolved
command/certificate/verify.go Outdated Show resolved Hide resolved
command/certificate/verify.go Outdated Show resolved Hide resolved
command/certificate/verify.go Outdated Show resolved Hide resolved
command/certificate/verify.go Outdated Show resolved Hide resolved
command/certificate/verify.go Show resolved Hide resolved
Add args and functionality to certificate verify to check a CRL
and OCSP for a certificate based on the extensions. Users can pass
flags to enable verification of each (CRL, OCSP). The command will try
and get the CRL and OCSP server from the certifiacate and verify the
certificate against each.

I also moved functions from the crl command into internal/crlutil
package so they can be re-used with the certificate verify command.

Implements smallstep#845
@redrac redrac force-pushed the feature/crl_and_ocsp_inspection branch from c369d92 to d64d33a Compare May 14, 2024 20:29
@redrac
Copy link
Contributor Author

redrac commented May 14, 2024

@maraino looks, good I made one small tweak to the break logic

@redrac redrac requested a review from maraino May 14, 2024 20:44
Copy link
Collaborator

@maraino maraino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@maraino maraino merged commit 9fef15b into smallstep:master May 14, 2024
12 of 13 checks passed
@hslatman hslatman added this to the v0.26.2 milestone May 15, 2024
@hslatman
Copy link
Member

Late to the game, but is it an option to rename the flags to shorter versions, e.g. --crl and --ocsp? Given that they're used on the verify subcommand, I think the shorter names are sufficient. Or is it expected that those will be reused on (many) other subcommands in the future?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs triage Waiting for discussion / prioritization by team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants