93ffbad1fe4277299a2ef80799a98ee0f9f07c26
[sfrench/samba-autobuild/.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 "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 (alpha-numeric)*/
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 = {"\x02\x01\x00", 3},
115                 .value = 0
116         },
117         {
118                 .blob = {"\x02\x01\x7f", 3},
119                 .value = 127
120         },
121         {
122                 .blob = {"\x02\x02\x00\x80", 4},
123                 .value = 128
124         },
125         {
126                 .blob = {"\x02\x02\x01\x00", 4},
127                 .value = 256
128         },
129         {
130                 .blob = {"\x02\x01\x80", 3},
131                 .value = -128
132         },
133         {
134                 .blob = {"\x02\x02\xff\x7f", 4},
135                 .value = -129
136         },
137         {
138                 .blob = {"\x02\x01\xff", 3},
139                 .value = -1
140         },
141         {
142                 .blob = {"\x02\x02\xff\x01", 4},
143                 .value = -255
144         },
145         {
146                 .blob = {"\x02\x02\x00\xff", 4},
147                 .value = 255
148         },
149         {
150                 .blob = {"\x02\x04\x80\x00\x00\x00", 6},
151                 .value = 0x80000000
152         },
153         {
154                 .blob = {"\x02\x04\x7f\xff\xff\xff", 6},
155                 .value = 0x7fffffff
156         }
157 };
158
159 /* Testing ber_write_OID_String() function */
160 static bool test_ber_write_OID_String(struct torture_context *tctx)
161 {
162         int i;
163         char *hex_str;
164         DATA_BLOB blob;
165         TALLOC_CTX *mem_ctx;
166         const struct oid_data *data = oid_data_ok;
167
168         mem_ctx = talloc_new(tctx);
169
170         /* check for valid OIDs */
171         for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
172                 torture_assert(tctx, ber_write_OID_String(mem_ctx, &blob, data[i].oid),
173                                 "ber_write_OID_String failed");
174
175                 hex_str = hex_encode_talloc(mem_ctx, blob.data, blob.length);
176                 torture_assert(tctx, hex_str, "No memory!");
177
178                 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         for (i = 0; i < ARRAY_SIZE(oid_data_err); i++) {
186                 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         talloc_free(mem_ctx);
195
196         return true;
197 }
198
199 /* Testing ber_read_OID_String() function */
200 static bool test_ber_read_OID_String(struct torture_context *tctx)
201 {
202         int i;
203         char *oid;
204         DATA_BLOB oid_blob;
205         TALLOC_CTX *mem_ctx;
206         const struct oid_data *data = oid_data_ok;
207
208         mem_ctx = talloc_new(tctx);
209
210         for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
211                 oid_blob = strhex_to_data_blob(mem_ctx, data[i].bin_oid);
212
213                 torture_assert(tctx, ber_read_OID_String(mem_ctx, oid_blob, &oid),
214                                 "ber_read_OID_String failed");
215
216                 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         talloc_free(mem_ctx);
223
224         return true;
225 }
226
227 /* Testing ber_write_partial_OID_String() function */
228 static bool test_ber_write_partial_OID_String(struct torture_context *tctx)
229 {
230         int i;
231         char *hex_str;
232         DATA_BLOB blob;
233         TALLOC_CTX *mem_ctx;
234         const struct oid_data *data = oid_data_ok;
235
236         mem_ctx = talloc_new(tctx);
237
238         /* ber_write_partial_OID_String() should work with not partial OIDs also */
239         for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
240                 torture_assert(tctx, ber_write_partial_OID_String(mem_ctx, &blob, data[i].oid),
241                                 "ber_write_partial_OID_String failed");
242
243                 hex_str = hex_encode_talloc(mem_ctx, blob.data, blob.length);
244                 torture_assert(tctx, hex_str, "No memory!");
245
246                 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         data = partial_oid_data_ok;
254         for (i = 0; i < ARRAY_SIZE(partial_oid_data_ok); i++) {
255                 torture_assert(tctx, ber_write_partial_OID_String(mem_ctx, &blob, data[i].oid),
256                                 "ber_write_partial_OID_String failed");
257
258                 hex_str = hex_encode_talloc(mem_ctx, blob.data, blob.length);
259                 torture_assert(tctx, hex_str, "No memory!");
260
261                 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         talloc_free(mem_ctx);
268
269         return true;
270 }
271
272 /* Testing ber_read_partial_OID_String() function */
273 static bool test_ber_read_partial_OID_String(struct torture_context *tctx)
274 {
275         int i;
276         char *oid;
277         DATA_BLOB oid_blob;
278         TALLOC_CTX *mem_ctx;
279         const struct oid_data *data = oid_data_ok;
280
281         mem_ctx = talloc_new(tctx);
282
283         /* ber_read_partial_OID_String() should work with not partial OIDs also */
284         for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
285                 oid_blob = strhex_to_data_blob(mem_ctx, data[i].bin_oid);
286
287                 torture_assert(tctx, ber_read_partial_OID_String(mem_ctx, oid_blob, &oid),
288                                 "ber_read_partial_OID_String failed");
289
290                 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         data = partial_oid_data_ok;
298         for (i = 0; i < ARRAY_SIZE(partial_oid_data_ok); i++) {
299                 oid_blob = strhex_to_data_blob(mem_ctx, data[i].bin_oid);
300
301                 torture_assert(tctx, ber_read_partial_OID_String(mem_ctx, oid_blob, &oid),
302                                 "ber_read_partial_OID_String failed");
303
304                 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         talloc_free(mem_ctx);
311
312         return true;
313 }
314
315 /*
316  * Testing asn1_read_Integer and asn1_write_Integer functions,
317  * inspired by Love Hornquist Astrand
318  */
319
320 static bool test_asn1_Integer(struct torture_context *tctx)
321 {
322         int i;
323         TALLOC_CTX *mem_ctx;
324
325         mem_ctx = talloc_new(tctx);
326
327         for (i = 0; i < ARRAY_SIZE(integer_tests); i++) {
328                 ASN1_DATA *data;
329                 DATA_BLOB blob;
330                 int val;
331
332                 data = asn1_init(mem_ctx);
333                 if (!data) {
334                         return -1;
335                 }
336
337                 asn1_write_Integer(data, integer_tests[i].value);
338
339                 blob.data = data->data;
340                 blob.length = data->length;
341                 torture_assert_data_blob_equal(tctx, blob, integer_tests[i].blob, "asn1_write_Integer gave incorrect result");
342
343                 asn1_load(data, blob);
344                 torture_assert(tctx, asn1_read_Integer(data, &val), "asn1_write_Integer output could not be read by asn1_read_Integer()");
345
346                 torture_assert_int_equal(tctx, val, integer_tests[i].value,
347                         "readback of asn1_write_Integer output by asn1_read_Integer() failed");
348         }
349
350         talloc_free(mem_ctx);
351
352         return true;
353 }
354
355
356 /* LOCAL-ASN1 test suite creation */
357 struct torture_suite *torture_local_util_asn1(TALLOC_CTX *mem_ctx)
358 {
359         struct torture_suite *suite = torture_suite_create(mem_ctx, "asn1");
360
361         torture_suite_add_simple_test(suite, "ber_write_OID_String",
362                                       test_ber_write_OID_String);
363
364         torture_suite_add_simple_test(suite, "ber_read_OID_String",
365                                       test_ber_read_OID_String);
366
367         torture_suite_add_simple_test(suite, "ber_write_partial_OID_String",
368                                       test_ber_write_partial_OID_String);
369
370         torture_suite_add_simple_test(suite, "ber_read_partial_OID_String",
371                                       test_ber_read_partial_OID_String);
372
373         torture_suite_add_simple_test(suite, "asn1_Integer",
374                                       test_asn1_Integer);
375
376         return suite;
377 }