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
kg_checksum_channel_bindings(context,cb,cksum,bigend)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