Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ext/openssl/ossl_asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,8 @@ int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length,
return asn1data;
}

#define MAX_NESTING_DEPTH 200

static VALUE
ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth,
int yield, long *num_read)
Expand All @@ -899,6 +901,10 @@ ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth,
int tag, tc, j;
VALUE asn1data, tag_class;

if (depth > MAX_NESTING_DEPTH) {
ossl_raise(eASN1Error, "nesting depth %d exceeds limit", depth);
}

p = *pp;
start = p;
p0 = p;
Expand Down
14 changes: 14 additions & 0 deletions test/openssl/test_asn1.rb
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,20 @@ def test_decode_constructed_overread
assert_equal 17, ret[0][6]
end

def test_decode_constructed_deeply_nested
bool = OpenSSL::ASN1::Boolean.new(true)
nested_100 = B(%w{ 30 80 }) * 100 + bool.to_der + B(%w{ 00 00 }) * 100
decoded = OpenSSL::ASN1.decode(nested_100)
assert_equal(nested_100, decoded.to_der)
content = 100.times.inject(decoded) { |a,| a.value[0] }
assert_kind_of(OpenSSL::ASN1::Boolean, content)

nested_500 = B(%w{ 30 80 }) * 500 + bool.to_der + B(%w{ 00 00 }) * 500
assert_raise_with_message(OpenSSL::ASN1::ASN1Error, /nesting depth/) {
OpenSSL::ASN1.decode(nested_500)
}
end

def test_constructive_each
data = [OpenSSL::ASN1::Integer.new(0), OpenSSL::ASN1::Integer.new(1)]
seq = OpenSSL::ASN1::Sequence.new data
Expand Down
Loading