2
* Copyright (c) 1997 - 2004 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/gsskrb5_locl.h"
40
(OM_uint32 * minor_status,
41
const gsskrb5_ctx context_handle,
42
const gss_buffer_t input_message_buffer,
43
gss_buffer_t output_message_buffer,
45
gss_qop_t * qop_state,
53
DES_key_schedule schedule;
64
if (IS_DCE_STYLE(context_handle)) {
65
token_len = 22 + 8 + 15; /* 45 */
67
token_len = input_message_buffer->length;
70
p = input_message_buffer->value;
71
ret = _gsskrb5_verify_header (&p,
78
if (memcmp (p, "\x00\x00", 2) != 0)
81
if (memcmp (p, "\x00\x00", 2) == 0) {
83
} else if (memcmp (p, "\xFF\xFF", 2) == 0) {
88
if(conf_state != NULL)
90
if (memcmp (p, "\xff\xff", 2) != 0)
91
return GSS_S_DEFECTIVE_TOKEN;
95
len = p - (u_char *)input_message_buffer->value;
99
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
101
for (i = 0; i < sizeof(deskey); ++i)
103
DES_set_key_unchecked (&deskey, &schedule);
104
memset (&zero, 0, sizeof(zero));
105
DES_cbc_encrypt ((void *)p,
107
input_message_buffer->length - len,
112
memset (deskey, 0, sizeof(deskey));
113
memset (&schedule, 0, sizeof(schedule));
116
if (IS_DCE_STYLE(context_handle)) {
120
ret = _gssapi_verify_pad(input_message_buffer,
121
input_message_buffer->length - len,
128
MD5_Update (&md5, p - 24, 8);
129
MD5_Update (&md5, p, input_message_buffer->length - len);
130
MD5_Final (hash, &md5);
132
memset (&zero, 0, sizeof(zero));
133
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
134
DES_set_key_unchecked (&deskey, &schedule);
135
DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
137
if (memcmp (p - 8, hash, 8) != 0)
138
return GSS_S_BAD_MIC;
140
/* verify sequence number */
142
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
145
DES_set_key_unchecked (&deskey, &schedule);
146
DES_cbc_encrypt ((void *)p, (void *)p, 8,
147
&schedule, (DES_cblock *)hash, DES_DECRYPT);
149
memset (deskey, 0, sizeof(deskey));
150
memset (&schedule, 0, sizeof(schedule));
153
_gsskrb5_decode_om_uint32(seq, &seq_number);
155
if (context_handle->more_flags & LOCAL)
156
cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4);
158
cmp = memcmp(&seq[4], "\x00\x00\x00\x00", 4);
161
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
162
return GSS_S_BAD_MIC;
165
ret = _gssapi_msg_order_check(context_handle->order, seq_number);
167
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
171
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
175
output_message_buffer->length = input_message_buffer->length
176
- len - padlength - 8;
177
output_message_buffer->value = malloc(output_message_buffer->length);
178
if(output_message_buffer->length != 0 && output_message_buffer->value == NULL)
179
return GSS_S_FAILURE;
180
memcpy (output_message_buffer->value,
182
output_message_buffer->length);
183
return GSS_S_COMPLETE;
188
(OM_uint32 * minor_status,
189
const gsskrb5_ctx context_handle,
190
krb5_context context,
191
const gss_buffer_t input_message_buffer,
192
gss_buffer_t output_message_buffer,
194
gss_qop_t * qop_state,
212
if (IS_DCE_STYLE(context_handle)) {
213
token_len = 34 + 8 + 15; /* 57 */
215
token_len = input_message_buffer->length;
218
p = input_message_buffer->value;
219
ret = _gsskrb5_verify_header (&p,
226
if (memcmp (p, "\x04\x00", 2) != 0) /* HMAC SHA1 DES3_KD */
227
return GSS_S_BAD_SIG;
229
if (memcmp (p, "\x02\x00", 2) == 0) {
231
} else if (memcmp (p, "\xff\xff", 2) == 0) {
234
return GSS_S_BAD_MIC;
236
if(conf_state != NULL)
237
*conf_state = cstate;
238
if (memcmp (p, "\xff\xff", 2) != 0)
239
return GSS_S_DEFECTIVE_TOKEN;
243
len = p - (u_char *)input_message_buffer->value;
249
ret = krb5_crypto_init(context, key,
250
ETYPE_DES3_CBC_NONE, &crypto);
253
return GSS_S_FAILURE;
255
ret = krb5_decrypt(context, crypto, KRB5_KU_USAGE_SEAL,
256
p, input_message_buffer->length - len, &tmp);
257
krb5_crypto_destroy(context, crypto);
260
return GSS_S_FAILURE;
262
assert (tmp.length == input_message_buffer->length - len);
264
memcpy (p, tmp.data, tmp.length);
265
krb5_data_free(&tmp);
268
if (IS_DCE_STYLE(context_handle)) {
272
ret = _gssapi_verify_pad(input_message_buffer,
273
input_message_buffer->length - len,
279
/* verify sequence number */
281
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
285
ret = krb5_crypto_init(context, key,
286
ETYPE_DES3_CBC_NONE, &crypto);
289
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
290
return GSS_S_FAILURE;
295
memcpy(&ivec, p + 8, 8);
296
ret = krb5_decrypt_ivec (context,
302
krb5_crypto_destroy (context, crypto);
305
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
306
return GSS_S_FAILURE;
308
if (seq_data.length != 8) {
309
krb5_data_free (&seq_data);
311
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
312
return GSS_S_BAD_MIC;
316
_gsskrb5_decode_om_uint32(seq, &seq_number);
318
if (context_handle->more_flags & LOCAL)
319
cmp = memcmp(&seq[4], "\xff\xff\xff\xff", 4);
321
cmp = memcmp(&seq[4], "\x00\x00\x00\x00", 4);
323
krb5_data_free (&seq_data);
326
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
327
return GSS_S_BAD_MIC;
330
ret = _gssapi_msg_order_check(context_handle->order, seq_number);
333
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
337
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
339
/* verify checksum */
341
memcpy (cksum, p + 8, 20);
343
memcpy (p + 20, p - 8, 8);
345
csum.cksumtype = CKSUMTYPE_HMAC_SHA1_DES3;
346
csum.checksum.length = 20;
347
csum.checksum.data = cksum;
349
ret = krb5_crypto_init(context, key, 0, &crypto);
352
return GSS_S_FAILURE;
355
ret = krb5_verify_checksum (context, crypto,
358
input_message_buffer->length - len + 8,
360
krb5_crypto_destroy (context, crypto);
363
return GSS_S_FAILURE;
368
output_message_buffer->length = input_message_buffer->length
369
- len - padlength - 8;
370
output_message_buffer->value = malloc(output_message_buffer->length);
371
if(output_message_buffer->length != 0 && output_message_buffer->value == NULL)
372
return GSS_S_FAILURE;
373
memcpy (output_message_buffer->value,
375
output_message_buffer->length);
376
return GSS_S_COMPLETE;
379
OM_uint32 _gsskrb5_unwrap
380
(OM_uint32 * minor_status,
381
const gss_ctx_id_t context_handle,
382
const gss_buffer_t input_message_buffer,
383
gss_buffer_t output_message_buffer,
385
gss_qop_t * qop_state
389
krb5_context context;
391
krb5_keytype keytype;
392
gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
394
output_message_buffer->value = NULL;
395
output_message_buffer->length = 0;
397
GSSAPI_KRB5_INIT (&context);
399
if (qop_state != NULL)
400
*qop_state = GSS_C_QOP_DEFAULT;
401
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
402
ret = _gsskrb5i_get_token_key(ctx, context, &key);
403
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
406
return GSS_S_FAILURE;
408
krb5_enctype_to_keytype (context, key->keytype, &keytype);
414
ret = unwrap_des (minor_status, ctx,
415
input_message_buffer, output_message_buffer,
416
conf_state, qop_state, key);
419
ret = unwrap_des3 (minor_status, ctx, context,
420
input_message_buffer, output_message_buffer,
421
conf_state, qop_state, key);
423
case KEYTYPE_ARCFOUR:
424
case KEYTYPE_ARCFOUR_56:
425
ret = _gssapi_unwrap_arcfour (minor_status, ctx, context,
426
input_message_buffer, output_message_buffer,
427
conf_state, qop_state, key);
430
ret = _gssapi_unwrap_cfx (minor_status, ctx, context,
431
input_message_buffer, output_message_buffer,
432
conf_state, qop_state, key);
435
krb5_free_keyblock (context, key);