OpenSSL::ASN1::ASN1Data
类 OpenSSL :: ASN1 :: ASN1Data
家长:对象(Parent:Object)
表示任何ASN.1对象的顶级类。当由OpenSSL :: ASN1.decode解析时,标记值始终由ASN1Data实例表示。
ASN1Data用于解析标记值的角色
当编码一个ASN.1类型时,它固有地清楚这个值的原始类型(例如INTEGER,OCTET STRING等)是什么,而不管它的标记如何。但与ASN.1类型的编码时间相反,解析它们时,不可能推断标记值的“真实类型”。这就是为什么标签值通常被解析为ASN1Data实例,但隐式和显式标签的结果不同。
解析的隐式标记值的示例
一个隐含1标签的INTEGER值将被解析为ASN1Data
tag
equal to 1
tag_class
equal to:CONTEXT_SPECIFIC
value
等于一个String
携带INTEGER的原始编码。这意味着需要后续的解码步骤来完全解码隐式标记的值。解析明确标记的值的示例显式带1标记的INTEGER值将被解析为ASN1Data,其中
tag
equal to 1
tag_class
equal to:CONTEXT_SPECIFIC
value
等于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
# @infinite_length=false,
# @tag=16,
# @tag_class=:UNIVERSAL,
# @tagging=nil,
# @value=
# [#<OpenSSL::ASN1::ASN1Data:0x87326f4
# @infinite_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
# @infinite_length=false,
# @tag=16,
# @tag_class=:UNIVERSAL,
# @tagging=nil,
# @value=
# [#<OpenSSL::ASN1::ASN1Data:0x87326f4
# @infinite_length=false,
# @tag=0,
# @tag_class=:CONTEXT_SPECIFIC,
# @value=
# [#<OpenSSL::ASN1::Integer:0x85bf308
# @infinite_length=false,
# @tag=2,
# @tag_class=:UNIVERSAL
# @tagging=nil,
# @value=1>]>]>
int2 = asn1.value[0].value[0]
puts int2.value # => 1
属性
infinite_lengthRW
从不nil
。一个Boolean
指示编码是无限长度(在解析的情况下)还是应该使用无限长度编码(在编码情况下)。在DER中,每个值都具有与其相关的有限长度。但是在需要传输大量数据的情况下,可能需要提供某种流媒体支持。例如,巨大的OCTET STRING最好每次以较小尺寸发送。这可以通过将编码的长度字节设置为零来实现,这表示以下值将以块形式发送。无限长度编码始终构建。通过发送EOC(End of Content)标签来指示这种块的结束。SET和SEQUENCE可以使用无限长度编码,但也可以使用基本类型,例如
tagRW
一个Number
表示此ASN1Data的标签号码。从不nil
。
tag_classRW
一个Symbol
代表标签类此ASN1Data的。从不nil
。请参阅ASN1Data了解可能的值。
valueRW
具有ASN.1类型的价值。请为ASN.1数据类型和Ruby类之间的映射赋予Constructive和Primitive。
公共类方法
OpenSSL :: ASN1 :: ASN1Data.new(value,tag,tag_class)→ASN1Data显示源代码
value
:请查看Constructive和Primitive来了解Ruby类型如何映射到ASN.1类型,反之亦然。
tag
:Number
表示标签号码。
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_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class)
{
if(!SYMBOL_P(tag_class))
ossl_raise(eASN1Error, "invalid tag class"
if (tag_class == sym_UNIVERSAL && NUM2INT(tag) > 31)
ossl_raise(eASN1Error, "tag number for Universal too large"
ossl_asn1_set_tag(self, tag
ossl_asn1_set_value(self, value
ossl_asn1_set_tag_class(self, tag_class
ossl_asn1_set_infinite_length(self, Qfalse
return self;
}
公共实例方法
to_der→DER编码的字符串显示源
将此ASN1Data编码为DER编码的字符串值。除了无限长编码的可能性之外,结果是DER编码。严格DER中不允许无限长度编码,因此严格地说,这种编码的结果将是BER编码。
static VALUE
ossl_asn1data_to_der(VALUE self)
{
VALUE value, der, inf_length;
int tag, tag_class, is_cons = 0;
long length;
unsigned char *p;
value = ossl_asn1_get_value(self
if(rb_obj_is_kind_of(value, rb_cArray)){
is_cons = 1;
value = join_der(value
}
StringValue(value
tag = ossl_asn1_tag(self
tag_class = ossl_asn1_tag_class(self
inf_length = ossl_asn1_get_infinite_length(self
if (inf_length == Qtrue) {
is_cons = 2;
}
if((length = ASN1_object_size(is_cons, RSTRING_LENINT(value), tag)) <= 0)
ossl_raise(eASN1Error, NULL
der = rb_str_new(0, length
p = (unsigned char *)RSTRING_PTR(der
ASN1_put_object(&p, is_cons, RSTRING_LENINT(value), tag, tag_class
memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value)
p += RSTRING_LEN(value
ossl_str_adjust(der, p
return der;
}