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