ber.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. package ber
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io"
  6. "reflect"
  7. )
  8. type Packet struct {
  9. ClassType uint8
  10. TagType uint8
  11. Tag uint8
  12. Value interface{}
  13. ByteValue []byte
  14. Data *bytes.Buffer
  15. Children []*Packet
  16. Description string
  17. }
  18. const (
  19. TagEOC = 0x00
  20. TagBoolean = 0x01
  21. TagInteger = 0x02
  22. TagBitString = 0x03
  23. TagOctetString = 0x04
  24. TagNULL = 0x05
  25. TagObjectIdentifier = 0x06
  26. TagObjectDescriptor = 0x07
  27. TagExternal = 0x08
  28. TagRealFloat = 0x09
  29. TagEnumerated = 0x0a
  30. TagEmbeddedPDV = 0x0b
  31. TagUTF8String = 0x0c
  32. TagRelativeOID = 0x0d
  33. TagSequence = 0x10
  34. TagSet = 0x11
  35. TagNumericString = 0x12
  36. TagPrintableString = 0x13
  37. TagT61String = 0x14
  38. TagVideotexString = 0x15
  39. TagIA5String = 0x16
  40. TagUTCTime = 0x17
  41. TagGeneralizedTime = 0x18
  42. TagGraphicString = 0x19
  43. TagVisibleString = 0x1a
  44. TagGeneralString = 0x1b
  45. TagUniversalString = 0x1c
  46. TagCharacterString = 0x1d
  47. TagBMPString = 0x1e
  48. TagBitmask = 0x1f // xxx11111b
  49. )
  50. var TagMap = map[uint8]string{
  51. TagEOC: "EOC (End-of-Content)",
  52. TagBoolean: "Boolean",
  53. TagInteger: "Integer",
  54. TagBitString: "Bit String",
  55. TagOctetString: "Octet String",
  56. TagNULL: "NULL",
  57. TagObjectIdentifier: "Object Identifier",
  58. TagObjectDescriptor: "Object Descriptor",
  59. TagExternal: "External",
  60. TagRealFloat: "Real (float)",
  61. TagEnumerated: "Enumerated",
  62. TagEmbeddedPDV: "Embedded PDV",
  63. TagUTF8String: "UTF8 String",
  64. TagRelativeOID: "Relative-OID",
  65. TagSequence: "Sequence and Sequence of",
  66. TagSet: "Set and Set OF",
  67. TagNumericString: "Numeric String",
  68. TagPrintableString: "Printable String",
  69. TagT61String: "T61 String",
  70. TagVideotexString: "Videotex String",
  71. TagIA5String: "IA5 String",
  72. TagUTCTime: "UTC Time",
  73. TagGeneralizedTime: "Generalized Time",
  74. TagGraphicString: "Graphic String",
  75. TagVisibleString: "Visible String",
  76. TagGeneralString: "General String",
  77. TagUniversalString: "Universal String",
  78. TagCharacterString: "Character String",
  79. TagBMPString: "BMP String",
  80. }
  81. const (
  82. ClassUniversal = 0 // 00xxxxxxb
  83. ClassApplication = 64 // 01xxxxxxb
  84. ClassContext = 128 // 10xxxxxxb
  85. ClassPrivate = 192 // 11xxxxxxb
  86. ClassBitmask = 192 // 11xxxxxxb
  87. )
  88. var ClassMap = map[uint8]string{
  89. ClassUniversal: "Universal",
  90. ClassApplication: "Application",
  91. ClassContext: "Context",
  92. ClassPrivate: "Private",
  93. }
  94. const (
  95. TypePrimitive = 0 // xx0xxxxxb
  96. TypeConstructed = 32 // xx1xxxxxb
  97. TypeBitmask = 32 // xx1xxxxxb
  98. )
  99. var TypeMap = map[uint8]string{
  100. TypePrimitive: "Primative",
  101. TypeConstructed: "Constructed",
  102. }
  103. var Debug bool = false
  104. func PrintBytes(buf []byte, indent string) {
  105. data_lines := make([]string, (len(buf)/30)+1)
  106. num_lines := make([]string, (len(buf)/30)+1)
  107. for i, b := range buf {
  108. data_lines[i/30] += fmt.Sprintf("%02x ", b)
  109. num_lines[i/30] += fmt.Sprintf("%02d ", (i+1)%100)
  110. }
  111. for i := 0; i < len(data_lines); i++ {
  112. fmt.Print(indent + data_lines[i] + "\n")
  113. fmt.Print(indent + num_lines[i] + "\n\n")
  114. }
  115. }
  116. func PrintPacket(p *Packet) {
  117. printPacket(p, 0, false)
  118. }
  119. func printPacket(p *Packet, indent int, printBytes bool) {
  120. indent_str := ""
  121. for len(indent_str) != indent {
  122. indent_str += " "
  123. }
  124. class_str := ClassMap[p.ClassType]
  125. tagtype_str := TypeMap[p.TagType]
  126. tag_str := fmt.Sprintf("0x%02X", p.Tag)
  127. if p.ClassType == ClassUniversal {
  128. tag_str = TagMap[p.Tag]
  129. }
  130. value := fmt.Sprint(p.Value)
  131. description := ""
  132. if p.Description != "" {
  133. description = p.Description + ": "
  134. }
  135. fmt.Printf("%s%s(%s, %s, %s) Len=%d %q\n", indent_str, description, class_str, tagtype_str, tag_str, p.Data.Len(), value)
  136. if printBytes {
  137. PrintBytes(p.Bytes(), indent_str)
  138. }
  139. for _, child := range p.Children {
  140. printPacket(child, indent+1, printBytes)
  141. }
  142. }
  143. func resizeBuffer(in []byte, new_size uint64) (out []byte) {
  144. out = make([]byte, new_size)
  145. copy(out, in)
  146. return
  147. }
  148. func readBytes(reader io.Reader, buf []byte) error {
  149. idx := 0
  150. buflen := len(buf)
  151. for idx < buflen {
  152. n, err := reader.Read(buf[idx:])
  153. if err != nil {
  154. return err
  155. }
  156. idx += n
  157. }
  158. return nil
  159. }
  160. func ReadPacket(reader io.Reader) (*Packet, error) {
  161. buf := make([]byte, 2)
  162. err := readBytes(reader, buf)
  163. if err != nil {
  164. return nil, err
  165. }
  166. idx := uint64(2)
  167. datalen := uint64(buf[1])
  168. if Debug {
  169. fmt.Printf("Read: datalen = %d len(buf) = %d ", datalen, len(buf))
  170. for _, b := range buf {
  171. fmt.Printf("%02X ", b)
  172. }
  173. fmt.Printf("\n")
  174. }
  175. if datalen&128 != 0 {
  176. a := datalen - 128
  177. idx += a
  178. buf = resizeBuffer(buf, 2+a)
  179. err := readBytes(reader, buf[2:])
  180. if err != nil {
  181. return nil, err
  182. }
  183. datalen = DecodeInteger(buf[2 : 2+a])
  184. if Debug {
  185. fmt.Printf("Read: a = %d idx = %d datalen = %d len(buf) = %d", a, idx, datalen, len(buf))
  186. for _, b := range buf {
  187. fmt.Printf("%02X ", b)
  188. }
  189. fmt.Printf("\n")
  190. }
  191. }
  192. buf = resizeBuffer(buf, idx+datalen)
  193. err = readBytes(reader, buf[idx:])
  194. if err != nil {
  195. return nil, err
  196. }
  197. if Debug {
  198. fmt.Printf("Read: len( buf ) = %d idx=%d datalen=%d idx+datalen=%d\n", len(buf), idx, datalen, idx+datalen)
  199. for _, b := range buf {
  200. fmt.Printf("%02X ", b)
  201. }
  202. }
  203. p := DecodePacket(buf)
  204. return p, nil
  205. }
  206. func DecodeString(data []byte) (string) {
  207. return string(data)
  208. }
  209. func DecodeInteger(data []byte) (ret uint64) {
  210. for _, i := range data {
  211. ret = ret * 256
  212. ret = ret + uint64(i)
  213. }
  214. return
  215. }
  216. func EncodeInteger(val uint64) []byte {
  217. var out bytes.Buffer
  218. found := false
  219. shift := uint(56)
  220. mask := uint64(0xFF00000000000000)
  221. for mask > 0 {
  222. if !found && (val&mask != 0) {
  223. found = true
  224. }
  225. if found || (shift == 0) {
  226. out.Write([]byte{byte((val & mask) >> shift)})
  227. }
  228. shift -= 8
  229. mask = mask >> 8
  230. }
  231. byteSlice := out.Bytes()
  232. // if first bit in first byte is 1 it is necessary to append a leading 00 byte to make signum clear
  233. // otherwise it happens that a request with messageId => 02 01 80 get response with messageId => 02 04 FF FF FF 80
  234. if len(byteSlice) > 0 && byteSlice[0]&byte(128) != 0 {
  235. return append([]byte{0x00}, byteSlice...)
  236. }
  237. return byteSlice
  238. }
  239. func DecodePacket(data []byte) *Packet {
  240. p, _ := decodePacket(data)
  241. return p
  242. }
  243. func decodePacket(data []byte) (*Packet, []byte) {
  244. if Debug {
  245. fmt.Printf("decodePacket: enter %d\n", len(data))
  246. }
  247. p := new(Packet)
  248. p.ClassType = data[0] & ClassBitmask
  249. p.TagType = data[0] & TypeBitmask
  250. p.Tag = data[0] & TagBitmask
  251. datalen := DecodeInteger(data[1:2])
  252. datapos := uint64(2)
  253. if datalen&128 != 0 {
  254. datalen -= 128
  255. datapos += datalen
  256. datalen = DecodeInteger(data[2 : 2+datalen])
  257. }
  258. p.Data = new(bytes.Buffer)
  259. p.Children = make([]*Packet, 0, 2)
  260. p.Value = nil
  261. value_data := data[datapos : datapos+datalen]
  262. if p.TagType == TypeConstructed {
  263. for len(value_data) != 0 {
  264. var child *Packet
  265. child, value_data = decodePacket(value_data)
  266. p.AppendChild(child)
  267. }
  268. } else if p.ClassType == ClassUniversal {
  269. p.Data.Write(data[datapos : datapos+datalen])
  270. p.ByteValue = value_data
  271. switch p.Tag {
  272. case TagEOC:
  273. case TagBoolean:
  274. val := DecodeInteger(value_data)
  275. p.Value = val != 0
  276. case TagInteger:
  277. p.Value = DecodeInteger(value_data)
  278. case TagBitString:
  279. case TagOctetString:
  280. p.Value = DecodeString(value_data)
  281. case TagNULL:
  282. case TagObjectIdentifier:
  283. case TagObjectDescriptor:
  284. case TagExternal:
  285. case TagRealFloat:
  286. case TagEnumerated:
  287. p.Value = DecodeInteger(value_data)
  288. case TagEmbeddedPDV:
  289. case TagUTF8String:
  290. case TagRelativeOID:
  291. case TagSequence:
  292. case TagSet:
  293. case TagNumericString:
  294. case TagPrintableString:
  295. p.Value = DecodeString(value_data)
  296. case TagT61String:
  297. case TagVideotexString:
  298. case TagIA5String:
  299. case TagUTCTime:
  300. case TagGeneralizedTime:
  301. case TagGraphicString:
  302. case TagVisibleString:
  303. case TagGeneralString:
  304. case TagUniversalString:
  305. case TagCharacterString:
  306. case TagBMPString:
  307. }
  308. } else {
  309. p.Data.Write(data[datapos : datapos+datalen])
  310. }
  311. return p, data[datapos+datalen:]
  312. }
  313. func (p *Packet) DataLength() uint64 {
  314. return uint64(p.Data.Len())
  315. }
  316. func (p *Packet) Bytes() []byte {
  317. var out bytes.Buffer
  318. out.Write([]byte{p.ClassType | p.TagType | p.Tag})
  319. packet_length := EncodeInteger(p.DataLength())
  320. if p.DataLength() > 127 || len(packet_length) > 1 {
  321. out.Write([]byte{byte(len(packet_length) | 128)})
  322. out.Write(packet_length)
  323. } else {
  324. out.Write(packet_length)
  325. }
  326. out.Write(p.Data.Bytes())
  327. return out.Bytes()
  328. }
  329. func (p *Packet) AppendChild(child *Packet) {
  330. p.Data.Write(child.Bytes())
  331. if len(p.Children) == cap(p.Children) {
  332. newChildren := make([]*Packet, cap(p.Children)*2)
  333. copy(newChildren, p.Children)
  334. p.Children = newChildren[0:len(p.Children)]
  335. }
  336. p.Children = p.Children[0 : len(p.Children)+1]
  337. p.Children[len(p.Children)-1] = child
  338. }
  339. func Encode(ClassType, TagType, Tag uint8, Value interface{}, Description string) *Packet {
  340. p := new(Packet)
  341. p.ClassType = ClassType
  342. p.TagType = TagType
  343. p.Tag = Tag
  344. p.Data = new(bytes.Buffer)
  345. p.Children = make([]*Packet, 0, 2)
  346. p.Value = Value
  347. p.Description = Description
  348. if Value != nil {
  349. v := reflect.ValueOf(Value)
  350. if ClassType == ClassUniversal {
  351. switch Tag {
  352. case TagOctetString:
  353. sv, ok := v.Interface().(string)
  354. if ok {
  355. p.Data.Write([]byte(sv))
  356. }
  357. }
  358. }
  359. }
  360. return p
  361. }
  362. func NewSequence(Description string) *Packet {
  363. return Encode(ClassUniversal, TypePrimitive, TagSequence, nil, Description)
  364. }
  365. func NewBoolean(ClassType, TagType, Tag uint8, Value bool, Description string) *Packet {
  366. intValue := 0
  367. if Value {
  368. intValue = 1
  369. }
  370. p := Encode(ClassType, TagType, Tag, nil, Description)
  371. p.Value = Value
  372. p.Data.Write(EncodeInteger(uint64(intValue)))
  373. return p
  374. }
  375. func NewInteger(ClassType, TagType, Tag uint8, Value uint64, Description string) *Packet {
  376. p := Encode(ClassType, TagType, Tag, nil, Description)
  377. p.Value = Value
  378. p.Data.Write(EncodeInteger(Value))
  379. return p
  380. }
  381. func NewString(ClassType, TagType, Tag uint8, Value, Description string) *Packet {
  382. p := Encode(ClassType, TagType, Tag, nil, Description)
  383. p.Value = Value
  384. p.Data.Write([]byte(Value))
  385. return p
  386. }