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  }