1/* 2 * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by the Kungliga Tekniska 20 * H�gskolan and its contributors. 21 * 22 * 4. Neither the name of the Institute nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 */ 38 39#include "sasl_mac_krb_locl.h" 40 41RCSID("$Id: rd_safe.c,v 1.4 2005/01/10 19:10:47 snsimon Exp $"); 42 43/* application include files */ 44#include "krb-archaeology.h" 45 46/* Generate two checksums in the given byteorder of the data, one 47 * new-form and one old-form. It has to be done this way to be 48 * compatible with the old version of des_quad_cksum. 49 */ 50 51/* des_quad_chsum-type; 0 == unknown, 1 == new PL10++, 2 == old */ 52int dqc_type = DES_QUAD_DEFAULT; 53 54void 55fixup_quad_cksum(void *start, size_t len, des_cblock *key, 56 void *new_checksum, void *old_checksum, int little) 57{ 58 des_quad_cksum((des_cblock*)start, (des_cblock*)new_checksum, len, 2, key); 59 if(HOST_BYTE_ORDER){ 60 if(little){ 61 memcpy(old_checksum, new_checksum, 16); 62 }else{ 63 u_int32_t *tmp = (u_int32_t*)new_checksum; 64 memcpy(old_checksum, new_checksum, 16); 65 swap_u_16(old_checksum); 66 swap_u_long(tmp[0]); 67 swap_u_long(tmp[1]); 68 swap_u_long(tmp[2]); 69 swap_u_long(tmp[3]); 70 } 71 }else{ 72 if(little){ 73 u_int32_t *tmp = (u_int32_t*)new_checksum; 74 swap_u_long(tmp[0]); 75 swap_u_long(tmp[1]); 76 swap_u_long(tmp[2]); 77 swap_u_long(tmp[3]); 78 memcpy(old_checksum, new_checksum, 16); 79 }else{ 80 u_int32_t tmp[4]; 81 tmp[0] = ((u_int32_t*)new_checksum)[3]; 82 tmp[1] = ((u_int32_t*)new_checksum)[2]; 83 tmp[2] = ((u_int32_t*)new_checksum)[1]; 84 tmp[3] = ((u_int32_t*)new_checksum)[0]; 85 memcpy(old_checksum, tmp, 16); 86 } 87 } 88} 89 90/* 91 * krb_rd_safe() checks the integrity of an AUTH_MSG_SAFE message. 92 * Given the message received, "in", the length of that message, 93 * "in_length", the "key" to compute the checksum with, and the 94 * network addresses of the "sender" and "receiver" of the message, 95 * krb_rd_safe() returns RD_AP_OK if message is okay, otherwise 96 * some error code. 97 * 98 * The message data retrieved from "in" is returned in the structure 99 * "m_data". The pointer to the application data (m_data->app_data) 100 * refers back to the appropriate place in "in". 101 * 102 * See the file "mk_safe.c" for the format of the AUTH_MSG_SAFE 103 * message. The structure containing the extracted message 104 * information, MSG_DAT, is defined in "krb.h". 105 */ 106 107int32_t 108krb_rd_safe(void *in, u_int32_t in_length, des_cblock *key, 109 struct sockaddr_in *sender, struct sockaddr_in *receiver, 110 MSG_DAT *m_data) 111{ 112 unsigned char *p = (unsigned char*)in, *start; 113 114 unsigned char pvno, type; 115 int little_endian; 116 struct timeval tv; 117 u_int32_t src_addr; 118 int delta_t; 119 120 121 pvno = *p++; 122 if(pvno != KRB_PROT_VERSION) 123 return RD_AP_VERSION; 124 125 type = *p++; 126 little_endian = type & 1; 127 type &= ~1; 128 if(type != AUTH_MSG_SAFE) 129 return RD_AP_MSG_TYPE; 130 131 start = p; 132 133 p += krb_get_int(p, &m_data->app_length, 4, little_endian); 134 135 if(m_data->app_length + 31 > in_length) 136 return RD_AP_MODIFIED; 137 138 m_data->app_data = p; 139 140 p += m_data->app_length; 141 142 m_data->time_5ms = *p++; 143 144 p += krb_get_address(p, &src_addr); 145 146 if (!krb_equiv(src_addr, sender->sin_addr.s_addr)) 147 return RD_AP_BADD; 148 149 p += krb_get_int(p, (u_int32_t *)&m_data->time_sec, 4, little_endian); 150 m_data->time_sec = lsb_time(m_data->time_sec, sender, receiver); 151 152 gettimeofday(&tv, NULL); 153 154 delta_t = abs((int)((long) tv.tv_sec - m_data->time_sec)); 155 if (delta_t > CLOCK_SKEW) return RD_AP_TIME; 156 157 /* 158 * caller must check timestamps for proper order and replays, since 159 * server might have multiple clients each with its own timestamps 160 * and we don't assume tightly synchronized clocks. 161 */ 162 163 { 164 unsigned char new_checksum[16]; 165 unsigned char old_checksum[16]; 166 fixup_quad_cksum(start, p - start, key, 167 new_checksum, old_checksum, little_endian); 168 if((dqc_type == DES_QUAD_GUESS || dqc_type == DES_QUAD_NEW) && 169 memcmp(new_checksum, p, 16) == 0) 170 dqc_type = DES_QUAD_NEW; 171 else if((dqc_type == DES_QUAD_GUESS || dqc_type == DES_QUAD_OLD) && 172 memcmp(old_checksum, p, 16) == 0) 173 dqc_type = DES_QUAD_OLD; 174 else 175 return RD_AP_MODIFIED; 176 } 177 return KSUCCESS; 178} 179