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.

492 lines
9.8 KiB

10 years ago
  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) (ret string) {
  207. for _, c := range data {
  208. ret += fmt.Sprintf("%c", c)
  209. }
  210. return
  211. }
  212. func DecodeInteger(data []byte) (ret uint64) {
  213. for _, i := range data {
  214. ret = ret * 256
  215. ret = ret + uint64(i)
  216. }
  217. return
  218. }
  219. func EncodeInteger(val uint64) []byte {
  220. var out bytes.Buffer
  221. found := false
  222. shift := uint(56)
  223. mask := uint64(0xFF00000000000000)
  224. for mask > 0 {
  225. if !found && (val&mask != 0) {
  226. found = true
  227. }
  228. if found || (shift == 0) {
  229. out.Write([]byte{byte((val & mask) >> shift)})
  230. }
  231. shift -= 8
  232. mask = mask >> 8
  233. }
  234. return out.Bytes()
  235. }
  236. func DecodePacket(data []byte) *Packet {
  237. p, _ := decodePacket(data)
  238. return p
  239. }
  240. func decodePacket(data []byte) (*Packet, []byte) {
  241. if Debug {
  242. fmt.Printf("decodePacket: enter %d\n", len(data))
  243. }
  244. p := new(Packet)
  245. p.ClassType = data[0] & ClassBitmask
  246. p.TagType = data[0] & TypeBitmask
  247. p.Tag = data[0] & TagBitmask
  248. datalen := DecodeInteger(data[1:2])
  249. datapos := uint64(2)
  250. if datalen&128 != 0 {
  251. datalen -= 128
  252. datapos += datalen
  253. datalen = DecodeInteger(data[2 : 2+datalen])
  254. }
  255. p.Data = new(bytes.Buffer)
  256. p.Children = make([]*Packet, 0, 2)
  257. p.Value = nil
  258. value_data := data[datapos : datapos+datalen]
  259. if p.TagType == TypeConstructed {
  260. for len(value_data) != 0 {
  261. var child *Packet
  262. child, value_data = decodePacket(value_data)
  263. p.AppendChild(child)
  264. }
  265. } else if p.ClassType == ClassUniversal {
  266. p.Data.Write(data[datapos : datapos+datalen])
  267. p.ByteValue = value_data
  268. switch p.Tag {
  269. case TagEOC:
  270. case TagBoolean:
  271. val := DecodeInteger(value_data)
  272. p.Value = val != 0
  273. case TagInteger:
  274. p.Value = DecodeInteger(value_data)
  275. case TagBitString:
  276. case TagOctetString:
  277. p.Value = DecodeString(value_data)
  278. case TagNULL:
  279. case TagObjectIdentifier:
  280. case TagObjectDescriptor:
  281. case TagExternal:
  282. case TagRealFloat:
  283. case TagEnumerated:
  284. p.Value = DecodeInteger(value_data)
  285. case TagEmbeddedPDV:
  286. case TagUTF8String:
  287. case TagRelativeOID:
  288. case TagSequence:
  289. case TagSet:
  290. case TagNumericString:
  291. case TagPrintableString:
  292. p.Value = DecodeString(value_data)
  293. case TagT61String:
  294. case TagVideotexString:
  295. case TagIA5String:
  296. case TagUTCTime:
  297. case TagGeneralizedTime:
  298. case TagGraphicString:
  299. case TagVisibleString:
  300. case TagGeneralString:
  301. case TagUniversalString:
  302. case TagCharacterString:
  303. case TagBMPString:
  304. }
  305. } else {
  306. p.Data.Write(data[datapos : datapos+datalen])
  307. }
  308. return p, data[datapos+datalen:]
  309. }
  310. func (p *Packet) DataLength() uint64 {
  311. return uint64(p.Data.Len())
  312. }
  313. func (p *Packet) Bytes() []byte {
  314. var out bytes.Buffer
  315. out.Write([]byte{p.ClassType | p.TagType | p.Tag})
  316. packet_length := EncodeInteger(p.DataLength())
  317. if p.DataLength() > 127 || len(packet_length) > 1 {
  318. out.Write([]byte{byte(len(packet_length) | 128)})
  319. out.Write(packet_length)
  320. } else {
  321. out.Write(packet_length)
  322. }
  323. out.Write(p.Data.Bytes())
  324. return out.Bytes()
  325. }
  326. func (p *Packet) AppendChild(child *Packet) {
  327. p.Data.Write(child.Bytes())
  328. if len(p.Children) == cap(p.Children) {
  329. newChildren := make([]*Packet, cap(p.Children)*2)
  330. copy(newChildren, p.Children)
  331. p.Children = newChildren[0:len(p.Children)]
  332. }
  333. p.Children = p.Children[0 : len(p.Children)+1]
  334. p.Children[len(p.Children)-1] = child
  335. }
  336. func Encode(ClassType, TagType, Tag uint8, Value interface{}, Description string) *Packet {
  337. p := new(Packet)
  338. p.ClassType = ClassType
  339. p.TagType = TagType
  340. p.Tag = Tag
  341. p.Data = new(bytes.Buffer)
  342. p.Children = make([]*Packet, 0, 2)
  343. p.Value = Value
  344. p.Description = Description
  345. if Value != nil {
  346. v := reflect.ValueOf(Value)
  347. if ClassType == ClassUniversal {
  348. switch Tag {
  349. case TagOctetString:
  350. sv, ok := v.Interface().(string)
  351. if ok {
  352. p.Data.Write([]byte(sv))
  353. }
  354. }
  355. }
  356. }
  357. return p
  358. }
  359. func NewSequence(Description string) *Packet {
  360. return Encode(ClassUniversal, TypePrimitive, TagSequence, nil, Description)
  361. }
  362. func NewBoolean(ClassType, TagType, Tag uint8, Value bool, Description string) *Packet {
  363. intValue := 0
  364. if Value {
  365. intValue = 1
  366. }
  367. p := Encode(ClassType, TagType, Tag, nil, Description)
  368. p.Value = Value
  369. p.Data.Write(EncodeInteger(uint64(intValue)))
  370. return p
  371. }
  372. func NewInteger(ClassType, TagType, Tag uint8, Value uint64, Description string) *Packet {
  373. p := Encode(ClassType, TagType, Tag, nil, Description)
  374. p.Value = Value
  375. p.Data.Write(EncodeInteger(Value))
  376. return p
  377. }
  378. func NewString(ClassType, TagType, Tag uint8, Value, Description string) *Packet {
  379. p := Encode(ClassType, TagType, Tag, nil, Description)
  380. p.Value = Value
  381. p.Data.Write([]byte(Value))
  382. return p
  383. }