...

Source file src/github.com/sigstore/cosign/v2/pkg/oci/static/signature.go

Documentation: github.com/sigstore/cosign/v2/pkg/oci/static

     1  //
     2  // Copyright 2021 The Sigstore Authors.
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  package static
    17  
    18  import (
    19  	"bytes"
    20  	"crypto/x509"
    21  	"encoding/base64"
    22  	"io"
    23  
    24  	v1 "github.com/google/go-containerregistry/pkg/v1"
    25  	"github.com/google/go-containerregistry/pkg/v1/types"
    26  	"github.com/sigstore/cosign/v2/pkg/cosign/bundle"
    27  	"github.com/sigstore/cosign/v2/pkg/oci"
    28  	"github.com/sigstore/sigstore/pkg/cryptoutils"
    29  )
    30  
    31  const (
    32  	SignatureAnnotationKey        = "dev.cosignproject.cosign/signature"
    33  	CertificateAnnotationKey      = "dev.sigstore.cosign/certificate"
    34  	ChainAnnotationKey            = "dev.sigstore.cosign/chain"
    35  	BundleAnnotationKey           = "dev.sigstore.cosign/bundle"
    36  	RFC3161TimestampAnnotationKey = "dev.sigstore.cosign/rfc3161timestamp"
    37  )
    38  
    39  // NewSignature constructs a new oci.Signature from the provided options.
    40  func NewSignature(payload []byte, b64sig string, opts ...Option) (oci.Signature, error) {
    41  	o, err := makeOptions(opts...)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  	return &staticLayer{
    46  		b:      payload,
    47  		b64sig: b64sig,
    48  		opts:   o,
    49  	}, nil
    50  }
    51  
    52  // NewAttestation constructs a new oci.Signature from the provided options.
    53  // Since Attestation is treated just like a Signature but the actual signature
    54  // is baked into the payload, the Signature does not actually have
    55  // the Base64Signature.
    56  func NewAttestation(payload []byte, opts ...Option) (oci.Signature, error) {
    57  	return NewSignature(payload, "", opts...)
    58  }
    59  
    60  // Copy constructs a new oci.Signature from the provided one.
    61  func Copy(sig oci.Signature) (oci.Signature, error) {
    62  	payload, err := sig.Payload()
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  	b64sig, err := sig.Base64Signature()
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  	var opts []Option
    71  
    72  	mt, err := sig.MediaType()
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  	opts = append(opts, WithLayerMediaType(mt))
    77  
    78  	ann, err := sig.Annotations()
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  	opts = append(opts, WithAnnotations(ann))
    83  
    84  	bundle, err := sig.Bundle()
    85  	if err != nil {
    86  		return nil, err
    87  	}
    88  	opts = append(opts, WithBundle(bundle))
    89  
    90  	rfc3161Timestamp, err := sig.RFC3161Timestamp()
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  	opts = append(opts, WithRFC3161Timestamp(rfc3161Timestamp))
    95  
    96  	cert, err := sig.Cert()
    97  	if err != nil {
    98  		return nil, err
    99  	}
   100  	if cert != nil {
   101  		rawCert, err := cryptoutils.MarshalCertificateToPEM(cert)
   102  		if err != nil {
   103  			return nil, err
   104  		}
   105  		chain, err := sig.Chain()
   106  		if err != nil {
   107  			return nil, err
   108  		}
   109  		rawChain, err := cryptoutils.MarshalCertificatesToPEM(chain)
   110  		if err != nil {
   111  			return nil, err
   112  		}
   113  		opts = append(opts, WithCertChain(rawCert, rawChain))
   114  	}
   115  	return NewSignature(payload, b64sig, opts...)
   116  }
   117  
   118  type staticLayer struct {
   119  	b      []byte
   120  	b64sig string
   121  	opts   *options
   122  }
   123  
   124  var _ v1.Layer = (*staticLayer)(nil)
   125  var _ oci.Signature = (*staticLayer)(nil)
   126  
   127  // Annotations implements oci.Signature
   128  func (l *staticLayer) Annotations() (map[string]string, error) {
   129  	m := make(map[string]string, len(l.opts.Annotations)+1)
   130  	for k, v := range l.opts.Annotations {
   131  		m[k] = v
   132  	}
   133  	m[SignatureAnnotationKey] = l.b64sig
   134  	return m, nil
   135  }
   136  
   137  // Payload implements oci.Signature
   138  func (l *staticLayer) Payload() ([]byte, error) {
   139  	return l.b, nil
   140  }
   141  
   142  // Signature implements oci.Signature
   143  func (l *staticLayer) Signature() ([]byte, error) {
   144  	b64sig, err := l.Base64Signature()
   145  	if err != nil {
   146  		return nil, err
   147  	}
   148  	return base64.StdEncoding.DecodeString(b64sig)
   149  }
   150  
   151  // Base64Signature implements oci.Signature
   152  func (l *staticLayer) Base64Signature() (string, error) {
   153  	return l.b64sig, nil
   154  }
   155  
   156  // Cert implements oci.Signature
   157  func (l *staticLayer) Cert() (*x509.Certificate, error) {
   158  	certs, err := cryptoutils.LoadCertificatesFromPEM(bytes.NewReader(l.opts.Cert))
   159  	if err != nil {
   160  		return nil, err
   161  	}
   162  	if len(certs) == 0 {
   163  		return nil, nil
   164  	}
   165  	return certs[0], nil
   166  }
   167  
   168  // Chain implements oci.Signature
   169  func (l *staticLayer) Chain() ([]*x509.Certificate, error) {
   170  	certs, err := cryptoutils.LoadCertificatesFromPEM(bytes.NewReader(l.opts.Chain))
   171  	if err != nil {
   172  		return nil, err
   173  	}
   174  	return certs, nil
   175  }
   176  
   177  // Bundle implements oci.Signature
   178  func (l *staticLayer) Bundle() (*bundle.RekorBundle, error) {
   179  	return l.opts.Bundle, nil
   180  }
   181  
   182  // RFC3161Timestamp implements oci.Signature
   183  func (l *staticLayer) RFC3161Timestamp() (*bundle.RFC3161Timestamp, error) {
   184  	return l.opts.RFC3161Timestamp, nil
   185  }
   186  
   187  // Digest implements v1.Layer
   188  func (l *staticLayer) Digest() (v1.Hash, error) {
   189  	h, _, err := v1.SHA256(bytes.NewReader(l.b))
   190  	return h, err
   191  }
   192  
   193  // DiffID implements v1.Layer
   194  func (l *staticLayer) DiffID() (v1.Hash, error) {
   195  	h, _, err := v1.SHA256(bytes.NewReader(l.b))
   196  	return h, err
   197  }
   198  
   199  // Compressed implements v1.Layer
   200  func (l *staticLayer) Compressed() (io.ReadCloser, error) {
   201  	return io.NopCloser(bytes.NewReader(l.b)), nil
   202  }
   203  
   204  // Uncompressed implements v1.Layer
   205  func (l *staticLayer) Uncompressed() (io.ReadCloser, error) {
   206  	return io.NopCloser(bytes.NewReader(l.b)), nil
   207  }
   208  
   209  // Size implements v1.Layer
   210  func (l *staticLayer) Size() (int64, error) {
   211  	return int64(len(l.b)), nil
   212  }
   213  
   214  // MediaType implements v1.Layer
   215  func (l *staticLayer) MediaType() (types.MediaType, error) {
   216  	return l.opts.LayerMediaType, nil
   217  }
   218  

View as plain text