Coverage Report

Created: 2026-10-17 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libcoap/tests/oss-fuzz/dtls_define_target.c
Line
Count
Source
1
/* libFuzzer harness for libcoap's (D)TLS key-type / define mapping
2
 * (coap_dtls.c).
3
 *
4
 * coap_dtls_map_key_type_to_define() is reached when the application hands
5
 * libcoap a coap_dtls_pki_t setup blob and walks every key_type variant
6
 * (PEM / ASN1 / PEM_BUF / PKCS11 / DEFINE), each with their own subfields.
7
 * coap_dtls_define_issue() then formats a diagnostic for every
8
 * type+fail+role combination. None of the existing harnesses drive this
9
 * matrix.
10
 */
11
12
#include "coap3/coap_internal.h"
13
#include "coap3/coap.h"
14
15
#include <stdint.h>
16
#include <stdio.h>
17
#include <string.h>
18
19
extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
20
21
static const coap_pki_key_t k_key_types[] = {
22
  COAP_PKI_KEY_PEM,
23
  COAP_PKI_KEY_ASN1,
24
  COAP_PKI_KEY_PEM_BUF,
25
  COAP_PKI_KEY_PKCS11,
26
  COAP_PKI_KEY_DEFINE,
27
};
28
342
#define K_KEY_TYPE_N (sizeof(k_key_types) / sizeof(k_key_types[0]))
29
30
static const coap_define_issue_key_t k_issue_keys[] = {
31
  COAP_DEFINE_KEY_CA,
32
  COAP_DEFINE_KEY_ROOT_CA,
33
  COAP_DEFINE_KEY_PUBLIC,
34
  COAP_DEFINE_KEY_PRIVATE,
35
};
36
37
static const coap_define_issue_fail_t k_issue_fails[] = {
38
  COAP_DEFINE_FAIL_BAD,
39
  COAP_DEFINE_FAIL_NOT_SUPPORTED,
40
  COAP_DEFINE_FAIL_NONE,
41
};
42
43
int
44
82
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
45
82
  if (size < 4 || size > 1024)
46
25
    return 0;
47
48
  /* Build a NUL-terminated string copy of the fuzz buffer so we can use it
49
   * as PEM/PKCS11 path strings without overrunning. */
50
57
  char strbuf[256];
51
57
  size_t slen = size < sizeof(strbuf) - 1 ? size : sizeof(strbuf) - 1;
52
57
  memcpy(strbuf, data, slen);
53
57
  strbuf[slen] = '\0';
54
55
  /* Stop unnecessary logging output */
56
57
  coap_set_log_level(COAP_LOG_EMERG);
57
58
  /* The PKCS11 branch does strncasecmp(name, "pkcs11:", 7); about a quarter
59
   * of the time we want that string to actually match. */
60
57
  char pkcs11_str[sizeof(strbuf) + 8];
61
57
  snprintf(pkcs11_str, sizeof(pkcs11_str), "pkcs11:%s", strbuf);
62
63
342
  for (size_t i = 0; i < K_KEY_TYPE_N; i++) {
64
285
    coap_dtls_pki_t setup;
65
285
    memset(&setup, 0, sizeof(setup));
66
285
    setup.version = COAP_DTLS_PKI_SETUP_VERSION;
67
285
    setup.is_rpk_not_cert = (data[0] >> i) & 1;
68
285
    setup.pki_key.key_type = k_key_types[i];
69
70
285
    switch (k_key_types[i]) {
71
57
    case COAP_PKI_KEY_PEM:
72
57
      setup.pki_key.key.pem.ca_file = strbuf;
73
57
      setup.pki_key.key.pem.public_cert = strbuf;
74
57
      setup.pki_key.key.pem.private_key = strbuf;
75
57
      break;
76
57
    case COAP_PKI_KEY_ASN1:
77
57
      setup.pki_key.key.asn1.ca_cert = data;
78
57
      setup.pki_key.key.asn1.public_cert = data;
79
57
      setup.pki_key.key.asn1.private_key = data;
80
57
      setup.pki_key.key.asn1.ca_cert_len = size;
81
57
      setup.pki_key.key.asn1.public_cert_len = size;
82
57
      setup.pki_key.key.asn1.private_key_len = size;
83
57
      setup.pki_key.key.asn1.private_key_type =
84
57
          (coap_asn1_privatekey_type_t)(data[1] & 0x0f);
85
57
      break;
86
57
    case COAP_PKI_KEY_PEM_BUF:
87
57
      setup.pki_key.key.pem_buf.ca_cert = data;
88
57
      setup.pki_key.key.pem_buf.public_cert = data;
89
57
      setup.pki_key.key.pem_buf.private_key = data;
90
57
      setup.pki_key.key.pem_buf.ca_cert_len = size;
91
57
      setup.pki_key.key.pem_buf.public_cert_len = size;
92
57
      setup.pki_key.key.pem_buf.private_key_len = size;
93
57
      break;
94
57
    case COAP_PKI_KEY_PKCS11: {
95
57
      const char *which = (data[1] & 1) ? pkcs11_str : strbuf;
96
57
      setup.pki_key.key.pkcs11.ca = which;
97
57
      setup.pki_key.key.pkcs11.public_cert = which;
98
57
      setup.pki_key.key.pkcs11.private_key = which;
99
57
      setup.pki_key.key.pkcs11.user_pin = strbuf;
100
57
      break;
101
0
    }
102
57
    case COAP_PKI_KEY_DEFINE:
103
57
      setup.pki_key.key.define.ca.s_byte = strbuf;
104
57
      setup.pki_key.key.define.public_cert.s_byte = strbuf;
105
57
      setup.pki_key.key.define.private_key.s_byte = strbuf;
106
57
      setup.pki_key.key.define.ca_def = (coap_pki_define_t)(data[2] & 0x0f);
107
57
      setup.pki_key.key.define.public_cert_def =
108
57
          (coap_pki_define_t)(data[2] & 0x0f);
109
57
      setup.pki_key.key.define.private_key_def =
110
57
          (coap_pki_define_t)(data[2] & 0x0f);
111
57
      break;
112
0
    default:
113
0
      break;
114
285
    }
115
116
285
    coap_dtls_key_t mapped;
117
285
    memset(&mapped, 0, sizeof(mapped));
118
285
    coap_dtls_map_key_type_to_define(&setup, &mapped);
119
120
    /* Now exercise the diagnostic formatter over the full type x fail x
121
     * role matrix using the mapped key. */
122
1.42k
    for (size_t t = 0; t < sizeof(k_issue_keys) / sizeof(k_issue_keys[0]);
123
1.14k
         t++) {
124
1.14k
      for (size_t f = 0;
125
4.56k
           f < sizeof(k_issue_fails) / sizeof(k_issue_fails[0]); f++) {
126
3.42k
        coap_dtls_define_issue(k_issue_keys[t], k_issue_fails[f], &mapped,
127
3.42k
                               COAP_DTLS_ROLE_SERVER, 0);
128
3.42k
        coap_dtls_define_issue(k_issue_keys[t], k_issue_fails[f], &mapped,
129
3.42k
                               COAP_DTLS_ROLE_CLIENT, 0);
130
3.42k
      }
131
1.14k
    }
132
285
  }
133
57
  return 0;
134
57
}