Add matching on EKU, validate EKUs, add hxtool matching glue, add check. Adapted from pach from Tim Miller of Mitre

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@22538 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2008-01-27 13:05:47 +00:00
parent f2a273e1a3
commit 0ff6dbc8bb
8 changed files with 142 additions and 10 deletions

View File

@@ -1,3 +1,8 @@
2008-01-27 Love H<>rnquist <20>strand <lha@it.su.se>
* Add matching on EKU, validate EKUs, add hxtool matching glue,
add check. Adapted from pach from Tim Miller of Mitre
2008-01-21 Love H<>rnquist <20>strand <lha@it.su.se> 2008-01-21 Love H<>rnquist <20>strand <lha@it.su.se>
* test_soft_pkcs11.c: use func for more C_ functions. * test_soft_pkcs11.c: use func for more C_ functions.

View File

@@ -2609,6 +2609,40 @@ hx509_query_match_friendly_name(hx509_query *q, const char *name)
return 0; return 0;
} }
/**
* Set the query controller to require an specific EKU (extended key
* usage).
*
* @param q a hx509 query controller.
* @param eku an EKU to match on
*
* @return An hx509 error code, see hx509_get_error_string().
*
* @ingroup hx509_cert
*/
int
hx509_query_match_eku(hx509_query *q, const heim_oid *eku)
{
int ret;
if (q->eku) {
der_free_oid(q->eku);
} else {
q->eku = calloc(1, sizeof(*q->eku));
if (q->eku == NULL)
return ENOMEM;
}
ret = der_copy_oid(eku, q->eku);
if (ret) {
free(q->eku);
q->eku = NULL;
return ret;
}
q->match |= HX509_QUERY_MATCH_EKU;
return 0;
}
/** /**
* Set the query controller to match using a specific match function. * Set the query controller to match using a specific match function.
* *
@@ -2648,20 +2682,24 @@ hx509_query_match_cmp_func(hx509_query *q,
void void
hx509_query_free(hx509_context context, hx509_query *q) hx509_query_free(hx509_context context, hx509_query *q)
{ {
if (q == NULL)
return;
if (q->serial) { if (q->serial) {
der_free_heim_integer(q->serial); der_free_heim_integer(q->serial);
free(q->serial); free(q->serial);
q->serial = NULL;
} }
if (q->issuer_name) { if (q->issuer_name) {
free_Name(q->issuer_name); free_Name(q->issuer_name);
free(q->issuer_name); free(q->issuer_name);
q->issuer_name = NULL;
} }
if (q) { if (q->eku) {
der_free_oid(q->eku);
free(q->eku);
}
if (q->friendlyname)
free(q->friendlyname); free(q->friendlyname);
memset(q, 0, sizeof(*q)); memset(q, 0, sizeof(*q));
}
free(q); free(q);
} }
@@ -2790,6 +2828,11 @@ _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert
return 0; return 0;
} }
/* If an EKU is required, check the cert for it. */
if ((q->match & HX509_QUERY_MATCH_EKU) &&
hx509_cert_check_eku(context, cert, q->eku, 0))
return 0;
if (q->match & ~HX509_QUERY_MASK) if (q->match & ~HX509_QUERY_MASK)
return 0; return 0;

View File

