Skip to content

Commit

Permalink
Merge pull request #122 from deeglaze/fakextra
Browse files Browse the repository at this point in the history
Add fake signer support for extra certs
  • Loading branch information
deeglaze authored Mar 15, 2024
2 parents 08d92a6 + b35cd59 commit 606477d
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 21 deletions.
58 changes: 37 additions & 21 deletions testing/fake_certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,13 @@ func GetProduct(t testing.TB) *spb.SevProduct {
// AmdSigner encapsulates a key and certificate chain following the format of AMD-SP's VCEK for
// signing attestation reports.
type AmdSigner struct {
Ark *x509.Certificate
Ask *x509.Certificate
Asvk *x509.Certificate
Vcek *x509.Certificate
Vlek *x509.Certificate
Keys *AmdKeys
Ark *x509.Certificate
Ask *x509.Certificate
Asvk *x509.Certificate
Vcek *x509.Certificate
Vlek *x509.Certificate
Extras map[string][]byte
Keys *AmdKeys
// This identity does not match AMD's notion of an HWID. It is purely to combine expectations of
// report data -> KDS URL construction for the fake KDS implementation.
HWID [abi.ChipIDSize]byte
Expand Down Expand Up @@ -189,11 +190,12 @@ type AmdSignerBuilder struct {
HWID [abi.ChipIDSize]byte
TCB kds.TCBVersion
// Intermediate built certificates
Ark *x509.Certificate
Ask *x509.Certificate
Asvk *x509.Certificate
Vcek *x509.Certificate
Vlek *x509.Certificate
Ark *x509.Certificate
Ask *x509.Certificate
Asvk *x509.Certificate
Vcek *x509.Certificate
Vlek *x509.Certificate
Extras map[string][]byte
}

func (b *AmdSignerBuilder) productName() string {
Expand Down Expand Up @@ -529,13 +531,14 @@ func (b *AmdSignerBuilder) TestOnlyCertChain() (*AmdSigner, error) {
}
}
s := &AmdSigner{
Ark: b.Ark,
Ask: b.Ask,
Asvk: b.Asvk,
Vcek: b.Vcek,
Vlek: b.Vlek,
Keys: b.Keys,
TCB: b.TCB,
Ark: b.Ark,
Ask: b.Ask,
Asvk: b.Asvk,
Vcek: b.Vcek,
Vlek: b.Vlek,
Keys: b.Keys,
Extras: b.Extras,
TCB: b.TCB,
}
copy(s.HWID[:], b.HWID[:])
return s, nil
Expand Down Expand Up @@ -563,7 +566,9 @@ func DefaultTestOnlyCertChain(productName string, creationTime time.Time) (*AmdS
// CertTableBytes outputs the certificates in AMD's ABI format.
func (s *AmdSigner) CertTableBytes() ([]byte, error) {
// Calculate the output size and the offset at which to copy each certificate.
headers := make([]abi.CertTableHeaderEntry, 6) // ARK, ASK, VCEK, VLEK, ASVK, NULL
const baseEntries = 6 // ARK, ASK, VCEK, VLEK, ASVK, NULL
entries := baseEntries + len(s.Extras)
headers := make([]abi.CertTableHeaderEntry, entries)
headers[0].GUID = uuid.Parse(abi.ArkGUID)
headers[0].Offset = uint32(len(headers) * abi.CertTableEntrySize)
headers[0].Length = uint32(len(s.Ark.Raw))
Expand All @@ -584,9 +589,20 @@ func (s *AmdSigner) CertTableBytes() ([]byte, error) {
headers[4].Offset = headers[3].Offset + headers[3].Length
headers[4].Length = uint32(len(s.Asvk.Raw))

index := 4
blobs := [][]byte{s.Ark.Raw, s.Ask.Raw, s.Vcek.Raw, s.Vlek.Raw, s.Asvk.Raw}
for guid, data := range s.Extras {
prior := index
index++
headers[index].GUID = uuid.Parse(guid)
headers[index].Offset = headers[prior].Offset + headers[prior].Length
headers[index].Length = uint32(len(data))
blobs = append(blobs, data)
}

// Write out the headers and the certificates at the appropriate offsets.
result := make([]byte, headers[4].Offset+headers[4].Length)
for i, cert := range [][]byte{s.Ark.Raw, s.Ask.Raw, s.Vcek.Raw, s.Vlek.Raw, s.Asvk.Raw} {
result := make([]byte, headers[index].Offset+headers[index].Length)
for i, cert := range blobs {
if err := (&headers[i]).Write(result[i*abi.CertTableEntrySize:]); err != nil {
return nil, err
}
Expand Down
36 changes: 36 additions & 0 deletions testing/fake_certs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package testing

import (
"bytes"
"crypto/x509"
"testing"
"time"
Expand Down Expand Up @@ -85,3 +86,38 @@ func TestCertificatesParse(t *testing.T) {
t.Errorf("could not parse generated VCEK extensions: %v", err)
}
}

func TestCertificatesExtras(t *testing.T) {
b := &AmdSignerBuilder{
Extras: map[string][]byte{abi.ExtraPlatformInfoGUID: []byte("test")},
}
s, err := b.TestOnlyCertChain()
if err != nil {
t.Fatal(err)
}
certBytes, err := s.CertTableBytes()
if err != nil {
t.Fatal(err)
}
entries, err := abi.ParseSnpCertTableHeader(certBytes)
if err != nil {
t.Fatal(err)
}
var hasXtra bool
if len(entries) != 6 {
t.Errorf("ParseSnpCertTableHeader(_) returned %d entries, want 6", len(entries))
}
for _, entry := range entries {
if uuid.Equal(entry.GUID, uuid.Parse(abi.ExtraPlatformInfoGUID)) {
hasXtra = true
got := certBytes[entry.Offset : entry.Offset+entry.Length]
want := []byte("test")
if !bytes.Equal(got, want) {
t.Errorf("%v data is %v, want %v", abi.ExtraPlatformInfoGUID, got, want)
}
}
}
if !hasXtra {
t.Errorf("fake certs missing extra cert")
}
}

0 comments on commit 606477d

Please sign in to comment.