1c7da899bSchristos /*
2*b0d17251Schristos * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
3c7da899bSchristos *
4*b0d17251Schristos * Licensed under the Apache License 2.0 (the "License"). You may not use
5c7da899bSchristos * this file except in compliance with the License. You can obtain a copy
6c7da899bSchristos * in the file LICENSE in the source distribution or at
7c7da899bSchristos * https://www.openssl.org/source/license.html
8c7da899bSchristos */
9c7da899bSchristos
10c7da899bSchristos /* Regression tests for ASN.1 parsing bugs. */
11c7da899bSchristos
12c7da899bSchristos #include <stdio.h>
13c7da899bSchristos #include <string.h>
14c7da899bSchristos
15c7da899bSchristos #include "testutil.h"
16c7da899bSchristos
17c7da899bSchristos #include <openssl/asn1.h>
18c7da899bSchristos #include <openssl/asn1t.h>
19c7da899bSchristos #include <openssl/bio.h>
20c7da899bSchristos #include <openssl/err.h>
21c7da899bSchristos #include <openssl/x509.h>
22c7da899bSchristos #include <openssl/x509v3.h>
2313d40330Schristos #include "internal/nelem.h"
24c7da899bSchristos
25c7da899bSchristos static const ASN1_ITEM *item_type;
26c7da899bSchristos static const char *test_file;
27c7da899bSchristos
28c7da899bSchristos typedef enum {
29c7da899bSchristos ASN1_UNKNOWN,
30c7da899bSchristos ASN1_OK,
31c7da899bSchristos ASN1_BIO,
32c7da899bSchristos ASN1_DECODE,
33c7da899bSchristos ASN1_ENCODE,
34c7da899bSchristos ASN1_COMPARE
35c7da899bSchristos } expected_error_t;
36c7da899bSchristos
37c7da899bSchristos typedef struct {
38c7da899bSchristos const char *str;
39c7da899bSchristos expected_error_t code;
40c7da899bSchristos } error_enum;
41c7da899bSchristos
42c7da899bSchristos static expected_error_t expected_error = ASN1_UNKNOWN;
43c7da899bSchristos
test_bad_asn1(void)4413d40330Schristos static int test_bad_asn1(void)
45c7da899bSchristos {
46c7da899bSchristos BIO *bio = NULL;
47c7da899bSchristos ASN1_VALUE *value = NULL;
48c7da899bSchristos int ret = 0;
49c7da899bSchristos unsigned char buf[2048];
50c7da899bSchristos const unsigned char *buf_ptr = buf;
51c7da899bSchristos unsigned char *der = NULL;
52c7da899bSchristos int derlen;
53c7da899bSchristos int len;
54c7da899bSchristos
5513d40330Schristos bio = BIO_new_file(test_file, "r");
5613d40330Schristos if (!TEST_ptr(bio))
57c7da899bSchristos return 0;
58c7da899bSchristos
59c7da899bSchristos if (expected_error == ASN1_BIO) {
6013d40330Schristos if (TEST_ptr_null(ASN1_item_d2i_bio(item_type, bio, NULL)))
61c7da899bSchristos ret = 1;
62c7da899bSchristos goto err;
63c7da899bSchristos }
64c7da899bSchristos
65c7da899bSchristos /*
66c7da899bSchristos * Unless we are testing it we don't use ASN1_item_d2i_bio because it
67c7da899bSchristos * performs sanity checks on the input and can reject it before the
68c7da899bSchristos * decoder is called.
69c7da899bSchristos */
7053060421Schristos len = BIO_read(bio, buf, sizeof(buf));
7113d40330Schristos if (!TEST_int_ge(len, 0))
72c7da899bSchristos goto err;
73c7da899bSchristos
74c7da899bSchristos value = ASN1_item_d2i(NULL, &buf_ptr, len, item_type);
75c7da899bSchristos if (value == NULL) {
7613d40330Schristos if (TEST_int_eq(expected_error, ASN1_DECODE))
77c7da899bSchristos ret = 1;
78c7da899bSchristos goto err;
79c7da899bSchristos }
80c7da899bSchristos
81c7da899bSchristos derlen = ASN1_item_i2d(value, &der, item_type);
82c7da899bSchristos
83c7da899bSchristos if (der == NULL || derlen < 0) {
8413d40330Schristos if (TEST_int_eq(expected_error, ASN1_ENCODE))
85c7da899bSchristos ret = 1;
86c7da899bSchristos goto err;
87c7da899bSchristos }
88c7da899bSchristos
89c7da899bSchristos if (derlen != len || memcmp(der, buf, derlen) != 0) {
9013d40330Schristos if (TEST_int_eq(expected_error, ASN1_COMPARE))
91c7da899bSchristos ret = 1;
92c7da899bSchristos goto err;
93c7da899bSchristos }
94c7da899bSchristos
9513d40330Schristos if (TEST_int_eq(expected_error, ASN1_OK))
96c7da899bSchristos ret = 1;
97c7da899bSchristos
98c7da899bSchristos err:
99c7da899bSchristos /* Don't indicate success for memory allocation errors */
10013d40330Schristos if (ret == 1
10113d40330Schristos && !TEST_false(ERR_GET_REASON(ERR_peek_error()) == ERR_R_MALLOC_FAILURE))
102c7da899bSchristos ret = 0;
103c7da899bSchristos BIO_free(bio);
104c7da899bSchristos OPENSSL_free(der);
105c7da899bSchristos ASN1_item_free(value, item_type);
106c7da899bSchristos return ret;
107c7da899bSchristos }
108c7da899bSchristos
109*b0d17251Schristos OPT_TEST_DECLARE_USAGE("item_name expected_error test_file.der\n")
110*b0d17251Schristos
111c7da899bSchristos /*
11213d40330Schristos * Usage: d2i_test <name> <type> <file>, e.g.
113c7da899bSchristos * d2i_test generalname bad_generalname.der
114c7da899bSchristos */
setup_tests(void)11513d40330Schristos int setup_tests(void)
116c7da899bSchristos {
117c7da899bSchristos const char *test_type_name;
118c7da899bSchristos const char *expected_error_string;
119c7da899bSchristos
120c7da899bSchristos size_t i;
121c7da899bSchristos
122c7da899bSchristos static error_enum expected_errors[] = {
123c7da899bSchristos {"OK", ASN1_OK},
124c7da899bSchristos {"BIO", ASN1_BIO},
125c7da899bSchristos {"decode", ASN1_DECODE},
126c7da899bSchristos {"encode", ASN1_ENCODE},
127c7da899bSchristos {"compare", ASN1_COMPARE}
128c7da899bSchristos };
129c7da899bSchristos
130*b0d17251Schristos if (!test_skip_common_options()) {
131*b0d17251Schristos TEST_error("Error parsing test options\n");
13213d40330Schristos return 0;
133c7da899bSchristos }
134c7da899bSchristos
135*b0d17251Schristos if (!TEST_ptr(test_type_name = test_get_argument(0))
136*b0d17251Schristos || !TEST_ptr(expected_error_string = test_get_argument(1))
137*b0d17251Schristos || !TEST_ptr(test_file = test_get_argument(2)))
138*b0d17251Schristos return 0;
139*b0d17251Schristos
14013d40330Schristos item_type = ASN1_ITEM_lookup(test_type_name);
141c7da899bSchristos
142c7da899bSchristos if (item_type == NULL) {
14313d40330Schristos TEST_error("Unknown type %s", test_type_name);
14413d40330Schristos TEST_note("Supported types:");
14513d40330Schristos for (i = 0;; i++) {
14613d40330Schristos const ASN1_ITEM *it = ASN1_ITEM_get(i);
14713d40330Schristos
14813d40330Schristos if (it == NULL)
14913d40330Schristos break;
15013d40330Schristos TEST_note("\t%s", it->sname);
151c7da899bSchristos }
15213d40330Schristos return 0;
153c7da899bSchristos }
154c7da899bSchristos
155c7da899bSchristos for (i = 0; i < OSSL_NELEM(expected_errors); i++) {
156c7da899bSchristos if (strcmp(expected_errors[i].str, expected_error_string) == 0) {
157c7da899bSchristos expected_error = expected_errors[i].code;
158c7da899bSchristos break;
159c7da899bSchristos }
160c7da899bSchristos }
161c7da899bSchristos
162c7da899bSchristos if (expected_error == ASN1_UNKNOWN) {
16313d40330Schristos TEST_error("Unknown expected error %s\n", expected_error_string);
16413d40330Schristos return 0;
165c7da899bSchristos }
166c7da899bSchristos
167c7da899bSchristos ADD_TEST(test_bad_asn1);
16813d40330Schristos return 1;
169c7da899bSchristos }
170