Coverage Report

Created: 2025-10-13 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}