Module: TLV
- Defined in:
- lib/tlv/b.rb,
lib/tlv/raw.rb,
lib/tlv/tag.rb,
lib/tlv/tlv.rb,
lib/tlv/field.rb,
lib/tlv/parse.rb,
lib/tlv/constructed.rb,
lib/tlv/parser/parser.rb
Defined Under Namespace
Classes: TLV, TLV_Object
Constant Summary collapse
- DICTIONARIES =
{}
- UNIVERSAL =
universal numbers, source en.wikipedia.org/wiki/Basic_Encoding_Rules
[ ['EOC (End-of-Content)',"P",0x00], ['BOOLEAN',"P",0x01], ['INTEGER',"P",0x02], ['BIT STRING',"P/C",0x03], ['OCTET STRING',"P/C",0x04], ['NULL',"P",0x05], ['OBJECT IDENTIFIER',"P",0x06], ['Object Descriptor',"P",0x07], ['EXTERNAL',"C",0x08], ['REAL (float)',"P",0x09], ['ENUMERATED',"P",0x0A], ['EMBEDDED PDV',"C",0x0B], ['UTF8String',"P/C",0x0C], ['RELATIVE-OID',"P",0x0D], ['SEQUENCE and SEQUENCE OF',"C",0x10], ['SET and SET OF',"C",0x11], ['NumericString',"P/C",0x12], ['PrintableString',"P/C",0x13], ['T61String',"P/C",0x14], ['VideotexString',"P/C",0x15], ['IA5String',"P/C",0x16], ['UTCTime',"P/C",0x17], ['GeneralizedTime',"P/C",0x18], ['GraphicString',"P/C",0x19], ['VisibleString',"P/C",0x1A], ['GeneralString',"P/C",0x1B], ['UniversalString',"P/C",0x1C], ['CHARACTER STRING',"P/C",0x1D], ['BMPString',"P/C",0x1E], ]
Class Method Summary collapse
-
._dump(tlvs, dictionary, indent = "") ⇒ Object
:nodoc:.
-
._parse(bytes) ⇒ Object
– Stop RDOC here.
-
._parse_dgi(bytes) ⇒ Object
:nodoc:.
-
._parse_tlv(bytes) ⇒ Object
:nodoc:.
- .b2s(bytestr) ⇒ Object
-
.parse(bytes, dictionary = {}) ⇒ Object
Attempt to parse a (series) or BER encoded datastructures.
-
.parse_dgi(bytes, dictionary = {}) ⇒ Object
Attempt to decode a DGI encoded datastructure.
-
.parse_dgi_hex(hex_str, dictionary = {}) ⇒ Object
Attempt to decode a DGI encoded datastructure.
-
.parse_hex(hex_str, dictionary = {}) ⇒ Object
Attempt to decode a (series) of BER encoded datastructures (see parse).
-
.printable?(bytes) ⇒ Boolean
heuristics to determine whether a string of bytes is worth printing.
- .s2b(string) ⇒ Object
Class Method Details
._dump(tlvs, dictionary, indent = "") ⇒ Object
:nodoc:
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/tlv/parser/parser.rb', line 114 def self._dump (tlvs, dictionary, indent = "") #:nodoc: dump = "" tlvs.each {|tlv| dump += "%s%-6s : %d" % [indent, "0x"+b2s(tlv.tag), tlv.length] if tlv.children dump += " ["+dictionary[tlv.tag]+"]" if (dictionary[tlv.tag]) dump += "\n" tlv.children.each {|child| dump += _dump([child], dictionary, indent+" ") } else if (tlv.value.length < 17) dump += " : " + b2s(tlv.value) dump += " (#{tlv.value})" if printable?(tlv.value) dump += " ["+dictionary[tlv.tag]+"]" if (dictionary[tlv.tag]) else dump += " ["+dictionary[tlv.tag]+"]" if (dictionary[tlv.tag]) dump +="\n" dump += Hexy.dump(tlv.value, :indent=>indent.length+2) end dump += "\n" end } #puts ">>>>" #puts dump #puts "<<<<" dump end |
._parse(bytes) ⇒ Object
– Stop RDOC here.
69 70 71 72 73 74 75 76 77 |
# File 'lib/tlv/parser/parser.rb', line 69 def self._parse bytes #:nodoc: tlvs = [] begin tlv, rest = _parse_tlv bytes tlvs << tlv bytes = rest end while rest && rest.length != 0 tlvs end |
._parse_dgi(bytes) ⇒ Object
:nodoc:
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/tlv/parser/parser.rb', line 79 def self._parse_dgi bytes #:nodoc: dgis = [] begin dgi = TLV_Object.new tag, rest = DGI.get_tag bytes dgi.tag = tag len, rest = DGI.get_length rest dgi.length = len if tag == "\x80\x00" || tag == "\x90\x00" # no children dgi.value = rest[0,len] else dgi.children = _parse rest[0,len] end dgis << dgi bytes = rest[len, rest.length] end while bytes && bytes.length != 0 dgis end |
._parse_tlv(bytes) ⇒ Object
:nodoc:
100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/tlv/parser/parser.rb', line 100 def self._parse_tlv bytes #:nodoc: tlv = TLV_Object.new tag, rest = TLV.get_tag bytes tlv.tag = tag len, rest = TLV.get_length rest tlv.length = len if (tag[0] & 0x20) != 0x00 # constructed object tlv.children = _parse rest[0,len] else tlv.value = rest[0,len] end [tlv, rest[len, rest.length]] end |
.b2s(bytestr) ⇒ Object
4 5 6 7 8 |
# File 'lib/tlv/tlv.rb', line 4 def self.b2s bytestr return "" unless bytestr r = bytestr.unpack("H*")[0] r.length > 1 ? r : " " end |
.parse(bytes, dictionary = {}) ⇒ Object
Attempt to parse a (series) or BER encoded datastructures. May be be passed a
"\x00"=> "Tag Name"
encoded dictionary to provide names for tags. Some dictionaries are predefined in TLV::DICTIONARIES
Parameters: bytes
: a string of raw bytes to decode dictionary
: a tag=>name dictionary for tagname lookup
Returns: a string respresenation of the datastructure
22 23 24 |
# File 'lib/tlv/parser/parser.rb', line 22 def self.parse bytes, dictionary={} _dump(_parse(bytes), dictionary) end |
.parse_dgi(bytes, dictionary = {}) ⇒ Object
Attempt to decode a DGI encoded datastructure. This is used in EMV (CPS). see parse
42 43 44 |
# File 'lib/tlv/parser/parser.rb', line 42 def self.parse_dgi bytes, dictionary={} _dump(_parse_dgi(bytes), dictionary) end |
.parse_dgi_hex(hex_str, dictionary = {}) ⇒ Object
Attempt to decode a DGI encoded datastructure. This is used in EMV (CPS). see parse_hex
51 52 53 |
# File 'lib/tlv/parser/parser.rb', line 51 def self.parse_dgi_hex hex_str, dictionary={} self.parse_dgi s2b(hex_str), dictionary end |
.parse_hex(hex_str, dictionary = {}) ⇒ Object
Attempt to decode a (series) of BER encoded datastructures (see parse)
The data passed to this method is expected to be hex formated instead of in binary form.
33 34 35 |
# File 'lib/tlv/parser/parser.rb', line 33 def self.parse_hex hex_str, dictionary={} self.parse s2b(hex_str), dictionary end |
.printable?(bytes) ⇒ Boolean
heuristics to determine whether a string of bytes is worth printing. If more than 90% of bytes are printable, will return true.
57 58 59 60 61 62 63 64 65 |
# File 'lib/tlv/parser/parser.rb', line 57 def self.printable? bytes count = 0 count_printable = 0 bytes.each_byte {|b| count += 1 count_printable += 1 if ((0x20..0x7e).include?(b) || (0xA0..0xff).include?(b)) } return (count_printable.to_f/count) > 0.90 end |
.s2b(string) ⇒ Object
9 10 11 12 13 14 |
# File 'lib/tlv/tlv.rb', line 9 def self.s2b string return "" unless string string = string.gsub(/\s+/, "") string = "0" + string unless (string.length % 2 == 0) [string].pack("H*") end |