mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-11-13 09:00:38 -05:00
attestation: merging of ImageMeasurementsV2
This commit is contained in:
parent
874c4b76cf
commit
0a7349ca41
2 changed files with 233 additions and 0 deletions
|
|
@ -78,6 +78,42 @@ type ImageMeasurementsV2Entry struct {
|
||||||
Measurements M `json:"measurements" yaml:"measurements"`
|
Measurements M `json:"measurements" yaml:"measurements"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MergeImageMeasurementsV2 combines the image measurement entries from multiple sources into a single
|
||||||
|
// ImageMeasurementsV2 object.
|
||||||
|
func MergeImageMeasurementsV2(measurements ...ImageMeasurementsV2) (ImageMeasurementsV2, error) {
|
||||||
|
if len(measurements) == 0 {
|
||||||
|
return ImageMeasurementsV2{}, errors.New("no measurement objects specified")
|
||||||
|
}
|
||||||
|
if len(measurements) == 1 {
|
||||||
|
return measurements[0], nil
|
||||||
|
}
|
||||||
|
out := ImageMeasurementsV2{
|
||||||
|
Version: measurements[0].Version,
|
||||||
|
Ref: measurements[0].Ref,
|
||||||
|
Stream: measurements[0].Stream,
|
||||||
|
List: []ImageMeasurementsV2Entry{},
|
||||||
|
}
|
||||||
|
for _, m := range measurements {
|
||||||
|
if m.Version != out.Version {
|
||||||
|
return ImageMeasurementsV2{}, errors.New("version mismatch")
|
||||||
|
}
|
||||||
|
if m.Ref != out.Ref {
|
||||||
|
return ImageMeasurementsV2{}, errors.New("ref mismatch")
|
||||||
|
}
|
||||||
|
if m.Stream != out.Stream {
|
||||||
|
return ImageMeasurementsV2{}, errors.New("stream mismatch")
|
||||||
|
}
|
||||||
|
out.List = append(out.List, m.List...)
|
||||||
|
}
|
||||||
|
sort.SliceStable(out.List, func(i, j int) bool {
|
||||||
|
if out.List[i].CSP != out.List[j].CSP {
|
||||||
|
return out.List[i].CSP < out.List[j].CSP
|
||||||
|
}
|
||||||
|
return out.List[i].AttestationVariant < out.List[j].AttestationVariant
|
||||||
|
})
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
// MarshalYAML returns the YAML encoding of m.
|
// MarshalYAML returns the YAML encoding of m.
|
||||||
func (m M) MarshalYAML() (any, error) {
|
func (m M) MarshalYAML() (any, error) {
|
||||||
// cast to prevent infinite recursion
|
// cast to prevent infinite recursion
|
||||||
|
|
|
||||||
|
|
@ -746,3 +746,200 @@ func TestEqualTo(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMergeImageMeasurementsV2(t *testing.T) {
|
||||||
|
testCases := map[string]struct {
|
||||||
|
measurements []ImageMeasurementsV2
|
||||||
|
wantMeasurements ImageMeasurementsV2
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
"only one element": {
|
||||||
|
measurements: []ImageMeasurementsV2{
|
||||||
|
{
|
||||||
|
Ref: "test-ref",
|
||||||
|
Stream: "nightly",
|
||||||
|
Version: "v1.0.0",
|
||||||
|
List: []ImageMeasurementsV2Entry{
|
||||||
|
{
|
||||||
|
CSP: cloudprovider.AWS,
|
||||||
|
AttestationVariant: "aws-nitro-tpm",
|
||||||
|
Measurements: M{
|
||||||
|
0: WithAllBytes(0x00, Enforce, PCRMeasurementLength),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantMeasurements: ImageMeasurementsV2{
|
||||||
|
Ref: "test-ref",
|
||||||
|
Stream: "nightly",
|
||||||
|
Version: "v1.0.0",
|
||||||
|
List: []ImageMeasurementsV2Entry{
|
||||||
|
{
|
||||||
|
CSP: cloudprovider.AWS,
|
||||||
|
AttestationVariant: "aws-nitro-tpm",
|
||||||
|
Measurements: M{
|
||||||
|
0: WithAllBytes(0x00, Enforce, PCRMeasurementLength),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"valid measurements": {
|
||||||
|
measurements: []ImageMeasurementsV2{
|
||||||
|
{
|
||||||
|
Ref: "test-ref",
|
||||||
|
Stream: "nightly",
|
||||||
|
Version: "v1.0.0",
|
||||||
|
List: []ImageMeasurementsV2Entry{
|
||||||
|
{
|
||||||
|
CSP: cloudprovider.AWS,
|
||||||
|
AttestationVariant: "aws-nitro-tpm",
|
||||||
|
Measurements: M{
|
||||||
|
0: WithAllBytes(0x00, Enforce, PCRMeasurementLength),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Ref: "test-ref",
|
||||||
|
Stream: "nightly",
|
||||||
|
Version: "v1.0.0",
|
||||||
|
List: []ImageMeasurementsV2Entry{
|
||||||
|
{
|
||||||
|
CSP: cloudprovider.GCP,
|
||||||
|
AttestationVariant: "gcp-sev-es",
|
||||||
|
Measurements: M{
|
||||||
|
1: WithAllBytes(0x11, Enforce, PCRMeasurementLength),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantMeasurements: ImageMeasurementsV2{
|
||||||
|
Ref: "test-ref",
|
||||||
|
Stream: "nightly",
|
||||||
|
Version: "v1.0.0",
|
||||||
|
List: []ImageMeasurementsV2Entry{
|
||||||
|
{
|
||||||
|
CSP: cloudprovider.AWS,
|
||||||
|
AttestationVariant: "aws-nitro-tpm",
|
||||||
|
Measurements: M{
|
||||||
|
0: WithAllBytes(0x00, Enforce, PCRMeasurementLength),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CSP: cloudprovider.GCP,
|
||||||
|
AttestationVariant: "gcp-sev-es",
|
||||||
|
Measurements: M{
|
||||||
|
1: WithAllBytes(0x11, Enforce, PCRMeasurementLength),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"sorting": {
|
||||||
|
measurements: []ImageMeasurementsV2{
|
||||||
|
{
|
||||||
|
Ref: "test-ref",
|
||||||
|
Stream: "nightly",
|
||||||
|
Version: "v1.0.0",
|
||||||
|
List: []ImageMeasurementsV2Entry{
|
||||||
|
{
|
||||||
|
CSP: cloudprovider.GCP,
|
||||||
|
AttestationVariant: "gcp-sev-es",
|
||||||
|
Measurements: M{
|
||||||
|
1: WithAllBytes(0x11, Enforce, PCRMeasurementLength),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Ref: "test-ref",
|
||||||
|
Stream: "nightly",
|
||||||
|
Version: "v1.0.0",
|
||||||
|
List: []ImageMeasurementsV2Entry{
|
||||||
|
{
|
||||||
|
CSP: cloudprovider.AWS,
|
||||||
|
AttestationVariant: "aws-nitro-tpm",
|
||||||
|
Measurements: M{
|
||||||
|
0: WithAllBytes(0x00, Enforce, PCRMeasurementLength),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantMeasurements: ImageMeasurementsV2{
|
||||||
|
Ref: "test-ref",
|
||||||
|
Stream: "nightly",
|
||||||
|
Version: "v1.0.0",
|
||||||
|
List: []ImageMeasurementsV2Entry{
|
||||||
|
{
|
||||||
|
CSP: cloudprovider.AWS,
|
||||||
|
AttestationVariant: "aws-nitro-tpm",
|
||||||
|
Measurements: M{
|
||||||
|
0: WithAllBytes(0x00, Enforce, PCRMeasurementLength),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CSP: cloudprovider.GCP,
|
||||||
|
AttestationVariant: "gcp-sev-es",
|
||||||
|
Measurements: M{
|
||||||
|
1: WithAllBytes(0x11, Enforce, PCRMeasurementLength),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"mismatch in base info": {
|
||||||
|
measurements: []ImageMeasurementsV2{
|
||||||
|
{
|
||||||
|
Ref: "test-ref",
|
||||||
|
Stream: "nightly",
|
||||||
|
Version: "v1.0.0",
|
||||||
|
List: []ImageMeasurementsV2Entry{
|
||||||
|
{
|
||||||
|
CSP: cloudprovider.AWS,
|
||||||
|
AttestationVariant: "aws-nitro-tpm",
|
||||||
|
Measurements: M{
|
||||||
|
0: WithAllBytes(0x00, Enforce, PCRMeasurementLength),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Ref: "other-ref",
|
||||||
|
Stream: "stable",
|
||||||
|
Version: "v2.0.0",
|
||||||
|
List: []ImageMeasurementsV2Entry{
|
||||||
|
{
|
||||||
|
CSP: cloudprovider.GCP,
|
||||||
|
AttestationVariant: "gcp-sev-es",
|
||||||
|
Measurements: M{
|
||||||
|
1: WithAllBytes(0x11, Enforce, PCRMeasurementLength),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
"empty list": {
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, tc := range testCases {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
gotMeasurements, err := MergeImageMeasurementsV2(tc.measurements...)
|
||||||
|
|
||||||
|
if tc.wantErr {
|
||||||
|
assert.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.Equal(tc.wantMeasurements, gotMeasurements)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue