1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/krb5/krb/get_etype_salt_s2kp.c - Retrieve enctype, salt and s2kparams */
3 /*
4 * Copyright (C) 2017 by Cloudera, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 * OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include "k5-int.h"
34 #include "fast.h"
35 #include "init_creds_ctx.h"
36 #include "os-proto.h"
37
38 /* Extract etype info from the error message pkt into icc, if it is a
39 * PREAUTH_REQUIRED error. Otherwise return the protocol error code. */
40 static krb5_error_code
get_from_error(krb5_context context,krb5_data * pkt,krb5_init_creds_context icc)41 get_from_error(krb5_context context, krb5_data *pkt,
42 krb5_init_creds_context icc)
43 {
44 krb5_error *error = NULL;
45 krb5_pa_data **padata = NULL;
46 krb5_error_code ret;
47
48 ret = decode_krb5_error(pkt, &error);
49 if (ret)
50 return ret;
51 ret = krb5int_fast_process_error(context, icc->fast_state, &error, &padata,
52 NULL);
53 if (ret)
54 goto cleanup;
55 if (error->error != KDC_ERR_PREAUTH_REQUIRED) {
56 ret = ERROR_TABLE_BASE_krb5 + error->error;
57 goto cleanup;
58 }
59 ret = k5_get_etype_info(context, icc, padata);
60
61 cleanup:
62 krb5_free_pa_data(context, padata);
63 krb5_free_error(context, error);
64 return ret;
65 }
66
67 /* Extract etype info from the AS reply pkt into icc. */
68 static krb5_error_code
get_from_reply(krb5_context context,krb5_data * pkt,krb5_init_creds_context icc)69 get_from_reply(krb5_context context, krb5_data *pkt,
70 krb5_init_creds_context icc)
71 {
72 krb5_kdc_rep *asrep = NULL;
73 krb5_error_code ret;
74 krb5_keyblock *strengthen_key = NULL;
75
76 ret = decode_krb5_as_rep(pkt, &asrep);
77 if (ret)
78 return ret;
79 ret = krb5int_fast_process_response(context, icc->fast_state, asrep,
80 &strengthen_key);
81 if (ret)
82 goto cleanup;
83 ret = k5_get_etype_info(context, icc, asrep->padata);
84
85 cleanup:
86 krb5_free_kdc_rep(context, asrep);
87 krb5_free_keyblock(context, strengthen_key);
88 return ret;
89 }
90
91 krb5_error_code KRB5_CALLCONV
krb5_get_etype_info(krb5_context context,krb5_principal principal,krb5_get_init_creds_opt * opt,krb5_enctype * enctype_out,krb5_data * salt_out,krb5_data * s2kparams_out)92 krb5_get_etype_info(krb5_context context, krb5_principal principal,
93 krb5_get_init_creds_opt *opt, krb5_enctype *enctype_out,
94 krb5_data *salt_out, krb5_data *s2kparams_out)
95 {
96 krb5_init_creds_context icc = NULL;
97 krb5_data reply = empty_data(), req = empty_data(), realm = empty_data();
98 krb5_data salt = empty_data(), s2kparams = empty_data();
99 unsigned int flags;
100 int no_udp;
101 krb5_error_code ret;
102
103 *enctype_out = ENCTYPE_NULL;
104 *salt_out = empty_data();
105 *s2kparams_out = empty_data();
106
107 /* Create an initial creds context and get the initial request packet. */
108 ret = krb5_init_creds_init(context, principal, NULL, NULL, 0, opt, &icc);
109 if (ret)
110 goto cleanup;
111 ret = krb5_init_creds_step(context, icc, &reply, &req, &realm, &flags);
112 if (ret)
113 goto cleanup;
114 if (flags != KRB5_INIT_CREDS_STEP_FLAG_CONTINUE) {
115 ret = KRB5KRB_AP_ERR_MSG_TYPE;
116 goto cleanup;
117 }
118
119 /* Send the packet (possibly once with UDP and again with TCP). */
120 no_udp = 0;
121 for (;;) {
122 ret = k5_sendto_kdc(context, &req, &realm, FALSE, no_udp, &reply,
123 NULL);
124 if (ret)
125 goto cleanup;
126
127 icc->etype = ENCTYPE_NULL;
128 if (krb5_is_krb_error(&reply)) {
129 ret = get_from_error(context, &reply, icc);
130 if (ret) {
131 if (!no_udp && ret == KRB5KRB_ERR_RESPONSE_TOO_BIG) {
132 no_udp = 1;
133 krb5_free_data_contents(context, &reply);
134 continue;
135 }
136 goto cleanup;
137 }
138 } else if (krb5_is_as_rep(&reply)) {
139 ret = get_from_reply(context, &reply, icc);
140 if (ret)
141 goto cleanup;
142 } else {
143 ret = KRB5KRB_AP_ERR_MSG_TYPE;
144 goto cleanup;
145 }
146 break;
147 }
148
149 /* If we found no etype-info, return successfully with all null values. */
150 if (icc->etype == ENCTYPE_NULL)
151 goto cleanup;
152
153 if (icc->default_salt)
154 ret = krb5_principal2salt(context, principal, &salt);
155 else if (icc->salt.length > 0)
156 ret = krb5int_copy_data_contents(context, &icc->salt, &salt);
157 if (ret)
158 goto cleanup;
159
160 if (icc->s2kparams.length > 0) {
161 ret = krb5int_copy_data_contents(context, &icc->s2kparams, &s2kparams);
162 if (ret)
163 goto cleanup;
164 }
165
166 *salt_out = salt;
167 *s2kparams_out = s2kparams;
168 *enctype_out = icc->etype;
169 salt = empty_data();
170 s2kparams = empty_data();
171
172 cleanup:
173 krb5_free_data_contents(context, &req);
174 krb5_free_data_contents(context, &reply);
175 krb5_free_data_contents(context, &realm);
176 krb5_free_data_contents(context, &salt);
177 krb5_free_data_contents(context, &s2kparams);
178 krb5_init_creds_free(context, icc);
179 return ret;
180 }
181