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

Megan/expiration #495

Merged
merged 20 commits into from Jul 8, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion command/certificate/certificate.go
Expand Up @@ -14,7 +14,7 @@ func init() {
Description: `**step certificate** command group provides facilities for creating
certificate signing requests (CSRs), creating self-signed certificates
(e.g., for use as a root certificate authority), generating leaf or
intermediate CA certificate by signing a CSR, validating certificates,
intermediate CA certificate by signing a CSR, validating certificates, check expiration of certificate,
Copy link
Contributor

Choose a reason for hiding this comment

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

checking certificate expiration

The tense on the other verbs all seem to end with ing, so we should be consistent.

renewing certificates, generating certificate bundles, and key-wrapping
of private keys.

Expand Down
38 changes: 38 additions & 0 deletions command/certificate/verify.go
Expand Up @@ -4,6 +4,8 @@ import (
"crypto/x509"
"encoding/pem"
"io/ioutil"
"time"
"fmt"

"github.com/pkg/errors"
"github.com/smallstep/cli/crypto/x509util"
Expand Down Expand Up @@ -65,12 +67,22 @@ Verify a certificate using a custom directory of root certificates for path vali
'''
$ step certificate verify ./certificate.crt --roots ./root-certificates/
'''

Verify the expiration time left of a certificate using a custom root certificate and host for path validation:
Copy link
Contributor

Choose a reason for hiding this comment

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

Verify the remaining validity of a certificate ...


'''
$ step certificate verify ./certificate.crt --host smallstep.com --expire
Copy link
Contributor

@dopey dopey Jun 22, 2021

Choose a reason for hiding this comment

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

@mmalone @tashian what did we want this flag to be called? expire, validity, verdancy?

Copy link
Contributor

Choose a reason for hiding this comment

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

verdancy

'''
`,
Flags: []cli.Flag{
cli.StringFlag{
Name: "host",
Usage: `Check whether the certificate is for the specified host.`,
},
cli.BoolFlag{
Name: "expire",
Usage: `Checks the certificate time till expiration`,
Copy link
Contributor

Choose a reason for hiding this comment

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

Checks the remaining certificate validity till expiration

},
cli.StringFlag{
Name: "roots",
Usage: `Root certificate(s) that will be used to verify the
Expand Down Expand Up @@ -100,6 +112,7 @@ func verifyAction(ctx *cli.Context) error {
var (
crtFile = ctx.Args().Get(0)
host = ctx.String("host")
expire = ctx.Bool("expire")
serverName = ctx.String("servername")
roots = ctx.String("roots")
intermediatePool = x509.NewCertPool()
Expand Down Expand Up @@ -164,6 +177,31 @@ func verifyAction(ctx *cli.Context) error {
}
}

if expire {

NowTillEndOfCert := time.Until(cert.NotAfter)
totalLifeTimeOfCert := cert.NotAfter.Sub(cert.NotBefore)

percentIntoLifeTime := ((totalLifeTimeOfCert.Hours() - NowTillEndOfCert.Hours()) / totalLifeTimeOfCert.Hours()) * 100

if percentIntoLifeTime >= 100 {
fmt.Println("\033[31m", "This certificate has already expired.", "\033[0m") //"\033[__m" are color codes
} else if percentIntoLifeTime > 90 {
fmt.Println("\033[31m", "Leaf is", int(percentIntoLifeTime), "% through its lifetime.", "\033[0m")
} else if percentIntoLifeTime > 66 && percentIntoLifeTime < 90 {
fmt.Println("\033[33m", "Leaf is", int(percentIntoLifeTime), "% through its lifetime.", "\033[0m")
} else if percentIntoLifeTime < 66 && percentIntoLifeTime > 1 {
fmt.Println("\033[32m", "Leaf is", int(percentIntoLifeTime), "% through its lifetime.", "\033[0m")
} else if percentIntoLifeTime < 1 {
fmt.Println("\033[32m", "Leaf is less than 1% through its lifetime.", "\033[0m")
} else {
fmt.Println("Error")
}

return nil
}


Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should verify the certificate first cert.VerifyOpts below, and then if it's valid we can analyze how much of the lifespan has been used. The benefit of this is that we won't have to check if now < cert.NotBefore or if the cert is already expired. The VerifyOpts method already does that for us. So only if the certificate is valid do we print expiry information.

opts := x509.VerifyOptions{
DNSName: host,
Roots: rootPool,
Expand Down