Class: RASN1::Model Abstract
Overview
Model class is a base class to define ASN.1 models.
Create a simple ASN.1 model
Given this ASN.1 example:
Record ::= SEQUENCE {
id INTEGER,
room [0] IMPLICIT INTEGER OPTIONAL,
house [1] EXPLICIT INTEGER DEFAULT 0
}
you may create your model like this:
class Record < RASN1::Model
sequence(:record,
content: [integer(:id),
integer(:room, implicit: 0, optional: true),
integer(:house, explicit: 1, default: 0)])
end
In a model, each element must have a unique name.
Parse a DER-encoded string
record = Record.parse(der_string)
record[:id] # => RASN1::Types::Integer
record[:id].value # => Integer
record[:id].to_i # => Integer
record[:id].asn1_class # => Symbol
record[:id].optional? # => false
record[:id].default # => nil
record[:room].optional # => true
record[:house].default # => 0
You may also parse a BER-encoded string this way:
record = Record.parse(der_string, ber: true)
Generate a DER-encoded string
record = Record.new(id: 12, room: 24)
record.to_der
Create a more complex model
Models may be nested. For example:
class Record2 < RASN1::Model
sequence(:record2,
content: [boolean(:rented, default: false),
model(:a_record, Record)])
end
Set values like this:
record2 = Record2.new
record2[:rented] = true
record2[:a_record][:id] = 65537
record2[:a_record][:room] = 43
or like this:
record2 = Record2.new(rented: true, a_record: { id: 65537, room: 43 })
Delegation
Model may delegate some methods to its root element. Thus, if root element is, for example, a Types::Choice, model may delegate #chosen
and #chosen_value
.
All methods defined by root may be delegated by model, unless model also defines this method.
Defined Under Namespace
Modules: Accel Classes: Elem, WrapElem
Instance Attribute Summary
Attributes included from Accel
Class Method Summary collapse
- .bit_string(name, options) ⇒ Elem
- .bmp_string(name, options) ⇒ Elem
- .boolean(name, options) ⇒ Elem
- .choice(name, options) ⇒ Elem
- .enumerated(name, options) ⇒ Elem
- .ia5_string(name, options) ⇒ Elem
- .integer(name, options) ⇒ Elem
- .null(name, options) ⇒ Elem
- .numeric_string(name, options) ⇒ Elem
- .octet_string(name, options) ⇒ Elem
- .printable_string(name, options) ⇒ Elem
- .sequence(name, options) ⇒ Elem
- .sequence_of(name, type, options) ⇒ Elem
- .set(name, options) ⇒ Elem
- .set_of(name, type, options) ⇒ Elem
- .universal_string(name, options) ⇒ Elem
- .utf8_string(name, options) ⇒ Elem
- .visible_string(name, options) ⇒ Elem
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
Objects are equal if they have same class AND same DER.
-
#[](name) ⇒ Types::Base
Give access to element
name
in model. -
#[]=(name, value) ⇒ Object
Set value of element
name
. -
#initialize(args = {}) ⇒ Model
constructor
Create a new instance of a Model.
- #inspect(level = 0) ⇒ String
-
#keys ⇒ Array<Symbol,String>
Get elements names.
-
#method_missing(meth, *args) ⇒ Object
Delegate some methods to root element.
-
#name ⇒ String, Symbol
Get name from root type.
-
#parse!(str, ber: false) ⇒ Integer
Parse a DER/BER encoded string, and modify object in-place.
- #respond_to_missing?(meth) ⇒ Boolean
-
#root ⇒ Types::Base, Model
Get root element from model.
- #to_der ⇒ String
-
#to_h ⇒ Hash
Return a hash image of model.
-
#type ⇒ String
Give type name (aka class name).
- #value(name = nil, *args) ⇒ Object?
Methods included from Accel
any, define_type_accel, define_type_accel_base, define_type_accel_of, inherited, model, objectid, parse, root_options, wrapper
Constructor Details
#initialize(args = {}) ⇒ Model
Create a new instance of a RASN1::Model
371 372 373 374 375 |
# File 'lib/rasn1/model.rb', line 371 def initialize(args={}) root = generate_root generate_elements(root) initialize_elements(self, args) end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
Class Method Details
.bit_string(name, options) ⇒ Elem
362 363 364 365 366 367 |
# File 'lib/rasn1/model.rb', line 362 Types.primitives.each do |prim| next if prim == Types::ObjectId method_name = prim.type.gsub(/([a-z0-9])([A-Z])/, '\1_\2').downcase.gsub(/\s+/, '_') self.define_type_accel_base(method_name, prim) end |
.bmp_string(name, options) ⇒ Elem
362 363 364 365 366 367 |
# File 'lib/rasn1/model.rb', line 362 Types.primitives.each do |prim| next if prim == Types::ObjectId method_name = prim.type.gsub(/([a-z0-9])([A-Z])/, '\1_\2').downcase.gsub(/\s+/, '_') self.define_type_accel_base(method_name, prim) end |
.boolean(name, options) ⇒ Elem
362 363 364 365 366 367 |
# File 'lib/rasn1/model.rb', line 362 Types.primitives.each do |prim| next if prim == Types::ObjectId method_name = prim.type.gsub(/([a-z0-9])([A-Z])/, '\1_\2').downcase.gsub(/\s+/, '_') self.define_type_accel_base(method_name, prim) end |
.choice(name, options) ⇒ Elem
262 263 264 |
# File 'lib/rasn1/model.rb', line 262 %w[sequence set choice].each do |type| self.define_type_accel_base(type, Types.const_get(type.capitalize)) end |
.enumerated(name, options) ⇒ Elem
362 363 364 365 366 367 |
# File 'lib/rasn1/model.rb', line 362 Types.primitives.each do |prim| next if prim == Types::ObjectId method_name = prim.type.gsub(/([a-z0-9])([A-Z])/, '\1_\2').downcase.gsub(/\s+/, '_') self.define_type_accel_base(method_name, prim) end |
.ia5_string(name, options) ⇒ Elem
362 363 364 365 366 367 |
# File 'lib/rasn1/model.rb', line 362 Types.primitives.each do |prim| next if prim == Types::ObjectId method_name = prim.type.gsub(/([a-z0-9])([A-Z])/, '\1_\2').downcase.gsub(/\s+/, '_') self.define_type_accel_base(method_name, prim) end |
.integer(name, options) ⇒ Elem
362 363 364 365 366 367 |
# File 'lib/rasn1/model.rb', line 362 Types.primitives.each do |prim| next if prim == Types::ObjectId method_name = prim.type.gsub(/([a-z0-9])([A-Z])/, '\1_\2').downcase.gsub(/\s+/, '_') self.define_type_accel_base(method_name, prim) end |
.null(name, options) ⇒ Elem
362 363 364 365 366 367 |
# File 'lib/rasn1/model.rb', line 362 Types.primitives.each do |prim| next if prim == Types::ObjectId method_name = prim.type.gsub(/([a-z0-9])([A-Z])/, '\1_\2').downcase.gsub(/\s+/, '_') self.define_type_accel_base(method_name, prim) end |
.numeric_string(name, options) ⇒ Elem
362 363 364 365 366 367 |
# File 'lib/rasn1/model.rb', line 362 Types.primitives.each do |prim| next if prim == Types::ObjectId method_name = prim.type.gsub(/([a-z0-9])([A-Z])/, '\1_\2').downcase.gsub(/\s+/, '_') self.define_type_accel_base(method_name, prim) end |
.octet_string(name, options) ⇒ Elem
362 363 364 365 366 367 |
# File 'lib/rasn1/model.rb', line 362 Types.primitives.each do |prim| next if prim == Types::ObjectId method_name = prim.type.gsub(/([a-z0-9])([A-Z])/, '\1_\2').downcase.gsub(/\s+/, '_') self.define_type_accel_base(method_name, prim) end |
.printable_string(name, options) ⇒ Elem
362 363 364 365 366 367 |
# File 'lib/rasn1/model.rb', line 362 Types.primitives.each do |prim| next if prim == Types::ObjectId method_name = prim.type.gsub(/([a-z0-9])([A-Z])/, '\1_\2').downcase.gsub(/\s+/, '_') self.define_type_accel_base(method_name, prim) end |
.sequence(name, options) ⇒ Elem
262 263 264 |
# File 'lib/rasn1/model.rb', line 262 %w[sequence set choice].each do |type| self.define_type_accel_base(type, Types.const_get(type.capitalize)) end |
.sequence_of(name, type, options) ⇒ Elem
280 281 282 |
# File 'lib/rasn1/model.rb', line 280 %w[sequence set].each do |type| define_type_accel_of(type, Types.const_get(:"#{type.capitalize}Of")) end |
.set(name, options) ⇒ Elem
262 263 264 |
# File 'lib/rasn1/model.rb', line 262 %w[sequence set choice].each do |type| self.define_type_accel_base(type, Types.const_get(type.capitalize)) end |
.set_of(name, type, options) ⇒ Elem
280 281 282 |
# File 'lib/rasn1/model.rb', line 280 %w[sequence set].each do |type| define_type_accel_of(type, Types.const_get(:"#{type.capitalize}Of")) end |
.universal_string(name, options) ⇒ Elem
362 363 364 365 366 367 |
# File 'lib/rasn1/model.rb', line 362 Types.primitives.each do |prim| next if prim == Types::ObjectId method_name = prim.type.gsub(/([a-z0-9])([A-Z])/, '\1_\2').downcase.gsub(/\s+/, '_') self.define_type_accel_base(method_name, prim) end |
.utf8_string(name, options) ⇒ Elem
362 363 364 365 366 367 |
# File 'lib/rasn1/model.rb', line 362 Types.primitives.each do |prim| next if prim == Types::ObjectId method_name = prim.type.gsub(/([a-z0-9])([A-Z])/, '\1_\2').downcase.gsub(/\s+/, '_') self.define_type_accel_base(method_name, prim) end |
.visible_string(name, options) ⇒ Elem
362 363 364 365 366 367 |
# File 'lib/rasn1/model.rb', line 362 Types.primitives.each do |prim| next if prim == Types::ObjectId method_name = prim.type.gsub(/([a-z0-9])([A-Z])/, '\1_\2').downcase.gsub(/\s+/, '_') self.define_type_accel_base(method_name, prim) end |
Instance Method Details
#==(other) ⇒ Boolean
Objects are equal if they have same class AND same DER
500 501 502 |
# File 'lib/rasn1/model.rb', line 500 def ==(other) (other.class == self.class) && (other.to_der == self.to_der) end |
#[](name) ⇒ Types::Base
Give access to element name
in model
380 381 382 |
# File 'lib/rasn1/model.rb', line 380 def [](name) @elements[name] end |
#[]=(name, value) ⇒ Object
Set value of element name
. Element should be a Types::Base.
388 389 390 391 392 |
# File 'lib/rasn1/model.rb', line 388 def []=(name, value) raise Error, 'cannot set value for a Model' if @elements[name].is_a? Model @elements[name].value = value end |
#inspect(level = 0) ⇒ String
493 494 495 |
# File 'lib/rasn1/model.rb', line 493 def inspect(level=0) ' ' * level + "(#{type}) #{root.inspect(-level)}" end |
#keys ⇒ Array<Symbol,String>
Get elements names
402 403 404 |
# File 'lib/rasn1/model.rb', line 402 def keys @elements.keys end |
#name ⇒ String, Symbol
Get name from root type
396 397 398 |
# File 'lib/rasn1/model.rb', line 396 def name @root_name end |
#parse!(str, ber: false) ⇒ Integer
Parse a DER/BER encoded string, and modify object in-place.
434 435 436 |
# File 'lib/rasn1/model.rb', line 434 def parse!(str, ber: false) root.parse!(str.dup.force_encoding('BINARY'), ber: ber) end |
#respond_to_missing?(meth) ⇒ Boolean
488 489 490 |
# File 'lib/rasn1/model.rb', line 488 def respond_to_missing?(meth, *) root.respond_to?(meth) || super end |
#root ⇒ Types::Base, Model
Get root element from model
414 415 416 |
# File 'lib/rasn1/model.rb', line 414 def root @elements[@root_name] end |
#to_h ⇒ Hash
Return a hash image of model
408 409 410 |
# File 'lib/rasn1/model.rb', line 408 def to_h private_to_h end |
#type ⇒ String
Give type name (aka class name)
425 426 427 |
# File 'lib/rasn1/model.rb', line 425 def type self.class.type end |
#value ⇒ Object? #value(name, *args) ⇒ Object?
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 |
# File 'lib/rasn1/model.rb', line 459 def value(name=nil, *args) if name.nil? root.value else elt = by_name(name) return nil if elt.nil? unless args.empty? args.each do |arg| elt = elt.root if elt.is_a?(Model) elt = elt[arg] end end elt.value end end |