summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/regress/lib/libcrypto/x509/Makefile4
-rw-r--r--src/regress/lib/libcrypto/x509/x509_extensions_test.c603
2 files changed, 605 insertions, 2 deletions
diff --git a/src/regress/lib/libcrypto/x509/Makefile b/src/regress/lib/libcrypto/x509/Makefile
index 283e3379d4..5a90facb2d 100644
--- a/src/regress/lib/libcrypto/x509/Makefile
+++ b/src/regress/lib/libcrypto/x509/Makefile
@@ -1,7 +1,7 @@
1# $OpenBSD: Makefile,v 1.21 2023/04/30 05:02:59 tb Exp $ 1# $OpenBSD: Makefile,v 1.22 2024/05/28 15:33:35 tb Exp $
2 2
3PROGS = constraints verify x509attribute x509name x509req_ext callback 3PROGS = constraints verify x509attribute x509name x509req_ext callback
4PROGS += expirecallback callbackfailures x509_asn1 4PROGS += expirecallback callbackfailures x509_asn1 x509_extensions_test
5LDADD = -lcrypto 5LDADD = -lcrypto
6DPADD = ${LIBCRYPTO} 6DPADD = ${LIBCRYPTO}
7 7
diff --git a/src/regress/lib/libcrypto/x509/x509_extensions_test.c b/src/regress/lib/libcrypto/x509/x509_extensions_test.c
new file mode 100644
index 0000000000..a90a173e1d
--- /dev/null
+++ b/src/regress/lib/libcrypto/x509/x509_extensions_test.c
@@ -0,0 +1,603 @@
1/* $OpenBSD: x509_extensions_test.c,v 1.1 2024/05/28 15:33:35 tb Exp $ */
2
3/*
4 * Copyright (c) 2024 Theo Buehler <tb@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <err.h>
20#include <stdio.h>
21
22#include <openssl/asn1.h>
23#include <openssl/err.h>
24#include <openssl/x509.h>
25#include <openssl/x509v3.h>
26
27#define ASN1_BOOLEAN_TRUE 0xff
28#define ASN1_BOOLEAN_FALSE 0x00
29
30static BASIC_CONSTRAINTS *
31create_basic_constraints(int ca)
32{
33 BASIC_CONSTRAINTS *bc;
34
35 if ((bc = BASIC_CONSTRAINTS_new()) == NULL)
36 errx(1, "BASIC_CONSTRAINTS_new");
37
38 bc->ca = ca ? ASN1_BOOLEAN_TRUE : ASN1_BOOLEAN_FALSE;
39
40 return bc;
41}
42
43static int
44test_x509v3_add1_i2d_empty_stack(STACK_OF(X509_EXTENSION) **extensions)
45{
46 unsigned long error;
47 int op, got;
48 int nid = NID_basic_constraints;
49 int failed = 1;
50
51 if (X509v3_get_ext_count(*extensions) != 0) {
52 fprintf(stderr, "%s: FAIL: need empty stack\n", __func__);
53 goto err;
54 }
55
56 ERR_clear_error();
57
58 op = X509V3_ADD_REPLACE_EXISTING;
59
60 if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 0) {
61 fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING "
62 "want %d, got %d.\n", __func__, 0, got);
63 goto err;
64 }
65
66 error = ERR_get_error();
67 if (ERR_GET_REASON(error) != X509V3_R_EXTENSION_NOT_FOUND) {
68 fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING "
69 "pushed %d for empty stack, want %d.\n", __func__,
70 ERR_GET_REASON(error), X509V3_R_EXTENSION_NOT_FOUND);
71 goto err;
72 }
73 if ((error = ERR_get_error()) != 0) {
74 fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING "
75 "expected exactly one error.\n", __func__);
76 goto err;
77 }
78
79 op = X509V3_ADD_REPLACE_EXISTING | X509V3_ADD_SILENT;
80
81 if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 0) {
82 fprintf(stderr, "%s: FAIL: silent X509V3_ADD_REPLACE_EXISTING "
83 "want %d, got %d.\n", __func__, 0, got);
84 goto err;
85 }
86 if ((error = ERR_get_error()) != 0) {
87 fprintf(stderr, "%s: FAIL: silent X509V3_ADD_REPLACE_EXISTING "
88 "added error %d, want %d.\n", __func__,
89 ERR_GET_REASON(error), 0);
90 goto err;
91 }
92
93 op = X509V3_ADD_DELETE;
94 if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 0) {
95 fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
96 "want %d, got %d.\n", __func__, 0, got);
97 goto err;
98 }
99
100 error = ERR_get_error();
101 if (ERR_GET_REASON(error) != X509V3_R_EXTENSION_NOT_FOUND) {
102 fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
103 "pushed %d for empty stack, want %d.\n", __func__,
104 ERR_GET_REASON(error), X509V3_R_EXTENSION_NOT_FOUND);
105 goto err;
106 }
107
108 if ((error = ERR_get_error()) != 0) {
109 fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
110 "expected exactly one error.\n", __func__);
111 goto err;
112 }
113
114 failed = 0;
115
116 err:
117
118 return failed;
119}
120
121static int
122test_x509v3_add1_i2d_single_nid(STACK_OF(X509_EXTENSION) **extensions)
123{
124 BASIC_CONSTRAINTS *bc = NULL;
125 unsigned long error;
126 int crit, got, nid, op;
127 int failed = 1;
128
129 if (X509v3_get_ext_count(*extensions) != 0) {
130 fprintf(stderr, "%s: FAIL: need an empty stack.\n", __func__);
131 goto err;
132 }
133
134 /*
135 * Add basic ca constraints.
136 */
137
138 nid = NID_basic_constraints;
139 bc = create_basic_constraints(1);
140 op = X509V3_ADD_DEFAULT;
141 if ((got = X509V3_add1_i2d(extensions, nid, bc, 1, op)) != 1) {
142 fprintf(stderr, "%s: FAIL: X509V3_ADD_DEFAULT failed to add "
143 "basic constraints to empty stack: want %d, got %d.\n",
144 __func__, 1, got);
145 goto err;
146 }
147 BASIC_CONSTRAINTS_free(bc);
148 bc = NULL;
149
150 if ((got = X509v3_get_ext_count(*extensions)) != 1) {
151 fprintf(stderr, "%s: FAIL: expected 1 extension, have %d.\n",
152 __func__, got);
153 goto err;
154 }
155
156 /*
157 * Can't delete or replace non-existent extension.
158 */
159
160 nid = NID_policy_constraints;
161 op = X509V3_ADD_DELETE;
162 if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 0) {
163 fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE non-existent "
164 "want %d, got %d,\n", __func__, 0, got);
165 goto err;
166 }
167 nid = NID_policy_constraints;
168 op = X509V3_ADD_REPLACE_EXISTING;
169 if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 0) {
170 fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING non-existent "
171 "want %d, got %d.\n", __func__, 0, got);
172 goto err;
173 }
174
175 /*
176 * X509V3_ADD_DEFAULT refuses to add second basic constraints extension.
177 */
178
179 ERR_clear_error();
180
181 nid = NID_basic_constraints;
182 bc = create_basic_constraints(0);
183 op = X509V3_ADD_DEFAULT;
184 if ((got = X509V3_add1_i2d(extensions, nid, bc, 1, op)) != 0) {
185 fprintf(stderr, "%s: FAIL: X509V3_ADD_DEFAULT second constraints "
186 "want %d, got %d.\n", __func__, 0, got);
187 goto err;
188 }
189 BASIC_CONSTRAINTS_free(bc);
190 bc = NULL;
191
192 error = ERR_get_error();
193 if (ERR_GET_REASON(error) != X509V3_R_EXTENSION_EXISTS) {
194 fprintf(stderr, "%s: FAIL: X509V3_ADD_DEFAULT second constraints "
195 " pushed %d, want %d.\n", __func__,
196 ERR_GET_REASON(error), X509V3_R_EXTENSION_EXISTS);
197 goto err;
198 }
199
200 if ((got = X509v3_get_ext_count(*extensions)) != 1) {
201 fprintf(stderr, "%s: FAIL: X509V3_ADD_DEFAULT second contraints "
202 "expected 1 extension, have %d.\n", __func__, got);
203 goto err;
204 }
205
206 /*
207 * We can replace existing basic constraints using X509V3_ADD_REPLACE.
208 */
209
210 nid = NID_basic_constraints;
211 bc = create_basic_constraints(0);
212 op = X509V3_ADD_REPLACE;
213 if ((got = X509V3_add1_i2d(extensions, nid, bc, 1, op)) != 1) {
214 fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
215 "want %d, got %d.\n", __func__, 1, got);
216 goto err;
217 }
218 BASIC_CONSTRAINTS_free(bc);
219 bc = NULL;
220
221 if ((got = X509v3_get_ext_count(*extensions)) != 1) {
222 fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
223 "expected 1 extension, have %d.\n", __func__, got);
224 goto err;
225 }
226
227 /* Check that the extension was actually replaced. */
228 nid = NID_basic_constraints;
229 if ((bc = X509V3_get_d2i(*extensions, nid, &crit, NULL)) == NULL) {
230 if (crit != -1)
231 errx(1, "X509V3_get_d2i");
232 fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
233 "expected basic constraints\n", __func__);
234 goto err;
235 }
236 if (bc->ca != ASN1_BOOLEAN_FALSE) {
237 fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
238 "expected cA = false in basic constraints\n", __func__);
239 goto err;
240 }
241 BASIC_CONSTRAINTS_free(bc);
242 bc = NULL;
243
244 /*
245 * X509V3_ADD_KEEP_EXISTING existing does what it is supposed to do
246 * if basic constraints are already present.
247 */
248
249 nid = NID_basic_constraints;
250 bc = create_basic_constraints(1);
251 op = X509V3_ADD_KEEP_EXISTING;
252 if ((got = X509V3_add1_i2d(extensions, nid, bc, 1, op)) != 1) {
253 fprintf(stderr, "%s: FAIL: X509V3_ADD_KEEP_EXISTING "
254 "want %d, got %d.\n", __func__, 1, got);
255 goto err;
256 }
257 BASIC_CONSTRAINTS_free(bc);
258 bc = NULL;
259
260 /*
261 * Check we still have non-ca basic constraints.
262 */
263
264 nid = NID_basic_constraints;
265 if ((bc = X509V3_get_d2i(*extensions, nid, &crit, NULL)) == NULL) {
266 if (crit != -1)
267 errx(1, "X509V3_get_d2i");
268 fprintf(stderr, "%s: FAIL: X509V3_ADD_KEEP_EXISTING "
269 "expected basic constraints\n", __func__);
270 goto err;
271 }
272 if (bc->ca != ASN1_BOOLEAN_FALSE) {
273 fprintf(stderr, "%s: FAIL: X509V3_ADD_KEEP_EXISTING "
274 "expected non-ca basic constraints\n", __func__);
275 goto err;
276 }
277 BASIC_CONSTRAINTS_free(bc);
278 bc = NULL;
279
280 /*
281 * X509V3_ADD_REPLACE_EXISTING also works.
282 */
283
284 nid = NID_basic_constraints;
285 bc = create_basic_constraints(1);
286 op = X509V3_ADD_REPLACE_EXISTING;
287 if ((got = X509V3_add1_i2d(extensions, nid, bc, 1, op)) != 1) {
288 fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING "
289 "want %d, got %d.\n", __func__, 1, got);
290 goto err;
291 }
292 BASIC_CONSTRAINTS_free(bc);
293 bc = NULL;
294
295 /*
296 * Check we again have ca basic constraints.
297 */
298
299 nid = NID_basic_constraints;
300 if ((bc = X509V3_get_d2i(*extensions, nid, &crit, NULL)) == NULL) {
301 if (crit != -1)
302 errx(1, "X509V3_get_d2i");
303 fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING "
304 "expected basic constraints\n", __func__);
305 goto err;
306 }
307 if (bc->ca != ASN1_BOOLEAN_TRUE) {
308 fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING "
309 "expected ca basic constraints\n", __func__);
310 goto err;
311 }
312 BASIC_CONSTRAINTS_free(bc);
313 bc = NULL;
314
315 /*
316 * And X509V3_ADD_DELETE now works.
317 */
318
319 nid = NID_basic_constraints;
320 op = X509V3_ADD_DELETE;
321 if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 1) {
322 fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
323 "want %d, got %d.\n", __func__, 0, got);
324 goto err;
325 }
326
327 if ((got = X509v3_get_ext_count(*extensions)) != 0) {
328 fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
329 "expected 0 extensions, have %d.\n", __func__, got);
330 goto err;
331 }
332
333 /*
334 * X509V3_ADD_REPLACE adds the extension to empty stack as it should.
335 */
336
337 nid = NID_basic_constraints;
338 bc = create_basic_constraints(0);
339 op = X509V3_ADD_REPLACE;
340 if ((got = X509V3_add1_i2d(extensions, nid, bc, 1, op)) != 1) {
341 fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE on empty stack "
342 "want %d, got %d.\n", __func__, 1, got);
343 goto err;
344 }
345 BASIC_CONSTRAINTS_free(bc);
346 bc = NULL;
347
348 if ((got = X509v3_get_ext_count(*extensions)) != 1) {
349 fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
350 "expected 1 extension, have %d.\n", __func__, got);
351 goto err;
352 }
353
354 /*
355 * And X509V3_ADD_DELETE works again.
356 */
357
358 nid = NID_basic_constraints;
359 op = X509V3_ADD_DELETE;
360 if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 1) {
361 fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE after add replace "
362 "want %d, got %d.\n", __func__, 0, got);
363 goto err;
364 }
365
366 if ((got = X509v3_get_ext_count(*extensions)) != 0) {
367 fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
368 "expected 0 extensions, have %d.\n", __func__, got);
369 goto err;
370 }
371
372 failed = 0;
373
374 err:
375 BASIC_CONSTRAINTS_free(bc);
376
377 return failed;
378}
379
380static int
381test_x509v3_add1_i2d_add_append(STACK_OF(X509_EXTENSION) **extensions)
382{
383 BASIC_CONSTRAINTS *bc = NULL;
384 int crit, got, idx, nid, op;
385 int failed = 1;
386
387 if (X509v3_get_ext_count(*extensions) != 0) {
388 fprintf(stderr, "%s: FAIL: need empty stack.\n", __func__);
389 goto err;
390 }
391
392 /*
393 * Let the toolkit add two basic constraints extensions.
394 */
395
396 nid = NID_basic_constraints;
397 bc = create_basic_constraints(1);
398 crit = 1;
399 op = X509V3_ADD_APPEND;
400 if ((got = X509V3_add1_i2d(extensions, nid, bc, crit, op)) != 1) {
401 fprintf(stderr, "%s: FAIL: first X509V3_ADD_APPEND "
402 "want %d, got %d.\n", __func__, 0, got);
403 goto err;
404 }
405 BASIC_CONSTRAINTS_free(bc);
406 bc = NULL;
407
408 nid = NID_basic_constraints;
409 bc = create_basic_constraints(0);
410 crit = 1;
411 op = X509V3_ADD_APPEND;
412 if ((got = X509V3_add1_i2d(extensions, nid, bc, crit, op)) != 1) {
413 fprintf(stderr, "%s: FAIL: second X509V3_ADD_APPEND "
414 "want %d, got %d.\n", __func__, 0, got);
415 goto err;
416 }
417 BASIC_CONSTRAINTS_free(bc);
418 bc = NULL;
419
420 if ((got = X509v3_get_ext_count(*extensions)) != 2) {
421 fprintf(stderr, "%s: FAIL: second X509V3_ADD_APPEND "
422 "expected 2 extensions, have %d.\n", __func__, got);
423 goto err;
424 }
425
426 /*
427 * Inspect the extensions on the stack. First we should get the one
428 * with the ca bit set and it should be critical.
429 */
430
431 nid = NID_basic_constraints;
432 idx = -1;
433 if ((bc = X509V3_get_d2i(*extensions, nid, &crit, &idx)) == NULL) {
434 fprintf(stderr, "%s: FAIL: X509V3_ADD_APPEND "
435 "expected basic constraints.\n", __func__);
436 goto err;
437 }
438 if (bc->ca != ASN1_BOOLEAN_TRUE) {
439 fprintf(stderr, "%s: FAIL: X509V3_ADD_APPEND "
440 "expected ca basic constraints.\n", __func__);
441 goto err;
442 }
443 if (crit != 1) {
444 fprintf(stderr, "%s: FAIL: X509V3_ADD_APPEND "
445 "expected critical basic constraints.\n", __func__);
446 goto err;
447 }
448 BASIC_CONSTRAINTS_free(bc);
449 bc = NULL;
450
451 /* Redo the exercise and get the basic constraints with ca bit unset. */
452 nid = NID_basic_constraints;
453 if ((bc = X509V3_get_d2i(*extensions, nid, &crit, &idx)) == NULL) {
454 fprintf(stderr, "%s: FAIL: second X509V3_ADD_APPEND "
455 "expected basic constraints.\n", __func__);
456 goto err;
457 }
458 if (bc->ca != ASN1_BOOLEAN_FALSE) {
459 fprintf(stderr, "%s: FAIL: second X509V3_ADD_APPEND "
460 "expected basic constraints to be non-ca.\n", __func__);
461 goto err;
462 }
463 if (crit != 1) {
464 fprintf(stderr, "%s: FAIL: second X509V3_ADD_APPEND "
465 "expected critical basic constraints.\n", __func__);
466 goto err;
467 }
468 BASIC_CONSTRAINTS_free(bc);
469 bc = NULL;
470
471 /*
472 * Now X509V3_ADD_REPLACE non-critical ca constraints. They should
473 * replace the critical ca constraints we added before.
474 */
475
476 nid = NID_basic_constraints;
477 bc = create_basic_constraints(1);
478 crit = 0;
479 op = X509V3_ADD_REPLACE;
480 if ((got = X509V3_add1_i2d(extensions, nid, bc, crit, op)) != 1) {
481 fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
482 "want %d, got %d\n", __func__, 1, got);
483 goto err;
484 }
485 BASIC_CONSTRAINTS_free(bc);
486 bc = NULL;
487
488 /*
489 * If we get basic constraints now, we get the non-critical one with the
490 * ca bit set.
491 */
492
493 nid = NID_basic_constraints;
494 idx = -1;
495 if ((bc = X509V3_get_d2i(*extensions, nid, &crit, &idx)) == NULL) {
496 fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
497 "expected basic constraints.\n", __func__);
498 goto err;
499 }
500 if (bc->ca != ASN1_BOOLEAN_TRUE) {
501 fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
502 "expected ca basic constraints.\n", __func__);
503 goto err;
504 }
505 if (crit != 0) {
506 fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
507 "expected non-critical basic constraints.\n", __func__);
508 goto err;
509 }
510 BASIC_CONSTRAINTS_free(bc);
511 bc = NULL;
512
513 if ((got = X509v3_get_ext_count(*extensions)) != 2) {
514 fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
515 "expected 2 extensions, got %d.\n", __func__, got);
516 goto err;
517 }
518
519 nid = NID_basic_constraints;
520 op = X509V3_ADD_DELETE;
521 if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 1) {
522 fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
523 "want %d, got %d\n", __func__, 1, got);
524 goto err;
525 }
526
527 if ((got = X509v3_get_ext_count(*extensions)) != 1) {
528 fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
529 "expected 1 extension, got %d.\n", __func__, got);
530 goto err;
531 }
532
533 /* The last deletion will have left the critical non-ca constraints. */
534 nid = NID_basic_constraints;
535 idx = -1;
536 if ((bc = X509V3_get_d2i(*extensions, nid, &crit, &idx)) == NULL) {
537 fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
538 "expected basic constraints.\n", __func__);
539 goto err;
540 }
541 if (bc->ca != ASN1_BOOLEAN_FALSE) {
542 fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
543 "expected ca basic constraints.\n", __func__);
544 goto err;
545 }
546 if (crit != 1) {
547 fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
548 "expected critical basic constraints.\n", __func__);
549 goto err;
550 }
551 BASIC_CONSTRAINTS_free(bc);
552 bc = NULL;
553
554 /* Now delete the last extension. */
555 nid = NID_basic_constraints;
556 op = X509V3_ADD_DELETE;
557 if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 1) {
558 fprintf(stderr, "%s: FAIL: second X509V3_ADD_DELETE "
559 "want %d, got %d\n", __func__, 1, got);
560 goto err;
561 }
562
563 if ((got = X509v3_get_ext_count(*extensions)) != 0) {
564 fprintf(stderr, "%s: FAIL: second X509V3_ADD_DELETE "
565 "expected 0 extensions, got %d.\n", __func__, got);
566 goto err;
567 }
568
569 failed = 0;
570
571 err:
572 BASIC_CONSTRAINTS_free(bc);
573
574 return failed;
575}
576
577static int
578test_x509v3_add1_i2d(void)
579{
580 STACK_OF(X509_EXTENSION) *extensions;
581 int failed = 0;
582
583 if ((extensions = sk_X509_EXTENSION_new_null()) == NULL)
584 errx(1, "sk_X509_EXTENSION_new_null");
585
586 failed |= test_x509v3_add1_i2d_empty_stack(&extensions);
587 failed |= test_x509v3_add1_i2d_single_nid(&extensions);
588 failed |= test_x509v3_add1_i2d_add_append(&extensions);
589
590 sk_X509_EXTENSION_pop_free(extensions, X509_EXTENSION_free);
591
592 return failed;
593}
594
595int
596main(void)
597{
598 int failed = 0;
599
600 failed |= test_x509v3_add1_i2d();
601
602 return failed;
603}