Skip to content

Commit cfd21b6

Browse files
committed
fix: support validating signatures generated with the time in the future
Now the validation code always validates it this point of time: `Now + min( KeyLifetime / 2, DefaultMaxSkew)`. Signed-off-by: Artem Chernyshev <artem.chernyshev@talos-systems.com>
1 parent 74dd3dc commit cfd21b6

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

pkg/pgp/key.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package pgp
77

88
import (
99
"crypto"
10+
"math"
1011
"time"
1112

1213
"github.com/ProtonMail/go-crypto/openpgp"
@@ -59,7 +60,19 @@ func (p *Key) Verify(data, signature []byte) error {
5960

6061
sig := pgpcrypto.NewPGPSignature(signature)
6162

62-
return p.keyring.VerifyDetached(message, sig, pgpcrypto.GetUnixTime())
63+
if p.keyring.VerifyDetached(message, sig, pgpcrypto.GetUnixTime()) == nil {
64+
return nil
65+
}
66+
67+
clockSkew := DefaultAllowedClockSkew.Seconds()
68+
69+
i := p.key.GetEntity().PrimaryIdentity()
70+
71+
if i.SelfSignature.KeyLifetimeSecs != nil {
72+
clockSkew = math.Min(float64(*i.SelfSignature.KeyLifetimeSecs)/2, clockSkew)
73+
}
74+
75+
return p.keyring.VerifyDetached(message, sig, pgpcrypto.GetUnixTime()+int64(clockSkew))
6376
}
6477

6578
// Sign signs the given data using the private key.

pkg/pgp/key_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,32 @@ func TestKeyFlow(t *testing.T) {
3535
assert.Error(t, key.Verify(message, signature[:len(signature)-1]))
3636
}
3737

38+
func TestTimeSkew(t *testing.T) {
39+
start := time.Now()
40+
41+
key, err := pgp.GenerateKey("John Smith", "Linux", "john.smith@example.com", time.Hour)
42+
require.NoError(t, err)
43+
44+
assert.True(t, key.IsPrivate())
45+
assert.NoError(t, key.Validate())
46+
47+
message := []byte("Hello, World!")
48+
49+
signature, err := key.Sign(message)
50+
require.NoError(t, err)
51+
52+
pgpcrypto.UpdateTime(start.Add(-time.Minute).Unix())
53+
54+
assert.NoError(t, key.Verify(message, signature))
55+
56+
pgpcrypto.UpdateTime(start.Add(time.Hour).Unix())
57+
58+
signature, err = key.Sign(message)
59+
require.NoError(t, err)
60+
61+
assert.NoError(t, key.Verify(message, signature))
62+
}
63+
3864
func genKey(t *testing.T, lifetimeSecs uint32, email string, now func() time.Time) *pgp.Key {
3965
cfg := &packet.Config{
4066
Algorithm: packet.PubKeyAlgoEdDSA,

0 commit comments

Comments
 (0)