2 * Copyright (c) 1997 - 2003 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 "gsskrb5_locl.h"
36 #ifdef HEIM_WEAK_CRYPTO
40 (OM_uint32
* minor_status
,
41 const gsskrb5_ctx ctx
,
44 const gss_buffer_t message_buffer
,
45 gss_buffer_t message_token
,
52 DES_key_schedule schedule
;
53 EVP_CIPHER_CTX des_ctx
;
57 size_t len
, total_len
;
59 _gsskrb5_encap_length (22, &len
, &total_len
, GSS_KRB5_MECHANISM
);
61 message_token
->length
= total_len
;
62 message_token
->value
= malloc (total_len
);
63 if (message_token
->value
== NULL
) {
64 message_token
->length
= 0;
65 *minor_status
= ENOMEM
;
69 p
= _gsskrb5_make_header(message_token
->value
,
71 "\x01\x01", /* TOK_ID */
74 memcpy (p
, "\x00\x00", 2); /* SGN_ALG = DES MAC MD5 */
77 memcpy (p
, "\xff\xff\xff\xff", 4); /* Filler */
80 /* Fill in later (SND-SEQ) */
85 md5
= EVP_MD_CTX_create();
86 EVP_DigestInit_ex(md5
, EVP_md5(), NULL
);
87 EVP_DigestUpdate(md5
, p
- 24, 8);
88 EVP_DigestUpdate(md5
, message_buffer
->value
, message_buffer
->length
);
89 EVP_DigestFinal_ex(md5
, hash
, NULL
);
90 EVP_MD_CTX_destroy(md5
);
92 memset (&zero
, 0, sizeof(zero
));
93 memcpy (&deskey
, key
->keyvalue
.data
, sizeof(deskey
));
94 DES_set_key_unchecked (&deskey
, &schedule
);
95 DES_cbc_cksum ((void *)hash
, (void *)hash
, sizeof(hash
),
97 memcpy (p
- 8, hash
, 8); /* SGN_CKSUM */
99 HEIMDAL_MUTEX_lock(&ctx
->ctx_id_mutex
);
100 /* sequence number */
101 krb5_auth_con_getlocalseqnumber (context
,
105 p
-= 16; /* SND_SEQ */
106 p
[0] = (seq_number
>> 0) & 0xFF;
107 p
[1] = (seq_number
>> 8) & 0xFF;
108 p
[2] = (seq_number
>> 16) & 0xFF;
109 p
[3] = (seq_number
>> 24) & 0xFF;
111 (ctx
->more_flags
& LOCAL
) ? 0 : 0xFF,
114 EVP_CIPHER_CTX_init(&des_ctx
);
115 EVP_CipherInit_ex(&des_ctx
, EVP_des_cbc(), NULL
, key
->keyvalue
.data
, p
+ 8, 1);
116 EVP_Cipher(&des_ctx
, p
, p
, 8);
117 EVP_CIPHER_CTX_cleanup(&des_ctx
);
119 krb5_auth_con_setlocalseqnumber (context
,
122 HEIMDAL_MUTEX_unlock(&ctx
->ctx_id_mutex
);
124 memset (deskey
, 0, sizeof(deskey
));
125 memset (&schedule
, 0, sizeof(schedule
));
128 return GSS_S_COMPLETE
;
134 (OM_uint32
* minor_status
,
135 const gsskrb5_ctx ctx
,
136 krb5_context context
,
138 const gss_buffer_t message_buffer
,
139 gss_buffer_t message_token
,
148 size_t len
, total_len
;
151 krb5_error_code kret
;
156 _gsskrb5_encap_length (36, &len
, &total_len
, GSS_KRB5_MECHANISM
);
158 message_token
->length
= total_len
;
159 message_token
->value
= malloc (total_len
);
160 if (message_token
->value
== NULL
) {
161 message_token
->length
= 0;
162 *minor_status
= ENOMEM
;
163 return GSS_S_FAILURE
;
166 p
= _gsskrb5_make_header(message_token
->value
,
168 "\x01\x01", /* TOK-ID */
171 memcpy (p
, "\x04\x00", 2); /* SGN_ALG = HMAC SHA1 DES3-KD */
174 memcpy (p
, "\xff\xff\xff\xff", 4); /* filler */
177 /* this should be done in parts */
179 tmp
= malloc (message_buffer
->length
+ 8);
181 free (message_token
->value
);
182 message_token
->value
= NULL
;
183 message_token
->length
= 0;
184 *minor_status
= ENOMEM
;
185 return GSS_S_FAILURE
;
187 memcpy (tmp
, p
- 8, 8);
188 memcpy (tmp
+ 8, message_buffer
->value
, message_buffer
->length
);
190 kret
= krb5_crypto_init(context
, key
, 0, &crypto
);
192 free (message_token
->value
);
193 message_token
->value
= NULL
;
194 message_token
->length
= 0;
196 *minor_status
= kret
;
197 return GSS_S_FAILURE
;
200 kret
= krb5_create_checksum (context
,
205 message_buffer
->length
+ 8,
208 krb5_crypto_destroy (context
, crypto
);
210 free (message_token
->value
);
211 message_token
->value
= NULL
;
212 message_token
->length
= 0;
213 *minor_status
= kret
;
214 return GSS_S_FAILURE
;
217 memcpy (p
+ 8, cksum
.checksum
.data
, cksum
.checksum
.length
);
219 HEIMDAL_MUTEX_lock(&ctx
->ctx_id_mutex
);
220 /* sequence number */
221 krb5_auth_con_getlocalseqnumber (context
,
225 seq
[0] = (seq_number
>> 0) & 0xFF;
226 seq
[1] = (seq_number
>> 8) & 0xFF;
227 seq
[2] = (seq_number
>> 16) & 0xFF;
228 seq
[3] = (seq_number
>> 24) & 0xFF;
230 (ctx
->more_flags
& LOCAL
) ? 0 : 0xFF,
233 kret
= krb5_crypto_init(context
, key
,
234 ETYPE_DES3_CBC_NONE
, &crypto
);
236 free (message_token
->value
);
237 message_token
->value
= NULL
;
238 message_token
->length
= 0;
239 *minor_status
= kret
;
240 return GSS_S_FAILURE
;
243 if (ctx
->more_flags
& COMPAT_OLD_DES3
)
246 memcpy(ivec
, p
+ 8, 8);
248 kret
= krb5_encrypt_ivec (context
,
251 seq
, 8, &encdata
, ivec
);
252 krb5_crypto_destroy (context
, crypto
);
254 free (message_token
->value
);
255 message_token
->value
= NULL
;
256 message_token
->length
= 0;
257 *minor_status
= kret
;
258 return GSS_S_FAILURE
;
261 assert (encdata
.length
== 8);
263 memcpy (p
, encdata
.data
, encdata
.length
);
264 krb5_data_free (&encdata
);
266 krb5_auth_con_setlocalseqnumber (context
,
269 HEIMDAL_MUTEX_unlock(&ctx
->ctx_id_mutex
);
271 free_Checksum (&cksum
);
273 return GSS_S_COMPLETE
;
276 OM_uint32 GSSAPI_CALLCONV _gsskrb5_get_mic
277 (OM_uint32
* minor_status
,
278 gss_const_ctx_id_t context_handle
,
280 const gss_buffer_t message_buffer
,
281 gss_buffer_t message_token
284 krb5_context context
;
285 const gsskrb5_ctx ctx
= (const gsskrb5_ctx
) context_handle
;
289 GSSAPI_KRB5_INIT (&context
);
291 if (ctx
->more_flags
& IS_CFX
)
292 return _gssapi_mic_cfx (minor_status
, ctx
, context
, qop_req
,
293 message_buffer
, message_token
);
295 HEIMDAL_MUTEX_lock(&ctx
->ctx_id_mutex
);
296 ret
= _gsskrb5i_get_token_key(ctx
, context
, &key
);
297 HEIMDAL_MUTEX_unlock(&ctx
->ctx_id_mutex
);
300 return GSS_S_FAILURE
;
303 switch (key
->keytype
) {
304 case KRB5_ENCTYPE_DES_CBC_CRC
:
305 case KRB5_ENCTYPE_DES_CBC_MD4
:
306 case KRB5_ENCTYPE_DES_CBC_MD5
:
307 #ifdef HEIM_WEAK_CRYPTO
308 ret
= mic_des (minor_status
, ctx
, context
, qop_req
,
309 message_buffer
, message_token
, key
);
314 case KRB5_ENCTYPE_DES3_CBC_MD5
:
315 case KRB5_ENCTYPE_DES3_CBC_SHA1
:
316 ret
= mic_des3 (minor_status
, ctx
, context
, qop_req
,
317 message_buffer
, message_token
, key
);
319 case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5
:
320 case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56
:
321 ret
= _gssapi_get_mic_arcfour (minor_status
, ctx
, context
, qop_req
,
322 message_buffer
, message_token
, key
);
328 krb5_free_keyblock (context
, key
);