xref: /openbsd-src/regress/lib/libcrypto/x509/x509_extensions_test.c (revision a1ec0f809e04c7af36697a189687e31c0f55315e)
1*a1ec0f80Stb /*	$OpenBSD: x509_extensions_test.c,v 1.3 2024/06/17 05:04:54 tb Exp $ */
25f283da1Stb 
35f283da1Stb /*
45f283da1Stb  * Copyright (c) 2024 Theo Buehler <tb@openbsd.org>
55f283da1Stb  *
65f283da1Stb  * Permission to use, copy, modify, and distribute this software for any
75f283da1Stb  * purpose with or without fee is hereby granted, provided that the above
85f283da1Stb  * copyright notice and this permission notice appear in all copies.
95f283da1Stb  *
105f283da1Stb  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
115f283da1Stb  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
125f283da1Stb  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
135f283da1Stb  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
145f283da1Stb  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
155f283da1Stb  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
165f283da1Stb  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
175f283da1Stb  */
185f283da1Stb 
195f283da1Stb #include <err.h>
205f283da1Stb #include <stdio.h>
215f283da1Stb 
225f283da1Stb #include <openssl/asn1.h>
235f283da1Stb #include <openssl/err.h>
245f283da1Stb #include <openssl/x509.h>
255f283da1Stb #include <openssl/x509v3.h>
265f283da1Stb 
275f283da1Stb #define ASN1_BOOLEAN_TRUE	0xff
285f283da1Stb #define ASN1_BOOLEAN_FALSE	0x00
295f283da1Stb 
30*a1ec0f80Stb #define X509V3_EXT_CRITICAL	1
31*a1ec0f80Stb #define X509V3_EXT_NONCRITICAL	0
32*a1ec0f80Stb 
335f283da1Stb static BASIC_CONSTRAINTS *
create_basic_constraints(int ca)345f283da1Stb create_basic_constraints(int ca)
355f283da1Stb {
365f283da1Stb 	BASIC_CONSTRAINTS *bc;
375f283da1Stb 
385f283da1Stb 	if ((bc = BASIC_CONSTRAINTS_new()) == NULL)
395f283da1Stb 		errx(1, "BASIC_CONSTRAINTS_new");
405f283da1Stb 
415f283da1Stb 	bc->ca = ca ? ASN1_BOOLEAN_TRUE : ASN1_BOOLEAN_FALSE;
425f283da1Stb 
435f283da1Stb 	return bc;
445f283da1Stb }
455f283da1Stb 
46*a1ec0f80Stb static X509_EXTENSION *
ext_create_basic_constraints(int ca,int critical)47*a1ec0f80Stb ext_create_basic_constraints(int ca, int critical)
48*a1ec0f80Stb {
49*a1ec0f80Stb 	X509_EXTENSION *ext;
50*a1ec0f80Stb 	BASIC_CONSTRAINTS *bc;
51*a1ec0f80Stb 
52*a1ec0f80Stb 	bc = create_basic_constraints(ca);
53*a1ec0f80Stb 	if ((ext = X509V3_EXT_i2d(NID_basic_constraints, critical, bc)) == NULL)
54*a1ec0f80Stb 		errx(1, "X509V3_EXT_i2d");
55*a1ec0f80Stb 	BASIC_CONSTRAINTS_free(bc);
56*a1ec0f80Stb 
57*a1ec0f80Stb 	return ext;
58*a1ec0f80Stb }
59*a1ec0f80Stb 
605f283da1Stb static int
test_x509v3_add1_i2d_empty_stack(STACK_OF (X509_EXTENSION)** extensions)615f283da1Stb test_x509v3_add1_i2d_empty_stack(STACK_OF(X509_EXTENSION) **extensions)
625f283da1Stb {
635f283da1Stb 	unsigned long error;
645f283da1Stb 	int op, got;
655f283da1Stb 	int nid = NID_basic_constraints;
665f283da1Stb 	int failed = 1;
675f283da1Stb 
685f283da1Stb 	if (X509v3_get_ext_count(*extensions) != 0) {
695f283da1Stb 		fprintf(stderr, "%s: FAIL: need empty stack\n", __func__);
705f283da1Stb 		goto err;
715f283da1Stb 	}
725f283da1Stb 
735f283da1Stb 	ERR_clear_error();
745f283da1Stb 
755f283da1Stb 	op = X509V3_ADD_REPLACE_EXISTING;
765f283da1Stb 
775f283da1Stb 	if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 0) {
785f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING "
795f283da1Stb 		    "want %d, got %d.\n", __func__, 0, got);
805f283da1Stb 		goto err;
815f283da1Stb 	}
825f283da1Stb 
835f283da1Stb 	error = ERR_get_error();
845f283da1Stb 	if (ERR_GET_REASON(error) != X509V3_R_EXTENSION_NOT_FOUND) {
855f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING "
865f283da1Stb 		    "pushed %d for empty stack, want %d.\n", __func__,
875f283da1Stb 		    ERR_GET_REASON(error), X509V3_R_EXTENSION_NOT_FOUND);
885f283da1Stb 		goto err;
895f283da1Stb 	}
905f283da1Stb 	if ((error = ERR_get_error()) != 0) {
915f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING "
925f283da1Stb 		    "expected exactly one error.\n", __func__);
935f283da1Stb 		goto err;
945f283da1Stb 	}
955f283da1Stb 
965f283da1Stb 	op = X509V3_ADD_REPLACE_EXISTING | X509V3_ADD_SILENT;
975f283da1Stb 
985f283da1Stb 	if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 0) {
995f283da1Stb 		fprintf(stderr, "%s: FAIL: silent X509V3_ADD_REPLACE_EXISTING "
1005f283da1Stb 		    "want %d, got %d.\n", __func__, 0, got);
1015f283da1Stb 		goto err;
1025f283da1Stb 	}
1035f283da1Stb 	if ((error = ERR_get_error()) != 0) {
1045f283da1Stb 		fprintf(stderr, "%s: FAIL: silent X509V3_ADD_REPLACE_EXISTING "
1055f283da1Stb 		    "added error %d, want %d.\n", __func__,
1065f283da1Stb 		    ERR_GET_REASON(error), 0);
1075f283da1Stb 		goto err;
1085f283da1Stb 	}
1095f283da1Stb 
1105f283da1Stb 	op = X509V3_ADD_DELETE;
1115f283da1Stb 	if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 0) {
1125f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
1135f283da1Stb 		    "want %d, got %d.\n", __func__, 0, got);
1145f283da1Stb 		goto err;
1155f283da1Stb 	}
1165f283da1Stb 
1175f283da1Stb 	error = ERR_get_error();
1185f283da1Stb 	if (ERR_GET_REASON(error) != X509V3_R_EXTENSION_NOT_FOUND) {
1195f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
1205f283da1Stb 		    "pushed %d for empty stack, want %d.\n", __func__,
1215f283da1Stb 		    ERR_GET_REASON(error), X509V3_R_EXTENSION_NOT_FOUND);
1225f283da1Stb 		goto err;
1235f283da1Stb 	}
1245f283da1Stb 
1255f283da1Stb 	if ((error = ERR_get_error()) != 0) {
1265f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
1275f283da1Stb 		    "expected exactly one error.\n", __func__);
1285f283da1Stb 		goto err;
1295f283da1Stb 	}
1305f283da1Stb 
1315f283da1Stb 	failed = 0;
1325f283da1Stb 
1335f283da1Stb  err:
1345f283da1Stb 
1355f283da1Stb 	return failed;
1365f283da1Stb }
1375f283da1Stb 
1385f283da1Stb static int
test_x509v3_add1_i2d_single_nid(STACK_OF (X509_EXTENSION)** extensions)1395f283da1Stb test_x509v3_add1_i2d_single_nid(STACK_OF(X509_EXTENSION) **extensions)
1405f283da1Stb {
1415f283da1Stb 	BASIC_CONSTRAINTS *bc = NULL;
1425f283da1Stb 	unsigned long error;
1435f283da1Stb 	int crit, got, nid, op;
1445f283da1Stb 	int failed = 1;
1455f283da1Stb 
1465f283da1Stb 	if (X509v3_get_ext_count(*extensions) != 0) {
1475f283da1Stb 		fprintf(stderr, "%s: FAIL: need an empty stack.\n", __func__);
1485f283da1Stb 		goto err;
1495f283da1Stb 	}
1505f283da1Stb 
1515f283da1Stb 	/*
1525f283da1Stb 	 * Add basic ca constraints.
1535f283da1Stb 	 */
1545f283da1Stb 
1555f283da1Stb 	nid = NID_basic_constraints;
1565f283da1Stb 	bc = create_basic_constraints(1);
1575f283da1Stb 	op = X509V3_ADD_DEFAULT;
1585f283da1Stb 	if ((got = X509V3_add1_i2d(extensions, nid, bc, 1, op)) != 1) {
1595f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_DEFAULT failed to add "
1605f283da1Stb 		    "basic constraints to empty stack: want %d, got %d.\n",
1615f283da1Stb 		    __func__, 1, got);
1625f283da1Stb 		goto err;
1635f283da1Stb 	}
1645f283da1Stb 	BASIC_CONSTRAINTS_free(bc);
1655f283da1Stb 	bc = NULL;
1665f283da1Stb 
1675f283da1Stb 	if ((got = X509v3_get_ext_count(*extensions)) != 1) {
1685f283da1Stb 		fprintf(stderr, "%s: FAIL: expected 1 extension, have %d.\n",
1695f283da1Stb 		    __func__, got);
1705f283da1Stb 		goto err;
1715f283da1Stb 	}
1725f283da1Stb 
1735f283da1Stb 	/*
1745f283da1Stb 	 * Can't delete or replace non-existent extension.
1755f283da1Stb 	 */
1765f283da1Stb 
1775f283da1Stb 	nid = NID_policy_constraints;
1785f283da1Stb 	op = X509V3_ADD_DELETE;
1795f283da1Stb 	if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 0) {
1805f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE non-existent "
1815f283da1Stb 		    "want %d, got %d,\n", __func__, 0, got);
1825f283da1Stb 		goto err;
1835f283da1Stb 	}
1845f283da1Stb 	nid = NID_policy_constraints;
1855f283da1Stb 	op = X509V3_ADD_REPLACE_EXISTING;
1865f283da1Stb 	if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 0) {
1875f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING non-existent "
1885f283da1Stb 		    "want %d, got %d.\n", __func__, 0, got);
1895f283da1Stb 		goto err;
1905f283da1Stb 	}
1915f283da1Stb 
1925f283da1Stb 	/*
1935f283da1Stb 	 * X509V3_ADD_DEFAULT refuses to add second basic constraints extension.
1945f283da1Stb 	 */
1955f283da1Stb 
1965f283da1Stb 	ERR_clear_error();
1975f283da1Stb 
1985f283da1Stb 	nid = NID_basic_constraints;
1995f283da1Stb 	bc = create_basic_constraints(0);
2005f283da1Stb 	op = X509V3_ADD_DEFAULT;
2015f283da1Stb 	if ((got = X509V3_add1_i2d(extensions, nid, bc, 1, op)) != 0) {
2025f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_DEFAULT second constraints "
2035f283da1Stb 		    "want %d, got %d.\n", __func__, 0, got);
2045f283da1Stb 		goto err;
2055f283da1Stb 	}
2065f283da1Stb 	BASIC_CONSTRAINTS_free(bc);
2075f283da1Stb 	bc = NULL;
2085f283da1Stb 
2095f283da1Stb 	error = ERR_get_error();
2105f283da1Stb 	if (ERR_GET_REASON(error) != X509V3_R_EXTENSION_EXISTS) {
2115f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_DEFAULT second constraints "
2125f283da1Stb 		    " pushed %d, want %d.\n", __func__,
2135f283da1Stb 		    ERR_GET_REASON(error), X509V3_R_EXTENSION_EXISTS);
2145f283da1Stb 		goto err;
2155f283da1Stb 	}
2165f283da1Stb 
2175f283da1Stb 	if ((got = X509v3_get_ext_count(*extensions)) != 1) {
2185f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_DEFAULT second contraints "
2195f283da1Stb 		    "expected 1 extension, have %d.\n", __func__, got);
2205f283da1Stb 		goto err;
2215f283da1Stb 	}
2225f283da1Stb 
2235f283da1Stb 	/*
2245f283da1Stb 	 * We can replace existing basic constraints using X509V3_ADD_REPLACE.
2255f283da1Stb 	 */
2265f283da1Stb 
2275f283da1Stb 	nid = NID_basic_constraints;
2285f283da1Stb 	bc = create_basic_constraints(0);
2295f283da1Stb 	op = X509V3_ADD_REPLACE;
2305f283da1Stb 	if ((got = X509V3_add1_i2d(extensions, nid, bc, 1, op)) != 1) {
2315f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
2325f283da1Stb 		    "want %d, got %d.\n", __func__, 1, got);
2335f283da1Stb 		goto err;
2345f283da1Stb 	}
2355f283da1Stb 	BASIC_CONSTRAINTS_free(bc);
2365f283da1Stb 	bc = NULL;
2375f283da1Stb 
2385f283da1Stb 	if ((got = X509v3_get_ext_count(*extensions)) != 1) {
2395f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
2405f283da1Stb 		    "expected 1 extension, have %d.\n", __func__, got);
2415f283da1Stb 		goto err;
2425f283da1Stb 	}
2435f283da1Stb 
2445f283da1Stb 	/* Check that the extension was actually replaced. */
2455f283da1Stb 	nid = NID_basic_constraints;
2465f283da1Stb 	if ((bc = X509V3_get_d2i(*extensions, nid, &crit, NULL)) == NULL) {
2475f283da1Stb 		if (crit != -1)
2485f283da1Stb 			errx(1, "X509V3_get_d2i");
2495f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
2505f283da1Stb 		    "expected basic constraints\n", __func__);
2515f283da1Stb 		goto err;
2525f283da1Stb 	}
2535f283da1Stb 	if (bc->ca != ASN1_BOOLEAN_FALSE) {
2545f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
2555f283da1Stb 		    "expected cA = false in basic constraints\n", __func__);
2565f283da1Stb 		goto err;
2575f283da1Stb 	}
2585f283da1Stb 	BASIC_CONSTRAINTS_free(bc);
2595f283da1Stb 	bc = NULL;
2605f283da1Stb 
2615f283da1Stb 	/*
2625f283da1Stb 	 * X509V3_ADD_KEEP_EXISTING existing does what it is supposed to do
2635f283da1Stb 	 * if basic constraints are already present.
2645f283da1Stb 	 */
2655f283da1Stb 
2665f283da1Stb 	nid = NID_basic_constraints;
2675f283da1Stb 	bc = create_basic_constraints(1);
2685f283da1Stb 	op = X509V3_ADD_KEEP_EXISTING;
2695f283da1Stb 	if ((got = X509V3_add1_i2d(extensions, nid, bc, 1, op)) != 1) {
2705f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_KEEP_EXISTING "
2715f283da1Stb 		    "want %d, got %d.\n", __func__, 1, got);
2725f283da1Stb 		goto err;
2735f283da1Stb 	}
2745f283da1Stb 	BASIC_CONSTRAINTS_free(bc);
2755f283da1Stb 	bc = NULL;
2765f283da1Stb 
2775f283da1Stb 	/*
2785f283da1Stb 	 * Check we still have non-ca basic constraints.
2795f283da1Stb 	 */
2805f283da1Stb 
2815f283da1Stb 	nid = NID_basic_constraints;
2825f283da1Stb 	if ((bc = X509V3_get_d2i(*extensions, nid, &crit, NULL)) == NULL) {
2835f283da1Stb 		if (crit != -1)
2845f283da1Stb 			errx(1, "X509V3_get_d2i");
2855f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_KEEP_EXISTING "
2865f283da1Stb 		   "expected basic constraints\n", __func__);
2875f283da1Stb 		goto err;
2885f283da1Stb 	}
2895f283da1Stb 	if (bc->ca != ASN1_BOOLEAN_FALSE) {
2905f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_KEEP_EXISTING "
2915f283da1Stb 		   "expected non-ca basic constraints\n", __func__);
2925f283da1Stb 		goto err;
2935f283da1Stb 	}
2945f283da1Stb 	BASIC_CONSTRAINTS_free(bc);
2955f283da1Stb 	bc = NULL;
2965f283da1Stb 
2975f283da1Stb 	/*
2985f283da1Stb 	 * X509V3_ADD_REPLACE_EXISTING also works.
2995f283da1Stb 	 */
3005f283da1Stb 
3015f283da1Stb 	nid = NID_basic_constraints;
3025f283da1Stb 	bc = create_basic_constraints(1);
3035f283da1Stb 	op = X509V3_ADD_REPLACE_EXISTING;
3045f283da1Stb 	if ((got = X509V3_add1_i2d(extensions, nid, bc, 1, op)) != 1) {
3055f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING "
3065f283da1Stb 		    "want %d, got %d.\n", __func__, 1, got);
3075f283da1Stb 		goto err;
3085f283da1Stb 	}
3095f283da1Stb 	BASIC_CONSTRAINTS_free(bc);
3105f283da1Stb 	bc = NULL;
3115f283da1Stb 
3125f283da1Stb 	/*
3135f283da1Stb 	 * Check we again have ca basic constraints.
3145f283da1Stb 	 */
3155f283da1Stb 
3165f283da1Stb 	nid = NID_basic_constraints;
3175f283da1Stb 	if ((bc = X509V3_get_d2i(*extensions, nid, &crit, NULL)) == NULL) {
3185f283da1Stb 		if (crit != -1)
3195f283da1Stb 			errx(1, "X509V3_get_d2i");
3205f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING "
3215f283da1Stb 		   "expected basic constraints\n", __func__);
3225f283da1Stb 		goto err;
3235f283da1Stb 	}
3245f283da1Stb 	if (bc->ca != ASN1_BOOLEAN_TRUE) {
3255f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING "
3265f283da1Stb 		   "expected ca basic constraints\n", __func__);
3275f283da1Stb 		goto err;
3285f283da1Stb 	}
3295f283da1Stb 	BASIC_CONSTRAINTS_free(bc);
3305f283da1Stb 	bc = NULL;
3315f283da1Stb 
3325f283da1Stb 	/*
3335f283da1Stb 	 * And X509V3_ADD_DELETE now works.
3345f283da1Stb 	 */
3355f283da1Stb 
3365f283da1Stb 	nid = NID_basic_constraints;
3375f283da1Stb 	op = X509V3_ADD_DELETE;
3385f283da1Stb 	if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 1) {
3395f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
3405f283da1Stb 		    "want %d, got %d.\n", __func__, 0, got);
3415f283da1Stb 		goto err;
3425f283da1Stb 	}
3435f283da1Stb 
3445f283da1Stb 	if ((got = X509v3_get_ext_count(*extensions)) != 0) {
3455f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
3465f283da1Stb 		    "expected 0 extensions, have %d.\n", __func__, got);
3475f283da1Stb 		goto err;
3485f283da1Stb 	}
3495f283da1Stb 
3505f283da1Stb 	/*
3515f283da1Stb 	 * X509V3_ADD_REPLACE adds the extension to empty stack as it should.
3525f283da1Stb 	 */
3535f283da1Stb 
3545f283da1Stb 	nid = NID_basic_constraints;
3555f283da1Stb 	bc = create_basic_constraints(0);
3565f283da1Stb 	op = X509V3_ADD_REPLACE;
3575f283da1Stb 	if ((got = X509V3_add1_i2d(extensions, nid, bc, 1, op)) != 1) {
3585f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE on empty stack "
3595f283da1Stb 		    "want %d, got %d.\n", __func__, 1, got);
3605f283da1Stb 		goto err;
3615f283da1Stb 	}
3625f283da1Stb 	BASIC_CONSTRAINTS_free(bc);
3635f283da1Stb 	bc = NULL;
3645f283da1Stb 
3655f283da1Stb 	if ((got = X509v3_get_ext_count(*extensions)) != 1) {
3665f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
3675f283da1Stb 		    "expected 1 extension, have %d.\n", __func__, got);
3685f283da1Stb 		goto err;
3695f283da1Stb 	}
3705f283da1Stb 
3715f283da1Stb 	/*
3725f283da1Stb 	 * And X509V3_ADD_DELETE works again.
3735f283da1Stb 	 */
3745f283da1Stb 
3755f283da1Stb 	nid = NID_basic_constraints;
3765f283da1Stb 	op = X509V3_ADD_DELETE;
3775f283da1Stb 	if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 1) {
3785f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE after add replace "
3795f283da1Stb 		    "want %d, got %d.\n", __func__, 0, got);
3805f283da1Stb 		goto err;
3815f283da1Stb 	}
3825f283da1Stb 
3835f283da1Stb 	if ((got = X509v3_get_ext_count(*extensions)) != 0) {
3845f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
3855f283da1Stb 		    "expected 0 extensions, have %d.\n", __func__, got);
3865f283da1Stb 		goto err;
3875f283da1Stb 	}
3885f283da1Stb 
3895f283da1Stb 	failed = 0;
3905f283da1Stb 
3915f283da1Stb  err:
3925f283da1Stb 	BASIC_CONSTRAINTS_free(bc);
3935f283da1Stb 
3945f283da1Stb 	return failed;
3955f283da1Stb }
3965f283da1Stb 
3975f283da1Stb static int
test_x509v3_add1_i2d_add_append(STACK_OF (X509_EXTENSION)** extensions)3985f283da1Stb test_x509v3_add1_i2d_add_append(STACK_OF(X509_EXTENSION) **extensions)
3995f283da1Stb {
4005f283da1Stb 	BASIC_CONSTRAINTS *bc = NULL;
4015f283da1Stb 	int crit, got, idx, nid, op;
4025f283da1Stb 	int failed = 1;
4035f283da1Stb 
4045f283da1Stb 	if (X509v3_get_ext_count(*extensions) != 0) {
4055f283da1Stb 		fprintf(stderr, "%s: FAIL: need empty stack.\n", __func__);
4065f283da1Stb 		goto err;
4075f283da1Stb 	}
4085f283da1Stb 
4095f283da1Stb 	/*
4105f283da1Stb 	 * Let the toolkit add two basic constraints extensions.
4115f283da1Stb 	 */
4125f283da1Stb 
4135f283da1Stb 	nid = NID_basic_constraints;
4145f283da1Stb 	bc = create_basic_constraints(1);
4155f283da1Stb 	crit = 1;
4165f283da1Stb 	op = X509V3_ADD_APPEND;
4175f283da1Stb 	if ((got = X509V3_add1_i2d(extensions, nid, bc, crit, op)) != 1) {
4185f283da1Stb 		fprintf(stderr, "%s: FAIL: first X509V3_ADD_APPEND "
4195f283da1Stb 		    "want %d, got %d.\n", __func__, 0, got);
4205f283da1Stb 		goto err;
4215f283da1Stb 	}
4225f283da1Stb 	BASIC_CONSTRAINTS_free(bc);
4235f283da1Stb 	bc = NULL;
4245f283da1Stb 
4255f283da1Stb 	nid = NID_basic_constraints;
4265f283da1Stb 	bc = create_basic_constraints(0);
4275f283da1Stb 	crit = 1;
4285f283da1Stb 	op = X509V3_ADD_APPEND;
4295f283da1Stb 	if ((got = X509V3_add1_i2d(extensions, nid, bc, crit, op)) != 1) {
4305f283da1Stb 		fprintf(stderr, "%s: FAIL: second X509V3_ADD_APPEND "
4315f283da1Stb 		    "want %d, got %d.\n", __func__, 0, got);
4325f283da1Stb 		goto err;
4335f283da1Stb 	}
4345f283da1Stb 	BASIC_CONSTRAINTS_free(bc);
4355f283da1Stb 	bc = NULL;
4365f283da1Stb 
4375f283da1Stb 	if ((got = X509v3_get_ext_count(*extensions)) != 2) {
4385f283da1Stb 		fprintf(stderr, "%s: FAIL: second X509V3_ADD_APPEND "
4395f283da1Stb 		    "expected 2 extensions, have %d.\n", __func__, got);
4405f283da1Stb 		goto err;
4415f283da1Stb 	}
4425f283da1Stb 
4435f283da1Stb 	/*
4445f283da1Stb 	 * Inspect the extensions on the stack. First we should get the one
4455f283da1Stb 	 * with the ca bit set and it should be critical.
4465f283da1Stb 	 */
4475f283da1Stb 
4485f283da1Stb 	nid = NID_basic_constraints;
4495f283da1Stb 	idx = -1;
4505f283da1Stb 	if ((bc = X509V3_get_d2i(*extensions, nid, &crit, &idx)) == NULL) {
4515f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_APPEND "
4525f283da1Stb 		    "expected basic constraints.\n", __func__);
4535f283da1Stb 		goto err;
4545f283da1Stb 	}
4555f283da1Stb 	if (bc->ca != ASN1_BOOLEAN_TRUE) {
4565f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_APPEND "
4575f283da1Stb 		    "expected ca basic constraints.\n", __func__);
4585f283da1Stb 		goto err;
4595f283da1Stb 	}
4605f283da1Stb 	if (crit != 1) {
4615f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_APPEND "
4625f283da1Stb 		    "expected critical basic constraints.\n", __func__);
4635f283da1Stb 		goto err;
4645f283da1Stb 	}
4655f283da1Stb 	BASIC_CONSTRAINTS_free(bc);
4665f283da1Stb 	bc = NULL;
4675f283da1Stb 
4685f283da1Stb 	/* Redo the exercise and get the basic constraints with ca bit unset. */
4695f283da1Stb 	nid = NID_basic_constraints;
4705f283da1Stb 	if ((bc = X509V3_get_d2i(*extensions, nid, &crit, &idx)) == NULL) {
4715f283da1Stb 		fprintf(stderr, "%s: FAIL: second X509V3_ADD_APPEND "
4725f283da1Stb 		    "expected basic constraints.\n", __func__);
4735f283da1Stb 		goto err;
4745f283da1Stb 	}
4755f283da1Stb 	if (bc->ca != ASN1_BOOLEAN_FALSE) {
4765f283da1Stb 		fprintf(stderr, "%s: FAIL: second X509V3_ADD_APPEND "
4775f283da1Stb 		    "expected basic constraints to be non-ca.\n", __func__);
4785f283da1Stb 		goto err;
4795f283da1Stb 	}
4805f283da1Stb 	if (crit != 1) {
4815f283da1Stb 		fprintf(stderr, "%s: FAIL: second X509V3_ADD_APPEND "
4825f283da1Stb 		    "expected critical basic constraints.\n", __func__);
4835f283da1Stb 		goto err;
4845f283da1Stb 	}
4855f283da1Stb 	BASIC_CONSTRAINTS_free(bc);
4865f283da1Stb 	bc = NULL;
4875f283da1Stb 
4885f283da1Stb 	/*
4895f283da1Stb 	 * Now X509V3_ADD_REPLACE non-critical ca constraints. They should
4905f283da1Stb 	 * replace the critical ca constraints we added before.
4915f283da1Stb 	 */
4925f283da1Stb 
4935f283da1Stb 	nid = NID_basic_constraints;
4945f283da1Stb 	bc = create_basic_constraints(1);
4955f283da1Stb 	crit = 0;
4965f283da1Stb 	op = X509V3_ADD_REPLACE;
4975f283da1Stb 	if ((got = X509V3_add1_i2d(extensions, nid, bc, crit, op)) != 1) {
4985f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
4995f283da1Stb 		    "want %d, got %d\n", __func__, 1, got);
5005f283da1Stb 		goto err;
5015f283da1Stb 	}
5025f283da1Stb 	BASIC_CONSTRAINTS_free(bc);
5035f283da1Stb 	bc = NULL;
5045f283da1Stb 
5055f283da1Stb 	/*
5065f283da1Stb 	 * If we get basic constraints now, we get the non-critical one with the
5075f283da1Stb 	 * ca bit set.
5085f283da1Stb 	 */
5095f283da1Stb 
5105f283da1Stb 	nid = NID_basic_constraints;
5115f283da1Stb 	idx = -1;
5125f283da1Stb 	if ((bc = X509V3_get_d2i(*extensions, nid, &crit, &idx)) == NULL) {
5135f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
5145f283da1Stb 		    "expected basic constraints.\n", __func__);
5155f283da1Stb 		goto err;
5165f283da1Stb 	}
5175f283da1Stb 	if (bc->ca != ASN1_BOOLEAN_TRUE) {
5185f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
5195f283da1Stb 		    "expected ca basic constraints.\n", __func__);
5205f283da1Stb 		goto err;
5215f283da1Stb 	}
5225f283da1Stb 	if (crit != 0) {
5235f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
5245f283da1Stb 		    "expected non-critical basic constraints.\n", __func__);
5255f283da1Stb 		goto err;
5265f283da1Stb 	}
5275f283da1Stb 	BASIC_CONSTRAINTS_free(bc);
5285f283da1Stb 	bc = NULL;
5295f283da1Stb 
5305f283da1Stb 	if ((got = X509v3_get_ext_count(*extensions)) != 2) {
5315f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
5325f283da1Stb 		    "expected 2 extensions, got %d.\n", __func__, got);
5335f283da1Stb 		goto err;
5345f283da1Stb 	}
5355f283da1Stb 
5365f283da1Stb 	nid = NID_basic_constraints;
5375f283da1Stb 	op = X509V3_ADD_DELETE;
5385f283da1Stb 	if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 1) {
5395f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
5405f283da1Stb 		    "want %d, got %d\n", __func__, 1, got);
5415f283da1Stb 		goto err;
5425f283da1Stb 	}
5435f283da1Stb 
5445f283da1Stb 	if ((got = X509v3_get_ext_count(*extensions)) != 1) {
5455f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
5465f283da1Stb 		    "expected 1 extension, got %d.\n", __func__, got);
5475f283da1Stb 		goto err;
5485f283da1Stb 	}
5495f283da1Stb 
5505f283da1Stb 	/* The last deletion will have left the critical non-ca constraints. */
5515f283da1Stb 	nid = NID_basic_constraints;
5525f283da1Stb 	idx = -1;
5535f283da1Stb 	if ((bc = X509V3_get_d2i(*extensions, nid, &crit, &idx)) == NULL) {
5545f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
5555f283da1Stb 		    "expected basic constraints.\n", __func__);
5565f283da1Stb 		goto err;
5575f283da1Stb 	}
5585f283da1Stb 	if (bc->ca != ASN1_BOOLEAN_FALSE) {
5595f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
5605f283da1Stb 		    "expected ca basic constraints.\n", __func__);
5615f283da1Stb 		goto err;
5625f283da1Stb 	}
5635f283da1Stb 	if (crit != 1) {
5645f283da1Stb 		fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
5655f283da1Stb 		    "expected critical basic constraints.\n", __func__);
5665f283da1Stb 		goto err;
5675f283da1Stb 	}
5685f283da1Stb 	BASIC_CONSTRAINTS_free(bc);
5695f283da1Stb 	bc = NULL;
5705f283da1Stb 
5715f283da1Stb 	/* Now delete the last extension. */
5725f283da1Stb 	nid = NID_basic_constraints;
5735f283da1Stb 	op = X509V3_ADD_DELETE;
5745f283da1Stb 	if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 1) {
5755f283da1Stb 		fprintf(stderr, "%s: FAIL: second X509V3_ADD_DELETE "
5765f283da1Stb 		    "want %d, got %d\n", __func__, 1, got);
5775f283da1Stb 		goto err;
5785f283da1Stb 	}
5795f283da1Stb 
5805f283da1Stb 	if ((got = X509v3_get_ext_count(*extensions)) != 0) {
5815f283da1Stb 		fprintf(stderr, "%s: FAIL: second X509V3_ADD_DELETE "
5825f283da1Stb 		    "expected 0 extensions, got %d.\n", __func__, got);
5835f283da1Stb 		goto err;
5845f283da1Stb 	}
5855f283da1Stb 
5865f283da1Stb 	failed = 0;
5875f283da1Stb 
5885f283da1Stb  err:
5895f283da1Stb 	BASIC_CONSTRAINTS_free(bc);
5905f283da1Stb 
5915f283da1Stb 	return failed;
5925f283da1Stb }
5935f283da1Stb 
5945f283da1Stb static int
test_x509v3_add1_i2d_invalid_operations(STACK_OF (X509_EXTENSION)** extensions)595f475ad27Stb test_x509v3_add1_i2d_invalid_operations(STACK_OF(X509_EXTENSION) **extensions)
596f475ad27Stb {
597f475ad27Stb 	BASIC_CONSTRAINTS *bc = NULL;
598f475ad27Stb 	long error;
599f475ad27Stb 	int crit, got, nid, op;
600f475ad27Stb 	int failed = 1;
601f475ad27Stb 
602f475ad27Stb 	if (X509v3_get_ext_count(*extensions) != 0) {
603f475ad27Stb 		fprintf(stderr, "%s: FAIL: need empty stack.\n", __func__);
604f475ad27Stb 		goto err;
605f475ad27Stb 	}
606f475ad27Stb 
607f475ad27Stb 	/*
608f475ad27Stb 	 * Attempt to add a basic constraint extension with invalid operations
609f475ad27Stb 	 */
610f475ad27Stb 
611f475ad27Stb 	nid = NID_basic_constraints;
612f475ad27Stb 	bc = create_basic_constraints(1);
613f475ad27Stb 	crit = 1;
614f475ad27Stb 	for (op = X509V3_ADD_DELETE + 1; op <= X509V3_ADD_OP_MASK; op++) {
615f475ad27Stb 		if ((got = X509V3_add1_i2d(extensions, nid, bc, crit, op)) != -1) {
616f475ad27Stb 			fprintf(stderr, "%s: FAIL: operation %d "
617f475ad27Stb 			    "want %d, got %d.\n", __func__, op, -1, got);
618f475ad27Stb 			goto err;
619f475ad27Stb 		}
620f475ad27Stb 		error = ERR_get_error();
621f475ad27Stb 		if (ERR_GET_REASON(error) != X509V3_R_UNSUPPORTED_OPTION) {
622f475ad27Stb 			fprintf(stderr, "%s: FAIL: invalid operation %d "
623f475ad27Stb 			    " pushed %d, want %d.\n", __func__, op,
624f475ad27Stb 			    ERR_GET_REASON(error), X509V3_R_EXTENSION_EXISTS);
625f475ad27Stb 			goto err;
626f475ad27Stb 		}
627f475ad27Stb 	}
628f475ad27Stb 	BASIC_CONSTRAINTS_free(bc);
629f475ad27Stb 	bc = NULL;
630f475ad27Stb 
631f475ad27Stb 	if ((got = X509v3_get_ext_count(*extensions)) != 0) {
632f475ad27Stb 		fprintf(stderr, "%s: FAIL: expected 0 extensions, have %d.\n",
633f475ad27Stb 		    __func__, got);
634f475ad27Stb 		goto err;
635f475ad27Stb 	}
636f475ad27Stb 
637f475ad27Stb 	failed = 0;
638f475ad27Stb 
639f475ad27Stb  err:
640f475ad27Stb 	BASIC_CONSTRAINTS_free(bc);
641f475ad27Stb 
642f475ad27Stb 	return failed;
643f475ad27Stb }
644f475ad27Stb 
645f475ad27Stb static int
test_x509v3_add1_i2d(void)6465f283da1Stb test_x509v3_add1_i2d(void)
6475f283da1Stb {
6485f283da1Stb 	STACK_OF(X509_EXTENSION) *extensions;
6495f283da1Stb 	int failed = 0;
6505f283da1Stb 
6515f283da1Stb 	if ((extensions = sk_X509_EXTENSION_new_null()) == NULL)
6525f283da1Stb 		errx(1, "sk_X509_EXTENSION_new_null");
6535f283da1Stb 
6545f283da1Stb 	failed |= test_x509v3_add1_i2d_empty_stack(&extensions);
6555f283da1Stb 	failed |= test_x509v3_add1_i2d_single_nid(&extensions);
6565f283da1Stb 	failed |= test_x509v3_add1_i2d_add_append(&extensions);
657f475ad27Stb 	failed |= test_x509v3_add1_i2d_invalid_operations(&extensions);
6585f283da1Stb 
6595f283da1Stb 	sk_X509_EXTENSION_pop_free(extensions, X509_EXTENSION_free);
6605f283da1Stb 
6615f283da1Stb 	return failed;
6625f283da1Stb }
6635f283da1Stb 
664*a1ec0f80Stb static int
test_x509v3_get_d2i_null(void)665*a1ec0f80Stb test_x509v3_get_d2i_null(void)
666*a1ec0f80Stb {
667*a1ec0f80Stb 	X509_EXTENSION *ext;
668*a1ec0f80Stb 	int crit, idx;
669*a1ec0f80Stb 	int failed = 1;
670*a1ec0f80Stb 
671*a1ec0f80Stb 	if ((ext = X509V3_get_d2i(NULL, NID_undef, NULL, NULL)) != NULL) {
672*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s: expected X509V3_get_d2i with three "
673*a1ec0f80Stb 		    "NULL arguments to return NULL\n", __func__);
674*a1ec0f80Stb 		goto err;
675*a1ec0f80Stb 	}
676*a1ec0f80Stb 
677*a1ec0f80Stb 	idx = -5;
678*a1ec0f80Stb 	if (X509V3_get_d2i(NULL, NID_undef, &crit, &idx) != NULL) {
679*a1ec0f80Stb 		/* Leaks whatever garbage libcrypto decoded. What to do... */
680*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s: expected X509V3_get_d2i NULL stack"
681*a1ec0f80Stb 		    "to return NULL\n", __func__);
682*a1ec0f80Stb 		goto err;
683*a1ec0f80Stb 	}
684*a1ec0f80Stb 
685*a1ec0f80Stb 	if (crit != -1 || idx != -1) {
686*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s: crit: want: %d, got: %d; "
687*a1ec0f80Stb 		    "idx: want: %d, got: %d\n", __func__, -1, crit, -1, idx);
688*a1ec0f80Stb 		goto err;
689*a1ec0f80Stb 	}
690*a1ec0f80Stb 
691*a1ec0f80Stb 	failed = 0;
692*a1ec0f80Stb 
693*a1ec0f80Stb  err:
694*a1ec0f80Stb 	X509_EXTENSION_free(ext);
695*a1ec0f80Stb 
696*a1ec0f80Stb 	return failed;
697*a1ec0f80Stb }
698*a1ec0f80Stb 
699*a1ec0f80Stb static int
test_x509v3_get_d2i_multiple_basic_constraints(void)700*a1ec0f80Stb test_x509v3_get_d2i_multiple_basic_constraints(void)
701*a1ec0f80Stb {
702*a1ec0f80Stb 	STACK_OF(X509_EXTENSION) *exts = NULL;
703*a1ec0f80Stb 	ASN1_BIT_STRING *abs = NULL;
704*a1ec0f80Stb 	BASIC_CONSTRAINTS *bc = NULL;
705*a1ec0f80Stb 	X509_EXTENSION *ext;
706*a1ec0f80Stb 	int crit, idx;
707*a1ec0f80Stb 	int ca, nid;
708*a1ec0f80Stb 	int failed = 1;
709*a1ec0f80Stb 
710*a1ec0f80Stb 	/*
711*a1ec0f80Stb 	 * Create extension stack containing three basic constraints extensions:
712*a1ec0f80Stb 	 * 1. critical CA basic constraints,
713*a1ec0f80Stb 	 * 2. non-critical CA basic constraints,
714*a1ec0f80Stb 	 * 3. critical non-CA basic constraints.
715*a1ec0f80Stb 	 */
716*a1ec0f80Stb 
717*a1ec0f80Stb 	if ((exts = sk_X509_EXTENSION_new_null()) == NULL)
718*a1ec0f80Stb 		errx(1, "sk_X509_EXTENSION_new_null");
719*a1ec0f80Stb 
720*a1ec0f80Stb 	ca = 1;
721*a1ec0f80Stb 	ext = ext_create_basic_constraints(ca, X509V3_EXT_CRITICAL);
722*a1ec0f80Stb 
723*a1ec0f80Stb 	if (sk_X509_EXTENSION_push(exts, ext) <= 0)
724*a1ec0f80Stb 		errx(1, "sk_X509_EXTENSION_push");
725*a1ec0f80Stb 	ext = NULL;
726*a1ec0f80Stb 
727*a1ec0f80Stb 	ca = 1;
728*a1ec0f80Stb 	ext = ext_create_basic_constraints(ca, X509V3_EXT_NONCRITICAL);
729*a1ec0f80Stb 
730*a1ec0f80Stb 	if (sk_X509_EXTENSION_push(exts, ext) <= 0)
731*a1ec0f80Stb 		errx(1, "sk_X509_EXTENSION_push");
732*a1ec0f80Stb 	ext = NULL;
733*a1ec0f80Stb 
734*a1ec0f80Stb 	ca = 0;
735*a1ec0f80Stb 	ext = ext_create_basic_constraints(ca, X509V3_EXT_CRITICAL);
736*a1ec0f80Stb 
737*a1ec0f80Stb 	if (sk_X509_EXTENSION_push(exts, ext) <= 0)
738*a1ec0f80Stb 		errx(1, "sk_X509_EXTENSION_push");
739*a1ec0f80Stb 	ext = NULL;
740*a1ec0f80Stb 
741*a1ec0f80Stb 	/*
742*a1ec0f80Stb 	 * There is no key usage in this stack, so we shouldn't find any.
743*a1ec0f80Stb 	 */
744*a1ec0f80Stb 
745*a1ec0f80Stb 	nid = NID_key_usage;
746*a1ec0f80Stb 	if ((abs = X509V3_get_d2i(exts, nid, &crit, NULL)) != NULL) {
747*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s: found key usage extension\n",
748*a1ec0f80Stb 		    __func__);
749*a1ec0f80Stb 		goto err;
750*a1ec0f80Stb 	}
751*a1ec0f80Stb 	if (crit != -1) {
752*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s: key usage: crit: want %d, got %d\n",
753*a1ec0f80Stb 		    __func__, -1, crit);
754*a1ec0f80Stb 		goto err;
755*a1ec0f80Stb 	}
756*a1ec0f80Stb 
757*a1ec0f80Stb 	/*
758*a1ec0f80Stb 	 * If we pass no idx and look for basic constraints,
759*a1ec0f80Stb 	 * we should fail with crit == -2.
760*a1ec0f80Stb 	 */
761*a1ec0f80Stb 
762*a1ec0f80Stb 	nid = NID_basic_constraints;
763*a1ec0f80Stb 	if ((bc = X509V3_get_d2i(exts, nid, &crit, NULL)) != NULL) {
764*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s (NULL idx): did not expect to find "
765*a1ec0f80Stb 		    "basic constraints\n", __func__);
766*a1ec0f80Stb 		goto err;
767*a1ec0f80Stb 	}
768*a1ec0f80Stb 	if (crit != -2) {
769*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s: basic constraints, no idx: \n"
770*a1ec0f80Stb 		    "crit: want %d, got %d\n", __func__, -2, crit);
771*a1ec0f80Stb 		goto err;
772*a1ec0f80Stb 	}
773*a1ec0f80Stb 
774*a1ec0f80Stb 	/*
775*a1ec0f80Stb 	 * If we pass idx = -1 and look for basic constraints, we should find
776*a1ec0f80Stb 	 * the first one: it is critical at idx = 0, with ca bit set to true.
777*a1ec0f80Stb 	 */
778*a1ec0f80Stb 
779*a1ec0f80Stb 	nid = NID_basic_constraints;
780*a1ec0f80Stb 	idx = -1;
781*a1ec0f80Stb 	if ((bc = X509V3_get_d2i(exts, nid, &crit, &idx)) == NULL) {
782*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s (idx %d): expected to find"
783*a1ec0f80Stb 		    "basic constraints\n", __func__, -1);
784*a1ec0f80Stb 		goto err;
785*a1ec0f80Stb 	}
786*a1ec0f80Stb 	if (crit != 1) {
787*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
788*a1ec0f80Stb 		    "crit: want %d, got %d\n", __func__, -1, 1, crit);
789*a1ec0f80Stb 		goto err;
790*a1ec0f80Stb 	}
791*a1ec0f80Stb 	if (idx != 0) {
792*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
793*a1ec0f80Stb 		    "idx: want %d, got %d\n", __func__, -1, 0, idx);
794*a1ec0f80Stb 		goto err;
795*a1ec0f80Stb 	}
796*a1ec0f80Stb 	if (bc->ca != ASN1_BOOLEAN_TRUE) {
797*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
798*a1ec0f80Stb 		    "cA bit: want %x, got %x\n", __func__, -1,
799*a1ec0f80Stb 		    ASN1_BOOLEAN_TRUE, bc->ca);
800*a1ec0f80Stb 		goto err;
801*a1ec0f80Stb 	}
802*a1ec0f80Stb 	BASIC_CONSTRAINTS_free(bc);
803*a1ec0f80Stb 	bc = NULL;
804*a1ec0f80Stb 
805*a1ec0f80Stb 	/*
806*a1ec0f80Stb 	 * Now pass idx = 0 and look for basic constraints, we should find
807*a1ec0f80Stb 	 * the second one: non-critical at idx = 1, with ca bit set to true.
808*a1ec0f80Stb 	 */
809*a1ec0f80Stb 
810*a1ec0f80Stb 	nid = NID_basic_constraints;
811*a1ec0f80Stb 	idx = 0;
812*a1ec0f80Stb 	if ((bc = X509V3_get_d2i(exts, nid, &crit, &idx)) == NULL) {
813*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s (idx %d): expected to find"
814*a1ec0f80Stb 		    "basic constraints\n", __func__, 0);
815*a1ec0f80Stb 		goto err;
816*a1ec0f80Stb 	}
817*a1ec0f80Stb 	if (crit != 0) {
818*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
819*a1ec0f80Stb 		    "crit: want %d, got %d\n", __func__, 0, 0, crit);
820*a1ec0f80Stb 		goto err;
821*a1ec0f80Stb 	}
822*a1ec0f80Stb 	if (idx != 1) {
823*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
824*a1ec0f80Stb 		    "idx: want %d, got %d\n", __func__, 0, 1, idx);
825*a1ec0f80Stb 		goto err;
826*a1ec0f80Stb 	}
827*a1ec0f80Stb 	if (bc->ca != ASN1_BOOLEAN_TRUE) {
828*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
829*a1ec0f80Stb 		    "cA bit: want %x, got %x\n", __func__, 0,
830*a1ec0f80Stb 		    ASN1_BOOLEAN_TRUE, bc->ca);
831*a1ec0f80Stb 		goto err;
832*a1ec0f80Stb 	}
833*a1ec0f80Stb 	BASIC_CONSTRAINTS_free(bc);
834*a1ec0f80Stb 	bc = NULL;
835*a1ec0f80Stb 
836*a1ec0f80Stb 	/*
837*a1ec0f80Stb 	 * Now pass idx = 1 and look for basic constraints, we should find the
838*a1ec0f80Stb 	 * third one: critical at idx = 2, with ca bit set to false.
839*a1ec0f80Stb 	 */
840*a1ec0f80Stb 
841*a1ec0f80Stb 	nid = NID_basic_constraints;
842*a1ec0f80Stb 	idx = 1;
843*a1ec0f80Stb 	if ((bc = X509V3_get_d2i(exts, nid, &crit, &idx)) == NULL) {
844*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s (idx %d): expected to find"
845*a1ec0f80Stb 		    "basic constraints\n", __func__, 1);
846*a1ec0f80Stb 		goto err;
847*a1ec0f80Stb 	}
848*a1ec0f80Stb 	if (crit != 1) {
849*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
850*a1ec0f80Stb 		    "crit: want %d, got %d\n", __func__, 1, 0, crit);
851*a1ec0f80Stb 		goto err;
852*a1ec0f80Stb 	}
853*a1ec0f80Stb 	if (idx != 2) {
854*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
855*a1ec0f80Stb 		    "idx: want %d, got %d\n", __func__, 1, 2, idx);
856*a1ec0f80Stb 		goto err;
857*a1ec0f80Stb 	}
858*a1ec0f80Stb 	if (bc->ca != ASN1_BOOLEAN_FALSE) {
859*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
860*a1ec0f80Stb 		    "cA bit: want %x, got %x\n", __func__, 1,
861*a1ec0f80Stb 		    ASN1_BOOLEAN_FALSE, bc->ca);
862*a1ec0f80Stb 		goto err;
863*a1ec0f80Stb 	}
864*a1ec0f80Stb 	BASIC_CONSTRAINTS_free(bc);
865*a1ec0f80Stb 	bc = NULL;
866*a1ec0f80Stb 
867*a1ec0f80Stb 	/*
868*a1ec0f80Stb 	 * Finally, pass idx = 2 and we should find no basic constraints.
869*a1ec0f80Stb 	 */
870*a1ec0f80Stb 
871*a1ec0f80Stb 	nid = NID_basic_constraints;
872*a1ec0f80Stb 	idx = 2;
873*a1ec0f80Stb 	if ((bc = X509V3_get_d2i(exts, nid, &crit, &idx)) != NULL) {
874*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s (idx %d): expected to find"
875*a1ec0f80Stb 		    "no basic constraints\n", __func__, 2);
876*a1ec0f80Stb 		goto err;
877*a1ec0f80Stb 	}
878*a1ec0f80Stb 	if (crit != -1) {
879*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
880*a1ec0f80Stb 		    "crit: want %d, got %d\n", __func__, 2, -1, crit);
881*a1ec0f80Stb 		goto err;
882*a1ec0f80Stb 	}
883*a1ec0f80Stb 	if (idx != -1) {
884*a1ec0f80Stb 		fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
885*a1ec0f80Stb 		    "idx: want %d, got %d\n", __func__, 2, -1, idx);
886*a1ec0f80Stb 		goto err;
887*a1ec0f80Stb 	}
888*a1ec0f80Stb 
889*a1ec0f80Stb 	failed = 0;
890*a1ec0f80Stb 
891*a1ec0f80Stb  err:
892*a1ec0f80Stb 	sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
893*a1ec0f80Stb 	ASN1_BIT_STRING_free(abs);
894*a1ec0f80Stb 	BASIC_CONSTRAINTS_free(bc);
895*a1ec0f80Stb 
896*a1ec0f80Stb 	return failed;
897*a1ec0f80Stb }
898*a1ec0f80Stb 
899*a1ec0f80Stb static int
test_x509v3_get_d2i(void)900*a1ec0f80Stb test_x509v3_get_d2i(void)
901*a1ec0f80Stb {
902*a1ec0f80Stb 	int failed = 0;
903*a1ec0f80Stb 
904*a1ec0f80Stb 	failed |= test_x509v3_get_d2i_null();
905*a1ec0f80Stb 	failed |= test_x509v3_get_d2i_multiple_basic_constraints();
906*a1ec0f80Stb 
907*a1ec0f80Stb 	return failed;
908*a1ec0f80Stb }
909*a1ec0f80Stb 
9105f283da1Stb int
main(void)9115f283da1Stb main(void)
9125f283da1Stb {
9135f283da1Stb 	int failed = 0;
9145f283da1Stb 
9155f283da1Stb 	failed |= test_x509v3_add1_i2d();
916*a1ec0f80Stb 	failed |= test_x509v3_get_d2i();
9175f283da1Stb 
9185f283da1Stb 	return failed;
9195f283da1Stb }
920