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 }