summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Harper <cabrel@zerklabs.com>2014-02-27 22:32:03 +0100
committerRobin Harper <cabrel@zerklabs.com>2014-02-27 22:32:03 +0100
commit0f360d2339e0580e1a506ba69f0972e8ed80a90f (patch)
treea8c87af2dba265e7dd2fb9de27bb753ab6b10122
parentMerge pull request #8 from bollenberger/master (diff)
downloadasn1-ber-0f360d2339e0580e1a506ba69f0972e8ed80a90f.tar
asn1-ber-0f360d2339e0580e1a506ba69f0972e8ed80a90f.tar.gz
asn1-ber-0f360d2339e0580e1a506ba69f0972e8ed80a90f.tar.bz2
asn1-ber-0f360d2339e0580e1a506ba69f0972e8ed80a90f.tar.lz
asn1-ber-0f360d2339e0580e1a506ba69f0972e8ed80a90f.tar.xz
asn1-ber-0f360d2339e0580e1a506ba69f0972e8ed80a90f.tar.zst
asn1-ber-0f360d2339e0580e1a506ba69f0972e8ed80a90f.zip
-rw-r--r--ber.go566
1 files changed, 282 insertions, 284 deletions
diff --git a/ber.go b/ber.go
index 058fd48..31c43bd 100644
--- a/ber.go
+++ b/ber.go
@@ -3,19 +3,18 @@ package ber
import (
"bytes"
"fmt"
- "io"
- "os"
+ "io"
"reflect"
)
type Packet struct {
- ClassType uint8
- TagType uint8
- Tag uint8
- Value interface{}
- Data *bytes.Buffer
- Children []*Packet
- Description string
+ ClassType uint8
+ TagType uint8
+ Tag uint8
+ Value interface{}
+ Data *bytes.Buffer
+ Children []*Packet
+ Description string
}
const (
@@ -51,211 +50,211 @@ const (
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",
+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
+ 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",
+var ClassMap = map[uint8]string{
+ ClassUniversal: "Universal",
+ ClassApplication: "Application",
+ ClassContext: "Context",
+ ClassPrivate: "Private",
}
const (
- TypePrimative = 0 // xx0xxxxxb
- TypeConstructed = 32 // xx1xxxxxb
- TypeBitmask = 32 // xx1xxxxxb
+ TypePrimative = 0 // xx0xxxxxb
+ TypeConstructed = 32 // xx1xxxxxb
+ TypeBitmask = 32 // xx1xxxxxb
)
-var TypeMap = map[uint8] string {
- TypePrimative : "Primative",
- TypeConstructed : "Constructed",
+var TypeMap = map[uint8]string{
+ TypePrimative: "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 )
+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, 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" )
- }
+ 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) {
+ printPacket(p, 0, false)
}
-func printPacket( p *Packet, indent int, printBytes bool ) {
+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 )
+ 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 ]
- }
+ if p.ClassType == ClassUniversal {
+ tag_str = TagMap[p.Tag]
+ }
- value := fmt.Sprint( p.Value )
- description := ""
- if p.Description != "" {
- description = p.Description + ": "
- }
+ 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 )
+ 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 )
- }
+ if printBytes {
+ PrintBytes(p.Bytes(), indent_str)
+ }
- for _, child := range p.Children {
- printPacket( child, indent + 1, printBytes )
- }
+ 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 resizeBuffer(in []byte, new_size uint64) (out []byte) {
+ out = make([]byte, new_size)
+ copy(out, in)
+ return
}
-func readBytes( reader io.Reader, buf []byte ) os.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 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, os.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 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 )
+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 {
+func DecodeInteger(data []byte) (ret uint64) {
+ for _, i := range data {
ret = ret * 256
ret = ret + uint64(i)
}
return
}
-func EncodeInteger( val uint64 ) []byte {
+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 ) {
+ if !found && (val&mask != 0) {
found = true
}
- if found || ( shift == 0 ) {
- out.Write( []byte { byte( ( val & mask ) >> shift ) } )
+ if found || (shift == 0) {
+ out.Write([]byte{byte((val & mask) >> shift)})
}
shift -= 8
mask = mask >> 8
@@ -263,135 +262,135 @@ func EncodeInteger( val uint64 ) []byte {
return out.Bytes()
}
-func DecodePacket( data []byte ) *Packet {
- p, _ := decodePacket( data )
- return p
+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] )
+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])
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:
+ 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] )
- }
+ } else {
+ p.Data.Write(data[datapos : datapos+datalen])
+ }
- return p, data[ datapos + datalen: ]
+ return p, data[datapos+datalen:]
}
func (p *Packet) DataLength() uint64 {
- return uint64( p.Data.Len() )
+ 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 )
+ 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(packet_length)
}
- out.Write( p.Data.Bytes() )
+ 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 (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 )
+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
+ p.Data = new(bytes.Buffer)
+ p.Children = make([]*Packet, 0, 2)
+ p.Value = Value
+ p.Description = Description
if Value != nil {
- v := reflect.NewValue(Value)
+ v := reflect.ValueOf(Value)
- if ( ClassType == ClassUniversal ) {
+ if ClassType == ClassUniversal {
switch Tag {
- case TagOctetString:
- sv, ok := v.Interface().(string)
- if ok {
- p.Data.Write( []byte(sv) )
- }
+ case TagOctetString:
+ sv, ok := v.Interface().(string)
+ if ok {
+ p.Data.Write([]byte(sv))
+ }
}
}
}
@@ -399,33 +398,32 @@ func Encode( ClassType, TagType, Tag uint8, Value interface{}, Description strin
return p
}
-func NewSequence( Description string) *Packet {
- return Encode( ClassUniversal, TypePrimative, TagSequence, nil, Description )
+func NewSequence(Description string) *Packet {
+ return Encode(ClassUniversal, TypePrimative, TagSequence, nil, Description)
}
-func NewBoolean( ClassType, TagType, Tag uint8, Value bool, Description string ) *Packet {
- intValue := 0
- if Value {
- intValue = 1
- }
+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
+ 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 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
+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
}
-