diff --git a/CHANGELOG.md b/CHANGELOG.md index 2352ffa5..a63d93d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ 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/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased +### Added +- API to ASCII encode (armor) KeyRings: + ```go + func (keyRing *KeyRing) Armor() (string, error) + ``` + ## [3.1.0] 2024-11-25 ### Added - Add decryption option to allow disabling the integrity tag requirement. diff --git a/crypto/keyring.go b/crypto/keyring.go index 35d01333..cdcc547a 100644 --- a/crypto/keyring.go +++ b/crypto/keyring.go @@ -7,6 +7,8 @@ import ( "github.com/ProtonMail/go-crypto/openpgp/packet" openpgp "github.com/ProtonMail/go-crypto/openpgp/v2" + "github.com/ProtonMail/gopenpgp/v2/armor" + "github.com/ProtonMail/gopenpgp/v2/constants" "github.com/pkg/errors" ) @@ -133,6 +135,16 @@ func (keyRing *KeyRing) Serialize() ([]byte, error) { return buffer.Bytes(), nil } +// Armor returns the armored keyring as a string with default gopenpgp headers. +func (keyRing *KeyRing) Armor() (string, error) { + serialized, err := keyRing.Serialize() + if err != nil { + return "", err + } + + return armor.ArmorWithType(serialized, constants.PublicKeyHeader) +} + // --- Extract info from key // CountEntities returns the number of entities in the keyring. diff --git a/crypto/keyring_test.go b/crypto/keyring_test.go index 5cd5dcd3..68964cdf 100644 --- a/crypto/keyring_test.go +++ b/crypto/keyring_test.go @@ -2,6 +2,7 @@ package crypto import ( "crypto/rsa" + "regexp" "testing" "github.com/stretchr/testify/assert" @@ -160,6 +161,14 @@ func TestSerializeParse(t *testing.T) { } } +func TestArmor(t *testing.T) { + armoredRing, err := keyRingTestMultiple.Armor() + assert.Nil(t, err) + + rTest := regexp.MustCompile(`(?s)^-----BEGIN PGP PUBLIC KEY BLOCK-----.*Version: GopenPGP [0-9]+\.[0-9]+\.[0-9]+.*-----END PGP PUBLIC KEY BLOCK-----$`) + assert.Regexp(t, rTest, armoredRing) +} + func TestClearPrivateKey(t *testing.T) { keyRingCopy, err := keyRingTestMultiple.Copy() if err != nil {