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 }