1249259Sdim/*- 2249259Sdim * SPDX-License-Identifier: BSD-2-Clause 3249259Sdim * 4249259Sdim * Copyright (c) 2008 Doug Rabson 5249259Sdim * All rights reserved. 6249259Sdim * 7249259Sdim * Redistribution and use in source and binary forms, with or without 8249259Sdim * modification, are permitted provided that the following conditions 9249259Sdim * are met: 10249259Sdim * 1. Redistributions of source code must retain the above copyright 11249259Sdim * notice, this list of conditions and the following disclaimer. 12249259Sdim * 2. Redistributions in binary form must reproduce the above copyright 13249259Sdim * notice, this list of conditions and the following disclaimer in the 14249259Sdim * documentation and/or other materials provided with the distribution. 15249259Sdim * 16249259Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17249259Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18249259Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19249259Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20249259Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21249259Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22249259Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23249259Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24249259Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25249259Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26249259Sdim * SUCH DAMAGE. 27249259Sdim */ 28249259Sdim 29249259Sdim#include <gssapi/gssapi.h> 30249259Sdim#include <stdlib.h> 31249259Sdim#include <string.h> 32263508Sdim 33249259Sdim#include "utils.h" 34249259Sdim 35249259SdimOM_uint32 36249259Sdimgss_decapsulate_token(const gss_buffer_t input_token, gss_OID oid, 37249259Sdim gss_buffer_t output_token) 38249259Sdim{ 39249259Sdim unsigned char *p = input_token->value; 40249259Sdim size_t len = input_token->length; 41249259Sdim size_t a, b; 42249259Sdim gss_OID_desc mech_oid; 43249259Sdim 44249259Sdim _gss_buffer_zero(output_token); 45263508Sdim 46249259Sdim /* 47249259Sdim * Token must start with [APPLICATION 0] SEQUENCE. 48249259Sdim */ 49249259Sdim if (len == 0 || *p != 0x60) 50249259Sdim return (GSS_S_DEFECTIVE_TOKEN); 51249259Sdim p++; 52249259Sdim len--; 53249259Sdim 54249259Sdim /* 55249259Sdim * Decode the length and make sure it agrees with the 56263508Sdim * token length. 57249259Sdim */ 58249259Sdim if (len == 0) 59249259Sdim return (GSS_S_DEFECTIVE_TOKEN); 60249259Sdim if ((*p & 0x80) == 0) { 61249259Sdim a = *p; 62249259Sdim p++; 63249259Sdim len--; 64249259Sdim } else { 65249259Sdim b = *p & 0x7f; 66249259Sdim p++; 67249259Sdim len--; 68249259Sdim if (len < b) 69249259Sdim return (GSS_S_DEFECTIVE_TOKEN); 70249259Sdim a = 0; 71249259Sdim while (b) { 72263508Sdim a = (a << 8) | *p; 73249259Sdim p++; 74249259Sdim len--; 75249259Sdim b--; 76249259Sdim } 77249259Sdim } 78249259Sdim if (a != len) 79249259Sdim return (GSS_S_DEFECTIVE_TOKEN); 80249259Sdim 81249259Sdim /* 82249259Sdim * Decode the OID for the mechanism. Simplify life by 83249259Sdim * assuming that the OID length is less than 128 bytes. 84249259Sdim */ 85249259Sdim if (len < 2 || *p != 0x06) 86249259Sdim return (GSS_S_DEFECTIVE_TOKEN); 87249259Sdim if ((p[1] & 0x80) || p[1] > (len - 2)) 88249259Sdim return (GSS_S_DEFECTIVE_TOKEN); 89249259Sdim mech_oid.length = p[1]; 90249259Sdim p += 2; 91249259Sdim len -= 2; 92249259Sdim mech_oid.elements = p; 93249259Sdim 94249259Sdim if (!gss_oid_equal(&mech_oid, oid)) 95249259Sdim return (GSS_S_FAILURE); 96249259Sdim 97249259Sdim p += mech_oid.length; 98249259Sdim len -= mech_oid.length; 99249259Sdim 100251662Sdim output_token->length = len; 101251662Sdim output_token->value = malloc(len); 102249259Sdim if (!output_token->value) 103249259Sdim return (GSS_S_DEFECTIVE_TOKEN); 104249259Sdim memcpy(output_token->value, p, len); 105249259Sdim 106249259Sdim return (GSS_S_COMPLETE); 107249259Sdim} 108249259Sdim