github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/support_libraries/secret_disclosure_support/secret_disclosure_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 secret_disclosure contains functions which create, interpret and verify 16 // secret disclosure directives of the following form: 17 // 'policyKey says programName can read protectedObjectId' 18 19 package secret_disclosure 20 21 import ( 22 "bytes" 23 "fmt" 24 "os" 25 "testing" 26 27 "github.com/golang/protobuf/proto" 28 po "github.com/jlmucb/cloudproxy/go/support_libraries/protected_objects" 29 "github.com/jlmucb/cloudproxy/go/tao" 30 "github.com/jlmucb/cloudproxy/go/tao/auth" 31 ) 32 33 var Delegate = auth.Prin{ 34 Type: "program", 35 KeyHash: auth.Bytes([]byte(`fake program`)), 36 } 37 38 var Delegator = auth.Prin{ 39 Type: "program", 40 KeyHash: auth.Bytes([]byte(`speaker program`)), 41 } 42 43 var ProtectedObjectName = "obj_name" 44 var ProtectedObjectEpoch = int32(0) 45 var ProtectedObjectId = po.ObjectIdMessage{ 46 ObjName: &ProtectedObjectName, 47 ObjEpoch: &ProtectedObjectEpoch, 48 } 49 50 var us = "US" 51 var google = "Google" 52 var x509Info = tao.X509Details{ 53 Country: &us, 54 Organization: &google} 55 56 func TestProcessDirectiveAndUpdateGuard(t *testing.T) { 57 domain := setUpDomain(t) 58 err := domain.Guard.Authorize(Delegator, OwnPredicate, 59 []string{ProtectedObjectId.String()}) 60 failOnError(t, err) 61 62 programKey, err := tao.NewTemporaryKeys(tao.Signing) 63 failOnError(t, err) 64 info := x509Info 65 speakerStr := Delegator.String() 66 info.CommonName = &speakerStr 67 subject := tao.NewX509Name(&info) 68 pkInt := tao.PublicKeyAlgFromSignerAlg(*domain.Keys.SigningKey.Header.KeyType) 69 sigInt := tao.SignatureAlgFromSignerAlg(*domain.Keys.SigningKey.Header.KeyType) 70 programKey.Cert, err = domain.Keys.SigningKey.CreateSignedX509( 71 domain.Keys.Cert, 1, programKey.SigningKey.GetVerifierFromSigner(), 72 pkInt, sigInt, subject) 73 failOnError(t, err) 74 directive, err := CreateSecretDisclosureDirective(programKey, &Delegator, 75 &Delegate, ReadPredicate, &ProtectedObjectId) 76 failOnError(t, err) 77 directive.Cert = programKey.Cert.Raw 78 79 err = ProcessDirectiveAndUpdateGuard(domain, directive) 80 failOnError(t, err) 81 82 if !domain.Guard.IsAuthorized(Delegate, ReadPredicate, 83 []string{ProtectedObjectId.String()}) { 84 t.Fatal("Domain guard not updated as expected.") 85 } 86 87 tearDown(t) 88 } 89 90 func TestCreateDirective(t *testing.T) { 91 policyKey, testDirective, err := generatePolicyKeyAndSignedDirective(Params{}) 92 failOnError(t, err) 93 signer := policyKey.SigningKey.ToPrincipal() 94 directive, err := CreateSecretDisclosureDirective(policyKey, &signer, &Delegate, 95 ReadPredicate, &ProtectedObjectId) 96 failOnError(t, err) 97 signatureValid, err := policyKey.SigningKey.GetVerifierFromSigner().Verify( 98 directive.SerializedStatement, SigningContext, directive.Signature) 99 failOnError(t, err) 100 if !signatureValid { 101 t.Fatal("Signature on directive not valid") 102 } 103 if testDirective.GetType() != directive.GetType() || 104 !bytes.Equal(testDirective.GetSerializedStatement(), 105 directive.GetSerializedStatement()) || 106 !bytes.Equal(testDirective.GetSigner(), directive.GetSigner()) { 107 t.Fatal("Fields in directive do not match expected value") 108 } 109 } 110 111 func TestVerifyDirective(t *testing.T) { 112 policyKey, directive, err := generatePolicyKeyAndSignedDirective(Params{}) 113 failOnError(t, err) 114 prin, programName, pred, protectedObjectId, err := 115 VerifySecretDisclosureDirective(policyKey, directive) 116 failOnError(t, err) 117 if !prin.Identical(policyKey.SigningKey.ToPrincipal()) { 118 t.Fatal("Verify returns different speaker principal from expected value.") 119 } 120 if !Delegate.Identical(programName) { 121 t.Fatal("Verify returns different programName from expected value.") 122 } 123 if *pred != ReadPredicate { 124 t.Fatal("Verify returns different predicate name from expected value.") 125 } 126 if *protectedObjectId.ObjName != *ProtectedObjectId.ObjName || 127 *protectedObjectId.ObjEpoch != *ProtectedObjectId.ObjEpoch { 128 t.Fatal("Verify returns different protectedObjectId from expected value.") 129 } 130 } 131 132 func TestCreateAndVerifyDirective(t *testing.T) { 133 policyKey, _, err := generatePolicyKeyAndSignedDirective(Params{}) 134 failOnError(t, err) 135 signer := policyKey.SigningKey.ToPrincipal() 136 directive, err := CreateSecretDisclosureDirective(policyKey, &signer, &Delegate, 137 ReadPredicate, &ProtectedObjectId) 138 failOnError(t, err) 139 prin, programName, pred, protectedObjectId, err := VerifySecretDisclosureDirective(policyKey, 140 directive) 141 failOnError(t, err) 142 if !prin.Identical(policyKey.SigningKey.ToPrincipal()) { 143 t.Fatal("Verify returns different speaker principal from expected value.") 144 } 145 if !Delegate.Identical(programName) { 146 t.Fatal("Verify returns different programName from expected value.") 147 } 148 if *pred != ReadPredicate { 149 t.Fatal("Verify returns different predicate name from expected value.") 150 } 151 if *protectedObjectId.ObjName != *ProtectedObjectId.ObjName || 152 *protectedObjectId.ObjEpoch != *ProtectedObjectId.ObjEpoch { 153 t.Fatal("Verify returns different protectedObjectId from expected value.") 154 } 155 } 156 157 func TestCreateAndVerifyDirectiveSignedByProgram(t *testing.T) { 158 policyKey, _, err := generatePolicyKeyAndSignedDirective(Params{}) 159 programKey, err := tao.NewTemporaryKeys(tao.Signing) 160 failOnError(t, err) 161 info := x509Info 162 speakerStr := Delegator.String() 163 info.CommonName = &speakerStr 164 subject := tao.NewX509Name(&info) 165 pkInt := tao.PublicKeyAlgFromSignerAlg(*policyKey.SigningKey.Header.KeyType) 166 sigInt := tao.SignatureAlgFromSignerAlg(*policyKey.SigningKey.Header.KeyType) 167 programKey.Cert, err = policyKey.SigningKey.CreateSignedX509( 168 policyKey.Cert, 1, programKey.SigningKey.GetVerifierFromSigner(), pkInt, sigInt, subject) 169 failOnError(t, err) 170 directive, err := CreateSecretDisclosureDirective(programKey, &Delegator, 171 &Delegate, ReadPredicate, &ProtectedObjectId) 172 failOnError(t, err) 173 directive.Cert = programKey.Cert.Raw 174 175 speaker, prog, pred, pobj, err := VerifySecretDisclosureDirective(policyKey, directive) 176 failOnError(t, err) 177 if !speaker.Identical(Delegator) { 178 t.Fatal(fmt.Sprintf("verify returns Speaker %v different from expected value %v", 179 speaker, Delegator)) 180 } 181 if !prog.Identical(Delegate) { 182 t.Fatal(fmt.Sprintf("verify returns program %v different from expected value %v", 183 prog, Delegate)) 184 } 185 if *pred != ReadPredicate { 186 t.Fatal(fmt.Sprintf("verify returns predicate %v different from expected value %v", 187 pred, ReadPredicate)) 188 } 189 if *pobj.ObjName != *ProtectedObjectId.ObjName || 190 *pobj.ObjEpoch != *ProtectedObjectId.ObjEpoch { 191 t.Fatal("Verify returns different protectedObjectId from expected value.") 192 } 193 } 194 195 func TestVerifyDirectiveWithBadType(t *testing.T) { 196 policyKey, testDirective, err := generatePolicyKeyAndSignedDirective(Params{}) 197 failOnError(t, err) 198 testDirective.Type = nil 199 _, _, _, _, err = VerifySecretDisclosureDirective(policyKey, testDirective) 200 if err == nil { 201 t.Fatal("Verify output is not an error") 202 } 203 } 204 205 func TestVerifyDirectiveWithDifferentSignerAndPolicyKey(t *testing.T) { 206 params := Params{ 207 Signer: []byte("Bad Signer"), 208 } 209 expectError(¶ms, t) 210 } 211 212 func TestVerifyDirectiveWithBadSignature(t *testing.T) { 213 params := Params{ 214 Signature: []byte("Bad Signature"), 215 } 216 expectError(¶ms, t) 217 } 218 219 func TestVerifyDirectiveWithBadSays(t *testing.T) { 220 params := Params{ 221 Says: auth.Const(true), 222 } 223 expectError(¶ms, t) 224 } 225 226 func TestVerifyDirectiveWithBadPredicate_badName(t *testing.T) { 227 params := Params{ 228 CanRead: auth.Pred{ 229 Name: "CanNotRead", 230 }, 231 } 232 expectError(¶ms, t) 233 } 234 235 func TestVerifyDirectiveWithBadPredicate_badTerms(t *testing.T) { 236 params := Params{ 237 CanRead: auth.Pred{ 238 Name: ReadPredicate, 239 Arg: []auth.Term{auth.Int(0), auth.Str(""), auth.Str("a")}, 240 // TODO: Note make([]auth.Term, 3) above causes NPE in auth.Marshal(thisPred) 241 // Is that a bug? 242 }, 243 } 244 expectError(¶ms, t) 245 } 246 247 func TestVerifyDirectiveWithBadDelegate(t *testing.T) { 248 params := Params{ 249 Delegate: auth.Str(""), 250 } 251 expectError(¶ms, t) 252 } 253 254 func TestVerifyDirectiveWithBadProtectedObjectId_invalidType(t *testing.T) { 255 params := Params{ 256 SerializedObjectId: auth.Str(""), 257 } 258 expectError(¶ms, t) 259 } 260 261 func TestVerifyDirectiveWithBadProtectedObjectId_invalidProtoBuf(t *testing.T) { 262 badBytes := []byte("bad bytes") 263 params := Params{ 264 SerializedObjectId: auth.Bytes(badBytes), 265 } 266 expectError(¶ms, t) 267 } 268 269 func expectError(params *Params, t *testing.T) { 270 policyKey, testDirective, err := generatePolicyKeyAndSignedDirective(*params) 271 failOnError(t, err) 272 testDirective.Type = nil 273 _, _, _, _, err = VerifySecretDisclosureDirective(policyKey, testDirective) 274 if err == nil { 275 t.Fatal("Verify output is not an error") 276 } 277 } 278 279 func failOnError(t *testing.T, err error) { 280 if err != nil { 281 t.Fatal(err) 282 } 283 } 284 285 type Params struct { 286 Delegate auth.Term 287 SerializedObjectId auth.Term 288 Says auth.Form 289 CanRead auth.Form 290 CanReadTerms []auth.Term 291 Signer []byte 292 Signature []byte 293 DirectiveType *DirectiveMessageDirectiveType 294 } 295 296 func generatePolicyKeyAndSignedDirective(params Params) (*tao.Keys, *DirectiveMessage, error) { 297 var programName auth.Term 298 if params.Delegate != nil { 299 programName = params.Delegate 300 } else { 301 programName = Delegate 302 } 303 var serializedObjectId auth.Term 304 if params.SerializedObjectId != nil { 305 serializedObjectId = params.SerializedObjectId 306 } else { 307 bytes, err := proto.Marshal(&ProtectedObjectId) 308 if err != nil { 309 return nil, nil, err 310 } 311 serializedObjectId = auth.Bytes(bytes) 312 } 313 terms := []auth.Term{programName, serializedObjectId} 314 if params.CanReadTerms != nil { 315 terms = params.CanReadTerms 316 } 317 var canRead auth.Form 318 if params.CanRead != nil { 319 canRead = params.CanRead 320 } else { 321 canRead = auth.Pred{ 322 Name: ReadPredicate, 323 Arg: terms, 324 } 325 } 326 policyKey, err := tao.NewTemporaryKeys(tao.Signing) 327 if err != nil { 328 return nil, nil, err 329 } 330 info := x509Info 331 name := policyKey.SigningKey.ToPrincipal().String() 332 info.CommonName = &name 333 subject := tao.NewX509Name(&info) 334 pkInt := tao.PublicKeyAlgFromSignerAlg(*policyKey.SigningKey.Header.KeyType) 335 sigInt := tao.SignatureAlgFromSignerAlg(*policyKey.SigningKey.Header.KeyType) 336 policyKey.Cert, err = policyKey.SigningKey.CreateSelfSignedX509(pkInt, sigInt, int64(1), subject) 337 if err != nil { 338 return nil, nil, err 339 } 340 var says auth.Form 341 if params.Says != nil { 342 says = params.Says 343 } else { 344 says = auth.Says{ 345 Speaker: policyKey.SigningKey.ToPrincipal(), 346 Time: nil, 347 Expiration: nil, 348 Message: canRead, 349 } 350 } 351 serializedSays := auth.Marshal(says) 352 var directiveType *DirectiveMessageDirectiveType 353 if params.DirectiveType != nil { 354 directiveType = params.DirectiveType 355 } else { 356 directiveType = DirectiveMessage_SECRET_DISCLOSURE.Enum() 357 } 358 var signature []byte 359 if params.Signature != nil { 360 signature = params.Signature 361 } else { 362 signature, err = policyKey.SigningKey.Sign(serializedSays, SigningContext) 363 if err != nil { 364 return nil, nil, err 365 } 366 } 367 var signer []byte 368 if params.Signer != nil { 369 signer = params.Signer 370 } else { 371 signer = auth.Marshal(policyKey.SigningKey.ToPrincipal()) 372 } 373 directive := &DirectiveMessage{ 374 Type: directiveType, 375 SerializedStatement: serializedSays, 376 Signature: signature, 377 Signer: signer, 378 } 379 return policyKey, directive, nil 380 } 381 382 func setUpDomain(t *testing.T) *tao.Domain { 383 var err error 384 if _, err = os.Stat("./tmpdir"); os.IsNotExist(err) { 385 err = os.Mkdir("./tmpdir", 0777) 386 if err != nil { 387 t.Fatal(err) 388 } 389 } 390 aclGuardType := "ACLs" 391 aclGuardPath := "acls" 392 cfg := tao.DomainConfig{ 393 DomainInfo: &tao.DomainDetails{ 394 GuardType: &aclGuardType}, 395 AclGuardInfo: &tao.ACLGuardDetails{ 396 SignedAclsPath: &aclGuardPath}} 397 domain, err := tao.CreateDomain(cfg, "./tmpdir/domain", []byte("xxx")) 398 if err != nil { 399 t.Fatal(err) 400 } 401 return domain 402 } 403 404 func tearDown(t *testing.T) { 405 err := os.RemoveAll("./tmpdir") 406 if err != nil { 407 t.Fatal(err) 408 } 409 }