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