Coverage Report

Created: 2026-10-13 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/nss/fuzz/targets/pkcs12.cc
Line
Count
Source
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
#include <algorithm>
6
#include <cassert>
7
#include <cstddef>
8
#include <cstdint>
9
#include <cstdio>
10
11
#include "nss_scoped_ptrs.h"
12
#include "p12.h"
13
#include "pk11pub.h"
14
#include "seccomon.h"
15
16
#include "asn1/mutators.h"
17
#include "base/database.h"
18
19
static SECItem* nicknameCollision(SECItem* oldNick, PRBool* cancel,
20
0
                                  void* wincx) {
21
0
  static unsigned int counter = 0;
22
23
  // Always return a unique nickname.
24
0
  SECItem* item = SECITEM_AllocItem(nullptr, nullptr, 12);
25
0
  item->len = snprintf((char*)item->data, 12, "%u", counter++) + 1;
26
27
0
  return item;
28
0
}
29
30
12.6k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
31
12.6k
  static NSSDatabase db = NSSDatabase();
32
33
12.6k
  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
34
12.6k
  assert(slot);
35
36
  // Initialize the decoder.
37
12.6k
  SECItem pwItem = {siBuffer, nullptr, 0};
38
12.6k
  ScopedSEC_PKCS12DecoderContext dcx(
39
12.6k
      SEC_PKCS12DecoderStart(&pwItem, slot.get(), nullptr, nullptr, nullptr,
40
12.6k
                             nullptr, nullptr, nullptr));
41
12.6k
  assert(dcx);
42
43
  // Cap the max element length at 1 MB to avoid OOMs during fuzzing.
44
12.6k
  SEC_PKCS12DecoderSetMaxElementLen(dcx.get(),
45
12.6k
                                    std::max(1024 * 1024, (int)size));
46
47
  // Cycle through target token CA modes.
48
12.6k
  SECPKCS12TargetTokenCAs modes[] = {SECPKCS12TargetTokenNoCAs,
49
12.6k
                                     SECPKCS12TargetTokenIntermediateCAs,
50
12.6k
                                     SECPKCS12TargetTokenAllCAs};
51
12.6k
  SEC_PKCS12DecoderSetTargetTokenCAs(dcx.get(), modes[size % 3]);
52
53
12.6k
  SECStatus rv = SEC_PKCS12DecoderUpdate(dcx.get(), (unsigned char*)data, size);
54
12.6k
  if (rv != SECSuccess) {
55
1.39k
    return 0;
56
1.39k
  }
57
58
  // Verify the blob.
59
11.2k
  rv = SEC_PKCS12DecoderVerify(dcx.get());
60
11.2k
  if (rv != SECSuccess) {
61
11.1k
    return 0;
62
11.1k
  }
63
64
  // Validate bags.
65
152
  rv = SEC_PKCS12DecoderValidateBags(dcx.get(), nicknameCollision);
66
152
  if (rv != SECSuccess) {
67
133
    return 0;
68
133
  }
69
70
  // Import cert and key.
71
19
  rv = SEC_PKCS12DecoderImportBags(dcx.get());
72
19
  if (rv != SECSuccess) {
73
0
    return 0;
74
0
  }
75
76
19
  return 0;
77
19
}
78
79
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
80
0
                                          size_t maxSize, unsigned int seed) {
81
0
  return ASN1Mutators::CustomMutator(data, size, maxSize, seed);
82
0
}
83
84
extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t* data1, size_t size1,
85
                                            const uint8_t* data2, size_t size2,
86
                                            uint8_t* out, size_t maxOutSize,
87
0
                                            unsigned int seed) {
88
0
  return ASN1Mutators::CustomCrossOver(data1, size1, data2, size2, out,
89
0
                                       maxOutSize, seed);
90
0
}