add support for KRB5_PADATA_ETYPE_INFO2

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@12512 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2003-07-23 18:56:59 +00:00
parent d73655dcc7
commit 5b1231ff3a

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997-2002 Kungliga Tekniska H<>gskolan
* Copyright (c) 1997-2003 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -329,6 +329,7 @@ get_pa_etype_info(METHOD_DATA *md, hdb_entry *client,
pa.val = malloc(pa.len * sizeof(*pa.val));
if(pa.val == NULL)
return ENOMEM;
memset(pa.val, 0, pa.len * sizeof(*pa.val));
for(j = 0; j < etypes_len; j++) {
for(i = 0; i < client->keys.len; i++) {
@@ -377,6 +378,142 @@ get_pa_etype_info(METHOD_DATA *md, hdb_entry *client,
return 0;
}
/*
*
*/
#ifdef ENABLE_AES
extern int _krb5_AES_string_to_default_iterator;
#endif
static krb5_error_code
make_etype_info2_entry(ETYPE_INFO2_ENTRY *ent, Key *key)
{
ent->etype = key->key.keytype;
if(key->salt) {
ALLOC(ent->salt);
if (ent->salt == NULL)
return ENOMEM;
*ent->salt = strndup(key->salt->salt.data, key->salt->salt.length);
} else
ent->salt = NULL;
switch (key->key.keytype) {
#ifdef ENABLE_AES
case KEYTYPE_AES128:
case KEYTYPE_AES256:
ALLOC(ent->s2kparams);
if (ent->s2kparams == NULL)
return ENOMEM;
ent->s2kparams->length = 4;
ent->s2kparams->data = malloc(ent->s2kparams->length);
if (ent->s2kparams->data == NULL)
return ENOMEM;
_krb5_put_int(ent->s2kparams->data,
_krb5_AES_string_to_default_iterator,
ent->s2kparams->length);
break;
#endif
default:
ent->s2kparams = NULL;
break;
}
return 0;
}
/*
* Return 1 if the client have only older enctypes, this is for
* determining if the server should send ETYPE_INFO2 or not.
*/
static int
only_older_enctype_p(const hdb_entry *client)
{
int i;
for(i = 0; i < client->keys.len; i++) {
switch (client->keys.val[i].key.keytype) {
case KEYTYPE_DES:
case KEYTYPE_DES3:
case KEYTYPE_ARCFOUR:
break;
default:
return 0;
}
}
return 1;
}
/*
*
*/
static krb5_error_code
get_pa_etype_info2(METHOD_DATA *md, hdb_entry *client,
ENCTYPE *etypes, unsigned int etypes_len)
{
krb5_error_code ret = 0;
int i, j;
unsigned int n = 0;
ETYPE_INFO2 pa;
unsigned char *buf;
size_t len;
pa.len = client->keys.len;
if(pa.len > UINT_MAX/sizeof(*pa.val))
return ERANGE;
pa.val = malloc(pa.len * sizeof(*pa.val));
if(pa.val == NULL)
return ENOMEM;
memset(pa.val, 0, pa.len * sizeof(*pa.val));
for(j = 0; j < etypes_len; j++) {
for(i = 0; i < client->keys.len; i++) {
if(client->keys.val[i].key.keytype == etypes[j])
if((ret = make_etype_info2_entry(&pa.val[n++],
&client->keys.val[i])) != 0) {
free_ETYPE_INFO2(&pa);
return ret;
}
}
}
for(i = 0; i < client->keys.len; i++) {
for(j = 0; j < etypes_len; j++) {
if(client->keys.val[i].key.keytype == etypes[j])
goto skip;
}
if((ret = make_etype_info2_entry(&pa.val[n++],
&client->keys.val[i])) != 0) {
free_ETYPE_INFO2(&pa);
return ret;
}
skip:;
}
if(n != pa.len) {
char *name;
krb5_unparse_name(context, client->principal, &name);
kdc_log(0, "internal error in get_pa_etype_info(%s): %d != %d",
name, n, pa.len);
free(name);
pa.len = n;
}
ASN1_MALLOC_ENCODE(ETYPE_INFO2, buf, len, &pa, &len, ret);
free_ETYPE_INFO2(&pa);
if(ret)
return ret;
ret = realloc_method_data(md);
if(ret) {
free(buf);
return ret;
}
md->val[md->len - 1].padata_type = KRB5_PADATA_ETYPE_INFO2;
md->val[md->len - 1].padata_value.length = len;
md->val[md->len - 1].padata_value.data = buf;
return 0;
}
/*
* verify the flags on `client' and `server', returning 0
* if they are OK and generating an error messages and returning
@@ -675,8 +812,14 @@ as_rep(KDC_REQ *req,
pa->padata_value.length = 0;
pa->padata_value.data = NULL;
ret = get_pa_etype_info(&method_data, client,
b->etype.val, b->etype.len); /* XXX check ret */
/* XXX check ret */
if (only_older_enctype_p(client))
ret = get_pa_etype_info(&method_data, client,
b->etype.val, b->etype.len);
/* XXX check ret */
ret = get_pa_etype_info2(&method_data, client,
b->etype.val, b->etype.len);
ASN1_MALLOC_ENCODE(METHOD_DATA, buf, len, &method_data, &len, ret);
free_METHOD_DATA(&method_data);