@@ -82,6 +82,14 @@ $ step certificate create foo foo.crt foo.key --profile leaf \
8282 --ca ./intermediate-ca.crt --ca-key ./intermediate-ca.key
8383'''
8484
85+ Create a leaf certificate and key with custom validity:
86+
87+ '''
88+ $ step certificate create foo foo.crt foo.key --profile leaf \
89+ --ca ./intermediate-ca.crt --ca-key ./intermediate-ca.key \
90+ --not-before 24h --not-after 2160h
91+ '''
92+
8593Create a root certificate and key with underlying OKP Ed25519:
8694
8795'''
@@ -193,6 +201,22 @@ unset, default is P-256 for EC keys and Ed25519 for OKP keys.
193201 **Ed25519**
194202 : Ed25519 Curve
195203` ,
204+ },
205+ cli.StringFlag {
206+ Name : "not-before" ,
207+ Usage : `The <time|duration> set in the NotBefore property of the certificate. If a
208+ <time> is used it is expected to be in RFC 3339 format. If a <duration> is
209+ used, it is a sequence of decimal numbers, each with optional fraction and a
210+ unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns",
211+ "us" (or "µs"), "ms", "s", "m", "h".` ,
212+ },
213+ cli.StringFlag {
214+ Name : "not-after" ,
215+ Usage : `The <time|duration> set in the NotAfter property of the certificate. If a
216+ <time> is used it is expected to be in RFC 3339 format. If a <duration> is
217+ used, it is a sequence of decimal numbers, each with optional fraction and a
218+ unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns",
219+ "us" (or "µs"), "ms", "s", "m", "h".` ,
196220 },
197221 flags .Force ,
198222 },
@@ -217,6 +241,18 @@ func createAction(ctx *cli.Context) error {
217241 return errs .EqualArguments (ctx , "CRT_FILE" , "KEY_FILE" )
218242 }
219243
244+ notBefore , ok := flags .ParseTimeOrDuration (ctx .String ("not-before" ))
245+ if ! ok {
246+ return errs .InvalidFlagValue (ctx , "not-before" , ctx .String ("not-before" ), "" )
247+ }
248+ notAfter , ok := flags .ParseTimeOrDuration (ctx .String ("not-after" ))
249+ if ! ok {
250+ return errs .InvalidFlagValue (ctx , "not-after" , ctx .String ("not-after" ), "" )
251+ }
252+ if ! notAfter .IsZero () && ! notBefore .IsZero () && notBefore .After (notAfter ) {
253+ return errs .IncompatibleFlagValues (ctx , "not-before" , ctx .String ("not-before" ), "not-after" , ctx .String ("not-after" ))
254+ }
255+
220256 var typ string
221257 if ctx .Bool ("csr" ) {
222258 typ = "x509-csr"
@@ -283,7 +319,8 @@ func createAction(ctx *cli.Context) error {
283319 return errors .WithStack (err )
284320 }
285321 profile , err = x509util .NewLeafProfile (subject , issIdentity .Crt ,
286- issIdentity .Key , x509util .GenerateKeyPair (kty , crv , size ))
322+ issIdentity .Key , x509util .GenerateKeyPair (kty , crv , size ),
323+ x509util .WithNotBeforeAfterDuration (notBefore , notAfter , 0 ))
287324 if err != nil {
288325 return errors .WithStack (err )
289326 }
@@ -297,14 +334,16 @@ func createAction(ctx *cli.Context) error {
297334 }
298335 profile , err = x509util .NewIntermediateProfile (subject ,
299336 issIdentity .Crt , issIdentity .Key ,
300- x509util .GenerateKeyPair (kty , crv , size ))
337+ x509util .GenerateKeyPair (kty , crv , size ),
338+ x509util .WithNotBeforeAfterDuration (notBefore , notAfter , 0 ))
301339 if err != nil {
302340 return errors .WithStack (err )
303341 }
304342 }
305343 case "root-ca" :
306344 profile , err = x509util .NewRootProfile (subject ,
307- x509util .GenerateKeyPair (kty , crv , size ))
345+ x509util .GenerateKeyPair (kty , crv , size ),
346+ x509util .WithNotBeforeAfterDuration (notBefore , notAfter , 0 ))
308347 if err != nil {
309348 return errors .WithStack (err )
310349 }
0 commit comments