2018-11-05 23:01:53 +01:00
|
|
|
package crypto
|
|
|
|
|
|
|
|
|
|
import (
|
2021-04-28 18:33:14 +02:00
|
|
|
"crypto/ed25519"
|
|
|
|
|
"crypto/rsa"
|
2021-09-23 10:40:56 +02:00
|
|
|
"errors"
|
2018-11-05 23:01:53 +01:00
|
|
|
"testing"
|
2019-05-14 14:42:38 +00:00
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
2019-05-08 13:04:22 +02:00
|
|
|
|
2020-12-08 18:34:39 +01:00
|
|
|
"github.com/ProtonMail/go-crypto/openpgp/ecdh"
|
2021-09-23 10:40:56 +02:00
|
|
|
"github.com/ProtonMail/gopenpgp/v2/constants"
|
2019-12-27 19:35:43 +01:00
|
|
|
)
|
2019-01-11 00:23:00 +01:00
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
var testSymmetricKey []byte
|
2019-06-03 17:00:01 +02:00
|
|
|
|
2020-05-06 18:50:18 +02:00
|
|
|
// Password for key in testdata/keyring_privateKeyLegacy: "123".
|
|
|
|
|
// Corresponding key in testdata/keyring_privateKey.
|
2019-12-27 19:35:43 +01:00
|
|
|
var testMailboxPassword = []byte("apple")
|
2019-05-08 13:04:22 +02:00
|
|
|
|
2018-11-05 23:01:53 +01:00
|
|
|
var (
|
2019-12-27 19:35:43 +01:00
|
|
|
keyRingTestPrivate *KeyRing
|
|
|
|
|
keyRingTestPublic *KeyRing
|
|
|
|
|
keyRingTestMultiple *KeyRing
|
2018-11-05 23:01:53 +01:00
|
|
|
)
|
|
|
|
|
|
2019-05-15 13:48:47 +02:00
|
|
|
var testIdentity = &Identity{
|
|
|
|
|
Name: "UserID",
|
|
|
|
|
Email: "",
|
|
|
|
|
}
|
2018-11-05 23:01:53 +01:00
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
func initKeyRings() {
|
2018-11-05 23:01:53 +01:00
|
|
|
var err error
|
2019-05-14 16:08:25 +00:00
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
testSymmetricKey, err = RandomToken(32)
|
2019-05-14 14:42:38 +00:00
|
|
|
if err != nil {
|
2019-12-27 19:35:43 +01:00
|
|
|
panic("Expected no error while generating random token, got:" + err.Error())
|
2018-11-05 23:01:53 +01:00
|
|
|
}
|
|
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
privateKey, err := NewKeyFromArmored(readTestFile("keyring_privateKey", false))
|
2019-05-14 14:42:38 +00:00
|
|
|
if err != nil {
|
2019-12-27 19:35:43 +01:00
|
|
|
panic("Expected no error while unarmoring private key, got:" + err.Error())
|
2018-11-05 23:01:53 +01:00
|
|
|
}
|
|
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
keyRingTestPrivate, err = NewKeyRing(privateKey)
|
|
|
|
|
if err == nil {
|
|
|
|
|
panic("Able to create a keyring with a locked key")
|
2018-11-05 23:01:53 +01:00
|
|
|
}
|
|
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
unlockedKey, err := privateKey.Unlock(testMailboxPassword)
|
2018-11-05 23:01:53 +01:00
|
|
|
if err != nil {
|
2019-12-27 19:35:43 +01:00
|
|
|
panic("Expected no error while unlocking private key, got:" + err.Error())
|
2018-11-05 23:01:53 +01:00
|
|
|
}
|
|
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
keyRingTestPrivate, err = NewKeyRing(unlockedKey)
|
2018-11-05 23:01:53 +01:00
|
|
|
if err != nil {
|
2019-12-27 19:35:43 +01:00
|
|
|
panic("Expected no error while building private keyring, got:" + err.Error())
|
2018-11-05 23:01:53 +01:00
|
|
|
}
|
2019-05-08 13:04:22 +02:00
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
publicKey, err := NewKeyFromArmored(readTestFile("keyring_publicKey", false))
|
2018-11-05 23:01:53 +01:00
|
|
|
if err != nil {
|
2019-12-27 19:35:43 +01:00
|
|
|
panic("Expected no error while unarmoring public key, got:" + err.Error())
|
2018-11-05 23:01:53 +01:00
|
|
|
}
|
|
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
keyRingTestPublic, err = NewKeyRing(publicKey)
|
2018-11-05 23:01:53 +01:00
|
|
|
if err != nil {
|
2019-12-27 19:35:43 +01:00
|
|
|
panic("Expected no error while building public keyring, got:" + err.Error())
|
2018-11-05 23:01:53 +01:00
|
|
|
}
|
2019-05-08 13:04:22 +02:00
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
keyRingTestMultiple, err = NewKeyRing(nil)
|
2018-11-05 23:01:53 +01:00
|
|
|
if err != nil {
|
2019-12-27 19:35:43 +01:00
|
|
|
panic("Expected no error while building empty keyring, got:" + err.Error())
|
2018-11-05 23:01:53 +01:00
|
|
|
}
|
|
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
err = keyRingTestMultiple.AddKey(keyTestRSA)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic("Expected no error while adding RSA key to keyring, got:" + err.Error())
|
|
|
|
|
}
|
2019-05-15 13:48:47 +02:00
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
err = keyRingTestMultiple.AddKey(keyTestEC)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic("Expected no error while adding EC key to keyring, got:" + err.Error())
|
|
|
|
|
}
|
2019-05-15 13:48:47 +02:00
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
err = keyRingTestMultiple.AddKey(unlockedKey)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic("Expected no error while adding unlocked key to keyring, got:" + err.Error())
|
|
|
|
|
}
|
2019-05-15 13:48:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestIdentities(t *testing.T) {
|
2019-12-27 19:35:43 +01:00
|
|
|
identities := keyRingTestPrivate.GetIdentities()
|
2019-05-15 13:48:47 +02:00
|
|
|
assert.Len(t, identities, 1)
|
|
|
|
|
assert.Exactly(t, identities[0], testIdentity)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFilterExpiredKeys(t *testing.T) {
|
2019-12-27 19:35:43 +01:00
|
|
|
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}
|
2019-05-15 13:48:47 +02:00
|
|
|
unexpired, err := FilterExpiredKeys(keys)
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal("Expected no error while filtering expired keyrings, got:", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert.Len(t, unexpired, 1)
|
2019-12-27 19:35:43 +01:00
|
|
|
assert.Exactly(t, unexpired[0].GetKeyIDs(), keyRingTestPrivate.GetKeyIDs())
|
2019-05-15 13:48:47 +02:00
|
|
|
}
|
2019-06-03 17:00:01 +02:00
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
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())
|
2019-06-03 17:00:01 +02:00
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
assert.Exactly(t, 3, len(keyRingTestMultiple.GetKeys()))
|
|
|
|
|
|
|
|
|
|
testKey, err := keyRingTestMultiple.GetKey(1)
|
2019-06-03 17:00:01 +02:00
|
|
|
if err != nil {
|
2019-12-27 19:35:43 +01:00
|
|
|
t.Fatal("Expected no error while extracting key, got:", err)
|
2019-06-03 17:00:01 +02:00
|
|
|
}
|
2019-12-27 19:35:43 +01:00
|
|
|
assert.Exactly(t, keyTestEC, testKey)
|
|
|
|
|
|
|
|
|
|
_, err = keyRingTestMultiple.GetKey(3)
|
|
|
|
|
assert.NotNil(t, err)
|
2019-06-03 17:00:01 +02:00
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
singleKeyRing, err := keyRingTestMultiple.FirstKey()
|
2019-06-03 17:00:01 +02:00
|
|
|
if err != nil {
|
2019-12-27 19:35:43 +01:00
|
|
|
t.Fatal("Expected no error while filtering the first key, got:", err)
|
2019-06-03 17:00:01 +02:00
|
|
|
}
|
2019-12-27 19:35:43 +01:00
|
|
|
assert.Exactly(t, 1, len(singleKeyRing.entities))
|
|
|
|
|
assert.Exactly(t, 1, singleKeyRing.CountEntities())
|
|
|
|
|
assert.Exactly(t, 1, singleKeyRing.CountDecryptionEntities())
|
|
|
|
|
}
|
2019-06-03 17:00:01 +02:00
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
func TestClearPrivateKey(t *testing.T) {
|
|
|
|
|
keyRingCopy, err := keyRingTestMultiple.Copy()
|
2019-06-03 17:00:01 +02:00
|
|
|
if err != nil {
|
2019-12-27 19:35:43 +01:00
|
|
|
t.Fatal("Expected no error while copying keyring, got:", err)
|
2019-06-03 17:00:01 +02:00
|
|
|
}
|
|
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
for _, key := range keyRingCopy.GetKeys() {
|
|
|
|
|
assert.Nil(t, clearPrivateKey(key.entity.PrivateKey.PrivateKey))
|
|
|
|
|
}
|
2019-06-03 17:00:01 +02:00
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
keys := keyRingCopy.GetKeys()
|
|
|
|
|
assertRSACleared(t, keys[0].entity.PrivateKey.PrivateKey.(*rsa.PrivateKey))
|
2020-11-04 17:40:45 +01:00
|
|
|
assertEdDSACleared(t, keys[1].entity.PrivateKey.PrivateKey.(*ed25519.PrivateKey))
|
2019-12-27 19:35:43 +01:00
|
|
|
assertRSACleared(t, keys[2].entity.PrivateKey.PrivateKey.(*rsa.PrivateKey))
|
2019-06-03 17:00:01 +02:00
|
|
|
}
|
|
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
func TestClearPrivateWithSubkeys(t *testing.T) {
|
|
|
|
|
keyRingCopy, err := keyRingTestMultiple.Copy()
|
2019-08-29 17:45:13 +02:00
|
|
|
if err != nil {
|
2019-12-27 19:35:43 +01:00
|
|
|
t.Fatal("Expected no error while copying keyring, got:", err)
|
2019-08-29 17:45:13 +02:00
|
|
|
}
|
|
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
for _, key := range keyRingCopy.GetKeys() {
|
|
|
|
|
assert.Exactly(t, 2, key.clearPrivateWithSubkeys())
|
|
|
|
|
}
|
2019-08-29 17:45:13 +02:00
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
keys := keyRingCopy.GetKeys()
|
|
|
|
|
assertRSACleared(t, keys[0].entity.PrivateKey.PrivateKey.(*rsa.PrivateKey))
|
|
|
|
|
assertRSACleared(t, keys[0].entity.Subkeys[0].PrivateKey.PrivateKey.(*rsa.PrivateKey))
|
2019-08-29 17:45:13 +02:00
|
|
|
|
2020-11-04 17:40:45 +01:00
|
|
|
assertEdDSACleared(t, keys[1].entity.PrivateKey.PrivateKey.(*ed25519.PrivateKey))
|
2019-12-27 19:35:43 +01:00
|
|
|
assertECDHCleared(t, keys[1].entity.Subkeys[0].PrivateKey.PrivateKey.(*ecdh.PrivateKey))
|
2019-08-29 17:45:13 +02:00
|
|
|
|
2019-12-27 19:35:43 +01:00
|
|
|
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())
|
|
|
|
|
}
|
2019-06-03 17:00:01 +02:00
|
|
|
}
|
2020-12-17 03:58:25 -08:00
|
|
|
|
|
|
|
|
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")
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-04-09 16:02:10 +05:30
|
|
|
|
|
|
|
|
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())
|
|
|
|
|
}
|
2021-09-23 10:40:56 +02:00
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
}
|