Blame src/tests/gssapi/t_invalid.c

Packit fd8b60
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
Packit fd8b60
/* tests/gssapi/t_invalid.c - Invalid message token regression tests */
Packit fd8b60
/*
Packit fd8b60
 * Copyright (C) 2014 by the Massachusetts Institute of Technology.
Packit fd8b60
 * All rights reserved.
Packit fd8b60
 *
Packit fd8b60
 * Redistribution and use in source and binary forms, with or without
Packit fd8b60
 * modification, are permitted provided that the following conditions
Packit fd8b60
 * are met:
Packit fd8b60
 *
Packit fd8b60
 * * Redistributions of source code must retain the above copyright
Packit fd8b60
 *   notice, this list of conditions and the following disclaimer.
Packit fd8b60
 *
Packit fd8b60
 * * Redistributions in binary form must reproduce the above copyright
Packit fd8b60
 *   notice, this list of conditions and the following disclaimer in
Packit fd8b60
 *   the documentation and/or other materials provided with the
Packit fd8b60
 *   distribution.
Packit fd8b60
 *
Packit fd8b60
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit fd8b60
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit fd8b60
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
Packit fd8b60
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
Packit fd8b60
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
Packit fd8b60
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
Packit fd8b60
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
Packit fd8b60
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
Packit fd8b60
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
Packit fd8b60
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
Packit fd8b60
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
Packit fd8b60
 * OF THE POSSIBILITY OF SUCH DAMAGE.
Packit fd8b60
 */
Packit fd8b60
Packit fd8b60
/*
Packit fd8b60
 * This file contains regression tests for some GSSAPI invalid token
Packit fd8b60
 * vulnerabilities.
Packit fd8b60
 *
Packit fd8b60
 * 1. A pre-CFX wrap or MIC token processed with a CFX-only context causes a
Packit fd8b60
 *    null pointer dereference.  (The token must use SEAL_ALG_NONE or it will
Packit fd8b60
 *    be rejected.)
Packit fd8b60
 *
Packit fd8b60
 * 2. A pre-CFX wrap or MIC token with fewer than 24 bytes after the ASN.1
Packit fd8b60
 *    header causes an input buffer overrun, usually leading to either a segv
Packit fd8b60
 *    or a GSS_S_DEFECTIVE_TOKEN error due to garbage algorithm, filler, or
Packit fd8b60
 *    sequence number values.
Packit fd8b60
 *
Packit fd8b60
 * 3. A pre-CFX wrap token with fewer than 16 + cksumlen bytes after the ASN.1
Packit fd8b60
 *    header causes an integer underflow when computing the ciphertext length,
Packit fd8b60
 *    leading to an allocation error on 32-bit platforms or a segv on 64-bit
Packit fd8b60
 *    platforms.  A pre-CFX MIC token of this size causes an input buffer
Packit fd8b60
 *    overrun when comparing the checksum, perhaps leading to a segv.
Packit fd8b60
 *
Packit fd8b60
 * 4. A pre-CFX wrap token with fewer than conflen + padlen bytes in the
Packit fd8b60
 *    ciphertext (where padlen is the last byte of the decrypted ciphertext)
Packit fd8b60
 *    causes an integer underflow when computing the original message length,
Packit fd8b60
 *    leading to an allocation error.
Packit fd8b60
 *
Packit fd8b60
 * 5. In the mechglue, truncated encapsulation in the initial context token can
Packit fd8b60
 *    cause input buffer overruns in gss_accept_sec_context().
Packit fd8b60
 *
Packit fd8b60
 * Vulnerabilities #1 and #2 also apply to IOV unwrap, although tokens with
Packit fd8b60
 * fewer than 16 bytes after the ASN.1 header will be rejected.
Packit fd8b60
 * Vulnerabilities #2 and #5 can only be robustly detected using a
Packit fd8b60
 * memory-checking environment such as valgrind.
Packit fd8b60
 */
Packit fd8b60
Packit fd8b60
#include "k5-int.h"
Packit fd8b60
#include "common.h"
Packit fd8b60
#include "mglueP.h"
Packit fd8b60
#include "gssapiP_krb5.h"
Packit fd8b60
Packit fd8b60
/*
Packit fd8b60
 * The following samples contain context parameters and otherwise valid seal
Packit fd8b60
 * tokens where the plain text is padded with byte value 100 instead of the
Packit fd8b60
 * proper value 1.
Packit fd8b60
 */
