1 /* Copyright 2021 Google LLC
2 Licensed under the Apache License, Version 2.0 (the "License");
3 you may not use this file except in compliance with the License.
4 You may obtain a copy of the License at
5 http://www.apache.org/licenses/LICENSE-2.0
6 Unless required by applicable law or agreed to in writing, software
7 distributed under the License is distributed on an "AS IS" BASIS,
8 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9 See the License for the specific language governing permissions and
10 limitations under the License.
11 */
12
13 #include "config.h"
14 #include "syshead.h"
15
16 #include <openssl/x509.h>
17 #include <openssl/x509v3.h>
18 #include <openssl/ssl.h>
19 #include <openssl/err.h>
20
21 #include "fuzz_verify_cert.h"
22 #include "misc.h"
23 #include "manage.h"
24 #include "otime.h"
25 #include "base64.h"
26 #include "ssl_verify.h"
27 #include "ssl_verify_backend.h"
28
29 #include "fuzz_randomizer.h"
30
31
parse_x509(const uint8_t * data,size_t size,X509 ** out)32 static int parse_x509(const uint8_t *data, size_t size, X509 **out) {
33 *out = d2i_X509(NULL, (const unsigned char **)&data, size);
34 if (*out == NULL) {
35 return -1;
36 }
37
38 return 0;
39 }
40
41
LLVMFuzzerInitialize(int * argc,char *** argv)42 int LLVMFuzzerInitialize(int *argc, char ***argv) {
43 OPENSSL_malloc_init();
44 SSL_library_init();
45 ERR_load_crypto_strings();
46
47 OpenSSL_add_all_algorithms();
48 OpenSSL_add_ssl_algorithms();
49
50 SSL_load_error_strings();
51 return 1;
52 }
53
54
init_session_opt(struct tls_options ** _opt,struct gc_arena * gc)55 static int init_session_opt(struct tls_options **_opt, struct gc_arena *gc) {
56 ssize_t nid;
57 ssize_t generic_ssizet;
58 struct tls_options *opt;
59 int r;
60
61 ALLOC_OBJ_GC(*_opt, struct tls_options, gc);
62 if (opt == NULL) {
63 return -1;
64 }
65
66 opt = *_opt;
67
68 memset(opt, 0xFE, sizeof(struct tls_options));
69
70 opt->es = env_set_create(gc);
71 opt->x509_username_field[0] = NULL;
72 opt->remote_cert_eku = NULL;
73
74 /* Prevents failure if x509 sha1 hashes do not match */
75 opt->verify_hash = NULL;
76
77 /* Prevent attempt to run --tls-verify script */
78 opt->verify_command = NULL;
79
80 /* Do not verify against CRL file */
81 opt->crl_file = NULL;
82
83 /* Do not run --tls-verify plugins */
84 opt->plugins = NULL;
85
86 r = fuzz_randomizer_get_int(0, 1);
87 if (r == 0) {
88 opt->x509_username_field[0] = nidstrs[fuzz_randomizer_get_int(0, (sizeof(nidstrs)/sizeof(nidstrs[0])) - 1)];
89 }
90 else {
91 opt->x509_username_field[0] = "ext:subjectAltName";
92 }
93 opt->x509_username_field[1] = NULL;
94
95 r = fuzz_randomizer_get_int(0, 2);
96 if (r == 0)
97 opt->ns_cert_type = NS_CERT_CHECK_CLIENT;
98 else if (r == 1)
99 opt->ns_cert_type = NS_CERT_CHECK_SERVER;
100 else
101 opt->ns_cert_type = NS_CERT_CHECK_NONE;
102
103 opt->x509_track = NULL;
104
105 r = fuzz_randomizer_get_int(0, 1);
106 if (r == 0)
107 opt->remote_cert_eku = NULL;
108 else
109 opt->remote_cert_eku = get_random_string();
110
111 return 0;
112 }
113
114
init_session(struct tls_session ** _session,struct gc_arena * gc)115 static int init_session(struct tls_session **_session, struct gc_arena *gc) {
116 struct tls_session *session;
117
118 ALLOC_OBJ_GC(*_session, struct tls_session, gc);
119 if (*_session == NULL) {
120 return -1;
121 }
122
123 session = *_session;
124 memset(session, 0xFE, sizeof(struct tls_session));
125
126 /* Accessed in set_common_name() */
127 session->common_name = get_random_string();;
128
129 /* Initialize the session->opt structure */
130 if (init_session_opt(&(session->opt), gc) == -1) {
131 free(session->common_name);
132 return -1;
133 }
134
135 /* Accessed in server_untrusted() */
136 session->untrusted_addr.dest.addr.sa.sa_family = AF_UNSPEC;
137
138 return 0;
139 }
140
141
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)142 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
143 fuzz_random_init(data, size);
144
145 struct gc_arena gc;
146 struct tls_session *session = NULL;
147 X509 *x509 = NULL;
148 gc = gc_new();
149
150 if (parse_x509(data, size, &x509) == 0) {
151 if (init_session(&session, &gc) == 0) {
152 verify_cert(session, x509, 100);
153 if (session->opt->remote_cert_eku != NULL) {
154 free(session->opt->remote_cert_eku);
155 }
156 free(session->common_name);
157 }
158
159 }
160
161 X509_free(x509);
162 gc_free(&gc);
163
164 fuzz_random_destroy();
165
166 return 0;
167 }
168