класс OpenSSL::ASN1::ASN1Data
Основной класс, представляющий любой объект ASN.1. При разборе с помощью ASN1.decode, помеченные значения всегда представлены экземпляром ASN1Data.
Роль ASN1Data при разборе помеченных значений
При кодировании типа ASN.1 изначально понятно, какой тип (например, INTEGER, OCTET STRING и т. д.) имеет это значение, независимо от его метки. Однако, в отличие от кодирования типа ASN.1, при его разборе невозможно определить «реальный тип» помеченных значений. Вот почему помеченные значения обычно разбираются в экземпляры ASN1Data, но с различным результатом для неявной и явной маркировки.
Пример разбора неявно помеченного значения
Неявно помеченное значение типа INTEGER с меткой 1 будет разобрано как ASN1Data со следующими характеристиками:
-
метка равна 1
-
класс_метки равен
:CONTEXT_SPECIFIC -
значение равно
String, который содержит исходное кодирование INTEGER.
Это подразумевает, что для полного разбора неявно помеченных значений требуется дополнительный шаг декодирования.
Пример разбора явно помеченного значения
Явно помеченное значение типа INTEGER с меткой 1 будет разобрано как ASN1Data со следующими характеристиками:
-
метка равна 1
-
класс_метки равен
:CONTEXT_SPECIFIC -
значение равно
Arrayс одним элементом, экземпляромOpenSSL::ASN1::Integer, т. е. внутренний элемент — это примитивное значение без метки, а метка представлена во внешнемASN1Data
Пример — Декодирование неявно помеченного INTEGER
int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT) # implicit 0-tagged seq = OpenSSL::ASN1::Sequence.new( [int] ) der = seq.to_der asn1 = OpenSSL::ASN1.decode(der) # pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0 # @indefinite_length=false, # @tag=16, # @tag_class=:UNIVERSAL, # @tagging=nil, # @value= # [#<OpenSSL::ASN1::ASN1Data:0x87326f4 # @indefinite_length=false, # @tag=0, # @tag_class=:CONTEXT_SPECIFIC, # @value="\x01">]> raw_int = asn1.value[0] # manually rewrite tag and tag class to make it an UNIVERSAL value raw_int.tag = OpenSSL::ASN1::INTEGER raw_int.tag_class = :UNIVERSAL int2 = OpenSSL::ASN1.decode(raw_int) puts int2.value # => 1
Пример — Декодирование явно помеченного INTEGER
int = OpenSSL::ASN1::Integer.new(1, 0, :EXPLICIT) # explicit 0-tagged seq = OpenSSL::ASN1::Sequence.new( [int] ) der = seq.to_der asn1 = OpenSSL::ASN1.decode(der) # pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0 # @indefinite_length=false, # @tag=16, # @tag_class=:UNIVERSAL, # @tagging=nil, # @value= # [#<OpenSSL::ASN1::ASN1Data:0x87326f4 # @indefinite_length=false, # @tag=0, # @tag_class=:CONTEXT_SPECIFIC, # @value= # [#<OpenSSL::ASN1::Integer:0x85bf308 # @indefinite_length=false, # @tag=2, # @tag_class=:UNIVERSAL # @tagging=nil, # @value=1>]>]> int2 = asn1.value[0].value[0] puts int2.value # => 1
Атрибуты
Никогда nil. Булево значение, указывающее, использует ли кодирование неопределенную длину (в случае разбора) или должна ли использоваться неопределенная длина (в случае кодирования). В DER каждое значение использует определенную длину. Но в сценариях, где необходимо передавать большие объемы данных, может потребоваться поддержка потоковой передачи. Например, огромные OCTET STRING предпочтительнее передавать небольшими частями по одной. Это возможно в BER, установив байты длины кодирования в ноль, тем самым указав, что последующее значение будет передано частями. Кодирования с неопределенной длиной всегда являются составными. Конец такого потока фрагментов обозначается отправкой метки EOC (Конец содержимого). SET и SEQUENCE могут использовать кодирование с неопределенной длиной, но также примитивные типы, такие как OCTET STRING или BIT STRING, могут использовать эту функциональность (см. ITU-T X.690).
Никогда nil. Булево значение, указывающее, использует ли кодирование неопределенную длину (в случае разбора) или должна ли использоваться неопределенная длина (в случае кодирования). В DER каждое значение использует определенную длину. Но в сценариях, где необходимо передавать большие объемы данных, может потребоваться поддержка потоковой передачи. Например, огромные OCTET STRING предпочтительнее передавать небольшими частями по одной. Это возможно в BER, установив байты длины кодирования в ноль, тем самым указав, что последующее значение будет передано частями. Кодирования с неопределенной длиной всегда являются составными. Конец такого потока фрагментов обозначается отправкой метки EOC (Конец содержимого). SET и SEQUENCE могут использовать кодирование с неопределенной длиной, но также примитивные типы, такие как OCTET STRING или BIT STRING, могут использовать эту функциональность (см. ITU-T X.690).
Содержит значение типа ASN.1. См. Constructive и Primitive для сопоставления типов данных ASN.1 и классов Ruby.
Публичные методы класса
static VALUE
ossl_asn1data_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class)
{
if(!SYMBOL_P(tag_class))
ossl_raise(eASN1Error, "invalid tag class");
ossl_asn1_set_tag(self, tag);
ossl_asn1_set_value(self, value);
ossl_asn1_set_tag_class(self, tag_class);
ossl_asn1_set_indefinite_length(self, Qfalse);
return self;
} value: Обратитесь к Constructive и Primitive, чтобы увидеть, как типы Ruby сопоставляются с типами ASN.1 и наоборот.
tag: Целое число Integer, указывающее номер метки.
tag_class: Символ Symbol, указывающий класс метки. Возможные значения см. в ASN1.
Пример
asn1_int = OpenSSL::ASN1Data.new(42, 2, :UNIVERSAL) # => Same as OpenSSL::ASN1::Integer.new(42) tagged_int = OpenSSL::ASN1Data.new(42, 0, :CONTEXT_SPECIFIC) # implicitly 0-tagged INTEGER
Публичные методы экземпляра
static VALUE
ossl_asn1data_to_der(VALUE self)
{
VALUE value = ossl_asn1_get_value(self);
if (rb_obj_is_kind_of(value, rb_cArray))
return ossl_asn1cons_to_der(self);
else {
if (RTEST(ossl_asn1_get_indefinite_length(self)))
ossl_raise(eASN1Error, "indefinite length form cannot be used " \
"with primitive encoding");
return ossl_asn1prim_to_der(self);
}
} Кодирует этот ASN1Data в DER-кодированное значение String. Результат — DER-кодированное, за исключением возможности использования форм с неопределенной длиной. Формы с неопределенной длиной не допускаются в строгом DER, поэтому строго говоря, результатом такого кодирования будет BER-кодирование.
Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.