1178825Sdfr/* 2233294Sstas * Copyright (c) 1997 - 2001 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 5178825Sdfr * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 9178825Sdfr * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 12178825Sdfr * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 16178825Sdfr * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 20178825Sdfr * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 32178825Sdfr */ 33178825Sdfr 34233294Sstas#include "gsskrb5_locl.h" 35178825Sdfr 36178825Sdfr/* 37178825Sdfr * return the length of the mechanism in token or -1 38178825Sdfr * (which implies that the token was bad - GSS_S_DEFECTIVE_TOKEN 39178825Sdfr */ 40178825Sdfr 41178825Sdfrssize_t 42178825Sdfr_gsskrb5_get_mech (const u_char *ptr, 43178825Sdfr size_t total_len, 44178825Sdfr const u_char **mech_ret) 45178825Sdfr{ 46178825Sdfr size_t len, len_len, mech_len, foo; 47178825Sdfr const u_char *p = ptr; 48178825Sdfr int e; 49178825Sdfr 50178825Sdfr if (total_len < 1) 51178825Sdfr return -1; 52178825Sdfr if (*p++ != 0x60) 53178825Sdfr return -1; 54178825Sdfr e = der_get_length (p, total_len - 1, &len, &len_len); 55178825Sdfr if (e || 1 + len_len + len != total_len) 56178825Sdfr return -1; 57178825Sdfr p += len_len; 58178825Sdfr if (*p++ != 0x06) 59178825Sdfr return -1; 60178825Sdfr e = der_get_length (p, total_len - 1 - len_len - 1, 61178825Sdfr &mech_len, &foo); 62178825Sdfr if (e) 63178825Sdfr return -1; 64178825Sdfr p += foo; 65178825Sdfr *mech_ret = p; 66178825Sdfr return mech_len; 67178825Sdfr} 68178825Sdfr 69178825SdfrOM_uint32 70178825Sdfr_gssapi_verify_mech_header(u_char **str, 71178825Sdfr size_t total_len, 72178825Sdfr gss_OID mech) 73178825Sdfr{ 74178825Sdfr const u_char *p; 75178825Sdfr ssize_t mech_len; 76178825Sdfr 77178825Sdfr mech_len = _gsskrb5_get_mech (*str, total_len, &p); 78178825Sdfr if (mech_len < 0) 79178825Sdfr return GSS_S_DEFECTIVE_TOKEN; 80178825Sdfr 81178825Sdfr if (mech_len != mech->length) 82178825Sdfr return GSS_S_BAD_MECH; 83233294Sstas if (ct_memcmp(p, 84233294Sstas mech->elements, 85233294Sstas mech->length) != 0) 86178825Sdfr return GSS_S_BAD_MECH; 87178825Sdfr p += mech_len; 88178825Sdfr *str = rk_UNCONST(p); 89178825Sdfr return GSS_S_COMPLETE; 90178825Sdfr} 91178825Sdfr 92178825SdfrOM_uint32 93178825Sdfr_gsskrb5_verify_header(u_char **str, 94178825Sdfr size_t total_len, 95178825Sdfr const void *type, 96178825Sdfr gss_OID oid) 97178825Sdfr{ 98178825Sdfr OM_uint32 ret; 99178825Sdfr size_t len; 100178825Sdfr u_char *p = *str; 101178825Sdfr 102178825Sdfr ret = _gssapi_verify_mech_header(str, total_len, oid); 103178825Sdfr if (ret) 104178825Sdfr return ret; 105178825Sdfr 106178825Sdfr len = total_len - (*str - p); 107178825Sdfr 108178825Sdfr if (len < 2) 109178825Sdfr return GSS_S_DEFECTIVE_TOKEN; 110178825Sdfr 111233294Sstas if (ct_memcmp (*str, type, 2) != 0) 112178825Sdfr return GSS_S_DEFECTIVE_TOKEN; 113178825Sdfr *str += 2; 114178825Sdfr 115178825Sdfr return 0; 116178825Sdfr} 117178825Sdfr 118178825Sdfr/* 119178825Sdfr * Remove the GSS-API wrapping from `in_token' giving `out_data. 120178825Sdfr * Does not copy data, so just free `in_token'. 121178825Sdfr */ 122178825Sdfr 123178825SdfrOM_uint32 124178825Sdfr_gssapi_decapsulate( 125178825Sdfr OM_uint32 *minor_status, 126178825Sdfr gss_buffer_t input_token_buffer, 127178825Sdfr krb5_data *out_data, 128178825Sdfr const gss_OID mech 129178825Sdfr) 130178825Sdfr{ 131178825Sdfr u_char *p; 132178825Sdfr OM_uint32 ret; 133178825Sdfr 134178825Sdfr p = input_token_buffer->value; 135178825Sdfr ret = _gssapi_verify_mech_header(&p, 136178825Sdfr input_token_buffer->length, 137178825Sdfr mech); 138178825Sdfr if (ret) { 139178825Sdfr *minor_status = 0; 140178825Sdfr return ret; 141178825Sdfr } 142178825Sdfr 143178825Sdfr out_data->length = input_token_buffer->length - 144178825Sdfr (p - (u_char *)input_token_buffer->value); 145178825Sdfr out_data->data = p; 146178825Sdfr return GSS_S_COMPLETE; 147178825Sdfr} 148178825Sdfr 149178825Sdfr/* 150178825Sdfr * Remove the GSS-API wrapping from `in_token' giving `out_data. 151178825Sdfr * Does not copy data, so just free `in_token'. 152178825Sdfr */ 153178825Sdfr 154178825SdfrOM_uint32 155233294Sstas_gsskrb5_decapsulate(OM_uint32 *minor_status, 156178825Sdfr gss_buffer_t input_token_buffer, 157178825Sdfr krb5_data *out_data, 158178825Sdfr const void *type, 159178825Sdfr gss_OID oid) 160178825Sdfr{ 161178825Sdfr u_char *p; 162178825Sdfr OM_uint32 ret; 163178825Sdfr 164178825Sdfr p = input_token_buffer->value; 165178825Sdfr ret = _gsskrb5_verify_header(&p, 166178825Sdfr input_token_buffer->length, 167178825Sdfr type, 168178825Sdfr oid); 169178825Sdfr if (ret) { 170178825Sdfr *minor_status = 0; 171178825Sdfr return ret; 172178825Sdfr } 173178825Sdfr 174178825Sdfr out_data->length = input_token_buffer->length - 175178825Sdfr (p - (u_char *)input_token_buffer->value); 176178825Sdfr out_data->data = p; 177178825Sdfr return GSS_S_COMPLETE; 178178825Sdfr} 179178825Sdfr 180178825Sdfr/* 181178825Sdfr * Verify padding of a gss wrapped message and return its length. 182178825Sdfr */ 183178825Sdfr 184178825SdfrOM_uint32 185233294Sstas_gssapi_verify_pad(gss_buffer_t wrapped_token, 186178825Sdfr size_t datalen, 187178825Sdfr size_t *padlen) 188178825Sdfr{ 189178825Sdfr u_char *pad; 190178825Sdfr size_t padlength; 191178825Sdfr int i; 192178825Sdfr 193178825Sdfr pad = (u_char *)wrapped_token->value + wrapped_token->length - 1; 194178825Sdfr padlength = *pad; 195178825Sdfr 196178825Sdfr if (padlength > datalen) 197178825Sdfr return GSS_S_BAD_MECH; 198178825Sdfr 199178825Sdfr for (i = padlength; i > 0 && *pad == padlength; i--, pad--) 200178825Sdfr ; 201178825Sdfr if (i != 0) 202178825Sdfr return GSS_S_BAD_MIC; 203178825Sdfr 204178825Sdfr *padlen = padlength; 205178825Sdfr 206178825Sdfr return 0; 207178825Sdfr} 208