github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/attestation/attestation.go (about)

     1  package attestation
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/base64"
     6  	"encoding/json"
     7  
     8  	"github.com/in-toto/in-toto-golang/in_toto"
     9  	"github.com/secure-systems-lab/go-securesystemslib/dsse"
    10  	"golang.org/x/xerrors"
    11  )
    12  
    13  // CosignPredicate specifies the format of the Custom Predicate.
    14  // Cosign uses this structure when creating an SBOM attestation.
    15  // cf. https://github.com/sigstore/cosign/blob/e0547cff64f98585a837a524ff77ff6b47ff5609/pkg/cosign/attestation/attestation.go#L39-L43
    16  type CosignPredicate struct {
    17  	Data interface{}
    18  }
    19  
    20  // Statement holds in-toto statement headers and the predicate.
    21  type Statement in_toto.Statement
    22  
    23  func (s *Statement) UnmarshalJSON(b []byte) error {
    24  	var envelope dsse.Envelope
    25  	err := json.NewDecoder(bytes.NewReader(b)).Decode(&envelope)
    26  	if err != nil {
    27  		return xerrors.Errorf("failed to decode as a dsse envelope: %w", err)
    28  	}
    29  	if envelope.PayloadType != in_toto.PayloadType {
    30  		return xerrors.Errorf("invalid attestation payload type: %s", envelope.PayloadType)
    31  	}
    32  
    33  	decoded, err := base64.StdEncoding.DecodeString(envelope.Payload)
    34  	if err != nil {
    35  		return xerrors.Errorf("failed to decode attestation payload: %w", err)
    36  	}
    37  
    38  	statement := (*in_toto.Statement)(s)
    39  	if err = json.NewDecoder(bytes.NewReader(decoded)).Decode(statement); err != nil {
    40  		return xerrors.Errorf("failed to decode attestation payload as in-toto statement: %w", err)
    41  	}
    42  
    43  	return nil
    44  }