Class: Krypt::ASN1::Constructive
- Includes:
- Enumerable
- Defined in:
- ext/krypt/core/krypt_asn1.c,
ext/krypt/core/krypt_asn1.c
Overview
The parent class for all constructed encodings. The value
attribute of a parsed Constructive is always an Array
. Attributes are the same as for ASN1Data.
SET and SEQUENCE
Most constructed encodings come in the form of a SET or a SEQUENCE. These encodings are represented by one of the two sub-classes of Constructive:
-
Krypt::ASN1::Set
-
Krypt::ASN1::Sequence
Please note that tagged sequences and sets are still parsed as instances of ASN1Data. Find further details on tagged values there.
Example - constructing a SEQUENCE
int = Krypt::ASN1::Integer.new(1)
str = Krypt::ASN1::PrintableString.new('abc')
sequence = Krypt::ASN1::Sequence.new( [ int, str ] )
Example - constructing a SET
int = Krypt::ASN1::Integer.new(1)
str = Krypt::ASN1::PrintableString.new('abc')
set = Krypt::ASN1::Set.new( [ int, str ] )
Infinite length primitive values
The only case where Constructive is used directly is for infinite length encodings of primitive values. These encodings are always constructed, with the contents of the value
Array
being either UNIVERSAL non-infinite length partial encodings of the actual value or again constructive encodings with infinite length (i.e. infinite length primitive encodings may be constructed recursively with another infinite length value within an already infinite length value). Each partial encoding must be of the same UNIVERSAL type as the overall encoding. The value of the overall encoding consists of the concatenation of each partial encoding taken in sequence. The value
array of the outer infinite length value must end with a Krypt::ASN1::EndOfContents instance.
Example - Infinite length OCTET STRING
partial1 = Krypt::ASN1::OctetString.new("\x01")
partial2 = Krypt::ASN1::OctetString.new("\x02")
inf_octets = Krypt::ASN1::OctetString.new( [ partial1,
partial2,
Krypt::ASN1::EndOfContent.new ])
# The real value of inf_octets is "\x01\x02", i.e. the concatenation
# of partial1 and partial2
inf_octets.infinite_length = true
der = inf_octets.to_der
asn1 = Krypt::ASN1.decode(der)
puts asn1.infinite_length # => true
Instance Method Summary collapse
-
#each {|asn1| ... } ⇒ Object
Calls block once for each element in
self
, passing that element as parameterasn1
. -
#new(value, tag, tag_class) ⇒ ASN1Data
constructor
-
value
: the value to be associated.
-
Methods inherited from ASN1Data
#<=>, #encode_to, #infinite_length, #infinite_length=, #tag, #tag=, #tag_class, #tag_class=, #to_der, #value, #value=
Constructor Details
#new(value, tag, tag_class) ⇒ ASN1Data
-
value
: the value to be associated. See Primitive for the mappings
between ASN.1 types and Ruby types.
-
tag
: aNumber
representing this value’s tag. -
tag_class
: aSymbol
representing one of the four valid tag classes
:UNIVERSAL
, :CONTEXT_SPECIFIC
, :APPLICATION
or :PRIVATE
.
Creates an ASN1Data from scratch.
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 |
# File 'ext/krypt/core/krypt_asn1.c', line 359
static VALUE
krypt_asn1_data_initialize(VALUE self, VALUE value, VALUE vtag, VALUE vtag_class)
{
ID stag_class;
int tag, tag_class, is_constructed;
krypt_asn1_data *data;
int_validate_tag_and_class(vtag, vtag_class);
tag = NUM2INT(vtag);
stag_class = SYM2ID(vtag_class);
if (stag_class == sKrypt_TC_EXPLICIT)
rb_raise(eKryptASN1Error, "Explicit tagging is only supported for explicit UNIVERSAL sub classes of ASN1Data");
if (stag_class == sKrypt_TC_UNIVERSAL && tag > 30)
rb_raise(eKryptASN1Error, "Tag too large for UNIVERSAL tag class");
if ((tag_class = krypt_asn1_tag_class_for_id(stag_class)) == KRYPT_ERR)
rb_raise(eKryptASN1Error, "Unknown tag class");
is_constructed = rb_respond_to(value, sKrypt_ID_EACH);
int_asn1_data_initialize(self, tag, tag_class, is_constructed, 0);
int_asn1_data_get(self, data);
data->update_cb = int_asn1_data_update_cb;
int_asn1_data_set_tag(self, vtag);
int_asn1_data_set_tag_class(self, vtag_class);
int_asn1_data_set_infinite_length(self, Qfalse);
int_asn1_data_set_value(self, value);
int_asn1_data_set_modified(data, 1); /* newly created is modified by default */
return self;
}
|
Instance Method Details
#each {|asn1| ... } ⇒ Object
Calls block once for each element in self
, passing that element as parameter asn1
. If no block is given, an enumerator is returned instead.
Example
asn1_ary.each do |asn1|
pp asn1
end
1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 |
# File 'ext/krypt/core/krypt_asn1.c', line 1136
static VALUE
krypt_asn1_cons_each(VALUE self)
{
VALUE enumerable = krypt_asn1_data_get_value(self);
KRYPT_RETURN_ENUMERATOR(enumerable, sKrypt_ID_EACH);
if (rb_obj_is_kind_of(enumerable, rb_cArray))
return rb_ary_each(krypt_asn1_data_get_value(self));
else
return rb_iterate(rb_each, enumerable, int_cons_each_i, Qnil);
}
|