...

Source file src/github.com/sigstore/cosign/v2/pkg/oci/static/signature_test.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  	"encoding/base64"
    20  	"io"
    21  	"strings"
    22  	"testing"
    23  
    24  	"github.com/google/go-cmp/cmp"
    25  	v1 "github.com/google/go-containerregistry/pkg/v1"
    26  	"github.com/google/go-containerregistry/pkg/v1/types"
    27  	"github.com/sigstore/cosign/v2/pkg/cosign/bundle"
    28  )
    29  
    30  func TestNewSignatureBasic(t *testing.T) {
    31  	payload := "this is the content!"
    32  	b64sig := "b64 content=="
    33  	l, err := NewSignature([]byte(payload), b64sig, WithLayerMediaType("foo"))
    34  	if err != nil {
    35  		t.Fatalf("NewSignature() = %v", err)
    36  	}
    37  
    38  	t.Run("check size", func(t *testing.T) {
    39  		wantSize := int64(len(payload))
    40  		gotSize, err := l.Size()
    41  		if err != nil {
    42  			t.Fatalf("Size() = %v", err)
    43  		}
    44  		if gotSize != wantSize {
    45  			t.Errorf("Size() = %d, wanted %d", gotSize, wantSize)
    46  		}
    47  	})
    48  
    49  	t.Run("check media type", func(t *testing.T) {
    50  		wantMT := types.MediaType("foo")
    51  		gotMT, err := l.MediaType()
    52  		if err != nil {
    53  			t.Fatalf("MediaType() = %v", err)
    54  		}
    55  		if gotMT != wantMT {
    56  			t.Errorf("MediaType() = %s, wanted %s", gotMT, wantMT)
    57  		}
    58  	})
    59  
    60  	t.Run("check hashes", func(t *testing.T) {
    61  		wantHash, _, err := v1.SHA256(strings.NewReader(payload))
    62  		if err != nil {
    63  			t.Fatalf("SHA256() = %v", err)
    64  		}
    65  
    66  		gotDigest, err := l.Digest()
    67  		if err != nil {
    68  			t.Fatalf("Digest() = %v", err)
    69  		}
    70  		if !cmp.Equal(gotDigest, wantHash) {
    71  			t.Errorf("Digest = %s", cmp.Diff(gotDigest, wantHash))
    72  		}
    73  
    74  		gotDiffID, err := l.DiffID()
    75  		if err != nil {
    76  			t.Fatalf("DiffID() = %v", err)
    77  		}
    78  		if !cmp.Equal(gotDiffID, wantHash) {
    79  			t.Errorf("DiffID = %s", cmp.Diff(gotDiffID, wantHash))
    80  		}
    81  	})
    82  
    83  	t.Run("check content", func(t *testing.T) {
    84  		comp, err := l.Compressed()
    85  		if err != nil {
    86  			t.Fatalf("Compressed() = %v", err)
    87  		}
    88  		defer comp.Close()
    89  		compContent, err := io.ReadAll(comp)
    90  		if err != nil {
    91  			t.Fatalf("ReadAll() = %v", err)
    92  		}
    93  		if got, want := string(compContent), payload; got != want {
    94  			t.Errorf("Compressed() = %s, wanted %s", got, want)
    95  		}
    96  
    97  		uncomp, err := l.Uncompressed()
    98  		if err != nil {
    99  			t.Fatalf("Uncompressed() = %v", err)
   100  		}
   101  		defer uncomp.Close()
   102  		uncompContent, err := io.ReadAll(uncomp)
   103  		if err != nil {
   104  			t.Fatalf("ReadAll() = %v", err)
   105  		}
   106  		if got, want := string(uncompContent), payload; got != want {
   107  			t.Errorf("Uncompressed() = %s, wanted %s", got, want)
   108  		}
   109  
   110  		gotPayload, err := l.Payload()
   111  		if err != nil {
   112  			t.Fatalf("Payload() = %v", err)
   113  		}
   114  		if got, want := string(gotPayload), payload; got != want {
   115  			t.Errorf("Payload() = %s, wanted %s", got, want)
   116  		}
   117  
   118  		gotSig, err := l.Base64Signature()
   119  		if err != nil {
   120  			t.Fatalf("Base64Signature() = %v", err)
   121  		}
   122  		if got, want := gotSig, b64sig; got != want {
   123  			t.Errorf("Base64Signature() = %s, wanted %s", got, want)
   124  		}
   125  
   126  		gotBundle, err := l.Bundle()
   127  		if err != nil {
   128  			t.Fatalf("Bundle() = %v", err)
   129  		}
   130  		if gotBundle != nil {
   131  			t.Errorf("Bundle() = %#v, wanted nil", gotBundle)
   132  		}
   133  	})
   134  
   135  	t.Run("check annotations", func(t *testing.T) {
   136  		want := map[string]string{
   137  			SignatureAnnotationKey: b64sig,
   138  		}
   139  		got, err := l.Annotations()
   140  		if err != nil {
   141  			t.Fatalf("Annotations() = %v", err)
   142  		}
   143  		if !cmp.Equal(got, want) {
   144  			t.Errorf("Annotations = %s", cmp.Diff(got, want))
   145  		}
   146  	})
   147  
   148  	t.Run("check signature accessors", func(t *testing.T) {
   149  		gotPayload, err := l.Payload()
   150  		if err != nil {
   151  			t.Fatalf("Payload() = %v", err)
   152  		}
   153  		if got, want := string(gotPayload), payload; got != want {
   154  			t.Errorf("Payload() = %s, wanted %s", got, want)
   155  		}
   156  
   157  		gotSig, err := l.Base64Signature()
   158  		if err != nil {
   159  			t.Fatalf("Base64Signature() = %v", err)
   160  		}
   161  		if got, want := gotSig, b64sig; got != want {
   162  			t.Errorf("Base64Signature() = %s, wanted %s", got, want)
   163  		}
   164  
   165  		if got, err := l.Bundle(); err != nil {
   166  			t.Fatalf("Bundle() = %v", err)
   167  		} else if got != nil {
   168  			t.Errorf("Bundle() = %#v, wanted nil", got)
   169  		}
   170  
   171  		if got, err := l.Cert(); err != nil {
   172  			t.Fatalf("Cert() = %v", err)
   173  		} else if got != nil {
   174  			t.Errorf("Cert() = %#v, wanted nil", got)
   175  		}
   176  
   177  		if got, err := l.Chain(); err != nil {
   178  			t.Fatalf("Chain() = %v", err)
   179  		} else if len(got) != 0 {
   180  			t.Errorf("len(Chain()) = %d, wanted 0", len(got))
   181  		}
   182  	})
   183  }
   184  
   185  func TestNewAttestationBasic(t *testing.T) {
   186  	payload := "this is the content!"
   187  	l, err := NewAttestation([]byte(payload), WithLayerMediaType("foo"))
   188  	if err != nil {
   189  		t.Fatalf("NewSignature() = %v", err)
   190  	}
   191  
   192  	t.Run("check size", func(t *testing.T) {
   193  		wantSize := int64(len(payload))
   194  		gotSize, err := l.Size()
   195  		if err != nil {
   196  			t.Fatalf("Size() = %v", err)
   197  		}
   198  		if gotSize != wantSize {
   199  			t.Errorf("Size() = %d, wanted %d", gotSize, wantSize)
   200  		}
   201  	})
   202  
   203  	t.Run("check media type", func(t *testing.T) {
   204  		wantMT := types.MediaType("foo")
   205  		gotMT, err := l.MediaType()
   206  		if err != nil {
   207  			t.Fatalf("MediaType() = %v", err)
   208  		}
   209  		if gotMT != wantMT {
   210  			t.Errorf("MediaType() = %s, wanted %s", gotMT, wantMT)
   211  		}
   212  	})
   213  
   214  	t.Run("check hashes", func(t *testing.T) {
   215  		wantHash, _, err := v1.SHA256(strings.NewReader(payload))
   216  		if err != nil {
   217  			t.Fatalf("SHA256() = %v", err)
   218  		}
   219  
   220  		gotDigest, err := l.Digest()
   221  		if err != nil {
   222  			t.Fatalf("Digest() = %v", err)
   223  		}
   224  		if !cmp.Equal(gotDigest, wantHash) {
   225  			t.Errorf("Digest = %s", cmp.Diff(gotDigest, wantHash))
   226  		}
   227  
   228  		gotDiffID, err := l.DiffID()
   229  		if err != nil {
   230  			t.Fatalf("DiffID() = %v", err)
   231  		}
   232  		if !cmp.Equal(gotDiffID, wantHash) {
   233  			t.Errorf("DiffID = %s", cmp.Diff(gotDiffID, wantHash))
   234  		}
   235  	})
   236  
   237  	t.Run("check content", func(t *testing.T) {
   238  		comp, err := l.Compressed()
   239  		if err != nil {
   240  			t.Fatalf("Compressed() = %v", err)
   241  		}
   242  		defer comp.Close()
   243  		compContent, err := io.ReadAll(comp)
   244  		if err != nil {
   245  			t.Fatalf("ReadAll() = %v", err)
   246  		}
   247  		if got, want := string(compContent), payload; got != want {
   248  			t.Errorf("Compressed() = %s, wanted %s", got, want)
   249  		}
   250  
   251  		uncomp, err := l.Uncompressed()
   252  		if err != nil {
   253  			t.Fatalf("Uncompressed() = %v", err)
   254  		}
   255  		defer uncomp.Close()
   256  		uncompContent, err := io.ReadAll(uncomp)
   257  		if err != nil {
   258  			t.Fatalf("ReadAll() = %v", err)
   259  		}
   260  		if got, want := string(uncompContent), payload; got != want {
   261  			t.Errorf("Uncompressed() = %s, wanted %s", got, want)
   262  		}
   263  
   264  		gotPayload, err := l.Payload()
   265  		if err != nil {
   266  			t.Fatalf("Payload() = %v", err)
   267  		}
   268  		if got, want := string(gotPayload), payload; got != want {
   269  			t.Errorf("Payload() = %s, wanted %s", got, want)
   270  		}
   271  
   272  		gotSig, err := l.Base64Signature()
   273  		if err != nil {
   274  			t.Fatalf("Base64Signature() = %v", err)
   275  		}
   276  		if got, want := gotSig, ""; got != want {
   277  			t.Errorf("Base64Signature() = %s, wanted %s", got, want)
   278  		}
   279  
   280  		gotBundle, err := l.Bundle()
   281  		if err != nil {
   282  			t.Fatalf("Bundle() = %v", err)
   283  		}
   284  		if gotBundle != nil {
   285  			t.Errorf("Bundle() = %#v, wanted nil", gotBundle)
   286  		}
   287  	})
   288  
   289  	t.Run("check annotations", func(t *testing.T) {
   290  		want := map[string]string{
   291  			SignatureAnnotationKey: "",
   292  		}
   293  		got, err := l.Annotations()
   294  		if err != nil {
   295  			t.Fatalf("Annotations() = %v", err)
   296  		}
   297  		if !cmp.Equal(got, want) {
   298  			t.Errorf("Annotations = %s", cmp.Diff(got, want))
   299  		}
   300  	})
   301  
   302  	t.Run("check signature accessors", func(t *testing.T) {
   303  		gotPayload, err := l.Payload()
   304  		if err != nil {
   305  			t.Fatalf("Payload() = %v", err)
   306  		}
   307  		if got, want := string(gotPayload), payload; got != want {
   308  			t.Errorf("Payload() = %s, wanted %s", got, want)
   309  		}
   310  
   311  		gotSig, err := l.Base64Signature()
   312  		if err != nil {
   313  			t.Fatalf("Base64Signature() = %v", err)
   314  		}
   315  		if got, want := gotSig, ""; got != want {
   316  			t.Errorf("Base64Signature() = %s, wanted %s", got, want)
   317  		}
   318  
   319  		if got, err := l.Bundle(); err != nil {
   320  			t.Fatalf("Bundle() = %v", err)
   321  		} else if got != nil {
   322  			t.Errorf("Bundle() = %#v, wanted nil", got)
   323  		}
   324  
   325  		if got, err := l.Cert(); err != nil {
   326  			t.Fatalf("Cert() = %v", err)
   327  		} else if got != nil {
   328  			t.Errorf("Cert() = %#v, wanted nil", got)
   329  		}
   330  
   331  		if got, err := l.Chain(); err != nil {
   332  			t.Fatalf("Chain() = %v", err)
   333  		} else if len(got) != 0 {
   334  			t.Errorf("len(Chain()) = %d, wanted 0", len(got))
   335  		}
   336  	})
   337  }
   338  
   339  func TestNewSignatureCertChainAndBundle(t *testing.T) {
   340  	payload := "this is the other content!"
   341  	b64sig := "b64 content="
   342  
   343  	// This was extracted from gcr.io/distroless/static:nonroot on 2021/09/16
   344  	var (
   345  		cert = []byte(`
   346  -----BEGIN CERTIFICATE-----
   347  MIICjzCCAhSgAwIBAgITV2heiswW9YldtVEAu98QxDO8TTAKBggqhkjOPQQDAzAq
   348  MRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIx
   349  MDkxNDE5MTI0MFoXDTIxMDkxNDE5MzIzOVowADBZMBMGByqGSM49AgEGCCqGSM49
   350  AwEHA0IABMF1AWZcfvubslc4ABNnvGbRjm6GWVHxrJ1RRthTHMCE4FpFmiHQBfGt
   351  6n80DqszGj77Whb35O33+Dal4Y2po+CjggFBMIIBPTAOBgNVHQ8BAf8EBAMCB4Aw
   352  EwYDVR0lBAwwCgYIKwYBBQUHAwMwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU340G
   353  3G1ozVNmFC5TBFV0yNuouvowHwYDVR0jBBgwFoAUyMUdAEGaJCkyUSTrDa5K7UoG
   354  0+wwgY0GCCsGAQUFBwEBBIGAMH4wfAYIKwYBBQUHMAKGcGh0dHA6Ly9wcml2YXRl
   355  Y2EtY29udGVudC02MDNmZTdlNy0wMDAwLTIyMjctYmY3NS1mNGY1ZTgwZDI5NTQu
   356  c3RvcmFnZS5nb29nbGVhcGlzLmNvbS9jYTM2YTFlOTYyNDJiOWZjYjE0Ni9jYS5j
   357  cnQwOAYDVR0RAQH/BC4wLIEqa2V5bGVzc0BkaXN0cm9sZXNzLmlhbS5nc2Vydmlj
   358  ZWFjY291bnQuY29tMAoGCCqGSM49BAMDA2kAMGYCMQDcH9cdkxW6ugsbPHqX9qrM
   359  wlMaprcwnlktS3+5xuABr5icuqwrB/Fj5doFtS7AnM0CMQD9MjSaUmHFFF7zoLMx
   360  uThR1Z6JuA21HwxtL3GyJ8UQZcEPOlTBV593HrSAwBhiCoY=
   361  -----END CERTIFICATE-----
   362  `)
   363  		chain = []byte(`
   364  -----BEGIN CERTIFICATE-----
   365  MIIB+DCCAX6gAwIBAgITNVkDZoCiofPDsy7dfm6geLbuhzAKBggqhkjOPQQDAzAq
   366  MRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIx
   367  MDMwNzAzMjAyOVoXDTMxMDIyMzAzMjAyOVowKjEVMBMGA1UEChMMc2lnc3RvcmUu
   368  ZGV2MREwDwYDVQQDEwhzaWdzdG9yZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLSy
   369  A7Ii5k+pNO8ZEWY0ylemWDowOkNa3kL+GZE5Z5GWehL9/A9bRNA3RbrsZ5i0Jcas
   370  taRL7Sp5fp/jD5dxqc/UdTVnlvS16an+2Yfswe/QuLolRUCrcOE2+2iA5+tzd6Nm
   371  MGQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYE
   372  FMjFHQBBmiQpMlEk6w2uSu1KBtPsMB8GA1UdIwQYMBaAFMjFHQBBmiQpMlEk6w2u
   373  Su1KBtPsMAoGCCqGSM49BAMDA2gAMGUCMH8liWJfMui6vXXBhjDgY4MwslmN/TJx
   374  Ve/83WrFomwmNf056y1X48F9c4m3a3ozXAIxAKjRay5/aj/jsKKGIkmQatjI8uup
   375  Hr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ==
   376  -----END CERTIFICATE-----
   377  `)
   378  		b = &bundle.RekorBundle{
   379  			SignedEntryTimestamp: mustDecode("MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE="),
   380  			Payload: bundle.RekorPayload{
   381  				Body:           "REMOVED",
   382  				IntegratedTime: 1631646761,
   383  				LogIndex:       693591,
   384  				LogID:          "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d",
   385  			},
   386  		}
   387  	)
   388  
   389  	l, err := NewSignature([]byte(payload), b64sig,
   390  		WithCertChain(cert, chain), WithBundle(b))
   391  	if err != nil {
   392  		t.Fatalf("NewSignature() = %v", err)
   393  	}
   394  
   395  	t.Run("check signature accessors", func(t *testing.T) {
   396  		gotPayload, err := l.Payload()
   397  		if err != nil {
   398  			t.Fatalf("Payload() = %v", err)
   399  		}
   400  		if got, want := string(gotPayload), payload; got != want {
   401  			t.Errorf("Payload() = %s, wanted %s", got, want)
   402  		}
   403  
   404  		gotSig, err := l.Base64Signature()
   405  		if err != nil {
   406  			t.Fatalf("Base64Signature() = %v", err)
   407  		}
   408  		if got, want := gotSig, b64sig; got != want {
   409  			t.Errorf("Base64Signature() = %s, wanted %s", got, want)
   410  		}
   411  
   412  		if got, err := l.Bundle(); err != nil {
   413  			t.Fatalf("Bundle() = %v", err)
   414  		} else if got != b {
   415  			t.Errorf("Bundle() = %#v, wanted %#v", got, b)
   416  		}
   417  
   418  		if got, err := l.Cert(); err != nil {
   419  			t.Fatalf("Cert() = %v", err)
   420  		} else if got == nil {
   421  			t.Error("Cert() = nil, wanted non-nil")
   422  		}
   423  
   424  		if got, err := l.Chain(); err != nil {
   425  			t.Fatalf("Chain() = %v", err)
   426  		} else if len(got) != 1 {
   427  			t.Errorf("len(Chain()) = %d, wanted 1", len(got))
   428  		}
   429  	})
   430  
   431  	t.Run("check annotations", func(t *testing.T) {
   432  		want := map[string]string{
   433  			SignatureAnnotationKey:   b64sig,
   434  			CertificateAnnotationKey: string(cert),
   435  			ChainAnnotationKey:       string(chain),
   436  			// This was extracted from gcr.io/distroless/static:nonroot on 2021/09/16.
   437  			// The Body has been removed for brevity
   438  			BundleAnnotationKey: `{"SignedEntryTimestamp":"MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE=","Payload":{"body":"REMOVED","integratedTime":1631646761,"logIndex":693591,"logID":"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"}}`,
   439  		}
   440  		got, err := l.Annotations()
   441  		if err != nil {
   442  			t.Fatalf("Annotations() = %v", err)
   443  		}
   444  		if !cmp.Equal(got, want) {
   445  			t.Errorf("Annotations = %s", cmp.Diff(got, want))
   446  		}
   447  	})
   448  }
   449  
   450  func TestNewSignatureCertChainAndRekorRFC3161Timestamp(t *testing.T) {
   451  	payload := "this is the other content!"
   452  	b64sig := "b64 content="
   453  
   454  	// This was extracted from gcr.io/distroless/static:nonroot on 2021/09/16
   455  	var (
   456  		cert = []byte(`
   457  -----BEGIN CERTIFICATE-----
   458  MIICjzCCAhSgAwIBAgITV2heiswW9YldtVEAu98QxDO8TTAKBggqhkjOPQQDAzAq
   459  MRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIx
   460  MDkxNDE5MTI0MFoXDTIxMDkxNDE5MzIzOVowADBZMBMGByqGSM49AgEGCCqGSM49
   461  AwEHA0IABMF1AWZcfvubslc4ABNnvGbRjm6GWVHxrJ1RRthTHMCE4FpFmiHQBfGt
   462  6n80DqszGj77Whb35O33+Dal4Y2po+CjggFBMIIBPTAOBgNVHQ8BAf8EBAMCB4Aw
   463  EwYDVR0lBAwwCgYIKwYBBQUHAwMwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU340G
   464  3G1ozVNmFC5TBFV0yNuouvowHwYDVR0jBBgwFoAUyMUdAEGaJCkyUSTrDa5K7UoG
   465  0+wwgY0GCCsGAQUFBwEBBIGAMH4wfAYIKwYBBQUHMAKGcGh0dHA6Ly9wcml2YXRl
   466  Y2EtY29udGVudC02MDNmZTdlNy0wMDAwLTIyMjctYmY3NS1mNGY1ZTgwZDI5NTQu
   467  c3RvcmFnZS5nb29nbGVhcGlzLmNvbS9jYTM2YTFlOTYyNDJiOWZjYjE0Ni9jYS5j
   468  cnQwOAYDVR0RAQH/BC4wLIEqa2V5bGVzc0BkaXN0cm9sZXNzLmlhbS5nc2Vydmlj
   469  ZWFjY291bnQuY29tMAoGCCqGSM49BAMDA2kAMGYCMQDcH9cdkxW6ugsbPHqX9qrM
   470  wlMaprcwnlktS3+5xuABr5icuqwrB/Fj5doFtS7AnM0CMQD9MjSaUmHFFF7zoLMx
   471  uThR1Z6JuA21HwxtL3GyJ8UQZcEPOlTBV593HrSAwBhiCoY=
   472  -----END CERTIFICATE-----
   473  `)
   474  		chain = []byte(`
   475  -----BEGIN CERTIFICATE-----
   476  MIIB+DCCAX6gAwIBAgITNVkDZoCiofPDsy7dfm6geLbuhzAKBggqhkjOPQQDAzAq
   477  MRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIx
   478  MDMwNzAzMjAyOVoXDTMxMDIyMzAzMjAyOVowKjEVMBMGA1UEChMMc2lnc3RvcmUu
   479  ZGV2MREwDwYDVQQDEwhzaWdzdG9yZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLSy
   480  A7Ii5k+pNO8ZEWY0ylemWDowOkNa3kL+GZE5Z5GWehL9/A9bRNA3RbrsZ5i0Jcas
   481  taRL7Sp5fp/jD5dxqc/UdTVnlvS16an+2Yfswe/QuLolRUCrcOE2+2iA5+tzd6Nm
   482  MGQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYE
   483  FMjFHQBBmiQpMlEk6w2uSu1KBtPsMB8GA1UdIwQYMBaAFMjFHQBBmiQpMlEk6w2u
   484  Su1KBtPsMAoGCCqGSM49BAMDA2gAMGUCMH8liWJfMui6vXXBhjDgY4MwslmN/TJx
   485  Ve/83WrFomwmNf056y1X48F9c4m3a3ozXAIxAKjRay5/aj/jsKKGIkmQatjI8uup
   486  Hr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ==
   487  -----END CERTIFICATE-----
   488  `)
   489  		b = &bundle.RFC3161Timestamp{
   490  			SignedRFC3161Timestamp: mustDecode("MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE="),
   491  		}
   492  		rekorBundle = &bundle.RekorBundle{
   493  			SignedEntryTimestamp: mustDecode("MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE="),
   494  			Payload: bundle.RekorPayload{
   495  				Body:           "REMOVED",
   496  				IntegratedTime: 1631646761,
   497  				LogIndex:       693591,
   498  				LogID:          "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d",
   499  			},
   500  		}
   501  	)
   502  
   503  	l, err := NewSignature([]byte(payload), b64sig,
   504  		WithCertChain(cert, chain), WithRFC3161Timestamp(b))
   505  	if err != nil {
   506  		t.Fatalf("NewSignature() = %v", err)
   507  	}
   508  
   509  	t.Run("check tsa signature accessors", func(t *testing.T) {
   510  		gotPayload, err := l.Payload()
   511  		if err != nil {
   512  			t.Fatalf("Payload() = %v", err)
   513  		}
   514  		if got, want := string(gotPayload), payload; got != want {
   515  			t.Errorf("Payload() = %s, wanted %s", got, want)
   516  		}
   517  
   518  		gotSig, err := l.Base64Signature()
   519  		if err != nil {
   520  			t.Fatalf("Base64Signature() = %v", err)
   521  		}
   522  		if got, want := gotSig, b64sig; got != want {
   523  			t.Errorf("Base64Signature() = %s, wanted %s", got, want)
   524  		}
   525  
   526  		if got, err := l.RFC3161Timestamp(); err != nil {
   527  			t.Fatalf("RFC3161Timestamp() = %v", err)
   528  		} else if got != b {
   529  			t.Errorf("RFC3161Timestamp() = %#v, wanted %#v", got, b)
   530  		}
   531  
   532  		if got, err := l.Cert(); err != nil {
   533  			t.Fatalf("Cert() = %v", err)
   534  		} else if got == nil {
   535  			t.Error("Cert() = nil, wanted non-nil")
   536  		}
   537  
   538  		if got, err := l.Chain(); err != nil {
   539  			t.Fatalf("Chain() = %v", err)
   540  		} else if len(got) != 1 {
   541  			t.Errorf("len(Chain()) = %d, wanted 1", len(got))
   542  		}
   543  	})
   544  
   545  	t.Run("check tsa annotations", func(t *testing.T) {
   546  		want := map[string]string{
   547  			SignatureAnnotationKey:   b64sig,
   548  			CertificateAnnotationKey: string(cert),
   549  			ChainAnnotationKey:       string(chain),
   550  
   551  			RFC3161TimestampAnnotationKey: `{"SignedRFC3161Timestamp":"MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE="}`,
   552  		}
   553  		got, err := l.Annotations()
   554  		if err != nil {
   555  			t.Fatalf("Annotations() = %v", err)
   556  		}
   557  		if !cmp.Equal(got, want) {
   558  			t.Errorf("Annotations = %s", cmp.Diff(got, want))
   559  		}
   560  	})
   561  
   562  	newSig, err := NewSignature([]byte(payload), b64sig,
   563  		WithCertChain(cert, chain), WithRFC3161Timestamp(b), WithBundle(rekorBundle))
   564  	if err != nil {
   565  		t.Fatalf("NewSignature() = %v", err)
   566  	}
   567  
   568  	t.Run("check signature accessors", func(t *testing.T) {
   569  		gotPayload, err := newSig.Payload()
   570  		if err != nil {
   571  			t.Fatalf("Payload() = %v", err)
   572  		}
   573  		if got, want := string(gotPayload), payload; got != want {
   574  			t.Errorf("Payload() = %s, wanted %s", got, want)
   575  		}
   576  
   577  		gotSig, err := newSig.Base64Signature()
   578  		if err != nil {
   579  			t.Fatalf("Base64Signature() = %v", err)
   580  		}
   581  		if got, want := gotSig, b64sig; got != want {
   582  			t.Errorf("Base64Signature() = %s, wanted %s", got, want)
   583  		}
   584  
   585  		if got, err := newSig.Bundle(); err != nil {
   586  			t.Fatalf("Bundle() = %v", err)
   587  		} else if got != rekorBundle {
   588  			t.Errorf("Bundle() = %#v, wanted %#v", got, b)
   589  		}
   590  
   591  		if got, err := newSig.RFC3161Timestamp(); err != nil {
   592  			t.Fatalf("RFC3161Timestamp() = %v", err)
   593  		} else if got != b {
   594  			t.Errorf("RFC3161Timestamp() = %#v, wanted %#v", got, b)
   595  		}
   596  
   597  		if got, err := newSig.Cert(); err != nil {
   598  			t.Fatalf("Cert() = %v", err)
   599  		} else if got == nil {
   600  			t.Error("Cert() = nil, wanted non-nil")
   601  		}
   602  
   603  		if got, err := newSig.Chain(); err != nil {
   604  			t.Fatalf("Chain() = %v", err)
   605  		} else if len(got) != 1 {
   606  			t.Errorf("len(Chain()) = %d, wanted 1", len(got))
   607  		}
   608  	})
   609  
   610  	t.Run("check rekor and tsa annotations", func(t *testing.T) {
   611  		want := map[string]string{
   612  			SignatureAnnotationKey:   b64sig,
   613  			CertificateAnnotationKey: string(cert),
   614  			ChainAnnotationKey:       string(chain),
   615  
   616  			RFC3161TimestampAnnotationKey: `{"SignedRFC3161Timestamp":"MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE="}`,
   617  			BundleAnnotationKey:           `{"SignedEntryTimestamp":"MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE=","Payload":{"body":"REMOVED","integratedTime":1631646761,"logIndex":693591,"logID":"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"}}`,
   618  		}
   619  		got, err := newSig.Annotations()
   620  		if err != nil {
   621  			t.Fatalf("Annotations() = %v", err)
   622  		}
   623  		if !cmp.Equal(got, want) {
   624  			t.Errorf("Annotations = %s", cmp.Diff(got, want))
   625  		}
   626  	})
   627  }
   628  
   629  func TestNewSignatureBadCertChain(t *testing.T) {
   630  	payload := "this is the other content!"
   631  	b64sig := "b64 content="
   632  
   633  	// This was extracted from gcr.io/distroless/static:nonroot on 2021/09/16
   634  	var (
   635  		cert = []byte(`
   636  -----BEGIN CERTIFICATE-----
   637  garbage in
   638  -----END CERTIFICATE-----
   639  `)
   640  		chain = []byte(`
   641  -----BEGIN CERTIFICATE-----
   642  garbage out
   643  -----END CERTIFICATE-----
   644  `)
   645  	)
   646  
   647  	l, err := NewSignature([]byte(payload), b64sig,
   648  		WithCertChain(cert, chain))
   649  	if err != nil {
   650  		t.Fatalf("NewSignature() = %v", err)
   651  	}
   652  
   653  	t.Run("check signature accessors", func(t *testing.T) {
   654  		if got, err := l.Cert(); err == nil {
   655  			t.Fatalf("Cert() = %#v, wanted error", got)
   656  		}
   657  
   658  		if got, err := l.Chain(); err == nil {
   659  			t.Fatalf("Chain() = %#v, wanted error", got)
   660  		}
   661  	})
   662  }
   663  
   664  func mustDecode(s string) []byte {
   665  	b, err := base64.StdEncoding.DecodeString(s)
   666  	if err != nil {
   667  		panic(err.Error())
   668  	}
   669  	return b
   670  }
   671  

View as plain text