CVE-2024-37371.patch 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. From 55fbf435edbe2e92dd8101669b1ce7144bc96fef Mon Sep 17 00:00:00 2001
  2. From: Greg Hudson <ghudson@mit.edu>
  3. Date: Fri, 14 Jun 2024 10:56:12 -0400
  4. Subject: [PATCH] Fix vulnerabilities in GSS message token handling
  5. In gss_krb5int_unseal_token_v3() and gss_krb5int_unseal_v3_iov(),
  6. verify the Extra Count field of CFX wrap tokens against the encrypted
  7. header. Reported by Jacob Champion.
  8. In gss_krb5int_unseal_token_v3(), check for a decrypted plaintext
  9. length too short to contain the encrypted header and extra count
  10. bytes. Reported by Jacob Champion.
  11. In kg_unseal_iov_token(), separately track the header IOV length and
  12. complete token length when parsing the token's ASN.1 wrapper. This
  13. fix contains modified versions of functions from k5-der.h and
  14. util_token.c; this duplication will be cleaned up in a future commit.
  15. CVE-2024-37370:
  16. In MIT krb5 release 1.3 and later, an attacker can modify the
  17. plaintext Extra Count field of a confidential GSS krb5 wrap token,
  18. causing the unwrapped token to appear truncated to the application.
  19. CVE-2024-37371:
  20. In MIT krb5 release 1.3 and later, an attacker can cause invalid
  21. memory reads by sending message tokens with invalid length fields.
  22. (cherry picked from commit b0a2f8a5365f2eec3e27d78907de9f9d2c80505a)
  23. ticket: 9128
  24. version_fixed: 1.21.3
  25. ---
  26. src/lib/gssapi/krb5/k5sealv3.c | 5 +
  27. src/lib/gssapi/krb5/k5sealv3iov.c | 3 +-
  28. src/lib/gssapi/krb5/k5unsealiov.c | 80 +++++++++-
  29. src/tests/gssapi/t_invalid.c | 233 +++++++++++++++++++++++++-----
  30. 4 files changed, 275 insertions(+), 46 deletions(-)
  31. diff --git a/src/lib/gssapi/krb5/k5sealv3.c b/src/lib/gssapi/krb5/k5sealv3.c
  32. index 3b4f8cb837b..1fcbdfbb870 100644
  33. --- a/src/lib/gssapi/krb5/k5sealv3.c
  34. +++ b/src/lib/gssapi/krb5/k5sealv3.c
  35. @@ -408,10 +408,15 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr,
  36. /* Don't use bodysize here! Use the fact that
  37. cipher.ciphertext.length has been adjusted to the
  38. correct length. */
  39. + if (plain.length < 16 + ec) {
  40. + free(plain.data);
  41. + goto defective;
  42. + }
  43. althdr = (unsigned char *)plain.data + plain.length - 16;
  44. if (load_16_be(althdr) != KG2_TOK_WRAP_MSG
  45. || althdr[2] != ptr[2]
  46. || althdr[3] != ptr[3]
  47. + || load_16_be(althdr+4) != ec
  48. || memcmp(althdr+8, ptr+8, 8)) {
  49. free(plain.data);
  50. goto defective;
  51. diff --git a/src/lib/gssapi/krb5/k5sealv3iov.c b/src/lib/gssapi/krb5/k5sealv3iov.c
  52. index 333ee124ddf..f8e90c35b44 100644
  53. --- a/src/lib/gssapi/krb5/k5sealv3iov.c
  54. +++ b/src/lib/gssapi/krb5/k5sealv3iov.c
  55. @@ -402,9 +402,10 @@ gss_krb5int_unseal_v3_iov(krb5_context context,
  56. if (load_16_be(althdr) != KG2_TOK_WRAP_MSG
  57. || althdr[2] != ptr[2]
  58. || althdr[3] != ptr[3]
  59. + || load_16_be(althdr + 4) != ec
  60. || memcmp(althdr + 8, ptr + 8, 8) != 0) {
  61. *minor_status = 0;
  62. - return GSS_S_BAD_SIG;
  63. + return GSS_S_DEFECTIVE_TOKEN;
  64. }
  65. } else {
  66. /* Verify checksum: note EC is checksum size here, not padding */
  67. diff --git a/src/lib/gssapi/krb5/k5unsealiov.c b/src/lib/gssapi/krb5/k5unsealiov.c
  68. index 85a9574f365..21b501731e6 100644
  69. --- a/src/lib/gssapi/krb5/k5unsealiov.c
  70. +++ b/src/lib/gssapi/krb5/k5unsealiov.c
  71. @@ -25,6 +25,7 @@
  72. */
  73. #include "k5-int.h"
  74. +#include "k5-der.h"
  75. #include "gssapiP_krb5.h"
  76. static OM_uint32
  77. @@ -265,6 +266,73 @@ kg_unseal_v1_iov(krb5_context context,
  78. return retval;
  79. }
  80. +/* Similar to k5_der_get_value(), but output an unchecked content length
  81. + * instead of a k5input containing the contents. */
  82. +static inline bool
  83. +get_der_tag(struct k5input *in, uint8_t idbyte, size_t *len_out)
  84. +{
  85. + uint8_t lenbyte, i;
  86. + size_t len;
  87. +
  88. + /* Do nothing if in is empty or the next byte doesn't match idbyte. */
  89. + if (in->status || in->len == 0 || *in->ptr != idbyte)
  90. + return false;
  91. +
  92. + /* Advance past the identifier byte and decode the length. */
  93. + (void)k5_input_get_byte(in);
  94. + lenbyte = k5_input_get_byte(in);
  95. + if (lenbyte < 128) {
  96. + len = lenbyte;
  97. + } else {
  98. + len = 0;
  99. + for (i = 0; i < (lenbyte & 0x7F); i++) {
  100. + if (len > (SIZE_MAX >> 8)) {
  101. + k5_input_set_status(in, EOVERFLOW);
  102. + return false;
  103. + }
  104. + len = (len << 8) | k5_input_get_byte(in);
  105. + }
  106. + }
  107. +
  108. + if (in->status)
  109. + return false;
  110. +
  111. + *len_out = len;
  112. + return true;
  113. +}
  114. +
  115. +/*
  116. + * Similar to g_verify_token_header() without toktype or flags, but do not read
  117. + * more than *header_len bytes of ASN.1 wrapper, and on output set *header_len
  118. + * to the remaining number of header bytes. Verify the outer DER tag's length
  119. + * against token_len, which may be larger (but not smaller) than *header_len.
  120. + */
  121. +static gss_int32
  122. +verify_detached_wrapper(const gss_OID_desc *mech, size_t *header_len,
  123. + uint8_t **header_in, size_t token_len)
  124. +{
  125. + struct k5input in, mech_der;
  126. + gss_OID_desc toid;
  127. + size_t len;
  128. +
  129. + k5_input_init(&in, *header_in, *header_len);
  130. +
  131. + if (get_der_tag(&in, 0x60, &len)) {
  132. + if (len != token_len - (in.ptr - *header_in))
  133. + return G_BAD_TOK_HEADER;
  134. + if (!k5_der_get_value(&in, 0x06, &mech_der))
  135. + return G_BAD_TOK_HEADER;
  136. + toid.elements = (uint8_t *)mech_der.ptr;
  137. + toid.length = mech_der.len;
  138. + if (!g_OID_equal(&toid, mech))
  139. + return G_WRONG_MECH;
  140. + }
  141. +
  142. + *header_in = (uint8_t *)in.ptr;
  143. + *header_len = in.len;
  144. + return 0;
  145. +}
  146. +
  147. /*
  148. * Caller must provide TOKEN | DATA | PADDING | TRAILER, except
  149. * for DCE in which case it can just provide TOKEN | DATA (must
  150. @@ -285,8 +353,7 @@ kg_unseal_iov_token(OM_uint32 *minor_status,
  151. gss_iov_buffer_t header;
  152. gss_iov_buffer_t padding;
  153. gss_iov_buffer_t trailer;
  154. - size_t input_length;
  155. - unsigned int bodysize;
  156. + size_t input_length, hlen;
  157. int toktype2;
  158. header = kg_locate_header_iov(iov, iov_count, toktype);
  159. @@ -316,15 +383,14 @@ kg_unseal_iov_token(OM_uint32 *minor_status,
  160. input_length += trailer->buffer.length;
  161. }
  162. - code = g_verify_token_header(ctx->mech_used,
  163. - &bodysize, &ptr, -1,
  164. - input_length, 0);
  165. + hlen = header->buffer.length;
  166. + code = verify_detached_wrapper(ctx->mech_used, &hlen, &ptr, input_length);
  167. if (code != 0) {
  168. *minor_status = code;
  169. return GSS_S_DEFECTIVE_TOKEN;
  170. }
  171. - if (bodysize < 2) {
  172. + if (hlen < 2) {
  173. *minor_status = (OM_uint32)G_BAD_TOK_HEADER;
  174. return GSS_S_DEFECTIVE_TOKEN;
  175. }
  176. @@ -332,7 +398,7 @@ kg_unseal_iov_token(OM_uint32 *minor_status,
  177. toktype2 = load_16_be(ptr);
  178. ptr += 2;
  179. - bodysize -= 2;
  180. + hlen -= 2;
  181. switch (toktype2) {
  182. case KG2_TOK_MIC_MSG:
  183. diff --git a/src/tests/gssapi/t_invalid.c b/src/tests/gssapi/t_invalid.c
  184. index 9876a11e673..882e163634d 100644
  185. --- a/src/tests/gssapi/t_invalid.c
  186. +++ b/src/tests/gssapi/t_invalid.c
  187. @@ -36,31 +36,41 @@
  188. *
  189. * 1. A pre-CFX wrap or MIC token processed with a CFX-only context causes a
  190. * null pointer dereference. (The token must use SEAL_ALG_NONE or it will
  191. - * be rejected.)
  192. + * be rejected.) This vulnerability also applies to IOV unwrap.
  193. *
  194. - * 2. A pre-CFX wrap or MIC token with fewer than 24 bytes after the ASN.1
  195. + * 2. A CFX wrap token with a different value of EC between the plaintext and
  196. + * encrypted copies will be erroneously accepted, which allows a message
  197. + * truncation attack. This vulnerability also applies to IOV unwrap.
  198. + *
  199. + * 3. A CFX wrap token with a plaintext length fewer than 16 bytes causes an
  200. + * access before the beginning of the input buffer, possibly leading to a
  201. + * crash.
  202. + *
  203. + * 4. A CFX wrap token with a plaintext EC value greater than the plaintext
  204. + * length - 16 causes an integer underflow when computing the result length,
  205. + * likely causing a crash.
  206. + *
  207. + * 5. An IOV unwrap operation will overrun the header buffer if an ASN.1
  208. + * wrapper longer than the header buffer is present.
  209. + *
  210. + * 6. A pre-CFX wrap or MIC token with fewer than 24 bytes after the ASN.1
  211. * header causes an input buffer overrun, usually leading to either a segv
  212. * or a GSS_S_DEFECTIVE_TOKEN error due to garbage algorithm, filler, or
  213. - * sequence number values.
  214. + * sequence number values. This vulnerability also applies to IOV unwrap.
  215. *
  216. - * 3. A pre-CFX wrap token with fewer than 16 + cksumlen bytes after the ASN.1
  217. + * 7. A pre-CFX wrap token with fewer than 16 + cksumlen bytes after the ASN.1
  218. * header causes an integer underflow when computing the ciphertext length,
  219. * leading to an allocation error on 32-bit platforms or a segv on 64-bit
  220. * platforms. A pre-CFX MIC token of this size causes an input buffer
  221. * overrun when comparing the checksum, perhaps leading to a segv.
  222. *
  223. - * 4. A pre-CFX wrap token with fewer than conflen + padlen bytes in the
  224. + * 8. A pre-CFX wrap token with fewer than conflen + padlen bytes in the
  225. * ciphertext (where padlen is the last byte of the decrypted ciphertext)
  226. * causes an integer underflow when computing the original message length,
  227. * leading to an allocation error.
  228. *
  229. - * 5. In the mechglue, truncated encapsulation in the initial context token can
  230. + * 9. In the mechglue, truncated encapsulation in the initial context token can
  231. * cause input buffer overruns in gss_accept_sec_context().
  232. - *
  233. - * Vulnerabilities #1 and #2 also apply to IOV unwrap, although tokens with
  234. - * fewer than 16 bytes after the ASN.1 header will be rejected.
  235. - * Vulnerabilities #2 and #5 can only be robustly detected using a
  236. - * memory-checking environment such as valgrind.
  237. */
  238. #include "k5-int.h"
  239. @@ -109,17 +119,25 @@ struct test {
  240. }
  241. };
  242. -/* Fake up enough of a CFX GSS context for gss_unwrap, using an AES key. */
  243. +static void *
  244. +ealloc(size_t len)
  245. +{
  246. + void *ptr = calloc(len, 1);
  247. +
  248. + if (ptr == NULL)
  249. + abort();
  250. + return ptr;
  251. +}
  252. +
  253. +/* Fake up enough of a CFX GSS context for gss_unwrap, using an AES key.
  254. + * The context takes ownership of subkey. */
  255. static gss_ctx_id_t
  256. -make_fake_cfx_context()
  257. +make_fake_cfx_context(krb5_key subkey)
  258. {
  259. gss_union_ctx_id_t uctx;
  260. krb5_gss_ctx_id_t kgctx;
  261. - krb5_keyblock kb;
  262. - kgctx = calloc(1, sizeof(*kgctx));
  263. - if (kgctx == NULL)
  264. - abort();
  265. + kgctx = ealloc(sizeof(*kgctx));
  266. kgctx->established = 1;
  267. kgctx->proto = 1;
  268. if (g_seqstate_init(&kgctx->seqstate, 0, 0, 0, 0) != 0)
  269. @@ -128,15 +146,10 @@ make_fake_cfx_context()
  270. kgctx->sealalg = -1;
  271. kgctx->signalg = -1;
  272. - kb.enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
  273. - kb.length = 16;
  274. - kb.contents = (unsigned char *)"1234567887654321";
  275. - if (krb5_k_create_key(NULL, &kb, &kgctx->subkey) != 0)
  276. - abort();
  277. + kgctx->subkey = subkey;
  278. + kgctx->cksumtype = CKSUMTYPE_HMAC_SHA1_96_AES128;
  279. - uctx = calloc(1, sizeof(*uctx));
  280. - if (uctx == NULL)
  281. - abort();
  282. + uctx = ealloc(sizeof(*uctx));
  283. uctx->mech_type = &mech_krb5;
  284. uctx->internal_ctx_id = (gss_ctx_id_t)kgctx;
  285. return (gss_ctx_id_t)uctx;
  286. @@ -150,9 +163,7 @@ make_fake_context(const struct test *test)
  287. krb5_gss_ctx_id_t kgctx;
  288. krb5_keyblock kb;
  289. - kgctx = calloc(1, sizeof(*kgctx));
  290. - if (kgctx == NULL)
  291. - abort();
  292. + kgctx = ealloc(sizeof(*kgctx));
  293. kgctx->established = 1;
  294. if (g_seqstate_init(&kgctx->seqstate, 0, 0, 0, 0) != 0)
  295. abort();
  296. @@ -174,9 +185,7 @@ make_fake_context(const struct test *test)
  297. if (krb5_k_create_key(NULL, &kb, &kgctx->enc) != 0)
  298. abort();
  299. - uctx = calloc(1, sizeof(*uctx));
  300. - if (uctx == NULL)
  301. - abort();
  302. + uctx = ealloc(sizeof(*uctx));
  303. uctx->mech_type = &mech_krb5;
  304. uctx->internal_ctx_id = (gss_ctx_id_t)kgctx;
  305. return (gss_ctx_id_t)uctx;
  306. @@ -206,9 +215,7 @@ make_token(unsigned char *token, size_t len, gss_buffer_t out)
  307. assert(mech_krb5.length == 9);
  308. assert(len + 11 < 128);
  309. - wrapped = malloc(len + 13);
  310. - if (wrapped == NULL)
  311. - abort();
  312. + wrapped = ealloc(len + 13);
  313. wrapped[0] = 0x60;
  314. wrapped[1] = len + 11;
  315. wrapped[2] = 0x06;
  316. @@ -219,6 +226,18 @@ make_token(unsigned char *token, size_t len, gss_buffer_t out)
  317. out->value = wrapped;
  318. }
  319. +/* Create a 16-byte header for a CFX confidential wrap token to be processed by
  320. + * the fake CFX context. */
  321. +static void
  322. +write_cfx_header(uint16_t ec, uint8_t *out)
  323. +{
  324. + memset(out, 0, 16);
  325. + store_16_be(KG2_TOK_WRAP_MSG, out);
  326. + out[2] = FLAG_WRAP_CONFIDENTIAL;
  327. + out[3] = 0xFF;
  328. + store_16_be(ec, out + 4);
  329. +}
  330. +
  331. /* Unwrap a superficially valid RFC 1964 token with a CFX-only context, with
  332. * regular and IOV unwrap. */
  333. static void
  334. @@ -250,6 +269,134 @@ test_bogus_1964_token(gss_ctx_id_t ctx)
  335. free(in.value);
  336. }
  337. +static void
  338. +test_cfx_altered_ec(gss_ctx_id_t ctx, krb5_key subkey)
  339. +{
  340. + OM_uint32 major, minor;
  341. + uint8_t tokbuf[128], plainbuf[24];
  342. + krb5_data plain;
  343. + krb5_enc_data cipher;
  344. + gss_buffer_desc in, out;
  345. + gss_iov_buffer_desc iov[2];
  346. +
  347. + /* Construct a header with a plaintext EC value of 3. */
  348. + write_cfx_header(3, tokbuf);
  349. +
  350. + /* Encrypt a plaintext and a copy of the header with the EC value 0. */
  351. + memcpy(plainbuf, "truncate", 8);
  352. + memcpy(plainbuf + 8, tokbuf, 16);
  353. + store_16_be(0, plainbuf + 12);
  354. + plain = make_data(plainbuf, 24);
  355. + cipher.ciphertext.data = (char *)tokbuf + 16;
  356. + cipher.ciphertext.length = sizeof(tokbuf) - 16;
  357. + cipher.enctype = subkey->keyblock.enctype;
  358. + if (krb5_k_encrypt(NULL, subkey, KG_USAGE_INITIATOR_SEAL, NULL,
  359. + &plain, &cipher) != 0)
  360. + abort();
  361. +
  362. + /* Verify that the token is rejected by gss_unwrap(). */
  363. + in.value = tokbuf;
  364. + in.length = 16 + cipher.ciphertext.length;
  365. + major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
  366. + if (major != GSS_S_DEFECTIVE_TOKEN)
  367. + abort();
  368. + (void)gss_release_buffer(&minor, &out);
  369. +
  370. + /* Verify that the token is rejected by gss_unwrap_iov(). */
  371. + iov[0].type = GSS_IOV_BUFFER_TYPE_STREAM;
  372. + iov[0].buffer = in;
  373. + iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
  374. + major = gss_unwrap_iov(&minor, ctx, NULL, NULL, iov, 2);
  375. + if (major != GSS_S_DEFECTIVE_TOKEN)
  376. + abort();
  377. +}
  378. +
  379. +static void
  380. +test_cfx_short_plaintext(gss_ctx_id_t ctx, krb5_key subkey)
  381. +{
  382. + OM_uint32 major, minor;
  383. + uint8_t tokbuf[128], zerobyte = 0;
  384. + krb5_data plain;
  385. + krb5_enc_data cipher;
  386. + gss_buffer_desc in, out;
  387. +
  388. + write_cfx_header(0, tokbuf);
  389. +
  390. + /* Encrypt a single byte, with no copy of the header. */
  391. + plain = make_data(&zerobyte, 1);
  392. + cipher.ciphertext.data = (char *)tokbuf + 16;
  393. + cipher.ciphertext.length = sizeof(tokbuf) - 16;
  394. + cipher.enctype = subkey->keyblock.enctype;
  395. + if (krb5_k_encrypt(NULL, subkey, KG_USAGE_INITIATOR_SEAL, NULL,
  396. + &plain, &cipher) != 0)
  397. + abort();
  398. +
  399. + /* Verify that the token is rejected by gss_unwrap(). */
  400. + in.value = tokbuf;
  401. + in.length = 16 + cipher.ciphertext.length;
  402. + major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
  403. + if (major != GSS_S_DEFECTIVE_TOKEN)
  404. + abort();
  405. + (void)gss_release_buffer(&minor, &out);
  406. +}
  407. +
  408. +static void
  409. +test_cfx_large_ec(gss_ctx_id_t ctx, krb5_key subkey)
  410. +{
  411. + OM_uint32 major, minor;
  412. + uint8_t tokbuf[128] = { 0 }, plainbuf[20];
  413. + krb5_data plain;
  414. + krb5_enc_data cipher;
  415. + gss_buffer_desc in, out;
  416. +
  417. + /* Construct a header with an EC value of 5. */
  418. + write_cfx_header(5, tokbuf);
  419. +
  420. + /* Encrypt a 4-byte plaintext plus the header. */
  421. + memcpy(plainbuf, "abcd", 4);
  422. + memcpy(plainbuf + 4, tokbuf, 16);
  423. + plain = make_data(plainbuf, 20);
  424. + cipher.ciphertext.data = (char *)tokbuf + 16;
  425. + cipher.ciphertext.length = sizeof(tokbuf) - 16;
  426. + cipher.enctype = subkey->keyblock.enctype;
  427. + if (krb5_k_encrypt(NULL, subkey, KG_USAGE_INITIATOR_SEAL, NULL,
  428. + &plain, &cipher) != 0)
  429. + abort();
  430. +
  431. + /* Verify that the token is rejected by gss_unwrap(). */
  432. + in.value = tokbuf;
  433. + in.length = 16 + cipher.ciphertext.length;
  434. + major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
  435. + if (major != GSS_S_DEFECTIVE_TOKEN)
  436. + abort();
  437. + (void)gss_release_buffer(&minor, &out);
  438. +}
  439. +
  440. +static void
  441. +test_iov_large_asn1_wrapper(gss_ctx_id_t ctx)
  442. +{
  443. + OM_uint32 minor, major;
  444. + uint8_t databuf[10] = { 0 };
  445. + gss_iov_buffer_desc iov[2];
  446. +
  447. + /*
  448. + * In this IOV array, the header contains a DER tag with a dangling eight
  449. + * bytes of length field. The data IOV indicates a total token length
  450. + * sufficient to contain the length bytes.
  451. + */
  452. + iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER;
  453. + iov[0].buffer.value = ealloc(2);
  454. + iov[0].buffer.length = 2;
  455. + memcpy(iov[0].buffer.value, "\x60\x88", 2);
  456. + iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
  457. + iov[1].buffer.value = databuf;
  458. + iov[1].buffer.length = 10;
  459. + major = gss_unwrap_iov(&minor, ctx, NULL, NULL, iov, 2);
  460. + if (major != GSS_S_DEFECTIVE_TOKEN)
  461. + abort();
  462. + free(iov[0].buffer.value);
  463. +}
  464. +
  465. /* Process wrap and MIC tokens with incomplete headers. */
  466. static void
  467. test_short_header(gss_ctx_id_t ctx)
  468. @@ -399,9 +546,7 @@ try_accept(void *value, size_t len)
  469. gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
  470. /* Copy the provided value to make input overruns more obvious. */
  471. - in.value = malloc(len);
  472. - if (in.value == NULL)
  473. - abort();
  474. + in.value = ealloc(len);
  475. memcpy(in.value, value, len);
  476. in.length = len;
  477. (void)gss_accept_sec_context(&minor, &ctx, GSS_C_NO_CREDENTIAL, &in,
  478. @@ -436,11 +581,23 @@ test_short_encapsulation()
  479. int
  480. main(int argc, char **argv)
  481. {
  482. + krb5_keyblock kb;
  483. + krb5_key cfx_subkey;
  484. gss_ctx_id_t ctx;
  485. size_t i;
  486. - ctx = make_fake_cfx_context();
  487. + kb.enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
  488. + kb.length = 16;
  489. + kb.contents = (unsigned char *)"1234567887654321";
  490. + if (krb5_k_create_key(NULL, &kb, &cfx_subkey) != 0)
  491. + abort();
  492. +
  493. + ctx = make_fake_cfx_context(cfx_subkey);
  494. test_bogus_1964_token(ctx);
  495. + test_cfx_altered_ec(ctx, cfx_subkey);
  496. + test_cfx_short_plaintext(ctx, cfx_subkey);
  497. + test_cfx_large_ec(ctx, cfx_subkey);
  498. + test_iov_large_asn1_wrapper(ctx);
  499. free_fake_context(ctx);
  500. for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {