133f12199SDoug Rabson /*- 233f12199SDoug Rabson * Copyright (c) 2008 Doug Rabson 333f12199SDoug Rabson * All rights reserved. 433f12199SDoug Rabson * 533f12199SDoug Rabson * Redistribution and use in source and binary forms, with or without 633f12199SDoug Rabson * modification, are permitted provided that the following conditions 733f12199SDoug Rabson * are met: 833f12199SDoug Rabson * 1. Redistributions of source code must retain the above copyright 933f12199SDoug Rabson * notice, this list of conditions and the following disclaimer. 1033f12199SDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright 1133f12199SDoug Rabson * notice, this list of conditions and the following disclaimer in the 1233f12199SDoug Rabson * documentation and/or other materials provided with the distribution. 1333f12199SDoug Rabson * 1433f12199SDoug Rabson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1533f12199SDoug Rabson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1633f12199SDoug Rabson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1733f12199SDoug Rabson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1833f12199SDoug Rabson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1933f12199SDoug Rabson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2033f12199SDoug Rabson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2133f12199SDoug Rabson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2233f12199SDoug Rabson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2333f12199SDoug Rabson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2433f12199SDoug Rabson * SUCH DAMAGE. 2533f12199SDoug Rabson * 2633f12199SDoug Rabson * $FreeBSD$ 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 3633f12199SDoug Rabson gss_encapsulate_token(const gss_buffer_t input_token, gss_OID oid, 3733f12199SDoug Rabson gss_buffer_t output_token) 3833f12199SDoug Rabson { 3933f12199SDoug Rabson unsigned char *p; 4033f12199SDoug Rabson size_t len, inside_len; 4133f12199SDoug Rabson size_t a, b; 4233f12199SDoug Rabson int i; 4333f12199SDoug Rabson 4433f12199SDoug Rabson _gss_buffer_zero(output_token); 4533f12199SDoug Rabson 4633f12199SDoug Rabson /* 4733f12199SDoug Rabson * First time around, we calculate the size, second time, we 4833f12199SDoug Rabson * encode the token. 4933f12199SDoug Rabson */ 50*6baf7cc8SPedro F. Giffuni p = NULL; 5133f12199SDoug Rabson for (i = 0; i < 2; i++) { 5233f12199SDoug Rabson len = 0; 5333f12199SDoug Rabson 5433f12199SDoug Rabson /* 5533f12199SDoug Rabson * Token starts with [APPLICATION 0] SEQUENCE. 5633f12199SDoug Rabson */ 5733f12199SDoug Rabson if (p) 5833f12199SDoug Rabson *p++ = 0x60; 5933f12199SDoug Rabson len++; 6033f12199SDoug Rabson 6133f12199SDoug Rabson /* 6233f12199SDoug Rabson * The length embedded in the token is the space 6333f12199SDoug Rabson * needed for the encapsulated oid plus the length of 6433f12199SDoug Rabson * the inner token. 6533f12199SDoug Rabson */ 6633f12199SDoug Rabson if (oid->length > 127) 6733f12199SDoug Rabson return (GSS_S_DEFECTIVE_TOKEN); 6833f12199SDoug Rabson 6933f12199SDoug Rabson inside_len = 2 + oid->length + input_token->length; 7033f12199SDoug Rabson 7133f12199SDoug Rabson /* 7233f12199SDoug Rabson * Figure out how to encode the length 7333f12199SDoug Rabson */ 7433f12199SDoug Rabson if (inside_len < 128) { 7533f12199SDoug Rabson if (p) 7633f12199SDoug Rabson *p++ = inside_len; 7733f12199SDoug Rabson len++; 7833f12199SDoug Rabson } else { 7933f12199SDoug Rabson b = 1; 8033f12199SDoug Rabson if (inside_len >= 0x100) 8133f12199SDoug Rabson b++; 8233f12199SDoug Rabson if (inside_len >= 0x10000) 8333f12199SDoug Rabson b++; 8433f12199SDoug Rabson if (inside_len >= 0x1000000) 8533f12199SDoug Rabson b++; 8633f12199SDoug Rabson if (p) 8733f12199SDoug Rabson *p++ = b | 0x80; 8833f12199SDoug Rabson len++; 8933f12199SDoug Rabson a = inside_len << 8*(4 - b); 9033f12199SDoug Rabson while (b) { 9133f12199SDoug Rabson if (p) 9233f12199SDoug Rabson *p++ = (a >> 24); 9333f12199SDoug Rabson a <<= 8; 9433f12199SDoug Rabson len++; 9533f12199SDoug Rabson b--; 9633f12199SDoug Rabson } 9733f12199SDoug Rabson } 9833f12199SDoug Rabson 9933f12199SDoug Rabson /* 10033f12199SDoug Rabson * Encode the OID for the mechanism. Simplify life by 10133f12199SDoug Rabson * assuming that the OID length is less than 128 bytes. 10233f12199SDoug Rabson */ 10333f12199SDoug Rabson if (p) 10433f12199SDoug Rabson *p++ = 0x06; 10533f12199SDoug Rabson len++; 10633f12199SDoug Rabson if (p) 10733f12199SDoug Rabson *p++ = oid->length; 10833f12199SDoug Rabson len++; 10933f12199SDoug Rabson if (p) { 11033f12199SDoug Rabson memcpy(p, oid->elements, oid->length); 11133f12199SDoug Rabson p += oid->length; 11233f12199SDoug Rabson } 11333f12199SDoug Rabson len += oid->length; 11433f12199SDoug Rabson 11533f12199SDoug Rabson if (p) { 11633f12199SDoug Rabson memcpy(p, input_token->value, input_token->length); 11733f12199SDoug Rabson p += input_token->length; 11833f12199SDoug Rabson } 11933f12199SDoug Rabson len += input_token->length; 12033f12199SDoug Rabson 12133f12199SDoug Rabson if (i == 0) { 12233f12199SDoug Rabson output_token->length = len; 12333f12199SDoug Rabson output_token->value = malloc(len); 12433f12199SDoug Rabson if (!output_token->value) 12533f12199SDoug Rabson return (GSS_S_DEFECTIVE_TOKEN); 12633f12199SDoug Rabson p = output_token->value; 12733f12199SDoug Rabson } 12833f12199SDoug Rabson } 12933f12199SDoug Rabson 13033f12199SDoug Rabson return (GSS_S_COMPLETE); 13133f12199SDoug Rabson } 132