Class: RASN1::Types::Base Abstract
- Inherits:
-
Object
- Object
- RASN1::Types::Base
- Defined in:
- lib/rasn1/types/base.rb
Overview
Define an optional value
An optional value may be defined using :optional key from #initialize:
Integer.new(:int, optional: true)
An optional value implies:
-
while parsing, if decoded tag is not optional expected tag, no ASN1Error is raised, and parser tries net tag,
-
while encoding, if #value is
nil, this value is not encoded.
Define a default value
A default value may be defined using :default key from #initialize:
Integer.new(:int, default: 0)
A default value implies:
-
while parsing, if decoded tag is not expected tag, no ASN1Error is raised and parser sets default value to this tag. Then parser tries nex tag,
-
while encoding, if #value is equal to default value, this value is not encoded.
Define a tagged value
ASN.1 permits to define tagged values. By example:
-- context specific tag
CType ::= [0] EXPLICIT INTEGER
-- application specific tag
AType ::= [APPLICATION 1] EXPLICIT INTEGER
-- private tag
PType ::= [PRIVATE 2] EXPLICIT INTEGER
These types may be defined as:
ctype = RASN1::Types::Integer.new(explicit: 0) # with explicit, default #asn1_class is :context
atype = RASN1::Types::Integer.new(explicit: 1, class: :application)
ptype = RASN1::Types::Integer.new(explicit: 2, class: :private)
Sometimes, an EXPLICIT type should be CONSTRUCTED. To do that, use :constructed option:
ptype = RASN1::Types::Integer.new(explicit: 2, class: :private, constructed: true)
Implicit tagged values may also be defined:
ctype_implicit = RASN1::Types::Integer.new(implicit: 0)
Direct Known Subclasses
Constant Summary collapse
- CLASSES =
Allowed ASN.1 tag classes
{ universal: 0x00, application: 0x40, context: 0x80, private: 0xc0 }.freeze
- UNDUPPABLE_TYPES =
[[NilClass, nil], [TrueClass, true], [FalseClass, false], [Integer, 0]].map do |klass, obj| begin obj.dup nil rescue => TypeError klass end end.compact.freeze
- CLASS_MASK =
Binary mask to get class
0xc0- MAX_TAG =
Maximum ASN.1 tag number
0x1e- INDEFINITE_LENGTH =
Length value for indefinite length
0x80
Instance Attribute Summary collapse
- #asn1_class ⇒ Symbol readonly
-
#default ⇒ Object?
readonly
Default value, if defined.
- #name ⇒ String? readonly
-
#value ⇒ Object
Get value or default value.
Class Method Summary collapse
-
.encode_type ⇒ String
Get ASN.1 type used to encode this one.
-
.parse(der_or_ber, options = {}) ⇒ Object
Parse a DER or BER string.
-
.type ⇒ String
Get ASN.1 type.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
Objects are equal if they have same class AND same DER.
-
#constructed? ⇒ ::Boolean
trueif this is a constructed type. -
#explicit? ⇒ ::Boolean?
Say if a tagged type is explicit.
-
#implicit? ⇒ ::Boolean?
Say if a tagged type is implicit.
-
#initialize(value_or_options = {}, options = {}) ⇒ Base
constructor
A new instance of Base.
-
#initialize_copy(_other) ⇒ Object
Used by
#dupand#clone. - #inspect(level = 0) ⇒ String
- #optional? ⇒ ::Boolean
-
#parse!(der, ber: false) ⇒ Integer
abstract
Parse a DER string.
-
#primitive? ⇒ ::Boolean
trueif this is a primitive type. -
#tag ⇒ Integer
Get tag value.
-
#tagged? ⇒ ::Boolean
Say if this type is tagged or not.
-
#to_der ⇒ String
abstract
DER-formated string.
-
#type ⇒ String
Get ASN.1 type.
-
#value_size ⇒ Integer
Give size in octets of encoded value.
Constructor Details
Instance Attribute Details
#asn1_class ⇒ Symbol (readonly)
79 80 81 |
# File 'lib/rasn1/types/base.rb', line 79 def asn1_class @asn1_class end |
#default ⇒ Object? (readonly)
Returns default value, if defined.
81 82 83 |
# File 'lib/rasn1/types/base.rb', line 81 def default @default end |
#name ⇒ String? (readonly)
77 78 79 |
# File 'lib/rasn1/types/base.rb', line 77 def name @name end |
#value ⇒ Object
Get value or default value
153 154 155 156 157 158 159 |
# File 'lib/rasn1/types/base.rb', line 153 def value if @value.nil? @default else @value end end |
Class Method Details
.encode_type ⇒ String
Get ASN.1 type used to encode this one
95 96 97 |
# File 'lib/rasn1/types/base.rb', line 95 def self.encode_type type end |
.parse(der_or_ber, options = {}) ⇒ Object
More options are supported. See #initialize.
Parse a DER or BER string
104 105 106 107 108 |
# File 'lib/rasn1/types/base.rb', line 104 def self.parse(der_or_ber, ={}) obj = self.new() obj.parse!(der_or_ber, ber: [:ber]) obj end |
.type ⇒ String
Get ASN.1 type
87 88 89 90 91 |
# File 'lib/rasn1/types/base.rb', line 87 def self.type return @type if defined? @type @type = self.to_s.gsub(/.*::/, '').gsub(/([a-z0-9])([A-Z])/, '\1 \2').upcase end |
Instance Method Details
#==(other) ⇒ Boolean
Objects are equal if they have same class AND same DER
265 266 267 |
# File 'lib/rasn1/types/base.rb', line 265 def ==(other) (other.class == self.class) && (other.to_der == self.to_der) end |
#constructed? ⇒ ::Boolean
Returns true if this is a constructed type.
199 200 201 |
# File 'lib/rasn1/types/base.rb', line 199 def constructed? (self.class < Constructed) || !!@constructed end |
#explicit? ⇒ ::Boolean?
Say if a tagged type is explicit
175 176 177 |
# File 'lib/rasn1/types/base.rb', line 175 def explicit? !defined?(@tag) ? nil : @tag == :explicit end |
#implicit? ⇒ ::Boolean?
Say if a tagged type is implicit
182 183 184 |
# File 'lib/rasn1/types/base.rb', line 182 def implicit? !defined?(@tag) ? nil : @tag == :implicit end |
#initialize_copy(_other) ⇒ Object
Used by #dup and #clone. Deep copy @value and @default.
147 148 149 150 |
# File 'lib/rasn1/types/base.rb', line 147 def initialize_copy(_other) @value = @value.dup unless UNDUPPABLE_TYPES.include?(@value.class) @default = @default.dup unless UNDUPPABLE_TYPES.include?(@default.class) end |
#inspect(level = 0) ⇒ String
254 255 256 257 258 259 260 |
# File 'lib/rasn1/types/base.rb', line 254 def inspect(level=0) str = common_inspect(level) str << " #{value.inspect}" str << ' OPTIONAL' if optional? str << " DEFAULT #{@default}" unless @default.nil? str end |
#optional? ⇒ ::Boolean
162 163 164 |
# File 'lib/rasn1/types/base.rb', line 162 def optional? @optional end |
#parse!(der, ber: false) ⇒ Integer
This method SHOULD be partly implemented by subclasses to parse data. Subclasses SHOULD respond to #der_to_value.
Parse a DER string. This method updates object.
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/rasn1/types/base.rb', line 229 def parse!(der, ber: false) return 0 unless check_tag(der) total_length, data = get_data(der, ber) if explicit? # Delegate to #explicit type to generate sub-tag type = explicit_type type.value = @value type.parse!(data) @value = type.value else der_to_value(data, ber: ber) end total_length end |
#primitive? ⇒ ::Boolean
Returns true if this is a primitive type.
194 195 196 |
# File 'lib/rasn1/types/base.rb', line 194 def primitive? (self.class < Primitive) && !@constructed end |
#tag ⇒ Integer
Get tag value
211 212 213 214 215 216 217 218 219 220 |
# File 'lib/rasn1/types/base.rb', line 211 def tag pc = if @constructed.nil? self.class::ASN1_PC elsif @constructed # true Constructed::ASN1_PC else # false 0 end tag_value | CLASSES[@asn1_class] | pc end |
#tagged? ⇒ ::Boolean
Say if this type is tagged or not
168 169 170 |
# File 'lib/rasn1/types/base.rb', line 168 def tagged? !@tag.nil? end |
#to_der ⇒ String
This method SHOULD be partly implemented by subclasses, which SHOULD respond to #value_to_der.
Returns DER-formated string.
189 190 191 |
# File 'lib/rasn1/types/base.rb', line 189 def to_der build_tag end |
#type ⇒ String
Get ASN.1 type
205 206 207 |
# File 'lib/rasn1/types/base.rb', line 205 def type self.class.type end |
#value_size ⇒ Integer
Give size in octets of encoded value
248 249 250 |
# File 'lib/rasn1/types/base.rb', line 248 def value_size value_to_der.size end |