From 979fdb3f4b7d78f67ba9cc811157dd150009441c Mon Sep 17 00:00:00 2001 From: wussler Date: Wed, 22 Jul 2020 17:13:23 +0200 Subject: [PATCH] Add ToPublic method to get a public key object from a private key (#65) --- CHANGELOG.md | 5 +++++ crypto/key.go | 15 +++++++++++++++ crypto/key_test.go | 16 ++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9eb6b67..97ea6f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,11 @@ EncryptBinaryMessageArmored(key string, data []byte) (string, error) DecryptBinaryMessageArmored(privateKey string, passphrase []byte, ciphertext string) ([]byte, error) ``` +- Method to derive a public key object from a private key +```go +(key *Key) ToPublic() (publicKey *Key, err error) +``` + ### Changed - Improved key and message armoring testing - `EncryptSessionKey` now creates encrypted key packets for each valid encryption key in the provided keyring. diff --git a/crypto/key.go b/crypto/key.go index bfbb0e1..1ede809 100644 --- a/crypto/key.go +++ b/crypto/key.go @@ -359,6 +359,21 @@ func (key *Key) GetEntity() *openpgp.Entity { return key.entity } +// ToPublic returns the corresponding public key of the given private key. +func (key *Key) ToPublic() (publicKey *Key, err error) { + if !key.IsPrivate() { + return nil, errors.New("gopenpgp: key is already public") + } + + publicKey, err = key.Copy() + if err != nil { + return nil, err + } + + publicKey.ClearPrivateParams() + return +} + // --- Internal methods // getSHA256FingerprintBytes computes the SHA256 fingerprint of a public key diff --git a/crypto/key_test.go b/crypto/key_test.go index 25b1c86..82e0577 100644 --- a/crypto/key_test.go +++ b/crypto/key_test.go @@ -389,3 +389,19 @@ func TestGetEntity(t *testing.T) { assert.True(t, entity.PrimaryIdentity().SelfSignature.FlagsValid) assert.IsType(t, &openpgp.Entity{}, entity) } + +func TestToPublic(t *testing.T) { + privateKey, err := NewKeyFromArmored(readTestFile("keyring_privateKey", false)) + if err != nil { + t.Fatal("Cannot unarmor key:", err) + } + assert.True(t, privateKey.IsPrivate()) + + publicKey, err := privateKey.ToPublic() + if err != nil { + t.Fatal("Cannot make key public:", err) + } + + assert.False(t, publicKey.IsPrivate()) + assert.True(t, privateKey.IsPrivate()) +}