Skip to content

Commit 00cc144

Browse files
committed
cleanup
1 parent 15bf10d commit 00cc144

File tree

5 files changed

+103
-144
lines changed

5 files changed

+103
-144
lines changed

cmd/attested-get/main.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package main
1919

2020
import (
2121
"encoding/asn1"
22-
"encoding/hex"
2322
"encoding/json"
2423
"errors"
2524
"fmt"
@@ -169,17 +168,17 @@ func runClient(cCtx *cli.Context) (err error) {
169168
return err
170169
}
171170

172-
measurementsInHeaderFormat := make(map[string]string, len(extractedMeasurements))
173-
for pcr, value := range extractedMeasurements {
174-
measurementsInHeaderFormat[fmt.Sprint(pcr)] = hex.EncodeToString(value)
171+
printableMeasurements := make(map[uint32]string)
172+
for k, v := range extractedMeasurements {
173+
printableMeasurements[k] = fmt.Sprintf("%x", v)
175174
}
176175

177-
marshaledPcrs, err := json.MarshalIndent(measurementsInHeaderFormat, "", " ")
176+
marshaledPcrs, err := json.MarshalIndent(printableMeasurements, "", " ")
178177
if err != nil {
179178
return errors.New("could not marshal measurement extracted from tls extension")
180179
}
181180

182-
log.Info(fmt.Sprintf("Measurements for %s with %d entries:", atlsVariant.String(), len(measurementsInHeaderFormat)))
181+
log.Info(fmt.Sprintf("Measurements for %s with %d entries:", atlsVariant.String(), len(extractedMeasurements)))
183182
fmt.Println(string(marshaledPcrs))
184183
if outMeasurements != "" {
185184
if err := os.WriteFile(outMeasurements, marshaledPcrs, 0o644); err != nil {
@@ -189,11 +188,11 @@ func runClient(cCtx *cli.Context) (err error) {
189188

190189
// Compare against expected measurements
191190
if expectedMeasurements != nil {
192-
found, name := expectedMeasurements.Contains(measurementsInHeaderFormat)
191+
found, foundMeasurement := expectedMeasurements.Contains(extractedMeasurements)
193192
if found {
194-
log.Info("Measurements match expected measurements for " + name)
193+
log.Info("Measurements match expected measurements for " + foundMeasurement.MeasurementID + " ✅")
195194
} else {
196-
log.Error("Measurements do not match expected measurements! ⚠️")
195+
log.Error("Measurements do not match expected measurements! ")
197196
}
198197
}
199198

common/expected_measurements.go

Lines changed: 11 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ package common
55
// provided measurements against them.
66
//
77
// Internally this uses the measurements data schema v2 (as served by
8-
// https://measurements.builder.flashbots.net), but is also backwards
9-
// compatible with v1 (i.e. measurements.json used by cvm-proxy).
10-
//
11-
// Data schema v2:
8+
// https://measurements.builder.flashbots.net):
129
//
1310
// [
1411
// {
@@ -24,33 +21,16 @@ package common
2421
// ...
2522
// ]
2623
//
27-
// Data schema v1:
28-
//
29-
// {
30-
// "azure-tdx-example": {
31-
// "15": {
32-
// "expected": "0000000000000000000000000000000000000000000000000000000000000000"
33-
// },
34-
// ...
35-
// },
36-
// "dcap-tdx-example": {
37-
// "4": {
38-
// "expected": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
39-
// },
40-
// ...
41-
// }
42-
// }
43-
//
44-
// The v2 data schema is an improvement because it allows additional data fields
45-
// besides the raw measurements.
46-
//
4724

4825
import (
26+
"bytes"
4927
"encoding/json"
5028
"io"
5129
"net/http"
5230
"os"
5331
"strings"
32+
33+
"github.com/flashbots/cvm-reverse-proxy/internal/attestation/measurements"
5434
)
5535

5636
// ExpectedMeasurements is a struct that represents a list of expected measurements,
@@ -59,18 +39,12 @@ type ExpectedMeasurements struct {
5939
Measurements []MeasurementsContainer
6040
}
6141

62-
type MeasurementEntry struct {
63-
Expected string `json:"expected"`
64-
}
65-
6642
type MeasurementsContainer struct {
67-
MeasurementID string `json:"measurement_id"`
68-
AttestationType string `json:"attestation_type"`
69-
Measurements map[string]MeasurementEntry `json:"measurements"`
43+
MeasurementID string `json:"measurement_id"`
44+
AttestationType string `json:"attestation_type"`
45+
Measurements measurements.M `json:"measurements"`
7046
}
7147

72-
type LegacyMeasurementsContainer map[string]map[string]MeasurementEntry
73-
7448
// NewExpectedMeasurementsFromFile returns an ExpectedMeasurements instance,
7549
// with the measurements loaded from a file or URL.
7650
func NewExpectedMeasurementsFromFile(path string) (m *ExpectedMeasurements, err error) {
@@ -95,43 +69,27 @@ func NewExpectedMeasurementsFromFile(path string) (m *ExpectedMeasurements, err
9569
}
9670

9771
m = &ExpectedMeasurements{}
98-
99-
// Try to load v2 data schema
10072
err = json.Unmarshal(data, &m.Measurements)
101-
// If loading v2 format fails, try to load the legacy v1 data schema
102-
if err != nil {
103-
var legacyData LegacyMeasurementsContainer
104-
err = json.Unmarshal(data, &legacyData)
105-
for measurementID, measurements := range legacyData {
106-
container := MeasurementsContainer{
107-
MeasurementID: measurementID,
108-
AttestationType: "azure-tdx",
109-
Measurements: measurements,
110-
}
111-
m.Measurements = append(m.Measurements, container)
112-
}
113-
}
114-
11573
return m, err
11674
}
11775

11876
// Contains checks if the provided measurements match one of the known measurements. Any keys in the provided
11977
// measurements which are not in the known measurements are ignored.
120-
func (m *ExpectedMeasurements) Contains(measurements map[string]string) (found bool, measurementID string) {
78+
func (m *ExpectedMeasurements) Contains(measurements map[uint32][]byte) (found bool, foundMeasurement *MeasurementsContainer) {
12179
// For every known container, all known measurements match (and additional ones are ignored)
12280
for _, container := range m.Measurements {
12381
allMatch := true
12482
for key, value := range container.Measurements {
125-
if value.Expected != measurements[key] {
83+
if !bytes.Equal(value.Expected, measurements[key]) {
12684
allMatch = false
12785
break
12886
}
12987
}
13088

13189
if allMatch {
132-
return true, container.MeasurementID
90+
return true, &container
13391
}
13492
}
13593

136-
return false, ""
94+
return false, nil
13795
}
Lines changed: 30 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,67 @@
11
package common
22

33
import (
4-
"encoding/json"
4+
"encoding/hex"
55
"testing"
66

77
"github.com/stretchr/testify/require"
88
)
99

1010
// TestMeasurements is kept simple: map[pcr]measurement
11-
type TestMeasurements map[string]string
11+
type TestMeasurements map[uint32][]byte
1212

13-
// Expected measurements v2 data schema. See also https://measurements.builder.flashbots.net
14-
var expectedMeasurementsV2JSON = `[{"measurement_id":"measurement-test-1","attestation_type":"azure-tdx","measurements":{"4":{"expected":"98ba2c602b62e67b8e0bd6c6676f12ade320a763e5e4564f62fd875a502dd651"},"9":{"expected":"e77938394412d83a8d4de52cdaf97df82a4d4059e1e7c4fc3c73581816cea496"},"11":{"expected":"0000000000000000000000000000000000000000000000000000000000000000"}}},{"measurement_id":"cvm-image-azure-tdx.rootfs-20241107200854.wic.vhd","attestation_type":"azure-tdx","measurements":{"4":{"expected":"1b8cd655f5ebdf50bedabfb5db6b896a0a7c56de54f318103a2de1e7cea57b6b"},"9":{"expected":"992465f922102234c196f596fdaba86ea16eaa4c264dc425ec26bc2d1c364472"}}}]`
13+
func mustBytesFromHex(hexValue string) []byte {
14+
bytes, err := hex.DecodeString(hexValue)
15+
if err != nil {
16+
panic(err)
17+
}
18+
return bytes
19+
}
1520

1621
// TestExpectedMeasurementsV2 tests the v2 data schema
1722
func TestExpectedMeasurementsV2(t *testing.T) {
18-
// Load expected measurements from provided JSON string
19-
m := ExpectedMeasurements{}
20-
err := json.Unmarshal([]byte(expectedMeasurementsV2JSON), &m.Measurements)
23+
// Load expected measurements from JSON file
24+
m, err := NewExpectedMeasurementsFromFile("../measurements.json")
2125
require.NoError(t, err)
22-
require.Len(t, m.Measurements, 2)
26+
require.Len(t, m.Measurements, 3)
2327

2428
// Setup test measurements (matching cvm-image-azure-tdx.rootfs-20241107200854.wic.vhd)
2529
testMeasurements := TestMeasurements{
26-
"4": "1b8cd655f5ebdf50bedabfb5db6b896a0a7c56de54f318103a2de1e7cea57b6b",
27-
"9": "992465f922102234c196f596fdaba86ea16eaa4c264dc425ec26bc2d1c364472",
30+
4: mustBytesFromHex("1b8cd655f5ebdf50bedabfb5db6b896a0a7c56de54f318103a2de1e7cea57b6b"),
31+
9: mustBytesFromHex("992465f922102234c196f596fdaba86ea16eaa4c264dc425ec26bc2d1c364472"),
2832
}
2933

3034
// Ensure matching entries works, and that additional fields are ignored
31-
testMeasurements["11"] = testMeasurements["4"]
32-
exists, name := m.Contains(testMeasurements)
35+
testMeasurements[11] = testMeasurements[4]
36+
exists, foundMeasurement := m.Contains(testMeasurements)
3337
require.True(t, exists)
34-
require.Equal(t, "cvm-image-azure-tdx.rootfs-20241107200854.wic.vhd", name)
38+
require.Equal(t, "cvm-image-azure-tdx.rootfs-20241107200854.wic.vhd", foundMeasurement.MeasurementID)
39+
require.Equal(t, "azure-tdx", foundMeasurement.AttestationType)
3540

3641
// Ensure check fails with a missing required key
37-
delete(testMeasurements, "4")
42+
delete(testMeasurements, 4)
3843
exists, _ = m.Contains(testMeasurements)
3944
require.False(t, exists)
4045

4146
// Double-check it works again
42-
testMeasurements["4"] = testMeasurements["11"]
47+
testMeasurements[4] = testMeasurements[11]
4348
exists, _ = m.Contains(testMeasurements)
4449
require.True(t, exists)
4550

4651
// Any changed value should make it fail
47-
testMeasurements["4"] = testMeasurements["9"]
52+
testMeasurements[4] = testMeasurements[9]
4853
exists, _ = m.Contains(testMeasurements)
4954
require.False(t, exists)
50-
}
51-
52-
// TestExpectedMeasurementsV1 tests the v1 data schema backwards compatibility
53-
func TestExpectedMeasurementsV1(t *testing.T) {
54-
// Load expected measurements from provided JSON string
55-
m, err := NewExpectedMeasurementsFromFile("../measurements.json")
56-
require.NoError(t, err)
57-
58-
// Ensure that two known measurements are loaded
59-
require.Len(t, m.Measurements, 2)
6055

61-
// Setup test measurements (matching dcap-tdx-example)
62-
testMeasurements := TestMeasurements{
63-
"0": "5d56080eb9ef8ce0bbaf6bdcdadeeb06e7c5b0a4d1ec16be868a85a953babe0c5e54d01c8e050a54fe1ca078372530d2",
64-
"1": "4216e925f796f4e282cfa6e72d4c77a80560987afa29155a61fdc33adb80eab0d4112abd52387e5e25a60deefb8a5287",
65-
"2": "4274fefb79092c164000b571b64ecb432fa2357adb421fd1c77a867168d7d7f7fe82796d1eba092c7bab35cf43f5ec55",
66-
"3": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
67-
"4": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
56+
// Check for another set of known measurements (dcap-tdx-example)
57+
testMeasurements = TestMeasurements{
58+
0: mustBytesFromHex("5d56080eb9ef8ce0bbaf6bdcdadeeb06e7c5b0a4d1ec16be868a85a953babe0c5e54d01c8e050a54fe1ca078372530d2"),
59+
1: mustBytesFromHex("4216e925f796f4e282cfa6e72d4c77a80560987afa29155a61fdc33adb80eab0d4112abd52387e5e25a60deefb8a5287"),
60+
2: mustBytesFromHex("4274fefb79092c164000b571b64ecb432fa2357adb421fd1c77a867168d7d7f7fe82796d1eba092c7bab35cf43f5ec55"),
61+
3: mustBytesFromHex("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
62+
4: mustBytesFromHex("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
6863
}
69-
70-
// Check if matching a known measurements entry
71-
exists, name := m.Contains(testMeasurements)
64+
exists, foundMeasurement = m.Contains(testMeasurements)
7265
require.True(t, exists)
73-
require.Equal(t, "dcap-tdx-example", name)
66+
require.Equal(t, "dcap-tdx-example-02", foundMeasurement.MeasurementID)
7467
}

measurements.json

Lines changed: 50 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,50 @@
1-
{
2-
"azure-tdx-example": {
3-
"11": {
4-
"expected": "efa43e0beff151b0f251c4abf48152382b1452b4414dbd737b4127de05ca31f7"
5-
},
6-
"12": {
7-
"expected": "0000000000000000000000000000000000000000000000000000000000000000"
8-
},
9-
"13": {
10-
"expected": "0000000000000000000000000000000000000000000000000000000000000000"
11-
},
12-
"15": {
13-
"expected": "0000000000000000000000000000000000000000000000000000000000000000"
14-
},
15-
"4": {
16-
"expected": "ea92ff762767eae6316794f1641c485d4846bc2b9df2eab6ba7f630ce6f4d66f"
17-
},
18-
"8": {
19-
"expected": "0000000000000000000000000000000000000000000000000000000000000000"
20-
},
21-
"9": {
22-
"expected": "c9f429296634072d1063a03fb287bed0b2d177b0a504755ad9194cffd90b2489"
23-
}
24-
},
25-
"dcap-tdx-example": {
26-
"0": {
27-
"expected": "5d56080eb9ef8ce0bbaf6bdcdadeeb06e7c5b0a4d1ec16be868a85a953babe0c5e54d01c8e050a54fe1ca078372530d2"
28-
},
29-
"1": {
30-
"expected": "4216e925f796f4e282cfa6e72d4c77a80560987afa29155a61fdc33adb80eab0d4112abd52387e5e25a60deefb8a5287"
31-
},
32-
"2": {
33-
"expected": "4274fefb79092c164000b571b64ecb432fa2357adb421fd1c77a867168d7d7f7fe82796d1eba092c7bab35cf43f5ec55"
34-
},
35-
"3": {
36-
"expected": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
37-
},
38-
"4": {
39-
"expected": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
40-
}
41-
}
42-
}
1+
[
2+
{
3+
"measurement_id": "azure-tdx-example-01",
4+
"attestation_type": "azure-tdx",
5+
"measurements": {
6+
"4": {
7+
"expected": "ea92ff762767eae6316794f1641c485d4846bc2b9df2eab6ba7f630ce6f4d66f"
8+
},
9+
"9": {
10+
"expected": "c9f429296634072d1063a03fb287bed0b2d177b0a504755ad9194cffd90b2489"
11+
},
12+
"11": {
13+
"expected": "efa43e0beff151b0f251c4abf48152382b1452b4414dbd737b4127de05ca31f7"
14+
}
15+
}
16+
},
17+
{
18+
"measurement_id": "cvm-image-azure-tdx.rootfs-20241107200854.wic.vhd",
19+
"attestation_type": "azure-tdx",
20+
"measurements": {
21+
"4": {
22+
"expected": "1b8cd655f5ebdf50bedabfb5db6b896a0a7c56de54f318103a2de1e7cea57b6b"
23+
},
24+
"9": {
25+
"expected": "992465f922102234c196f596fdaba86ea16eaa4c264dc425ec26bc2d1c364472"
26+
}
27+
}
28+
},
29+
{
30+
"measurement_id": "dcap-tdx-example-02",
31+
"attestation_type": "dcap-tdx",
32+
"measurements": {
33+
"0": {
34+
"expected": "5d56080eb9ef8ce0bbaf6bdcdadeeb06e7c5b0a4d1ec16be868a85a953babe0c5e54d01c8e050a54fe1ca078372530d2"
35+
},
36+
"1": {
37+
"expected": "4216e925f796f4e282cfa6e72d4c77a80560987afa29155a61fdc33adb80eab0d4112abd52387e5e25a60deefb8a5287"
38+
},
39+
"2": {
40+
"expected": "4274fefb79092c164000b571b64ecb432fa2357adb421fd1c77a867168d7d7f7fe82796d1eba092c7bab35cf43f5ec55"
41+
},
42+
"3": {
43+
"expected": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
44+
},
45+
"4": {
46+
"expected": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
47+
}
48+
}
49+
}
50+
]

proxy/atls_config.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"log/slog"
1111
"os"
1212

13+
"github.com/flashbots/cvm-reverse-proxy/common"
1314
"github.com/flashbots/cvm-reverse-proxy/internal/atls"
1415
azure_tdx "github.com/flashbots/cvm-reverse-proxy/internal/attestation/azure/tdx"
1516
"github.com/flashbots/cvm-reverse-proxy/internal/attestation/measurements"
@@ -65,7 +66,7 @@ func CreateAttestationValidators(log *slog.Logger, attestationType AttestationTy
6566
return nil, err
6667
}
6768

68-
parsedMeasurements := make(map[string]measurements.M)
69+
var parsedMeasurements []common.MeasurementsContainer
6970
err = json.Unmarshal(jsonMeasurements, &parsedMeasurements)
7071
if err != nil {
7172
return nil, err
@@ -76,15 +77,15 @@ func CreateAttestationValidators(log *slog.Logger, attestationType AttestationTy
7677
validators := []atls.Validator{}
7778
for _, measurement := range parsedMeasurements {
7879
attConfig := config.DefaultForAzureTDX()
79-
attConfig.SetMeasurements(measurement)
80+
attConfig.SetMeasurements(measurement.Measurements)
8081
validators = append(validators, azure_tdx.NewValidator(attConfig, AttestationLogger{Log: log}))
8182
}
8283
return []atls.Validator{NewMultiValidator(validators)}, nil
8384
case AttestationDCAPTDX:
8485
validators := []atls.Validator{}
8586
for _, measurement := range parsedMeasurements {
8687
attConfig := &config.QEMUTDX{Measurements: measurements.DefaultsFor(cloudprovider.QEMU, variant.QEMUTDX{})}
87-
attConfig.SetMeasurements(measurement)
88+
attConfig.SetMeasurements(measurement.Measurements)
8889
validators = append(validators, dcap_tdx.NewValidator(attConfig, AttestationLogger{Log: log}))
8990
}
9091
return []atls.Validator{NewMultiValidator(validators)}, nil

0 commit comments

Comments
 (0)