Filled in a few blanks, and reworked the mechanism
for handling application-specific ASN.1 syntaxes. We now allow applications to define application tag numbers that are the same, as long as one is constructed and the other primitive.
This commit is contained in:
parent
9b59d3fd93
commit
2f56d3e258
|
@ -44,17 +44,25 @@ module Net
|
||||||
|
|
||||||
BuiltinSyntax = {
|
BuiltinSyntax = {
|
||||||
:universal => {
|
:universal => {
|
||||||
|
:primitive => {
|
||||||
1 => :boolean,
|
1 => :boolean,
|
||||||
2 => :integer,
|
2 => :integer,
|
||||||
4 => :string,
|
4 => :string,
|
||||||
10 => :integer,
|
10 => :integer,
|
||||||
|
},
|
||||||
|
:constructed => {
|
||||||
16 => :array,
|
16 => :array,
|
||||||
17 => :array,
|
17 => :array
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# read_ber
|
# read_ber
|
||||||
|
# TODO: clean this up so it works properly with partial
|
||||||
|
# packets coming from streams that don't block when
|
||||||
|
# we ask for more data (like StringIOs). At it is,
|
||||||
|
# this can throw TypeErrors and other nasties.
|
||||||
#
|
#
|
||||||
def read_ber syntax=nil
|
def read_ber syntax=nil
|
||||||
eof? and return nil
|
eof? and return nil
|
||||||
|
@ -63,7 +71,7 @@ module Net
|
||||||
tag = id & 31
|
tag = id & 31
|
||||||
tag < 31 or raise BerError.new( "unsupported tag encoding: #{id}" )
|
tag < 31 or raise BerError.new( "unsupported tag encoding: #{id}" )
|
||||||
tagclass = TagClasses[ id >> 6 ]
|
tagclass = TagClasses[ id >> 6 ]
|
||||||
constructed = (id & 0x20 != 0)
|
encoding = (id & 0x20 != 0) ? :constructed : :primitive
|
||||||
|
|
||||||
n = getc
|
n = getc
|
||||||
lengthlength,contentlength = if n <= 127
|
lengthlength,contentlength = if n <= 127
|
||||||
|
@ -75,24 +83,30 @@ module Net
|
||||||
|
|
||||||
newobj = read contentlength
|
newobj = read contentlength
|
||||||
|
|
||||||
objtype = (ot = BuiltinSyntax[tagclass]) && ot[tag]
|
objtype = nil
|
||||||
objtype = objtype || (syntax && (ot = syntax[tagclass]) && ot[tag])
|
[syntax, BuiltinSyntax].each {|syn|
|
||||||
|
if syn && (ot = syn[tagclass]) && (ot = ot[encoding]) && ot[tag]
|
||||||
|
objtype = ot[tag]
|
||||||
|
break
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
obj = case objtype
|
obj = case objtype
|
||||||
when :boolean
|
when :boolean
|
||||||
raise BerError.new( "boolean unimplemented- fix this now, dummy" )
|
newobj != "\000"
|
||||||
when :string
|
when :string
|
||||||
newobj.dup
|
(newobj || "").dup
|
||||||
when :integer
|
when :integer
|
||||||
j = 0
|
j = 0
|
||||||
newobj.each_byte {|b| j = (j << 8) + b}
|
newobj.each_byte {|b| j = (j << 8) + b}
|
||||||
j
|
j
|
||||||
when :array
|
when :array
|
||||||
seq = []
|
seq = []
|
||||||
sio = StringIO.new newobj
|
sio = StringIO.new( newobj || "" )
|
||||||
while e = sio.read_ber(syntax); seq << e; end
|
while e = sio.read_ber(syntax); seq << e; end
|
||||||
seq
|
seq
|
||||||
else
|
else
|
||||||
raise BerError.new( "unsupported object type: class=#{tagclass}, tag=#{tag}" )
|
raise BerError.new( "unsupported object type: class=#{tagclass}, encoding=#{encoding}, tag=#{tag}" )
|
||||||
end
|
end
|
||||||
|
|
||||||
# Add the identifier bits into the object if it's a String or an Array.
|
# Add the identifier bits into the object if it's a String or an Array.
|
||||||
|
|
Loading…
Reference in a new issue