Spec-Zone.ru › Ruby 2.7

класс 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

Атрибуты

indefinite_length[RW]

Никогда nil. Логическое значение, указывающее, использует ли кодирование неопределенную длину (в случае парсинга) или должна ли использоваться форма неопределенной длины (в случае кодирования). В DER каждое значение использует форму определенной длины. Однако в сценариях, когда необходимо передавать большие объемы данных, может быть желательно иметь некоторую поддержку потоковой передачи. Например, огромные OCTET STRING лучше отправлять частями меньшего размера, каждая по отдельности. Это возможно в BER, устанавливая байты длины кодирования в ноль, тем самым указывая, что последующее значение будет отправлено частями. Кодирования неопределенной длины всегда являются составными. Конец такого потока фрагментов указывается отправкой метки EOC (Конец содержимого). Множества и последовательности могут использовать кодирование неопределенной длины, но также и примитивные типы, такие как, например, OCTET STRING или BIT STRING, могут использовать эту функциональность (см. ITU-T X.690).

infinite_length[RW]

Никогда nil. Логическое значение, указывающее, использует ли кодирование неопределенную длину (в случае парсинга) или должна ли использоваться форма неопределенной длины (в случае кодирования). В DER каждое значение использует форму определенной длины. Однако в сценариях, когда необходимо передавать большие объемы данных, может быть желательно иметь некоторую поддержку потоковой передачи. Например, огромные OCTET STRING лучше отправлять частями меньшего размера, каждая по отдельности. Это возможно в BER, устанавливая байты длины кодирования в ноль, тем самым указывая, что последующее значение будет отправлено частями. Кодирования неопределенной длины всегда являются составными. Конец такого потока фрагментов указывается отправкой метки EOC (Конец содержимого). Множества и последовательности могут использовать кодирование неопределенной длины, но также и примитивные типы, такие как, например, OCTET STRING или BIT STRING, могут использовать эту функциональность (см. ITU-T X.690).

метка[RW]

Целое число, представляющее номер метки этого ASN1Data. Никогда nil.

класс_метки[RW]

Символ, представляющий класс метки этого ASN1Data. Никогда nil. Возможные значения см. в ASN1Data.

значение[RW]

Содержит значение типа ASN.1. Обратитесь к Constructive и Primitive для отображения соответствия между типами данных ASN.1 и классами Ruby.

Общедоступные методы класса

OpenSSL::ASN1::ASN1Data.new(значение, метка, класс_метки) → ASN1Data Показать исходный код
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

Общедоступные методы экземпляра

to_der → строка в формате DER Показать исходный код
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.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API