mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-08-06 22:14:24 -04:00
snp: ensure we never use ARK supplied by Issuer (#3025)
This commit is contained in:
parent
d9dec5caa6
commit
ec87c2ee06
3 changed files with 33 additions and 35 deletions
|
@ -8,11 +8,11 @@ go_library(
|
||||||
visibility = ["//:__subpackages__"],
|
visibility = ["//:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
"//internal/attestation",
|
"//internal/attestation",
|
||||||
"//internal/constants",
|
|
||||||
"@com_github_google_go_sev_guest//abi",
|
"@com_github_google_go_sev_guest//abi",
|
||||||
"@com_github_google_go_sev_guest//kds",
|
"@com_github_google_go_sev_guest//kds",
|
||||||
"@com_github_google_go_sev_guest//proto/sevsnp",
|
"@com_github_google_go_sev_guest//proto/sevsnp",
|
||||||
"@com_github_google_go_sev_guest//verify/trust",
|
"@com_github_google_go_sev_guest//verify/trust",
|
||||||
|
"@com_github_google_go_tpm_tools//proto/attest",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,11 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation"
|
"github.com/edgelesssys/constellation/v2/internal/attestation"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
|
||||||
"github.com/google/go-sev-guest/abi"
|
"github.com/google/go-sev-guest/abi"
|
||||||
"github.com/google/go-sev-guest/kds"
|
"github.com/google/go-sev-guest/kds"
|
||||||
spb "github.com/google/go-sev-guest/proto/sevsnp"
|
spb "github.com/google/go-sev-guest/proto/sevsnp"
|
||||||
"github.com/google/go-sev-guest/verify/trust"
|
"github.com/google/go-sev-guest/verify/trust"
|
||||||
|
"github.com/google/go-tpm-tools/proto/attest"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Product returns the SEV product info currently supported by Constellation's SNP attestation.
|
// Product returns the SEV product info currently supported by Constellation's SNP attestation.
|
||||||
|
@ -39,6 +39,7 @@ type InstanceInfo struct {
|
||||||
// AttestationReport is the attestation report from the vTPM (NVRAM) of the CVM.
|
// AttestationReport is the attestation report from the vTPM (NVRAM) of the CVM.
|
||||||
AttestationReport []byte
|
AttestationReport []byte
|
||||||
Azure *AzureInstanceInfo
|
Azure *AzureInstanceInfo
|
||||||
|
GCP *attest.GCEInstanceInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// AzureInstanceInfo contains Azure specific information related to SNP attestation.
|
// AzureInstanceInfo contains Azure specific information related to SNP attestation.
|
||||||
|
@ -95,7 +96,7 @@ func (a *InstanceInfo) addReportSigner(att *spb.Attestation, report *spb.Report,
|
||||||
|
|
||||||
// AttestationWithCerts returns a formatted version of the attestation report and its certificates from the instanceInfo.
|
// AttestationWithCerts returns a formatted version of the attestation report and its certificates from the instanceInfo.
|
||||||
// Certificates are retrieved in the following precedence:
|
// Certificates are retrieved in the following precedence:
|
||||||
// 1. ASK or ARK from issuer. On Azure: THIM. One AWS: not prefilled.
|
// 1. ASK from issuer. On Azure: THIM. One AWS: not prefilled. (Go to option 2) On GCP: prefilled.
|
||||||
// 2. ASK or ARK from fallbackCerts.
|
// 2. ASK or ARK from fallbackCerts.
|
||||||
// 3. ASK or ARK from AMD KDS.
|
// 3. ASK or ARK from AMD KDS.
|
||||||
func (a *InstanceInfo) AttestationWithCerts(getter trust.HTTPSGetter,
|
func (a *InstanceInfo) AttestationWithCerts(getter trust.HTTPSGetter,
|
||||||
|
@ -120,30 +121,28 @@ func (a *InstanceInfo) AttestationWithCerts(getter trust.HTTPSGetter,
|
||||||
return nil, fmt.Errorf("adding report signer: %w", err)
|
return nil, fmt.Errorf("adding report signer: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the certificate chain from THIM is present, parse it and format it.
|
// If a certificate chain was pre-fetched by the Issuer, parse it and format it.
|
||||||
ask, ark, err := a.ParseCertChain()
|
// Make sure to only use the ask, since using an ark from the Issuer would invalidate security guarantees.
|
||||||
|
ask, _, err := a.ParseCertChain()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warn(fmt.Sprintf("Error parsing certificate chain: %v", err))
|
logger.Warn(fmt.Sprintf("Error parsing certificate chain: %v", err))
|
||||||
}
|
}
|
||||||
if ask != nil {
|
if ask != nil {
|
||||||
logger.Info("Using ASK certificate from Azure THIM")
|
logger.Info("Using ASK certificate from pre-fetched certificate chain")
|
||||||
att.CertificateChain.AskCert = ask.Raw
|
att.CertificateChain.AskCert = ask.Raw
|
||||||
}
|
}
|
||||||
if ark != nil {
|
|
||||||
logger.Info("Using ARK certificate from Azure THIM")
|
|
||||||
att.CertificateChain.ArkCert = ark.Raw
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a cached ASK or an ARK from the Constellation config is present, use it.
|
// If a cached ASK or an ARK from the Constellation config is present, use it.
|
||||||
if att.CertificateChain.AskCert == nil && fallbackCerts.ask != nil {
|
if att.CertificateChain.AskCert == nil && fallbackCerts.ask != nil {
|
||||||
logger.Info("Using cached ASK certificate")
|
logger.Info("Using cached ASK certificate")
|
||||||
att.CertificateChain.AskCert = fallbackCerts.ask.Raw
|
att.CertificateChain.AskCert = fallbackCerts.ask.Raw
|
||||||
}
|
}
|
||||||
if att.CertificateChain.ArkCert == nil && fallbackCerts.ark != nil {
|
if fallbackCerts.ark != nil {
|
||||||
logger.Info(fmt.Sprintf("Using ARK certificate from %s", constants.ConfigFilename))
|
logger.Info("Using cached ARK certificate")
|
||||||
att.CertificateChain.ArkCert = fallbackCerts.ark.Raw
|
att.CertificateChain.ArkCert = fallbackCerts.ark.Raw
|
||||||
}
|
}
|
||||||
// Otherwise, retrieve it from AMD KDS.
|
|
||||||
|
// Otherwise, retrieve missing certificates from AMD KDS.
|
||||||
if att.CertificateChain.AskCert == nil || att.CertificateChain.ArkCert == nil {
|
if att.CertificateChain.AskCert == nil || att.CertificateChain.ArkCert == nil {
|
||||||
logger.Info(fmt.Sprintf(
|
logger.Info(fmt.Sprintf(
|
||||||
"Certificate chain not fully present (ARK present: %t, ASK present: %t), falling back to retrieving it from AMD KDS",
|
"Certificate chain not fully present (ARK present: %t, ASK present: %t), falling back to retrieving it from AMD KDS",
|
||||||
|
|
|
@ -149,12 +149,24 @@ func TestAttestationWithCerts(t *testing.T) {
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
"success": {
|
"success": {
|
||||||
|
report: defaultReport,
|
||||||
|
idkeydigest: "57e229e0ffe5fa92d0faddff6cae0e61c926fc9ef9afd20a8b8cfcf7129db9338cbe5bf3f6987733a2bf65d06dc38fc1",
|
||||||
|
reportSigner: testdata.AzureThimVCEK,
|
||||||
|
certChain: testdata.CertChain,
|
||||||
|
fallbackCerts: CertificateChain{ark: testdataArk},
|
||||||
|
expectedArk: testdataArk,
|
||||||
|
expectedAsk: testdataAsk,
|
||||||
|
getter: newStubHTTPSGetter(&urlResponseMatcher{}, nil),
|
||||||
|
},
|
||||||
|
"ark only in pre-fetched cert-chain": {
|
||||||
report: defaultReport,
|
report: defaultReport,
|
||||||
idkeydigest: "57e229e0ffe5fa92d0faddff6cae0e61c926fc9ef9afd20a8b8cfcf7129db9338cbe5bf3f6987733a2bf65d06dc38fc1",
|
idkeydigest: "57e229e0ffe5fa92d0faddff6cae0e61c926fc9ef9afd20a8b8cfcf7129db9338cbe5bf3f6987733a2bf65d06dc38fc1",
|
||||||
reportSigner: testdata.AzureThimVCEK,
|
reportSigner: testdata.AzureThimVCEK,
|
||||||
certChain: testdata.CertChain,
|
certChain: testdata.CertChain,
|
||||||
expectedArk: testdataArk,
|
expectedArk: testdataArk,
|
||||||
expectedAsk: testdataAsk,
|
expectedAsk: testdataAsk,
|
||||||
|
getter: newStubHTTPSGetter(nil, assert.AnError),
|
||||||
|
wantErr: true,
|
||||||
},
|
},
|
||||||
"vlek success": {
|
"vlek success": {
|
||||||
report: vlekReport,
|
report: vlekReport,
|
||||||
|
@ -173,9 +185,10 @@ func TestAttestationWithCerts(t *testing.T) {
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
"retrieve vcek": {
|
"retrieve vcek": {
|
||||||
report: defaultReport,
|
report: defaultReport,
|
||||||
idkeydigest: "57e229e0ffe5fa92d0faddff6cae0e61c926fc9ef9afd20a8b8cfcf7129db9338cbe5bf3f6987733a2bf65d06dc38fc1",
|
idkeydigest: "57e229e0ffe5fa92d0faddff6cae0e61c926fc9ef9afd20a8b8cfcf7129db9338cbe5bf3f6987733a2bf65d06dc38fc1",
|
||||||
certChain: testdata.CertChain,
|
certChain: testdata.CertChain,
|
||||||
|
fallbackCerts: CertificateChain{ark: testdataArk},
|
||||||
getter: newStubHTTPSGetter(
|
getter: newStubHTTPSGetter(
|
||||||
&urlResponseMatcher{
|
&urlResponseMatcher{
|
||||||
vcekResponse: testdata.AmdKdsVCEK,
|
vcekResponse: testdata.AmdKdsVCEK,
|
||||||
|
@ -205,25 +218,9 @@ func TestAttestationWithCerts(t *testing.T) {
|
||||||
idkeydigest: "57e229e0ffe5fa92d0faddff6cae0e61c926fc9ef9afd20a8b8cfcf7129db9338cbe5bf3f6987733a2bf65d06dc38fc1",
|
idkeydigest: "57e229e0ffe5fa92d0faddff6cae0e61c926fc9ef9afd20a8b8cfcf7129db9338cbe5bf3f6987733a2bf65d06dc38fc1",
|
||||||
reportSigner: testdata.AzureThimVCEK,
|
reportSigner: testdata.AzureThimVCEK,
|
||||||
fallbackCerts: NewCertificateChain(exampleCert, exampleCert),
|
fallbackCerts: NewCertificateChain(exampleCert, exampleCert),
|
||||||
getter: newStubHTTPSGetter(
|
getter: newStubHTTPSGetter(&urlResponseMatcher{}, nil),
|
||||||
&urlResponseMatcher{},
|
expectedArk: exampleCert,
|
||||||
nil,
|
expectedAsk: exampleCert,
|
||||||
),
|
|
||||||
expectedArk: exampleCert,
|
|
||||||
expectedAsk: exampleCert,
|
|
||||||
},
|
|
||||||
"use certchain with fallback certs": {
|
|
||||||
report: defaultReport,
|
|
||||||
idkeydigest: "57e229e0ffe5fa92d0faddff6cae0e61c926fc9ef9afd20a8b8cfcf7129db9338cbe5bf3f6987733a2bf65d06dc38fc1",
|
|
||||||
certChain: testdata.CertChain,
|
|
||||||
reportSigner: testdata.AzureThimVCEK,
|
|
||||||
fallbackCerts: NewCertificateChain(&x509.Certificate{}, &x509.Certificate{}),
|
|
||||||
getter: newStubHTTPSGetter(
|
|
||||||
&urlResponseMatcher{},
|
|
||||||
nil,
|
|
||||||
),
|
|
||||||
expectedArk: testdataArk,
|
|
||||||
expectedAsk: testdataAsk,
|
|
||||||
},
|
},
|
||||||
"retrieve vcek and certchain": {
|
"retrieve vcek and certchain": {
|
||||||
report: defaultReport,
|
report: defaultReport,
|
||||||
|
@ -242,10 +239,12 @@ func TestAttestationWithCerts(t *testing.T) {
|
||||||
},
|
},
|
||||||
"report too short": {
|
"report too short": {
|
||||||
report: defaultReport[:len(defaultReport)-100],
|
report: defaultReport[:len(defaultReport)-100],
|
||||||
|
getter: newStubHTTPSGetter(nil, assert.AnError),
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
"corrupted report": {
|
"corrupted report": {
|
||||||
report: defaultReport[10 : len(defaultReport)-10],
|
report: defaultReport[10 : len(defaultReport)-10],
|
||||||
|
getter: newStubHTTPSGetter(nil, assert.AnError),
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
"certificate fetch error": {
|
"certificate fetch error": {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue