passforios-gopenpgp/crypto/keyring_test.go
marin thiercelin 5558d4a177
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.
2021-09-23 17:14:19 +02:00

275 lines
7.8 KiB
Go

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
// Password for key in testdata/keyring_privateKeyLegacy: "123".
// Corresponding key in testdata/keyring_privateKey.
var testMailboxPassword = []byte("apple")
var (
keyRingTestPrivate *KeyRing
keyRingTestPublic *KeyRing
keyRingTestMultiple *KeyRing
)
var testIdentity = &Identity{
Name: "UserID",
Email: "",
}
func initKeyRings() {
var err error
testSymmetricKey, err = RandomToken(32)
if err != nil {
panic("Expected no error while generating random token, got:" + err.Error())
}
privateKey, err := NewKeyFromArmored(readTestFile("keyring_privateKey", false))
if err != nil {
panic("Expected no error while unarmoring private key, got:" + err.Error())
}
keyRingTestPrivate, err = NewKeyRing(privateKey)
if err == nil {
panic("Able to create a keyring with a locked key")
}
unlockedKey, err := privateKey.Unlock(testMailboxPassword)
if err != nil {
panic("Expected no error while unlocking private key, got:" + err.Error())
}
keyRingTestPrivate, err = NewKeyRing(unlockedKey)
if err != nil {
panic("Expected no error while building private keyring, got:" + err.Error())
}
publicKey, err := NewKeyFromArmored(readTestFile("keyring_publicKey", false))
if err != nil {
panic("Expected no error while unarmoring public key, got:" + err.Error())
}
keyRingTestPublic, err = NewKeyRing(publicKey)
if err != nil {
panic("Expected no error while building public keyring, got:" + err.Error())
}
keyRingTestMultiple, err = NewKeyRing(nil)
if err != nil {
panic("Expected no error while building empty keyring, got:" + err.Error())
}
err = keyRingTestMultiple.AddKey(keyTestRSA)
if err != nil {
panic("Expected no error while adding RSA key to keyring, got:" + err.Error())
}
err = keyRingTestMultiple.AddKey(keyTestEC)
if err != nil {
panic("Expected no error while adding EC key to keyring, got:" + err.Error())
}
err = keyRingTestMultiple.AddKey(unlockedKey)
if err != nil {
panic("Expected no error while adding unlocked key to keyring, got:" + err.Error())
}
}
func TestIdentities(t *testing.T) {
identities := keyRingTestPrivate.GetIdentities()
assert.Len(t, identities, 1)
assert.Exactly(t, identities[0], testIdentity)
}
func TestFilterExpiredKeys(t *testing.T) {
expiredKey, err := NewKeyFromArmored(readTestFile("key_expiredKey", false))
if err != nil {
t.Fatal("Cannot unarmor expired key:", err)
}
expiredKeyRing, err := NewKeyRing(expiredKey)
if err != nil {
t.Fatal("Cannot create keyring with expired key:", err)
}
keys := []*KeyRing{keyRingTestPrivate, expiredKeyRing}
unexpired, err := FilterExpiredKeys(keys)
if err != nil {
t.Fatal("Expected no error while filtering expired keyrings, got:", err)
}
assert.Len(t, unexpired, 1)
assert.Exactly(t, unexpired[0].GetKeyIDs(), keyRingTestPrivate.GetKeyIDs())
}
func TestKeyIds(t *testing.T) {
keyIDs := keyRingTestPrivate.GetKeyIDs()
var assertKeyIDs = []uint64{4518840640391470884}
assert.Exactly(t, assertKeyIDs, keyIDs)
}
func TestMultipleKeyRing(t *testing.T) {
assert.Exactly(t, 3, len(keyRingTestMultiple.entities))
assert.Exactly(t, 3, keyRingTestMultiple.CountEntities())
assert.Exactly(t, 3, keyRingTestMultiple.CountDecryptionEntities())
assert.Exactly(t, 3, len(keyRingTestMultiple.GetKeys()))
testKey, err := keyRingTestMultiple.GetKey(1)
if err != nil {
t.Fatal("Expected no error while extracting key, got:", err)
}
assert.Exactly(t, keyTestEC, testKey)
_, err = keyRingTestMultiple.GetKey(3)
assert.NotNil(t, err)
singleKeyRing, err := keyRingTestMultiple.FirstKey()
if err != nil {
t.Fatal("Expected no error while filtering the first key, got:", err)
}
assert.Exactly(t, 1, len(singleKeyRing.entities))
assert.Exactly(t, 1, singleKeyRing.CountEntities())
assert.Exactly(t, 1, singleKeyRing.CountDecryptionEntities())
}
func TestClearPrivateKey(t *testing.T) {
keyRingCopy, err := keyRingTestMultiple.Copy()
if err != nil {
t.Fatal("Expected no error while copying keyring, got:", err)
}
for _, key := range keyRingCopy.GetKeys() {
assert.Nil(t, clearPrivateKey(key.entity.PrivateKey.PrivateKey))
}
keys := keyRingCopy.GetKeys()
assertRSACleared(t, keys[0].entity.PrivateKey.PrivateKey.(*rsa.PrivateKey))
assertEdDSACleared(t, keys[1].entity.PrivateKey.PrivateKey.(*ed25519.PrivateKey))
assertRSACleared(t, keys[2].entity.PrivateKey.PrivateKey.(*rsa.PrivateKey))
}
func TestClearPrivateWithSubkeys(t *testing.T) {
keyRingCopy, err := keyRingTestMultiple.Copy()
if err != nil {
t.Fatal("Expected no error while copying keyring, got:", err)
}
for _, key := range keyRingCopy.GetKeys() {
assert.Exactly(t, 2, key.clearPrivateWithSubkeys())
}
keys := keyRingCopy.GetKeys()
assertRSACleared(t, keys[0].entity.PrivateKey.PrivateKey.(*rsa.PrivateKey))
assertRSACleared(t, keys[0].entity.Subkeys[0].PrivateKey.PrivateKey.(*rsa.PrivateKey))
assertEdDSACleared(t, keys[1].entity.PrivateKey.PrivateKey.(*ed25519.PrivateKey))
assertECDHCleared(t, keys[1].entity.Subkeys[0].PrivateKey.PrivateKey.(*ecdh.PrivateKey))
assertRSACleared(t, keys[2].entity.PrivateKey.PrivateKey.(*rsa.PrivateKey))
assertRSACleared(t, keys[2].entity.Subkeys[0].PrivateKey.PrivateKey.(*rsa.PrivateKey))
}
func TestClearPrivateParams(t *testing.T) {
keyRingCopy, err := keyRingTestMultiple.Copy()
if err != nil {
t.Fatal("Expected no error while copying keyring, got:", err)
}
for _, key := range keyRingCopy.GetKeys() {
assert.True(t, key.IsPrivate())
assert.True(t, key.ClearPrivateParams())
assert.False(t, key.IsPrivate())
assert.Nil(t, key.entity.PrivateKey)
assert.Nil(t, key.entity.Subkeys[0].PrivateKey)
assert.False(t, key.ClearPrivateParams())
}
}
func TestEncryptedDetachedSignature(t *testing.T) {
keyRingPrivate, err := keyRingTestPrivate.Copy()
if err != nil {
t.Fatal("Expected no error while copying keyring, got:", err)
}
keyRingPublic, err := keyRingTestPublic.Copy()
if err != nil {
t.Fatal("Expected no error while copying keyring, got:", err)
}
message := NewPlainMessageFromString("Hello World!")
encSign, err := keyRingPrivate.SignDetachedEncrypted(message, keyRingPublic)
if err != nil {
t.Fatal("Expected no error while encryptedSigning, got:", err)
}
err = keyRingPublic.VerifyDetachedEncrypted(message, encSign, keyRingPrivate, 0)
if err != nil {
t.Fatal("Expected no error while verifying encSignature, got:", err)
}
message2 := NewPlainMessageFromString("Bye!")
err = keyRingPublic.VerifyDetachedEncrypted(message2, encSign, keyRingPrivate, 0)
if err == nil {
t.Fatal("Expected an error while verifying bad encSignature, got nil")
}
}
func TestKeyringCapabilities(t *testing.T) {
assert.True(t, keyRingTestPrivate.CanVerify())
assert.True(t, keyRingTestPrivate.CanEncrypt())
assert.True(t, keyRingTestPublic.CanVerify())
assert.True(t, keyRingTestPublic.CanEncrypt())
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)
}
}