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