xref: /freebsd-src/crypto/heimdal/lib/krb5/rd_priv.c (revision b528cefc6b8f9670b31a865051741d946cb37085)
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