mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/openssl/ossl_asn1.c: indefinite length BER to DER encoding is
properly supported. Thanks Martin Bosslet! [ruby-core:33082] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30178 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
5e14eeb482
commit
b82ba18990
3 changed files with 351 additions and 26 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
Sun Dec 12 02:42:24 2010 Aaron Patterson <aaron@tenderlovemaking.com>
|
||||||
|
|
||||||
|
* ext/openssl/ossl_asn1.c: indefinite length BER to DER encoding is
|
||||||
|
properly supported. Thanks Martin Bosslet! [ruby-core:33082]
|
||||||
|
|
||||||
Sat Dec 11 17:43:34 2010 Kazuhiro NISHIYAMA <zn@mbf.nifty.com>
|
Sat Dec 11 17:43:34 2010 Kazuhiro NISHIYAMA <zn@mbf.nifty.com>
|
||||||
|
|
||||||
* ext/bigdecimal/bigdecimal.h: suppress "warning: 'VPrint' declared
|
* ext/bigdecimal/bigdecimal.h: suppress "warning: 'VPrint' declared
|
||||||
|
|
|
@ -19,6 +19,8 @@ struct timeval {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static VALUE join_der(VALUE enumerable);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DATE conversion
|
* DATE conversion
|
||||||
*/
|
*/
|
||||||
|
@ -156,15 +158,17 @@ num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)
|
||||||
/*
|
/*
|
||||||
* ASN1 module
|
* ASN1 module
|
||||||
*/
|
*/
|
||||||
#define ossl_asn1_get_value(o) rb_attr_get((o),rb_intern("@value"))
|
#define ossl_asn1_get_value(o) rb_attr_get((o),rb_intern("@value"))
|
||||||
#define ossl_asn1_get_tag(o) rb_attr_get((o),rb_intern("@tag"))
|
#define ossl_asn1_get_tag(o) rb_attr_get((o),rb_intern("@tag"))
|
||||||
#define ossl_asn1_get_tagging(o) rb_attr_get((o),rb_intern("@tagging"))
|
#define ossl_asn1_get_tagging(o) rb_attr_get((o),rb_intern("@tagging"))
|
||||||
#define ossl_asn1_get_tag_class(o) rb_attr_get((o),rb_intern("@tag_class"))
|
#define ossl_asn1_get_tag_class(o) rb_attr_get((o),rb_intern("@tag_class"))
|
||||||
|
#define ossl_asn1_get_infinite_length(o) rb_attr_get((o),rb_intern("@infinite_length"))
|
||||||
|
|
||||||
#define ossl_asn1_set_value(o,v) rb_iv_set((o),"@value",(v))
|
#define ossl_asn1_set_value(o,v) rb_iv_set((o),"@value",(v))
|
||||||
#define ossl_asn1_set_tag(o,v) rb_iv_set((o),"@tag",(v))
|
#define ossl_asn1_set_tag(o,v) rb_iv_set((o),"@tag",(v))
|
||||||
#define ossl_asn1_set_tagging(o,v) rb_iv_set((o),"@tagging",(v))
|
#define ossl_asn1_set_tagging(o,v) rb_iv_set((o),"@tagging",(v))
|
||||||
#define ossl_asn1_set_tag_class(o,v) rb_iv_set((o),"@tag_class",(v))
|
#define ossl_asn1_set_tag_class(o,v) rb_iv_set((o),"@tag_class",(v))
|
||||||
|
#define ossl_asn1_set_infinite_length(o,v) rb_iv_set((o),"@infinite_length",(v))
|
||||||
|
|
||||||
VALUE mASN1;
|
VALUE mASN1;
|
||||||
VALUE eASN1Error;
|
VALUE eASN1Error;
|
||||||
|
@ -173,6 +177,7 @@ VALUE cASN1Data;
|
||||||
VALUE cASN1Primitive;
|
VALUE cASN1Primitive;
|
||||||
VALUE cASN1Constructive;
|
VALUE cASN1Constructive;
|
||||||
|
|
||||||
|
VALUE cASN1EndOfContent;
|
||||||
VALUE cASN1Boolean; /* BOOLEAN */
|
VALUE cASN1Boolean; /* BOOLEAN */
|
||||||
VALUE cASN1Integer, cASN1Enumerated; /* INTEGER */
|
VALUE cASN1Integer, cASN1Enumerated; /* INTEGER */
|
||||||
VALUE cASN1BitString; /* BIT STRING */
|
VALUE cASN1BitString; /* BIT STRING */
|
||||||
|
@ -449,7 +454,7 @@ typedef struct {
|
||||||
} ossl_asn1_info_t;
|
} ossl_asn1_info_t;
|
||||||
|
|
||||||
static ossl_asn1_info_t ossl_asn1_info[] = {
|
static ossl_asn1_info_t ossl_asn1_info[] = {
|
||||||
{ "EOC", NULL, }, /* 0 */
|
{ "EOC", &cASN1EndOfContent, }, /* 0 */
|
||||||
{ "BOOLEAN", &cASN1Boolean, }, /* 1 */
|
{ "BOOLEAN", &cASN1Boolean, }, /* 1 */
|
||||||
{ "INTEGER", &cASN1Integer, }, /* 2 */
|
{ "INTEGER", &cASN1Integer, }, /* 2 */
|
||||||
{ "BIT_STRING", &cASN1BitString, }, /* 3 */
|
{ "BIT_STRING", &cASN1BitString, }, /* 3 */
|
||||||
|
@ -660,6 +665,7 @@ ossl_asn1data_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class)
|
||||||
ossl_asn1_set_tag(self, tag);
|
ossl_asn1_set_tag(self, tag);
|
||||||
ossl_asn1_set_value(self, value);
|
ossl_asn1_set_value(self, value);
|
||||||
ossl_asn1_set_tag_class(self, tag_class);
|
ossl_asn1_set_tag_class(self, tag_class);
|
||||||
|
ossl_asn1_set_infinite_length(self, Qfalse);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -684,8 +690,8 @@ join_der(VALUE enumerable)
|
||||||
static VALUE
|
static VALUE
|
||||||
ossl_asn1data_to_der(VALUE self)
|
ossl_asn1data_to_der(VALUE self)
|
||||||
{
|
{
|
||||||
VALUE value, der;
|
VALUE value, der, inf_length;
|
||||||
int tag, tag_class, is_cons = 0;
|
int tag, tag_class, is_cons = 0, tmp_cons = 1;
|
||||||
long length;
|
long length;
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
|
|
||||||
|
@ -698,7 +704,12 @@ ossl_asn1data_to_der(VALUE self)
|
||||||
|
|
||||||
tag = ossl_asn1_tag(self);
|
tag = ossl_asn1_tag(self);
|
||||||
tag_class = ossl_asn1_tag_class(self);
|
tag_class = ossl_asn1_tag_class(self);
|
||||||
if((length = ASN1_object_size(1, RSTRING_LEN(value), tag)) <= 0)
|
inf_length = ossl_asn1_get_infinite_length(self);
|
||||||
|
if (inf_length == Qtrue) {
|
||||||
|
is_cons = 2;
|
||||||
|
tmp_cons = 2;
|
||||||
|
}
|
||||||
|
if((length = ASN1_object_size(tmp_cons, RSTRING_LEN(value), tag)) <= 0)
|
||||||
ossl_raise(eASN1Error, NULL);
|
ossl_raise(eASN1Error, NULL);
|
||||||
der = rb_str_new(0, length);
|
der = rb_str_new(0, length);
|
||||||
p = (unsigned char *)RSTRING_PTR(der);
|
p = (unsigned char *)RSTRING_PTR(der);
|
||||||
|
@ -717,7 +728,7 @@ ossl_asn1_decode0(unsigned char **pp, long length, long *offset, long depth,
|
||||||
unsigned char *start, *p;
|
unsigned char *start, *p;
|
||||||
const unsigned char *p0;
|
const unsigned char *p0;
|
||||||
long len, off = *offset;
|
long len, off = *offset;
|
||||||
int hlen, tag, tc, j;
|
int hlen, tag, tc, j, infinite = 0;
|
||||||
VALUE ary, asn1data, value, tag_class;
|
VALUE ary, asn1data, value, tag_class;
|
||||||
|
|
||||||
ary = rb_ary_new();
|
ary = rb_ary_new();
|
||||||
|
@ -752,8 +763,8 @@ ossl_asn1_decode0(unsigned char **pp, long length, long *offset, long depth,
|
||||||
else
|
else
|
||||||
tag_class = sUNIVERSAL;
|
tag_class = sUNIVERSAL;
|
||||||
if(j & V_ASN1_CONSTRUCTED){
|
if(j & V_ASN1_CONSTRUCTED){
|
||||||
/* TODO: if j == 0x21 it is indefinite length object. */
|
|
||||||
if((j == 0x21) && (len == 0)){
|
if((j == 0x21) && (len == 0)){
|
||||||
|
infinite = 1;
|
||||||
long lastoff = off;
|
long lastoff = off;
|
||||||
value = ossl_asn1_decode0(&p, length, &off, depth+1, 0, yield);
|
value = ossl_asn1_decode0(&p, length, &off, depth+1, 0, yield);
|
||||||
len = off - lastoff;
|
len = off - lastoff;
|
||||||
|
@ -798,15 +809,39 @@ ossl_asn1_decode0(unsigned char **pp, long length, long *offset, long depth,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
asn1data = rb_funcall(klass, rb_intern("new"), 1, value);
|
if (infinite && !(tag == V_ASN1_SEQUENCE || tag == V_ASN1_SET)){
|
||||||
|
asn1data = rb_funcall(cASN1Constructive,
|
||||||
|
rb_intern("new"),
|
||||||
|
4,
|
||||||
|
value,
|
||||||
|
INT2NUM(tag),
|
||||||
|
Qnil,
|
||||||
|
ID2SYM(tag_class));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if (tag == V_ASN1_EOC){
|
||||||
|
asn1data = rb_funcall(cASN1EndOfContent,
|
||||||
|
rb_intern("new"),
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
asn1data = rb_funcall(klass, rb_intern("new"), 1, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
if(tag == V_ASN1_BIT_STRING){
|
if(tag == V_ASN1_BIT_STRING){
|
||||||
rb_iv_set(asn1data, "@unused_bits", LONG2NUM(flag));
|
rb_iv_set(asn1data, "@unused_bits", LONG2NUM(flag));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
asn1data = rb_funcall(cASN1Data, rb_intern("new"), 3,
|
asn1data = rb_funcall(cASN1Data, rb_intern("new"), 3,
|
||||||
value, INT2NUM(tag), ID2SYM(tag_class));
|
value, INT2NUM(tag), ID2SYM(tag_class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (infinite)
|
||||||
|
ossl_asn1_set_infinite_length(asn1data, Qtrue);
|
||||||
|
else
|
||||||
|
ossl_asn1_set_infinite_length(asn1data, Qfalse);
|
||||||
|
|
||||||
rb_ary_push(ary, asn1data);
|
rb_ary_push(ary, asn1data);
|
||||||
length -= len;
|
length -= len;
|
||||||
if(once) break;
|
if(once) break;
|
||||||
|
@ -894,10 +929,26 @@ ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
|
||||||
ossl_asn1_set_value(self, value);
|
ossl_asn1_set_value(self, value);
|
||||||
ossl_asn1_set_tagging(self, tagging);
|
ossl_asn1_set_tagging(self, tagging);
|
||||||
ossl_asn1_set_tag_class(self, tag_class);
|
ossl_asn1_set_tag_class(self, tag_class);
|
||||||
|
ossl_asn1_set_infinite_length(self, Qfalse);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
ossl_asn1eoc_initialize(VALUE self) {
|
||||||
|
VALUE tag, tagging, tag_class, value;
|
||||||
|
tag = INT2NUM(ossl_asn1_default_tag(self));
|
||||||
|
tagging = Qnil;
|
||||||
|
tag_class = ID2SYM(sUNIVERSAL);
|
||||||
|
value = rb_str_new("", 0);
|
||||||
|
ossl_asn1_set_tag(self, tag);
|
||||||
|
ossl_asn1_set_value(self, value);
|
||||||
|
ossl_asn1_set_tagging(self, tagging);
|
||||||
|
ossl_asn1_set_tag_class(self, tag_class);
|
||||||
|
ossl_asn1_set_infinite_length(self, Qfalse);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ossl_i2d_ASN1_TYPE(ASN1_TYPE *a, unsigned char **pp)
|
ossl_i2d_ASN1_TYPE(ASN1_TYPE *a, unsigned char **pp)
|
||||||
{
|
{
|
||||||
|
@ -962,29 +1013,64 @@ ossl_asn1prim_to_der(VALUE self)
|
||||||
static VALUE
|
static VALUE
|
||||||
ossl_asn1cons_to_der(VALUE self)
|
ossl_asn1cons_to_der(VALUE self)
|
||||||
{
|
{
|
||||||
int tag, tn, tc, explicit;
|
int tag, tn, tc, explicit, constructed = 1;
|
||||||
|
int found_prim = 0;
|
||||||
long seq_len, length;
|
long seq_len, length;
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
VALUE value, str;
|
VALUE value, str, inf_length, ary, example;
|
||||||
|
|
||||||
tag = ossl_asn1_default_tag(self);
|
|
||||||
tn = NUM2INT(ossl_asn1_get_tag(self));
|
tn = NUM2INT(ossl_asn1_get_tag(self));
|
||||||
tc = ossl_asn1_tag_class(self);
|
tc = ossl_asn1_tag_class(self);
|
||||||
|
inf_length = ossl_asn1_get_infinite_length(self);
|
||||||
|
if (inf_length == Qtrue) {
|
||||||
|
constructed = 2;
|
||||||
|
if (CLASS_OF(self) == cASN1Sequence ||
|
||||||
|
CLASS_OF(self) == cASN1Set) {
|
||||||
|
tag = ossl_asn1_default_tag(self);
|
||||||
|
}
|
||||||
|
else { /*BIT_STRING OR OCTET_STRING*/
|
||||||
|
ary = ossl_asn1_get_value(self);
|
||||||
|
/* Recursively descend until a primitive value is found.
|
||||||
|
The overall value of the entire constructed encoding
|
||||||
|
is of the type of the first primitive encoding to be
|
||||||
|
found. */
|
||||||
|
while (!found_prim){
|
||||||
|
example = rb_ary_entry(ary, 0);
|
||||||
|
if (rb_obj_is_kind_of(example, cASN1Primitive)){
|
||||||
|
found_prim = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* example is another ASN1Constructive */
|
||||||
|
if (!rb_obj_is_kind_of(example, cASN1Constructive)){
|
||||||
|
ossl_raise(eASN1Error, "invalid constructed encoding");
|
||||||
|
return Qnil; /* dummy */
|
||||||
|
}
|
||||||
|
ary = ossl_asn1_get_value(example);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tag = ossl_asn1_default_tag(example);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tag = ossl_asn1_default_tag(self);
|
||||||
|
}
|
||||||
explicit = ossl_asn1_is_explicit(self);
|
explicit = ossl_asn1_is_explicit(self);
|
||||||
value = join_der(ossl_asn1_get_value(self));
|
value = join_der(ossl_asn1_get_value(self));
|
||||||
|
|
||||||
seq_len = ASN1_object_size(1, RSTRING_LEN(value), tag);
|
seq_len = ASN1_object_size(constructed, RSTRING_LEN(value), tag);
|
||||||
length = ASN1_object_size(1, seq_len, tn);
|
length = ASN1_object_size(constructed, seq_len, tn);
|
||||||
str = rb_str_new(0, length);
|
str = rb_str_new(0, length);
|
||||||
p = (unsigned char *)RSTRING_PTR(str);
|
p = (unsigned char *)RSTRING_PTR(str);
|
||||||
if(tc == V_ASN1_UNIVERSAL)
|
if(tc == V_ASN1_UNIVERSAL)
|
||||||
ASN1_put_object(&p, 1, RSTRING_LEN(value), tn, tc);
|
ASN1_put_object(&p, constructed, RSTRING_LEN(value), tn, tc);
|
||||||
else{
|
else{
|
||||||
if(explicit){
|
if(explicit){
|
||||||
ASN1_put_object(&p, 1, seq_len, tn, tc);
|
ASN1_put_object(&p, constructed, seq_len, tn, tc);
|
||||||
ASN1_put_object(&p, 1, RSTRING_LEN(value), tag, V_ASN1_UNIVERSAL);
|
ASN1_put_object(&p, constructed, RSTRING_LEN(value), tag, V_ASN1_UNIVERSAL);
|
||||||
}
|
}
|
||||||
else ASN1_put_object(&p, 1, RSTRING_LEN(value), tn, tc);
|
else{
|
||||||
|
ASN1_put_object(&p, constructed, RSTRING_LEN(value), tn, tc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value));
|
memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value));
|
||||||
p += RSTRING_LEN(value);
|
p += RSTRING_LEN(value);
|
||||||
|
@ -1080,6 +1166,7 @@ OSSL_ASN1_IMPL_FACTORY_METHOD(UTCTime)
|
||||||
OSSL_ASN1_IMPL_FACTORY_METHOD(GeneralizedTime)
|
OSSL_ASN1_IMPL_FACTORY_METHOD(GeneralizedTime)
|
||||||
OSSL_ASN1_IMPL_FACTORY_METHOD(Sequence)
|
OSSL_ASN1_IMPL_FACTORY_METHOD(Sequence)
|
||||||
OSSL_ASN1_IMPL_FACTORY_METHOD(Set)
|
OSSL_ASN1_IMPL_FACTORY_METHOD(Set)
|
||||||
|
OSSL_ASN1_IMPL_FACTORY_METHOD(EndOfContent)
|
||||||
|
|
||||||
void
|
void
|
||||||
Init_ossl_asn1()
|
Init_ossl_asn1()
|
||||||
|
@ -1115,11 +1202,13 @@ Init_ossl_asn1()
|
||||||
rb_attr(cASN1Data, rb_intern("value"), 1, 1, 0);
|
rb_attr(cASN1Data, rb_intern("value"), 1, 1, 0);
|
||||||
rb_attr(cASN1Data, rb_intern("tag"), 1, 1, 0);
|
rb_attr(cASN1Data, rb_intern("tag"), 1, 1, 0);
|
||||||
rb_attr(cASN1Data, rb_intern("tag_class"), 1, 1, 0);
|
rb_attr(cASN1Data, rb_intern("tag_class"), 1, 1, 0);
|
||||||
|
rb_attr(cASN1Data, rb_intern("infinite_length"), 1, 1, 0);
|
||||||
rb_define_method(cASN1Data, "initialize", ossl_asn1data_initialize, 3);
|
rb_define_method(cASN1Data, "initialize", ossl_asn1data_initialize, 3);
|
||||||
rb_define_method(cASN1Data, "to_der", ossl_asn1data_to_der, 0);
|
rb_define_method(cASN1Data, "to_der", ossl_asn1data_to_der, 0);
|
||||||
|
|
||||||
cASN1Primitive = rb_define_class_under(mASN1, "Primitive", cASN1Data);
|
cASN1Primitive = rb_define_class_under(mASN1, "Primitive", cASN1Data);
|
||||||
rb_attr(cASN1Primitive, rb_intern("tagging"), 1, 1, Qtrue);
|
rb_attr(cASN1Primitive, rb_intern("tagging"), 1, 1, Qtrue);
|
||||||
|
rb_undef_method(cASN1Primitive, "infinite_length=");
|
||||||
rb_define_method(cASN1Primitive, "initialize", ossl_asn1_initialize, -1);
|
rb_define_method(cASN1Primitive, "initialize", ossl_asn1_initialize, -1);
|
||||||
rb_define_method(cASN1Primitive, "to_der", ossl_asn1prim_to_der, 0);
|
rb_define_method(cASN1Primitive, "to_der", ossl_asn1prim_to_der, 0);
|
||||||
|
|
||||||
|
@ -1160,6 +1249,8 @@ do{\
|
||||||
OSSL_ASN1_DEFINE_CLASS(Sequence, Constructive);
|
OSSL_ASN1_DEFINE_CLASS(Sequence, Constructive);
|
||||||
OSSL_ASN1_DEFINE_CLASS(Set, Constructive);
|
OSSL_ASN1_DEFINE_CLASS(Set, Constructive);
|
||||||
|
|
||||||
|
OSSL_ASN1_DEFINE_CLASS(EndOfContent, Data);
|
||||||
|
|
||||||
rb_define_singleton_method(cASN1ObjectId, "register", ossl_asn1obj_s_register, 3);
|
rb_define_singleton_method(cASN1ObjectId, "register", ossl_asn1obj_s_register, 3);
|
||||||
rb_define_method(cASN1ObjectId, "sn", ossl_asn1obj_get_sn, 0);
|
rb_define_method(cASN1ObjectId, "sn", ossl_asn1obj_get_sn, 0);
|
||||||
rb_define_method(cASN1ObjectId, "ln", ossl_asn1obj_get_ln, 0);
|
rb_define_method(cASN1ObjectId, "ln", ossl_asn1obj_get_ln, 0);
|
||||||
|
@ -1167,4 +1258,6 @@ do{\
|
||||||
rb_define_alias(cASN1ObjectId, "short_name", "sn");
|
rb_define_alias(cASN1ObjectId, "short_name", "sn");
|
||||||
rb_define_alias(cASN1ObjectId, "long_name", "ln");
|
rb_define_alias(cASN1ObjectId, "long_name", "ln");
|
||||||
rb_attr(cASN1BitString, rb_intern("unused_bits"), 1, 1, 0);
|
rb_attr(cASN1BitString, rb_intern("unused_bits"), 1, 1, 0);
|
||||||
|
|
||||||
|
rb_define_method(cASN1EndOfContent, "initialize", ossl_asn1eoc_initialize, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,4 +203,231 @@ class OpenSSL::TestASN1 < Test::Unit::TestCase
|
||||||
assert_equal(v, OpenSSL::ASN1.decode(type.new(v).to_der).value)
|
assert_equal(v, OpenSSL::ASN1.decode(type.new(v).to_der).value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_primitive_cannot_set_infinite_length
|
||||||
|
begin
|
||||||
|
prim = OpenSSL::ASN1::Integer.new(50)
|
||||||
|
assert_equal(false, prim.infinite_length)
|
||||||
|
prim.infinite_length = true
|
||||||
|
flunk('Could set infinite length on primitive value')
|
||||||
|
rescue NoMethodError => e
|
||||||
|
#ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_seq_infinite_length
|
||||||
|
begin
|
||||||
|
content = [ OpenSSL::ASN1::Null.new(nil),
|
||||||
|
OpenSSL::ASN1::EndOfContent.new ]
|
||||||
|
cons = OpenSSL::ASN1::Sequence.new(content)
|
||||||
|
cons.infinite_length = true
|
||||||
|
expected = %w{ 30 80 05 00 00 00 }
|
||||||
|
raw = [expected.join('')].pack('H*')
|
||||||
|
assert_equal(raw, cons.to_der)
|
||||||
|
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_set_infinite_length
|
||||||
|
begin
|
||||||
|
content = [ OpenSSL::ASN1::Null.new(nil),
|
||||||
|
OpenSSL::ASN1::EndOfContent.new() ]
|
||||||
|
cons = OpenSSL::ASN1::Set.new(content)
|
||||||
|
cons.infinite_length = true
|
||||||
|
expected = %w{ 31 80 05 00 00 00 }
|
||||||
|
raw = [expected.join('')].pack('H*')
|
||||||
|
assert_equal(raw, cons.to_der)
|
||||||
|
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_octet_string_infinite_length
|
||||||
|
begin
|
||||||
|
octets = [ OpenSSL::ASN1::OctetString.new('aaa'),
|
||||||
|
OpenSSL::ASN1::EndOfContent.new() ]
|
||||||
|
cons = OpenSSL::ASN1::Constructive.new(
|
||||||
|
octets,
|
||||||
|
OpenSSL::ASN1::OCTET_STRING,
|
||||||
|
nil,
|
||||||
|
:UNIVERSAL)
|
||||||
|
cons.infinite_length = true
|
||||||
|
expected = %w{ 24 80 04 03 61 61 61 00 00 }
|
||||||
|
raw = [expected.join('')].pack('H*')
|
||||||
|
assert_equal(raw, cons.to_der)
|
||||||
|
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_prim_explicit_tagging
|
||||||
|
begin
|
||||||
|
oct_str = OpenSSL::ASN1::OctetString.new("a", 0, :EXPLICIT)
|
||||||
|
expected = %w{ A0 03 04 01 61 }
|
||||||
|
raw = [expected.join('')].pack('H*')
|
||||||
|
assert_equal(raw, oct_str.to_der)
|
||||||
|
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_prim_explicit_tagging_tag_class
|
||||||
|
begin
|
||||||
|
oct_str = OpenSSL::ASN1::OctetString.new("a", 0, :EXPLICIT)
|
||||||
|
oct_str2 = OpenSSL::ASN1::OctetString.new(
|
||||||
|
"a",
|
||||||
|
0,
|
||||||
|
:EXPLICIT,
|
||||||
|
:CONTEXT_SPECIFIC)
|
||||||
|
assert_equal(oct_str.to_der, oct_str2.to_der)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_prim_implicit_tagging
|
||||||
|
begin
|
||||||
|
int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT)
|
||||||
|
expected = %w{ 80 01 01 }
|
||||||
|
raw = [expected.join('')].pack('H*')
|
||||||
|
assert_equal(raw, int.to_der)
|
||||||
|
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_prim_implicit_tagging_tag_class
|
||||||
|
begin
|
||||||
|
int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT)
|
||||||
|
int2 = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT, :CONTEXT_SPECIFIC);
|
||||||
|
assert_equal(int.to_der, int2.to_der)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_cons_explicit_tagging
|
||||||
|
begin
|
||||||
|
content = [ OpenSSL::ASN1::PrintableString.new('abc') ]
|
||||||
|
seq = OpenSSL::ASN1::Sequence.new(content, 2, :EXPLICIT)
|
||||||
|
expected = %w{ A2 07 30 05 13 03 61 62 63 }
|
||||||
|
raw = [expected.join('')].pack('H*')
|
||||||
|
assert_equal(raw, seq.to_der)
|
||||||
|
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_cons_explicit_tagging_inf_length
|
||||||
|
begin
|
||||||
|
content = [ OpenSSL::ASN1::PrintableString.new('abc') ,
|
||||||
|
OpenSSL::ASN1::EndOfContent.new() ]
|
||||||
|
seq = OpenSSL::ASN1::Sequence.new(content, 2, :EXPLICIT)
|
||||||
|
seq.infinite_length = true
|
||||||
|
expected = %w{ A2 80 30 80 13 03 61 62 63 00 00 }
|
||||||
|
raw = [expected.join('')].pack('H*')
|
||||||
|
assert_equal(raw, seq.to_der)
|
||||||
|
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_cons_implicit_tagging
|
||||||
|
begin
|
||||||
|
content = [ OpenSSL::ASN1::Null.new(nil) ]
|
||||||
|
seq = OpenSSL::ASN1::Sequence.new(content, 1, :IMPLICIT)
|
||||||
|
expected = %w{ A1 02 05 00 }
|
||||||
|
raw = [expected.join('')].pack('H*')
|
||||||
|
assert_equal(raw, seq.to_der)
|
||||||
|
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_cons_implicit_tagging_inf_length
|
||||||
|
begin
|
||||||
|
content = [ OpenSSL::ASN1::Null.new(nil),
|
||||||
|
OpenSSL::ASN1::EndOfContent.new() ]
|
||||||
|
seq = OpenSSL::ASN1::Sequence.new(content, 1, :IMPLICIT)
|
||||||
|
seq.infinite_length = true
|
||||||
|
expected = %w{ A1 80 05 00 00 00 }
|
||||||
|
raw = [expected.join('')].pack('H*')
|
||||||
|
assert_equal(raw, seq.to_der)
|
||||||
|
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_octet_string_infinite_length_explicit_tagging
|
||||||
|
begin
|
||||||
|
octets = [ OpenSSL::ASN1::OctetString.new('aaa'),
|
||||||
|
OpenSSL::ASN1::EndOfContent.new() ]
|
||||||
|
cons = OpenSSL::ASN1::Constructive.new(
|
||||||
|
octets,
|
||||||
|
1,
|
||||||
|
:EXPLICIT)
|
||||||
|
cons.infinite_length = true
|
||||||
|
expected = %w{ A1 80 24 80 04 03 61 61 61 00 00 }
|
||||||
|
raw = [expected.join('')].pack('H*')
|
||||||
|
assert_equal(raw, cons.to_der)
|
||||||
|
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_octet_string_infinite_length_implicit_tagging
|
||||||
|
begin
|
||||||
|
octets = [ OpenSSL::ASN1::OctetString.new('aaa'),
|
||||||
|
OpenSSL::ASN1::EndOfContent.new() ]
|
||||||
|
cons = OpenSSL::ASN1::Constructive.new(
|
||||||
|
octets,
|
||||||
|
0,
|
||||||
|
:IMPLICIT)
|
||||||
|
cons.infinite_length = true
|
||||||
|
expected = %w{ A0 80 04 03 61 61 61 00 00 }
|
||||||
|
raw = [expected.join('')].pack('H*')
|
||||||
|
assert_equal(raw, cons.to_der)
|
||||||
|
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_recursive_octet_string_infinite_length
|
||||||
|
begin
|
||||||
|
octets_sub1 = [ OpenSSL::ASN1::OctetString.new("\x01"),
|
||||||
|
OpenSSL::ASN1::EndOfContent.new() ]
|
||||||
|
octets_sub2 = [ OpenSSL::ASN1::OctetString.new("\x02"),
|
||||||
|
OpenSSL::ASN1::EndOfContent.new() ]
|
||||||
|
container1 = OpenSSL::ASN1::Constructive.new(
|
||||||
|
octets_sub1,
|
||||||
|
OpenSSL::ASN1::OCTET_STRING,
|
||||||
|
nil,
|
||||||
|
:UNIVERSAL)
|
||||||
|
container1.infinite_length = true
|
||||||
|
container2 = OpenSSL::ASN1::Constructive.new(
|
||||||
|
octets_sub2,
|
||||||
|
OpenSSL::ASN1::OCTET_STRING,
|
||||||
|
nil,
|
||||||
|
:UNIVERSAL)
|
||||||
|
container2.infinite_length = true
|
||||||
|
octets3 = OpenSSL::ASN1::OctetString.new("\x03")
|
||||||
|
|
||||||
|
octets = [ container1, container2, octets3,
|
||||||
|
OpenSSL::ASN1::EndOfContent.new() ]
|
||||||
|
cons = OpenSSL::ASN1::Constructive.new(
|
||||||
|
octets,
|
||||||
|
OpenSSL::ASN1::OCTET_STRING,
|
||||||
|
nil,
|
||||||
|
:UNIVERSAL)
|
||||||
|
cons.infinite_length = true
|
||||||
|
expected = %w{ 24 80 24 80 04 01 01 00 00 24 80 04 01 02 00 00 04 01 03 00 00 }
|
||||||
|
raw = [expected.join('')].pack('H*')
|
||||||
|
assert_equal(raw, cons.to_der)
|
||||||
|
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_bit_string_infinite_length
|
||||||
|
begin
|
||||||
|
content = [ OpenSSL::ASN1::BitString.new("\x01"),
|
||||||
|
OpenSSL::ASN1::EndOfContent.new() ]
|
||||||
|
cons = OpenSSL::ASN1::Constructive.new(
|
||||||
|
content,
|
||||||
|
OpenSSL::ASN1::BIT_STRING,
|
||||||
|
nil,
|
||||||
|
:UNIVERSAL)
|
||||||
|
cons.infinite_length = true
|
||||||
|
expected = %w{ 23 80 03 02 00 01 00 00 }
|
||||||
|
raw = [expected.join('')].pack('H*')
|
||||||
|
assert_equal(raw, cons.to_der)
|
||||||
|
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end if defined?(OpenSSL)
|
end if defined?(OpenSSL)
|
||||||
|
|
Loading…
Reference in a new issue