The Go Programming Language

Source file src/pkg/asn1/asn1.go

     1	// Copyright 2009 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// Package asn1 implements parsing of DER-encoded ASN.1 data structures,
     6	// as defined in ITU-T Rec X.690.
     7	//
     8	// See also ``A Layman's Guide to a Subset of ASN.1, BER, and DER,''
     9	// http://luca.ntop.org/Teaching/Appunti/asn1.html.
    10	package asn1
    11	
    12	// ASN.1 is a syntax for specifying abstract objects and BER, DER, PER, XER etc
    13	// are different encoding formats for those objects. Here, we'll be dealing
    14	// with DER, the Distinguished Encoding Rules. DER is used in X.509 because
    15	// it's fast to parse and, unlike BER, has a unique encoding for every object.
    16	// When calculating hashes over objects, it's important that the resulting
    17	// bytes be the same at both ends and DER removes this margin of error.
    18	//
    19	// ASN.1 is very complex and this package doesn't attempt to implement
    20	// everything by any means.
    21	
    22	import (
    23		"big"
    24		"fmt"
    25		"os"
    26		"reflect"
    27		"time"
    28	)
    29	
    30	// A StructuralError suggests that the ASN.1 data is valid, but the Go type
    31	// which is receiving it doesn't match.
    32	type StructuralError struct {
    33		Msg string
    34	}
    35	
    36	func (e StructuralError) String() string { return "ASN.1 structure error: " + e.Msg }
    37	
    38	// A SyntaxError suggests that the ASN.1 data is invalid.
    39	type SyntaxError struct {
    40		Msg string
    41	}
    42	
    43	func (e SyntaxError) String() string { return "ASN.1 syntax error: " + e.Msg }
    44	
    45	// We start by dealing with each of the primitive types in turn.
    46	
    47	// BOOLEAN
    48	
    49	func parseBool(bytes []byte) (ret bool, err os.Error) {
    50		if len(bytes) != 1 {
    51			err = SyntaxError{"invalid boolean"}
    52			return
    53		}
    54	
    55		return bytes[0] != 0, nil
    56	}
    57	
    58	// INTEGER
    59	
    60	// parseInt64 treats the given bytes as a big-endian, signed integer and
    61	// returns the result.
    62	func parseInt64(bytes []byte) (ret int64, err os.Error) {
    63		if len(bytes) > 8 {
    64			// We'll overflow an int64 in this case.
    65			err = StructuralError{"integer too large"}
    66			return
    67		}
    68		for bytesRead := 0; bytesRead < len(bytes); bytesRead++ {
    69			ret <<= 8
    70			ret |= int64(bytes[bytesRead])
    71		}
    72	
    73		// Shift up and down in order to sign extend the result.
    74		ret <<= 64 - uint8(len(bytes))*8
    75		ret >>= 64 - uint8(len(bytes))*8
    76		return
    77	}
    78	
    79	// parseInt treats the given bytes as a big-endian, signed integer and returns
    80	// the result.
    81	func parseInt(bytes []byte) (int, os.Error) {
    82		ret64, err := parseInt64(bytes)
    83		if err != nil {
    84			return 0, err
    85		}
    86		if ret64 != int64(int(ret64)) {
    87			return 0, StructuralError{"integer too large"}
    88		}
    89		return int(ret64), nil
    90	}
    91	
    92	var bigOne = big.NewInt(1)
    93	
    94	// parseBigInt treats the given bytes as a big-endian, signed integer and returns
    95	// the result.
    96	func parseBigInt(bytes []byte) *big.Int {
    97		ret := new(big.Int)
    98		if len(bytes) > 0 && bytes[0]&0x80 == 0x80 {
    99			// This is a negative number.
   100			notBytes := make([]byte, len(bytes))
   101			for i := range notBytes {
   102				notBytes[i] = ^bytes[i]
   103			}
   104			ret.SetBytes(notBytes)
   105			ret.Add(ret, bigOne)
   106			ret.Neg(ret)
   107			return ret
   108		}
   109		ret.SetBytes(bytes)
   110		return ret
   111	}
   112	
   113	// BIT STRING
   114	
   115	// BitString is the structure to use when you want an ASN.1 BIT STRING type. A
   116	// bit string is padded up to the nearest byte in memory and the number of
   117	// valid bits is recorded. Padding bits will be zero.
   118	type BitString struct {
   119		Bytes     []byte // bits packed into bytes.
   120		BitLength int    // length in bits.
   121	}
   122	
   123	// At returns the bit at the given index. If the index is out of range it
   124	// returns false.
   125	func (b BitString) At(i int) int {
   126		if i < 0 || i >= b.BitLength {
   127			return 0
   128		}
   129		x := i / 8
   130		y := 7 - uint(i%8)
   131		return int(b.Bytes[x]>>y) & 1
   132	}
   133	
   134	// RightAlign returns a slice where the padding bits are at the beginning. The
   135	// slice may share memory with the BitString.
   136	func (b BitString) RightAlign() []byte {
   137		shift := uint(8 - (b.BitLength % 8))
   138		if shift == 8 || len(b.Bytes) == 0 {
   139			return b.Bytes
   140		}
   141	
   142		a := make([]byte, len(b.Bytes))
   143		a[0] = b.Bytes[0] >> shift
   144		for i := 1; i < len(b.Bytes); i++ {
   145			a[i] = b.Bytes[i-1] << (8 - shift)
   146			a[i] |= b.Bytes[i] >> shift
   147		}
   148	
   149		return a
   150	}
   151	
   152	// parseBitString parses an ASN.1 bit string from the given byte slice and returns it.
   153	func parseBitString(bytes []byte) (ret BitString, err os.Error) {
   154		if len(bytes) == 0 {
   155			err = SyntaxError{"zero length BIT STRING"}
   156			return
   157		}
   158		paddingBits := int(bytes[0])
   159		if paddingBits > 7 ||
   160			len(bytes) == 1 && paddingBits > 0 ||
   161			bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 {
   162			err = SyntaxError{"invalid padding bits in BIT STRING"}
   163			return
   164		}
   165		ret.BitLength = (len(bytes)-1)*8 - paddingBits
   166		ret.Bytes = bytes[1:]
   167		return
   168	}
   169	
   170	// OBJECT IDENTIFIER
   171	
   172	// An ObjectIdentifier represents an ASN.1 OBJECT IDENTIFIER.
   173	type ObjectIdentifier []int
   174	
   175	// Equal returns true iff oi and other represent the same identifier.
   176	func (oi ObjectIdentifier) Equal(other ObjectIdentifier) bool {
   177		if len(oi) != len(other) {
   178			return false
   179		}
   180		for i := 0; i < len(oi); i++ {
   181			if oi[i] != other[i] {
   182				return false
   183			}
   184		}
   185	
   186		return true
   187	}
   188	
   189	// parseObjectIdentifier parses an OBJECT IDENTIFIER from the given bytes and
   190	// returns it. An object identifier is a sequence of variable length integers
   191	// that are assigned in a hierarchy.
   192	func parseObjectIdentifier(bytes []byte) (s []int, err os.Error) {
   193		if len(bytes) == 0 {
   194			err = SyntaxError{"zero length OBJECT IDENTIFIER"}
   195			return
   196		}
   197	
   198		// In the worst case, we get two elements from the first byte (which is
   199		// encoded differently) and then every varint is a single byte long.
   200		s = make([]int, len(bytes)+1)
   201	
   202		// The first byte is 40*value1 + value2:
   203		s[0] = int(bytes[0]) / 40
   204		s[1] = int(bytes[0]) % 40
   205		i := 2
   206		for offset := 1; offset < len(bytes); i++ {
   207			var v int
   208			v, offset, err = parseBase128Int(bytes, offset)
   209			if err != nil {
   210				return
   211			}
   212			s[i] = v
   213		}
   214		s = s[0:i]
   215		return
   216	}
   217	
   218	// ENUMERATED
   219	
   220	// An Enumerated is represented as a plain int.
   221	type Enumerated int
   222	
   223	// FLAG
   224	
   225	// A Flag accepts any data and is set to true if present.
   226	type Flag bool
   227	
   228	// parseBase128Int parses a base-128 encoded int from the given offset in the
   229	// given byte slice. It returns the value and the new offset.
   230	func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, err os.Error) {
   231		offset = initOffset
   232		for shifted := 0; offset < len(bytes); shifted++ {
   233			if shifted > 4 {
   234				err = StructuralError{"base 128 integer too large"}
   235				return
   236			}
   237			ret <<= 7
   238			b := bytes[offset]
   239			ret |= int(b & 0x7f)
   240			offset++
   241			if b&0x80 == 0 {
   242				return
   243			}
   244		}
   245		err = SyntaxError{"truncated base 128 integer"}
   246		return
   247	}
   248	
   249	// UTCTime
   250	
   251	func parseUTCTime(bytes []byte) (ret *time.Time, err os.Error) {
   252		s := string(bytes)
   253		ret, err = time.Parse("0601021504Z0700", s)
   254		if err == nil {
   255			return
   256		}
   257		ret, err = time.Parse("060102150405Z0700", s)
   258		return
   259	}
   260	
   261	// parseGeneralizedTime parses the GeneralizedTime from the given byte slice
   262	// and returns the resulting time.
   263	func parseGeneralizedTime(bytes []byte) (ret *time.Time, err os.Error) {
   264		return time.Parse("20060102150405Z0700", string(bytes))
   265	}
   266	
   267	// PrintableString
   268	
   269	// parsePrintableString parses a ASN.1 PrintableString from the given byte
   270	// array and returns it.
   271	func parsePrintableString(bytes []byte) (ret string, err os.Error) {
   272		for _, b := range bytes {
   273			if !isPrintable(b) {
   274				err = SyntaxError{"PrintableString contains invalid character"}
   275				return
   276			}
   277		}
   278		ret = string(bytes)
   279		return
   280	}
   281	
   282	// isPrintable returns true iff the given b is in the ASN.1 PrintableString set.
   283	func isPrintable(b byte) bool {
   284		return 'a' <= b && b <= 'z' ||
   285			'A' <= b && b <= 'Z' ||
   286			'0' <= b && b <= '9' ||
   287			'\'' <= b && b <= ')' ||
   288			'+' <= b && b <= '/' ||
   289			b == ' ' ||
   290			b == ':' ||
   291			b == '=' ||
   292			b == '?' ||
   293			// This is technically not allowed in a PrintableString.
   294			// However, x509 certificates with wildcard strings don't
   295			// always use the correct string type so we permit it.
   296			b == '*'
   297	}
   298	
   299	// IA5String
   300	
   301	// parseIA5String parses a ASN.1 IA5String (ASCII string) from the given
   302	// byte slice and returns it.
   303	func parseIA5String(bytes []byte) (ret string, err os.Error) {
   304		for _, b := range bytes {
   305			if b >= 0x80 {
   306				err = SyntaxError{"IA5String contains invalid character"}
   307				return
   308			}
   309		}
   310		ret = string(bytes)
   311		return
   312	}
   313	
   314	// T61String
   315	
   316	// parseT61String parses a ASN.1 T61String (8-bit clean string) from the given
   317	// byte slice and returns it.
   318	func parseT61String(bytes []byte) (ret string, err os.Error) {
   319		return string(bytes), nil
   320	}
   321	
   322	// UTF8String
   323	
   324	// parseUTF8String parses a ASN.1 UTF8String (raw UTF-8) from the given byte
   325	// array and returns it.
   326	func parseUTF8String(bytes []byte) (ret string, err os.Error) {
   327		return string(bytes), nil
   328	}
   329	
   330	// A RawValue represents an undecoded ASN.1 object.
   331	type RawValue struct {
   332		Class, Tag int
   333		IsCompound bool
   334		Bytes      []byte
   335		FullBytes  []byte // includes the tag and length
   336	}
   337	
   338	// RawContent is used to signal that the undecoded, DER data needs to be
   339	// preserved for a struct. To use it, the first field of the struct must have
   340	// this type. It's an error for any of the other fields to have this type.
   341	type RawContent []byte
   342	
   343	// Tagging
   344	
   345	// parseTagAndLength parses an ASN.1 tag and length pair from the given offset
   346	// into a byte slice. It returns the parsed data and the new offset. SET and
   347	// SET OF (tag 17) are mapped to SEQUENCE and SEQUENCE OF (tag 16) since we
   348	// don't distinguish between ordered and unordered objects in this code.
   349	func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset int, err os.Error) {
   350		offset = initOffset
   351		b := bytes[offset]
   352		offset++
   353		ret.class = int(b >> 6)
   354		ret.isCompound = b&0x20 == 0x20
   355		ret.tag = int(b & 0x1f)
   356	
   357		// If the bottom five bits are set, then the tag number is actually base 128
   358		// encoded afterwards
   359		if ret.tag == 0x1f {
   360			ret.tag, offset, err = parseBase128Int(bytes, offset)
   361			if err != nil {
   362				return
   363			}
   364		}
   365		if offset >= len(bytes) {
   366			err = SyntaxError{"truncated tag or length"}
   367			return
   368		}
   369		b = bytes[offset]
   370		offset++
   371		if b&0x80 == 0 {
   372			// The length is encoded in the bottom 7 bits.
   373			ret.length = int(b & 0x7f)
   374		} else {
   375			// Bottom 7 bits give the number of length bytes to follow.
   376			numBytes := int(b & 0x7f)
   377			// We risk overflowing a signed 32-bit number if we accept more than 3 bytes.
   378			if numBytes > 3 {
   379				err = StructuralError{"length too large"}
   380				return
   381			}
   382			if numBytes == 0 {
   383				err = SyntaxError{"indefinite length found (not DER)"}
   384				return
   385			}
   386			ret.length = 0
   387			for i := 0; i < numBytes; i++ {
   388				if offset >= len(bytes) {
   389					err = SyntaxError{"truncated tag or length"}
   390					return
   391				}
   392				b = bytes[offset]
   393				offset++
   394				ret.length <<= 8
   395				ret.length |= int(b)
   396			}
   397		}
   398	
   399		return
   400	}
   401	
   402	// parseSequenceOf is used for SEQUENCE OF and SET OF values. It tries to parse
   403	// a number of ASN.1 values from the given byte slice and returns them as a
   404	// slice of Go values of the given type.
   405	func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type) (ret reflect.Value, err os.Error) {
   406		expectedTag, compoundType, ok := getUniversalType(elemType)
   407		if !ok {
   408			err = StructuralError{"unknown Go type for slice"}
   409			return
   410		}
   411	
   412		// First we iterate over the input and count the number of elements,
   413		// checking that the types are correct in each case.
   414		numElements := 0
   415		for offset := 0; offset < len(bytes); {
   416			var t tagAndLength
   417			t, offset, err = parseTagAndLength(bytes, offset)
   418			if err != nil {
   419				return
   420			}
   421			// We pretend that GENERAL STRINGs are PRINTABLE STRINGs so
   422			// that a sequence of them can be parsed into a []string.
   423			if t.tag == tagGeneralString {
   424				t.tag = tagPrintableString
   425			}
   426			if t.class != classUniversal || t.isCompound != compoundType || t.tag != expectedTag {
   427				err = StructuralError{"sequence tag mismatch"}
   428				return
   429			}
   430			if invalidLength(offset, t.length, len(bytes)) {
   431				err = SyntaxError{"truncated sequence"}
   432				return
   433			}
   434			offset += t.length
   435			numElements++
   436		}
   437		ret = reflect.MakeSlice(sliceType, numElements, numElements)
   438		params := fieldParameters{}
   439		offset := 0
   440		for i := 0; i < numElements; i++ {
   441			offset, err = parseField(ret.Index(i), bytes, offset, params)
   442			if err != nil {
   443				return
   444			}
   445		}
   446		return
   447	}
   448	
   449	var (
   450		bitStringType        = reflect.TypeOf(BitString{})
   451		objectIdentifierType = reflect.TypeOf(ObjectIdentifier{})
   452		enumeratedType       = reflect.TypeOf(Enumerated(0))
   453		flagType             = reflect.TypeOf(Flag(false))
   454		timeType             = reflect.TypeOf(&time.Time{})
   455		rawValueType         = reflect.TypeOf(RawValue{})
   456		rawContentsType      = reflect.TypeOf(RawContent(nil))
   457		bigIntType           = reflect.TypeOf(new(big.Int))
   458	)
   459	
   460	// invalidLength returns true iff offset + length > sliceLength, or if the
   461	// addition would overflow.
   462	func invalidLength(offset, length, sliceLength int) bool {
   463		return offset+length < offset || offset+length > sliceLength
   464	}
   465	
   466	// parseField is the main parsing function. Given a byte slice and an offset
   467	// into the array, it will try to parse a suitable ASN.1 value out and store it
   468	// in the given Value.
   469	func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParameters) (offset int, err os.Error) {
   470		offset = initOffset
   471		fieldType := v.Type()
   472	
   473		// If we have run out of data, it may be that there are optional elements at the end.
   474		if offset == len(bytes) {
   475			if !setDefaultValue(v, params) {
   476				err = SyntaxError{"sequence truncated"}
   477			}
   478			return
   479		}
   480	
   481		// Deal with raw values.
   482		if fieldType == rawValueType {
   483			var t tagAndLength
   484			t, offset, err = parseTagAndLength(bytes, offset)
   485			if err != nil {
   486				return
   487			}
   488			if invalidLength(offset, t.length, len(bytes)) {
   489				err = SyntaxError{"data truncated"}
   490				return
   491			}
   492			result := RawValue{t.class, t.tag, t.isCompound, bytes[offset : offset+t.length], bytes[initOffset : offset+t.length]}
   493			offset += t.length
   494			v.Set(reflect.ValueOf(result))
   495			return
   496		}
   497	
   498		// Deal with the ANY type.
   499		if ifaceType := fieldType; ifaceType.Kind() == reflect.Interface && ifaceType.NumMethod() == 0 {
   500			var t tagAndLength
   501			t, offset, err = parseTagAndLength(bytes, offset)
   502			if err != nil {
   503				return
   504			}
   505			if invalidLength(offset, t.length, len(bytes)) {
   506				err = SyntaxError{"data truncated"}
   507				return
   508			}
   509			var result interface{}
   510			if !t.isCompound && t.class == classUniversal {
   511				innerBytes := bytes[offset : offset+t.length]
   512				switch t.tag {
   513				case tagPrintableString:
   514					result, err = parsePrintableString(innerBytes)
   515				case tagIA5String:
   516					result, err = parseIA5String(innerBytes)
   517				case tagT61String:
   518					result, err = parseT61String(innerBytes)
   519				case tagInteger:
   520					result, err = parseInt64(innerBytes)
   521				case tagBitString:
   522					result, err = parseBitString(innerBytes)
   523				case tagOID:
   524					result, err = parseObjectIdentifier(innerBytes)
   525				case tagUTCTime:
   526					result, err = parseUTCTime(innerBytes)
   527				case tagOctetString:
   528					result = innerBytes
   529				default:
   530					// If we don't know how to handle the type, we just leave Value as nil.
   531				}
   532			}
   533			offset += t.length
   534			if err != nil {
   535				return
   536			}
   537			if result != nil {
   538				v.Set(reflect.ValueOf(result))
   539			}
   540			return
   541		}
   542		universalTag, compoundType, ok1 := getUniversalType(fieldType)
   543		if !ok1 {
   544			err = StructuralError{fmt.Sprintf("unknown Go type: %v", fieldType)}
   545			return
   546		}
   547	
   548		t, offset, err := parseTagAndLength(bytes, offset)
   549		if err != nil {
   550			return
   551		}
   552		if params.explicit {
   553			expectedClass := classContextSpecific
   554			if params.application {
   555				expectedClass = classApplication
   556			}
   557			if t.class == expectedClass && t.tag == *params.tag && (t.length == 0 || t.isCompound) {
   558				if t.length > 0 {
   559					t, offset, err = parseTagAndLength(bytes, offset)
   560					if err != nil {
   561						return
   562					}
   563				} else {
   564					if fieldType != flagType {
   565						err = StructuralError{"Zero length explicit tag was not an asn1.Flag"}
   566						return
   567					}
   568					v.SetBool(true)
   569					return
   570				}
   571			} else {
   572				// The tags didn't match, it might be an optional element.
   573				ok := setDefaultValue(v, params)
   574				if ok {
   575					offset = initOffset
   576				} else {
   577					err = StructuralError{"explicitly tagged member didn't match"}
   578				}
   579				return
   580			}
   581		}
   582	
   583		// Special case for strings: all the ASN.1 string types map to the Go
   584		// type string. getUniversalType returns the tag for PrintableString
   585		// when it sees a string, so if we see a different string type on the
   586		// wire, we change the universal type to match.
   587		if universalTag == tagPrintableString {
   588			switch t.tag {
   589			case tagIA5String, tagGeneralString, tagT61String, tagUTF8String:
   590				universalTag = t.tag
   591			}
   592		}
   593	
   594		// Special case for time: UTCTime and GeneralizedTime both map to the
   595		// Go type time.Time.
   596		if universalTag == tagUTCTime && t.tag == tagGeneralizedTime {
   597			universalTag = tagGeneralizedTime
   598		}
   599	
   600		expectedClass := classUniversal
   601		expectedTag := universalTag
   602	
   603		if !params.explicit && params.tag != nil {
   604			expectedClass = classContextSpecific
   605			expectedTag = *params.tag
   606		}
   607	
   608		if !params.explicit && params.application && params.tag != nil {
   609			expectedClass = classApplication
   610			expectedTag = *params.tag
   611		}
   612	
   613		// We have unwrapped any explicit tagging at this point.
   614		if t.class != expectedClass || t.tag != expectedTag || t.isCompound != compoundType {
   615			// Tags don't match. Again, it could be an optional element.
   616			ok := setDefaultValue(v, params)
   617			if ok {
   618				offset = initOffset
   619			} else {
   620				err = StructuralError{fmt.Sprintf("tags don't match (%d vs %+v) %+v %s @%d", expectedTag, t, params, fieldType.Name(), offset)}
   621			}
   622			return
   623		}
   624		if invalidLength(offset, t.length, len(bytes)) {
   625			err = SyntaxError{"data truncated"}
   626			return
   627		}
   628		innerBytes := bytes[offset : offset+t.length]
   629		offset += t.length
   630	
   631		// We deal with the structures defined in this package first.
   632		switch fieldType {
   633		case objectIdentifierType:
   634			newSlice, err1 := parseObjectIdentifier(innerBytes)
   635			v.Set(reflect.MakeSlice(v.Type(), len(newSlice), len(newSlice)))
   636			if err1 == nil {
   637				reflect.Copy(v, reflect.ValueOf(newSlice))
   638			}
   639			err = err1
   640			return
   641		case bitStringType:
   642			bs, err1 := parseBitString(innerBytes)
   643			if err1 == nil {
   644				v.Set(reflect.ValueOf(bs))
   645			}
   646			err = err1
   647			return
   648		case timeType:
   649			var time *time.Time
   650			var err1 os.Error
   651			if universalTag == tagUTCTime {
   652				time, err1 = parseUTCTime(innerBytes)
   653			} else {
   654				time, err1 = parseGeneralizedTime(innerBytes)
   655			}
   656			if err1 == nil {
   657				v.Set(reflect.ValueOf(time))
   658			}
   659			err = err1
   660			return
   661		case enumeratedType:
   662			parsedInt, err1 := parseInt(innerBytes)
   663			if err1 == nil {
   664				v.SetInt(int64(parsedInt))
   665			}
   666			err = err1
   667			return
   668		case flagType:
   669			v.SetBool(true)
   670			return
   671		case bigIntType:
   672			parsedInt := parseBigInt(innerBytes)
   673			v.Set(reflect.ValueOf(parsedInt))
   674			return
   675		}
   676		switch val := v; val.Kind() {
   677		case reflect.Bool:
   678			parsedBool, err1 := parseBool(innerBytes)
   679			if err1 == nil {
   680				val.SetBool(parsedBool)
   681			}
   682			err = err1
   683			return
   684		case reflect.Int, reflect.Int32:
   685			parsedInt, err1 := parseInt(innerBytes)
   686			if err1 == nil {
   687				val.SetInt(int64(parsedInt))
   688			}
   689			err = err1
   690			return
   691		case reflect.Int64:
   692			parsedInt, err1 := parseInt64(innerBytes)
   693			if err1 == nil {
   694				val.SetInt(parsedInt)
   695			}
   696			err = err1
   697			return
   698		// TODO(dfc) Add support for the remaining integer types
   699		case reflect.Struct:
   700			structType := fieldType
   701	
   702			if structType.NumField() > 0 &&
   703				structType.Field(0).Type == rawContentsType {
   704				bytes := bytes[initOffset:offset]
   705				val.Field(0).Set(reflect.ValueOf(RawContent(bytes)))
   706			}
   707	
   708			innerOffset := 0
   709			for i := 0; i < structType.NumField(); i++ {
   710				field := structType.Field(i)
   711				if i == 0 && field.Type == rawContentsType {
   712					continue
   713				}
   714				innerOffset, err = parseField(val.Field(i), innerBytes, innerOffset, parseFieldParameters(field.Tag.Get("asn1")))
   715				if err != nil {
   716					return
   717				}
   718			}
   719			// We allow extra bytes at the end of the SEQUENCE because
   720			// adding elements to the end has been used in X.509 as the
   721			// version numbers have increased.
   722			return
   723		case reflect.Slice:
   724			sliceType := fieldType
   725			if sliceType.Elem().Kind() == reflect.Uint8 {
   726				val.Set(reflect.MakeSlice(sliceType, len(innerBytes), len(innerBytes)))
   727				reflect.Copy(val, reflect.ValueOf(innerBytes))
   728				return
   729			}
   730			newSlice, err1 := parseSequenceOf(innerBytes, sliceType, sliceType.Elem())
   731			if err1 == nil {
   732				val.Set(newSlice)
   733			}
   734			err = err1
   735			return
   736		case reflect.String:
   737			var v string
   738			switch universalTag {
   739			case tagPrintableString:
   740				v, err = parsePrintableString(innerBytes)
   741			case tagIA5String:
   742				v, err = parseIA5String(innerBytes)
   743			case tagT61String:
   744				v, err = parseT61String(innerBytes)
   745			case tagUTF8String:
   746				v, err = parseUTF8String(innerBytes)
   747			case tagGeneralString:
   748				// GeneralString is specified in ISO-2022/ECMA-35,
   749				// A brief review suggests that it includes structures
   750				// that allow the encoding to change midstring and
   751				// such. We give up and pass it as an 8-bit string.
   752				v, err = parseT61String(innerBytes)
   753			default:
   754				err = SyntaxError{fmt.Sprintf("internal error: unknown string type %d", universalTag)}
   755			}
   756			if err == nil {
   757				val.SetString(v)
   758			}
   759			return
   760		}
   761		err = StructuralError{"unsupported: " + v.Type().String()}
   762		return
   763	}
   764	
   765	// setDefaultValue is used to install a default value, from a tag string, into
   766	// a Value. It is successful is the field was optional, even if a default value
   767	// wasn't provided or it failed to install it into the Value.
   768	func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) {
   769		if !params.optional {
   770			return
   771		}
   772		ok = true
   773		if params.defaultValue == nil {
   774			return
   775		}
   776		switch val := v; val.Kind() {
   777		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   778			val.SetInt(*params.defaultValue)
   779		}
   780		return
   781	}
   782	
   783	// Unmarshal parses the DER-encoded ASN.1 data structure b
   784	// and uses the reflect package to fill in an arbitrary value pointed at by val.
   785	// Because Unmarshal uses the reflect package, the structs
   786	// being written to must use upper case field names.
   787	//
   788	// An ASN.1 INTEGER can be written to an int, int32 or int64.
   789	// If the encoded value does not fit in the Go type,
   790	// Unmarshal returns a parse error.
   791	//
   792	// An ASN.1 BIT STRING can be written to a BitString.
   793	//
   794	// An ASN.1 OCTET STRING can be written to a []byte.
   795	//
   796	// An ASN.1 OBJECT IDENTIFIER can be written to an
   797	// ObjectIdentifier.
   798	//
   799	// An ASN.1 ENUMERATED can be written to an Enumerated.
   800	//
   801	// An ASN.1 UTCTIME or GENERALIZEDTIME can be written to a *time.Time.
   802	//
   803	// An ASN.1 PrintableString or IA5String can be written to a string.
   804	//
   805	// Any of the above ASN.1 values can be written to an interface{}.
   806	// The value stored in the interface has the corresponding Go type.
   807	// For integers, that type is int64.
   808	//
   809	// An ASN.1 SEQUENCE OF x or SET OF x can be written
   810	// to a slice if an x can be written to the slice's element type.
   811	//
   812	// An ASN.1 SEQUENCE or SET can be written to a struct
   813	// if each of the elements in the sequence can be
   814	// written to the corresponding element in the struct.
   815	//
   816	// The following tags on struct fields have special meaning to Unmarshal:
   817	//
   818	//	optional		marks the field as ASN.1 OPTIONAL
   819	//	[explicit] tag:x	specifies the ASN.1 tag number; implies ASN.1 CONTEXT SPECIFIC
   820	//	default:x		sets the default value for optional integer fields
   821	//
   822	// If the type of the first field of a structure is RawContent then the raw
   823	// ASN1 contents of the struct will be stored in it.
   824	//
   825	// Other ASN.1 types are not supported; if it encounters them,
   826	// Unmarshal returns a parse error.
   827	func Unmarshal(b []byte, val interface{}) (rest []byte, err os.Error) {
   828		return UnmarshalWithParams(b, val, "")
   829	}
   830	
   831	// UnmarshalWithParams allows field parameters to be specified for the
   832	// top-level element. The form of the params is the same as the field tags.
   833	func UnmarshalWithParams(b []byte, val interface{}, params string) (rest []byte, err os.Error) {
   834		v := reflect.ValueOf(val).Elem()
   835		offset, err := parseField(v, b, 0, parseFieldParameters(params))
   836		if err != nil {
   837			return nil, err
   838		}
   839		return b[offset:], nil
   840	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.