diff --git a/pkg/pgp/key.go b/pkg/pgp/key.go index 321f91a..62c7502 100644 --- a/pkg/pgp/key.go +++ b/pkg/pgp/key.go @@ -104,9 +104,19 @@ func (p *Key) ArmorPublic() (string, error) { // IsExpired returns true if the key is expired with clock skew. func (p *Key) IsExpired(clockSkew time.Duration) bool { + if clockSkew < 0 { + panic("clock skew can't be negative") + } + now := time.Now() i := p.key.GetEntity().PrimaryIdentity() + keyLifetimeSecs := i.SelfSignature.KeyLifetimeSecs + + if keyLifetimeSecs != nil && *keyLifetimeSecs < uint32(clockSkew/time.Second) { + // if the key is short-lived, limit clock skew to the half of the key lifetime + clockSkew = time.Duration(*keyLifetimeSecs) * time.Second / 2 + } expired := func(t time.Time) bool { return p.key.GetEntity().PrimaryKey.KeyExpired(i.SelfSignature, t) || // primary key has expired diff --git a/pkg/pgp/key_test.go b/pkg/pgp/key_test.go index 1a4dbe5..1ea29ee 100644 --- a/pkg/pgp/key_test.go +++ b/pkg/pgp/key_test.go @@ -96,6 +96,10 @@ func TestKeyExpiration(t *testing.T) { lifetime: pgp.MaxAllowedLifetime / 2, shift: pgp.AllowedClockSkew / 2, }, + { + name: "short-lived key", + lifetime: pgp.AllowedClockSkew / 2, + }, } { t.Run(tt.name, func(t *testing.T) { key := genKey(t, uint32(tt.lifetime/time.Second), func() time.Time {