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>
|
||||
|
||||
* version-script.map: add hx509_pem_read
|
||||
|
||||
* hxtool-commands.in: Add --pem to cms-verify-sd.
|
||||
|
||||
* test_cms.in: Test verifying PEM signature files.
|
||||
|
@@ -6,6 +6,7 @@ lib_LTLIBRARIES = libhx509.la
|
||||
libhx509_la_LDFLAGS = -version-info 3:0:0
|
||||
|
||||
BUILT_SOURCES = \
|
||||
sel-gram.h \
|
||||
$(gen_files_ocsp:.x=.c) \
|
||||
$(gen_files_pkcs10:.x=.c) \
|
||||
hx509_err.c \
|
||||
@@ -50,6 +51,8 @@ gen_files_crmf = \
|
||||
asn1_ProofOfPossession.x \
|
||||
asn1_SubsequentMessage.x
|
||||
|
||||
AM_YFLAGS = -d
|
||||
|
||||
dist_libhx509_la_SOURCES = \
|
||||
ca.c \
|
||||
cert.c \
|
||||
@@ -64,6 +67,10 @@ dist_libhx509_la_SOURCES = \
|
||||
hx509-protos.h \
|
||||
hx509.h \
|
||||
hx_locl.h \
|
||||
sel.c \
|
||||
sel.h \
|
||||
sel-gram.y \
|
||||
sel-lex.l \
|
||||
keyset.c \
|
||||
ks_dir.c \
|
||||
ks_file.c \
|
||||
@@ -81,6 +88,8 @@ dist_libhx509_la_SOURCES = \
|
||||
req.c \
|
||||
revoke.c
|
||||
|
||||
sel-lex.c: sel-gram.h
|
||||
|
||||
libhx509_la_LIBADD = \
|
||||
$(LIB_com_err) \
|
||||
$(LIB_hcrypto) \
|
||||
@@ -184,7 +193,8 @@ test_soft_pkcs11_CPPFLAGS = -I$(srcdir)/ref
|
||||
TESTS = $(SCRIPT_TESTS) $(PROGRAM_TESTS)
|
||||
|
||||
PROGRAM_TESTS = \
|
||||
test_name
|
||||
test_name \
|
||||
test_expr
|
||||
|
||||
SCRIPT_TESTS = \
|
||||
test_ca \
|
||||
|
138
lib/hx509/cert.c
138
lib/hx509/cert.c
@@ -2355,7 +2355,7 @@ hx509_verify_hostname(hx509_context context,
|
||||
} while (1);
|
||||
|
||||
{
|
||||
Name *name = &cert->data->tbsCertificate.subject;
|
||||
const Name *name = &cert->data->tbsCertificate.subject;
|
||||
|
||||
/* match if first component is a CN= */
|
||||
if (name->u.rdnSequence.len > 0
|
||||
@@ -2548,6 +2548,7 @@ hx509_query_alloc(hx509_context context, hx509_query **q)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
@@ -2753,6 +2773,9 @@ hx509_query_free(hx509_context context, hx509_query *q)
|
||||
}
|
||||
if (q->friendlyname)
|
||||
free(q->friendlyname);
|
||||
if (q->expr)
|
||||
_hx509_expr_free(q->expr);
|
||||
|
||||
memset(q, 0, sizeof(*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))
|
||||
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)
|
||||
return 0;
|
||||
|
||||
@@ -3206,3 +3242,103 @@ hx509_xfree(void *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).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -40,36 +40,6 @@ RCSID("$Id$");
|
||||
* 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.
|
||||
*
|
||||
@@ -84,34 +54,92 @@ hx509_env_init(hx509_context context, hx509_env *env)
|
||||
*/
|
||||
|
||||
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)
|
||||
{
|
||||
void *ptr;
|
||||
hx509_env n;
|
||||
|
||||
ptr = realloc(env->val, sizeof(env->val[0]) * (env->len + 1));
|
||||
if (ptr == NULL) {
|
||||
n = malloc(sizeof(*n));
|
||||
if (n == NULL) {
|
||||
hx509_set_error_string(context, 0, ENOMEM, "out of memory");
|
||||
return ENOMEM;
|
||||
}
|
||||
env->val = ptr;
|
||||
env->val[env->len].key = strdup(key);
|
||||
if (env->val[env->len].key == NULL) {
|
||||
hx509_set_error_string(context, 0, ENOMEM, "out of memory");
|
||||
|
||||
n->type = env_string;
|
||||
n->next = NULL;
|
||||
n->name = strdup(key);
|
||||
if (n->name == NULL) {
|
||||
free(n);
|
||||
return ENOMEM;
|
||||
}
|
||||
env->val[env->len].value = strdup(value);
|
||||
if (env->val[env->len].value == NULL) {
|
||||
free(env->val[env->len].key);
|
||||
hx509_set_error_string(context, 0, ENOMEM, "out of memory");
|
||||
n->u.string = strdup(value);
|
||||
if (n->u.string == NULL) {
|
||||
free(n->name);
|
||||
free(n);
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 env enviroment to add the enviroment variable too.
|
||||
@@ -127,16 +155,80 @@ const char *
|
||||
hx509_env_lfind(hx509_context context, hx509_env env,
|
||||
const char *key, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < env->len; i++) {
|
||||
char *s = env->val[i].key;
|
||||
if (strncmp(key, s, len) == 0 && s[len] == '\0')
|
||||
return env->val[i].value;
|
||||
while(env) {
|
||||
if (strncmp(key, env->name ,len) == 0
|
||||
&& env->name[len] == '\0' && env->type == env_string)
|
||||
return env->u.string;
|
||||
env = env->next;
|
||||
}
|
||||
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.
|
||||
*
|
||||
@@ -148,14 +240,7 @@ hx509_env_lfind(hx509_context context, hx509_env env,
|
||||
void
|
||||
hx509_env_free(hx509_env *env)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < (*env)->len; i++) {
|
||||
free((*env)->val[i].key);
|
||||
free((*env)->val[i].value);
|
||||
}
|
||||
free((*env)->val);
|
||||
free(*env);
|
||||
if (*env)
|
||||
env_free(*env);
|
||||
*env = NULL;
|
||||
}
|
||||
|
||||
|
@@ -50,7 +50,7 @@ typedef struct hx509_request_data *hx509_request;
|
||||
typedef struct hx509_error_data *hx509_error;
|
||||
typedef struct hx509_peer_info *hx509_peer_info;
|
||||
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 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;
|
||||
|
||||
#include "sel.h"
|
||||
|
||||
#include <hx509-private.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_TIME 0x200000
|
||||
#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 *certificate;
|
||||
heim_integer *serial;
|
||||
@@ -144,6 +147,7 @@ struct hx509_query_data {
|
||||
heim_octet_string *keyhash_sha1;
|
||||
time_t timenow;
|
||||
heim_oid *eku;
|
||||
struct hx_expr *expr;
|
||||
};
|
||||
|
||||
struct hx509_keyset_ops {
|
||||
@@ -188,6 +192,18 @@ struct hx509_context_data {
|
||||
/* _hx509_calculate_path flag field */
|
||||
#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_digest_alg;
|
||||
extern const AlgorithmIdentifier * _hx509_crypto_default_secret_alg;
|
||||
|
@@ -448,6 +448,12 @@ command = {
|
||||
argument = "oid-string"
|
||||
help = "match on EKU"
|
||||
}
|
||||
option = {
|
||||
long = "expr"
|
||||
type = "string"
|
||||
argument = "expression"
|
||||
help = "match on expression"
|
||||
}
|
||||
option = {
|
||||
long = "keyEncipherment"
|
||||
type = "flag"
|
||||
|
@@ -942,6 +942,9 @@ query(struct query_options *opt, int argc, char **argv)
|
||||
if (opt->digitalSignature_flag)
|
||||
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);
|
||||
hx509_query_free(context, q);
|
||||
if (ret)
|
||||
|
@@ -897,7 +897,7 @@ hx509_name_is_null_p(const hx509_name name)
|
||||
* @param name the name to print
|
||||
* @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
|
||||
*/
|
||||
|
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
|
||||
test_expand(hx509_context context, const char *name, const char *expected)
|
||||
{
|
||||
hx509_env env;
|
||||
hx509_env env = NULL;
|
||||
hx509_name n;
|
||||
char *s;
|
||||
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);
|
||||
if (ret)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2005 - 2007 Kungliga Tekniska H<>gskolan
|
||||
# Copyright (c) 2005 - 2008 Kungliga Tekniska H<>gskolan
|
||||
# (Royal Institute of Technology, Stockholm, Sweden).
|
||||
# All rights reserved.
|
||||
#
|
||||
@@ -51,7 +51,7 @@ echo "try printing"
|
||||
${hxtool} print \
|
||||
--pass=PASS:foobar \
|
||||
--info --content \
|
||||
FILE:$srcdir/data/kdc.crt || exit 1
|
||||
FILE:$srcdir/data/kdc.crt >/dev/null 2>/dev/null || exit 1
|
||||
|
||||
${hxtool} print \
|
||||
--pass=PASS:foobar \
|
||||
@@ -159,5 +159,39 @@ ${hxtool} query \
|
||||
--keyEncipherment \
|
||||
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