From 0559b7d4eab07cacf0f005e8e756c1d04470e0c7 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Fri, 25 Sep 2015 15:07:15 +0200 Subject: Broken, but a step in right direction --- ber/base128.go | 14 ++++++++++++++ ber/class.go | 37 +++++++++---------------------------- ber/class_test.go | 7 +++++-- ber/dump.go | 17 ++++++++++------- ber/len.go | 24 +++++++++++++++++++++--- ber/len_test.go | 2 +- ber/packet.go | 19 +++++++++++-------- 7 files changed, 71 insertions(+), 49 deletions(-) (limited to 'ber') diff --git a/ber/base128.go b/ber/base128.go index 4777651..bf894bb 100644 --- a/ber/base128.go +++ b/ber/base128.go @@ -1,5 +1,7 @@ package ber +import "io" + func base128(n int) (b []byte) { if n == 0 { return []byte{0} @@ -29,3 +31,15 @@ func debase128(b []byte) (i, n int) { } return } + +func Debase128(r io.ByteReader) (i int) { + for { + b, _ := r.ReadByte() + i <<= 7 + i |= int(b & 0x7f) + if b&0x80 == 0 { + return + } + } + return +} diff --git a/ber/class.go b/ber/class.go index b734964..ab455f1 100644 --- a/ber/class.go +++ b/ber/class.go @@ -1,5 +1,7 @@ package ber +import "io" + type Class byte const ( @@ -105,36 +107,15 @@ var tagNames = map[Tag]string{ func (t Tag) String() string { return tagNames[t] } -func Ident(b []byte) (Class, Kind, Tag, int) { - var d, n int - c := Class(b[0]) & classMask - k := Kind(b[0]) & kindMask - t := Tag(b[0]) & tagMask +func Ident(r io.ByteReader) (Class, Kind, Tag) { + b, _ := r.ReadByte() + c := Class(b) & classMask + k := Kind(b) & kindMask + t := Tag(b) & tagMask if t == tagMask { - d, n = debase128(b[1:]) - t = Tag(d) + t = Tag(Debase128(r)) } - return c, k, t, n + 1 -} - -func Unversal(b []byte) (int, bool) { - c, _, t, _ := Ident(b) - return int(t), c == classUniversal -} - -func Application(b []byte) (int, bool) { - c, _, t, _ := Ident(b) - return int(t), c == classApplication -} - -func ContextSpecific(b []byte) (int, bool) { - c, _, t, _ := Ident(b) - return int(t), c == classContextSpecific -} - -func Private(b []byte) (int, bool) { - c, _, t, _ := Ident(b) - return int(t), c == classPrivate + return c, k, t } func MarshalClass(c Class, k Kind, t Tag) []byte { diff --git a/ber/class_test.go b/ber/class_test.go index a0b2569..2eac220 100644 --- a/ber/class_test.go +++ b/ber/class_test.go @@ -1,6 +1,9 @@ package ber -import "fmt" +import ( + "bytes" + "fmt" +) var berTestData = []byte{ 0x02, 0x04, 0x0A, 0x30, @@ -10,7 +13,7 @@ var berTestData = []byte{ func ExampleIdent() { for _, test := range berTestData { - c, k, t, _ := Ident([]byte{test}) + c, k, t := Ident(bytes.NewBuffer([]byte{test})) if c == classUniversal { fmt.Printf("%#x: %v %v %v\n", test, c, k, t) diff --git a/ber/dump.go b/ber/dump.go index 64a2672..da2c8bf 100644 --- a/ber/dump.go +++ b/ber/dump.go @@ -1,9 +1,12 @@ package ber -import "fmt" +import ( + "bytes" + "fmt" +) func Dump(b []byte) string { - return dump(b, 0) + return dump(bytes.NewBuffer(b), 0) } func short(b []byte) string { @@ -13,8 +16,8 @@ func short(b []byte) string { return fmt.Sprint(b) } -func dump(b []byte, indent int) (s string) { - class, kind, tag, _, value, rest := Split(b) +func dump(r *bytes.Buffer, indent int) (s string) { + class, kind, tag, _, value := Split(r) s += fmt.Sprintf("%*s", indent*2, "") @@ -39,11 +42,11 @@ func dump(b []byte, indent int) (s string) { } if len(value) > 0 && kind != kindPrimitive { - s += dump(value, indent+1) + s += dump(bytes.NewBuffer(value), indent+1) } - if len(rest) > 0 { - s += dump(rest, indent) + if r.Len() > 0 { + s += dump(r, indent) } return } diff --git a/ber/len.go b/ber/len.go index 67aff34..2bccf59 100644 --- a/ber/len.go +++ b/ber/len.go @@ -1,12 +1,30 @@ package ber -func UnmarshalLen(b []byte) (i, n int) { +import ( + "io" +) + +func UnmarshalLen(r io.ByteReader) int { + b, _ := r.ReadByte() + if b&0x80 == 0 { + return int(b) + } + n := int(b & 0x7f) + var i int + for k := 0; k <= n; k++ { + b, _ := r.ReadByte() + i |= int(b) << uint(k*8) + } + return i +} + +func unmarshalLen(b []byte) (i, n int) { if b[0]&0x80 == 0 { return int(b[0]), 1 } n = int(b[0] & 0x7f) - for k := n; k > 0; k-- { - i += int(b[k]) << uint((k-1)*8) + for k := 0; k <= n; k++ { + i |= int(b[k]) << uint((k-1)*8) } return i, n + 1 } diff --git a/ber/len_test.go b/ber/len_test.go index ea40453..2db6453 100644 --- a/ber/len_test.go +++ b/ber/len_test.go @@ -24,7 +24,7 @@ func TestLen(t *testing.T) { if !bytes.Equal(a, test.out) { t.Error(test.in, "expected", test.out, "got", a) } - n, _ := UnmarshalLen(test.out) + n := UnmarshalLen(bytes.NewBuffer(test.out)) if n != test.in { t.Error(test.out, "expected", test.in, "got", n) } diff --git a/ber/packet.go b/ber/packet.go index f244c4e..ea90240 100644 --- a/ber/packet.go +++ b/ber/packet.go @@ -1,12 +1,15 @@ package ber -func Split(b []byte) (c Class, k Kind, t Tag, l int, v []byte, r []byte) { - var n int - c, k, t, n = Ident(b) - b = b[n:] - l, n = UnmarshalLen(b) - b = b[n:] - v = b[:l] - r = b[l:] +import "io" + +func Split(r io.ByteReader) (c Class, k Kind, t Tag, l int, v []byte) { + c, k, t = Ident(r) + l = UnmarshalLen(r) + if l > 0 { + v = make([]byte, l) + for i := 0; i < l; i++ { + v[i], _ = r.ReadByte() + } + } return } -- cgit v1.2.3