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

Added utility func to compute cert expiry. #339

Merged
merged 5 commits into from
Aug 23, 2019

Conversation

banaag
Copy link
Collaborator

@banaag banaag commented Aug 22, 2019

Addresses #93

// Returns -1 if cert is already expired. This will be used to periodically check if cert
// is still within validity range.
func GetDurationToExpiry(cert *x509.Certificate, currentTime time.Time) time.Duration {
if cert.NotBefore.After(currentTime) || cert.NotAfter.Before(currentTime) {
Copy link
Member

Choose a reason for hiding this comment

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

Depending on how this ends up being used, I'd suggest two changes:

  1. Drop the NotAfter.Before(currentTime) bit; the return statement below will already return a negative value in that case.
  2. Print a warning to the screen when NotBefore.After(currentTime); this probably indicates some configuration error (either with the CA, or the local clock), and it would be good to have some knowledge if the server ends up spinning in a loop because of this.

If you choose to do #2 in the caller function instead of here (reasonable choice either way), then I'd prefer returning (time.Duration, error) instead of using a sentinel value.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I decided to keep #1 because the logic seems cleaner if I can just return a valid duration plus nil (for the error).
I also decided to let the caller handle the error message.

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 that it is no use to check if the cert is expired at the currentTime because the cert should be valid until the SXG signature is expired. It is too late to know its expiry at the currentTime.
The signature expiry time of Expires: now.Add(6 * 24 * time.Hour) needs to be considered and it is better to add it in this check.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I agree, this utility is not meant to check it at current time (as in time.Now()), it was meant to check the cert against a specified deadline. Your point about the naming of the parameters is well taken, I will rename it to certExpiryDeadline.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe add a note, too, to the function doc that this should be the expected SXG expiration time.

@shigeki Also note that we discussed making a toml config parameter (something like renewalGracePeriod), with a default of say, 2 days, so that the process for requesting a new cert via ACME will begin 6+2=8 days before expiration, to allow for ACME server outages. Does this seem OK?

Copy link
Contributor

Choose a reason for hiding this comment

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

c365be8 is fine for me. Thanks.

packager/util/util_test.go Outdated Show resolved Hide resolved
// is still within validity range.
func GetDurationToExpiry(cert *x509.Certificate, currentTime time.Time) (time.Duration, error) {
if cert.NotBefore.After(currentTime) || cert.NotAfter.Before(currentTime) {
return time.Duration(-1), errors.New("Certificate has invalid duration")
Copy link
Member

Choose a reason for hiding this comment

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

Go convention is to return the zero value on error. In this case, I think you can say return 0, errors...; the cast to Duration is implicit.

return time.Duration(-1), errors.New("Certificate has invalid duration")
}

return cert.NotAfter.Sub(currentTime), nil;
Copy link
Member

Choose a reason for hiding this comment

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

No semicolon

// is still within validity range.
func GetDurationToExpiry(cert *x509.Certificate, currentTime time.Time) (time.Duration, error) {
if cert.NotBefore.After(currentTime) || cert.NotAfter.Before(currentTime) {
return time.Duration(-1), errors.New("Certificate has invalid duration")
Copy link
Member

Choose a reason for hiding this comment

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

"invalid duration" error message is wrong. Perhaps "Certificate is expired". (Maybe have a second error message for NotBefore like "Certificate is future-dated".)

zeroDaysBeforeExpiry := time.Date(2019, time.August, 7, 5, 43, 32, 0, time.UTC)

d, err := util.GetDurationToExpiry(pkgt.B3Certs[0], beforeCert)
assert.Contains(t, errorFrom(err), "Certificate has invalid duration")
Copy link
Member

Choose a reason for hiding this comment

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

Maybe use https://godoc.org/github.com/stretchr/testify/assert#EqualError ? Unless an exact string match is prohibitive.

// Returns -1 if cert is already expired. This will be used to periodically check if cert
// is still within validity range.
func GetDurationToExpiry(cert *x509.Certificate, currentTime time.Time) time.Duration {
if cert.NotBefore.After(currentTime) || cert.NotAfter.Before(currentTime) {
Copy link
Member

Choose a reason for hiding this comment

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

Maybe add a note, too, to the function doc that this should be the expected SXG expiration time.

@shigeki Also note that we discussed making a toml config parameter (something like renewalGracePeriod), with a default of say, 2 days, so that the process for requesting a new cert via ACME will begin 6+2=8 days before expiration, to allow for ACME server outages. Does this seem OK?

@shigeki
Copy link
Contributor

shigeki commented Aug 23, 2019

@twifkak 8 days are fine because OCSP next update is 7 days duration and we need not care about OCSP validation period against the cert expiry date.

@@ -78,14 +78,17 @@ func hasCanSignHttpExchangesExtension(cert *x509.Certificate) bool {

// Returns the Duration of time before cert expires with given deadline.
// Note that the certExpiryDeadline should be the expected SXG expiration time.
// Returns -1 if cert is already expired. This will be used to periodically check if cert
// Returns 0 if cert is already expired. This will be used to periodically check if cert
Copy link
Member

Choose a reason for hiding this comment

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

s/0/error/

Copy link
Member

@twifkak twifkak left a comment

Choose a reason for hiding this comment

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

Thanks!

@banaag banaag merged commit 3358870 into ampproject:master Aug 23, 2019
@banaag banaag added the acme All ACME related PRs label Feb 24, 2020
@banaag banaag deleted the packager-cert-cache-mods branch March 5, 2020 22:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
acme All ACME related PRs cla: yes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants