From 59117f0b7867979952d9c1c89b055cd0c9578fb6 Mon Sep 17 00:00:00 2001 From: John Kohl Date: Fri, 6 Apr 1990 15:38:37 +0000 Subject: [PATCH] not yet tested git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@471 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/krb/rd_safe.c | 145 +++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 src/lib/krb5/krb/rd_safe.c diff --git a/src/lib/krb5/krb/rd_safe.c b/src/lib/krb5/krb/rd_safe.c new file mode 100644 index 000000000..4864cc2b3 --- /dev/null +++ b/src/lib/krb5/krb/rd_safe.c @@ -0,0 +1,145 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * krb5_rd_safe() + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_rd_safe_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include +#include + +#include +#include +#include +#include + +extern krb5_deltat krb5_clockskew; +#define in_clock_skew(date) (abs((date)-currenttime) < krb5_clockskew) + +/* + parses a KRB_SAFE message from inbuf, placing the integrity-protected user + data in *outbuf. + + key specifies the key to be used for decryption of the message. + + sender_addr and recv_addr specify the full addresses (host and port) of + the sender and receiver. + + outbuf points to allocated storage which the caller should free when finished. + + returns system errors, integrity errors + */ +krb5_error_code +krb5_rd_safe(inbuf, key, sender_addr, recv_addr, outbuf) +krb5_data *inbuf; +krb5_keyblock *key; +krb5_fulladdr *sender_addr; +krb5_fulladdr *recv_addr; +krb5_data *outbuf; +{ + krb5_error_code retval; + krb5_safe *message; + krb5_ui_2 computed_direction; + krb5_checksum our_cksum, *his_cksum; + krb5_octet zero_octet = 0; + krb5_data *scratch; + krb5_timestamp currenttime; + + if (retval = decode_krb5_safe(inbuf, &message)) + return retval; + +#define cleanup() krb5_free_safe(message) + + if (!valid_cksumtype(message->checksum->checksum_type)) + return KRB5_PROG_SUMTYPE_NOSUPP; + + /* length bounds check XXX ?? how */ + + if (sender_addr && !krb5_address_search(sender_addr->address, + message->addresses)) { + cleanup(); + return KRB5KRB_AP_ERR_BADADDR; + } + + if (retval = krb5_timeofday(¤ttime)) { + cleanup(); + return retval; + } + if (!in_clock_skew(message->timestamp)) { + cleanup(); + return KRB5KRB_AP_ERR_SKEW; + } + + /* replay detection goes here... XXX */ + computed_direction = (krb5_fulladdr_order(sender_addr, recv_addr) > 0) ? + MSEC_DIRBIT : 0; + /* what if sender_addr == 0 ?????*/ + if (computed_direction != message->msec & MSEC_DIRBIT) { + cleanup(); + return KRB5KRB_AP_ERR_REPEAT; /* XXX */ + } + + /* verify the checksum */ + /* to do the checksum stuff, we need to re-encode the message with a + zero-length zero-type checksum, then checksum the encoding, and verify. + */ + his_cksum = message->checksum; + + our_cksum.checksum_type = 0; + our_cksum.length = 0; + our_cksum.contents = &zero_octet; + + message->checksum = &our_cksum; + + if (retval = encode_krb5_safe(&message, &scratch)) { + message->checksum = his_cksum; + cleanup(); + return retval; + } + + retval = (*(krb5_cksumarray[his_cksum->checksum_type]-> + sum_func))(scratch->data, + 0, /* XXX? */ + (krb5_pointer) key->contents, + scratch->length, + key->length, + &our_cksum); + (void) bzero((char *)scratch->data, scratch->length); + krb5_free_data(scratch); + + if (retval) { + cleanup(); + return retval; + } + +#undef cleanup +#define cleanup() {krb5_free_safe(message); xfree(our_cksum.contents);} + + if (our_cksum.length != his_cksum->length || + bcmp((char *)our_cksum.contents, (char *)his_cksum->contents, + our_cksum.length)) { + cleanup(); + return KRB5KRB_AP_ERR_MODIFIED; + } + + *outbuf = message->user_data; + + xfree(our_cksum.contents); + if (message->addresses) + krb5_free_address(message->addresses); + krb5_free_checksum(his_cksum); + xfree(message); + + return 0; +} -- 2.26.2