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 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
37 krb5_salttype_to_string (krb5_context context
,
42 struct _krb5_encryption_type
*e
;
45 e
= _krb5_find_enctype (etype
);
47 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
48 "encryption type %d not supported",
50 return KRB5_PROG_ETYPE_NOSUPP
;
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", ""));
63 krb5_set_error_message (context
, HEIM_ERR_SALTTYPE_NOSUPP
,
64 "salttype %d not supported", stype
);
65 return HEIM_ERR_SALTTYPE_NOSUPP
;
68 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
69 krb5_string_to_salttype (krb5_context context
,
72 krb5_salttype
*salttype
)
74 struct _krb5_encryption_type
*e
;
77 e
= _krb5_find_enctype (etype
);
79 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
80 N_("encryption type %d not supported", ""),
82 return KRB5_PROG_ETYPE_NOSUPP
;
84 for (st
= e
->keytype
->string_to_key
; st
&& st
->type
; st
++) {
85 if (strcasecmp (st
->name
, string
) == 0) {
90 krb5_set_error_message(context
, HEIM_ERR_SALTTYPE_NOSUPP
,
91 N_("salttype %s not supported", ""), string
);
92 return HEIM_ERR_SALTTYPE_NOSUPP
;
95 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
96 krb5_get_pw_salt(krb5_context context
,
97 krb5_const_principal principal
,
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
);
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
) {
117 principal
->name
.name_string
.val
[i
],
118 strlen(principal
->name
.name_string
.val
[i
]));
119 p
+= strlen(principal
->name
.name_string
.val
[i
]);
124 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
125 krb5_free_salt(krb5_context context
,
128 krb5_data_free(&salt
.saltvalue
);
132 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
133 krb5_string_to_key_data (krb5_context context
,
134 krb5_enctype enctype
,
136 krb5_principal principal
,
142 ret
= krb5_get_pw_salt(context
, principal
, &salt
);
145 ret
= krb5_string_to_key_data_salt(context
, enctype
, password
, salt
, key
);
146 krb5_free_salt(context
, salt
);
150 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
151 krb5_string_to_key (krb5_context context
,
152 krb5_enctype enctype
,
153 const char *password
,
154 krb5_principal principal
,
158 pw
.data
= rk_UNCONST(password
);
159 pw
.length
= strlen(password
);
160 return krb5_string_to_key_data(context
, enctype
, pw
, principal
, key
);
163 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
164 krb5_string_to_key_data_salt (krb5_context context
,
165 krb5_enctype enctype
,
171 krb5_data_zero(&opaque
);
172 return krb5_string_to_key_data_salt_opaque(context
, enctype
, password
,
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'
182 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
183 krb5_string_to_key_data_salt_opaque (krb5_context context
,
184 krb5_enctype enctype
,
190 struct _krb5_encryption_type
*et
=_krb5_find_enctype(enctype
);
191 struct salt_type
*st
;
193 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
194 N_("encryption type %d not supported", ""),
196 return KRB5_PROG_ETYPE_NOSUPP
;
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
,
202 krb5_set_error_message(context
, HEIM_ERR_SALTTYPE_NOSUPP
,
203 N_("salt type %d not supported", ""),
205 return HEIM_ERR_SALTTYPE_NOSUPP
;
209 * Do a string -> key for encryption type `enctype' operation on the
210 * string `password' (with salt `salt'), returning the resulting key
214 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
215 krb5_string_to_key_salt (krb5_context context
,
216 krb5_enctype enctype
,
217 const char *password
,
222 pw
.data
= rk_UNCONST(password
);
223 pw
.length
= strlen(password
);
224 return krb5_string_to_key_data_salt(context
, enctype
, pw
, salt
, key
);
227 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
228 krb5_string_to_key_salt_opaque (krb5_context context
,
229 krb5_enctype enctype
,
230 const char *password
,
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
);
243 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
244 krb5_string_to_key_derived(krb5_context context
,
250 struct _krb5_encryption_type
*et
= _krb5_find_enctype(etype
);
252 struct _krb5_key_data kd
;
257 krb5_set_error_message (context
, KRB5_PROG_ETYPE_NOSUPP
,
258 N_("encryption type %d not supported", ""),
260 return KRB5_PROG_ETYPE_NOSUPP
;
262 keylen
= et
->keytype
->bits
/ 8;
266 krb5_set_error_message (context
, ENOMEM
,
267 N_("malloc: out of memory", ""));
270 ret
= krb5_data_alloc(&kd
.key
->keyvalue
, et
->keytype
->size
);
275 kd
.key
->keytype
= etype
;
276 tmp
= malloc (keylen
);
278 krb5_free_keyblock(context
, kd
.key
);
279 krb5_set_error_message (context
, ENOMEM
, N_("malloc: out of memory", ""));
282 ret
= _krb5_n_fold(str
, len
, tmp
, keylen
);
285 krb5_set_error_message (context
, ENOMEM
, N_("malloc: out of memory", ""));
289 _krb5_DES3_random_to_key(context
, kd
.key
, tmp
, keylen
);
290 memset(tmp
, 0, keylen
);
292 ret
= _krb5_derive_key(context
,
295 "kerberos", /* XXX well known constant */
298 _krb5_free_key_data(context
, &kd
, et
);
301 ret
= krb5_copy_keyblock_contents(context
, kd
.key
, key
);
302 _krb5_free_key_data(context
, &kd
, et
);