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:
parent
0b639a2d93
commit
5558d4a177
4 changed files with 68 additions and 2 deletions
|
|
@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Use the provided `verifyTime` instead of the current time when verifying embedded signatures.
|
||||||
|
|
||||||
## [2.2.3] 2021-09-21
|
## [2.2.3] 2021-09-21
|
||||||
### Changed
|
### Changed
|
||||||
- Keys are now generated with ZLIB as preferred compression algorithm
|
- Keys are now generated with ZLIB as preferred compression algorithm
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"crypto"
|
"crypto"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ProtonMail/go-crypto/openpgp"
|
"github.com/ProtonMail/go-crypto/openpgp"
|
||||||
"github.com/ProtonMail/go-crypto/openpgp/packet"
|
"github.com/ProtonMail/go-crypto/openpgp/packet"
|
||||||
|
|
@ -190,6 +191,7 @@ func asymmetricDecrypt(
|
||||||
encryptedIO,
|
encryptedIO,
|
||||||
privateKey,
|
privateKey,
|
||||||
verifyKey,
|
verifyKey,
|
||||||
|
verifyTime,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -215,7 +217,10 @@ func asymmetricDecrypt(
|
||||||
|
|
||||||
// Core for decryption+verification (all) functions.
|
// Core for decryption+verification (all) functions.
|
||||||
func asymmetricDecryptStream(
|
func asymmetricDecryptStream(
|
||||||
encryptedIO io.Reader, privateKey *KeyRing, verifyKey *KeyRing,
|
encryptedIO io.Reader,
|
||||||
|
privateKey *KeyRing,
|
||||||
|
verifyKey *KeyRing,
|
||||||
|
verifyTime int64,
|
||||||
) (messageDetails *openpgp.MessageDetails, err error) {
|
) (messageDetails *openpgp.MessageDetails, err error) {
|
||||||
privKeyEntries := privateKey.entities
|
privKeyEntries := privateKey.entities
|
||||||
var additionalEntries openpgp.EntityList
|
var additionalEntries openpgp.EntityList
|
||||||
|
|
@ -228,7 +233,19 @@ func asymmetricDecryptStream(
|
||||||
privKeyEntries = append(privKeyEntries, additionalEntries...)
|
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)
|
messageDetails, err = openpgp.ReadMessage(encryptedIO, privKeyEntries, nil, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,7 @@ func (keyRing *KeyRing) DecryptStream(
|
||||||
message,
|
message,
|
||||||
keyRing,
|
keyRing,
|
||||||
verifyKeyRing,
|
verifyKeyRing,
|
||||||
|
verifyTime,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,13 @@ package crypto
|
||||||
import (
|
import (
|
||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/ProtonMail/go-crypto/openpgp/ecdh"
|
"github.com/ProtonMail/go-crypto/openpgp/ecdh"
|
||||||
|
"github.com/ProtonMail/gopenpgp/v2/constants"
|
||||||
)
|
)
|
||||||
|
|
||||||
var testSymmetricKey []byte
|
var testSymmetricKey []byte
|
||||||
|
|
@ -231,3 +233,43 @@ func TestKeyringCapabilities(t *testing.T) {
|
||||||
assert.True(t, keyRingTestMultiple.CanVerify())
|
assert.True(t, keyRingTestMultiple.CanVerify())
|
||||||
assert.True(t, keyRingTestMultiple.CanEncrypt())
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue