github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/tao/auth/auth_test.go (about) 1 // Copyright (c) 2014, Kevin Walsh. 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 auth 16 17 import ( 18 "encoding/base64" 19 "fmt" 20 "strings" 21 "testing" 22 ) 23 24 var key = []string{ 25 `key([4b657930])`, // hex("Key1") 26 `key([4b657931])`, // hex("Key2") 27 `tpm({S2V5Mw==})`, // base64w("Key3") 28 `tpm({BgWWala-pkV7l_Yg043wLQ==})`, // base64w(some random bytes) 29 `tpm({BgWWala+pkV7l/Yg043wLQ==})`, // base64(some other random bytes) 30 } 31 32 var termtests = []string{ 33 `bogus([face])`, 34 "42", 35 "0", 36 "-1", 37 `"Hello World"`, 38 `"Includes \n newlines and \t tabs"`, 39 "[010203abcdef]", 40 key[0], 41 key[1], 42 key[0] + ".Extension(1)", 43 key[0] + `.Extension(1).A().B(1).C(1, "Hello").D(` + key[1] + `.E(` + key[1] + `.G().H()))`, 44 "ext.Extension(1)", 45 `ext.Extension(1).A().B(1).C(1, "Hello").D(` + key[1] + `.E(` + key[1] + `.G().H()))`, 46 key[0] + ".E(" + key[3] + ")", 47 "[01 02 03abcd ef]", 48 } 49 50 func TestParseBase64W(t *testing.T) { 51 var x AnyTerm 52 n, err := fmt.Sscanf(key[0]+".E("+key[3]+")", "%v", &x) 53 if err != nil { 54 t.Fatal(err.Error()) 55 } 56 if n != 1 { 57 t.Fatal("incomplete parse") 58 } 59 60 // Base64 data (as opposed to Base64w data) shouldn't work. 61 n, err = fmt.Sscanf(key[0]+".E("+key[4]+")", "%v", &x) 62 if err == nil { 63 t.Fatalf("Incorrectly parsed Base64 data: %s", err.Error()) 64 } 65 } 66 67 func TestParseTerm(t *testing.T) { 68 for i, s := range termtests { 69 var x AnyTerm 70 n, err := fmt.Sscanf(s, "%v", &x) 71 if err != nil { 72 t.Fatal(err.Error()) 73 } 74 if n != 1 { 75 t.Fatal("incomplete parse") 76 } 77 if (i < len(termtests)-2) != (x.Term.String() == s) { 78 t.Fatalf("bad print: %v vs %v", x.Term.String(), s) 79 } 80 } 81 82 s := termtests[0] + " " + termtests[3] + " " + termtests[4] + " " + termtests[6] 83 var w, x, y, z AnyTerm 84 n, err := fmt.Sscanf(s, "%v %v %v %v", &w, &x, &y, &z) 85 if err != nil { 86 t.Fatal(err.Error()) 87 } 88 if n != 4 { 89 t.Fatal("incomplete parse") 90 } 91 } 92 93 func TestBinaryTerm(t *testing.T) { 94 for _, s := range termtests { 95 var x AnyTerm 96 fmt.Sscanf("("+s+")", "%v", &x) 97 f := x.Term 98 99 buf := Marshal(f) 100 g, err := UnmarshalTerm(buf) 101 if err != nil { 102 t.Fatalf("can't unmarshal %s: %v", s, err) 103 } 104 if f.String() != g.String() { 105 t.Fatalf("bad binary: %s vs %s", f.String(), g.String()) 106 } 107 } 108 } 109 110 func TestScanTerm(t *testing.T) { 111 var i1, i2 Int 112 n, err := fmt.Sscanf("42 -17", "%v %v", &i1, &i2) 113 if err != nil { 114 t.Fatal(err.Error()) 115 } 116 if n != 2 || i1 != Int(42) || i2 != Int(-17) { 117 t.Fatal("incomplete parse") 118 } 119 120 var s1, s2 Str 121 n, err = fmt.Sscanf(`"a" "b"`, "%v %v", &s1, &s2) 122 if err != nil { 123 t.Fatal(err.Error()) 124 } 125 if n != 2 || s1 != Str("a") || s2 != Str("b") { 126 t.Fatal("incomplete parse") 127 } 128 129 var p Prin 130 n, err = fmt.Sscanf(key[0]+`.A(1).B("2", "3")`, "%v", &p) 131 if err != nil { 132 t.Fatal(err.Error()) 133 } 134 p2 := Prin{Type: "key", KeyHash: Bytes([]byte("abc")), Ext: SubPrin{ 135 PrinExt{"A", []Term{Int(1)}}, 136 PrinExt{"B", []Term{Str("2"), Str("#")}}, 137 }} 138 if n != 1 || p2.Identical(p) { 139 t.Fatal("incomplete parse") 140 } 141 } 142 143 func TestParseSentence(t *testing.T) { 144 var x Prin 145 s := `My name is ` + key[0] + `.Prog("foo", 1).Args("foo", "bar")` 146 n, err := fmt.Sscanf(s, "My name is %v", &x) 147 if err != nil { 148 t.Fatal(err.Error()) 149 } 150 if n != 1 { 151 t.Fatal("incomplete parse") 152 } 153 } 154 155 func TestParsePred(t *testing.T) { 156 predtests := []string{ 157 `P(42)`, 158 `Foo()`, 159 `Pred(1, 2, 3)`, 160 `Foo(1, "a", ` + key[0] + `)`, 161 `Foo()`, 162 } 163 164 for _, s := range predtests { 165 var x Pred 166 n, err := fmt.Sscanf(s, "%v", &x) 167 if err != nil { 168 t.Fatal(err.Error()) 169 } 170 if n != 1 { 171 t.Fatal("incomplete parse") 172 } 173 if s != "Foo()" && x.String() != s { 174 t.Fatalf("bad print: %v vs %s", x.String(), s) 175 } 176 } 177 178 s := predtests[0] + " " + predtests[1] + " " + predtests[2] + " " + predtests[3] 179 var w, x, y, z Pred 180 n, err := fmt.Sscanf(s, "%v %v %v %v", &w, &x, &y, &z) 181 if err != nil { 182 t.Fatal(err.Error()) 183 } 184 if n != 4 { 185 t.Fatal("incomplete parse") 186 } 187 } 188 189 var formtests = []string{ 190 `true`, 191 `false`, 192 key[0] + ` says true`, 193 key[0] + ` from 1 says true`, 194 key[0] + ` until 2 says true`, 195 key[0] + ` from 1 until 2 says true`, 196 key[0] + ` speaksfor ` + key[1], 197 key[0] + `.Sub(1).Sub(2) speaksfor ` + key[1] + `.Sub(1).Sub(2)`, 198 `P(1)`, 199 `P(1) and P(2)`, 200 `P(1) and P(2) and P(3) and P(4)`, 201 `P(1) or P(2)`, 202 `P(1) or P(2) or P(3) or P(4)`, 203 `P(1) implies P(2)`, 204 `P(1) implies P(2) implies P(3) or P(4)`, 205 `not P(1)`, 206 `not not P(1)`, 207 `not not not not P(1)`, 208 `P(1) and ` + key[0] + ` speaksfor ` + key[1], 209 `P(1) and P(2) and P(3) or P(4)`, 210 `P(1) and P(2) and (P(3) or P(4))`, 211 `P(1) and (P(2) or P(3)) and P(4)`, 212 `(P(1) or P(2)) and P(3) and P(4)`, 213 `P(1) and P(2) and P(3) implies P(4)`, 214 `P(1) and P(2) and (P(3) implies P(4))`, 215 `P(1) and (P(2) implies P(3)) and P(4)`, 216 `(P(1) implies P(2)) and P(3) and P(4)`, 217 `P(1) or P(2) or P(3) implies P(4)`, 218 `P(1) or P(2) or (P(3) implies P(4))`, 219 `P(1) or (P(2) implies P(3)) or P(4)`, 220 `(P(1) implies P(2)) or P(3) or P(4)`, 221 `P(1) or ` + key[0] + ` says P(2) or P(3)`, 222 `forall X: P(X)`, 223 `forall X: forall Y: P(X, Y)`, 224 `exists X: P(X)`, 225 `exists X: exists Y: P(X, Y)`, 226 `forall X: P(X) implies exists Y: Q(X, Y) and R(X)`, 227 `P(1) and forall X: Q(X)`, 228 `(forall X: Q(X)) and P(1)`, 229 `forall X: forall Y: X says P(1) implies Y says P(1)`, 230 `(((P(((1)), (` + key[2] + `)))))`, 231 } 232 233 func TestParseForm(t *testing.T) { 234 for i, s := range formtests { 235 var x AnyForm 236 n, err := fmt.Sscanf("("+s+")", "%v", &x) 237 if err != nil { 238 t.Fatal(err.Error()) 239 } 240 if n != 1 { 241 t.Fatal("incomplete parse") 242 } 243 if i != len(formtests)-1 && x.Form.String() != s && "("+x.Form.String()+")" != s { 244 t.Fatalf("bad print: %v vs %s", x.Form.String(), s) 245 } 246 247 // Try parsing with the specific type 248 switch v := x.Form.(type) { 249 case Says: 250 n, err = fmt.Sscanf("("+s+")", "%v", &v) 251 x.Form = v 252 case Speaksfor: 253 n, err = fmt.Sscanf("("+s+")", "%v", &v) 254 x.Form = v 255 case Implies: 256 n, err = fmt.Sscanf("("+s+")", "%v", &v) 257 x.Form = v 258 case And: 259 n, err = fmt.Sscanf("("+s+")", "%v", &v) 260 x.Form = v 261 case Or: 262 n, err = fmt.Sscanf("("+s+")", "%v", &v) 263 x.Form = v 264 case Not: 265 n, err = fmt.Sscanf("("+s+")", "%v", &v) 266 x.Form = v 267 case Pred: 268 n, err = fmt.Sscanf("("+s+")", "%v", &v) 269 x.Form = v 270 case Const: 271 n, err = fmt.Sscanf("("+s+")", "%v", &v) 272 x.Form = v 273 case Forall: 274 n, err = fmt.Sscanf("("+s+")", "%v", &v) 275 x.Form = v 276 case Exists: 277 n, err = fmt.Sscanf("("+s+")", "%v", &v) 278 x.Form = v 279 default: 280 t.Fatalf("not reached") 281 } 282 if err != nil { 283 t.Fatal(err.Error()) 284 } 285 if n != 1 { 286 t.Fatal("incomplete parse") 287 } 288 if i != len(formtests)-1 && x.Form.String() != s && "("+x.Form.String()+")" != s { 289 t.Fatalf("bad print: %v vs %s", x.Form.String(), s) 290 } 291 } 292 } 293 294 func TestParseShortForm(t *testing.T) { 295 for _, s := range formtests { 296 var x, y AnyForm 297 _, err := fmt.Sscanf("("+s+")", "%v", &x) 298 if err != nil { 299 t.Fatal(err) 300 } 301 if x.Form.String() != x.Form.ShortString() { 302 t.Fatalf("bad short string: %s vs %s", x.Form.String(), x.Form.ShortString()) 303 } 304 305 longstr := `"abcdefghijklmnopqrstuvwxyz"` 306 shortstr := `"abcdefghij"...` 307 short := strings.Replace(s, `"a"`, longstr, -1) 308 fmt.Sscanf("("+short+")", "%v", &y) 309 shortened := strings.Replace(x.Form.String(), `"a"`, shortstr, -1) 310 if shortened != y.Form.ShortString() { 311 t.Fatalf("bad short string: %s vs %s", y.Form.ShortString(), shortened) 312 } 313 314 if y.Form.String() != fmt.Sprintf("%v", y.Form) { 315 t.Fatalf("bad long format: %s vs %s", x.Form.String(), fmt.Sprintf("%v", x.Form)) 316 } 317 if shortened != fmt.Sprintf("%s", y.Form) { 318 t.Fatalf("bad short format: %s vs %s", shortened, fmt.Sprintf("%s", x.Form)) 319 } 320 321 } 322 } 323 324 func TestBinaryForm(t *testing.T) { 325 for _, s := range formtests { 326 var x AnyForm 327 fmt.Sscanf("("+s+")", "%v", &x) 328 f := x.Form 329 330 buf := Marshal(f) 331 g, err := UnmarshalForm(buf) 332 if err != nil { 333 t.Fatalf("can't unmarshal: %s", s) 334 } 335 if f.String() != g.String() { 336 t.Fatalf("bad binary: %s vs %s", f.String(), g.String()) 337 } 338 } 339 } 340 341 func TestPrinIdentical(t *testing.T) { 342 p := make([]Prin, 6) 343 fmt.Sscanf(key[0], "%s", &p[0]) 344 fmt.Sscanf(key[0]+`.Kid(1)`, "%s", &p[1]) 345 fmt.Sscanf(key[0]+`.Kid(1).Kid(2)`, "%s", &p[2]) 346 fmt.Sscanf(key[1]+`.Kid(1).Kid(2)`, "%s", &p[3]) 347 fmt.Sscanf(key[0]+`.Kid(2).Kid(2)`, "%s", &p[4]) 348 fmt.Sscanf(key[0]+`.Kid(1, 2).Kid(2)`, "%s", &p[5]) 349 350 for i, prin := range p { 351 for j, other := range p { 352 if (i == j) != prin.Identical(other) || (i == j) != other.Identical(prin) { 353 t.Fatalf("identical failed for %v vs %v", prin, other) 354 } 355 if ((i <= j && j <= 2) || (i == 0 && j >= 4) || (i == j)) != 356 SubprinOrIdentical(other, prin) { 357 t.Fatalf("subprin failed for %v vs %v", prin, other) 358 } 359 } 360 } 361 362 if p[0].Identical(Str("a")) { 363 t.Fatalf("identical failed against str") 364 } 365 } 366 367 func TestTrivialConjuncts(t *testing.T) { 368 p := And{} 369 if p.String() != "true" || p.ShortString() != p.String() { 370 t.Fatalf("bad print for empty conjunct ") 371 } 372 q := Or{} 373 if q.String() != "false" || q.ShortString() != q.String() { 374 t.Fatalf("bad print for empty disnjunct ") 375 } 376 var f AnyForm 377 s := "P(1, 2, 3)" 378 fmt.Sscanf(s, "%v", &f) 379 p = And{Conjunct: []Form{f.Form}} 380 if p.String() != s || p.ShortString() != s { 381 t.Fatalf("bad print for unary conjunct ") 382 } 383 q = Or{Disjunct: []Form{f.Form}} 384 if q.String() != s || q.ShortString() != s { 385 t.Fatalf("bad print for unary disnjunct ") 386 } 387 } 388 389 type ptest struct { 390 name string 391 args []interface{} 392 s string 393 } 394 395 type testStringer bool 396 397 func (t testStringer) String() string { 398 return "test" 399 } 400 401 func TestMakePredicate(t *testing.T) { 402 tests := []ptest{ 403 ptest{"Foo", nil, "Foo()"}, 404 ptest{"Foo", []interface{}{}, "Foo()"}, 405 ptest{"Foo", []interface{}{1, 2, 3}, "Foo(1, 2, 3)"}, 406 ptest{"Foo", []interface{}{"a", 2, Prin{Type: "key", KeyHash: Bytes([]byte("abc"))}}, `Foo("a", 2, key([616263]))`}, 407 ptest{"Foo", []interface{}{3.14, testStringer(false), true}, `Foo("3.14", "test", "true")`}, 408 } 409 410 for _, test := range tests { 411 pred := MakePredicate(test.name, test.args...) 412 if pred.String() != test.s { 413 t.Fatalf("MakePredicate failed for %v vs. %v", test.s, pred) 414 } 415 } 416 } 417 418 var extprins = []string{ 419 `ext.PCRs("17, 18", "0a877e9010800b0c0d98, b7c5820097262978e8a7")`, 420 `ext.PCRs("17, 18", "0a877e9010800b0c0d98, b7c5820097262978e8a7").Hash([71])`, 421 `ext.Kid(1).Kid(2)`, 422 } 423 424 func TestExtPrin(t *testing.T) { 425 for _, e := range extprins { 426 var pt PrinTail 427 if _, err := fmt.Sscanf(e, "%s", &pt); err != nil { 428 t.Fatal("Couldn't scan the ext principal:", err) 429 } 430 } 431 } 432 433 var badprins = []string{ 434 `ext([704569])`, 435 `ext`, 436 `key()`, 437 `tpm()`, 438 } 439 440 func TestBadExtPrin(t *testing.T) { 441 for _, e := range badprins { 442 var at AnyTerm 443 if _, err := fmt.Sscanf(e, "%s", &at); err == nil { 444 t.Log(at) 445 t.Fatal("Incorrectly successfully scanned an invalid Term") 446 } 447 } 448 } 449 450 var binaryEncodings = []string{ 451 `DQEDa2V5BAh0ZXN0IGtleREAAQNrZXkEDHRlc3QgdGFvIGtleREA`, 452 } 453 454 func TestBinaryEncodings(t *testing.T) { 455 for _, b := range binaryEncodings { 456 e, err := base64.URLEncoding.DecodeString(b) 457 if err != nil { 458 t.Log(b) 459 t.Fatal("Couldn't decode a binary encoding") 460 } 461 462 f, err := UnmarshalForm(e) 463 if err != nil { 464 t.Log(b) 465 t.Fatal("Couldn't unmarshal a binary encoding") 466 } 467 t.Logf("%v\n", f) 468 } 469 }