config: enable azure snp version fetcher again + minimum age for latest version (#1899)

* fetch latest version when older than 2 weeks

* extend hack upload tool to pass an upload date

* Revert "config: disable user-facing version Azure SEV SNP fetch for v2.8  (#1882)"

This reverts commit c7b22d314a.

* fix tests

* use NewAzureSEVSNPVersionList for type guarantees

* Revert "use NewAzureSEVSNPVersionList for type guarantees"

This reverts commit 942566453f4b4a2b6dc16f8689248abf1dc47db4.

* assure list is sorted

* improve root.go style

* daniel feedback
This commit is contained in:
Adrian Stobbe 2023-06-09 12:48:12 +02:00 committed by GitHub
parent 72e168e653
commit 3fde118b33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 239 additions and 189 deletions

View file

@ -10,6 +10,7 @@ import (
"fmt"
"net/url"
"path"
"sort"
"strings"
"github.com/edgelesssys/constellation/v2/internal/constants"
@ -110,6 +111,11 @@ func (i AzureSEVSNPVersionList) ValidateRequest() error {
return nil
}
// SortAzureSEVSNPVersionList sorts the list of versions in reverse order.
func SortAzureSEVSNPVersionList(versions AzureSEVSNPVersionList) {
sort.Sort(sort.Reverse(sort.StringSlice(versions)))
}
// Validate validates the response.
func (i AzureSEVSNPVersionList) Validate() error {
if len(i) < 1 {

View file

@ -9,7 +9,6 @@ import (
"context"
"encoding/json"
"fmt"
"sort"
"time"
apiclient "github.com/edgelesssys/constellation/v2/internal/api/client"
@ -43,7 +42,7 @@ func NewClient(ctx context.Context, cfg staticupload.Config, cosignPwd, privateK
return repo, clientClose, nil
}
// UploadAzureSEVSNP uploads the latest version numbers of the Azure SEVSNP.
// UploadAzureSEVSNP uploads the latest version numbers of the Azure SEVSNP. Then version name is the UTC timestamp of the date. The /list entry stores the version name + .json suffix.
func (a Client) UploadAzureSEVSNP(ctx context.Context, version AzureSEVSNPVersion, date time.Time) error {
versions, err := a.List(ctx, variant.AzureSEVSNP{})
if err != nil {
@ -181,6 +180,6 @@ func executeAllCmds(ctx context.Context, client *apiclient.Client, cmds []crudCm
func addVersion(versions []string, newVersion string) []string {
versions = append(versions, newVersion)
versions = variant.RemoveDuplicate(versions)
sort.Sort(sort.Reverse(sort.StringSlice(versions)))
SortAzureSEVSNPVersionList(versions)
return versions
}

View file

@ -10,24 +10,30 @@ import (
"context"
"encoding/json"
"fmt"
"strings"
"time"
apifetcher "github.com/edgelesssys/constellation/v2/internal/api/fetcher"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/sigstore"
)
// minimumAgeVersion is the minimum age to accept the version as latest.
const minimumAgeVersion = 14 * 24 * time.Hour
const cosignPublicKey = constants.CosignPublicKeyReleases
// Fetcher fetches config API resources without authentication.
type Fetcher interface {
FetchAzureSEVSNPVersion(ctx context.Context, azureVersion AzureSEVSNPVersionAPI) (AzureSEVSNPVersionAPI, error)
FetchAzureSEVSNPVersionList(ctx context.Context, attestation AzureSEVSNPVersionList) (AzureSEVSNPVersionList, error)
FetchAzureSEVSNPVersionLatest(ctx context.Context) (AzureSEVSNPVersionAPI, error)
FetchAzureSEVSNPVersionLatest(ctx context.Context, now time.Time) (AzureSEVSNPVersionAPI, error)
}
// fetcher fetches AttestationCfg API resources without authentication.
type fetcher struct {
apifetcher.HTTPClient
verifier sigstore.Verifier
}
// NewFetcher returns a new apifetcher.
@ -37,7 +43,11 @@ func NewFetcher() Fetcher {
// NewFetcherWithClient returns a new fetcher with custom http client.
func NewFetcherWithClient(client apifetcher.HTTPClient) Fetcher {
return &fetcher{client}
return newFetcherWithClientAndVerifier(client, sigstore.CosignVerifier{})
}
func newFetcherWithClientAndVerifier(client apifetcher.HTTPClient, cosignVerifier sigstore.Verifier) Fetcher {
return &fetcher{client, cosignVerifier}
}
// FetchAzureSEVSNPVersionList fetches the version list information from the config API.
@ -63,7 +73,7 @@ func (f *fetcher) FetchAzureSEVSNPVersion(ctx context.Context, azureVersion Azur
return fetchedVersion, fmt.Errorf("fetch version %s signature: %w", azureVersion.Version, err)
}
err = sigstore.CosignVerifier{}.VerifySignature(versionBytes, signature.Signature, []byte(cosignPublicKey))
err = f.verifier.VerifySignature(versionBytes, signature.Signature, []byte(cosignPublicKey))
if err != nil {
return fetchedVersion, fmt.Errorf("verify version %s signature: %w", azureVersion.Version, err)
}
@ -71,16 +81,34 @@ func (f *fetcher) FetchAzureSEVSNPVersion(ctx context.Context, azureVersion Azur
}
// FetchAzureSEVSNPVersionLatest returns the latest versions of the given type.
func (f *fetcher) FetchAzureSEVSNPVersionLatest(ctx context.Context) (res AzureSEVSNPVersionAPI, err error) {
func (f *fetcher) FetchAzureSEVSNPVersionLatest(ctx context.Context, now time.Time) (res AzureSEVSNPVersionAPI, err error) {
var list AzureSEVSNPVersionList
list, err = f.FetchAzureSEVSNPVersionList(ctx, list)
if err != nil {
return res, fmt.Errorf("fetching versions list: %w", err)
}
get := AzureSEVSNPVersionAPI{Version: list[0]} // get latest version (as sorted reversely alphanumerically)
get, err = f.FetchAzureSEVSNPVersion(ctx, get)
getVersionRequest, err := getLatestVersionOlderThanMinimumAge(list, now, minimumAgeVersion)
if err != nil {
return res, fmt.Errorf("finding latest valid version: %w", err)
}
res, err = f.FetchAzureSEVSNPVersion(ctx, getVersionRequest)
if err != nil {
return res, fmt.Errorf("fetching version: %w", err)
}
return get, nil
return
}
func getLatestVersionOlderThanMinimumAge(list AzureSEVSNPVersionList, now time.Time, minimumAgeVersion time.Duration) (AzureSEVSNPVersionAPI, error) {
SortAzureSEVSNPVersionList(list)
for _, v := range list {
dateStr := strings.TrimSuffix(v, ".json")
versionDate, err := time.Parse("2006-01-01-01-01", dateStr)
if err != nil {
return AzureSEVSNPVersionAPI{}, fmt.Errorf("parsing version date %s: %w", dateStr, err)
}
if now.Sub(versionDate) > minimumAgeVersion {
return AzureSEVSNPVersionAPI{Version: v}, nil
}
}
return AzureSEVSNPVersionAPI{}, fmt.Errorf("no valid version fulfilling minimum age found")
}

View file

@ -13,11 +13,56 @@ import (
"io"
"net/http"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
var testCfg = AzureSEVSNPVersionAPI{
func TestFetchLatestAzureSEVSNPVersion(t *testing.T) {
now := time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC)
testcases := map[string]struct {
fetcherVersions []string
timeAtTest time.Time
wantErr bool
want AzureSEVSNPVersionAPI
}{
"get latest version if older than 2 weeks": {
fetcherVersions: []string{"2021-01-01-01-01.json", "2019-01-01-01-01.json"},
timeAtTest: now.Add(days(15)),
want: latestVersion,
},
"get older version if latest version is not older than minimum age": {
fetcherVersions: []string{"2021-01-01-01-01.json", "2019-01-01-01-01.json"},
timeAtTest: now.Add(days(7)),
want: olderVersion,
},
"fail when no version is older minimum age": {
fetcherVersions: []string{"2021-01-01-01-01.json", "2020-12-31-00-00.json"},
timeAtTest: now.Add(days(2)),
wantErr: true,
},
}
for name, tc := range testcases {
t.Run(name, func(t *testing.T) {
client := &http.Client{
Transport: &fakeConfigAPIHandler{
versions: tc.fetcherVersions,
},
}
fetcher := newFetcherWithClientAndVerifier(client, dummyVerifier{})
res, err := fetcher.FetchAzureSEVSNPVersionLatest(context.Background(), tc.timeAtTest)
assert := assert.New(t)
if tc.wantErr {
assert.Error(err)
} else {
assert.NoError(err)
assert.Equal(tc.want, res)
}
})
}
}
var latestVersion = AzureSEVSNPVersionAPI{
AzureSEVSNPVersion: AzureSEVSNPVersion{
Microcode: 93,
TEE: 0,
@ -26,52 +71,29 @@ var testCfg = AzureSEVSNPVersionAPI{
},
}
func TestFetchLatestAzureSEVSNPVersion(t *testing.T) {
testcases := map[string]struct {
signature []byte
wantErr bool
want AzureSEVSNPVersionAPI
}{
"get version with valid signature": {
signature: []byte("MEQCIBPEbYg89MIQuaGStLhKGLGMKvKFoYCaAniDLwoIwulqAiB+rj7KMaMOMGxmUsjI7KheCXSNM8NzN+tuDw6AywI75A=="), // signed with release key
want: testCfg,
},
"fail with invalid signature": {
signature: []byte("invalid"),
wantErr: true,
},
}
for name, tc := range testcases {
t.Run(name, func(t *testing.T) {
client := &http.Client{
Transport: &fakeConfigAPIHandler{
signature: tc.signature,
},
}
fetcher := NewFetcherWithClient(client)
res, err := fetcher.FetchAzureSEVSNPVersionLatest(context.Background())
var olderVersion = AzureSEVSNPVersionAPI{
AzureSEVSNPVersion: AzureSEVSNPVersion{
Microcode: 1,
TEE: 0,
SNP: 1,
Bootloader: 1,
},
}
assert := assert.New(t)
if tc.wantErr {
assert.Error(err)
} else {
assert.NoError(err)
assert.Equal(testCfg, res)
}
})
}
func days(days int) time.Duration {
return time.Duration(days*24) * time.Hour
}
type fakeConfigAPIHandler struct {
signature []byte
versions []string
}
// RoundTrip resolves the request and returns a dummy response.
func (f *fakeConfigAPIHandler) RoundTrip(req *http.Request) (*http.Response, error) {
signature := []byte("placeholderSignature")
if req.URL.Path == "/constellation/v1/attestation/azure-sev-snp/list" {
res := &http.Response{}
data := []string{"2021-01-01-01-01.json", "2019-01-01-01-02.json"} // return multiple versions to check that latest version is correctly selected
bt, err := json.Marshal(data)
bt, err := json.Marshal(f.versions)
if err != nil {
return nil, err
}
@ -82,7 +104,17 @@ func (f *fakeConfigAPIHandler) RoundTrip(req *http.Request) (*http.Response, err
return res, nil
} else if req.URL.Path == "/constellation/v1/attestation/azure-sev-snp/2021-01-01-01-01.json" {
res := &http.Response{}
bt, err := json.Marshal(testCfg)
bt, err := json.Marshal(latestVersion)
if err != nil {
return nil, err
}
res.Body = io.NopCloser(bytes.NewReader(bt))
res.StatusCode = http.StatusOK
return res, nil
} else if req.URL.Path == "/constellation/v1/attestation/azure-sev-snp/2019-01-01-01-01.json" {
res := &http.Response{}
bt, err := json.Marshal(olderVersion)
if err != nil {
return nil, err
}
@ -93,7 +125,20 @@ func (f *fakeConfigAPIHandler) RoundTrip(req *http.Request) (*http.Response, err
} else if req.URL.Path == "/constellation/v1/attestation/azure-sev-snp/2021-01-01-01-01.json.sig" {
res := &http.Response{}
obj := AzureSEVSNPVersionSignature{
Signature: f.signature,
Signature: signature,
}
bt, err := json.Marshal(obj)
if err != nil {
return nil, err
}
res.Body = io.NopCloser(bytes.NewReader(bt))
res.StatusCode = http.StatusOK
return res, nil
} else if req.URL.Path == "/constellation/v1/attestation/azure-sev-snp/2019-01-01-01-01.json.sig" {
res := &http.Response{}
obj := AzureSEVSNPVersionSignature{
Signature: signature,
}
bt, err := json.Marshal(obj)
if err != nil {
@ -106,3 +151,9 @@ func (f *fakeConfigAPIHandler) RoundTrip(req *http.Request) (*http.Response, err
}
return nil, errors.New("no endpoint found")
}
type dummyVerifier struct{}
func (s dummyVerifier) VerifySignature(_, _, _ []byte) error {
return nil
}

View file

@ -218,10 +218,6 @@ func TestTrustedKeyFromSNP(t *testing.T) {
AcceptedKeyDigests: tc.idkeydigests,
EnforcementPolicy: tc.enforceIDKeyDigest,
}
cfg.BootloaderVersion = config.AttestationVersion{Value: 2}
cfg.TEEVersion = config.AttestationVersion{Value: 0}
cfg.MicrocodeVersion = config.AttestationVersion{Value: 93}
cfg.SNPVersion = config.AttestationVersion{Value: 6}
validator := &Validator{
hclValidator: &instanceInfo,
@ -353,12 +349,6 @@ func TestNewSNPReportFromBytes(t *testing.T) {
},
}
cfg := config.DefaultForAzureSEVSNP()
cfg.BootloaderVersion = config.AttestationVersion{Value: 2}
cfg.TEEVersion = config.AttestationVersion{Value: 0}
cfg.MicrocodeVersion = config.AttestationVersion{Value: 93}
cfg.SNPVersion = config.AttestationVersion{Value: 6}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)

View file

@ -8,7 +8,6 @@ package config
import (
"encoding/json"
"errors"
"fmt"
"strings"
)
@ -34,7 +33,7 @@ func (v AttestationVersion) MarshalYAML() (any, error) {
if v.IsLatest {
return "latest", nil
}
return int(v.Value), nil
return v.Value, nil
}
// UnmarshalYAML implements a custom unmarshaller to resolve "atest" values.
@ -68,12 +67,11 @@ func (v *AttestationVersion) parseRawUnmarshal(rawUnmarshal any) error {
switch s := rawUnmarshal.(type) {
case string:
if strings.ToLower(s) == "latest" {
// TODO(elchead): activate latest logic for next release AB#3036
return errors.New("latest is not supported as a version value")
// v.IsLatest = true
// v.Value = placeholderVersionValue
v.IsLatest = true
v.Value = placeholderVersionValue
} else {
return fmt.Errorf("invalid version value: %s", s)
}
return fmt.Errorf("invalid version value: %s", s)
case int:
v.Value = uint8(s)
// yaml spec allows "1" as float64, so version number might come as a float: https://github.com/go-yaml/yaml/issues/430

View file

@ -9,7 +9,6 @@ package config
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
)
@ -45,39 +44,3 @@ func TestVersionMarshalYAML(t *testing.T) {
})
}
}
func TestVersionUnmarshalYAML(t *testing.T) {
tests := []struct {
name string
expected AttestationVersion
yamlInput string
wantErr bool
}{
// TODO(elchead): activate latest logic for next release AB#3036
{
name: "latest value is not allowed",
expected: AttestationVersion{},
yamlInput: "latest\n",
wantErr: true,
},
{
name: "value 5 resolves to 5",
expected: AttestationVersion{
Value: 5,
},
yamlInput: "5\n",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
sut := AttestationVersion{}
err := yaml.Unmarshal([]byte(tt.yamlInput), &sut)
if tt.wantErr {
assert.Error(t, err)
return
}
assert.NoError(t, err)
assert.Equal(t, tt.expected.IsLatest, sut.IsLatest)
})
}
}

View file

@ -27,6 +27,7 @@ import (
"os"
"reflect"
"strings"
"time"
"github.com/go-playground/locales/en"
ut "github.com/go-playground/universal-translator"
@ -386,19 +387,18 @@ func fromFile(fileHandler file.Handler, name string) (*Config, error) {
// 2. For "latest" version values of the attestation variants fetch the version numbers.
// 3. Read secrets from environment variables.
// 4. Validate config. If `--force` is set the version validation will be disabled and any version combination is allowed.
func New(fileHandler file.Handler, name string, _ attestationconfigapi.Fetcher, force bool) (*Config, error) {
func New(fileHandler file.Handler, name string, fetcher attestationconfigapi.Fetcher, force bool) (*Config, error) {
// Read config file
c, err := fromFile(fileHandler, name)
if err != nil {
return nil, err
}
// TODO(elchead): activate latest logic for next release AB#3036
//if azure := c.Attestation.AzureSEVSNP; azure != nil {
// if err := azure.FetchAndSetLatestVersionNumbers(fetcher); err != nil {
// return c, err
// }
//}
if azure := c.Attestation.AzureSEVSNP; azure != nil {
if err := azure.FetchAndSetLatestVersionNumbers(context.Background(), fetcher, time.Now()); err != nil {
return c, err
}
}
// Read secrets from env-vars.
clientSecretValue := os.Getenv(constants.EnvVarAzureClientSecretValue)
@ -925,19 +925,12 @@ type AzureSEVSNP struct {
// DefaultForAzureSEVSNP returns the default configuration for Azure SEV-SNP attestation.
// Version numbers have placeholder values and the latest available values can be fetched using [AzureSEVSNP.FetchAndSetLatestVersionNumbers].
func DefaultForAzureSEVSNP() *AzureSEVSNP {
// TODO(elchead): activate latest logic for next release AB#3036
azureSNPCfg := attestationconfigapi.AzureSEVSNPVersion{
Bootloader: 3,
TEE: 0,
SNP: 8,
Microcode: 115,
}
return &AzureSEVSNP{
Measurements: measurements.DefaultsFor(cloudprovider.Azure, variant.AzureSEVSNP{}),
BootloaderVersion: AttestationVersion{Value: azureSNPCfg.Bootloader}, // NewLatestPlaceholderVersion(),
TEEVersion: AttestationVersion{Value: azureSNPCfg.TEE}, // NewLatestPlaceholderVersion(),
SNPVersion: AttestationVersion{Value: azureSNPCfg.SNP}, // NewLatestPlaceholderVersion(),
MicrocodeVersion: AttestationVersion{Value: azureSNPCfg.Microcode}, // NewLatestPlaceholderVersion(),
BootloaderVersion: NewLatestPlaceholderVersion(),
TEEVersion: NewLatestPlaceholderVersion(),
SNPVersion: NewLatestPlaceholderVersion(),
MicrocodeVersion: NewLatestPlaceholderVersion(),
FirmwareSignerConfig: SNPFirmwareSignerConfig{
AcceptedKeyDigests: idkeydigest.DefaultList(),
EnforcementPolicy: idkeydigest.MAAFallback,
@ -981,8 +974,8 @@ func (c AzureSEVSNP) EqualTo(old AttestationCfg) (bool, error) {
}
// FetchAndSetLatestVersionNumbers fetches the latest version numbers from the configapi and sets them.
func (c *AzureSEVSNP) FetchAndSetLatestVersionNumbers(fetcher attestationconfigapi.Fetcher) error {
versions, err := fetcher.FetchAzureSEVSNPVersionLatest(context.Background())
func (c *AzureSEVSNP) FetchAndSetLatestVersionNumbers(ctx context.Context, fetcher attestationconfigapi.Fetcher, now time.Time) error {
versions, err := fetcher.FetchAzureSEVSNPVersionLatest(ctx, now)
if err != nil {
return err
}

View file

@ -11,6 +11,7 @@ import (
"errors"
"reflect"
"testing"
"time"
"github.com/go-playground/locales/en"
ut "github.com/go-playground/universal-translator"
@ -41,21 +42,20 @@ func TestDefaultConfig(t *testing.T) {
assert.NotNil(def)
}
// TODO(elchead): activate latest logic for next release AB#3036
// func TestDefaultConfigWritesLatestVersion(t *testing.T) {
// conf := Default()
// bt, err := yaml.Marshal(conf)
// require := require.New(t)
// require.NoError(err)
func TestDefaultConfigWritesLatestVersion(t *testing.T) {
conf := Default()
bt, err := yaml.Marshal(conf)
require := require.New(t)
require.NoError(err)
// var mp configMap
// require.NoError(yaml.Unmarshal(bt, &mp))
// assert := assert.New(t)
// assert.Equal("latest", mp.getAzureSEVSNPVersion("microcodeVersion"))
// assert.Equal("latest", mp.getAzureSEVSNPVersion("teeVersion"))
// assert.Equal("latest", mp.getAzureSEVSNPVersion("snpVersion"))
// assert.Equal("latest", mp.getAzureSEVSNPVersion("bootloaderVersion"))
//}
var mp configMap
require.NoError(yaml.Unmarshal(bt, &mp))
assert := assert.New(t)
assert.Equal("latest", mp.getAzureSEVSNPVersion("microcodeVersion"))
assert.Equal("latest", mp.getAzureSEVSNPVersion("teeVersion"))
assert.Equal("latest", mp.getAzureSEVSNPVersion("snpVersion"))
assert.Equal("latest", mp.getAzureSEVSNPVersion("bootloaderVersion"))
}
func TestReadConfigFile(t *testing.T) {
testCases := map[string]struct {
@ -64,41 +64,29 @@ func TestReadConfigFile(t *testing.T) {
wantResult *Config
wantErr bool
}{
// TODO(elchead): activate latest logic for next release AB#3036
//"mix of Latest and uint as version value": {
// config: func() configMap {
// conf := Default()
// m := getConfigAsMap(conf, t)
// m.setAzureSEVSNPVersion("microcodeVersion", "Latest") // check uppercase also works
// m.setAzureSEVSNPVersion("teeVersion", 2)
// m.setAzureSEVSNPVersion("bootloaderVersion", 1)
// return m
// }(),
// configName: constants.ConfigFilename,
// wantResult: func() *Config {
// conf := Default()
// conf.Attestation.AzureSEVSNP.BootloaderVersion = AttestationVersion{
// Value: 1,
// IsLatest: false,
// }
// conf.Attestation.AzureSEVSNP.TEEVersion = AttestationVersion{
// Value: 2,
// IsLatest: false,
// }
// return conf
// }(),
//},
// TODO(elchead): activate latest logic for next release AB#3036
"refuse invalid latest value": {
"mix of Latest and uint as version value": {
config: func() configMap {
conf := Default()
m := getConfigAsMap(conf, t)
m.setAzureSEVSNPVersion("microcodeVersion", "latest")
m.setAzureSEVSNPVersion("microcodeVersion", "Latest") // check uppercase also works
m.setAzureSEVSNPVersion("teeVersion", 2)
m.setAzureSEVSNPVersion("bootloaderVersion", 1)
return m
}(),
configName: constants.ConfigFilename,
wantErr: true,
wantResult: func() *Config {
conf := Default()
conf.Attestation.AzureSEVSNP.BootloaderVersion = AttestationVersion{
Value: 1,
IsLatest: false,
}
conf.Attestation.AzureSEVSNP.TEEVersion = AttestationVersion{
Value: 2,
IsLatest: false,
}
return conf
}(),
},
"refuse invalid version value": {
config: func() configMap {
@ -271,7 +259,7 @@ func TestNewWithDefaultOptions(t *testing.T) {
}
// Test
c, err := New(fileHandler, constants.ConfigFilename, fakeConfigFetcher{}, false)
c, err := New(fileHandler, constants.ConfigFilename, stubAttestationFetcher{}, false)
if tc.wantErr {
assert.Error(err)
return
@ -889,9 +877,9 @@ func (c configMap) setAzureSEVSNPVersion(versionType string, value interface{})
c["attestation"].(configMap)["azureSEVSNP"].(configMap)[versionType] = value
}
//func (c configMap) getAzureSEVSNPVersion(versionType string) interface{} {
// return c["attestation"].(configMap)["azureSEVSNP"].(configMap)[versionType]
//}
func (c configMap) getAzureSEVSNPVersion(versionType string) interface{} {
return c["attestation"].(configMap)["azureSEVSNP"].(configMap)[versionType]
}
// getConfigAsMap returns a map of the config.
func getConfigAsMap(conf *Config, t *testing.T) (res configMap) {
@ -905,21 +893,21 @@ func getConfigAsMap(conf *Config, t *testing.T) (res configMap) {
return
}
type fakeConfigFetcher struct{}
type stubAttestationFetcher struct{}
func (f fakeConfigFetcher) FetchAzureSEVSNPVersionList(_ context.Context, _ configapi.AzureSEVSNPVersionList) (configapi.AzureSEVSNPVersionList, error) {
func (f stubAttestationFetcher) FetchAzureSEVSNPVersionList(_ context.Context, _ configapi.AzureSEVSNPVersionList) (configapi.AzureSEVSNPVersionList, error) {
return configapi.AzureSEVSNPVersionList(
[]string{},
), nil
}
func (f fakeConfigFetcher) FetchAzureSEVSNPVersion(_ context.Context, _ configapi.AzureSEVSNPVersionAPI) (configapi.AzureSEVSNPVersionAPI, error) {
func (f stubAttestationFetcher) FetchAzureSEVSNPVersion(_ context.Context, _ configapi.AzureSEVSNPVersionAPI) (configapi.AzureSEVSNPVersionAPI, error) {
return configapi.AzureSEVSNPVersionAPI{
AzureSEVSNPVersion: testCfg,
}, nil
}
func (f fakeConfigFetcher) FetchAzureSEVSNPVersionLatest(_ context.Context) (configapi.AzureSEVSNPVersionAPI, error) {
func (f stubAttestationFetcher) FetchAzureSEVSNPVersionLatest(_ context.Context, _ time.Time) (configapi.AzureSEVSNPVersionAPI, error) {
return configapi.AzureSEVSNPVersionAPI{
AzureSEVSNPVersion: testCfg,
}, nil

View file

@ -18,6 +18,11 @@ import (
sigsig "github.com/sigstore/sigstore/pkg/signature"
)
// Verifier checks if the signature of content can be verified.
type Verifier interface {
VerifySignature(content, signature, publicKey []byte) error
}
// CosignVerifier checks if the signature of content can be verified
// using a cosign public key.
type CosignVerifier struct{}