github.com/choria-io/go-choria@v0.28.1-0.20240416190746-b3bf9c7d5a45/aagent/watchers/pluginswatcher/specification.go (about) 1 // Copyright (c) 2023, R.I. Pienaar and the Choria Project contributors 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 5 package pluginswatcher 6 7 import ( 8 "crypto/ed25519" 9 "encoding/hex" 10 "encoding/json" 11 "fmt" 12 13 iu "github.com/choria-io/go-choria/internal/util" 14 ) 15 16 // Specification holds []ManagedPlugin marshaled to JSON with an optional ed25519 signature 17 type Specification struct { 18 Plugins string `json:"plugins"` 19 Signature string `json:"signature,omitempty"` 20 } 21 22 // Encode sets the signature and Marshals the specification to JSON, if key is empty signature is not made 23 func (s *Specification) Encode(key string) ([]byte, error) { 24 var pk ed25519.PrivateKey 25 var err error 26 27 if key != "" { 28 if iu.FileExist(key) { 29 _, pk, err = iu.Ed25519KeyPairFromSeedFile(key) 30 } else { 31 pk, err = hex.DecodeString(key) 32 } 33 if err != nil { 34 return nil, err 35 } 36 37 sig, err := iu.Ed25519Sign(pk, []byte(s.Plugins)) 38 if err != nil { 39 return nil, err 40 } 41 42 s.Signature = hex.EncodeToString(sig) 43 } 44 45 return json.Marshal(s) 46 } 47 48 // VerifySignature verifies that the data is signed using the supplied key 49 func (s *Specification) VerifySignature(key ed25519.PublicKey) (bool, error) { 50 sig, err := hex.DecodeString(s.Signature) 51 if err != nil { 52 return false, fmt.Errorf("invalid signature data: %w", err) 53 } 54 55 return iu.Ed25519Verify(key, []byte(s.Plugins), sig) 56 }