summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/krb5
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib/krb5')
-rw-r--r--source4/heimdal/lib/krb5/acache.c64
-rw-r--r--source4/heimdal/lib/krb5/addr_families.c3
-rw-r--r--source4/heimdal/lib/krb5/build_auth.c11
-rw-r--r--source4/heimdal/lib/krb5/cache.c5
-rw-r--r--source4/heimdal/lib/krb5/config_file.c4
-rw-r--r--source4/heimdal/lib/krb5/crypto.c6
-rw-r--r--source4/heimdal/lib/krb5/data.c3
-rw-r--r--source4/heimdal/lib/krb5/fcache.c7
-rw-r--r--source4/heimdal/lib/krb5/get_for_creds.c7
-rw-r--r--source4/heimdal/lib/krb5/init_creds.c4
-rw-r--r--source4/heimdal/lib/krb5/init_creds_pw.c29
-rw-r--r--source4/heimdal/lib/krb5/keytab_any.c33
-rw-r--r--source4/heimdal/lib/krb5/keytab_file.c40
-rw-r--r--source4/heimdal/lib/krb5/keytab_keyfile.c3
-rw-r--r--source4/heimdal/lib/krb5/keytab_krb4.c13
-rw-r--r--source4/heimdal/lib/krb5/krb5-private.h14
-rw-r--r--source4/heimdal/lib/krb5/krb5-protos.h2
-rw-r--r--source4/heimdal/lib/krb5/krb5_ccapi.h21
-rw-r--r--source4/heimdal/lib/krb5/krbhst.c7
-rw-r--r--source4/heimdal/lib/krb5/log.c8
-rwxr-xr-xsource4/heimdal/lib/krb5/pkinit.c1732
-rw-r--r--source4/heimdal/lib/krb5/principal.c22
-rw-r--r--source4/heimdal/lib/krb5/rd_cred.c7
-rw-r--r--source4/heimdal/lib/krb5/rd_priv.c8
-rw-r--r--source4/heimdal/lib/krb5/rd_req.c25
-rw-r--r--source4/heimdal/lib/krb5/replay.c10
-rw-r--r--source4/heimdal/lib/krb5/send_to_kdc.c5
-rw-r--r--source4/heimdal/lib/krb5/store.c23
-rw-r--r--source4/heimdal/lib/krb5/transited.c11
-rw-r--r--source4/heimdal/lib/krb5/v4_glue.c19
30 files changed, 594 insertions, 1552 deletions
diff --git a/source4/heimdal/lib/krb5/acache.c b/source4/heimdal/lib/krb5/acache.c
index 7cf2c65d89..b38104fc2d 100644
--- a/source4/heimdal/lib/krb5/acache.c
+++ b/source4/heimdal/lib/krb5/acache.c
@@ -37,7 +37,7 @@
#include <dlfcn.h>
#endif
-RCSID("$Id: acache.c,v 1.14 2005/10/03 08:44:18 lha Exp $");
+RCSID("$Id: acache.c,v 1.15 2006/03/27 04:22:23 lha Exp $");
/* XXX should we fetch these for each open ? */
static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER;
@@ -218,7 +218,36 @@ make_cred_from_ccred(krb5_context context,
}
}
- cred->flags.b = int2TicketFlags(incred->ticket_flags); /* XXX */
+ cred->flags.i = 0;
+ if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_FORWARDABLE)
+ cred->flags.b.forwardable = 1;
+ if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_FORWARDED)
+ cred->flags.b.forwarded = 1;
+ if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_PROXIABLE)
+ cred->flags.b.proxiable = 1;
+ if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_PROXY)
+ cred->flags.b.proxy = 1;
+ if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_MAY_POSTDATE)
+ cred->flags.b.may_postdate = 1;
+ if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_POSTDATED)
+ cred->flags.b.postdated = 1;
+ if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_INVALID)
+ cred->flags.b.invalid = 1;
+ if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_RENEWABLE)
+ cred->flags.b.renewable = 1;
+ if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_INITIAL)
+ cred->flags.b.initial = 1;
+ if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_PRE_AUTH)
+ cred->flags.b.pre_authent = 1;
+ if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_HW_AUTH)
+ cred->flags.b.hw_authent = 1;
+ if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_TRANSIT_POLICY_CHECKED)
+ cred->flags.b.transited_policy_checked = 1;
+ if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_OK_AS_DELEGATE)
+ cred->flags.b.ok_as_delegate = 1;
+ if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_ANONYMOUS)
+ cred->flags.b.anonymous = 1;
+
return 0;
nomem:
@@ -310,7 +339,36 @@ make_ccred_from_cred(krb5_context context,
}
cred->addresses[i] = NULL;
- cred->ticket_flags = TicketFlags2int(incred->flags.b); /* XXX */
+ cred->ticket_flags = 0;
+ if (incred->flags.b.forwardable)
+ cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_FORWARDABLE;
+ if (incred->flags.b.forwarded)
+ cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_FORWARDED;
+ if (incred->flags.b.proxiable)
+ cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_PROXIABLE;
+ if (incred->flags.b.proxy)
+ cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_PROXY;
+ if (incred->flags.b.may_postdate)
+ cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_MAY_POSTDATE;
+ if (incred->flags.b.postdated)
+ cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_POSTDATED;
+ if (incred->flags.b.invalid)
+ cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_INVALID;
+ if (incred->flags.b.renewable)
+ cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_RENEWABLE;
+ if (incred->flags.b.initial)
+ cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_INITIAL;
+ if (incred->flags.b.pre_authent)
+ cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_PRE_AUTH;
+ if (incred->flags.b.hw_authent)
+ cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_HW_AUTH;
+ if (incred->flags.b.transited_policy_checked)
+ cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_TRANSIT_POLICY_CHECKED;
+ if (incred->flags.b.ok_as_delegate)
+ cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_OK_AS_DELEGATE;
+ if (incred->flags.b.anonymous)
+ cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_ANONYMOUS;
+
return 0;
fail:
diff --git a/source4/heimdal/lib/krb5/addr_families.c b/source4/heimdal/lib/krb5/addr_families.c
index cf460ba725..ebdbcfed46 100644
--- a/source4/heimdal/lib/krb5/addr_families.c
+++ b/source4/heimdal/lib/krb5/addr_families.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: addr_families.c,v 1.50 2006/03/17 22:12:13 lha Exp $");
+RCSID("$Id: addr_families.c,v 1.51 2006/04/02 02:17:31 lha Exp $");
struct addr_operations {
int af;
@@ -1136,6 +1136,7 @@ krb5_make_addrport (krb5_context context,
if (ret) {
krb5_set_error_string(context, "malloc: out of memory");
free (*res);
+ *res = NULL;
return ret;
}
p = (*res)->address.data;
diff --git a/source4/heimdal/lib/krb5/build_auth.c b/source4/heimdal/lib/krb5/build_auth.c
index 1c38721b02..9eff09bb0a 100644
--- a/source4/heimdal/lib/krb5/build_auth.c
+++ b/source4/heimdal/lib/krb5/build_auth.c
@@ -33,7 +33,7 @@
#include <krb5_locl.h>
-RCSID("$Id: build_auth.c,v 1.42 2005/01/05 02:34:53 lukeh Exp $");
+RCSID("$Id: build_auth.c,v 1.43 2006/04/10 08:53:21 lha Exp $");
static krb5_error_code
make_etypelist(krb5_context context,
@@ -116,13 +116,12 @@ krb5_build_authenticator (krb5_context context,
krb5_error_code ret;
krb5_crypto crypto;
- auth = malloc(sizeof(*auth));
+ auth = calloc(1, sizeof(*auth));
if (auth == NULL) {
krb5_set_error_string(context, "malloc: out of memory");
return ENOMEM;
}
- memset (auth, 0, sizeof(*auth));
auth->authenticator_vno = 5;
copy_Realm(&cred->client->realm, &auth->crealm);
copy_PrincipalName(&cred->client->name, &auth->cname);
@@ -161,10 +160,8 @@ krb5_build_authenticator (krb5_context context,
/* XXX - Copy more to auth_context? */
- if (auth_context) {
- auth_context->authenticator->ctime = auth->ctime;
- auth_context->authenticator->cusec = auth->cusec;
- }
+ auth_context->authenticator->ctime = auth->ctime;
+ auth_context->authenticator->cusec = auth->cusec;
ASN1_MALLOC_ENCODE(Authenticator, buf, buf_size, auth, &len, ret);
if (ret)
diff --git a/source4/heimdal/lib/krb5/cache.c b/source4/heimdal/lib/krb5/cache.c
index efb2ad1374..b21d42d653 100644
--- a/source4/heimdal/lib/krb5/cache.c
+++ b/source4/heimdal/lib/krb5/cache.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: cache.c,v 1.77 2005/12/13 15:42:36 lha Exp $");
+RCSID("$Id: cache.c,v 1.79 2006/04/02 00:54:48 lha Exp $");
/*
* Add a new ccache type with operations `ops', overwriting any
@@ -316,7 +316,7 @@ _krb5_expand_default_cc_name(krb5_context context, const char *str, char **res)
}
if (append == NULL) {
free(*res);
- res = NULL;
+ *res = NULL;
krb5_set_error_string(context, "malloc - out of memory");
return ENOMEM;
}
@@ -324,6 +324,7 @@ _krb5_expand_default_cc_name(krb5_context context, const char *str, char **res)
tlen = strlen(append);
tmp = realloc(*res, len + tlen + 1);
if (tmp == NULL) {
+ free(append);
free(*res);
*res = NULL;
krb5_set_error_string(context, "malloc - out of memory");
diff --git a/source4/heimdal/lib/krb5/config_file.c b/source4/heimdal/lib/krb5/config_file.c
index 86e286c638..66051303ed 100644
--- a/source4/heimdal/lib/krb5/config_file.c
+++ b/source4/heimdal/lib/krb5/config_file.c
@@ -32,7 +32,7 @@
*/
#include "krb5_locl.h"
-RCSID("$Id: config_file.c,v 1.53 2005/06/16 20:22:53 lha Exp $");
+RCSID("$Id: config_file.c,v 1.54 2006/04/02 00:59:19 lha Exp $");
#ifndef HAVE_NETINFO
@@ -574,7 +574,7 @@ krb5_config_vget_strings(krb5_context context,
}
if(nstr){
char **tmp = realloc(strings, (nstr + 1) * sizeof(*strings));
- if(strings == NULL)
+ if(tmp == NULL)
goto cleanup;
strings = tmp;
strings[nstr] = NULL;
diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c
index 039484c650..3a90995283 100644
--- a/source4/heimdal/lib/krb5/crypto.c
+++ b/source4/heimdal/lib/krb5/crypto.c
@@ -32,7 +32,7 @@
*/
#include "krb5_locl.h"
-RCSID("$Id: crypto.c,v 1.133 2006/03/07 19:34:55 lha Exp $");
+RCSID("$Id: crypto.c,v 1.134 2006/04/10 08:58:53 lha Exp $");
#undef CRYPTO_DEBUG
#ifdef CRYPTO_DEBUG
@@ -4096,7 +4096,7 @@ krb5_string_to_key_derived(krb5_context context,
struct encryption_type *et = _find_enctype(etype);
krb5_error_code ret;
struct key_data kd;
- size_t keylen = et->keytype->bits / 8;
+ size_t keylen;
u_char *tmp;
if(et == NULL) {
@@ -4104,6 +4104,8 @@ krb5_string_to_key_derived(krb5_context context,
etype);
return KRB5_PROG_ETYPE_NOSUPP;
}
+ keylen = et->keytype->bits / 8;
+
ALLOC(kd.key, 1);
if(kd.key == NULL) {
krb5_set_error_string (context, "malloc: out of memory");
diff --git a/source4/heimdal/lib/krb5/data.c b/source4/heimdal/lib/krb5/data.c
index 9cf1410e70..3192c4c64f 100644
--- a/source4/heimdal/lib/krb5/data.c
+++ b/source4/heimdal/lib/krb5/data.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: data.c,v 1.19 2004/05/25 21:22:23 lha Exp $");
+RCSID("$Id: data.c,v 1.20 2006/04/02 01:06:07 lha Exp $");
void KRB5_LIB_FUNCTION
krb5_data_zero(krb5_data *p)
@@ -114,6 +114,7 @@ krb5_copy_data(krb5_context context,
if(ret) {
krb5_clear_error_string (context);
free(*outdata);
+ *outdata = NULL;
}
return ret;
}
diff --git a/source4/heimdal/lib/krb5/fcache.c b/source4/heimdal/lib/krb5/fcache.c
index f8ebe837b7..79b809d2a2 100644
--- a/source4/heimdal/lib/krb5/fcache.c
+++ b/source4/heimdal/lib/krb5/fcache.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: fcache.c,v 1.51 2005/08/12 13:31:19 lha Exp $");
+RCSID("$Id: fcache.c,v 1.52 2006/04/02 01:04:37 lha Exp $");
typedef struct krb5_fcache{
char *filename;
@@ -269,10 +269,11 @@ fcc_gen_new(krb5_context context, krb5_ccache *id)
}
fd = mkstemp(file);
if(fd < 0) {
+ int ret = errno;
+ krb5_set_error_string(context, "mkstemp %s", file);
free(f);
free(file);
- krb5_set_error_string(context, "mkstemp %s", file);
- return errno;
+ return ret;
}
close(fd);
f->filename = file;
diff --git a/source4/heimdal/lib/krb5/get_for_creds.c b/source4/heimdal/lib/krb5/get_for_creds.c
index dafe668b5d..661d05663b 100644
--- a/source4/heimdal/lib/krb5/get_for_creds.c
+++ b/source4/heimdal/lib/krb5/get_for_creds.c
@@ -33,7 +33,7 @@
#include <krb5_locl.h>
-RCSID("$Id: get_for_creds.c,v 1.48 2006/03/07 19:38:09 lha Exp $");
+RCSID("$Id: get_for_creds.c,v 1.49 2006/04/10 09:28:15 lha Exp $");
static krb5_error_code
add_addrs(krb5_context context,
@@ -180,10 +180,7 @@ krb5_get_forwarded_creds (krb5_context context,
addrs.len = 0;
addrs.val = NULL;
- if (in_creds->client && in_creds->client->realm)
- realm = in_creds->client->realm;
- else
- realm = in_creds->server->realm;
+ realm = in_creds->client->realm;
krb5_appdefault_boolean(context, NULL, realm, "no-addresses-ever",
TRUE, &noaddr_ever);
diff --git a/source4/heimdal/lib/krb5/init_creds.c b/source4/heimdal/lib/krb5/init_creds.c
index 316c2f02eb..88de280a00 100644
--- a/source4/heimdal/lib/krb5/init_creds.c
+++ b/source4/heimdal/lib/krb5/init_creds.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: init_creds.c,v 1.22 2006/02/03 11:42:31 lha Exp $");
+RCSID("$Id: init_creds.c,v 1.23 2006/04/02 01:08:30 lha Exp $");
void KRB5_LIB_FUNCTION
krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt)
@@ -75,7 +75,7 @@ _krb5_get_init_creds_opt_copy(krb5_context context,
krb5_get_init_creds_opt *opt;
*out = NULL;
- opt = malloc(sizeof(*opt));
+ opt = calloc(1, sizeof(*opt));
if (opt == NULL) {
krb5_set_error_string(context, "out of memory");
return ENOMEM;
diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c
index 3c694624bf..489a88a31b 100644
--- a/source4/heimdal/lib/krb5/init_creds_pw.c
+++ b/source4/heimdal/lib/krb5/init_creds_pw.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: init_creds_pw.c,v 1.90 2005/10/12 12:45:11 lha Exp $");
+RCSID("$Id: init_creds_pw.c,v 1.92 2006/04/02 01:20:15 lha Exp $");
typedef struct krb5_get_init_creds_ctx {
krb5_kdc_flags flags;
@@ -79,8 +79,10 @@ default_s2k_func(krb5_context context, krb5_enctype type,
return ENOMEM;
ret = krb5_string_to_key_data_salt_opaque(context, type, password,
salt, opaque, *key);
- if (ret)
+ if (ret) {
free(*key);
+ *key = NULL;
+ }
return ret;
}
@@ -545,23 +547,14 @@ init_creds_init_as_req (krb5_context context,
krb5_set_error_string(context, "malloc: out of memory");
goto fail;
}
- if (creds->client) {
- ret = _krb5_principal2principalname (a->req_body.cname, creds->client);
- if (ret)
- goto fail;
- ret = copy_Realm(&creds->client->realm, &a->req_body.realm);
- if (ret)
- goto fail;
- } else {
- krb5_realm realm;
- a->req_body.cname = NULL;
- ret = krb5_get_default_realm(context, &realm);
- if (ret)
- goto fail;
- ret = copy_Realm(&realm, &a->req_body.realm);
- free(realm);
- }
+ ret = _krb5_principal2principalname (a->req_body.cname, creds->client);
+ if (ret)
+ goto fail;
+ ret = copy_Realm(&creds->client->realm, &a->req_body.realm);
+ if (ret)
+ goto fail;
+
ret = _krb5_principal2principalname (a->req_body.sname, creds->server);
if (ret)
goto fail;
diff --git a/source4/heimdal/lib/krb5/keytab_any.c b/source4/heimdal/lib/krb5/keytab_any.c
index 667788c69d..d5130aaad8 100644
--- a/source4/heimdal/lib/krb5/keytab_any.c
+++ b/source4/heimdal/lib/krb5/keytab_any.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: keytab_any.c,v 1.7 2002/10/21 13:36:59 joda Exp $");
+RCSID("$Id: keytab_any.c,v 1.8 2006/04/10 09:20:13 lha Exp $");
struct any_data {
krb5_keytab kt;
@@ -162,23 +162,22 @@ any_next_entry (krb5_context context,
ret = krb5_kt_next_entry(context, ed->a->kt, entry, &ed->cursor);
if (ret == 0)
return 0;
- else if (ret == KRB5_KT_END) {
- ret2 = krb5_kt_end_seq_get (context, ed->a->kt, &ed->cursor);
- if (ret2)
- return ret2;
- while ((ed->a = ed->a->next) != NULL) {
- ret2 = krb5_kt_start_seq_get(context, ed->a->kt, &ed->cursor);
- if (ret2 == 0)
- break;
- }
- if (ed->a == NULL) {
- krb5_clear_error_string (context);
- return KRB5_KT_END;
- }
- } else
+ else if (ret != KRB5_KT_END)
return ret;
- } while (ret == KRB5_KT_END);
- return ret;
+
+ ret2 = krb5_kt_end_seq_get (context, ed->a->kt, &ed->cursor);
+ if (ret2)
+ return ret2;
+ while ((ed->a = ed->a->next) != NULL) {
+ ret2 = krb5_kt_start_seq_get(context, ed->a->kt, &ed->cursor);
+ if (ret2 == 0)
+ break;
+ }
+ if (ed->a == NULL) {
+ krb5_clear_error_string (context);
+ return KRB5_KT_END;
+ }
+ } while (1);
}
static krb5_error_code
diff --git a/source4/heimdal/lib/krb5/keytab_file.c b/source4/heimdal/lib/krb5/keytab_file.c
index 6ff2680ed1..f9a76e634a 100644
--- a/source4/heimdal/lib/krb5/keytab_file.c
+++ b/source4/heimdal/lib/krb5/keytab_file.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: keytab_file.c,v 1.20 2005/07/13 06:08:07 lha Exp $");
+RCSID("$Id: keytab_file.c,v 1.22 2006/04/07 21:57:31 lha Exp $");
#define KRB5_KT_VNO_1 1
#define KRB5_KT_VNO_2 2
@@ -164,7 +164,7 @@ krb5_kt_ret_principal(krb5_context context,
int i;
int ret;
krb5_principal p;
- int16_t tmp;
+ int16_t len;
ALLOC(p, 1);
if(p == NULL) {
@@ -172,25 +172,34 @@ krb5_kt_ret_principal(krb5_context context,
return ENOMEM;
}
- ret = krb5_ret_int16(sp, &tmp);
- if(ret)
- return ret;
+ ret = krb5_ret_int16(sp, &len);
+ if(ret) {
+ krb5_set_error_string(context,
+ "Failed decoding length of keytab principal");
+ goto out;
+ }
if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
- tmp--;
- p->name.name_string.len = tmp;
+ len--;
+ if (len < 0) {
+ krb5_set_error_string(context,
+ "Keytab principal contains invalid length");
+ ret = KRB5_KT_END;
+ goto out;
+ }
ret = krb5_kt_ret_string(context, sp, &p->realm);
if(ret)
- return ret;
- p->name.name_string.val = calloc(p->name.name_string.len,
- sizeof(*p->name.name_string.val));
+ goto out;
+ p->name.name_string.val = calloc(len, sizeof(*p->name.name_string.val));
if(p->name.name_string.val == NULL) {
krb5_set_error_string (context, "malloc: out of memory");
- return ENOMEM;
+ ret = ENOMEM;
+ goto out;
}
+ p->name.name_string.len = len;
for(i = 0; i < p->name.name_string.len; i++){
ret = krb5_kt_ret_string(context, sp, p->name.name_string.val + i);
if(ret)
- return ret;
+ goto out;
}
if (krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
p->name.name_type = KRB5_NT_UNKNOWN;
@@ -199,10 +208,13 @@ krb5_kt_ret_principal(krb5_context context,
ret = krb5_ret_int32(sp, &tmp32);
p->name.name_type = tmp32;
if (ret)
- return ret;
+ goto out;
}
*princ = p;
return 0;
+out:
+ krb5_free_principal(context, p);
+ return ret;
}
static krb5_error_code
@@ -423,7 +435,7 @@ loop:
}
}
if(start) *start = pos;
- if(end) *end = *start + 4 + len;
+ if(end) *end = pos + 4 + len;
out:
krb5_storage_seek(cursor->sp, pos + 4 + len, SEEK_SET);
return ret;
diff --git a/source4/heimdal/lib/krb5/keytab_keyfile.c b/source4/heimdal/lib/krb5/keytab_keyfile.c
index 5c94291e72..32fb48a8a2 100644
--- a/source4/heimdal/lib/krb5/keytab_keyfile.c
+++ b/source4/heimdal/lib/krb5/keytab_keyfile.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: keytab_keyfile.c,v 1.17 2005/09/30 11:20:53 lha Exp $");
+RCSID("$Id: keytab_keyfile.c,v 1.18 2006/04/02 01:24:52 lha Exp $");
/* afs keyfile operations --------------------------------------- */
@@ -94,6 +94,7 @@ get_cell_and_realm (krb5_context context,
f = fopen (AFS_SERVERMAGICKRBCONF, "r");
if (f != NULL) {
if (fgets (buf, sizeof(buf), f) == NULL) {
+ free (d->cell);
fclose (f);
krb5_set_error_string (context, "no realm in %s",
AFS_SERVERMAGICKRBCONF);
diff --git a/source4/heimdal/lib/krb5/keytab_krb4.c b/source4/heimdal/lib/krb5/keytab_krb4.c
index 1a83faca57..19e7f106bf 100644
--- a/source4/heimdal/lib/krb5/keytab_krb4.c
+++ b/source4/heimdal/lib/krb5/keytab_krb4.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: keytab_krb4.c,v 1.13 2005/05/19 04:13:18 lha Exp $");
+RCSID("$Id: keytab_krb4.c,v 1.15 2006/04/10 17:10:53 lha Exp $");
struct krb4_kt_data {
char *filename;
@@ -139,6 +139,11 @@ krb4_kt_start_seq_get_int (krb5_context context,
return ret;
}
c->sp = krb5_storage_from_fd(c->fd);
+ if(c->sp == NULL) {
+ close(c->fd);
+ free(ed);
+ return ENOMEM;
+ }
krb5_storage_set_eof_code(c->sp, KRB5_KT_END);
return 0;
}
@@ -302,11 +307,11 @@ krb4_kt_add_entry (krb5_context context,
}
}
sp = krb5_storage_from_fd(fd);
- krb5_storage_set_eof_code(sp, KRB5_KT_END);
if(sp == NULL) {
close(fd);
return ENOMEM;
}
+ krb5_storage_set_eof_code(sp, KRB5_KT_END);
ret = krb4_store_keytab_entry(context, entry, sp);
krb5_storage_free(sp);
if(close (fd) < 0)
@@ -316,8 +321,8 @@ krb4_kt_add_entry (krb5_context context,
static krb5_error_code
krb4_kt_remove_entry(krb5_context context,
- krb5_keytab id,
- krb5_keytab_entry *entry)
+ krb5_keytab id,
+ krb5_keytab_entry *entry)
{
struct krb4_kt_data *d = id->data;
krb5_error_code ret;
diff --git a/source4/heimdal/lib/krb5/krb5-private.h b/source4/heimdal/lib/krb5/krb5-private.h
index 8d9b3c62ac..00126d60ed 100644
--- a/source4/heimdal/lib/krb5/krb5-private.h
+++ b/source4/heimdal/lib/krb5/krb5-private.h
@@ -302,19 +302,13 @@ void KRB5_LIB_FUNCTION
_krb5_pk_cert_free (struct krb5_pk_cert */*cert*/);
krb5_error_code KRB5_LIB_FUNCTION
-_krb5_pk_create_sign (
- krb5_context /*context*/,
- const heim_oid */*eContentType*/,
- krb5_data */*eContent*/,
- struct krb5_pk_identity */*id*/,
- krb5_data */*sd_data*/);
-
-krb5_error_code KRB5_LIB_FUNCTION
-_krb5_pk_load_openssl_id (
+_krb5_pk_load_id (
krb5_context /*context*/,
struct krb5_pk_identity **/*ret_id*/,
const char */*user_id*/,
- const char */*x509_anchors*/,
+ const char */*anchor_id*/,
+ char * const */*chain*/,
+ char * const */*revoke*/,
krb5_prompter_fct /*prompter*/,
void */*prompter_data*/,
char */*password*/);
diff --git a/source4/heimdal/lib/krb5/krb5-protos.h b/source4/heimdal/lib/krb5/krb5-protos.h
index d7e74621ef..56f43f6c3d 100644
--- a/source4/heimdal/lib/krb5/krb5-protos.h
+++ b/source4/heimdal/lib/krb5/krb5-protos.h
@@ -1874,6 +1874,8 @@ krb5_get_init_creds_opt_set_pkinit (
krb5_principal /*principal*/,
const char */*user_id*/,
const char */*x509_anchors*/,
+ char * const * /*chain*/,
+ char * const * /*revoke*/,
int /*flags*/,
krb5_prompter_fct /*prompter*/,
void */*prompter_data*/,
diff --git a/source4/heimdal/lib/krb5/krb5_ccapi.h b/source4/heimdal/lib/krb5/krb5_ccapi.h
index 00c30d7791..29b2ddbecc 100644
--- a/source4/heimdal/lib/krb5/krb5_ccapi.h
+++ b/source4/heimdal/lib/krb5/krb5_ccapi.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-/* $Id: krb5_ccapi.h,v 1.1 2004/09/11 04:00:42 lha Exp $ */
+/* $Id: krb5_ccapi.h,v 1.2 2006/03/27 04:21:06 lha Exp $ */
#ifndef KRB5_CCAPI_H
#define KRB5_CCAPI_H 1
@@ -43,7 +43,8 @@ enum {
};
enum {
- ccapi_version_3 = 3
+ ccapi_version_3 = 3,
+ ccapi_version_4 = 4
};
enum {
@@ -108,7 +109,21 @@ struct cc_credentials_v5_t {
cc_time_t endtime;
cc_time_t renew_till;
cc_uint32 is_skey;
- cc_uint32 ticket_flags; /* XXX ticket flags undefined */
+ cc_uint32 ticket_flags;
+#define KRB5_CCAPI_TKT_FLG_FORWARDABLE 0x40000000
+#define KRB5_CCAPI_TKT_FLG_FORWARDED 0x20000000
+#define KRB5_CCAPI_TKT_FLG_PROXIABLE 0x10000000
+#define KRB5_CCAPI_TKT_FLG_PROXY 0x08000000
+#define KRB5_CCAPI_TKT_FLG_MAY_POSTDATE 0x04000000
+#define KRB5_CCAPI_TKT_FLG_POSTDATED 0x02000000
+#define KRB5_CCAPI_TKT_FLG_INVALID 0x01000000
+#define KRB5_CCAPI_TKT_FLG_RENEWABLE 0x00800000
+#define KRB5_CCAPI_TKT_FLG_INITIAL 0x00400000
+#define KRB5_CCAPI_TKT_FLG_PRE_AUTH 0x00200000
+#define KRB5_CCAPI_TKT_FLG_HW_AUTH 0x00100000
+#define KRB5_CCAPI_TKT_FLG_TRANSIT_POLICY_CHECKED 0x00080000
+#define KRB5_CCAPI_TKT_FLG_OK_AS_DELEGATE 0x00040000
+#define KRB5_CCAPI_TKT_FLG_ANONYMOUS 0x00020000
cc_data **addresses;
cc_data ticket;
cc_data second_ticket;
diff --git a/source4/heimdal/lib/krb5/krbhst.c b/source4/heimdal/lib/krb5/krbhst.c
index ef9f5dbd60..221bd706f4 100644
--- a/source4/heimdal/lib/krb5/krbhst.c
+++ b/source4/heimdal/lib/krb5/krbhst.c
@@ -34,7 +34,7 @@
#include "krb5_locl.h"
#include <resolve.h>
-RCSID("$Id: krbhst.c,v 1.53 2005/10/08 15:40:50 lha Exp $");
+RCSID("$Id: krbhst.c,v 1.55 2006/04/02 10:32:20 lha Exp $");
static int
string_to_proto(const char *string)
@@ -241,8 +241,9 @@ _krb5_krbhost_info_move(krb5_context context,
krb5_krbhst_info *from,
krb5_krbhst_info **to)
{
+ size_t hostnamelen = strlen(from->hostname);
/* trailing NUL is included in structure */
- *to = calloc(1, sizeof(**to) + strlen(from->hostname));
+ *to = calloc(1, sizeof(**to) + hostnamelen);
if(*to == NULL) {
krb5_set_error_string(context, "malloc - out of memory");
return ENOMEM;
@@ -254,7 +255,7 @@ _krb5_krbhost_info_move(krb5_context context,
(*to)->ai = from->ai;
from->ai = NULL;
(*to)->next = NULL;
- strcpy((*to)->hostname, from->hostname);
+ memcpy((*to)->hostname, from->hostname, hostnamelen + 1);
return 0;
}
diff --git a/source4/heimdal/lib/krb5/log.c b/source4/heimdal/lib/krb5/log.c
index 4f6381c858..7e478bf1e0 100644
--- a/source4/heimdal/lib/krb5/log.c
+++ b/source4/heimdal/lib/krb5/log.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: log.c,v 1.36 2005/06/17 04:25:05 lha Exp $");
+RCSID("$Id: log.c,v 1.38 2006/04/10 09:41:26 lha Exp $");
struct facility {
int min;
@@ -284,7 +284,7 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig)
ret = open_file(context, f, min, max, NULL, NULL, stderr, 1);
}else if(strcmp(p, "CONSOLE") == 0){
ret = open_file(context, f, min, max, "/dev/console", "w", NULL, 0);
- }else if(strncmp(p, "FILE:", 4) == 0 && (p[4] == ':' || p[4] == '=')){
+ }else if(strncmp(p, "FILE", 4) == 0 && (p[4] == ':' || p[4] == '=')){
char *fn;
FILE *file = NULL;
int keep_open = 0;
@@ -300,6 +300,7 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig)
ret = errno;
krb5_set_error_string (context, "open(%s): %s", fn,
strerror(ret));
+ free(fn);
return ret;
}
file = fdopen(i, "a");
@@ -308,12 +309,13 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig)
close(i);
krb5_set_error_string (context, "fdopen(%s): %s", fn,
strerror(ret));
+ free(fn);
return ret;
}
keep_open = 1;
}
ret = open_file(context, f, min, max, fn, "a", file, keep_open);
- }else if(strncmp(p, "DEVICE=", 6) == 0){
+ }else if(strncmp(p, "DEVICE", 6) == 0 && (p[6] == ':' || p[6] == '=')){
ret = open_file(context, f, min, max, strdup(p + 7), "w", NULL, 0);
}else if(strncmp(p, "SYSLOG", 6) == 0 && (p[6] == '\0' || p[6] == ':')){
char severity[128] = "";
diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c
index 1247bb22ca..fa4fb4699e 100755
--- a/source4/heimdal/lib/krb5/pkinit.c
+++ b/source4/heimdal/lib/krb5/pkinit.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 - 2005 Kungliga Tekniska Högskolan
+ * Copyright (c) 2003 - 2006 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: pkinit.c,v 1.77 2006/02/14 10:08:29 lha Exp $");
+RCSID("$Id: pkinit.c,v 1.88 2006/04/23 21:30:17 lha Exp $");
struct krb5_dh_moduli {
char *name;
@@ -45,71 +45,35 @@ struct krb5_dh_moduli {
#ifdef PKINIT
-#include <openssl/evp.h>
-#include <openssl/x509.h>
-#include <openssl/pem.h>
-#include <openssl/err.h>
-#include <openssl/dh.h>
-#include <openssl/bn.h>
-#include <openssl/engine.h>
-#include <openssl/ui.h>
-
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#endif
+#include <heim_asn1.h>
+#include <rfc2459_asn1.h>
+#include <cms_asn1.h>
+#include <pkcs8_asn1.h>
+#include <pkcs9_asn1.h>
+#include <pkcs12_asn1.h>
+#include <pkinit_asn1.h>
+#include <asn1_err.h>
+
+#include <der.h>
-#include "heim_asn1.h"
-#include "rfc2459_asn1.h"
-#include "cms_asn1.h"
-#include "pkinit_asn1.h"
+#include <hx509.h>
enum {
COMPAT_WIN2K = 1,
COMPAT_IETF = 2
};
-#define OPENSSL_ASN1_MALLOC_ENCODE(T, B, BL, S, R) \
-{ \
- unsigned char *p; \
- (BL) = i2d_##T((S), NULL); \
- if ((BL) <= 0) { \
- (R) = EINVAL; \
- } else { \
- (B) = malloc((BL)); \
- if ((B) == NULL) { \
- (R) = ENOMEM; \
- } else { \
- p = (B); \
- (R) = 0; \
- (BL) = i2d_##T((S), &p); \
- if ((BL) <= 0) { \
- free((B)); \
- (R) = ASN1_OVERRUN; \
- } \
- } \
- } \
-}
-
-/* ENGING_load_private_key requires a UI_METHOD and data
- * if to be usable from PAM
- */
-
-struct krb5_ui_data {
- krb5_context context;
- krb5_prompter_fct prompter;
- void * prompter_data;
-};
-
struct krb5_pk_identity {
- EVP_PKEY *private_key;
- STACK_OF(X509) *cert;
- STACK_OF(X509) *trusted_certs;
- STACK_OF(X509_CRL) *crls;
- ENGINE *engine;
+ hx509_context hx509ctx;
+ hx509_verify_ctx verify_ctx;
+ hx509_certs certs;
+ hx509_certs anchors;
+ hx509_certs certpool;
+ hx509_revoke_ctx revoke;
};
struct krb5_pk_cert {
- X509 *cert;
+ hx509_cert cert;
};
struct krb5_pk_init_ctx_data {
@@ -118,13 +82,16 @@ struct krb5_pk_init_ctx_data {
krb5_data *clientDHNonce;
struct krb5_dh_moduli **m;
int require_binding;
+ int require_eku;
+ int require_krbtgt_otherName;
};
void KRB5_LIB_FUNCTION
_krb5_pk_cert_free(struct krb5_pk_cert *cert)
{
- if (cert->cert)
- X509_free(cert->cert);
+ if (cert->cert) {
+ hx509_cert_free(cert->cert);
+ }
free(cert);
}
@@ -138,7 +105,7 @@ BN_to_integer(krb5_context context, BIGNUM *bn, heim_integer *integer)
return ENOMEM;
}
BN_bn2bin(bn, integer->data);
- integer->negative = bn->neg;
+ integer->negative = BN_is_negative(bn);
return 0;
}
@@ -152,315 +119,44 @@ integer_to_BN(krb5_context context, const char *field, const heim_integer *f)
krb5_set_error_string(context, "PKINIT: parsing BN failed %s", field);
return NULL;
}
- bn->neg = f->negative;
+ BN_set_negative(bn, f->negative);
return bn;
}
-/*
- * UI ex_data has the callback_data as passed to Engine. This is far
- * from being complete, we will only process one prompt
- */
-
-static int
-krb5_ui_method_read_string(UI *ui, UI_STRING *uis)
-{
- char *buffer;
- size_t length;
- krb5_error_code ret;
- krb5_prompt prompt;
- krb5_data password_data;
- struct krb5_ui_data *ui_data;
-
- ui_data = (struct krb5_ui_data *)UI_get_app_data(ui);
-
- switch (UI_get_string_type(uis)) {
- case UIT_INFO:
- case UIT_ERROR:
- /* looks like the RedHat pam_prompter might handle
- * INFO and ERROR, Will see what happens */
- case UIT_VERIFY:
- case UIT_PROMPT:
- length = UI_get_result_maxsize(uis);
- buffer = malloc(length);
- if (buffer == NULL) {
- krb5_set_error_string(ui_data->context, "malloc: out of memory");
- return 0;
- }
- password_data.data = buffer;
- password_data.length = length;
-
- prompt.prompt = UI_get0_output_string(uis);
- prompt.hidden = !(UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO);
- prompt.reply = &password_data;
- prompt.type = KRB5_PROMPT_TYPE_PASSWORD;
-
- ret = (*ui_data->prompter)(ui_data->context,
- ui_data->prompter_data,
- NULL, NULL, 1, &prompt);
- if (ret == 0) {
- buffer[length - 1] = '\0';
- UI_set_result(ui, uis, password_data.data);
-
- /*
- * RedHat pam_krb5 pam_prompter does a strdup but others
- * may copy into buffer. XXX should we just leak the
- * memory instead ?
- */
-
- if (buffer != password_data.data)
- free(password_data.data);
- memset (buffer, 0, length);
- free(buffer);
- return 1;
- }
- memset (buffer, 0, length);
- free(buffer);
- break;
- case UIT_NONE:
- case UIT_BOOLEAN:
- /* XXX for now do not handle */
- break;
-
- }
- return 0;
-}
-
static krb5_error_code
-set_digest_alg(DigestAlgorithmIdentifier *id,
- const heim_oid *oid,
- void *param, size_t length)
-{
- krb5_error_code ret;
- if (param) {
- id->parameters = malloc(sizeof(*id->parameters));
- if (id->parameters == NULL)
- return ENOMEM;
- id->parameters->data = malloc(length);
- if (id->parameters->data == NULL) {
- free(id->parameters);
- id->parameters = NULL;
- return ENOMEM;
- }
- memcpy(id->parameters->data, param, length);
- id->parameters->length = length;
- } else
- id->parameters = NULL;
- ret = copy_oid(oid, &id->algorithm);
- if (ret) {
- if (id->parameters) {
- free(id->parameters->data);
- free(id->parameters);
- id->parameters = NULL;
- }
- return ret;
- }
- return 0;
-}
-
-krb5_error_code KRB5_LIB_FUNCTION
_krb5_pk_create_sign(krb5_context context,
const heim_oid *eContentType,
krb5_data *eContent,
struct krb5_pk_identity *id,
krb5_data *sd_data)
{
- SignerInfo *signer_info;
- X509 *user_cert;
- heim_integer *serial;
- krb5_error_code ret;
- krb5_data buf;
- SignedData sd;
- EVP_MD_CTX md;
- int i;
- unsigned len;
- size_t size;
-
- X509_NAME *issuer_name;
-
- memset(&sd, 0, sizeof(sd));
-
- if (id == NULL)
- return HEIM_PKINIT_NO_CERTIFICATE;
- if (id->cert == NULL)
- return HEIM_PKINIT_NO_CERTIFICATE;
- if (id->private_key == NULL)
- return HEIM_PKINIT_NO_PRIVATE_KEY;
-
- if (sk_X509_num(id->cert) == 0)
- return HEIM_PKINIT_NO_CERTIFICATE;
-
- sd.version = 3;
-
- sd.digestAlgorithms.len = 0;
- sd.digestAlgorithms.val = NULL;
- copy_oid(eContentType, &sd.encapContentInfo.eContentType);
- ALLOC(sd.encapContentInfo.eContent, 1);
- if (sd.encapContentInfo.eContent == NULL) {
- krb5_clear_error_string(context);
- ret = ENOMEM;
- goto out;
- }
-
- ret = krb5_data_copy(&buf, eContent->data, eContent->length);
- if (ret) {
- krb5_clear_error_string(context);
- ret = ENOMEM;
- goto out;
- }
-
- sd.encapContentInfo.eContent->data = buf.data;
- sd.encapContentInfo.eContent->length = buf.length;
-
- ALLOC_SEQ(&sd.signerInfos, 1);
- if (sd.signerInfos.val == NULL) {
- krb5_set_error_string(context, "malloc: out of memory");
- ret = ENOMEM;
- goto out;
- }
-
- signer_info = &sd.signerInfos.val[0];
-
- user_cert = sk_X509_value(id->cert, 0);
- if (user_cert == NULL) {
- krb5_set_error_string(context, "pkinit: no user certificate");
- ret = HEIM_PKINIT_NO_CERTIFICATE;
- goto out;
- }
-
- signer_info->version = 1;
-
- issuer_name = X509_get_issuer_name(user_cert);
-
- OPENSSL_ASN1_MALLOC_ENCODE(X509_NAME,
- buf.data,
- buf.length,
- issuer_name,
- ret);
- if (ret) {
- krb5_set_error_string(context, "pkinit: failed encoding name");
- goto out;
- }
- ret = decode_Name(buf.data, buf.length,
- &signer_info->sid.u.issuerAndSerialNumber.issuer,
- NULL);
- free(buf.data);
- if (ret) {
- krb5_set_error_string(context, "pkinit: failed to parse Name");
- goto out;
- }
- signer_info->sid.element = choice_CMSIdentifier_issuerAndSerialNumber;
-
- serial = &signer_info->sid.u.issuerAndSerialNumber.serialNumber;
- {
- ASN1_INTEGER *isn = X509_get_serialNumber(user_cert);
- BIGNUM *bn = ASN1_INTEGER_to_BN(isn, NULL);
- if (bn == NULL) {
- ret = ENOMEM;
- krb5_set_error_string(context, "pkinit: failed allocating "
- "serial number");
- goto out;
- }
- ret = BN_to_integer(context, bn, serial);
- BN_free(bn);
- if (ret) {
- krb5_set_error_string(context, "pkinit: failed encoding "
- "serial number");
- goto out;
- }
- }
-
- ret = set_digest_alg(&signer_info->digestAlgorithm,
- oid_id_secsig_sha_1(), "\x05\x00", 2);
- if (ret) {
- krb5_set_error_string(context, "malloc: out of memory");
- goto out;
- }
-
- signer_info->signedAttrs = NULL;
- signer_info->unsignedAttrs = NULL;
-
- copy_oid(oid_id_pkcs1_rsaEncryption(),
- &signer_info->signatureAlgorithm.algorithm);
- signer_info->signatureAlgorithm.parameters = NULL;
-
- buf.data = malloc(EVP_PKEY_size(id->private_key));
- if (buf.data == NULL) {
- krb5_set_error_string(context, "malloc: out of memory");
- ret = ENOMEM;
- goto out;
- }
-
- EVP_SignInit(&md, EVP_sha1());
- EVP_SignUpdate(&md,
- sd.encapContentInfo.eContent->data,
- sd.encapContentInfo.eContent->length);
- ret = EVP_SignFinal(&md, buf.data, &len, id->private_key);
- if (ret != 1) {
- free(buf.data);
- krb5_set_error_string(context, "PKINIT: failed to sign with "
- "private key: %s",
- ERR_error_string(ERR_get_error(), NULL));
- ret = EINVAL;
- goto out;
- }
-
- signer_info->signature.data = buf.data;
- signer_info->signature.length = len;
-
- ALLOC_SEQ(&sd.digestAlgorithms, 1);
- if (sd.digestAlgorithms.val == NULL) {
- krb5_clear_error_string(context);
- ret = ENOMEM;
- goto out;
- }
-
- ret = set_digest_alg(&sd.digestAlgorithms.val[0],
- oid_id_secsig_sha_1(), "\x05\x00", 2);
- if (ret) {
- krb5_set_error_string(context, "malloc: out of memory");
- goto out;
- }
+ hx509_cert cert;
+ hx509_query *q;
+ int ret;
- ALLOC(sd.certificates, 1);
- if (sd.certificates == NULL) {
- krb5_clear_error_string(context);
- ret = ENOMEM;
- goto out;
- }
+ ret = hx509_query_alloc(id->hx509ctx, &q);
+ if (ret)
+ return ret;
- i = sk_X509_num(id->cert);
- sd.certificates->val = malloc(sizeof(sd.certificates->val[0]) * i);
- if (sd.certificates->val == NULL) {
- krb5_clear_error_string(context);
- ret = ENOMEM;
- goto out;
- }
- sd.certificates->len = i;
-
- for (i = 0; i < sk_X509_num(id->cert); i++) {
- OPENSSL_ASN1_MALLOC_ENCODE(X509,
- sd.certificates->val[i].data,
- sd.certificates->val[i].length,
- sk_X509_value(id->cert, i),
- ret);
- if (ret) {
- krb5_clear_error_string(context);
- goto out;
- }
- }
+ hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
+ hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
- ASN1_MALLOC_ENCODE(SignedData, sd_data->data, sd_data->length,
- &sd, &size, ret);
- if (ret) {
- krb5_set_error_string(context, "SignedData failed %d", ret);
- goto out;
- }
- if (sd_data->length != size)
- krb5_abortx(context, "internal ASN1 encoder error");
+ ret = hx509_certs_find(id->hx509ctx, id->certs, q, &cert);
+ hx509_query_free(id->hx509ctx, q);
+ if (ret)
+ return ret;
- out:
- free_SignedData(&sd);
+ ret = hx509_cms_create_signed_1(id->hx509ctx,
+ eContentType,
+ eContent->data,
+ eContent->length,
+ NULL,
+ cert,
+ NULL,
+ NULL,
+ sd_data);
+ hx509_cert_free(cert);
return ret;
}
@@ -813,230 +509,23 @@ _krb5_pk_mk_padata(krb5_context context,
} else
type = COMPAT_IETF;
- return pk_mk_padata(context, type, ctx, req_body, nonce, md);
-}
+ ctx->require_eku =
+ krb5_config_get_bool_default(context, NULL,
+ TRUE,
+ "realms",
+ req_body->realm,
+ "pkinit_require_eku",
+ NULL);
+ ctx->require_krbtgt_otherName =
+ krb5_config_get_bool_default(context, NULL,
+ TRUE,
+ "realms",
+ req_body->realm,
+ "pkinit_require_krbtgt_otherName",
+ NULL);
-static krb5_boolean
-pk_peer_compare(krb5_context context,
- const SignerIdentifier *peer1,
- X509 *peer2)
-{
- switch (peer1->element) {
- case choice_CMSIdentifier_issuerAndSerialNumber: {
- ASN1_INTEGER *i;
- const heim_integer *serial;
- X509_NAME *name;
- unsigned char *p;
- size_t len;
-
- i = X509_get_serialNumber(peer2);
- serial = &peer1->u.issuerAndSerialNumber.serialNumber;
-
- if (i->length != serial->length ||
- memcmp(i->data, serial->data, i->length) != 0)
- return FALSE;
-
- p = peer1->u.issuerAndSerialNumber.issuer._save.data;
- len = peer1->u.issuerAndSerialNumber.issuer._save.length;
- name = d2i_X509_NAME(NULL, &p, len);
- if (name == NULL)
- return FALSE;
-
- if (X509_NAME_cmp(name, X509_get_issuer_name(peer2)) != 0) {
- X509_NAME_free(name);
- return FALSE;
- }
- X509_NAME_free(name);
- break;
- }
- case choice_CMSIdentifier_subjectKeyIdentifier:
- return FALSE;
- default:
- return FALSE;
- }
- return TRUE;
-}
-static krb5_error_code
-pk_decrypt_key(krb5_context context,
- heim_octet_string *encrypted_key,
- EVP_PKEY *priv_key,
- krb5_keyblock *key)
-{
- int ret;
- unsigned char *buf;
-
- buf = malloc(EVP_PKEY_size(priv_key));
- if (buf == NULL) {
- krb5_set_error_string(context, "malloc: out of memory");
- return ENOMEM;
- }
- ret = EVP_PKEY_decrypt(buf,
- encrypted_key->data,
- encrypted_key->length,
- priv_key);
- if (ret <= 0) {
- free(buf);
- krb5_set_error_string(context, "Can't decrypt key: %s",
- ERR_error_string(ERR_get_error(), NULL));
- return ENOMEM;
- }
-
- key->keytype = 0;
- key->keyvalue.length = ret;
- key->keyvalue.data = malloc(ret);
- if (key->keyvalue.data == NULL) {
- free(buf);
- krb5_set_error_string(context, "malloc: out of memory");
- return ENOMEM;
- }
- memcpy(key->keyvalue.data, buf, ret);
- free(buf);
- return 0;
-}
-
-
-static krb5_error_code
-pk_verify_chain_standard(krb5_context context,
- struct krb5_pk_identity *id,
- const SignerIdentifier *client,
- STACK_OF(X509) *chain,
- X509 **client_cert)
-{
- X509_STORE *cert_store = NULL;
- X509_STORE_CTX *store_ctx = NULL;
- X509 *cert = NULL;
- int i;
- int ret;
-
- ret = KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;
- for (i = 0; i < sk_X509_num(chain); i++) {
- cert = sk_X509_value(chain, i);
- if (pk_peer_compare(context, client, cert) == TRUE) {
- ret = 0;
- break;
- }
- }
- if (ret) {
- krb5_set_error_string(context, "PKINIT: verify chain failed "
- "to find client in chain");
- return ret;
- }
-
- cert_store = X509_STORE_new();
- if (cert_store == NULL) {
- ret = ENOMEM;
- krb5_set_error_string(context, "PKINIT: can't create X509 store: %s",
- ERR_error_string(ERR_get_error(), NULL));
- }
-
- store_ctx = X509_STORE_CTX_new();
- if (store_ctx == NULL) {
- ret = ENOMEM;
- krb5_set_error_string(context,
- "PKINIT: can't create X509 store ctx: %s",
- ERR_error_string(ERR_get_error(), NULL));
- goto end;
- }
-
- X509_STORE_CTX_init(store_ctx, cert_store, cert, chain);
- X509_STORE_CTX_trusted_stack(store_ctx, id->trusted_certs);
- X509_verify_cert(store_ctx);
- /* the last checked certificate is in store_ctx->current_cert */
- krb5_clear_error_string(context);
- switch(store_ctx->error) {
- case X509_V_OK:
- ret = 0;
- break;
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
- ret = KRB5_KDC_ERR_CANT_VERIFY_CERTIFICATE;
- krb5_set_error_string(context, "PKINIT: failed to verify "
- "certificate: %s ",
- X509_verify_cert_error_string(store_ctx->error));
- break;
- case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
- case X509_V_ERR_CERT_SIGNATURE_FAILURE:
- case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
- case X509_V_ERR_CERT_NOT_YET_VALID:
- case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
- case X509_V_ERR_CERT_HAS_EXPIRED:
- ret = KRB5_KDC_ERR_INVALID_CERTIFICATE;
- krb5_set_error_string(context, "PKINIT: invalid certificate: %s ",
- X509_verify_cert_error_string(store_ctx->error));
- break;
- case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
- case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
- case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
- case X509_V_ERR_CERT_CHAIN_TOO_LONG:
- case X509_V_ERR_PATH_LENGTH_EXCEEDED:
- case X509_V_ERR_INVALID_CA:
- ret = KRB5_KDC_ERR_INVALID_CERTIFICATE;
- krb5_set_error_string(context, "PKINIT: unknown CA or can't "
- "verify certificate: %s",
- X509_verify_cert_error_string(store_ctx->error));
- break;
- default:
- ret = KRB5_KDC_ERR_INVALID_CERTIFICATE; /* XXX */
- krb5_set_error_string(context, "PKINIT: failed to verify "
- "certificate: %s (%ld) ",
- X509_verify_cert_error_string(store_ctx->error),
- (long)store_ctx->error);
- break;
- }
- if (ret)
- goto end;
-
- /*
- * Since X509_verify_cert() doesn't do CRL checking at all, we have to
- * perform own verification against CRLs
- */
- /*
- * XXX add crl checking
- */
-
- if (client_cert && cert)
- *client_cert = X509_dup(cert);
-
- end:
- if (cert_store)
- X509_STORE_free(cert_store);
- if (store_ctx)
- X509_STORE_CTX_free(store_ctx);
- return ret;
-}
-
-static int
-cert_to_X509(krb5_context context, CertificateSet *set,
- STACK_OF(X509_CRL) **certs)
-{
- krb5_error_code ret;
- int i;
-
- *certs = sk_X509_new_null();
-
- if (set == NULL)
- return 0;
-
- ret = 0;
- for (i = 0; i < set->len; i++) {
- unsigned char *p;
- X509 *cert;
-
- p = set->val[i].data;
- cert = d2i_X509(NULL, &p, set->val[i].length);
- if (cert == NULL) {
- ret = ASN1_BAD_FORMAT;
- break;
- }
- sk_X509_insert(*certs, cert, i);
- }
- if (ret) {
- krb5_set_error_string(context,
- "PKINIT: Failed to decode certificate chain");
- sk_X509_free(*certs);
- *certs = NULL;
- }
- return ret;
+ return pk_mk_padata(context, type, ctx, req_body, nonce, md);
}
krb5_error_code KRB5_LIB_FUNCTION
@@ -1048,144 +537,67 @@ _krb5_pk_verify_sign(krb5_context context,
krb5_data *content,
struct krb5_pk_cert **signer)
{
- STACK_OF(X509) *certificates;
- SignerInfo *signer_info;
- const EVP_MD *evp_type;
- EVP_PKEY *public_key;
- krb5_error_code ret;
- EVP_MD_CTX md;
- X509 *cert = NULL;
- SignedData sd;
- size_t size;
-
- *signer = NULL;
- krb5_data_zero(content);
- contentType->length = 0;
- contentType->components = NULL;
-
- memset(&sd, 0, sizeof(sd));
-
- ret = decode_SignedData(data, length, &sd, &size);
- if (ret) {
- krb5_set_error_string(context,
- "PKINIT: decoding failed SignedData: %d",
- ret);
- goto out;
- }
-
- if (sd.encapContentInfo.eContent == NULL) {
- krb5_set_error_string(context,
- "PKINIT: signature missing encapContent");
- ret = KRB5KRB_AP_ERR_MSG_TYPE;
- goto out;
- }
-
- /* XXX Check CMS version */
-
- if (sd.signerInfos.len < 1) {
- krb5_set_error_string(context,
- "PKINIT: signature information missing from "
- "pkinit response");
- ret = KRB5_KDC_ERR_INVALID_SIG;
- goto out;
- }
-
- signer_info = &sd.signerInfos.val[0];
-
- {
- CertificateSet set;
- set.val = sd.certificates->val;
- set.len = sd.certificates->len;
+ hx509_certs signer_certs;
+ int ret;
- ret = cert_to_X509(context, &set, &certificates);
- }
- if (ret) {
- krb5_set_error_string(context,
- "PKINIT: failed to decode Certificates");
- goto out;
- }
+ *signer = NULL;
- ret = pk_verify_chain_standard(context, id,
- &signer_info->sid,
- certificates,
- &cert);
- sk_X509_free(certificates);
+ ret = hx509_cms_verify_signed(id->hx509ctx,
+ id->verify_ctx,
+ data,
+ length,
+ id->certpool,
+ contentType,
+ content,
+ &signer_certs);
if (ret)
- goto out;
-
- if (signer_info->signature.length == 0) {
- free_SignedData(&sd);
- X509_free(cert);
- krb5_set_error_string(context, "PKINIT: signature missing from"
- "pkinit response");
- return KRB5_KDC_ERR_INVALID_SIG;
- }
-
- public_key = X509_get_pubkey(cert);
-
- /* verify signature */
- if (heim_oid_cmp(&signer_info->digestAlgorithm.algorithm,
- oid_id_pkcs1_sha1WithRSAEncryption()) == 0)
- evp_type = EVP_sha1();
- else if (heim_oid_cmp(&signer_info->digestAlgorithm.algorithm,
- oid_id_pkcs1_md5WithRSAEncryption()) == 0)
- evp_type = EVP_md5();
- else if (heim_oid_cmp(&signer_info->digestAlgorithm.algorithm,
- oid_id_secsig_sha_1()) == 0)
- evp_type = EVP_sha1();
- else {
- X509_free(cert);
- krb5_set_error_string(context, "PKINIT: The requested digest "
- "algorithm is not supported");
- ret = KRB5_KDC_ERR_INVALID_SIG;
- goto out;
- }
-
- EVP_VerifyInit(&md, evp_type);
- EVP_VerifyUpdate(&md,
- sd.encapContentInfo.eContent->data,
- sd.encapContentInfo.eContent->length);
- ret = EVP_VerifyFinal(&md,
- signer_info->signature.data,
- signer_info->signature.length,
- public_key);
- if (ret != 1) {
- X509_free(cert);
- krb5_set_error_string(context, "PKINIT: signature didn't verify: %s",
- ERR_error_string(ERR_get_error(), NULL));
- ret = KRB5_KDC_ERR_INVALID_SIG;
- goto out;
- }
-
- ret = copy_oid(&sd.encapContentInfo.eContentType, contentType);
- if (ret) {
- krb5_clear_error_string(context);
- goto out;
- }
+ return ret;
- content->data = malloc(sd.encapContentInfo.eContent->length);
- if (content->data == NULL) {
+ *signer = calloc(1, sizeof(**signer));
+ if (*signer == NULL) {
krb5_clear_error_string(context);
ret = ENOMEM;
goto out;
}
- content->length = sd.encapContentInfo.eContent->length;
- memcpy(content->data,sd.encapContentInfo.eContent->data,content->length);
+
+ /* XXX */
+ {
+ hx509_cursor cursor;
- *signer = malloc(sizeof(**signer));
- if (*signer == NULL) {
- krb5_clear_error_string(context);
- ret = ENOMEM;
- goto out;
+ ret = hx509_certs_start_seq(id->hx509ctx,
+ signer_certs,
+ &cursor);
+ if (ret) {
+ krb5_clear_error_string(context);
+ goto out;
+ }
+ ret = hx509_certs_next_cert(id->hx509ctx,
+ signer_certs,
+ cursor,
+ &(*signer)->cert);
+ if (ret) {
+ krb5_clear_error_string(context);
+ goto out;
+ }
+ ret = hx509_certs_end_seq(id->hx509ctx,
+ signer_certs,
+ cursor);
+ if (ret) {
+ krb5_clear_error_string(context);
+ goto out;
+ }
}
- (*signer)->cert = cert;
- out:
- free_SignedData(&sd);
+out:
+ hx509_certs_free(&signer_certs);
if (ret) {
- free_oid(contentType);
- krb5_data_free(content);
+ if (*signer) {
+ hx509_cert_free((*signer)->cert);
+ free(*signer);
+ *signer = NULL;
+ }
}
+
return ret;
}
@@ -1297,10 +709,60 @@ get_reply_key(krb5_context context,
static krb5_error_code
-pk_verify_host(krb5_context context, struct krb5_pk_cert *host)
+pk_verify_host(krb5_context context,
+ struct krb5_pk_init_ctx_data *ctx,
+ struct krb5_pk_cert *host)
{
- /* XXX */
- return 0;
+ krb5_error_code ret = 0;
+
+ if (ctx->require_eku) {
+ ret = hx509_cert_check_eku(ctx->id->hx509ctx, host->cert,
+ oid_id_pkkdcekuoid(), 0);
+ if (ret) {
+ krb5_clear_error_string(context);
+ return ret;
+ }
+ }
+ if (ctx->require_krbtgt_otherName) {
+ hx509_octet_string_list list;
+ krb5_error_code ret;
+ int i;
+
+ ret = hx509_cert_find_subjectAltName_otherName(host->cert,
+ oid_id_pkinit_san(),
+ &list);
+ if (ret) {
+ krb5_clear_error_string(context);
+ return ret;
+ }
+
+ for (i = 0; i < list.len; i++) {
+ KRB5PrincipalName r;
+ ret = decode_KRB5PrincipalName(list.val[i].data,
+ list.val[i].length,
+ &r,
+ NULL);
+ if (ret) {
+ krb5_clear_error_string(context);
+ break;
+ }
+
+#if 0
+ if (r.principalName.name.len != 2) {
+ krb5_clear_error_string(context);
+ ret = EINVAL;
+ }
+#endif
+ /* XXX verify realm */
+
+ free_KRB5PrincipalName(&r);
+ if (ret)
+ break;
+ }
+ hx509_free_octet_string_list(&list);
+ }
+
+ return ret;
}
static krb5_error_code
@@ -1316,33 +778,12 @@ pk_rd_pa_reply_enckey(krb5_context context,
krb5_keyblock **key)
{
krb5_error_code ret;
- EnvelopedData ed;
- krb5_keyblock tmp_key;
- krb5_crypto crypto;
- krb5_data plain;
- KeyTransRecipientInfo *ri;
- int length;
+ struct krb5_pk_cert *host = NULL;
size_t size;
- X509 *user_cert;
+ int length;
void *p;
- krb5_boolean bret;
krb5_data content;
heim_oid contentType = { 0, NULL };
- struct krb5_pk_cert *host = NULL;
- heim_octet_string encryptedContent;
- heim_octet_string *any;
- krb5_data ivec;
- krb5_data params;
-
-
- memset(&tmp_key, 0, sizeof(tmp_key));
- memset(&ed, 0, sizeof(ed));
- krb5_data_zero(&plain);
- krb5_data_zero(&content);
- krb5_data_zero(&encryptedContent);
- krb5_data_zero(&ivec);
-
- user_cert = sk_X509_value(ctx->id->cert, 0);
if (heim_oid_cmp(oid_id_pkcs7_envelopedData(), &rep->contentType)) {
krb5_set_error_string(context, "PKINIT: Invalid content type");
@@ -1354,106 +795,17 @@ pk_rd_pa_reply_enckey(krb5_context context,
return EINVAL;
}
- ret = decode_EnvelopedData(rep->content->data,
+ ret = hx509_cms_unenvelope(ctx->id->hx509ctx,
+ ctx->id->certs,
+ rep->content->data,
rep->content->length,
- &ed,
- &size);
- if (ret) {
- free_EnvelopedData(&ed);
- return ret;
- }
-
- if (ed.recipientInfos.len != 1) {
- free_EnvelopedData(&ed);
- krb5_set_error_string(context, "pkinit: Number of recipient infos "
- "not one (%d)",
- ed.recipientInfos.len);
- return EINVAL; /* XXX */
- }
-
- ri = &ed.recipientInfos.val[0];
-
- /* XXX make SignerIdentifier and RecipientIdentifier the same */
- bret = pk_peer_compare(context, (SignerIdentifier *)&ri->rid, user_cert);
- if (bret == FALSE) {
- ret = KRB5KRB_AP_ERR_BADMATCH; /* XXX */
- goto out;
- }
-
- if (heim_oid_cmp(oid_id_pkcs1_rsaEncryption(),
- &ri->keyEncryptionAlgorithm.algorithm)) {
- krb5_set_error_string(context, "PKINIT: invalid content type");
- return EINVAL;
- }
-
- ret = pk_decrypt_key(context, &ri->encryptedKey,
- ctx->id->private_key, &tmp_key);
- if (ret)
- goto out;
-
-
- /*
- * Try to verify content type. We can't do this for W2K case
- * because W2K/W2K3 sends id-pkcs7-data, but Windows Vista sends
- * id-pkcs7-signedData to all versions, even W2K clients.
- */
-
- if (type != COMPAT_WIN2K) {
- if (heim_oid_cmp(&ed.encryptedContentInfo.contentType, oid_id_pkcs7_signedData())) {
- ret = KRB5KRB_AP_ERR_MSG_TYPE;
- goto out;
- }
- }
-
- if (ed.encryptedContentInfo.encryptedContent == NULL) {
- krb5_set_error_string(context, "PKINIT: OPTIONAL encryptedContent "
- "field not filled in in KDC reply");
- ret = KRB5_BADMSGTYPE;
- goto out;
- }
-
- any = ed.encryptedContentInfo.encryptedContent;
- ret = der_get_octet_string(any->data, any->length,
- &encryptedContent, NULL);
- if (ret) {
- krb5_set_error_string(context,
- "PKINIT: encryptedContent content invalid");
- goto out;
- }
-
- if (ed.encryptedContentInfo.contentEncryptionAlgorithm.parameters == NULL){
- krb5_set_error_string(context,
- "PKINIT: encryptedContent parameter missing");
- ret = KRB5_BADMSGTYPE;
- goto out;
- }
-
- params.data = ed.encryptedContentInfo.contentEncryptionAlgorithm.parameters->data;
- params.length = ed.encryptedContentInfo.contentEncryptionAlgorithm.parameters->length;
-
- ret = _krb5_oid_to_enctype(context,
- &ed.encryptedContentInfo.contentEncryptionAlgorithm.algorithm,
- &tmp_key.keytype);
- if (ret)
- goto out;
-
- ret = krb5_crypto_init(context, &tmp_key, 0, &crypto);
- if (ret)
- goto out;
-
- ret = krb5_crypto_get_params(context, crypto, &params, &ivec);
+ &contentType,
+ &content);
if (ret)
- goto out;
-
- ret = krb5_decrypt_ivec(context, crypto,
- 0,
- encryptedContent.data,
- encryptedContent.length,
- &plain,
- ivec.data);
+ return ret;
- p = plain.data;
- length = plain.length;
+ p = content.data;
+ length = content.length;
/* win2k uses ContentInfo */
if (type == COMPAT_WIN2K) {
@@ -1472,6 +824,13 @@ pk_rd_pa_reply_enckey(krb5_context context,
krb5_set_error_string(context, "PKINIT: Invalid content type");
goto out;
}
+ if (ci.content == NULL) {
+ ret = EINVAL; /* XXX */
+ krb5_set_error_string(context, "PKINIT: Invalid content type");
+ goto out;
+ }
+ krb5_data_free(&content);
+ content = *ci.content;
p = ci.content->data;
length = ci.content->length;
}
@@ -1487,7 +846,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
goto out;
/* make sure that it is the kdc's certificate */
- ret = pk_verify_host(context, host);
+ ret = pk_verify_host(context, ctx, host);
if (ret) {
krb5_set_error_string(context, "PKINIT: failed verify host: %d", ret);
goto out;
@@ -1528,11 +887,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
if (host)
_krb5_pk_cert_free(host);
free_oid(&contentType);
- free_octet_string(&encryptedContent);
krb5_data_free(&content);
- krb5_free_keyblock_contents(context, &tmp_key);
- krb5_data_free(&plain);
- krb5_data_free(&ivec);
return ret;
}
@@ -1550,7 +905,6 @@ pk_rd_pa_reply_dh(krb5_context context,
krb5_keyblock **key)
{
unsigned char *p, *dh_gen_key = NULL;
- ASN1_INTEGER *dh_pub_key = NULL;
struct krb5_pk_cert *host = NULL;
BIGNUM *kdc_dh_pubkey = NULL;
KDCDHKeyInfo kdc_dh_info;
@@ -1584,7 +938,7 @@ pk_rd_pa_reply_dh(krb5_context context,
goto out;
/* make sure that it is the kdc's certificate */
- ret = pk_verify_host(context, host);
+ ret = pk_verify_host(context, ctx, host);
if (ret)
goto out;
@@ -1623,7 +977,7 @@ pk_rd_pa_reply_dh(krb5_context context,
}
} else {
if (k_n) {
- krb5_set_error_string(context, "pkinit; got server nonce "
+ krb5_set_error_string(context, "pkinit: got server nonce "
"without key expiration");
ret = KRB5KRB_ERR_GENERIC;
goto out;
@@ -1634,22 +988,24 @@ pk_rd_pa_reply_dh(krb5_context context,
p = kdc_dh_info.subjectPublicKey.data;
size = (kdc_dh_info.subjectPublicKey.length + 7) / 8;
- dh_pub_key = d2i_ASN1_INTEGER(NULL, &p, size);
- if (dh_pub_key == NULL) {
- krb5_set_error_string(context,
- "PKINIT: Can't parse KDC's DH public key");
- ret = KRB5KRB_ERR_GENERIC;
- goto out;
- }
- kdc_dh_pubkey = ASN1_INTEGER_to_BN(dh_pub_key, NULL);
- if (kdc_dh_pubkey == NULL) {
- krb5_set_error_string(context,
- "PKINIT: Can't convert KDC's DH public key");
- ret = KRB5KRB_ERR_GENERIC;
- goto out;
- }
+ {
+ DHPublicKey k;
+ ret = decode_DHPublicKey(p, size, &k, NULL);
+ if (ret) {
+ krb5_set_error_string(context, "pkinit: can't decode "
+ "without key expiration");
+ goto out;
+ }
+ kdc_dh_pubkey = integer_to_BN(context, "DHPublicKey", &k);
+ free_DHPublicKey(&k);
+ if (kdc_dh_pubkey == NULL) {
+ ret = KRB5KRB_ERR_GENERIC;
+ goto out;
+ }
+ }
+
dh_gen_keylen = DH_size(ctx->dh);
size = BN_num_bytes(ctx->dh->p);
if (size < dh_gen_keylen)
@@ -1667,8 +1023,7 @@ pk_rd_pa_reply_dh(krb5_context context,
kdc_dh_pubkey, ctx->dh);
if (dh_gen_keylen == -1) {
krb5_set_error_string(context,
- "PKINIT: Can't compute Diffie-Hellman key (%s)",
- ERR_error_string(ERR_get_error(), NULL));
+ "PKINIT: Can't compute Diffie-Hellman key");
ret = KRB5KRB_ERR_GENERIC;
goto out;
}
@@ -1700,8 +1055,6 @@ pk_rd_pa_reply_dh(krb5_context context,
memset(dh_gen_key, 0, DH_size(ctx->dh));
free(dh_gen_key);
}
- if (dh_pub_key)
- ASN1_INTEGER_free(dh_pub_key);
if (host)
_krb5_pk_cert_free(host);
if (content.data)
@@ -1726,7 +1079,7 @@ _krb5_pk_rd_pa_reply(krb5_context context,
ContentInfo ci;
size_t size;
- /* Check for PK-INIT -27 */
+ /* Check for IETF PK-INIT first */
if (pa->padata_type == KRB5_PADATA_PK_AS_REP) {
PA_PK_AS_REP rep;
@@ -1747,7 +1100,7 @@ _krb5_pk_rd_pa_reply(krb5_context context,
&size);
if (ret) {
krb5_set_error_string(context,
- "PKINIT: -25 decoding failed DH "
+ "PKINIT: decoding failed DH "
"ContentInfo: %d", ret);
free_PA_PK_AS_REP(&rep);
@@ -1821,7 +1174,7 @@ _krb5_pk_rd_pa_reply(krb5_context context,
return ret;
}
ret = pk_rd_pa_reply_enckey(context, COMPAT_WIN2K, &ci, ctx,
- etype, hi, nonce, NULL, pa, key);
+ etype, hi, nonce, req_buffer, pa, key);
free_ContentInfo(&ci);
break;
default:
@@ -1837,598 +1190,158 @@ _krb5_pk_rd_pa_reply(krb5_context context,
return ret;
}
-static int
-ssl_pass_cb(char *buf, int size, int rwflag, void *u)
+struct prompter {
+ krb5_context context;
+ krb5_prompter_fct prompter;
+ void *prompter_data;
+};
+
+static int
+hx_pass_prompter(void *data, const hx509_prompt *prompter)
{
krb5_error_code ret;
krb5_prompt prompt;
krb5_data password_data;
- krb5_prompter_fct prompter = u;
+ struct prompter *p = data;
- password_data.data = buf;
- password_data.length = size;
+ password_data.data = prompter->reply->data;
+ password_data.length = prompter->reply->length;
prompt.prompt = "Enter your private key passphrase: ";
prompt.hidden = 1;
prompt.reply = &password_data;
- prompt.type = KRB5_PROMPT_TYPE_PASSWORD;
+ if (prompter->hidden)
+ prompt.type = KRB5_PROMPT_TYPE_PASSWORD;
+ else
+ prompt.type = KRB5_PROMPT_TYPE_PREAUTH; /* XXX */
- ret = (*prompter)(NULL, NULL, NULL, NULL, 1, &prompt);
+ ret = (*p->prompter)(p->context, p->prompter_data, NULL, NULL, 1, &prompt);
if (ret) {
- memset (buf, 0, size);
+ memset (prompter->reply->data, 0, prompter->reply->length);
return 0;
}
- return strlen(buf);
-}
-
-static krb5_error_code
-load_openssl_cert(krb5_context context,
- const char *file,
- STACK_OF(X509) **c)
-{
- STACK_OF(X509) *certificate;
- krb5_error_code ret;
- FILE *f;
-
- f = fopen(file, "r");
- if (f == NULL) {
- ret = errno;
- krb5_set_error_string(context, "PKINIT: open failed %s: %s",
- file, strerror(ret));
- return ret;
- }
-
- certificate = sk_X509_new_null();
- while (1) {
- /* see http://www.openssl.org/docs/crypto/pem.html section BUGS */
- X509 *cert;
- cert = PEM_read_X509(f, NULL, NULL, NULL);
- if (cert == NULL) {
- if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE) {
- /* End of file reached. no error */
- ERR_clear_error();
- break;
- }
- krb5_set_error_string(context, "PKINIT: Can't read certificate");
- fclose(f);
- return HEIM_PKINIT_CERTIFICATE_INVALID;
- }
- sk_X509_insert(certificate, cert, sk_X509_num(certificate));
- }
- fclose(f);
- if (sk_X509_num(certificate) == 0) {
- krb5_set_error_string(context, "PKINIT: No certificate found");
- return HEIM_PKINIT_NO_CERTIFICATE;
- }
- *c = certificate;
- return 0;
-}
-
-static krb5_error_code
-load_openssl_file(krb5_context context,
- char *password,
- krb5_prompter_fct prompter,
- void *prompter_data,
- const char *user_id,
- struct krb5_pk_identity *id)
-{
- krb5_error_code ret;
- STACK_OF(X509) *certificate = NULL;
- char *cert_file = NULL, *key_file;
- EVP_PKEY *private_key = NULL;
- FILE *f;
-
- cert_file = strdup(user_id);
- if (cert_file == NULL) {
- krb5_set_error_string(context, "malloc: out of memory");
- return ENOMEM;
- }
- key_file = strchr(cert_file, ',');
- if (key_file == NULL) {
- krb5_set_error_string(context, "PKINIT: key file missing");
- ret = HEIM_PKINIT_NO_PRIVATE_KEY;
- goto out;
- }
- *key_file++ = '\0';
-
- ret = load_openssl_cert(context, cert_file, &certificate);
- if (ret)
- goto out;
-
- /* load private key */
- f = fopen(key_file, "r");
- if (f == NULL) {
- ret = errno;
- krb5_set_error_string(context, "PKINIT: open %s: %s",
- key_file, strerror(ret));
- goto out;
- }
- if (password == NULL || password[0] == '\0') {
- if (prompter == NULL)
- prompter = krb5_prompter_posix;
- private_key = PEM_read_PrivateKey(f, NULL, ssl_pass_cb, prompter);
- } else
- private_key = PEM_read_PrivateKey(f, NULL, NULL, password);
- fclose(f);
- if (private_key == NULL) {
- krb5_set_error_string(context, "PKINIT: Can't read private key");
- ret = HEIM_PKINIT_PRIVATE_KEY_INVALID;
- goto out;
- }
- ret = X509_check_private_key(sk_X509_value(certificate, 0), private_key);
- if (ret != 1) {
- ret = HEIM_PKINIT_PRIVATE_KEY_INVALID;
- krb5_set_error_string(context,
- "PKINIT: The private key doesn't match "
- "the public key certificate");
- goto out;
- }
-
- id->private_key = private_key;
- id->cert = certificate;
-
- return 0;
- out:
- if (cert_file)
- free(cert_file);
- if (certificate)
- sk_X509_pop_free(certificate, X509_free);
- if (private_key)
- EVP_PKEY_free(private_key);
-
- return ret;
-}
-
-static int
-add_pair(krb5_context context, char *str, char ***cmds, int *num)
-{
- char **c;
- char *p;
- int i;
-
- p = strchr(str, ':');
- if (p) {
- *p = '\0';
- p++;
- }
-
- /* filter out dup keys */
- for (i = 0; i < *num; i++)
- if (strcmp((*cmds)[i * 2], str) == 0)
- return 0;
-
- c = realloc(*cmds, sizeof(*c) * ((*num + 1) * 2));
- if (c == NULL) {
- krb5_set_error_string(context, "malloc: out of memory");
- return ENOMEM;
- }
-
- c[(*num * 2)] = str;
- c[(*num * 2) + 1] = p;
- *num += 1;
- *cmds = c;
- return 0;
-}
-
-static krb5_error_code
-eval_pairs(krb5_context context, ENGINE *e, const char *name,
- const char *type, char **cmds, int num)
-{
- int i;
-
- for (i = 0; i < num; i++) {
- char *a1 = cmds[i * 2], *a2 = cmds[(i * 2) + 1];
- if(!ENGINE_ctrl_cmd_string(e, a1, a2, 0)) {
- krb5_set_error_string(context,
- "PKINIT: Failed %scommand (%s - %s:%s): %s",
- type, name, a1, a2 ? a2 : "(NULL)",
- ERR_error_string(ERR_get_error(), NULL));
- return HEIM_PKINIT_NO_PRIVATE_KEY;
- }
- }
- return 0;
-}
-
-struct engine_context {
- char **pre_cmds;
- char **post_cmds;
- int num_pre;
- int num_post;
- char *engine_name;
- char *cert_file;
- char *key_id;
-};
-
-static krb5_error_code
-parse_openssl_engine_conf(krb5_context context,
- struct engine_context *ctx,
- char *line)
-{
- krb5_error_code ret;
- char *last, *p, *q;
-
- for (p = strtok_r(line, ",", &last);
- p != NULL;
- p = strtok_r(NULL, ",", &last)) {
-
- q = strchr(p, '=');
- if (q == NULL) {
- krb5_set_error_string(context,
- "PKINIT: openssl engine configuration "
- "key %s missing = and thus value", p);
- return HEIM_PKINIT_NO_PRIVATE_KEY;
- }
- *q = '\0';
- q++;
- if (strcasecmp("PRE", p) == 0) {
- ret = add_pair(context, q, &ctx->pre_cmds, &ctx->num_pre);
- if (ret)
- return ret;
- } else if (strcasecmp("POST", p) == 0) {
- ret = add_pair(context, q, &ctx->post_cmds, &ctx->num_post);
- if (ret)
- return ret;
- } else if (strcasecmp("KEY", p) == 0) {
- ctx->key_id = q;
- } else if (strcasecmp("CERT", p) == 0) {
- ctx->cert_file = q;
- } else if (strcasecmp("ENGINE", p) == 0) {
- ctx->engine_name = q;
- } else {
- krb5_set_error_string(context,
- "PKINIT: openssl engine configuration "
- "key %s is unknown", p);
- return HEIM_PKINIT_NO_PRIVATE_KEY;
- }
- }
- return 0;
-}
-
-
-static krb5_error_code
-load_openssl_engine(krb5_context context,
- char *password,
- krb5_prompter_fct prompter,
- void *prompter_data,
- const char *string,
- struct krb5_pk_identity *id)
-{
- struct engine_context ctx;
- krb5_error_code ret;
- const char *f;
- char *file_conf = NULL, *user_conf = NULL;
- ENGINE *e = NULL;
-
- memset(&ctx, 0, sizeof(ctx));
-
- ENGINE_load_builtin_engines();
-
- user_conf = strdup(string);
- if (user_conf == NULL) {
- krb5_set_error_string(context, "malloc: out of memory");
- return ENOMEM;
- }
-
- ret = parse_openssl_engine_conf(context, &ctx, user_conf);
- if (ret)
- goto out;
-
- f = krb5_config_get_string_default(context, NULL, NULL,
- "libdefaults",
- "pkinit-openssl-engine",
- NULL);
- if (f) {
- file_conf = strdup(f);
- if (file_conf) {
- ret = parse_openssl_engine_conf(context, &ctx, file_conf);
- if (ret)
- goto out;
- }
- }
-
- if (ctx.cert_file == NULL) {
- krb5_set_error_string(context,
- "PKINIT: openssl engine missing certificate");
- ret = HEIM_PKINIT_NO_CERTIFICATE;
- goto out;
- }
- if (ctx.key_id == NULL) {
- krb5_set_error_string(context,
- "PKINIT: openssl engine missing key id");
- ret = HEIM_PKINIT_NO_PRIVATE_KEY;
- goto out;
- }
- if (ctx.engine_name == NULL) {
- krb5_set_error_string(context,
- "PKINIT: openssl engine missing engine name");
- ret = HEIM_PKINIT_NO_PRIVATE_KEY;
- goto out;
- }
-
- e = ENGINE_by_id(ctx.engine_name);
- if (e == NULL) {
- krb5_set_error_string(context,
- "PKINIT: failed getting openssl engine %s: %s",
- ctx.engine_name,
- ERR_error_string(ERR_get_error(), NULL));
- ret = HEIM_PKINIT_NO_PRIVATE_KEY;
- goto out;
- }
-
- ret = eval_pairs(context, e, ctx.engine_name, "pre",
- ctx.pre_cmds, ctx.num_pre);
- if (ret)
- goto out;
-
- if(!ENGINE_init(e)) {
- ret = HEIM_PKINIT_NO_PRIVATE_KEY;
- krb5_set_error_string(context,
- "PKINIT: openssl engine init %s failed: %s",
- ctx.engine_name,
- ERR_error_string(ERR_get_error(), NULL));
- ENGINE_free(e);
- goto out;
- }
-
- ret = eval_pairs(context, e, ctx.engine_name, "post",
- ctx.post_cmds, ctx.num_post);
- if (ret)
- goto out;
-
- /*
- * If the engine supports a LOAD_CERT_CTRL function, lets try
- * it. OpenSC support this function. Eventially this should be
- * a ENGINE_load_cert function if it failes, treat it like a
- * non fatal error.
- */
- {
- struct {
- const char * cert_id;
- X509 * cert;
- } parms;
-
- parms.cert_id = ctx.cert_file;
- parms.cert = NULL;
- ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &parms, NULL, 1);
- if (parms.cert) {
- id->cert = sk_X509_new_null();
- sk_X509_insert(id->cert, parms.cert, 0);
- }
- }
-
- if (id->cert == NULL) {
- ret = load_openssl_cert(context, ctx.cert_file, &id->cert);
- if (ret)
- goto out;
- }
-
- {
- UI_METHOD * krb5_ui_method = NULL;
- struct krb5_ui_data ui_data;
-
- krb5_ui_method = UI_create_method("Krb5 ui method");
- if (krb5_ui_method == NULL) {
- krb5_set_error_string(context,
- "PKINIT: failed to setup prompter "
- "function: %s",
- ERR_error_string(ERR_get_error(), NULL));
- ret = HEIM_PKINIT_NO_PRIVATE_KEY;
- goto out;
- }
- UI_method_set_reader(krb5_ui_method, krb5_ui_method_read_string);
-
- ui_data.context = context;
- ui_data.prompter = prompter;
- if (prompter == NULL)
- ui_data.prompter = krb5_prompter_posix;
- ui_data.prompter_data = prompter_data;
-
- id->private_key = ENGINE_load_private_key(e,
- ctx.key_id,
- krb5_ui_method,
- (void*) &ui_data);
- UI_destroy_method(krb5_ui_method);
- }
-
- if (id->private_key == NULL) {
- krb5_set_error_string(context,
- "PKINIT: failed to load private key: %s",
- ERR_error_string(ERR_get_error(), NULL));
- ret = HEIM_PKINIT_NO_PRIVATE_KEY;
- goto out;
- }
-
- ret = X509_check_private_key(sk_X509_value(id->cert, 0), id->private_key);
- if (ret != 1) {
- ret = HEIM_PKINIT_PRIVATE_KEY_INVALID;
- krb5_set_error_string(context,
- "PKINIT: The private key doesn't match "
- "the public key certificate");
- goto out;
- }
-
- if (user_conf)
- free(user_conf);
- if (file_conf)
- free(file_conf);
-
- id->engine = e;
-
- return 0;
-
- out:
- if (user_conf)
- free(user_conf);
- if (file_conf)
- free(file_conf);
- if (e) {
- ENGINE_finish(e); /* make sure all shared libs are unloaded */
- ENGINE_free(e);
- }
-
- return ret;
+ return strlen(prompter->reply->data);
}
krb5_error_code KRB5_LIB_FUNCTION
-_krb5_pk_load_openssl_id(krb5_context context,
- struct krb5_pk_identity **ret_id,
- const char *user_id,
- const char *x509_anchors,
- krb5_prompter_fct prompter,
- void *prompter_data,
- char *password)
+_krb5_pk_load_id(krb5_context context,
+ struct krb5_pk_identity **ret_id,
+ const char *user_id,
+ const char *anchor_id,
+ char * const *chain,
+ char * const *revoke,
+ krb5_prompter_fct prompter,
+ void *prompter_data,
+ char *password)
{
- STACK_OF(X509) *trusted_certs = NULL;
struct krb5_pk_identity *id = NULL;
- krb5_error_code ret;
- struct dirent *file;
- char *dirname = NULL;
- DIR *dir;
- FILE *f;
- krb5_error_code (*load_pair)(krb5_context,
- char *,
- krb5_prompter_fct,
- void *,
- const char *,
- struct krb5_pk_identity *) = NULL;
-
+ hx509_lock lock = NULL;
+ struct prompter p;
+ int ret;
*ret_id = NULL;
- if (x509_anchors == NULL) {
- krb5_set_error_string(context, "PKINIT: No root ca directory given");
+ if (anchor_id == NULL) {
+ krb5_set_error_string(context, "PKINIT: No anchor given");
return HEIM_PKINIT_NO_VALID_CA;
}
if (user_id == NULL) {
krb5_set_error_string(context,
- "PKINIT: No user X509 source given given");
+ "PKINIT: No user certificate given");
return HEIM_PKINIT_NO_PRIVATE_KEY;
}
- /*
- *
- */
-
- if (strncasecmp(user_id, "FILE:", 5) == 0) {
- load_pair = load_openssl_file;
- user_id += 5;
- } else if (strncasecmp(user_id, "ENGINE:", 7) == 0) {
- load_pair = load_openssl_engine;
- user_id += 7;
- } else {
- krb5_set_error_string(context, "PKINIT: user identity not FILE");
- return HEIM_PKINIT_NO_CERTIFICATE;
- }
- if (strncasecmp(x509_anchors, "OPENSSL-ANCHOR-DIR:", 19) != 0) {
- krb5_set_error_string(context, "PKINIT: anchor OPENSSL-ANCHOR-DIR");
- return HEIM_PKINIT_NO_VALID_CA;
- }
- x509_anchors += 19;
+ /* load cert */
- id = malloc(sizeof(*id));
+ id = calloc(1, sizeof(*id));
if (id == NULL) {
krb5_set_error_string(context, "malloc: out of memory");
ret = ENOMEM;
goto out;
}
- memset(id, 0, sizeof(*id));
-
- OpenSSL_add_all_algorithms();
- ERR_load_crypto_strings();
-
- ret = (*load_pair)(context, password, prompter, prompter_data, user_id, id);
+ ret = hx509_context_init(&id->hx509ctx);
if (ret)
goto out;
- /* load anchors */
+ ret = hx509_lock_init(id->hx509ctx, &lock);
+ if (password)
+ hx509_lock_add_password(lock, password);
- dirname = strdup(x509_anchors);
- if (dirname == NULL) {
- krb5_set_error_string(context, "malloc: out of memory");
- ret = ENOMEM;
- goto out;
- }
+ if (prompter) {
+ p.context = context;
+ p.prompter = prompter;
+ p.prompter_data = prompter_data;
- {
- size_t len;
- len = strlen(dirname);
- if (dirname[len - 1] == '/')
- dirname[len - 1] = '\0';
+ ret = hx509_lock_set_prompter(lock, hx_pass_prompter, &p);
+ if (ret)
+ goto out;
}
- /* read ca certificates */
- dir = opendir(dirname);
- if (dir == NULL) {
- ret = errno;
- krb5_set_error_string(context, "PKINIT: open directory %s: %s",
- dirname, strerror(ret));
+ ret = hx509_certs_init(id->hx509ctx, user_id, 0, NULL, &id->certs);
+ if (ret)
goto out;
- }
- trusted_certs = sk_X509_new_null();
- while ((file = readdir(dir)) != NULL) {
- X509 *cert;
- char *filename;
+ ret = hx509_certs_init(id->hx509ctx, anchor_id, 0, NULL, &id->anchors);
+ if (ret)
+ goto out;
- /*
- * Assume the certificate filenames constist of hashed subject
- * name followed by suffix ".0"
- */
+ ret = hx509_certs_init(id->hx509ctx, "MEMORY:pkinit-cert-chain",
+ 0, NULL, &id->certpool);
+ if (ret)
+ goto out;
- if (strlen(file->d_name) == 10 && strcmp(&file->d_name[8],".0") == 0) {
- asprintf(&filename, "%s/%s", dirname, file->d_name);
- if (filename == NULL) {
- ret = ENOMEM;
- krb5_set_error_string(context, "malloc: out or memory");
- goto out;
- }
- f = fopen(filename, "r");
- if (f == NULL) {
- ret = errno;
- krb5_set_error_string(context, "PKINIT: open %s: %s",
- filename, strerror(ret));
- free(filename);
- closedir(dir);
- goto out;
- }
- cert = PEM_read_X509(f, NULL, NULL, NULL);
- fclose(f);
- if (cert != NULL) {
- /* order of the certs is not important */
- sk_X509_push(trusted_certs, cert);
- }
- free(filename);
+ while (chain && *chain) {
+ ret = hx509_certs_append(id->hx509ctx, id->certpool, NULL, *chain);
+ if (ret) {
+ krb5_set_error_string(context,
+ "pkinit failed to load chain %s",
+ *chain);
+ goto out;
}
+ chain++;
}
- closedir(dir);
- if (sk_X509_num(trusted_certs) == 0) {
- krb5_set_error_string(context,
- "PKINIT: No CA certificate(s) found in %s",
- dirname);
- ret = HEIM_PKINIT_NO_VALID_CA;
- goto out;
- }
+ if (revoke) {
+ ret = hx509_revoke_init(id->hx509ctx, &id->revoke);
+ if (ret) {
+ krb5_set_error_string(context, "revoke failed to init");
+ goto out;
+ }
- id->trusted_certs = trusted_certs;
+ while (*revoke) {
+ ret = hx509_revoke_add_crl(id->hx509ctx, id->revoke, *revoke);
+ if (ret) {
+ krb5_set_error_string(context,
+ "pkinit failed to load revoke %s",
+ *revoke);
+ goto out;
+ }
+ revoke++;
+ }
+ } else
+ hx509_context_set_missing_revoke(id->hx509ctx, 1);
- *ret_id = id;
+ ret = hx509_verify_init_ctx(id->hx509ctx, &id->verify_ctx);
+ if (ret)
+ goto out;
- return 0;
+ hx509_verify_attach_anchors(id->verify_ctx, id->anchors);
+ hx509_verify_attach_revoke(id->verify_ctx, id->revoke);
- out:
- if (dirname)
- free(dirname);
- if (trusted_certs)
- sk_X509_pop_free(trusted_certs, X509_free);
- if (id) {
- if (id->cert)
- sk_X509_pop_free(id->cert, X509_free);
- if (id->private_key)
- EVP_PKEY_free(id->private_key);
+out:
+ if (ret) {
+ hx509_verify_destroy_ctx(id->verify_ctx);
+ hx509_certs_free(&id->certs);
+ hx509_certs_free(&id->anchors);
+ hx509_certs_free(&id->certpool);
+ hx509_revoke_free(&id->revoke);
+ hx509_context_free(&id->hx509ctx);
free(id);
- }
+ } else
+ *ret_id = id;
+
+ hx509_lock_free(lock);
return ret;
}
@@ -2704,17 +1617,12 @@ _krb5_get_init_creds_opt_free_pkinit(krb5_get_init_creds_opt *opt)
DH_free(ctx->dh);
ctx->dh = NULL;
if (ctx->id) {
- if (ctx->id->cert)
- sk_X509_pop_free(ctx->id->cert, X509_free);
- if (ctx->id->trusted_certs)
- sk_X509_pop_free(ctx->id->trusted_certs, X509_free);
- if (ctx->id->private_key)
- EVP_PKEY_free(ctx->id->private_key);
- if (ctx->id->engine) {
- ENGINE_finish(ctx->id->engine); /* unload shared libs etc */
- ENGINE_free(ctx->id->engine);
- ctx->id->engine = NULL;
- }
+ hx509_verify_destroy_ctx(ctx->id->verify_ctx);
+ hx509_certs_free(&ctx->id->certs);
+ hx509_certs_free(&ctx->id->anchors);
+ hx509_certs_free(&ctx->id->certpool);
+ hx509_context_free(&ctx->id->hx509ctx);
+
if (ctx->clientDHNonce) {
krb5_free_data(NULL, ctx->clientDHNonce);
ctx->clientDHNonce = NULL;
@@ -2734,6 +1642,8 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context,
krb5_principal principal,
const char *user_id,
const char *x509_anchors,
+ char * const * chain,
+ char * const * revoke,
int flags,
krb5_prompter_fct prompter,
void *prompter_data,
@@ -2757,14 +1667,18 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context,
opt->opt_private->pk_init_ctx->id = NULL;
opt->opt_private->pk_init_ctx->clientDHNonce = NULL;
opt->opt_private->pk_init_ctx->require_binding = 0;
-
- ret = _krb5_pk_load_openssl_id(context,
- &opt->opt_private->pk_init_ctx->id,
- user_id,
- x509_anchors,
- prompter,
- prompter_data,
- password);
+ opt->opt_private->pk_init_ctx->require_eku = 1;
+ opt->opt_private->pk_init_ctx->require_krbtgt_otherName = 1;
+
+ ret = _krb5_pk_load_id(context,
+ &opt->opt_private->pk_init_ctx->id,
+ user_id,
+ x509_anchors,
+ chain,
+ revoke,
+ prompter,
+ prompter_data,
+ password);
if (ret) {
free(opt->opt_private->pk_init_ctx);
opt->opt_private->pk_init_ctx = NULL;
diff --git a/source4/heimdal/lib/krb5/principal.c b/source4/heimdal/lib/krb5/principal.c
index 6cc49945cc..34086b1fbe 100644
--- a/source4/heimdal/lib/krb5/principal.c
+++ b/source4/heimdal/lib/krb5/principal.c
@@ -41,7 +41,7 @@
#include <fnmatch.h>
#include "resolve.h"
-RCSID("$Id: principal.c,v 1.92 2005/12/11 17:48:13 lha Exp $");
+RCSID("$Id: principal.c,v 1.94 2006/04/10 10:10:01 lha Exp $");
#define princ_num_comp(P) ((P)->name.name_string.len)
#define princ_type(P) ((P)->name.name_type)
@@ -105,7 +105,7 @@ parse_name(krb5_context context,
{
krb5_error_code ret;
heim_general_string *comp;
- heim_general_string realm;
+ heim_general_string realm = NULL;
int ncomp;
const char *p;
@@ -246,6 +246,7 @@ exit:
free(comp[--n]);
}
free(comp);
+ free(realm);
free(s);
return ret;
}
@@ -825,16 +826,21 @@ krb5_425_conv_principal_ext2(krb5_context context,
struct dns_reply *r;
r = dns_lookup(instance, "aaaa");
- if (r && r->head && r->head->type == T_AAAA) {
- inst = strdup(r->head->domain);
+ if (r) {
+ if (r->head && r->head->type == T_AAAA) {
+ inst = strdup(r->head->domain);
+ dns_free_data(r);
+ passed = TRUE;
+ }
dns_free_data(r);
- passed = TRUE;
} else {
r = dns_lookup(instance, "a");
- if(r && r->head && r->head->type == T_A) {
- inst = strdup(r->head->domain);
+ if (r) {
+ if(r->head && r->head->type == T_A) {
+ inst = strdup(r->head->domain);
+ passed = TRUE;
+ }
dns_free_data(r);
- passed = TRUE;
}
}
#else
diff --git a/source4/heimdal/lib/krb5/rd_cred.c b/source4/heimdal/lib/krb5/rd_cred.c
index d62adadf26..520b3a1418 100644
--- a/source4/heimdal/lib/krb5/rd_cred.c
+++ b/source4/heimdal/lib/krb5/rd_cred.c
@@ -33,7 +33,7 @@
#include <krb5_locl.h>
-RCSID("$Id: rd_cred.c,v 1.26 2005/11/02 08:36:42 lha Exp $");
+RCSID("$Id: rd_cred.c,v 1.28 2006/04/02 02:27:33 lha Exp $");
static krb5_error_code
compare_addrs(krb5_context context,
@@ -257,8 +257,10 @@ krb5_rd_cred(krb5_context context,
ASN1_MALLOC_ENCODE(Ticket, creds->ticket.data, creds->ticket.length,
&cred.tickets.val[i], &len, ret);
- if (ret)
+ if (ret) {
+ free(creds);
goto out;
+ }
if(creds->ticket.length != len)
krb5_abortx(context, "internal error in ASN.1 encoder");
copy_EncryptionKey (&kci->key, &creds->session);
@@ -302,6 +304,7 @@ krb5_rd_cred(krb5_context context,
for(i = 0; (*ret_creds)[i]; i++)
krb5_free_creds(context, (*ret_creds)[i]);
free(*ret_creds);
+ *ret_creds = NULL;
}
return ret;
}
diff --git a/source4/heimdal/lib/krb5/rd_priv.c b/source4/heimdal/lib/krb5/rd_priv.c
index bf82ad556e..c52ac175fd 100644
--- a/source4/heimdal/lib/krb5/rd_priv.c
+++ b/source4/heimdal/lib/krb5/rd_priv.c
@@ -33,7 +33,7 @@
#include <krb5_locl.h>
-RCSID("$Id: rd_priv.c,v 1.32 2006/03/18 22:15:57 lha Exp $");
+RCSID("$Id: rd_priv.c,v 1.33 2006/04/12 16:18:10 lha Exp $");
krb5_error_code KRB5_LIB_FUNCTION
krb5_rd_priv(krb5_context context,
@@ -50,8 +50,8 @@ krb5_rd_priv(krb5_context context,
krb5_keyblock *key;
krb5_crypto crypto;
- if (outdata)
- krb5_data_zero(outdata);
+ if (outbuf)
+ krb5_data_zero(outbuf);
if ((auth_context->flags &
(KRB5_AUTH_CONTEXT_RET_TIME | KRB5_AUTH_CONTEXT_RET_SEQUENCE)) &&
@@ -161,7 +161,7 @@ krb5_rd_priv(krb5_context context,
(KRB5_AUTH_CONTEXT_RET_TIME | KRB5_AUTH_CONTEXT_RET_SEQUENCE))) {
/* if these fields are not present in the priv-part, silently
return zero */
- krb5_data_zero(outdata);
+ memset(outdata, 0, sizeof(*outdata));
if(part.timestamp)
outdata->timestamp = *part.timestamp;
if(part.usec)
diff --git a/source4/heimdal/lib/krb5/rd_req.c b/source4/heimdal/lib/krb5/rd_req.c
index 313c14f6e6..0d4635b964 100644
--- a/source4/heimdal/lib/krb5/rd_req.c
+++ b/source4/heimdal/lib/krb5/rd_req.c
@@ -33,7 +33,7 @@
#include <krb5_locl.h>
-RCSID("$Id: rd_req.c,v 1.61 2005/11/29 18:22:51 lha Exp $");
+RCSID("$Id: rd_req.c,v 1.63 2006/04/10 10:14:44 lha Exp $");
static krb5_error_code
decrypt_tkt_enc_part (krb5_context context,
@@ -279,8 +279,10 @@ krb5_verify_authenticator_checksum(krb5_context context,
&authenticator);
if(ret)
return ret;
- if(authenticator->cksum == NULL)
+ if(authenticator->cksum == NULL) {
+ krb5_free_authenticator(context, &authenticator);
return -17;
+ }
ret = krb5_auth_con_getkey(context, ac, &key);
if(ret) {
krb5_free_authenticator(context, &authenticator);
@@ -340,6 +342,9 @@ krb5_verify_ap_req2(krb5_context context,
krb5_error_code ret;
EtypeList etypes;
+ if (ticket)
+ *ticket = NULL;
+
if (auth_context && *auth_context) {
ac = *auth_context;
} else {
@@ -348,13 +353,12 @@ krb5_verify_ap_req2(krb5_context context,
return ret;
}
- t = malloc(sizeof(*t));
+ t = calloc(1, sizeof(*t));
if (t == NULL) {
ret = ENOMEM;
krb5_clear_error_string (context);
goto out;
}
- memset(t, 0, sizeof(*t));
if (ap_req->ap_options.use_session_key && ac->keyblock){
ret = krb5_decrypt_ticket(context, &ap_req->ticket,
@@ -372,14 +376,17 @@ krb5_verify_ap_req2(krb5_context context,
if(ret)
goto out;
- _krb5_principalname2krb5_principal(&t->server, ap_req->ticket.sname,
- ap_req->ticket.realm);
- _krb5_principalname2krb5_principal(&t->client, t->ticket.cname,
- t->ticket.crealm);
+ ret = _krb5_principalname2krb5_principal(&t->server, ap_req->ticket.sname,
+ ap_req->ticket.realm);
+ if (ret) goto out;
+ ret = _krb5_principalname2krb5_principal(&t->client, t->ticket.cname,
+ t->ticket.crealm);
+ if (ret) goto out;
/* save key */
- krb5_copy_keyblock(context, &t->ticket.key, &ac->keyblock);
+ ret = krb5_copy_keyblock(context, &t->ticket.key, &ac->keyblock);
+ if (ret) goto out;
ret = decrypt_authenticator (context,
&t->ticket.key,
diff --git a/source4/heimdal/lib/krb5/replay.c b/source4/heimdal/lib/krb5/replay.c
index ec99f86c7c..b89f150159 100644
--- a/source4/heimdal/lib/krb5/replay.c
+++ b/source4/heimdal/lib/krb5/replay.c
@@ -34,7 +34,7 @@
#include "krb5_locl.h"
#include <vis.h>
-RCSID("$Id: replay.c,v 1.10 2004/05/25 21:41:15 lha Exp $");
+RCSID("$Id: replay.c,v 1.12 2006/04/10 17:13:49 lha Exp $");
struct krb5_rcache_data {
char *name;
@@ -58,6 +58,7 @@ krb5_rc_resolve_type(krb5_context context,
krb5_rcache *id,
const char *type)
{
+ *id = NULL;
if(strcmp(type, "FILE")) {
krb5_set_error_string (context, "replay cache type %s not supported",
type);
@@ -77,6 +78,9 @@ krb5_rc_resolve_full(krb5_context context,
const char *string_name)
{
krb5_error_code ret;
+
+ *id = NULL;
+
if(strncmp(string_name, "FILE:", 5)) {
krb5_set_error_string (context, "replay cache type %s not supported",
string_name);
@@ -86,6 +90,10 @@ krb5_rc_resolve_full(krb5_context context,
if(ret)
return ret;
ret = krb5_rc_resolve(context, *id, string_name + 5);
+ if (ret) {
+ krb5_rc_close(context, *id);
+ *id = NULL;
+ }
return ret;
}
diff --git a/source4/heimdal/lib/krb5/send_to_kdc.c b/source4/heimdal/lib/krb5/send_to_kdc.c
index d3d21aea3f..0bcafa70a1 100644
--- a/source4/heimdal/lib/krb5/send_to_kdc.c
+++ b/source4/heimdal/lib/krb5/send_to_kdc.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: send_to_kdc.c,v 1.57 2006/03/07 19:39:59 lha Exp $");
+RCSID("$Id: send_to_kdc.c,v 1.58 2006/04/02 02:32:03 lha Exp $");
struct send_and_recv {
krb5_send_and_recv_func_t func;
@@ -231,6 +231,7 @@ send_and_recv_http(int fd,
s[rep->length] = 0;
p = strstr(s, "\r\n\r\n");
if(p == NULL) {
+ krb5_data_zero(rep);
free(s);
return -1;
}
@@ -238,12 +239,14 @@ send_and_recv_http(int fd,
rep->data = s;
rep->length -= p - s;
if(rep->length < 4) { /* remove length */
+ krb5_data_zero(rep);
free(s);
return -1;
}
rep->length -= 4;
_krb5_get_int(p, &rep_len, 4);
if (rep_len != rep->length) {
+ krb5_data_zero(rep);
free(s);
return -1;
}
diff --git a/source4/heimdal/lib/krb5/store.c b/source4/heimdal/lib/krb5/store.c
index 42667765fb..4a567bb379 100644
--- a/source4/heimdal/lib/krb5/store.c
+++ b/source4/heimdal/lib/krb5/store.c
@@ -34,7 +34,7 @@
#include "krb5_locl.h"
#include "store-int.h"
-RCSID("$Id: store.c,v 1.50 2005/06/17 04:36:33 lha Exp $");
+RCSID("$Id: store.c,v 1.51 2006/04/07 22:23:20 lha Exp $");
#define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V))
#define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE)
@@ -420,7 +420,7 @@ krb5_ret_principal(krb5_storage *sp,
if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
type = KRB5_NT_UNKNOWN;
- else if((ret = krb5_ret_int32(sp, &type))){
+ else if((ret = krb5_ret_int32(sp, &type))){
free(p);
return ret;
}
@@ -430,18 +430,31 @@ krb5_ret_principal(krb5_storage *sp,
}
if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
ncomp--;
+ if (ncomp < 0) {
+ free(p);
+ return EINVAL;
+ }
p->name.name_type = type;
p->name.name_string.len = ncomp;
ret = krb5_ret_string(sp, &p->realm);
- if(ret) return ret;
+ if(ret) {
+ free(p);
+ return ret;
+ }
p->name.name_string.val = calloc(ncomp, sizeof(*p->name.name_string.val));
- if(p->name.name_string.val == NULL){
+ if(p->name.name_string.val == NULL && ncomp != 0){
free(p->realm);
return ENOMEM;
}
for(i = 0; i < ncomp; i++){
ret = krb5_ret_string(sp, &p->name.name_string.val[i]);
- if(ret) return ret; /* XXX */
+ if(ret) {
+ while (i >= 0)
+ free(p->name.name_string.val[i--]);
+ free(p->realm);
+ free(p);
+ return ret;
+ }
}
*princ = p;
return 0;
diff --git a/source4/heimdal/lib/krb5/transited.c b/source4/heimdal/lib/krb5/transited.c
index 9e24db0da0..7f18b30c88 100644
--- a/source4/heimdal/lib/krb5/transited.c
+++ b/source4/heimdal/lib/krb5/transited.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: transited.c,v 1.16 2005/06/17 04:53:35 lha Exp $");
+RCSID("$Id: transited.c,v 1.18 2006/04/10 10:26:35 lha Exp $");
/* this is an attempt at one of the most horrible `compression'
schemes that has ever been invented; it's so amazingly brain-dead
@@ -100,8 +100,10 @@ make_path(krb5_context context, struct tr_realm *r,
p = from + strlen(from);
while(1){
while(p >= from && *p != '/') p--;
- if(p == from)
+ if(p == from) {
+ r->next = path; /* XXX */
return KRB5KDC_ERR_POLICY;
+ }
if(strncmp(to, from, p - from) == 0)
break;
tmp = calloc(1, sizeof(*tmp));
@@ -166,10 +168,13 @@ expand_realms(krb5_context context,
for(r = realms; r; r = r->next){
if(r->trailing_dot){
char *tmp;
- size_t len = strlen(r->realm) + strlen(prev_realm) + 1;
+ size_t len;
if(prev_realm == NULL)
prev_realm = client_realm;
+
+ len = strlen(r->realm) + strlen(prev_realm) + 1;
+
tmp = realloc(r->realm, len);
if(tmp == NULL){
free_realms(realms);
diff --git a/source4/heimdal/lib/krb5/v4_glue.c b/source4/heimdal/lib/krb5/v4_glue.c
index c66b06c09f..dd294c8943 100644
--- a/source4/heimdal/lib/krb5/v4_glue.c
+++ b/source4/heimdal/lib/krb5/v4_glue.c
@@ -32,7 +32,7 @@
*/
#include "krb5_locl.h"
-RCSID("$Id: v4_glue.c,v 1.2 2005/04/24 13:44:02 lha Exp $");
+RCSID("$Id: v4_glue.c,v 1.3 2006/04/02 01:39:54 lha Exp $");
#include "krb5-v4compat.h"
@@ -155,19 +155,20 @@ write_v4_cc(krb5_context context, const char *tkfile,
fd = open(path, O_WRONLY|O_CREAT, 0600);
if (fd < 0) {
- free(path);
+ ret = errno;
krb5_set_error_string(context,
"krb5_krb_tf_setup: error opening file %s",
path);
- return errno;
+ free(path);
+ return ret;
}
if (fstat(fd, &sb) != 0 || !S_ISREG(sb.st_mode)) {
- free(path);
- close(fd);
krb5_set_error_string(context,
"krb5_krb_tf_setup: tktfile %s is not a file",
path);
+ free(path);
+ close(fd);
return KRB5_FCC_PERM;
}
@@ -178,11 +179,11 @@ write_v4_cc(krb5_context context, const char *tkfile,
break;
}
if (i == KRB5_TF_LCK_RETRY_COUNT) {
- free(path);
- close(fd);
krb5_set_error_string(context,
"krb5_krb_tf_setup: failed to lock %s",
path);
+ free(path);
+ close(fd);
return KRB5_FCC_PERM;
}
@@ -190,11 +191,11 @@ write_v4_cc(krb5_context context, const char *tkfile,
ret = ftruncate(fd, 0);
if (ret < 0) {
flock(fd, LOCK_UN);
- free(path);
- close(fd);
krb5_set_error_string(context,
"krb5_krb_tf_setup: failed to truncate %s",
path);
+ free(path);
+ close(fd);
return KRB5_FCC_PERM;
}
}