Coverage Report

Created: 2026-10-15 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/FreeRDP/winpr/libwinpr/utils/test/TestFuzzCredSSP_Asn1.c
Line
Count
Source
1
/**
2
 * WinPR: Windows Portable Runtime
3
 * libFuzzer harness for the WinPrAsn1 decoder
4
 */
5
6
#include <stddef.h>
7
#include <stdint.h>
8
9
#include <winpr/asn1.h>
10
#include <winpr/crt.h>
11
#include <winpr/wlog.h>
12
13
static void fuzz_walk_sequence(WinPrAsn1Decoder* outer, int depth);
14
15
static void fuzz_consume_one(WinPrAsn1Decoder* decoder, int depth)
16
155k
{
17
155k
  WinPrAsn1Decoder inner = WinPrAsn1Decoder_init();
18
155k
  WinPrAsn1_tag tag = 0;
19
155k
  size_t len = 0;
20
21
155k
  if (depth > 6)
22
0
    return;
23
24
155k
  if (WinPrAsn1DecReadTagLenValue(decoder, &tag, &len, &inner) == 0)
25
120k
    return;
26
27
35.3k
  switch (tag & ER_TAG_MASK)
28
35.3k
  {
29
5.20k
    case ER_TAG_BOOLEAN:
30
5.20k
    {
31
5.20k
      WinPrAsn1_BOOL value = 0;
32
5.20k
      (void)WinPrAsn1DecReadBoolean(&inner, &value);
33
5.20k
      break;
34
0
    }
35
2.54k
    case ER_TAG_INTEGER:
36
2.54k
    {
37
2.54k
      WinPrAsn1_INTEGER value = 0;
38
2.54k
      (void)WinPrAsn1DecReadInteger(&inner, &value);
39
2.54k
      break;
40
0
    }
41
2.13k
    case ER_TAG_OCTET_STRING:
42
2.13k
    {
43
2.13k
      WinPrAsn1_OctetString value = WINPR_C_ARRAY_INIT;
44
2.13k
      if (WinPrAsn1DecReadOctetString(&inner, &value, TRUE))
45
586
        WinPrAsn1FreeOctetString(&value);
46
2.13k
      break;
47
0
    }
48
1.09k
    case ER_TAG_OBJECT_IDENTIFIER:
49
1.09k
    {
50
1.09k
      WinPrAsn1_OID value = WINPR_C_ARRAY_INIT;
51
1.09k
      if (WinPrAsn1DecReadOID(&inner, &value, TRUE))
52
216
        WinPrAsn1FreeOID(&value);
53
1.09k
      break;
54
0
    }
55
1.00k
    case ER_TAG_ENUMERATED:
56
1.00k
    {
57
1.00k
      WinPrAsn1_ENUMERATED value = 0;
58
1.00k
      (void)WinPrAsn1DecReadEnumerated(&inner, &value);
59
1.00k
      break;
60
0
    }
61
4.50k
    case ER_TAG_UTCTIME:
62
4.50k
    {
63
4.50k
      WinPrAsn1_UTCTIME value = WINPR_C_ARRAY_INIT;
64
4.50k
      (void)WinPrAsn1DecReadUtcTime(&inner, &value);
65
4.50k
      break;
66
0
    }
67
1.52k
    case ER_TAG_IA5STRING:
68
1.52k
    {
69
1.52k
      WinPrAsn1_IA5STRING value = nullptr;
70
1.52k
      (void)WinPrAsn1DecReadIA5String(&inner, &value);
71
1.52k
      free(value);
72
1.52k
      break;
73
0
    }
74
1.54k
    case ER_TAG_NULL:
75
1.54k
      (void)WinPrAsn1DecReadNull(&inner);
76
1.54k
      break;
77
15.8k
    default:
78
15.8k
      break;
79
35.3k
  }
80
81
35.3k
  if ((tag == ER_TAG_SEQUENCE) || (tag == ER_TAG_SET))
82
1.82k
    fuzz_walk_sequence(&inner, depth + 1);
83
33.5k
  else if ((tag & 0xC0) == 0x80)
84
9.07k
    fuzz_walk_sequence(&inner, depth + 1);
85
35.3k
}
86
87
static void fuzz_walk_sequence(WinPrAsn1Decoder* outer, int depth)
88
14.0k
{
89
14.0k
  if (depth > 6)
90
242
    return;
91
92
169k
  for (size_t index = 0; index < 64; index++)
93
168k
  {
94
168k
    WinPrAsn1_tag tag = 0;
95
96
168k
    if (!WinPrAsn1DecPeekTag(outer, &tag))
97
13.2k
      return;
98
99
155k
    fuzz_consume_one(outer, depth);
100
155k
  }
101
13.7k
}
102
103
int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
104
1.43k
{
105
1.43k
  static BOOL loggingInitialized = FALSE;
106
107
1.43k
  if (!loggingInitialized)
108
1
  {
109
1
    (void)WLog_SetLogLevel(WLog_GetRoot(), WLOG_TRACE);
110
1
    (void)WLog_SetLogAppenderType(WLog_GetRoot(), WLOG_APPENDER_CALLBACK);
111
1
    loggingInitialized = TRUE;
112
1
  }
113
114
1.43k
  if ((size == 0) || (size > (1u << 20)))
115
0
    return 0;
116
117
1.43k
  {
118
1.43k
    WinPrAsn1Decoder decoder = WinPrAsn1Decoder_init();
119
1.43k
    WinPrAsn1Decoder_InitMem(&decoder, WINPR_ASN1_DER, data, size);
120
1.43k
    fuzz_walk_sequence(&decoder, 0);
121
1.43k
  }
122
123
1.43k
  {
124
1.43k
    WinPrAsn1Decoder decoder = WinPrAsn1Decoder_init();
125
1.43k
    WinPrAsn1Decoder_InitMem(&decoder, WINPR_ASN1_BER, data, size);
126
1.43k
    fuzz_walk_sequence(&decoder, 0);
127
1.43k
  }
128
129
1.43k
  {
130
1.43k
    WinPrAsn1Decoder decoder = WinPrAsn1Decoder_init();
131
1.43k
    WinPrAsn1Decoder sequence = WinPrAsn1Decoder_init();
132
133
1.43k
    WinPrAsn1Decoder_InitMem(&decoder, WINPR_ASN1_DER, data, size);
134
1.43k
    if (WinPrAsn1DecReadSequence(&decoder, &sequence))
135
254
      fuzz_walk_sequence(&sequence, 1);
136
1.43k
  }
137
138
1.43k
  return 0;
139
1.43k
}