]>
Commit | Line | Data |
---|---|---|
3d7f83eb HL |
1 | /* |
2 | * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. | |
3 | * | |
4 | * Licensed under the Apache License 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at | |
7 | * https://www.openssl.org/source/license.html | |
8 | * or in the file LICENSE in the source distribution. | |
9 | */ | |
10 | ||
11 | #include <openssl/ssl.h> | |
12 | #include <openssl/err.h> | |
13 | #include <openssl/bio.h> | |
14 | #include "fuzzer.h" | |
15 | #include "internal/quic_lcidm.h" | |
16 | #include "internal/packet.h" | |
17 | ||
18 | int FuzzerInitialize(int *argc, char ***argv) | |
19 | { | |
20 | FuzzerSetRand(); | |
21 | OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS | OPENSSL_INIT_ASYNC, NULL); | |
22 | OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); | |
23 | ERR_clear_error(); | |
24 | return 1; | |
25 | } | |
26 | ||
27 | /* | |
28 | * Fuzzer input "protocol": | |
29 | * Big endian | |
30 | * u8(LCID length) | |
31 | * Zero or more of: | |
32 | * ENROL_ODCID u0(0x00) u64(opaque) u8(cidl):cid | |
33 | * RETIRE_ODCID u8(0x01) u64(opaque) | |
34 | * GENERATE_INITIAL u8(0x02) u64(opaque) | |
35 | * GENERATE u8(0x03) u64(opaque) | |
36 | * RETIRE u8(0x04) u64(opaque) u64(retire_prior_to) | |
37 | * CULL u8(0x05) u64(opaque) | |
38 | * LOOKUP u8(0x06) u8(cidl):cid | |
39 | */ | |
40 | ||
41 | enum { | |
42 | CMD_ENROL_ODCID, | |
43 | CMD_RETIRE_ODCID, | |
44 | CMD_GENERATE_INITIAL, | |
45 | CMD_GENERATE, | |
46 | CMD_RETIRE, | |
47 | CMD_CULL, | |
48 | CMD_LOOKUP | |
49 | }; | |
50 | ||
51 | static int get_cid(PACKET *pkt, QUIC_CONN_ID *cid) | |
52 | { | |
53 | unsigned int cidl; | |
54 | ||
55 | if (!PACKET_get_1(pkt, &cidl) | |
56 | || cidl > QUIC_MAX_CONN_ID_LEN | |
57 | || !PACKET_copy_bytes(pkt, cid->id, cidl)) | |
58 | return 0; | |
59 | ||
60 | cid->id_len = (unsigned char)cidl; | |
61 | return 1; | |
62 | } | |
63 | ||
64 | int FuzzerTestOneInput(const uint8_t *buf, size_t len) | |
65 | { | |
66 | int rc = 0; | |
67 | QUIC_LCIDM *lcidm = NULL; | |
68 | PACKET pkt; | |
69 | uint64_t arg_opaque, arg_retire_prior_to, seq_num_out; | |
70 | unsigned int cmd, lcidl; | |
71 | QUIC_CONN_ID arg_cid, cid_out; | |
72 | OSSL_QUIC_FRAME_NEW_CONN_ID ncid_frame; | |
73 | int did_retire; | |
74 | void *opaque_out; | |
75 | ||
76 | if (!PACKET_buf_init(&pkt, buf, len)) | |
77 | goto err; | |
78 | ||
79 | if (!PACKET_get_1(&pkt, &lcidl) | |
80 | || lcidl > QUIC_MAX_CONN_ID_LEN) { | |
81 | rc = -1; | |
82 | goto err; | |
83 | } | |
84 | ||
85 | if ((lcidm = ossl_quic_lcidm_new(NULL, lcidl)) == NULL) { | |
86 | rc = -1; | |
87 | goto err; | |
88 | } | |
89 | ||
90 | while (PACKET_remaining(&pkt) > 0) { | |
91 | if (!PACKET_get_1(&pkt, &cmd)) | |
92 | goto err; | |
93 | ||
94 | switch (cmd) { | |
95 | case CMD_ENROL_ODCID: | |
96 | if (!PACKET_get_net_8(&pkt, &arg_opaque) | |
97 | || !get_cid(&pkt, &arg_cid)) { | |
98 | rc = -1; | |
99 | goto err; | |
100 | } | |
101 | ||
102 | ossl_quic_lcidm_enrol_odcid(lcidm, (void *)(uintptr_t)arg_opaque, | |
103 | &arg_cid); | |
104 | break; | |
105 | ||
106 | case CMD_RETIRE_ODCID: | |
107 | if (!PACKET_get_net_8(&pkt, &arg_opaque)) { | |
108 | rc = -1; | |
109 | goto err; | |
110 | } | |
111 | ||
112 | ossl_quic_lcidm_retire_odcid(lcidm, (void *)(uintptr_t)arg_opaque); | |
113 | break; | |
114 | ||
115 | case CMD_GENERATE_INITIAL: | |
116 | if (!PACKET_get_net_8(&pkt, &arg_opaque)) { | |
117 | rc = -1; | |
118 | goto err; | |
119 | } | |
120 | ||
121 | ossl_quic_lcidm_generate_initial(lcidm, (void *)(uintptr_t)arg_opaque, | |
122 | &cid_out); | |
123 | break; | |
124 | ||
125 | case CMD_GENERATE: | |
126 | if (!PACKET_get_net_8(&pkt, &arg_opaque)) { | |
127 | rc = -1; | |
128 | goto err; | |
129 | } | |
130 | ||
131 | ossl_quic_lcidm_generate(lcidm, (void *)(uintptr_t)arg_opaque, | |
132 | &ncid_frame); | |
133 | break; | |
134 | ||
135 | case CMD_RETIRE: | |
136 | if (!PACKET_get_net_8(&pkt, &arg_opaque) | |
137 | || !PACKET_get_net_8(&pkt, &arg_retire_prior_to)) { | |
138 | rc = -1; | |
139 | goto err; | |
140 | } | |
141 | ||
142 | ossl_quic_lcidm_retire(lcidm, (void *)(uintptr_t)arg_opaque, | |
143 | arg_retire_prior_to, | |
144 | NULL, &cid_out, | |
145 | &seq_num_out, &did_retire); | |
146 | break; | |
147 | ||
148 | case CMD_CULL: | |
149 | if (!PACKET_get_net_8(&pkt, &arg_opaque)) { | |
150 | rc = -1; | |
151 | goto err; | |
152 | } | |
153 | ||
154 | ossl_quic_lcidm_cull(lcidm, (void *)(uintptr_t)arg_opaque); | |
155 | break; | |
156 | ||
157 | case CMD_LOOKUP: | |
158 | if (!get_cid(&pkt, &arg_cid)) { | |
159 | rc = -1; | |
160 | goto err; | |
161 | } | |
162 | ||
163 | ossl_quic_lcidm_lookup(lcidm, &arg_cid, &seq_num_out, &opaque_out); | |
164 | break; | |
165 | ||
166 | default: | |
167 | rc = -1; | |
168 | goto err; | |
169 | } | |
170 | } | |
171 | ||
172 | err: | |
173 | ossl_quic_lcidm_free(lcidm); | |
174 | return rc; | |
175 | } | |
176 | ||
177 | void FuzzerCleanup(void) | |
178 | { | |
179 | FuzzerClearRand(); | |
180 | } |