source: trunk/server/source4/heimdal/lib/krb5/salt.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 9.3 KB
Line 
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
36KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
37krb5_salttype_to_string (krb5_context context,
38 krb5_enctype etype,
39 krb5_salttype stype,
40 char **string)
41{
42 struct _krb5_encryption_type *e;
43 struct salt_type *st;
44
45 e = _krb5_find_enctype (etype);
46 if (e == NULL) {
47 krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
48 "encryption type %d not supported",
49 etype);
50 return KRB5_PROG_ETYPE_NOSUPP;
51 }
52 for (st = e->keytype->string_to_key; st && st->type; st++) {
53 if (st->type == stype) {
54 *string = strdup (st->name);
55 if (*string == NULL) {
56 krb5_set_error_message (context, ENOMEM,
57 N_("malloc: out of memory", ""));
58 return ENOMEM;
59 }
60 return 0;
61 }
62 }
63 krb5_set_error_message (context, HEIM_ERR_SALTTYPE_NOSUPP,
64 "salttype %d not supported", stype);
65 return HEIM_ERR_SALTTYPE_NOSUPP;
66}
67
68KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
69krb5_string_to_salttype (krb5_context context,
70 krb5_enctype etype,
71 const char *string,
72 krb5_salttype *salttype)
73{
74 struct _krb5_encryption_type *e;
75 struct salt_type *st;
76
77 e = _krb5_find_enctype (etype);
78 if (e == NULL) {
79 krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
80 N_("encryption type %d not supported", ""),
81 etype);
82 return KRB5_PROG_ETYPE_NOSUPP;
83 }
84 for (st = e->keytype->string_to_key; st && st->type; st++) {
85 if (strcasecmp (st->name, string) == 0) {
86 *salttype = st->type;
87 return 0;
88 }
89 }
90 krb5_set_error_message(context, HEIM_ERR_SALTTYPE_NOSUPP,
91 N_("salttype %s not supported", ""), string);
92 return HEIM_ERR_SALTTYPE_NOSUPP;
93}
94
95KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
96krb5_get_pw_salt(krb5_context context,
97 krb5_const_principal principal,
98 krb5_salt *salt)
99{
100 size_t len;
101 int i;
102 krb5_error_code ret;
103 char *p;
104
105 salt->salttype = KRB5_PW_SALT;
106 len = strlen(principal->realm);
107 for (i = 0; i < principal->name.name_string.len; ++i)
108 len += strlen(principal->name.name_string.val[i]);
109 ret = krb5_data_alloc (&salt->saltvalue, len);
110 if (ret)
111 return ret;
112 p = salt->saltvalue.data;
113 memcpy (p, principal->realm, strlen(principal->realm));
114 p += strlen(principal->realm);
115 for (i = 0; i < principal->name.name_string.len; ++i) {
116 memcpy (p,
117 principal->name.name_string.val[i],
118 strlen(principal->name.name_string.val[i]));
119 p += strlen(principal->name.name_string.val[i]);
120 }
121 return 0;
122}
123
124KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
125krb5_free_salt(krb5_context context,
126 krb5_salt salt)
127{
128 krb5_data_free(&salt.saltvalue);
129 return 0;
130}
131
132KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
133krb5_string_to_key_data (krb5_context context,
134 krb5_enctype enctype,
135 krb5_data password,
136 krb5_principal principal,
137 krb5_keyblock *key)
138{
139 krb5_error_code ret;
140 krb5_salt salt;
141
142 ret = krb5_get_pw_salt(context, principal, &salt);
143 if(ret)
144 return ret;
145 ret = krb5_string_to_key_data_salt(context, enctype, password, salt, key);
146 krb5_free_salt(context, salt);
147 return ret;
148}
149
150KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
151krb5_string_to_key (krb5_context context,
152 krb5_enctype enctype,
153 const char *password,
154 krb5_principal principal,
155 krb5_keyblock *key)
156{
157 krb5_data pw;
158 pw.data = rk_UNCONST(password);
159 pw.length = strlen(password);
160 return krb5_string_to_key_data(context, enctype, pw, principal, key);
161}
162
163KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
164krb5_string_to_key_data_salt (krb5_context context,
165 krb5_enctype enctype,
166 krb5_data password,
167 krb5_salt salt,
168 krb5_keyblock *key)
169{
170 krb5_data opaque;
171 krb5_data_zero(&opaque);
172 return krb5_string_to_key_data_salt_opaque(context, enctype, password,
173 salt, opaque, key);
174}
175
176/*
177 * Do a string -> key for encryption type `enctype' operation on
178 * `password' (with salt `salt' and the enctype specific data string
179 * `opaque'), returning the resulting key in `key'
180 */
181
182KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
183krb5_string_to_key_data_salt_opaque (krb5_context context,
184 krb5_enctype enctype,
185 krb5_data password,
186 krb5_salt salt,
187 krb5_data opaque,
188 krb5_keyblock *key)
189{
190 struct _krb5_encryption_type *et =_krb5_find_enctype(enctype);
191 struct salt_type *st;
192 if(et == NULL) {
193 krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
194 N_("encryption type %d not supported", ""),
195 enctype);
196 return KRB5_PROG_ETYPE_NOSUPP;
197 }
198 for(st = et->keytype->string_to_key; st && st->type; st++)
199 if(st->type == salt.salttype)
200 return (*st->string_to_key)(context, enctype, password,
201 salt, opaque, key);
202 krb5_set_error_message(context, HEIM_ERR_SALTTYPE_NOSUPP,
203 N_("salt type %d not supported", ""),
204 salt.salttype);
205 return HEIM_ERR_SALTTYPE_NOSUPP;
206}
207
208/*
209 * Do a string -> key for encryption type `enctype' operation on the
210 * string `password' (with salt `salt'), returning the resulting key
211 * in `key'
212 */
213
214KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
215krb5_string_to_key_salt (krb5_context context,
216 krb5_enctype enctype,
217 const char *password,
218 krb5_salt salt,
219 krb5_keyblock *key)
220{
221 krb5_data pw;
222 pw.data = rk_UNCONST(password);
223 pw.length = strlen(password);
224 return krb5_string_to_key_data_salt(context, enctype, pw, salt, key);
225}
226
227KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
228krb5_string_to_key_salt_opaque (krb5_context context,
229 krb5_enctype enctype,
230 const char *password,
231 krb5_salt salt,
232 krb5_data opaque,
233 krb5_keyblock *key)
234{
235 krb5_data pw;
236 pw.data = rk_UNCONST(password);
237 pw.length = strlen(password);
238 return krb5_string_to_key_data_salt_opaque(context, enctype,
239 pw, salt, opaque, key);
240}
241
242
243KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
244krb5_string_to_key_derived(krb5_context context,
245 const void *str,
246 size_t len,
247 krb5_enctype etype,
248 krb5_keyblock *key)
249{
250 struct _krb5_encryption_type *et = _krb5_find_enctype(etype);
251 krb5_error_code ret;
252 struct _krb5_key_data kd;
253 size_t keylen;
254 u_char *tmp;
255
256 if(et == NULL) {
257 krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP,
258 N_("encryption type %d not supported", ""),
259 etype);
260 return KRB5_PROG_ETYPE_NOSUPP;
261 }
262 keylen = et->keytype->bits / 8;
263
264 ALLOC(kd.key, 1);
265 if(kd.key == NULL) {
266 krb5_set_error_message (context, ENOMEM,
267 N_("malloc: out of memory", ""));
268 return ENOMEM;
269 }
270 ret = krb5_data_alloc(&kd.key->keyvalue, et->keytype->size);
271 if(ret) {
272 free(kd.key);
273 return ret;
274 }
275 kd.key->keytype = etype;
276 tmp = malloc (keylen);
277 if(tmp == NULL) {
278 krb5_free_keyblock(context, kd.key);
279 krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", ""));
280 return ENOMEM;
281 }
282 ret = _krb5_n_fold(str, len, tmp, keylen);
283 if (ret) {
284 free(tmp);
285 krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", ""));
286 return ret;
287 }
288 kd.schedule = NULL;
289 _krb5_DES3_random_to_key(context, kd.key, tmp, keylen);
290 memset(tmp, 0, keylen);
291 free(tmp);
292 ret = _krb5_derive_key(context,
293 et,
294 &kd,
295 "kerberos", /* XXX well known constant */
296 strlen("kerberos"));
297 if (ret) {
298 _krb5_free_key_data(context, &kd, et);
299 return ret;
300 }
301 ret = krb5_copy_keyblock_contents(context, kd.key, key);
302 _krb5_free_key_data(context, &kd, et);
303 return ret;
304}
Note: See TracBrowser for help on using the repository browser.