класс 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 (End of Content). SET и SEQUENCE могут использовать кодирование неопределённой длины, но и примитивные типы, такие как, например, OCTET STRING или BIT STRING, могут использовать эту функциональность (см. ITU-T X.690).
Никогда nil. Булевое значение, указывающее, использует ли кодирование неопределенную длину (в случае парсинга) или следует использовать форму неопределенной длины (в случае кодирования). В DER каждое значение использует форму определенной длины. Но в сценариях, где необходимо передавать большие объемы данных, может быть желательно иметь какую-то поддержку потоковой передачи. Например, огромные OCTET STRING предпочтительно отправлять в виде меньших фрагментов по одному. Это возможно в BER, установив байты длины кодирования в ноль и тем самым указав, что последующее значение будет отправлено частями. Кодирование неопределенной длины всегда является составным. Конец такого потока фрагментов указывается путем отправки тега EOC (End of Content). 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.