136 lines
3.1 KiB
Go
136 lines
3.1 KiB
Go
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
|
|
|
package config
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"github.com/ProtonMail/go-crypto/openpgp"
|
|
|
|
"io"
|
|
"strings"
|
|
"strconv"
|
|
"gopkg.in/yaml.v3"
|
|
"decl/internal/data"
|
|
"decl/internal/codec"
|
|
"fmt"
|
|
"log/slog"
|
|
)
|
|
|
|
type OpenPGPSignature struct {
|
|
KeyRing string `json:"keyring,omitempty" yaml:"keyring,omitempty"`
|
|
Signature string `json:"signature,omitempty" yaml:"signature,omitempty"`
|
|
entities openpgp.EntityList
|
|
}
|
|
|
|
func NewOpenPGPSignature() *OpenPGPSignature {
|
|
o := &OpenPGPSignature{}
|
|
return o
|
|
}
|
|
|
|
func (o *OpenPGPSignature) URI() string {
|
|
return fmt.Sprintf("%s://%s", o.Type(), "")
|
|
}
|
|
|
|
func (o *OpenPGPSignature) SetURI(uri string) error {
|
|
return nil
|
|
}
|
|
|
|
func (o *OpenPGPSignature) SetParsedURI(uri data.URIParser) error {
|
|
return nil
|
|
}
|
|
|
|
func (o *OpenPGPSignature) Read(ctx context.Context) (yamlData []byte, err error) {
|
|
pemReader := io.NopCloser(strings.NewReader(o.KeyRing))
|
|
o.entities, err = openpgp.ReadArmoredKeyRing(pemReader)
|
|
return
|
|
}
|
|
|
|
func (o *OpenPGPSignature) Load(r io.Reader) (err error) {
|
|
err = codec.NewYAMLDecoder(r).Decode(o)
|
|
if err == nil {
|
|
_, err = o.Read(context.Background())
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (o *OpenPGPSignature) LoadYAML(yamlData string) (err error) {
|
|
err = codec.NewYAMLStringDecoder(yamlData).Decode(o)
|
|
slog.Info("OpenPGP.LoadYAML()", "keyring", len(o.KeyRing), "err", err)
|
|
if err == nil {
|
|
_, err = o.Read(context.Background())
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (o *OpenPGPSignature) UnmarshalJSON(data []byte) error {
|
|
if unmarshalErr := json.Unmarshal(data, o); unmarshalErr != nil {
|
|
return unmarshalErr
|
|
}
|
|
//o.NewReadConfigCommand()
|
|
return nil
|
|
}
|
|
|
|
func (o *OpenPGPSignature) UnmarshalYAML(value *yaml.Node) error {
|
|
type decodeOpenPGP OpenPGPSignature
|
|
if unmarshalErr := value.Decode((*decodeOpenPGP)(o)); unmarshalErr != nil {
|
|
return unmarshalErr
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (o *OpenPGPSignature) Clone() data.Configuration {
|
|
jsonGeneric, _ := json.Marshal(o)
|
|
clone := NewOpenPGPSignature()
|
|
if unmarshalErr := json.Unmarshal(jsonGeneric, &clone); unmarshalErr != nil {
|
|
panic(unmarshalErr)
|
|
}
|
|
return clone
|
|
}
|
|
|
|
func (o *OpenPGPSignature) Type() string {
|
|
return "openpgp"
|
|
}
|
|
|
|
func (o *OpenPGPSignature) GetEntityIndex(key string) (index int, field string, err error) {
|
|
values := strings.SplitN(key, ".", 2)
|
|
if len(values) == 2 {
|
|
if index, err = strconv.Atoi(values[0]); err == nil {
|
|
field = values[1]
|
|
}
|
|
} else {
|
|
err = data.ErrUnknownConfigurationKey
|
|
}
|
|
return
|
|
}
|
|
|
|
func (o *OpenPGPSignature) GetValue(name string) (result any, err error) {
|
|
index, field, err := o.GetEntityIndex(name)
|
|
if len(o.entities) > index && err == nil {
|
|
switch field {
|
|
case "PublicKey":
|
|
return o.entities[index].PrimaryKey, err
|
|
case "PrivateKey":
|
|
return o.entities[index].PrimaryKey, err
|
|
}
|
|
}
|
|
err = data.ErrUnknownConfigurationKey
|
|
return
|
|
}
|
|
|
|
|
|
// Expected key: 0.PrivateKey
|
|
func (o *OpenPGPSignature) Has(key string) (ok bool) {
|
|
index, field, err := o.GetEntityIndex(key)
|
|
if len(o.entities) > index && err == nil {
|
|
switch field {
|
|
case "PublicKey":
|
|
ok = o.entities[index].PrimaryKey != nil
|
|
case "PrivateKey":
|
|
ok = o.entities[index].PrimaryKey != nil
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|