Coverage Report

Created: 2025-12-07 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/tests/fuzzing/fuzz_pkcs15_decode.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2019 Frank Morgner <frankmorgner@gmail.com>
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2.1 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15
 * License along with this library; if not, write to the Free Software
16
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
 */
18
19
#ifdef HAVE_CONFIG_H
20
#include "config.h"
21
#endif
22
23
#include "fuzzer_reader.h"
24
#include "libopensc/pkcs15.h"
25
#include "libopensc/internal.h"
26
27
uint16_t fuzz_get_buffer(const uint8_t **buf, size_t buf_len, const uint8_t **out, size_t *out_len)
28
13.9k
{
29
13.9k
  uint16_t len = 0;
30
31
13.9k
  if (!buf || !(*buf) || buf_len < 2)
32
1
    return 0;
33
34
  /* Get length of the result buffer*/
35
13.9k
  len = *((uint16_t *) *buf);
36
13.9k
  if (buf_len - 2 <= len)
37
18
    return 0;
38
13.9k
  (*buf) += 2;
39
13.9k
  buf_len -= 2;
40
  
41
  /* Set out buffer to new reader data*/
42
13.9k
  *out = *buf + len;
43
13.9k
  *out_len = buf_len - len;
44
13.9k
  return len;
45
13.9k
}
46
47
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
48
13.9k
{
49
13.9k
  size_t i = 0;
50
13.9k
  struct sc_reader *reader = NULL;
51
13.9k
  const uint8_t *buf = Data, *reader_data = NULL;
52
13.9k
  uint16_t buf_len = 0;
53
13.9k
  size_t reader_data_len = 0;
54
13.9k
  struct sc_context *ctx = NULL;
55
13.9k
  struct sc_pkcs15_card *p15card = NULL;
56
13.9k
  sc_card_t *card = NULL;
57
13.9k
  struct sc_pkcs15_tokeninfo *tokeninfo = NULL;
58
13.9k
  int (* decode_entries[])(struct sc_pkcs15_card *, struct sc_pkcs15_object *,
59
13.9k
      const u8 **nbuf, size_t *nbufsize) = {
60
13.9k
    sc_pkcs15_decode_prkdf_entry, sc_pkcs15_decode_pukdf_entry,
61
13.9k
    sc_pkcs15_decode_skdf_entry, sc_pkcs15_decode_cdf_entry,
62
13.9k
    sc_pkcs15_decode_dodf_entry, sc_pkcs15_decode_aodf_entry
63
13.9k
  };
64
13.9k
  int algorithms[] = { SC_ALGORITHM_RSA, SC_ALGORITHM_EC, SC_ALGORITHM_GOSTR3410, SC_ALGORITHM_EDDSA };
65
66
  /* Split data into testing buffer and APDU for connecting */
67
13.9k
  if ((buf_len = fuzz_get_buffer(&buf, Size, &reader_data, &reader_data_len)) == 0)
68
29
    return 0;
69
70
  /* Establish context for fuzz app*/
71
13.9k
  sc_establish_context(&ctx, "fuzz");
72
13.9k
  if (!ctx)
73
0
    return 0;
74
75
13.9k
  if (fuzz_connect_card(ctx, &card, &reader, reader_data, reader_data_len) != SC_SUCCESS)
76
3.14k
    goto err;
77
78
10.7k
  sc_pkcs15_bind(card, NULL, &p15card);
79
10.7k
  if (!p15card)
80
6.84k
    goto err;
81
82
27.5k
  for (i = 0; i < sizeof decode_entries/sizeof *decode_entries; i++) {
83
23.6k
    struct sc_pkcs15_object *obj;
84
23.6k
    const u8 *p = buf;
85
23.6k
    size_t len = (size_t) buf_len;
86
23.6k
    if (!(obj = calloc(1, sizeof *obj)))
87
0
      goto err;
88
23.8k
    while (SC_SUCCESS == decode_entries[i](p15card, obj, &p, &len)) {
89
229
      sc_pkcs15_free_object(obj);
90
229
      if (!(obj = calloc(1, sizeof *obj)))
91
0
        goto err;
92
229
    }
93
23.6k
    sc_pkcs15_free_object(obj);
94
23.6k
  }
95
96
19.6k
  for (i = 0; i < 4; i++) {
97
15.7k
    struct sc_pkcs15_pubkey *pubkey = calloc(1, sizeof *pubkey);
98
15.7k
    if (!pubkey)
99
0
      goto err;
100
15.7k
    pubkey->algorithm = algorithms[i];
101
15.7k
    sc_pkcs15_decode_pubkey(ctx, pubkey, buf, buf_len);
102
15.7k
    sc_pkcs15_free_pubkey(pubkey);
103
15.7k
  }
104
105
3.93k
  tokeninfo = sc_pkcs15_tokeninfo_new();
106
3.93k
  sc_pkcs15_parse_tokeninfo(ctx, tokeninfo, buf, buf_len);
107
3.93k
  sc_pkcs15_free_tokeninfo(tokeninfo);
108
109
3.93k
  sc_pkcs15_parse_unusedspace(buf, buf_len, p15card);
110
111
13.9k
err:
112
13.9k
  sc_pkcs15_card_free(p15card);
113
13.9k
  sc_disconnect_card(card);
114
13.9k
  sc_release_context(ctx);
115
13.9k
  return 0;
116
3.93k
}