1 /* 2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Copyright 1993 by OpenVision Technologies, Inc. 8 * 9 * Permission to use, copy, modify, distribute, and sell this software 10 * and its documentation for any purpose is hereby granted without fee, 11 * provided that the above copyright notice appears in all copies and 12 * that both that copyright notice and this permission notice appear in 13 * supporting documentation, and that the name of OpenVision not be used 14 * in advertising or publicity pertaining to distribution of the software 15 * without specific, written prior permission. OpenVision makes no 16 * representations about the suitability of this software for any 17 * purpose. It is provided "as is" without express or implied warranty. 18 * 19 * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 20 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 21 * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR 22 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 23 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 24 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 25 * PERFORMANCE OF THIS SOFTWARE. 26 */ 27 28 #include "gssapiP_krb5.h" 29 #ifdef HAVE_MEMORY_H 30 #include <memory.h> 31 #endif 32 33 /* Checksumming the channel bindings always uses plain MD5. */ 34 krb5_error_code 35 kg_checksum_channel_bindings(context, cb, cksum, bigend) 36 krb5_context context; 37 gss_channel_bindings_t cb; 38 krb5_checksum *cksum; 39 int bigend; 40 { 41 size_t len; 42 char *buf = 0; 43 char *ptr; 44 size_t sumlen; 45 krb5_data plaind; 46 krb5_error_code code; 47 void *temp; 48 49 /* initialize the the cksum */ 50 code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen); 51 if (code) 52 return(code); 53 54 cksum->checksum_type = CKSUMTYPE_RSA_MD5; 55 cksum->length = sumlen; 56 57 /* generate a buffer full of zeros if no cb specified */ 58 59 if (cb == GSS_C_NO_CHANNEL_BINDINGS) { 60 if ((cksum->contents = (krb5_octet *) xmalloc(cksum->length)) == NULL) { 61 return(ENOMEM); 62 } 63 memset(cksum->contents, '\0', cksum->length); 64 return(0); 65 } 66 67 /* create the buffer to checksum into */ 68 69 len = (sizeof(krb5_int32)*5+ 70 cb->initiator_address.length+ 71 cb->acceptor_address.length+ 72 cb->application_data.length); 73 74 if ((buf = (char *) xmalloc(len)) == NULL) 75 return(ENOMEM); 76 77 /* helper macros. This code currently depends on a long being 32 78 bits, and htonl dtrt. */ 79 80 ptr = buf; 81 82 TWRITE_INT(ptr, cb->initiator_addrtype, bigend); 83 TWRITE_BUF(ptr, cb->initiator_address, bigend); 84 TWRITE_INT(ptr, cb->acceptor_addrtype, bigend); 85 TWRITE_BUF(ptr, cb->acceptor_address, bigend); 86 TWRITE_BUF(ptr, cb->application_data, bigend); 87 88 /* checksum the data */ 89 90 plaind.length = len; 91 plaind.data = buf; 92 93 #if 0 94 /* 95 * SUNW15resync 96 * MIT 1.5-6 seems/is wrong here in 2 ways 97 * - why free then alloc contents again? 98 * - calling krb5_free_checksum_contents results in cksum->length 99 * getting set to 0 which causes ftp to fail 100 * so lets stick w/oldey-but-goodey code. 101 */ 102 code = krb5_c_make_checksum(context, CKSUMTYPE_RSA_MD5, 0, 0, 103 &plaind, cksum); 104 if (code) 105 goto cleanup; 106 107 if ((temp = xmalloc(cksum->length)) == NULL) { 108 krb5_free_checksum_contents(context, cksum); 109 code = ENOMEM; 110 goto cleanup; 111 } 112 113 memcpy(temp, cksum->contents, cksum->length); 114 krb5_free_checksum_contents(context, cksum); 115 cksum->contents = (krb5_octet *)temp; 116 /* SUNW15resync - need to reset cksum->length here */ 117 118 /* success */ 119 cleanup: 120 if (buf) 121 xfree(buf); 122 #endif /* 0 */ 123 124 if (code = krb5_c_make_checksum(context, CKSUMTYPE_RSA_MD5, 0, 0, 125 &plaind, cksum)) { 126 xfree(cksum->contents); /* SUNW15resync -just in case not already free */ 127 xfree(buf); 128 return(code); 129 } 130 131 /* success */ 132 133 xfree(buf); 134 return code; 135 } 136