Line data Source code
1 : /*
2 : * Copyright (c) 1997 - 2001 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 :
36 : /*
37 : * return the length of the mechanism in token or -1
38 : * (which implies that the token was bad - GSS_S_DEFECTIVE_TOKEN
39 : */
40 :
41 : ssize_t
42 150809 : _gsskrb5_get_mech (const u_char *ptr,
43 : size_t total_len,
44 : const u_char **mech_ret)
45 : {
46 1678 : size_t len, len_len, mech_len, foo;
47 150809 : const u_char *p = ptr;
48 1678 : int e;
49 :
50 150809 : if (total_len < 1)
51 0 : return -1;
52 150809 : if (*p++ != 0x60)
53 31880 : return -1;
54 118833 : e = der_get_length (p, total_len - 1, &len, &len_len);
55 118833 : if (e || 1 + len_len + len != total_len)
56 0 : return -1;
57 118833 : if (total_len < 1 + len_len + 1)
58 0 : return -1;
59 118832 : p += len_len;
60 118832 : if (*p++ != 0x06)
61 0 : return -1;
62 118832 : e = der_get_length (p, total_len - 1 - len_len - 1,
63 : &mech_len, &foo);
64 118832 : if (e)
65 0 : return -1;
66 118832 : p += foo;
67 118832 : *mech_ret = p;
68 118832 : return mech_len;
69 : }
70 :
71 : OM_uint32
72 150809 : _gssapi_verify_mech_header(u_char **str,
73 : size_t total_len,
74 : gss_OID mech)
75 : {
76 1678 : const u_char *p;
77 1678 : ssize_t mech_len;
78 :
79 150809 : mech_len = _gsskrb5_get_mech (*str, total_len, &p);
80 150809 : if (mech_len < 0)
81 31880 : return GSS_S_DEFECTIVE_TOKEN;
82 :
83 118832 : if (mech_len != mech->length)
84 0 : return GSS_S_BAD_MECH;
85 118832 : if (mech_len > total_len)
86 0 : return GSS_S_BAD_MECH;
87 118831 : if (p - *str > total_len - mech_len)
88 0 : return GSS_S_BAD_MECH;
89 118831 : if (ct_memcmp(p,
90 118831 : mech->elements,
91 117251 : mech->length) != 0)
92 0 : return GSS_S_BAD_MECH;
93 118831 : p += mech_len;
94 118831 : *str = rk_UNCONST(p);
95 118831 : return GSS_S_COMPLETE;
96 : }
97 :
98 : OM_uint32
99 87408 : _gsskrb5_verify_header(u_char **str,
100 : size_t total_len,
101 : const void *type,
102 : gss_OID oid)
103 : {
104 1678 : OM_uint32 ret;
105 1678 : size_t len;
106 87408 : u_char *p = *str;
107 :
108 87408 : ret = _gssapi_verify_mech_header(str, total_len, oid);
109 87408 : if (ret)
110 31880 : return ret;
111 :
112 55430 : len = total_len - (*str - p);
113 :
114 55430 : if (len < 2)
115 0 : return GSS_S_DEFECTIVE_TOKEN;
116 :
117 55430 : if (ct_memcmp (*str, type, 2) != 0)
118 0 : return GSS_S_DEFECTIVE_TOKEN;
119 55430 : *str += 2;
120 :
121 55430 : return 0;
122 : }
123 :
124 : /*
125 : * Remove the GSS-API wrapping from `in_token' giving `out_data.
126 : * Does not copy data, so just free `in_token'.
127 : */
128 :
129 : OM_uint32
130 0 : _gssapi_decapsulate(
131 : OM_uint32 *minor_status,
132 : gss_buffer_t input_token_buffer,
133 : krb5_data *out_data,
134 : const gss_OID mech
135 : )
136 : {
137 0 : u_char *p;
138 0 : OM_uint32 ret;
139 :
140 0 : p = input_token_buffer->value;
141 0 : ret = _gssapi_verify_mech_header(&p,
142 : input_token_buffer->length,
143 : mech);
144 0 : if (ret) {
145 0 : *minor_status = 0;
146 0 : return ret;
147 : }
148 :
149 0 : out_data->length = input_token_buffer->length -
150 0 : (p - (u_char *)input_token_buffer->value);
151 0 : out_data->data = p;
152 0 : return GSS_S_COMPLETE;
153 : }
154 :
155 : /*
156 : * Remove the GSS-API wrapping from `in_token' giving `out_data.
157 : * Does not copy data, so just free `in_token'.
158 : */
159 :
160 : OM_uint32
161 72222 : _gsskrb5_decapsulate(OM_uint32 *minor_status,
162 : gss_buffer_t input_token_buffer,
163 : krb5_data *out_data,
164 : const void *type,
165 : gss_OID oid)
166 : {
167 1665 : u_char *p;
168 1665 : OM_uint32 ret;
169 :
170 72222 : p = input_token_buffer->value;
171 72222 : ret = _gsskrb5_verify_header(&p,
172 : input_token_buffer->length,
173 : type,
174 : oid);
175 72222 : if (ret) {
176 31976 : *minor_status = 0;
177 31976 : return ret;
178 : }
179 :
180 40246 : out_data->length = input_token_buffer->length -
181 40246 : (p - (u_char *)input_token_buffer->value);
182 40246 : out_data->data = p;
183 40246 : return GSS_S_COMPLETE;
184 : }
185 :
186 : /*
187 : * Verify padding of a gss wrapped message and return its length.
188 : */
189 :
190 : OM_uint32
191 51339 : _gssapi_verify_pad(gss_buffer_t wrapped_token,
192 : size_t datalen,
193 : size_t *padlen)
194 : {
195 6 : u_char *pad;
196 6 : size_t padlength;
197 6 : int i;
198 :
199 51339 : if (wrapped_token->length < 1)
200 0 : return GSS_S_BAD_MECH;
201 :
202 51339 : pad = (u_char *)wrapped_token->value + wrapped_token->length;
203 51339 : padlength = pad[-1];
204 :
205 51339 : if (padlength > datalen)
206 0 : return GSS_S_BAD_MECH;
207 :
208 102678 : for (i = padlength; i > 0 && *--pad == padlength; i--)
209 : ;
210 51337 : if (i != 0)
211 0 : return GSS_S_BAD_MIC;
212 :
213 51337 : *padlen = padlength;
214 :
215 51337 : return 0;
216 : }
|