k5unseal.c revision ae5b046d8f8cec187d40041c4b74b43f561d5ac7
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appears in all copies and
* that both that copyright notice and this permission notice appear in
* supporting documentation, and that the name of OpenVision not be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. OpenVision makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
* OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
* 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 FundsXpress. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
* permission. FundsXpress makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <gssapiP_krb5.h>
#include <k5-int.h>
/*
* $Id: k5unseal.c,v 1.19.6.2 2000/05/31 17:17:38 raeburn Exp $
*/
/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
conf_state is only valid if SEAL.
*/
unsigned char *ptr;
int bodysize;
int *conf_state;
int *qop_state;
int toktype;
{
int conflen = 0;
int signalg;
int sealalg;
char *data_ptr;
unsigned char *plain;
int cksum_len = 0;
int plainlen;
int direction;
int tmsglen;
/* Solaris Kerberos: make sure this is initialized */
*minor_status = 0;
if (toktype == KG_TOK_SEAL_MSG) {
message_buffer->length = 0;
}
/* get the sign and seal algorithms */
/* Sanity checks */
*minor_status = 0;
return GSS_S_DEFECTIVE_TOKEN;
}
if ((toktype != KG_TOK_SEAL_MSG) &&
(sealalg != 0xffff)) {
*minor_status = 0;
return GSS_S_DEFECTIVE_TOKEN;
}
/* in the current spec, there is only one valid seal algorithm per
key type, so a simple comparison is ok */
if ((toktype == KG_TOK_SEAL_MSG) &&
!((sealalg == 0xffff) ||
*minor_status = 0;
return GSS_S_DEFECTIVE_TOKEN;
}
/* there are several mappings of seal algorithms to sign algorithms,
but few enough that we can try them all. */
signalg != SGN_ALG_HMAC_SHA1_DES3_KD) ||
signalg != SGN_ALG_HMAC_MD5)) {
*minor_status = 0;
return GSS_S_DEFECTIVE_TOKEN;
}
switch (signalg) {
case SGN_ALG_DES_MAC_MD5:
case SGN_ALG_MD2_5:
case SGN_ALG_HMAC_MD5:
cksum_len = 8;
if (toktype != KG_TOK_SEAL_MSG)
sign_usage = 15;
break;
case SGN_ALG_3:
cksum_len = 16;
break;
cksum_len = 20;
break;
default:
*minor_status = 0;
return GSS_S_DEFECTIVE_TOKEN;
}
#ifdef _KERNEL
/*
* Because the ARCFOUR code bypasses the standard
* crypto interfaces, we must make sure the kernel
* crypto framework mechanism types are properly
* initialized here.
*/
*minor_status = code;
return (GSS_S_FAILURE);
}
*minor_status = code;
return (GSS_S_FAILURE);
}
#endif /* _KERNEL */
/* get the token parameters */
&seqnum))) {
*minor_status = code;
return(GSS_S_BAD_SIG);
}
/* decode the message, if SEAL */
if (toktype == KG_TOK_SEAL_MSG) {
if (sealalg != 0xffff) {
*minor_status = ENOMEM;
return(GSS_S_FAILURE);
}
unsigned char bigend_seqnum[4];
int i;
if (code)
{
*minor_status = code;
return(GSS_S_FAILURE);
}
for (i = 0; i <= 15; i++)
#ifndef _KERNEL
/*
* The enc_key contents were modified, delete the
* key object so it doesn't get used later.
*/
}
#endif
enc_key, 0,
&bigend_seqnum[0], 4,
plain);
} else {
}
if (code) {
*minor_status = code;
return(GSS_S_FAILURE);
}
} else {
}
} else {
/*
* Solaris Kerberos: we want to perform a sanity check on the
* pad length, so we know it can not be more than the blocksize.
*/
if (code != 0) {
if (sealalg != 0xffff)
*minor_status = code;
return(GSS_S_FAILURE);
}
if (sealalg != 0xffff)
return(GSS_S_FAILURE);
}
}
if (sealalg != 0xffff)
*minor_status = ENOMEM;
return(GSS_S_FAILURE);
}
} else {
}
} else if (toktype == KG_TOK_SIGN_MSG) {
token = *message_buffer;
} else {
}
/* compute the checksum of the message */
/* initialize the the cksum */
switch (signalg) {
case SGN_ALG_DES_MAC_MD5:
case SGN_ALG_MD2_5:
case SGN_ALG_DES_MAC:
case SGN_ALG_3:
break;
break;
case SGN_ALG_HMAC_MD5:
break;
default:
#ifndef _KERNEL
abort ();
#else
*minor_status = 0;
return(GSS_S_DEFECTIVE_TOKEN);
#endif /* _KERNEL */
}
&sumlen))
{
"code=%d\n", code);
return(code);
}
switch (signalg) {
case SGN_ALG_DES_MAC_MD5:
case SGN_ALG_3:
/* compute the checksum of the message */
/* 8 = bytes of token body to be checksummed according to spec */
if (! (data_ptr = (void *)
if (sealalg != 0xffff)
if (toktype == KG_TOK_SEAL_MSG) {
/* Solaris Kerberos: just to be safe since token.value is an
* output parameter.
*/
}
*minor_status = ENOMEM;
return(GSS_S_FAILURE);
}
if (ctx->big_endian)
else
if (code) {
if (toktype == KG_TOK_SEAL_MSG) {
/* Solaris Kerberos: just to be safe since token.value is an
* output parameter.
*/
}
*minor_status = code;
"error code = %d\n", code);
return(GSS_S_FAILURE);
}
if (toktype == KG_TOK_SEAL_MSG) {
/* Solaris Kerberos: just to be safe since token.value is an
* output parameter.
*/
}
*minor_status = code;
"code = %d\n", code);
return GSS_S_FAILURE;
}
if (signalg == 0)
else
break;
case SGN_ALG_MD2_5:
if (sealalg != 0xffff)
if (toktype == KG_TOK_SEAL_MSG) {
/* Solaris Kerberos: just to be safe since token.value is an
* output parameter.
*/
}
*minor_status = code;
return GSS_S_FAILURE;
}
if (! (data_ptr = (void *)
if (sealalg == 0)
if (toktype == KG_TOK_SEAL_MSG) {
/* Solaris Kerberos: just to be safe since token.value is an
* output parameter.
*/
}
*minor_status = ENOMEM;
return(GSS_S_FAILURE);
}
if (ctx->big_endian)
else
if (code) {
if (sealalg == 0)
if (toktype == KG_TOK_SEAL_MSG) {
/* Solaris Kerberos: just to be safe since token.value is an
* output parameter.
*/
}
*minor_status = code;
return(GSS_S_FAILURE);
}
/* Falls through to defective-token?? */
default:
*minor_status = 0;
"GSS_S_DEFECTIVE_TOKEN\n");
return(GSS_S_DEFECTIVE_TOKEN);
case SGN_ALG_HMAC_MD5:
/* compute the checksum of the message */
/* 8 = bytes of token body to be checksummed according to spec */
if (! (data_ptr = (void *)
if (sealalg != 0xffff)
if (toktype == KG_TOK_SEAL_MSG) {
/* Solaris Kerberos: just to be safe since token.value is an
* output parameter.
*/
}
*minor_status = ENOMEM;
return(GSS_S_FAILURE);
}
if (ctx->big_endian) {
}
else {
}
if (code) {
if (toktype == KG_TOK_SEAL_MSG) {
/* Solaris Kerberos: just to be safe since token.value is an
* output parameter.
*/
}
*minor_status = code;
"SGN_ALG_HMAC_SHA1_DES3_KD GSS_S_FAILURE\n");
return(GSS_S_FAILURE);
}
/* compare the computed checksum against the transmitted checksum */
break;
}
if (sealalg != 0xffff)
if (code) {
if (toktype == KG_TOK_SEAL_MSG) {
/* Solaris Kerberos: just to be safe since token.value is an
* output parameter.
*/
}
*minor_status = 0;
return(GSS_S_BAD_SIG);
}
if (conf_state)
if (qop_state)
*minor_status = code;
"error code = %d\n", code);
return(GSS_S_FAILURE);
}
*minor_status = 0;
return(GSS_S_CONTEXT_EXPIRED);
}
/* do sequencing checks */
if (toktype == KG_TOK_SEAL_MSG) {
/* Solaris Kerberos: just to be safe since token.value is an
* output parameter.
*/
}
"G_BAD_DIRECTION ctx->initiate = %d "
return(GSS_S_BAD_SIG);
}
/* It got through unscathed, adjust the output message buffer. */
*message_buffer = token;
*minor_status = 0;
return(retval);
}
/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
conf_state is only valid if SEAL. */
int *conf_state;
int *qop_state;
int toktype;
{
unsigned char *ptr;
int bodysize;
int err;
int toktype2;
/* validate the context handle */
if (! kg_validate_ctx_id(context_handle)) {
"G_VALIDATE_FAILED \n");
return(GSS_S_NO_CONTEXT);
}
if (! ctx->established) {
return(GSS_S_NO_CONTEXT);
}
/* parse the token, leave the data in message_buffer, setting conf_state */
/* verify the header */
switch (toktype) {
case KG_TOK_SIGN_MSG:
toktype2 = 0x0404;
break;
case KG_TOK_SEAL_MSG:
toktype2 = 0x0504;
break;
case KG_TOK_DEL_CTX:
toktype2 = 0x0405;
break;
default:
break;
}
else
if (err) {
*minor_status = err;
return GSS_S_DEFECTIVE_TOKEN;
}
toktype);
} else {
}
*minor_status = err;
return(err);
}