Fix: use verifyTime in the config time instead of Now()

When decrypting message, we have to use verifyTime in the config
otherwise signatures not valid at verifyTime but valid at Now()
will be seen as valid.
This commit is contained in:
marin thiercelin 2021-09-23 10:40:56 +02:00
parent 0b639a2d93
commit 5558d4a177
No known key found for this signature in database
GPG key ID: 117C025B1F21B2C6
4 changed files with 68 additions and 2 deletions

View file

@ -5,6 +5,7 @@ import (
"crypto"
"io"
"io/ioutil"
"time"
"github.com/ProtonMail/go-crypto/openpgp"
"github.com/ProtonMail/go-crypto/openpgp/packet"
@ -190,6 +191,7 @@ func asymmetricDecrypt(
encryptedIO,
privateKey,
verifyKey,
verifyTime,
)
if err != nil {
return nil, err
@ -215,7 +217,10 @@ func asymmetricDecrypt(
// Core for decryption+verification (all) functions.
func asymmetricDecryptStream(
encryptedIO io.Reader, privateKey *KeyRing, verifyKey *KeyRing,
encryptedIO io.Reader,
privateKey *KeyRing,
verifyKey *KeyRing,
verifyTime int64,
) (messageDetails *openpgp.MessageDetails, err error) {
privKeyEntries := privateKey.entities
var additionalEntries openpgp.EntityList
@ -228,7 +233,19 @@ func asymmetricDecryptStream(
privKeyEntries = append(privKeyEntries, additionalEntries...)
}
config := &packet.Config{Time: getTimeGenerator()}
config := &packet.Config{
Time: func() time.Time {
if verifyTime == 0 {
/*
We default to current time while decrypting and verifying
but the caller will remove signature expiration errors later on.
See processSignatureExpiration().
*/
return getNow()
}
return time.Unix(verifyTime, 0)
},
}
messageDetails, err = openpgp.ReadMessage(encryptedIO, privKeyEntries, nil, config)
if err != nil {

View file

@ -194,6 +194,7 @@ func (keyRing *KeyRing) DecryptStream(
message,
keyRing,
verifyKeyRing,
verifyTime,
)
if err != nil {
return nil, err

View file

@ -3,11 +3,13 @@ package crypto
import (
"crypto/ed25519"
"crypto/rsa"
"errors"
"testing"
"github.com/stretchr/testify/assert"
"github.com/ProtonMail/go-crypto/openpgp/ecdh"
"github.com/ProtonMail/gopenpgp/v2/constants"
)
var testSymmetricKey []byte
@ -231,3 +233,43 @@ func TestKeyringCapabilities(t *testing.T) {
assert.True(t, keyRingTestMultiple.CanVerify())
assert.True(t, keyRingTestMultiple.CanEncrypt())
}
func TestVerificationTime(t *testing.T) {
message := NewPlainMessageFromString("Hello")
pgp.latestServerTime = 1632312383
defer func() {
pgp.latestServerTime = testTime
}()
enc, err := keyRingTestPublic.Encrypt(
message,
keyRingTestPrivate,
)
if err != nil {
t.Fatalf("Encryption error: %v", err)
}
_, err = keyRingTestPrivate.Decrypt(
enc,
keyRingTestPublic,
392039755,
)
if err == nil {
t.Fatal("No signature error")
}
castedErr := &SignatureVerificationError{}
isType := errors.As(err, castedErr)
if !isType {
t.Fatalf("No signature error %v", err)
}
if castedErr.Status != constants.SIGNATURE_FAILED {
t.Fatalf("Wrong status %v", castedErr)
}
_, err = keyRingTestPrivate.Decrypt(
enc,
keyRingTestPublic,
0,
)
if err != nil {
t.Fatalf("Got an error while decrypting %v", err)
}
}