github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/tpm2/tpm2_protocol_test.go (about)

     1  // Copyright (c) 2016, Google Inc. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package tpm2
    16  
    17  import (
    18  	"bytes"
    19  	"crypto/rand"
    20  	"crypto/rsa"
    21  	"fmt"
    22  	"io/ioutil"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/golang/protobuf/proto"
    27  )
    28  
    29  func TestClearKeyHierarchy(t *testing.T) {
    30  	rw, err := OpenTPM("/dev/tpm0")
    31  	if err != nil {
    32  		t.Fatal("Can't open tpm")
    33  	}
    34  	defer rw.Close()
    35  	err = EvictControl(rw, Handle(OrdTPM_RH_OWNER),
    36  		Handle(RootKeyHandle),
    37  		Handle(RootKeyHandle))
    38  	if err != nil {
    39  		fmt.Printf("Evict existing permanent primary handle failed (OK)\n")
    40  	}
    41  	err = EvictControl(rw, Handle(OrdTPM_RH_OWNER),
    42  		Handle(QuoteKeyHandle),
    43  		Handle(QuoteKeyHandle))
    44  	if err != nil {
    45  		fmt.Printf("Evict existing permanant primary quote failed (OK)\n")
    46  	}
    47  }
    48  
    49  func TestCreateKeyHierarchy(t *testing.T) {
    50  	rw, err := OpenTPM("/dev/tpm0")
    51  	if err != nil {
    52  		t.Fatal("Can't open tpm")
    53  	}
    54  	defer rw.Close()
    55  	pcrs := []int{7}
    56  	rootHandle, quoteHandle, storeHandle, err := CreateTpm2KeyHierarchy(rw, pcrs,
    57  		2048, uint16(AlgTPM_ALG_SHA1), "01020304")
    58  	if err != nil {
    59  		t.Fatal("Can't create keys")
    60  	}
    61  	FlushContext(rw, rootHandle)
    62  	FlushContext(rw, quoteHandle)
    63  	FlushContext(rw, storeHandle)
    64  	PersistTpm2KeyHierarchy(rw, pcrs, 2048, uint16(AlgTPM_ALG_SHA1),
    65  		RootKeyHandle, QuoteKeyHandle, "")
    66  }
    67  
    68  func TestCreateAndStoreKeyHierarchy(t *testing.T) {
    69  	rw, err := OpenTPM("/dev/tpm0")
    70  	if err != nil {
    71  		t.Fatal("Can't open tpm")
    72  	}
    73  	defer rw.Close()
    74  	pcrs := []int{7}
    75  	keySize := uint16(2048)
    76  	hash_alg_id := AlgTPM_ALG_SHA1
    77  	quotePassword := ""
    78  	rootFileName := "./tmptest/rootContext"
    79  	quoteFileName := "./tmptest/quoteContext"
    80  	storeFileName := "./tmptest/storeContext"
    81  
    82  	err = InitTpm2KeysandContexts(rw, pcrs, keySize, hash_alg_id,
    83  		quotePassword, rootFileName, quoteFileName, storeFileName)
    84  	if err != nil {
    85  		t.Fatal("Can't InitTpm2Keys")
    86  	}
    87  	rootHandle, quoteHandle, storeHandle, err := RestoreTpm2KeysFromContext(
    88  		rw, quotePassword, rootFileName, quoteFileName, storeFileName)
    89  	if err != nil {
    90  		t.Fatal("Can't RestoreTpm2Keys")
    91  	}
    92  	defer FlushContext(rw, rootHandle)
    93  	defer FlushContext(rw, quoteHandle)
    94  	defer FlushContext(rw, storeHandle)
    95  }
    96  
    97  func TestMakeEndorsementCert(t *testing.T) {
    98  	rw, err := OpenTPM("/dev/tpm0")
    99  	if err != nil {
   100  		t.Fatal("Can't open tpm")
   101  	}
   102  	defer rw.Close()
   103  
   104  	var notBefore time.Time
   105  	notBefore = time.Now()
   106  	validFor := 365 * 24 * time.Hour
   107  	notAfter := notBefore.Add(validFor)
   108  
   109  	policyKey, err := rsa.GenerateKey(rand.Reader, 2048)
   110  	if err != nil {
   111  		t.Fatal("Can't generate policy key\n")
   112  	}
   113  	derPolicyCert, err := GenerateSelfSignedCertFromKey(policyKey,
   114  		"Cloudproxy Authority", "Application Policy Key",
   115  		GetSerialNumber(), notBefore, notAfter)
   116  	if err != nil {
   117  		t.Fatal("Can't generate policy key\n")
   118  	}
   119  	fmt.Printf("policyKey: %x\n", policyKey)
   120  
   121  	ekHandle, _, err := CreateEndorsement(rw, 2048, []int{7})
   122  	if err != nil {
   123  		t.Fatal("Can't CreateEndorsement")
   124  	}
   125  	defer FlushContext(rw, ekHandle)
   126  	endorsementCert, err := GenerateHWCert(rw,
   127  		ekHandle, "JohnsHw", notBefore,
   128  		notAfter, GetSerialNumber(), derPolicyCert, policyKey)
   129  	if err != nil {
   130  		t.Fatal("Can't create endorsement cert")
   131  	}
   132  	ioutil.WriteFile("./tmptest/policy_cert.test", derPolicyCert, 0644)
   133  	ioutil.WriteFile("./tmptest/endorsement_cert.test", endorsementCert, 0644)
   134  }
   135  
   136  func TestSignAttest(t *testing.T) {
   137  	rw, err := OpenTPM("/dev/tpm0")
   138  	if err != nil {
   139  		t.Fatal("Can't open tpm")
   140  	}
   141  	defer rw.Close()
   142  	pcrs := []int{7}
   143  	rootHandle, quoteHandle, storeHandle, err := CreateTpm2KeyHierarchy(rw, pcrs,
   144  		2048, uint16(AlgTPM_ALG_SHA1), "")
   145  	if err != nil {
   146  		t.Fatal("Can't create keys")
   147  	}
   148  	defer FlushContext(rw, rootHandle)
   149  	defer FlushContext(rw, quoteHandle)
   150  	FlushContext(rw, storeHandle)
   151  
   152  	var notBefore time.Time
   153  	notBefore = time.Now()
   154  	validFor := 365 * 24 * time.Hour
   155  	notAfter := notBefore.Add(validFor)
   156  
   157  	policyKey, err := rsa.GenerateKey(rand.Reader, 2048)
   158  	if err != nil {
   159  		t.Fatal("Can't generate policy key\n")
   160  	}
   161  	derPolicyCert, err := GenerateSelfSignedCertFromKey(policyKey,
   162  		"Cloudproxy Authority", "Application Policy Key",
   163  		GetSerialNumber(), notBefore, notAfter)
   164  	if err != nil {
   165  		t.Fatal("Can't generate policy key\n")
   166  	}
   167  	fmt.Printf("policyKey: %x\n", policyKey)
   168  	attestCert, err := GenerateHWCert(rw, quoteHandle,
   169  		"JohnsHw", notBefore, notAfter,
   170  		GetSerialNumber(), derPolicyCert, policyKey)
   171  	if err != nil {
   172  		t.Fatal("Can't create attest cert")
   173  	}
   174  	fmt.Printf("Attest cert: %x\n", attestCert)
   175  	ioutil.WriteFile("./tmptest/policy_cert.test", derPolicyCert, 0644)
   176  	ioutil.WriteFile("./tmptest/attest_cert.test", attestCert, 0644)
   177  }
   178  
   179  // Combined Activate test
   180  func TestMakeActivate(t *testing.T) {
   181  	rw, err := OpenTPM("/dev/tpm0")
   182  	if err != nil {
   183  		t.Fatal("Can't open tpm")
   184  	}
   185  	defer rw.Close()
   186  
   187  	pcrs := []int{7}
   188  	rootHandle, quoteHandle, storeHandle, err := CreateTpm2KeyHierarchy(rw, pcrs,
   189  		2048, uint16(AlgTPM_ALG_SHA1), "")
   190  	if err != nil {
   191  		t.Fatal("Can't create keys")
   192  	}
   193  	defer FlushContext(rw, rootHandle)
   194  	defer FlushContext(rw, quoteHandle)
   195  	FlushContext(rw, storeHandle)
   196  
   197  	// Generate Credential
   198  	credential := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10}
   199  	fmt.Printf("Credential: %x\n", credential)
   200  
   201  	// ReadPublic
   202  	_, name, _, err := ReadPublic(rw, quoteHandle)
   203  	if err != nil {
   204  		t.Fatal("ReadPublic fails")
   205  	}
   206  
   207  	ekHandle, _, err := CreateEndorsement(rw, 2048, pcrs)
   208  	if err != nil {
   209  		t.Fatal("CreateEndorsement fails")
   210  	}
   211  	defer FlushContext(rw, ekHandle)
   212  
   213  	protectorPublic, err := GetRsaKeyFromHandle(rw, ekHandle)
   214  	if err != nil {
   215  		t.Fatal("Can't get key from handle")
   216  	}
   217  
   218  	// MakeCredential
   219  	secret, encIdentity, integrityHmac, err := MakeCredential(
   220  		protectorPublic, uint16(AlgTPM_ALG_SHA1), credential, name)
   221  	if err != nil {
   222  		t.Fatal("Can't MakeCredential\n")
   223  	}
   224  
   225  	// ActivateCredential
   226  	recovered, err := ActivateCredential(rw,
   227  		quoteHandle, ekHandle, "", "",
   228  		append(integrityHmac, encIdentity...), secret)
   229  	if err != nil {
   230  		t.Fatal("Can't ActivateCredential\n")
   231  	}
   232  	if bytes.Compare(credential, recovered) != 0 {
   233  		t.Fatal("Credential and recovered credential differ\n")
   234  	}
   235  	fmt.Printf("Make/Activate test succeeds\n")
   236  }
   237  
   238  func TestInternalSignProtocol(t *testing.T) {
   239  	rw, err := OpenTPM("/dev/tpm0")
   240  	if err != nil {
   241  		t.Fatal("Can't open tpm")
   242  	}
   243  	defer rw.Close()
   244  
   245  	pcrs := []int{7}
   246  	rootHandle, quoteHandle, storeHandle, err := CreateTpm2KeyHierarchy(rw, pcrs,
   247  		2048, uint16(AlgTPM_ALG_SHA1), "")
   248  	if err != nil {
   249  		t.Fatal("Can't create keys")
   250  	}
   251  	FlushContext(rw, rootHandle)
   252  	defer FlushContext(rw, storeHandle)
   253  
   254  	var notBefore time.Time
   255  	notBefore = time.Now()
   256  	validFor := 365 * 24 * time.Hour
   257  	notAfter := notBefore.Add(validFor)
   258  
   259  	policyKey, err := rsa.GenerateKey(rand.Reader, 2048)
   260  	if err != nil {
   261  		t.Fatal("Can't generate policy key\n")
   262  	}
   263  	derPolicyCert, err := GenerateSelfSignedCertFromKey(policyKey,
   264  		"Cloudproxy Authority", "Application Policy Key",
   265  		GetSerialNumber(), notBefore, notAfter)
   266  	if err != nil {
   267  		t.Fatal("Can't generate policy key\n")
   268  	}
   269  
   270  	ekHandle, _, err := CreateEndorsement(rw, 2048, []int{7})
   271  	if err != nil {
   272  		t.Fatal("Can't CreateEndorsement")
   273  	}
   274  
   275  	derEndorsementCert, err := GenerateHWCert(rw,
   276  		ekHandle, "JohnsHw", notBefore, notAfter,
   277  		GetSerialNumber(), derPolicyCert, policyKey)
   278  	if err != nil {
   279  		t.Fatal("Can't create endorsement cert")
   280  	}
   281  
   282  	// signing instructions
   283  	signing_instructions_message := new(SigningInstructionsMessage)
   284  	issuer := "JLM CA"
   285  	signing_instructions_message.Issuer = &issuer
   286  	var duration int64
   287  	duration = 86500 * 365
   288  	signing_instructions_message.Duration = &duration
   289  	purpose := "Signing"
   290  	signing_instructions_message.Purpose = &purpose
   291  	signalg := "RSA"
   292  	hashalg := "sha1"
   293  	signing_instructions_message.SignAlg = &signalg
   294  	signing_instructions_message.HashAlg = &hashalg
   295  	isCA := false
   296  	canSign := true
   297  	signing_instructions_message.IsCA = &isCA
   298  	signing_instructions_message.CanSign = &canSign
   299  
   300  	//
   301  	// Cloudproxy protocol
   302  	//
   303  
   304  	programName := "TestProgram"
   305  	fmt.Printf("Program name is %s\n", programName)
   306  	quotePassword := ""
   307  
   308  	// Client request.
   309  	protoClientPrivateKey, request, err := ConstructClientRequest(rw,
   310  		derEndorsementCert, quoteHandle, "",
   311  		quotePassword, programName)
   312  	if err != nil {
   313  		t.Fatal("ConstructClientRequest failed")
   314  	}
   315  	fmt.Printf("ConstructClientRequest succeeded\n")
   316  
   317  	// Create Session for seal/unseal
   318  	sessionHandle, policy_digest, err := AssistCreateSession(rw,
   319  		AlgTPM_ALG_SHA1, pcrs)
   320  	if err != nil {
   321  		t.Fatal("Can't start session for Seal")
   322  	}
   323  	fmt.Printf("Session handle: %x\n", sessionHandle)
   324  	fmt.Printf("policy_digest: %x\n\n", policy_digest)
   325  	defer FlushContext(rw, sessionHandle)
   326  
   327  	// Serialize the client private key proto, seal it and save it.
   328  	var unsealing_secret [32]byte
   329  	rand.Read(unsealing_secret[0:32])
   330  	sealed_priv, sealed_pub, err := AssistSeal(rw,
   331  		storeHandle, unsealing_secret[0:32],
   332  		"", "", pcrs, policy_digest)
   333  	if err != nil {
   334  		t.Fatal("Can't seal Program private key sealing secret")
   335  	}
   336  	serialized_program_key, err := proto.Marshal(protoClientPrivateKey)
   337  	if err != nil {
   338  		t.Fatal("Can't marshal Program private key")
   339  	}
   340  
   341  	// Encrypt private key.
   342  	var inHmac []byte
   343  	calcHmac, encrypted_program_key, err := EncryptDataWithCredential(
   344  		true, AlgTPM_ALG_SHA1, unsealing_secret[0:32],
   345  		serialized_program_key, inHmac)
   346  	if err != nil {
   347  		t.Fatal("Can't EncryptDataWithCredential program key")
   348  	}
   349  
   350  	// Server response.
   351  	response, err := ConstructServerResponse(policyKey,
   352  		derPolicyCert, *signing_instructions_message, *request)
   353  	if err != nil {
   354  		t.Fatal("ConstructServerResponse failed")
   355  	}
   356  	if response == nil {
   357  		t.Fatal("response is nil")
   358  	}
   359  	fmt.Printf("Response for ProgramName %s\n", *response.ProgramName)
   360  
   361  	// Client cert recovery.
   362  	cert, err := ClientDecodeServerResponse(rw, ekHandle,
   363  		quoteHandle, quotePassword, *response)
   364  	if err != nil {
   365  		fmt.Printf("err: %s\n", err)
   366  		t.Fatal("ClientDecodeServerResponse failed")
   367  	}
   368  	fmt.Printf("Client cert: %x\n", cert)
   369  
   370  	// if we don;t do this we run out of tpm memory
   371  	FlushContext(rw, ekHandle)
   372  	FlushContext(rw, quoteHandle)
   373  
   374  	// Example: recover program private key from buffer.
   375  	encryptedProgramKey := append(calcHmac, encrypted_program_key...)
   376  	programPrivateBlob := sealed_priv
   377  	programPublicBlob := sealed_pub
   378  	recovered_hmac := encryptedProgramKey[0:20]
   379  	recovered_cipher_text := encryptedProgramKey[20:len(encryptedProgramKey)]
   380  	fmt.Printf("Recovered hmac, cipher_text: %x, %x\n", recovered_hmac,
   381  		recovered_cipher_text)
   382  	fmt.Printf("encryptedProgramKey: %x\n", encryptedProgramKey)
   383  	fmt.Printf("Recovered priv, pub: %x, %x\n\n", programPrivateBlob,
   384  		programPublicBlob)
   385  
   386  	// Unseal secret and decrypt private policy key.
   387  	unsealed, _, err := AssistUnseal(rw, sessionHandle,
   388  		storeHandle, sealed_pub, sealed_priv, "",
   389  		"", policy_digest)
   390  	if err != nil {
   391  		t.Fatal("Can't Unseal")
   392  	}
   393  	_, decrypted_program_key, err := EncryptDataWithCredential(false,
   394  		AlgTPM_ALG_SHA1, unsealed, encrypted_program_key, calcHmac)
   395  	if err != nil {
   396  		t.Fatal("Can't EncryptDataWithCredential (decrypt) program key")
   397  	}
   398  	fmt.Printf("serialized_program_key: %x\n\n", serialized_program_key)
   399  	fmt.Printf("unsealed: %x\n\n", unsealed)
   400  	fmt.Printf("decrypted_program_key: %x\n\n", decrypted_program_key)
   401  	fmt.Printf("Cloudproxy protocol succeeds\n")
   402  }
   403  
   404  func RestSignProtocolChannel(t *testing.T) {
   405  }
   406  
   407  func RestPCR1718(t *testing.T) {
   408  }