| | |
| | |
| | |
| |
|
| | package asn1 |
| |
|
| | import ( |
| | "reflect" |
| | "strconv" |
| | "strings" |
| | ) |
| |
|
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| |
|
| | |
| | const ( |
| | TagBoolean = 1 |
| | TagInteger = 2 |
| | TagBitString = 3 |
| | TagOctetString = 4 |
| | TagNull = 5 |
| | TagOID = 6 |
| | TagEnum = 10 |
| | TagUTF8String = 12 |
| | TagSequence = 16 |
| | TagSet = 17 |
| | TagNumericString = 18 |
| | TagPrintableString = 19 |
| | TagT61String = 20 |
| | TagIA5String = 22 |
| | TagUTCTime = 23 |
| | TagGeneralizedTime = 24 |
| | TagGeneralString = 27 |
| | TagBMPString = 30 |
| | ) |
| |
|
| | |
| | const ( |
| | ClassUniversal = 0 |
| | ClassApplication = 1 |
| | ClassContextSpecific = 2 |
| | ClassPrivate = 3 |
| | ) |
| |
|
| | type tagAndLength struct { |
| | class, tag, length int |
| | isCompound bool |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | type fieldParameters struct { |
| | optional bool |
| | explicit bool |
| | application bool |
| | private bool |
| | defaultValue *int64 |
| | tag *int |
| | stringType int |
| | timeType int |
| | set bool |
| | omitEmpty bool |
| |
|
| | |
| | |
| | } |
| |
|
| | |
| | |
| | |
| | func parseFieldParameters(str string) (ret fieldParameters) { |
| | var part string |
| | for len(str) > 0 { |
| | part, str, _ = strings.Cut(str, ",") |
| | switch { |
| | case part == "optional": |
| | ret.optional = true |
| | case part == "explicit": |
| | ret.explicit = true |
| | if ret.tag == nil { |
| | ret.tag = new(int) |
| | } |
| | case part == "generalized": |
| | ret.timeType = TagGeneralizedTime |
| | case part == "utc": |
| | ret.timeType = TagUTCTime |
| | case part == "ia5": |
| | ret.stringType = TagIA5String |
| | case part == "printable": |
| | ret.stringType = TagPrintableString |
| | case part == "numeric": |
| | ret.stringType = TagNumericString |
| | case part == "utf8": |
| | ret.stringType = TagUTF8String |
| | case strings.HasPrefix(part, "default:"): |
| | i, err := strconv.ParseInt(part[8:], 10, 64) |
| | if err == nil { |
| | ret.defaultValue = new(int64) |
| | *ret.defaultValue = i |
| | } |
| | case strings.HasPrefix(part, "tag:"): |
| | i, err := strconv.Atoi(part[4:]) |
| | if err == nil { |
| | ret.tag = new(int) |
| | *ret.tag = i |
| | } |
| | case part == "set": |
| | ret.set = true |
| | case part == "application": |
| | ret.application = true |
| | if ret.tag == nil { |
| | ret.tag = new(int) |
| | } |
| | case part == "private": |
| | ret.private = true |
| | if ret.tag == nil { |
| | ret.tag = new(int) |
| | } |
| | case part == "omitempty": |
| | ret.omitEmpty = true |
| | } |
| | } |
| | return |
| | } |
| |
|
| | |
| | |
| | func getUniversalType(t reflect.Type) (matchAny bool, tagNumber int, isCompound, ok bool) { |
| | switch t { |
| | case rawValueType: |
| | return true, -1, false, true |
| | case objectIdentifierType: |
| | return false, TagOID, false, true |
| | case bitStringType: |
| | return false, TagBitString, false, true |
| | case timeType: |
| | return false, TagUTCTime, false, true |
| | case enumeratedType: |
| | return false, TagEnum, false, true |
| | case bigIntType: |
| | return false, TagInteger, false, true |
| | } |
| | switch t.Kind() { |
| | case reflect.Bool: |
| | return false, TagBoolean, false, true |
| | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: |
| | return false, TagInteger, false, true |
| | case reflect.Struct: |
| | return false, TagSequence, true, true |
| | case reflect.Slice: |
| | if t.Elem().Kind() == reflect.Uint8 { |
| | return false, TagOctetString, false, true |
| | } |
| | if strings.HasSuffix(t.Name(), "SET") { |
| | return false, TagSet, true, true |
| | } |
| | return false, TagSequence, true, true |
| | case reflect.String: |
| | return false, TagPrintableString, false, true |
| | } |
| | return false, 0, false, false |
| | } |
| |
|