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 * $FreeBSD$ 2933f12199SDoug Rabson */ 3033f12199SDoug Rabson 3133f12199SDoug Rabson #include <gssapi/gssapi.h> 3233f12199SDoug Rabson #include <stdlib.h> 3333f12199SDoug Rabson #include <string.h> 3433f12199SDoug Rabson 3533f12199SDoug Rabson #include "utils.h" 3633f12199SDoug Rabson 3733f12199SDoug Rabson OM_uint32 3833f12199SDoug Rabson gss_encapsulate_token(const gss_buffer_t input_token, gss_OID oid, 3933f12199SDoug Rabson gss_buffer_t output_token) 4033f12199SDoug Rabson { 4133f12199SDoug Rabson unsigned char *p; 4233f12199SDoug Rabson size_t len, inside_len; 4333f12199SDoug Rabson size_t a, b; 4433f12199SDoug Rabson int i; 4533f12199SDoug Rabson 4633f12199SDoug Rabson _gss_buffer_zero(output_token); 4733f12199SDoug Rabson 4833f12199SDoug Rabson /* 4933f12199SDoug Rabson * First time around, we calculate the size, second time, we 5033f12199SDoug Rabson * encode the token. 5133f12199SDoug Rabson */ 526baf7cc8SPedro F. Giffuni p = NULL; 5333f12199SDoug Rabson for (i = 0; i < 2; i++) { 5433f12199SDoug Rabson len = 0; 5533f12199SDoug Rabson 5633f12199SDoug Rabson /* 5733f12199SDoug Rabson * Token starts with [APPLICATION 0] SEQUENCE. 5833f12199SDoug Rabson */ 5933f12199SDoug Rabson if (p) 6033f12199SDoug Rabson *p++ = 0x60; 6133f12199SDoug Rabson len++; 6233f12199SDoug Rabson 6333f12199SDoug Rabson /* 6433f12199SDoug Rabson * The length embedded in the token is the space 6533f12199SDoug Rabson * needed for the encapsulated oid plus the length of 6633f12199SDoug Rabson * the inner token. 6733f12199SDoug Rabson */ 6833f12199SDoug Rabson if (oid->length > 127) 6933f12199SDoug Rabson return (GSS_S_DEFECTIVE_TOKEN); 7033f12199SDoug Rabson 7133f12199SDoug Rabson inside_len = 2 + oid->length + input_token->length; 7233f12199SDoug Rabson 7333f12199SDoug Rabson /* 7433f12199SDoug Rabson * Figure out how to encode the length 7533f12199SDoug Rabson */ 7633f12199SDoug Rabson if (inside_len < 128) { 7733f12199SDoug Rabson if (p) 7833f12199SDoug Rabson *p++ = inside_len; 7933f12199SDoug Rabson len++; 8033f12199SDoug Rabson } else { 8133f12199SDoug Rabson b = 1; 8233f12199SDoug Rabson if (inside_len >= 0x100) 8333f12199SDoug Rabson b++; 8433f12199SDoug Rabson if (inside_len >= 0x10000) 8533f12199SDoug Rabson b++; 8633f12199SDoug Rabson if (inside_len >= 0x1000000) 8733f12199SDoug Rabson b++; 8833f12199SDoug Rabson if (p) 8933f12199SDoug Rabson *p++ = b | 0x80; 9033f12199SDoug Rabson len++; 9133f12199SDoug Rabson a = inside_len << 8*(4 - b); 9233f12199SDoug Rabson while (b) { 9333f12199SDoug Rabson if (p) 9433f12199SDoug Rabson *p++ = (a >> 24); 9533f12199SDoug Rabson a <<= 8; 9633f12199SDoug Rabson len++; 9733f12199SDoug Rabson b--; 9833f12199SDoug Rabson } 9933f12199SDoug Rabson } 10033f12199SDoug Rabson 10133f12199SDoug Rabson /* 10233f12199SDoug Rabson * Encode the OID for the mechanism. Simplify life by 10333f12199SDoug Rabson * assuming that the OID length is less than 128 bytes. 10433f12199SDoug Rabson */ 10533f12199SDoug Rabson if (p) 10633f12199SDoug Rabson *p++ = 0x06; 10733f12199SDoug Rabson len++; 10833f12199SDoug Rabson if (p) 10933f12199SDoug Rabson *p++ = oid->length; 11033f12199SDoug Rabson len++; 11133f12199SDoug Rabson if (p) { 11233f12199SDoug Rabson memcpy(p, oid->elements, oid->length); 11333f12199SDoug Rabson p += oid->length; 11433f12199SDoug Rabson } 11533f12199SDoug Rabson len += oid->length; 11633f12199SDoug Rabson 11733f12199SDoug Rabson if (p) { 11833f12199SDoug Rabson memcpy(p, input_token->value, input_token->length); 11933f12199SDoug Rabson p += input_token->length; 12033f12199SDoug Rabson } 12133f12199SDoug Rabson len += input_token->length; 12233f12199SDoug Rabson 12333f12199SDoug Rabson if (i == 0) { 12433f12199SDoug Rabson output_token->length = len; 12533f12199SDoug Rabson output_token->value = malloc(len); 12633f12199SDoug Rabson if (!output_token->value) 12733f12199SDoug Rabson return (GSS_S_DEFECTIVE_TOKEN); 12833f12199SDoug Rabson p = output_token->value; 12933f12199SDoug Rabson } 13033f12199SDoug Rabson } 13133f12199SDoug Rabson 13233f12199SDoug Rabson return (GSS_S_COMPLETE); 13333f12199SDoug Rabson } 134