3ee64c3f7a88336e292662150d8fe94bd5c03920
[metze/samba/wip.git] / lib / util / tests / asn1_tests.c
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 "../asn1.h"
27
28 struct oid_data {
29         const char *oid;        /* String OID */
30         const char *bin_oid;    /* Binary OID represented as string */
31 };
32
33 /* Data for successful OIDs conversions */
34 static const struct oid_data oid_data_ok[] = {
35         {
36                 .oid = "2.5.4.0",
37                 .bin_oid = "550400"
38         },
39         {
40                 .oid = "2.5.4.1",
41                 .bin_oid = "550401"
42         },
43         {
44                 .oid = "2.5.4.130",
45                 .bin_oid = "55048102"
46         },
47         {
48                 .oid = "2.5.130.4",
49                 .bin_oid = "55810204"
50         },
51         {
52                 .oid = "2.5.4.16387",
53                 .bin_oid = "5504818003"
54         },
55         {
56                 .oid = "2.5.16387.4",
57                 .bin_oid = "5581800304"
58         },
59         {
60                 .oid = "2.5.2097155.4",
61                 .bin_oid = "558180800304"
62         },
63         {
64                 .oid = "2.5.4.130.16387.2097155.268435459",
65                 .bin_oid = "55048102818003818080038180808003"
66         },
67 };
68
69 /* Data for successful OIDs conversions */
70 static const char *oid_data_err[] = {
71                 "",             /* empty OID */
72                 ".2.5.4.130",   /* first sub-identifier is empty */
73                 "2.5.4.130.",   /* last sub-identifier is empty */
74                 "2..5.4.130",   /* second sub-identifier is empty */
75                 "2.5..4.130",   /* third sub-identifier is empty */
76                 "2.abc.4.130",  /* invalid sub-identifier */
77                 "2.5abc.4.130", /* invalid sub-identifier (alpha-numeric)*/
78 };
79
80 /* Data for successful Partial OIDs conversions */
81 static const struct oid_data partial_oid_data_ok[] = {
82         {
83                 .oid = "2.5.4.130:0x81",
84                 .bin_oid = "5504810281"
85         },
86         {
87                 .oid = "2.5.4.16387:0x8180",
88                 .bin_oid = "55048180038180"
89         },
90         {
91                 .oid = "2.5.4.16387:0x81",
92                 .bin_oid = "550481800381"
93         },
94         {
95                 .oid = "2.5.2097155.4:0x818080",
96                 .bin_oid = "558180800304818080"
97         },
98         {
99                 .oid = "2.5.2097155.4:0x8180",
100                 .bin_oid = "5581808003048180"
101         },
102         {
103                 .oid = "2.5.2097155.4:0x81",
104                 .bin_oid = "55818080030481"
105         },
106 };
107
108 static const struct {
109         DATA_BLOB blob;
110         int value;
111 } integer_tests[] = {
112         {
113                 .blob = {"\x02\x01\x00", 3},
114                 .value = 0
115         },
116         {
117                 .blob = {"\x02\x01\x7f", 3},
118                 .value = 127
119         },
120         {
121                 .blob = {"\x02\x02\x00\x80", 4},
122                 .value = 128
123         },
124         {
125                 .blob = {"\x02\x02\x01\x00", 4},
126                 .value = 256
127         },
128         {
129                 .blob = {"\x02\x01\x80", 3},
130                 .value = -128
131         },
132         {
133                 .blob = {"\x02\x02\xff\x7f", 4},
134                 .value = -129
135         },
136         {
137                 .blob = {"\x02\x01\xff", 3},
138                 .value = -1
139         },
140         {
141                 .blob = {"\x02\x02\xff\x01", 4},
142                 .value = -255
143         },
144         {
145                 .blob = {"\x02\x02\x00\xff", 4},
146                 .value = 255
147         },
148         {
149                 .blob = {"\x02\x04\x80\x00\x00\x00", 6},
150                 .value = 0x80000000
151         },
152         {
153                 .blob = {"\x02\x04\x7f\xff\xff\xff", 6},
154                 .value = 0x7fffffff
155         }
156 };
157
158 /* Testing ber_write_OID_String() function */
159 static bool test_ber_write_OID_String(struct torture_context *tctx)
160 {
161         int i;
162         char *hex_str;
163         DATA_BLOB blob;
164         TALLOC_CTX *mem_ctx;
165         const struct oid_data *data = oid_data_ok;
166
167         mem_ctx = talloc_new(tctx);
168
169         /* check for valid OIDs */
170         for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
171                 torture_assert(tctx, ber_write_OID_String(mem_ctx, &blob, data[i].oid),
172                                 "ber_write_OID_String failed");
173
174                 hex_str = hex_encode_talloc(mem_ctx, blob.data, blob.length);
175                 torture_assert(tctx, hex_str, "No memory!");
176
177                 torture_assert(tctx, strequal(data[i].bin_oid, hex_str),
178                                 talloc_asprintf(mem_ctx,
179                                                 "Failed: oid=%s, bin_oid:%s",
180                                                 data[i].oid, data[i].bin_oid));
181         }
182
183         /* check for invalid OIDs */
184         for (i = 0; i < ARRAY_SIZE(oid_data_err); i++) {
185                 torture_assert(tctx,
186                                !ber_write_OID_String(mem_ctx, &blob, oid_data_err[i]),
187                                talloc_asprintf(mem_ctx,
188                                                "Should fail for [%s] -> %s",
189                                                oid_data_err[i],
190                                                hex_encode_talloc(mem_ctx, blob.data, blob.length)));
191         }
192
193         talloc_free(mem_ctx);
194
195         return true;
196 }
197
198 /* Testing ber_read_OID_String() function */
199 static bool test_ber_read_OID_String(struct torture_context *tctx)
200 {
201         int i;
202         char *oid;
203         DATA_BLOB oid_blob;
204         TALLOC_CTX *mem_ctx;
205         const struct oid_data *data = oid_data_ok;
206
207         mem_ctx = talloc_new(tctx);
208
209         for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
210                 oid_blob = strhex_to_data_blob(mem_ctx, data[i].bin_oid);
211
212                 torture_assert(tctx, ber_read_OID_String(mem_ctx, oid_blob, &oid),
213                                 "ber_read_OID_String failed");
214
215                 torture_assert(tctx, strequal(data[i].oid, oid),
216                                 talloc_asprintf(mem_ctx,
217                                                 "Failed: oid=%s, bin_oid:%s",
218                                                 data[i].oid, data[i].bin_oid));
219         }
220
221         talloc_free(mem_ctx);
222
223         return true;
224 }
225
226 /* Testing ber_write_partial_OID_String() function */
227 static bool test_ber_write_partial_OID_String(struct torture_context *tctx)
228 {
229         int i;
230         char *hex_str;
231         DATA_BLOB blob;
232         TALLOC_CTX *mem_ctx;
233         const struct oid_data *data = oid_data_ok;
234
235         mem_ctx = talloc_new(tctx);
236
237         /* ber_write_partial_OID_String() should work with not partial OIDs also */
238         for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
239                 torture_assert(tctx, ber_write_partial_OID_String(mem_ctx, &blob, data[i].oid),
240                                 "ber_write_partial_OID_String failed");
241
242                 hex_str = hex_encode_talloc(mem_ctx, blob.data, blob.length);
243                 torture_assert(tctx, hex_str, "No memory!");
244
245                 torture_assert(tctx, strequal(data[i].bin_oid, hex_str),
246                                 talloc_asprintf(mem_ctx,
247                                                 "Failed: oid=%s, bin_oid:%s",
248                                                 data[i].oid, data[i].bin_oid));
249         }
250
251         /* ber_write_partial_OID_String() test with partial OIDs */
252         data = partial_oid_data_ok;
253         for (i = 0; i < ARRAY_SIZE(partial_oid_data_ok); i++) {
254                 torture_assert(tctx, ber_write_partial_OID_String(mem_ctx, &blob, data[i].oid),
255                                 "ber_write_partial_OID_String failed");
256
257                 hex_str = hex_encode_talloc(mem_ctx, blob.data, blob.length);
258                 torture_assert(tctx, hex_str, "No memory!");
259
260                 torture_assert(tctx, strequal(data[i].bin_oid, hex_str),
261                                 talloc_asprintf(mem_ctx,
262                                                 "Failed: oid=%s, bin_oid:%s",
263                                                 data[i].oid, data[i].bin_oid));
264         }
265
266         talloc_free(mem_ctx);
267
268         return true;
269 }
270
271 /* Testing ber_read_partial_OID_String() function */
272 static bool test_ber_read_partial_OID_String(struct torture_context *tctx)
273 {
274         int i;
275         char *oid;
276         DATA_BLOB oid_blob;
277         TALLOC_CTX *mem_ctx;
278         const struct oid_data *data = oid_data_ok;
279
280         mem_ctx = talloc_new(tctx);
281
282         /* ber_read_partial_OID_String() should work with not partial OIDs also */
283         for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
284                 oid_blob = strhex_to_data_blob(mem_ctx, data[i].bin_oid);
285
286                 torture_assert(tctx, ber_read_partial_OID_String(mem_ctx, oid_blob, &oid),
287                                 "ber_read_partial_OID_String failed");
288
289                 torture_assert(tctx, strequal(data[i].oid, oid),
290                                 talloc_asprintf(mem_ctx,
291                                                 "Failed: oid=%s, bin_oid:%s",
292                                                 data[i].oid, data[i].bin_oid));
293         }
294
295         /* ber_read_partial_OID_String() test with partial OIDs */
296         data = partial_oid_data_ok;
297         for (i = 0; i < ARRAY_SIZE(partial_oid_data_ok); i++) {
298                 oid_blob = strhex_to_data_blob(mem_ctx, data[i].bin_oid);
299
300                 torture_assert(tctx, ber_read_partial_OID_String(mem_ctx, oid_blob, &oid),
301                                 "ber_read_partial_OID_String failed");
302
303                 torture_assert(tctx, strequal(data[i].oid, oid),
304                                 talloc_asprintf(mem_ctx,
305                                                 "Failed: oid=%s, bin_oid:%s",
306                                                 data[i].oid, data[i].bin_oid));
307         }
308
309         talloc_free(mem_ctx);
310
311         return true;
312 }
313
314 /*
315  * Testing asn1_read_Integer and asn1_write_Integer functions,
316  * inspired by Love Hornquist Astrand
317  */
318
319 static bool test_asn1_Integer(struct torture_context *tctx)
320 {
321         int i;
322         TALLOC_CTX *mem_ctx;
323
324         mem_ctx = talloc_new(tctx);
325
326         for (i = 0; i < ARRAY_SIZE(integer_tests); i++) {
327                 ASN1_DATA *data;
328                 DATA_BLOB blob;
329                 int val;
330
331                 data = asn1_init(mem_ctx);
332                 if (!data) {
333                         return -1;
334                 }
335
336                 asn1_write_Integer(data, integer_tests[i].value);
337
338                 blob.data = data->data;
339                 blob.length = data->length;
340                 torture_assert_data_blob_equal(tctx, blob, integer_tests[i].blob, "asn1_write_Integer gave incorrect result");
341
342                 asn1_load(data, blob);
343                 torture_assert(tctx, asn1_read_Integer(data, &val), "asn1_write_Integer output could not be read by asn1_read_Integer()");
344
345                 torture_assert_int_equal(tctx, val, integer_tests[i].value,
346                         "readback of asn1_write_Integer output by asn1_read_Integer() failed");
347         }
348
349         talloc_free(mem_ctx);
350
351         return true;
352 }
353
354
355 /* LOCAL-ASN1 test suite creation */
356 struct torture_suite *torture_local_util_asn1(TALLOC_CTX *mem_ctx)
357 {
358         struct torture_suite *suite = torture_suite_create(mem_ctx, "asn1");
359
360         torture_suite_add_simple_test(suite, "ber_write_OID_String",
361                                       test_ber_write_OID_String);
362
363         torture_suite_add_simple_test(suite, "ber_read_OID_String",
364                                       test_ber_read_OID_String);
365
366         torture_suite_add_simple_test(suite, "ber_write_partial_OID_String",
367                                       test_ber_write_partial_OID_String);
368
369         torture_suite_add_simple_test(suite, "ber_read_partial_OID_String",
370                                       test_ber_read_partial_OID_String);
371
372         torture_suite_add_simple_test(suite, "asn1_Integer",
373                                       test_asn1_Integer);
374
375         return suite;
376 }