func (s *String) ReadASN1Enum(out *int) bool {
	var bytes String
	var i int64
	if !s.ReadASN1(&bytes, asn1.TagEnum) || !checkASN1Integer(bytes) || !asn1Signed(&i, bytes) {
		return false
	}
	if int64(int(i)) != i {
		return false
	}
	*out = int(i)
	return true
}
ReadASN1Enum decodes an ASN.1 ENUMERATION into out and advances. It returns
true on success and false on error.
package cryptobyte
import (
	"encoding/asn1"
	"fmt"
	"math/big"
	"reflect"
	"time"
)
type Tag uint8
func (t Tag) ContextSpecific() Tag { return t | 0x80 }
func (t Tag) Constructed() Tag { return t | 0x20 }
func (b *Builder) AddASN1Int64(v int64) {
	b.addASN1Signed(asn1.TagInteger, v)
}
func (b *Builder) AddASN1Enum(v int64) {
	b.addASN1Signed(asn1.TagEnum, v)
}
func (b *Builder) addASN1Signed(tag Tag, v int64) {
	b.AddASN1(tag, func(c *Builder) {
		length := 1
		for i := v; i >= 0x80 || i < -0x80; i >>= 8 {
			length++
		}
		for ; length > 0; length-- {
			i := v >> uint((length-1)*8) & 0xff
			c.AddUint8(uint8(i))
		}
	})
}
func (b *Builder) AddASN1Uint64(v uint64) {
	b.AddASN1(asn1.TagInteger, func(c *Builder) {
		length := 1
		for i := v; i >= 0x80; i >>= 8 {
			length++
		}
		for ; length > 0; length-- {
			i := v >> uint((length-1)*8) & 0xff
			c.AddUint8(uint8(i))
		}
	})
}
func (b *Builder) AddASN1BigInt(n *big.Int) {
	if b.err != nil {
		return
	}
	b.AddASN1(asn1.TagInteger, func(c *Builder) {
		if n.Sign() < 0 {
			nMinus1 := new(big.Int).Neg(n)
			nMinus1.Sub(nMinus1, bigOne)
			bytes := nMinus1.Bytes()
			for i := range bytes {
				bytes[i] ^= 0xff
			}
			if bytes[0]&0x80 == 0 {
				c.add(0xff)
			}
			c.add(bytes...)
		} else if n.Sign() == 0 {
			c.add(0)
		} else {
			bytes := n.Bytes()
			if bytes[0]&0x80 != 0 {
				c.add(0)
			}
			c.add(bytes...)
		}
	})
}
func (b *Builder) AddASN1OctetString(bytes []byte) {
	b.AddASN1(asn1.TagOctetString, func(c *Builder) {
		c.AddBytes(bytes)
	})
}
const generalizedTimeFormatStr = "20060102150405Z0700"
func (b *Builder) AddASN1GeneralizedTime(t time.Time) {
	if t.Year() < 0 || t.Year() > 9999 {
		b.err = fmt.Errorf("cryptobyte: cannot represent %v as a GeneralizedTime", t)
		return
	}
	b.AddASN1(asn1.TagGeneralizedTime, func(c *Builder) {
		c.AddBytes([]byte(t.Format(generalizedTimeFormatStr)))
	})
}
func (b *Builder) AddASN1BitString(s asn1.BitString) {
	b.MarshalASN1(s)
}
func (b *Builder) MarshalASN1(v interface{}) {
	if b.err != nil {
		return
	}
	bytes, err := asn1.Marshal(v)
	if err != nil {
		b.err = err
		return
	}
	b.AddBytes(bytes)
}
func (b *Builder) AddASN1(tag Tag, f BuilderContinuation) {
	if b.err != nil {
		return
	}
	if tag&0x1f == 0x1f {
		b.err = fmt.Errorf("cryptobyte: high-tag number identifier octects not supported: 0x%x", tag)
		return
	}
	b.AddUint8(uint8(tag))
	b.addLengthPrefixed(1, true, f)
}
var bigIntType = reflect.TypeOf((*big.Int)(nil)).Elem()
func (s *String) ReadASN1Integer(out interface{}) bool {
	if reflect.TypeOf(out).Kind() != reflect.Ptr {
		panic("out is not a pointer")
	}
	switch reflect.ValueOf(out).Elem().Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		var i int64
		if !s.readASN1Int64(&i) || reflect.ValueOf(out).Elem().OverflowInt(i) {
			return false
		}
		reflect.ValueOf(out).Elem().SetInt(i)
		return true
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		var u uint64
		if !s.readASN1Uint64(&u) || reflect.ValueOf(out).Elem().OverflowUint(u) {
			return false
		}
		reflect.ValueOf(out).Elem().SetUint(u)
		return true
	case reflect.Struct:
		if reflect.TypeOf(out).Elem() == bigIntType {
			return s.readASN1BigInt(out.(*big.Int))
		}
	}
	panic("out does not point to an integer type")
}
func checkASN1Integer(bytes []byte) bool {
	if len(bytes) == 0 {
		return false
	}
	if len(bytes) == 1 {
		return true
	}
	if bytes[0] == 0 && bytes[1]&0x80 == 0 || bytes[0] == 0xff && bytes[1]&0x80 == 0x80 {
		return false
	}
	return true
}
var bigOne = big.NewInt(1)
func (s *String) readASN1BigInt(out *big.Int) bool {
	var bytes String
	if !s.ReadASN1(&bytes, asn1.TagInteger) || !checkASN1Integer(bytes) {
		return false
	}
	if bytes[0]&0x80 == 0x80 {
		neg := make([]byte, len(bytes))
		for i, b := range bytes {
			neg[i] = ^b
		}
		out.SetBytes(neg)
		out.Add(out, bigOne)
		out.Neg(out)
	} else {
		out.SetBytes(bytes)
	}
	return true
}
func (s *String) readASN1Int64(out *int64) bool {
	var bytes String
	if !s.ReadASN1(&bytes, asn1.TagInteger) || !checkASN1Integer(bytes) || !asn1Signed(out, bytes) {
		return false
	}
	return true
}
func asn1Signed(out *int64, n []byte) bool {
	length := len(n)
	if length > 8 {
		return false
	}
	for i := 0; i < length; i++ {
		*out <<= 8
		*out |= int64(n[i])
	}
	*out <<= 64 - uint8(length)*8
	*out >>= 64 - uint8(length)*8
	return true
}
func (s *String) readASN1Uint64(out *uint64) bool {
	var bytes String
	if !s.ReadASN1(&bytes, asn1.TagInteger) || !checkASN1Integer(bytes) || !asn1Unsigned(out, bytes) {
		return false
	}
	return true
}
func asn1Unsigned(out *uint64, n []byte) bool {
	length := len(n)
	if length > 9 || length == 9 && n[0] != 0 {
		return false
	}
	if n[0]&0x80 != 0 {
		return false
	}
	for i := 0; i < length; i++ {
		*out <<= 8
		*out |= uint64(n[i])
	}
	return true
}