Line data Source code
1 : /*
2 : * Copyright (c) 1997 - 2008 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. Neither the name of the Institute nor the names of its contributors
18 : * may be used to endorse or promote products derived from this software
19 : * without specific prior written permission.
20 : *
21 : * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 : * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 : * SUCH DAMAGE.
32 : */
33 :
34 : #include "krb5_locl.h"
35 :
36 : /* coverity[+alloc : arg-*3] */
37 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
38 0 : krb5_salttype_to_string (krb5_context context,
39 : krb5_enctype etype,
40 : krb5_salttype stype,
41 : char **string)
42 : {
43 : struct _krb5_encryption_type *e;
44 : struct salt_type *st;
45 :
46 0 : e = _krb5_find_enctype (etype);
47 0 : if (e == NULL) {
48 0 : krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
49 : "encryption type %d not supported",
50 : etype);
51 0 : return KRB5_PROG_ETYPE_NOSUPP;
52 : }
53 0 : for (st = e->keytype->string_to_key; st && st->type; st++) {
54 0 : if (st->type == stype) {
55 0 : *string = strdup (st->name);
56 0 : if (*string == NULL) {
57 0 : krb5_set_error_message (context, ENOMEM,
58 0 : N_("malloc: out of memory", ""));
59 0 : return ENOMEM;
60 : }
61 0 : return 0;
62 : }
63 : }
64 0 : krb5_set_error_message (context, HEIM_ERR_SALTTYPE_NOSUPP,
65 : "salttype %d not supported", stype);
66 0 : return HEIM_ERR_SALTTYPE_NOSUPP;
67 : }
68 :
69 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
70 0 : krb5_string_to_salttype (krb5_context context,
71 : krb5_enctype etype,
72 : const char *string,
73 : krb5_salttype *salttype)
74 : {
75 : struct _krb5_encryption_type *e;
76 : struct salt_type *st;
77 :
78 0 : e = _krb5_find_enctype (etype);
79 0 : if (e == NULL) {
80 0 : krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
81 0 : N_("encryption type %d not supported", ""),
82 : etype);
83 0 : return KRB5_PROG_ETYPE_NOSUPP;
84 : }
85 0 : for (st = e->keytype->string_to_key; st && st->type; st++) {
86 0 : if (strcasecmp (st->name, string) == 0) {
87 0 : *salttype = st->type;
88 0 : return 0;
89 : }
90 : }
91 0 : krb5_set_error_message(context, HEIM_ERR_SALTTYPE_NOSUPP,
92 0 : N_("salttype %s not supported", ""), string);
93 0 : return HEIM_ERR_SALTTYPE_NOSUPP;
94 : }
95 :
96 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
97 119984 : krb5_get_pw_salt(krb5_context context,
98 : krb5_const_principal principal,
99 : krb5_salt *salt)
100 : {
101 : size_t len;
102 : size_t i;
103 : krb5_error_code ret;
104 : char *p;
105 :
106 119984 : salt->salttype = KRB5_PW_SALT;
107 119984 : len = strlen(principal->realm);
108 289773 : for (i = 0; i < principal->name.name_string.len; ++i)
109 169789 : len += strlen(principal->name.name_string.val[i]);
110 119984 : ret = krb5_data_alloc (&salt->saltvalue, len);
111 119984 : if (ret)
112 0 : return ret;
113 119984 : p = salt->saltvalue.data;
114 122581 : memcpy (p, principal->realm, strlen(principal->realm));
115 119984 : p += strlen(principal->realm);
116 289773 : for (i = 0; i < principal->name.name_string.len; ++i) {
117 339578 : memcpy (p,
118 165935 : principal->name.name_string.val[i],
119 169789 : strlen(principal->name.name_string.val[i]));
120 169789 : p += strlen(principal->name.name_string.val[i]);
121 : }
122 117387 : return 0;
123 : }
124 :
125 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
126 129637 : krb5_free_salt(krb5_context context,
127 : krb5_salt salt)
128 : {
129 129637 : krb5_data_free(&salt.saltvalue);
130 129637 : return 0;
131 : }
132 :
133 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
134 0 : krb5_string_to_key_data (krb5_context context,
135 : krb5_enctype enctype,
136 : krb5_data password,
137 : krb5_principal principal,
138 : krb5_keyblock *key)
139 : {
140 : krb5_error_code ret;
141 : krb5_salt salt;
142 :
143 0 : ret = krb5_get_pw_salt(context, principal, &salt);
144 0 : if(ret)
145 0 : return ret;
146 0 : ret = krb5_string_to_key_data_salt(context, enctype, password, salt, key);
147 0 : krb5_free_salt(context, salt);
148 0 : return ret;
149 : }
150 :
151 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
152 0 : krb5_string_to_key (krb5_context context,
153 : krb5_enctype enctype,
154 : const char *password,
155 : krb5_principal principal,
156 : krb5_keyblock *key)
157 : {
158 : krb5_data pw;
159 0 : pw.data = rk_UNCONST(password);
160 0 : pw.length = strlen(password);
161 0 : return krb5_string_to_key_data(context, enctype, pw, principal, key);
162 : }
163 :
164 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
165 37806 : krb5_string_to_key_data_salt (krb5_context context,
166 : krb5_enctype enctype,
167 : krb5_data password,
168 : krb5_salt salt,
169 : krb5_keyblock *key)
170 : {
171 : krb5_data opaque;
172 37806 : krb5_data_zero(&opaque);
173 37806 : return krb5_string_to_key_data_salt_opaque(context, enctype, password,
174 : salt, opaque, key);
175 : }
176 :
177 : /*
178 : * Do a string -> key for encryption type `enctype' operation on
179 : * `password' (with salt `salt' and the enctype specific data string
180 : * `opaque'), returning the resulting key in `key'
181 : */
182 :
183 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
184 65965 : krb5_string_to_key_data_salt_opaque (krb5_context context,
185 : krb5_enctype enctype,
186 : krb5_data password,
187 : krb5_salt salt,
188 : krb5_data opaque,
189 : krb5_keyblock *key)
190 : {
191 65965 : struct _krb5_encryption_type *et =_krb5_find_enctype(enctype);
192 : struct salt_type *st;
193 65965 : if(et == NULL) {
194 0 : krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
195 0 : N_("encryption type %d not supported", ""),
196 : enctype);
197 0 : return KRB5_PROG_ETYPE_NOSUPP;
198 : }
199 65965 : for(st = et->keytype->string_to_key; st && st->type; st++)
200 65965 : if(st->type == salt.salttype)
201 65965 : return (*st->string_to_key)(context, enctype, password,
202 : salt, opaque, key);
203 0 : krb5_set_error_message(context, HEIM_ERR_SALTTYPE_NOSUPP,
204 0 : N_("salt type %d not supported", ""),
205 0 : salt.salttype);
206 0 : return HEIM_ERR_SALTTYPE_NOSUPP;
207 : }
208 :
209 : /*
210 : * Do a string -> key for encryption type `enctype' operation on the
211 : * string `password' (with salt `salt'), returning the resulting key
212 : * in `key'
213 : */
214 :
215 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
216 37806 : krb5_string_to_key_salt (krb5_context context,
217 : krb5_enctype enctype,
218 : const char *password,
219 : krb5_salt salt,
220 : krb5_keyblock *key)
221 : {
222 : krb5_data pw;
223 37806 : pw.data = rk_UNCONST(password);
224 37806 : pw.length = strlen(password);
225 37806 : return krb5_string_to_key_data_salt(context, enctype, pw, salt, key);
226 : }
227 :
228 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
229 0 : krb5_string_to_key_salt_opaque (krb5_context context,
230 : krb5_enctype enctype,
231 : const char *password,
232 : krb5_salt salt,
233 : krb5_data opaque,
234 : krb5_keyblock *key)
235 : {
236 : krb5_data pw;
237 0 : pw.data = rk_UNCONST(password);
238 0 : pw.length = strlen(password);
239 0 : return krb5_string_to_key_data_salt_opaque(context, enctype,
240 : pw, salt, opaque, key);
241 : }
242 :
243 :
244 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
245 0 : krb5_string_to_key_derived(krb5_context context,
246 : const void *str,
247 : size_t len,
248 : krb5_enctype etype,
249 : krb5_keyblock *key)
250 : {
251 0 : struct _krb5_encryption_type *et = _krb5_find_enctype(etype);
252 : krb5_error_code ret;
253 : struct _krb5_key_data kd;
254 : size_t keylen;
255 : u_char *tmp;
256 :
257 0 : if(et == NULL) {
258 0 : krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP,
259 0 : N_("encryption type %d not supported", ""),
260 : etype);
261 0 : return KRB5_PROG_ETYPE_NOSUPP;
262 : }
263 0 : keylen = et->keytype->bits / 8;
264 :
265 0 : ALLOC(kd.key, 1);
266 0 : if(kd.key == NULL) {
267 0 : krb5_set_error_message (context, ENOMEM,
268 0 : N_("malloc: out of memory", ""));
269 0 : return ENOMEM;
270 : }
271 0 : ret = krb5_data_alloc(&kd.key->keyvalue, et->keytype->size);
272 0 : if(ret) {
273 0 : free(kd.key);
274 0 : return ret;
275 : }
276 0 : kd.key->keytype = etype;
277 0 : tmp = malloc (keylen);
278 0 : if(tmp == NULL) {
279 0 : krb5_free_keyblock(context, kd.key);
280 0 : krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", ""));
281 0 : return ENOMEM;
282 : }
283 0 : ret = _krb5_n_fold(str, len, tmp, keylen);
284 0 : if (ret) {
285 0 : free(tmp);
286 0 : krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", ""));
287 0 : return ret;
288 : }
289 0 : kd.schedule = NULL;
290 0 : _krb5_DES3_random_to_key(context, kd.key, tmp, keylen);
291 0 : memset(tmp, 0, keylen);
292 0 : free(tmp);
293 0 : ret = _krb5_derive_key(context,
294 : et,
295 : &kd,
296 : "kerberos", /* XXX well known constant */
297 : strlen("kerberos"));
298 0 : if (ret) {
299 0 : _krb5_free_key_data(context, &kd, et);
300 0 : return ret;
301 : }
302 0 : ret = krb5_copy_keyblock_contents(context, kd.key, key);
303 0 : _krb5_free_key_data(context, &kd, et);
304 0 : return ret;
305 : }
|