mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-08-20 20:48:12 -04:00
AB#2644 Fetch measurements from CDN (#653)
* Fetch measurements from CDN * Perform metadata validation on fetched measurements * Remove deprecated public bucket Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
parent
c978329839
commit
d52f3db2a3
16 changed files with 406 additions and 144 deletions
|
@ -40,15 +40,18 @@ type M map[uint32]Measurement
|
|||
|
||||
// WithMetadata is a struct supposed to provide CSP & image metadata next to measurements.
|
||||
type WithMetadata struct {
|
||||
CSP string `json:"csp" yaml:"csp"`
|
||||
Image string `json:"image" yaml:"image"`
|
||||
Measurements M `json:"measurements" yaml:"measurements"`
|
||||
CSP cloudprovider.Provider `json:"csp" yaml:"csp"`
|
||||
Image string `json:"image" yaml:"image"`
|
||||
Measurements M `json:"measurements" yaml:"measurements"`
|
||||
}
|
||||
|
||||
// FetchAndVerify fetches measurement and signature files via provided URLs,
|
||||
// using client for download. The publicKey is used to verify the measurements.
|
||||
// The hash of the fetched measurements is returned.
|
||||
func (m *M) FetchAndVerify(ctx context.Context, client *http.Client, measurementsURL *url.URL, signatureURL *url.URL, publicKey []byte) (string, error) {
|
||||
func (m *M) FetchAndVerify(
|
||||
ctx context.Context, client *http.Client, measurementsURL, signatureURL *url.URL,
|
||||
publicKey []byte, metadata WithMetadata,
|
||||
) (string, error) {
|
||||
measurements, err := getFromURL(ctx, client, measurementsURL)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to fetch measurements: %w", err)
|
||||
|
@ -61,8 +64,9 @@ func (m *M) FetchAndVerify(ctx context.Context, client *http.Client, measurement
|
|||
return "", err
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(measurements, m); err != nil {
|
||||
if yamlErr := yaml.Unmarshal(measurements, m); yamlErr != nil {
|
||||
var mWithMetadata WithMetadata
|
||||
if err := json.Unmarshal(measurements, &mWithMetadata); err != nil {
|
||||
if yamlErr := yaml.Unmarshal(measurements, &mWithMetadata); yamlErr != nil {
|
||||
return "", multierr.Append(
|
||||
err,
|
||||
fmt.Errorf("trying yaml format: %w", yamlErr),
|
||||
|
@ -70,6 +74,15 @@ func (m *M) FetchAndVerify(ctx context.Context, client *http.Client, measurement
|
|||
}
|
||||
}
|
||||
|
||||
if mWithMetadata.CSP != metadata.CSP {
|
||||
return "", fmt.Errorf("invalid measurement metadata: CSP mismatch: expected %s, got %s", metadata.CSP, mWithMetadata.CSP)
|
||||
}
|
||||
if mWithMetadata.Image != metadata.Image {
|
||||
return "", fmt.Errorf("invalid measurement metadata: image mismatch: expected %s, got %s", metadata.Image, mWithMetadata.Image)
|
||||
}
|
||||
|
||||
*m = mWithMetadata.Measurements
|
||||
|
||||
shaHash := sha256.Sum256(measurements)
|
||||
|
||||
return hex.EncodeToString(shaHash[:]), nil
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
@ -278,80 +279,86 @@ func TestMeasurementsFetchAndVerify(t *testing.T) {
|
|||
// TDcvRjBBVy9vUDVqZXR3dmJMNmQxOEhjck9kWE8yVmYxY2w0YzNLZjVRcnFSZzlN
|
||||
// dlRxQWFsNXJCNHNpY1JaMVhpUUJjb0YwNHc9PSJ9
|
||||
// -----END ENCRYPTED COSIGN PRIVATE KEY-----
|
||||
cosignPublicKey := []byte("-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEu78QgxOOcao6U91CSzEXxrKhvFTt\nJHNy+eX6EMePtDm8CnDF9HSwnTlD0itGJ/XHPQA5YX10fJAqI1y+ehlFMw==\n-----END PUBLIC KEY-----")
|
||||
|
||||
testCases := map[string]struct {
|
||||
measurements string
|
||||
metadata WithMetadata
|
||||
measurementsStatus int
|
||||
signature string
|
||||
signatureStatus int
|
||||
publicKey []byte
|
||||
wantMeasurements M
|
||||
wantSHA string
|
||||
wantError bool
|
||||
}{
|
||||
"simple": {
|
||||
measurements: "0: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\n",
|
||||
measurementsStatus: http.StatusOK,
|
||||
signature: "MEUCIQDcHS2bLls7OrLHpQKuiFGXhPrTcehPDwgVyERHl4V02wIgeIxK4J9oJpXWRBjokbog2lgifRXuJK8ljlAID26MbHk=",
|
||||
signatureStatus: http.StatusOK,
|
||||
publicKey: []byte("-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEu78QgxOOcao6U91CSzEXxrKhvFTt\nJHNy+eX6EMePtDm8CnDF9HSwnTlD0itGJ/XHPQA5YX10fJAqI1y+ehlFMw==\n-----END PUBLIC KEY-----"),
|
||||
wantMeasurements: M{
|
||||
0: WithAllBytes(0x00, false),
|
||||
},
|
||||
wantSHA: "4cd9d6ed8d9322150dff7738994c5e2fabff35f3bae6f5c993412d13249a5e87",
|
||||
},
|
||||
"json measurements": {
|
||||
measurements: `{"0":{"expected":"0000000000000000000000000000000000000000000000000000000000000000","warnOnly":false}}`,
|
||||
measurements: `{"csp":"test","image":"test","measurements":{"0":{"expected":"0000000000000000000000000000000000000000000000000000000000000000","warnOnly":false}}}`,
|
||||
metadata: WithMetadata{CSP: cloudprovider.Unknown, Image: "test"},
|
||||
measurementsStatus: http.StatusOK,
|
||||
signature: "MEUCIQDh3nCgrdTiYWiV4NkiaZ6vxovj79Pk8V90mdWAnmCEOwIgMAVWAx5dW0saut+8X15SgtBEiKqEixYiSICSqqhxUMg=",
|
||||
signature: "MEYCIQD1RR91pWPw1BMWXTSmTBHg/JtfKerbZNQ9PJTWDdW0sgIhANQbETJGb67qzQmMVmcq007VUFbHRMtYWKZeeyRf0gVa",
|
||||
signatureStatus: http.StatusOK,
|
||||
publicKey: []byte("-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEu78QgxOOcao6U91CSzEXxrKhvFTt\nJHNy+eX6EMePtDm8CnDF9HSwnTlD0itGJ/XHPQA5YX10fJAqI1y+ehlFMw==\n-----END PUBLIC KEY-----"),
|
||||
wantMeasurements: M{
|
||||
0: WithAllBytes(0x00, false),
|
||||
},
|
||||
wantSHA: "1da09758c89537946496358f80b892e508563fcbbc695c90b6c16bf158e69c11",
|
||||
wantSHA: "c04e13c1312b6f5659303871d14bf49b05c99a6515548763b6322f60bbb61a24",
|
||||
},
|
||||
"yaml measurements": {
|
||||
measurements: "0:\n expected: \"0000000000000000000000000000000000000000000000000000000000000000\"\n warnOnly: false\n",
|
||||
measurements: "csp: test\nimage: test\nmeasurements:\n 0:\n expected: \"0000000000000000000000000000000000000000000000000000000000000000\"\n warnOnly: false\n",
|
||||
metadata: WithMetadata{CSP: cloudprovider.Unknown, Image: "test"},
|
||||
measurementsStatus: http.StatusOK,
|
||||
signature: "MEUCIFzQdwBS92aJjY0bcIag1uQRl42lUSBmmjEvO0tM/N0ZAiEAvuWaP744qYMw5uEmc7BY4mm4Ij3TEqAWFgxNhFkckp4=",
|
||||
signature: "MEUCIQC9WI2ijlQjBktYFctKpbnqkUTey3U9W99Jp1NTLi5AbQIgNZxxOtiawgTkWPXLoH9D2CxpEjxQrqLn/zWF6NoKxWQ=",
|
||||
signatureStatus: http.StatusOK,
|
||||
publicKey: []byte("-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEu78QgxOOcao6U91CSzEXxrKhvFTt\nJHNy+eX6EMePtDm8CnDF9HSwnTlD0itGJ/XHPQA5YX10fJAqI1y+ehlFMw==\n-----END PUBLIC KEY-----"),
|
||||
wantMeasurements: M{
|
||||
0: WithAllBytes(0x00, false),
|
||||
},
|
||||
wantSHA: "c651cd419fd536c63cfc5349ad44da140a09987465e31192660059d383413807",
|
||||
wantSHA: "648fcfd5d22e623a948ab2dd4eb334be2701d8f158231726084323003daab8d4",
|
||||
},
|
||||
"404 measurements": {
|
||||
measurements: `{"0":{"expected":"0000000000000000000000000000000000000000000000000000000000000000","warnOnly":false}}`,
|
||||
measurements: `{"csp":"test","image":"test","measurements":{"0":{"expected":"0000000000000000000000000000000000000000000000000000000000000000","warnOnly":false}}}`,
|
||||
metadata: WithMetadata{CSP: cloudprovider.Unknown, Image: "test"},
|
||||
measurementsStatus: http.StatusNotFound,
|
||||
signature: "MEUCIQDh3nCgrdTiYWiV4NkiaZ6vxovj79Pk8V90mdWAnmCEOwIgMAVWAx5dW0saut+8X15SgtBEiKqEixYiSICSqqhxUMg=",
|
||||
signature: "MEYCIQD1RR91pWPw1BMWXTSmTBHg/JtfKerbZNQ9PJTWDdW0sgIhANQbETJGb67qzQmMVmcq007VUFbHRMtYWKZeeyRf0gVa",
|
||||
signatureStatus: http.StatusOK,
|
||||
publicKey: []byte("-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEu78QgxOOcao6U91CSzEXxrKhvFTt\nJHNy+eX6EMePtDm8CnDF9HSwnTlD0itGJ/XHPQA5YX10fJAqI1y+ehlFMw==\n-----END PUBLIC KEY-----"),
|
||||
wantError: true,
|
||||
},
|
||||
"404 signature": {
|
||||
measurements: `{"0":{"expected":"0000000000000000000000000000000000000000000000000000000000000000","warnOnly":false}}`,
|
||||
measurements: `{"csp":"test","image":"test","measurements":{"0":{"expected":"0000000000000000000000000000000000000000000000000000000000000000","warnOnly":false}}}`,
|
||||
metadata: WithMetadata{CSP: cloudprovider.Unknown, Image: "test"},
|
||||
measurementsStatus: http.StatusOK,
|
||||
signature: "MEUCIQDh3nCgrdTiYWiV4NkiaZ6vxovj79Pk8V90mdWAnmCEOwIgMAVWAx5dW0saut+8X15SgtBEiKqEixYiSICSqqhxUMg=",
|
||||
signature: "MEYCIQD1RR91pWPw1BMWXTSmTBHg/JtfKerbZNQ9PJTWDdW0sgIhANQbETJGb67qzQmMVmcq007VUFbHRMtYWKZeeyRf0gVa",
|
||||
signatureStatus: http.StatusNotFound,
|
||||
publicKey: []byte("-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEu78QgxOOcao6U91CSzEXxrKhvFTt\nJHNy+eX6EMePtDm8CnDF9HSwnTlD0itGJ/XHPQA5YX10fJAqI1y+ehlFMw==\n-----END PUBLIC KEY-----"),
|
||||
wantError: true,
|
||||
},
|
||||
"broken signature": {
|
||||
measurements: `{"0":{"expected":"0000000000000000000000000000000000000000000000000000000000000000","warnOnly":false}}`,
|
||||
measurements: `{"csp":"test","image":"test","measurements":{"0":{"expected":"0000000000000000000000000000000000000000000000000000000000000000","warnOnly":false}}}`,
|
||||
metadata: WithMetadata{CSP: cloudprovider.Unknown, Image: "test"},
|
||||
measurementsStatus: http.StatusOK,
|
||||
signature: "AAAAAAAA3nCgrdTiYWiV4NkiaZ6vxovj79Pk8V90mdWAnmCEOwIgMAVWAx5dW0saut+8X15SgtBEiKqEixYiSICSqqhxUMg=",
|
||||
signature: "AAAAAAA1RR91pWPw1BMWXTSmTBHg/JtfKerbZNQ9PJTWDdW0sgIhANQbETJGb67qzQmMVmcq007VUFbHRMtYWKZeeyRf0gVa",
|
||||
signatureStatus: http.StatusOK,
|
||||
wantError: true,
|
||||
},
|
||||
"metadata CSP mismatch": {
|
||||
measurements: `{"csp":"test","image":"test","measurements":{"0":{"expected":"0000000000000000000000000000000000000000000000000000000000000000","warnOnly":false}}}`,
|
||||
metadata: WithMetadata{CSP: cloudprovider.GCP, Image: "test"},
|
||||
measurementsStatus: http.StatusOK,
|
||||
signature: "MEYCIQD1RR91pWPw1BMWXTSmTBHg/JtfKerbZNQ9PJTWDdW0sgIhANQbETJGb67qzQmMVmcq007VUFbHRMtYWKZeeyRf0gVa",
|
||||
signatureStatus: http.StatusOK,
|
||||
wantError: true,
|
||||
},
|
||||
"metadata image mismatch": {
|
||||
measurements: `{"csp":"test","image":"test","measurements":{"0":{"expected":"0000000000000000000000000000000000000000000000000000000000000000","warnOnly":false}}}`,
|
||||
metadata: WithMetadata{CSP: cloudprovider.Unknown, Image: "another-image"},
|
||||
measurementsStatus: http.StatusOK,
|
||||
signature: "MEYCIQD1RR91pWPw1BMWXTSmTBHg/JtfKerbZNQ9PJTWDdW0sgIhANQbETJGb67qzQmMVmcq007VUFbHRMtYWKZeeyRf0gVa",
|
||||
signatureStatus: http.StatusOK,
|
||||
publicKey: []byte("-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEu78QgxOOcao6U91CSzEXxrKhvFTt\nJHNy+eX6EMePtDm8CnDF9HSwnTlD0itGJ/XHPQA5YX10fJAqI1y+ehlFMw==\n-----END PUBLIC KEY-----"),
|
||||
wantError: true,
|
||||
},
|
||||
"not yaml or json": {
|
||||
measurements: "This is some content to be signed!\n",
|
||||
metadata: WithMetadata{CSP: cloudprovider.Unknown, Image: "test"},
|
||||
measurementsStatus: http.StatusOK,
|
||||
signature: "MEUCIQCGA/lSu5qCJgNNvgMaTKJ9rj6vQMecUDaQo3ukaiAfUgIgWoxXRoDKLY9naN7YgxokM7r2fwnyYk3M2WKJJO1g6yo=",
|
||||
signatureStatus: http.StatusOK,
|
||||
publicKey: []byte("-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEu78QgxOOcao6U91CSzEXxrKhvFTt\nJHNy+eX6EMePtDm8CnDF9HSwnTlD0itGJ/XHPQA5YX10fJAqI1y+ehlFMw==\n-----END PUBLIC KEY-----"),
|
||||
wantError: true,
|
||||
},
|
||||
}
|
||||
|
@ -386,7 +393,13 @@ func TestMeasurementsFetchAndVerify(t *testing.T) {
|
|||
})
|
||||
|
||||
m := M{}
|
||||
hash, err := m.FetchAndVerify(context.Background(), client, measurementsURL, signatureURL, tc.publicKey)
|
||||
|
||||
hash, err := m.FetchAndVerify(
|
||||
context.Background(), client,
|
||||
measurementsURL, signatureURL,
|
||||
cosignPublicKey,
|
||||
tc.metadata,
|
||||
)
|
||||
|
||||
if tc.wantError {
|
||||
assert.Error(err)
|
||||
|
|
|
@ -44,6 +44,21 @@ func (p *Provider) UnmarshalJSON(b []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// MarshalYAML marshals the Provider to YAML string.
|
||||
func (p Provider) MarshalYAML() (interface{}, error) {
|
||||
return p.String(), nil
|
||||
}
|
||||
|
||||
// UnmarshalYAML unmarshals the Provider from YAML string.
|
||||
func (p *Provider) UnmarshalYAML(unmarshal func(any) error) error {
|
||||
var s string
|
||||
if err := unmarshal(&s); err != nil {
|
||||
return err
|
||||
}
|
||||
*p = FromString(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
// FromString returns cloud provider from string.
|
||||
func FromString(s string) Provider {
|
||||
s = strings.ToLower(s)
|
||||
|
|
|
@ -7,9 +7,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
package cloudprovider
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func TestMarshalJSON(t *testing.T) {
|
||||
|
@ -43,7 +45,7 @@ func TestMarshalJSON(t *testing.T) {
|
|||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
b, err := tc.input.MarshalJSON()
|
||||
b, err := json.Marshal(tc.input)
|
||||
|
||||
assert.NoError(err)
|
||||
assert.Equal(tc.want, b)
|
||||
|
@ -88,7 +90,95 @@ func TestUnmarshalJSON(t *testing.T) {
|
|||
assert := assert.New(t)
|
||||
|
||||
var p Provider
|
||||
err := p.UnmarshalJSON(tc.input)
|
||||
err := json.Unmarshal(tc.input, &p)
|
||||
|
||||
if tc.wantErr {
|
||||
assert.Error(err)
|
||||
} else {
|
||||
assert.NoError(err)
|
||||
assert.Equal(tc.want, p)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarshalYAML(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
input Provider
|
||||
want []byte
|
||||
}{
|
||||
"unknown": {
|
||||
input: Unknown,
|
||||
want: []byte("Unknown\n"),
|
||||
},
|
||||
"aws": {
|
||||
input: AWS,
|
||||
want: []byte("AWS\n"),
|
||||
},
|
||||
"azure": {
|
||||
input: Azure,
|
||||
want: []byte("Azure\n"),
|
||||
},
|
||||
"gcp": {
|
||||
input: GCP,
|
||||
want: []byte("GCP\n"),
|
||||
},
|
||||
"qemu": {
|
||||
input: QEMU,
|
||||
want: []byte("QEMU\n"),
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
b, err := yaml.Marshal(tc.input)
|
||||
|
||||
assert.NoError(err)
|
||||
assert.Equal(tc.want, b)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalYAML(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
input []byte
|
||||
want Provider
|
||||
wantErr bool
|
||||
}{
|
||||
"empty": {
|
||||
input: []byte("foo: bar\n"),
|
||||
wantErr: true,
|
||||
},
|
||||
"unknown": {
|
||||
input: []byte("unknown\n"),
|
||||
want: Unknown,
|
||||
},
|
||||
"aws": {
|
||||
input: []byte("aws\n"),
|
||||
want: AWS,
|
||||
},
|
||||
"azure": {
|
||||
input: []byte("azure\n"),
|
||||
want: Azure,
|
||||
},
|
||||
"gcp": {
|
||||
input: []byte("gcp\n"),
|
||||
want: GCP,
|
||||
},
|
||||
"qemu": {
|
||||
input: []byte("qemu\n"),
|
||||
want: QEMU,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
var p Provider
|
||||
err := yaml.Unmarshal(tc.input, &p)
|
||||
|
||||
if tc.wantErr {
|
||||
assert.Error(err)
|
||||
|
|
|
@ -73,6 +73,10 @@ type UpgradeConfig struct {
|
|||
// description: |
|
||||
// Measurements of the updated image.
|
||||
Measurements Measurements `yaml:"measurements"`
|
||||
// description: |
|
||||
// temporary field for upgrade migration
|
||||
// TODO(AB#2654): Remove with refactoring upgrade plan command
|
||||
CSP cloudprovider.Provider `yaml:"csp"`
|
||||
}
|
||||
|
||||
// ProviderConfig are cloud-provider specific configuration values used by the CLI.
|
||||
|
|
|
@ -74,7 +74,7 @@ func init() {
|
|||
FieldName: "upgrade",
|
||||
},
|
||||
}
|
||||
UpgradeConfigDoc.Fields = make([]encoder.Doc, 2)
|
||||
UpgradeConfigDoc.Fields = make([]encoder.Doc, 3)
|
||||
UpgradeConfigDoc.Fields[0].Name = "image"
|
||||
UpgradeConfigDoc.Fields[0].Type = "string"
|
||||
UpgradeConfigDoc.Fields[0].Note = ""
|
||||
|
@ -85,6 +85,11 @@ func init() {
|
|||
UpgradeConfigDoc.Fields[1].Note = ""
|
||||
UpgradeConfigDoc.Fields[1].Description = "Measurements of the updated image."
|
||||
UpgradeConfigDoc.Fields[1].Comments[encoder.LineComment] = "Measurements of the updated image."
|
||||
UpgradeConfigDoc.Fields[2].Name = "csp"
|
||||
UpgradeConfigDoc.Fields[2].Type = "Provider"
|
||||
UpgradeConfigDoc.Fields[2].Note = ""
|
||||
UpgradeConfigDoc.Fields[2].Description = "temporary field for upgrade migration\nTODO(AB#2654): Remove with refactoring upgrade plan command"
|
||||
UpgradeConfigDoc.Fields[2].Comments[encoder.LineComment] = "temporary field for upgrade migration"
|
||||
|
||||
ProviderConfigDoc.Type = "ProviderConfig"
|
||||
ProviderConfigDoc.Comments[encoder.LineComment] = "ProviderConfig are cloud-provider specific configuration values used by the CLI."
|
||||
|
|
|
@ -148,18 +148,12 @@ const (
|
|||
// Releases.
|
||||
//
|
||||
|
||||
// S3PublicBucket contains measurements & releases.
|
||||
S3PublicBucket = "https://public-edgeless-constellation.s3.us-east-2.amazonaws.com/"
|
||||
// CosignPublicKey signs all our releases.
|
||||
CosignPublicKey = `-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf8F1hpmwE+YCFXzjGtaQcrL6XZVT
|
||||
JmEe5iSLvG1SyQSAew7WdMKF6o9t8e2TFuCkzlOhhlws2OHWbiFZnFWCFw==
|
||||
-----END PUBLIC KEY-----
|
||||
`
|
||||
|
||||
// ImageVersionRepositoryURL is the base URL of the repository containing
|
||||
// image version information.
|
||||
ImageVersionRepositoryURL = "https://cdn.confidential.cloud"
|
||||
// CDNRepositoryURL is the base URL of the Constellation CDN artifact repository.
|
||||
CDNRepositoryURL = "https://cdn.confidential.cloud"
|
||||
// CDNImagePath is the default path to image references in the CDN repository.
|
||||
CDNImagePath = "constellation/v1/images"
|
||||
// CDNMeasurementsPath is the default path to image measurements in the CDN repository.
|
||||
CDNMeasurementsPath = "constellation/v1/measurements"
|
||||
)
|
||||
|
||||
// VersionInfo is the version of a binary. Left as a separate variable to allow override during build.
|
||||
|
|
16
internal/constants/keys_enterprise.go
Normal file
16
internal/constants/keys_enterprise.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
//go:build enterprise
|
||||
|
||||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package constants
|
||||
|
||||
// CosignPublicKey signs all our releases.
|
||||
const CosignPublicKey = `-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf8F1hpmwE+YCFXzjGtaQcrL6XZVT
|
||||
JmEe5iSLvG1SyQSAew7WdMKF6o9t8e2TFuCkzlOhhlws2OHWbiFZnFWCFw==
|
||||
-----END PUBLIC KEY-----
|
||||
`
|
16
internal/constants/keys_oss.go
Normal file
16
internal/constants/keys_oss.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
//go:build !enterprise
|
||||
|
||||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package constants
|
||||
|
||||
// CosignPublicKey signs all our development builds.
|
||||
const CosignPublicKey = `-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELcPl4Ik+qZuH4K049wksoXK/Os3Z
|
||||
b92PDCpM7FZAINQF88s1TZS/HmRXYk62UJ4eqPduvUnJmXhNikhLbMi6fw==
|
||||
-----END PUBLIC KEY-----
|
||||
`
|
|
@ -125,12 +125,12 @@ func getFromFile(fs *afero.Afero, version string) ([]byte, error) {
|
|||
|
||||
// getFromURL fetches the image lookup table from a URL.
|
||||
func getFromURL(ctx context.Context, client httpc, version string) ([]byte, error) {
|
||||
url, err := url.Parse(constants.ImageVersionRepositoryURL)
|
||||
url, err := url.Parse(constants.CDNRepositoryURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing image version repository URL: %w", err)
|
||||
}
|
||||
versionFilename := path.Base(version) + ".json"
|
||||
url.Path = path.Join("constellation/v1/images", versionFilename)
|
||||
url.Path = path.Join(constants.CDNImagePath, versionFilename)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url.String(), http.NoBody)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue