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  }