diff options
Diffstat (limited to 'src/pkg/encoding/asn1/asn1.go')
-rw-r--r-- | src/pkg/encoding/asn1/asn1.go | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/src/pkg/encoding/asn1/asn1.go b/src/pkg/encoding/asn1/asn1.go index 992356c26..ec7f91c1b 100644 --- a/src/pkg/encoding/asn1/asn1.go +++ b/src/pkg/encoding/asn1/asn1.go @@ -23,6 +23,7 @@ import ( "fmt" "math/big" "reflect" + "strconv" "time" ) @@ -197,6 +198,19 @@ func (oi ObjectIdentifier) Equal(other ObjectIdentifier) bool { 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 +} + // parseObjectIdentifier parses an OBJECT IDENTIFIER from the given bytes and // returns it. An object identifier is a sequence of variable length integers // that are assigned in a hierarchy. @@ -451,11 +465,17 @@ func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type if err != nil { return } - // We pretend that GENERAL STRINGs are PRINTABLE STRINGs so - // that a sequence of them can be parsed into a []string. - if t.tag == tagGeneralString { + switch t.tag { + case tagIA5String, tagGeneralString, tagT61String, tagUTF8String: + // We pretend that various other string types are + // PRINTABLE STRINGs so that a sequence of them can be + // parsed into a []string. t.tag = tagPrintableString + case tagGeneralizedTime, tagUTCTime: + // Likewise, both time types are treated the same. + t.tag = tagUTCTime } + if t.class != classUniversal || t.isCompound != compoundType || t.tag != expectedTag { err = StructuralError{"sequence tag mismatch"} return @@ -632,6 +652,10 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam universalTag = tagGeneralizedTime } + if params.set { + universalTag = tagSet + } + expectedClass := classUniversal expectedTag := universalTag @@ -852,13 +876,20 @@ func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) { // // The following tags on struct fields have special meaning to Unmarshal: // -// optional marks the field as ASN.1 OPTIONAL -// [explicit] tag:x specifies the ASN.1 tag number; implies ASN.1 CONTEXT SPECIFIC -// default:x sets the default value for optional integer fields +// application specifies that a APPLICATION tag is used +// default:x sets the default value for optional integer fields +// explicit specifies that an additional, explicit tag wraps the implicit one +// optional marks the field as ASN.1 OPTIONAL +// set causes a SET, rather than a SEQUENCE type to be expected +// tag:x specifies the ASN.1 tag number; implies ASN.1 CONTEXT SPECIFIC // // If the type of the first field of a structure is RawContent then the raw // ASN1 contents of the struct will be stored in it. // +// If the type name of a slice element ends with "SET" then it's treated as if +// the "set" tag was set on it. This can be used with nested slices where a +// struct tag cannot be given. +// // Other ASN.1 types are not supported; if it encounters them, // Unmarshal returns a parse error. func Unmarshal(b []byte, val interface{}) (rest []byte, err error) { |