/src/opensc/src/tests/fuzzing/fuzz_pkcs15_crypt.c
Line | Count | Source |
1 | | /* |
2 | | * fuzz_pkcs15_crypt.c: Fuzz target for pkcs15-crypt |
3 | | * |
4 | | * Copyright (C) 2022 Red Hat, Inc. |
5 | | * |
6 | | * Author: Veronika Hanulikova <vhanulik@redhat.com> |
7 | | * |
8 | | * This library is free software; you can redistribute it and/or |
9 | | * modify it under the terms of the GNU Lesser General Public |
10 | | * License as published by the Free Software Foundation; either |
11 | | * version 2.1 of the License, or (at your option) any later version. |
12 | | * |
13 | | * This library is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | | * Lesser General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU General Public License |
19 | | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 | | */ |
21 | | |
22 | | #ifdef HAVE_CONFIG_H |
23 | | #include "config.h" |
24 | | #endif |
25 | | |
26 | | #include "libopensc/internal.h" |
27 | | #include <stdlib.h> |
28 | | #include <string.h> |
29 | | #include <stdbool.h> |
30 | | #include "fuzzer_reader.h" |
31 | | #include "fuzzer_tool.h" |
32 | | #undef stderr |
33 | 12.0k | #define stderr stdout |
34 | | |
35 | | /* Rename main to call it in fuzz target */ |
36 | | #define main _main |
37 | 15.1k | #define util_connect_card_ex(ctx, card, id, do_wait, do_lock) fuzz_util_connect_card(ctx, card) |
38 | | # include "tools/pkcs15-crypt.c" |
39 | | #undef main |
40 | | |
41 | | static const uint8_t *reader_data = NULL; |
42 | | static size_t reader_data_size = 0; |
43 | | |
44 | | /* Use instead of util_connect_card() */ |
45 | | int fuzz_util_connect_card(sc_context_t *ctx, sc_card_t **card) |
46 | 18.4k | { |
47 | 18.4k | opt_output = NULL; /* Do not create new outputfile */ |
48 | 18.4k | return fuzz_connect_card(ctx, card, NULL, reader_data, reader_data_size); |
49 | 18.4k | } |
50 | | |
51 | | void initialize_global() |
52 | 15.9k | { |
53 | | /* Global variables need to be reser between runs, |
54 | | fuzz target is called repetitively in one execution */ |
55 | 15.9k | verbose = 0, opt_wait = 0, opt_raw = 0; |
56 | 15.9k | opt_reader = NULL; |
57 | 15.9k | opt_pincode = NULL, opt_key_id = NULL; |
58 | 15.9k | opt_input = NULL, opt_output = NULL; |
59 | 15.9k | opt_bind_to_aid = NULL; |
60 | 15.9k | opt_sig_format = NULL; |
61 | 15.9k | opt_crypt_flags = 0; |
62 | 15.9k | ctx = NULL; |
63 | 15.9k | card = NULL; |
64 | 15.9k | p15card = NULL; |
65 | | |
66 | 15.9k | optind = 0; |
67 | 15.9k | opterr = 0; |
68 | 15.9k | optopt = 0; |
69 | 15.9k | } |
70 | | |
71 | | void test_operation(char *op, char *pin, const uint8_t *data, size_t size, char *filename, |
72 | | char *hash, char *format, char *aid, char *id, uint8_t pad) |
73 | 4.67k | { |
74 | 4.67k | char *argv[] = {"./fuzz_pkcs15_crypt", op, "-p", pin, "-i", filename, |
75 | 4.67k | hash, "-f", format, NULL, NULL, NULL, NULL, NULL, NULL}; |
76 | 4.67k | int argc = 9; |
77 | | |
78 | 4.67k | if (aid) { |
79 | 281 | argv[argc++] = "--aid"; |
80 | 281 | argv[argc++] = aid; |
81 | 281 | } |
82 | 4.67k | if (id) { |
83 | 22 | argv[argc++] = "-k"; |
84 | 22 | argv[argc++] = id; |
85 | 22 | } |
86 | 4.67k | if (pad) |
87 | 2.70k | argv[argc++] = "--pkcs1"; |
88 | | |
89 | 4.67k | reader_data = data; |
90 | 4.67k | reader_data_size = size; |
91 | 4.67k | _main(argc, argv); |
92 | 4.67k | } |
93 | | |
94 | | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) |
95 | 15.3k | { |
96 | 15.3k | uint8_t operation = 0; |
97 | 15.3k | uint8_t hash = 0; |
98 | 15.3k | char *hash_options[] = {"--md5", "--sha-1", "--sha-224", "--sha-256", "--sha-384", "--sha-512"}; |
99 | 15.3k | uint8_t pad = 0; |
100 | 15.3k | uint8_t format = 0; |
101 | 15.3k | char *formats[] = {"rs", "sequence", "openssl"}; |
102 | 15.3k | uint8_t aid = 0; |
103 | 15.3k | char *opt_aid = NULL; |
104 | 15.3k | uint8_t id = 0; |
105 | 15.3k | char *opt_id = NULL; |
106 | 15.3k | char *pin = NULL; |
107 | 15.3k | char *filename = NULL; |
108 | | |
109 | 15.3k | if (size < 15) |
110 | 6 | return 0; |
111 | | |
112 | 15.3k | #ifdef FUZZING_ENABLED |
113 | 15.3k | fclose(stdout); |
114 | 15.3k | #endif |
115 | | |
116 | 15.3k | initialize_global(); |
117 | | |
118 | 15.3k | operation = data[0] % 3; |
119 | 15.3k | data++; size--; |
120 | | |
121 | 15.3k | if (!(pin = extract_word(&data, &size))) |
122 | 3 | return 0; |
123 | | |
124 | 15.3k | if (operation == 0) { /* test random arguments */ |
125 | 10.6k | char **argv = NULL; |
126 | 10.6k | int argc = 0; |
127 | | |
128 | | /* setup pin and input file otherwise fuzz target waits for input from stdin */ |
129 | 10.6k | opt_pincode = pin; |
130 | 10.6k | opt_input = "invalid_filename"; |
131 | | |
132 | 10.6k | if (get_fuzzed_argv("./fuzz_pkcs15_crypt", data, size, &argv, &argc, &reader_data, &reader_data_size) != 0) |
133 | 2 | goto err; |
134 | 10.6k | _main(argc, argv); |
135 | 10.6k | free_arguments(argc, argv); |
136 | 10.6k | } else { |
137 | | /* Set options */ |
138 | 4.70k | if (size < 5) |
139 | 2 | goto err; |
140 | 4.70k | hash = data[0] % 6; data++; size--; |
141 | 4.70k | pad = data[0] % 2; data++; size--; |
142 | 4.70k | format = data[0] % 3; data++; size--; |
143 | | |
144 | 4.70k | aid = data[0] % 2; data++; size--; |
145 | 4.70k | if (aid) { |
146 | 284 | if (!(opt_aid = extract_word(&data, &size))) |
147 | 1 | goto err; |
148 | 284 | } |
149 | 4.70k | if (size < 3) |
150 | 1 | goto err; |
151 | | |
152 | 4.70k | id = data[0] % 2; data++; size--; |
153 | 4.70k | if (id) { |
154 | 32 | if (!(opt_id = extract_word(&data, &size))) |
155 | 2 | goto err; |
156 | 32 | } |
157 | | |
158 | 4.70k | if (create_input_file(&filename, &data, &size) != 0) |
159 | 26 | goto err; |
160 | 4.67k | test_operation(operation == 1 ? "-c" : "-s", pin, data, size, filename, hash_options[hash], formats[format], opt_aid, opt_id, pad); |
161 | | |
162 | 4.67k | remove_file(filename); |
163 | 4.67k | } |
164 | | |
165 | 15.3k | err: |
166 | 15.3k | free(pin); |
167 | 15.3k | free(opt_aid); |
168 | 15.3k | free(opt_id); |
169 | 15.3k | return 0; |
170 | 15.3k | } |