2 * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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
34 #include "krb5_locl.h"
36 /* coverity[+alloc : arg-*3] */
37 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
38 krb5_salttype_to_string (krb5_context context
,
43 struct _krb5_encryption_type
*e
;
47 e
= _krb5_find_enctype (etype
);
49 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
50 "encryption type %d not supported",
52 return KRB5_PROG_ETYPE_NOSUPP
;
54 for (st
= e
->keytype
->string_to_key
; st
&& st
->type
; st
++) {
55 if (st
->type
== stype
) {
56 *string
= strdup (st
->name
);
58 return krb5_enomem(context
);
62 krb5_set_error_message (context
, HEIM_ERR_SALTTYPE_NOSUPP
,
63 "salttype %d not supported", stype
);
64 return HEIM_ERR_SALTTYPE_NOSUPP
;
67 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
68 krb5_string_to_salttype (krb5_context context
,
71 krb5_salttype
*salttype
)
73 struct _krb5_encryption_type
*e
;
76 e
= _krb5_find_enctype (etype
);
78 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
79 N_("encryption type %d not supported", ""),
81 return KRB5_PROG_ETYPE_NOSUPP
;
83 for (st
= e
->keytype
->string_to_key
; st
&& st
->type
; st
++) {
84 if (strcasecmp (st
->name
, string
) == 0) {
89 krb5_set_error_message(context
, HEIM_ERR_SALTTYPE_NOSUPP
,
90 N_("salttype %s not supported", ""), string
);
91 return HEIM_ERR_SALTTYPE_NOSUPP
;
95 * Like MIT's krb5_string_to_keysalts(), but simpler and with a context
98 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
99 krb5_string_to_keysalts2(krb5_context context
, const char *string
,
100 size_t *nksaltp
, krb5_key_salt_tuple
**ksaltp
)
102 /* deleted: tupleseps, ksaltseps, dups */
103 krb5_key_salt_tuple
*tmp
= NULL
;
104 krb5_error_code ret
= 0;
105 char *copy
, *token
, *stype_str
;
113 if ((copy
= strdup(string
)) == NULL
)
114 return krb5_enomem(context
);
115 for (token
= strtok_r(copy
, ", \t", &lasts
), ret
= 0;
117 token
= strtok_r(NULL
, ", \t", &lasts
)) {
118 if ((stype_str
= strchr(token
, ':')) != NULL
)
119 *(stype_str
++) = '\0';
120 if ((ret
= krb5_string_to_enctype(context
, token
, &etype
)))
122 if (stype_str
== NULL
)
123 stype
= KRB5_PW_SALT
;
124 else if ((ret
= krb5_string_to_salttype(context
, etype
, stype_str
, &stype
)))
126 for (i
= 0; i
< *nksaltp
; i
++) {
127 if ((*ksaltp
)[i
].ks_enctype
== etype
&&
128 (*ksaltp
)[i
].ks_salttype
== stype
)
131 tmp
= realloc(*ksaltp
, ((*nksaltp
) + 1) * sizeof(**ksaltp
));
133 ret
= krb5_enomem(context
);
137 (*ksaltp
)[*nksaltp
].ks_enctype
= etype
;
138 (*ksaltp
)[*nksaltp
].ks_salttype
= stype
;
148 } else if (*nksaltp
) {
150 } else if (ret
== 0) {
151 return KRB5_PROG_ETYPE_NOSUPP
;
157 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
158 krb5_get_pw_salt(krb5_context context
,
159 krb5_const_principal principal
,
167 salt
->salttype
= KRB5_PW_SALT
;
168 len
= strlen(principal
->realm
);
169 for (i
= 0; i
< principal
->name
.name_string
.len
; ++i
)
170 len
+= strlen(principal
->name
.name_string
.val
[i
]);
171 ret
= krb5_data_alloc (&salt
->saltvalue
, len
);
174 p
= salt
->saltvalue
.data
;
175 memcpy (p
, principal
->realm
, strlen(principal
->realm
));
176 p
+= strlen(principal
->realm
);
177 for (i
= 0; i
< principal
->name
.name_string
.len
; ++i
) {
179 principal
->name
.name_string
.val
[i
],
180 strlen(principal
->name
.name_string
.val
[i
]));
181 p
+= strlen(principal
->name
.name_string
.val
[i
]);
186 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
187 krb5_free_salt(krb5_context context
,
190 krb5_data_free(&salt
.saltvalue
);
194 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
195 krb5_string_to_key_data (krb5_context context
,
196 krb5_enctype enctype
,
198 krb5_const_principal principal
,
204 ret
= krb5_get_pw_salt(context
, principal
, &salt
);
207 ret
= krb5_string_to_key_data_salt(context
, enctype
, password
, salt
, key
);
208 krb5_free_salt(context
, salt
);
212 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
213 krb5_string_to_key (krb5_context context
,
214 krb5_enctype enctype
,
215 const char *password
,
216 krb5_const_principal principal
,
220 pw
.data
= rk_UNCONST(password
);
221 pw
.length
= strlen(password
);
222 return krb5_string_to_key_data(context
, enctype
, pw
, principal
, key
);
225 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
226 krb5_string_to_key_data_salt (krb5_context context
,
227 krb5_enctype enctype
,
233 krb5_data_zero(&opaque
);
234 return krb5_string_to_key_data_salt_opaque(context
, enctype
, password
,
239 * Do a string -> key for encryption type `enctype' operation on
240 * `password' (with salt `salt' and the enctype specific data string
241 * `opaque'), returning the resulting key in `key'
244 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
245 krb5_string_to_key_data_salt_opaque (krb5_context context
,
246 krb5_enctype enctype
,
252 struct _krb5_encryption_type
*et
=_krb5_find_enctype(enctype
);
253 struct salt_type
*st
;
255 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
256 N_("encryption type %d not supported", ""),
258 return KRB5_PROG_ETYPE_NOSUPP
;
260 for(st
= et
->keytype
->string_to_key
; st
&& st
->type
; st
++)
261 if(st
->type
== salt
.salttype
)
262 return (*st
->string_to_key
)(context
, enctype
, password
,
264 krb5_set_error_message(context
, HEIM_ERR_SALTTYPE_NOSUPP
,
265 N_("salt type %d not supported", ""),
267 return HEIM_ERR_SALTTYPE_NOSUPP
;
271 * Do a string -> key for encryption type `enctype' operation on the
272 * string `password' (with salt `salt'), returning the resulting key
276 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
277 krb5_string_to_key_salt (krb5_context context
,
278 krb5_enctype enctype
,
279 const char *password
,
284 pw
.data
= rk_UNCONST(password
);
285 pw
.length
= strlen(password
);
286 return krb5_string_to_key_data_salt(context
, enctype
, pw
, salt
, key
);
289 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
290 krb5_string_to_key_salt_opaque (krb5_context context
,
291 krb5_enctype enctype
,
292 const char *password
,
298 pw
.data
= rk_UNCONST(password
);
299 pw
.length
= strlen(password
);
300 return krb5_string_to_key_data_salt_opaque(context
, enctype
,
301 pw
, salt
, opaque
, key
);
305 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
306 krb5_string_to_key_derived(krb5_context context
,
312 struct _krb5_encryption_type
*et
= _krb5_find_enctype(etype
);
314 struct _krb5_key_data kd
;
319 krb5_set_error_message (context
, KRB5_PROG_ETYPE_NOSUPP
,
320 N_("encryption type %d not supported", ""),
322 return KRB5_PROG_ETYPE_NOSUPP
;
324 keylen
= et
->keytype
->bits
/ 8;
328 return krb5_enomem(context
);
329 ret
= krb5_data_alloc(&kd
.key
->keyvalue
, et
->keytype
->size
);
334 kd
.key
->keytype
= etype
;
335 tmp
= malloc (keylen
);
337 krb5_free_keyblock(context
, kd
.key
);
338 return krb5_enomem(context
);
340 ret
= _krb5_n_fold(str
, len
, tmp
, keylen
);
343 krb5_enomem(context
);
347 _krb5_DES3_random_to_key(context
, kd
.key
, tmp
, keylen
);
348 memset(tmp
, 0, keylen
);
350 ret
= _krb5_derive_key(context
,
353 "kerberos", /* XXX well known constant */
356 _krb5_free_key_data(context
, &kd
, et
);
359 ret
= krb5_copy_keyblock_contents(context
, kd
.key
, key
);
360 _krb5_free_key_data(context
, &kd
, et
);