vendor: revendor

This commit is contained in:
Eric Chiang
2016-12-22 11:39:28 -08:00
parent d87a4c35b9
commit 1451213dd7
268 changed files with 484 additions and 59530 deletions

View File

@@ -1,15 +0,0 @@
language: go
go:
- 1.2
- 1.3
- 1.4
- 1.5
- tip
go_import_path: gopkg.in/asn-ber.v1
install:
- go list -f '{{range .Imports}}{{.}} {{end}}' ./... | xargs go get -v
- go list -f '{{range .TestImports}}{{.}} {{end}}' ./... | xargs go get -v
- go get code.google.com/p/go.tools/cmd/cover || go get golang.org/x/tools/cmd/cover
- go build -v ./...
script:
- go test -v -cover ./...

View File

@@ -1,24 +0,0 @@
[![GoDoc](https://godoc.org/gopkg.in/asn1-ber.v1?status.svg)](https://godoc.org/gopkg.in/asn1-ber.v1) [![Build Status](https://travis-ci.org/go-asn1-ber/asn1-ber.svg)](https://travis-ci.org/go-asn1-ber/asn1-ber)
ASN1 BER Encoding / Decoding Library for the GO programming language.
---------------------------------------------------------------------
Required libraries:
None
Working:
Very basic encoding / decoding needed for LDAP protocol
Tests Implemented:
A few
TODO:
Fix all encoding / decoding to conform to ASN1 BER spec
Implement Tests / Benchmarks
---
The Go gopher was designed by Renee French. (http://reneefrench.blogspot.com/)
The design is licensed under the Creative Commons 3.0 Attributions license.
Read this article for more details: http://blog.golang.org/gopher

View File

@@ -1,168 +0,0 @@
package ber
import (
"bytes"
"math"
"io"
"testing"
)
func TestEncodeDecodeInteger(t *testing.T) {
for _, v := range []int64{0, 10, 128, 1024, math.MaxInt64, -1, -100, -128, -1024, math.MinInt64} {
enc := encodeInteger(v)
dec, err := parseInt64(enc)
if err != nil {
t.Fatalf("Error decoding %d : %s", v, err)
}
if v != dec {
t.Error("TestEncodeDecodeInteger failed for %d (got %d)", v, dec)
}
}
}
func TestBoolean(t *testing.T) {
var value bool = true
packet := NewBoolean(ClassUniversal, TypePrimitive, TagBoolean, value, "first Packet, True")
newBoolean, ok := packet.Value.(bool)
if !ok || newBoolean != value {
t.Error("error during creating packet")
}
encodedPacket := packet.Bytes()
newPacket := DecodePacket(encodedPacket)
newBoolean, ok = newPacket.Value.(bool)
if !ok || newBoolean != value {
t.Error("error during decoding packet")
}
}
func TestInteger(t *testing.T) {
var value int64 = 10
packet := NewInteger(ClassUniversal, TypePrimitive, TagInteger, value, "Integer, 10")
{
newInteger, ok := packet.Value.(int64)
if !ok || newInteger != value {
t.Error("error creating packet")
}
}
encodedPacket := packet.Bytes()
newPacket := DecodePacket(encodedPacket)
{
newInteger, ok := newPacket.Value.(int64)
if !ok || int64(newInteger) != value {
t.Error("error decoding packet")
}
}
}
func TestString(t *testing.T) {
var value string = "Hic sunt dracones"
packet := NewString(ClassUniversal, TypePrimitive, TagOctetString, value, "String")
newValue, ok := packet.Value.(string)
if !ok || newValue != value {
t.Error("error during creating packet")
}
encodedPacket := packet.Bytes()
newPacket := DecodePacket(encodedPacket)
newValue, ok = newPacket.Value.(string)
if !ok || newValue != value {
t.Error("error during decoding packet")
}
}
func TestSequenceAndAppendChild(t *testing.T) {
values := []string{
"HIC SVNT LEONES",
"Iñtërnâtiônàlizætiøn",
"Terra Incognita",
}
sequence := NewSequence("a sequence")
for _, s := range values {
sequence.AppendChild(NewString(ClassUniversal, TypePrimitive, TagOctetString, s, "String"))
}
if len(sequence.Children) != len(values) {
t.Errorf("wrong length for children array should be %d, got %d", len(values), len(sequence.Children))
}
encodedSequence := sequence.Bytes()
decodedSequence := DecodePacket(encodedSequence)
if len(decodedSequence.Children) != len(values) {
t.Errorf("wrong length for children array should be %d => %d", len(values), len(decodedSequence.Children))
}
for i, s := range values {
if decodedSequence.Children[i].Value.(string) != s {
t.Errorf("expected %d to be %q, got %q", i, s, decodedSequence.Children[i].Value.(string))
}
}
}
func TestReadPacket(t *testing.T) {
packet := NewString(ClassUniversal, TypePrimitive, TagOctetString, "Ad impossibilia nemo tenetur", "string")
var buffer io.ReadWriter
buffer = new(bytes.Buffer)
buffer.Write(packet.Bytes())
newPacket, err := ReadPacket(buffer)
if err != nil {
t.Error("error during ReadPacket", err)
}
newPacket.ByteValue = nil
if !bytes.Equal(newPacket.ByteValue, packet.ByteValue) {
t.Error("packets should be the same")
}
}
func TestBinaryInteger(t *testing.T) {
// data src : http://luca.ntop.org/Teaching/Appunti/asn1.html 5.7
var data = []struct {
v int64
e []byte
}{
{v: 0, e: []byte{0x02, 0x01, 0x00}},
{v: 127, e: []byte{0x02, 0x01, 0x7F}},
{v: 128, e: []byte{0x02, 0x02, 0x00, 0x80}},
{v: 256, e: []byte{0x02, 0x02, 0x01, 0x00}},
{v: -128, e: []byte{0x02, 0x01, 0x80}},
{v: -129, e: []byte{0x02, 0x02, 0xFF, 0x7F}},
{v: math.MaxInt64, e: []byte{0x02, 0x08, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
{v: math.MinInt64, e: []byte{0x02, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
}
for _, d := range data {
if b := NewInteger(ClassUniversal, TypePrimitive, TagInteger, int64(d.v), "").Bytes(); !bytes.Equal(d.e, b) {
t.Errorf("Wrong binary generated for %d : got % X, expected % X", d.v, b, d.e)
}
}
}
func TestBinaryOctetString(t *testing.T) {
// data src : http://luca.ntop.org/Teaching/Appunti/asn1.html 5.10
if !bytes.Equal([]byte{0x04, 0x08, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, NewString(ClassUniversal, TypePrimitive, TagOctetString, "\x01\x23\x45\x67\x89\xab\xcd\xef", "").Bytes()) {
t.Error("wrong binary generated")
}
}

View File

@@ -1,135 +0,0 @@
package ber
import (
"bytes"
"io"
"testing"
)
func TestReadHeader(t *testing.T) {
testcases := map[string]struct {
Data []byte
ExpectedIdentifier Identifier
ExpectedLength int
ExpectedBytesRead int
ExpectedError string
}{
"empty": {
Data: []byte{},
ExpectedIdentifier: Identifier{},
ExpectedLength: 0,
ExpectedBytesRead: 0,
ExpectedError: io.ErrUnexpectedEOF.Error(),
},
"valid short form": {
Data: []byte{
byte(ClassUniversal) | byte(TypePrimitive) | byte(TagCharacterString),
127,
},
ExpectedIdentifier: Identifier{
ClassType: ClassUniversal,
TagType: TypePrimitive,
Tag: TagCharacterString,
},
ExpectedLength: 127,
ExpectedBytesRead: 2,
ExpectedError: "",
},
"valid long form": {
Data: []byte{
// 2-byte encoding of tag
byte(ClassUniversal) | byte(TypePrimitive) | byte(HighTag),
byte(TagCharacterString),
// 2-byte encoding of length
LengthLongFormBitmask | 1,
127,
},
ExpectedIdentifier: Identifier{
ClassType: ClassUniversal,
TagType: TypePrimitive,
Tag: TagCharacterString,
},
ExpectedLength: 127,
ExpectedBytesRead: 4,
ExpectedError: "",
},
"valid indefinite length": {
Data: []byte{
byte(ClassUniversal) | byte(TypeConstructed) | byte(TagCharacterString),
LengthLongFormBitmask,
},
ExpectedIdentifier: Identifier{
ClassType: ClassUniversal,
TagType: TypeConstructed,
Tag: TagCharacterString,
},
ExpectedLength: LengthIndefinite,
ExpectedBytesRead: 2,
ExpectedError: "",
},
"invalid indefinite length": {
Data: []byte{
byte(ClassUniversal) | byte(TypePrimitive) | byte(TagCharacterString),
LengthLongFormBitmask,
},
ExpectedIdentifier: Identifier{},
ExpectedLength: 0,
ExpectedBytesRead: 2,
ExpectedError: "indefinite length used with primitive type",
},
}
for k, tc := range testcases {
reader := bytes.NewBuffer(tc.Data)
identifier, length, read, err := readHeader(reader)
if err != nil {
if tc.ExpectedError == "" {
t.Errorf("%s: unexpected error: %v", k, err)
} else if err.Error() != tc.ExpectedError {
t.Errorf("%s: expected error %v, got %v", k, tc.ExpectedError, err)
}
} else if tc.ExpectedError != "" {
t.Errorf("%s: expected error %v, got none", k, tc.ExpectedError)
continue
}
if read != tc.ExpectedBytesRead {
t.Errorf("%s: expected read %d, got %d", k, tc.ExpectedBytesRead, read)
}
if identifier.ClassType != tc.ExpectedIdentifier.ClassType {
t.Errorf("%s: expected class type %d (%s), got %d (%s)", k,
tc.ExpectedIdentifier.ClassType,
ClassMap[tc.ExpectedIdentifier.ClassType],
identifier.ClassType,
ClassMap[identifier.ClassType],
)
}
if identifier.TagType != tc.ExpectedIdentifier.TagType {
t.Errorf("%s: expected tag type %d (%s), got %d (%s)", k,
tc.ExpectedIdentifier.TagType,
TypeMap[tc.ExpectedIdentifier.TagType],
identifier.TagType,
TypeMap[identifier.TagType],
)
}
if identifier.Tag != tc.ExpectedIdentifier.Tag {
t.Errorf("%s: expected tag %d (%s), got %d (%s)", k,
tc.ExpectedIdentifier.Tag,
tagMap[tc.ExpectedIdentifier.Tag],
identifier.Tag,
tagMap[identifier.Tag],
)
}
if length != tc.ExpectedLength {
t.Errorf("%s: expected length %d, got %d", k, tc.ExpectedLength, length)
}
}
}

View File

@@ -1,344 +0,0 @@
package ber
import (
"bytes"
"io"
"math"
"testing"
)
func TestReadIdentifier(t *testing.T) {
testcases := map[string]struct {
Data []byte
ExpectedIdentifier Identifier
ExpectedBytesRead int
ExpectedError string
}{
"empty": {
Data: []byte{},
ExpectedBytesRead: 0,
ExpectedError: io.ErrUnexpectedEOF.Error(),
},
"universal primitive eoc": {
Data: []byte{byte(ClassUniversal) | byte(TypePrimitive) | byte(TagEOC)},
ExpectedIdentifier: Identifier{
ClassType: ClassUniversal,
TagType: TypePrimitive,
Tag: TagEOC,
},
ExpectedBytesRead: 1,
},
"universal primitive character string": {
Data: []byte{byte(ClassUniversal) | byte(TypePrimitive) | byte(TagCharacterString)},
ExpectedIdentifier: Identifier{
ClassType: ClassUniversal,
TagType: TypePrimitive,
Tag: TagCharacterString,
},
ExpectedBytesRead: 1,
},
"universal constructed bit string": {
Data: []byte{byte(ClassUniversal) | byte(TypeConstructed) | byte(TagBitString)},
ExpectedIdentifier: Identifier{
ClassType: ClassUniversal,
TagType: TypeConstructed,
Tag: TagBitString,
},
ExpectedBytesRead: 1,
},
"universal constructed character string": {
Data: []byte{byte(ClassUniversal) | byte(TypeConstructed) | byte(TagCharacterString)},
ExpectedIdentifier: Identifier{
ClassType: ClassUniversal,
TagType: TypeConstructed,
Tag: TagCharacterString,
},
ExpectedBytesRead: 1,
},
"application constructed object descriptor": {
Data: []byte{byte(ClassApplication) | byte(TypeConstructed) | byte(TagObjectDescriptor)},
ExpectedIdentifier: Identifier{
ClassType: ClassApplication,
TagType: TypeConstructed,
Tag: TagObjectDescriptor,
},
ExpectedBytesRead: 1,
},
"context constructed object descriptor": {
Data: []byte{byte(ClassContext) | byte(TypeConstructed) | byte(TagObjectDescriptor)},
ExpectedIdentifier: Identifier{
ClassType: ClassContext,
TagType: TypeConstructed,
Tag: TagObjectDescriptor,
},
ExpectedBytesRead: 1,
},
"private constructed object descriptor": {
Data: []byte{byte(ClassPrivate) | byte(TypeConstructed) | byte(TagObjectDescriptor)},
ExpectedIdentifier: Identifier{
ClassType: ClassPrivate,
TagType: TypeConstructed,
Tag: TagObjectDescriptor,
},
ExpectedBytesRead: 1,
},
"high-tag-number tag missing bytes": {
Data: []byte{byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag)},
ExpectedError: io.ErrUnexpectedEOF.Error(),
ExpectedBytesRead: 1,
},
"high-tag-number tag invalid first byte": {
Data: []byte{byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag), 0x0},
ExpectedError: "invalid first high-tag-number tag byte",
ExpectedBytesRead: 2,
},
"high-tag-number tag invalid first byte with continue bit": {
Data: []byte{byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag), byte(HighTagContinueBitmask)},
ExpectedError: "invalid first high-tag-number tag byte",
ExpectedBytesRead: 2,
},
"high-tag-number tag continuation missing bytes": {
Data: []byte{byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag), byte(HighTagContinueBitmask | 0x1)},
ExpectedError: io.ErrUnexpectedEOF.Error(),
ExpectedBytesRead: 2,
},
"high-tag-number tag overflow": {
Data: []byte{
byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag),
byte(HighTagContinueBitmask | 0x1),
byte(HighTagContinueBitmask | 0x1),
byte(HighTagContinueBitmask | 0x1),
byte(HighTagContinueBitmask | 0x1),
byte(HighTagContinueBitmask | 0x1),
byte(HighTagContinueBitmask | 0x1),
byte(HighTagContinueBitmask | 0x1),
byte(HighTagContinueBitmask | 0x1),
byte(HighTagContinueBitmask | 0x1),
byte(0x1),
},
ExpectedError: "high-tag-number tag overflow",
ExpectedBytesRead: 11,
},
"max high-tag-number tag": {
Data: []byte{
byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(0x7f),
},
ExpectedIdentifier: Identifier{
ClassType: ClassUniversal,
TagType: TypeConstructed,
Tag: Tag(0x7FFFFFFFFFFFFFFF), // 01111111...(63)...11111b
},
ExpectedBytesRead: 10,
},
"high-tag-number encoding of low-tag value": {
Data: []byte{
byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag),
byte(TagObjectDescriptor),
},
ExpectedIdentifier: Identifier{
ClassType: ClassUniversal,
TagType: TypeConstructed,
Tag: TagObjectDescriptor,
},
ExpectedBytesRead: 2,
},
"max high-tag-number tag ignores extra data": {
Data: []byte{
byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(0x7f),
byte(0x01), // extra data, shouldn't be read
byte(0x02), // extra data, shouldn't be read
byte(0x03), // extra data, shouldn't be read
},
ExpectedIdentifier: Identifier{
ClassType: ClassUniversal,
TagType: TypeConstructed,
Tag: Tag(0x7FFFFFFFFFFFFFFF), // 01111111...(63)...11111b
},
ExpectedBytesRead: 10,
},
}
for k, tc := range testcases {
reader := bytes.NewBuffer(tc.Data)
identifier, read, err := readIdentifier(reader)
if err != nil {
if tc.ExpectedError == "" {
t.Errorf("%s: unexpected error: %v", k, err)
} else if err.Error() != tc.ExpectedError {
t.Errorf("%s: expected error %v, got %v", k, tc.ExpectedError, err)
}
} else if tc.ExpectedError != "" {
t.Errorf("%s: expected error %v, got none", k, tc.ExpectedError)
continue
}
if read != tc.ExpectedBytesRead {
t.Errorf("%s: expected read %d, got %d", k, tc.ExpectedBytesRead, read)
}
if identifier.ClassType != tc.ExpectedIdentifier.ClassType {
t.Errorf("%s: expected class type %d (%s), got %d (%s)", k,
tc.ExpectedIdentifier.ClassType,
ClassMap[tc.ExpectedIdentifier.ClassType],
identifier.ClassType,
ClassMap[identifier.ClassType],
)
}
if identifier.TagType != tc.ExpectedIdentifier.TagType {
t.Errorf("%s: expected tag type %d (%s), got %d (%s)", k,
tc.ExpectedIdentifier.TagType,
TypeMap[tc.ExpectedIdentifier.TagType],
identifier.TagType,
TypeMap[identifier.TagType],
)
}
if identifier.Tag != tc.ExpectedIdentifier.Tag {
t.Errorf("%s: expected tag %d (%s), got %d (%s)", k,
tc.ExpectedIdentifier.Tag,
tagMap[tc.ExpectedIdentifier.Tag],
identifier.Tag,
tagMap[identifier.Tag],
)
}
}
}
func TestEncodeIdentifier(t *testing.T) {
testcases := map[string]struct {
Identifier Identifier
ExpectedBytes []byte
}{
"universal primitive eoc": {
Identifier: Identifier{
ClassType: ClassUniversal,
TagType: TypePrimitive,
Tag: TagEOC,
},
ExpectedBytes: []byte{byte(ClassUniversal) | byte(TypePrimitive) | byte(TagEOC)},
},
"universal primitive character string": {
Identifier: Identifier{
ClassType: ClassUniversal,
TagType: TypePrimitive,
Tag: TagCharacterString,
},
ExpectedBytes: []byte{byte(ClassUniversal) | byte(TypePrimitive) | byte(TagCharacterString)},
},
"universal constructed bit string": {
Identifier: Identifier{
ClassType: ClassUniversal,
TagType: TypeConstructed,
Tag: TagBitString,
},
ExpectedBytes: []byte{byte(ClassUniversal) | byte(TypeConstructed) | byte(TagBitString)},
},
"universal constructed character string": {
Identifier: Identifier{
ClassType: ClassUniversal,
TagType: TypeConstructed,
Tag: TagCharacterString,
},
ExpectedBytes: []byte{byte(ClassUniversal) | byte(TypeConstructed) | byte(TagCharacterString)},
},
"application constructed object descriptor": {
Identifier: Identifier{
ClassType: ClassApplication,
TagType: TypeConstructed,
Tag: TagObjectDescriptor,
},
ExpectedBytes: []byte{byte(ClassApplication) | byte(TypeConstructed) | byte(TagObjectDescriptor)},
},
"context constructed object descriptor": {
Identifier: Identifier{
ClassType: ClassContext,
TagType: TypeConstructed,
Tag: TagObjectDescriptor,
},
ExpectedBytes: []byte{byte(ClassContext) | byte(TypeConstructed) | byte(TagObjectDescriptor)},
},
"private constructed object descriptor": {
Identifier: Identifier{
ClassType: ClassPrivate,
TagType: TypeConstructed,
Tag: TagObjectDescriptor,
},
ExpectedBytes: []byte{byte(ClassPrivate) | byte(TypeConstructed) | byte(TagObjectDescriptor)},
},
"max low-tag-number tag": {
Identifier: Identifier{
ClassType: ClassUniversal,
TagType: TypeConstructed,
Tag: TagBMPString,
},
ExpectedBytes: []byte{
byte(ClassUniversal) | byte(TypeConstructed) | byte(TagBMPString),
},
},
"min high-tag-number tag": {
Identifier: Identifier{
ClassType: ClassUniversal,
TagType: TypeConstructed,
Tag: TagBMPString + 1,
},
ExpectedBytes: []byte{
byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag),
byte(TagBMPString + 1),
},
},
"max high-tag-number tag": {
Identifier: Identifier{
ClassType: ClassUniversal,
TagType: TypeConstructed,
Tag: Tag(math.MaxInt64),
},
ExpectedBytes: []byte{
byte(ClassUniversal) | byte(TypeConstructed) | byte(HighTag),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(HighTagContinueBitmask | 0x7f),
byte(0x7f),
},
},
}
for k, tc := range testcases {
b := encodeIdentifier(tc.Identifier)
if bytes.Compare(tc.ExpectedBytes, b) != 0 {
t.Errorf("%s: Expected\n\t%#v\ngot\n\t%#v", k, tc.ExpectedBytes, b)
}
}
}

View File

@@ -1,158 +0,0 @@
package ber
import (
"bytes"
"io"
"math"
"testing"
)
func TestReadLength(t *testing.T) {
testcases := map[string]struct {
Data []byte
ExpectedLength int
ExpectedBytesRead int
ExpectedError string
}{
"empty": {
Data: []byte{},
ExpectedBytesRead: 0,
ExpectedError: io.ErrUnexpectedEOF.Error(),
},
"invalid first byte": {
Data: []byte{0xFF},
ExpectedBytesRead: 1,
ExpectedError: "invalid length byte 0xff",
},
"indefinite form": {
Data: []byte{LengthLongFormBitmask},
ExpectedLength: LengthIndefinite,
ExpectedBytesRead: 1,
},
"short-definite-form zero length": {
Data: []byte{0},
ExpectedLength: 0,
ExpectedBytesRead: 1,
},
"short-definite-form length 1": {
Data: []byte{1},
ExpectedLength: 1,
ExpectedBytesRead: 1,
},
"short-definite-form max length": {
Data: []byte{127},
ExpectedLength: 127,
ExpectedBytesRead: 1,
},
"long-definite-form missing bytes": {
Data: []byte{LengthLongFormBitmask | 1},
ExpectedBytesRead: 1,
ExpectedError: io.ErrUnexpectedEOF.Error(),
},
"long-definite-form overflow": {
Data: []byte{LengthLongFormBitmask | 9},
ExpectedBytesRead: 1,
ExpectedError: "long-form length overflow",
},
"long-definite-form zero length": {
Data: []byte{LengthLongFormBitmask | 1, 0x0},
ExpectedLength: 0,
ExpectedBytesRead: 2,
},
"long-definite-form length 127": {
Data: []byte{LengthLongFormBitmask | 1, 127},
ExpectedLength: 127,
ExpectedBytesRead: 2,
},
"long-definite-form max length": {
Data: []byte{
LengthLongFormBitmask | 8,
0x7F,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
},
ExpectedLength: math.MaxInt64,
ExpectedBytesRead: 9,
},
}
for k, tc := range testcases {
reader := bytes.NewBuffer(tc.Data)
length, read, err := readLength(reader)
if err != nil {
if tc.ExpectedError == "" {
t.Errorf("%s: unexpected error: %v", k, err)
} else if err.Error() != tc.ExpectedError {
t.Errorf("%s: expected error %v, got %v", k, tc.ExpectedError, err)
}
} else if tc.ExpectedError != "" {
t.Errorf("%s: expected error %v, got none", k, tc.ExpectedError)
continue
}
if read != tc.ExpectedBytesRead {
t.Errorf("%s: expected read %d, got %d", k, tc.ExpectedBytesRead, read)
}
if length != tc.ExpectedLength {
t.Errorf("%s: expected length %d, got %d", k, tc.ExpectedLength, length)
}
}
}
func TestEncodeLength(t *testing.T) {
testcases := map[string]struct {
Length int
ExpectedBytes []byte
}{
"0": {
Length: 0,
ExpectedBytes: []byte{0},
},
"1": {
Length: 1,
ExpectedBytes: []byte{1},
},
"max short-form length": {
Length: 127,
ExpectedBytes: []byte{127},
},
"min long-form length": {
Length: 128,
ExpectedBytes: []byte{LengthLongFormBitmask | 1, 128},
},
"max long-form length": {
Length: math.MaxInt64,
ExpectedBytes: []byte{
LengthLongFormBitmask | 8,
0x7F,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
},
},
}
for k, tc := range testcases {
b := encodeLength(tc.Length)
if bytes.Compare(tc.ExpectedBytes, b) != 0 {
t.Errorf("%s: Expected\n\t%#v\ngot\n\t%#v", k, tc.ExpectedBytes, b)
}
}
}

View File

@@ -1,182 +0,0 @@
package ber
import (
"bytes"
"io"
"io/ioutil"
"testing"
)
var errEOF = io.ErrUnexpectedEOF.Error()
// Tests from http://www.strozhevsky.com/free_docs/free_asn1_testsuite_descr.pdf
// Source files and descriptions at http://www.strozhevsky.com/free_docs/TEST_SUITE.zip
var testcases = []struct {
// File contains the path to the BER-encoded file
File string
// Error indicates whether a decoding error is expected
Error string
// AbnormalEncoding indicates whether a normalized re-encoding is expected to differ from the original source
AbnormalEncoding bool
// IndefiniteEncoding indicates the source file used indefinite-length encoding, so the re-encoding is expected to differ (since the length is known)
IndefiniteEncoding bool
}{
// Common blocks
{File: "tests/tc1.ber", Error: "high-tag-number tag overflow"},
{File: "tests/tc2.ber", Error: errEOF},
{File: "tests/tc3.ber", Error: errEOF},
{File: "tests/tc4.ber", Error: "invalid length byte 0xff"},
{File: "tests/tc5.ber", Error: "", AbnormalEncoding: true},
// Real numbers (some expected failures are disabled until support is added)
{File: "tests/tc6.ber", Error: ""}, // Error: "REAL value +0 must be encoded with zero-length value block"},
{File: "tests/tc7.ber", Error: ""}, // Error: "REAL value -0 must be encoded as a special value"},
{File: "tests/tc8.ber", Error: ""},
{File: "tests/tc9.ber", Error: ""}, // Error: "Bits 6 and 5 of information octet for REAL are equal to 11"
{File: "tests/tc10.ber", Error: ""},
{File: "tests/tc11.ber", Error: ""}, // Error: "Incorrect NR form"
{File: "tests/tc12.ber", Error: ""}, // Error: "Encoding of "special value" not from ASN.1 standard"
{File: "tests/tc13.ber", Error: errEOF},
{File: "tests/tc14.ber", Error: errEOF},
{File: "tests/tc15.ber", Error: ""}, // Error: "Too big value of exponent"
{File: "tests/tc16.ber", Error: ""}, // Error: "Too big value of mantissa"
{File: "tests/tc17.ber", Error: ""}, // Error: "Too big values for exponent and mantissa + using of "scaling factor" value"
// Integers
{File: "tests/tc18.ber", Error: ""},
{File: "tests/tc19.ber", Error: errEOF},
{File: "tests/tc20.ber", Error: ""},
// Object identifiers
{File: "tests/tc21.ber", Error: ""},
{File: "tests/tc22.ber", Error: ""},
{File: "tests/tc23.ber", Error: errEOF},
{File: "tests/tc24.ber", Error: ""},
// Booleans
{File: "tests/tc25.ber", Error: ""},
{File: "tests/tc26.ber", Error: ""},
{File: "tests/tc27.ber", Error: errEOF},
{File: "tests/tc28.ber", Error: ""},
{File: "tests/tc29.ber", Error: ""},
// Null
{File: "tests/tc30.ber", Error: ""},
{File: "tests/tc31.ber", Error: errEOF},
{File: "tests/tc32.ber", Error: ""},
// Bitstring (some expected failures are disabled until support is added)
{File: "tests/tc33.ber", Error: ""}, // Error: "Too big value for "unused bits""
{File: "tests/tc34.ber", Error: errEOF},
{File: "tests/tc35.ber", Error: "", IndefiniteEncoding: true}, // Error: "Using of different from BIT STRING types as internal types for constructive encoding"
{File: "tests/tc36.ber", Error: "", IndefiniteEncoding: true}, // Error: "Using of "unused bits" in internal BIT STRINGs with constructive form of encoding"
{File: "tests/tc37.ber", Error: ""},
{File: "tests/tc38.ber", Error: "", IndefiniteEncoding: true},
{File: "tests/tc39.ber", Error: ""},
{File: "tests/tc40.ber", Error: ""},
// Octet string (some expected failures are disabled until support is added)
{File: "tests/tc41.ber", Error: "", IndefiniteEncoding: true}, // Error: "Using of different from OCTET STRING types as internal types for constructive encoding"
{File: "tests/tc42.ber", Error: errEOF},
{File: "tests/tc43.ber", Error: errEOF},
{File: "tests/tc44.ber", Error: ""},
{File: "tests/tc45.ber", Error: ""},
// Bitstring
{File: "tests/tc46.ber", Error: "indefinite length used with primitive type"},
{File: "tests/tc47.ber", Error: "eoc child not allowed with definite length"},
{File: "tests/tc48.ber", Error: "", IndefiniteEncoding: true}, // Error: "Using of more than 7 "unused bits" in BIT STRING with constrictive encoding form"
}
func TestSuiteDecodePacket(t *testing.T) {
// Debug = true
for _, tc := range testcases {
file := tc.File
dataIn, err := ioutil.ReadFile(file)
if err != nil {
t.Errorf("%s: %v", file, err)
continue
}
// fmt.Printf("%s: decode %d\n", file, len(dataIn))
packet, err := DecodePacketErr(dataIn)
if err != nil {
if tc.Error == "" {
t.Errorf("%s: unexpected error during DecodePacket: %v", file, err)
} else if tc.Error != err.Error() {
t.Errorf("%s: expected error %q during DecodePacket, got %q", file, tc.Error, err)
}
continue
}
if tc.Error != "" {
t.Errorf("%s: expected error %q, got none", file, tc.Error)
continue
}
dataOut := packet.Bytes()
if tc.AbnormalEncoding || tc.IndefiniteEncoding {
// Abnormal encodings and encodings that used indefinite length should re-encode differently
if bytes.Equal(dataOut, dataIn) {
t.Errorf("%s: data should have been re-encoded differently", file)
}
} else if !bytes.Equal(dataOut, dataIn) {
// Make sure the serialized data matches the source
t.Errorf("%s: data should be the same", file)
}
packet, err = DecodePacketErr(dataOut)
if err != nil {
t.Errorf("%s: unexpected error: %v", file, err)
continue
}
// Make sure the re-serialized data matches our original serialization
dataOut2 := packet.Bytes()
if !bytes.Equal(dataOut, dataOut2) {
t.Errorf("%s: data should be the same", file)
}
}
}
func TestSuiteReadPacket(t *testing.T) {
for _, tc := range testcases {
file := tc.File
dataIn, err := ioutil.ReadFile(file)
if err != nil {
t.Errorf("%s: %v", file, err)
continue
}
buffer := bytes.NewBuffer(dataIn)
packet, err := ReadPacket(buffer)
if err != nil {
if tc.Error == "" {
t.Errorf("%s: unexpected error during ReadPacket: %v", file, err)
} else if tc.Error != err.Error() {
t.Errorf("%s: expected error %q during ReadPacket, got %q", file, tc.Error, err)
}
continue
}
if tc.Error != "" {
t.Errorf("%s: expected error %q, got none", file, tc.Error)
continue
}
dataOut := packet.Bytes()
if tc.AbnormalEncoding || tc.IndefiniteEncoding {
// Abnormal encodings and encodings that used indefinite length should re-encode differently
if bytes.Equal(dataOut, dataIn) {
t.Errorf("%s: data should have been re-encoded differently", file)
}
} else if !bytes.Equal(dataOut, dataIn) {
// Make sure the serialized data matches the source
t.Errorf("%s: data should be the same", file)
}
packet, err = DecodePacketErr(dataOut)
if err != nil {
t.Errorf("%s: unexpected error: %v", file, err)
continue
}
// Make sure the re-serialized data matches our original serialization
dataOut2 := packet.Bytes()
if !bytes.Equal(dataOut, dataOut2) {
t.Errorf("%s: data should be the same", file)
}
}
}