/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 | 90.0k | { |
17 | 90.0k | WinPrAsn1Decoder inner = WinPrAsn1Decoder_init(); |
18 | 90.0k | WinPrAsn1_tag tag = 0; |
19 | 90.0k | size_t len = 0; |
20 | | |
21 | 90.0k | if (depth > 6) |
22 | 0 | return; |
23 | | |
24 | 90.0k | if (WinPrAsn1DecReadTagLenValue(decoder, &tag, &len, &inner) == 0) |
25 | 56.7k | return; |
26 | | |
27 | 33.2k | switch (tag & ER_TAG_MASK) |
28 | 33.2k | { |
29 | 4.11k | case ER_TAG_BOOLEAN: |
30 | 4.11k | { |
31 | 4.11k | WinPrAsn1_BOOL value = 0; |
32 | 4.11k | (void)WinPrAsn1DecReadBoolean(&inner, &value); |
33 | 4.11k | break; |
34 | 0 | } |
35 | 3.23k | case ER_TAG_INTEGER: |
36 | 3.23k | { |
37 | 3.23k | WinPrAsn1_INTEGER value = 0; |
38 | 3.23k | (void)WinPrAsn1DecReadInteger(&inner, &value); |
39 | 3.23k | break; |
40 | 0 | } |
41 | 1.76k | case ER_TAG_OCTET_STRING: |
42 | 1.76k | { |
43 | 1.76k | WinPrAsn1_OctetString value = WINPR_C_ARRAY_INIT; |
44 | 1.76k | if (WinPrAsn1DecReadOctetString(&inner, &value, TRUE)) |
45 | 253 | WinPrAsn1FreeOctetString(&value); |
46 | 1.76k | 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 | 332 | WinPrAsn1FreeOID(&value); |
53 | 1.09k | break; |
54 | 0 | } |
55 | 827 | case ER_TAG_ENUMERATED: |
56 | 827 | { |
57 | 827 | WinPrAsn1_ENUMERATED value = 0; |
58 | 827 | (void)WinPrAsn1DecReadEnumerated(&inner, &value); |
59 | 827 | break; |
60 | 0 | } |
61 | 3.26k | case ER_TAG_UTCTIME: |
62 | 3.26k | { |
63 | 3.26k | WinPrAsn1_UTCTIME value = WINPR_C_ARRAY_INIT; |
64 | 3.26k | (void)WinPrAsn1DecReadUtcTime(&inner, &value); |
65 | 3.26k | break; |
66 | 0 | } |
67 | 1.23k | case ER_TAG_IA5STRING: |
68 | 1.23k | { |
69 | 1.23k | WinPrAsn1_IA5STRING value = nullptr; |
70 | 1.23k | (void)WinPrAsn1DecReadIA5String(&inner, &value); |
71 | 1.23k | free(value); |
72 | 1.23k | break; |
73 | 0 | } |
74 | 1.24k | case ER_TAG_NULL: |
75 | 1.24k | (void)WinPrAsn1DecReadNull(&inner); |
76 | 1.24k | break; |
77 | 16.5k | default: |
78 | 16.5k | break; |
79 | 33.2k | } |
80 | | |
81 | 33.2k | if ((tag == ER_TAG_SEQUENCE) || (tag == ER_TAG_SET)) |
82 | 1.86k | fuzz_walk_sequence(&inner, depth + 1); |
83 | 31.4k | else if ((tag & 0xC0) == 0x80) |
84 | 9.36k | fuzz_walk_sequence(&inner, depth + 1); |
85 | 33.2k | } |
86 | | |
87 | | static void fuzz_walk_sequence(WinPrAsn1Decoder* outer, int depth) |
88 | 14.3k | { |
89 | 14.3k | if (depth > 6) |
90 | 218 | return; |
91 | | |
92 | 104k | for (size_t index = 0; index < 64; index++) |
93 | 103k | { |
94 | 103k | WinPrAsn1_tag tag = 0; |
95 | | |
96 | 103k | if (!WinPrAsn1DecPeekTag(outer, &tag)) |
97 | 13.8k | return; |
98 | | |
99 | 90.0k | fuzz_consume_one(outer, depth); |
100 | 90.0k | } |
101 | 14.1k | } |
102 | | |
103 | | int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) |
104 | 1.45k | { |
105 | 1.45k | static BOOL loggingInitialized = FALSE; |
106 | | |
107 | 1.45k | if (!loggingInitialized) |
108 | 1 | { |
109 | 1 | (void)WLog_SetLogLevel(WLog_GetRoot(), WLOG_TRACE); |
110 | 1 | loggingInitialized = TRUE; |
111 | 1 | } |
112 | | |
113 | 1.45k | if ((size == 0) || (size > (1u << 20))) |
114 | 0 | return 0; |
115 | | |
116 | 1.45k | { |
117 | 1.45k | WinPrAsn1Decoder decoder = WinPrAsn1Decoder_init(); |
118 | 1.45k | WinPrAsn1Decoder_InitMem(&decoder, WINPR_ASN1_DER, data, size); |
119 | 1.45k | fuzz_walk_sequence(&decoder, 0); |
120 | 1.45k | } |
121 | | |
122 | 1.45k | { |
123 | 1.45k | WinPrAsn1Decoder decoder = WinPrAsn1Decoder_init(); |
124 | 1.45k | WinPrAsn1Decoder_InitMem(&decoder, WINPR_ASN1_BER, data, size); |
125 | 1.45k | fuzz_walk_sequence(&decoder, 0); |
126 | 1.45k | } |
127 | | |
128 | 1.45k | { |
129 | 1.45k | WinPrAsn1Decoder decoder = WinPrAsn1Decoder_init(); |
130 | 1.45k | WinPrAsn1Decoder sequence = WinPrAsn1Decoder_init(); |
131 | | |
132 | 1.45k | WinPrAsn1Decoder_InitMem(&decoder, WINPR_ASN1_DER, data, size); |
133 | 1.45k | if (WinPrAsn1DecReadSequence(&decoder, &sequence)) |
134 | 200 | fuzz_walk_sequence(&sequence, 1); |
135 | 1.45k | } |
136 | | |
137 | 1.45k | return 0; |
138 | 1.45k | } |