Skip to content

Commit

Permalink
fix: support validating signatures generated with the time in the future
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Unix4ever committed Aug 1, 2023
1 parent 74dd3dc commit cfd21b6
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
15 changes: 14 additions & 1 deletion pkg/pgp/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package pgp

import (
"crypto"
"math"
"time"

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

sig := pgpcrypto.NewPGPSignature(signature)

return p.keyring.VerifyDetached(message, sig, pgpcrypto.GetUnixTime())
if p.keyring.VerifyDetached(message, sig, pgpcrypto.GetUnixTime()) == nil {
return nil
}

clockSkew := DefaultAllowedClockSkew.Seconds()

i := p.key.GetEntity().PrimaryIdentity()

if i.SelfSignature.KeyLifetimeSecs != nil {
clockSkew = math.Min(float64(*i.SelfSignature.KeyLifetimeSecs)/2, clockSkew)
}

return p.keyring.VerifyDetached(message, sig, pgpcrypto.GetUnixTime()+int64(clockSkew))
}

// Sign signs the given data using the private key.
Expand Down
26 changes: 26 additions & 0 deletions pkg/pgp/key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,32 @@ func TestKeyFlow(t *testing.T) {
assert.Error(t, key.Verify(message, signature[:len(signature)-1]))
}

func TestTimeSkew(t *testing.T) {
start := time.Now()

key, err := pgp.GenerateKey("John Smith", "Linux", "john.smith@example.com", time.Hour)
require.NoError(t, err)

assert.True(t, key.IsPrivate())
assert.NoError(t, key.Validate())

message := []byte("Hello, World!")

signature, err := key.Sign(message)
require.NoError(t, err)

pgpcrypto.UpdateTime(start.Add(-time.Minute).Unix())

assert.NoError(t, key.Verify(message, signature))

pgpcrypto.UpdateTime(start.Add(time.Hour).Unix())

signature, err = key.Sign(message)
require.NoError(t, err)

assert.NoError(t, key.Verify(message, signature))
}

func genKey(t *testing.T, lifetimeSecs uint32, email string, now func() time.Time) *pgp.Key {
cfg := &packet.Config{
Algorithm: packet.PubKeyAlgoEdDSA,
Expand Down

0 comments on commit cfd21b6

Please sign in to comment.