aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/asn1/ber_dec.cpp27
-rw-r--r--src/tests/test_asn1.cpp67
2 files changed, 83 insertions, 11 deletions
diff --git a/src/lib/asn1/ber_dec.cpp b/src/lib/asn1/ber_dec.cpp
index 7b2147600..bf728a8e8 100644
--- a/src/lib/asn1/ber_dec.cpp
+++ b/src/lib/asn1/ber_dec.cpp
@@ -218,20 +218,25 @@ BER_Object BER_Decoder::get_next_object()
return next;
}
- decode_tag(m_source, next.type_tag, next.class_tag);
- if(next.type_tag == NO_OBJECT)
- return next;
+ for(;;)
+ {
+ decode_tag(m_source, next.type_tag, next.class_tag);
+ if(next.type_tag == NO_OBJECT)
+ return next;
- const size_t length = decode_length(m_source);
- if(!m_source->check_available(length))
- throw BER_Decoding_Error("Value truncated");
+ const size_t length = decode_length(m_source);
+ if(!m_source->check_available(length))
+ throw BER_Decoding_Error("Value truncated");
- next.value.resize(length);
- if(m_source->read(next.value.data(), length) != length)
- throw BER_Decoding_Error("Value truncated");
+ next.value.resize(length);
+ if(m_source->read(next.value.data(), length) != length)
+ throw BER_Decoding_Error("Value truncated");
- if(next.type_tag == EOC && next.class_tag == UNIVERSAL)
- return get_next_object();
+ if(next.type_tag == EOC && next.class_tag == UNIVERSAL)
+ continue;
+ else
+ break;
+ }
return next;
}
diff --git a/src/tests/test_asn1.cpp b/src/tests/test_asn1.cpp
new file mode 100644
index 000000000..3427d391d
--- /dev/null
+++ b/src/tests/test_asn1.cpp
@@ -0,0 +1,67 @@
+/*
+* (C) 2017 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "tests.h"
+
+#if defined(BOTAN_HAS_ASN1)
+ #include <botan/der_enc.h>
+ #include <botan/ber_dec.h>
+#endif
+
+namespace Botan_Tests {
+
+#if defined(BOTAN_HAS_ASN1)
+
+namespace {
+
+Test::Result test_ber_stack_recursion()
+ {
+ Test::Result result("BER stack recursion");
+
+ // OSS-Fuzz #813 GitHub #989
+
+ try
+ {
+ const std::vector<uint8_t> in(10000000, 0);
+ Botan::DataSource_Memory input(in.data(), in.size());
+ Botan::BER_Decoder dec(input);
+
+ while(dec.more_items())
+ {
+ Botan::BER_Object obj;
+ dec.get_next(obj);
+ }
+ }
+ catch(Botan::Decoding_Error&)
+ {
+ }
+
+ result.test_success("No crash");
+
+ return result;
+ }
+
+}
+
+class ASN1_Tests : public Test
+ {
+ public:
+ std::vector<Test::Result> run() override
+ {
+ std::vector<Test::Result> results;
+
+ results.push_back(test_ber_stack_recursion());
+
+ return results;
+ }
+ };
+
+BOTAN_REGISTER_TEST("asn1", ASN1_Tests);
+
+#endif
+
+}
+