1*7f2fe78bSCy Schubert /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2*7f2fe78bSCy Schubert /* tests/gssapi/t_invalid.c - Invalid message token regression tests */
3*7f2fe78bSCy Schubert /*
4*7f2fe78bSCy Schubert * Copyright (C) 2014 by the Massachusetts Institute of Technology.
5*7f2fe78bSCy Schubert * All rights reserved.
6*7f2fe78bSCy Schubert *
7*7f2fe78bSCy Schubert * Redistribution and use in source and binary forms, with or without
8*7f2fe78bSCy Schubert * modification, are permitted provided that the following conditions
9*7f2fe78bSCy Schubert * are met:
10*7f2fe78bSCy Schubert *
11*7f2fe78bSCy Schubert * * Redistributions of source code must retain the above copyright
12*7f2fe78bSCy Schubert * notice, this list of conditions and the following disclaimer.
13*7f2fe78bSCy Schubert *
14*7f2fe78bSCy Schubert * * Redistributions in binary form must reproduce the above copyright
15*7f2fe78bSCy Schubert * notice, this list of conditions and the following disclaimer in
16*7f2fe78bSCy Schubert * the documentation and/or other materials provided with the
17*7f2fe78bSCy Schubert * distribution.
18*7f2fe78bSCy Schubert *
19*7f2fe78bSCy Schubert * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20*7f2fe78bSCy Schubert * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21*7f2fe78bSCy Schubert * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22*7f2fe78bSCy Schubert * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23*7f2fe78bSCy Schubert * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24*7f2fe78bSCy Schubert * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25*7f2fe78bSCy Schubert * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26*7f2fe78bSCy Schubert * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27*7f2fe78bSCy Schubert * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28*7f2fe78bSCy Schubert * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29*7f2fe78bSCy Schubert * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30*7f2fe78bSCy Schubert * OF THE POSSIBILITY OF SUCH DAMAGE.
31*7f2fe78bSCy Schubert */
32*7f2fe78bSCy Schubert
33*7f2fe78bSCy Schubert /*
34*7f2fe78bSCy Schubert * This file contains regression tests for some GSSAPI invalid token
35*7f2fe78bSCy Schubert * vulnerabilities.
36*7f2fe78bSCy Schubert *
37*7f2fe78bSCy Schubert * 1. A pre-CFX wrap or MIC token processed with a CFX-only context causes a
38*7f2fe78bSCy Schubert * null pointer dereference. (The token must use SEAL_ALG_NONE or it will
39*7f2fe78bSCy Schubert * be rejected.) This vulnerability also applies to IOV unwrap.
40*7f2fe78bSCy Schubert *
41*7f2fe78bSCy Schubert * 2. A CFX wrap token with a different value of EC between the plaintext and
42*7f2fe78bSCy Schubert * encrypted copies will be erroneously accepted, which allows a message
43*7f2fe78bSCy Schubert * truncation attack. This vulnerability also applies to IOV unwrap.
44*7f2fe78bSCy Schubert *
45*7f2fe78bSCy Schubert * 3. A CFX wrap token with a plaintext length fewer than 16 bytes causes an
46*7f2fe78bSCy Schubert * access before the beginning of the input buffer, possibly leading to a
47*7f2fe78bSCy Schubert * crash.
48*7f2fe78bSCy Schubert *
49*7f2fe78bSCy Schubert * 4. A CFX wrap token with a plaintext EC value greater than the plaintext
50*7f2fe78bSCy Schubert * length - 16 causes an integer underflow when computing the result length,
51*7f2fe78bSCy Schubert * likely causing a crash.
52*7f2fe78bSCy Schubert *
53*7f2fe78bSCy Schubert * 5. An IOV unwrap operation will overrun the header buffer if an ASN.1
54*7f2fe78bSCy Schubert * wrapper longer than the header buffer is present.
55*7f2fe78bSCy Schubert *
56*7f2fe78bSCy Schubert * 6. A pre-CFX wrap or MIC token with fewer than 24 bytes after the ASN.1
57*7f2fe78bSCy Schubert * header causes an input buffer overrun, usually leading to either a segv
58*7f2fe78bSCy Schubert * or a GSS_S_DEFECTIVE_TOKEN error due to garbage algorithm, filler, or
59*7f2fe78bSCy Schubert * sequence number values. This vulnerability also applies to IOV unwrap.
60*7f2fe78bSCy Schubert *
61*7f2fe78bSCy Schubert * 7. A pre-CFX wrap token with fewer than 16 + cksumlen bytes after the ASN.1
62*7f2fe78bSCy Schubert * header causes an integer underflow when computing the ciphertext length,
63*7f2fe78bSCy Schubert * leading to an allocation error on 32-bit platforms or a segv on 64-bit
64*7f2fe78bSCy Schubert * platforms. A pre-CFX MIC token of this size causes an input buffer
65*7f2fe78bSCy Schubert * overrun when comparing the checksum, perhaps leading to a segv.
66*7f2fe78bSCy Schubert *
67*7f2fe78bSCy Schubert * 8. A pre-CFX wrap token with fewer than conflen + padlen bytes in the
68*7f2fe78bSCy Schubert * ciphertext (where padlen is the last byte of the decrypted ciphertext)
69*7f2fe78bSCy Schubert * causes an integer underflow when computing the original message length,
70*7f2fe78bSCy Schubert * leading to an allocation error.
71*7f2fe78bSCy Schubert *
72*7f2fe78bSCy Schubert * 9. In the mechglue, truncated encapsulation in the initial context token can
73*7f2fe78bSCy Schubert * cause input buffer overruns in gss_accept_sec_context().
74*7f2fe78bSCy Schubert */
75*7f2fe78bSCy Schubert
76*7f2fe78bSCy Schubert #include "k5-int.h"
77*7f2fe78bSCy Schubert #include "common.h"
78*7f2fe78bSCy Schubert #include "mglueP.h"
79*7f2fe78bSCy Schubert #include "gssapiP_krb5.h"
80*7f2fe78bSCy Schubert
81*7f2fe78bSCy Schubert /*
82*7f2fe78bSCy Schubert * The following samples contain context parameters and otherwise valid seal
83*7f2fe78bSCy Schubert * tokens where the plain text is padded with byte value 100 instead of the
84*7f2fe78bSCy Schubert * proper value 1.
85*7f2fe78bSCy Schubert */
86*7f2fe78bSCy Schubert struct test {
87*7f2fe78bSCy Schubert krb5_enctype enctype;
88*7f2fe78bSCy Schubert krb5_enctype encseq_enctype;
89*7f2fe78bSCy Schubert int sealalg;
90*7f2fe78bSCy Schubert int signalg;
91*7f2fe78bSCy Schubert size_t cksum_size;
92*7f2fe78bSCy Schubert size_t keylen;
93*7f2fe78bSCy Schubert const char *keydata;
94*7f2fe78bSCy Schubert size_t toklen;
95*7f2fe78bSCy Schubert const char *token;
96*7f2fe78bSCy Schubert } tests[] = {
97*7f2fe78bSCy Schubert {
98*7f2fe78bSCy Schubert ENCTYPE_DES3_CBC_SHA1, ENCTYPE_DES3_CBC_RAW,
99*7f2fe78bSCy Schubert SEAL_ALG_DES3KD, SGN_ALG_HMAC_SHA1_DES3_KD, 20,
100*7f2fe78bSCy Schubert 24,
101*7f2fe78bSCy Schubert "\x4F\xEA\x19\x19\x5E\x0E\x10\xDF\x3D\x29\xB5\x13\x8F\x01\xC7\xA7"
102*7f2fe78bSCy Schubert "\x92\x3D\x38\xF7\x26\x73\x0D\x6D",
103*7f2fe78bSCy Schubert 65,
104*7f2fe78bSCy Schubert "\x60\x3F\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02\x01\x04"
105*7f2fe78bSCy Schubert "\x00\x02\x00\xFF\xFF\xEB\xF3\x9A\x89\x24\x57\xB8\x63\x95\x25\xE8"
106*7f2fe78bSCy Schubert "\x6E\x8E\x79\xE6\x2E\xCA\xD3\xFF\x57\x9F\x8C\xAB\xEF\xDD\x28\x10"
107*7f2fe78bSCy Schubert "\x2F\x93\x21\x2E\xF2\x52\xB6\x6F\xA8\xBB\x8A\x6D\xAA\x6F\xB7\xF4\xD4"
108*7f2fe78bSCy Schubert },
109*7f2fe78bSCy Schubert {
110*7f2fe78bSCy Schubert ENCTYPE_ARCFOUR_HMAC, ENCTYPE_ARCFOUR_HMAC,
111*7f2fe78bSCy Schubert SEAL_ALG_MICROSOFT_RC4, SGN_ALG_HMAC_MD5, 8,
112*7f2fe78bSCy Schubert 16,
113*7f2fe78bSCy Schubert "\x66\x64\x41\x64\x55\x78\x21\xD0\xD0\xFD\x05\x6A\xFF\x6F\xE8\x09",
114*7f2fe78bSCy Schubert 53,
115*7f2fe78bSCy Schubert "\x60\x33\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02\x01\x11"
116*7f2fe78bSCy Schubert "\x00\x10\x00\xFF\xFF\x35\xD4\x79\xF3\x8C\x47\x8F\x6E\x23\x6F\x3E"
117*7f2fe78bSCy Schubert "\xCC\x5E\x57\x5C\x6A\x89\xF0\xA2\x03\x4F\x0B\x51\x11\xEE\x89\x7E"
118*7f2fe78bSCy Schubert "\xD6\xF6\xB5\xD6\x51"
119*7f2fe78bSCy Schubert }
120*7f2fe78bSCy Schubert };
121*7f2fe78bSCy Schubert
122*7f2fe78bSCy Schubert static void *
ealloc(size_t len)123*7f2fe78bSCy Schubert ealloc(size_t len)
124*7f2fe78bSCy Schubert {
125*7f2fe78bSCy Schubert void *ptr = calloc(len, 1);
126*7f2fe78bSCy Schubert
127*7f2fe78bSCy Schubert if (ptr == NULL)
128*7f2fe78bSCy Schubert abort();
129*7f2fe78bSCy Schubert return ptr;
130*7f2fe78bSCy Schubert }
131*7f2fe78bSCy Schubert
132*7f2fe78bSCy Schubert /* Fake up enough of a CFX GSS context for gss_unwrap, using an AES key.
133*7f2fe78bSCy Schubert * The context takes ownership of subkey. */
134*7f2fe78bSCy Schubert static gss_ctx_id_t
make_fake_cfx_context(krb5_key subkey)135*7f2fe78bSCy Schubert make_fake_cfx_context(krb5_key subkey)
136*7f2fe78bSCy Schubert {
137*7f2fe78bSCy Schubert gss_union_ctx_id_t uctx;
138*7f2fe78bSCy Schubert krb5_gss_ctx_id_t kgctx;
139*7f2fe78bSCy Schubert
140*7f2fe78bSCy Schubert kgctx = ealloc(sizeof(*kgctx));
141*7f2fe78bSCy Schubert kgctx->established = 1;
142*7f2fe78bSCy Schubert kgctx->proto = 1;
143*7f2fe78bSCy Schubert if (g_seqstate_init(&kgctx->seqstate, 0, 0, 0, 0) != 0)
144*7f2fe78bSCy Schubert abort();
145*7f2fe78bSCy Schubert kgctx->mech_used = &mech_krb5;
146*7f2fe78bSCy Schubert kgctx->sealalg = -1;
147*7f2fe78bSCy Schubert kgctx->signalg = -1;
148*7f2fe78bSCy Schubert
149*7f2fe78bSCy Schubert kgctx->subkey = subkey;
150*7f2fe78bSCy Schubert kgctx->cksumtype = CKSUMTYPE_HMAC_SHA1_96_AES128;
151*7f2fe78bSCy Schubert
152*7f2fe78bSCy Schubert uctx = ealloc(sizeof(*uctx));
153*7f2fe78bSCy Schubert uctx->mech_type = &mech_krb5;
154*7f2fe78bSCy Schubert uctx->internal_ctx_id = (gss_ctx_id_t)kgctx;
155*7f2fe78bSCy Schubert return (gss_ctx_id_t)uctx;
156*7f2fe78bSCy Schubert }
157*7f2fe78bSCy Schubert
158*7f2fe78bSCy Schubert /* Fake up enough of a GSS context for gss_unwrap, using keys from test. */
159*7f2fe78bSCy Schubert static gss_ctx_id_t
make_fake_context(const struct test * test)160*7f2fe78bSCy Schubert make_fake_context(const struct test *test)
161*7f2fe78bSCy Schubert {
162*7f2fe78bSCy Schubert gss_union_ctx_id_t uctx;
163*7f2fe78bSCy Schubert krb5_gss_ctx_id_t kgctx;
164*7f2fe78bSCy Schubert krb5_keyblock kb;
165*7f2fe78bSCy Schubert
166*7f2fe78bSCy Schubert kgctx = ealloc(sizeof(*kgctx));
167*7f2fe78bSCy Schubert kgctx->established = 1;
168*7f2fe78bSCy Schubert if (g_seqstate_init(&kgctx->seqstate, 0, 0, 0, 0) != 0)
169*7f2fe78bSCy Schubert abort();
170*7f2fe78bSCy Schubert kgctx->mech_used = &mech_krb5;
171*7f2fe78bSCy Schubert kgctx->sealalg = test->sealalg;
172*7f2fe78bSCy Schubert kgctx->signalg = test->signalg;
173*7f2fe78bSCy Schubert kgctx->cksum_size = test->cksum_size;
174*7f2fe78bSCy Schubert
175*7f2fe78bSCy Schubert kb.enctype = test->enctype;
176*7f2fe78bSCy Schubert kb.length = test->keylen;
177*7f2fe78bSCy Schubert kb.contents = (unsigned char *)test->keydata;
178*7f2fe78bSCy Schubert if (krb5_k_create_key(NULL, &kb, &kgctx->subkey) != 0)
179*7f2fe78bSCy Schubert abort();
180*7f2fe78bSCy Schubert
181*7f2fe78bSCy Schubert kb.enctype = test->encseq_enctype;
182*7f2fe78bSCy Schubert if (krb5_k_create_key(NULL, &kb, &kgctx->seq) != 0)
183*7f2fe78bSCy Schubert abort();
184*7f2fe78bSCy Schubert
185*7f2fe78bSCy Schubert if (krb5_k_create_key(NULL, &kb, &kgctx->enc) != 0)
186*7f2fe78bSCy Schubert abort();
187*7f2fe78bSCy Schubert
188*7f2fe78bSCy Schubert uctx = ealloc(sizeof(*uctx));
189*7f2fe78bSCy Schubert uctx->mech_type = &mech_krb5;
190*7f2fe78bSCy Schubert uctx->internal_ctx_id = (gss_ctx_id_t)kgctx;
191*7f2fe78bSCy Schubert return (gss_ctx_id_t)uctx;
192*7f2fe78bSCy Schubert }
193*7f2fe78bSCy Schubert
194*7f2fe78bSCy Schubert /* Free a context created by make_fake_context. */
195*7f2fe78bSCy Schubert static void
free_fake_context(gss_ctx_id_t ctx)196*7f2fe78bSCy Schubert free_fake_context(gss_ctx_id_t ctx)
197*7f2fe78bSCy Schubert {
198*7f2fe78bSCy Schubert gss_union_ctx_id_t uctx = (gss_union_ctx_id_t)ctx;
199*7f2fe78bSCy Schubert krb5_gss_ctx_id_t kgctx = (krb5_gss_ctx_id_t)uctx->internal_ctx_id;
200*7f2fe78bSCy Schubert
201*7f2fe78bSCy Schubert free(kgctx->seqstate);
202*7f2fe78bSCy Schubert krb5_k_free_key(NULL, kgctx->subkey);
203*7f2fe78bSCy Schubert krb5_k_free_key(NULL, kgctx->seq);
204*7f2fe78bSCy Schubert krb5_k_free_key(NULL, kgctx->enc);
205*7f2fe78bSCy Schubert free(kgctx);
206*7f2fe78bSCy Schubert free(uctx);
207*7f2fe78bSCy Schubert }
208*7f2fe78bSCy Schubert
209*7f2fe78bSCy Schubert /* Prefix a token (starting at the two-byte ID) with an ASN.1 header and return
210*7f2fe78bSCy Schubert * it in an allocated block to facilitate checking by valgrind or similar. */
211*7f2fe78bSCy Schubert static void
make_token(unsigned char * token,size_t len,gss_buffer_t out)212*7f2fe78bSCy Schubert make_token(unsigned char *token, size_t len, gss_buffer_t out)
213*7f2fe78bSCy Schubert {
214*7f2fe78bSCy Schubert char *wrapped;
215*7f2fe78bSCy Schubert
216*7f2fe78bSCy Schubert assert(mech_krb5.length == 9);
217*7f2fe78bSCy Schubert assert(len + 11 < 128);
218*7f2fe78bSCy Schubert wrapped = ealloc(len + 13);
219*7f2fe78bSCy Schubert wrapped[0] = 0x60;
220*7f2fe78bSCy Schubert wrapped[1] = len + 11;
221*7f2fe78bSCy Schubert wrapped[2] = 0x06;
222*7f2fe78bSCy Schubert wrapped[3] = 9;
223*7f2fe78bSCy Schubert memcpy(wrapped + 4, mech_krb5.elements, 9);
224*7f2fe78bSCy Schubert memcpy(wrapped + 13, token, len);
225*7f2fe78bSCy Schubert out->length = len + 13;
226*7f2fe78bSCy Schubert out->value = wrapped;
227*7f2fe78bSCy Schubert }
228*7f2fe78bSCy Schubert
229*7f2fe78bSCy Schubert /* Create a 16-byte header for a CFX confidential wrap token to be processed by
230*7f2fe78bSCy Schubert * the fake CFX context. */
231*7f2fe78bSCy Schubert static void
write_cfx_header(uint16_t ec,uint8_t * out)232*7f2fe78bSCy Schubert write_cfx_header(uint16_t ec, uint8_t *out)
233*7f2fe78bSCy Schubert {
234*7f2fe78bSCy Schubert memset(out, 0, 16);
235*7f2fe78bSCy Schubert store_16_be(KG2_TOK_WRAP_MSG, out);
236*7f2fe78bSCy Schubert out[2] = FLAG_WRAP_CONFIDENTIAL;
237*7f2fe78bSCy Schubert out[3] = 0xFF;
238*7f2fe78bSCy Schubert store_16_be(ec, out + 4);
239*7f2fe78bSCy Schubert }
240*7f2fe78bSCy Schubert
241*7f2fe78bSCy Schubert /* Unwrap a superficially valid RFC 1964 token with a CFX-only context, with
242*7f2fe78bSCy Schubert * regular and IOV unwrap. */
243*7f2fe78bSCy Schubert static void
test_bogus_1964_token(gss_ctx_id_t ctx)244*7f2fe78bSCy Schubert test_bogus_1964_token(gss_ctx_id_t ctx)
245*7f2fe78bSCy Schubert {
246*7f2fe78bSCy Schubert OM_uint32 minor, major;
247*7f2fe78bSCy Schubert unsigned char tokbuf[128];
248*7f2fe78bSCy Schubert gss_buffer_desc in, out;
249*7f2fe78bSCy Schubert gss_iov_buffer_desc iov;
250*7f2fe78bSCy Schubert
251*7f2fe78bSCy Schubert store_16_be(KG_TOK_SIGN_MSG, tokbuf);
252*7f2fe78bSCy Schubert store_16_le(SGN_ALG_HMAC_MD5, tokbuf + 2);
253*7f2fe78bSCy Schubert store_16_le(SEAL_ALG_NONE, tokbuf + 4);
254*7f2fe78bSCy Schubert store_16_le(0xFFFF, tokbuf + 6);
255*7f2fe78bSCy Schubert memset(tokbuf + 8, 0, 16);
256*7f2fe78bSCy Schubert make_token(tokbuf, 24, &in);
257*7f2fe78bSCy Schubert
258*7f2fe78bSCy Schubert major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
259*7f2fe78bSCy Schubert if (major != GSS_S_DEFECTIVE_TOKEN)
260*7f2fe78bSCy Schubert abort();
261*7f2fe78bSCy Schubert (void)gss_release_buffer(&minor, &out);
262*7f2fe78bSCy Schubert
263*7f2fe78bSCy Schubert iov.type = GSS_IOV_BUFFER_TYPE_HEADER;
264*7f2fe78bSCy Schubert iov.buffer = in;
265*7f2fe78bSCy Schubert major = gss_unwrap_iov(&minor, ctx, NULL, NULL, &iov, 1);
266*7f2fe78bSCy Schubert if (major != GSS_S_DEFECTIVE_TOKEN)
267*7f2fe78bSCy Schubert abort();
268*7f2fe78bSCy Schubert
269*7f2fe78bSCy Schubert free(in.value);
270*7f2fe78bSCy Schubert }
271*7f2fe78bSCy Schubert
272*7f2fe78bSCy Schubert static void
test_cfx_altered_ec(gss_ctx_id_t ctx,krb5_key subkey)273*7f2fe78bSCy Schubert test_cfx_altered_ec(gss_ctx_id_t ctx, krb5_key subkey)
274*7f2fe78bSCy Schubert {
275*7f2fe78bSCy Schubert OM_uint32 major, minor;
276*7f2fe78bSCy Schubert uint8_t tokbuf[128], plainbuf[24];
277*7f2fe78bSCy Schubert krb5_data plain;
278*7f2fe78bSCy Schubert krb5_enc_data cipher;
279*7f2fe78bSCy Schubert gss_buffer_desc in, out;
280*7f2fe78bSCy Schubert gss_iov_buffer_desc iov[2];
281*7f2fe78bSCy Schubert
282*7f2fe78bSCy Schubert /* Construct a header with a plaintext EC value of 3. */
283*7f2fe78bSCy Schubert write_cfx_header(3, tokbuf);
284*7f2fe78bSCy Schubert
285*7f2fe78bSCy Schubert /* Encrypt a plaintext and a copy of the header with the EC value 0. */
286*7f2fe78bSCy Schubert memcpy(plainbuf, "truncate", 8);
287*7f2fe78bSCy Schubert memcpy(plainbuf + 8, tokbuf, 16);
288*7f2fe78bSCy Schubert store_16_be(0, plainbuf + 12);
289*7f2fe78bSCy Schubert plain = make_data(plainbuf, 24);
290*7f2fe78bSCy Schubert cipher.ciphertext.data = (char *)tokbuf + 16;
291*7f2fe78bSCy Schubert cipher.ciphertext.length = sizeof(tokbuf) - 16;
292*7f2fe78bSCy Schubert cipher.enctype = subkey->keyblock.enctype;
293*7f2fe78bSCy Schubert if (krb5_k_encrypt(NULL, subkey, KG_USAGE_INITIATOR_SEAL, NULL,
294*7f2fe78bSCy Schubert &plain, &cipher) != 0)
295*7f2fe78bSCy Schubert abort();
296*7f2fe78bSCy Schubert
297*7f2fe78bSCy Schubert /* Verify that the token is rejected by gss_unwrap(). */
298*7f2fe78bSCy Schubert in.value = tokbuf;
299*7f2fe78bSCy Schubert in.length = 16 + cipher.ciphertext.length;
300*7f2fe78bSCy Schubert major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
301*7f2fe78bSCy Schubert if (major != GSS_S_DEFECTIVE_TOKEN)
302*7f2fe78bSCy Schubert abort();
303*7f2fe78bSCy Schubert (void)gss_release_buffer(&minor, &out);
304*7f2fe78bSCy Schubert
305*7f2fe78bSCy Schubert /* Verify that the token is rejected by gss_unwrap_iov(). */
306*7f2fe78bSCy Schubert iov[0].type = GSS_IOV_BUFFER_TYPE_STREAM;
307*7f2fe78bSCy Schubert iov[0].buffer = in;
308*7f2fe78bSCy Schubert iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
309*7f2fe78bSCy Schubert major = gss_unwrap_iov(&minor, ctx, NULL, NULL, iov, 2);
310*7f2fe78bSCy Schubert if (major != GSS_S_DEFECTIVE_TOKEN)
311*7f2fe78bSCy Schubert abort();
312*7f2fe78bSCy Schubert }
313*7f2fe78bSCy Schubert
314*7f2fe78bSCy Schubert static void
test_cfx_short_plaintext(gss_ctx_id_t ctx,krb5_key subkey)315*7f2fe78bSCy Schubert test_cfx_short_plaintext(gss_ctx_id_t ctx, krb5_key subkey)
316*7f2fe78bSCy Schubert {
317*7f2fe78bSCy Schubert OM_uint32 major, minor;
318*7f2fe78bSCy Schubert uint8_t tokbuf[128], zerobyte = 0;
319*7f2fe78bSCy Schubert krb5_data plain;
320*7f2fe78bSCy Schubert krb5_enc_data cipher;
321*7f2fe78bSCy Schubert gss_buffer_desc in, out;
322*7f2fe78bSCy Schubert
323*7f2fe78bSCy Schubert write_cfx_header(0, tokbuf);
324*7f2fe78bSCy Schubert
325*7f2fe78bSCy Schubert /* Encrypt a single byte, with no copy of the header. */
326*7f2fe78bSCy Schubert plain = make_data(&zerobyte, 1);
327*7f2fe78bSCy Schubert cipher.ciphertext.data = (char *)tokbuf + 16;
328*7f2fe78bSCy Schubert cipher.ciphertext.length = sizeof(tokbuf) - 16;
329*7f2fe78bSCy Schubert cipher.enctype = subkey->keyblock.enctype;
330*7f2fe78bSCy Schubert if (krb5_k_encrypt(NULL, subkey, KG_USAGE_INITIATOR_SEAL, NULL,
331*7f2fe78bSCy Schubert &plain, &cipher) != 0)
332*7f2fe78bSCy Schubert abort();
333*7f2fe78bSCy Schubert
334*7f2fe78bSCy Schubert /* Verify that the token is rejected by gss_unwrap(). */
335*7f2fe78bSCy Schubert in.value = tokbuf;
336*7f2fe78bSCy Schubert in.length = 16 + cipher.ciphertext.length;
337*7f2fe78bSCy Schubert major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
338*7f2fe78bSCy Schubert if (major != GSS_S_DEFECTIVE_TOKEN)
339*7f2fe78bSCy Schubert abort();
340*7f2fe78bSCy Schubert (void)gss_release_buffer(&minor, &out);
341*7f2fe78bSCy Schubert }
342*7f2fe78bSCy Schubert
343*7f2fe78bSCy Schubert static void
test_cfx_large_ec(gss_ctx_id_t ctx,krb5_key subkey)344*7f2fe78bSCy Schubert test_cfx_large_ec(gss_ctx_id_t ctx, krb5_key subkey)
345*7f2fe78bSCy Schubert {
346*7f2fe78bSCy Schubert OM_uint32 major, minor;
347*7f2fe78bSCy Schubert uint8_t tokbuf[128] = { 0 }, plainbuf[20];
348*7f2fe78bSCy Schubert krb5_data plain;
349*7f2fe78bSCy Schubert krb5_enc_data cipher;
350*7f2fe78bSCy Schubert gss_buffer_desc in, out;
351*7f2fe78bSCy Schubert
352*7f2fe78bSCy Schubert /* Construct a header with an EC value of 5. */
353*7f2fe78bSCy Schubert write_cfx_header(5, tokbuf);
354*7f2fe78bSCy Schubert
355*7f2fe78bSCy Schubert /* Encrypt a 4-byte plaintext plus the header. */
356*7f2fe78bSCy Schubert memcpy(plainbuf, "abcd", 4);
357*7f2fe78bSCy Schubert memcpy(plainbuf + 4, tokbuf, 16);
358*7f2fe78bSCy Schubert plain = make_data(plainbuf, 20);
359*7f2fe78bSCy Schubert cipher.ciphertext.data = (char *)tokbuf + 16;
360*7f2fe78bSCy Schubert cipher.ciphertext.length = sizeof(tokbuf) - 16;
361*7f2fe78bSCy Schubert cipher.enctype = subkey->keyblock.enctype;
362*7f2fe78bSCy Schubert if (krb5_k_encrypt(NULL, subkey, KG_USAGE_INITIATOR_SEAL, NULL,
363*7f2fe78bSCy Schubert &plain, &cipher) != 0)
364*7f2fe78bSCy Schubert abort();
365*7f2fe78bSCy Schubert
366*7f2fe78bSCy Schubert /* Verify that the token is rejected by gss_unwrap(). */
367*7f2fe78bSCy Schubert in.value = tokbuf;
368*7f2fe78bSCy Schubert in.length = 16 + cipher.ciphertext.length;
369*7f2fe78bSCy Schubert major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
370*7f2fe78bSCy Schubert if (major != GSS_S_DEFECTIVE_TOKEN)
371*7f2fe78bSCy Schubert abort();
372*7f2fe78bSCy Schubert (void)gss_release_buffer(&minor, &out);
373*7f2fe78bSCy Schubert }
374*7f2fe78bSCy Schubert
375*7f2fe78bSCy Schubert static void
test_iov_large_asn1_wrapper(gss_ctx_id_t ctx)376*7f2fe78bSCy Schubert test_iov_large_asn1_wrapper(gss_ctx_id_t ctx)
377*7f2fe78bSCy Schubert {
378*7f2fe78bSCy Schubert OM_uint32 minor, major;
379*7f2fe78bSCy Schubert uint8_t databuf[10] = { 0 };
380*7f2fe78bSCy Schubert gss_iov_buffer_desc iov[2];
381*7f2fe78bSCy Schubert
382*7f2fe78bSCy Schubert /*
383*7f2fe78bSCy Schubert * In this IOV array, the header contains a DER tag with a dangling eight
384*7f2fe78bSCy Schubert * bytes of length field. The data IOV indicates a total token length
385*7f2fe78bSCy Schubert * sufficient to contain the length bytes.
386*7f2fe78bSCy Schubert */
387*7f2fe78bSCy Schubert iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER;
388*7f2fe78bSCy Schubert iov[0].buffer.value = ealloc(2);
389*7f2fe78bSCy Schubert iov[0].buffer.length = 2;
390*7f2fe78bSCy Schubert memcpy(iov[0].buffer.value, "\x60\x88", 2);
391*7f2fe78bSCy Schubert iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
392*7f2fe78bSCy Schubert iov[1].buffer.value = databuf;
393*7f2fe78bSCy Schubert iov[1].buffer.length = 10;
394*7f2fe78bSCy Schubert major = gss_unwrap_iov(&minor, ctx, NULL, NULL, iov, 2);
395*7f2fe78bSCy Schubert if (major != GSS_S_DEFECTIVE_TOKEN)
396*7f2fe78bSCy Schubert abort();
397*7f2fe78bSCy Schubert free(iov[0].buffer.value);
398*7f2fe78bSCy Schubert }
399*7f2fe78bSCy Schubert
400*7f2fe78bSCy Schubert /* Process wrap and MIC tokens with incomplete headers. */
401*7f2fe78bSCy Schubert static void
test_short_header(gss_ctx_id_t ctx)402*7f2fe78bSCy Schubert test_short_header(gss_ctx_id_t ctx)
403*7f2fe78bSCy Schubert {
404*7f2fe78bSCy Schubert OM_uint32 minor, major;
405*7f2fe78bSCy Schubert unsigned char tokbuf[128];
406*7f2fe78bSCy Schubert gss_buffer_desc in, out, empty = GSS_C_EMPTY_BUFFER;
407*7f2fe78bSCy Schubert
408*7f2fe78bSCy Schubert /* Seal token, 2-24 bytes */
409*7f2fe78bSCy Schubert store_16_be(KG_TOK_SEAL_MSG, tokbuf);
410*7f2fe78bSCy Schubert make_token(tokbuf, 2, &in);
411*7f2fe78bSCy Schubert major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
412*7f2fe78bSCy Schubert if (major != GSS_S_DEFECTIVE_TOKEN)
413*7f2fe78bSCy Schubert abort();
414*7f2fe78bSCy Schubert free(in.value);
415*7f2fe78bSCy Schubert (void)gss_release_buffer(&minor, &out);
416*7f2fe78bSCy Schubert
417*7f2fe78bSCy Schubert /* Sign token, 2-24 bytes */
418*7f2fe78bSCy Schubert store_16_be(KG_TOK_SIGN_MSG, tokbuf);
419*7f2fe78bSCy Schubert make_token(tokbuf, 2, &in);
420*7f2fe78bSCy Schubert major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
421*7f2fe78bSCy Schubert if (major != GSS_S_DEFECTIVE_TOKEN)
422*7f2fe78bSCy Schubert abort();
423*7f2fe78bSCy Schubert free(in.value);
424*7f2fe78bSCy Schubert (void)gss_release_buffer(&minor, &out);
425*7f2fe78bSCy Schubert
426*7f2fe78bSCy Schubert /* MIC token, 2-24 bytes */
427*7f2fe78bSCy Schubert store_16_be(KG_TOK_MIC_MSG, tokbuf);
428*7f2fe78bSCy Schubert make_token(tokbuf, 2, &in);
429*7f2fe78bSCy Schubert major = gss_verify_mic(&minor, ctx, &empty, &in, NULL);
430*7f2fe78bSCy Schubert if (major != GSS_S_DEFECTIVE_TOKEN)
431*7f2fe78bSCy Schubert abort();
432*7f2fe78bSCy Schubert free(in.value);
433*7f2fe78bSCy Schubert }
434*7f2fe78bSCy Schubert
435*7f2fe78bSCy Schubert /* Process wrap and MIC tokens with incomplete headers. */
436*7f2fe78bSCy Schubert static void
test_short_header_iov(gss_ctx_id_t ctx,const struct test * test)437*7f2fe78bSCy Schubert test_short_header_iov(gss_ctx_id_t ctx, const struct test *test)
438*7f2fe78bSCy Schubert {
439*7f2fe78bSCy Schubert OM_uint32 minor, major;
440*7f2fe78bSCy Schubert unsigned char tokbuf[128];
441*7f2fe78bSCy Schubert gss_iov_buffer_desc iov;
442*7f2fe78bSCy Schubert
443*7f2fe78bSCy Schubert /* IOV seal token, 16-23 bytes */
444*7f2fe78bSCy Schubert store_16_be(KG_TOK_SEAL_MSG, tokbuf);
445*7f2fe78bSCy Schubert store_16_le(test->signalg, tokbuf + 2);
446*7f2fe78bSCy Schubert store_16_le(test->sealalg, tokbuf + 4);
447*7f2fe78bSCy Schubert store_16_be(0xFFFF, tokbuf + 6);
448*7f2fe78bSCy Schubert memset(tokbuf + 8, 0, 8);
449*7f2fe78bSCy Schubert iov.type = GSS_IOV_BUFFER_TYPE_HEADER;
450*7f2fe78bSCy Schubert make_token(tokbuf, 16, &iov.buffer);
451*7f2fe78bSCy Schubert major = gss_unwrap_iov(&minor, ctx, NULL, NULL, &iov, 1);
452*7f2fe78bSCy Schubert if (major != GSS_S_DEFECTIVE_TOKEN)
453*7f2fe78bSCy Schubert abort();
454*7f2fe78bSCy Schubert free(iov.buffer.value);
455*7f2fe78bSCy Schubert
456*7f2fe78bSCy Schubert /* IOV sign token, 16-23 bytes */
457*7f2fe78bSCy Schubert store_16_be(KG_TOK_SIGN_MSG, tokbuf);
458*7f2fe78bSCy Schubert store_16_le(test->signalg, tokbuf + 2);
459*7f2fe78bSCy Schubert store_16_le(SEAL_ALG_NONE, tokbuf + 4);
460*7f2fe78bSCy Schubert store_16_le(0xFFFF, tokbuf + 6);
461*7f2fe78bSCy Schubert memset(tokbuf + 8, 0, 8);
462*7f2fe78bSCy Schubert iov.type = GSS_IOV_BUFFER_TYPE_HEADER;
463*7f2fe78bSCy Schubert make_token(tokbuf, 16, &iov.buffer);
464*7f2fe78bSCy Schubert major = gss_unwrap_iov(&minor, ctx, NULL, NULL, &iov, 1);
465*7f2fe78bSCy Schubert if (major != GSS_S_DEFECTIVE_TOKEN)
466*7f2fe78bSCy Schubert abort();
467*7f2fe78bSCy Schubert free(iov.buffer.value);
468*7f2fe78bSCy Schubert
469*7f2fe78bSCy Schubert /* IOV MIC token, 16-23 bytes */
470*7f2fe78bSCy Schubert store_16_be(KG_TOK_MIC_MSG, tokbuf);
471*7f2fe78bSCy Schubert store_16_be(test->signalg, tokbuf + 2);
472*7f2fe78bSCy Schubert store_16_le(SEAL_ALG_NONE, tokbuf + 4);
473*7f2fe78bSCy Schubert store_16_le(0xFFFF, tokbuf + 6);
474*7f2fe78bSCy Schubert memset(tokbuf + 8, 0, 8);
475*7f2fe78bSCy Schubert iov.type = GSS_IOV_BUFFER_TYPE_MIC_TOKEN;
476*7f2fe78bSCy Schubert make_token(tokbuf, 16, &iov.buffer);
477*7f2fe78bSCy Schubert major = gss_verify_mic_iov(&minor, ctx, NULL, &iov, 1);
478*7f2fe78bSCy Schubert if (major != GSS_S_DEFECTIVE_TOKEN)
479*7f2fe78bSCy Schubert abort();
480*7f2fe78bSCy Schubert free(iov.buffer.value);
481*7f2fe78bSCy Schubert }
482*7f2fe78bSCy Schubert
483*7f2fe78bSCy Schubert /* Process wrap and MIC tokens with incomplete checksums. */
484*7f2fe78bSCy Schubert static void
test_short_checksum(gss_ctx_id_t ctx,const struct test * test)485*7f2fe78bSCy Schubert test_short_checksum(gss_ctx_id_t ctx, const struct test *test)
486*7f2fe78bSCy Schubert {
487*7f2fe78bSCy Schubert OM_uint32 minor, major;
488*7f2fe78bSCy Schubert unsigned char tokbuf[128];
489*7f2fe78bSCy Schubert gss_buffer_desc in, out, empty = GSS_C_EMPTY_BUFFER;
490*7f2fe78bSCy Schubert
491*7f2fe78bSCy Schubert /* Can only do this with the DES3 checksum, as we can't easily get past
492*7f2fe78bSCy Schubert * retrieving the sequence number when the checksum is only eight bytes. */
493*7f2fe78bSCy Schubert if (test->cksum_size <= 8)
494*7f2fe78bSCy Schubert return;
495*7f2fe78bSCy Schubert /* Seal token, fewer than 16 + cksum_size bytes. Use the token from the
496*7f2fe78bSCy Schubert * test data to get a valid sequence number. */
497*7f2fe78bSCy Schubert make_token((unsigned char *)test->token + 13, 24, &in);
498*7f2fe78bSCy Schubert major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
499*7f2fe78bSCy Schubert if (major != GSS_S_DEFECTIVE_TOKEN)
500*7f2fe78bSCy Schubert abort();
501*7f2fe78bSCy Schubert free(in.value);
502*7f2fe78bSCy Schubert (void)gss_release_buffer(&minor, &out);
503*7f2fe78bSCy Schubert
504*7f2fe78bSCy Schubert /* Sign token, fewer than 16 + cksum_size bytes. */
505*7f2fe78bSCy Schubert memcpy(tokbuf, test->token + 13, 24);
506*7f2fe78bSCy Schubert store_16_be(KG_TOK_SIGN_MSG, tokbuf);
507*7f2fe78bSCy Schubert store_16_le(SEAL_ALG_NONE, tokbuf + 4);
508*7f2fe78bSCy Schubert make_token(tokbuf, 24, &in);
509*7f2fe78bSCy Schubert major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
510*7f2fe78bSCy Schubert if (major != GSS_S_DEFECTIVE_TOKEN)
511*7f2fe78bSCy Schubert abort();
512*7f2fe78bSCy Schubert free(in.value);
513*7f2fe78bSCy Schubert (void)gss_release_buffer(&minor, &out);
514*7f2fe78bSCy Schubert
515*7f2fe78bSCy Schubert /* MIC token, fewer than 16 + cksum_size bytes. */
516*7f2fe78bSCy Schubert memcpy(tokbuf, test->token + 13, 24);
517*7f2fe78bSCy Schubert store_16_be(KG_TOK_MIC_MSG, tokbuf);
518*7f2fe78bSCy Schubert store_16_le(SEAL_ALG_NONE, tokbuf + 4);
519*7f2fe78bSCy Schubert make_token(tokbuf, 24, &in);
520*7f2fe78bSCy Schubert major = gss_verify_mic(&minor, ctx, &empty, &in, NULL);
521*7f2fe78bSCy Schubert if (major != GSS_S_DEFECTIVE_TOKEN)
522*7f2fe78bSCy Schubert abort();
523*7f2fe78bSCy Schubert free(in.value);
524*7f2fe78bSCy Schubert }
525*7f2fe78bSCy Schubert
526*7f2fe78bSCy Schubert /* Unwrap a token with a bogus padding byte in the decrypted ciphertext. */
527*7f2fe78bSCy Schubert static void
test_bad_pad(gss_ctx_id_t ctx,const struct test * test)528*7f2fe78bSCy Schubert test_bad_pad(gss_ctx_id_t ctx, const struct test *test)
529*7f2fe78bSCy Schubert {
530*7f2fe78bSCy Schubert OM_uint32 minor, major;
531*7f2fe78bSCy Schubert gss_buffer_desc in, out;
532*7f2fe78bSCy Schubert
533*7f2fe78bSCy Schubert in.length = test->toklen;
534*7f2fe78bSCy Schubert in.value = (char *)test->token;
535*7f2fe78bSCy Schubert major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
536*7f2fe78bSCy Schubert if (major != GSS_S_BAD_SIG)
537*7f2fe78bSCy Schubert abort();
538*7f2fe78bSCy Schubert (void)gss_release_buffer(&minor, &out);
539*7f2fe78bSCy Schubert }
540*7f2fe78bSCy Schubert
541*7f2fe78bSCy Schubert static void
try_accept(void * value,size_t len)542*7f2fe78bSCy Schubert try_accept(void *value, size_t len)
543*7f2fe78bSCy Schubert {
544*7f2fe78bSCy Schubert OM_uint32 minor;
545*7f2fe78bSCy Schubert gss_buffer_desc in, out;
546*7f2fe78bSCy Schubert gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
547*7f2fe78bSCy Schubert
548*7f2fe78bSCy Schubert /* Copy the provided value to make input overruns more obvious. */
549*7f2fe78bSCy Schubert in.value = ealloc(len);
550*7f2fe78bSCy Schubert memcpy(in.value, value, len);
551*7f2fe78bSCy Schubert in.length = len;
552*7f2fe78bSCy Schubert (void)gss_accept_sec_context(&minor, &ctx, GSS_C_NO_CREDENTIAL, &in,
553*7f2fe78bSCy Schubert GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL,
554*7f2fe78bSCy Schubert &out, NULL, NULL, NULL);
555*7f2fe78bSCy Schubert gss_release_buffer(&minor, &out);
556*7f2fe78bSCy Schubert gss_delete_sec_context(&minor, &ctx, GSS_C_NO_BUFFER);
557*7f2fe78bSCy Schubert free(in.value);
558*7f2fe78bSCy Schubert }
559*7f2fe78bSCy Schubert
560*7f2fe78bSCy Schubert /* Accept contexts using superficially valid but truncated encapsulations. */
561*7f2fe78bSCy Schubert static void
test_short_encapsulation()562*7f2fe78bSCy Schubert test_short_encapsulation()
563*7f2fe78bSCy Schubert {
564*7f2fe78bSCy Schubert /* Include just the initial application tag, to see if we overrun reading
565*7f2fe78bSCy Schubert * the sequence length. */
566*7f2fe78bSCy Schubert try_accept("\x60", 1);
567*7f2fe78bSCy Schubert
568*7f2fe78bSCy Schubert /* Indicate four additional sequence length bytes, to see if we overrun
569*7f2fe78bSCy Schubert * reading them (or skipping them and reading the next byte). */
570*7f2fe78bSCy Schubert try_accept("\x60\x84", 2);
571*7f2fe78bSCy Schubert
572*7f2fe78bSCy Schubert /* Include an object identifier tag but no length, to see if we overrun
573*7f2fe78bSCy Schubert * reading the length. */
574*7f2fe78bSCy Schubert try_accept("\x60\x40\x06", 3);
575*7f2fe78bSCy Schubert
576*7f2fe78bSCy Schubert /* Include an object identifier tag with a length matching the krb5 mech,
577*7f2fe78bSCy Schubert * but no OID bytes, to see if we overrun comparing against mechs. */
578*7f2fe78bSCy Schubert try_accept("\x60\x40\x06\x09", 4);
579*7f2fe78bSCy Schubert }
580*7f2fe78bSCy Schubert
581*7f2fe78bSCy Schubert int
main(int argc,char ** argv)582*7f2fe78bSCy Schubert main(int argc, char **argv)
583*7f2fe78bSCy Schubert {
584*7f2fe78bSCy Schubert krb5_keyblock kb;
585*7f2fe78bSCy Schubert krb5_key cfx_subkey;
586*7f2fe78bSCy Schubert gss_ctx_id_t ctx;
587*7f2fe78bSCy Schubert size_t i;
588*7f2fe78bSCy Schubert
589*7f2fe78bSCy Schubert kb.enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
590*7f2fe78bSCy Schubert kb.length = 16;
591*7f2fe78bSCy Schubert kb.contents = (unsigned char *)"1234567887654321";
592*7f2fe78bSCy Schubert if (krb5_k_create_key(NULL, &kb, &cfx_subkey) != 0)
593*7f2fe78bSCy Schubert abort();
594*7f2fe78bSCy Schubert
595*7f2fe78bSCy Schubert ctx = make_fake_cfx_context(cfx_subkey);
596*7f2fe78bSCy Schubert test_bogus_1964_token(ctx);
597*7f2fe78bSCy Schubert test_cfx_altered_ec(ctx, cfx_subkey);
598*7f2fe78bSCy Schubert test_cfx_short_plaintext(ctx, cfx_subkey);
599*7f2fe78bSCy Schubert test_cfx_large_ec(ctx, cfx_subkey);
600*7f2fe78bSCy Schubert test_iov_large_asn1_wrapper(ctx);
601*7f2fe78bSCy Schubert free_fake_context(ctx);
602*7f2fe78bSCy Schubert
603*7f2fe78bSCy Schubert for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
604*7f2fe78bSCy Schubert ctx = make_fake_context(&tests[i]);
605*7f2fe78bSCy Schubert test_short_header(ctx);
606*7f2fe78bSCy Schubert test_short_header_iov(ctx, &tests[i]);
607*7f2fe78bSCy Schubert test_short_checksum(ctx, &tests[i]);
608*7f2fe78bSCy Schubert test_bad_pad(ctx, &tests[i]);
609*7f2fe78bSCy Schubert free_fake_context(ctx);
610*7f2fe78bSCy Schubert }
611*7f2fe78bSCy Schubert
612*7f2fe78bSCy Schubert test_short_encapsulation();
613*7f2fe78bSCy Schubert
614*7f2fe78bSCy Schubert return 0;
615*7f2fe78bSCy Schubert }
616