Add language to support querying certificates to find a match. Support constructs like "1.3.6.1.5.2.3.5" IN %{certificate.eku} AND %{certificate.subject} TAILMATCH "C=SE"".
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@22677 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
2008-02-26 Love H<>rnquist <20>strand <lha@it.su.se>
|
2008-02-26 Love H<>rnquist <20>strand <lha@it.su.se>
|
||||||
|
|
||||||
|
* version-script.map: add hx509_pem_read
|
||||||
|
|
||||||
* hxtool-commands.in: Add --pem to cms-verify-sd.
|
* hxtool-commands.in: Add --pem to cms-verify-sd.
|
||||||
|
|
||||||
* test_cms.in: Test verifying PEM signature files.
|
* test_cms.in: Test verifying PEM signature files.
|
||||||
|
@@ -6,6 +6,7 @@ lib_LTLIBRARIES = libhx509.la
|
|||||||
libhx509_la_LDFLAGS = -version-info 3:0:0
|
libhx509_la_LDFLAGS = -version-info 3:0:0
|
||||||
|
|
||||||
BUILT_SOURCES = \
|
BUILT_SOURCES = \
|
||||||
|
sel-gram.h \
|
||||||
$(gen_files_ocsp:.x=.c) \
|
$(gen_files_ocsp:.x=.c) \
|
||||||
$(gen_files_pkcs10:.x=.c) \
|
$(gen_files_pkcs10:.x=.c) \
|
||||||
hx509_err.c \
|
hx509_err.c \
|
||||||
@@ -50,6 +51,8 @@ gen_files_crmf = \
|
|||||||
asn1_ProofOfPossession.x \
|
asn1_ProofOfPossession.x \
|
||||||
asn1_SubsequentMessage.x
|
asn1_SubsequentMessage.x
|
||||||
|
|
||||||
|
AM_YFLAGS = -d
|
||||||
|
|
||||||
dist_libhx509_la_SOURCES = \
|
dist_libhx509_la_SOURCES = \
|
||||||
ca.c \
|
ca.c \
|
||||||
cert.c \
|
cert.c \
|
||||||
@@ -64,6 +67,10 @@ dist_libhx509_la_SOURCES = \
|
|||||||
hx509-protos.h \
|
hx509-protos.h \
|
||||||
hx509.h \
|
hx509.h \
|
||||||
hx_locl.h \
|
hx_locl.h \
|
||||||
|
sel.c \
|
||||||
|
sel.h \
|
||||||
|
sel-gram.y \
|
||||||
|
sel-lex.l \
|
||||||
keyset.c \
|
keyset.c \
|
||||||
ks_dir.c \
|
ks_dir.c \
|
||||||
ks_file.c \
|
ks_file.c \
|
||||||
@@ -81,6 +88,8 @@ dist_libhx509_la_SOURCES = \
|
|||||||
req.c \
|
req.c \
|
||||||
revoke.c
|
revoke.c
|
||||||
|
|
||||||
|
sel-lex.c: sel-gram.h
|
||||||
|
|
||||||
libhx509_la_LIBADD = \
|
libhx509_la_LIBADD = \
|
||||||
$(LIB_com_err) \
|
$(LIB_com_err) \
|
||||||
$(LIB_hcrypto) \
|
$(LIB_hcrypto) \
|
||||||
@@ -184,7 +193,8 @@ test_soft_pkcs11_CPPFLAGS = -I$(srcdir)/ref
|
|||||||
TESTS = $(SCRIPT_TESTS) $(PROGRAM_TESTS)
|
TESTS = $(SCRIPT_TESTS) $(PROGRAM_TESTS)
|
||||||
|
|
||||||
PROGRAM_TESTS = \
|
PROGRAM_TESTS = \
|
||||||
test_name
|
test_name \
|
||||||
|
test_expr
|
||||||
|
|
||||||
SCRIPT_TESTS = \
|
SCRIPT_TESTS = \
|
||||||
test_ca \
|
test_ca \
|
||||||
|
138
lib/hx509/cert.c
138
lib/hx509/cert.c
@@ -2355,7 +2355,7 @@ hx509_verify_hostname(hx509_context context,
|
|||||||
} while (1);
|
} while (1);
|
||||||
|
|
||||||
{
|
{
|
||||||
Name *name = &cert->data->tbsCertificate.subject;
|
const Name *name = &cert->data->tbsCertificate.subject;
|
||||||
|
|
||||||
/* match if first component is a CN= */
|
/* match if first component is a CN= */
|
||||||
if (name->u.rdnSequence.len > 0
|
if (name->u.rdnSequence.len > 0
|
||||||
@@ -2548,6 +2548,7 @@ hx509_query_alloc(hx509_context context, hx509_query **q)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set match options for the hx509 query controller.
|
* Set match options for the hx509 query controller.
|
||||||
*
|
*
|
||||||
@@ -2697,6 +2698,25 @@ hx509_query_match_eku(hx509_query *q, const heim_oid *eku)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
hx509_query_match_expr(hx509_context context, hx509_query *q, const char *expr)
|
||||||
|
{
|
||||||
|
if (q->expr) {
|
||||||
|
_hx509_expr_free(q->expr);
|
||||||
|
q->expr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expr == NULL) {
|
||||||
|
q->match &= ~HX509_QUERY_MATCH_EXPR;
|
||||||
|
} else {
|
||||||
|
q->expr = _hx509_expr_parse(expr);
|
||||||
|
if (q->expr)
|
||||||
|
q->match |= HX509_QUERY_MATCH_EXPR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the query controller to match using a specific match function.
|
* Set the query controller to match using a specific match function.
|
||||||
*
|
*
|
||||||
@@ -2753,6 +2773,9 @@ hx509_query_free(hx509_context context, hx509_query *q)
|
|||||||
}
|
}
|
||||||
if (q->friendlyname)
|
if (q->friendlyname)
|
||||||
free(q->friendlyname);
|
free(q->friendlyname);
|
||||||
|
if (q->expr)
|
||||||
|
_hx509_expr_free(q->expr);
|
||||||
|
|
||||||
memset(q, 0, sizeof(*q));
|
memset(q, 0, sizeof(*q));
|
||||||
free(q);
|
free(q);
|
||||||
}
|
}
|
||||||
@@ -2890,6 +2913,19 @@ _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert
|
|||||||
hx509_cert_check_eku(context, cert, q->eku, 0))
|
hx509_cert_check_eku(context, cert, q->eku, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if ((q->match & HX509_QUERY_MATCH_EXPR)) {
|
||||||
|
hx509_env env = NULL;
|
||||||
|
|
||||||
|
ret = _hx509_cert_to_env(context, cert, &env);
|
||||||
|
if (ret)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = _hx509_eval_expr(context, env, q->expr);
|
||||||
|
hx509_env_free(&env);
|
||||||
|
if (ret == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (q->match & ~HX509_QUERY_MASK)
|
if (q->match & ~HX509_QUERY_MASK)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -3206,3 +3242,103 @@ hx509_xfree(void *ptr)
|
|||||||
{
|
{
|
||||||
free(ptr);
|
free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
_hx509_cert_to_env(hx509_context context, hx509_cert cert, hx509_env *env)
|
||||||
|
{
|
||||||
|
ExtKeyUsage eku;
|
||||||
|
hx509_name name;
|
||||||
|
char *buf;
|
||||||
|
int ret;
|
||||||
|
hx509_env envcert = NULL;
|
||||||
|
|
||||||
|
*env = NULL;
|
||||||
|
|
||||||
|
/* version */
|
||||||
|
asprintf(&buf, "%d", _hx509_cert_get_version(_hx509_get_cert(cert)));
|
||||||
|
ret = hx509_env_add(context, &envcert, "version", buf);
|
||||||
|
free(buf);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* subject */
|
||||||
|
ret = hx509_cert_get_subject(cert, &name);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = hx509_name_to_string(name, &buf);
|
||||||
|
if (ret) {
|
||||||
|
hx509_name_free(&name);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = hx509_env_add(context, &envcert, "subject", buf);
|
||||||
|
hx509_name_free(&name);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* issuer */
|
||||||
|
ret = hx509_cert_get_issuer(cert, &name);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = hx509_name_to_string(name, &buf);
|
||||||
|
hx509_name_free(&name);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = hx509_env_add(context, &envcert, "issuer", buf);
|
||||||
|
hx509_xfree(buf);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* eku */
|
||||||
|
|
||||||
|
ret = _hx509_cert_get_eku(context, cert, &eku);
|
||||||
|
if (ret == HX509_EXTENSION_NOT_FOUND)
|
||||||
|
;
|
||||||
|
else if (ret != 0)
|
||||||
|
goto out;
|
||||||
|
else {
|
||||||
|
int i;
|
||||||
|
hx509_env enveku = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < eku.len; i++) {
|
||||||
|
|
||||||
|
ret = der_print_heim_oid(&eku.val[i], '.', &buf);
|
||||||
|
if (ret) {
|
||||||
|
free_ExtKeyUsage(&eku);
|
||||||
|
hx509_env_free(&enveku);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
ret = hx509_env_add(context, &enveku, buf, "oid-name-here");
|
||||||
|
free(buf);
|
||||||
|
if (ret) {
|
||||||
|
free_ExtKeyUsage(&eku);
|
||||||
|
hx509_env_free(&enveku);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free_ExtKeyUsage(&eku);
|
||||||
|
|
||||||
|
ret = hx509_env_add_binding(context, &envcert, "eku", enveku);
|
||||||
|
if (ret) {
|
||||||
|
hx509_env_free(&enveku);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = hx509_env_add_binding(context, env, "certificate", envcert);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
hx509_env_free(&envcert);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
205
lib/hx509/env.c
205
lib/hx509/env.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Kungliga Tekniska H<>gskolan
|
* Copyright (c) 2007 - 2008 Kungliga Tekniska H<>gskolan
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -40,36 +40,6 @@ RCSID("$Id$");
|
|||||||
* See the library functions here: @ref hx509_env
|
* See the library functions here: @ref hx509_env
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct hx509_env {
|
|
||||||
struct {
|
|
||||||
char *key;
|
|
||||||
char *value;
|
|
||||||
} *val;
|
|
||||||
size_t len;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocate a new hx509_env container object.
|
|
||||||
*
|
|
||||||
* @param context A hx509 context.
|
|
||||||
* @param env return a hx509_env structure, free with hx509_env_free().
|
|
||||||
*
|
|
||||||
* @return An hx509 error code, see hx509_get_error_string().
|
|
||||||
*
|
|
||||||
* @ingroup hx509_env
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
hx509_env_init(hx509_context context, hx509_env *env)
|
|
||||||
{
|
|
||||||
*env = calloc(1, sizeof(**env));
|
|
||||||
if (*env == NULL) {
|
|
||||||
hx509_set_error_string(context, 0, ENOMEM, "out of memory");
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new key/value pair to the hx509_env.
|
* Add a new key/value pair to the hx509_env.
|
||||||
*
|
*
|
||||||
@@ -84,34 +54,92 @@ hx509_env_init(hx509_context context, hx509_env *env)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_env_add(hx509_context context, hx509_env env,
|
hx509_env_add(hx509_context context, hx509_env *env,
|
||||||
const char *key, const char *value)
|
const char *key, const char *value)
|
||||||
{
|
{
|
||||||
void *ptr;
|
hx509_env n;
|
||||||
|
|
||||||
ptr = realloc(env->val, sizeof(env->val[0]) * (env->len + 1));
|
n = malloc(sizeof(*n));
|
||||||
if (ptr == NULL) {
|
if (n == NULL) {
|
||||||
hx509_set_error_string(context, 0, ENOMEM, "out of memory");
|
hx509_set_error_string(context, 0, ENOMEM, "out of memory");
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
env->val = ptr;
|
|
||||||
env->val[env->len].key = strdup(key);
|
n->type = env_string;
|
||||||
if (env->val[env->len].key == NULL) {
|
n->next = NULL;
|
||||||
hx509_set_error_string(context, 0, ENOMEM, "out of memory");
|
n->name = strdup(key);
|
||||||
|
if (n->name == NULL) {
|
||||||
|
free(n);
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
env->val[env->len].value = strdup(value);
|
n->u.string = strdup(value);
|
||||||
if (env->val[env->len].value == NULL) {
|
if (n->u.string == NULL) {
|
||||||
free(env->val[env->len].key);
|
free(n->name);
|
||||||
hx509_set_error_string(context, 0, ENOMEM, "out of memory");
|
free(n);
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
env->len++;
|
|
||||||
|
/* add to tail */
|
||||||
|
if (*env) {
|
||||||
|
hx509_env e = *env;
|
||||||
|
while (e->next)
|
||||||
|
e = e->next;
|
||||||
|
e->next = n;
|
||||||
|
} else
|
||||||
|
*env = n;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search the hx509_env for a key.
|
* Add a new key/binding pair to the hx509_env.
|
||||||
|
*
|
||||||
|
* @param context A hx509 context.
|
||||||
|
* @param env enviroment to add the enviroment variable too.
|
||||||
|
* @param key key to add
|
||||||
|
* @param list binding list to add
|
||||||
|
*
|
||||||
|
* @return An hx509 error code, see hx509_get_error_string().
|
||||||
|
*
|
||||||
|
* @ingroup hx509_env
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
hx509_env_add_binding(hx509_context context, hx509_env *env,
|
||||||
|
const char *key, hx509_env list)
|
||||||
|
{
|
||||||
|
hx509_env n;
|
||||||
|
|
||||||
|
n = malloc(sizeof(*n));
|
||||||
|
if (n == NULL) {
|
||||||
|
hx509_set_error_string(context, 0, ENOMEM, "out of memory");
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
n->type = env_list;
|
||||||
|
n->next = NULL;
|
||||||
|
n->name = strdup(key);
|
||||||
|
if (n->name == NULL) {
|
||||||
|
free(n);
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
n->u.list = list;
|
||||||
|
|
||||||
|
/* add to tail */
|
||||||
|
if (*env) {
|
||||||
|
hx509_env e = *env;
|
||||||
|
while (e->next)
|
||||||
|
e = e->next;
|
||||||
|
e->next = n;
|
||||||
|
} else
|
||||||
|
*env = n;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search the hx509_env for a length based key.
|
||||||
*
|
*
|
||||||
* @param context A hx509 context.
|
* @param context A hx509 context.
|
||||||
* @param env enviroment to add the enviroment variable too.
|
* @param env enviroment to add the enviroment variable too.
|
||||||
@@ -127,16 +155,80 @@ const char *
|
|||||||
hx509_env_lfind(hx509_context context, hx509_env env,
|
hx509_env_lfind(hx509_context context, hx509_env env,
|
||||||
const char *key, size_t len)
|
const char *key, size_t len)
|
||||||
{
|
{
|
||||||
size_t i;
|
while(env) {
|
||||||
|
if (strncmp(key, env->name ,len) == 0
|
||||||
for (i = 0; i < env->len; i++) {
|
&& env->name[len] == '\0' && env->type == env_string)
|
||||||
char *s = env->val[i].key;
|
return env->u.string;
|
||||||
if (strncmp(key, s, len) == 0 && s[len] == '\0')
|
env = env->next;
|
||||||
return env->val[i].value;
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search the hx509_env for a key.
|
||||||
|
*
|
||||||
|
* @param context A hx509 context.
|
||||||
|
* @param env enviroment to add the enviroment variable too.
|
||||||
|
* @param key key to search for.
|
||||||
|
*
|
||||||
|
* @return the value if the key is found, NULL otherwise.
|
||||||
|
*
|
||||||
|
* @ingroup hx509_env
|
||||||
|
*/
|
||||||
|
|
||||||
|
const char *
|
||||||
|
hx509_env_find(hx509_context context, hx509_env env, const char *key)
|
||||||
|
{
|
||||||
|
while(env) {
|
||||||
|
if (strcmp(key, env->name) == 0 && env->type == env_string)
|
||||||
|
return env->u.string;
|
||||||
|
env = env->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search the hx509_env for a binding.
|
||||||
|
*
|
||||||
|
* @param context A hx509 context.
|
||||||
|
* @param env enviroment to add the enviroment variable too.
|
||||||
|
* @param key key to search for.
|
||||||
|
*
|
||||||
|
* @return the binding if the key is found, NULL if not found.
|
||||||
|
*
|
||||||
|
* @ingroup hx509_env
|
||||||
|
*/
|
||||||
|
|
||||||
|
hx509_env
|
||||||
|
hx509_env_find_binding(hx509_context context,
|
||||||
|
hx509_env env,
|
||||||
|
const char *key)
|
||||||
|
{
|
||||||
|
while(env) {
|
||||||
|
if (strcmp(key, env->name) == 0 && env->type == env_list)
|
||||||
|
return env->u.list;
|
||||||
|
env = env->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
env_free(hx509_env b)
|
||||||
|
{
|
||||||
|
while(b) {
|
||||||
|
hx509_env next = b->next;
|
||||||
|
|
||||||
|
if (b->type == env_string)
|
||||||
|
free(b->u.string);
|
||||||
|
else if (b->type == env_list)
|
||||||
|
env_free(b->u.list);
|
||||||
|
|
||||||
|
free(b->name);
|
||||||
|
free(b);
|
||||||
|
b = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free an hx509_env enviroment context.
|
* Free an hx509_env enviroment context.
|
||||||
*
|
*
|
||||||
@@ -148,14 +240,7 @@ hx509_env_lfind(hx509_context context, hx509_env env,
|
|||||||
void
|
void
|
||||||
hx509_env_free(hx509_env *env)
|
hx509_env_free(hx509_env *env)
|
||||||
{
|
{
|
||||||
size_t i;
|
if (*env)
|
||||||
|
env_free(*env);
|
||||||
for (i = 0; i < (*env)->len; i++) {
|
|
||||||
free((*env)->val[i].key);
|
|
||||||
free((*env)->val[i].value);
|
|
||||||
}
|
|
||||||
free((*env)->val);
|
|
||||||
free(*env);
|
|
||||||
*env = NULL;
|
*env = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -50,7 +50,7 @@ typedef struct hx509_request_data *hx509_request;
|
|||||||
typedef struct hx509_error_data *hx509_error;
|
typedef struct hx509_error_data *hx509_error;
|
||||||
typedef struct hx509_peer_info *hx509_peer_info;
|
typedef struct hx509_peer_info *hx509_peer_info;
|
||||||
typedef struct hx509_ca_tbs *hx509_ca_tbs;
|
typedef struct hx509_ca_tbs *hx509_ca_tbs;
|
||||||
typedef struct hx509_env *hx509_env;
|
typedef struct hx509_env_data *hx509_env;
|
||||||
typedef struct hx509_crl *hx509_crl;
|
typedef struct hx509_crl *hx509_crl;
|
||||||
|
|
||||||
typedef void (*hx509_vprint_func)(void *, const char *, va_list);
|
typedef void (*hx509_vprint_func)(void *, const char *, va_list);
|
||||||
|
@@ -80,6 +80,8 @@ typedef void (*_hx509_cert_release_func)(struct hx509_cert_data *, void *);
|
|||||||
|
|
||||||
typedef struct hx509_private_key_ops hx509_private_key_ops;
|
typedef struct hx509_private_key_ops hx509_private_key_ops;
|
||||||
|
|
||||||
|
#include "sel.h"
|
||||||
|
|
||||||
#include <hx509-private.h>
|
#include <hx509-private.h>
|
||||||
#include <hx509_err.h>
|
#include <hx509_err.h>
|
||||||
|
|
||||||
@@ -129,7 +131,8 @@ struct hx509_query_data {
|
|||||||
#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_MATCH_EKU 0x400000
|
#define HX509_QUERY_MATCH_EKU 0x400000
|
||||||
#define HX509_QUERY_MASK 0x7fffff
|
#define HX509_QUERY_MATCH_EXPR 0x800000
|
||||||
|
#define HX509_QUERY_MASK 0xffffff
|
||||||
Certificate *subject;
|
Certificate *subject;
|
||||||
Certificate *certificate;
|
Certificate *certificate;
|
||||||
heim_integer *serial;
|
heim_integer *serial;
|
||||||
@@ -144,6 +147,7 @@ struct hx509_query_data {
|
|||||||
heim_octet_string *keyhash_sha1;
|
heim_octet_string *keyhash_sha1;
|
||||||
time_t timenow;
|
time_t timenow;
|
||||||
heim_oid *eku;
|
heim_oid *eku;
|
||||||
|
struct hx_expr *expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hx509_keyset_ops {
|
struct hx509_keyset_ops {
|
||||||
@@ -188,6 +192,18 @@ struct hx509_context_data {
|
|||||||
/* _hx509_calculate_path flag field */
|
/* _hx509_calculate_path flag field */
|
||||||
#define HX509_CALCULATE_PATH_NO_ANCHOR 1
|
#define HX509_CALCULATE_PATH_NO_ANCHOR 1
|
||||||
|
|
||||||
|
/* environment */
|
||||||
|
struct hx509_env_data {
|
||||||
|
enum { env_string, env_list } type;
|
||||||
|
char *name;
|
||||||
|
struct hx509_env_data *next;
|
||||||
|
union {
|
||||||
|
char *string;
|
||||||
|
struct hx509_env_data *list;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
extern const AlgorithmIdentifier * _hx509_crypto_default_sig_alg;
|
extern const AlgorithmIdentifier * _hx509_crypto_default_sig_alg;
|
||||||
extern const AlgorithmIdentifier * _hx509_crypto_default_digest_alg;
|
extern const AlgorithmIdentifier * _hx509_crypto_default_digest_alg;
|
||||||
extern const AlgorithmIdentifier * _hx509_crypto_default_secret_alg;
|
extern const AlgorithmIdentifier * _hx509_crypto_default_secret_alg;
|
||||||
|
@@ -448,6 +448,12 @@ command = {
|
|||||||
argument = "oid-string"
|
argument = "oid-string"
|
||||||
help = "match on EKU"
|
help = "match on EKU"
|
||||||
}
|
}
|
||||||
|
option = {
|
||||||
|
long = "expr"
|
||||||
|
type = "string"
|
||||||
|
argument = "expression"
|
||||||
|
help = "match on expression"
|
||||||
|
}
|
||||||
option = {
|
option = {
|
||||||
long = "keyEncipherment"
|
long = "keyEncipherment"
|
||||||
type = "flag"
|
type = "flag"
|
||||||
|
@@ -942,6 +942,9 @@ query(struct query_options *opt, int argc, char **argv)
|
|||||||
if (opt->digitalSignature_flag)
|
if (opt->digitalSignature_flag)
|
||||||
hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
|
hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
|
||||||
|
|
||||||
|
if (opt->expr_string)
|
||||||
|
hx509_query_match_expr(context, q, opt->expr_string);
|
||||||
|
|
||||||
ret = hx509_certs_find(context, certs, q, &c);
|
ret = hx509_certs_find(context, certs, q, &c);
|
||||||
hx509_query_free(context, q);
|
hx509_query_free(context, q);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@@ -897,7 +897,7 @@ hx509_name_is_null_p(const hx509_name name)
|
|||||||
* @param name the name to print
|
* @param name the name to print
|
||||||
* @param str an allocated string returns the name in string form
|
* @param str an allocated string returns the name in string form
|
||||||
*
|
*
|
||||||
* @return An hx509 error code, see krb5_get_error_string().
|
* @return An hx509 error code, see hx509_get_error_string().
|
||||||
*
|
*
|
||||||
* @ingroup hx509_name
|
* @ingroup hx509_name
|
||||||
*/
|
*/
|
||||||
|
115
lib/hx509/sel-gram.y
Normal file
115
lib/hx509/sel-gram.y
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2008 Kungliga Tekniska H<>gskolan
|
||||||
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the Institute nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
%{
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <hx_locl.h>
|
||||||
|
|
||||||
|
RCSID("$Id$");
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
%union {
|
||||||
|
char *string;
|
||||||
|
struct hx_expr *expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
%token kw_TRUE
|
||||||
|
%token kw_FALSE
|
||||||
|
%token kw_AND
|
||||||
|
%token kw_OR
|
||||||
|
%token kw_IN
|
||||||
|
%token kw_TAILMATCH
|
||||||
|
|
||||||
|
%type <expr> expr
|
||||||
|
%type <expr> comp
|
||||||
|
%type <expr> word words
|
||||||
|
%type <expr> number
|
||||||
|
%type <expr> string
|
||||||
|
%type <expr> function
|
||||||
|
%type <expr> variable variables
|
||||||
|
|
||||||
|
%token <string> NUMBER
|
||||||
|
%token <string> STRING
|
||||||
|
%token <string> IDENTIFIER
|
||||||
|
|
||||||
|
%start start
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
start: expr { _hx509_expr_input.expr = $1; }
|
||||||
|
|
||||||
|
expr : kw_TRUE { $$ = _hx509_make_expr(op_TRUE, NULL, NULL); }
|
||||||
|
| kw_FALSE { $$ = _hx509_make_expr(op_FALSE, NULL, NULL); }
|
||||||
|
| '!' expr { $$ = _hx509_make_expr(op_NOT, $2, NULL); }
|
||||||
|
| expr kw_AND expr { $$ = _hx509_make_expr(op_AND, $1, $3); }
|
||||||
|
| expr kw_OR expr { $$ = _hx509_make_expr(op_OR, $1, $3); }
|
||||||
|
| '(' expr ')' { $$ = $2; }
|
||||||
|
| comp { $$ = _hx509_make_expr(op_COMP, $1, NULL); }
|
||||||
|
;
|
||||||
|
|
||||||
|
words : word { $$ = _hx509_make_expr(expr_WORDS, $1, NULL); }
|
||||||
|
| word ',' words { $$ = _hx509_make_expr(expr_WORDS, $1, $3); }
|
||||||
|
;
|
||||||
|
|
||||||
|
comp : word '=' '=' word { $$ = _hx509_make_expr(comp_EQ, $1, $4); }
|
||||||
|
| word '!' '=' word { $$ = _hx509_make_expr(comp_NE, $1, $4); }
|
||||||
|
| word kw_TAILMATCH word { $$ = _hx509_make_expr(comp_TAILEQ, $1, $3); }
|
||||||
|
| word kw_IN '(' words ')' { $$ = _hx509_make_expr(comp_IN, $1, $4); }
|
||||||
|
| word kw_IN variable { $$ = _hx509_make_expr(comp_IN, $1, $3); }
|
||||||
|
;
|
||||||
|
|
||||||
|
word : number { $$ = $1; }
|
||||||
|
| string { $$ = $1; }
|
||||||
|
| function { $$ = $1; }
|
||||||
|
| variable { $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
number : NUMBER { $$ = _hx509_make_expr(expr_NUMBER, $1, NULL); };
|
||||||
|
string : STRING { $$ = _hx509_make_expr(expr_STRING, $1, NULL); };
|
||||||
|
|
||||||
|
function: IDENTIFIER '(' words ')' {
|
||||||
|
$$ = _hx509_make_expr(expr_FUNCTION, $1, $3); }
|
||||||
|
;
|
||||||
|
variable: '%' '{' variables '}' { $$ = $3; }
|
||||||
|
;
|
||||||
|
|
||||||
|
variables: IDENTIFIER '.' variables {
|
||||||
|
$$ = _hx509_make_expr(expr_VAR, $1, $3); }
|
||||||
|
| IDENTIFIER {
|
||||||
|
$$ = _hx509_make_expr(expr_VAR, $1, NULL); }
|
||||||
|
;
|
152
lib/hx509/sel-lex.l
Normal file
152
lib/hx509/sel-lex.l
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
%{
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2004, 2008 Kungliga Tekniska H<>gskolan
|
||||||
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the Institute nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#undef ECHO
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "sel.h"
|
||||||
|
#include "sel-gram.h"
|
||||||
|
unsigned lineno = 1;
|
||||||
|
|
||||||
|
static char * handle_string(void);
|
||||||
|
static int lex_input(char *, int);
|
||||||
|
static void error_message (const char *format, ...);
|
||||||
|
void yyerror (char *);
|
||||||
|
|
||||||
|
struct hx_expr_input _hx509_expr_input;
|
||||||
|
|
||||||
|
#define YY_NO_UNPUT 1
|
||||||
|
|
||||||
|
#undef YY_INPUT
|
||||||
|
#define YY_INPUT(buf,res,maxsize) (res = lex_input(buf, maxsize))
|
||||||
|
|
||||||
|
#undef ECHO
|
||||||
|
|
||||||
|
%}
|
||||||
|
%%
|
||||||
|
|
||||||
|
TRUE { return kw_TRUE; }
|
||||||
|
FALSE { return kw_FALSE; }
|
||||||
|
AND { return kw_AND; }
|
||||||
|
OR { return kw_OR; }
|
||||||
|
IN { return kw_IN; }
|
||||||
|
TAILMATCH { return kw_TAILMATCH; }
|
||||||
|
|
||||||
|
[A-Za-z][-A-Za-z0-9_]* {
|
||||||
|
yylval.string = strdup ((const char *)yytext);
|
||||||
|
return IDENTIFIER;
|
||||||
|
}
|
||||||
|
"\"" { yylval.string = handle_string(); return STRING; }
|
||||||
|
\n { ++lineno; }
|
||||||
|
[,.!={}()%] { return *yytext; }
|
||||||
|
[ \t] ;
|
||||||
|
%%
|
||||||
|
|
||||||
|
void
|
||||||
|
error_message (const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
if (_hx509_expr_input.error)
|
||||||
|
free(_hx509_expr_input.error);
|
||||||
|
|
||||||
|
va_start (args, format);
|
||||||
|
vasprintf(&_hx509_expr_input.error, format, args);
|
||||||
|
va_end (args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
yyerror (char *s)
|
||||||
|
{
|
||||||
|
error_message("%s", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
handle_string(void)
|
||||||
|
{
|
||||||
|
char x[1024];
|
||||||
|
int i = 0;
|
||||||
|
int c;
|
||||||
|
int quote = 0;
|
||||||
|
while((c = input()) != EOF){
|
||||||
|
if(quote) {
|
||||||
|
x[i++] = '\\';
|
||||||
|
x[i++] = c;
|
||||||
|
quote = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(c == '\n'){
|
||||||
|
error_message("unterminated string");
|
||||||
|
lineno++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(c == '\\'){
|
||||||
|
quote++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(c == '\"')
|
||||||
|
break;
|
||||||
|
x[i++] = c;
|
||||||
|
}
|
||||||
|
x[i] = '\0';
|
||||||
|
return strdup(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
yywrap ()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
lex_input(char *buf, int max_size)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
n = _hx509_expr_input.length - _hx509_expr_input.offset;
|
||||||
|
if (max_size < n)
|
||||||
|
n = max_size;
|
||||||
|
if (n <= 0)
|
||||||
|
return YY_NULL;
|
||||||
|
|
||||||
|
memcpy(buf, _hx509_expr_input.buf + _hx509_expr_input.offset, n);
|
||||||
|
_hx509_expr_input.offset += n;
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
222
lib/hx509/sel.c
Normal file
222
lib/hx509/sel.c
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2008 Kungliga Tekniska H<>gskolan
|
||||||
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the Institute nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hx_locl.h"
|
||||||
|
|
||||||
|
struct hx_expr *
|
||||||
|
_hx509_make_expr(enum hx_expr_op op, void *arg1, void *arg2)
|
||||||
|
{
|
||||||
|
struct hx_expr *expr;
|
||||||
|
|
||||||
|
expr = malloc(sizeof(*expr));
|
||||||
|
if (expr == NULL)
|
||||||
|
return NULL;
|
||||||
|
expr->op = op;
|
||||||
|
expr->arg1 = arg1;
|
||||||
|
expr->arg2 = arg2;
|
||||||
|
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
eval_word(hx509_context context, hx509_env env, struct hx_expr *word)
|
||||||
|
{
|
||||||
|
switch (word->op) {
|
||||||
|
case expr_STRING:
|
||||||
|
return word->arg1;
|
||||||
|
case expr_VAR:
|
||||||
|
if (word->arg2 == NULL)
|
||||||
|
return hx509_env_find(context, env, word->arg1);
|
||||||
|
|
||||||
|
env = hx509_env_find_binding(context, env, word->arg1);
|
||||||
|
if (env == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return eval_word(context, env, word->arg2);
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static hx509_env
|
||||||
|
find_variable(hx509_context context, hx509_env env, struct hx_expr *word)
|
||||||
|
{
|
||||||
|
assert(word->op == expr_VAR);
|
||||||
|
|
||||||
|
if (word->arg2 == NULL)
|
||||||
|
return hx509_env_find_binding(context, env, word->arg1);
|
||||||
|
|
||||||
|
env = hx509_env_find_binding(context, env, word->arg1);
|
||||||
|
if (env == NULL)
|
||||||
|
return NULL;
|
||||||
|
return find_variable(context, env, word->arg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
eval_comp(hx509_context context, hx509_env env, struct hx_expr *expr)
|
||||||
|
{
|
||||||
|
switch (expr->op) {
|
||||||
|
case comp_NE:
|
||||||
|
case comp_EQ:
|
||||||
|
case comp_TAILEQ: {
|
||||||
|
const char *s1, *s2;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
s1 = eval_word(context, env, expr->arg1);
|
||||||
|
s2 = eval_word(context, env, expr->arg2);
|
||||||
|
|
||||||
|
if (s1 == NULL || s2 == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (expr->op == comp_TAILEQ) {
|
||||||
|
size_t len1 = strlen(s1);
|
||||||
|
size_t len2 = strlen(s2);
|
||||||
|
|
||||||
|
if (len1 < len2)
|
||||||
|
return 0;
|
||||||
|
ret = strcmp(s1 + (len1 - len2), s2) == 0;
|
||||||
|
} else {
|
||||||
|
ret = strcmp(s1, s2) == 0;
|
||||||
|
if (expr->op == comp_NE)
|
||||||
|
ret = !ret;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
case comp_IN: {
|
||||||
|
struct hx_expr *subexpr;
|
||||||
|
const char *w, *s1;
|
||||||
|
|
||||||
|
w = eval_word(context, env, expr->arg1);
|
||||||
|
|
||||||
|
subexpr = expr->arg2;
|
||||||
|
|
||||||
|
if (subexpr->op == expr_WORDS) {
|
||||||
|
while (subexpr) {
|
||||||
|
s1 = eval_word(context, env, subexpr->arg1);
|
||||||
|
if (strcmp(w, s1) == 0)
|
||||||
|
return TRUE;
|
||||||
|
subexpr = subexpr->arg2;
|
||||||
|
}
|
||||||
|
} else if (subexpr->op == expr_VAR) {
|
||||||
|
hx509_env subenv;
|
||||||
|
|
||||||
|
subenv = find_variable(context, env, subexpr);
|
||||||
|
if (subenv == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
while (subenv) {
|
||||||
|
if (subenv->type != env_string)
|
||||||
|
continue;
|
||||||
|
if (strcmp(w, subenv->name) == 0)
|
||||||
|
return TRUE;
|
||||||
|
if (strcmp(w, subenv->u.string) == 0)
|
||||||
|
return TRUE;
|
||||||
|
subenv = subenv->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else
|
||||||
|
_hx509_abort("hx509 eval IN unknown op: %d", (int)subexpr->op);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
_hx509_abort("hx509 eval expr with unknown op: %d", (int)expr->op);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_hx509_eval_expr(hx509_context context, hx509_env env, struct hx_expr *expr)
|
||||||
|
{
|
||||||
|
switch (expr->op) {
|
||||||
|
case op_TRUE:
|
||||||
|
return 1;
|
||||||
|
case op_FALSE:
|
||||||
|
return 0;
|
||||||
|
case op_NOT:
|
||||||
|
return ! _hx509_eval_expr(context, env, expr->arg1);
|
||||||
|
case op_AND:
|
||||||
|
return _hx509_eval_expr(context, env, expr->arg1) &&
|
||||||
|
_hx509_eval_expr(context, env, expr->arg2);
|
||||||
|
case op_OR:
|
||||||
|
return _hx509_eval_expr(context, env, expr->arg1) ||
|
||||||
|
_hx509_eval_expr(context, env, expr->arg2);
|
||||||
|
case op_COMP:
|
||||||
|
return eval_comp(context, env, expr->arg1);
|
||||||
|
default:
|
||||||
|
_hx509_abort("hx509 eval expr with unknown op: %d", (int)expr->op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_hx509_expr_free(struct hx_expr *expr)
|
||||||
|
{
|
||||||
|
switch (expr->op) {
|
||||||
|
case expr_STRING:
|
||||||
|
case expr_NUMBER:
|
||||||
|
free(expr->arg1);
|
||||||
|
break;
|
||||||
|
case expr_WORDS:
|
||||||
|
case expr_FUNCTION:
|
||||||
|
case expr_VAR:
|
||||||
|
free(expr->arg1);
|
||||||
|
if (expr->arg2)
|
||||||
|
_hx509_expr_free(expr->arg2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (expr->arg1)
|
||||||
|
_hx509_expr_free(expr->arg1);
|
||||||
|
if (expr->arg2)
|
||||||
|
_hx509_expr_free(expr->arg2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hx_expr *
|
||||||
|
_hx509_expr_parse(const char *buf)
|
||||||
|
{
|
||||||
|
_hx509_expr_input.buf = buf;
|
||||||
|
_hx509_expr_input.length = strlen(buf);
|
||||||
|
_hx509_expr_input.offset = 0;
|
||||||
|
_hx509_expr_input.expr = NULL;
|
||||||
|
|
||||||
|
if (_hx509_expr_input.error) {
|
||||||
|
free(_hx509_expr_input.error);
|
||||||
|
_hx509_expr_input.error = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
yyparse();
|
||||||
|
|
||||||
|
return _hx509_expr_input.expr;
|
||||||
|
}
|
70
lib/hx509/sel.h
Normal file
70
lib/hx509/sel.h
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2008 Kungliga Tekniska H<>gskolan
|
||||||
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the Institute nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum hx_expr_op {
|
||||||
|
op_TRUE,
|
||||||
|
op_FALSE,
|
||||||
|
op_NOT,
|
||||||
|
op_AND,
|
||||||
|
op_OR,
|
||||||
|
op_COMP,
|
||||||
|
|
||||||
|
comp_EQ,
|
||||||
|
comp_NE,
|
||||||
|
comp_IN,
|
||||||
|
comp_TAILEQ,
|
||||||
|
|
||||||
|
expr_NUMBER,
|
||||||
|
expr_STRING,
|
||||||
|
expr_FUNCTION,
|
||||||
|
expr_VAR,
|
||||||
|
expr_WORDS
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hx_expr {
|
||||||
|
enum hx_expr_op op;
|
||||||
|
void *arg1;
|
||||||
|
void *arg2;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hx_expr_input {
|
||||||
|
const char *buf;
|
||||||
|
size_t length;
|
||||||
|
size_t offset;
|
||||||
|
struct hx_expr *expr;
|
||||||
|
char *error;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct hx_expr_input _hx509_expr_input;
|
||||||
|
|
||||||
|
int yyparse(void);
|
85
lib/hx509/test_expr.c
Normal file
85
lib/hx509/test_expr.c
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
|
||||||
|
#include "hx_locl.h"
|
||||||
|
#include <err.h>
|
||||||
|
|
||||||
|
struct foo {
|
||||||
|
int val;
|
||||||
|
char *str;
|
||||||
|
} foo[] = {
|
||||||
|
{ 0, "FALSE" },
|
||||||
|
{ 1, "TRUE" },
|
||||||
|
{ 0, "!TRUE" },
|
||||||
|
{ 0, "! TRUE" },
|
||||||
|
{ 0, "!\tTRUE" },
|
||||||
|
{ 0, "( FALSE AND FALSE )" },
|
||||||
|
{ 0, "( TRUE AND FALSE )" },
|
||||||
|
{ 1, "( TRUE AND TRUE )" },
|
||||||
|
{ 1, "( TRUE OR TRUE )" },
|
||||||
|
{ 1, "( TRUE OR FALSE )" },
|
||||||
|
{ 0, "( FALSE OR FALSE )" },
|
||||||
|
{ 1, "! ( FALSE OR FALSE )" },
|
||||||
|
|
||||||
|
{ 1, "\"foo\" TAILMATCH \"foo\"" },
|
||||||
|
{ 1, "\"foobar\" TAILMATCH \"bar\"" },
|
||||||
|
{ 0, "\"foobar\" TAILMATCH \"foo\"" },
|
||||||
|
|
||||||
|
{ 1, "\"foo\" == \"foo\"" },
|
||||||
|
{ 0, "\"foo\" == \"bar\"" },
|
||||||
|
{ 0, "\"foo\" != \"foo\"" },
|
||||||
|
{ 1, "\"foo\" != \"bar\"" },
|
||||||
|
{ 1, "%{variable} == \"foo\"" },
|
||||||
|
{ 0, "%{variable} == \"bar\"" },
|
||||||
|
{ 1, "%{context.variable} == \"foo\"" },
|
||||||
|
{ 0, "%{context.variable} == \"bar\"" },
|
||||||
|
{ 1, "\"foo\" IN ( \"bar\", \"foo\")" },
|
||||||
|
{ 0, "\"foo\" IN ( \"bar\", \"baz\")" },
|
||||||
|
{ 0, "\"bar\" IN %{context}" },
|
||||||
|
{ 1, "\"foo\" IN %{context}" },
|
||||||
|
{ 1, "\"variable\" IN %{context}" },
|
||||||
|
|
||||||
|
{ 1, "\"foo\" IN %{context} AND %{context.variable} == \"foo\"" }
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct hx_expr *expr;
|
||||||
|
hx509_context context;
|
||||||
|
hx509_env env = NULL, env2 = NULL;
|
||||||
|
int val, i, ret;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
extern int yydebug;
|
||||||
|
yydebug = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = hx509_context_init(&context);
|
||||||
|
if (ret)
|
||||||
|
errx(1, "hx509_context_init failed with %d", ret);
|
||||||
|
|
||||||
|
hx509_env_add(context, &env, "variable", "foo");
|
||||||
|
hx509_env_add(context, &env2, "variable", "foo");
|
||||||
|
hx509_env_add_binding(context, &env, "context", env2);
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(foo)/sizeof(foo[0]); i++) {
|
||||||
|
|
||||||
|
expr = _hx509_expr_parse(foo[i].str);
|
||||||
|
if (expr == NULL)
|
||||||
|
errx(1, "_hx509_expr_parse failed for %d: %s", i, foo[i].str);
|
||||||
|
|
||||||
|
val = _hx509_eval_expr(context, env, expr);
|
||||||
|
if (foo[i].val) {
|
||||||
|
if (val == 0)
|
||||||
|
errx(1, "_hx509_eval_expr not true when it should: %d: %s",
|
||||||
|
i, foo[i].str);
|
||||||
|
} else {
|
||||||
|
if (val)
|
||||||
|
errx(1, "_hx509_eval_expr true when it should not: %d: %s",
|
||||||
|
i, foo[i].str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hx509_env_free(&env);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -72,13 +72,12 @@ test_name_fail(hx509_context context, const char *name)
|
|||||||
static int
|
static int
|
||||||
test_expand(hx509_context context, const char *name, const char *expected)
|
test_expand(hx509_context context, const char *name, const char *expected)
|
||||||
{
|
{
|
||||||
hx509_env env;
|
hx509_env env = NULL;
|
||||||
hx509_name n;
|
hx509_name n;
|
||||||
char *s;
|
char *s;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
hx509_env_init(context, &env);
|
hx509_env_add(context, &env, "uid", "lha");
|
||||||
hx509_env_add(context, env, "uid", "lha");
|
|
||||||
|
|
||||||
ret = hx509_parse_name(context, name, &n);
|
ret = hx509_parse_name(context, name, &n);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
# Copyright (c) 2005 - 2007 Kungliga Tekniska H<>gskolan
|
# Copyright (c) 2005 - 2008 Kungliga Tekniska H<>gskolan
|
||||||
# (Royal Institute of Technology, Stockholm, Sweden).
|
# (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
@@ -51,7 +51,7 @@ echo "try printing"
|
|||||||
${hxtool} print \
|
${hxtool} print \
|
||||||
--pass=PASS:foobar \
|
--pass=PASS:foobar \
|
||||||
--info --content \
|
--info --content \
|
||||||
FILE:$srcdir/data/kdc.crt || exit 1
|
FILE:$srcdir/data/kdc.crt >/dev/null 2>/dev/null || exit 1
|
||||||
|
|
||||||
${hxtool} print \
|
${hxtool} print \
|
||||||
--pass=PASS:foobar \
|
--pass=PASS:foobar \
|
||||||
@@ -159,5 +159,39 @@ ${hxtool} query \
|
|||||||
--keyEncipherment \
|
--keyEncipherment \
|
||||||
FILE:$srcdir/data/test-ke-only.crt >/dev/null 2>/dev/null && exit 1
|
FILE:$srcdir/data/test-ke-only.crt >/dev/null 2>/dev/null && exit 1
|
||||||
|
|
||||||
exit 0
|
echo "make sure entry is found (eku) in query language"
|
||||||
|
${hxtool} query \
|
||||||
|
--expr='"1.3.6.1.5.2.3.5" IN %{certificate.eku}' \
|
||||||
|
FILE:$srcdir/data/kdc.crt > /dev/null || exit 1
|
||||||
|
|
||||||
|
echo "make sure entry is not found (eku) in query language"
|
||||||
|
${hxtool} query \
|
||||||
|
--expr='"1.3.6.1.5.2.3.6" IN %{certificate.eku}' \
|
||||||
|
FILE:$srcdir/data/kdc.crt > /dev/null && exit 1
|
||||||
|
|
||||||
|
echo "make sure entry is found (subject) in query language"
|
||||||
|
${hxtool} query \
|
||||||
|
--expr='%{certificate.subject} == "CN=kdc,C=SE"' \
|
||||||
|
FILE:$srcdir/data/kdc.crt > /dev/null || exit 1
|
||||||
|
|
||||||
|
echo "make sure entry is found using TAILMATCH (subject) in query language"
|
||||||
|
${hxtool} query \
|
||||||
|
--expr='%{certificate.subject} TAILMATCH "C=SE"' \
|
||||||
|
FILE:$srcdir/data/kdc.crt > /dev/null || exit 1
|
||||||
|
|
||||||
|
echo "make sure entry is not found using TAILMATCH (subject) in query language"
|
||||||
|
${hxtool} query \
|
||||||
|
--expr='%{certificate.subject} TAILMATCH "C=FI"' \
|
||||||
|
FILE:$srcdir/data/kdc.crt > /dev/null && exit 1
|
||||||
|
|
||||||
|
echo "make sure entry is found (issuer) in query language"
|
||||||
|
${hxtool} query \
|
||||||
|
--expr='%{certificate.issuer} == "C=SE,CN=hx509 Test Root CA"' \
|
||||||
|
FILE:$srcdir/data/kdc.crt > /dev/null || exit 1
|
||||||
|
|
||||||
|
echo "make sure entry match with EKU and TAILMATCH in query language"
|
||||||
|
${hxtool} query \
|
||||||
|
--expr='"1.3.6.1.5.2.3.5" IN %{certificate.eku} AND %{certificate.subject} TAILMATCH "C=SE"' \
|
||||||
|
FILE:$srcdir/data/kdc.crt > /dev/null || exit 1
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
Reference in New Issue
Block a user