1*b528cefcSMark Murray /* 2*b528cefcSMark Murray * Copyright (c) 1997, 1998 Kungliga Tekniska H�gskolan 3*b528cefcSMark Murray * (Royal Institute of Technology, Stockholm, Sweden). 4*b528cefcSMark Murray * All rights reserved. 5*b528cefcSMark Murray * 6*b528cefcSMark Murray * Redistribution and use in source and binary forms, with or without 7*b528cefcSMark Murray * modification, are permitted provided that the following conditions 8*b528cefcSMark Murray * are met: 9*b528cefcSMark Murray * 10*b528cefcSMark Murray * 1. Redistributions of source code must retain the above copyright 11*b528cefcSMark Murray * notice, this list of conditions and the following disclaimer. 12*b528cefcSMark Murray * 13*b528cefcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright 14*b528cefcSMark Murray * notice, this list of conditions and the following disclaimer in the 15*b528cefcSMark Murray * documentation and/or other materials provided with the distribution. 16*b528cefcSMark Murray * 17*b528cefcSMark Murray * 3. Neither the name of the Institute nor the names of its contributors 18*b528cefcSMark Murray * may be used to endorse or promote products derived from this software 19*b528cefcSMark Murray * without specific prior written permission. 20*b528cefcSMark Murray * 21*b528cefcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22*b528cefcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23*b528cefcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24*b528cefcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25*b528cefcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26*b528cefcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27*b528cefcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28*b528cefcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29*b528cefcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30*b528cefcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31*b528cefcSMark Murray * SUCH DAMAGE. 32*b528cefcSMark Murray */ 33*b528cefcSMark Murray 34*b528cefcSMark Murray #include <krb5_locl.h> 35*b528cefcSMark Murray 36*b528cefcSMark Murray RCSID("$Id: rd_priv.c,v 1.22 1999/12/02 17:05:12 joda Exp $"); 37*b528cefcSMark Murray 38*b528cefcSMark Murray krb5_error_code 39*b528cefcSMark Murray krb5_rd_priv(krb5_context context, 40*b528cefcSMark Murray krb5_auth_context auth_context, 41*b528cefcSMark Murray const krb5_data *inbuf, 42*b528cefcSMark Murray krb5_data *outbuf, 43*b528cefcSMark Murray /*krb5_replay_data*/ void *outdata) 44*b528cefcSMark Murray { 45*b528cefcSMark Murray krb5_error_code ret; 46*b528cefcSMark Murray KRB_PRIV priv; 47*b528cefcSMark Murray EncKrbPrivPart part; 48*b528cefcSMark Murray size_t len; 49*b528cefcSMark Murray krb5_data plain; 50*b528cefcSMark Murray krb5_keyblock *key; 51*b528cefcSMark Murray krb5_crypto crypto; 52*b528cefcSMark Murray 53*b528cefcSMark Murray memset(&priv, 0, sizeof(priv)); 54*b528cefcSMark Murray ret = decode_KRB_PRIV (inbuf->data, inbuf->length, &priv, &len); 55*b528cefcSMark Murray if (ret) 56*b528cefcSMark Murray goto failure; 57*b528cefcSMark Murray if (priv.pvno != 5) { 58*b528cefcSMark Murray ret = KRB5KRB_AP_ERR_BADVERSION; 59*b528cefcSMark Murray goto failure; 60*b528cefcSMark Murray } 61*b528cefcSMark Murray if (priv.msg_type != krb_priv) { 62*b528cefcSMark Murray ret = KRB5KRB_AP_ERR_MSG_TYPE; 63*b528cefcSMark Murray goto failure; 64*b528cefcSMark Murray } 65*b528cefcSMark Murray 66*b528cefcSMark Murray /* XXX - Is this right? */ 67*b528cefcSMark Murray 68*b528cefcSMark Murray if (auth_context->local_subkey) 69*b528cefcSMark Murray key = auth_context->local_subkey; 70*b528cefcSMark Murray else if (auth_context->remote_subkey) 71*b528cefcSMark Murray key = auth_context->remote_subkey; 72*b528cefcSMark Murray else 73*b528cefcSMark Murray key = auth_context->keyblock; 74*b528cefcSMark Murray 75*b528cefcSMark Murray krb5_crypto_init(context, key, 0, &crypto); 76*b528cefcSMark Murray ret = krb5_decrypt_EncryptedData(context, 77*b528cefcSMark Murray crypto, 78*b528cefcSMark Murray KRB5_KU_KRB_PRIV, 79*b528cefcSMark Murray &priv.enc_part, 80*b528cefcSMark Murray &plain); 81*b528cefcSMark Murray krb5_crypto_destroy(context, crypto); 82*b528cefcSMark Murray if (ret) 83*b528cefcSMark Murray goto failure; 84*b528cefcSMark Murray 85*b528cefcSMark Murray ret = decode_EncKrbPrivPart (plain.data, plain.length, &part, &len); 86*b528cefcSMark Murray krb5_data_free (&plain); 87*b528cefcSMark Murray if (ret) 88*b528cefcSMark Murray goto failure; 89*b528cefcSMark Murray 90*b528cefcSMark Murray /* check sender address */ 91*b528cefcSMark Murray 92*b528cefcSMark Murray if (part.s_address 93*b528cefcSMark Murray && auth_context->remote_address 94*b528cefcSMark Murray && !krb5_address_compare (context, 95*b528cefcSMark Murray auth_context->remote_address, 96*b528cefcSMark Murray part.s_address)) { 97*b528cefcSMark Murray ret = KRB5KRB_AP_ERR_BADADDR; 98*b528cefcSMark Murray goto failure_part; 99*b528cefcSMark Murray } 100*b528cefcSMark Murray 101*b528cefcSMark Murray /* check receiver address */ 102*b528cefcSMark Murray 103*b528cefcSMark Murray if (part.r_address 104*b528cefcSMark Murray && auth_context->local_address 105*b528cefcSMark Murray && !krb5_address_compare (context, 106*b528cefcSMark Murray auth_context->local_address, 107*b528cefcSMark Murray part.r_address)) { 108*b528cefcSMark Murray ret = KRB5KRB_AP_ERR_BADADDR; 109*b528cefcSMark Murray goto failure_part; 110*b528cefcSMark Murray } 111*b528cefcSMark Murray 112*b528cefcSMark Murray /* check timestamp */ 113*b528cefcSMark Murray if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_TIME) { 114*b528cefcSMark Murray int32_t sec; 115*b528cefcSMark Murray 116*b528cefcSMark Murray krb5_timeofday (context, &sec); 117*b528cefcSMark Murray if (part.timestamp == NULL || 118*b528cefcSMark Murray part.usec == NULL || 119*b528cefcSMark Murray abs(*part.timestamp - sec) > context->max_skew) { 120*b528cefcSMark Murray ret = KRB5KRB_AP_ERR_SKEW; 121*b528cefcSMark Murray goto failure_part; 122*b528cefcSMark Murray } 123*b528cefcSMark Murray } 124*b528cefcSMark Murray 125*b528cefcSMark Murray /* XXX - check replay cache */ 126*b528cefcSMark Murray 127*b528cefcSMark Murray /* check sequence number */ 128*b528cefcSMark Murray if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) { 129*b528cefcSMark Murray if (part.seq_number == NULL || 130*b528cefcSMark Murray *part.seq_number != ++auth_context->remote_seqnumber) { 131*b528cefcSMark Murray ret = KRB5KRB_AP_ERR_BADORDER; 132*b528cefcSMark Murray goto failure_part; 133*b528cefcSMark Murray } 134*b528cefcSMark Murray } 135*b528cefcSMark Murray 136*b528cefcSMark Murray ret = krb5_data_copy (outbuf, part.user_data.data, part.user_data.length); 137*b528cefcSMark Murray if (ret) 138*b528cefcSMark Murray goto failure_part; 139*b528cefcSMark Murray 140*b528cefcSMark Murray free_EncKrbPrivPart (&part); 141*b528cefcSMark Murray free_KRB_PRIV (&priv); 142*b528cefcSMark Murray return 0; 143*b528cefcSMark Murray 144*b528cefcSMark Murray failure_part: 145*b528cefcSMark Murray free_EncKrbPrivPart (&part); 146*b528cefcSMark Murray 147*b528cefcSMark Murray failure: 148*b528cefcSMark Murray free_KRB_PRIV (&priv); 149*b528cefcSMark Murray return ret; 150*b528cefcSMark Murray } 151