merge new-crypto branch

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@5332 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Johan Danielsson
1999-02-11 21:03:59 +00:00
parent 0a6c3f7fde
commit aaae186ab9
83 changed files with 4175 additions and 1509 deletions

View File

@@ -47,6 +47,7 @@ do_524(Ticket *t, krb5_data *reply, const char *from)
{
krb5_error_code ret = 0;
krb5_principal sprinc = NULL;
krb5_crypto crypto;
hdb_entry *server;
Key *skey;
krb5_data et_data;
@@ -65,18 +66,19 @@ do_524(Ticket *t, krb5_data *reply, const char *from)
from, spn);
goto out;
}
ret = hdb_etype2key(context, server, t->enc_part.etype, &skey);
ret = hdb_enctype2key(context, server, t->enc_part.etype, &skey);
if(ret){
kdc_log(0, "No suitable key found for server (%s) "
"when converting ticket from ", spn, from);
goto out;
}
ret = krb5_decrypt (context,
t->enc_part.cipher.data,
t->enc_part.cipher.length,
t->enc_part.etype,
&skey->key,
&et_data);
krb5_crypto_init(context, &skey->key, 0, &crypto);
ret = krb5_decrypt_EncryptedData (context,
crypto,
KRB5_KU_TICKET,
&t->enc_part,
&et_data);
krb5_crypto_destroy(context, crypto);
if(ret){
kdc_log(0, "Failed to decrypt ticket from %s for %s", from, spn);
goto out;
@@ -118,7 +120,7 @@ do_524(Ticket *t, krb5_data *reply, const char *from)
kdc_log(0, "Failed to encode v4 ticket (%s)", spn);
goto out;
}
ret = hdb_etype2key(context, server, KEYTYPE_DES, &skey);
ret = get_des_key(server, &skey);
if(ret){
kdc_log(0, "No DES key for server (%s)", spn);
goto out;

View File

@@ -289,6 +289,7 @@ process_request(unsigned char *buf,
else if(maybe_version4(buf, len)){
*sendlength = 0; /* elbitapmoc sdrawkcab XXX */
do_version4(buf, len, reply, from, (struct sockaddr_in*)addr);
return 0;
}else if(decode_Ticket(buf, len, &ticket, &i) == 0){
ret = do_524(&ticket, reply, from);
free_Ticket(&ticket);

View File

@@ -149,13 +149,13 @@ v4_prop(void *arg, Principal *p)
free(s);
}
ent.keys.len = 1;
ALLOC(ent.keys.val);
ent.kvno = p->key_version;
ent.keys.len = 3;
ent.keys.val = malloc(ent.keys.len * sizeof(*ent.keys.val));
ent.keys.val[0].mkvno = p->kdc_key_ver;
ent.keys.val[0].salt = calloc(1, sizeof(*ent.keys.val[0].salt));
ent.keys.val[0].salt->type = pa_pw_salt;
ent.kvno = p->key_version;
ent.keys.val[0].key.keytype = KEYTYPE_DES;
ent.keys.val[0].key.keytype = ETYPE_DES_CBC_MD5;
krb5_data_alloc(&ent.keys.val[0].key.keyvalue, sizeof(des_cblock));
{
@@ -170,6 +170,10 @@ v4_prop(void *arg, Principal *p)
ent.flags.invalid = 1;
}
}
copy_Key(&ent.keys.val[0], &ent.keys.val[1]);
ent.keys.val[1].key.keytype = ETYPE_DES_CBC_MD4;
copy_Key(&ent.keys.val[0], &ent.keys.val[2]);
ent.keys.val[2].key.keytype = ETYPE_DES_CBC_CRC;
ALLOC(ent.max_life);
*ent.max_life = krb_life_to_time(0, p->max_life);
@@ -270,17 +274,21 @@ ka_convert(struct prop_data *pd, int fd, struct ka_entry *ent, const char *cell)
krb5_warn(pd->context, ret, "krb5_425_conv_principal");
return 0;
}
hdb.keys.len = 1;
ALLOC(hdb.keys.val);
hdb.kvno = ntohl(ent->kvno);
hdb.keys.len = 3;
hdb.keys.val = malloc(hdb.keys.len * sizeof(*hdb.keys.val));
hdb.keys.val[0].mkvno = 0; /* XXX */
hdb.keys.val[0].salt = calloc(1, sizeof(*hdb.keys.val[0].salt));
hdb.keys.val[0].salt->type = hdb_afs3_salt;
hdb.keys.val[0].salt->salt.data = strdup(cell);
hdb.keys.val[0].salt->salt.length = strlen(cell);
hdb.kvno = ntohl(ent->kvno);
hdb.keys.val[0].key.keytype = KEYTYPE_DES;
hdb.keys.val[0].key.keytype = ETYPE_DES_CBC_MD5;
krb5_data_copy(&hdb.keys.val[0].key.keyvalue, ent->key, sizeof(ent->key));
copy_Key(&hdb.keys.val[0], &hdb.keys.val[1]);
hdb.keys.val[1].key.keytype = ETYPE_DES_CBC_MD4;
copy_Key(&hdb.keys.val[0], &hdb.keys.val[2]);
hdb.keys.val[2].key.keytype = ETYPE_DES_CBC_CRC;
ALLOC(hdb.max_life);
*hdb.max_life = ntohl(ent->max_life);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -422,7 +422,7 @@ do_authenticate (struct rx_header *hdr,
}
/* find a DES key */
ret = hdb_keytype2key(context, client_entry, KEYTYPE_DES, &ckey);
ret = get_des_key(client_entry, &ckey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
make_error_reply (hdr, KANOKEYS, reply);
@@ -430,7 +430,7 @@ do_authenticate (struct rx_header *hdr,
}
/* find a DES key */
ret = hdb_keytype2key(context, server_entry, KEYTYPE_DES, &skey);
ret = get_des_key(server_entry, &skey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
make_error_reply (hdr, KANOKEYS, reply);
@@ -595,7 +595,7 @@ do_getticket (struct rx_header *hdr,
}
/* find a DES key */
ret = hdb_keytype2key(context, krbtgt_entry, KEYTYPE_DES, &kkey);
ret = get_des_key(krbtgt_entry, &kkey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
make_error_reply (hdr, KANOKEYS, reply);
@@ -603,7 +603,7 @@ do_getticket (struct rx_header *hdr,
}
/* find a DES key */
ret = hdb_keytype2key(context, server_entry, KEYTYPE_DES, &skey);
ret = get_des_key(server_entry, &skey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
make_error_reply (hdr, KANOKEYS, reply);

View File

@@ -87,6 +87,7 @@ krb5_error_code do_version4 (unsigned char*, size_t, krb5_data*, const char*,
krb5_error_code encode_v4_ticket (void*, size_t, EncTicketPart*,
PrincipalName*, size_t*);
krb5_error_code encrypt_v4_ticket (void*, size_t, des_cblock*, EncryptedData*);
krb5_error_code get_des_key(hdb_entry*, Key**);
int maybe_version4 (unsigned char*, int);
#endif

View File

@@ -111,6 +111,18 @@ db_fetch4(const char *name, const char *instance, const char *realm)
return ent;
}
krb5_error_code
get_des_key(hdb_entry *principal, Key **key)
{
krb5_error_code ret;
ret = hdb_enctype2key(context, principal, ETYPE_DES_CBC_MD5, key);
if(ret)
ret = hdb_enctype2key(context, principal, ETYPE_DES_CBC_MD4, key);
if(ret)
ret = hdb_enctype2key(context, principal, ETYPE_DES_CBC_CRC, key);
return ret;
}
#define RCHECK(X, L) if(X){make_err_reply(reply, KFAILURE, "Packet too short"); goto L;}
krb5_error_code
@@ -172,7 +184,7 @@ do_version4(unsigned char *buf,
goto out1;
}
ret = hdb_keytype2key(context, client, KEYTYPE_DES, &ckey);
ret = get_des_key(client, &ckey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
/* XXX */
@@ -195,7 +207,7 @@ do_version4(unsigned char *buf,
}
#endif
ret = hdb_keytype2key(context, server, KEYTYPE_DES, &skey);
ret = get_des_key(server, &skey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
/* XXX */
@@ -275,7 +287,7 @@ do_version4(unsigned char *buf,
goto out2;
}
ret = hdb_keytype2key(context, tgt, KEYTYPE_DES, &tkey);
ret = get_des_key(tgt, &tkey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
/* XXX */
@@ -283,7 +295,6 @@ do_version4(unsigned char *buf,
"No DES key in database (krbtgt)");
goto out2;
}
RCHECK(krb5_ret_int8(sp, &ticket_len), out2);
RCHECK(krb5_ret_int8(sp, &req_len), out2);
@@ -347,12 +358,12 @@ do_version4(unsigned char *buf,
goto out2;
}
ret = hdb_keytype2key(context, server, KEYTYPE_DES, &skey);
ret = get_des_key(server, &skey);
if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret));
/* XXX */
make_err_reply(reply, KDC_NULL_KEY,
"Server has no DES key");
"No DES key in database (server)");
goto out2;
}
@@ -513,7 +524,9 @@ encode_v4_ticket(void *buf, size_t len, EncTicketPart *et,
sp->store(sp, tmp, sizeof(tmp));
}
if(et->key.keytype != KEYTYPE_DES ||
if((et->key.keytype != ETYPE_DES_CBC_MD5 &&
et->key.keytype != ETYPE_DES_CBC_MD4 &&
et->key.keytype != ETYPE_DES_CBC_CRC) ||
et->key.keyvalue.length != 8)
return -1;
sp->store(sp, et->key.keyvalue.data, 8);

View File

@@ -76,6 +76,40 @@ find_padata(KDC_REQ *req, int *start, int type)
return NULL;
}
#if 0
static krb5_error_code
find_keys(hdb_entry *client,
hdb_entry *server,
Key **ckey,
krb5_enctype *cetype,
Key **skey,
krb5_enctype *setype,
unsigned *etypes,
unsigned num_etypes)
{
int i;
krb5_error_code ret;
for(i = 0; i < num_etypes; i++) {
if(client){
ret = hdb_enctype2key(context, client, etypes[i], ckey);
if(ret)
continue;
}
if(server){
ret = hdb_enctype2key(context, server, etypes[i], skey);
if(ret)
continue;
}
if(etype)
*cetype = *setype = etypes[i];
return 0;
}
return KRB5KDC_ERR_ETYPE_NOSUPP;
}
#else
static krb5_error_code
find_etype(hdb_entry *princ, unsigned *etypes, unsigned len,
Key **key, int *index)
@@ -83,49 +117,21 @@ find_etype(hdb_entry *princ, unsigned *etypes, unsigned len,
int i;
krb5_error_code ret = -1;
for(i = 0; i < len ; i++)
if((ret = hdb_etype2key(context, princ, etypes[i], key)) == 0)
if((ret = hdb_enctype2key(context, princ, etypes[i], key)) == 0)
break;
if(index) *index = i;
return ret;
}
static krb5_error_code
find_keys1(hdb_entry *client, hdb_entry *server,
Key **ckey, krb5_enctype *cetype,
Key **skey, krb5_enctype *setype,
krb5_enctype *sess_ktype,
unsigned *etypes, unsigned num_etypes)
{
int i;
krb5_error_code ret;
for(i = 0; i < num_etypes; i++) {
if(client){
ret = hdb_etype2key(context, client, etypes[i], ckey);
if(ret)
continue;
}
if(server){
ret = hdb_etype2key(context, server, etypes[i], skey);
if(ret)
continue;
}
if(cetype)
*cetype = etypes[i];
if(setype)
*setype = etypes[i];
if(sess_ktype)
*sess_ktype = etypes[i];
return 0;
}
return KRB5KDC_ERR_ETYPE_NOSUPP;
}
static krb5_error_code
find_keys2(hdb_entry *client, hdb_entry *server,
Key **ckey, krb5_enctype *cetype,
Key **skey, krb5_enctype *setype,
krb5_keytype *sess_ktype,
unsigned *etypes, unsigned num_etypes)
find_keys(hdb_entry *client,
hdb_entry *server,
Key **ckey,
krb5_enctype *cetype,
Key **skey,
krb5_enctype *setype,
unsigned *etypes,
unsigned num_etypes)
{
int i;
krb5_error_code ret;
@@ -140,43 +146,29 @@ find_keys2(hdb_entry *client, hdb_entry *server,
}
if(server){
/* find session key type */
/* find server key */
ret = find_etype(server, etypes, num_etypes, skey, NULL);
if(ret){
kdc_log(0, "Server has no support for etypes");
return KRB5KDC_ERR_ETYPE_NOSUPP;
}
*sess_ktype = (*skey)->key.keytype;
}
if(server){
/* find server key */
*skey = NULL;
#define is_better(x, y) ((x) > (y))
for(i = 0; i < server->keys.len; i++){
if(*skey == NULL || is_better(server->keys.val[i].key.keytype,
(*skey)->key.keytype))
*skey = &server->keys.val[i];
}
if(*skey == NULL){
kdc_log(0, "No key found for server");
return KRB5KDC_ERR_NULL_KEY;
}
ret = krb5_keytype_to_etype(context, (*skey)->key.keytype, setype);
if(ret)
return ret;
*setype = (*skey)->key.keytype;
}
return 0;
}
#endif
static krb5_error_code
encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek,
krb5_enctype setype, int skvno, EncryptionKey *skey,
krb5_enctype cetype, int ckvno, EncryptionKey *ckey,
krb5_enctype etype,
int skvno, EncryptionKey *skey,
int ckvno, EncryptionKey *ckey,
krb5_data *reply)
{
unsigned char buf[8192]; /* XXX The data could be indefinite */
size_t len;
krb5_error_code ret;
krb5_crypto crypto;
ret = encode_EncTicketPart(buf + sizeof(buf) - 1, sizeof(buf), et, &len);
if(ret) {
@@ -185,13 +177,18 @@ encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek,
return ret;
}
krb5_crypto_init(context, skey, etype, &crypto);
krb5_encrypt_EncryptedData(context,
crypto,
KRB5_KU_TICKET,
buf + sizeof(buf) - len,
len,
setype,
skvno,
skey,
&rep->ticket.enc_part);
krb5_crypto_destroy(context, crypto);
if(rep->msg_type == krb_as_rep && !encode_as_rep_as_tgs_rep)
ret = encode_EncASRepPart(buf + sizeof(buf) - 1, sizeof(buf),
@@ -204,18 +201,27 @@ encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek,
krb5_get_err_text(context, ret));
return ret;
}
krb5_encrypt_EncryptedData(context,
buf + sizeof(buf) - len,
len,
cetype,
ckvno,
ckey,
&rep->enc_part);
if(rep->msg_type == krb_as_rep)
krb5_crypto_init(context, ckey, 0, &crypto);
if(rep->msg_type == krb_as_rep) {
krb5_encrypt_EncryptedData(context,
crypto,
KRB5_KU_AS_REP_ENC_PART,
buf + sizeof(buf) - len,
len,
ckvno,
&rep->enc_part);
ret = encode_AS_REP(buf + sizeof(buf) - 1, sizeof(buf), rep, &len);
else
} else {
krb5_encrypt_EncryptedData(context,
crypto,
KRB5_KU_TGS_REP_ENC_PART_SESSION,
buf + sizeof(buf) - len,
len,
ckvno,
&rep->enc_part);
ret = encode_TGS_REP(buf + sizeof(buf) - 1, sizeof(buf), rep, &len);
}
krb5_crypto_destroy(context, crypto);
if(ret) {
kdc_log(0, "Failed to encode KDC-REP: %s",
krb5_get_err_text(context, ret));
@@ -243,51 +249,47 @@ get_pa_etype_info(METHOD_DATA *md, hdb_entry *client)
krb5_error_code ret = 0;
int i;
ETYPE_INFO pa;
ETYPE_INFO_ENTRY *tmp;
unsigned char *buf;
size_t len;
pa.val = NULL;
pa.len = 0;
for(i = 0; i < client->keys.len; i++){
krb5_enctype *etypes, *e;
krb5_enctype ex[2];
ex[0] = client->keys.val[i].key.keytype;
ex[1] = 0;
if(context->ktype_is_etype)
ret = krb5_keytype_to_etypes(context,
client->keys.val[i].key.keytype,
&etypes);
else
etypes = ex;
for(e = etypes; *e; e++){
tmp = realloc(pa.val, (pa.len + 1) * sizeof(*pa.val));
if(tmp == NULL) {
free_ETYPE_INFO(&pa);
return ret;
}
pa.val = tmp;
pa.val[pa.len].etype = *e;
ALLOC(pa.val[pa.len].salttype);
if(client->keys.val[i].salt){
*pa.val[pa.len].salttype = client->keys.val[i].salt->type;
ALLOC(pa.val[pa.len].salt);
ret = copy_octet_string(&client->keys.val[i].salt->salt,
pa.val[pa.len].salt);
if(tmp == NULL) {
free_ETYPE_INFO(&pa);
return ret;
}
}
pa.len = client->keys.len;
pa.val = malloc(pa.len * sizeof(*pa.val));
if(pa.val == NULL)
return ENOMEM;
for(i = 0; i < client->keys.len; i++) {
pa.val[i].etype = client->keys.val[i].key.keytype;
ALLOC(pa.val[i].salttype);
if(client->keys.val[i].salt){
#if 0
if(client->keys.val[i].salt->type == hdb_pw_salt)
*pa.val[i].salttype = 0; /* or 1? or NULL? */
else if(client->keys.val[i].salt->type == hdb_afs3_salt)
*pa.val[i].salttype = 2;
else {
*pa.val[pa.len].salttype = pa_pw_salt;
pa.val[pa.len].salt = NULL;
free_ETYPE_INFO(&pa);
kdc_log(0, "unknown salt-type: %d",
client->keys.val[i].salt->type);
return KRB5KRB_ERR_GENERIC;
}
pa.len++;
/* according to `the specs', we can't send a salt if
we have AFS3 salted key, but that requires that you
*know* what cell you are using (e.g by assuming
that the cell is the same as the realm in lower
case) */
#else
*pa.val[i].salttype = client->keys.val[i].salt->type;
#endif
krb5_copy_data(context, &client->keys.val[i].salt->salt,
&pa.val[i].salt);
} else {
#if 0
*pa.val[i].salttype = 1; /* or 0 with salt? */
#else
*pa.val[i].salttype = pa_pw_salt;
#endif
pa.val[i].salt = NULL;
}
if(context->ktype_is_etype)
free(etypes);
}
len = length_ETYPE_INFO(&pa);
buf = malloc(len);
@@ -313,29 +315,29 @@ check_flags(hdb_entry *client, const char *client_name,
hdb_entry *server, const char *server_name,
krb5_boolean is_as_req)
{
/* check client */
if (client != NULL) {
if(client != NULL) {
/* check client */
if (client->flags.invalid) {
kdc_log(0, "Client (%s) has invalid bit set", client_name);
return KRB5KDC_ERR_POLICY;
}
if(!client->flags.client){
kdc_log(0, "Principal may not act as client -- %s",
client_name);
return KRB5KDC_ERR_POLICY;
}
if (client->valid_start && *client->valid_start > kdc_time) {
kdc_log(0, "Client not yet valid -- %s", client_name);
return KRB5KDC_ERR_CLIENT_NOTYET;
}
if (client->valid_end && *client->valid_end < kdc_time) {
kdc_log(0, "Client expired -- %s", client_name);
return KRB5KDC_ERR_NAME_EXP;
}
if (client->pw_end && *client->pw_end < kdc_time
&& !server->flags.change_pw) {
kdc_log(0, "Client's key has expired -- %s", client_name);
@@ -410,17 +412,13 @@ as_rep(KDC_REQ *req,
KDCOptions f = b->kdc_options;
hdb_entry *client = NULL, *server = NULL;
krb5_enctype cetype, setype;
#ifndef KTYPE_IS_ETYPE
krb5_keytype sess_ktype;
#else
krb5_enctype sess_ktype;
#endif
EncTicketPart et;
EncKDCRepPart ek;
krb5_principal client_princ, server_princ;
char *client_name, *server_name;
krb5_error_code ret = 0;
const char *e_text = NULL;
krb5_crypto crypto;
Key *ckey, *skey;
@@ -495,7 +493,7 @@ as_rep(KDC_REQ *req,
goto out;
}
ret = hdb_etype2key(context, client, enc_data.etype, &pa_key);
ret = hdb_enctype2key(context, client, enc_data.etype, &pa_key);
if(ret){
e_text = "No key matches pa-data";
ret = KRB5KDC_ERR_PREAUTH_FAILED;
@@ -505,10 +503,13 @@ as_rep(KDC_REQ *req,
continue;
}
krb5_crypto_init(context, &pa_key->key, 0, &crypto);
ret = krb5_decrypt_EncryptedData (context,
crypto,
KRB5_KU_PA_ENC_TIMESTAMP,
&enc_data,
&pa_key->key,
&ts_data);
krb5_crypto_destroy(context, crypto);
free_EncryptedData(&enc_data);
if(ret){
e_text = "Failed to decrypt PA-DATA";
@@ -567,7 +568,7 @@ as_rep(KDC_REQ *req,
pa->padata_value.length = 0;
pa->padata_value.data = NULL;
ret = get_pa_etype_info(&method_data, client);
ret = get_pa_etype_info(&method_data, client); /* XXX check ret */
len = length_METHOD_DATA(&method_data);
buf = malloc(len);
@@ -593,35 +594,22 @@ as_rep(KDC_REQ *req,
ret = 0;
goto out2;
}
if(context->ktype_is_etype)
ret = find_keys1(client, server, &ckey, &cetype, &skey, &setype,
&sess_ktype, b->etype.val, b->etype.len);
else
ret = find_keys2(client, server, &ckey, &cetype, &skey, &setype,
&sess_ktype, b->etype.val, b->etype.len);
ret = find_keys(client, server, &ckey, &cetype, &skey, &setype,
b->etype.val, b->etype.len);
if(ret) {
kdc_log(0, "Server/client has no support for etypes");
goto out;
}
{
char *cet, *set = NULL, *skt = NULL;
krb5_etype_to_string(context, cetype, &cet);
if(context->ktype_is_etype){
kdc_log(5, "Using %s", cet);
}else{
if(cetype != setype)
krb5_etype_to_string(context, setype, &set);
krb5_keytype_to_string(context, sess_ktype, &skt);
if(set)
kdc_log(5, "Using %s/%s/%s", cet, set, skt);
else
kdc_log(5, "Using %s/%s", cet, skt);
}
free(skt);
free(set);
char *cet;
char *set;
krb5_enctype_to_string(context, cetype, &cet);
krb5_enctype_to_string(context, setype, &set);
kdc_log(5, "Using %s/%s", cet, set);
free(cet);
free(set);
}
@@ -678,13 +666,7 @@ as_rep(KDC_REQ *req,
goto out;
}
if(context->ktype_is_etype) {
krb5_keytype kt;
ret = krb5_etype_to_keytype(context, sess_ktype, &kt);
krb5_generate_random_keyblock(context, kt, &et.key);
et.key.keytype = sess_ktype;
}else
krb5_generate_random_keyblock(context, sess_ktype, &et.key);
krb5_generate_random_keyblock(context, setype, &et.key);
copy_PrincipalName(b->cname, &et.cname);
copy_Realm(&b->realm, &et.crealm);
@@ -774,12 +756,12 @@ as_rep(KDC_REQ *req,
ek.nonce = b->nonce;
if (client->valid_end || client->pw_end) {
ALLOC(ek.key_expiration);
if (client->valid_end)
if (client->valid_end) {
if (client->pw_end)
*ek.key_expiration = min(*client->valid_end, *client->pw_end);
else
*ek.key_expiration = *client->valid_end;
else
} else
*ek.key_expiration = *client->pw_end;
} else
ek.key_expiration = NULL;
@@ -803,7 +785,7 @@ as_rep(KDC_REQ *req,
set_salt_padata (&rep.padata, ckey->salt);
ret = encode_reply(&rep, &et, &ek, setype, server->kvno, &skey->key,
cetype, client->kvno, &ckey->key, reply);
client->kvno, &ckey->key, reply);
free_EncTicketPart(&et);
free_EncKDCRepPart(&ek);
free_AS_REP(&rep);
@@ -1017,21 +999,16 @@ tgs_make_reply(KDC_REQ_BODY *b,
EncTicketPart et;
KDCOptions f = b->kdc_options;
krb5_error_code ret;
krb5_enctype setype;
krb5_enctype etype;
Key *skey;
EncryptionKey *ekey;
#ifndef KTYPE_IS_ETYPE
krb5_keytype sess_ktype;
#else
krb5_enctype sess_ktype;
#endif
if(adtkt) {
int i;
krb5_keytype kt;
ekey = &adtkt->key;
for(i = 0; i < b->etype.len; i++){
ret = krb5_etype_to_keytype(context, b->etype.val[i], &kt);
ret = krb5_enctype_to_keytype(context, b->etype.val[i], &kt);
if(ret)
continue;
if(adtkt->key.keytype == kt)
@@ -1039,18 +1016,10 @@ tgs_make_reply(KDC_REQ_BODY *b,
}
if(i == b->etype.len)
return KRB5KDC_ERR_ETYPE_NOSUPP;
setype = b->etype.val[i];
if(context->ktype_is_etype)
sess_ktype = b->etype.val[i];
else
sess_ktype = kt;
etype = b->etype.val[i];
}else{
if(context->ktype_is_etype)
ret = find_keys1(NULL, server, NULL, NULL, &skey, &setype,
&sess_ktype, b->etype.val, b->etype.len);
else
ret = find_keys2(NULL, server, NULL, NULL, &skey, &setype,
&sess_ktype, b->etype.val, b->etype.len);
ret = find_keys(NULL, server, NULL, NULL, &skey, &etype,
b->etype.val, b->etype.len);
if(ret) {
kdc_log(0, "Server has no support for etypes");
return ret;
@@ -1146,13 +1115,7 @@ tgs_make_reply(KDC_REQ_BODY *b,
/* XXX Check enc-authorization-data */
et.authorization_data = auth_data;
if(context->ktype_is_etype) {
krb5_keytype kt;
ret = krb5_etype_to_keytype(context, sess_ktype, &kt);
krb5_generate_random_keyblock(context, kt, &et.key);
et.key.keytype = sess_ktype;
}else
krb5_generate_random_keyblock(context, sess_ktype, &et.key);
krb5_generate_random_keyblock(context, etype, &et.key);
et.crealm = tgt->crealm;
et.cname = tgt->cname;
@@ -1179,8 +1142,8 @@ tgs_make_reply(KDC_REQ_BODY *b,
CAST session key. Should the DES3 etype be added to the
etype list, even if we don't want a session key with
DES3? */
ret = encode_reply(&rep, &et, &ek, setype, adtkt ? 0 : server->kvno, ekey,
cetype, 0, &tgt->key, reply);
ret = encode_reply(&rep, &et, &ek, etype, adtkt ? 0 : server->kvno, ekey,
0, &tgt->key, reply);
out:
free_TGS_REP(&rep);
free_TransitedEncoding(&et.transited);
@@ -1196,12 +1159,14 @@ out:
static krb5_error_code
tgs_check_authenticator(krb5_auth_context ac,
KDC_REQ_BODY *b, krb5_keyblock *key)
KDC_REQ_BODY *b,
krb5_keyblock *key)
{
krb5_authenticator auth;
size_t len;
unsigned char buf[8192];
krb5_error_code ret;
krb5_crypto crypto;
krb5_auth_getauthenticator(context, ac, &auth);
if(auth->cksum == NULL){
@@ -1215,10 +1180,10 @@ tgs_check_authenticator(krb5_auth_context ac,
*/
if (
#if 0
!krb5_checksum_is_keyed(auth->cksum->cksumtype)
!krb5_checksum_is_keyed(context, auth->cksum->cksumtype)
||
#endif
!krb5_checksum_is_collision_proof(auth->cksum->cksumtype)) {
!krb5_checksum_is_collision_proof(context, auth->cksum->cksumtype)) {
kdc_log(0, "Bad checksum type in authenticator: %d",
auth->cksum->cksumtype);
ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
@@ -1233,9 +1198,14 @@ tgs_check_authenticator(krb5_auth_context ac,
krb5_get_err_text(context, ret));
goto out;
}
ret = krb5_verify_checksum(context, buf + sizeof(buf) - len, len,
key,
krb5_crypto_init(context, key, 0, &crypto);
ret = krb5_verify_checksum(context,
crypto,
KRB5_KU_TGS_REQ_AUTH_CKSUM,
buf + sizeof(buf) - len,
len,
auth->cksum);
krb5_crypto_destroy(context, crypto);
if(ret){
kdc_log(0, "Failed to verify checksum: %s",
krb5_get_err_text(context, ret));
@@ -1282,6 +1252,7 @@ tgs_rep2(KDC_REQ_BODY *b,
krb5_ticket *ticket = NULL;
krb5_flags ap_req_options;
const char *e_text = NULL;
krb5_crypto crypto;
hdb_entry *krbtgt = NULL;
EncTicketPart *tgt;
@@ -1335,10 +1306,10 @@ tgs_rep2(KDC_REQ_BODY *b,
goto out2;
}
ret = hdb_etype2key(context, krbtgt, ap_req.ticket.enc_part.etype, &tkey);
ret = hdb_enctype2key(context, krbtgt, ap_req.ticket.enc_part.etype, &tkey);
if(ret){
char *str;
krb5_etype_to_string(context, ap_req.ticket.enc_part.etype, &str);
krb5_enctype_to_string(context, ap_req.ticket.enc_part.etype, &str);
kdc_log(0, "No server key found for %s", str);
free(str);
ret = KRB5KRB_AP_ERR_BADKEYVER;
@@ -1390,10 +1361,13 @@ tgs_rep2(KDC_REQ_BODY *b,
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
goto out2;
}
krb5_crypto_init(context, subkey, 0, &crypto);
ret = krb5_decrypt_EncryptedData (context,
crypto,
KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY,
b->enc_authorization_data,
subkey,
&ad);
krb5_crypto_destroy(context, crypto);
if(ret){
kdc_log(0, "Failed to decrypt enc-authorization-data");
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
@@ -1455,7 +1429,7 @@ tgs_rep2(KDC_REQ_BODY *b,
ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
goto out;
}
ret = hdb_etype2key(context, uu, t->enc_part.etype, &tkey);
ret = hdb_enctype2key(context, uu, t->enc_part.etype, &tkey);
if(ret){
ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
goto out;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -71,18 +71,23 @@ int main(int argc, char **argv)
krb5_errx(context, 0, "%s", heimdal_version);
key.keytype = KEYTYPE_DES;
key.keyvalue.length = sizeof(des_cblock);
key.keyvalue.data = malloc(key.keyvalue.length);
key.keytype = ETYPE_DES_CBC_MD5; /* XXX */
if(v4_keyfile){
f = fopen(v4_keyfile, "r");
if(f == NULL)
krb5_err(context, 1, errno, "fopen(%s)", v4_keyfile);
key.keyvalue.length = sizeof(des_cblock);
key.keyvalue.data = malloc(key.keyvalue.length);
fread(key.keyvalue.data, 1, key.keyvalue.length, f);
fclose(f);
}else{
krb5_salt salt;
salt.salttype = KRB5_PW_SALT;
/* XXX better value? */
salt.saltvalue.data = NULL;
salt.saltvalue.length = 0;
des_read_pw_string(buf, sizeof(buf), "Master key: ", 1);
des_string_to_key(buf, key.keyvalue.data);
krb5_string_to_key_salt(context, key.keytype, buf, salt, &key);
}
#ifdef HAVE_UMASK

View File

@@ -47,7 +47,7 @@ int afs;
char *principal;
char *cell;
char *password;
char *keytype_str = "des";
char *keytype_str = "des-cbc-md5";
int version;
int help;
@@ -73,12 +73,15 @@ usage(int status)
}
static void
tokey(krb5_context context, const char *password, krb5_data *salt,
krb5_keytype keytype, const char *label)
tokey(krb5_context context,
krb5_enctype enctype,
const char *password,
krb5_salt salt,
const char *label)
{
int i;
krb5_keyblock key;
krb5_string_to_key(password, salt, keytype, &key);
krb5_string_to_key_salt(context, enctype, password, salt, &key);
printf("%s: ", label);
for(i = 0; i < key.keyvalue.length; i++)
printf("%02x", ((unsigned char*)key.keyvalue.data)[i]);
@@ -91,10 +94,10 @@ main(int argc, char **argv)
{
krb5_context context;
krb5_principal princ;
krb5_data salt;
krb5_salt salt;
int optind;
char buf[1024];
krb5_keytype keytype;
krb5_enctype etype;
krb5_error_code ret;
set_progname(argv[0]);
@@ -120,11 +123,21 @@ main(int argc, char **argv)
if(!version5 && !version4 && !afs)
version5 = 1;
ret = krb5_string_to_keytype(context, keytype_str, &keytype);
ret = krb5_string_to_enctype(context, keytype_str, &etype);
#if 0
if(ret) {
krb5_keytype keytype;
ret = krb5_string_to_keytype(context, keytype_str, &keytype);
ret = krb5_keytype_to_enctype(context, keytype, &etype);
}
#endif
if(ret)
krb5_err(context, 1, ret, "%s", keytype);
krb5_err(context, 1, ret, "%s", keytype_str);
if(keytype != KEYTYPE_DES && (afs || version4))
if((etype != ETYPE_DES_CBC_CRC &&
etype != ETYPE_DES_CBC_MD4 &&
etype != ETYPE_DES_CBC_MD5) &&
(afs || version4))
krb5_errx(context, 1,
"DES is the only valid keytype for AFS and Kerberos 4");
@@ -150,20 +163,21 @@ main(int argc, char **argv)
if(version5){
krb5_parse_name(context, principal, &princ);
salt.length = 0;
salt.data = NULL;
krb5_get_salt(princ, &salt);
tokey(context, password, &salt, keytype, "Kerberos v5 key");
krb5_get_pw_salt(context, princ, &salt);
tokey(context, etype, password, salt, "Kerberos v5 key");
krb5_free_salt(context, salt);
}
if(version4){
salt.length = 0;
salt.data = NULL;
tokey(context, password, &salt, KEYTYPE_DES, "Kerberos v4 key");
salt.salttype = KRB5_PW_SALT;
salt.saltvalue.length = 0;
salt.saltvalue.data = NULL;
tokey(context, ETYPE_DES_CBC_MD5, password, salt, "Kerberos v4 key");
}
if(afs){
salt.length = strlen(cell);
salt.data = cell;
tokey(context, password, &salt, KEYTYPE_DES_AFS3, "AFS key");
salt.salttype = KRB5_AFS3_SALT;
salt.saltvalue.length = strlen(cell);
salt.saltvalue.data = cell;
tokey(context, ETYPE_DES_CBC_MD5, password, salt, "AFS key");
}
return 0;
}