encapsulate.c revision 233294
1/*
2 * Copyright (c) 1997 - 2003 Kungliga Tekniska H��gskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the Institute nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "gsskrb5_locl.h"
35
36void
37_gssapi_encap_length (size_t data_len,
38		      size_t *len,
39		      size_t *total_len,
40		      const gss_OID mech)
41{
42    size_t len_len;
43
44    *len = 1 + 1 + mech->length + data_len;
45
46    len_len = der_length_len(*len);
47
48    *total_len = 1 + len_len + *len;
49}
50
51void
52_gsskrb5_encap_length (size_t data_len,
53			  size_t *len,
54			  size_t *total_len,
55			  const gss_OID mech)
56{
57    _gssapi_encap_length(data_len + 2, len, total_len, mech);
58}
59
60void *
61_gsskrb5_make_header (void *ptr,
62			 size_t len,
63			 const void *type,
64			 const gss_OID mech)
65{
66    u_char *p = ptr;
67    p = _gssapi_make_mech_header(p, len, mech);
68    memcpy (p, type, 2);
69    p += 2;
70    return p;
71}
72
73void *
74_gssapi_make_mech_header(void *ptr,
75			 size_t len,
76			 const gss_OID mech)
77{
78    u_char *p = ptr;
79    int e;
80    size_t len_len, foo;
81
82    *p++ = 0x60;
83    len_len = der_length_len(len);
84    e = der_put_length (p + len_len - 1, len_len, len, &foo);
85    if(e || foo != len_len)
86	abort ();
87    p += len_len;
88    *p++ = 0x06;
89    *p++ = mech->length;
90    memcpy (p, mech->elements, mech->length);
91    p += mech->length;
92    return p;
93}
94
95/*
96 * Give it a krb5_data and it will encapsulate with extra GSS-API wrappings.
97 */
98
99OM_uint32
100_gssapi_encapsulate(
101    OM_uint32 *minor_status,
102    const krb5_data *in_data,
103    gss_buffer_t output_token,
104    const gss_OID mech
105)
106{
107    size_t len, outer_len;
108    void *p;
109
110    _gssapi_encap_length (in_data->length, &len, &outer_len, mech);
111
112    output_token->length = outer_len;
113    output_token->value  = malloc (outer_len);
114    if (output_token->value == NULL) {
115	*minor_status = ENOMEM;
116	return GSS_S_FAILURE;
117    }
118
119    p = _gssapi_make_mech_header (output_token->value, len, mech);
120    memcpy (p, in_data->data, in_data->length);
121    return GSS_S_COMPLETE;
122}
123
124/*
125 * Give it a krb5_data and it will encapsulate with extra GSS-API krb5
126 * wrappings.
127 */
128
129OM_uint32
130_gsskrb5_encapsulate(
131			OM_uint32 *minor_status,
132			const krb5_data *in_data,
133			gss_buffer_t output_token,
134			const void *type,
135			const gss_OID mech
136)
137{
138    size_t len, outer_len;
139    u_char *p;
140
141    _gsskrb5_encap_length (in_data->length, &len, &outer_len, mech);
142
143    output_token->length = outer_len;
144    output_token->value  = malloc (outer_len);
145    if (output_token->value == NULL) {
146	*minor_status = ENOMEM;
147	return GSS_S_FAILURE;
148    }
149
150    p = _gsskrb5_make_header (output_token->value, len, type, mech);
151    memcpy (p, in_data->data, in_data->length);
152    return GSS_S_COMPLETE;
153}
154