1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 7*7c478bd9Sstevel@tonic-gate 8*7c478bd9Sstevel@tonic-gate /* 9*7c478bd9Sstevel@tonic-gate * Copyright 1993 by OpenVision Technologies, Inc. 10*7c478bd9Sstevel@tonic-gate * 11*7c478bd9Sstevel@tonic-gate * Permission to use, copy, modify, distribute, and sell this software 12*7c478bd9Sstevel@tonic-gate * and its documentation for any purpose is hereby granted without fee, 13*7c478bd9Sstevel@tonic-gate * provided that the above copyright notice appears in all copies and 14*7c478bd9Sstevel@tonic-gate * that both that copyright notice and this permission notice appear in 15*7c478bd9Sstevel@tonic-gate * supporting documentation, and that the name of OpenVision not be used 16*7c478bd9Sstevel@tonic-gate * in advertising or publicity pertaining to distribution of the software 17*7c478bd9Sstevel@tonic-gate * without specific, written prior permission. OpenVision makes no 18*7c478bd9Sstevel@tonic-gate * representations about the suitability of this software for any 19*7c478bd9Sstevel@tonic-gate * purpose. It is provided "as is" without express or implied warranty. 20*7c478bd9Sstevel@tonic-gate * 21*7c478bd9Sstevel@tonic-gate * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 22*7c478bd9Sstevel@tonic-gate * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 23*7c478bd9Sstevel@tonic-gate * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR 24*7c478bd9Sstevel@tonic-gate * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 25*7c478bd9Sstevel@tonic-gate * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 26*7c478bd9Sstevel@tonic-gate * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 27*7c478bd9Sstevel@tonic-gate * PERFORMANCE OF THIS SOFTWARE. 28*7c478bd9Sstevel@tonic-gate */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate /* 31*7c478bd9Sstevel@tonic-gate * Copyright (C) 1998 by the FundsXpress, INC. 32*7c478bd9Sstevel@tonic-gate * 33*7c478bd9Sstevel@tonic-gate * All rights reserved. 34*7c478bd9Sstevel@tonic-gate * 35*7c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may require 36*7c478bd9Sstevel@tonic-gate * a specific license from the United States Government. It is the 37*7c478bd9Sstevel@tonic-gate * responsibility of any person or organization contemplating export to 38*7c478bd9Sstevel@tonic-gate * obtain such a license before exporting. 39*7c478bd9Sstevel@tonic-gate * 40*7c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 41*7c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 42*7c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 43*7c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 44*7c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 45*7c478bd9Sstevel@tonic-gate * the name of FundsXpress. not be used in advertising or publicity pertaining 46*7c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior 47*7c478bd9Sstevel@tonic-gate * permission. FundsXpress makes no representations about the suitability of 48*7c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 49*7c478bd9Sstevel@tonic-gate * or implied warranty. 50*7c478bd9Sstevel@tonic-gate * 51*7c478bd9Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 52*7c478bd9Sstevel@tonic-gate * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 53*7c478bd9Sstevel@tonic-gate * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 54*7c478bd9Sstevel@tonic-gate */ 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate #include <gssapiP_krb5.h> 57*7c478bd9Sstevel@tonic-gate #include <k5-int.h> 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate /* 60*7c478bd9Sstevel@tonic-gate * $Id: k5unseal.c,v 1.19.6.2 2000/05/31 17:17:38 raeburn Exp $ 61*7c478bd9Sstevel@tonic-gate */ 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate /* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX 64*7c478bd9Sstevel@tonic-gate conf_state is only valid if SEAL. 65*7c478bd9Sstevel@tonic-gate */ 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate OM_uint32 68*7c478bd9Sstevel@tonic-gate kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer, 69*7c478bd9Sstevel@tonic-gate conf_state, qop_state, toktype) 70*7c478bd9Sstevel@tonic-gate krb5_context context; 71*7c478bd9Sstevel@tonic-gate OM_uint32 *minor_status; 72*7c478bd9Sstevel@tonic-gate krb5_gss_ctx_id_rec *ctx; 73*7c478bd9Sstevel@tonic-gate unsigned char *ptr; 74*7c478bd9Sstevel@tonic-gate int bodysize; 75*7c478bd9Sstevel@tonic-gate gss_buffer_t message_buffer; 76*7c478bd9Sstevel@tonic-gate int *conf_state; 77*7c478bd9Sstevel@tonic-gate int *qop_state; 78*7c478bd9Sstevel@tonic-gate int toktype; 79*7c478bd9Sstevel@tonic-gate { 80*7c478bd9Sstevel@tonic-gate krb5_error_code code; 81*7c478bd9Sstevel@tonic-gate int conflen = 0; 82*7c478bd9Sstevel@tonic-gate int signalg; 83*7c478bd9Sstevel@tonic-gate int sealalg; 84*7c478bd9Sstevel@tonic-gate gss_buffer_desc token; 85*7c478bd9Sstevel@tonic-gate krb5_checksum cksum; 86*7c478bd9Sstevel@tonic-gate krb5_checksum md5cksum; 87*7c478bd9Sstevel@tonic-gate krb5_data plaind; 88*7c478bd9Sstevel@tonic-gate char *data_ptr; 89*7c478bd9Sstevel@tonic-gate krb5_timestamp now; 90*7c478bd9Sstevel@tonic-gate unsigned char *plain; 91*7c478bd9Sstevel@tonic-gate int cksum_len = 0; 92*7c478bd9Sstevel@tonic-gate int plainlen; 93*7c478bd9Sstevel@tonic-gate int direction; 94*7c478bd9Sstevel@tonic-gate krb5_ui_4 seqnum; 95*7c478bd9Sstevel@tonic-gate OM_uint32 retval; 96*7c478bd9Sstevel@tonic-gate size_t sumlen; 97*7c478bd9Sstevel@tonic-gate int tmsglen; 98*7c478bd9Sstevel@tonic-gate krb5_keyusage sign_usage = KG_USAGE_SIGN; 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_INFO, "kg_unseal_v1() start\n"); 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate /* Solaris Kerberos: make sure this is initialized */ 103*7c478bd9Sstevel@tonic-gate *minor_status = 0; 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate if (toktype == KG_TOK_SEAL_MSG) { 106*7c478bd9Sstevel@tonic-gate message_buffer->length = 0; 107*7c478bd9Sstevel@tonic-gate message_buffer->value = NULL; 108*7c478bd9Sstevel@tonic-gate } 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate /* get the sign and seal algorithms */ 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate signalg = ptr[0] + (ptr[1]<<8); 113*7c478bd9Sstevel@tonic-gate sealalg = ptr[2] + (ptr[3]<<8); 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate /* Sanity checks */ 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) { 118*7c478bd9Sstevel@tonic-gate *minor_status = 0; 119*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR, "kg_unseal_v1() end, error GSS_S_DEFECTIVE_TOKEN\n"); 120*7c478bd9Sstevel@tonic-gate return GSS_S_DEFECTIVE_TOKEN; 121*7c478bd9Sstevel@tonic-gate } 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate if ((toktype != KG_TOK_SEAL_MSG) && 124*7c478bd9Sstevel@tonic-gate (sealalg != 0xffff)) { 125*7c478bd9Sstevel@tonic-gate *minor_status = 0; 126*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR, "kg_unseal_v1() end, error2 GSS_S_DEFECTIVE_TOKEN\n"); 127*7c478bd9Sstevel@tonic-gate return GSS_S_DEFECTIVE_TOKEN; 128*7c478bd9Sstevel@tonic-gate } 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate /* in the current spec, there is only one valid seal algorithm per 131*7c478bd9Sstevel@tonic-gate key type, so a simple comparison is ok */ 132*7c478bd9Sstevel@tonic-gate 133*7c478bd9Sstevel@tonic-gate if ((toktype == KG_TOK_SEAL_MSG) && 134*7c478bd9Sstevel@tonic-gate !((sealalg == 0xffff) || 135*7c478bd9Sstevel@tonic-gate (sealalg == ctx->sealalg))) { 136*7c478bd9Sstevel@tonic-gate *minor_status = 0; 137*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR, "kg_unseal_v1() end, error3 GSS_S_DEFECTIVE_TOKEN\n"); 138*7c478bd9Sstevel@tonic-gate return GSS_S_DEFECTIVE_TOKEN; 139*7c478bd9Sstevel@tonic-gate } 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate /* there are several mappings of seal algorithms to sign algorithms, 142*7c478bd9Sstevel@tonic-gate but few enough that we can try them all. */ 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate if ((ctx->sealalg == SEAL_ALG_NONE && signalg > 1) || 145*7c478bd9Sstevel@tonic-gate (ctx->sealalg == SEAL_ALG_1 && signalg != SGN_ALG_3) || 146*7c478bd9Sstevel@tonic-gate (ctx->sealalg == SEAL_ALG_DES3KD && 147*7c478bd9Sstevel@tonic-gate signalg != SGN_ALG_HMAC_SHA1_DES3_KD) || 148*7c478bd9Sstevel@tonic-gate (ctx->sealalg == SEAL_ALG_MICROSOFT_RC4 && 149*7c478bd9Sstevel@tonic-gate signalg != SGN_ALG_HMAC_MD5)) { 150*7c478bd9Sstevel@tonic-gate *minor_status = 0; 151*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR, "kg_unseal_v1() end, error4 GSS_S_DEFECTIVE_TOKEN\n"); 152*7c478bd9Sstevel@tonic-gate return GSS_S_DEFECTIVE_TOKEN; 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_INFO, "kg_unseal_v1() signalg = %d\n", signalg); 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate switch (signalg) { 158*7c478bd9Sstevel@tonic-gate case SGN_ALG_DES_MAC_MD5: 159*7c478bd9Sstevel@tonic-gate case SGN_ALG_MD2_5: 160*7c478bd9Sstevel@tonic-gate case SGN_ALG_HMAC_MD5: 161*7c478bd9Sstevel@tonic-gate cksum_len = 8; 162*7c478bd9Sstevel@tonic-gate if (toktype != KG_TOK_SEAL_MSG) 163*7c478bd9Sstevel@tonic-gate sign_usage = 15; 164*7c478bd9Sstevel@tonic-gate break; 165*7c478bd9Sstevel@tonic-gate case SGN_ALG_3: 166*7c478bd9Sstevel@tonic-gate cksum_len = 16; 167*7c478bd9Sstevel@tonic-gate break; 168*7c478bd9Sstevel@tonic-gate case SGN_ALG_HMAC_SHA1_DES3_KD: 169*7c478bd9Sstevel@tonic-gate cksum_len = 20; 170*7c478bd9Sstevel@tonic-gate break; 171*7c478bd9Sstevel@tonic-gate default: 172*7c478bd9Sstevel@tonic-gate *minor_status = 0; 173*7c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "kg_unseal_v1() end, error signalg=%d\n", signalg); 174*7c478bd9Sstevel@tonic-gate return GSS_S_DEFECTIVE_TOKEN; 175*7c478bd9Sstevel@tonic-gate } 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL 178*7c478bd9Sstevel@tonic-gate /* 179*7c478bd9Sstevel@tonic-gate * Because the ARCFOUR code bypasses the standard 180*7c478bd9Sstevel@tonic-gate * crypto interfaces, we must make sure the kernel 181*7c478bd9Sstevel@tonic-gate * crypto framework mechanism types are properly 182*7c478bd9Sstevel@tonic-gate * initialized here. 183*7c478bd9Sstevel@tonic-gate */ 184*7c478bd9Sstevel@tonic-gate context->kef_cipher_mt = get_cipher_mech_type(context, 185*7c478bd9Sstevel@tonic-gate ctx->seq); 186*7c478bd9Sstevel@tonic-gate context->kef_hash_mt = get_hash_mech_type(context, 187*7c478bd9Sstevel@tonic-gate ctx->seq); 188*7c478bd9Sstevel@tonic-gate if ((code = init_key_kef(context->kef_cipher_mt, 189*7c478bd9Sstevel@tonic-gate ctx->seq))) { 190*7c478bd9Sstevel@tonic-gate *minor_status = code; 191*7c478bd9Sstevel@tonic-gate return (GSS_S_FAILURE); 192*7c478bd9Sstevel@tonic-gate } 193*7c478bd9Sstevel@tonic-gate if ((code = init_key_kef(context->kef_cipher_mt, 194*7c478bd9Sstevel@tonic-gate ctx->enc))) { 195*7c478bd9Sstevel@tonic-gate *minor_status = code; 196*7c478bd9Sstevel@tonic-gate return (GSS_S_FAILURE); 197*7c478bd9Sstevel@tonic-gate } 198*7c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate /* get the token parameters */ 201*7c478bd9Sstevel@tonic-gate if ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction, 202*7c478bd9Sstevel@tonic-gate &seqnum))) { 203*7c478bd9Sstevel@tonic-gate *minor_status = code; 204*7c478bd9Sstevel@tonic-gate return(GSS_S_BAD_SIG); 205*7c478bd9Sstevel@tonic-gate } 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate /* decode the message, if SEAL */ 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate if (toktype == KG_TOK_SEAL_MSG) { 210*7c478bd9Sstevel@tonic-gate tmsglen = bodysize-(14+cksum_len); 211*7c478bd9Sstevel@tonic-gate KRB5_LOG1(KRB5_INFO, "kg_unseal_v1() tmsglen = %d cksum_len = %d", 212*7c478bd9Sstevel@tonic-gate tmsglen, cksum_len); 213*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_INFO, "kg_unseal_v1() toktype == KG_TOK_SEAL_MSG\n"); 214*7c478bd9Sstevel@tonic-gate 215*7c478bd9Sstevel@tonic-gate if (sealalg != 0xffff) { 216*7c478bd9Sstevel@tonic-gate if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) { 217*7c478bd9Sstevel@tonic-gate *minor_status = ENOMEM; 218*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR, "kg_unseal_v1() end, error ENOMEM\n"); 219*7c478bd9Sstevel@tonic-gate return(GSS_S_FAILURE); 220*7c478bd9Sstevel@tonic-gate } 221*7c478bd9Sstevel@tonic-gate if (ctx->enc->enctype == ENCTYPE_ARCFOUR_HMAC) { 222*7c478bd9Sstevel@tonic-gate unsigned char bigend_seqnum[4]; 223*7c478bd9Sstevel@tonic-gate krb5_keyblock *enc_key; 224*7c478bd9Sstevel@tonic-gate int i; 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate bigend_seqnum[0] = (seqnum>>24) & 0xff; 227*7c478bd9Sstevel@tonic-gate bigend_seqnum[1] = (seqnum>>16) & 0xff; 228*7c478bd9Sstevel@tonic-gate bigend_seqnum[2] = (seqnum>>8) & 0xff; 229*7c478bd9Sstevel@tonic-gate bigend_seqnum[3] = seqnum & 0xff; 230*7c478bd9Sstevel@tonic-gate code = krb5_copy_keyblock (context, ctx->enc, &enc_key); 231*7c478bd9Sstevel@tonic-gate if (code) 232*7c478bd9Sstevel@tonic-gate { 233*7c478bd9Sstevel@tonic-gate xfree_wrap(plain, tmsglen); 234*7c478bd9Sstevel@tonic-gate *minor_status = code; 235*7c478bd9Sstevel@tonic-gate return(GSS_S_FAILURE); 236*7c478bd9Sstevel@tonic-gate } 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate for (i = 0; i <= 15; i++) 239*7c478bd9Sstevel@tonic-gate ((char *) enc_key->contents)[i] ^=0xf0; 240*7c478bd9Sstevel@tonic-gate 241*7c478bd9Sstevel@tonic-gate #ifndef _KERNEL 242*7c478bd9Sstevel@tonic-gate /* 243*7c478bd9Sstevel@tonic-gate * The enc_key contents were modified, delete the 244*7c478bd9Sstevel@tonic-gate * key object so it doesn't get used later. 245*7c478bd9Sstevel@tonic-gate */ 246*7c478bd9Sstevel@tonic-gate if (enc_key->hKey != CK_INVALID_HANDLE) { 247*7c478bd9Sstevel@tonic-gate (void)C_DestroyObject(krb_ctx_hSession(context), 248*7c478bd9Sstevel@tonic-gate enc_key->hKey); 249*7c478bd9Sstevel@tonic-gate enc_key->hKey = CK_INVALID_HANDLE; 250*7c478bd9Sstevel@tonic-gate } 251*7c478bd9Sstevel@tonic-gate #endif 252*7c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_INFO, "kg_unseal_v1() enc_key->enctype = %d", 253*7c478bd9Sstevel@tonic-gate enc_key->enctype); 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate code = kg_arcfour_docrypt (context, 256*7c478bd9Sstevel@tonic-gate enc_key, 0, 257*7c478bd9Sstevel@tonic-gate &bigend_seqnum[0], 4, 258*7c478bd9Sstevel@tonic-gate ptr+14+cksum_len, tmsglen, 259*7c478bd9Sstevel@tonic-gate plain); 260*7c478bd9Sstevel@tonic-gate krb5_free_keyblock (context, enc_key); 261*7c478bd9Sstevel@tonic-gate } else { 262*7c478bd9Sstevel@tonic-gate code = kg_decrypt(context, ctx->enc, KG_USAGE_SEAL, NULL, 263*7c478bd9Sstevel@tonic-gate ptr+14+cksum_len, plain, tmsglen); 264*7c478bd9Sstevel@tonic-gate } 265*7c478bd9Sstevel@tonic-gate if (code) { 266*7c478bd9Sstevel@tonic-gate xfree_wrap(plain, tmsglen); 267*7c478bd9Sstevel@tonic-gate *minor_status = code; 268*7c478bd9Sstevel@tonic-gate return(GSS_S_FAILURE); 269*7c478bd9Sstevel@tonic-gate } 270*7c478bd9Sstevel@tonic-gate } else { 271*7c478bd9Sstevel@tonic-gate plain = ptr+14+cksum_len; 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate plainlen = tmsglen; 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate if ((sealalg == 0xffff) && ctx->big_endian) { 277*7c478bd9Sstevel@tonic-gate token.length = tmsglen; 278*7c478bd9Sstevel@tonic-gate } else { 279*7c478bd9Sstevel@tonic-gate conflen = kg_confounder_size(context, ctx->enc); 280*7c478bd9Sstevel@tonic-gate token.length = tmsglen - conflen - plain[tmsglen-1]; 281*7c478bd9Sstevel@tonic-gate } 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gate if (token.length) { 284*7c478bd9Sstevel@tonic-gate if ((token.value = (void *) xmalloc(token.length)) == NULL) { 285*7c478bd9Sstevel@tonic-gate if (sealalg != 0xffff) 286*7c478bd9Sstevel@tonic-gate xfree_wrap(plain, tmsglen); 287*7c478bd9Sstevel@tonic-gate *minor_status = ENOMEM; 288*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR, "kg_unseal_v1() end, error2 ENOMEM\n"); 289*7c478bd9Sstevel@tonic-gate return(GSS_S_FAILURE); 290*7c478bd9Sstevel@tonic-gate } 291*7c478bd9Sstevel@tonic-gate (void) memcpy(token.value, plain+conflen, token.length); 292*7c478bd9Sstevel@tonic-gate } else { 293*7c478bd9Sstevel@tonic-gate token.value = NULL; 294*7c478bd9Sstevel@tonic-gate } 295*7c478bd9Sstevel@tonic-gate } else if (toktype == KG_TOK_SIGN_MSG) { 296*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_INFO, "kg_unseal_v1() toktype == KG_TOK_SIGN_MSG\n"); 297*7c478bd9Sstevel@tonic-gate token = *message_buffer; 298*7c478bd9Sstevel@tonic-gate plain = token.value; 299*7c478bd9Sstevel@tonic-gate plainlen = token.length; 300*7c478bd9Sstevel@tonic-gate } else { 301*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_INFO, "kg_unseal_v1() toktype == NULL\n"); 302*7c478bd9Sstevel@tonic-gate token.length = 0; 303*7c478bd9Sstevel@tonic-gate token.value = NULL; 304*7c478bd9Sstevel@tonic-gate plain = token.value; 305*7c478bd9Sstevel@tonic-gate plainlen = token.length; 306*7c478bd9Sstevel@tonic-gate } 307*7c478bd9Sstevel@tonic-gate 308*7c478bd9Sstevel@tonic-gate /* compute the checksum of the message */ 309*7c478bd9Sstevel@tonic-gate 310*7c478bd9Sstevel@tonic-gate /* initialize the the cksum */ 311*7c478bd9Sstevel@tonic-gate switch (signalg) { 312*7c478bd9Sstevel@tonic-gate case SGN_ALG_DES_MAC_MD5: 313*7c478bd9Sstevel@tonic-gate case SGN_ALG_MD2_5: 314*7c478bd9Sstevel@tonic-gate case SGN_ALG_DES_MAC: 315*7c478bd9Sstevel@tonic-gate case SGN_ALG_3: 316*7c478bd9Sstevel@tonic-gate md5cksum.checksum_type = CKSUMTYPE_RSA_MD5; 317*7c478bd9Sstevel@tonic-gate break; 318*7c478bd9Sstevel@tonic-gate case SGN_ALG_HMAC_SHA1_DES3_KD: 319*7c478bd9Sstevel@tonic-gate md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3; 320*7c478bd9Sstevel@tonic-gate break; 321*7c478bd9Sstevel@tonic-gate case SGN_ALG_HMAC_MD5: 322*7c478bd9Sstevel@tonic-gate md5cksum.checksum_type = CKSUMTYPE_HMAC_MD5_ARCFOUR; 323*7c478bd9Sstevel@tonic-gate break; 324*7c478bd9Sstevel@tonic-gate default: 325*7c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "kg_unseal_v1() end, error2 signalg=%d\n", signalg); 326*7c478bd9Sstevel@tonic-gate #ifndef _KERNEL 327*7c478bd9Sstevel@tonic-gate abort (); 328*7c478bd9Sstevel@tonic-gate #else 329*7c478bd9Sstevel@tonic-gate *minor_status = 0; 330*7c478bd9Sstevel@tonic-gate return(GSS_S_DEFECTIVE_TOKEN); 331*7c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 332*7c478bd9Sstevel@tonic-gate } 333*7c478bd9Sstevel@tonic-gate 334*7c478bd9Sstevel@tonic-gate if (code = krb5_c_checksum_length(context, md5cksum.checksum_type, 335*7c478bd9Sstevel@tonic-gate &sumlen)) 336*7c478bd9Sstevel@tonic-gate { 337*7c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "kg_unseal_v1() end, krb5_c_checksum_length() error " 338*7c478bd9Sstevel@tonic-gate "code=%d\n", code); 339*7c478bd9Sstevel@tonic-gate return(code); 340*7c478bd9Sstevel@tonic-gate } 341*7c478bd9Sstevel@tonic-gate md5cksum.length = (size_t)sumlen; 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate switch (signalg) { 344*7c478bd9Sstevel@tonic-gate case SGN_ALG_DES_MAC_MD5: 345*7c478bd9Sstevel@tonic-gate case SGN_ALG_3: 346*7c478bd9Sstevel@tonic-gate /* compute the checksum of the message */ 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate /* 8 = bytes of token body to be checksummed according to spec */ 349*7c478bd9Sstevel@tonic-gate 350*7c478bd9Sstevel@tonic-gate if (! (data_ptr = (void *) 351*7c478bd9Sstevel@tonic-gate xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) { 352*7c478bd9Sstevel@tonic-gate if (sealalg != 0xffff) 353*7c478bd9Sstevel@tonic-gate xfree_wrap(plain, tmsglen); 354*7c478bd9Sstevel@tonic-gate if (toktype == KG_TOK_SEAL_MSG) { 355*7c478bd9Sstevel@tonic-gate xfree_wrap(token.value, token.length); 356*7c478bd9Sstevel@tonic-gate /* Solaris Kerberos: just to be safe since token.value is an 357*7c478bd9Sstevel@tonic-gate * output parameter. 358*7c478bd9Sstevel@tonic-gate */ 359*7c478bd9Sstevel@tonic-gate token.value = NULL; 360*7c478bd9Sstevel@tonic-gate token.length = 0; 361*7c478bd9Sstevel@tonic-gate } 362*7c478bd9Sstevel@tonic-gate *minor_status = ENOMEM; 363*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR, "kg_unseal_v1() end, error3 ENOMEM\n"); 364*7c478bd9Sstevel@tonic-gate return(GSS_S_FAILURE); 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate (void) memcpy(data_ptr, ptr-2, 8); 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate if (ctx->big_endian) 370*7c478bd9Sstevel@tonic-gate (void) memcpy(data_ptr+8, token.value, token.length); 371*7c478bd9Sstevel@tonic-gate else 372*7c478bd9Sstevel@tonic-gate (void) memcpy(data_ptr+8, plain, plainlen); 373*7c478bd9Sstevel@tonic-gate 374*7c478bd9Sstevel@tonic-gate plaind.length = 8 + (ctx->big_endian ? token.length : plainlen); 375*7c478bd9Sstevel@tonic-gate plaind.data = data_ptr; 376*7c478bd9Sstevel@tonic-gate code = krb5_c_make_checksum(context, md5cksum.checksum_type, 377*7c478bd9Sstevel@tonic-gate ctx->seq, sign_usage, 378*7c478bd9Sstevel@tonic-gate &plaind, &md5cksum); 379*7c478bd9Sstevel@tonic-gate xfree_wrap(data_ptr, 8 + (ctx->big_endian ? token.length : plainlen)); 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate if (code) { 382*7c478bd9Sstevel@tonic-gate if (toktype == KG_TOK_SEAL_MSG) { 383*7c478bd9Sstevel@tonic-gate xfree_wrap(token.value, token.length); 384*7c478bd9Sstevel@tonic-gate /* Solaris Kerberos: just to be safe since token.value is an 385*7c478bd9Sstevel@tonic-gate * output parameter. 386*7c478bd9Sstevel@tonic-gate */ 387*7c478bd9Sstevel@tonic-gate token.value = NULL; 388*7c478bd9Sstevel@tonic-gate token.length = 0; 389*7c478bd9Sstevel@tonic-gate } 390*7c478bd9Sstevel@tonic-gate *minor_status = code; 391*7c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "kg_unseal_v1() end, krb5_c_make_checksum() " 392*7c478bd9Sstevel@tonic-gate "error code = %d\n", code); 393*7c478bd9Sstevel@tonic-gate return(GSS_S_FAILURE); 394*7c478bd9Sstevel@tonic-gate } 395*7c478bd9Sstevel@tonic-gate 396*7c478bd9Sstevel@tonic-gate if ((code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL, 397*7c478bd9Sstevel@tonic-gate (g_OID_equal(&ctx->mech_used, gss_mech_krb5_old) ? 398*7c478bd9Sstevel@tonic-gate ctx->seq->contents : NULL), 399*7c478bd9Sstevel@tonic-gate md5cksum.contents, md5cksum.contents, 16))) { 400*7c478bd9Sstevel@tonic-gate xfree_wrap(md5cksum.contents, md5cksum.length); 401*7c478bd9Sstevel@tonic-gate if (toktype == KG_TOK_SEAL_MSG) { 402*7c478bd9Sstevel@tonic-gate xfree_wrap(token.value, token.length); 403*7c478bd9Sstevel@tonic-gate /* Solaris Kerberos: just to be safe since token.value is an 404*7c478bd9Sstevel@tonic-gate * output parameter. 405*7c478bd9Sstevel@tonic-gate */ 406*7c478bd9Sstevel@tonic-gate token.value = NULL; 407*7c478bd9Sstevel@tonic-gate token.length = 0; 408*7c478bd9Sstevel@tonic-gate } 409*7c478bd9Sstevel@tonic-gate *minor_status = code; 410*7c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "kg_unseal_v1() end, kg_encrypt() error" 411*7c478bd9Sstevel@tonic-gate "code = %d\n", code); 412*7c478bd9Sstevel@tonic-gate return GSS_S_FAILURE; 413*7c478bd9Sstevel@tonic-gate } 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate if (signalg == 0) 416*7c478bd9Sstevel@tonic-gate cksum.length = 8; 417*7c478bd9Sstevel@tonic-gate else 418*7c478bd9Sstevel@tonic-gate cksum.length = 16; 419*7c478bd9Sstevel@tonic-gate cksum.contents = md5cksum.contents + 16 - cksum.length; 420*7c478bd9Sstevel@tonic-gate 421*7c478bd9Sstevel@tonic-gate code = memcmp(cksum.contents, ptr+14, cksum.length); 422*7c478bd9Sstevel@tonic-gate break; 423*7c478bd9Sstevel@tonic-gate 424*7c478bd9Sstevel@tonic-gate case SGN_ALG_MD2_5: 425*7c478bd9Sstevel@tonic-gate if (!ctx->seed_init && 426*7c478bd9Sstevel@tonic-gate (code = kg_make_seed(context, ctx->subkey, ctx->seed))) { 427*7c478bd9Sstevel@tonic-gate xfree_wrap(md5cksum.contents, md5cksum.length); 428*7c478bd9Sstevel@tonic-gate if (sealalg != 0xffff) 429*7c478bd9Sstevel@tonic-gate xfree_wrap(plain, tmsglen); 430*7c478bd9Sstevel@tonic-gate if (toktype == KG_TOK_SEAL_MSG) { 431*7c478bd9Sstevel@tonic-gate xfree_wrap(token.value, token.length); 432*7c478bd9Sstevel@tonic-gate /* Solaris Kerberos: just to be safe since token.value is an 433*7c478bd9Sstevel@tonic-gate * output parameter. 434*7c478bd9Sstevel@tonic-gate */ 435*7c478bd9Sstevel@tonic-gate token.value = NULL; 436*7c478bd9Sstevel@tonic-gate token.length = 0; 437*7c478bd9Sstevel@tonic-gate } 438*7c478bd9Sstevel@tonic-gate *minor_status = code; 439*7c478bd9Sstevel@tonic-gate return GSS_S_FAILURE; 440*7c478bd9Sstevel@tonic-gate } 441*7c478bd9Sstevel@tonic-gate 442*7c478bd9Sstevel@tonic-gate if (! (data_ptr = (void *) 443*7c478bd9Sstevel@tonic-gate xmalloc(sizeof(ctx->seed) + 8 + 444*7c478bd9Sstevel@tonic-gate (ctx->big_endian ? token.length : plainlen)))) { 445*7c478bd9Sstevel@tonic-gate xfree_wrap(md5cksum.contents, md5cksum.length); 446*7c478bd9Sstevel@tonic-gate if (sealalg == 0) 447*7c478bd9Sstevel@tonic-gate xfree_wrap(plain, tmsglen); 448*7c478bd9Sstevel@tonic-gate if (toktype == KG_TOK_SEAL_MSG) { 449*7c478bd9Sstevel@tonic-gate xfree_wrap(token.value, token.length); 450*7c478bd9Sstevel@tonic-gate /* Solaris Kerberos: just to be safe since token.value is an 451*7c478bd9Sstevel@tonic-gate * output parameter. 452*7c478bd9Sstevel@tonic-gate */ 453*7c478bd9Sstevel@tonic-gate token.value = NULL; 454*7c478bd9Sstevel@tonic-gate token.length = 0; 455*7c478bd9Sstevel@tonic-gate } 456*7c478bd9Sstevel@tonic-gate *minor_status = ENOMEM; 457*7c478bd9Sstevel@tonic-gate return(GSS_S_FAILURE); 458*7c478bd9Sstevel@tonic-gate } 459*7c478bd9Sstevel@tonic-gate (void) memcpy(data_ptr, ptr-2, 8); 460*7c478bd9Sstevel@tonic-gate (void) memcpy(data_ptr+8, ctx->seed, sizeof(ctx->seed)); 461*7c478bd9Sstevel@tonic-gate if (ctx->big_endian) 462*7c478bd9Sstevel@tonic-gate (void) memcpy(data_ptr+8+sizeof(ctx->seed), 463*7c478bd9Sstevel@tonic-gate token.value, token.length); 464*7c478bd9Sstevel@tonic-gate else 465*7c478bd9Sstevel@tonic-gate (void) memcpy(data_ptr+8+sizeof(ctx->seed), 466*7c478bd9Sstevel@tonic-gate plain, plainlen); 467*7c478bd9Sstevel@tonic-gate plaind.length = 8 + sizeof(ctx->seed) + 468*7c478bd9Sstevel@tonic-gate (ctx->big_endian ? token.length : plainlen); 469*7c478bd9Sstevel@tonic-gate plaind.data = data_ptr; 470*7c478bd9Sstevel@tonic-gate xfree_wrap(md5cksum.contents, md5cksum.length); 471*7c478bd9Sstevel@tonic-gate code = krb5_c_make_checksum(context, md5cksum.checksum_type, 472*7c478bd9Sstevel@tonic-gate ctx->seq, KG_USAGE_SIGN, 473*7c478bd9Sstevel@tonic-gate &plaind, &md5cksum); 474*7c478bd9Sstevel@tonic-gate xfree_wrap(data_ptr, 8 + sizeof(ctx->seed) + 475*7c478bd9Sstevel@tonic-gate (ctx->big_endian ? token.length : plainlen)); 476*7c478bd9Sstevel@tonic-gate 477*7c478bd9Sstevel@tonic-gate if (code) { 478*7c478bd9Sstevel@tonic-gate if (sealalg == 0) 479*7c478bd9Sstevel@tonic-gate xfree_wrap(plain, tmsglen); 480*7c478bd9Sstevel@tonic-gate if (toktype == KG_TOK_SEAL_MSG) { 481*7c478bd9Sstevel@tonic-gate xfree_wrap(token.value, token.length); 482*7c478bd9Sstevel@tonic-gate /* Solaris Kerberos: just to be safe since token.value is an 483*7c478bd9Sstevel@tonic-gate * output parameter. 484*7c478bd9Sstevel@tonic-gate */ 485*7c478bd9Sstevel@tonic-gate token.value = NULL; 486*7c478bd9Sstevel@tonic-gate token.length = 0; 487*7c478bd9Sstevel@tonic-gate } 488*7c478bd9Sstevel@tonic-gate *minor_status = code; 489*7c478bd9Sstevel@tonic-gate return(GSS_S_FAILURE); 490*7c478bd9Sstevel@tonic-gate } 491*7c478bd9Sstevel@tonic-gate 492*7c478bd9Sstevel@tonic-gate code = memcmp(md5cksum.contents, ptr+14, 8); 493*7c478bd9Sstevel@tonic-gate /* Falls through to defective-token?? */ 494*7c478bd9Sstevel@tonic-gate 495*7c478bd9Sstevel@tonic-gate default: 496*7c478bd9Sstevel@tonic-gate *minor_status = 0; 497*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR, "kg_unseal_v1() end, error SGN_ALG_MD2_5 " 498*7c478bd9Sstevel@tonic-gate "GSS_S_DEFECTIVE_TOKEN\n"); 499*7c478bd9Sstevel@tonic-gate return(GSS_S_DEFECTIVE_TOKEN); 500*7c478bd9Sstevel@tonic-gate 501*7c478bd9Sstevel@tonic-gate case SGN_ALG_HMAC_SHA1_DES3_KD: 502*7c478bd9Sstevel@tonic-gate case SGN_ALG_HMAC_MD5: 503*7c478bd9Sstevel@tonic-gate /* compute the checksum of the message */ 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate /* 8 = bytes of token body to be checksummed according to spec */ 506*7c478bd9Sstevel@tonic-gate 507*7c478bd9Sstevel@tonic-gate if (! (data_ptr = (void *) 508*7c478bd9Sstevel@tonic-gate xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) { 509*7c478bd9Sstevel@tonic-gate if (sealalg != 0xffff) 510*7c478bd9Sstevel@tonic-gate xfree_wrap(plain, tmsglen); 511*7c478bd9Sstevel@tonic-gate if (toktype == KG_TOK_SEAL_MSG) { 512*7c478bd9Sstevel@tonic-gate xfree_wrap(token.value, token.length); 513*7c478bd9Sstevel@tonic-gate /* Solaris Kerberos: just to be safe since token.value is an 514*7c478bd9Sstevel@tonic-gate * output parameter. 515*7c478bd9Sstevel@tonic-gate */ 516*7c478bd9Sstevel@tonic-gate token.value = NULL; 517*7c478bd9Sstevel@tonic-gate token.length = 0; 518*7c478bd9Sstevel@tonic-gate } 519*7c478bd9Sstevel@tonic-gate *minor_status = ENOMEM; 520*7c478bd9Sstevel@tonic-gate return(GSS_S_FAILURE); 521*7c478bd9Sstevel@tonic-gate } 522*7c478bd9Sstevel@tonic-gate 523*7c478bd9Sstevel@tonic-gate (void) memcpy(data_ptr, ptr-2, 8); 524*7c478bd9Sstevel@tonic-gate 525*7c478bd9Sstevel@tonic-gate if (ctx->big_endian) { 526*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_INFO, "kg_unseal_v1() ctx->big_endian = 1\n"); 527*7c478bd9Sstevel@tonic-gate (void) memcpy(data_ptr+8, token.value, token.length); 528*7c478bd9Sstevel@tonic-gate } 529*7c478bd9Sstevel@tonic-gate else { 530*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_INFO, "kg_unseal_v1() ctx->big_endian = 0\n"); 531*7c478bd9Sstevel@tonic-gate (void) memcpy(data_ptr+8, plain, plainlen); 532*7c478bd9Sstevel@tonic-gate } 533*7c478bd9Sstevel@tonic-gate 534*7c478bd9Sstevel@tonic-gate plaind.length = 8 + (ctx->big_endian ? token.length : plainlen); 535*7c478bd9Sstevel@tonic-gate plaind.data = data_ptr; 536*7c478bd9Sstevel@tonic-gate 537*7c478bd9Sstevel@tonic-gate code = krb5_c_make_checksum(context, md5cksum.checksum_type, 538*7c478bd9Sstevel@tonic-gate ctx->seq, sign_usage, 539*7c478bd9Sstevel@tonic-gate &plaind, &md5cksum); 540*7c478bd9Sstevel@tonic-gate 541*7c478bd9Sstevel@tonic-gate xfree_wrap(data_ptr, 8 + (ctx->big_endian ? token.length : plainlen)); 542*7c478bd9Sstevel@tonic-gate 543*7c478bd9Sstevel@tonic-gate if (code) { 544*7c478bd9Sstevel@tonic-gate if (toktype == KG_TOK_SEAL_MSG) { 545*7c478bd9Sstevel@tonic-gate xfree_wrap(token.value, token.length); 546*7c478bd9Sstevel@tonic-gate /* Solaris Kerberos: just to be safe since token.value is an 547*7c478bd9Sstevel@tonic-gate * output parameter. 548*7c478bd9Sstevel@tonic-gate */ 549*7c478bd9Sstevel@tonic-gate token.value = NULL; 550*7c478bd9Sstevel@tonic-gate token.length = 0; 551*7c478bd9Sstevel@tonic-gate } 552*7c478bd9Sstevel@tonic-gate *minor_status = code; 553*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR, "kg_unseal_v1() end, error " 554*7c478bd9Sstevel@tonic-gate "SGN_ALG_HMAC_SHA1_DES3_KD GSS_S_FAILURE\n"); 555*7c478bd9Sstevel@tonic-gate return(GSS_S_FAILURE); 556*7c478bd9Sstevel@tonic-gate } 557*7c478bd9Sstevel@tonic-gate 558*7c478bd9Sstevel@tonic-gate /* compare the computed checksum against the transmitted checksum */ 559*7c478bd9Sstevel@tonic-gate code = memcmp(md5cksum.contents, ptr+14, cksum_len); 560*7c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_INFO, "kg_unseal_v1() memcmp %d bytes", cksum_len); 561*7c478bd9Sstevel@tonic-gate break; 562*7c478bd9Sstevel@tonic-gate } 563*7c478bd9Sstevel@tonic-gate 564*7c478bd9Sstevel@tonic-gate xfree_wrap(md5cksum.contents, md5cksum.length); 565*7c478bd9Sstevel@tonic-gate if (sealalg != 0xffff) 566*7c478bd9Sstevel@tonic-gate xfree_wrap(plain, tmsglen); 567*7c478bd9Sstevel@tonic-gate 568*7c478bd9Sstevel@tonic-gate if (code) { 569*7c478bd9Sstevel@tonic-gate if (toktype == KG_TOK_SEAL_MSG) { 570*7c478bd9Sstevel@tonic-gate xfree_wrap(token.value, token.length); 571*7c478bd9Sstevel@tonic-gate /* Solaris Kerberos: just to be safe since token.value is an 572*7c478bd9Sstevel@tonic-gate * output parameter. 573*7c478bd9Sstevel@tonic-gate */ 574*7c478bd9Sstevel@tonic-gate token.value = NULL; 575*7c478bd9Sstevel@tonic-gate token.length = 0; 576*7c478bd9Sstevel@tonic-gate } 577*7c478bd9Sstevel@tonic-gate *minor_status = 0; 578*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR, "kg_unseal_v1() end, error GSS_S_BAD_SIG\n"); 579*7c478bd9Sstevel@tonic-gate return(GSS_S_BAD_SIG); 580*7c478bd9Sstevel@tonic-gate } 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate if (conf_state) 583*7c478bd9Sstevel@tonic-gate *conf_state = (sealalg != 0xffff); 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate if (qop_state) 586*7c478bd9Sstevel@tonic-gate *qop_state = GSS_C_QOP_DEFAULT; 587*7c478bd9Sstevel@tonic-gate 588*7c478bd9Sstevel@tonic-gate if ((code = krb5_timeofday(context, &now))) { 589*7c478bd9Sstevel@tonic-gate *minor_status = code; 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "kg_unseal_v1() end, krb5_timeofday()" 592*7c478bd9Sstevel@tonic-gate "error code = %d\n", code); 593*7c478bd9Sstevel@tonic-gate 594*7c478bd9Sstevel@tonic-gate return(GSS_S_FAILURE); 595*7c478bd9Sstevel@tonic-gate } 596*7c478bd9Sstevel@tonic-gate 597*7c478bd9Sstevel@tonic-gate if (now > ctx->endtime) { 598*7c478bd9Sstevel@tonic-gate *minor_status = 0; 599*7c478bd9Sstevel@tonic-gate 600*7c478bd9Sstevel@tonic-gate KRB5_LOG1(KRB5_ERR, "kg_unseal_v1() end, error " 601*7c478bd9Sstevel@tonic-gate "now %d > ctx->endtime %d\n", now, ctx->endtime); 602*7c478bd9Sstevel@tonic-gate 603*7c478bd9Sstevel@tonic-gate return(GSS_S_CONTEXT_EXPIRED); 604*7c478bd9Sstevel@tonic-gate } 605*7c478bd9Sstevel@tonic-gate 606*7c478bd9Sstevel@tonic-gate /* do sequencing checks */ 607*7c478bd9Sstevel@tonic-gate if ((ctx->initiate && direction != 0xff) || 608*7c478bd9Sstevel@tonic-gate (!ctx->initiate && direction != 0)) { 609*7c478bd9Sstevel@tonic-gate if (toktype == KG_TOK_SEAL_MSG) { 610*7c478bd9Sstevel@tonic-gate xfree_wrap(token.value, token.length); 611*7c478bd9Sstevel@tonic-gate /* Solaris Kerberos: just to be safe since token.value is an 612*7c478bd9Sstevel@tonic-gate * output parameter. 613*7c478bd9Sstevel@tonic-gate */ 614*7c478bd9Sstevel@tonic-gate token.value = NULL; 615*7c478bd9Sstevel@tonic-gate token.length = 0; 616*7c478bd9Sstevel@tonic-gate } 617*7c478bd9Sstevel@tonic-gate *minor_status = (OM_uint32) G_BAD_DIRECTION; 618*7c478bd9Sstevel@tonic-gate 619*7c478bd9Sstevel@tonic-gate KRB5_LOG1(KRB5_ERR, "kg_unseal_v1() end, error GSS_S_BAD_SIG " 620*7c478bd9Sstevel@tonic-gate "G_BAD_DIRECTION ctx->initiate = %d " 621*7c478bd9Sstevel@tonic-gate "direction = %d\n", ctx->initiate, direction); 622*7c478bd9Sstevel@tonic-gate 623*7c478bd9Sstevel@tonic-gate return(GSS_S_BAD_SIG); 624*7c478bd9Sstevel@tonic-gate } 625*7c478bd9Sstevel@tonic-gate 626*7c478bd9Sstevel@tonic-gate retval = g_order_check(&(ctx->seqstate), (gssint_uint64)seqnum); 627*7c478bd9Sstevel@tonic-gate 628*7c478bd9Sstevel@tonic-gate /* It got through unscathed, adjust the output message buffer. */ 629*7c478bd9Sstevel@tonic-gate if (retval == 0 && toktype == KG_TOK_SEAL_MSG) 630*7c478bd9Sstevel@tonic-gate *message_buffer = token; 631*7c478bd9Sstevel@tonic-gate 632*7c478bd9Sstevel@tonic-gate *minor_status = 0; 633*7c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_INFO, "kg_unseal_v1() end, retval = %d\n", retval); 634*7c478bd9Sstevel@tonic-gate return(retval); 635*7c478bd9Sstevel@tonic-gate } 636*7c478bd9Sstevel@tonic-gate 637*7c478bd9Sstevel@tonic-gate /* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX 638*7c478bd9Sstevel@tonic-gate conf_state is only valid if SEAL. */ 639*7c478bd9Sstevel@tonic-gate 640*7c478bd9Sstevel@tonic-gate OM_uint32 641*7c478bd9Sstevel@tonic-gate kg_unseal(context, minor_status, context_handle, input_token_buffer, 642*7c478bd9Sstevel@tonic-gate message_buffer, conf_state, qop_state, toktype) 643*7c478bd9Sstevel@tonic-gate krb5_context context; 644*7c478bd9Sstevel@tonic-gate OM_uint32 *minor_status; 645*7c478bd9Sstevel@tonic-gate gss_ctx_id_t context_handle; 646*7c478bd9Sstevel@tonic-gate gss_buffer_t input_token_buffer; 647*7c478bd9Sstevel@tonic-gate gss_buffer_t message_buffer; 648*7c478bd9Sstevel@tonic-gate int *conf_state; 649*7c478bd9Sstevel@tonic-gate int *qop_state; 650*7c478bd9Sstevel@tonic-gate int toktype; 651*7c478bd9Sstevel@tonic-gate { 652*7c478bd9Sstevel@tonic-gate krb5_gss_ctx_id_rec *ctx; 653*7c478bd9Sstevel@tonic-gate unsigned char *ptr; 654*7c478bd9Sstevel@tonic-gate int bodysize; 655*7c478bd9Sstevel@tonic-gate int err; 656*7c478bd9Sstevel@tonic-gate int toktype2; 657*7c478bd9Sstevel@tonic-gate 658*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_INFO, "kg_unseal() start \n"); 659*7c478bd9Sstevel@tonic-gate 660*7c478bd9Sstevel@tonic-gate /* validate the context handle */ 661*7c478bd9Sstevel@tonic-gate if (! kg_validate_ctx_id(context_handle)) { 662*7c478bd9Sstevel@tonic-gate *minor_status = (OM_uint32) G_VALIDATE_FAILED; 663*7c478bd9Sstevel@tonic-gate 664*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR, "kg_unseal() end, kg_validate_ctx_id() error " 665*7c478bd9Sstevel@tonic-gate "G_VALIDATE_FAILED \n"); 666*7c478bd9Sstevel@tonic-gate 667*7c478bd9Sstevel@tonic-gate return(GSS_S_NO_CONTEXT); 668*7c478bd9Sstevel@tonic-gate } 669*7c478bd9Sstevel@tonic-gate 670*7c478bd9Sstevel@tonic-gate ctx = (krb5_gss_ctx_id_rec *) context_handle; 671*7c478bd9Sstevel@tonic-gate 672*7c478bd9Sstevel@tonic-gate if (! ctx->established) { 673*7c478bd9Sstevel@tonic-gate *minor_status = KG_CTX_INCOMPLETE; 674*7c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR, "kg_unseal() end, error ! ctx->established \n"); 675*7c478bd9Sstevel@tonic-gate return(GSS_S_NO_CONTEXT); 676*7c478bd9Sstevel@tonic-gate } 677*7c478bd9Sstevel@tonic-gate 678*7c478bd9Sstevel@tonic-gate /* parse the token, leave the data in message_buffer, setting conf_state */ 679*7c478bd9Sstevel@tonic-gate 680*7c478bd9Sstevel@tonic-gate /* verify the header */ 681*7c478bd9Sstevel@tonic-gate ptr = (unsigned char *) input_token_buffer->value; 682*7c478bd9Sstevel@tonic-gate if (ctx->proto) 683*7c478bd9Sstevel@tonic-gate switch (toktype) { 684*7c478bd9Sstevel@tonic-gate case KG_TOK_SIGN_MSG: 685*7c478bd9Sstevel@tonic-gate toktype2 = 0x0404; 686*7c478bd9Sstevel@tonic-gate break; 687*7c478bd9Sstevel@tonic-gate case KG_TOK_SEAL_MSG: 688*7c478bd9Sstevel@tonic-gate toktype2 = 0x0504; 689*7c478bd9Sstevel@tonic-gate break; 690*7c478bd9Sstevel@tonic-gate case KG_TOK_DEL_CTX: 691*7c478bd9Sstevel@tonic-gate toktype2 = 0x0405; 692*7c478bd9Sstevel@tonic-gate break; 693*7c478bd9Sstevel@tonic-gate default: 694*7c478bd9Sstevel@tonic-gate toktype2 = toktype; 695*7c478bd9Sstevel@tonic-gate break; 696*7c478bd9Sstevel@tonic-gate } 697*7c478bd9Sstevel@tonic-gate else 698*7c478bd9Sstevel@tonic-gate toktype2 = toktype; 699*7c478bd9Sstevel@tonic-gate err = g_verify_token_header(&ctx->mech_used, 700*7c478bd9Sstevel@tonic-gate (uint32_t *)&bodysize, &ptr, toktype2, 701*7c478bd9Sstevel@tonic-gate input_token_buffer->length, 702*7c478bd9Sstevel@tonic-gate !ctx->proto); 703*7c478bd9Sstevel@tonic-gate if (err) { 704*7c478bd9Sstevel@tonic-gate *minor_status = err; 705*7c478bd9Sstevel@tonic-gate return GSS_S_DEFECTIVE_TOKEN; 706*7c478bd9Sstevel@tonic-gate } 707*7c478bd9Sstevel@tonic-gate 708*7c478bd9Sstevel@tonic-gate 709*7c478bd9Sstevel@tonic-gate 710*7c478bd9Sstevel@tonic-gate if (ctx->proto == 0) { 711*7c478bd9Sstevel@tonic-gate err = kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, 712*7c478bd9Sstevel@tonic-gate message_buffer, conf_state, qop_state, 713*7c478bd9Sstevel@tonic-gate toktype); 714*7c478bd9Sstevel@tonic-gate 715*7c478bd9Sstevel@tonic-gate } else { 716*7c478bd9Sstevel@tonic-gate err = gss_krb5int_unseal_token_v3(context, minor_status, ctx, 717*7c478bd9Sstevel@tonic-gate ptr, bodysize, message_buffer, 718*7c478bd9Sstevel@tonic-gate conf_state, qop_state, toktype); 719*7c478bd9Sstevel@tonic-gate } 720*7c478bd9Sstevel@tonic-gate 721*7c478bd9Sstevel@tonic-gate *minor_status = err; 722*7c478bd9Sstevel@tonic-gate 723*7c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_INFO, "kg_unseal() end, err = %d", err); 724*7c478bd9Sstevel@tonic-gate 725*7c478bd9Sstevel@tonic-gate return(err); 726*7c478bd9Sstevel@tonic-gate } 727