diff options
Diffstat (limited to 'src/crypto/asn1/asn1_test.cc')
-rw-r--r-- | src/crypto/asn1/asn1_test.cc | 62 |
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); +} |