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:
		@@ -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>
 | 
			
		||||
 | 
			
		||||
	* test_soft_pkcs11.c: use func for more C_ functions.
 | 
			
		||||
 
 | 
			
		||||
@@ -2609,6 +2609,40 @@ hx509_query_match_friendly_name(hx509_query *q, const char *name)
 | 
			
		||||
    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.
 | 
			
		||||
 *
 | 
			
		||||
@@ -2648,20 +2682,24 @@ hx509_query_match_cmp_func(hx509_query *q,
 | 
			
		||||
void
 | 
			
		||||
hx509_query_free(hx509_context context, hx509_query *q)
 | 
			
		||||
{
 | 
			
		||||
    if (q == NULL)
 | 
			
		||||
	return;
 | 
			
		||||
 | 
			
		||||
    if (q->serial) {
 | 
			
		||||
	der_free_heim_integer(q->serial);
 | 
			
		||||
	free(q->serial);
 | 
			
		||||
	q->serial = NULL;
 | 
			
		||||
    }
 | 
			
		||||
    if (q->issuer_name) {
 | 
			
		||||
	free_Name(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);
 | 
			
		||||
	memset(q, 0, sizeof(*q));
 | 
			
		||||
    }
 | 
			
		||||
    memset(q, 0, sizeof(*q));
 | 
			
		||||
    free(q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2790,6 +2828,11 @@ _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert
 | 
			
		||||
	    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)
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -128,7 +128,8 @@ struct hx509_query_data {
 | 
			
		||||
#define HX509_QUERY_MATCH_FUNCTION		0x080000
 | 
			
		||||
#define HX509_QUERY_MATCH_KEY_HASH_SHA1		0x100000
 | 
			
		||||
#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 *certificate;
 | 
			
		||||
    heim_integer *serial;
 | 
			
		||||
@@ -142,6 +143,7 @@ struct hx509_query_data {
 | 
			
		||||
    void *cmp_func_ctx;
 | 
			
		||||
    heim_octet_string *keyhash_sha1;
 | 
			
		||||
    time_t timenow;
 | 
			
		||||
    heim_oid *eku;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct hx509_keyset_ops {
 | 
			
		||||
 
 | 
			
		||||
@@ -437,6 +437,12 @@ command = {
 | 
			
		||||
		argument = "name"
 | 
			
		||||
		help = "match on friendly name"
 | 
			
		||||
	}
 | 
			
		||||
	option = {
 | 
			
		||||
		long = "eku"
 | 
			
		||||
		type = "string"
 | 
			
		||||
		argument = "oid-string"
 | 
			
		||||
		help = "match on EKU"
 | 
			
		||||
	}
 | 
			
		||||
	option = {
 | 
			
		||||
		long = "keyEncipherment"
 | 
			
		||||
		type = "flag"
 | 
			
		||||
 
 | 
			
		||||
@@ -885,6 +885,17 @@ query(struct query_options *opt, int argc, char **argv)
 | 
			
		||||
    if (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)
 | 
			
		||||
	hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -335,9 +335,6 @@ check_authorityKeyIdentifier(hx509_validate_ctx ctx,
 | 
			
		||||
    status->haveAKI = 1;
 | 
			
		||||
    check_Null(ctx, status, cf, e);
 | 
			
		||||
 | 
			
		||||
    status->haveSKI = 1;
 | 
			
		||||
    check_Null(ctx, status, cf, e);
 | 
			
		||||
 | 
			
		||||
    ret = decode_AuthorityKeyIdentifier(e->extnValue.data, 
 | 
			
		||||
					e->extnValue.length,
 | 
			
		||||
					&ai, &size);
 | 
			
		||||
@@ -365,6 +362,56 @@ check_authorityKeyIdentifier(hx509_validate_ctx ctx,
 | 
			
		||||
    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
 | 
			
		||||
check_pkinit_san(hx509_validate_ctx ctx, heim_any *a)
 | 
			
		||||
@@ -731,7 +778,7 @@ struct {
 | 
			
		||||
    { ext(policyMappings, Null), M_N_C },
 | 
			
		||||
    { ext(authorityKeyIdentifier, authorityKeyIdentifier), M_N_C },
 | 
			
		||||
    { ext(policyConstraints, Null), D_C },
 | 
			
		||||
    { ext(extKeyUsage, Null), D_C },
 | 
			
		||||
    { ext(extKeyUsage, extKeyUsage), D_C },
 | 
			
		||||
    { ext(freshestCRL, Null), M_N_C },
 | 
			
		||||
    { ext(inhibitAnyPolicy, Null), M_C },
 | 
			
		||||
#undef ext
 | 
			
		||||
 
 | 
			
		||||
@@ -44,8 +44,15 @@ hxtool="${TESTS_ENVIRONMENT} ./hxtool ${stat}"
 | 
			
		||||
echo "try printing"
 | 
			
		||||
${hxtool} print \
 | 
			
		||||
	--pass=PASS:foobar \
 | 
			
		||||
        --info --content \
 | 
			
		||||
	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 \
 | 
			
		||||
	--pass=PASS:foobar \
 | 
			
		||||
	--info \
 | 
			
		||||
@@ -63,6 +70,16 @@ ${hxtool} query \
 | 
			
		||||
	--friendlyname=friendlyname-test-not  \
 | 
			
		||||
	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)"
 | 
			
		||||
${hxtool} query \
 | 
			
		||||
	--friendlyname=friendlyname-cert  \
 | 
			
		||||
 
 | 
			
		||||
@@ -139,6 +139,7 @@ HEIMDAL_X509_1.0 {
 | 
			
		||||
		hx509_query_alloc;
 | 
			
		||||
		hx509_query_free;
 | 
			
		||||
		hx509_query_match_cmp_func;
 | 
			
		||||
		hx509_query_match_eku;
 | 
			
		||||
		hx509_query_match_friendly_name;
 | 
			
		||||
		hx509_query_match_issuer_serial;
 | 
			
		||||
		hx509_query_match_option;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user