summaryrefslogtreecommitdiffstats
path: root/modules/asn1-ber
diff options
context:
space:
mode:
authorUnknwon <joe2010xtmf@163.com>2014-09-07 20:04:47 -0400
committerUnknwon <joe2010xtmf@163.com>2014-09-07 20:04:47 -0400
commit59a7c7c5a530cead1905c0c686869ea0f6a7949c (patch)
tree00e1e6a987b9fd032e24b2edd1603a0a711f3878 /modules/asn1-ber
parent25d6ae69d1cb392922b9d9dc0da1c17aef9a9db2 (diff)
downloadgitea-59a7c7c5a530cead1905c0c686869ea0f6a7949c.tar.gz
gitea-59a7c7c5a530cead1905c0c686869ea0f6a7949c.zip
Remove ldap dep
Diffstat (limited to 'modules/asn1-ber')
-rw-r--r--modules/asn1-ber/LICENSE27
-rw-r--r--modules/asn1-ber/Makefile11
-rw-r--r--modules/asn1-ber/README14
-rw-r--r--modules/asn1-ber/ber.go492
4 files changed, 544 insertions, 0 deletions
diff --git a/modules/asn1-ber/LICENSE b/modules/asn1-ber/LICENSE
new file mode 100644
index 0000000000..7448756763
--- /dev/null
+++ b/modules/asn1-ber/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/modules/asn1-ber/Makefile b/modules/asn1-ber/Makefile
new file mode 100644
index 0000000000..acda29afb7
--- /dev/null
+++ b/modules/asn1-ber/Makefile
@@ -0,0 +1,11 @@
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+include $(GOROOT)/src/Make.inc
+
+TARG=github.com/mmitton/asn1-ber
+GOFILES=\
+ ber.go\
+
+include $(GOROOT)/src/Make.pkg
diff --git a/modules/asn1-ber/README b/modules/asn1-ber/README
new file mode 100644
index 0000000000..bb785a06fc
--- /dev/null
+++ b/modules/asn1-ber/README
@@ -0,0 +1,14 @@
+ASN1 BER Encoding / Decoding Library for the GO programming language.
+
+Required Librarys:
+ None
+
+Working:
+ Very basic encoding / decoding needed for LDAP protocol
+
+Tests Implemented:
+ None
+
+TODO:
+ Fix all encoding / decoding to conform to ASN1 BER spec
+ Implement Tests / Benchmarks
diff --git a/modules/asn1-ber/ber.go b/modules/asn1-ber/ber.go
new file mode 100644
index 0000000000..3e99a273c6
--- /dev/null
+++ b/modules/asn1-ber/ber.go
@@ -0,0 +1,492 @@
+package ber
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "reflect"
+)
+
+type Packet struct {
+ ClassType uint8
+ TagType uint8
+ Tag uint8
+ Value interface{}
+ ByteValue []byte
+ Data *bytes.Buffer
+ Children []*Packet
+ Description string
+}
+
+const (
+ TagEOC = 0x00
+ TagBoolean = 0x01
+ TagInteger = 0x02
+ TagBitString = 0x03
+ TagOctetString = 0x04
+ TagNULL = 0x05
+ TagObjectIdentifier = 0x06
+ TagObjectDescriptor = 0x07
+ TagExternal = 0x08
+ TagRealFloat = 0x09
+ TagEnumerated = 0x0a
+ TagEmbeddedPDV = 0x0b
+ TagUTF8String = 0x0c
+ TagRelativeOID = 0x0d
+ TagSequence = 0x10
+ TagSet = 0x11
+ TagNumericString = 0x12
+ TagPrintableString = 0x13
+ TagT61String = 0x14
+ TagVideotexString = 0x15
+ TagIA5String = 0x16
+ TagUTCTime = 0x17
+ TagGeneralizedTime = 0x18
+ TagGraphicString = 0x19
+ TagVisibleString = 0x1a
+ TagGeneralString = 0x1b
+ TagUniversalString = 0x1c
+ TagCharacterString = 0x1d
+ TagBMPString = 0x1e
+ TagBitmask = 0x1f // xxx11111b
+)
+
+var TagMap = map[uint8]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",
+}
+
+const (
+ ClassUniversal = 0 // 00xxxxxxb
+ ClassApplication = 64 // 01xxxxxxb
+ ClassContext = 128 // 10xxxxxxb
+ ClassPrivate = 192 // 11xxxxxxb
+ ClassBitmask = 192 // 11xxxxxxb
+)
+
+var ClassMap = map[uint8]string{
+ ClassUniversal: "Universal",
+ ClassApplication: "Application",
+ ClassContext: "Context",
+ ClassPrivate: "Private",
+}
+
+const (
+ TypePrimitive = 0 // xx0xxxxxb
+ TypeConstructed = 32 // xx1xxxxxb
+ TypeBitmask = 32 // xx1xxxxxb
+)
+
+var TypeMap = map[uint8]string{
+ TypePrimitive: "Primative",
+ TypeConstructed: "Constructed",
+}
+
+var Debug bool = false
+
+func PrintBytes(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++ {
+ fmt.Print(indent + data_lines[i] + "\n")
+ fmt.Print(indent + num_lines[i] + "\n\n")
+ }
+}
+
+func PrintPacket(p *Packet) {
+ printPacket(p, 0, false)
+}
+
+func printPacket(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.Printf("%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(p.Bytes(), indent_str)
+ }
+
+ for _, child := range p.Children {
+ printPacket(child, indent+1, printBytes)
+ }
+}
+
+func resizeBuffer(in []byte, new_size uint64) (out []byte) {
+ out = make([]byte, new_size)
+
+ copy(out, in)
+
+ return
+}
+
+func readBytes(reader io.Reader, buf []byte) error {
+ idx := 0
+ buflen := len(buf)
+
+ for idx < buflen {
+ n, err := reader.Read(buf[idx:])
+ if err != nil {
+ return err
+ }
+ idx += n
+ }
+
+ return nil
+}
+
+func ReadPacket(reader io.Reader) (*Packet, error) {
+ buf := make([]byte, 2)
+
+ err := readBytes(reader, buf)
+
+ if err != nil {
+ return nil, err
+ }
+
+ idx := uint64(2)
+ datalen := uint64(buf[1])
+
+ if Debug {
+ fmt.Printf("Read: datalen = %d len(buf) = %d ", datalen, len(buf))
+
+ for _, b := range buf {
+ fmt.Printf("%02X ", b)
+ }
+
+ fmt.Printf("\n")
+ }
+
+ if datalen&128 != 0 {
+ a := datalen - 128
+
+ idx += a
+ buf = resizeBuffer(buf, 2+a)
+
+ err := readBytes(reader, buf[2:])
+
+ if err != nil {
+ return nil, err
+ }
+
+ datalen = DecodeInteger(buf[2 : 2+a])
+
+ if Debug {
+ fmt.Printf("Read: a = %d idx = %d datalen = %d len(buf) = %d", a, idx, datalen, len(buf))
+
+ for _, b := range buf {
+ fmt.Printf("%02X ", b)
+ }
+
+ fmt.Printf("\n")
+ }
+ }
+
+ buf = resizeBuffer(buf, idx+datalen)
+ err = readBytes(reader, buf[idx:])
+
+ if err != nil {
+ return nil, err
+ }
+
+ if Debug {
+ fmt.Printf("Read: len( buf ) = %d idx=%d datalen=%d idx+datalen=%d\n", len(buf), idx, datalen, idx+datalen)
+
+ for _, b := range buf {
+ fmt.Printf("%02X ", b)
+ }
+ }
+
+ p := DecodePacket(buf)
+
+ return p, nil
+}
+
+func DecodeString(data []byte) (ret string) {
+ for _, c := range data {
+ ret += fmt.Sprintf("%c", c)
+ }
+
+ return
+}
+
+func DecodeInteger(data []byte) (ret uint64) {
+ for _, i := range data {
+ ret = ret * 256
+ ret = ret + uint64(i)
+ }
+
+ return
+}
+
+func EncodeInteger(val uint64) []byte {
+ var out bytes.Buffer
+
+ found := false
+
+ shift := uint(56)
+
+ mask := uint64(0xFF00000000000000)
+
+ for mask > 0 {
+ if !found && (val&mask != 0) {
+ found = true
+ }
+
+ if found || (shift == 0) {
+ out.Write([]byte{byte((val & mask) >> shift)})
+ }
+
+ shift -= 8
+ mask = mask >> 8
+ }
+
+ return out.Bytes()
+}
+
+func DecodePacket(data []byte) *Packet {
+ p, _ := decodePacket(data)
+
+ return p
+}
+
+func decodePacket(data []byte) (*Packet, []byte) {
+ if Debug {
+ fmt.Printf("decodePacket: enter %d\n", len(data))
+ }
+
+ p := new(Packet)
+
+ p.ClassType = data[0] & ClassBitmask
+ p.TagType = data[0] & TypeBitmask
+ p.Tag = data[0] & TagBitmask
+
+ datalen := DecodeInteger(data[1:2])
+ datapos := uint64(2)
+
+ if datalen&128 != 0 {
+ datalen -= 128
+ datapos += datalen
+ datalen = DecodeInteger(data[2 : 2+datalen])
+ }
+
+ p.Data = new(bytes.Buffer)
+
+ p.Children = make([]*Packet, 0, 2)
+
+ p.Value = nil
+
+ value_data := data[datapos : datapos+datalen]
+
+ if p.TagType == TypeConstructed {
+ for len(value_data) != 0 {
+ var child *Packet
+
+ child, value_data = decodePacket(value_data)
+ p.AppendChild(child)
+ }
+ } else if p.ClassType == ClassUniversal {
+ p.Data.Write(data[datapos : datapos+datalen])
+ p.ByteValue = value_data
+
+ switch p.Tag {
+ case TagEOC:
+ case TagBoolean:
+ val := DecodeInteger(value_data)
+
+ p.Value = val != 0
+ case TagInteger:
+ p.Value = DecodeInteger(value_data)
+ case TagBitString:
+ case TagOctetString:
+ p.Value = DecodeString(value_data)
+ case TagNULL:
+ case TagObjectIdentifier:
+ case TagObjectDescriptor:
+ case TagExternal:
+ case TagRealFloat:
+ case TagEnumerated:
+ p.Value = DecodeInteger(value_data)
+ case TagEmbeddedPDV:
+ case TagUTF8String:
+ case TagRelativeOID:
+ case TagSequence:
+ case TagSet:
+ case TagNumericString:
+ case TagPrintableString:
+ p.Value = DecodeString(value_data)
+ 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(data[datapos : datapos+datalen])
+ }
+
+ return p, data[datapos+datalen:]
+}
+
+func (p *Packet) DataLength() uint64 {
+ return uint64(p.Data.Len())
+}
+
+func (p *Packet) Bytes() []byte {
+ var out bytes.Buffer
+
+ out.Write([]byte{p.ClassType | p.TagType | p.Tag})
+ packet_length := EncodeInteger(p.DataLength())
+
+ if p.DataLength() > 127 || len(packet_length) > 1 {
+ out.Write([]byte{byte(len(packet_length) | 128)})
+ out.Write(packet_length)
+ } else {
+ out.Write(packet_length)
+ }
+
+ out.Write(p.Data.Bytes())
+
+ return out.Bytes()
+}
+
+func (p *Packet) AppendChild(child *Packet) {
+ p.Data.Write(child.Bytes())
+
+ if len(p.Children) == cap(p.Children) {
+ newChildren := make([]*Packet, cap(p.Children)*2)
+
+ copy(newChildren, p.Children)
+ p.Children = newChildren[0:len(p.Children)]
+ }
+
+ p.Children = p.Children[0 : len(p.Children)+1]
+ p.Children[len(p.Children)-1] = child
+}
+
+func Encode(ClassType, TagType, Tag uint8, 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, TypePrimitive, TagSequence, nil, Description)
+}
+
+func NewBoolean(ClassType, TagType, Tag uint8, Value bool, Description string) *Packet {
+ intValue := 0
+
+ if Value {
+ intValue = 1
+ }
+
+ p := Encode(ClassType, TagType, Tag, nil, Description)
+
+ p.Value = Value
+ p.Data.Write(EncodeInteger(uint64(intValue)))
+
+ return p
+}
+
+func NewInteger(ClassType, TagType, Tag uint8, Value uint64, Description string) *Packet {
+ p := Encode(ClassType, TagType, Tag, nil, Description)
+
+ p.Value = Value
+ p.Data.Write(EncodeInteger(Value))
+
+ return p
+}
+
+func NewString(ClassType, TagType, Tag uint8, Value, Description string) *Packet {
+ p := Encode(ClassType, TagType, Tag, nil, Description)
+
+ p.Value = Value
+ p.Data.Write([]byte(Value))
+
+ return p
+}