github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/tao/auth/doc.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 supports Tao authorization and authentication, primarily by 16 // defining and implementing a logic for describing principals, their trust 17 // relationships, and their beliefs. 18 // 19 // The grammar for a formula in the logic is roughly: 20 // Form ::= Term [from Time] [until Time] says Form 21 // | Term speaksfor Term 22 // | forall TermVar : Form 23 // | exists TermVar : Form 24 // | Form implies Form 25 // | Form or Form or ... 26 // | Form and Form and ... 27 // | not Form 28 // | Pred | false | true 29 // 30 // Quantification variables range over Terms. 31 // TermVar : Identifier 32 // 33 // Times are integers interpreted as 64-bit unix timestamps. 34 // Time ::= int64 35 // 36 // Predicates are like boolean-valued pure functions, with a name and zero or 37 // more terms as arguments. 38 // Pred ::= Identifier(Term, Term, ...) 39 // | Identifier() 40 // 41 // Terms are concrete values, like strings, integers, or names of principals. 42 // Term ::= Str | Bytes | Int | Prin | PrinTail | TermVar 43 // 44 // Int can be any Go int. Str is a double-quoted Go string. Bytes is written as 45 // pairs of hex digits, optionally separated by whitespace, between square 46 // brackets. Bytes can also be written as base64w without whitespace between 47 // curly braces. 48 // 49 // Principal names specify a key or a tpm, and zero or more extensions to 50 // specify a sub-principal of that key. 51 // PrinType ::= key | tpm 52 // Prin ::= PrinType(Term) 53 // | PrinType(Term).PrinExt.PrinExt... 54 // PrinExt ::= Identifier(Term, Term, ...) 55 // | Identifier() 56 // 57 // Principal tails represent a sequence of extensions that are not rooted in a 58 // principal. They are used to make statements about authorized extensions 59 // independent of the root principal. For example, they are used to specify that 60 // a given program is authorized to execute on any platform. A PrinTail must be 61 // followed by at least one extension. 62 // PrinTail ::= ext.PrinExt.PrinExt... 63 // 64 // Identifiers for predicate and principal extension names and quantification 65 // variables are limited to simple ascii printable identifiers, with inital 66 // upper-case, and no punctuation except '_': 67 // PredName ::= [A-Z][a-zA-Z0-9_]* 68 // ExtName ::= [A-Z][a-zA-Z0-9_]* 69 // 70 // The keywords used in the above grammar are: 71 // from, until, says, speaskfor, forall, exists, implies, or, and, not, false, 72 // true, key 73 // The punctuation used are those for strings and byte slices, plus: 74 // '(', ')', ',', '.', ':' 75 // 76 // It is possible to represent nonsensical formulas, so some sanity checking may 77 // be called for. For example, in general: 78 // 1. The left operand of Says should be Prin or TermVar, as should both 79 // operands of Speaksfor. 80 // 2. All TermVar variables should be bound. 81 // 3. Conjunctions should have at least one conjunct. 82 // 4. Disjunctions should have at least one disjunct. 83 // 5. Identifiers should be legal using the above rules. 84 // 6. The parameter for key() should be TermVar or Bytes. 85 // Specific applications may impose additional restrictions on the structure of 86 // formulas they accept. 87 // 88 // All of the above elements have three distinct representations. The first 89 // representation is ast-like, with each element represented by an appropriate 90 // Go type, e.g. an int, a string, or a struct containing pointers (or 91 // interfaces) for child elements. This representation is meant to be easy to 92 // programmatically construct, split apart using type switches, rearrange, 93 // traverse, etc. 94 // 95 // The second representation is textual, which is convenient for humans but 96 // isn't canonical and can involve tricky parsing. When parsing elements from 97 // text: 98 // Whitespace is ignored between elements (except around the suprincipal dot 99 // operator, and before the open paren of a Pred, Prin, or, PrinExt); 100 // For binary operators taking two Forms, the above list shows the productions 101 // in order of increasing precedence; 102 // In all other cases, operations are parsed left to right; 103 // Parenthesis can be used for specifying precedence explicitly. 104 // When pretty-printing elements to text, a single space is used before and 105 // after keywords, commas, and colons. Elements can also be pretty-printed with 106 // elision, in which case keys and long strings are truncated. 107 // 108 // The third representation is an encoded sequence of bytes. This is meant to be 109 // compact, relatively easy to parse, and suitable for passing over sockets, 110 // network connections, etc. The encoding format is custom-designed, but is 111 // roughly similar to the format used by protobuf. 112 // 113 // Several alternative encodings were considered: 114 // 115 // Protobuf encoding with protobuf definitions: This would require either 116 // duplicating all Form and Term types as proto definitions, then writing 117 // conversion and validation code. The encoding would likely not be space 118 // efficient, and it would be essentially Tao's only hard dependency on 119 // protobuf. 120 // 121 // Protobuf encoding with hand-written encoding/decoding: The goprotobuf 122 // library currently lacks good support for this. Also, protobuf allows 123 // encoded data to be shuffled, making decoding much more complicated than 124 // necessary. 125 // 126 // encoding/gob: Not language-agnostic. The self-describing datatype encoding 127 // scheme is probably overkill as well. 128 // 129 // strings using textual representation of Form and Term elements: This 130 // pulls into all TCB a somewhat complex lexer and parser. The encoding is 131 // also not space efficient. 132 // 133 // The encoding we use instead is meant to be conceptually simple, reasonably 134 // space efficient, and simple to decode. And unlike most of the other schemes 135 // agove, strictness rather than flexibility is preferred. For example, when 136 // decoding a Form used for authorization, unrecognized fields should not be 137 // silently skipped, and unexpected types should not be silently coerced. 138 // 139 // Each element is encoded as a type tag followed by encodings for one or more 140 // values. The tag is encoded as a plain (i.e. not zig-zag encoded) varint, and 141 // it determines the meaning, number, and types of the values. Values are 142 // encoded according to their type: 143 // 144 // An integer or bool is encoded as plain varint. 145 // 146 // A string is encoded as a length (plain varint) followed by raw bytes. 147 // 148 // A pointer is encoded the same as a boolean optionally followed by a value. 149 // 150 // Variable-length slices (e.g. for conjuncts, disjuncts, predicate arguments) 151 // are encoded as a count (plain varint) followed by the encoding for the each 152 // element. 153 // 154 // An embedded struct or interface is encoded as a tag and encoded value. 155 // 156 // Differences from protobuf: 157 // 158 // Our tags carry implicit type information. In protobuf, the low 3 bits of 159 // each tag carries an explicit type marker. That allows protobuf to skip over 160 // unrecognized fields (not a design goal for us). It also means protobuf can 161 // only handle 15 unique tags before overflowing to 2 byte encodings. 162 // 163 // Our tags describe both the meaning and the type of all enclosed values, and 164 // we use tags only when the meaning or type can vary (i.e. for interface 165 // types). Protobuf uses tags for every enclosed value, and those tags also 166 // carry type information. Protobuf is more efficient when there are many 167 // optional fields. For us, nearly all fields are required. 168 // 169 // Enclosed values in our encoding must appear in order. Protobuf values can 170 // appear in any order. Protobuf encodings can concatenated, truncated, etc., 171 // all non-features for us. 172 // 173 // Note: In most cases, a tag appears only when the type would be ambiguous, 174 // i.e. when encoding Term or Form. 175 package auth