1
0
mirror of https://github.com/smallstep/cli.git synced 2026-10-29 00:17:23 +03:00

Merge pull request #52 from smallstep/mariano/validity

Allow to add custom validity in `step certificate create`
This commit is contained in:
Mariano Cano
2018-12-21 17:19:25 -08:00
committed by GitHub
4 changed files with 68 additions and 25 deletions

View File

@@ -208,11 +208,11 @@ func signCertificateTokenFlow(ctx *cli.Context, subject string) (string, error)
}
// parse times or durations
notBefore, ok := parseTimeOrDuration(ctx.String("not-before"))
notBefore, ok := flags.ParseTimeOrDuration(ctx.String("not-before"))
if !ok {
return "", errs.InvalidFlagValue(ctx, "not-before", ctx.String("not-before"), "")
}
notAfter, ok := parseTimeOrDuration(ctx.String("not-after"))
notAfter, ok := flags.ParseTimeOrDuration(ctx.String("not-after"))
if !ok {
return "", errs.InvalidFlagValue(ctx, "not-after", ctx.String("not-after"), "")
}
@@ -232,11 +232,11 @@ func signCertificateRequest(ctx *cli.Context, token string, csr api.CertificateR
caURL := ctx.String("ca-url")
// parse times or durations
notBefore, ok := parseTimeOrDuration(ctx.String("not-before"))
notBefore, ok := flags.ParseTimeOrDuration(ctx.String("not-before"))
if !ok {
return errs.InvalidFlagValue(ctx, "not-before", ctx.String("not-before"), "")
}
notAfter, ok := parseTimeOrDuration(ctx.String("not-after"))
notAfter, ok := flags.ParseTimeOrDuration(ctx.String("not-after"))
if !ok {
return errs.InvalidFlagValue(ctx, "not-after", ctx.String("not-after"), "")
}

View File

@@ -151,11 +151,11 @@ func newTokenAction(ctx *cli.Context) error {
}
// parse times or durations
notBefore, ok := parseTimeOrDuration(ctx.String("not-before"))
notBefore, ok := flags.ParseTimeOrDuration(ctx.String("not-before"))
if !ok {
return errs.InvalidFlagValue(ctx, "not-before", ctx.String("not-before"), "")
}
notAfter, ok := parseTimeOrDuration(ctx.String("not-after"))
notAfter, ok := flags.ParseTimeOrDuration(ctx.String("not-after"))
if !ok {
return errs.InvalidFlagValue(ctx, "not-after", ctx.String("not-after"), "")
}
@@ -360,22 +360,6 @@ func newTokenFlow(ctx *cli.Context, subject, caURL, root, kid, issuer, passwordF
return generateToken(subject, kid, issuer, audience, root, notBefore, notAfter, jwk)
}
func parseTimeOrDuration(s string) (time.Time, bool) {
if s == "" {
return time.Time{}, true
}
var t time.Time
if err := t.UnmarshalText([]byte(s)); err != nil {
d, err := time.ParseDuration(s)
if err != nil {
return time.Time{}, false
}
t = time.Now().Add(d)
}
return t, true
}
// provisionerFilter returns a slice of provisioners that pass the given filter.
func provisionerFilter(provisioners []*authority.Provisioner, f func(*authority.Provisioner) bool) []*authority.Provisioner {
var result []*authority.Provisioner

View File

@@ -82,6 +82,14 @@ $ step certificate create foo foo.crt foo.key --profile leaf \
--ca ./intermediate-ca.crt --ca-key ./intermediate-ca.key
'''
Create a leaf certificate and key with custom validity:
'''
$ step certificate create foo foo.crt foo.key --profile leaf \
--ca ./intermediate-ca.crt --ca-key ./intermediate-ca.key \
--not-before 24h --not-after 2160h
'''
Create a root certificate and key with underlying OKP Ed25519:
'''
@@ -193,6 +201,22 @@ unset, default is P-256 for EC keys and Ed25519 for OKP keys.
**Ed25519**
: Ed25519 Curve
`,
},
cli.StringFlag{
Name: "not-before",
Usage: `The <time|duration> set in the NotBefore property of the certificate. If a
<time> is used it is expected to be in RFC 3339 format. If a <duration> is
used, it is a sequence of decimal numbers, each with optional fraction and a
unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns",
"us" (or "µs"), "ms", "s", "m", "h".`,
},
cli.StringFlag{
Name: "not-after",
Usage: `The <time|duration> set in the NotAfter property of the certificate. If a
<time> is used it is expected to be in RFC 3339 format. If a <duration> is
used, it is a sequence of decimal numbers, each with optional fraction and a
unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns",
"us" (or "µs"), "ms", "s", "m", "h".`,
},
flags.Force,
},
@@ -217,6 +241,18 @@ func createAction(ctx *cli.Context) error {
return errs.EqualArguments(ctx, "CRT_FILE", "KEY_FILE")
}
notBefore, ok := flags.ParseTimeOrDuration(ctx.String("not-before"))
if !ok {
return errs.InvalidFlagValue(ctx, "not-before", ctx.String("not-before"), "")
}
notAfter, ok := flags.ParseTimeOrDuration(ctx.String("not-after"))
if !ok {
return errs.InvalidFlagValue(ctx, "not-after", ctx.String("not-after"), "")
}
if !notAfter.IsZero() && !notBefore.IsZero() && notBefore.After(notAfter) {
return errs.IncompatibleFlagValues(ctx, "not-before", ctx.String("not-before"), "not-after", ctx.String("not-after"))
}
var typ string
if ctx.Bool("csr") {
typ = "x509-csr"
@@ -283,7 +319,8 @@ func createAction(ctx *cli.Context) error {
return errors.WithStack(err)
}
profile, err = x509util.NewLeafProfile(subject, issIdentity.Crt,
issIdentity.Key, x509util.GenerateKeyPair(kty, crv, size))
issIdentity.Key, x509util.GenerateKeyPair(kty, crv, size),
x509util.WithNotBeforeAfterDuration(notBefore, notAfter, 0))
if err != nil {
return errors.WithStack(err)
}
@@ -297,14 +334,16 @@ func createAction(ctx *cli.Context) error {
}
profile, err = x509util.NewIntermediateProfile(subject,
issIdentity.Crt, issIdentity.Key,
x509util.GenerateKeyPair(kty, crv, size))
x509util.GenerateKeyPair(kty, crv, size),
x509util.WithNotBeforeAfterDuration(notBefore, notAfter, 0))
if err != nil {
return errors.WithStack(err)
}
}
case "root-ca":
profile, err = x509util.NewRootProfile(subject,
x509util.GenerateKeyPair(kty, crv, size))
x509util.GenerateKeyPair(kty, crv, size),
x509util.WithNotBeforeAfterDuration(notBefore, notAfter, 0))
if err != nil {
return errors.WithStack(err)
}

View File

@@ -1,6 +1,8 @@
package flags
import (
"time"
"github.com/urfave/cli"
)
@@ -19,3 +21,21 @@ var Force = cli.BoolFlag{
Name: "f,force",
Usage: "Force the overwrite of files without asking.",
}
// ParseTimeOrDuration is a helper that returns the time or the current time
// with an extra duration. It's used in flags like --not-before, --not-after.
func ParseTimeOrDuration(s string) (time.Time, bool) {
if s == "" {
return time.Time{}, true
}
var t time.Time
if err := t.UnmarshalText([]byte(s)); err != nil {
d, err := time.ParseDuration(s)
if err != nil {
return time.Time{}, false
}
t = time.Now().Add(d)
}
return t, true
}