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: releng/10.2/lib/libgssapi/gss_decapsulate_token.c 178828 2008-05-07 13:53:12Z dfr $ 27178828Sdfr */ 28178828Sdfr 29178828Sdfr#include <gssapi/gssapi.h> 30178828Sdfr#include <stdlib.h> 31178828Sdfr#include <string.h> 32178828Sdfr 33178828Sdfr#include "utils.h" 34178828Sdfr 35178828SdfrOM_uint32 36178828Sdfrgss_decapsulate_token(const gss_buffer_t input_token, gss_OID oid, 37178828Sdfr gss_buffer_t output_token) 38178828Sdfr{ 39178828Sdfr unsigned char *p = input_token->value; 40178828Sdfr size_t len = input_token->length; 41178828Sdfr size_t a, b; 42178828Sdfr gss_OID_desc mech_oid; 43178828Sdfr 44178828Sdfr _gss_buffer_zero(output_token); 45178828Sdfr 46178828Sdfr /* 47178828Sdfr * Token must start with [APPLICATION 0] SEQUENCE. 48178828Sdfr */ 49178828Sdfr if (len == 0 || *p != 0x60) 50178828Sdfr return (GSS_S_DEFECTIVE_TOKEN); 51178828Sdfr p++; 52178828Sdfr len--; 53178828Sdfr 54178828Sdfr /* 55178828Sdfr * Decode the length and make sure it agrees with the 56178828Sdfr * token length. 57178828Sdfr */ 58178828Sdfr if (len == 0) 59178828Sdfr return (GSS_S_DEFECTIVE_TOKEN); 60178828Sdfr if ((*p & 0x80) == 0) { 61178828Sdfr a = *p; 62178828Sdfr p++; 63178828Sdfr len--; 64178828Sdfr } else { 65178828Sdfr b = *p & 0x7f; 66178828Sdfr p++; 67178828Sdfr len--; 68178828Sdfr if (len < b) 69178828Sdfr return (GSS_S_DEFECTIVE_TOKEN); 70178828Sdfr a = 0; 71178828Sdfr while (b) { 72178828Sdfr a = (a << 8) | *p; 73178828Sdfr p++; 74178828Sdfr len--; 75178828Sdfr b--; 76178828Sdfr } 77178828Sdfr } 78178828Sdfr if (a != len) 79178828Sdfr return (GSS_S_DEFECTIVE_TOKEN); 80178828Sdfr 81178828Sdfr /* 82178828Sdfr * Decode the OID for the mechanism. Simplify life by 83178828Sdfr * assuming that the OID length is less than 128 bytes. 84178828Sdfr */ 85178828Sdfr if (len < 2 || *p != 0x06) 86178828Sdfr return (GSS_S_DEFECTIVE_TOKEN); 87178828Sdfr if ((p[1] & 0x80) || p[1] > (len - 2)) 88178828Sdfr return (GSS_S_DEFECTIVE_TOKEN); 89178828Sdfr mech_oid.length = p[1]; 90178828Sdfr p += 2; 91178828Sdfr len -= 2; 92178828Sdfr mech_oid.elements = p; 93178828Sdfr 94178828Sdfr if (!gss_oid_equal(&mech_oid, oid)) 95178828Sdfr return (GSS_S_FAILURE); 96178828Sdfr 97178828Sdfr p += mech_oid.length; 98178828Sdfr len -= mech_oid.length; 99178828Sdfr 100178828Sdfr output_token->length = len; 101178828Sdfr output_token->value = malloc(len); 102178828Sdfr if (!output_token->value) 103178828Sdfr return (GSS_S_DEFECTIVE_TOKEN); 104178828Sdfr memcpy(output_token->value, p, len); 105178828Sdfr 106178828Sdfr return (GSS_S_COMPLETE); 107178828Sdfr} 108