1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 /* 3 * Copyright 1993 by OpenVision Technologies, Inc. 4 * 5 * Permission to use, copy, modify, distribute, and sell this software 6 * and its documentation for any purpose is hereby granted without fee, 7 * provided that the above copyright notice appears in all copies and 8 * that both that copyright notice and this permission notice appear in 9 * supporting documentation, and that the name of OpenVision not be used 10 * in advertising or publicity pertaining to distribution of the software 11 * without specific, written prior permission. OpenVision makes no 12 * representations about the suitability of this software for any 13 * purpose. It is provided "as is" without express or implied warranty. 14 * 15 * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 19 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 20 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 * PERFORMANCE OF THIS SOFTWARE. 22 */ 23 24 #include "gssapiP_generic.h" 25 #include "k5-der.h" 26 #ifdef HAVE_MEMORY_H 27 #include <memory.h> 28 #endif 29 #include <limits.h> 30 31 /* 32 * $Id$ 33 */ 34 35 /* Return the length of an RFC 4121 token with RFC 2743 token framing, given 36 * the mech oid and the body size (without the two-byte RFC 4121 token ID). */ 37 unsigned int 38 g_token_size(const gss_OID_desc * mech, unsigned int body_size) 39 { 40 size_t mech_der_len = k5_der_value_len(mech->length); 41 42 return k5_der_value_len(mech_der_len + 2 + body_size); 43 } 44 45 /* 46 * Add RFC 2743 generic token framing to buf with room left for body_size bytes 47 * in the sequence to be added by the caller. If tok_type is not -1, add it as 48 * a two-byte RFC 4121 token identifier after the framing and include room for 49 * it in the sequence. 50 */ 51 void 52 g_make_token_header(struct k5buf *buf, const gss_OID_desc *mech, 53 size_t body_size, int tok_type) 54 { 55 size_t tok_len = (tok_type == -1) ? 0 : 2; 56 size_t seq_len = k5_der_value_len(mech->length) + body_size + tok_len; 57 58 k5_der_add_taglen(buf, 0x60, seq_len); 59 k5_der_add_value(buf, 0x06, mech->elements, mech->length); 60 if (tok_type != -1) 61 k5_buf_add_uint16_be(buf, tok_type); 62 } 63 64 /* 65 * Given a buffer containing a token, reads and verifies the token, 66 * leaving buf advanced past the token header, and setting body_size 67 * to the number of remaining bytes. Returns 0 on success, 68 * G_BAD_TOK_HEADER for a variety of errors, and G_WRONG_MECH if the 69 * mechanism in the token does not match the mech argument. buf and 70 * *body_size are left unmodified on error. 71 */ 72 73 gss_int32 74 g_verify_token_header( 75 const gss_OID_desc * mech, 76 unsigned int *body_size, 77 unsigned char **buf_in, 78 int tok_type, 79 unsigned int toksize_in, 80 int flags) 81 { 82 struct k5input in, mech_der; 83 gss_OID_desc toid; 84 85 k5_input_init(&in, *buf_in, toksize_in); 86 87 if (k5_der_get_value(&in, 0x60, &in)) { 88 if (in.ptr + in.len != *buf_in + toksize_in) 89 return G_BAD_TOK_HEADER; 90 if (!k5_der_get_value(&in, 0x06, &mech_der)) 91 return G_BAD_TOK_HEADER; 92 toid.elements = (uint8_t *)mech_der.ptr; 93 toid.length = mech_der.len; 94 if (!g_OID_equal(&toid, mech)) 95 return G_WRONG_MECH; 96 } else if (flags & G_VFY_TOKEN_HDR_WRAPPER_REQUIRED) { 97 return G_BAD_TOK_HEADER; 98 } 99 100 if (tok_type != -1) { 101 if (k5_input_get_uint16_be(&in) != tok_type) 102 return in.status ? G_BAD_TOK_HEADER : G_WRONG_TOKID; 103 } 104 105 *buf_in = (uint8_t *)in.ptr; 106 *body_size = in.len; 107 return 0; 108 } 109