...

Source file src/github.com/in-toto/in-toto-golang/in_toto/envelope.go

Documentation: github.com/in-toto/in-toto-golang/in_toto

     1  package in_toto
     2  
     3  import (
     4  	"context"
     5  	"encoding/base64"
     6  	"encoding/json"
     7  	"errors"
     8  	"fmt"
     9  	"os"
    10  
    11  	"github.com/secure-systems-lab/go-securesystemslib/cjson"
    12  	"github.com/secure-systems-lab/go-securesystemslib/dsse"
    13  	"github.com/secure-systems-lab/go-securesystemslib/signerverifier"
    14  )
    15  
    16  // PayloadType is the payload type used for links and layouts.
    17  const PayloadType = "application/vnd.in-toto+json"
    18  
    19  // ErrInvalidPayloadType indicates that the envelope used an unknown payload type
    20  var ErrInvalidPayloadType = errors.New("unknown payload type")
    21  
    22  type Envelope struct {
    23  	envelope *dsse.Envelope
    24  	payload  any
    25  }
    26  
    27  func loadEnvelope(env *dsse.Envelope) (*Envelope, error) {
    28  	e := &Envelope{envelope: env}
    29  
    30  	contentBytes, err := env.DecodeB64Payload()
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  
    35  	payload, err := loadPayload(contentBytes)
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  	e.payload = payload
    40  
    41  	return e, nil
    42  }
    43  
    44  func (e *Envelope) SetPayload(payload any) error {
    45  	encodedBytes, err := cjson.EncodeCanonical(payload)
    46  	if err != nil {
    47  		return err
    48  	}
    49  
    50  	e.payload = payload
    51  	e.envelope = &dsse.Envelope{
    52  		Payload:     base64.StdEncoding.EncodeToString(encodedBytes),
    53  		PayloadType: PayloadType,
    54  	}
    55  
    56  	return nil
    57  }
    58  
    59  func (e *Envelope) GetPayload() any {
    60  	return e.payload
    61  }
    62  
    63  func (e *Envelope) VerifySignature(key Key) error {
    64  	verifier, err := getSignerVerifierFromKey(key)
    65  	if err != nil {
    66  		return err
    67  	}
    68  
    69  	ev, err := dsse.NewEnvelopeVerifier(verifier)
    70  	if err != nil {
    71  		return err
    72  	}
    73  
    74  	_, err = ev.Verify(context.Background(), e.envelope)
    75  	return err
    76  }
    77  
    78  func (e *Envelope) Sign(key Key) error {
    79  	signer, err := getSignerVerifierFromKey(key)
    80  	if err != nil {
    81  		return err
    82  	}
    83  
    84  	es, err := dsse.NewEnvelopeSigner(signer)
    85  	if err != nil {
    86  		return err
    87  	}
    88  
    89  	payload, err := e.envelope.DecodeB64Payload()
    90  	if err != nil {
    91  		return err
    92  	}
    93  
    94  	env, err := es.SignPayload(context.Background(), e.envelope.PayloadType, payload)
    95  	if err != nil {
    96  		return err
    97  	}
    98  
    99  	e.envelope = env
   100  	return nil
   101  }
   102  
   103  func (e *Envelope) Sigs() []Signature {
   104  	sigs := []Signature{}
   105  	for _, s := range e.envelope.Signatures {
   106  		sigs = append(sigs, Signature{
   107  			KeyID: s.KeyID,
   108  			Sig:   s.Sig,
   109  		})
   110  	}
   111  	return sigs
   112  }
   113  
   114  func (e *Envelope) GetSignatureForKeyID(keyID string) (Signature, error) {
   115  	for _, s := range e.Sigs() {
   116  		if s.KeyID == keyID {
   117  			return s, nil
   118  		}
   119  	}
   120  
   121  	return Signature{}, fmt.Errorf("no signature found for key '%s'", keyID)
   122  }
   123  
   124  func (e *Envelope) Dump(path string) error {
   125  	jsonBytes, err := json.MarshalIndent(e.envelope, "", "  ")
   126  	if err != nil {
   127  		return err
   128  	}
   129  
   130  	// Write JSON bytes to the passed path with permissions (-rw-r--r--)
   131  	err = os.WriteFile(path, jsonBytes, 0644)
   132  	if err != nil {
   133  		return err
   134  	}
   135  
   136  	return nil
   137  }
   138  
   139  func getSignerVerifierFromKey(key Key) (dsse.SignerVerifier, error) {
   140  	sslibKey := getSSLibKeyFromKey(key)
   141  
   142  	switch sslibKey.KeyType {
   143  	case signerverifier.RSAKeyType:
   144  		return signerverifier.NewRSAPSSSignerVerifierFromSSLibKey(&sslibKey)
   145  	case signerverifier.ED25519KeyType:
   146  		return signerverifier.NewED25519SignerVerifierFromSSLibKey(&sslibKey)
   147  	case signerverifier.ECDSAKeyType:
   148  		return signerverifier.NewECDSASignerVerifierFromSSLibKey(&sslibKey)
   149  	}
   150  
   151  	return nil, ErrUnsupportedKeyType
   152  }
   153  
   154  func getSSLibKeyFromKey(key Key) signerverifier.SSLibKey {
   155  	return signerverifier.SSLibKey{
   156  		KeyType:             key.KeyType,
   157  		KeyIDHashAlgorithms: key.KeyIDHashAlgorithms,
   158  		KeyID:               key.KeyID,
   159  		Scheme:              key.Scheme,
   160  		KeyVal: signerverifier.KeyVal{
   161  			Public:      key.KeyVal.Public,
   162  			Private:     key.KeyVal.Private,
   163  			Certificate: key.KeyVal.Certificate,
   164  		},
   165  	}
   166  }
   167  

View as plain text