@@ -128,7 +128,8 @@ struct hx509_query_data {
#define HX509_QUERY_MATCH_FUNCTION 0x080000 #define HX509_QUERY_MATCH_FUNCTION 0x080000
#define HX509_QUERY_MATCH_KEY_HASH_SHA1 0x100000 #define HX509_QUERY_MATCH_KEY_HASH_SHA1 0x100000
#define HX509_QUERY_MATCH_TIME 0x200000 #define HX509_QUERY_MATCH_TIME 0x200000
#define HX509_QUERY_MASK 0x3fffff #define HX509_QUERY_MATCH_EKU 0x400000
#define HX509_QUERY_MASK 0x7fffff
Certificate *subject; Certificate *subject;
Certificate *certificate; Certificate *certificate;
heim_integer *serial; heim_integer *serial;
@@ -142,6 +143,7 @@ struct hx509_query_data {
void *cmp_func_ctx; void *cmp_func_ctx;
heim_octet_string *keyhash_sha1; heim_octet_string *keyhash_sha1;
time_t timenow; time_t timenow;
heim_oid *eku;
}; };
struct hx509_keyset_ops { struct hx509_keyset_ops {

View File

@@ -437,6 +437,12 @@ command = {
argument = "name" argument = "name"
help = "match on friendly name" help = "match on friendly name"
} }
option = {
long = "eku"
type = "string"
argument = "oid-string"
help = "match on EKU"
}
option = { option = {
long = "keyEncipherment" long = "keyEncipherment"
type = "flag" type = "flag"

View File

@@ -885,6 +885,17 @@ query(struct query_options *opt, int argc, char **argv)
if (opt->friendlyname_string) if (opt->friendlyname_string)
hx509_query_match_friendly_name(q, opt->friendlyname_string); hx509_query_match_friendly_name(q, opt->friendlyname_string);
if (opt->eku_string) {
heim_oid oid;
parse_oid(opt->eku_string, NULL, &oid);
ret = hx509_query_match_eku(q, &oid);
if (ret)
errx(1, "hx509_query_match_eku: %d", ret);
der_free_oid(&oid);
}
if (opt->private_key_flag) if (opt->private_key_flag)
hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY); hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);

View File

@@ -335,9 +335,6 @@ check_authorityKeyIdentifier(hx509_validate_ctx ctx,
status->haveAKI = 1; status->haveAKI = 1;
check_Null(ctx, status, cf, e); check_Null(ctx, status, cf, e);
status->haveSKI = 1;
check_Null(ctx, status, cf, e);
ret = decode_AuthorityKeyIdentifier(e->extnValue.data, ret = decode_AuthorityKeyIdentifier(e->extnValue.data,
e->extnValue.length, e->extnValue.length,
&ai, &size); &ai, &size);
@@ -365,6 +362,56 @@ check_authorityKeyIdentifier(hx509_validate_ctx ctx,
return 0; return 0;
} }
static int
check_extKeyUsage(hx509_validate_ctx ctx,
struct cert_status *status,
enum critical_flag cf,
const Extension *e)
{
ExtKeyUsage eku;
size_t size, i;
int ret;
check_Null(ctx, status, cf, e);
ret = decode_ExtKeyUsage(e->extnValue.data,
e->extnValue.length,
&eku, &size);
if (ret) {
validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
"Decoding ExtKeyUsage failed: %d", ret);
return 1;
}
if (size != e->extnValue.length) {
validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
"Padding data in EKU");
free_ExtKeyUsage(&eku);
return 1;
}
if (eku.len == 0) {
validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
"ExtKeyUsage length is 0");
return 1;
}
for (i = 0; i < eku.len; i++) {
char *str;
ret = der_print_heim_oid (&eku.val[i], '.', &str);
if (ret) {
validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
"\tEKU: failed to print oid %d", i);
free_ExtKeyUsage(&eku);
return 1;
}
validate_print(ctx, HX509_VALIDATE_F_VERBOSE,
"\teku-%d: %s\n", i, str);;
free(str);
}
free_ExtKeyUsage(&eku);
return 0;
}
static int static int
check_pkinit_san(hx509_validate_ctx ctx, heim_any *a) check_pkinit_san(hx509_validate_ctx ctx, heim_any *a)
@@ -731,7 +778,7 @@ struct {
{ ext(policyMappings, Null), M_N_C }, { ext(policyMappings, Null), M_N_C },
{ ext(authorityKeyIdentifier, authorityKeyIdentifier), M_N_C }, { ext(authorityKeyIdentifier, authorityKeyIdentifier), M_N_C },
{ ext(policyConstraints, Null), D_C }, { ext(policyConstraints, Null), D_C },
{ ext(extKeyUsage, Null), D_C }, { ext(extKeyUsage, extKeyUsage), D_C },
{ ext(freshestCRL, Null), M_N_C }, { ext(freshestCRL, Null), M_N_C },
{ ext(inhibitAnyPolicy, Null), M_C }, { ext(inhibitAnyPolicy, Null), M_C },
#undef ext #undef ext

View File

@@ -44,8 +44,15 @@ hxtool="${TESTS_ENVIRONMENT} ./hxtool ${stat}"
echo "try printing" echo "try printing"
${hxtool} print \ ${hxtool} print \
--pass=PASS:foobar \ --pass=PASS:foobar \
--info --content \
PKCS12:$srcdir/data/test.p12 >/dev/null 2>/dev/null || exit 1 PKCS12:$srcdir/data/test.p12 >/dev/null 2>/dev/null || exit 1
echo "try printing"
${hxtool} print \
--pass=PASS:foobar \
--info --content \
FILE:$srcdir/data/kdc.crt || exit 1
${hxtool} print \ ${hxtool} print \
--pass=PASS:foobar \ --pass=PASS:foobar \
--info \ --info \
@@ -63,6 +70,16 @@ ${hxtool} query \
--friendlyname=friendlyname-test-not \ --friendlyname=friendlyname-test-not \
PKCS12:$srcdir/data/test.p12 >/dev/null 2>/dev/null && exit 1 PKCS12:$srcdir/data/test.p12 >/dev/null 2>/dev/null && exit 1
echo "make sure entry is found (eku)"
${hxtool} query \
--eku=1.3.6.1.5.2.3.5 \
FILE:$srcdir/data/kdc.crt >/dev/null 2>/dev/null || exit 1
echo "make sure entry is not found (eku)"
${hxtool} query \
--eku=1.3.6.1.5.2.3.6 \
FILE:$srcdir/data/kdc.crt >/dev/null 2>/dev/null && exit 1
echo "make sure entry is found (friendlyname, no-pw)" echo "make sure entry is found (friendlyname, no-pw)"
${hxtool} query \ ${hxtool} query \
--friendlyname=friendlyname-cert \ --friendlyname=friendlyname-cert \

View File

@@ -139,6 +139,7 @@ HEIMDAL_X509_1.0 {
hx509_query_alloc; hx509_query_alloc;
hx509_query_free; hx509_query_free;
hx509_query_match_cmp_func; hx509_query_match_cmp_func;
hx509_query_match_eku;
hx509_query_match_friendly_name; hx509_query_match_friendly_name;
hx509_query_match_issuer_serial; hx509_query_match_issuer_serial;
hx509_query_match_option; hx509_query_match_option;