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