You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

497 lines
9.9 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  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. }