класс OpenSSL::ASN1::ASN1Data
Базовый класс, представляющий любой объект ASN.1. При парсинге с помощью ASN1.decode, помеченные значения всегда представляются экземпляром ASN1Data.
Роль ASN1Data при парсинге помеченных значений
При кодировании типа ASN.1, исходный тип (например, INTEGER, OCTET STRING и т.д.) значения очевиден независимо от его метки. Но в отличие от кодирования, при парсинге невозможно вывести «реальный тип» помеченных значений. Именно поэтому помеченные значения обычно парсятся в экземпляры 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 (Конец содержимого). Множества и последовательности могут использовать кодирование неопределенной длины, но также и примитивные типы, такие как, например, OCTET STRING или BIT STRING, могут использовать эту функциональность (см. ITU-T X.690).
Никогда nil. Логическое значение, указывающее, использует ли кодирование неопределенную длину (в случае парсинга) или должна ли использоваться форма неопределенной длины (в случае кодирования). В DER каждое значение использует форму определенной длины. Однако в сценариях, когда необходимо передавать большие объемы данных, может быть желательно иметь некоторую поддержку потоковой передачи. Например, огромные OCTET STRING лучше отправлять частями меньшего размера, каждая по отдельности. Это возможно в BER, устанавливая байты длины кодирования в ноль, тем самым указывая, что последующее значение будет отправлено частями. Кодирования неопределенной длины всегда являются составными. Конец такого потока фрагментов указывается отправкой метки EOC (Конец содержимого). Множества и последовательности могут использовать кодирование неопределенной длины, но также и примитивные типы, такие как, например, OCTET STRING или BIT STRING, могут использовать эту функциональность (см. ITU-T X.690).
Целое число, представляющее номер метки этого ASN1Data. Никогда nil.
Содержит значение типа 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;
} значение: Пожалуйста, обратитесь к Constructive и Primitive, чтобы увидеть, как типы Ruby отображаются в типы ASN.1 и наоборот.
метка: Целое число, указывающее номер метки.
класс_метки: Символ, указывающий класс метки. Возможные значения см. в 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. Результат закодирован в формате DER, за исключением возможности использования форм неопределенной длины. Формы неопределенной длины не допускаются в строгом DER, поэтому строго говоря, результат такого кодирования будет BER-кодированием.
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.