summaryrefslogtreecommitdiff
path: root/src/crypto/asn1/asn1_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/asn1/asn1_test.cc')
-rw-r--r--src/crypto/asn1/asn1_test.cc62
1 files changed, 61 insertions, 1 deletions
diff --git a/src/crypto/asn1/asn1_test.cc b/src/crypto/asn1/asn1_test.cc
index 7c114ddf..1cca36ce 100644
--- a/src/crypto/asn1/asn1_test.cc
+++ b/src/crypto/asn1/asn1_test.cc
@@ -12,13 +12,18 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+#include <limits.h>
#include <stdio.h>
+#include <vector>
+
#include <gtest/gtest.h>
-#include <limits.h>
#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/bytestring.h>
#include <openssl/err.h>
+#include <openssl/mem.h>
#include "../test/test_util.h"
@@ -88,3 +93,58 @@ TEST(ASN1Test, IntegerSetting) {
}
}
}
+
+typedef struct asn1_linked_list_st {
+ struct asn1_linked_list_st *next;
+} ASN1_LINKED_LIST;
+
+DECLARE_ASN1_ITEM(ASN1_LINKED_LIST)
+DECLARE_ASN1_FUNCTIONS(ASN1_LINKED_LIST)
+
+ASN1_SEQUENCE(ASN1_LINKED_LIST) = {
+ ASN1_OPT(ASN1_LINKED_LIST, next, ASN1_LINKED_LIST),
+} ASN1_SEQUENCE_END(ASN1_LINKED_LIST)
+
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_LINKED_LIST)
+
+static bool MakeLinkedList(bssl::UniquePtr<uint8_t> *out, size_t *out_len,
+ size_t count) {
+ bssl::ScopedCBB cbb;
+ std::vector<CBB> cbbs(count);
+ if (!CBB_init(cbb.get(), 2 * count) ||
+ !CBB_add_asn1(cbb.get(), &cbbs[0], CBS_ASN1_SEQUENCE)) {
+ return false;
+ }
+ for (size_t i = 1; i < count; i++) {
+ if (!CBB_add_asn1(&cbbs[i - 1], &cbbs[i], CBS_ASN1_SEQUENCE)) {
+ return false;
+ }
+ }
+ uint8_t *ptr;
+ if (!CBB_finish(cbb.get(), &ptr, out_len)) {
+ return false;
+ }
+ out->reset(ptr);
+ return true;
+}
+
+TEST(ASN1Test, Recursive) {
+ bssl::UniquePtr<uint8_t> data;
+ size_t len;
+
+ // Sanity-check that MakeLinkedList can be parsed.
+ ASSERT_TRUE(MakeLinkedList(&data, &len, 5));
+ const uint8_t *ptr = data.get();
+ ASN1_LINKED_LIST *list = d2i_ASN1_LINKED_LIST(nullptr, &ptr, len);
+ EXPECT_TRUE(list);
+ ASN1_LINKED_LIST_free(list);
+
+ // Excessively deep structures are rejected.
+ ASSERT_TRUE(MakeLinkedList(&data, &len, 100));
+ ptr = data.get();
+ list = d2i_ASN1_LINKED_LIST(nullptr, &ptr, len);
+ EXPECT_FALSE(list);
+ // Note checking the error queue here does not work. The error "stack trace"
+ // is too deep, so the |ASN1_R_NESTED_TOO_DEEP| entry drops off the queue.
+ ASN1_LINKED_LIST_free(list);
+}