package tce import ( "unicode/utf8" ) // Decoder reads canonical TCE bytes. // // The decoder is strict: it accepts only the exact byte sequence the encoder // would produce for a given object, and treats every other input as an error. // In particular it never skips a field it does not understand. Skipping would // mean two implementations computed different meanings for the same signed // bytes while both saw a valid signature, so an old verifier could approve an // object whose actual content it never examined. // // Every length prefix is checked against the remaining input and against the // field's maximum before any allocation, so a hostile length cannot cause a // large allocation or a long loop. type Decoder struct { buf []byte off int } // NewDecoder returns a decoder reading b. The slice is not copied; the caller // must not modify it while decoding. func NewDecoder(b []byte) *Decoder { return &Decoder{buf: b} } // Offset returns the current read position. func (d *Decoder) Offset() int { return d.off } // Remaining returns the number of unread bytes. func (d *Decoder) Remaining() int { return len(d.buf) - d.off } // End asserts that the input is fully consumed. // // Trailing bytes are an error rather than ignored data: an object with extra // bytes appended has a different byte string, and therefore a different object // ID and a different signature, from the object it appears to contain. func (d *Decoder) End() error { if d.off != len(d.buf) { return ErrTrailing } return nil } // Header reads and validates the magic, object tag and object version. func (d *Decoder) Header() (ObjectTag, error) { if d.Remaining() < MagicLen { return TagReserved, ErrTruncated } if string(d.buf[d.off:d.off+MagicLen]) != Magic { return TagReserved, ErrMagic } d.off += MagicLen if d.Remaining() < 1 { return TagReserved, ErrTruncated } tag := ObjectTag(d.buf[d.off]) d.off++ if !knownTag(tag) { return TagReserved, ErrObjectTag } ver, err := d.Uvarint() if err != nil { return TagReserved, fieldErr("version", err) } if ver != Version { return TagReserved, ErrVersion } return tag, nil } // Uvarint reads a canonical LEB128 unsigned varint. // // A multi-byte encoding whose final group is zero is a longer spelling of a // shorter value and is rejected, because permitting it would give the same // number two encodings and therefore the same object two byte strings. func (d *Decoder) Uvarint() (uint64, error) { var n uint64 var shift uint start := d.off for { if d.off >= len(d.buf) { return 0, ErrTruncated } if d.off-start >= MaxUvarintBytes { return 0, ErrUvarint } b := d.buf[d.off] d.off++ if shift >= 64 || (shift == 63 && b > 1) { return 0, ErrOverflow } n |= uint64(b&0x7f) << shift if b&0x80 == 0 { if d.off-start > 1 && b == 0x00 { return 0, ErrNonMinimal } return n, nil } shift += 7 } } // RawBytes reads a length-prefixed byte string, enforcing maxLen. // // The returned slice aliases the decoder's buffer. Callers that retain the // data must copy it; the object constructors in the protocol package do. func (d *Decoder) RawBytes(maxLen int) ([]byte, error) { n, err := d.Uvarint() if err != nil { return nil, err } // Compare against the remaining input first so that an absurd length is // rejected before it is compared with anything else. if n > uint64(d.Remaining()) { return nil, ErrTruncated } if n > uint64(maxLen) { return nil, ErrTooLong } b := d.buf[d.off : d.off+int(n)] d.off += int(n) return b, nil } // FixedBytes reads a length-prefixed byte string of exactly want bytes. func (d *Decoder) FixedBytes(want int) ([]byte, error) { b, err := d.RawBytes(want) if err != nil { return nil, err } if len(b) != want { return nil, ErrFieldSize } return b, nil } // String reads a length-prefixed UTF-8 string and validates it. func (d *Decoder) String(maxLen int) (string, error) { b, err := d.RawBytes(maxLen) if err != nil { return "", err } if !utf8.Valid(b) { return "", ErrUTF8 } s := string(b) for _, r := range s { if r <= 0x1f || r == 0x7f || (r >= 0x80 && r <= 0x9f) { return "", ErrControlChar } } return s, nil } // Identity reads an identity field and returns a copy of the public key. // // The key is copied so that a decoded object does not alias the input buffer, // which means a caller cannot alter an identity after the object containing it // has been verified. func (d *Decoder) Identity() ([]byte, error) { ver, err := d.Uvarint() if err != nil { return nil, err } if ver != AddressVersion { return nil, ErrAddressVersion } b, err := d.FixedBytes(PubKeySize) if err != nil { return nil, err } out := make([]byte, PubKeySize) copy(out, b) return out, nil } // Timestamp reads a timestamp and validates its range. func (d *Decoder) Timestamp(allowZero bool) (uint64, error) { ts, err := d.Uvarint() if err != nil { return 0, err } if err := ValidateTimestamp(ts, allowZero); err != nil { return 0, err } return ts, nil } // Value reads a typed value. // // Reserved and unknown tags are rejected. This is the opposite of the // "ignore what you do not understand" rule common in extensible formats, and // it is deliberate: in a signed protocol, skipping an unrecognised value means // the verifier's view of the object differs from the signer's. func (d *Decoder) Value() (Value, error) { if d.Remaining() < 1 { return Value{}, ErrTruncated } tag := ValueTag(d.buf[d.off]) d.off++ switch tag { case ValNull: return Null(), nil case ValFalse: return Bool(false), nil case ValTrue: return Bool(true), nil case ValString: s, err := d.String(MaxStringValue) if err != nil { return Value{}, err } return String(s), nil case ValNumber: b, err := d.RawBytes(MaxNumberToken) if err != nil { return Value{}, err } tok := string(b) // A number must arrive in canonical form. Accepting "1.0" here would // mean two byte strings encoded the same value. if !IsCanonicalNumber(tok) { return Value{}, ErrNumberFormat } return Number(tok), nil default: return Value{}, ErrValueTag } } // Map reads a map, enforcing ascending key order, key uniqueness, the key // grammar and the entry limit. func (d *Decoder) Map(minEntries int) (map[string]Value, error) { n, err := d.Uvarint() if err != nil { return nil, err } if n > MaxMapEntries { return nil, ErrTooLong } if n < uint64(minEntries) { return nil, ErrEmptyMap } // Each entry costs at least two bytes, so a count larger than the // remaining input cannot be satisfied. Checking this before allocating // prevents a small input from reserving a large map. if n > uint64(d.Remaining()) { return nil, ErrTruncated } m := make(map[string]Value, n) prev := "" for i := uint64(0); i < n; i++ { kb, err := d.RawBytes(MaxKeyLen) if err != nil { return nil, err } key := string(kb) if err := ValidateKey(key); err != nil { return nil, err } if i > 0 { switch { case key == prev: return nil, ErrDuplicateKey case key < prev: // Out-of-order entries parse, but would give one map two // encodings, so they are rejected. return nil, ErrKeyOrder } } v, err := d.Value() if err != nil { return nil, err } m[key] = v prev = key } return m, nil }