1 /*
2 * lib/krb5/krb/rd_rep.c
3 *
4 * Copyright 1990,1991 by the Massachusetts Institute of Technology.
5 * All Rights Reserved.
6 *
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
11 *
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. Furthermore if you modify this software you must label
20 * your software as modified software and not distribute it in such a
21 * fashion that it might be confused with the original M.I.T. software.
22 * M.I.T. makes no representations about the suitability of
23 * this software for any purpose. It is provided "as is" without express
24 * or implied warranty.
25 *
26 *
27 * krb5_rd_rep()
28 */
29
30 #include "k5-int.h"
31 #include "auth_con.h"
32
33 /*
34 * Parses a KRB_AP_REP message, returning its contents.
35 *
36 * repl is filled in with with a pointer to allocated memory containing
37 * the fields from the encrypted response.
38 *
39 * the key in kblock is used to decrypt the message.
40 *
41 * returns system errors, encryption errors, replay errors
42 */
43
44 krb5_error_code KRB5_CALLCONV
krb5_rd_rep(krb5_context context,krb5_auth_context auth_context,const krb5_data * inbuf,krb5_ap_rep_enc_part ** repl)45 krb5_rd_rep(krb5_context context, krb5_auth_context auth_context, const krb5_data *inbuf, krb5_ap_rep_enc_part **repl)
46 {
47 krb5_error_code retval;
48 krb5_ap_rep * reply;
49 krb5_data scratch;
50
51 if (!krb5_is_ap_rep(inbuf))
52 return KRB5KRB_AP_ERR_MSG_TYPE;
53
54 /* decode it */
55
56 if ((retval = decode_krb5_ap_rep(inbuf, &reply)))
57 return retval;
58
59 /* put together an eblock for this encryption */
60
61 scratch.length = reply->enc_part.ciphertext.length;
62 if (!(scratch.data = malloc(scratch.length))) {
63 krb5_free_ap_rep(context, reply);
64 return(ENOMEM);
65 }
66
67 if ((retval = krb5_c_decrypt(context, auth_context->keyblock,
68 KRB5_KEYUSAGE_AP_REP_ENCPART, 0,
69 &reply->enc_part, &scratch)))
70 goto clean_scratch;
71
72 /* now decode the decrypted stuff */
73 retval = decode_krb5_ap_rep_enc_part(&scratch, repl);
74 if (retval)
75 goto clean_scratch;
76
77 /* Check reply fields */
78 if (((*repl)->ctime != auth_context->authentp->ctime) ||
79 ((*repl)->cusec != auth_context->authentp->cusec)) {
80 retval = KRB5_MUTUAL_FAILED;
81 goto clean_scratch;
82 }
83
84 /* Set auth subkey */
85 if ((*repl)->subkey) {
86 if (auth_context->recv_subkey) {
87 krb5_free_keyblock(context, auth_context->recv_subkey);
88 auth_context->recv_subkey = NULL;
89 }
90 retval = krb5_copy_keyblock(context, (*repl)->subkey,
91 &auth_context->recv_subkey);
92 if (retval)
93 goto clean_scratch;
94 if (auth_context->send_subkey) {
95 krb5_free_keyblock(context, auth_context->send_subkey);
96 auth_context->send_subkey = NULL;
97 }
98 retval = krb5_copy_keyblock(context, (*repl)->subkey,
99 &auth_context->send_subkey);
100 if (retval) {
101 krb5_free_keyblock(context, auth_context->send_subkey);
102 auth_context->send_subkey = NULL;
103 }
104 }
105
106 /* Get remote sequence number */
107 auth_context->remote_seq_number = (*repl)->seq_number;
108
109 clean_scratch:
110 memset(scratch.data, 0, scratch.length);
111
112 krb5_free_ap_rep(context, reply);
113 free(scratch.data);
114 return retval;
115 }
116