From 7d5cf34ce5453c105d12314f61218b5a7a059042 Mon Sep 17 00:00:00 2001 From: max furman Date: Tue, 16 Jun 2020 12:16:43 -0700 Subject: [PATCH] Update profileLimitDuration validator ... - respect notBefore of the provisioner - modify/fix the reported errors --- authority/provisioner/sign_options.go | 16 +++++++++------- authority/provisioner/sign_options_test.go | 12 ++++++------ authority/provisioner/x5c.go | 3 ++- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/authority/provisioner/sign_options.go b/authority/provisioner/sign_options.go index 1d88131e..55ed9d3a 100644 --- a/authority/provisioner/sign_options.go +++ b/authority/provisioner/sign_options.go @@ -221,8 +221,8 @@ func (v profileDefaultDuration) Option(so Options) x509util.WithOption { // profileLimitDuration is an x509 profile option that modifies an x509 validity // period according to an imposed expiration time. type profileLimitDuration struct { - def time.Duration - notAfter time.Time + def time.Duration + notBefore, notAfter time.Time } // Option returns an x509util option that limits the validity period of a @@ -236,15 +236,17 @@ func (v profileLimitDuration) Option(so Options) x509util.WithOption { notBefore = n backdate = -1 * so.Backdate } - if notBefore.After(v.notAfter) { - return errors.Errorf("provisioning credential expiration (%s) is before "+ - "requested certificate notBefore (%s)", v.notAfter, notBefore) + if notBefore.Before(v.notBefore) { + return errors.Errorf("requested certificate notBefore (%s) is before "+ + "the active validity window of the provisioning credential (%s)", + notBefore, v.notBefore) } notAfter := so.NotAfter.RelativeTime(notBefore) if notAfter.After(v.notAfter) { - return errors.Errorf("provisioning credential expiration (%s) is before "+ - "requested certificate notAfter (%s)", v.notAfter, notBefore) + return errors.Errorf("requested certificate notAfter (%s) is after "+ + "the expiration of the provisioning credential (%s)", + notAfter, v.notAfter) } if notAfter.IsZero() { t := notBefore.Add(v.def) diff --git a/authority/provisioner/sign_options_test.go b/authority/provisioner/sign_options_test.go index 2aa6dd05..829dbbba 100644 --- a/authority/provisioner/sign_options_test.go +++ b/authority/provisioner/sign_options_test.go @@ -485,7 +485,7 @@ func Test_profileDefaultDuration_Option(t *testing.T) { cert: new(x509.Certificate), valid: func(cert *x509.Certificate) { n := now() - assert.True(t, n.After(cert.NotBefore), fmt.Sprintf("expected now = %s to be after cert.NotBefore = %s", n, cert.NotBefore)) + assert.True(t, n.Add(3*time.Second).After(cert.NotBefore), fmt.Sprintf("expected now = %s to be after cert.NotBefore = %s", n.Add(3*time.Second), cert.NotBefore)) assert.True(t, n.Add(-1*time.Minute).Before(cert.NotBefore)) assert.Equals(t, cert.NotAfter, na) @@ -530,14 +530,14 @@ func Test_profileLimitDuration_Option(t *testing.T) { err error } tests := map[string]func() test{ - "fail/notBefore-after-limit": func() test { - d, err := ParseTimeDuration("8h") + "fail/notBefore-before-active-window": func() test { + d, err := ParseTimeDuration("6h") assert.FatalError(t, err) return test{ - pld: profileLimitDuration{def: 4 * time.Hour, notAfter: n.Add(6 * time.Hour)}, + pld: profileLimitDuration{def: 4 * time.Hour, notBefore: n.Add(8 * time.Hour)}, so: Options{NotBefore: d}, cert: new(x509.Certificate), - err: errors.New("provisioning credential expiration ("), + err: errors.New("requested certificate notBefore ("), } }, "fail/requested-notAfter-after-limit": func() test { @@ -547,7 +547,7 @@ func Test_profileLimitDuration_Option(t *testing.T) { pld: profileLimitDuration{def: 4 * time.Hour, notAfter: n.Add(6 * time.Hour)}, so: Options{NotBefore: NewTimeDuration(n.Add(3 * time.Hour)), NotAfter: d}, cert: new(x509.Certificate), - err: errors.New("provisioning credential expiration ("), + err: errors.New("requested certificate notAfter ("), } }, "ok/valid-notAfter-requested": func() test { diff --git a/authority/provisioner/x5c.go b/authority/provisioner/x5c.go index f00a215d..c174aa3f 100644 --- a/authority/provisioner/x5c.go +++ b/authority/provisioner/x5c.go @@ -199,7 +199,8 @@ func (p *X5C) AuthorizeSign(ctx context.Context, token string) ([]SignOption, er return []SignOption{ // modifiers / withOptions newProvisionerExtensionOption(TypeX5C, p.Name, ""), - profileLimitDuration{p.claimer.DefaultTLSCertDuration(), claims.chains[0][0].NotAfter}, + profileLimitDuration{p.claimer.DefaultTLSCertDuration(), + claims.chains[0][0].NotBefore, claims.chains[0][0].NotAfter}, // validators commonNameValidator(claims.Subject), defaultPublicKeyValidator{},