148 lines
3.7 KiB
Go
148 lines
3.7 KiB
Go
package truststores
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/zalando/go-keyring"
|
|
|
|
"github.com/safing/jess"
|
|
)
|
|
|
|
const (
|
|
keyringServiceNamePrefix = "jess:"
|
|
|
|
keyringSelfcheckKey = "_selfcheck"
|
|
keyringSelfcheckValue = "!selfcheck"
|
|
)
|
|
|
|
// KeyringTrustStore is a trust store that uses the system keyring.
|
|
// It does not support listing entries, so it cannot be easily managed.
|
|
type KeyringTrustStore struct {
|
|
serviceName string
|
|
}
|
|
|
|
// NewKeyringTrustStore returns a new keyring trust store with the given service name.
|
|
// The effect of the service name depends on the operating system.
|
|
// Read more at https://pkg.go.dev/github.com/zalando/go-keyring
|
|
func NewKeyringTrustStore(serviceName string) (*KeyringTrustStore, error) {
|
|
krts := &KeyringTrustStore{
|
|
serviceName: keyringServiceNamePrefix + serviceName,
|
|
}
|
|
|
|
// Run a self-check.
|
|
err := keyring.Set(krts.serviceName, keyringSelfcheckKey, keyringSelfcheckValue)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
selfcheckReturn, err := keyring.Get(krts.serviceName, keyringSelfcheckKey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if selfcheckReturn != keyringSelfcheckValue {
|
|
return nil, errors.New("keyring is faulty")
|
|
}
|
|
|
|
return krts, nil
|
|
}
|
|
|
|
// GetSignet returns the Signet with the given ID.
|
|
func (krts *KeyringTrustStore) GetSignet(id string, recipient bool) (*jess.Signet, error) {
|
|
// Build ID.
|
|
if recipient {
|
|
id += recipientSuffix
|
|
} else {
|
|
id += signetSuffix
|
|
}
|
|
|
|
// Get data from keyring.
|
|
data, err := keyring.Get(krts.serviceName, id)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("%w: %w", jess.ErrSignetNotFound, err)
|
|
}
|
|
|
|
// Parse and return.
|
|
return jess.SignetFromBase58(data)
|
|
}
|
|
|
|
// StoreSignet stores a Signet.
|
|
func (krts *KeyringTrustStore) StoreSignet(signet *jess.Signet) error {
|
|
// Build ID.
|
|
var id string
|
|
if signet.Public {
|
|
id = signet.ID + recipientSuffix
|
|
} else {
|
|
id = signet.ID + signetSuffix
|
|
}
|
|
|
|
// Serialize.
|
|
data, err := signet.ToBase58()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Save to keyring.
|
|
return keyring.Set(krts.serviceName, id, data)
|
|
}
|
|
|
|
// DeleteSignet deletes the Signet or Recipient with the given ID.
|
|
func (krts *KeyringTrustStore) DeleteSignet(id string, recipient bool) error {
|
|
// Build ID.
|
|
if recipient {
|
|
id += recipientSuffix
|
|
} else {
|
|
id += signetSuffix
|
|
}
|
|
|
|
// Delete from keyring.
|
|
return keyring.Delete(krts.serviceName, id)
|
|
}
|
|
|
|
// SelectSignets returns a selection of the signets in the trust store. Results are filtered by tool/algorithm and whether it you're looking for a signet (private key) or a recipient (public key).
|
|
func (krts *KeyringTrustStore) SelectSignets(filter uint8, schemes ...string) ([]*jess.Signet, error) {
|
|
return nil, ErrNotSupportedByTrustStore
|
|
}
|
|
|
|
// GetEnvelope returns the Envelope with the given name.
|
|
func (krts *KeyringTrustStore) GetEnvelope(name string) (*jess.Envelope, error) {
|
|
// Build ID.
|
|
name += envelopeSuffix
|
|
|
|
// Get data from keyring.
|
|
data, err := keyring.Get(krts.serviceName, name)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("%w: %w", jess.ErrEnvelopeNotFound, err)
|
|
}
|
|
|
|
// Parse and return.
|
|
return jess.EnvelopeFromBase58(data)
|
|
}
|
|
|
|
// StoreEnvelope stores an Envelope.
|
|
func (krts *KeyringTrustStore) StoreEnvelope(envelope *jess.Envelope) error {
|
|
// Build ID.
|
|
name := envelope.Name + envelopeSuffix
|
|
|
|
// Serialize.
|
|
data, err := envelope.ToBase58()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Save to keyring.
|
|
return keyring.Set(krts.serviceName, name, data)
|
|
}
|
|
|
|
// DeleteEnvelope deletes the Envelope with the given name.
|
|
func (krts *KeyringTrustStore) DeleteEnvelope(name string) error {
|
|
// Build ID.
|
|
name += envelopeSuffix
|
|
|
|
// Delete from keyring.
|
|
return keyring.Delete(krts.serviceName, name)
|
|
}
|
|
|
|
// AllEnvelopes returns all envelopes.
|
|
func (krts *KeyringTrustStore) AllEnvelopes() ([]*jess.Envelope, error) {
|
|
return nil, ErrNotSupportedByTrustStore
|
|
}
|