xref: /freebsd-src/lib/libgssapi/gss_decapsulate_token.c (revision b3e7694832e81d7a904a10f525f8797b753bf0d3)
133f12199SDoug Rabson /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
35e53a4f9SPedro F. Giffuni  *
433f12199SDoug Rabson  * Copyright (c) 2008 Doug Rabson
533f12199SDoug Rabson  * All rights reserved.
633f12199SDoug Rabson  *
733f12199SDoug Rabson  * Redistribution and use in source and binary forms, with or without
833f12199SDoug Rabson  * modification, are permitted provided that the following conditions
933f12199SDoug Rabson  * are met:
1033f12199SDoug Rabson  * 1. Redistributions of source code must retain the above copyright
1133f12199SDoug Rabson  *    notice, this list of conditions and the following disclaimer.
1233f12199SDoug Rabson  * 2. Redistributions in binary form must reproduce the above copyright
1333f12199SDoug Rabson  *    notice, this list of conditions and the following disclaimer in the
1433f12199SDoug Rabson  *    documentation and/or other materials provided with the distribution.
1533f12199SDoug Rabson  *
1633f12199SDoug Rabson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1733f12199SDoug Rabson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1833f12199SDoug Rabson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1933f12199SDoug Rabson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2033f12199SDoug Rabson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2133f12199SDoug Rabson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2233f12199SDoug Rabson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2333f12199SDoug Rabson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2433f12199SDoug Rabson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2533f12199SDoug Rabson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2633f12199SDoug Rabson  * SUCH DAMAGE.
2733f12199SDoug Rabson  */
2833f12199SDoug Rabson 
2933f12199SDoug Rabson #include <gssapi/gssapi.h>
3033f12199SDoug Rabson #include <stdlib.h>
3133f12199SDoug Rabson #include <string.h>
3233f12199SDoug Rabson 
3333f12199SDoug Rabson #include "utils.h"
3433f12199SDoug Rabson 
3533f12199SDoug Rabson OM_uint32
gss_decapsulate_token(const gss_buffer_t input_token,gss_OID oid,gss_buffer_t output_token)3633f12199SDoug Rabson gss_decapsulate_token(const gss_buffer_t input_token, gss_OID oid,
3733f12199SDoug Rabson     gss_buffer_t output_token)
3833f12199SDoug Rabson {
3933f12199SDoug Rabson 	unsigned char *p = input_token->value;
4033f12199SDoug Rabson 	size_t len = input_token->length;
4133f12199SDoug Rabson 	size_t a, b;
4233f12199SDoug Rabson 	gss_OID_desc mech_oid;
4333f12199SDoug Rabson 
4433f12199SDoug Rabson 	_gss_buffer_zero(output_token);
4533f12199SDoug Rabson 
4633f12199SDoug Rabson 	/*
4733f12199SDoug Rabson 	 * Token must start with [APPLICATION 0] SEQUENCE.
4833f12199SDoug Rabson 	 */
4933f12199SDoug Rabson 	if (len == 0 || *p != 0x60)
5033f12199SDoug Rabson 		return (GSS_S_DEFECTIVE_TOKEN);
5133f12199SDoug Rabson 	p++;
5233f12199SDoug Rabson 	len--;
5333f12199SDoug Rabson 
5433f12199SDoug Rabson 	/*
5533f12199SDoug Rabson 	 * Decode the length and make sure it agrees with the
5633f12199SDoug Rabson 	 * token length.
5733f12199SDoug Rabson 	 */
5833f12199SDoug Rabson 	if (len == 0)
5933f12199SDoug Rabson 		return (GSS_S_DEFECTIVE_TOKEN);
6033f12199SDoug Rabson 	if ((*p & 0x80) == 0) {
6133f12199SDoug Rabson 		a = *p;
6233f12199SDoug Rabson 		p++;
6333f12199SDoug Rabson 		len--;
6433f12199SDoug Rabson 	} else {
6533f12199SDoug Rabson 		b = *p & 0x7f;
6633f12199SDoug Rabson 		p++;
6733f12199SDoug Rabson 		len--;
6833f12199SDoug Rabson 		if (len < b)
6933f12199SDoug Rabson 			return (GSS_S_DEFECTIVE_TOKEN);
7033f12199SDoug Rabson 		a = 0;
7133f12199SDoug Rabson 		while (b) {
7233f12199SDoug Rabson 			a = (a << 8) | *p;
7333f12199SDoug Rabson 			p++;
7433f12199SDoug Rabson 			len--;
7533f12199SDoug Rabson 			b--;
7633f12199SDoug Rabson 		}
7733f12199SDoug Rabson 	}
7833f12199SDoug Rabson 	if (a != len)
7933f12199SDoug Rabson 		return (GSS_S_DEFECTIVE_TOKEN);
8033f12199SDoug Rabson 
8133f12199SDoug Rabson 	/*
8233f12199SDoug Rabson 	 * Decode the OID for the mechanism. Simplify life by
8333f12199SDoug Rabson 	 * assuming that the OID length is less than 128 bytes.
8433f12199SDoug Rabson 	 */
8533f12199SDoug Rabson 	if (len < 2 || *p != 0x06)
8633f12199SDoug Rabson 		return (GSS_S_DEFECTIVE_TOKEN);
8733f12199SDoug Rabson 	if ((p[1] & 0x80) || p[1] > (len - 2))
8833f12199SDoug Rabson 		return (GSS_S_DEFECTIVE_TOKEN);
8933f12199SDoug Rabson 	mech_oid.length = p[1];
9033f12199SDoug Rabson 	p += 2;
9133f12199SDoug Rabson 	len -= 2;
9233f12199SDoug Rabson 	mech_oid.elements = p;
9333f12199SDoug Rabson 
9433f12199SDoug Rabson 	if (!gss_oid_equal(&mech_oid, oid))
9533f12199SDoug Rabson 		return (GSS_S_FAILURE);
9633f12199SDoug Rabson 
9733f12199SDoug Rabson 	p += mech_oid.length;
9833f12199SDoug Rabson 	len -= mech_oid.length;
9933f12199SDoug Rabson 
10033f12199SDoug Rabson 	output_token->length = len;
10133f12199SDoug Rabson 	output_token->value = malloc(len);
10233f12199SDoug Rabson 	if (!output_token->value)
10333f12199SDoug Rabson 		return (GSS_S_DEFECTIVE_TOKEN);
10433f12199SDoug Rabson 	memcpy(output_token->value, p, len);
10533f12199SDoug Rabson 
10633f12199SDoug Rabson 	return (GSS_S_COMPLETE);
10733f12199SDoug Rabson }
108