Skip to content

Commit 400d9ca

Browse files
committed
asn1: allow constructed encoding with definite length form
Constructed encoding can use the definite length form as well as the indefinite length form, regardless of the tag number.
1 parent af895bc commit 400d9ca

File tree

2 files changed

+16
-32
lines changed

2 files changed

+16
-32
lines changed

ext/openssl/ossl_asn1.c

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -833,23 +833,10 @@ int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length,
833833

834834
if (tc == sym_UNIVERSAL) {
835835
VALUE args[4];
836-
int not_sequence_or_set;
837-
838-
not_sequence_or_set = tag != V_ASN1_SEQUENCE && tag != V_ASN1_SET;
839-
840-
if (not_sequence_or_set) {
841-
if (indefinite) {
842-
asn1data = rb_obj_alloc(cASN1Constructive);
843-
}
844-
else {
845-
ossl_raise(eASN1Error, "invalid non-indefinite tag");
846-
return Qnil;
847-
}
848-
}
849-
else {
850-
VALUE klass = *ossl_asn1_info[tag].klass;
851-
asn1data = rb_obj_alloc(klass);
852-
}
836+
if (tag == V_ASN1_SEQUENCE || tag == V_ASN1_SET)
837+
asn1data = rb_obj_alloc(*ossl_asn1_info[tag].klass);
838+
else
839+
asn1data = rb_obj_alloc(cASN1Constructive);
853840
args[0] = ary;
854841
args[1] = INT2NUM(tag);
855842
args[2] = Qnil;
@@ -1224,9 +1211,9 @@ ossl_asn1cons_to_der(VALUE self)
12241211
}
12251212
}
12261213
else {
1227-
if (rb_obj_class(self) == cASN1Constructive)
1228-
ossl_raise(eASN1Error, "Constructive shall only be used with indefinite length");
12291214
tag = ossl_asn1_default_tag(self);
1215+
if (tag == -1) /* neither SEQUENCE nor SET */
1216+
tag = ossl_asn1_tag(self);
12301217
}
12311218
explicit = ossl_asn1_is_explicit(self);
12321219
value = join_der(ossl_asn1_get_value(self));

test/test_asn1.rb

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,10 @@ def test_basic_primitive
436436

437437
def test_basic_constructed
438438
octet_string = OpenSSL::ASN1::OctetString.new(B(%w{ AB CD }))
439+
encode_test B(%w{ 20 00 }), OpenSSL::ASN1::Constructive.new([], 0)
440+
encode_test B(%w{ 21 00 }), OpenSSL::ASN1::Constructive.new([], 1, nil, :UNIVERSAL)
441+
encode_test B(%w{ A1 00 }), OpenSSL::ASN1::Constructive.new([], 1, nil, :CONTEXT_SPECIFIC)
442+
encode_test B(%w{ 21 04 04 02 AB CD }), OpenSSL::ASN1::Constructive.new([octet_string], 1)
439443
obj = OpenSSL::ASN1::Constructive.new([
440444
octet_string,
441445
OpenSSL::ASN1::EndOfContent.new
@@ -444,14 +448,6 @@ def test_basic_constructed
444448
encode_decode_test B(%w{ 21 80 04 02 AB CD 00 00 }), obj
445449
end
446450

447-
def test_cons_without_inf_length_forbidden
448-
assert_raise(OpenSSL::ASN1::ASN1Error) do
449-
val = OpenSSL::ASN1::OctetString.new('a')
450-
cons = OpenSSL::ASN1::Constructive.new([val], OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL)
451-
cons.to_der
452-
end
453-
end
454-
455451
def test_prim_explicit_tagging
456452
oct_str = OpenSSL::ASN1::OctetString.new("a", 0, :EXPLICIT)
457453
encode_test B(%w{ A0 03 04 01 61 }), oct_str
@@ -517,15 +513,16 @@ def test_octet_string_indefinite_length_explicit_tagging
517513
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
518514
end
519515

520-
def test_octet_string_indefinite_length_implicit_tagging
516+
def test_octet_string_constructed_tagging
517+
octets = [ OpenSSL::ASN1::OctetString.new('aaa') ]
518+
cons = OpenSSL::ASN1::Constructive.new(octets, 0, :IMPLICIT)
519+
encode_test B(%w{ A0 05 04 03 61 61 61 }), cons
520+
521521
octets = [ OpenSSL::ASN1::OctetString.new('aaa'),
522522
OpenSSL::ASN1::EndOfContent.new() ]
523523
cons = OpenSSL::ASN1::Constructive.new(octets, 0, :IMPLICIT)
524524
cons.indefinite_length = true
525-
expected = %w{ A0 80 04 03 61 61 61 00 00 }
526-
raw = [expected.join('')].pack('H*')
527-
assert_equal(raw, cons.to_der)
528-
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
525+
encode_test B(%w{ A0 80 04 03 61 61 61 00 00 }), cons
529526
end
530527

531528
def test_recursive_octet_string_indefinite_length

0 commit comments

Comments
 (0)