Add parsing and serializing interfaces for keyrings (#275)
* Add parsing and serializing interfaces for keyrings * Make error check more compact
This commit is contained in:
parent
453e81905b
commit
0d1ce13767
3 changed files with 69 additions and 0 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
|
@ -4,6 +4,18 @@ 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/),
|
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).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- API to serialize KeyRings to binary data:
|
||||||
|
```go
|
||||||
|
func (keyRing *KeyRing) Serialize() ([]byte, error)
|
||||||
|
```
|
||||||
|
- API to parse KeyRings from binary data:
|
||||||
|
```go
|
||||||
|
func NewKeyRingFromBinary(binKeys []byte) (*KeyRing, error)
|
||||||
|
```
|
||||||
|
|
||||||
## [2.7.5] 2023-31-01
|
## [2.7.5] 2023-31-01
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,29 @@ func (keyRing *KeyRing) AddKey(key *Key) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewKeyRingFromBinary creates a new keyring with all the keys contained in the unarmored binary data.
|
||||||
|
// Note that it accepts only unlocked or public keys, as KeyRing cannot contain locked keys.
|
||||||
|
func NewKeyRingFromBinary(binKeys []byte) (*KeyRing, error) {
|
||||||
|
entities, err := openpgp.ReadKeyRing(bytes.NewReader(binKeys))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "gopenpgp: error in reading keyring")
|
||||||
|
}
|
||||||
|
|
||||||
|
keyring := &KeyRing{}
|
||||||
|
for _, entity := range entities {
|
||||||
|
key, err := NewKeyFromEntity(entity)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "gopenpgp: error in reading keyring")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = keyring.AddKey(key); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "gopenpgp: error in reading keyring")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return keyring, nil
|
||||||
|
}
|
||||||
|
|
||||||
// --- Extract keys from keyring
|
// --- Extract keys from keyring
|
||||||
|
|
||||||
// GetKeys returns openpgp keys contained in this KeyRing.
|
// GetKeys returns openpgp keys contained in this KeyRing.
|
||||||
|
|
@ -88,6 +111,25 @@ func (keyRing *KeyRing) getSigningEntity() (*openpgp.Entity, error) {
|
||||||
return signEntity, nil
|
return signEntity, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Serialize serializes a KeyRing to binary data.
|
||||||
|
func (keyRing *KeyRing) Serialize() ([]byte, error) {
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
|
||||||
|
for _, entity := range keyRing.entities {
|
||||||
|
var err error
|
||||||
|
if entity.PrivateKey == nil {
|
||||||
|
err = entity.Serialize(&buffer)
|
||||||
|
} else {
|
||||||
|
err = entity.SerializePrivateWithoutSigning(&buffer, nil)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "gopenpgp: error in serializing keyring")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
// --- Extract info from key
|
// --- Extract info from key
|
||||||
|
|
||||||
// CountEntities returns the number of entities in the keyring.
|
// CountEntities returns the number of entities in the keyring.
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,21 @@ func TestMultipleKeyRing(t *testing.T) {
|
||||||
assert.Exactly(t, 1, singleKeyRing.CountDecryptionEntities())
|
assert.Exactly(t, 1, singleKeyRing.CountDecryptionEntities())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSerializeParse(t *testing.T) {
|
||||||
|
serialized, err := keyRingTestMultiple.Serialize()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
parsed, err := NewKeyRingFromBinary(serialized)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
assert.Exactly(t, 3, len(parsed.GetKeys()))
|
||||||
|
for i, parsedKey := range parsed.GetKeys() {
|
||||||
|
expectedKey, err := keyRingTestMultiple.GetKey(i)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Exactly(t, parsedKey.GetFingerprint(), expectedKey.GetFingerprint())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestClearPrivateKey(t *testing.T) {
|
func TestClearPrivateKey(t *testing.T) {
|
||||||
keyRingCopy, err := keyRingTestMultiple.Copy()
|
keyRingCopy, err := keyRingTestMultiple.Copy()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue