123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- // Copyright 2017 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- // Package cryptobyte implements building and parsing of byte strings for
- // DER-encoded ASN.1 and TLS messages. See the examples for the Builder and
- // String types to get started.
- package cryptobyte // import "golang.org/x/crypto/cryptobyte"
- // String represents a string of bytes. It provides methods for parsing
- // fixed-length and length-prefixed values from it.
- type String []byte
- // read advances a String by n bytes and returns them. If less than n bytes
- // remain, it returns nil.
- func (s *String) read(n int) []byte {
- if len(*s) < n {
- return nil
- }
- v := (*s)[:n]
- *s = (*s)[n:]
- return v
- }
- // Skip advances the String by n byte and reports whether it was successful.
- func (s *String) Skip(n int) bool {
- return s.read(n) != nil
- }
- // ReadUint8 decodes an 8-bit value into out and advances over it. It
- // returns true on success and false on error.
- func (s *String) ReadUint8(out *uint8) bool {
- v := s.read(1)
- if v == nil {
- return false
- }
- *out = uint8(v[0])
- return true
- }
- // ReadUint16 decodes a big-endian, 16-bit value into out and advances over it.
- // It returns true on success and false on error.
- func (s *String) ReadUint16(out *uint16) bool {
- v := s.read(2)
- if v == nil {
- return false
- }
- *out = uint16(v[0])<<8 | uint16(v[1])
- return true
- }
- // ReadUint24 decodes a big-endian, 24-bit value into out and advances over it.
- // It returns true on success and false on error.
- func (s *String) ReadUint24(out *uint32) bool {
- v := s.read(3)
- if v == nil {
- return false
- }
- *out = uint32(v[0])<<16 | uint32(v[1])<<8 | uint32(v[2])
- return true
- }
- // ReadUint32 decodes a big-endian, 32-bit value into out and advances over it.
- // It returns true on success and false on error.
- func (s *String) ReadUint32(out *uint32) bool {
- v := s.read(4)
- if v == nil {
- return false
- }
- *out = uint32(v[0])<<24 | uint32(v[1])<<16 | uint32(v[2])<<8 | uint32(v[3])
- return true
- }
- func (s *String) readUnsigned(out *uint32, length int) bool {
- v := s.read(length)
- if v == nil {
- return false
- }
- var result uint32
- for i := 0; i < length; i++ {
- result <<= 8
- result |= uint32(v[i])
- }
- *out = result
- return true
- }
- func (s *String) readLengthPrefixed(lenLen int, outChild *String) bool {
- lenBytes := s.read(lenLen)
- if lenBytes == nil {
- return false
- }
- var length uint32
- for _, b := range lenBytes {
- length = length << 8
- length = length | uint32(b)
- }
- if int(length) < 0 {
- // This currently cannot overflow because we read uint24 at most, but check
- // anyway in case that changes in the future.
- return false
- }
- v := s.read(int(length))
- if v == nil {
- return false
- }
- *outChild = v
- return true
- }
- // ReadUint8LengthPrefixed reads the content of an 8-bit length-prefixed value
- // into out and advances over it. It returns true on success and false on
- // error.
- func (s *String) ReadUint8LengthPrefixed(out *String) bool {
- return s.readLengthPrefixed(1, out)
- }
- // ReadUint16LengthPrefixed reads the content of a big-endian, 16-bit
- // length-prefixed value into out and advances over it. It returns true on
- // success and false on error.
- func (s *String) ReadUint16LengthPrefixed(out *String) bool {
- return s.readLengthPrefixed(2, out)
- }
- // ReadUint24LengthPrefixed reads the content of a big-endian, 24-bit
- // length-prefixed value into out and advances over it. It returns true on
- // success and false on error.
- func (s *String) ReadUint24LengthPrefixed(out *String) bool {
- return s.readLengthPrefixed(3, out)
- }
- // ReadBytes reads n bytes into out and advances over them. It returns true on
- // success and false and error.
- func (s *String) ReadBytes(out *[]byte, n int) bool {
- v := s.read(n)
- if v == nil {
- return false
- }
- *out = v
- return true
- }
- // CopyBytes copies len(out) bytes into out and advances over them. It returns
- // true on success and false on error.
- func (s *String) CopyBytes(out []byte) bool {
- n := len(out)
- v := s.read(n)
- if v == nil {
- return false
- }
- return copy(out, v) == n
- }
- // Empty reports whether the string does not contain any bytes.
- func (s String) Empty() bool {
- return len(s) == 0
- }
|