1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
package ber
type Class byte
const (
classUniversal Class = iota << 6
classApplication
classContextSpecific
classPrivate
classMask Class = 3 << 6
)
var classNames = map[Class]string{
classUniversal: "Universal",
classApplication: "Application",
classContextSpecific: "Context-specific",
classPrivate: "Private",
}
func (c Class) String() string { return classNames[c] }
type Kind byte
const (
kindPrimitive Kind = iota << 5
kindConstructed
kindMask Kind = 1 << 5
)
var kindNames = map[Kind]string{
kindPrimitive: "Primitive",
kindConstructed: "Constructed",
}
func (k Kind) String() string { return kindNames[k] }
type Tag int
const (
tagEOT Tag = iota
tagBoolean
tagInteger
tagBitString
tagOctetString
tagNull
tagObjectIdentifier
tagObjectDescriptor
tagInstanceOf
tagReal
tagEnumerated
tagEmbeddedPDV
tagUTF8String
tagRelativeOID
_
_
tagSequence // SequenceOf
tagSet // SetOf
tagNumericString
tagPrintableString
tagTeletexString // T61String
tagVideotexString
tagIA5String
tagUTCTime
tagGeneralizedTime
tagGraphicString
tagVisibleString // ISO646String
tagGeneralString
tagUniversalString
tagCharacterString
tagBMPString
tagMask Tag = (1 << 5) - 1
)
var tagNames = map[Tag]string{
tagEOT: "End-of-Content",
tagBoolean: "Boolean",
tagInteger: "Integer",
tagBitString: "Bit String",
tagOctetString: "Octet String",
tagNull: "Null",
tagObjectIdentifier: "Object Identifier",
tagObjectDescriptor: "Object Descriptor",
tagInstanceOf: "Instance Of",
tagReal: "Real",
tagEnumerated: "Enumerated",
tagEmbeddedPDV: "Embedded PDV",
tagUTF8String: "UTF8 String",
tagRelativeOID: "Relative OID",
tagSequence: "Sequence (Of)",
tagSet: "Set (Of)",
tagNumericString: "Numeric String",
tagPrintableString: "Printable String",
tagTeletexString: "Teletext String",
tagVideotexString: "Videotex String",
tagIA5String: "IA5 String",
tagUTCTime: "UTC Time",
tagGeneralizedTime: "Generalized Time",
tagGraphicString: "Graphic String",
tagVisibleString: "Visible String",
tagGeneralString: "General String",
tagUniversalString: "Universal String",
tagCharacterString: "Character String",
tagBMPString: "BMP String",
}
func (t Tag) String() string { return tagNames[t] }
func Ident(b []byte) (Class, Kind, Tag, int) {
var d, n int
c := Class(b[0]) & classMask
k := Kind(b[0]) & kindMask
t := Tag(b[0]) & tagMask
if t == tagMask {
d, n = debase128(b[1:])
t = Tag(d)
}
return c, k, t, n + 1
}
func Unversal(b []byte) (int, bool) {
c, _, t, _ := Ident(b)
return int(t), c == classUniversal
}
func Application(b []byte) (int, bool) {
c, _, t, _ := Ident(b)
return int(t), c == classApplication
}
func ContextSpecific(b []byte) (int, bool) {
c, _, t, _ := Ident(b)
return int(t), c == classContextSpecific
}
func Private(b []byte) (int, bool) {
c, _, t, _ := Ident(b)
return int(t), c == classPrivate
}
func MarshalClass(c Class, k Kind, t Tag) []byte {
tag := base128(int(t))
tag[0] |= byte(c) | byte(k)
return tag
}
|