intenal: add logging to attestation issuer (#1264)

Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
Daniel Weiße 2023-02-28 16:34:18 +01:00 committed by GitHub
parent af8c6e70ad
commit b3486fc32b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 63 additions and 28 deletions

View File

@ -82,7 +82,7 @@ func main() {
log.With(zap.Error(err)).Fatalf("Failed to get selected PCRs")
}
issuer = aws.NewIssuer()
issuer = aws.NewIssuer(log)
metadata, err := awscloud.New(ctx)
if err != nil {
@ -108,7 +108,7 @@ func main() {
log.With(zap.Error(err)).Fatalf("Failed to get selected PCRs")
}
issuer = gcp.NewIssuer()
issuer = gcp.NewIssuer(log)
metadata, err := gcpcloud.New(ctx)
if err != nil {
@ -137,10 +137,10 @@ func main() {
}
if _, err := snp.GetIDKeyDigest(vtpm.OpenVTPM); err == nil {
issuer = snp.NewIssuer()
issuer = snp.NewIssuer(log)
} else {
// assume we are running in a trusted-launch VM
issuer = trustedlaunch.NewIssuer()
issuer = trustedlaunch.NewIssuer(log)
}
metadata, err := azurecloud.New(ctx)
@ -166,7 +166,7 @@ func main() {
log.With(zap.Error(err)).Fatalf("Failed to get selected PCRs")
}
issuer = qemu.NewIssuer()
issuer = qemu.NewIssuer(log)
cloudLogger = qemucloud.NewLogger()
metadata := qemucloud.New()

View File

@ -79,7 +79,7 @@ func main() {
log.With(zap.Error(err)).Fatalf("Failed to set up AWS metadata API")
}
issuer = aws.NewIssuer()
issuer = aws.NewIssuer(log)
case cloudprovider.Azure:
diskPath, err = filepath.EvalSymlinks(azureStateDiskPath)
@ -92,7 +92,7 @@ func main() {
log.With(zap.Error).Fatalf("Failed to set up Azure metadata API")
}
issuer = azure.NewIssuer()
issuer = azure.NewIssuer(log)
case cloudprovider.GCP:
diskPath, err = filepath.EvalSymlinks(gcpStateDiskPath)
@ -100,7 +100,7 @@ func main() {
_ = exportPCRs()
log.With(zap.Error(err)).Fatalf("Unable to resolve GCP state disk path")
}
issuer = gcp.NewIssuer()
issuer = gcp.NewIssuer(log)
gcpMeta, err := gcpcloud.New(context.Background())
if err != nil {
log.With(zap.Error).Fatalf("Failed to create GCP client")
@ -116,7 +116,7 @@ func main() {
case cloudprovider.QEMU:
diskPath = qemuStateDiskPath
issuer = qemu.NewIssuer()
issuer = qemu.NewIssuer(log)
metadataAPI = qemucloud.New()
_ = exportPCRs()

View File

@ -28,12 +28,13 @@ type Issuer struct {
}
// NewIssuer creates a new OpenVTPM based issuer for AWS.
func NewIssuer() *Issuer {
func NewIssuer(log vtpm.AttestationLogger) *Issuer {
return &Issuer{
Issuer: vtpm.NewIssuer(
vtpm.OpenVTPM,
getAttestationKey,
getInstanceInfo(imds.New(imds.Options{})),
log,
),
}
}

View File

@ -28,9 +28,9 @@ import (
// NewIssuer returns an SNP issuer if it can successfully read the idkeydigest from the TPM.
// Otherwise returns a Trusted Launch issuer.
func NewIssuer() atls.Issuer {
func NewIssuer(log vtpm.AttestationLogger) atls.Issuer {
if _, err := snp.GetIDKeyDigest(vtpm.OpenVTPM); err == nil {
return snp.NewIssuer()
return snp.NewIssuer(log)
}
return trustedlaunch.NewIssuer()
return trustedlaunch.NewIssuer(log)
}

View File

@ -56,7 +56,7 @@ type Issuer struct {
}
// NewIssuer initializes a new Azure Issuer.
func NewIssuer() *Issuer {
func NewIssuer(log vtpm.AttestationLogger) *Issuer {
imdsAPI := imdsClient{
client: &http.Client{Transport: &http.Transport{Proxy: nil}},
}
@ -66,6 +66,7 @@ func NewIssuer() *Issuer {
vtpm.OpenVTPM,
getAttestationKey,
getInstanceInfo(&tpmReport{}, imdsAPI),
log,
),
}
}

View File

@ -35,7 +35,7 @@ type Issuer struct {
}
// NewIssuer initializes a new Azure Issuer.
func NewIssuer() *Issuer {
func NewIssuer(log vtpm.AttestationLogger) *Issuer {
i := &Issuer{
hClient: &http.Client{},
}
@ -43,6 +43,7 @@ func NewIssuer() *Issuer {
vtpm.OpenVTPM,
getAttestationKey,
i.getAttestationCert,
log,
)
return i
}

View File

@ -20,6 +20,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/simulator"
"github.com/edgelesssys/constellation/v2/internal/crypto"
"github.com/edgelesssys/constellation/v2/internal/logger"
tpmclient "github.com/google/go-tpm-tools/client"
"github.com/google/go-tpm/tpm2"
"github.com/stretchr/testify/assert"
@ -179,7 +180,7 @@ func TestGetAttestationCert(t *testing.T) {
))
require.NoError(tpm2.NVWrite(tpm, tpm2.HandleOwner, tpmAkCertIdx, "", akCert, 0))
issuer := NewIssuer()
issuer := NewIssuer(logger.NewTest(t))
issuer.hClient = newTestClient(tc.crlServer)
certs, err := issuer.getAttestationCert(tpm)

View File

@ -25,12 +25,13 @@ type Issuer struct {
}
// NewIssuer initializes a new GCP Issuer.
func NewIssuer() *Issuer {
func NewIssuer(log vtpm.AttestationLogger) *Issuer {
return &Issuer{
Issuer: vtpm.NewIssuer(
vtpm.OpenVTPM,
tpmclient.GceAttestationKeyRSA,
getGCEInstanceInfo(metadataClient{}),
log,
),
}
}

View File

@ -21,12 +21,13 @@ type Issuer struct {
}
// NewIssuer initializes a new QEMU Issuer.
func NewIssuer() *Issuer {
func NewIssuer(log vtpm.AttestationLogger) *Issuer {
return &Issuer{
Issuer: vtpm.NewIssuer(
vtpm.OpenVTPM,
tpmclient.AttestationKeyRSA,
func(tpm io.ReadWriteCloser) ([]byte, error) { return nil, nil },
log,
),
}
}

View File

@ -85,19 +85,34 @@ type Issuer struct {
openTPM TPMOpenFunc
getAttestationKey GetTPMAttestationKey
getInstanceInfo GetInstanceInfo
log AttestationLogger
}
// NewIssuer returns a new Issuer.
func NewIssuer(openTPM TPMOpenFunc, getAttestationKey GetTPMAttestationKey, getInstanceInfo GetInstanceInfo) *Issuer {
func NewIssuer(
openTPM TPMOpenFunc, getAttestationKey GetTPMAttestationKey,
getInstanceInfo GetInstanceInfo, log AttestationLogger,
) *Issuer {
if log == nil {
log = &nopAttestationLogger{}
}
return &Issuer{
openTPM: openTPM,
getAttestationKey: getAttestationKey,
getInstanceInfo: getInstanceInfo,
log: log,
}
}
// Issue generates an attestation document using a TPM.
func (i *Issuer) Issue(userData []byte, nonce []byte) ([]byte, error) {
func (i *Issuer) Issue(userData []byte, nonce []byte) (res []byte, err error) {
i.log.Infof("Issuing attestation statement")
defer func() {
if err != nil {
i.log.Warnf("Failed to issue attestation statement: %s", err)
}
}()
tpm, err := i.openTPM()
if err != nil {
return nil, fmt.Errorf("opening TPM: %w", err)
@ -113,7 +128,7 @@ func (i *Issuer) Issue(userData []byte, nonce []byte) ([]byte, error) {
// Create an attestation using the loaded key
extraData := makeExtraData(userData, nonce)
attestation, err := aK.Attest(tpmClient.AttestOpts{Nonce: extraData})
tpmAttestation, err := aK.Attest(tpmClient.AttestOpts{Nonce: extraData})
if err != nil {
return nil, fmt.Errorf("creating attestation: %w", err)
}
@ -125,11 +140,18 @@ func (i *Issuer) Issue(userData []byte, nonce []byte) ([]byte, error) {
}
attDoc := AttestationDocument{
Attestation: attestation,
Attestation: tpmAttestation,
InstanceInfo: instanceInfo,
UserData: userData,
}
return json.Marshal(attDoc)
rawAttDoc, err := json.Marshal(attDoc)
if err != nil {
return nil, fmt.Errorf("marshaling attestation document: %w", err)
}
i.log.Infof("Successfully issued attestation statement")
return rawAttDoc, nil
}
// Validator handles validation of TPM based attestation.

View File

@ -16,6 +16,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
tpmsim "github.com/edgelesssys/constellation/v2/internal/attestation/simulator"
"github.com/edgelesssys/constellation/v2/internal/logger"
tpmclient "github.com/google/go-tpm-tools/client"
"github.com/google/go-tpm-tools/proto/attest"
"github.com/google/go-tpm-tools/proto/tpm"
@ -75,7 +76,7 @@ func TestValidate(t *testing.T) {
tpmOpen, tpmCloser := tpmsim.NewSimulatedTPMOpenFunc()
defer tpmCloser.Close()
issuer := NewIssuer(tpmOpen, tpmclient.AttestationKeyRSA, fakeGetInstanceInfo)
issuer := NewIssuer(tpmOpen, tpmclient.AttestationKeyRSA, fakeGetInstanceInfo, logger.NewTest(t))
validator := NewValidator(testExpectedPCRs, fakeGetTrustedKey, fakeValidateCVM, nil)
nonce := []byte{1, 2, 3, 4}
@ -266,6 +267,7 @@ func TestFailIssuer(t *testing.T) {
},
tpmclient.AttestationKeyRSA,
fakeGetInstanceInfo,
nil,
),
userData: []byte("Constellation"),
nonce: []byte{1, 2, 3, 4},
@ -277,6 +279,7 @@ func TestFailIssuer(t *testing.T) {
return nil, errors.New("failure")
},
fakeGetInstanceInfo,
nil,
),
userData: []byte("Constellation"),
nonce: []byte{1, 2, 3, 4},
@ -288,6 +291,7 @@ func TestFailIssuer(t *testing.T) {
return &tpmclient.Key{}, nil
},
fakeGetInstanceInfo,
nil,
),
userData: []byte("Constellation"),
nonce: []byte{1, 2, 3, 4},
@ -297,6 +301,7 @@ func TestFailIssuer(t *testing.T) {
newSimTPMWithEventLog,
tpmclient.AttestationKeyRSA,
func(io.ReadWriteCloser) ([]byte, error) { return nil, errors.New("failure") },
nil,
),
userData: []byte("Constellation"),
nonce: []byte{1, 2, 3, 4},
@ -307,6 +312,8 @@ func TestFailIssuer(t *testing.T) {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
tc.issuer.log = logger.NewTest(t)
_, err := tc.issuer.Issue(tc.userData, tc.nonce)
assert.Error(err)
})

View File

@ -35,13 +35,13 @@ func main() {
var issuer server.AttestationIssuer
switch cloudprovider.FromString(*provider) {
case cloudprovider.AWS:
issuer = aws.NewIssuer()
issuer = aws.NewIssuer(log)
case cloudprovider.GCP:
issuer = gcp.NewIssuer()
issuer = gcp.NewIssuer(log)
case cloudprovider.Azure:
issuer = azure.NewIssuer()
issuer = azure.NewIssuer(log)
case cloudprovider.QEMU:
issuer = qemu.NewIssuer()
issuer = qemu.NewIssuer(log)
default:
log.With(zap.String("cloudProvider", *provider)).Fatalf("Unknown cloud provider")
}