#include <err.h>
#include <stdio.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#define ASN1_BOOLEAN_TRUE 0xff
#define ASN1_BOOLEAN_FALSE 0x00
#define X509V3_EXT_CRITICAL 1
#define X509V3_EXT_NONCRITICAL 0
static BASIC_CONSTRAINTS *
create_basic_constraints(int ca)
{
BASIC_CONSTRAINTS *bc;
if ((bc = BASIC_CONSTRAINTS_new()) == NULL)
errx(1, "BASIC_CONSTRAINTS_new");
bc->ca = ca ? ASN1_BOOLEAN_TRUE : ASN1_BOOLEAN_FALSE;
return bc;
}
static X509_EXTENSION *
ext_create_basic_constraints(int ca, int critical)
{
X509_EXTENSION *ext;
BASIC_CONSTRAINTS *bc;
bc = create_basic_constraints(ca);
if ((ext = X509V3_EXT_i2d(NID_basic_constraints, critical, bc)) == NULL)
errx(1, "X509V3_EXT_i2d");
BASIC_CONSTRAINTS_free(bc);
return ext;
}
static int
test_x509v3_add1_i2d_empty_stack(STACK_OF(X509_EXTENSION) **extensions)
{
unsigned long error;
int op, got;
int nid = NID_basic_constraints;
int failed = 1;
if (X509v3_get_ext_count(*extensions) != 0) {
fprintf(stderr, "%s: FAIL: need empty stack\n", __func__);
goto err;
}
ERR_clear_error();
op = X509V3_ADD_REPLACE_EXISTING;
if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 0) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING "
"want %d, got %d.\n", __func__, 0, got);
goto err;
}
error = ERR_get_error();
if (ERR_GET_REASON(error) != X509V3_R_EXTENSION_NOT_FOUND) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING "
"pushed %d for empty stack, want %d.\n", __func__,
ERR_GET_REASON(error), X509V3_R_EXTENSION_NOT_FOUND);
goto err;
}
if ((error = ERR_get_error()) != 0) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING "
"expected exactly one error.\n", __func__);
goto err;
}
op = X509V3_ADD_REPLACE_EXISTING | X509V3_ADD_SILENT;
if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 0) {
fprintf(stderr, "%s: FAIL: silent X509V3_ADD_REPLACE_EXISTING "
"want %d, got %d.\n", __func__, 0, got);
goto err;
}
if ((error = ERR_get_error()) != 0) {
fprintf(stderr, "%s: FAIL: silent X509V3_ADD_REPLACE_EXISTING "
"added error %d, want %d.\n", __func__,
ERR_GET_REASON(error), 0);
goto err;
}
op = X509V3_ADD_DELETE;
if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 0) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
"want %d, got %d.\n", __func__, 0, got);
goto err;
}
error = ERR_get_error();
if (ERR_GET_REASON(error) != X509V3_R_EXTENSION_NOT_FOUND) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
"pushed %d for empty stack, want %d.\n", __func__,
ERR_GET_REASON(error), X509V3_R_EXTENSION_NOT_FOUND);
goto err;
}
if ((error = ERR_get_error()) != 0) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
"expected exactly one error.\n", __func__);
goto err;
}
failed = 0;
err:
return failed;
}
static int
test_x509v3_add1_i2d_single_nid(STACK_OF(X509_EXTENSION) **extensions)
{
BASIC_CONSTRAINTS *bc = NULL;
unsigned long error;
int crit, got, nid, op;
int failed = 1;
if (X509v3_get_ext_count(*extensions) != 0) {
fprintf(stderr, "%s: FAIL: need an empty stack.\n", __func__);
goto err;
}
nid = NID_basic_constraints;
bc = create_basic_constraints(1);
op = X509V3_ADD_DEFAULT;
if ((got = X509V3_add1_i2d(extensions, nid, bc, 1, op)) != 1) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_DEFAULT failed to add "
"basic constraints to empty stack: want %d, got %d.\n",
__func__, 1, got);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
if ((got = X509v3_get_ext_count(*extensions)) != 1) {
fprintf(stderr, "%s: FAIL: expected 1 extension, have %d.\n",
__func__, got);
goto err;
}
nid = NID_policy_constraints;
op = X509V3_ADD_DELETE;
if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 0) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE non-existent "
"want %d, got %d,\n", __func__, 0, got);
goto err;
}
nid = NID_policy_constraints;
op = X509V3_ADD_REPLACE_EXISTING;
if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 0) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING non-existent "
"want %d, got %d.\n", __func__, 0, got);
goto err;
}
ERR_clear_error();
nid = NID_basic_constraints;
bc = create_basic_constraints(0);
op = X509V3_ADD_DEFAULT;
if ((got = X509V3_add1_i2d(extensions, nid, bc, 1, op)) != 0) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_DEFAULT second constraints "
"want %d, got %d.\n", __func__, 0, got);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
error = ERR_get_error();
if (ERR_GET_REASON(error) != X509V3_R_EXTENSION_EXISTS) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_DEFAULT second constraints "
" pushed %d, want %d.\n", __func__,
ERR_GET_REASON(error), X509V3_R_EXTENSION_EXISTS);
goto err;
}
if ((got = X509v3_get_ext_count(*extensions)) != 1) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_DEFAULT second constraints "
"expected 1 extension, have %d.\n", __func__, got);
goto err;
}
nid = NID_basic_constraints;
bc = create_basic_constraints(0);
op = X509V3_ADD_REPLACE;
if ((got = X509V3_add1_i2d(extensions, nid, bc, 1, op)) != 1) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
"want %d, got %d.\n", __func__, 1, got);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
if ((got = X509v3_get_ext_count(*extensions)) != 1) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
"expected 1 extension, have %d.\n", __func__, got);
goto err;
}
nid = NID_basic_constraints;
if ((bc = X509V3_get_d2i(*extensions, nid, &crit, NULL)) == NULL) {
if (crit != -1)
errx(1, "X509V3_get_d2i");
fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
"expected basic constraints\n", __func__);
goto err;
}
if (bc->ca != ASN1_BOOLEAN_FALSE) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
"expected cA = false in basic constraints\n", __func__);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
nid = NID_basic_constraints;
bc = create_basic_constraints(1);
op = X509V3_ADD_KEEP_EXISTING;
if ((got = X509V3_add1_i2d(extensions, nid, bc, 1, op)) != 1) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_KEEP_EXISTING "
"want %d, got %d.\n", __func__, 1, got);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
nid = NID_basic_constraints;
if ((bc = X509V3_get_d2i(*extensions, nid, &crit, NULL)) == NULL) {
if (crit != -1)
errx(1, "X509V3_get_d2i");
fprintf(stderr, "%s: FAIL: X509V3_ADD_KEEP_EXISTING "
"expected basic constraints\n", __func__);
goto err;
}
if (bc->ca != ASN1_BOOLEAN_FALSE) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_KEEP_EXISTING "
"expected non-ca basic constraints\n", __func__);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
nid = NID_basic_constraints;
bc = create_basic_constraints(1);
op = X509V3_ADD_REPLACE_EXISTING;
if ((got = X509V3_add1_i2d(extensions, nid, bc, 1, op)) != 1) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING "
"want %d, got %d.\n", __func__, 1, got);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
nid = NID_basic_constraints;
if ((bc = X509V3_get_d2i(*extensions, nid, &crit, NULL)) == NULL) {
if (crit != -1)
errx(1, "X509V3_get_d2i");
fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING "
"expected basic constraints\n", __func__);
goto err;
}
if (bc->ca != ASN1_BOOLEAN_TRUE) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE_EXISTING "
"expected ca basic constraints\n", __func__);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
nid = NID_basic_constraints;
op = X509V3_ADD_DELETE;
if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 1) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
"want %d, got %d.\n", __func__, 0, got);
goto err;
}
if ((got = X509v3_get_ext_count(*extensions)) != 0) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
"expected 0 extensions, have %d.\n", __func__, got);
goto err;
}
nid = NID_basic_constraints;
bc = create_basic_constraints(0);
op = X509V3_ADD_REPLACE;
if ((got = X509V3_add1_i2d(extensions, nid, bc, 1, op)) != 1) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE on empty stack "
"want %d, got %d.\n", __func__, 1, got);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
if ((got = X509v3_get_ext_count(*extensions)) != 1) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
"expected 1 extension, have %d.\n", __func__, got);
goto err;
}
nid = NID_basic_constraints;
op = X509V3_ADD_DELETE;
if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 1) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE after add replace "
"want %d, got %d.\n", __func__, 0, got);
goto err;
}
if ((got = X509v3_get_ext_count(*extensions)) != 0) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
"expected 0 extensions, have %d.\n", __func__, got);
goto err;
}
failed = 0;
err:
BASIC_CONSTRAINTS_free(bc);
return failed;
}
static int
test_x509v3_add1_i2d_add_append(STACK_OF(X509_EXTENSION) **extensions)
{
BASIC_CONSTRAINTS *bc = NULL;
int crit, got, idx, nid, op;
int failed = 1;
if (X509v3_get_ext_count(*extensions) != 0) {
fprintf(stderr, "%s: FAIL: need empty stack.\n", __func__);
goto err;
}
nid = NID_basic_constraints;
bc = create_basic_constraints(1);
crit = 1;
op = X509V3_ADD_APPEND;
if ((got = X509V3_add1_i2d(extensions, nid, bc, crit, op)) != 1) {
fprintf(stderr, "%s: FAIL: first X509V3_ADD_APPEND "
"want %d, got %d.\n", __func__, 0, got);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
nid = NID_basic_constraints;
bc = create_basic_constraints(0);
crit = 1;
op = X509V3_ADD_APPEND;
if ((got = X509V3_add1_i2d(extensions, nid, bc, crit, op)) != 1) {
fprintf(stderr, "%s: FAIL: second X509V3_ADD_APPEND "
"want %d, got %d.\n", __func__, 0, got);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
if ((got = X509v3_get_ext_count(*extensions)) != 2) {
fprintf(stderr, "%s: FAIL: second X509V3_ADD_APPEND "
"expected 2 extensions, have %d.\n", __func__, got);
goto err;
}
nid = NID_basic_constraints;
idx = -1;
if ((bc = X509V3_get_d2i(*extensions, nid, &crit, &idx)) == NULL) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_APPEND "
"expected basic constraints.\n", __func__);
goto err;
}
if (bc->ca != ASN1_BOOLEAN_TRUE) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_APPEND "
"expected ca basic constraints.\n", __func__);
goto err;
}
if (crit != 1) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_APPEND "
"expected critical basic constraints.\n", __func__);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
nid = NID_basic_constraints;
if ((bc = X509V3_get_d2i(*extensions, nid, &crit, &idx)) == NULL) {
fprintf(stderr, "%s: FAIL: second X509V3_ADD_APPEND "
"expected basic constraints.\n", __func__);
goto err;
}
if (bc->ca != ASN1_BOOLEAN_FALSE) {
fprintf(stderr, "%s: FAIL: second X509V3_ADD_APPEND "
"expected basic constraints to be non-ca.\n", __func__);
goto err;
}
if (crit != 1) {
fprintf(stderr, "%s: FAIL: second X509V3_ADD_APPEND "
"expected critical basic constraints.\n", __func__);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
nid = NID_basic_constraints;
bc = create_basic_constraints(1);
crit = 0;
op = X509V3_ADD_REPLACE;
if ((got = X509V3_add1_i2d(extensions, nid, bc, crit, op)) != 1) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
"want %d, got %d\n", __func__, 1, got);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
nid = NID_basic_constraints;
idx = -1;
if ((bc = X509V3_get_d2i(*extensions, nid, &crit, &idx)) == NULL) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
"expected basic constraints.\n", __func__);
goto err;
}
if (bc->ca != ASN1_BOOLEAN_TRUE) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
"expected ca basic constraints.\n", __func__);
goto err;
}
if (crit != 0) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
"expected non-critical basic constraints.\n", __func__);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
if ((got = X509v3_get_ext_count(*extensions)) != 2) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_REPLACE "
"expected 2 extensions, got %d.\n", __func__, got);
goto err;
}
nid = NID_basic_constraints;
op = X509V3_ADD_DELETE;
if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 1) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
"want %d, got %d\n", __func__, 1, got);
goto err;
}
if ((got = X509v3_get_ext_count(*extensions)) != 1) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
"expected 1 extension, got %d.\n", __func__, got);
goto err;
}
nid = NID_basic_constraints;
idx = -1;
if ((bc = X509V3_get_d2i(*extensions, nid, &crit, &idx)) == NULL) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
"expected basic constraints.\n", __func__);
goto err;
}
if (bc->ca != ASN1_BOOLEAN_FALSE) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
"expected ca basic constraints.\n", __func__);
goto err;
}
if (crit != 1) {
fprintf(stderr, "%s: FAIL: X509V3_ADD_DELETE "
"expected critical basic constraints.\n", __func__);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
nid = NID_basic_constraints;
op = X509V3_ADD_DELETE;
if ((got = X509V3_add1_i2d(extensions, nid, NULL, 0, op)) != 1) {
fprintf(stderr, "%s: FAIL: second X509V3_ADD_DELETE "
"want %d, got %d\n", __func__, 1, got);
goto err;
}
if ((got = X509v3_get_ext_count(*extensions)) != 0) {
fprintf(stderr, "%s: FAIL: second X509V3_ADD_DELETE "
"expected 0 extensions, got %d.\n", __func__, got);
goto err;
}
failed = 0;
err:
BASIC_CONSTRAINTS_free(bc);
return failed;
}
static int
test_x509v3_add1_i2d_invalid_operations(STACK_OF(X509_EXTENSION) **extensions)
{
BASIC_CONSTRAINTS *bc = NULL;
long error;
int crit, got, nid, op;
int failed = 1;
if (X509v3_get_ext_count(*extensions) != 0) {
fprintf(stderr, "%s: FAIL: need empty stack.\n", __func__);
goto err;
}
nid = NID_basic_constraints;
bc = create_basic_constraints(1);
crit = 1;
for (op = X509V3_ADD_DELETE + 1; op <= X509V3_ADD_OP_MASK; op++) {
if ((got = X509V3_add1_i2d(extensions, nid, bc, crit, op)) != -1) {
fprintf(stderr, "%s: FAIL: operation %d "
"want %d, got %d.\n", __func__, op, -1, got);
goto err;
}
error = ERR_get_error();
if (ERR_GET_REASON(error) != X509V3_R_UNSUPPORTED_OPTION) {
fprintf(stderr, "%s: FAIL: invalid operation %d "
" pushed %d, want %d.\n", __func__, op,
ERR_GET_REASON(error), X509V3_R_EXTENSION_EXISTS);
goto err;
}
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
if ((got = X509v3_get_ext_count(*extensions)) != 0) {
fprintf(stderr, "%s: FAIL: expected 0 extensions, have %d.\n",
__func__, got);
goto err;
}
failed = 0;
err:
BASIC_CONSTRAINTS_free(bc);
return failed;
}
static int
test_x509v3_add1_i2d(void)
{
STACK_OF(X509_EXTENSION) *extensions;
int failed = 0;
if ((extensions = sk_X509_EXTENSION_new_null()) == NULL)
errx(1, "sk_X509_EXTENSION_new_null");
failed |= test_x509v3_add1_i2d_empty_stack(&extensions);
failed |= test_x509v3_add1_i2d_single_nid(&extensions);
failed |= test_x509v3_add1_i2d_add_append(&extensions);
failed |= test_x509v3_add1_i2d_invalid_operations(&extensions);
sk_X509_EXTENSION_pop_free(extensions, X509_EXTENSION_free);
return failed;
}
static int
test_x509v3_get_d2i_null(void)
{
X509_EXTENSION *ext;
int crit, idx;
int failed = 1;
if ((ext = X509V3_get_d2i(NULL, NID_undef, NULL, NULL)) != NULL) {
fprintf(stderr, "FAIL: %s: expected X509V3_get_d2i with three "
"NULL arguments to return NULL\n", __func__);
goto err;
}
idx = -5;
if (X509V3_get_d2i(NULL, NID_undef, &crit, &idx) != NULL) {
fprintf(stderr, "FAIL: %s: expected X509V3_get_d2i NULL stack"
"to return NULL\n", __func__);
goto err;
}
if (crit != -1 || idx != -1) {
fprintf(stderr, "FAIL: %s: crit: want: %d, got: %d; "
"idx: want: %d, got: %d\n", __func__, -1, crit, -1, idx);
goto err;
}
failed = 0;
err:
X509_EXTENSION_free(ext);
return failed;
}
static int
test_x509v3_get_d2i_multiple_basic_constraints(void)
{
STACK_OF(X509_EXTENSION) *exts = NULL;
ASN1_BIT_STRING *abs = NULL;
BASIC_CONSTRAINTS *bc = NULL;
X509_EXTENSION *ext;
int crit, idx;
int ca, nid;
int failed = 1;
if ((exts = sk_X509_EXTENSION_new_null()) == NULL)
errx(1, "sk_X509_EXTENSION_new_null");
ca = 1;
ext = ext_create_basic_constraints(ca, X509V3_EXT_CRITICAL);
if (sk_X509_EXTENSION_push(exts, ext) <= 0)
errx(1, "sk_X509_EXTENSION_push");
ext = NULL;
ca = 1;
ext = ext_create_basic_constraints(ca, X509V3_EXT_NONCRITICAL);
if (sk_X509_EXTENSION_push(exts, ext) <= 0)
errx(1, "sk_X509_EXTENSION_push");
ext = NULL;
ca = 0;
ext = ext_create_basic_constraints(ca, X509V3_EXT_CRITICAL);
if (sk_X509_EXTENSION_push(exts, ext) <= 0)
errx(1, "sk_X509_EXTENSION_push");
ext = NULL;
nid = NID_key_usage;
if ((abs = X509V3_get_d2i(exts, nid, &crit, NULL)) != NULL) {
fprintf(stderr, "FAIL: %s: found key usage extension\n",
__func__);
goto err;
}
if (crit != -1) {
fprintf(stderr, "FAIL: %s: key usage: crit: want %d, got %d\n",
__func__, -1, crit);
goto err;
}
nid = NID_basic_constraints;
if ((bc = X509V3_get_d2i(exts, nid, &crit, NULL)) != NULL) {
fprintf(stderr, "FAIL: %s (NULL idx): did not expect to find "
"basic constraints\n", __func__);
goto err;
}
if (crit != -2) {
fprintf(stderr, "FAIL: %s: basic constraints, no idx: \n"
"crit: want %d, got %d\n", __func__, -2, crit);
goto err;
}
nid = NID_basic_constraints;
idx = -1;
if ((bc = X509V3_get_d2i(exts, nid, &crit, &idx)) == NULL) {
fprintf(stderr, "FAIL: %s (idx %d): expected to find"
"basic constraints\n", __func__, -1);
goto err;
}
if (crit != 1) {
fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
"crit: want %d, got %d\n", __func__, -1, 1, crit);
goto err;
}
if (idx != 0) {
fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
"idx: want %d, got %d\n", __func__, -1, 0, idx);
goto err;
}
if (bc->ca != ASN1_BOOLEAN_TRUE) {
fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
"cA bit: want %x, got %x\n", __func__, -1,
ASN1_BOOLEAN_TRUE, bc->ca);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
nid = NID_basic_constraints;
idx = 0;
if ((bc = X509V3_get_d2i(exts, nid, &crit, &idx)) == NULL) {
fprintf(stderr, "FAIL: %s (idx %d): expected to find"
"basic constraints\n", __func__, 0);
goto err;
}
if (crit != 0) {
fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
"crit: want %d, got %d\n", __func__, 0, 0, crit);
goto err;
}
if (idx != 1) {
fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
"idx: want %d, got %d\n", __func__, 0, 1, idx);
goto err;
}
if (bc->ca != ASN1_BOOLEAN_TRUE) {
fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
"cA bit: want %x, got %x\n", __func__, 0,
ASN1_BOOLEAN_TRUE, bc->ca);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
nid = NID_basic_constraints;
idx = 1;
if ((bc = X509V3_get_d2i(exts, nid, &crit, &idx)) == NULL) {
fprintf(stderr, "FAIL: %s (idx %d): expected to find"
"basic constraints\n", __func__, 1);
goto err;
}
if (crit != 1) {
fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
"crit: want %d, got %d\n", __func__, 1, 0, crit);
goto err;
}
if (idx != 2) {
fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
"idx: want %d, got %d\n", __func__, 1, 2, idx);
goto err;
}
if (bc->ca != ASN1_BOOLEAN_FALSE) {
fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
"cA bit: want %x, got %x\n", __func__, 1,
ASN1_BOOLEAN_FALSE, bc->ca);
goto err;
}
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
nid = NID_basic_constraints;
idx = 2;
if ((bc = X509V3_get_d2i(exts, nid, &crit, &idx)) != NULL) {
fprintf(stderr, "FAIL: %s (idx %d): expected to find"
"no basic constraints\n", __func__, 2);
goto err;
}
if (crit != -1) {
fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
"crit: want %d, got %d\n", __func__, 2, -1, crit);
goto err;
}
if (idx != -1) {
fprintf(stderr, "FAIL: %s: basic constraints (idx %d): "
"idx: want %d, got %d\n", __func__, 2, -1, idx);
goto err;
}
failed = 0;
err:
sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
ASN1_BIT_STRING_free(abs);
BASIC_CONSTRAINTS_free(bc);
return failed;
}
static int
test_x509v3_get_d2i(void)
{
int failed = 0;
failed |= test_x509v3_get_d2i_null();
failed |= test_x509v3_get_d2i_multiple_basic_constraints();
return failed;
}
int
main(void)
{
int failed = 0;
failed |= test_x509v3_add1_i2d();
failed |= test_x509v3_get_d2i();
return failed;
}