summaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/gopkg.in
diff options
context:
space:
mode:
authorChristopher Speller <crspeller@gmail.com>2015-12-08 13:38:43 -0500
committerChristopher Speller <crspeller@gmail.com>2015-12-16 17:30:15 -0500
commit58358ddd7cd0152bf16a7326e1d595524fb51246 (patch)
tree350cd462f9b530529e0f098fa1d458c3a36abd4a /Godeps/_workspace/src/gopkg.in
parent4f881046bf2a4c74fb44d71e2e78826c70719a8c (diff)
downloadchat-58358ddd7cd0152bf16a7326e1d595524fb51246.tar.gz
chat-58358ddd7cd0152bf16a7326e1d595524fb51246.tar.bz2
chat-58358ddd7cd0152bf16a7326e1d595524fb51246.zip
Some refactoring
Diffstat (limited to 'Godeps/_workspace/src/gopkg.in')
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/.travis.yml15
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/LICENSE27
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/README.md24
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/ber.go504
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/ber_test.go168
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/content_int.go25
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/header.go29
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/header_test.go135
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/identifier.go103
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/identifier_test.go344
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/length.go71
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/length_test.go158
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/suite_test.go182
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc1.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc10.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc11.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc12.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc13.berbin0 -> 11 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc14.berbin0 -> 7 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc15.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc16.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc17.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc18.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc19.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc2.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc20.berbin0 -> 11 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc21.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc22.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc23.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc24.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc25.berbin0 -> 5 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc26.berbin0 -> 5 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc27.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc28.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc29.berbin0 -> 3 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc3.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc30.berbin0 -> 5 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc31.berbin0 -> 4 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc32.berbin0 -> 2 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc33.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc34.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc35.berbin0 -> 16 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc36.berbin0 -> 20 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc37.berbin0 -> 14 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc38.berbin0 -> 16 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc39.berbin0 -> 2 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc4.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc40.berbin0 -> 2 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc41.berbin0 -> 16 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc42.berbin0 -> 14 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc43.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc44.berbin0 -> 2 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc45.berbin0 -> 2 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc46.berbin0 -> 11 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc47.berbin0 -> 16 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc48.berbin0 -> 16 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc5.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc6.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc7.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc8.berbin0 -> 5 bytes
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc9.ber1
-rw-r--r--Godeps/_workspace/src/gopkg.in/asn1-ber.v1/util.go24
62 files changed, 1834 insertions, 0 deletions
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/.travis.yml b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/.travis.yml
new file mode 100644
index 000000000..44aa48b87
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/.travis.yml
@@ -0,0 +1,15 @@
+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 ./...
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/LICENSE b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/LICENSE
new file mode 100644
index 000000000..744875676
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2012 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/README.md b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/README.md
new file mode 100644
index 000000000..e3a9560d6
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/README.md
@@ -0,0 +1,24 @@
+[![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
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/ber.go b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/ber.go
new file mode 100644
index 000000000..25cc921be
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/ber.go
@@ -0,0 +1,504 @@
+package ber
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "reflect"
+)
+
+type Packet struct {
+ Identifier
+ Value interface{}
+ ByteValue []byte
+ Data *bytes.Buffer
+ Children []*Packet
+ Description string
+}
+
+type Identifier struct {
+ ClassType Class
+ TagType Type
+ Tag Tag
+}
+
+type Tag uint64
+
+const (
+ TagEOC Tag = 0x00
+ TagBoolean Tag = 0x01
+ TagInteger Tag = 0x02
+ TagBitString Tag = 0x03
+ TagOctetString Tag = 0x04
+ TagNULL Tag = 0x05
+ TagObjectIdentifier Tag = 0x06
+ TagObjectDescriptor Tag = 0x07
+ TagExternal Tag = 0x08
+ TagRealFloat Tag = 0x09
+ TagEnumerated Tag = 0x0a
+ TagEmbeddedPDV Tag = 0x0b
+ TagUTF8String Tag = 0x0c
+ TagRelativeOID Tag = 0x0d
+ TagSequence Tag = 0x10
+ TagSet Tag = 0x11
+ TagNumericString Tag = 0x12
+ TagPrintableString Tag = 0x13
+ TagT61String Tag = 0x14
+ TagVideotexString Tag = 0x15
+ TagIA5String Tag = 0x16
+ TagUTCTime Tag = 0x17
+ TagGeneralizedTime Tag = 0x18
+ TagGraphicString Tag = 0x19
+ TagVisibleString Tag = 0x1a
+ TagGeneralString Tag = 0x1b
+ TagUniversalString Tag = 0x1c
+ TagCharacterString Tag = 0x1d
+ TagBMPString Tag = 0x1e
+ TagBitmask Tag = 0x1f // xxx11111b
+
+ // HighTag indicates the start of a high-tag byte sequence
+ HighTag Tag = 0x1f // xxx11111b
+ // HighTagContinueBitmask indicates the high-tag byte sequence should continue
+ HighTagContinueBitmask Tag = 0x80 // 10000000b
+ // HighTagValueBitmask obtains the tag value from a high-tag byte sequence byte
+ HighTagValueBitmask Tag = 0x7f // 01111111b
+)
+
+const (
+ // LengthLongFormBitmask is the mask to apply to the length byte to see if a long-form byte sequence is used
+ LengthLongFormBitmask = 0x80
+ // LengthValueBitmask is the mask to apply to the length byte to get the number of bytes in the long-form byte sequence
+ LengthValueBitmask = 0x7f
+
+ // LengthIndefinite is returned from readLength to indicate an indefinite length
+ LengthIndefinite = -1
+)
+
+var tagMap = map[Tag]string{
+ TagEOC: "EOC (End-of-Content)",
+ TagBoolean: "Boolean",
+ TagInteger: "Integer",
+ TagBitString: "Bit String",
+ TagOctetString: "Octet String",
+ TagNULL: "NULL",
+ TagObjectIdentifier: "Object Identifier",
+ TagObjectDescriptor: "Object Descriptor",
+ TagExternal: "External",
+ TagRealFloat: "Real (float)",
+ TagEnumerated: "Enumerated",
+ TagEmbeddedPDV: "Embedded PDV",
+ TagUTF8String: "UTF8 String",
+ TagRelativeOID: "Relative-OID",
+ TagSequence: "Sequence and Sequence of",
+ TagSet: "Set and Set OF",
+ TagNumericString: "Numeric String",
+ TagPrintableString: "Printable String",
+ TagT61String: "T61 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",
+}
+
+type Class uint8
+
+const (
+ ClassUniversal Class = 0 // 00xxxxxxb
+ ClassApplication Class = 64 // 01xxxxxxb
+ ClassContext Class = 128 // 10xxxxxxb
+ ClassPrivate Class = 192 // 11xxxxxxb
+ ClassBitmask Class = 192 // 11xxxxxxb
+)
+
+var ClassMap = map[Class]string{
+ ClassUniversal: "Universal",
+ ClassApplication: "Application",
+ ClassContext: "Context",
+ ClassPrivate: "Private",
+}
+
+type Type uint8
+
+const (
+ TypePrimitive Type = 0 // xx0xxxxxb
+ TypeConstructed Type = 32 // xx1xxxxxb
+ TypeBitmask Type = 32 // xx1xxxxxb
+)
+
+var TypeMap = map[Type]string{
+ TypePrimitive: "Primitive",
+ TypeConstructed: "Constructed",
+}
+
+var Debug bool = false
+
+func PrintBytes(out io.Writer, buf []byte, indent string) {
+ data_lines := make([]string, (len(buf)/30)+1)
+ num_lines := make([]string, (len(buf)/30)+1)
+
+ for i, b := range buf {
+ data_lines[i/30] += fmt.Sprintf("%02x ", b)
+ num_lines[i/30] += fmt.Sprintf("%02d ", (i+1)%100)
+ }
+
+ for i := 0; i < len(data_lines); i++ {
+ out.Write([]byte(indent + data_lines[i] + "\n"))
+ out.Write([]byte(indent + num_lines[i] + "\n\n"))
+ }
+}
+
+func PrintPacket(p *Packet) {
+ printPacket(os.Stdout, p, 0, false)
+}
+
+func printPacket(out io.Writer, p *Packet, indent int, printBytes bool) {
+ indent_str := ""
+
+ for len(indent_str) != indent {
+ indent_str += " "
+ }
+
+ class_str := ClassMap[p.ClassType]
+
+ tagtype_str := TypeMap[p.TagType]
+
+ tag_str := fmt.Sprintf("0x%02X", p.Tag)
+
+ if p.ClassType == ClassUniversal {
+ tag_str = tagMap[p.Tag]
+ }
+
+ value := fmt.Sprint(p.Value)
+ description := ""
+
+ if p.Description != "" {
+ description = p.Description + ": "
+ }
+
+ fmt.Fprintf(out, "%s%s(%s, %s, %s) Len=%d %q\n", indent_str, description, class_str, tagtype_str, tag_str, p.Data.Len(), value)
+
+ if printBytes {
+ PrintBytes(out, p.Bytes(), indent_str)
+ }
+
+ for _, child := range p.Children {
+ printPacket(out, child, indent+1, printBytes)
+ }
+}
+
+// ReadPacket reads a single Packet from the reader
+func ReadPacket(reader io.Reader) (*Packet, error) {
+ p, _, err := readPacket(reader)
+ if err != nil {
+ return nil, err
+ }
+ return p, nil
+}
+
+func DecodeString(data []byte) string {
+ return string(data)
+}
+
+func parseInt64(bytes []byte) (ret int64, err error) {
+ if len(bytes) > 8 {
+ // We'll overflow an int64 in this case.
+ err = fmt.Errorf("integer too large")
+ return
+ }
+ for bytesRead := 0; bytesRead < len(bytes); bytesRead++ {
+ ret <<= 8
+ ret |= int64(bytes[bytesRead])
+ }
+
+ // Shift up and down in order to sign extend the result.
+ ret <<= 64 - uint8(len(bytes))*8
+ ret >>= 64 - uint8(len(bytes))*8
+ return
+}
+
+func encodeInteger(i int64) []byte {
+ n := int64Length(i)
+ out := make([]byte, n)
+
+ var j int
+ for ; n > 0; n-- {
+ out[j] = (byte(i >> uint((n-1)*8)))
+ j++
+ }
+
+ return out
+}
+
+func int64Length(i int64) (numBytes int) {
+ numBytes = 1
+
+ for i > 127 {
+ numBytes++
+ i >>= 8
+ }
+
+ for i < -128 {
+ numBytes++
+ i >>= 8
+ }
+
+ return
+}
+
+// DecodePacket decodes the given bytes into a single Packet
+// If a decode error is encountered, nil is returned.
+func DecodePacket(data []byte) *Packet {
+ p, _, _ := readPacket(bytes.NewBuffer(data))
+
+ return p
+}
+
+// DecodePacketErr decodes the given bytes into a single Packet
+// If a decode error is encountered, nil is returned
+func DecodePacketErr(data []byte) (*Packet, error) {
+ p, _, err := readPacket(bytes.NewBuffer(data))
+ if err != nil {
+ return nil, err
+ }
+ return p, nil
+}
+
+// readPacket reads a single Packet from the reader, returning the number of bytes read
+func readPacket(reader io.Reader) (*Packet, int, error) {
+ identifier, length, read, err := readHeader(reader)
+ if err != nil {
+ return nil, read, err
+ }
+
+ p := &Packet{
+ Identifier: identifier,
+ }
+
+ p.Data = new(bytes.Buffer)
+ p.Children = make([]*Packet, 0, 2)
+ p.Value = nil
+
+ if p.TagType == TypeConstructed {
+ // TODO: if universal, ensure tag type is allowed to be constructed
+
+ // Track how much content we've read
+ contentRead := 0
+ for {
+ if length != LengthIndefinite {
+ // End if we've read what we've been told to
+ if contentRead == length {
+ break
+ }
+ // Detect if a packet boundary didn't fall on the expected length
+ if contentRead > length {
+ return nil, read, fmt.Errorf("expected to read %d bytes, read %d", length, contentRead)
+ }
+ }
+
+ // Read the next packet
+ child, r, err := readPacket(reader)
+ if err != nil {
+ return nil, read, err
+ }
+ contentRead += r
+ read += r
+
+ // Test is this is the EOC marker for our packet
+ if isEOCPacket(child) {
+ if length == LengthIndefinite {
+ break
+ }
+ return nil, read, errors.New("eoc child not allowed with definite length")
+ }
+
+ // Append and continue
+ p.AppendChild(child)
+ }
+ return p, read, nil
+ }
+
+ if length == LengthIndefinite {
+ return nil, read, errors.New("indefinite length used with primitive type")
+ }
+
+ // Read definite-length content
+ content := make([]byte, length, length)
+ if length > 0 {
+ _, err := io.ReadFull(reader, content)
+ if err != nil {
+ if err == io.EOF {
+ return nil, read, io.ErrUnexpectedEOF
+ }
+ return nil, read, err
+ }
+ read += length
+ }
+
+ if p.ClassType == ClassUniversal {
+ p.Data.Write(content)
+ p.ByteValue = content
+
+ switch p.Tag {
+ case TagEOC:
+ case TagBoolean:
+ val, _ := parseInt64(content)
+
+ p.Value = val != 0
+ case TagInteger:
+ p.Value, _ = parseInt64(content)
+ case TagBitString:
+ case TagOctetString:
+ // the actual string encoding is not known here
+ // (e.g. for LDAP content is already an UTF8-encoded
+ // string). Return the data without further processing
+ p.Value = DecodeString(content)
+ case TagNULL:
+ case TagObjectIdentifier:
+ case TagObjectDescriptor:
+ case TagExternal:
+ case TagRealFloat:
+ case TagEnumerated:
+ p.Value, _ = parseInt64(content)
+ case TagEmbeddedPDV:
+ case TagUTF8String:
+ p.Value = DecodeString(content)
+ case TagRelativeOID:
+ case TagSequence:
+ case TagSet:
+ case TagNumericString:
+ case TagPrintableString:
+ p.Value = DecodeString(content)
+ case TagT61String:
+ case TagVideotexString:
+ case TagIA5String:
+ case TagUTCTime:
+ case TagGeneralizedTime:
+ case TagGraphicString:
+ case TagVisibleString:
+ case TagGeneralString:
+ case TagUniversalString:
+ case TagCharacterString:
+ case TagBMPString:
+ }
+ } else {
+ p.Data.Write(content)
+ }
+
+ return p, read, nil
+}
+
+func (p *Packet) Bytes() []byte {
+ var out bytes.Buffer
+
+ out.Write(encodeIdentifier(p.Identifier))
+ out.Write(encodeLength(p.Data.Len()))
+ out.Write(p.Data.Bytes())
+
+ return out.Bytes()
+}
+
+func (p *Packet) AppendChild(child *Packet) {
+ p.Data.Write(child.Bytes())
+ p.Children = append(p.Children, child)
+}
+
+func Encode(ClassType Class, TagType Type, Tag Tag, Value interface{}, Description string) *Packet {
+ p := new(Packet)
+
+ p.ClassType = ClassType
+ p.TagType = TagType
+ p.Tag = Tag
+ p.Data = new(bytes.Buffer)
+
+ p.Children = make([]*Packet, 0, 2)
+
+ p.Value = Value
+ p.Description = Description
+
+ if Value != nil {
+ v := reflect.ValueOf(Value)
+
+ if ClassType == ClassUniversal {
+ switch Tag {
+ case TagOctetString:
+ sv, ok := v.Interface().(string)
+
+ if ok {
+ p.Data.Write([]byte(sv))
+ }
+ }
+ }
+ }
+
+ return p
+}
+
+func NewSequence(Description string) *Packet {
+ return Encode(ClassUniversal, TypeConstructed, TagSequence, nil, Description)
+}
+
+func NewBoolean(ClassType Class, TagType Type, Tag Tag, Value bool, Description string) *Packet {
+ intValue := int64(0)
+
+ if Value {
+ intValue = 1
+ }
+
+ p := Encode(ClassType, TagType, Tag, nil, Description)
+
+ p.Value = Value
+ p.Data.Write(encodeInteger(intValue))
+
+ return p
+}
+
+func NewInteger(ClassType Class, TagType Type, Tag Tag, Value interface{}, Description string) *Packet {
+ p := Encode(ClassType, TagType, Tag, nil, Description)
+
+ p.Value = Value
+ switch v := Value.(type) {
+ case int:
+ p.Data.Write(encodeInteger(int64(v)))
+ case uint:
+ p.Data.Write(encodeInteger(int64(v)))
+ case int64:
+ p.Data.Write(encodeInteger(v))
+ case uint64:
+ // TODO : check range or add encodeUInt...
+ p.Data.Write(encodeInteger(int64(v)))
+ case int32:
+ p.Data.Write(encodeInteger(int64(v)))
+ case uint32:
+ p.Data.Write(encodeInteger(int64(v)))
+ case int16:
+ p.Data.Write(encodeInteger(int64(v)))
+ case uint16:
+ p.Data.Write(encodeInteger(int64(v)))
+ case int8:
+ p.Data.Write(encodeInteger(int64(v)))
+ case uint8:
+ p.Data.Write(encodeInteger(int64(v)))
+ default:
+ // TODO : add support for big.Int ?
+ panic(fmt.Sprintf("Invalid type %T, expected {u|}int{64|32|16|8}", v))
+ }
+
+ return p
+}
+
+func NewString(ClassType Class, TagType Type, Tag Tag, Value, Description string) *Packet {
+ p := Encode(ClassType, TagType, Tag, nil, Description)
+
+ p.Value = Value
+ p.Data.Write([]byte(Value))
+
+ return p
+}
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/ber_test.go b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/ber_test.go
new file mode 100644
index 000000000..bbd22db6d
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/ber_test.go
@@ -0,0 +1,168 @@
+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")
+ }
+}
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/content_int.go b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/content_int.go
new file mode 100644
index 000000000..1858b74b6
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/content_int.go
@@ -0,0 +1,25 @@
+package ber
+
+func encodeUnsignedInteger(i uint64) []byte {
+ n := uint64Length(i)
+ out := make([]byte, n)
+
+ var j int
+ for ; n > 0; n-- {
+ out[j] = (byte(i >> uint((n-1)*8)))
+ j++
+ }
+
+ return out
+}
+
+func uint64Length(i uint64) (numBytes int) {
+ numBytes = 1
+
+ for i > 255 {
+ numBytes++
+ i >>= 8
+ }
+
+ return
+}
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/header.go b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/header.go
new file mode 100644
index 000000000..123744e9b
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/header.go
@@ -0,0 +1,29 @@
+package ber
+
+import (
+ "errors"
+ "io"
+)
+
+func readHeader(reader io.Reader) (identifier Identifier, length int, read int, err error) {
+ if i, c, err := readIdentifier(reader); err != nil {
+ return Identifier{}, 0, read, err
+ } else {
+ identifier = i
+ read += c
+ }
+
+ if l, c, err := readLength(reader); err != nil {
+ return Identifier{}, 0, read, err
+ } else {
+ length = l
+ read += c
+ }
+
+ // Validate length type with identifier (x.600, 8.1.3.2.a)
+ if length == LengthIndefinite && identifier.TagType == TypePrimitive {
+ return Identifier{}, 0, read, errors.New("indefinite length used with primitive type")
+ }
+
+ return identifier, length, read, nil
+}
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/header_test.go b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/header_test.go
new file mode 100644
index 000000000..cac1e2e2b
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/header_test.go
@@ -0,0 +1,135 @@
+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)
+ }
+ }
+}
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/identifier.go b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/identifier.go
new file mode 100644
index 000000000..f7672a844
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/identifier.go
@@ -0,0 +1,103 @@
+package ber
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "math"
+)
+
+func readIdentifier(reader io.Reader) (Identifier, int, error) {
+ identifier := Identifier{}
+ read := 0
+
+ // identifier byte
+ b, err := readByte(reader)
+ if err != nil {
+ if Debug {
+ fmt.Printf("error reading identifier byte: %v\n", err)
+ }
+ return Identifier{}, read, err
+ }
+ read++
+
+ identifier.ClassType = Class(b) & ClassBitmask
+ identifier.TagType = Type(b) & TypeBitmask
+
+ if tag := Tag(b) & TagBitmask; tag != HighTag {
+ // short-form tag
+ identifier.Tag = tag
+ return identifier, read, nil
+ }
+
+ // high-tag-number tag
+ tagBytes := 0
+ for {
+ b, err := readByte(reader)
+ if err != nil {
+ if Debug {
+ fmt.Printf("error reading high-tag-number tag byte %d: %v\n", tagBytes, err)
+ }
+ return Identifier{}, read, err
+ }
+ tagBytes++
+ read++
+
+ // Lowest 7 bits get appended to the tag value (x.690, 8.1.2.4.2.b)
+ identifier.Tag <<= 7
+ identifier.Tag |= Tag(b) & HighTagValueBitmask
+
+ // First byte may not be all zeros (x.690, 8.1.2.4.2.c)
+ if tagBytes == 1 && identifier.Tag == 0 {
+ return Identifier{}, read, errors.New("invalid first high-tag-number tag byte")
+ }
+ // Overflow of int64
+ // TODO: support big int tags?
+ if tagBytes > 9 {
+ return Identifier{}, read, errors.New("high-tag-number tag overflow")
+ }
+
+ // Top bit of 0 means this is the last byte in the high-tag-number tag (x.690, 8.1.2.4.2.a)
+ if Tag(b)&HighTagContinueBitmask == 0 {
+ break
+ }
+ }
+
+ return identifier, read, nil
+}
+
+func encodeIdentifier(identifier Identifier) []byte {
+ b := []byte{0x0}
+ b[0] |= byte(identifier.ClassType)
+ b[0] |= byte(identifier.TagType)
+
+ if identifier.Tag < HighTag {
+ // Short-form
+ b[0] |= byte(identifier.Tag)
+ } else {
+ // high-tag-number
+ b[0] |= byte(HighTag)
+
+ tag := identifier.Tag
+
+ highBit := uint(63)
+ for {
+ if tag&(1<<highBit) != 0 {
+ break
+ }
+ highBit--
+ }
+
+ tagBytes := int(math.Ceil(float64(highBit) / 7.0))
+ for i := tagBytes - 1; i >= 0; i-- {
+ offset := uint(i) * 7
+ mask := Tag(0x7f) << offset
+ tagByte := (tag & mask) >> offset
+ if i != 0 {
+ tagByte |= 0x80
+ }
+ b = append(b, byte(tagByte))
+ }
+ }
+ return b
+}
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/identifier_test.go b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/identifier_test.go
new file mode 100644
index 000000000..7169362e2
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/identifier_test.go
@@ -0,0 +1,344 @@
+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)
+ }
+ }
+}
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/length.go b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/length.go
new file mode 100644
index 000000000..8e2ae4ddd
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/length.go
@@ -0,0 +1,71 @@
+package ber
+
+import (
+ "errors"
+ "fmt"
+ "io"
+)
+
+func readLength(reader io.Reader) (length int, read int, err error) {
+ // length byte
+ b, err := readByte(reader)
+ if err != nil {
+ if Debug {
+ fmt.Printf("error reading length byte: %v\n", err)
+ }
+ return 0, 0, err
+ }
+ read++
+
+ switch {
+ case b == 0xFF:
+ // Invalid 0xFF (x.600, 8.1.3.5.c)
+ return 0, read, errors.New("invalid length byte 0xff")
+
+ case b == LengthLongFormBitmask:
+ // Indefinite form, we have to decode packets until we encounter an EOC packet (x.600, 8.1.3.6)
+ length = LengthIndefinite
+
+ case b&LengthLongFormBitmask == 0:
+ // Short definite form, extract the length from the bottom 7 bits (x.600, 8.1.3.4)
+ length = int(b) & LengthValueBitmask
+
+ case b&LengthLongFormBitmask != 0:
+ // Long definite form, extract the number of length bytes to follow from the bottom 7 bits (x.600, 8.1.3.5.b)
+ lengthBytes := int(b) & LengthValueBitmask
+ // Protect against overflow
+ // TODO: support big int length?
+ if lengthBytes > 8 {
+ return 0, read, errors.New("long-form length overflow")
+ }
+ for i := 0; i < lengthBytes; i++ {
+ b, err = readByte(reader)
+ if err != nil {
+ if Debug {
+ fmt.Printf("error reading long-form length byte %d: %v\n", i, err)
+ }
+ return 0, read, err
+ }
+ read++
+
+ // x.600, 8.1.3.5
+ length <<= 8
+ length |= int(b)
+ }
+
+ default:
+ return 0, read, errors.New("invalid length byte")
+ }
+
+ return length, read, nil
+}
+
+func encodeLength(length int) []byte {
+ length_bytes := encodeUnsignedInteger(uint64(length))
+ if length > 127 || len(length_bytes) > 1 {
+ longFormBytes := []byte{(LengthLongFormBitmask | byte(len(length_bytes)))}
+ longFormBytes = append(longFormBytes, length_bytes...)
+ length_bytes = longFormBytes
+ }
+ return length_bytes
+}
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/length_test.go b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/length_test.go
new file mode 100644
index 000000000..afe0e8037
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/length_test.go
@@ -0,0 +1,158 @@
+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)
+ }
+ }
+}
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/suite_test.go b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/suite_test.go
new file mode 100644
index 000000000..ace8e6705
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/suite_test.go
@@ -0,0 +1,182 @@
+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)
+ }
+ }
+}
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc1.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc1.ber
new file mode 100644
index 000000000..5c6ba1c6a
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc1.ber
@@ -0,0 +1 @@
+@ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc10.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc10.ber
new file mode 100644
index 000000000..f733125d4
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc10.ber
@@ -0,0 +1 @@
+  \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc11.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc11.ber
new file mode 100644
index 000000000..cc4a609c8
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc11.ber
@@ -0,0 +1 @@
+  015625 \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc12.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc12.ber
new file mode 100644
index 000000000..dbb538d69
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc12.ber
@@ -0,0 +1 @@
+ I \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc13.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc13.ber
new file mode 100644
index 000000000..f4f438e0d
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc13.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc14.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc14.ber
new file mode 100644
index 000000000..b6f2fd3a4
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc14.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc15.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc15.ber
new file mode 100644
index 000000000..3d6da6764
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc15.ber
@@ -0,0 +1 @@
+  \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc16.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc16.ber
new file mode 100644
index 000000000..68634f5f3
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc16.ber
@@ -0,0 +1 @@
+  \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc17.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc17.ber
new file mode 100644
index 000000000..adb9e3320
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc17.ber
@@ -0,0 +1 @@
+   \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc18.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc18.ber
new file mode 100644
index 000000000..fb6843f7f
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc18.ber
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc19.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc19.ber
new file mode 100644
index 000000000..03afaa5de
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc19.ber
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc2.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc2.ber
new file mode 100644
index 000000000..7e785773c
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc2.ber
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc20.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc20.ber
new file mode 100644
index 000000000..a976464b9
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc20.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc21.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc21.ber
new file mode 100644
index 000000000..d6c2f9aa7
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc21.ber
@@ -0,0 +1 @@
+Q \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc22.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc22.ber
new file mode 100644
index 000000000..d1d70afab
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc22.ber
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc23.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc23.ber
new file mode 100644
index 000000000..0e8d18f62
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc23.ber
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc24.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc24.ber
new file mode 100644
index 000000000..10565aefa
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc24.ber
@@ -0,0 +1 @@
+`HO Jc/ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc25.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc25.ber
new file mode 100644
index 000000000..1e1140524
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc25.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc26.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc26.ber
new file mode 100644
index 000000000..d28653b3b
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc26.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc27.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc27.ber
new file mode 100644
index 000000000..c8c781144
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc27.ber
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc28.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc28.ber
new file mode 100644
index 000000000..415fe23ed
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc28.ber
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc29.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc29.ber
new file mode 100644
index 000000000..4076f4487
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc29.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc3.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc3.ber
new file mode 100644
index 000000000..c05c900b6
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc3.ber
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc30.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc30.ber
new file mode 100644
index 000000000..72bcf80f4
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc30.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc31.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc31.ber
new file mode 100644
index 000000000..1fcc4f254
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc31.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc32.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc32.ber
new file mode 100644
index 000000000..19b3e940a
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc32.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc33.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc33.ber
new file mode 100644
index 000000000..6ea70c4d2
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc33.ber
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc34.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc34.ber
new file mode 100644
index 000000000..61337095d
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc34.ber
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc35.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc35.ber
new file mode 100644
index 000000000..d27eb301a
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc35.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc36.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc36.ber
new file mode 100644
index 000000000..e5baaeacd
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc36.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc37.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc37.ber
new file mode 100644
index 000000000..d0b1cfbe1
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc37.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc38.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc38.ber
new file mode 100644
index 000000000..090bce74b
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc38.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc39.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc39.ber
new file mode 100644
index 000000000..d9d01199b
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc39.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc4.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc4.ber
new file mode 100644
index 000000000..2b888baac
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc4.ber
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc40.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc40.ber
new file mode 100644
index 000000000..15294a501
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc40.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc41.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc41.ber
new file mode 100644
index 000000000..276836b65
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc41.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc42.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc42.ber
new file mode 100644
index 000000000..21cbfd10f
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc42.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc43.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc43.ber
new file mode 100644
index 000000000..98dbd7419
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc43.ber
@@ -0,0 +1 @@
+$ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc44.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc44.ber
new file mode 100644
index 000000000..d825e1ad7
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc44.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc45.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc45.ber
new file mode 100644
index 000000000..7b861b02c
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc45.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc46.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc46.ber
new file mode 100644
index 000000000..e78deee34
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc46.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc47.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc47.ber
new file mode 100644
index 000000000..190bb86f6
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc47.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc48.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc48.ber
new file mode 100644
index 000000000..f7f111ae6
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc48.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc5.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc5.ber
new file mode 100644
index 000000000..45e0a0093
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc5.ber
@@ -0,0 +1 @@
+@ \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc6.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc6.ber
new file mode 100644
index 000000000..cee1aaf0c
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc6.ber
@@ -0,0 +1 @@
+ +0.E-5 \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc7.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc7.ber
new file mode 100644
index 000000000..d5ae68572
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc7.ber
@@ -0,0 +1 @@
+ -0.E-5 \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc8.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc8.ber
new file mode 100644
index 000000000..cb32a09cb
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc8.ber
Binary files differ
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc9.ber b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc9.ber
new file mode 100644
index 000000000..50b43a510
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/tests/tc9.ber
@@ -0,0 +1 @@
+  \ No newline at end of file
diff --git a/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/util.go b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/util.go
new file mode 100644
index 000000000..3e56b66c8
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/asn1-ber.v1/util.go
@@ -0,0 +1,24 @@
+package ber
+
+import "io"
+
+func readByte(reader io.Reader) (byte, error) {
+ bytes := make([]byte, 1, 1)
+ _, err := io.ReadFull(reader, bytes)
+ if err != nil {
+ if err == io.EOF {
+ return 0, io.ErrUnexpectedEOF
+ }
+ return 0, err
+ }
+ return bytes[0], nil
+}
+
+func isEOCPacket(p *Packet) bool {
+ return p != nil &&
+ p.Tag == TagEOC &&
+ p.ClassType == ClassUniversal &&
+ p.TagType == TypePrimitive &&
+ len(p.ByteValue) == 0 &&
+ len(p.Children) == 0
+}