github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/support_infrastructure/domain_service/domain_service_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 domain_service 16 17 import ( 18 "crypto/rand" 19 "crypto/rsa" 20 "crypto/x509" 21 "crypto/x509/pkix" 22 "fmt" 23 "io/ioutil" 24 "math/big" 25 "os" 26 "testing" 27 "time" 28 29 "github.com/golang/protobuf/proto" 30 "github.com/google/go-tpm/tpm" 31 "github.com/jlmucb/cloudproxy/go/tao" 32 "github.com/jlmucb/cloudproxy/go/tao/auth" 33 ) 34 35 var machineName = "Encode Machine Information" 36 37 var hostName = &auth.Prin{ 38 Type: "program", 39 KeyHash: auth.Str("hostHash")} 40 41 var programName = &auth.Prin{ 42 Type: "program", 43 KeyHash: auth.Str("programHash")} 44 45 var us = "US" 46 var google = "Google" 47 var x509Info = &tao.X509Details{ 48 Country: &us, 49 Organization: &google} 50 51 func TestVerifyHostAttestation_stackedHost(t *testing.T) { 52 aikblob, err := ioutil.ReadFile("./aikblob") 53 if err != nil { 54 t.Skip("Skipping tests, since there's no ./aikblob file") 55 } 56 tpmtao, err := tao.NewTPMTao("/dev/tpm0", aikblob, []int{17, 18}, nil) 57 if err != nil { 58 t.Skip("Couldn't create a new TPM Tao:", err) 59 } 60 tt, ok := tpmtao.(*tao.TPMTao) 61 if !ok { 62 t.Fatal("Failed to create the right kind of Tao object from NewTPMTao") 63 } 64 defer tao.CleanUpTPMTao(tt) 65 hwPublicKey, err := tpm.UnmarshalRSAPublicKey(aikblob) 66 if err != nil { 67 t.Fatal(err) 68 } 69 70 domain := generateDomain(t) 71 policyKey, policyCert := domain.Keys, domain.Keys.Cert 72 hwCert := generateEndorsementCertficate(t, policyKey, hwPublicKey, policyCert) 73 hostKey, hostAtt := generateTpmAttestation(t, tt, hostName) 74 programKey, programAtt := generateAttestation(t, hostKey, programName) 75 rawEnd1, err := proto.Marshal(hostAtt) 76 if err != nil { 77 t.Fatal("Error serializing attestation.") 78 } 79 rawEnd2 := hwCert.Raw 80 programAtt.SerializedEndorsements = [][]byte{rawEnd1, rawEnd2} 81 rawAtt, err := proto.Marshal(programAtt) 82 if err != nil { 83 t.Fatal("Error serializing attestation.") 84 } 85 certPool := x509.NewCertPool() 86 certPool.AddCert(policyCert) 87 speaker, key, prog, err := VerifyHostAttestation(rawAtt, domain, certPool) 88 if err != nil { 89 t.Fatal("Test attesation failed verification checks.", err) 90 } 91 if !programName.Identical(prog) { 92 t.Fatal("Attestation program name not identical to expected program name.") 93 } 94 if !programKey.SigningKey.ToPrincipal().Identical(key) { 95 t.Fatal("Attestation program key not identical to expected program key.") 96 } 97 if !hostKey.SigningKey.ToPrincipal().Identical(speaker) { 98 t.Fatal("Attestation host key not identical to expected host key.") 99 } 100 } 101 102 func TestVerifyHostAttestation_rootHost(t *testing.T) { 103 domain := generateDomain(t) 104 policyKey, policyCert := domain.Keys, domain.Keys.Cert 105 hostKey, hostAtt := generateAttestation(t, policyKey, hostName) 106 programKey, programAtt := generateAttestation(t, hostKey, programName) 107 rawEnd, err := proto.Marshal(hostAtt) 108 if err != nil { 109 t.Fatal("Error serializing attestation.") 110 } 111 programAtt.SerializedEndorsements = [][]byte{rawEnd} 112 rawAtt, err := proto.Marshal(programAtt) 113 if err != nil { 114 t.Fatal("Error serializing attestation.") 115 } 116 certPool := x509.NewCertPool() 117 certPool.AddCert(policyCert) 118 speaker, key, prog, err := VerifyHostAttestation(rawAtt, domain, certPool) 119 if err != nil { 120 t.Fatal("Test attesation failed verification checks.", err) 121 } 122 if !programName.Identical(prog) { 123 t.Fatal("Attestation program name not identical to expected program name.") 124 } 125 if !programKey.SigningKey.ToPrincipal().Identical(key) { 126 t.Fatal("Attestation program key not identical to expected program key.") 127 } 128 if !hostKey.SigningKey.ToPrincipal().Identical(speaker) { 129 t.Fatal("Attestation host key not identical to expected host key.") 130 } 131 } 132 133 func TestGenerateProgramCert(t *testing.T) { 134 domain := generateDomain(t) 135 programKey, err := tao.NewTemporaryKeys(tao.Signing) 136 if err != nil { 137 t.Fatal("Error generating keys.", err) 138 } 139 cert, err := GenerateProgramCert(domain, 0, programName, programKey.VerifyingKey, 140 time.Now(), time.Now().AddDate(1, 0, 0)) 141 rootCerts := x509.NewCertPool() 142 rootCerts.AddCert(domain.Keys.Cert) 143 options := x509.VerifyOptions{Roots: rootCerts} 144 _, err = cert.Verify(options) 145 if err != nil { 146 t.Fatal("Program cert fails verification check.", err) 147 } 148 } 149 150 func TestValidateEndorsementCert(t *testing.T) { 151 aikblob, err := ioutil.ReadFile("./aikblob") 152 if err != nil { 153 t.Skip("Skipping tests, since there's no ./aikblob file") 154 } 155 tpmtao, err := tao.NewTPMTao("/dev/tpm0", aikblob, []int{17, 18}, nil) 156 if err != nil { 157 t.Skip("Couldn't create a new TPM Tao:", err) 158 } 159 tt, ok := tpmtao.(*tao.TPMTao) 160 if !ok { 161 t.Fatal("Failed to create the right kind of Tao object from NewTPMTao") 162 } 163 defer tao.CleanUpTPMTao(tt) 164 hwPublicKey, err := tpm.UnmarshalRSAPublicKey(aikblob) 165 if err != nil { 166 t.Fatal(err) 167 } 168 169 domain := generateDomain(t) 170 policyKey, policyCert := domain.Keys, domain.Keys.Cert 171 hwCert := generateEndorsementCertficate(t, policyKey, hwPublicKey, policyCert) 172 rootCerts := x509.NewCertPool() 173 rootCerts.AddCert(policyCert) 174 taoname, err := tt.GetTaoName() 175 if err != nil { 176 t.Fatal(err) 177 } 178 err = validateEndorsementCertificate(hwCert, *generateGuard(t), &taoname, rootCerts) 179 if err != nil { 180 t.Fatal(err) 181 } 182 } 183 184 func TestInitAcls(t *testing.T) { 185 if _, err := os.Stat("./tmpdir"); os.IsNotExist(err) { 186 err = os.Mkdir("./tmpdir", 0777) 187 if err != nil { 188 t.Fatal(err) 189 } 190 } 191 trustedEntities := TrustedEntities{ 192 TrustedProgramTaoNames: []string{fmt.Sprintf("%v", programName)}, 193 TrustedHostTaoNames: []string{fmt.Sprintf("%v", hostName)}, 194 TrustedMachineInfos: []string{machineName}} 195 f, err := os.Create("./tmpdir/TrustedEntities") 196 if err != nil { 197 t.Fatal(err) 198 } 199 err = proto.MarshalText(f, &trustedEntities) 200 if err != nil { 201 t.Fatal(err) 202 } 203 err = f.Close() 204 if err != nil { 205 t.Fatal(err) 206 } 207 aclGuardType := "ACLs" 208 aclGuardPath := "acls" 209 cfg := tao.DomainConfig{ 210 DomainInfo: &tao.DomainDetails{ 211 GuardType: &aclGuardType}, 212 AclGuardInfo: &tao.ACLGuardDetails{ 213 SignedAclsPath: &aclGuardPath}} 214 domain, err := tao.CreateDomain(cfg, "./tmpdir/domain", []byte("xxx")) 215 if err != nil { 216 t.Fatal(err) 217 } 218 err = InitAcls(domain, "./tmpdir/TrustedEntities") 219 if err != nil { 220 t.Fatal(err) 221 } 222 machinePrin := auth.Prin{ 223 Type: "MachineInfo", 224 KeyHash: auth.Str(machineName), 225 } 226 if !domain.Guard.IsAuthorized(*programName, "Execute", []string{}) || 227 !domain.Guard.IsAuthorized(*hostName, "Host", []string{}) || 228 !domain.Guard.IsAuthorized(machinePrin, "Root", []string{}) { 229 t.Fatal("Authorization checks fail") 230 } 231 err = os.RemoveAll("./tmpdir") 232 if err != nil { 233 t.Fatal(err) 234 } 235 } 236 237 func TestRevokeCertificate(t *testing.T) { 238 k, err := tao.NewTemporaryKeys(tao.Signing) 239 if k == nil || err != nil { 240 t.Fatal("Can't generate signing key") 241 } 242 serialNumber := big.NewInt(5) 243 says := auth.Says{ 244 Speaker: k.SigningKey.ToPrincipal(), 245 Message: auth.Pred{ 246 Name: "revoke", 247 Arg: []auth.Term{auth.Bytes(serialNumber.Bytes())}}} 248 249 att, err := tao.GenerateAttestation(k.SigningKey, nil, says) 250 if err != nil { 251 t.Fatal("Error generating attestation.") 252 } 253 serAtt, err := proto.Marshal(att) 254 if err != nil { 255 t.Fatal("Error serializing attestation.") 256 } 257 revokedCerts := []pkix.RevokedCertificate{} 258 revokedCerts, err = RevokeCertificate(serAtt, revokedCerts, &tao.Domain{Keys: k}) 259 if err != nil { 260 t.Fatal(err) 261 } 262 if num := revokedCerts[0].SerialNumber.Int64(); num != 5 { 263 t.Fatal(fmt.Sprintf("Serial number %v doesnt match expected value 5", num)) 264 } 265 } 266 267 func generateDomain(t *testing.T) *tao.Domain { 268 domain := tao.Domain{} 269 domain.Keys, domain.Keys.Cert = generatePolicyKey(t) 270 domain.Guard = *generateGuard(t) 271 domain.Config = tao.DomainConfig{X509Info: x509Info} 272 return &domain 273 } 274 275 func generatePolicyKey(t *testing.T) (*tao.Keys, *x509.Certificate) { 276 k, err := tao.NewTemporaryKeys(tao.Signing) 277 if k == nil || err != nil { 278 t.Fatal("Can't generate signing key") 279 } 280 us := "US" 281 google := "Google" 282 subjectName := "Policy" 283 details := tao.X509Details{ 284 Country: &us, 285 Organization: &google, 286 CommonName: &subjectName} 287 subjectname := tao.NewX509Name(&details) 288 pkInt := tao.PublicKeyAlgFromSignerAlg(*k.SigningKey.Header.KeyType) 289 sigInt := tao.SignatureAlgFromSignerAlg(*k.SigningKey.Header.KeyType) 290 cert, err := k.SigningKey.CreateSelfSignedX509(pkInt, sigInt, int64(1), subjectname) 291 if err != nil { 292 t.Fatal("Can't self sign cert\n") 293 } 294 return k, cert 295 } 296 297 func generateEndorsementCertficate(t *testing.T, policyKey *tao.Keys, hwPublicKey *rsa.PublicKey, 298 policyCert *x509.Certificate) *x509.Certificate { 299 us := "US" 300 google := "Google" 301 details := tao.X509Details{ 302 Country: &us, 303 Organization: &google, 304 CommonName: &machineName} 305 subject := tao.NewX509Name(&details) 306 pkInt := tao.PublicKeyAlgFromSignerAlg(*policyKey.SigningKey.Header.KeyType) 307 sigInt := tao.SignatureAlgFromSignerAlg(*policyKey.SigningKey.Header.KeyType) 308 signTemplate := tao.PrepareX509Template(pkInt, sigInt, int64(1), subject) 309 derSignedCert, err := x509.CreateCertificate(rand.Reader, signTemplate, policyCert, 310 hwPublicKey, policyKey.SigningKey) 311 if err != nil { 312 t.Fatal(err) 313 } 314 cert, err := x509.ParseCertificate(derSignedCert) 315 if err != nil { 316 t.Fatal(err) 317 } 318 return cert 319 } 320 321 func generateTpmAttestation(t *testing.T, tpmtao *tao.TPMTao, delegator *auth.Prin) (*tao.Keys, 322 *tao.Attestation) { 323 k, err := tao.NewTemporaryKeys(tao.Signing) 324 if k == nil || err != nil { 325 t.Fatal("Can't generate signing key") 326 } 327 speaksFor := &auth.Speaksfor{ 328 Delegate: k.SigningKey.ToPrincipal(), 329 Delegator: delegator, 330 } 331 taoname, err := tpmtao.GetTaoName() 332 if err != nil { 333 t.Fatal("Couldn't get the name of the tao:", err) 334 } 335 says := &auth.Says{ 336 Speaker: taoname, 337 Time: nil, 338 Expiration: nil, 339 Message: speaksFor, 340 } 341 342 att, err := tpmtao.Attest(&taoname, nil, nil, says) 343 if err != nil { 344 t.Fatal("TPM couldn't attest:", err) 345 } 346 return k, att 347 } 348 349 func generateAttestation(t *testing.T, signingKey *tao.Keys, delegator *auth.Prin) (*tao.Keys, 350 *tao.Attestation) { 351 k, err := tao.NewTemporaryKeys(tao.Signing) 352 if k == nil || err != nil { 353 t.Fatal("Can't generate signing key") 354 } 355 speaksFor := &auth.Speaksfor{ 356 Delegate: k.SigningKey.ToPrincipal(), 357 Delegator: delegator, 358 } 359 says := &auth.Says{ 360 Speaker: signingKey.SigningKey.ToPrincipal(), 361 Time: nil, 362 Expiration: nil, 363 Message: speaksFor, 364 } 365 366 att, err := tao.GenerateAttestation(signingKey.SigningKey, nil, *says) 367 if err != nil { 368 t.Fatal("Error generating attestation:", err) 369 } 370 return k, att 371 } 372 373 func generateGuard(t *testing.T) *tao.Guard { 374 guard := tao.NewACLGuard(nil, tao.ACLGuardDetails{}) 375 err := guard.Authorize(*hostName, "Host", []string{}) 376 if err != nil { 377 t.Fatal("Error adding a rule to the guard", err) 378 } 379 err = guard.Authorize(*programName, "Execute", []string{}) 380 if err != nil { 381 t.Fatal("Error adding a rule to the guard", err) 382 } 383 machinePrin := auth.Prin{Type: "MachineInfo", KeyHash: auth.Str(machineName)} 384 err = guard.Authorize(machinePrin, "Root", []string{}) 385 if err != nil { 386 t.Fatal("Error adding a rule to the guard", err) 387 } 388 return &guard 389 }