Codebase list golang-gopkg-asn1-ber.v1 / cced1bf
Imported Upstream version 1.1 aviau 8 years ago
61 changed file(s) with 1246 addition(s) and 155 deletion(s). Raw diff Collapse all Expand all
11 go:
22 - 1.2
33 - 1.3
4 - 1.4
5 - 1.5
46 - tip
7 go_import_path: gopkg.in/asn-ber.v1
58 install:
69 - go list -f '{{range .Imports}}{{.}} {{end}}' ./... | xargs go get -v
710 - go list -f '{{range .TestImports}}{{.}} {{end}}' ./... | xargs go get -v
8 - go get code.google.com/p/go.tools/cmd/cover
11 - go get code.google.com/p/go.tools/cmd/cover || go get golang.org/x/tools/cmd/cover
912 - go build -v ./...
1013 script:
1114 - go test -v -cover ./...
1515 TODO:
1616 Fix all encoding / decoding to conform to ASN1 BER spec
1717 Implement Tests / Benchmarks
18
19 ---
20
21 The Go gopher was designed by Renee French. (http://reneefrench.blogspot.com/)
22 The design is licensed under the Creative Commons 3.0 Attributions license.
23 Read this article for more details: http://blog.golang.org/gopher
+119
-143
ber.go less more
11
22 import (
33 "bytes"
4 "errors"
45 "fmt"
56 "io"
67 "os"
89 )
910
1011 type Packet struct {
11 ClassType Class
12 TagType Type
13 Tag Tag
12 Identifier
1413 Value interface{}
1514 ByteValue []byte
1615 Data *bytes.Buffer
1817 Description string
1918 }
2019
21 type Tag uint8
20 type Identifier struct {
21 ClassType Class
22 TagType Type
23 Tag Tag
24 }
25
26 type Tag uint64
2227
2328 const (
2429 TagEOC Tag = 0x00
5156 TagCharacterString Tag = 0x1d
5257 TagBMPString Tag = 0x1e
5358 TagBitmask Tag = 0x1f // xxx11111b
59
60 // HighTag indicates the start of a high-tag byte sequence
61 HighTag Tag = 0x1f // xxx11111b
62 // HighTagContinueBitmask indicates the high-tag byte sequence should continue
63 HighTagContinueBitmask Tag = 0x80 // 10000000b
64 // HighTagValueBitmask obtains the tag value from a high-tag byte sequence byte
65 HighTagValueBitmask Tag = 0x7f // 01111111b
66 )
67
68 const (
69 // LengthLongFormBitmask is the mask to apply to the length byte to see if a long-form byte sequence is used
70 LengthLongFormBitmask = 0x80
71 // LengthValueBitmask is the mask to apply to the length byte to get the number of bytes in the long-form byte sequence
72 LengthValueBitmask = 0x7f
73
74 // LengthIndefinite is returned from readLength to indicate an indefinite length
75 LengthIndefinite = -1
5476 )
5577
5678 var tagMap = map[Tag]string{
171193 }
172194 }
173195
174 func resizeBuffer(in []byte, new_size int) (out []byte) {
175 out = make([]byte, new_size)
176
177 copy(out, in)
178
179 return
180 }
181
196 // ReadPacket reads a single Packet from the reader
182197 func ReadPacket(reader io.Reader) (*Packet, error) {
183 var header [2]byte
184 buf := header[:]
185 _, err := io.ReadFull(reader, buf)
186
198 p, _, err := readPacket(reader)
187199 if err != nil {
188200 return nil, err
189201 }
190
191 idx := 2
192 var datalen int
193 l := buf[1]
194
195 if l&0x80 == 0 {
196 // The length is encoded in the bottom 7 bits.
197 datalen = int(l & 0x7f)
198 if Debug {
199 fmt.Printf("Read: datalen = %d len(buf) = %d\n ", l, len(buf))
200
201 for _, b := range buf {
202 fmt.Printf("%02X ", b)
203 }
204
205 fmt.Printf("\n")
206 }
207 } else {
208 // Bottom 7 bits give the number of length bytes to follow.
209 numBytes := int(l & 0x7f)
210 if numBytes == 0 {
211 return nil, fmt.Errorf("invalid length found")
212 }
213 idx += numBytes
214 buf = resizeBuffer(buf, 2+numBytes)
215 _, err := io.ReadFull(reader, buf[2:])
216
217 if err != nil {
218 return nil, err
219 }
220 datalen = 0
221 for i := 0; i < numBytes; i++ {
222 b := buf[2+i]
223 datalen <<= 8
224 datalen |= int(b)
225 }
226
227 if Debug {
228 fmt.Printf("Read: datalen = %d numbytes=%d len(buf) = %d\n ", datalen, numBytes, len(buf))
229
230 for _, b := range buf {
231 fmt.Printf("%02X ", b)
232 }
233
234 fmt.Printf("\n")
235 }
236 }
237
238 buf = resizeBuffer(buf, idx+datalen)
239 _, err = io.ReadFull(reader, buf[idx:])
240
241 if err != nil {
242 return nil, err
243 }
244
245 if Debug {
246 fmt.Printf("Read: len( buf ) = %d idx=%d datalen=%d idx+datalen=%d\n ", len(buf), idx, datalen, idx+datalen)
247
248 for _, b := range buf {
249 fmt.Printf("%02X ", b)
250 }
251 }
252
253 p, _ := decodePacket(buf)
254
255202 return p, nil
256203 }
257204
305252 return
306253 }
307254
255 // DecodePacket decodes the given bytes into a single Packet
256 // If a decode error is encountered, nil is returned.
308257 func DecodePacket(data []byte) *Packet {
309 p, _ := decodePacket(data)
258 p, _, _ := readPacket(bytes.NewBuffer(data))
310259
311260 return p
312261 }
313262
314 func decodePacket(data []byte) (*Packet, []byte) {
315 if Debug {
316 fmt.Printf("decodePacket: enter %d\n", len(data))
317 }
318
319 p := new(Packet)
320
321 p.ClassType = Class(data[0]) & ClassBitmask
322 p.TagType = Type(data[0]) & TypeBitmask
323 p.Tag = Tag(data[0]) & TagBitmask
324
325 var datalen int
326 l := data[1]
327 datapos := 2
328 if l&0x80 == 0 {
329 // The length is encoded in the bottom 7 bits.
330 datalen = int(l & 0x7f)
331 } else {
332 // Bottom 7 bits give the number of length bytes to follow.
333 numBytes := int(l & 0x7f)
334 if numBytes == 0 {
335 return nil, nil
336 }
337 datapos += numBytes
338 datalen = 0
339 for i := 0; i < numBytes; i++ {
340 b := data[2+i]
341 datalen <<= 8
342 datalen |= int(b)
343 }
263 // DecodePacketErr decodes the given bytes into a single Packet
264 // If a decode error is encountered, nil is returned
265 func DecodePacketErr(data []byte) (*Packet, error) {
266 p, _, err := readPacket(bytes.NewBuffer(data))
267 if err != nil {
268 return nil, err
269 }
270 return p, nil
271 }
272
273 // readPacket reads a single Packet from the reader, returning the number of bytes read
274 func readPacket(reader io.Reader) (*Packet, int, error) {
275 identifier, length, read, err := readHeader(reader)
276 if err != nil {
277 return nil, read, err
278 }
279
280 p := &Packet{
281 Identifier: identifier,
344282 }
345283
346284 p.Data = new(bytes.Buffer)
347
348285 p.Children = make([]*Packet, 0, 2)
349
350286 p.Value = nil
351287
352 value_data := data[datapos : datapos+datalen]
353
354288 if p.TagType == TypeConstructed {
355 for len(value_data) != 0 {
356 var child *Packet
357
358 child, value_data = decodePacket(value_data)
289 // TODO: if universal, ensure tag type is allowed to be constructed
290
291 // Track how much content we've read
292 contentRead := 0
293 for {
294 if length != LengthIndefinite {
295 // End if we've read what we've been told to
296 if contentRead == length {
297 break
298 }
299 // Detect if a packet boundary didn't fall on the expected length
300 if contentRead > length {
301 return nil, read, fmt.Errorf("expected to read %d bytes, read %d", length, contentRead)
302 }
303 }
304
305 // Read the next packet
306 child, r, err := readPacket(reader)
307 if err != nil {
308 return nil, read, err
309 }
310 contentRead += r
311 read += r
312
313 // Test is this is the EOC marker for our packet
314 if isEOCPacket(child) {
315 if length == LengthIndefinite {
316 break
317 }
318 return nil, read, errors.New("eoc child not allowed with definite length")
319 }
320
321 // Append and continue
359322 p.AppendChild(child)
360323 }
361 } else if p.ClassType == ClassUniversal {
362 p.Data.Write(data[datapos : datapos+datalen])
363 p.ByteValue = value_data
324 return p, read, nil
325 }
326
327 if length == LengthIndefinite {
328 return nil, read, errors.New("indefinite length used with primitive type")
329 }
330
331 // Read definite-length content
332 content := make([]byte, length, length)
333 if length > 0 {
334 _, err := io.ReadFull(reader, content)
335 if err != nil {
336 if err == io.EOF {
337 return nil, read, io.ErrUnexpectedEOF
338 }
339 return nil, read, err
340 }
341 read += length
342 }
343
344 if p.ClassType == ClassUniversal {
345 p.Data.Write(content)
346 p.ByteValue = content
364347
365348 switch p.Tag {
366349 case TagEOC:
367350 case TagBoolean:
368 val, _ := parseInt64(value_data)
351 val, _ := parseInt64(content)
369352
370353 p.Value = val != 0
371354 case TagInteger:
372 p.Value, _ = parseInt64(value_data)
355 p.Value, _ = parseInt64(content)
373356 case TagBitString:
374357 case TagOctetString:
375358 // the actual string encoding is not known here
376 // (e.g. for LDAP value_data is already an UTF8-encoded
359 // (e.g. for LDAP content is already an UTF8-encoded
377360 // string). Return the data without further processing
378 p.Value = DecodeString(value_data)
361 p.Value = DecodeString(content)
379362 case TagNULL:
380363 case TagObjectIdentifier:
381364 case TagObjectDescriptor:
382365 case TagExternal:
383366 case TagRealFloat:
384367 case TagEnumerated:
385 p.Value, _ = parseInt64(value_data)
368 p.Value, _ = parseInt64(content)
386369 case TagEmbeddedPDV:
387370 case TagUTF8String:
371 p.Value = DecodeString(content)
388372 case TagRelativeOID:
389373 case TagSequence:
390374 case TagSet:
391375 case TagNumericString:
392376 case TagPrintableString:
393 p.Value = DecodeString(value_data)
377 p.Value = DecodeString(content)
394378 case TagT61String:
395379 case TagVideotexString:
396380 case TagIA5String:
404388 case TagBMPString:
405389 }
406390 } else {
407 p.Data.Write(data[datapos : datapos+datalen])
408 }
409
410 return p, data[datapos+datalen:]
391 p.Data.Write(content)
392 }
393
394 return p, read, nil
411395 }
412396
413397 func (p *Packet) Bytes() []byte {
414398 var out bytes.Buffer
415399
416 out.Write([]byte{byte(p.ClassType) | byte(p.TagType) | byte(p.Tag)})
417 packet_length := encodeInteger(int64(p.Data.Len()))
418
419 if p.Data.Len() > 127 || len(packet_length) > 1 {
420 out.Write([]byte{byte(len(packet_length) | 128)})
421 out.Write(packet_length)
422 } else {
423 out.Write(packet_length)
424 }
425
400 out.Write(encodeIdentifier(p.Identifier))
401 out.Write(encodeLength(p.Data.Len()))
426402 out.Write(p.Data.Bytes())
427403
428404 return out.Bytes()
11
22 import (
33 "bytes"
4 "math"
45
56 "io"
67 "testing"
78 )
89
910 func TestEncodeDecodeInteger(t *testing.T) {
10 for _, v := range []int64{0, 10, 128, 1024, -1, -100, -128, -1024} {
11 for _, v := range []int64{0, 10, 128, 1024, math.MaxInt64, -1, -100, -128, -1024, math.MinInt64} {
1112 enc := encodeInteger(v)
1213 dec, err := parseInt64(enc)
1314 if err != nil {
8889
8990 func TestSequenceAndAppendChild(t *testing.T) {
9091
91 p1 := NewString(ClassUniversal, TypePrimitive, TagOctetString, "HIC SVNT LEONES", "String")
92 p2 := NewString(ClassUniversal, TypePrimitive, TagOctetString, "HIC SVNT DRACONES", "String")
93 p3 := NewString(ClassUniversal, TypePrimitive, TagOctetString, "Terra Incognita", "String")
92 values := []string{
93 "HIC SVNT LEONES",
94 "Iñtërnâtiônàlizætiøn",
95 "Terra Incognita",
96 }
9497
9598 sequence := NewSequence("a sequence")
96 sequence.AppendChild(p1)
97 sequence.AppendChild(p2)
98 sequence.AppendChild(p3)
99 for _, s := range values {
100 sequence.AppendChild(NewString(ClassUniversal, TypePrimitive, TagOctetString, s, "String"))
101 }
99102
100 if len(sequence.Children) != 3 {
101 t.Error("wrong length for children array should be three =>", len(sequence.Children))
103 if len(sequence.Children) != len(values) {
104 t.Errorf("wrong length for children array should be %d, got %d", len(values), len(sequence.Children))
102105 }
103106
104107 encodedSequence := sequence.Bytes()
105108
106109 decodedSequence := DecodePacket(encodedSequence)
107 if len(decodedSequence.Children) != 3 {
108 t.Error("wrong length for children array should be three =>", len(decodedSequence.Children))
110 if len(decodedSequence.Children) != len(values) {
111 t.Errorf("wrong length for children array should be %d => %d", len(values), len(decodedSequence.Children))
109112 }
110113
114 for i, s := range values {
115 if decodedSequence.Children[i].Value.(string) != s {
116 t.Errorf("expected %d to be %q, got %q", i, s, decodedSequence.Children[i].Value.(string))
117 }
118 }
111119 }
112120
113121 func TestReadPacket(t *testing.T) {
139147 {v: 256, e: []byte{0x02, 0x02, 0x01, 0x00}},
140148 {v: -128, e: []byte{0x02, 0x01, 0x80}},
141149 {v: -129, e: []byte{0x02, 0x02, 0xFF, 0x7F}},
150 {v: math.MaxInt64, e: []byte{0x02, 0x08, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
151 {v: math.MinInt64, e: []byte{0x02, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
142152 }
143153
144154 for _, d := range data {
0 package ber
1
2 func encodeUnsignedInteger(i uint64) []byte {
3 n := uint64Length(i)
4 out := make([]byte, n)
5
6 var j int
7 for ; n > 0; n-- {
8 out[j] = (byte(i >> uint((n-1)*8)))
9 j++
10 }
11
12 return out
13 }
14
15 func uint64Length(i uint64) (numBytes int) {
16 numBytes = 1
17
18 for i > 255 {
19 numBytes++
20 i >>= 8
21 }
22
23 return
24 }
0 package ber
1
2 import (
3 "errors"
4 "io"
5 )
6
7 func readHeader(reader io.Reader) (identifier Identifier, length int, read int, err error) {
8 if i, c, err := readIdentifier(reader); err != nil {
9 return Identifier{}, 0, read, err
10 } else {
11 identifier = i
12 read += c
13 }
14
15 if l, c, err := readLength(reader); err != nil {
16 return Identifier{}, 0, read, err
17 } else {
18 length = l
19 read += c
20 }
21
22 // Validate length type with identifier (x.600, 8.1.3.2.a)
23 if length == LengthIndefinite && identifier.TagType == TypePrimitive {
24 return Identifier{}, 0, read, errors.New("indefinite length used with primitive type")
25 }
26
27 return identifier, length, read, nil
28 }
0 package ber
1
2 import (
3 "bytes"
4 "io"
5 "testing"
6 )
7
8 func TestReadHeader(t *testing.T) {
9 testcases := map[string]struct {
10 Data []byte
11 ExpectedIdentifier Identifier
12 ExpectedLength int
13 ExpectedBytesRead int
14 ExpectedError string
15 }{
16 "empty": {
17 Data: []byte{},
18 ExpectedIdentifier: Identifier{},
19 ExpectedLength: 0,
20 ExpectedBytesRead: 0,
21 ExpectedError: io.ErrUnexpectedEOF.Error(),
22 },
23
24 "valid short form": {
25 Data: []byte{
26 byte(ClassUniversal) | byte(TypePrimitive) | byte(TagCharacterString),
27 127,
28 },
29 ExpectedIdentifier: Identifier{
30 ClassType: ClassUniversal,
31 TagType: TypePrimitive,
32 Tag: TagCharacterString,
33 },
34 ExpectedLength: 127,
35 ExpectedBytesRead: 2,
36 ExpectedError: "",
37 },
38
39 "valid long form": {
40 Data: []byte{
41 // 2-byte encoding of tag
42 byte(ClassUniversal) | byte(TypePrimitive) | byte(HighTag),
43 byte(TagCharacterString),
44
45 // 2-byte encoding of length
46 LengthLongFormBitmask | 1,
47 127,
48 },
49 ExpectedIdentifier: Identifier{
50 ClassType: ClassUniversal,
51 TagType: TypePrimitive,
52 Tag: TagCharacterString,
53 },
54 ExpectedLength: 127,
55 ExpectedBytesRead: 4,
56 ExpectedError: "",
57 },
58
59 "valid indefinite length": {
60 Data: []byte{
61 byte(ClassUniversal) | byte(TypeConstructed) | byte(TagCharacterString),
62 LengthLongFormBitmask,
63 },
64 ExpectedIdentifier: Identifier{
65 ClassType: ClassUniversal,
66 TagType: TypeConstructed,
67 Tag: TagCharacterString,
68 },
69 ExpectedLength: LengthIndefinite,
70 ExpectedBytesRead: 2,
71 ExpectedError: "",
72 },
73
74 "invalid indefinite length": {
75 Data: []byte{
76 byte(ClassUniversal) | byte(TypePrimitive) | byte(TagCharacterString),
77 LengthLongFormBitmask,
78 },
79 ExpectedIdentifier: Identifier{},
80 ExpectedLength: 0,
81 ExpectedBytesRead: 2,
82 ExpectedError: "indefinite length used with primitive type",
83 },
84 }
85
86 for k, tc := range testcases {
87 reader := bytes.NewBuffer(tc.Data)
88 identifier, length, read, err := readHeader(reader)
89
90 if err != nil {
91 if tc.ExpectedError == "" {
92 t.Errorf("%s: unexpected error: %v", k, err)
93 } else if err.Error() != tc.ExpectedError {
94 t.Errorf("%s: expected error %v, got %v", k, tc.ExpectedError, err)
95 }
96 } else if tc.ExpectedError != "" {
97 t.Errorf("%s: expected error %v, got none", k, tc.ExpectedError)
98 continue
99 }
100
101 if read != tc.ExpectedBytesRead {
102 t.Errorf("%s: expected read %d, got %d", k, tc.ExpectedBytesRead, read)
103 }
104
105 if identifier.ClassType != tc.ExpectedIdentifier.ClassType {
106 t.Errorf("%s: expected class type %d (%s), got %d (%s)", k,
107 tc.ExpectedIdentifier.ClassType,
108 ClassMap[tc.ExpectedIdentifier.ClassType],
109 identifier.ClassType,
110 ClassMap[identifier.ClassType],
111 )
112 }
113 if identifier.TagType != tc.ExpectedIdentifier.TagType {
114 t.Errorf("%s: expected tag type %d (%s), got %d (%s)", k,
115 tc.ExpectedIdentifier.TagType,
116 TypeMap[tc.ExpectedIdentifier.TagType],
117 identifier.TagType,
118 TypeMap[identifier.TagType],
119 )
120 }
121 if identifier.Tag != tc.ExpectedIdentifier.Tag {
122 t.Errorf("%s: expected tag %d (%s), got %d (%s)", k,
123 tc.ExpectedIdentifier.Tag,
124 tagMap[tc.ExpectedIdentifier.Tag],
125 identifier.Tag,
126 tagMap[identifier.Tag],
127 )
128 }
129
130 if length != tc.ExpectedLength {
131 t.Errorf("%s: expected length %d, got %d", k, tc.ExpectedLength, length)
132 }
133 }
134 }
0 package ber
1
2 import (
3 "errors"
4 "fmt"
5 "io"
6 "math"
7 )
8
9 func readIdentifier(reader io.Reader) (Identifier, int, error) {
10 identifier := Identifier{}
11 read := 0
12
13 // identifier byte
14 b, err := readByte(reader)
15 if err != nil {
16 if Debug {
17 fmt.Printf("error reading identifier byte: %v\n", err)
18 }
19 return Identifier{}, read, err
20 }
21 read++
22
23 identifier.ClassType = Class(b) & ClassBitmask
24 identifier.TagType = Type(b) & TypeBitmask
25
26 if tag := Tag(b) & TagBitmask; tag != HighTag {
27 // short-form tag
28 identifier.Tag = tag
29 return identifier, read, nil
30 }
31
32 // high-tag-number tag
33 tagBytes := 0
34 for {
35 b, err := readByte(reader)
36 if err != nil {
37 if Debug {
38 fmt.Printf("error reading high-tag-number tag byte %d: %v\n", tagBytes, err)
39 }
40 return Identifier{}, read, err
41 }
42 tagBytes++
43 read++
44
45 // Lowest 7 bits get appended to the tag value (x.690, 8.1.2.4.2.b)
46 identifier.Tag <<= 7
47 identifier.Tag |= Tag(b) & HighTagValueBitmask
48
49 // First byte may not be all zeros (x.690, 8.1.2.4.2.c)
50 if tagBytes == 1 && identifier.Tag == 0 {
51 return Identifier{}, read, errors.New("invalid first high-tag-number tag byte")
52 }
53 // Overflow of int64
54 // TODO: support big int tags?
55 if tagBytes > 9 {
56 return Identifier{}, read, errors.New("high-tag-number tag overflow")
57 }
58
59 // Top bit of 0 means this is the last byte in the high-tag-number tag (x.690, 8.1.2.4.2.a)
60 if Tag(b)&HighTagContinueBitmask == 0 {
61 break
62 }
63 }
64
65 return identifier, read, nil
66 }
67
68 func encodeIdentifier(identifier Identifier) []byte {
69 b := []byte{0x0}
70 b[0] |= byte(identifier.ClassType)
71 b[0] |= byte(identifier.TagType)
72
73 if identifier.Tag < HighTag {
74 // Short-form
75 b[0] |= byte(identifier.Tag)
76 } else {
77 // high-tag-number
78 b[0] |= byte(HighTag)
79
80 tag := identifier.Tag
81
82 highBit := uint(63)
83 for {
84 if tag&(1<<highBit) != 0 {
85 break
86 }
87 highBit--
88 }
89
90 tagBytes := int(math.Ceil(float64(highBit) / 7.0))
91 for i := tagBytes - 1; i >= 0; i-- {
92 offset := uint(i) * 7
93 mask := Tag(0x7f) << offset
94 tagByte := (tag & mask) >> offset
95 if i != 0 {
96 tagByte |= 0x80
97 }
98 b = append(b, byte(tagByte))
99 }
100 }
101 return b
102 }
0 package ber
1
2 import (
3 "bytes"
4 "io"
5 "math"
6 "testing"
7 )
8
9 func TestReadIdentifier(t *testing.T) {
10 testcases := map[string]struct {
11 Data []byte
12
13 ExpectedIdentifier Identifier
14 ExpectedBytesRead int
15 ExpectedError string
16 }{
17 "empty": {
18 Data: []byte{},
19 ExpectedBytesRead: 0,
20 ExpectedError: io.ErrUnexpectedEOF.Error(),
21 },
22
23 "universal primitive eoc": {
24 Data: []byte{byte(ClassUniversal) | byte(TypePrimitive) | byte(TagEOC)},
25 ExpectedIdentifier: Identifier{
26 ClassType: ClassUniversal,
27 TagType: TypePrimitive,
28 Tag: TagEOC,
29 },
30 ExpectedBytesRead: 1,
31 },
32 "universal primitive character string": {
33 Data: []byte{byte(ClassUniversal) | byte(TypePrimitive) | byte(TagCharacterString)},
34 ExpectedIdentifier: Identifier{
35 ClassType: ClassUniversal,
36 TagType: TypePrimitive,
37 Tag: TagCharacterString,
38 },
39 ExpectedBytesRead: 1,
40 },
41
42 "universal constructed bit string": {
43 Data: []byte{byte(ClassUniversal) | byte(TypeConstructed) | byte(TagBitString)},
44 ExpectedIdentifier: Identifier{
45 ClassType: ClassUniversal,
46 TagType: TypeConstructed,
47 Tag: TagBitString,
48 },
49 ExpectedBytesRead: 1,
50 },
51 "universal constructed character string": {
52 Data: []byte{byte(ClassUniversal) | byte(TypeConstructed) | byte(TagCharacterString)},
53 ExpectedIdentifier: Identifier{
54 ClassType: ClassUniversal,
55 TagType: TypeConstructed,
56 Tag: TagCharacterString,
57 },
58 ExpectedBytesRead: 1,
59 },
60
61 "application constructed object descriptor": {
62 Data: []byte{byte(ClassApplication) | byte(TypeConstructed) | byte(TagObjectDescriptor)},
63 ExpectedIdentifier: Identifier{
64 ClassType: ClassApplication,
65 TagType: TypeConstructed,
66 Tag: TagObjectDescriptor,
67 },
68 ExpectedBytesRead: 1,
69 },
70 "context constructed object descriptor": {
71 Data: []byte{byte(ClassContext) | byte(TypeConstructed) | byte(TagObjectDescriptor)},
72 ExpectedIdentifier: Identifier{
73 ClassType: ClassContext,
74 TagType: TypeConstructed,
75 Tag: TagObjectDescriptor,
76 },
77 ExpectedBytesRead: 1,
78 },
79 "private constructed object descriptor": {
80 Data: []byte{byte(ClassPrivate) | byte(TypeConstructed) | byte(TagObjectDescriptor)},
81 ExpectedIdentifier: Identifier{
82 ClassType: ClassPrivate,
83 TagType: TypeConstructed,
84 Tag: TagObjectDescriptor,
85 },
86 ExpectedBytesRead: 1,
87 },
88
89 "high-tag-number tag missing bytes": {
90 Data: []byte{byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag)},
91 ExpectedError: io.ErrUnexpectedEOF.Error(),
92 ExpectedBytesRead: 1,
93 },
94 "high-tag-number tag invalid first byte": {
95 Data: []byte{byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag), 0x0},
96 ExpectedError: "invalid first high-tag-number tag byte",
97 ExpectedBytesRead: 2,
98 },
99 "high-tag-number tag invalid first byte with continue bit": {
100 Data: []byte{byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag), byte(HighTagContinueBitmask)},
101 ExpectedError: "invalid first high-tag-number tag byte",
102 ExpectedBytesRead: 2,
103 },
104 "high-tag-number tag continuation missing bytes": {
105 Data: []byte{byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag), byte(HighTagContinueBitmask | 0x1)},
106 ExpectedError: io.ErrUnexpectedEOF.Error(),
107 ExpectedBytesRead: 2,
108 },
109 "high-tag-number tag overflow": {
110 Data: []byte{
111 byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag),
112 byte(HighTagContinueBitmask | 0x1),
113 byte(HighTagContinueBitmask | 0x1),
114 byte(HighTagContinueBitmask | 0x1),
115 byte(HighTagContinueBitmask | 0x1),
116 byte(HighTagContinueBitmask | 0x1),
117 byte(HighTagContinueBitmask | 0x1),
118 byte(HighTagContinueBitmask | 0x1),
119 byte(HighTagContinueBitmask | 0x1),
120 byte(HighTagContinueBitmask | 0x1),
121 byte(0x1),
122 },
123 ExpectedError: "high-tag-number tag overflow",
124 ExpectedBytesRead: 11,
125 },
126 "max high-tag-number tag": {
127 Data: []byte{
128 byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag),
129 byte(HighTagContinueBitmask | 0x7f),
130 byte(HighTagContinueBitmask | 0x7f),
131 byte(HighTagContinueBitmask | 0x7f),
132 byte(HighTagContinueBitmask | 0x7f),
133 byte(HighTagContinueBitmask | 0x7f),
134 byte(HighTagContinueBitmask | 0x7f),
135 byte(HighTagContinueBitmask | 0x7f),
136 byte(HighTagContinueBitmask | 0x7f),
137 byte(0x7f),
138 },
139 ExpectedIdentifier: Identifier{
140 ClassType: ClassUniversal,
141 TagType: TypeConstructed,
142 Tag: Tag(0x7FFFFFFFFFFFFFFF), // 01111111...(63)...11111b
143 },
144 ExpectedBytesRead: 10,
145 },
146 "high-tag-number encoding of low-tag value": {
147 Data: []byte{
148 byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag),
149 byte(TagObjectDescriptor),
150 },
151 ExpectedIdentifier: Identifier{
152 ClassType: ClassUniversal,
153 TagType: TypeConstructed,
154 Tag: TagObjectDescriptor,
155 },
156 ExpectedBytesRead: 2,
157 },
158 "max high-tag-number tag ignores extra data": {
159 Data: []byte{
160 byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag),
161 byte(HighTagContinueBitmask | 0x7f),
162 byte(HighTagContinueBitmask | 0x7f),
163 byte(HighTagContinueBitmask | 0x7f),
164 byte(HighTagContinueBitmask | 0x7f),
165 byte(HighTagContinueBitmask | 0x7f),
166 byte(HighTagContinueBitmask | 0x7f),
167 byte(HighTagContinueBitmask | 0x7f),
168 byte(HighTagContinueBitmask | 0x7f),
169 byte(0x7f),
170 byte(0x01), // extra data, shouldn't be read
171 byte(0x02), // extra data, shouldn't be read
172 byte(0x03), // extra data, shouldn't be read
173 },
174 ExpectedIdentifier: Identifier{
175 ClassType: ClassUniversal,
176 TagType: TypeConstructed,
177 Tag: Tag(0x7FFFFFFFFFFFFFFF), // 01111111...(63)...11111b
178 },
179 ExpectedBytesRead: 10,
180 },
181 }
182
183 for k, tc := range testcases {
184 reader := bytes.NewBuffer(tc.Data)
185 identifier, read, err := readIdentifier(reader)
186
187 if err != nil {
188 if tc.ExpectedError == "" {
189 t.Errorf("%s: unexpected error: %v", k, err)
190 } else if err.Error() != tc.ExpectedError {
191 t.Errorf("%s: expected error %v, got %v", k, tc.ExpectedError, err)
192 }
193 } else if tc.ExpectedError != "" {
194 t.Errorf("%s: expected error %v, got none", k, tc.ExpectedError)
195 continue
196 }
197
198 if read != tc.ExpectedBytesRead {
199 t.Errorf("%s: expected read %d, got %d", k, tc.ExpectedBytesRead, read)
200 }
201
202 if identifier.ClassType != tc.ExpectedIdentifier.ClassType {
203 t.Errorf("%s: expected class type %d (%s), got %d (%s)", k,
204 tc.ExpectedIdentifier.ClassType,
205 ClassMap[tc.ExpectedIdentifier.ClassType],
206 identifier.ClassType,
207 ClassMap[identifier.ClassType],
208 )
209 }
210 if identifier.TagType != tc.ExpectedIdentifier.TagType {
211 t.Errorf("%s: expected tag type %d (%s), got %d (%s)", k,
212 tc.ExpectedIdentifier.TagType,
213 TypeMap[tc.ExpectedIdentifier.TagType],
214 identifier.TagType,
215 TypeMap[identifier.TagType],
216 )
217 }
218 if identifier.Tag != tc.ExpectedIdentifier.Tag {
219 t.Errorf("%s: expected tag %d (%s), got %d (%s)", k,
220 tc.ExpectedIdentifier.Tag,
221 tagMap[tc.ExpectedIdentifier.Tag],
222 identifier.Tag,
223 tagMap[identifier.Tag],
224 )
225 }
226 }
227 }
228
229 func TestEncodeIdentifier(t *testing.T) {
230 testcases := map[string]struct {
231 Identifier Identifier
232 ExpectedBytes []byte
233 }{
234 "universal primitive eoc": {
235 Identifier: Identifier{
236 ClassType: ClassUniversal,
237 TagType: TypePrimitive,
238 Tag: TagEOC,
239 },
240 ExpectedBytes: []byte{byte(ClassUniversal) | byte(TypePrimitive) | byte(TagEOC)},
241 },
242 "universal primitive character string": {
243 Identifier: Identifier{
244 ClassType: ClassUniversal,
245 TagType: TypePrimitive,
246 Tag: TagCharacterString,
247 },
248 ExpectedBytes: []byte{byte(ClassUniversal) | byte(TypePrimitive) | byte(TagCharacterString)},
249 },
250
251 "universal constructed bit string": {
252 Identifier: Identifier{
253 ClassType: ClassUniversal,
254 TagType: TypeConstructed,
255 Tag: TagBitString,
256 },
257 ExpectedBytes: []byte{byte(ClassUniversal) | byte(TypeConstructed) | byte(TagBitString)},
258 },
259 "universal constructed character string": {
260 Identifier: Identifier{
261 ClassType: ClassUniversal,
262 TagType: TypeConstructed,
263 Tag: TagCharacterString,
264 },
265 ExpectedBytes: []byte{byte(ClassUniversal) | byte(TypeConstructed) | byte(TagCharacterString)},
266 },
267
268 "application constructed object descriptor": {
269 Identifier: Identifier{
270 ClassType: ClassApplication,
271 TagType: TypeConstructed,
272 Tag: TagObjectDescriptor,
273 },
274 ExpectedBytes: []byte{byte(ClassApplication) | byte(TypeConstructed) | byte(TagObjectDescriptor)},
275 },
276 "context constructed object descriptor": {
277 Identifier: Identifier{
278 ClassType: ClassContext,
279 TagType: TypeConstructed,
280 Tag: TagObjectDescriptor,
281 },
282 ExpectedBytes: []byte{byte(ClassContext) | byte(TypeConstructed) | byte(TagObjectDescriptor)},
283 },
284 "private constructed object descriptor": {
285 Identifier: Identifier{
286 ClassType: ClassPrivate,
287 TagType: TypeConstructed,
288 Tag: TagObjectDescriptor,
289 },
290 ExpectedBytes: []byte{byte(ClassPrivate) | byte(TypeConstructed) | byte(TagObjectDescriptor)},
291 },
292
293 "max low-tag-number tag": {
294 Identifier: Identifier{
295 ClassType: ClassUniversal,
296 TagType: TypeConstructed,
297 Tag: TagBMPString,
298 },
299 ExpectedBytes: []byte{
300 byte(ClassUniversal) | byte(TypeConstructed) | byte(TagBMPString),
301 },
302 },
303
304 "min high-tag-number tag": {
305 Identifier: Identifier{
306 ClassType: ClassUniversal,
307 TagType: TypeConstructed,
308 Tag: TagBMPString + 1,
309 },
310 ExpectedBytes: []byte{
311 byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag),
312 byte(TagBMPString + 1),
313 },
314 },
315
316 "max high-tag-number tag": {
317 Identifier: Identifier{
318 ClassType: ClassUniversal,
319 TagType: TypeConstructed,
320 Tag: Tag(math.MaxInt64),
321 },
322 ExpectedBytes: []byte{
323 byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag),
324 byte(HighTagContinueBitmask | 0x7f),
325 byte(HighTagContinueBitmask | 0x7f),
326 byte(HighTagContinueBitmask | 0x7f),
327 byte(HighTagContinueBitmask | 0x7f),
328 byte(HighTagContinueBitmask | 0x7f),
329 byte(HighTagContinueBitmask | 0x7f),
330 byte(HighTagContinueBitmask | 0x7f),
331 byte(HighTagContinueBitmask | 0x7f),
332 byte(0x7f),
333 },
334 },
335 }
336
337 for k, tc := range testcases {
338 b := encodeIdentifier(tc.Identifier)
339 if bytes.Compare(tc.ExpectedBytes, b) != 0 {
340 t.Errorf("%s: Expected\n\t%#v\ngot\n\t%#v", k, tc.ExpectedBytes, b)
341 }
342 }
343 }
0 package ber
1
2 import (
3 "errors"
4 "fmt"
5 "io"
6 )
7
8 func readLength(reader io.Reader) (length int, read int, err error) {
9 // length byte
10 b, err := readByte(reader)
11 if err != nil {
12 if Debug {
13 fmt.Printf("error reading length byte: %v\n", err)
14 }
15 return 0, 0, err
16 }
17 read++
18
19 switch {
20 case b == 0xFF:
21 // Invalid 0xFF (x.600, 8.1.3.5.c)
22 return 0, read, errors.New("invalid length byte 0xff")
23
24 case b == LengthLongFormBitmask:
25 // Indefinite form, we have to decode packets until we encounter an EOC packet (x.600, 8.1.3.6)
26 length = LengthIndefinite
27
28 case b&LengthLongFormBitmask == 0:
29 // Short definite form, extract the length from the bottom 7 bits (x.600, 8.1.3.4)
30 length = int(b) & LengthValueBitmask
31
32 case b&LengthLongFormBitmask != 0:
33 // Long definite form, extract the number of length bytes to follow from the bottom 7 bits (x.600, 8.1.3.5.b)
34 lengthBytes := int(b) & LengthValueBitmask
35 // Protect against overflow
36 // TODO: support big int length?
37 if lengthBytes > 8 {
38 return 0, read, errors.New("long-form length overflow")
39 }
40 for i := 0; i < lengthBytes; i++ {
41 b, err = readByte(reader)
42 if err != nil {
43 if Debug {
44 fmt.Printf("error reading long-form length byte %d: %v\n", i, err)
45 }
46 return 0, read, err
47 }
48 read++
49
50 // x.600, 8.1.3.5
51 length <<= 8
52 length |= int(b)
53 }
54
55 default:
56 return 0, read, errors.New("invalid length byte")
57 }
58
59 return length, read, nil
60 }
61
62 func encodeLength(length int) []byte {
63 length_bytes := encodeUnsignedInteger(uint64(length))
64 if length > 127 || len(length_bytes) > 1 {
65 longFormBytes := []byte{(LengthLongFormBitmask | byte(len(length_bytes)))}
66 longFormBytes = append(longFormBytes, length_bytes...)
67 length_bytes = longFormBytes
68 }
69 return length_bytes
70 }
0 package ber
1
2 import (
3 "bytes"
4 "io"
5 "math"
6 "testing"
7 )
8
9 func TestReadLength(t *testing.T) {
10 testcases := map[string]struct {
11 Data []byte
12
13 ExpectedLength int
14 ExpectedBytesRead int
15 ExpectedError string
16 }{
17 "empty": {
18 Data: []byte{},
19 ExpectedBytesRead: 0,
20 ExpectedError: io.ErrUnexpectedEOF.Error(),
21 },
22 "invalid first byte": {
23 Data: []byte{0xFF},
24 ExpectedBytesRead: 1,
25 ExpectedError: "invalid length byte 0xff",
26 },
27
28 "indefinite form": {
29 Data: []byte{LengthLongFormBitmask},
30 ExpectedLength: LengthIndefinite,
31 ExpectedBytesRead: 1,
32 },
33
34 "short-definite-form zero length": {
35 Data: []byte{0},
36 ExpectedLength: 0,
37 ExpectedBytesRead: 1,
38 },
39 "short-definite-form length 1": {
40 Data: []byte{1},
41 ExpectedLength: 1,
42 ExpectedBytesRead: 1,
43 },
44 "short-definite-form max length": {
45 Data: []byte{127},
46 ExpectedLength: 127,
47 ExpectedBytesRead: 1,
48 },
49
50 "long-definite-form missing bytes": {
51 Data: []byte{LengthLongFormBitmask | 1},
52 ExpectedBytesRead: 1,
53 ExpectedError: io.ErrUnexpectedEOF.Error(),
54 },
55 "long-definite-form overflow": {
56 Data: []byte{LengthLongFormBitmask | 9},
57 ExpectedBytesRead: 1,
58 ExpectedError: "long-form length overflow",
59 },
60 "long-definite-form zero length": {
61 Data: []byte{LengthLongFormBitmask | 1, 0x0},
62 ExpectedLength: 0,
63 ExpectedBytesRead: 2,
64 },
65 "long-definite-form length 127": {
66 Data: []byte{LengthLongFormBitmask | 1, 127},
67 ExpectedLength: 127,
68 ExpectedBytesRead: 2,
69 },
70 "long-definite-form max length": {
71 Data: []byte{
72 LengthLongFormBitmask | 8,
73 0x7F,
74 0xFF,
75 0xFF,
76 0xFF,
77 0xFF,
78 0xFF,
79 0xFF,
80 0xFF,
81 },
82 ExpectedLength: math.MaxInt64,
83 ExpectedBytesRead: 9,
84 },
85 }
86
87 for k, tc := range testcases {
88 reader := bytes.NewBuffer(tc.Data)
89 length, read, err := readLength(reader)
90
91 if err != nil {
92 if tc.ExpectedError == "" {
93 t.Errorf("%s: unexpected error: %v", k, err)
94 } else if err.Error() != tc.ExpectedError {
95 t.Errorf("%s: expected error %v, got %v", k, tc.ExpectedError, err)
96 }
97 } else if tc.ExpectedError != "" {
98 t.Errorf("%s: expected error %v, got none", k, tc.ExpectedError)
99 continue
100 }
101
102 if read != tc.ExpectedBytesRead {
103 t.Errorf("%s: expected read %d, got %d", k, tc.ExpectedBytesRead, read)
104 }
105
106 if length != tc.ExpectedLength {
107 t.Errorf("%s: expected length %d, got %d", k, tc.ExpectedLength, length)
108 }
109 }
110 }
111
112 func TestEncodeLength(t *testing.T) {
113 testcases := map[string]struct {
114 Length int
115 ExpectedBytes []byte
116 }{
117 "0": {
118 Length: 0,
119 ExpectedBytes: []byte{0},
120 },
121 "1": {
122 Length: 1,
123 ExpectedBytes: []byte{1},
124 },
125
126 "max short-form length": {
127 Length: 127,
128 ExpectedBytes: []byte{127},
129 },
130 "min long-form length": {
131 Length: 128,
132 ExpectedBytes: []byte{LengthLongFormBitmask | 1, 128},
133 },
134
135 "max long-form length": {
136 Length: math.MaxInt64,
137 ExpectedBytes: []byte{
138 LengthLongFormBitmask | 8,
139 0x7F,
140 0xFF,
141 0xFF,
142 0xFF,
143 0xFF,
144 0xFF,
145 0xFF,
146 0xFF,
147 },
148 },
149 }
150
151 for k, tc := range testcases {
152 b := encodeLength(tc.Length)
153 if bytes.Compare(tc.ExpectedBytes, b) != 0 {
154 t.Errorf("%s: Expected\n\t%#v\ngot\n\t%#v", k, tc.ExpectedBytes, b)
155 }
156 }
157 }
0 package ber
1
2 import (
3 "bytes"
4 "io"
5 "io/ioutil"
6 "testing"
7 )
8
9 var errEOF = io.ErrUnexpectedEOF.Error()
10
11 // Tests from http://www.strozhevsky.com/free_docs/free_asn1_testsuite_descr.pdf
12 // Source files and descriptions at http://www.strozhevsky.com/free_docs/TEST_SUITE.zip
13 var testcases = []struct {
14 // File contains the path to the BER-encoded file
15 File string
16 // Error indicates whether a decoding error is expected
17 Error string
18 // AbnormalEncoding indicates whether a normalized re-encoding is expected to differ from the original source
19 AbnormalEncoding bool
20 // IndefiniteEncoding indicates the source file used indefinite-length encoding, so the re-encoding is expected to differ (since the length is known)
21 IndefiniteEncoding bool
22 }{
23 // Common blocks
24 {File: "tests/tc1.ber", Error: "high-tag-number tag overflow"},
25 {File: "tests/tc2.ber", Error: errEOF},
26 {File: "tests/tc3.ber", Error: errEOF},
27 {File: "tests/tc4.ber", Error: "invalid length byte 0xff"},
28 {File: "tests/tc5.ber", Error: "", AbnormalEncoding: true},
29 // Real numbers (some expected failures are disabled until support is added)
30 {File: "tests/tc6.ber", Error: ""}, // Error: "REAL value +0 must be encoded with zero-length value block"},
31 {File: "tests/tc7.ber", Error: ""}, // Error: "REAL value -0 must be encoded as a special value"},
32 {File: "tests/tc8.ber", Error: ""},
33 {File: "tests/tc9.ber", Error: ""}, // Error: "Bits 6 and 5 of information octet for REAL are equal to 11"
34 {File: "tests/tc10.ber", Error: ""},
35 {File: "tests/tc11.ber", Error: ""}, // Error: "Incorrect NR form"
36 {File: "tests/tc12.ber", Error: ""}, // Error: "Encoding of "special value" not from ASN.1 standard"
37 {File: "tests/tc13.ber", Error: errEOF},
38 {File: "tests/tc14.ber", Error: errEOF},
39 {File: "tests/tc15.ber", Error: ""}, // Error: "Too big value of exponent"
40 {File: "tests/tc16.ber", Error: ""}, // Error: "Too big value of mantissa"
41 {File: "tests/tc17.ber", Error: ""}, // Error: "Too big values for exponent and mantissa + using of "scaling factor" value"
42 // Integers
43 {File: "tests/tc18.ber", Error: ""},
44 {File: "tests/tc19.ber", Error: errEOF},
45 {File: "tests/tc20.ber", Error: ""},
46 // Object identifiers
47 {File: "tests/tc21.ber", Error: ""},
48 {File: "tests/tc22.ber", Error: ""},
49 {File: "tests/tc23.ber", Error: errEOF},
50 {File: "tests/tc24.ber", Error: ""},
51 // Booleans
52 {File: "tests/tc25.ber", Error: ""},
53 {File: "tests/tc26.ber", Error: ""},
54 {File: "tests/tc27.ber", Error: errEOF},
55 {File: "tests/tc28.ber", Error: ""},
56 {File: "tests/tc29.ber", Error: ""},
57 // Null
58 {File: "tests/tc30.ber", Error: ""},
59 {File: "tests/tc31.ber", Error: errEOF},
60 {File: "tests/tc32.ber", Error: ""},
61 // Bitstring (some expected failures are disabled until support is added)
62 {File: "tests/tc33.ber", Error: ""}, // Error: "Too big value for "unused bits""
63 {File: "tests/tc34.ber", Error: errEOF},
64 {File: "tests/tc35.ber", Error: "", IndefiniteEncoding: true}, // Error: "Using of different from BIT STRING types as internal types for constructive encoding"
65 {File: "tests/tc36.ber", Error: "", IndefiniteEncoding: true}, // Error: "Using of "unused bits" in internal BIT STRINGs with constructive form of encoding"
66 {File: "tests/tc37.ber", Error: ""},
67 {File: "tests/tc38.ber", Error: "", IndefiniteEncoding: true},
68 {File: "tests/tc39.ber", Error: ""},
69 {File: "tests/tc40.ber", Error: ""},
70 // Octet string (some expected failures are disabled until support is added)
71 {File: "tests/tc41.ber", Error: "", IndefiniteEncoding: true}, // Error: "Using of different from OCTET STRING types as internal types for constructive encoding"
72 {File: "tests/tc42.ber", Error: errEOF},
73 {File: "tests/tc43.ber", Error: errEOF},
74 {File: "tests/tc44.ber", Error: ""},
75 {File: "tests/tc45.ber", Error: ""},
76 // Bitstring
77 {File: "tests/tc46.ber", Error: "indefinite length used with primitive type"},
78 {File: "tests/tc47.ber", Error: "eoc child not allowed with definite length"},
79 {File: "tests/tc48.ber", Error: "", IndefiniteEncoding: true}, // Error: "Using of more than 7 "unused bits" in BIT STRING with constrictive encoding form"
80 }
81
82 func TestSuiteDecodePacket(t *testing.T) {
83 // Debug = true
84 for _, tc := range testcases {
85 file := tc.File
86
87 dataIn, err := ioutil.ReadFile(file)
88 if err != nil {
89 t.Errorf("%s: %v", file, err)
90 continue
91 }
92
93 // fmt.Printf("%s: decode %d\n", file, len(dataIn))
94 packet, err := DecodePacketErr(dataIn)
95 if err != nil {
96 if tc.Error == "" {
97 t.Errorf("%s: unexpected error during DecodePacket: %v", file, err)
98 } else if tc.Error != err.Error() {
99 t.Errorf("%s: expected error %q during DecodePacket, got %q", file, tc.Error, err)
100 }
101 continue
102 }
103 if tc.Error != "" {
104 t.Errorf("%s: expected error %q, got none", file, tc.Error)
105 continue
106 }
107
108 dataOut := packet.Bytes()
109 if tc.AbnormalEncoding || tc.IndefiniteEncoding {
110 // Abnormal encodings and encodings that used indefinite length should re-encode differently
111 if bytes.Equal(dataOut, dataIn) {
112 t.Errorf("%s: data should have been re-encoded differently", file)
113 }
114 } else if !bytes.Equal(dataOut, dataIn) {
115 // Make sure the serialized data matches the source
116 t.Errorf("%s: data should be the same", file)
117 }
118
119 packet, err = DecodePacketErr(dataOut)
120 if err != nil {
121 t.Errorf("%s: unexpected error: %v", file, err)
122 continue
123 }
124
125 // Make sure the re-serialized data matches our original serialization
126 dataOut2 := packet.Bytes()
127 if !bytes.Equal(dataOut, dataOut2) {
128 t.Errorf("%s: data should be the same", file)
129 }
130 }
131 }
132
133 func TestSuiteReadPacket(t *testing.T) {
134 for _, tc := range testcases {
135 file := tc.File
136
137 dataIn, err := ioutil.ReadFile(file)
138 if err != nil {
139 t.Errorf("%s: %v", file, err)
140 continue
141 }
142
143 buffer := bytes.NewBuffer(dataIn)
144 packet, err := ReadPacket(buffer)
145 if err != nil {
146 if tc.Error == "" {
147 t.Errorf("%s: unexpected error during ReadPacket: %v", file, err)
148 } else if tc.Error != err.Error() {
149 t.Errorf("%s: expected error %q during ReadPacket, got %q", file, tc.Error, err)
150 }
151 continue
152 }
153 if tc.Error != "" {
154 t.Errorf("%s: expected error %q, got none", file, tc.Error)
155 continue
156 }
157
158 dataOut := packet.Bytes()
159 if tc.AbnormalEncoding || tc.IndefiniteEncoding {
160 // Abnormal encodings and encodings that used indefinite length should re-encode differently
161 if bytes.Equal(dataOut, dataIn) {
162 t.Errorf("%s: data should have been re-encoded differently", file)
163 }
164 } else if !bytes.Equal(dataOut, dataIn) {
165 // Make sure the serialized data matches the source
166 t.Errorf("%s: data should be the same", file)
167 }
168
169 packet, err = DecodePacketErr(dataOut)
170 if err != nil {
171 t.Errorf("%s: unexpected error: %v", file, err)
172 continue
173 }
174
175 // Make sure the re-serialized data matches our original serialization
176 dataOut2 := packet.Bytes()
177 if !bytes.Equal(dataOut, dataOut2) {
178 t.Errorf("%s: data should be the same", file)
179 }
180 }
181 }
0 Ÿÿÿÿÿÿÿÿÿÿ@
0 ƒÿÿÿû
0  015625
Binary diff not shown
Binary diff not shown
0 ƒ ÿÿÿÿÿÿÿû
0 €û
0 ¯ þÿÿÿÿÿÿÿÿ
0 ÿð
0 Ÿÿÿÿÿÿÿÿÿÿ
Binary diff not shown
0 €€Q€€
0 ÿÿÿÿÿÿÿÿÿÿ…
0 ÿÿÿÿÿ
0 Ξ`†H��O …ξεJ…δΏc‹Ϋ/
Binary diff not shown
Binary diff not shown
0 ÿ
Binary diff not shown
0 Ÿÿÿÿÿÿÿÿÿ
Binary diff not shown
Binary diff not shown
Binary diff not shown
0 
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
0 Ÿÿÿÿÿÿÿÿÿÿ
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
0 џяяяяяяяяЃ@
0 +0.E-5
0 -0.E-5
Binary diff not shown
0 ¼þ
0 package ber
1
2 import "io"
3
4 func readByte(reader io.Reader) (byte, error) {
5 bytes := make([]byte, 1, 1)
6 _, err := io.ReadFull(reader, bytes)
7 if err != nil {
8 if err == io.EOF {
9 return 0, io.ErrUnexpectedEOF
10 }
11 return 0, err
12 }
13 return bytes[0], nil
14 }
15
16 func isEOCPacket(p *Packet) bool {
17 return p != nil &&
18 p.Tag == TagEOC &&
19 p.ClassType == ClassUniversal &&
20 p.TagType == TypePrimitive &&
21 len(p.ByteValue) == 0 &&
22 len(p.Children) == 0
23 }