ber.go 9.9 KB

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