Spec-Zone.ru › Ruby 2.5

класс OpenSSL::ASN1::ASN1Data

Родитель:
Object

Основной класс, представляющий любой объект ASN.1. При парсинге с помощью OpenSSL::ASN1.decode, помеченные значения всегда представлены экземпляром ASN1Data.

Роль ASN1Data при парсинге помеченных значений

При кодировании типа ASN.1, тип исходного значения (например, INTEGER, OCTET STRING и т. д.) ясен, независимо от его метки. Однако при парсинге типов ASN.1, невозможно определить «реальный тип» помеченных значений. Именно поэтому помеченные значения обычно парсятся в экземпляры ASN1Data, но с разными результатами для неявной и явной метки.

Пример парсинга неявного помеченного значения

Неявное значение INTEGER с меткой 1 будет обработано как ASN1Data с

  • меткой равной 1

  • классом метки равной :CONTEXT_SPECIFIC

  • значением равным строке, содержащей исходное кодирование INTEGER.

Это подразумевает, что для полного декодирования неявных помеченных значений требуется последующий шаг декодирования.

Пример парсинга явного помеченного значения

Явное значение INTEGER с меткой 1 будет обработано как ASN1Data с

  • меткой равной 1

  • классом метки равной :CONTEXT_SPECIFIC

  • значением равным массиву с одним элементом — экземпляром 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 (End of Content). Множества и последовательности могут использовать кодирование с неопределённой длиной, но и примитивные типы, такие как OCTET STRINGS или BIT STRINGS, могут использовать эту функциональность (см. ITU-T X.690).

infinite_length[RW]

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

tag[RW]

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

tag_class[RW]

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

value[RW]

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

Публичные методы класса

OpenSSL::ASN1::ASN1Data.new(value, tag, tag_class) → 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;
}

value: См. Constructive и Primitive для отображения между типами Ruby и типами ASN.1 и наоборот.

tag: Целое число, указывающее номер метки.

tag_class: Символ, указывающий класс метки. Возможные значения см. в 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