/*
*/
/*
*
* Copyright 2003,2004 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
* require a specific license from the United States Government.
* It is the responsibility of any person or organization contemplating
* export to obtain such a license before exporting.
*
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright notice and
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
* permission. Furthermore if you modify this software you must label
* your software as modified software and not distribute it in such a
* fashion that it might be confused with the original M.I.T. software.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*
*
*/
/* draft-ietf-krb-wg-gssapi-cfx-05 */
#ifndef _KERNEL
#include <assert.h>
#include <stdarg.h>
#endif
/* Solaris Kerberos */
#include "k5-int.h" /* for zap() */
#include "k5-platform.h"
/* Solaris Kerberos */
#include "k5-platform-store_16.h"
#include "k5-platform-store_64.h"
#include "k5-platform-load_16.h"
#include "k5-platform-load_64.h"
#include "gssapiP_krb5.h"
#include <sys/int_limits.h>
static int
{
/* Optimize for receiving. After some debugging is done, the MIT
implementation won't do any rotates on sending, and while
debugging, they'll be randomly chosen.
Return 1 for success, 0 for failure (ENOMEM). */
void *tbuf;
if (bufsiz == 0)
return 1;
if (rc == 0)
return 1;
if (tbuf == 0)
return 0;
return 1;
}
const gss_buffer_desc * message,
int conf_req_flag, int toktype)
{
unsigned char *outbuf = 0;
int key_usage;
unsigned char acceptor_flag;
#ifdef CFX_EXERCISE
#endif
unsigned short tok_id;
if (ctx->have_acceptor_subkey) {
} else {
}
#ifdef _KERNEL
return (GSS_S_FAILURE);
}
#endif /* _KERNEL */
#ifdef CFX_EXERCISE
{
static int initialized = 0;
if (!initialized) {
initialized = 1;
}
}
#endif
/* 300: Adds some slop. */
return ENOMEM;
if (ec_max > 0xffff)
ec_max = 0xffff;
/*
* EC should really be a multiple (1) of the number of octets that
* the cryptosystem would pad by if we didn't have the filler.
*
* For AES-CTS this will always be 0 and we expect no further
* enctypes, so there should be no issue here.
*/
ec = 0;
return ENOMEM;
/* Get size of ciphertext. */
return (err);
}
/* Allocate space for header plus encrypted data. */
return ENOMEM;
}
/* TOK_ID */
/* flags */
| (conf_req_flag ? FLAG_WRAP_CONFIDENTIAL : 0)
/* filler */
/* EC */
/* RRC */
if (err)
goto error;
/* Now that we know we're returning a valid token.... */
#ifdef CFX_EXERCISE
/* If the rotate fails, don't worry about it. */
#endif
/* Here, message is the application-supplied data; message2 is
what goes into the output token. They may be the same, or
message2 may be empty (for MIC). */
tok_id = 0x0504;
return ENOMEM;
return EINVAL;
}
goto error;
}
/* TOK_ID */
/* flags */
/* filler */
if (toktype == KG_TOK_WRAP_MSG) {
/* Use 0 for checksum calculation, substitute
checksum length later. */
/* EC */
/* RRC */
} else {
/* MIC and DEL store 0xFF in EC and RRC. */
}
/* Fill in the output token -- data contents, if any, and
space for the checksum. */
if (err) {
goto error;
}
goto error;
}
ctx->cksum_size);
/* Now that we know we're actually generating the token... */
if (toktype == KG_TOK_WRAP_MSG) {
#ifdef CFX_EXERCISE
/* If the rotate fails, don't worry about it. */
#endif
/* Fix up EC field. */
} else {
}
} else if (toktype == KG_TOK_MIC_MSG) {
tok_id = 0x0404;
goto wrap_with_checksum;
} else if (toktype == KG_TOK_DEL_CTX) {
/*
* Solaris Kerberos:
* No token should be generated for context deletion. Just
* return.
*/
return 0;
} else {
goto error;
}
return 0;
return err;
}
/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
conf_state is only valid if SEAL. */
{
int key_usage;
unsigned char acceptor_flag;
if (qop_state)
/* Oops. I wrote this code assuming ptr would be at the start of
the token header. */
ptr -= 2;
bodysize += 2;
if (bodysize < 16) {
*minor_status = 0;
return GSS_S_DEFECTIVE_TOKEN;
}
return GSS_S_BAD_SIG;
}
/* Two things to note here.
First, we can't really enforce the use of the acceptor's subkey,
if we're the acceptor; the initiator may have sent messages
before getting the subkey. We could probably enforce it if
we're the initiator.
Second, if someone tweaks the code to not set the flag telling
the krb5 library to generate a new subkey in the AP-REP
message, the MIT library may include a subkey anyways --
namely, a copy of the AP-REQ subkey, if it was provided. So
the initiator may think we wanted a subkey, and set the flag,
even though we weren't trying to set the subkey. The "other"
key, the one not asserted by the acceptor, will have the same
value in that case, though, so we can just ignore the flag. */
} else {
}
#ifdef _KERNEL
return (GSS_S_FAILURE);
}
#endif /* _KERNEL */
if (toktype == KG_TOK_WRAP_MSG) {
goto defective;
goto defective;
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
/* confidentiality */
unsigned char *althdr;
if (conf_state)
*conf_state = 1;
/* Do we have no decrypt_size function?
For all current cryptosystems, the ciphertext size will
be larger than the plaintext size. */
goto no_mem;
if (err) {
goto error;
}
/* Don't use bodysize here! Use the fact that
plain.length has been adjusted to the
correct length. */
goto defective;
}
goto no_mem;
}
} else {
/* no confidentiality */
if (conf_state)
*conf_state = 0;
/* overflow check */
goto defective;
goto defective;
/* We have: header | msg | cksum.
We need cksum(msg | header).
Rotate the first two. */
goto no_mem;
*minor_status = 0;
return GSS_S_BAD_SIG;
}
if (err) {
*minor_status = err;
return GSS_S_BAD_SIG;
}
if (!valid) {
*minor_status = 0;
return GSS_S_BAD_SIG;
}
goto no_mem;
/*
* Solaris Kerberos: Restore the original token.
* This allows the token to be detected as a duplicate if it
* is passed in to gss_unwrap() again.
*/
goto no_mem;
}
*minor_status = 0;
return err;
} else if (toktype == KG_TOK_MIC_MSG) {
/* wrap token, no confidentiality */
goto defective;
goto defective;
goto defective;
goto no_mem;
if (message_buffer->length)
if (err) {
*minor_status = err;
return GSS_S_BAD_SIG; /* XXX */
}
if (!valid) {
*minor_status = 0;
return GSS_S_BAD_SIG;
}
*minor_status = 0;
return err;
} else if (toktype == KG_TOK_DEL_CTX) {
goto defective;
goto verify_mic_1;
} else {
goto defective;
}
}