diff --git a/crypto/key.go b/crypto/key.go index 8a76107..a02f01a 100644 --- a/crypto/key.go +++ b/crypto/key.go @@ -114,13 +114,15 @@ func (key *Key) Lock(passphrase []byte) (*Key, error) { return lockedKey, nil } - err = lockedKey.entity.PrivateKey.Encrypt(passphrase) - if err != nil { - return nil, errors.Wrap(err, "gopenpgp: error in locking key") + if lockedKey.entity.PrivateKey != nil && !lockedKey.entity.PrivateKey.Dummy() { + err = lockedKey.entity.PrivateKey.Encrypt(passphrase) + if err != nil { + return nil, errors.Wrap(err, "gopenpgp: error in locking key") + } } for _, sub := range lockedKey.entity.Subkeys { - if sub.PrivateKey != nil { + if sub.PrivateKey != nil && !sub.PrivateKey.Dummy() { if err := sub.PrivateKey.Encrypt(passphrase); err != nil { return nil, errors.Wrap(err, "gopenpgp: error in locking sub key") } @@ -157,9 +159,11 @@ func (key *Key) Unlock(passphrase []byte) (*Key, error) { return nil, err } - err = unlockedKey.entity.PrivateKey.Decrypt(passphrase) - if err != nil { - return nil, errors.Wrap(err, "gopenpgp: error in unlocking key") + if unlockedKey.entity.PrivateKey != nil && !unlockedKey.entity.PrivateKey.Dummy() { + err = unlockedKey.entity.PrivateKey.Decrypt(passphrase) + if err != nil { + return nil, errors.Wrap(err, "gopenpgp: error in unlocking key") + } } for _, sub := range unlockedKey.entity.Subkeys { diff --git a/crypto/message_test.go b/crypto/message_test.go index c0de997..392e2c0 100644 --- a/crypto/message_test.go +++ b/crypto/message_test.go @@ -214,6 +214,54 @@ func TestIssue11(t *testing.T) { assert.Exactly(t, "message from sender", plainMessage.GetString()) } + +func TestDummy(t *testing.T) { + pgp.latestServerTime = 1636644417 + defer func() { pgp.latestServerTime = testTime }() + + dummyKey, err := NewKeyFromArmored(readTestFile("key_dummy", false)) + if err != nil { + t.Fatal("Expected no error while unarmoring public keyring, got:", err) + } + + unlockedDummyKey, err := dummyKey.Unlock([]byte("golang")) + if err != nil { + t.Fatal("Expected no error while unlocking private key, got:", err) + } + + _, err = unlockedDummyKey.Lock([]byte("golang")) + if err != nil { + t.Fatal("Expected no error while unlocking private key, got:", err) + } + + dummyKeyRing, err := NewKeyRing(unlockedDummyKey) + if err != nil { + t.Fatal("Expected no error while building private keyring, got:", err) + } + + var message = NewPlainMessageFromString( + "The secret code is... 1, 2, 3, 4, 5. I repeat: the secret code is... 1, 2, 3, 4, 5", + ) + + ciphertext, err := dummyKeyRing.Encrypt(message, nil) + if err != nil { + t.Fatal("Expected no error when encrypting, got:", err) + } + + split, err := ciphertext.SeparateKeyAndData(1024, 0) + if err != nil { + t.Fatal("Expected no error when splitting, got:", err) + } + + assert.Len(t, split.GetBinaryDataPacket(), 133) // Assert uncompressed encrypted body length + + decrypted, err := dummyKeyRing.Decrypt(ciphertext, nil, 0) + if err != nil { + t.Fatal("Expected no error when decrypting, got:", err) + } + assert.Exactly(t, message.GetString(), decrypted.GetString()) +} + func TestSignedMessageDecryption(t *testing.T) { pgpMessage, err := NewPGPMessageFromArmored(readTestFile("message_signed", false)) if err != nil { diff --git a/crypto/testdata/key_dummy b/crypto/testdata/key_dummy new file mode 100644 index 0000000..e3fa805 --- /dev/null +++ b/crypto/testdata/key_dummy @@ -0,0 +1,45 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +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 +XGP4suk8zJsKrEscczTb +=HRg1 +-----END PGP PRIVATE KEY BLOCK-----