go-attestation/attest/example_test.go
2019-08-29 11:26:42 -07:00

177 lines
4.1 KiB
Go

package attest_test
import (
"crypto/subtle"
"flag"
"log"
"testing"
"github.com/google/go-attestation/attest"
)
var (
testExamples = flag.Bool("test-examples", false, "Enable tests for examples.")
)
func ExampleAIK() {
tpm, err := attest.OpenTPM(nil)
if err != nil {
log.Fatalf("Failed to open the TPM: %v", err)
}
defer tpm.Close()
// Create a new AIK.
aik, err := tpm.NewAIK(nil)
if err != nil {
log.Fatalf("Failed to create AIK: %v", err)
}
// Save a re-loadable representation to blob.
blob, err := aik.Marshal()
if err != nil {
log.Fatalf("Failed to marshal AIK: %v", err)
}
// Close our handle to the AIK.
if err := aik.Close(tpm); err != nil {
log.Fatalf("Failed to close AIK: %v", err)
}
// Re-load the created AIK from the blob.
aik, err = tpm.LoadAIK(blob)
if err != nil {
log.Fatalf("Failed to load AIK: %v", err)
}
if err := aik.Close(tpm); err != nil {
log.Fatalf("Failed to close AIK: %v", err)
}
}
func ExampleAIK_credentialActivation() {
tpm, err := attest.OpenTPM(nil)
if err != nil {
log.Fatalf("Failed to open TPM: %v", err)
}
defer tpm.Close()
// Create a new AIK.
aik, err := tpm.NewAIK(nil)
if err != nil {
log.Fatalf("Failed to create AIK: %v", err)
}
defer aik.Close(tpm)
// Read the EK.
ek, err := tpm.EKs()
if err != nil {
log.Fatalf("Failed to enumerate EKs: %v", err)
}
// Read parameters necessary to generate a challenge.
ap := aik.AttestationParameters()
// Generate a credential activation challenge (usually done on the server).
activation := attest.ActivationParameters{
TPMVersion: tpm.Version(),
EK: ek[0].Public,
AIK: ap,
}
secret, challenge, err := activation.Generate()
if err != nil {
log.Fatalf("Failed to generate activation challenge: %v", err)
}
// Challenge the AIK & EK properties to recieve the decrypted secret.
decrypted, err := aik.ActivateCredential(tpm, *challenge)
if err != nil {
log.Fatalf("Failed to activate credential: %v", err)
}
// Check that the AIK completed the challenge (usually done on the server).
if subtle.ConstantTimeCompare(secret, decrypted) == 0 {
log.Fatal("Activation response did not match secret")
}
}
func ExampleAIK_quote() {
tpm, err := attest.OpenTPM(nil)
if err != nil {
log.Fatalf("Failed to open TPM: %v", err)
}
defer tpm.Close()
// Create a new AIK.
aik, err := tpm.NewAIK(nil)
if err != nil {
log.Fatalf("Failed to create AIK: %v", err)
}
defer aik.Close(tpm)
// The nonce would typically be provided by the server.
nonce := []byte{1, 2, 3, 4, 5, 6, 7, 8}
// Perform the quote & gather information necessary to verify it.
quote, err := aik.Quote(tpm, nonce, attest.HashSHA1)
if err != nil {
log.Fatalf("Failed to generate quote: %v", err)
}
pcrs, err := tpm.PCRs(attest.HashSHA1)
if err != nil {
log.Fatalf("Failed to collect PCR values: %v", err)
}
log.Printf("quote = %+v", quote)
log.Printf("PCRs = %+v", pcrs)
}
func TestExampleAIK(t *testing.T) {
if !*testExamples {
t.SkipNow()
}
ExampleAIK()
ExampleAIK_credentialActivation()
ExampleAIK_quote()
}
func ExampleAIKPublic_Verify() {
tpm, err := attest.OpenTPM(nil)
if err != nil {
log.Fatalf("Failed to open TPM: %v", err)
}
defer tpm.Close()
// Create a new AIK.
aik, err := tpm.NewAIK(nil)
if err != nil {
log.Fatalf("Failed to create AIK: %v", err)
}
defer aik.Close(tpm)
// The nonce would typically be provided by the server.
nonce := []byte{1, 2, 3, 4, 5, 6, 7, 8}
// Perform the quote & gather information necessary to verify it.
quote, err := aik.Quote(tpm, nonce, attest.HashSHA256)
if err != nil {
log.Fatalf("Failed to generate quote: %v", err)
}
pcrs, err := tpm.PCRs(attest.HashSHA256)
if err != nil {
log.Fatalf("Failed to collect PCR values: %v", err)
}
// Construct an AIKPublic struct from the parameters of the key.
pub, err := attest.ParseAIKPublic(tpm.Version(), aik.AttestationParameters().Public)
if err != nil {
log.Fatalf("Failed to parse AIK public: %v", err)
}
if err := pub.Verify(*quote, pcrs, nonce); err != nil {
log.Fatalf("Verification failed: %v", err)
}
}
func TestExampleAIKPublic(t *testing.T) {
if !*testExamples {
t.SkipNow()
}
ExampleAIKPublic_Verify()
}