aboutsummaryrefslogtreecommitdiff
path: root/ber/class.go
blob: b7349648e895aadbd083728dfd89e72f58ce84da (plain)
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
}