func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type, fieldName string) (ret reflect.Value, err error) {
	matchAny, expectedTag, compoundType, ok := getUniversalType(elemType)
	if !ok {
		err = StructuralError{"unknown Go type for slice", fieldName}
		return
	}
	numElements := 0
	for offset := 0; offset < len(bytes); {
		var t tagAndLength
		t, offset, err = parseTagAndLength(bytes, offset, fieldName)
		if err != nil {
			return
		}
		switch t.tag {
		case TagIA5String, TagGeneralString, TagT61String, TagUTF8String, TagNumericString:
			t.tag = TagPrintableString
		case TagGeneralizedTime, TagUTCTime:
			t.tag = TagUTCTime
		}
		if !matchAny && (t.class != ClassUniversal || t.isCompound != compoundType || t.tag != expectedTag) {
			err = StructuralError{fmt.Sprintf("sequence tag mismatch (got:%+v, want:0/%d/%t)", t, expectedTag, compoundType), fieldName}
			return
		}
		if invalidLength(offset, t.length, len(bytes)) {
			err = SyntaxError{"truncated sequence", fieldName}
			return
		}
		offset += t.length
		numElements++
	}
	ret = reflect.MakeSlice(sliceType, numElements, numElements)
	params := fieldParameters{}
	offset := 0
	for i := 0; i < numElements; i++ {
		offset, err = parseField(ret.Index(i), bytes, offset, params)
		if err != nil {
			return
		}
	}
	return
}
parseSequenceOf is used for SEQUENCE OF and SET OF values. It tries to parse
a number of ASN.1 values from the given byte slice and returns them as a
slice of Go values of the given type.
package asn1
import (
	"errors"
	"fmt"
	"math"
	"math/big"
	"reflect"
	"strconv"
	"strings"
	"time"
	"unicode/utf8"
)
type StructuralError struct {
	Msg   string
	Field string
}
func (e StructuralError) Error() string {
	var prefix string
	if e.Field != "" {
		prefix = e.Field + ": "
	}
	return "asn1: structure error: " + prefix + e.Msg
}
type SyntaxError struct {
	Msg   string
	Field string
}
func (e SyntaxError) Error() string {
	var prefix string
	if e.Field != "" {
		prefix = e.Field + ": "
	}
	return "asn1: syntax error: " + prefix + e.Msg
}
func parseBool(bytes []byte, fieldName string) (ret bool, err error) {
	if len(bytes) != 1 {
		err = SyntaxError{"invalid boolean", fieldName}
		return
	}
	switch bytes[0] {
	case 0:
		ret = false
	case 0xff:
		ret = true
	default:
		err = SyntaxError{"invalid boolean", fieldName}
	}
	return
}
func checkInteger(bytes []byte, fieldName string) error {
	if len(bytes) == 0 {
		return StructuralError{"empty integer", fieldName}
	}
	if len(bytes) == 1 {
		return nil
	}
	if (bytes[0] == 0 && bytes[1]&0x80 == 0) || (bytes[0] == 0xff && bytes[1]&0x80 == 0x80) {
		return StructuralError{"integer not minimally-encoded", fieldName}
	}
	return nil
}
func parseInt64(bytes []byte, fieldName string) (ret int64, err error) {
	err = checkInteger(bytes, fieldName)
	if err != nil {
		return
	}
	if len(bytes) > 8 {
		err = StructuralError{"integer too large", fieldName}
		return
	}
	for bytesRead := 0; bytesRead < len(bytes); bytesRead++ {
		ret <<= 8
		ret |= int64(bytes[bytesRead])
	}
	ret <<= 64 - uint8(len(bytes))*8
	ret >>= 64 - uint8(len(bytes))*8
	return
}
func parseInt32(bytes []byte, fieldName string) (int32, error) {
	if err := checkInteger(bytes, fieldName); err != nil {
		return 0, err
	}
	ret64, err := parseInt64(bytes, fieldName)
	if err != nil {
		return 0, err
	}
	if ret64 != int64(int32(ret64)) {
		return 0, StructuralError{"integer too large", fieldName}
	}
	return int32(ret64), nil
}
var bigOne = big.NewInt(1)
func parseBigInt(bytes []byte, fieldName string) (*big.Int, error) {
	if err := checkInteger(bytes, fieldName); err != nil {
		return nil, err
	}
	ret := new(big.Int)
	if len(bytes) > 0 && bytes[0]&0x80 == 0x80 {
		notBytes := make([]byte, len(bytes))
		for i := range notBytes {
			notBytes[i] = ^bytes[i]
		}
		ret.SetBytes(notBytes)
		ret.Add(ret, bigOne)
		ret.Neg(ret)
		return ret, nil
	}
	ret.SetBytes(bytes)
	return ret, nil
}
type BitString struct {
	Bytes     []byte  
	BitLength int     
}
func (b BitString) At(i int) int {
	if i < 0 || i >= b.BitLength {
		return 0
	}
	x := i / 8
	y := 7 - uint(i%8)
	return int(b.Bytes[x]>>y) & 1
}
func (b BitString) RightAlign() []byte {
	shift := uint(8 - (b.BitLength % 8))
	if shift == 8 || len(b.Bytes) == 0 {
		return b.Bytes
	}
	a := make([]byte, len(b.Bytes))
	a[0] = b.Bytes[0] >> shift
	for i := 1; i < len(b.Bytes); i++ {
		a[i] = b.Bytes[i-1] << (8 - shift)
		a[i] |= b.Bytes[i] >> shift
	}
	return a
}
func parseBitString(bytes []byte, fieldName string) (ret BitString, err error) {
	if len(bytes) == 0 {
		err = SyntaxError{"zero length BIT STRING", fieldName}
		return
	}
	paddingBits := int(bytes[0])
	if paddingBits > 7 ||
		len(bytes) == 1 && paddingBits > 0 ||
		bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 {
		err = SyntaxError{"invalid padding bits in BIT STRING", fieldName}
		return
	}
	ret.BitLength = (len(bytes)-1)*8 - paddingBits
	ret.Bytes = bytes[1:]
	return
}
var NullRawValue = RawValue{Tag: TagNull}
var NullBytes = []byte{TagNull, 0}
type ObjectIdentifier []int
func (oi ObjectIdentifier) Equal(other ObjectIdentifier) bool {
	if len(oi) != len(other) {
		return false
	}
	for i := 0; i < len(oi); i++ {
		if oi[i] != other[i] {
			return false
		}
	}
	return true
}
func (oi ObjectIdentifier) String() string {
	var s string
	for i, v := range oi {
		if i > 0 {
			s += "."
		}
		s += strconv.Itoa(v)
	}
	return s
}
func parseObjectIdentifier(bytes []byte, fieldName string) (s []int, err error) {
	if len(bytes) == 0 {
		err = SyntaxError{"zero length OBJECT IDENTIFIER", fieldName}
		return
	}
	s = make([]int, len(bytes)+1)
	v, offset, err := parseBase128Int(bytes, 0, fieldName)
	if err != nil {
		return
	}
	if v < 80 {
		s[0] = v / 40
		s[1] = v % 40
	} else {
		s[0] = 2
		s[1] = v - 80
	}
	i := 2
	for ; offset < len(bytes); i++ {
		v, offset, err = parseBase128Int(bytes, offset, fieldName)
		if err != nil {
			return
		}
		s[i] = v
	}
	s = s[0:i]
	return
}
type Enumerated int
type Flag bool
func parseBase128Int(bytes []byte, initOffset int, fieldName string) (ret, offset int, err error) {
	offset = initOffset
	var ret64 int64
	for shifted := 0; offset < len(bytes); shifted++ {
		if shifted == 5 {
			err = StructuralError{"base 128 integer too large", fieldName}
			return
		}
		ret64 <<= 7
		b := bytes[offset]
		ret64 |= int64(b & 0x7f)
		offset++
		if b&0x80 == 0 {
			ret = int(ret64)
			if ret64 > math.MaxInt32 {
				err = StructuralError{"base 128 integer too large", fieldName}
			}
			return
		}
	}
	err = SyntaxError{"truncated base 128 integer", fieldName}
	return
}
func parseUTCTime(bytes []byte) (ret time.Time, err error) {
	s := string(bytes)
	formatStr := "0601021504Z0700"
	ret, err = time.Parse(formatStr, s)
	if err != nil {
		formatStr = "060102150405Z0700"
		ret, err = time.Parse(formatStr, s)
	}
	if err != nil {
		return
	}
	if serialized := ret.Format(formatStr); serialized != s {
		err = fmt.Errorf("asn1: time did not serialize back to the original value and may be invalid: given %q, but serialized as %q", s, serialized)
		return
	}
	if ret.Year() >= 2050 {
		ret = ret.AddDate(-100, 0, 0)
	}
	return
}
func parseGeneralizedTime(bytes []byte) (ret time.Time, err error) {
	const formatStr = "20060102150405Z0700"
	s := string(bytes)
	if ret, err = time.Parse(formatStr, s); err != nil {
		return
	}
	if serialized := ret.Format(formatStr); serialized != s {
		err = fmt.Errorf("asn1: time did not serialize back to the original value and may be invalid: given %q, but serialized as %q", s, serialized)
	}
	return
}
func parseNumericString(bytes []byte, fieldName string) (ret string, err error) {
	for _, b := range bytes {
		if !isNumeric(b) {
			return "", SyntaxError{"NumericString contains invalid character", fieldName}
		}
	}
	return string(bytes), nil
}
func isNumeric(b byte) bool {
	return '0' <= b && b <= '9' ||
		b == ' '
}
func parsePrintableString(bytes []byte, fieldName string) (ret string, err error) {
	for _, b := range bytes {
		if !isPrintable(b, allowAsterisk, allowAmpersand) {
			err = SyntaxError{"PrintableString contains invalid character", fieldName}
			return
		}
	}
	ret = string(bytes)
	return
}
type asteriskFlag bool
type ampersandFlag bool
const (
	allowAsterisk  asteriskFlag = true
	rejectAsterisk asteriskFlag = false
	allowAmpersand  ampersandFlag = true
	rejectAmpersand ampersandFlag = false
)
func isPrintable(b byte, asterisk asteriskFlag, ampersand ampersandFlag) bool {
	return 'a' <= b && b <= 'z' ||
		'A' <= b && b <= 'Z' ||
		'0' <= b && b <= '9' ||
		'\'' <= b && b <= ')' ||
		'+' <= b && b <= '/' ||
		b == ' ' ||
		b == ':' ||
		b == '=' ||
		b == '?' ||
		(bool(asterisk) && b == '*') ||
		(bool(ampersand) && b == '&')
}
func parseIA5String(bytes []byte, fieldName string) (ret string, err error) {
	for _, b := range bytes {
		if b >= utf8.RuneSelf {
			err = SyntaxError{"IA5String contains invalid character", fieldName}
			return
		}
	}
	ret = string(bytes)
	return
}
func parseT61String(bytes []byte) (ret string, err error) {
	return string(bytes), nil
}
func parseUTF8String(bytes []byte) (ret string, err error) {
	if !utf8.Valid(bytes) {
		return "", errors.New("asn1: invalid UTF-8 string")
	}
	return string(bytes), nil
}
type RawValue struct {
	Class, Tag int
	IsCompound bool
	Bytes      []byte
	FullBytes  []byte  
}
type RawContent []byte
func parseTagAndLength(bytes []byte, initOffset int, fieldName string) (ret tagAndLength, offset int, err error) {
	offset = initOffset
	if offset >= len(bytes) {
		err = errors.New("asn1: internal error in parseTagAndLength")
		return
	}
	b := bytes[offset]
	offset++
	ret.class = int(b >> 6)
	ret.isCompound = b&0x20 == 0x20
	ret.tag = int(b & 0x1f)
	if ret.tag == 0x1f {
		ret.tag, offset, err = parseBase128Int(bytes, offset, fieldName)
		if err != nil {
			return
		}
		if ret.tag < 0x1f {
			err = SyntaxError{"non-minimal tag", fieldName}
			return
		}
	}
	if offset >= len(bytes) {
		err = SyntaxError{"truncated tag or length", fieldName}
		return
	}
	b = bytes[offset]
	offset++
	if b&0x80 == 0 {
		ret.length = int(b & 0x7f)
	} else {
		numBytes := int(b & 0x7f)
		if numBytes == 0 {
			err = SyntaxError{"indefinite length found (not DER)", fieldName}
			return
		}
		ret.length = 0
		for i := 0; i < numBytes; i++ {
			if offset >= len(bytes) {
				err = SyntaxError{"truncated tag or length", fieldName}
				return
			}
			b = bytes[offset]
			offset++
			if ret.length >= 1<<23 {
				err = StructuralError{"length too large", fieldName}
				return
			}
			ret.length <<= 8
			ret.length |= int(b)
			if ret.length == 0 {
				err = StructuralError{"superfluous leading zeros in length", fieldName}
				return
			}
		}
		if ret.length < 0x80 {
			err = StructuralError{"non-minimal length", fieldName}
			return
		}
	}
	return
}