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