Packit fd8b60
struct test {
Packit fd8b60
    krb5_enctype enctype;
Packit fd8b60
    krb5_enctype encseq_enctype;
Packit fd8b60
    int sealalg;
Packit fd8b60
    int signalg;
Packit fd8b60
    size_t cksum_size;
Packit fd8b60
    size_t keylen;
Packit fd8b60
    const char *keydata;
Packit fd8b60
    size_t toklen;
Packit fd8b60
    const char *token;
Packit fd8b60
} tests[] = {
Packit fd8b60
    {
Packit fd8b60
        ENCTYPE_ARCFOUR_HMAC, ENCTYPE_ARCFOUR_HMAC,
Packit fd8b60
        SEAL_ALG_MICROSOFT_RC4, SGN_ALG_HMAC_MD5, 8,
Packit fd8b60
        16,
Packit fd8b60
        "\x66\x64\x41\x64\x55\x78\x21\xD0\xD0\xFD\x05\x6A\xFF\x6F\xE8\x09",
Packit fd8b60
        53,
Packit fd8b60
        "\x60\x33\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02\x01\x11"
Packit fd8b60
        "\x00\x10\x00\xFF\xFF\x35\xD4\x79\xF3\x8C\x47\x8F\x6E\x23\x6F\x3E"
Packit fd8b60
        "\xCC\x5E\x57\x5C\x6A\x89\xF0\xA2\x03\x4F\x0B\x51\x11\xEE\x89\x7E"
Packit fd8b60
        "\xD6\xF6\xB5\xD6\x51"
Packit fd8b60
    }
Packit fd8b60
};
Packit fd8b60
Packit fd8b60
/* Fake up enough of a CFX GSS context for gss_unwrap, using an AES key. */
Packit fd8b60
static gss_ctx_id_t
Packit fd8b60
make_fake_cfx_context()
Packit fd8b60
{
Packit fd8b60
    gss_union_ctx_id_t uctx;
Packit fd8b60
    krb5_gss_ctx_id_t kgctx;
Packit fd8b60
    krb5_keyblock kb;
Packit fd8b60
Packit fd8b60
    kgctx = calloc(1, sizeof(*kgctx));
Packit fd8b60
    if (kgctx == NULL)
Packit fd8b60
        abort();
Packit fd8b60
    kgctx->established = 1;
Packit fd8b60
    kgctx->proto = 1;
Packit fd8b60
    if (g_seqstate_init(&kgctx->seqstate, 0, 0, 0, 0) != 0)
Packit fd8b60
        abort();
Packit fd8b60
    kgctx->mech_used = &mech_krb5;
Packit fd8b60
    kgctx->sealalg = -1;
Packit fd8b60
    kgctx->signalg = -1;
Packit fd8b60
Packit fd8b60
    kb.enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
Packit fd8b60
    kb.length = 16;
Packit fd8b60
    kb.contents = (unsigned char *)"1234567887654321";
Packit fd8b60
    if (krb5_k_create_key(NULL, &kb, &kgctx->subkey) != 0)
Packit fd8b60
        abort();
Packit fd8b60
Packit fd8b60
    uctx = calloc(1, sizeof(*uctx));
Packit fd8b60
    if (uctx == NULL)
Packit fd8b60
        abort();
Packit fd8b60
    uctx->mech_type = &mech_krb5;
Packit fd8b60
    uctx->internal_ctx_id = (gss_ctx_id_t)kgctx;
Packit fd8b60
    return (gss_ctx_id_t)uctx;
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
/* Fake up enough of a GSS context for gss_unwrap, using keys from test. */
Packit fd8b60
static gss_ctx_id_t
Packit fd8b60
make_fake_context(const struct test *test)
Packit fd8b60
{
Packit fd8b60
    gss_union_ctx_id_t uctx;
Packit fd8b60
    krb5_gss_ctx_id_t kgctx;
Packit fd8b60
    krb5_keyblock kb;
Packit fd8b60
Packit fd8b60
    kgctx = calloc(1, sizeof(*kgctx));
Packit fd8b60
    if (kgctx == NULL)
Packit fd8b60
        abort();
Packit fd8b60
    kgctx->established = 1;
Packit fd8b60
    if (g_seqstate_init(&kgctx->seqstate, 0, 0, 0, 0) != 0)
Packit fd8b60
        abort();
Packit fd8b60
    kgctx->mech_used = &mech_krb5;
Packit fd8b60
    kgctx->sealalg = test->sealalg;
Packit fd8b60
    kgctx->signalg = test->signalg;
Packit fd8b60
    kgctx->cksum_size = test->cksum_size;
Packit fd8b60
Packit fd8b60
    kb.enctype = test->enctype;
Packit fd8b60
    kb.length = test->keylen;
Packit fd8b60
    kb.contents = (unsigned char *)test->keydata;
Packit fd8b60
    if (krb5_k_create_key(NULL, &kb, &kgctx->subkey) != 0)
Packit fd8b60
        abort();
Packit fd8b60
Packit fd8b60
    kb.enctype = test->encseq_enctype;
Packit fd8b60
    if (krb5_k_create_key(NULL, &kb, &kgctx->seq) != 0)
Packit fd8b60
        abort();
Packit fd8b60
Packit fd8b60
    if (krb5_k_create_key(NULL, &kb, &kgctx->enc) != 0)
Packit fd8b60
        abort();
Packit fd8b60
Packit fd8b60
    uctx = calloc(1, sizeof(*uctx));
Packit fd8b60
    if (uctx == NULL)
Packit fd8b60
        abort();
Packit fd8b60
    uctx->mech_type = &mech_krb5;
Packit fd8b60
    uctx->internal_ctx_id = (gss_ctx_id_t)kgctx;
Packit fd8b60
    return (gss_ctx_id_t)uctx;
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
/* Free a context created by make_fake_context. */
Packit fd8b60
static void
Packit fd8b60
free_fake_context(gss_ctx_id_t ctx)
Packit fd8b60
{
Packit fd8b60
    gss_union_ctx_id_t uctx = (gss_union_ctx_id_t)ctx;
Packit fd8b60
    krb5_gss_ctx_id_t kgctx = (krb5_gss_ctx_id_t)uctx->internal_ctx_id;
Packit fd8b60
Packit fd8b60
    free(kgctx->seqstate);
Packit fd8b60
    krb5_k_free_key(NULL, kgctx->subkey);
Packit fd8b60
    krb5_k_free_key(NULL, kgctx->seq);
Packit fd8b60
    krb5_k_free_key(NULL, kgctx->enc);
Packit fd8b60
    free(kgctx);
Packit fd8b60
    free(uctx);
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
/* Prefix a token (starting at the two-byte ID) with an ASN.1 header and return
Packit fd8b60
 * it in an allocated block to facilitate checking by valgrind or similar. */
Packit fd8b60
static void
Packit fd8b60
make_token(unsigned char *token, size_t len, gss_buffer_t out)
Packit fd8b60
{
Packit fd8b60
    char *wrapped;
Packit fd8b60
Packit fd8b60
    assert(mech_krb5.length == 9);
Packit fd8b60
    assert(len + 11 < 128);
Packit fd8b60
    wrapped = malloc(len + 13);
Packit fd8b60
    if (wrapped == NULL)
Packit fd8b60
        abort();
Packit fd8b60
    wrapped[0] = 0x60;
Packit fd8b60
    wrapped[1] = len + 11;
Packit fd8b60
    wrapped[2] = 0x06;
Packit fd8b60
    wrapped[3] = 9;
Packit fd8b60
    memcpy(wrapped + 4, mech_krb5.elements, 9);
Packit fd8b60
    memcpy(wrapped + 13, token, len);
Packit fd8b60
    out->length = len + 13;
Packit fd8b60
    out->value = wrapped;
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
/* Unwrap a superficially valid RFC 1964 token with a CFX-only context, with
Packit fd8b60
 * regular and IOV unwrap. */
Packit fd8b60
static void
Packit fd8b60
test_bogus_1964_token(gss_ctx_id_t ctx)
Packit fd8b60
{
Packit fd8b60
    OM_uint32 minor, major;
Packit fd8b60
    unsigned char tokbuf[128];
Packit fd8b60
    gss_buffer_desc in, out;
Packit fd8b60
    gss_iov_buffer_desc iov;
Packit fd8b60
Packit fd8b60
    store_16_be(KG_TOK_SIGN_MSG, tokbuf);
Packit fd8b60
    store_16_le(SGN_ALG_HMAC_MD5, tokbuf + 2);
Packit fd8b60
    store_16_le(SEAL_ALG_NONE, tokbuf + 4);
Packit fd8b60
    store_16_le(0xFFFF, tokbuf + 6);
Packit fd8b60
    memset(tokbuf + 8, 0, 16);
Packit fd8b60
    make_token(tokbuf, 24, &in);
Packit fd8b60
Packit fd8b60
    major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
Packit fd8b60
    if (major != GSS_S_DEFECTIVE_TOKEN)
Packit fd8b60
        abort();
Packit fd8b60
    (void)gss_release_buffer(&minor, &out;;
Packit fd8b60
Packit fd8b60
    iov.type = GSS_IOV_BUFFER_TYPE_HEADER;
Packit fd8b60
    iov.buffer = in;
Packit fd8b60
    major = gss_unwrap_iov(&minor, ctx, NULL, NULL, &iov, 1);
Packit fd8b60
    if (major != GSS_S_DEFECTIVE_TOKEN)
Packit fd8b60
        abort();
Packit fd8b60
Packit fd8b60
    free(in.value);
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
/* Process wrap and MIC tokens with incomplete headers. */
Packit fd8b60
static void
Packit fd8b60
test_short_header(gss_ctx_id_t ctx)
Packit fd8b60
{
Packit fd8b60
    OM_uint32 minor, major;
Packit fd8b60
    unsigned char tokbuf[128];
Packit fd8b60
    gss_buffer_desc in, out, empty = GSS_C_EMPTY_BUFFER;
Packit fd8b60
Packit fd8b60
    /* Seal token, 2-24 bytes */
Packit fd8b60
    store_16_be(KG_TOK_SEAL_MSG, tokbuf);
Packit fd8b60
    make_token(tokbuf, 2, &in);
Packit fd8b60
    major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
Packit fd8b60
    if (major != GSS_S_DEFECTIVE_TOKEN)
Packit fd8b60
        abort();
Packit fd8b60
    free(in.value);
Packit fd8b60
    (void)gss_release_buffer(&minor, &out;;
Packit fd8b60
Packit fd8b60
    /* Sign token, 2-24 bytes */
Packit fd8b60
    store_16_be(KG_TOK_SIGN_MSG, tokbuf);
Packit fd8b60
    make_token(tokbuf, 2, &in);
Packit fd8b60
    major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
Packit fd8b60
    if (major != GSS_S_DEFECTIVE_TOKEN)
Packit fd8b60
        abort();
Packit fd8b60
    free(in.value);
Packit fd8b60
    (void)gss_release_buffer(&minor, &out;;
Packit fd8b60
Packit fd8b60
    /* MIC token, 2-24 bytes */
Packit fd8b60
    store_16_be(KG_TOK_MIC_MSG, tokbuf);
Packit fd8b60
    make_token(tokbuf, 2, &in);
Packit fd8b60
    major = gss_verify_mic(&minor, ctx, &empty, &in, NULL);
Packit fd8b60
    if (major != GSS_S_DEFECTIVE_TOKEN)
Packit fd8b60
        abort();
Packit fd8b60
    free(in.value);
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
/* Process wrap and MIC tokens with incomplete headers. */
Packit fd8b60
static void
Packit fd8b60
test_short_header_iov(gss_ctx_id_t ctx, const struct test *test)
Packit fd8b60
{
Packit fd8b60
    OM_uint32 minor, major;
Packit fd8b60
    unsigned char tokbuf[128];
Packit fd8b60
    gss_iov_buffer_desc iov;
Packit fd8b60
Packit fd8b60
    /* IOV seal token, 16-23 bytes */
Packit fd8b60
    store_16_be(KG_TOK_SEAL_MSG, tokbuf);
Packit fd8b60
    store_16_le(test->signalg, tokbuf + 2);
Packit fd8b60
    store_16_le(test->sealalg, tokbuf + 4);
Packit fd8b60
    store_16_be(0xFFFF, tokbuf + 6);
Packit fd8b60
    memset(tokbuf + 8, 0, 8);
Packit fd8b60
    iov.type = GSS_IOV_BUFFER_TYPE_HEADER;
Packit fd8b60
    make_token(tokbuf, 16, &iov.buffer);
Packit fd8b60
    major = gss_unwrap_iov(&minor, ctx, NULL, NULL, &iov, 1);
Packit fd8b60
    if (major != GSS_S_DEFECTIVE_TOKEN)
Packit fd8b60
        abort();
Packit fd8b60
    free(iov.buffer.value);
Packit fd8b60
Packit fd8b60
    /* IOV sign token, 16-23 bytes */
Packit fd8b60
    store_16_be(KG_TOK_SIGN_MSG, tokbuf);
Packit fd8b60
    store_16_le(test->signalg, tokbuf + 2);
Packit fd8b60
    store_16_le(SEAL_ALG_NONE, tokbuf + 4);
Packit fd8b60
    store_16_le(0xFFFF, tokbuf + 6);
Packit fd8b60
    memset(tokbuf + 8, 0, 8);
Packit fd8b60
    iov.type = GSS_IOV_BUFFER_TYPE_HEADER;
Packit fd8b60
    make_token(tokbuf, 16, &iov.buffer);
Packit fd8b60
    major = gss_unwrap_iov(&minor, ctx, NULL, NULL, &iov, 1);
Packit fd8b60
    if (major != GSS_S_DEFECTIVE_TOKEN)
Packit fd8b60
        abort();
Packit fd8b60
    free(iov.buffer.value);
Packit fd8b60
Packit fd8b60
    /* IOV MIC token, 16-23 bytes */
Packit fd8b60
    store_16_be(KG_TOK_MIC_MSG, tokbuf);
Packit fd8b60
    store_16_be(test->signalg, tokbuf + 2);
Packit fd8b60
    store_16_le(SEAL_ALG_NONE, tokbuf + 4);
Packit fd8b60
    store_16_le(0xFFFF, tokbuf + 6);
Packit fd8b60
    memset(tokbuf + 8, 0, 8);
Packit fd8b60
    iov.type = GSS_IOV_BUFFER_TYPE_MIC_TOKEN;
Packit fd8b60
    make_token(tokbuf, 16, &iov.buffer);
Packit fd8b60
    major = gss_verify_mic_iov(&minor, ctx, NULL, &iov, 1);
Packit fd8b60
    if (major != GSS_S_DEFECTIVE_TOKEN)
Packit fd8b60
        abort();
Packit fd8b60
    free(iov.buffer.value);
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
/* Process wrap and MIC tokens with incomplete checksums. */
Packit fd8b60
static void
Packit fd8b60
test_short_checksum(gss_ctx_id_t ctx, const struct test *test)
Packit fd8b60
{
Packit fd8b60
    OM_uint32 minor, major;
Packit fd8b60
    unsigned char tokbuf[128];
Packit fd8b60
    gss_buffer_desc in, out, empty = GSS_C_EMPTY_BUFFER;
Packit fd8b60
Packit fd8b60
    /* Can only do this with the DES3 checksum, as we can't easily get past
Packit fd8b60
     * retrieving the sequence number when the checksum is only eight bytes. */
Packit fd8b60
    if (test->cksum_size <= 8)
Packit fd8b60
        return;
Packit fd8b60
    /* Seal token, fewer than 16 + cksum_size bytes.  Use the token from the
Packit fd8b60
     * test data to get a valid sequence number. */
Packit fd8b60
    make_token((unsigned char *)test->token + 13, 24, &in);
Packit fd8b60
    major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
Packit fd8b60
    if (major != GSS_S_DEFECTIVE_TOKEN)
Packit fd8b60
        abort();
Packit fd8b60
    free(in.value);
Packit fd8b60
    (void)gss_release_buffer(&minor, &out;;
Packit fd8b60
Packit fd8b60
    /* Sign token, fewer than 16 + cksum_size bytes. */
Packit fd8b60
    memcpy(tokbuf, test->token + 13, 24);
Packit fd8b60
    store_16_be(KG_TOK_SIGN_MSG, tokbuf);
Packit fd8b60
    store_16_le(SEAL_ALG_NONE, tokbuf + 4);
Packit fd8b60
    make_token(tokbuf, 24, &in);
Packit fd8b60
    major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
Packit fd8b60
    if (major != GSS_S_DEFECTIVE_TOKEN)
Packit fd8b60
        abort();
Packit fd8b60
    free(in.value);
Packit fd8b60
    (void)gss_release_buffer(&minor, &out;;
Packit fd8b60
Packit fd8b60
    /* MIC token, fewer than 16 + cksum_size bytes. */
Packit fd8b60
    memcpy(tokbuf, test->token + 13, 24);
Packit fd8b60
    store_16_be(KG_TOK_MIC_MSG, tokbuf);
Packit fd8b60
    store_16_le(SEAL_ALG_NONE, tokbuf + 4);
Packit fd8b60
    make_token(tokbuf, 24, &in);
Packit fd8b60
    major = gss_verify_mic(&minor, ctx, &empty, &in, NULL);
Packit fd8b60
    if (major != GSS_S_DEFECTIVE_TOKEN)
Packit fd8b60
        abort();
Packit fd8b60
    free(in.value);
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
/* Unwrap a token with a bogus padding byte in the decrypted ciphertext. */
Packit fd8b60
static void
Packit fd8b60
test_bad_pad(gss_ctx_id_t ctx, const struct test *test)
Packit fd8b60
{
Packit fd8b60
    OM_uint32 minor, major;
Packit fd8b60
    gss_buffer_desc in, out;
Packit fd8b60
Packit fd8b60
    in.length = test->toklen;
Packit fd8b60
    in.value = (char *)test->token;
Packit fd8b60
    major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
Packit fd8b60
    if (major != GSS_S_BAD_SIG)
Packit fd8b60
        abort();
Packit fd8b60
    (void)gss_release_buffer(&minor, &out;;
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
static void
Packit fd8b60
try_accept(void *value, size_t len)
Packit fd8b60
{
Packit fd8b60
    OM_uint32 minor;
Packit fd8b60
    gss_buffer_desc in, out;
Packit fd8b60
    gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
Packit fd8b60
Packit fd8b60
    /* Copy the provided value to make input overruns more obvious. */
Packit fd8b60
    in.value = malloc(len);
Packit fd8b60
    if (in.value == NULL)
Packit fd8b60
        abort();
Packit fd8b60
    memcpy(in.value, value, len);
Packit fd8b60
    in.length = len;
Packit fd8b60
    (void)gss_accept_sec_context(&minor, &ctx, GSS_C_NO_CREDENTIAL, &in,
Packit fd8b60
                                 GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL,
Packit fd8b60
                                 &out, NULL, NULL, NULL);
Packit fd8b60
    gss_release_buffer(&minor, &out;;
Packit fd8b60
    gss_delete_sec_context(&minor, &ctx, GSS_C_NO_BUFFER);
Packit fd8b60
    free(in.value);
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
/* Accept contexts using superficially valid but truncated encapsulations. */
Packit fd8b60
static void
Packit fd8b60
test_short_encapsulation()
Packit fd8b60
{
Packit fd8b60
    /* Include just the initial application tag, to see if we overrun reading
Packit fd8b60
     * the sequence length. */
Packit fd8b60
    try_accept("\x60", 1);
Packit fd8b60
Packit fd8b60
    /* Indicate four additional sequence length bytes, to see if we overrun
Packit fd8b60
     * reading them (or skipping them and reading the next byte). */
Packit fd8b60
    try_accept("\x60\x84", 2);
Packit fd8b60
Packit fd8b60
    /* Include an object identifier tag but no length, to see if we overrun
Packit fd8b60
     * reading the length. */
Packit fd8b60
    try_accept("\x60\x40\x06", 3);
Packit fd8b60
Packit fd8b60
    /* Include an object identifier tag with a length matching the krb5 mech,
Packit fd8b60
     * but no OID bytes, to see if we overrun comparing against mechs. */
Packit fd8b60
    try_accept("\x60\x40\x06\x09", 4);
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
int
Packit fd8b60
main(int argc, char **argv)
Packit fd8b60
{
Packit fd8b60
    gss_ctx_id_t ctx;
Packit fd8b60
    size_t i;
Packit fd8b60
Packit fd8b60
    ctx = make_fake_cfx_context();
Packit fd8b60
    test_bogus_1964_token(ctx);
Packit fd8b60
    free_fake_context(ctx);
Packit fd8b60
Packit fd8b60
    for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
Packit fd8b60
        ctx = make_fake_context(&tests[i]);
Packit fd8b60
        test_short_header(ctx);
Packit fd8b60
        test_short_header_iov(ctx, &tests[i]);
Packit fd8b60
        test_short_checksum(ctx, &tests[i]);
Packit fd8b60
        test_bad_pad(ctx, &tests[i]);
Packit fd8b60
        free_fake_context(ctx);
Packit fd8b60
    }
Packit fd8b60
Packit fd8b60
    test_short_encapsulation();
Packit fd8b60
Packit fd8b60
    return 0;
Packit fd8b60
}