1178828Sdfr/*- 2178828Sdfr * Copyright (c) 2008 Doug Rabson 3178828Sdfr * All rights reserved. 4178828Sdfr * 5178828Sdfr * Redistribution and use in source and binary forms, with or without 6178828Sdfr * modification, are permitted provided that the following conditions 7178828Sdfr * are met: 8178828Sdfr * 1. Redistributions of source code must retain the above copyright 9178828Sdfr * notice, this list of conditions and the following disclaimer. 10178828Sdfr * 2. Redistributions in binary form must reproduce the above copyright 11178828Sdfr * notice, this list of conditions and the following disclaimer in the 12178828Sdfr * documentation and/or other materials provided with the distribution. 13178828Sdfr * 14178828Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15178828Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16178828Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17178828Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18178828Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19178828Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20178828Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21178828Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22178828Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23178828Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24178828Sdfr * SUCH DAMAGE. 25178828Sdfr * 26178828Sdfr * $FreeBSD$ 27178828Sdfr */ 28178828Sdfr 29178828Sdfr#include <gssapi/gssapi.h> 30178828Sdfr#include <stdlib.h> 31178828Sdfr#include <string.h> 32178828Sdfr 33178828Sdfr#include "utils.h" 34178828Sdfr 35178828SdfrOM_uint32 36178828Sdfrgss_encapsulate_token(const gss_buffer_t input_token, gss_OID oid, 37178828Sdfr gss_buffer_t output_token) 38178828Sdfr{ 39178828Sdfr unsigned char *p; 40178828Sdfr size_t len, inside_len; 41178828Sdfr size_t a, b; 42178828Sdfr int i; 43178828Sdfr 44178828Sdfr _gss_buffer_zero(output_token); 45178828Sdfr 46178828Sdfr /* 47178828Sdfr * First time around, we calculate the size, second time, we 48178828Sdfr * encode the token. 49178828Sdfr */ 50178828Sdfr p = 0; 51178828Sdfr for (i = 0; i < 2; i++) { 52178828Sdfr len = 0; 53178828Sdfr 54178828Sdfr /* 55178828Sdfr * Token starts with [APPLICATION 0] SEQUENCE. 56178828Sdfr */ 57178828Sdfr if (p) 58178828Sdfr *p++ = 0x60; 59178828Sdfr len++; 60178828Sdfr 61178828Sdfr /* 62178828Sdfr * The length embedded in the token is the space 63178828Sdfr * needed for the encapsulated oid plus the length of 64178828Sdfr * the inner token. 65178828Sdfr */ 66178828Sdfr if (oid->length > 127) 67178828Sdfr return (GSS_S_DEFECTIVE_TOKEN); 68178828Sdfr 69178828Sdfr inside_len = 2 + oid->length + input_token->length; 70178828Sdfr 71178828Sdfr /* 72178828Sdfr * Figure out how to encode the length 73178828Sdfr */ 74178828Sdfr if (inside_len < 128) { 75178828Sdfr if (p) 76178828Sdfr *p++ = inside_len; 77178828Sdfr len++; 78178828Sdfr } else { 79178828Sdfr b = 1; 80178828Sdfr if (inside_len >= 0x100) 81178828Sdfr b++; 82178828Sdfr if (inside_len >= 0x10000) 83178828Sdfr b++; 84178828Sdfr if (inside_len >= 0x1000000) 85178828Sdfr b++; 86178828Sdfr if (p) 87178828Sdfr *p++ = b | 0x80; 88178828Sdfr len++; 89178828Sdfr a = inside_len << 8*(4 - b); 90178828Sdfr while (b) { 91178828Sdfr if (p) 92178828Sdfr *p++ = (a >> 24); 93178828Sdfr a <<= 8; 94178828Sdfr len++; 95178828Sdfr b--; 96178828Sdfr } 97178828Sdfr } 98178828Sdfr 99178828Sdfr /* 100178828Sdfr * Encode the OID for the mechanism. Simplify life by 101178828Sdfr * assuming that the OID length is less than 128 bytes. 102178828Sdfr */ 103178828Sdfr if (p) 104178828Sdfr *p++ = 0x06; 105178828Sdfr len++; 106178828Sdfr if (p) 107178828Sdfr *p++ = oid->length; 108178828Sdfr len++; 109178828Sdfr if (p) { 110178828Sdfr memcpy(p, oid->elements, oid->length); 111178828Sdfr p += oid->length; 112178828Sdfr } 113178828Sdfr len += oid->length; 114178828Sdfr 115178828Sdfr if (p) { 116178828Sdfr memcpy(p, input_token->value, input_token->length); 117178828Sdfr p += input_token->length; 118178828Sdfr } 119178828Sdfr len += input_token->length; 120178828Sdfr 121178828Sdfr if (i == 0) { 122178828Sdfr output_token->length = len; 123178828Sdfr output_token->value = malloc(len); 124178828Sdfr if (!output_token->value) 125178828Sdfr return (GSS_S_DEFECTIVE_TOKEN); 126178828Sdfr p = output_token->value; 127178828Sdfr } 128178828Sdfr } 129178828Sdfr 130178828Sdfr return (GSS_S_COMPLETE); 131178828Sdfr} 132