github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/tao/auth/ast.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  	"bytes"
    19  	"crypto/sha256"
    20  	"fmt"
    21  )
    22  
    23  // LogicElement is any element of the authorization logic, i.e. a formula, a
    24  // term, or a principal extension.
    25  type LogicElement interface {
    26  
    27  	// Marshal writes a binary encoding of the element into b.
    28  	Marshal(b *Buffer)
    29  
    30  	// String returns verbose pretty-printing text for the element.
    31  	String() string
    32  
    33  	// ShortString returns short debug-printing text for the element.
    34  	ShortString() string
    35  
    36  	// fmt.Formatter is satisfied by all elements. Using format %v will result in
    37  	// verbose pretty-printing, using format %s will result in short
    38  	// debug-printing, and other formats will use an unspecified format.
    39  	fmt.Formatter // Format(out fmt.State, verb rune)
    40  
    41  	isLogicElement() // marker
    42  }
    43  
    44  // isLogicElement ensures only appropriate types can be assigned to an
    45  // LogicElement.
    46  func (t Prin) isLogicElement()      {}
    47  func (t PrinTail) isLogicElement()  {}
    48  func (t SubPrin) isLogicElement()   {}
    49  func (t Str) isLogicElement()       {}
    50  func (t Bytes) isLogicElement()     {}
    51  func (t Int) isLogicElement()       {}
    52  func (t TermVar) isLogicElement()   {}
    53  func (f Pred) isLogicElement()      {}
    54  func (f Const) isLogicElement()     {}
    55  func (f Not) isLogicElement()       {}
    56  func (f And) isLogicElement()       {}
    57  func (f Or) isLogicElement()        {}
    58  func (f Implies) isLogicElement()   {}
    59  func (f Speaksfor) isLogicElement() {}
    60  func (f Says) isLogicElement()      {}
    61  func (f Forall) isLogicElement()    {}
    62  func (f Exists) isLogicElement()    {}
    63  
    64  // These declarations ensure all the appropriate types can be assigned to an
    65  // LogicElement.
    66  var _ LogicElement = Prin{}
    67  var _ LogicElement = PrinTail{}
    68  var _ LogicElement = SubPrin{}
    69  var _ LogicElement = Str("")
    70  var _ LogicElement = Bytes(nil)
    71  var _ LogicElement = Int(0)
    72  var _ LogicElement = TermVar("X")
    73  var _ LogicElement = Pred{}
    74  var _ LogicElement = Const(false)
    75  var _ LogicElement = Not{}
    76  var _ LogicElement = And{}
    77  var _ LogicElement = Or{}
    78  var _ LogicElement = Implies{}
    79  var _ LogicElement = Speaksfor{}
    80  var _ LogicElement = Says{}
    81  var _ LogicElement = Forall{}
    82  var _ LogicElement = Exists{}
    83  
    84  // These declarations ensure all the appropriate types can be assigned to a
    85  // fmt.Scanner.
    86  var _ fmt.Scanner = &Prin{}
    87  var _ fmt.Scanner = &PrinTail{}
    88  var _ fmt.Scanner = &SubPrin{}
    89  var _ fmt.Scanner = new(Str)
    90  var _ fmt.Scanner = new(Bytes)
    91  var _ fmt.Scanner = new(Int)
    92  var _ fmt.Scanner = new(TermVar)
    93  var _ fmt.Scanner = &Pred{}
    94  var _ fmt.Scanner = new(Const)
    95  var _ fmt.Scanner = &Not{}
    96  var _ fmt.Scanner = &And{}
    97  var _ fmt.Scanner = &Or{}
    98  var _ fmt.Scanner = &Implies{}
    99  var _ fmt.Scanner = &Speaksfor{}
   100  var _ fmt.Scanner = &Says{}
   101  var _ fmt.Scanner = &Forall{}
   102  var _ fmt.Scanner = &Exists{}
   103  var _ fmt.Scanner = &AnyForm{}
   104  var _ fmt.Scanner = &AnyTerm{}
   105  
   106  // Prin uniquely identifies a principal by a public key, used to verify
   107  // signatures on credentials issued by the principal, and a sequence of zero or
   108  // more extensions to identify the subprincipal of that key.
   109  type Prin struct {
   110  	Type    string  // The keyword of a principal token, e.g. "key" or "tpm".
   111  	KeyHash Term    // TermVar or Bytes with hashed CryptoKey protobuf structure with purpose CryptoKey.VERIFYING. Or this can be a hashed marshalled TPM AIK, or a X.509 certificate, marshalled as ASN.1 DER then hashed.
   112  	Ext     SubPrin // zero or more extensions for descendents
   113  }
   114  
   115  // PrinExt is an extension of a principal.
   116  type PrinExt struct {
   117  	Name string // [A-Z][a-zA-Z0-9_]*
   118  	Arg  []Term
   119  }
   120  
   121  // SubPrin is a series of extensions of a principal.
   122  type SubPrin []PrinExt
   123  
   124  // A PrinTail is a Term that represents a free-floating sequence of PrinExt
   125  // values. It represents the tail of a list of Prin extensions. Its textual
   126  // representation always starts with the keyword "ext".
   127  type PrinTail struct {
   128  	Ext SubPrin // one or more extensions
   129  }
   130  
   131  // Term is an argument to a predicate or a principal extension.
   132  type Term interface {
   133  	LogicElement
   134  	Identical(other Term) bool
   135  	isTerm() // marker
   136  }
   137  
   138  // isTerm ensures only appropriate types can be assigned to a Term.
   139  func (t Prin) isTerm()     {}
   140  func (t PrinTail) isTerm() {}
   141  func (t Str) isTerm()      {}
   142  func (t Bytes) isTerm()    {}
   143  func (t Int) isTerm()      {}
   144  func (t TermVar) isTerm()  {}
   145  
   146  // Str is a string used as a Term.
   147  type Str string
   148  
   149  // Bytes is a byte slice used as a Term.
   150  type Bytes []byte
   151  
   152  // Int is an int used as a Term.
   153  type Int int
   154  
   155  // TermVar is a term-valued variable.
   156  type TermVar string
   157  
   158  // Form is a formula in the Tao authorization logic.
   159  type Form interface {
   160  	LogicElement
   161  	isForm() // marker
   162  }
   163  
   164  // isForm ensures only appropriate types can be assigned to a Form.
   165  func (f Pred) isForm()      {}
   166  func (f Const) isForm()     {}
   167  func (f Not) isForm()       {}
   168  func (f And) isForm()       {}
   169  func (f Or) isForm()        {}
   170  func (f Implies) isForm()   {}
   171  func (f Speaksfor) isForm() {}
   172  func (f Says) isForm()      {}
   173  func (f Forall) isForm()    {}
   174  func (f Exists) isForm()    {}
   175  
   176  // Pred is a predicate, i.e. a boolean-valued (pure) function.
   177  type Pred struct {
   178  	Name string // [A-Z][a-zA-Z0-9_]*
   179  	Arg  []Term
   180  }
   181  
   182  // Const conveys formula "true" or formula "false"
   183  type Const bool
   184  
   185  // Not conveys formula "not Negand"
   186  type Not struct {
   187  	Negand Form
   188  }
   189  
   190  // And conveys formula "Conjunct[0] and Conjunct[1] and ... and Conjunct[n]"
   191  type And struct {
   192  	Conjunct []Form
   193  }
   194  
   195  // Or conveys formula "Disjunct[0] or Disjunct[1] or ... or Disjunct[n]"
   196  type Or struct {
   197  	Disjunct []Form
   198  }
   199  
   200  // Implies conveys formula "Antecedent implies Consequent"
   201  type Implies struct {
   202  	Antecedent Form
   203  	Consequent Form
   204  }
   205  
   206  // Speaksfor conveys formula "Delegate speaksfor Delegator"
   207  type Speaksfor struct {
   208  	Delegate  Term
   209  	Delegator Term
   210  }
   211  
   212  // Says conveys formula "Speaker from Time until Expiration says Message"
   213  type Says struct {
   214  	Speaker    Term
   215  	Time       *int64 // nil to omit
   216  	Expiration *int64 // nil to omit
   217  	Message    Form
   218  }
   219  
   220  // Commences checks if statement f has a commencement time.
   221  func (f Says) Commences() bool {
   222  	return f.Time != nil
   223  }
   224  
   225  // Expires checks if statement f has an expiration time.
   226  func (f Says) Expires() bool {
   227  	return f.Expiration != nil
   228  }
   229  
   230  // Forall conveys formula "(forall Var : Body)" where Var ranges over Terms.
   231  type Forall struct {
   232  	Var  string
   233  	Body Form
   234  }
   235  
   236  // Exists conveys formula "(exists Var : Body)" where Var ranges over Terms.
   237  type Exists struct {
   238  	Var  string
   239  	Body Form
   240  }
   241  
   242  // Identical checks if an Int is identical to another Term.
   243  func (t Int) Identical(other Term) bool {
   244  	return t == other
   245  }
   246  
   247  // Identical checks if a Str is identical to another Term.
   248  func (t Str) Identical(other Term) bool {
   249  	return t == other
   250  }
   251  
   252  // Identical checks if a Bytes is identical to another Term.
   253  func (t Bytes) Identical(other Term) bool {
   254  	// other must be type Bytes or *Bytes
   255  	var b *Bytes
   256  	if ptr, ok := other.(*Bytes); ok {
   257  		b = ptr
   258  	} else if val, ok := other.(Bytes); ok {
   259  		b = &val
   260  	} else {
   261  		return false
   262  	}
   263  	return bytes.Equal([]byte(t), []byte(*b))
   264  }
   265  
   266  // Identical checks if a Prin is identical to another Term.
   267  func (t Prin) Identical(other Term) bool {
   268  	// other must be type Prin or *Prin
   269  	var p *Prin
   270  	if ptr, ok := other.(*Prin); ok {
   271  		p = ptr
   272  	} else if val, ok := other.(Prin); ok {
   273  		p = &val
   274  	} else {
   275  		return false
   276  	}
   277  	return t.Type == p.Type && t.KeyHash.Identical(p.KeyHash) && t.Ext.Identical(p.Ext)
   278  }
   279  
   280  // Identical checks if a PrinTail is identical to another Term.
   281  func (t PrinTail) Identical(other Term) bool {
   282  	// other must be type PrinTail or *PrinTail
   283  	var p *PrinTail
   284  	if ptr, ok := other.(*PrinTail); ok {
   285  		p = ptr
   286  	} else if val, ok := other.(PrinTail); ok {
   287  		p = &val
   288  	} else {
   289  		return false
   290  	}
   291  	return t.Ext.Identical(p.Ext)
   292  }
   293  
   294  // Identical checks if a TermVar is identical to another Term.
   295  func (t TermVar) Identical(other Term) bool {
   296  	return t == other
   297  }
   298  
   299  // Identical checks if one PrinExt is identical to another.
   300  func (e PrinExt) Identical(other PrinExt) bool {
   301  	if e.Name != other.Name || len(e.Arg) != len(other.Arg) {
   302  		return false
   303  	}
   304  	for i, a := range e.Arg {
   305  		if !a.Identical(other.Arg[i]) {
   306  			return false
   307  		}
   308  	}
   309  	return true
   310  }
   311  
   312  // Identical checks if one SubPrin is identical to another.
   313  func (t SubPrin) Identical(other SubPrin) bool {
   314  	if len(t) != len(other) {
   315  		return false
   316  	}
   317  	for i, e := range t {
   318  		if !e.Identical(other[i]) {
   319  			return false
   320  		}
   321  	}
   322  	return true
   323  }
   324  
   325  // SubprinOrIdentical checks whether child is a subprincipal of parent or is
   326  // identical to parent.
   327  func SubprinOrIdentical(child, parent Term) bool {
   328  	// Both must be type Prin or *Prin
   329  	var c, p *Prin
   330  	if ptr, ok := child.(*Prin); ok {
   331  		c = ptr
   332  	} else if val, ok := child.(Prin); ok {
   333  		c = &val
   334  	} else {
   335  		return false
   336  	}
   337  	if ptr, ok := parent.(*Prin); ok {
   338  		p = ptr
   339  	} else if val, ok := parent.(Prin); ok {
   340  		p = &val
   341  	} else {
   342  		return false
   343  	}
   344  	if p.Type != c.Type || !p.KeyHash.Identical(c.KeyHash) || len(p.Ext) > len(c.Ext) {
   345  		return false
   346  	}
   347  	for i, a := range p.Ext {
   348  		if !a.Identical(c.Ext[i]) {
   349  			return false
   350  		}
   351  	}
   352  	return true
   353  }
   354  
   355  // MakeSubprincipal creates principal p.e... given principal p and extensions e.
   356  func (t Prin) MakeSubprincipal(e SubPrin) Prin {
   357  	other := Prin{Type: t.Type, KeyHash: t.KeyHash, Ext: append([]PrinExt{}, t.Ext...)}
   358  	other.Ext = append(other.Ext, []PrinExt(e)...)
   359  	return other
   360  }
   361  
   362  // MakePredicate creates a predicate with the given name and arguments.
   363  // Arguments can be Prin, Int (or integer types that be coerced to it), Str (or
   364  // string), or PrinTail. Anything else is coerced to Str.
   365  func MakePredicate(name string, arg ...interface{}) Pred {
   366  	terms := make([]Term, len(arg))
   367  	for i, a := range arg {
   368  		switch a := a.(type) {
   369  		case Int:
   370  			terms[i] = a
   371  		case Str:
   372  			terms[i] = a
   373  		case Bytes:
   374  			terms[i] = a
   375  		case Prin:
   376  			terms[i] = a
   377  		case PrinTail:
   378  			terms[i] = a
   379  		case *Int:
   380  			terms[i] = a
   381  		case *Str:
   382  			terms[i] = a
   383  		case *Bytes:
   384  			terms[i] = a
   385  		case *Prin:
   386  			terms[i] = a
   387  		case *PrinTail:
   388  			terms[i] = a
   389  		case int:
   390  			terms[i] = Int(a)
   391  		case int32:
   392  			terms[i] = Int(int(a))
   393  		case int16:
   394  			terms[i] = Int(int(a))
   395  		case byte:
   396  			terms[i] = Int(int(a))
   397  		case string:
   398  			terms[i] = Str(a)
   399  		case []byte:
   400  			terms[i] = Bytes(a)
   401  		default:
   402  			terms[i] = Str(fmt.Sprintf("%v", a))
   403  		}
   404  	}
   405  	return Pred{name, terms}
   406  }
   407  
   408  // NewPrin returns a new Prin with the given key type and material.
   409  func NewPrin(keytype string, material []byte) Prin {
   410  	// TODO: This might depend on the CryptoSuite.
   411  	// by calling MakeUniversalKeyNameFromCanonicalBytes in keys.go.
   412  	// this causes an import cycle now.
   413  	hash := sha256.Sum256(material)
   414  	return Prin{Type: keytype, KeyHash: Bytes(hash[:])}
   415  }
   416  
   417  // NewKeyPrin returns a new Prin of type "key" with the given key material.
   418  func NewKeyPrin(material []byte) Prin {
   419  	return NewPrin("key", material)
   420  }
   421  
   422  // NewTpmPrin returns a new Prin of type "tpm" with the given (aik) key material.
   423  func NewTPMPrin(material []byte) Prin {
   424  	return NewPrin("tpm", material)
   425  }
   426  
   427  // NewTpm2Prin returns a new Prin of type "tpm2" with the given (ek) key material.
   428  func NewTPM2Prin(material []byte) Prin {
   429  	return NewPrin("tpm2", material)
   430  }