Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : util_asn1 testing
5 :
6 : Copyright (C) Kamen Mazdrashki <kamen.mazdrashki@postpath.com> 2009
7 : Copyright (C) Volker Lendecke 2004
8 : Copyright (C) Andrew Bartlett 2011
9 :
10 : This program is free software; you can redistribute it and/or modify
11 : it under the terms of the GNU General Public License as published by
12 : the Free Software Foundation; either version 3 of the License, or
13 : (at your option) any later version.
14 :
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with this program. If not, see <http://www.gnu.org/licenses/>.
22 : */
23 :
24 : #include "includes.h"
25 : #include "torture/torture.h"
26 : #include "torture/local/proto.h"
27 : #include "../asn1.h"
28 :
29 : struct oid_data {
30 : const char *oid; /* String OID */
31 : const char *bin_oid; /* Binary OID represented as string */
32 : };
33 :
34 : /* Data for successful OIDs conversions */
35 : static const struct oid_data oid_data_ok[] = {
36 : {
37 : .oid = "2.5.4.0",
38 : .bin_oid = "550400"
39 : },
40 : {
41 : .oid = "2.5.4.1",
42 : .bin_oid = "550401"
43 : },
44 : {
45 : .oid = "2.5.4.130",
46 : .bin_oid = "55048102"
47 : },
48 : {
49 : .oid = "2.5.130.4",
50 : .bin_oid = "55810204"
51 : },
52 : {
53 : .oid = "2.5.4.16387",
54 : .bin_oid = "5504818003"
55 : },
56 : {
57 : .oid = "2.5.16387.4",
58 : .bin_oid = "5581800304"
59 : },
60 : {
61 : .oid = "2.5.2097155.4",
62 : .bin_oid = "558180800304"
63 : },
64 : {
65 : .oid = "2.5.4.130.16387.2097155.268435459",
66 : .bin_oid = "55048102818003818080038180808003"
67 : },
68 : };
69 :
70 : /* Data for successful OIDs conversions */
71 : static const char *oid_data_err[] = {
72 : "", /* empty OID */
73 : ".2.5.4.130", /* first sub-identifier is empty */
74 : "2.5.4.130.", /* last sub-identifier is empty */
75 : "2..5.4.130", /* second sub-identifier is empty */
76 : "2.5..4.130", /* third sub-identifier is empty */
77 : "2.abc.4.130", /* invalid sub-identifier */
78 : "2.5abc.4.130", /* invalid sub-identifier (alphanumeric)*/
79 : };
80 :
81 : /* Data for successful Partial OIDs conversions */
82 : static const struct oid_data partial_oid_data_ok[] = {
83 : {
84 : .oid = "2.5.4.130:0x81",
85 : .bin_oid = "5504810281"
86 : },
87 : {
88 : .oid = "2.5.4.16387:0x8180",
89 : .bin_oid = "55048180038180"
90 : },
91 : {
92 : .oid = "2.5.4.16387:0x81",
93 : .bin_oid = "550481800381"
94 : },
95 : {
96 : .oid = "2.5.2097155.4:0x818080",
97 : .bin_oid = "558180800304818080"
98 : },
99 : {
100 : .oid = "2.5.2097155.4:0x8180",
101 : .bin_oid = "5581808003048180"
102 : },
103 : {
104 : .oid = "2.5.2097155.4:0x81",
105 : .bin_oid = "55818080030481"
106 : },
107 : };
108 :
109 : static const struct {
110 : DATA_BLOB blob;
111 : int value;
112 : } integer_tests[] = {
113 : {
114 : .blob = { discard_const_p(uint8_t, "\x02\x01\x00"), 3},
115 : .value = 0
116 : },
117 : {
118 : .blob = { discard_const_p(uint8_t, "\x02\x01\x7f"), 3},
119 : .value = 127
120 : },
121 : {
122 : .blob = { discard_const_p(uint8_t, "\x02\x02\x00\x80"), 4},
123 : .value = 128
124 : },
125 : {
126 : .blob = { discard_const_p(uint8_t, "\x02\x02\x01\x00"), 4},
127 : .value = 256
128 : },
129 : {
130 : .blob = { discard_const_p(uint8_t, "\x02\x01\x80"), 3},
131 : .value = -128
132 : },
133 : {
134 : .blob = { discard_const_p(uint8_t, "\x02\x02\xff\x7f"), 4},
135 : .value = -129
136 : },
137 : {
138 : .blob = { discard_const_p(uint8_t, "\x02\x01\xff"), 3},
139 : .value = -1
140 : },
141 : {
142 : .blob = { discard_const_p(uint8_t, "\x02\x02\xff\x01"), 4},
143 : .value = -255
144 : },
145 : {
146 : .blob = { discard_const_p(uint8_t, "\x02\x02\x00\xff"), 4},
147 : .value = 255
148 : },
149 : {
150 : .blob = { discard_const_p(uint8_t, "\x02\x04\x80\x00\x00\x00"), 6},
151 : .value = 0x80000000
152 : },
153 : {
154 : .blob = { discard_const_p(uint8_t, "\x02\x04\x7f\xff\xff\xff"), 6},
155 : .value = 0x7fffffff
156 : }
157 : };
158 :
159 : /* Testing ber_write_OID_String() function */
160 1 : static bool test_ber_write_OID_String(struct torture_context *tctx)
161 : {
162 1 : int i;
163 1 : char *hex_str;
164 1 : DATA_BLOB blob;
165 1 : TALLOC_CTX *mem_ctx;
166 1 : const struct oid_data *data = oid_data_ok;
167 :
168 1 : mem_ctx = talloc_new(tctx);
169 :
170 : /* check for valid OIDs */
171 10 : for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
172 8 : torture_assert(tctx, ber_write_OID_String(mem_ctx, &blob, data[i].oid),
173 : "ber_write_OID_String failed");
174 :
175 8 : hex_str = hex_encode_talloc(mem_ctx, blob.data, blob.length);
176 8 : torture_assert(tctx, hex_str, "No memory!");
177 :
178 8 : torture_assert(tctx, strequal(data[i].bin_oid, hex_str),
179 : talloc_asprintf(mem_ctx,
180 : "Failed: oid=%s, bin_oid:%s",
181 : data[i].oid, data[i].bin_oid));
182 : }
183 :
184 : /* check for invalid OIDs */
185 8 : for (i = 0; i < ARRAY_SIZE(oid_data_err); i++) {
186 7 : torture_assert(tctx,
187 : !ber_write_OID_String(mem_ctx, &blob, oid_data_err[i]),
188 : talloc_asprintf(mem_ctx,
189 : "Should fail for [%s] -> %s",
190 : oid_data_err[i],
191 : hex_encode_talloc(mem_ctx, blob.data, blob.length)));
192 : }
193 :
194 1 : talloc_free(mem_ctx);
195 :
196 1 : return true;
197 : }
198 :
199 : /* Testing ber_read_OID_String() function */
200 1 : static bool test_ber_read_OID_String(struct torture_context *tctx)
201 : {
202 1 : int i;
203 1 : char *oid;
204 1 : DATA_BLOB oid_blob;
205 1 : TALLOC_CTX *mem_ctx;
206 1 : const struct oid_data *data = oid_data_ok;
207 :
208 1 : mem_ctx = talloc_new(tctx);
209 :
210 10 : for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
211 8 : oid_blob = strhex_to_data_blob(mem_ctx, data[i].bin_oid);
212 :
213 8 : torture_assert(tctx, ber_read_OID_String(mem_ctx, oid_blob, &oid),
214 : "ber_read_OID_String failed");
215 :
216 8 : torture_assert(tctx, strequal(data[i].oid, oid),
217 : talloc_asprintf(mem_ctx,
218 : "Failed: oid=%s, bin_oid:%s",
219 : data[i].oid, data[i].bin_oid));
220 : }
221 :
222 1 : talloc_free(mem_ctx);
223 :
224 1 : return true;
225 : }
226 :
227 : /* Testing ber_write_partial_OID_String() function */
228 1 : static bool test_ber_write_partial_OID_String(struct torture_context *tctx)
229 : {
230 1 : int i;
231 1 : char *hex_str;
232 1 : DATA_BLOB blob;
233 1 : TALLOC_CTX *mem_ctx;
234 1 : const struct oid_data *data = oid_data_ok;
235 :
236 1 : mem_ctx = talloc_new(tctx);
237 :
238 : /* ber_write_partial_OID_String() should work with not partial OIDs also */
239 10 : for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
240 8 : torture_assert(tctx, ber_write_partial_OID_String(mem_ctx, &blob, data[i].oid),
241 : "ber_write_partial_OID_String failed");
242 :
243 8 : hex_str = hex_encode_talloc(mem_ctx, blob.data, blob.length);
244 8 : torture_assert(tctx, hex_str, "No memory!");
245 :
246 8 : torture_assert(tctx, strequal(data[i].bin_oid, hex_str),
247 : talloc_asprintf(mem_ctx,
248 : "Failed: oid=%s, bin_oid:%s",
249 : data[i].oid, data[i].bin_oid));
250 : }
251 :
252 : /* ber_write_partial_OID_String() test with partial OIDs */
253 7 : data = partial_oid_data_ok;
254 7 : for (i = 0; i < ARRAY_SIZE(partial_oid_data_ok); i++) {
255 6 : torture_assert(tctx, ber_write_partial_OID_String(mem_ctx, &blob, data[i].oid),
256 : "ber_write_partial_OID_String failed");
257 :
258 6 : hex_str = hex_encode_talloc(mem_ctx, blob.data, blob.length);
259 6 : torture_assert(tctx, hex_str, "No memory!");
260 :
261 6 : torture_assert(tctx, strequal(data[i].bin_oid, hex_str),
262 : talloc_asprintf(mem_ctx,
263 : "Failed: oid=%s, bin_oid:%s",
264 : data[i].oid, data[i].bin_oid));
265 : }
266 :
267 1 : talloc_free(mem_ctx);
268 :
269 1 : return true;
270 : }
271 :
272 : /* Testing ber_read_partial_OID_String() function */
273 1 : static bool test_ber_read_partial_OID_String(struct torture_context *tctx)
274 : {
275 1 : int i;
276 1 : char *oid;
277 1 : DATA_BLOB oid_blob;
278 1 : TALLOC_CTX *mem_ctx;
279 1 : const struct oid_data *data = oid_data_ok;
280 :
281 1 : mem_ctx = talloc_new(tctx);
282 :
283 : /* ber_read_partial_OID_String() should work with not partial OIDs also */
284 10 : for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
285 8 : oid_blob = strhex_to_data_blob(mem_ctx, data[i].bin_oid);
286 :
287 8 : torture_assert(tctx, ber_read_partial_OID_String(mem_ctx, oid_blob, &oid),
288 : "ber_read_partial_OID_String failed");
289 :
290 8 : torture_assert(tctx, strequal(data[i].oid, oid),
291 : talloc_asprintf(mem_ctx,
292 : "Failed: oid=%s, bin_oid:%s",
293 : data[i].oid, data[i].bin_oid));
294 : }
295 :
296 : /* ber_read_partial_OID_String() test with partial OIDs */
297 7 : data = partial_oid_data_ok;
298 7 : for (i = 0; i < ARRAY_SIZE(partial_oid_data_ok); i++) {
299 6 : oid_blob = strhex_to_data_blob(mem_ctx, data[i].bin_oid);
300 :
301 6 : torture_assert(tctx, ber_read_partial_OID_String(mem_ctx, oid_blob, &oid),
302 : "ber_read_partial_OID_String failed");
303 :
304 6 : torture_assert(tctx, strequal(data[i].oid, oid),
305 : talloc_asprintf(mem_ctx,
306 : "Failed: oid=%s, bin_oid:%s",
307 : data[i].oid, data[i].bin_oid));
308 : }
309 :
310 1 : talloc_free(mem_ctx);
311 :
312 1 : return true;
313 : }
314 :
315 : /*
316 : * Testing asn1_read_Integer and asn1_write_Integer functions,
317 : * inspired by Love Hornquist Astrand
318 : */
319 :
320 1 : static bool test_asn1_Integer(struct torture_context *tctx)
321 : {
322 1 : int i;
323 1 : TALLOC_CTX *mem_ctx;
324 1 : bool ret = false;
325 :
326 1 : mem_ctx = talloc_new(tctx);
327 :
328 13 : for (i = 0; i < ARRAY_SIZE(integer_tests); i++) {
329 11 : ASN1_DATA *data;
330 11 : DATA_BLOB blob;
331 11 : int val;
332 :
333 11 : data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
334 11 : if (!data) {
335 0 : goto err;
336 : }
337 :
338 11 : if (!asn1_write_Integer(data, integer_tests[i].value)) goto err;
339 :
340 11 : if (!asn1_blob(data, &blob)) {
341 0 : goto err;
342 : }
343 :
344 11 : torture_assert_data_blob_equal(tctx, blob, integer_tests[i].blob, "asn1_write_Integer gave incorrect result");
345 :
346 11 : if (!asn1_load(data, blob)) goto err;
347 11 : torture_assert(tctx, asn1_read_Integer(data, &val), "asn1_write_Integer output could not be read by asn1_read_Integer()");
348 :
349 11 : torture_assert_int_equal(tctx, val, integer_tests[i].value,
350 : "readback of asn1_write_Integer output by asn1_read_Integer() failed");
351 : }
352 :
353 0 : ret = true;
354 :
355 1 : err:
356 :
357 1 : talloc_free(mem_ctx);
358 1 : return ret;
359 : }
360 :
361 :
362 : /* LOCAL-ASN1 test suite creation */
363 2354 : struct torture_suite *torture_local_util_asn1(TALLOC_CTX *mem_ctx)
364 : {
365 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "asn1");
366 :
367 2354 : torture_suite_add_simple_test(suite, "ber_write_OID_String",
368 : test_ber_write_OID_String);
369 :
370 2354 : torture_suite_add_simple_test(suite, "ber_read_OID_String",
371 : test_ber_read_OID_String);
372 :
373 2354 : torture_suite_add_simple_test(suite, "ber_write_partial_OID_String",
374 : test_ber_write_partial_OID_String);
375 :
376 2354 : torture_suite_add_simple_test(suite, "ber_read_partial_OID_String",
377 : test_ber_read_partial_OID_String);
378 :
379 2354 : torture_suite_add_simple_test(suite, "asn1_Integer",
380 : test_asn1_Integer);
381 :
382 2354 : return suite;
383 : }
|