mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-12 17:34:28 -05:00
c7d12055d1
* config: move AMD root key to global constant * attestation: add SNP based attestation for aws * Always enable SNP, regardless of attestation type. * Make AWSNitroTPM default again There exists a bug in AWS SNP implementation where sometimes a host might not be able to produce valid SNP reports. Since we have to wait for AWS to fix this we are merging SNP attestation as opt-in feature.
318 lines
22 KiB
Go
318 lines
22 KiB
Go
/*
|
|
Copyright (c) Edgeless Systems GmbH
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
*/
|
|
|
|
package snp
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"crypto"
|
|
"crypto/x509"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
|
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
|
"github.com/google/go-tpm-tools/proto/attest"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
const (
|
|
// askPEM is a PEM encoded AMD signing key.
|
|
askPEM = `-----BEGIN CERTIFICATE-----
|
|
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
|
|
0YPk
|
|
-----END CERTIFICATE-----
|
|
`
|
|
|
|
// certTableValid is a valid cert table from an extended SNP report. It includes a valid VLEK.
|
|
certTableValid = "a8074bc2a25a483eaae639c045a0b8a1300000002b05000000000000000000000000000000000000000000000000000030820527308202d6a003020102020100304606092a864886f70d01010a3039a00f300d06096086480165030402020500a11c301a06092a864886f70d010108300d06096086480165030402020500a203020130a30302010130818031143012060355040b0c0b456e67696e656572696e67310b30090603550406130255533114301206035504070c0b53616e746120436c617261310b300906035504080c024341311f301d060355040a0c16416476616e636564204d6963726f20446576696365733117301506035504030c0e5345562d564c454b2d4d696c616e301e170d3233303432303138333031365a170d3234303432303138333031365a307a31143012060355040b0c0b456e67696e656572696e67310b30090603550406130255533114301206035504070c0b53616e746120436c617261310b300906035504080c024341311f301d060355040a0c16416476616e636564204d6963726f20446576696365733111300f06035504030c085345562d564c454b3076301006072a8648ce3d020106052b81040022036200049c1a9fd526e4f0abfb3b70bc53136ee75c2f6ffc38fee47790e4e3f1f13b08009db13f086c94f74b13f89c70b3b9d9cb296f1834114904754a3d844a3d7ddab170800912d7d8407e155b389b580ea39f108ce68b56d3321bdfc3414324a852eea381ec3081e9301006092b060104019c7801010403020100301406092b060104019c780102040716054d696c616e3011060a2b060104019c7801030104030201033011060a2b060104019c7801030204030201003011060a2b060104019c7801030404030201003011060a2b060104019c7801030504030201003011060a2b060104019c7801030604030201003011060a2b060104019c7801030704030201003011060a2b060104019c78010303040302010a3011060a2b060104019c780103080403020173302706092b060104019c780105041a1618434e3d63632d746573742e616d617a6f6e6177732e636f6d304606092a864886f70d01010a3039a00f300d06096086480165030402020500a11c301a06092a864886f70d010108300d06096086480165030402020500a203020130a30302010103820201002f5dc1b2c04023b90ef20ed2d791705407f6cbecb5ba9a2fa4354f1bfb4806e7bff976a5f6a2474c29a8e04a898a6a699dba12b0be88bbb4b713696b1e54c6cd946d17d9890ebd0ec68b3446f9f093149e1b57c4470e70ebdb911bb51d8a6f4678e710ca932fa8ed736a209d44656ffaba4447ee2e42b91a787c6049b94dbc2b31fe57f782c06894c9c2b33406e90f329d022c4ef5ed47061f8956d04c28bf47a79dbdb7f08e35a478589dba5cedbd66d3259ef86aecec528ea4889870f18bf900477146338d42749fbf0a6f245326998766cf1bd8449f434a00151ba3c4aa12812032b7c5bac2ac908cd9b9006749257a634356ca92c2a47edf728979174e9fe096ed65137f069bc8866591537b2ff0f8a6527963dfd83a18ea81ee13a3174ae8c5d200bddc8cd2813430e99048175ffc0b9614364f4d0c1278412f47e8dec380196fc6bee27bc8037bfc642ee4b100f11f6ce259b58fb908db2a3cf64f8460bb837aa0f4caaebb7bed22ea85d9984d2b9ccaca736da4bde2cbb1273e5086f63432206274e87adca8030a6a61640d396d2f301b4e29731da2c2ae3b9899bc515e7d1213e7033baec8da466d7b15489746310df8727b55feda3de413b65a1ab6336312ecb59088955533d304caa118bdd24cfdf1c1b15fcfda42cb4c1d86091e1949a6b79b5e8a65aa9ecdc3a5cd2a69ff1970317c11f074fc85fd630d7b34ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
|
// hashValid is the AK hash of the public key embedded in 'reportValid'.
|
|
hashValid = "44a93ab043ad14ece9bfa97305d95302c9cc6ed95e17efaf7348ed7a7603e1ca89d12758e089d2abcf5a4dd16a99e3cb4cba8f0b8e8cb8eac3e926f1d2b5cfec"
|
|
// reportValid is a valid SNP report.
|
|
reportValid = "02000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000300000000000ace0300000000000000040000000000000044a93ab043ad14ece9bfa97305d95302c9cc6ed95e17efaf7348ed7a7603e1ca89d12758e089d2abcf5a4dd16a99e3cb4cba8f0b8e8cb8eac3e926f1d2b5cfecc2c84b9364fc9f0f54b04534768c860c6e0e386ad98b96e8b98eca46ac8971d05c531ba48373f054c880cfd1f4a0a84e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008c5d6770df734a203cd061a3698e702caed25e7f744dc060eb9dcba0f2e4bdb2ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300000000000a73000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000a7301360100013601000300000000000a73000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b9853dac65f127574c6a578c11885e1887d4c7ae446237d4273715dd8c05cfe4bd49facc1392f2ca7354c8f0d34d65500000000000000000000000000000000000000000000000004013481e9c6a6bb112818aeba3bd178d788dedf62600b8c7892a8d3df4d880265010e7d833201156364a001e62f47b570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
|
// reportInvalid = reportValid[0x2A0]+1. 673. character in the below string. That address is the start of the signature.
|
|
reportInvalid = "02000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000300000000000ace0300000000000000040000000000000044a93ab043ad14ece9bfa97305d95302c9cc6ed95e17efaf7348ed7a7603e1ca89d12758e089d2abcf5a4dd16a99e3cb4cba8f0b8e8cb8eac3e926f1d2b5cfecc2c84b9364fc9f0f54b04534768c860c6e0e386ad98b96e8b98eca46ac8971d05c531ba48373f054c880cfd1f4a0a84e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008c5d6770df734a203cd061a3698e702cbed25e7f744dc060eb9dcba0f2e4bdb2ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300000000000a73000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000a7301360100013601000300000000000a73000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b9853dac65f127574c6a578c11885e1887d4c7ae446237d4273715dd8c05cfe4bd49facc1392f2ca7354c8f0d34d65500000000000000000000000000000000000000000000000004013481e9c6a6bb112818aeba3bd178d788dedf62600b8c7892a8d3df4d880265010e7d833201156364a001e62f47b570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
|
)
|
|
|
|
func TestGetTrustedKey(t *testing.T) {
|
|
validator := &Validator{ark: nil, kdsClient: nil, reportValidator: stubawsValidator{}}
|
|
testCases := map[string]struct {
|
|
akPub []byte
|
|
info []byte
|
|
wantErr bool
|
|
assertCorrectError func(error)
|
|
}{
|
|
"null byte docs": {
|
|
akPub: []byte{0x00, 0x00, 0x00, 0x00},
|
|
info: []byte{0x00, 0x00, 0x00, 0x00},
|
|
wantErr: true,
|
|
assertCorrectError: func(err error) {
|
|
target := &decodeError{}
|
|
assert.ErrorAs(t, err, &target)
|
|
},
|
|
},
|
|
"nil": {
|
|
akPub: nil,
|
|
info: nil,
|
|
wantErr: true,
|
|
assertCorrectError: func(err error) {
|
|
target := &decodeError{}
|
|
assert.ErrorAs(t, err, &target)
|
|
},
|
|
},
|
|
}
|
|
|
|
for name, tc := range testCases {
|
|
t.Run(name, func(t *testing.T) {
|
|
assert := assert.New(t)
|
|
out, err := validator.getTrustedKey(
|
|
context.Background(),
|
|
vtpm.AttestationDocument{
|
|
Attestation: &attest.Attestation{
|
|
AkPub: tc.akPub,
|
|
},
|
|
InstanceInfo: tc.info,
|
|
},
|
|
nil,
|
|
)
|
|
|
|
if tc.wantErr {
|
|
assert.Error(err)
|
|
tc.assertCorrectError(err)
|
|
} else {
|
|
assert.NoError(err)
|
|
}
|
|
|
|
assert.Nil(out)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetASK(t *testing.T) {
|
|
testCases := map[string]struct {
|
|
client askGetter
|
|
wantErr bool
|
|
}{
|
|
"success": {
|
|
client: kdsClient{stubClient{ask: []byte(askPEM)}},
|
|
},
|
|
"no cert": {
|
|
client: kdsClient{stubClient{ask: []byte{}}},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for name, tc := range testCases {
|
|
t.Run(name, func(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
ask, err := tc.client.getASK(context.Background())
|
|
|
|
if tc.wantErr {
|
|
assert.Error(err)
|
|
} else {
|
|
assert.NoError(err)
|
|
assert.NotNil(ask)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestValidateSNPReport has to setup the following to run ValidateSNPReport:
|
|
// - parse ARK certificate from constants.go.
|
|
// - parse cached ASK certificate.
|
|
// - parse cached SNP report.
|
|
// - parse cached AK hash. Hash and SNP report have to match.
|
|
// - parse cache VLEK cert.
|
|
func TestValidateSNPReport(t *testing.T) {
|
|
ark, err := loadARK()
|
|
require.NoError(t, err)
|
|
|
|
testCases := map[string]struct {
|
|
ak string
|
|
client kdsClient
|
|
report string
|
|
wantErr bool
|
|
}{
|
|
"success": {
|
|
ak: hashValid,
|
|
client: kdsClient{stubClient{ask: []byte(askPEM)}},
|
|
report: reportValid,
|
|
},
|
|
"fail": {
|
|
ak: hashValid,
|
|
client: kdsClient{stubClient{ask: []byte(askPEM)}},
|
|
report: reportInvalid,
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for name, tc := range testCases {
|
|
t.Run(name, func(t *testing.T) {
|
|
assert := assert.New(t)
|
|
require := require.New(t)
|
|
|
|
info, err := loadInstanceInfo(tc.report, certTableValid)
|
|
require.NoError(err)
|
|
|
|
hash, err := hex.DecodeString(tc.ak)
|
|
require.NoError(err)
|
|
|
|
v := awsValidator{}
|
|
err = v.validate(context.Background(), vtpm.AttestationDocument{InstanceInfo: info}, tc.client, ark, [64]byte(hash))
|
|
if tc.wantErr {
|
|
assert.Error(err)
|
|
} else {
|
|
assert.NoError(err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSha512sum(t *testing.T) {
|
|
testCases := map[string]struct {
|
|
key string
|
|
hash string
|
|
match bool
|
|
}{
|
|
"success": {
|
|
// Generated using: rsa.GenerateKey(rand.Reader, 1024).
|
|
key: "30819f300d06092a864886f70d010101050003818d0030818902818100d4b2f072a32fa98456eb7f5938e2ff361fb64d698ea91e003d34bfc5374b814c16ba9ae3ec392ef6d48cf79b63067e338aa941219a7bcdf18aa43cd38bbe5567504838a3b1dca482035458853c5a171709dfae9df551815010bdfbc6df733cde84c4f7a5b0591d9cda9db087fb411ee3e2a4f19ad50c8331712ecdc5dd7ce34b0203010001",
|
|
hash: "2d6fe5ec59d7240b8a4c27c2ff27ba1071105fa50d45543768fcbabf9ee3cb8f8fa0afa51e08e053af30f6d11066ebfd47e75bda5ccc085c115d7e1896f3c62f",
|
|
match: true,
|
|
},
|
|
"mismatching hash": {
|
|
key: "30819f300d06092a864886f70d010101050003818d0030818902818100d4b2f072a32fa98456eb7f5938e2ff361fb64d698ea91e003d34bfc5374b814c16ba9ae3ec392ef6d48cf79b63067e338aa941219a7bcdf18aa43cd38bbe5567504838a3b1dca482035458853c5a171709dfae9df551815010bdfbc6df733cde84c4f7a5b0591d9cda9db087fb411ee3e2a4f19ad50c8331712ecdc5dd7ce34b0203010001",
|
|
hash: "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
match: false,
|
|
},
|
|
}
|
|
|
|
for name, tc := range testCases {
|
|
t.Run(name, func(t *testing.T) {
|
|
assert := assert.New(t)
|
|
require := require.New(t)
|
|
|
|
newKey, err := loadKeyFromHex(tc.key)
|
|
require.NoError(err)
|
|
|
|
// Function under test:
|
|
hash, err := sha512sum(newKey)
|
|
assert.NoError(err)
|
|
|
|
expected, err := hex.DecodeString(tc.hash)
|
|
require.NoError(err)
|
|
|
|
if tc.match {
|
|
assert.True(bytes.Equal(expected, hash[:]), fmt.Sprintf("expected hash %x, got %x", expected, hash))
|
|
} else {
|
|
assert.False(bytes.Equal(expected, hash[:]), fmt.Sprintf("expected mismatching hashes, got %x", hash))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func loadKeyFromHex(key string) (crypto.PublicKey, error) {
|
|
decoded, err := hex.DecodeString(key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return x509.ParsePKIXPublicKey(decoded)
|
|
}
|
|
|
|
// loadCachedCertChain loads a valid ARK and ASK from the testdata folder.
|
|
func loadARK() (*x509.Certificate, error) {
|
|
// Replacement is needed as the newline chars are not interpreted due to the backticks. Backticks are required for config formatting.
|
|
tmp := strings.ReplaceAll(constants.AMDRootKey, "\\n", "\n")
|
|
block, _ := pem.Decode([]byte(tmp))
|
|
ark, err := x509.ParseCertificate(block.Bytes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return ark, nil
|
|
}
|
|
|
|
// loadInstanceInfo loads a valid SNP report and VLEK cert from the testdata folder.
|
|
func loadInstanceInfo(report, certs string) ([]byte, error) {
|
|
reportDec, err := hex.DecodeString(report)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
certsDec, err := hex.DecodeString(certs)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
info := instanceInfo{Report: reportDec, Certs: certsDec}
|
|
infoRaw, err := json.Marshal(info)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return infoRaw, nil
|
|
}
|
|
|
|
type stubClient struct {
|
|
ask []byte
|
|
}
|
|
|
|
func (s stubClient) Do(*http.Request) (*http.Response, error) {
|
|
return &http.Response{
|
|
Body: io.NopCloser(bytes.NewReader(s.ask)),
|
|
}, nil
|
|
}
|
|
|
|
type stubawsValidator struct{}
|
|
|
|
func (stubawsValidator) validate(context.Context, vtpm.AttestationDocument, askGetter, *x509.Certificate, [64]byte) error {
|
|
return nil
|
|
}
|