From: Theodore Tso Date: Mon, 14 Nov 1994 21:35:28 +0000 (+0000) Subject: get_in_tkt (krb5_get_in_tkt): Set the encryption type of the session X-Git-Tag: krb5-1.0-beta5~989 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=376c6cbaa3d42bb4348ec0e2d2e8511c10c2413d;p=krb5.git get_in_tkt (krb5_get_in_tkt): Set the encryption type of the session keyblock to be the type used to encrypt the ticket. mk_cred.c, rd_cred.c: New routines for forwarding credentials --- note that the API is still subject to change! (Moved from telnet and bsd directories) git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@4659 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/lib/krb5/krb/ChangeLog b/src/lib/krb5/krb/ChangeLog index e7276c98a..e8cf4de6e 100644 --- a/src/lib/krb5/krb/ChangeLog +++ b/src/lib/krb5/krb/ChangeLog @@ -1,3 +1,9 @@ +Fri Nov 11 01:20:22 1994 Theodore Y. Ts'o (tytso@dcl) + + * get_in_tkt (krb5_get_in_tkt): Set the encryption type of the + session keyblock to be the type used to encrypt the + ticket. + Thu Nov 10 23:56:43 1994 Theodore Y. Ts'o (tytso@dcl) * rd_rep.c (krb5_rd_rep): Set the encryption type in diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in index d647f1e12..2a278bc62 100644 --- a/src/lib/krb5/krb/Makefile.in +++ b/src/lib/krb5/krb/Makefile.in @@ -40,6 +40,7 @@ OBJS= addr_comp.o \ in_tkt_sky.o \ kdc_rep_dc.o \ krbconfig.o \ + mk_cred.o \ mk_error.o \ mk_priv.o \ mk_rep.o \ @@ -50,6 +51,7 @@ OBJS= addr_comp.o \ pr_to_salt.o \ preauth.o \ princ_comp.o \ + rd_cred.o \ rd_error.o \ rd_priv.o \ rd_rep.o \ @@ -100,6 +102,7 @@ SRCS= $(srcdir)/addr_comp.c \ $(srcdir)/in_tkt_sky.c \ $(srcdir)/kdc_rep_dc.c \ $(srcdir)/krbconfig.c \ + $(srcdir)/mk_cred.c \ $(srcdir)/mk_error.c \ $(srcdir)/mk_priv.c \ $(srcdir)/mk_rep.c \ @@ -110,6 +113,7 @@ SRCS= $(srcdir)/addr_comp.c \ $(srcdir)/pr_to_salt.c \ $(srcdir)/preauth.c \ $(srcdir)/princ_comp.c \ + $(srcdir)/rd_cred.c \ $(srcdir)/rd_error.c \ $(srcdir)/rd_priv.c \ $(srcdir)/rd_rep.c \ diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c index f9366a6ab..90e200c76 100644 --- a/src/lib/krb5/krb/get_in_tkt.c +++ b/src/lib/krb5/krb/get_in_tkt.c @@ -279,6 +279,7 @@ OLDDECLARG(krb5_kdc_rep **, ret_as_reply) if (retval = krb5_copy_keyblock_contents(as_reply->enc_part2->session, &creds->keyblock)) goto cleanup; + creds->keyblock.etype = as_reply->ticket->enc_part.etype; creds->times = as_reply->enc_part2->times; creds->is_skey = FALSE; /* this is an AS_REQ, so cannot diff --git a/src/lib/krb5/krb/mk_cred.c b/src/lib/krb5/krb/mk_cred.c new file mode 100644 index 000000000..4422bcdfb --- /dev/null +++ b/src/lib/krb5/krb/mk_cred.c @@ -0,0 +1,174 @@ +/* + * lib/krb5/krb/mk_cred.c + * + * Copyright 1994 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * krb5_mk_cred() + */ + + +/* XXX This API is going to change; what's here isn't general enough! */ + +#include +#include +#include +#include + +/* Create asn.1 encoded KRB-CRED message from the kdc reply. */ +krb5_error_code +mk_cred(dec_rep, etype, key, sender_addr, recv_addr, outbuf) +krb5_kdc_rep *dec_rep; +krb5_enctype etype; +krb5_keyblock *key; +krb5_address *sender_addr; +krb5_address *recv_addr; +krb5_data *outbuf; +{ + krb5_error_code retval; + krb5_encrypt_block eblock; + krb5_cred ret_cred; + krb5_cred_enc_part cred_enc_part; + krb5_data *scratch; + + if (!valid_etype(etype)) + return KRB5_PROG_ETYPE_NOSUPP; + + ret_cred.tickets = (krb5_ticket **) calloc(2, sizeof(*ret_cred.tickets)); + if (!ret_cred.tickets) + return ENOMEM; + ret_cred.tickets[0] = dec_rep->ticket; + ret_cred.tickets[1] = 0; + + ret_cred.enc_part.etype = etype; + ret_cred.enc_part.kvno = 0; + + cred_enc_part.ticket_info = (krb5_cred_info **) + calloc(2, sizeof(*cred_enc_part.ticket_info)); + if (!cred_enc_part.ticket_info) { + krb5_free_tickets(ret_cred.tickets); + return ENOMEM; + } + cred_enc_part.ticket_info[0] = (krb5_cred_info *) + malloc(sizeof(*cred_enc_part.ticket_info[0])); + if (!cred_enc_part.ticket_info[0]) { + krb5_free_tickets(ret_cred.tickets); + krb5_free_cred_enc_part(cred_enc_part); + return ENOMEM; + } + cred_enc_part.nonce = 0; + + if (retval = krb5_us_timeofday(&cred_enc_part.timestamp, + &cred_enc_part.usec)) + return retval; + + cred_enc_part.s_address = (krb5_address *)sender_addr; + cred_enc_part.r_address = (krb5_address *)recv_addr; + + cred_enc_part.ticket_info[0]->session = dec_rep->enc_part2->session; + cred_enc_part.ticket_info[0]->client = dec_rep->client; + cred_enc_part.ticket_info[0]->server = dec_rep->enc_part2->server; + cred_enc_part.ticket_info[0]->flags = dec_rep->enc_part2->flags; + cred_enc_part.ticket_info[0]->times = dec_rep->enc_part2->times; + cred_enc_part.ticket_info[0]->caddrs = dec_rep->enc_part2->caddrs; + + cred_enc_part.ticket_info[1] = 0; + + /* start by encoding to-be-encrypted part of the message */ + + if (retval = encode_krb5_enc_cred_part(&cred_enc_part, &scratch)) + return retval; + +#define cleanup_scratch() { (void) memset(scratch->data, 0, scratch->length); krb5_free_data(scratch); } + + /* put together an eblock for this encryption */ + + krb5_use_cstype(&eblock, etype); + ret_cred.enc_part.ciphertext.length = krb5_encrypt_size(scratch->length, + eblock.crypto_entry); + /* add padding area, and zero it */ + if (!(scratch->data = realloc(scratch->data, + ret_cred.enc_part.ciphertext.length))) { + /* may destroy scratch->data */ + krb5_xfree(scratch); + return ENOMEM; + } + memset(scratch->data + scratch->length, 0, + ret_cred.enc_part.ciphertext.length - scratch->length); + if (!(ret_cred.enc_part.ciphertext.data = + malloc(ret_cred.enc_part.ciphertext.length))) { + retval = ENOMEM; + goto clean_scratch; + } + +#define cleanup_encpart() {\ + (void) memset(ret_cred.enc_part.ciphertext.data, 0, \ + ret_cred.enc_part.ciphertext.length); \ + free(ret_cred.enc_part.ciphertext.data); \ + ret_cred.enc_part.ciphertext.length = 0; \ + ret_cred.enc_part.ciphertext.data = 0;} + + /* do any necessary key pre-processing */ + if (retval = krb5_process_key(&eblock, key)) { + goto clean_encpart; + } + +#define cleanup_prockey() {(void) krb5_finish_key(&eblock);} + + /* call the encryption routine */ + if (retval = krb5_encrypt((krb5_pointer) scratch->data, + (krb5_pointer) + ret_cred.enc_part.ciphertext.data, + scratch->length, &eblock, + 0)) { + goto clean_prockey; + } + + /* private message is now assembled-- do some cleanup */ + cleanup_scratch(); + + if (retval = krb5_finish_key(&eblock)) { + cleanup_encpart(); + return retval; + } + /* encode private message */ + if (retval = encode_krb5_cred(&ret_cred, &scratch)) { + cleanup_encpart(); + return retval; + } + + cleanup_encpart(); + + *outbuf = *scratch; + krb5_xfree(scratch); + return 0; + + clean_prockey: + cleanup_prockey(); + clean_encpart: + cleanup_encpart(); + clean_scratch: + cleanup_scratch(); + + return retval; +#undef cleanup_prockey +#undef cleanup_encpart +#undef cleanup_scratch +} + diff --git a/src/lib/krb5/krb/rd_cred.c b/src/lib/krb5/krb/rd_cred.c new file mode 100644 index 000000000..f9d7e4314 --- /dev/null +++ b/src/lib/krb5/krb/rd_cred.c @@ -0,0 +1,219 @@ +/* + * lib/krb5/krb/rd_cred.c + * + * Copyright 1994 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * krb5_rd_cred() + */ + +/* XXX This API is going to change; what's here isn't general enough! */ + +#include +#include +#include +#include + +extern krb5_deltat krb5_clockskew; +#define in_clock_skew(date) (abs((date)-currenttime) < krb5_clockskew) + +/* Decode the KRB-CRED message, and return creds */ +krb5_error_code +rd_cred(inbuf, key, creds, sender_addr, recv_addr) +const krb5_data *inbuf; +const krb5_keyblock *key; +krb5_creds *creds; /* Filled in */ +const krb5_address *sender_addr; /* optional */ +const krb5_address *recv_addr; /* optional */ +{ + krb5_error_code retval; + krb5_encrypt_block eblock; + krb5_cred *credmsg; + krb5_cred_enc_part *credmsg_enc_part; + krb5_data *scratch; + krb5_timestamp currenttime; + + if (!krb5_is_krb_cred(inbuf)) + return KRB5KRB_AP_ERR_MSG_TYPE; + + /* decode private message */ + if (retval = decode_krb5_cred(inbuf, &credmsg)) { + return retval; + } + +#define cleanup_credmsg() {(void)krb5_xfree(credmsg->enc_part.ciphertext.data); (void)krb5_xfree(credmsg);} + + if (!(scratch = (krb5_data *) malloc(sizeof(*scratch)))) { + cleanup_credmsg(); + return ENOMEM; + } + +#define cleanup_scratch() {(void)memset(scratch->data, 0, scratch->length); (void)krb5_xfree(scratch->data);} + + if (retval = encode_krb5_ticket(credmsg->tickets[0], &scratch)) { + cleanup_credmsg(); + cleanup_scratch(); + return(retval); + } + + creds->ticket = *scratch; + if (!(creds->ticket.data = malloc(scratch->length))) { + krb5_xfree(creds->ticket.data); + return ENOMEM; + } + memcpy((char *)creds->ticket.data, (char *) scratch->data, scratch->length); + + cleanup_scratch(); + + if (!valid_etype(credmsg->enc_part.etype)) { + cleanup_credmsg(); + return KRB5_PROG_ETYPE_NOSUPP; + } + + /* put together an eblock for this decryption */ + + krb5_use_cstype(&eblock, credmsg->enc_part.etype); + scratch->length = credmsg->enc_part.ciphertext.length; + + if (!(scratch->data = malloc(scratch->length))) { + cleanup_credmsg(); + return ENOMEM; + } + + /* do any necessary key pre-processing */ + if (retval = krb5_process_key(&eblock, key)) { + cleanup_credmsg(); + cleanup_scratch(); + return retval; + } + +#define cleanup_prockey() {(void) krb5_finish_key(&eblock);} + + /* call the decryption routine */ + if (retval = krb5_decrypt((krb5_pointer) credmsg->enc_part.ciphertext.data, + (krb5_pointer) scratch->data, + scratch->length, &eblock, + 0)) { + cleanup_credmsg(); + cleanup_scratch(); + cleanup_prockey(); + return retval; + } + + /* cred message is now decrypted -- do some cleanup */ + + cleanup_credmsg(); + + if (retval = krb5_finish_key(&eblock)) { + cleanup_scratch(); + return retval; + } + + /* now decode the decrypted stuff */ + if (retval = decode_krb5_enc_cred_part(scratch, &credmsg_enc_part)) { + cleanup_scratch(); + return retval; + } + cleanup_scratch(); + +#define cleanup_mesg() {(void)krb5_xfree(credmsg_enc_part);} + + if (retval = krb5_timeofday(¤ttime)) { + cleanup_mesg(); + return retval; + } + if (!in_clock_skew(credmsg_enc_part->timestamp)) { + cleanup_mesg(); + return KRB5KRB_AP_ERR_SKEW; + } + + if (sender_addr && credmsg_enc_part->s_address && + !krb5_address_compare(sender_addr, + credmsg_enc_part->s_address)) { + cleanup_mesg(); + return KRB5KRB_AP_ERR_BADADDR; + } + if (recv_addr && credmsg_enc_part->r_address && + !krb5_address_compare(recv_addr, + credmsg_enc_part->r_address)) { + cleanup_mesg(); + return KRB5KRB_AP_ERR_BADADDR; + } + + if (credmsg_enc_part->r_address) { + krb5_address **our_addrs; + + if (retval = krb5_os_localaddr(&our_addrs)) { + cleanup_mesg(); + return retval; + } + if (!krb5_address_search(credmsg_enc_part->r_address, + our_addrs)) { + krb5_free_addresses(our_addrs); + cleanup_mesg(); + return KRB5KRB_AP_ERR_BADADDR; + } + krb5_free_addresses(our_addrs); + } + + if (retval = krb5_copy_principal(credmsg_enc_part->ticket_info[0]->client, + &creds->client)) { + return(retval); + } + + if (retval = krb5_copy_principal(credmsg_enc_part->ticket_info[0]->server, + &creds->server)) { + return(retval); + } + + if (retval = + krb5_copy_keyblock_contents(credmsg_enc_part->ticket_info[0]->session, + &creds->keyblock)) { + return(retval); + } + creds->keyblock.magic = KV5M_KEYBLOCK; + creds->keyblock.etype = credmsg->tickets[0]->enc_part.etype; + +#undef clean +#define clean() {\ + memset((char *)creds->keyblock.contents, 0, creds->keyblock.length);} + + creds->times = credmsg_enc_part->ticket_info[0]->times; + creds->is_skey = FALSE; + creds->ticket_flags = credmsg_enc_part->ticket_info[0]->flags; + + if (retval = krb5_copy_addresses(credmsg_enc_part->ticket_info[0]->caddrs, + &creds->addresses)) { + clean(); + return(retval); + } + + creds->second_ticket.length = 0; + + creds->authdata = 0; + + cleanup_mesg(); + return 0; +#undef clean +#undef cleanup_credmsg +#undef cleanup_scratch +#undef cleanup_prockey +#undef cleanup_mesg +} +