Class: RASN1::Wrapper

Inherits:
SimpleDelegator
  • Object
show all
Defined in:
lib/rasn1/wrapper.rb

Overview

This class is used to wrap a Types::Base or Model instance to force its options.

Usage

This class may be used to wrap another RASN1 object by 4 ways:

  • wrap an object to modify its options,

  • implicitly wrap an object (i.e. change its tag),

  • explicitly wrap an object (i.e wrap the object in another explicit ASN.1 tag),

  • wrap a choice model to reuse it in its own definition.

Examples:

Wrapping object

# object to wrap
int = RASN1::Types::Integer.new(implicit: 1)    # its tag is 0x81
# simple wrapper, change an option
wrapper = RASN1::Wrapper.new(int, default: 1)
# implicit wrapper
wrapper = RASN1::Wrapper.new(int, implicit: 3)  # wrapped int tag is now 0x83
# explicit wrapper
wrapper = RASN1::Wrapper.new(int, explicit: 4)  # int tag is always 0x81, but it is wrapped in a 0x84 tag

Wrapping a choice to make it recursive

class RecursiveChoice < RASN1::Model
  choice :choice,
         content: [
           integer(:value, implicit: 1),
           wrapper(model(:recursive, RecursiveChoice), implicit:2)
         ]
end

Author:

  • Sylvain Daubert

  • LemonTree55

