summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/hx509/cert.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib/hx509/cert.c')
-rw-r--r--source4/heimdal/lib/hx509/cert.c162
1 files changed, 157 insertions, 5 deletions
diff --git a/source4/heimdal/lib/hx509/cert.c b/source4/heimdal/lib/hx509/cert.c
index 09c85bc084..3194526e34 100644
--- a/source4/heimdal/lib/hx509/cert.c
+++ b/source4/heimdal/lib/hx509/cert.c
@@ -32,7 +32,7 @@
*/
#include "hx_locl.h"
-RCSID("$Id: cert.c 22583 2008-02-11 20:46:21Z lha $");
+RCSID("$Id: cert.c 23457 2008-07-27 12:12:56Z lha $");
#include "crypto-headers.h"
#include <rtbl.h>
@@ -138,7 +138,7 @@ hx509_context_init(hx509_context *context)
/**
* Selects if the hx509_revoke_verify() function is going to require
- * the existans of a revokation method (OSCP, CRL) or not. Note that
+ * the existans of a revokation method (OCSP, CRL) or not. Note that
* hx509_verify_path(), hx509_cms_verify_signed(), and other function
* call hx509_revoke_verify().
*
@@ -485,6 +485,12 @@ hx509_verify_set_time(hx509_verify_ctx ctx, time_t t)
ctx->time_now = t;
}
+time_t
+_hx509_verify_get_time(hx509_verify_ctx ctx)
+{
+ return ctx->time_now;
+}
+
/**
* Set the maximum depth of the certificate chain that the path
* builder is going to try.
@@ -2355,7 +2361,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
@@ -2491,8 +2497,16 @@ hx509_cert_get_friendly_name(hx509_cert cert)
a = hx509_cert_get_attribute(cert, oid_id_pkcs_9_at_friendlyName());
if (a == NULL) {
- /* XXX use subject name ? */
- return NULL;
+ hx509_name name;
+
+ ret = hx509_cert_get_subject(cert, &name);
+ if (ret)
+ return NULL;
+ ret = hx509_name_to_string(name, &cert->friendlyname);
+ hx509_name_free(&name);
+ if (ret)
+ return NULL;
+ return cert->friendlyname;
}
ret = decode_PKCS9_friendlyName(a->data.data, a->data.length, &n, &sz);
@@ -2548,6 +2562,7 @@ hx509_query_alloc(hx509_context context, hx509_query **q)
return 0;
}
+
/**
* Set match options for the hx509 query controller.
*
@@ -2697,6 +2712,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 +2787,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 +2927,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_expr_eval(context, env, q->expr);
+ hx509_env_free(&env);
+ if (ret == 0)
+ return 0;
+ }
+
if (q->match & ~HX509_QUERY_MASK)
return 0;
@@ -2922,6 +2972,7 @@ _hx509_query_statistic(hx509_context context, int type, const hx509_query *q)
f = fopen(context->querystat, "a");
if (f == NULL)
return;
+ rk_cloexec_file(f);
fprintf(f, "%d %d\n", type, q->match);
fclose(f);
}
@@ -2992,6 +3043,7 @@ hx509_query_unparse_stats(hx509_context context, int printtype, FILE *out)
context->querystat, strerror(errno));
return;
}
+ rk_cloexec_file(f);
for (i = 0; i < sizeof(stats)/sizeof(stats[0]); i++) {
stats[i].index = i;
@@ -3206,3 +3258,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;
+}