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:
blackhedd 2006-04-15 02:22:38 +00:00
parent 9b59d3fd93
commit 2f56d3e258

View file

@ -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.