Since:

  • 0.12.0

  • 0.15.0 Wrappers are lazy. They allocate their inner element only when needed (i.e. when calling #to_der, #parse! or #element)

Defined Under Namespace

Classes: ExplicitWrapper

Instance Method Summary collapse

Constructor Details

#initialize(element, options = {}) ⇒ Wrapper

Returns a new instance of Wrapper.

Parameters:

  • element (Types::Base, Model)

    element to wrap

  • options (Hash) (defaults to: {})

Raises:

Since:

  • 0.12.0

  • 0.15.0 Wrappers are lazy. They allocate their inner element only when needed (i.e. when calling #to_der, #parse! or #element)



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/rasn1/wrapper.rb', line 68

def initialize(element, options={})
  @lazy = true
  opts = explicit_implicit(options)

  if explicit?
    generate_explicit_wrapper(opts)
    @element_options_to_merge = generate_explicit_wrapper_options(opts)
    @options = opts
  else
    opts[:value] = element.value if element.respond_to?(:value)
    @element_options_to_merge = opts
    @options = {}
  end
  raise RASN1::Error, 'Cannot be implicit and explicit' if explicit? && implicit?

  super(element)
end

Instance Method Details

#asn1_classSymbol

Returns:

  • (Symbol)

See Also:

Since:

  • 0.12.0

  • 0.15.0 Wrappers are lazy. They allocate their inner element only when needed (i.e. when calling #to_der, #parse! or #element)



184
185
186
187
188
# File 'lib/rasn1/wrapper.rb', line 184

def asn1_class
  return lazy_generation(register: false).asn1_class unless @options.key?(:class)

  @options[:class]
end

#constructed?Boolean

Returns:

  • (Boolean)

See Also:

  • Types::Base#constructed

Since:

  • 0.12.0

  • 0.15.0 Wrappers are lazy. They allocate their inner element only when needed (i.e. when calling #to_der, #parse! or #element)



192
193
194
195
196
# File 'lib/rasn1/wrapper.rb', line 192

def constructed?
  return lazy_generation(register: false).constructed? unless @options.key?(:constructed)

  @options[:constructed]
end

#do_parse(der, ber: false) ⇒ Object

See Also:

Since:

  • 0.12.0

  • 0.15.0 Wrappers are lazy. They allocate their inner element only when needed (i.e. when calling #to_der, #parse! or #element)



140
141
142
143
144
145
146
147
148
# File 'lib/rasn1/wrapper.rb', line 140

def do_parse(der, ber: false)
  if implicit?
    generate_implicit_element(Types::Base.new(constructed: element.constructed?)).do_parse(der, ber: ber)
  elsif explicit?
    @explicit_wrapper.do_parse(der, ber: ber)
  else
    element.do_parse(der, ber: ber)
  end
end

#elementTypes::Base, Model

Return Wrapped element

Returns:

Since:

  • 0.12.0

  • 0.15.0 Allocate element (lazy wrapper)



166
167
168
# File 'lib/rasn1/wrapper.rb', line 166

def element
  lazy_generation
end

#explicit?Boolean

Say if wrapper is an explicit one (i.e. add tag and length to its element)

Returns:

  • (Boolean)

Since:

  • 0.12.0

  • 0.15.0 Wrappers are lazy. They allocate their inner element only when needed (i.e. when calling #to_der, #parse! or #element)



88
89
90
# File 'lib/rasn1/wrapper.rb', line 88

def explicit?
  !!@explicit
end

#id::Integer

Returns:

  • (::Integer)

See Also:

Since:

  • 0.12.0

  • 0.15.0 Wrappers are lazy. They allocate their inner element only when needed (i.e. when calling #to_der, #parse! or #element)



172
173
174
175
176
177
178
179
180
# File 'lib/rasn1/wrapper.rb', line 172

def id
  if implicit?
    @implicit
  elsif explicit?
    @explicit
  else
    lazy_generation(register: false).id
  end
end

#implicit?Boolean

Say if wrapper is an implicit one (i.e. change tag of its element)

Returns:

  • (Boolean)

Since:

  • 0.12.0

  • 0.15.0 Wrappers are lazy. They allocate their inner element only when needed (i.e. when calling #to_der, #parse! or #element)



94
95
96
# File 'lib/rasn1/wrapper.rb', line 94

def implicit?
  !!@implicit
end

#inspect(level = 0) ⇒ String

Parameters:

  • level (::Integer) (defaults to: 0)

Returns:

  • (String)

Since:

  • 0.12.0

  • 0.15.0 Wrappers are lazy. They allocate their inner element only when needed (i.e. when calling #to_der, #parse! or #element)



206
207
208
209
210
# File 'lib/rasn1/wrapper.rb', line 206

def inspect(level=0)
  return super() unless explicit?

  @explicit_wrapper.inspect(level) << ' ' << super()
end

#parse!(der, ber: false) ⇒ Integer

Parse a DER string. This method updates object.

Parameters:

  • der (String)

    DER string

  • ber (Boolean) (defaults to: false)

    if true, accept BER encoding

Returns:

  • (Integer)

    total number of parsed bytes

Raises:

Since:

  • 0.12.0

  • 0.15.0 Allocate element (lazy wrapper)



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/rasn1/wrapper.rb', line 122

def parse!(der, ber: false)
  lazy_generation
  if implicit?
    el = generate_implicit_element
    parsed = el.parse!(der, ber: ber)
    element.value = el.value
    parsed
  elsif explicit?
    parsed = @explicit_wrapper.parse!(der, ber: ber)
    element.parse!(@explicit_wrapper.value, ber: ber) if parsed.positive?
    parsed
  else
    element.parse!(der, ber: ber)
  end
end

#primitive?Boolean

Returns:

  • (Boolean)

See Also:

  • Types::Base#primitive

Since:

  • 0.12.0

  • 0.15.0 Wrappers are lazy. They allocate their inner element only when needed (i.e. when calling #to_der, #parse! or #element)



200
201
202
# File 'lib/rasn1/wrapper.rb', line 200

def primitive?
  !constructed?
end

#to_derString

Convert wrapper and its element to a DER string

Returns:

  • (String)

Since:

  • 0.12.0

  • 0.15.0 Allocate element (lazy wrapper)



102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/rasn1/wrapper.rb', line 102

def to_der
  lazy_generation
  if implicit?
    el = generate_implicit_element
    el.to_der
  elsif explicit?
    @explicit_wrapper.value = element
    @explicit_wrapper.to_der
  else
    element.to_der
  end
end

#value?Boolean

Returns:

  • (Boolean)

See Also:

Since:

  • 0.12.0

  • 0.15.0 Wrappers are lazy. They allocate their inner element only when needed (i.e. when calling #to_der, #parse! or #element)



152
153
154
155
156
157
158
159
160
# File 'lib/rasn1/wrapper.rb', line 152

def value?
  if explicit?
    @explicit_wrapper.value?
  elsif __getobj__.is_a?(Class)
    false
  else
    __getobj__.value?
  end
end