17c478bd9Sstevel@tonic-gate /* 2220c5023Swyllys * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate */ 57c478bd9Sstevel@tonic-gate 67c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 77c478bd9Sstevel@tonic-gate 87c478bd9Sstevel@tonic-gate /* 97c478bd9Sstevel@tonic-gate * Copyright 1993 by OpenVision Technologies, Inc. 107c478bd9Sstevel@tonic-gate * 117c478bd9Sstevel@tonic-gate * Permission to use, copy, modify, distribute, and sell this software 127c478bd9Sstevel@tonic-gate * and its documentation for any purpose is hereby granted without fee, 137c478bd9Sstevel@tonic-gate * provided that the above copyright notice appears in all copies and 147c478bd9Sstevel@tonic-gate * that both that copyright notice and this permission notice appear in 157c478bd9Sstevel@tonic-gate * supporting documentation, and that the name of OpenVision not be used 167c478bd9Sstevel@tonic-gate * in advertising or publicity pertaining to distribution of the software 177c478bd9Sstevel@tonic-gate * without specific, written prior permission. OpenVision makes no 187c478bd9Sstevel@tonic-gate * representations about the suitability of this software for any 197c478bd9Sstevel@tonic-gate * purpose. It is provided "as is" without express or implied warranty. 207c478bd9Sstevel@tonic-gate * 217c478bd9Sstevel@tonic-gate * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 227c478bd9Sstevel@tonic-gate * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 237c478bd9Sstevel@tonic-gate * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR 247c478bd9Sstevel@tonic-gate * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 257c478bd9Sstevel@tonic-gate * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 267c478bd9Sstevel@tonic-gate * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 277c478bd9Sstevel@tonic-gate * PERFORMANCE OF THIS SOFTWARE. 287c478bd9Sstevel@tonic-gate */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate /* 317c478bd9Sstevel@tonic-gate * Copyright (C) 1998 by the FundsXpress, INC. 327c478bd9Sstevel@tonic-gate * 337c478bd9Sstevel@tonic-gate * All rights reserved. 347c478bd9Sstevel@tonic-gate * 357c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may require 367c478bd9Sstevel@tonic-gate * a specific license from the United States Government. It is the 377c478bd9Sstevel@tonic-gate * responsibility of any person or organization contemplating export to 387c478bd9Sstevel@tonic-gate * obtain such a license before exporting. 397c478bd9Sstevel@tonic-gate * 407c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 417c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 427c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 437c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 447c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 457c478bd9Sstevel@tonic-gate * the name of FundsXpress. not be used in advertising or publicity pertaining 467c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior 477c478bd9Sstevel@tonic-gate * permission. FundsXpress makes no representations about the suitability of 487c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 497c478bd9Sstevel@tonic-gate * or implied warranty. 507c478bd9Sstevel@tonic-gate * 517c478bd9Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 527c478bd9Sstevel@tonic-gate * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 537c478bd9Sstevel@tonic-gate * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 547c478bd9Sstevel@tonic-gate */ 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate #include <gssapiP_krb5.h> 577c478bd9Sstevel@tonic-gate #include <k5-int.h> 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate static krb5_error_code 60*ab9b2e15Sgtb make_seal_token_v1 (krb5_context context, 617c478bd9Sstevel@tonic-gate krb5_keyblock *enc, 627c478bd9Sstevel@tonic-gate krb5_keyblock *seq, 637c478bd9Sstevel@tonic-gate gssint_uint64 *seqnum, 647c478bd9Sstevel@tonic-gate int direction, 657c478bd9Sstevel@tonic-gate gss_buffer_t text, 667c478bd9Sstevel@tonic-gate gss_buffer_t token, 677c478bd9Sstevel@tonic-gate int signalg, 687c478bd9Sstevel@tonic-gate int cksum_size, 697c478bd9Sstevel@tonic-gate int sealalg, 707c478bd9Sstevel@tonic-gate int encrypt, 717c478bd9Sstevel@tonic-gate int toktype, 727c478bd9Sstevel@tonic-gate int bigend, 73*ab9b2e15Sgtb gss_OID oid); 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate static krb5_error_code 767c478bd9Sstevel@tonic-gate make_seal_token_v1(context, enc, seq, seqnum, direction, text, token, 777c478bd9Sstevel@tonic-gate signalg, cksum_size, sealalg, encrypt, toktype, 787c478bd9Sstevel@tonic-gate bigend, oid) 797c478bd9Sstevel@tonic-gate krb5_context context; 807c478bd9Sstevel@tonic-gate krb5_keyblock *enc; 817c478bd9Sstevel@tonic-gate krb5_keyblock *seq; 827c478bd9Sstevel@tonic-gate gssint_uint64 *seqnum; 837c478bd9Sstevel@tonic-gate int direction; 847c478bd9Sstevel@tonic-gate gss_buffer_t text; 857c478bd9Sstevel@tonic-gate gss_buffer_t token; 867c478bd9Sstevel@tonic-gate int signalg; 877c478bd9Sstevel@tonic-gate int cksum_size; 887c478bd9Sstevel@tonic-gate int sealalg; 897c478bd9Sstevel@tonic-gate int encrypt; 907c478bd9Sstevel@tonic-gate int toktype; 917c478bd9Sstevel@tonic-gate int bigend; 927c478bd9Sstevel@tonic-gate gss_OID oid; 937c478bd9Sstevel@tonic-gate { 947c478bd9Sstevel@tonic-gate krb5_error_code code; 957c478bd9Sstevel@tonic-gate size_t sumlen; 967c478bd9Sstevel@tonic-gate char *data_ptr; 977c478bd9Sstevel@tonic-gate krb5_data plaind; 987c478bd9Sstevel@tonic-gate krb5_checksum md5cksum; 997c478bd9Sstevel@tonic-gate krb5_checksum cksum; 1007c478bd9Sstevel@tonic-gate /* 1017c478bd9Sstevel@tonic-gate * msglen contains the message length 1027c478bd9Sstevel@tonic-gate * we are signing/encrypting. tmsglen 1037c478bd9Sstevel@tonic-gate * contains the length of the message 1047c478bd9Sstevel@tonic-gate * we plan to write out to the token. 1057c478bd9Sstevel@tonic-gate * tlen is the length of the token 1067c478bd9Sstevel@tonic-gate * including header. 1077c478bd9Sstevel@tonic-gate */ 1087c478bd9Sstevel@tonic-gate int conflen=0, tmsglen, tlen, msglen; 1097c478bd9Sstevel@tonic-gate unsigned char *t, *ptr; 1107c478bd9Sstevel@tonic-gate unsigned char *plain; 1117c478bd9Sstevel@tonic-gate unsigned char pad; 1127c478bd9Sstevel@tonic-gate krb5_keyusage sign_usage = KG_USAGE_SIGN; 1137c478bd9Sstevel@tonic-gate OM_uint32 seqnum32; 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate /* Solaris Kerberos: check for recognized signalg and sealalg */ 1167c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_INFO, "make_seal_token_v1() start\n"); 1177c478bd9Sstevel@tonic-gate #ifdef _KERNEL 1187c478bd9Sstevel@tonic-gate /* 1197c478bd9Sstevel@tonic-gate * Because the ARCFOUR code bypasses the standard 1207c478bd9Sstevel@tonic-gate * crypto interfaces, we must make sure the kernel 1217c478bd9Sstevel@tonic-gate * crypto framework mechanism types are properly 1227c478bd9Sstevel@tonic-gate * initialized here. 1237c478bd9Sstevel@tonic-gate */ 1247c478bd9Sstevel@tonic-gate context->kef_cipher_mt = get_cipher_mech_type(context, seq); 1257c478bd9Sstevel@tonic-gate context->kef_hash_mt = get_hash_mech_type(context, seq); 1267c478bd9Sstevel@tonic-gate if ((code = init_key_kef(context->kef_cipher_mt, seq))) { 1277c478bd9Sstevel@tonic-gate return (code); 1287c478bd9Sstevel@tonic-gate } 1297c478bd9Sstevel@tonic-gate if ((code = init_key_kef(context->kef_cipher_mt, enc))) { 1307c478bd9Sstevel@tonic-gate return (code); 1317c478bd9Sstevel@tonic-gate } 1327c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate /* create the token buffer */ 1357c478bd9Sstevel@tonic-gate /* Do we need confounder? */ 1367c478bd9Sstevel@tonic-gate if (encrypt || (!bigend && (toktype == KG_TOK_SEAL_MSG))) 1377c478bd9Sstevel@tonic-gate conflen = kg_confounder_size(context, enc); 1387c478bd9Sstevel@tonic-gate else 1397c478bd9Sstevel@tonic-gate conflen = 0; 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate if (toktype == KG_TOK_SEAL_MSG) { 1427c478bd9Sstevel@tonic-gate switch (sealalg) { 1437c478bd9Sstevel@tonic-gate case SEAL_ALG_MICROSOFT_RC4: 1447c478bd9Sstevel@tonic-gate msglen = conflen + text->length+1; 1457c478bd9Sstevel@tonic-gate pad = 1; 1467c478bd9Sstevel@tonic-gate break; 1477c478bd9Sstevel@tonic-gate default: 1487c478bd9Sstevel@tonic-gate /* XXX knows that des block size is 8 */ 1497c478bd9Sstevel@tonic-gate msglen = (conflen+text->length+8)&(~7); 1507c478bd9Sstevel@tonic-gate pad = 8-(text->length%8); 1517c478bd9Sstevel@tonic-gate } 1527c478bd9Sstevel@tonic-gate tmsglen = msglen; 1537c478bd9Sstevel@tonic-gate } else { 1547c478bd9Sstevel@tonic-gate tmsglen = 0; 1557c478bd9Sstevel@tonic-gate msglen = text->length; 1567c478bd9Sstevel@tonic-gate pad = 0; 1577c478bd9Sstevel@tonic-gate } 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate tlen = g_token_size((gss_OID) oid, 14+cksum_size+tmsglen); 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate if ((t = (unsigned char *) xmalloc(tlen)) == NULL) 1627c478bd9Sstevel@tonic-gate return(ENOMEM); 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate /*** fill in the token */ 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate ptr = t; 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate g_make_token_header((gss_OID) oid, 14+cksum_size+tmsglen, &ptr, toktype); 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate /* 0..1 SIGN_ALG */ 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate ptr[0] = (unsigned char) (signalg & 0xff); 1737c478bd9Sstevel@tonic-gate ptr[1] = (unsigned char) ((signalg >> 8) & 0xff); 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate /* 2..3 SEAL_ALG or Filler */ 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate if ((toktype == KG_TOK_SEAL_MSG) && encrypt) { 1787c478bd9Sstevel@tonic-gate ptr[2] = (unsigned char) (sealalg & 0xff); 1797c478bd9Sstevel@tonic-gate ptr[3] = (unsigned char) ((sealalg >> 8) & 0xff); 1807c478bd9Sstevel@tonic-gate } else { 1817c478bd9Sstevel@tonic-gate /* No seal */ 1827c478bd9Sstevel@tonic-gate ptr[2] = 0xff; 1837c478bd9Sstevel@tonic-gate ptr[3] = 0xff; 1847c478bd9Sstevel@tonic-gate } 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate /* 4..5 Filler */ 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate ptr[4] = 0xff; 1897c478bd9Sstevel@tonic-gate ptr[5] = 0xff; 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate /* pad the plaintext, encrypt if needed, and stick it in the token */ 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate /* initialize the the cksum */ 1947c478bd9Sstevel@tonic-gate switch (signalg) { 1957c478bd9Sstevel@tonic-gate case SGN_ALG_DES_MAC_MD5: 1967c478bd9Sstevel@tonic-gate case SGN_ALG_MD2_5: 1977c478bd9Sstevel@tonic-gate md5cksum.checksum_type = CKSUMTYPE_RSA_MD5; 1987c478bd9Sstevel@tonic-gate break; 1997c478bd9Sstevel@tonic-gate case SGN_ALG_HMAC_SHA1_DES3_KD: 2007c478bd9Sstevel@tonic-gate md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3; 2017c478bd9Sstevel@tonic-gate break; 2027c478bd9Sstevel@tonic-gate case SGN_ALG_HMAC_MD5: 2037c478bd9Sstevel@tonic-gate md5cksum.checksum_type = CKSUMTYPE_HMAC_MD5_ARCFOUR; 2047c478bd9Sstevel@tonic-gate if (toktype != KG_TOK_SEAL_MSG) 2057c478bd9Sstevel@tonic-gate sign_usage = 15; 2067c478bd9Sstevel@tonic-gate break; 2077c478bd9Sstevel@tonic-gate default: 2087c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "make_seal_token_v1() end, error2 signalg=%d\n", 2097c478bd9Sstevel@tonic-gate signalg); 2107c478bd9Sstevel@tonic-gate #ifndef _KERNEL 2117c478bd9Sstevel@tonic-gate abort (); 2127c478bd9Sstevel@tonic-gate #else 2137c478bd9Sstevel@tonic-gate return (GSS_S_DEFECTIVE_TOKEN); 2147c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 2157c478bd9Sstevel@tonic-gate } 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate code = krb5_c_checksum_length(context, md5cksum.checksum_type, &sumlen); 2187c478bd9Sstevel@tonic-gate if (code) { 2197c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "make_seal_token_v1() end, krb5_c_checksum_length() " 2207c478bd9Sstevel@tonic-gate "error code=%d\n", code); 2217c478bd9Sstevel@tonic-gate return(code); 2227c478bd9Sstevel@tonic-gate } 2237c478bd9Sstevel@tonic-gate md5cksum.length = (size_t)sumlen; 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate if ((plain = (unsigned char *) xmalloc(msglen ? msglen : 1)) == NULL) { 2267c478bd9Sstevel@tonic-gate xfree_wrap(t, tlen); 2277c478bd9Sstevel@tonic-gate return(ENOMEM); 2287c478bd9Sstevel@tonic-gate } 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate if (conflen) { 2317c478bd9Sstevel@tonic-gate if ((code = kg_make_confounder(context, enc, plain))) { 2327c478bd9Sstevel@tonic-gate xfree_wrap(plain, msglen ? msglen : 1); 2337c478bd9Sstevel@tonic-gate xfree_wrap(t, tlen); 2347c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "make_seal_token_v1() end, " 2357c478bd9Sstevel@tonic-gate "kg_make_confounder() error code=%d\n", code); 2367c478bd9Sstevel@tonic-gate return(code); 2377c478bd9Sstevel@tonic-gate } 2387c478bd9Sstevel@tonic-gate } 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate (void) memcpy(plain+conflen, text->value, text->length); 2417c478bd9Sstevel@tonic-gate if (pad) 2427c478bd9Sstevel@tonic-gate (void) memset(plain+conflen+text->length, pad, pad); 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate /* compute the checksum */ 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate /* 8 = head of token body as specified by mech spec */ 2477c478bd9Sstevel@tonic-gate if (! (data_ptr = (char *) xmalloc(8 + 2487c478bd9Sstevel@tonic-gate (bigend ? text->length : msglen)))) { 2497c478bd9Sstevel@tonic-gate xfree_wrap(plain, msglen ? msglen : 1); 2507c478bd9Sstevel@tonic-gate xfree_wrap(t, tlen); 2517c478bd9Sstevel@tonic-gate return(ENOMEM); 2527c478bd9Sstevel@tonic-gate } 2537c478bd9Sstevel@tonic-gate (void) memcpy(data_ptr, ptr-2, 8); 2547c478bd9Sstevel@tonic-gate if (bigend) 2557c478bd9Sstevel@tonic-gate (void) memcpy(data_ptr+8, text->value, text->length); 2567c478bd9Sstevel@tonic-gate else 2577c478bd9Sstevel@tonic-gate (void) memcpy(data_ptr+8, plain, msglen); 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate plaind.length = 8 + (bigend ? text->length : msglen); 2607c478bd9Sstevel@tonic-gate plaind.data = data_ptr; 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate code = krb5_c_make_checksum(context, md5cksum.checksum_type, seq, 2637c478bd9Sstevel@tonic-gate sign_usage, &plaind, &md5cksum); 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate xfree_wrap(data_ptr,8 + (bigend ? text->length : msglen)); 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate if (code) { 2687c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "make_seal_token_v1() end, " 2697c478bd9Sstevel@tonic-gate "krb5_c_make_checksum() error code=%d\n", code); 2707c478bd9Sstevel@tonic-gate xfree_wrap(plain, msglen ? msglen : 1); 2717c478bd9Sstevel@tonic-gate xfree_wrap(t, tlen); 2727c478bd9Sstevel@tonic-gate return(code); 2737c478bd9Sstevel@tonic-gate } 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate switch(signalg) { 2767c478bd9Sstevel@tonic-gate case SGN_ALG_DES_MAC_MD5: 2777c478bd9Sstevel@tonic-gate case 3: 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate if ((code = kg_encrypt(context, seq, KG_USAGE_SEAL, 2807c478bd9Sstevel@tonic-gate (g_OID_equal(oid, gss_mech_krb5_old) ? 2817c478bd9Sstevel@tonic-gate seq->contents : NULL), 2827c478bd9Sstevel@tonic-gate md5cksum.contents, md5cksum.contents, 16))) { 2837c478bd9Sstevel@tonic-gate xfree_wrap(md5cksum.contents, md5cksum.length); 2847c478bd9Sstevel@tonic-gate xfree_wrap(t, tlen); 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "make_seal_token_v1() end, kg_encrypt() " 2877c478bd9Sstevel@tonic-gate "error code=%d\n", code); 2887c478bd9Sstevel@tonic-gate return code; 2897c478bd9Sstevel@tonic-gate } 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate cksum.length = cksum_size; 2927c478bd9Sstevel@tonic-gate cksum.contents = md5cksum.contents + 16 - cksum.length; 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate (void) memcpy(ptr+14, cksum.contents, cksum.length); 2957c478bd9Sstevel@tonic-gate break; 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate case SGN_ALG_HMAC_SHA1_DES3_KD: 2987c478bd9Sstevel@tonic-gate /* 2997c478bd9Sstevel@tonic-gate * Using key derivation, the call to krb5_c_make_checksum 3007c478bd9Sstevel@tonic-gate * already dealt with encrypting. 3017c478bd9Sstevel@tonic-gate */ 3027c478bd9Sstevel@tonic-gate if (md5cksum.length != cksum_size) 3037c478bd9Sstevel@tonic-gate { 3047c478bd9Sstevel@tonic-gate KRB5_LOG1(KRB5_ERR, "make_seal_token_v1() end, error " 3057c478bd9Sstevel@tonic-gate "md5cksum.length %d != " 3067c478bd9Sstevel@tonic-gate "cksum_size %d\n", 3077c478bd9Sstevel@tonic-gate md5cksum.length, cksum_size); 3087c478bd9Sstevel@tonic-gate #ifndef _KERNEL 3097c478bd9Sstevel@tonic-gate abort (); 3107c478bd9Sstevel@tonic-gate #else 3117c478bd9Sstevel@tonic-gate return (GSS_S_DEFECTIVE_TOKEN); 3127c478bd9Sstevel@tonic-gate #endif 3137c478bd9Sstevel@tonic-gate } 3147c478bd9Sstevel@tonic-gate (void) memcpy(ptr+14, md5cksum.contents, md5cksum.length); 3157c478bd9Sstevel@tonic-gate break; 3167c478bd9Sstevel@tonic-gate case SGN_ALG_HMAC_MD5: 3177c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_INFO, "make_seal_token_v1() cksum_size = %d", 3187c478bd9Sstevel@tonic-gate cksum_size); 3197c478bd9Sstevel@tonic-gate (void) memcpy(ptr+14, md5cksum.contents, cksum_size); 3207c478bd9Sstevel@tonic-gate break; 3217c478bd9Sstevel@tonic-gate } 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate xfree_wrap(md5cksum.contents, md5cksum.length); 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate /* create the seq_num */ 3267c478bd9Sstevel@tonic-gate seqnum32 = (OM_uint32)(*seqnum & 0xFFFFFFFF); 3277c478bd9Sstevel@tonic-gate if ((code = kg_make_seq_num(context, seq, direction?0:0xff, seqnum32, 3287c478bd9Sstevel@tonic-gate ptr+14, ptr+6))) { 3297c478bd9Sstevel@tonic-gate xfree_wrap(t, tlen); 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "make_seal_token_v1() end, kg_make_seq_num() " 3327c478bd9Sstevel@tonic-gate "error code=%d\n", code); 3337c478bd9Sstevel@tonic-gate return(code); 3347c478bd9Sstevel@tonic-gate } 3357c478bd9Sstevel@tonic-gate if (encrypt) { 3367c478bd9Sstevel@tonic-gate switch(sealalg) { 3377c478bd9Sstevel@tonic-gate case SEAL_ALG_MICROSOFT_RC4: 3387c478bd9Sstevel@tonic-gate { 3397c478bd9Sstevel@tonic-gate unsigned char bigend_seqnum[4]; 3407c478bd9Sstevel@tonic-gate krb5_keyblock *enc_key; 3417c478bd9Sstevel@tonic-gate int i; 3427c478bd9Sstevel@tonic-gate bigend_seqnum[0] = (*seqnum>>24) & 0xff; 3437c478bd9Sstevel@tonic-gate bigend_seqnum[1] = (*seqnum>>16) & 0xff; 3447c478bd9Sstevel@tonic-gate bigend_seqnum[2] = (*seqnum>>8) & 0xff; 3457c478bd9Sstevel@tonic-gate bigend_seqnum[3] = *seqnum & 0xff; 3467c478bd9Sstevel@tonic-gate code = krb5_copy_keyblock (context, enc, &enc_key); 3477c478bd9Sstevel@tonic-gate if (code) 3487c478bd9Sstevel@tonic-gate { 3497c478bd9Sstevel@tonic-gate xfree_wrap(plain, msglen ? msglen : 1); 3507c478bd9Sstevel@tonic-gate xfree_wrap(t, tlen); 3517c478bd9Sstevel@tonic-gate return(code); 3527c478bd9Sstevel@tonic-gate } 3537c478bd9Sstevel@tonic-gate for (i = 0; i <= 15; i++) 3547c478bd9Sstevel@tonic-gate ((char *) enc_key->contents)[i] ^=0xf0; 3557c478bd9Sstevel@tonic-gate code = kg_arcfour_docrypt (context, 3567c478bd9Sstevel@tonic-gate enc_key, 0, 3577c478bd9Sstevel@tonic-gate bigend_seqnum, 4, 3587c478bd9Sstevel@tonic-gate plain, tmsglen, 3597c478bd9Sstevel@tonic-gate ptr+14+cksum_size); 3607c478bd9Sstevel@tonic-gate krb5_free_keyblock (context, enc_key); 3617c478bd9Sstevel@tonic-gate if (code) 3627c478bd9Sstevel@tonic-gate { 3637c478bd9Sstevel@tonic-gate xfree_wrap(plain, msglen ? msglen : 1); 3647c478bd9Sstevel@tonic-gate xfree_wrap(t, tlen); 3657c478bd9Sstevel@tonic-gate return(code); 3667c478bd9Sstevel@tonic-gate } 3677c478bd9Sstevel@tonic-gate } 3687c478bd9Sstevel@tonic-gate break; 3697c478bd9Sstevel@tonic-gate default: 3707c478bd9Sstevel@tonic-gate if ((code = kg_encrypt(context, enc, KG_USAGE_SEAL, NULL, 3717c478bd9Sstevel@tonic-gate (krb5_pointer) plain, 3727c478bd9Sstevel@tonic-gate (krb5_pointer) (ptr+cksum_size+14), 3737c478bd9Sstevel@tonic-gate tmsglen))) { 3747c478bd9Sstevel@tonic-gate xfree_wrap(plain, msglen ? msglen : 1); 3757c478bd9Sstevel@tonic-gate xfree_wrap(t, tlen); 3767c478bd9Sstevel@tonic-gate return(code); 3777c478bd9Sstevel@tonic-gate } 3787c478bd9Sstevel@tonic-gate } 3797c478bd9Sstevel@tonic-gate }else { 3807c478bd9Sstevel@tonic-gate if (tmsglen) 3817c478bd9Sstevel@tonic-gate (void) memcpy(ptr+14+cksum_size, plain, tmsglen); 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate xfree_wrap(plain, msglen ? msglen : 1); 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate /* that's it. return the token */ 3867c478bd9Sstevel@tonic-gate 3877c478bd9Sstevel@tonic-gate (*seqnum)++; 3887c478bd9Sstevel@tonic-gate *seqnum &= (ulong_t)0xffffffffU; 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate token->length = tlen; 3917c478bd9Sstevel@tonic-gate token->value = (void *) t; 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_INFO, "make_seal_token_v1() end\n"); 3947c478bd9Sstevel@tonic-gate return(0); 3957c478bd9Sstevel@tonic-gate } 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate /* if signonly is true, ignore conf_req, conf_state, 3987c478bd9Sstevel@tonic-gate and do not encode the ENC_TYPE, MSG_LENGTH, or MSG_TEXT fields */ 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate OM_uint32 401*ab9b2e15Sgtb kg_seal(minor_status, context_handle, conf_req_flag, qop_req, 4027c478bd9Sstevel@tonic-gate input_message_buffer, conf_state, output_message_buffer, toktype) 4037c478bd9Sstevel@tonic-gate OM_uint32 *minor_status; 4047c478bd9Sstevel@tonic-gate gss_ctx_id_t context_handle; 4057c478bd9Sstevel@tonic-gate int conf_req_flag; 4067c478bd9Sstevel@tonic-gate int qop_req; 4077c478bd9Sstevel@tonic-gate gss_buffer_t input_message_buffer; 4087c478bd9Sstevel@tonic-gate int *conf_state; 4097c478bd9Sstevel@tonic-gate gss_buffer_t output_message_buffer; 4107c478bd9Sstevel@tonic-gate int toktype; 4117c478bd9Sstevel@tonic-gate { 4127c478bd9Sstevel@tonic-gate krb5_gss_ctx_id_rec *ctx; 4137c478bd9Sstevel@tonic-gate krb5_error_code code; 4147c478bd9Sstevel@tonic-gate krb5_timestamp now; 415*ab9b2e15Sgtb krb5_context context; 4167c478bd9Sstevel@tonic-gate 4177c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_INFO, "kg_seal() start"); 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate output_message_buffer->length = 0; 4207c478bd9Sstevel@tonic-gate output_message_buffer->value = NULL; 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate /* Only default qop or matching established cryptosystem is allowed. 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate There are NO EXTENSIONS to this set for AES and friends! The 4257c478bd9Sstevel@tonic-gate new spec says "just use 0". The old spec plus extensions would 4267c478bd9Sstevel@tonic-gate actually allow for certain non-zero values. Fix this to handle 4277c478bd9Sstevel@tonic-gate them later. */ 4287c478bd9Sstevel@tonic-gate if (qop_req != 0) { 4297c478bd9Sstevel@tonic-gate *minor_status = (OM_uint32) G_UNKNOWN_QOP; 4307c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR, "kg_seal() end, error G_UNKNOWN_QOP\n"); 4317c478bd9Sstevel@tonic-gate return (GSS_S_BAD_QOP); 4327c478bd9Sstevel@tonic-gate } 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate /* validate the context handle */ 4357c478bd9Sstevel@tonic-gate if (! kg_validate_ctx_id(context_handle)) { 4367c478bd9Sstevel@tonic-gate *minor_status = (OM_uint32) G_VALIDATE_FAILED; 4377c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_ERR, "kg_seal() kg_validate_ctx_id() end, " 4387c478bd9Sstevel@tonic-gate "error GSS_S_NO_CONTEXT\n"); 4397c478bd9Sstevel@tonic-gate return (GSS_S_NO_CONTEXT); 4407c478bd9Sstevel@tonic-gate } 4417c478bd9Sstevel@tonic-gate 4427c478bd9Sstevel@tonic-gate ctx = (krb5_gss_ctx_id_rec *) context_handle; 4437c478bd9Sstevel@tonic-gate 444220c5023Swyllys if (ctx->subkey == NULL && !ctx->established) { 4457c478bd9Sstevel@tonic-gate *minor_status = KG_CTX_INCOMPLETE; 4467c478bd9Sstevel@tonic-gate return(GSS_S_NO_CONTEXT); 4477c478bd9Sstevel@tonic-gate } 4487c478bd9Sstevel@tonic-gate 449*ab9b2e15Sgtb context = ctx->k5_context; 4507c478bd9Sstevel@tonic-gate if ((code = krb5_timeofday(context, &now))) { 4517c478bd9Sstevel@tonic-gate *minor_status = code; 4527c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "kg_seal() end, krb5_timeofday() error code=%d\n", code); 4537c478bd9Sstevel@tonic-gate return (GSS_S_FAILURE); 4547c478bd9Sstevel@tonic-gate } 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate switch (ctx->proto) 4577c478bd9Sstevel@tonic-gate { 4587c478bd9Sstevel@tonic-gate case 0: 4597c478bd9Sstevel@tonic-gate code = make_seal_token_v1(context, ctx->enc, ctx->seq, 4607c478bd9Sstevel@tonic-gate &ctx->seq_send, ctx->initiate, 4617c478bd9Sstevel@tonic-gate input_message_buffer, output_message_buffer, 4627c478bd9Sstevel@tonic-gate ctx->signalg, ctx->cksum_size, ctx->sealalg, 4637c478bd9Sstevel@tonic-gate conf_req_flag, toktype, ctx->big_endian, 464*ab9b2e15Sgtb ctx->mech_used); 4657c478bd9Sstevel@tonic-gate break; 4667c478bd9Sstevel@tonic-gate case 1: 4677c478bd9Sstevel@tonic-gate code = gss_krb5int_make_seal_token_v3(context, ctx, 4687c478bd9Sstevel@tonic-gate input_message_buffer, 4697c478bd9Sstevel@tonic-gate output_message_buffer, 4707c478bd9Sstevel@tonic-gate conf_req_flag, toktype); 4717c478bd9Sstevel@tonic-gate break; 4727c478bd9Sstevel@tonic-gate default: 4737c478bd9Sstevel@tonic-gate code = G_UNKNOWN_QOP; 4747c478bd9Sstevel@tonic-gate break; 4757c478bd9Sstevel@tonic-gate } 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate if (code) { 4787c478bd9Sstevel@tonic-gate *minor_status = code; 4797c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "kg_seal() end, make_seal_token_v1() " 4807c478bd9Sstevel@tonic-gate "error code=%d\n", code); 4817c478bd9Sstevel@tonic-gate return (GSS_S_FAILURE); 4827c478bd9Sstevel@tonic-gate } 4837c478bd9Sstevel@tonic-gate 4847c478bd9Sstevel@tonic-gate if (conf_state) 4857c478bd9Sstevel@tonic-gate *conf_state = conf_req_flag; 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate *minor_status = 0; 4887c478bd9Sstevel@tonic-gate if (ctx->endtime < now) { 4897c478bd9Sstevel@tonic-gate (void) gss_release_buffer(minor_status, output_message_buffer); 4907c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_ERR, "kg_seal() end, error GSS_S_CONTEXT_EXPIRED " 4917c478bd9Sstevel@tonic-gate "ctx->endtime = %d\n", ctx->endtime); 4927c478bd9Sstevel@tonic-gate return (GSS_S_CONTEXT_EXPIRED); 4937c478bd9Sstevel@tonic-gate } 4947c478bd9Sstevel@tonic-gate 4957c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_INFO, "kg_seal() end\n"); 4967c478bd9Sstevel@tonic-gate return (GSS_S_COMPLETE); 4977c478bd9Sstevel@tonic-gate } 498