Source file src/pkg/encoding/asn1/common.go
1
2
3
4
5 package asn1
6
7 import (
8 "reflect"
9 "strconv"
10 "strings"
11 )
12
13
14
15
16
17
18
19
20
21
22 const (
23 TagBoolean = 1
24 TagInteger = 2
25 TagBitString = 3
26 TagOctetString = 4
27 TagNull = 5
28 TagOID = 6
29 TagEnum = 10
30 TagUTF8String = 12
31 TagSequence = 16
32 TagSet = 17
33 TagNumericString = 18
34 TagPrintableString = 19
35 TagT61String = 20
36 TagIA5String = 22
37 TagUTCTime = 23
38 TagGeneralizedTime = 24
39 TagGeneralString = 27
40 )
41
42
43 const (
44 ClassUniversal = 0
45 ClassApplication = 1
46 ClassContextSpecific = 2
47 ClassPrivate = 3
48 )
49
50 type tagAndLength struct {
51 class, tag, length int
52 isCompound bool
53 }
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 type fieldParameters struct {
75 optional bool
76 explicit bool
77 application bool
78 private bool
79 defaultValue *int64
80 tag *int
81 stringType int
82 timeType int
83 set bool
84 omitEmpty bool
85
86
87
88 }
89
90
91
92
93 func parseFieldParameters(str string) (ret fieldParameters) {
94 for _, part := range strings.Split(str, ",") {
95 switch {
96 case part == "optional":
97 ret.optional = true
98 case part == "explicit":
99 ret.explicit = true
100 if ret.tag == nil {
101 ret.tag = new(int)
102 }
103 case part == "generalized":
104 ret.timeType = TagGeneralizedTime
105 case part == "utc":
106 ret.timeType = TagUTCTime
107 case part == "ia5":
108 ret.stringType = TagIA5String
109 case part == "printable":
110 ret.stringType = TagPrintableString
111 case part == "numeric":
112 ret.stringType = TagNumericString
113 case part == "utf8":
114 ret.stringType = TagUTF8String
115 case strings.HasPrefix(part, "default:"):
116 i, err := strconv.ParseInt(part[8:], 10, 64)
117 if err == nil {
118 ret.defaultValue = new(int64)
119 *ret.defaultValue = i
120 }
121 case strings.HasPrefix(part, "tag:"):
122 i, err := strconv.Atoi(part[4:])
123 if err == nil {
124 ret.tag = new(int)
125 *ret.tag = i
126 }
127 case part == "set":
128 ret.set = true
129 case part == "application":
130 ret.application = true
131 if ret.tag == nil {
132 ret.tag = new(int)
133 }
134 case part == "private":
135 ret.private = true
136 if ret.tag == nil {
137 ret.tag = new(int)
138 }
139 case part == "omitempty":
140 ret.omitEmpty = true
141 }
142 }
143 return
144 }
145
146
147
148 func getUniversalType(t reflect.Type) (matchAny bool, tagNumber int, isCompound, ok bool) {
149 switch t {
150 case rawValueType:
151 return true, -1, false, true
152 case objectIdentifierType:
153 return false, TagOID, false, true
154 case bitStringType:
155 return false, TagBitString, false, true
156 case timeType:
157 return false, TagUTCTime, false, true
158 case enumeratedType:
159 return false, TagEnum, false, true
160 case bigIntType:
161 return false, TagInteger, false, true
162 }
163 switch t.Kind() {
164 case reflect.Bool:
165 return false, TagBoolean, false, true
166 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
167 return false, TagInteger, false, true
168 case reflect.Struct:
169 return false, TagSequence, true, true
170 case reflect.Slice:
171 if t.Elem().Kind() == reflect.Uint8 {
172 return false, TagOctetString, false, true
173 }
174 if strings.HasSuffix(t.Name(), "SET") {
175 return false, TagSet, true, true
176 }
177 return false, TagSequence, true, true
178 case reflect.String:
179 return false, TagPrintableString, false, true
180 }
181 return false, 0, false, false
182 }
183
View as plain text