Implement gss_wrap_iov, gss_unwrap_iov for CFX type encryption types.
[heimdal.git] / lib / gssapi / test_context.c
blob27f83da5278e17bfb7c5be35cf45752b2c4cef1d
1 /*
2 * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of KTH nor the names of its contributors may be
18 * used to endorse or promote products derived from this software without
19 * specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "krb5/gsskrb5_locl.h"
35 #include <err.h>
36 #include <getarg.h>
37 #include <gssapi.h>
38 #include <gssapi_krb5.h>
39 #include <gssapi_spnego.h>
40 #include <gssapi_ntlm.h>
41 #include "test_common.h"
43 RCSID("$Id$");
45 static char *type_string;
46 static char *mech_string;
47 static char *ret_mech_string;
48 static int dns_canon_flag = -1;
49 static int mutual_auth_flag = 0;
50 static int dce_style_flag = 0;
51 static int wrapunwrap_flag = 0;
52 static int iov_flag = 0;
53 static int getverifymic_flag = 0;
54 static int deleg_flag = 0;
55 static int policy_deleg_flag = 0;
56 static int server_no_deleg_flag = 0;
57 static char *gsskrb5_acceptor_identity = NULL;
58 static char *session_enctype_string = NULL;
59 static int client_time_offset = 0;
60 static int server_time_offset = 0;
61 static int max_loops = 0;
62 static int version_flag = 0;
63 static int verbose_flag = 0;
64 static int help_flag = 0;
66 static struct {
67 const char *name;
68 gss_OID *oid;
69 } o2n[] = {
70 { "krb5", &GSS_KRB5_MECHANISM },
71 { "spnego", &GSS_SPNEGO_MECHANISM },
72 { "ntlm", &GSS_NTLM_MECHANISM },
73 { "sasl-digest-md5", &GSS_SASL_DIGEST_MD5_MECHANISM }
76 static gss_OID
77 string_to_oid(const char *name)
79 int i;
80 for (i = 0; i < sizeof(o2n)/sizeof(o2n[0]); i++)
81 if (strcasecmp(name, o2n[i].name) == 0)
82 return *o2n[i].oid;
83 errx(1, "name '%s' not unknown", name);
86 static const char *
87 oid_to_string(const gss_OID oid)
89 int i;
90 for (i = 0; i < sizeof(o2n)/sizeof(o2n[0]); i++)
91 if (gss_oid_equal(oid, *o2n[i].oid))
92 return o2n[i].name;
93 return "unknown oid";
96 static void
97 loop(gss_OID mechoid,
98 gss_OID nameoid, const char *target,
99 gss_cred_id_t init_cred,
100 gss_ctx_id_t *sctx, gss_ctx_id_t *cctx,
101 gss_OID *actual_mech,
102 gss_cred_id_t *deleg_cred)
104 int server_done = 0, client_done = 0;
105 int num_loops = 0;
106 OM_uint32 maj_stat, min_stat;
107 gss_name_t gss_target_name;
108 gss_buffer_desc input_token, output_token;
109 OM_uint32 flags = 0, ret_cflags, ret_sflags;
110 gss_OID actual_mech_client;
111 gss_OID actual_mech_server;
113 *actual_mech = GSS_C_NO_OID;
115 flags |= GSS_C_INTEG_FLAG;
116 flags |= GSS_C_CONF_FLAG;
118 if (mutual_auth_flag)
119 flags |= GSS_C_MUTUAL_FLAG;
120 if (dce_style_flag)
121 flags |= GSS_C_DCE_STYLE;
122 if (deleg_flag)
123 flags |= GSS_C_DELEG_FLAG;
124 if (policy_deleg_flag)
125 flags |= GSS_C_DELEG_POLICY_FLAG;
127 input_token.value = rk_UNCONST(target);
128 input_token.length = strlen(target);
130 maj_stat = gss_import_name(&min_stat,
131 &input_token,
132 nameoid,
133 &gss_target_name);
134 if (GSS_ERROR(maj_stat))
135 err(1, "import name creds failed with: %d", maj_stat);
137 input_token.length = 0;
138 input_token.value = NULL;
140 while (!server_done || !client_done) {
141 num_loops++;
143 gsskrb5_set_time_offset(client_time_offset);
145 maj_stat = gss_init_sec_context(&min_stat,
146 init_cred,
147 cctx,
148 gss_target_name,
149 mechoid,
150 flags,
152 NULL,
153 &input_token,
154 &actual_mech_client,
155 &output_token,
156 &ret_cflags,
157 NULL);
158 if (GSS_ERROR(maj_stat))
159 errx(1, "init_sec_context: %s",
160 gssapi_err(maj_stat, min_stat, mechoid));
161 if (maj_stat & GSS_S_CONTINUE_NEEDED)
163 else
164 client_done = 1;
166 gsskrb5_get_time_offset(&client_time_offset);
168 if (client_done && server_done)
169 break;
171 if (input_token.length != 0)
172 gss_release_buffer(&min_stat, &input_token);
174 gsskrb5_set_time_offset(server_time_offset);
176 maj_stat = gss_accept_sec_context(&min_stat,
177 sctx,
178 GSS_C_NO_CREDENTIAL,
179 &output_token,
180 GSS_C_NO_CHANNEL_BINDINGS,
181 NULL,
182 &actual_mech_server,
183 &input_token,
184 &ret_sflags,
185 NULL,
186 deleg_cred);
187 if (GSS_ERROR(maj_stat))
188 errx(1, "accept_sec_context: %s",
189 gssapi_err(maj_stat, min_stat, actual_mech_server));
191 gsskrb5_get_time_offset(&server_time_offset);
193 if (output_token.length != 0)
194 gss_release_buffer(&min_stat, &output_token);
196 if (maj_stat & GSS_S_CONTINUE_NEEDED)
198 else
199 server_done = 1;
201 if (output_token.length != 0)
202 gss_release_buffer(&min_stat, &output_token);
203 if (input_token.length != 0)
204 gss_release_buffer(&min_stat, &input_token);
205 gss_release_name(&min_stat, &gss_target_name);
207 if (deleg_flag || policy_deleg_flag) {
208 if (server_no_deleg_flag) {
209 if (*deleg_cred != GSS_C_NO_CREDENTIAL)
210 errx(1, "got delegated cred but didn't expect one");
211 } else if (*deleg_cred == GSS_C_NO_CREDENTIAL)
212 errx(1, "asked for delegarated cred but did get one");
213 } else if (*deleg_cred != GSS_C_NO_CREDENTIAL)
214 errx(1, "got deleg_cred cred but didn't ask");
216 if (gss_oid_equal(actual_mech_server, actual_mech_client) == 0)
217 errx(1, "mech mismatch");
218 *actual_mech = actual_mech_server;
220 if (max_loops && num_loops > max_loops)
221 errx(1, "num loops %d was lager then max loops %d",
222 num_loops, max_loops);
224 if (verbose_flag) {
225 printf("server time offset: %d\n", server_time_offset);
226 printf("client time offset: %d\n", client_time_offset);
227 printf("num loops %d\n", num_loops);
231 static void
232 wrapunwrap(gss_ctx_id_t cctx, gss_ctx_id_t sctx, int flags, gss_OID mechoid)
234 gss_buffer_desc input_token, output_token, output_token2;
235 OM_uint32 min_stat, maj_stat;
236 gss_qop_t qop_state;
237 int conf_state;
239 input_token.value = "foo";
240 input_token.length = 3;
242 maj_stat = gss_wrap(&min_stat, cctx, flags, 0, &input_token,
243 &conf_state, &output_token);
244 if (maj_stat != GSS_S_COMPLETE)
245 errx(1, "gss_wrap failed: %s",
246 gssapi_err(maj_stat, min_stat, mechoid));
248 maj_stat = gss_unwrap(&min_stat, sctx, &output_token,
249 &output_token2, &conf_state, &qop_state);
250 if (maj_stat != GSS_S_COMPLETE)
251 errx(1, "gss_unwrap failed: %s",
252 gssapi_err(maj_stat, min_stat, mechoid));
253 #if 0 /* doesn't work for NTLM yet */
254 if (!!conf_state != !!flags)
255 errx(1, "conf_state mismatch");
256 #endif
259 #define USE_CONF 1
260 #define USE_HEADER_ONLY 2
261 #define USE_SIGN_ONLY 4
262 #define FORCE_IOV 8
264 static void
265 wrapunwrap_iov(gss_ctx_id_t cctx, gss_ctx_id_t sctx, int flags, gss_OID mechoid)
267 krb5_data token, header, trailer;
268 OM_uint32 min_stat, maj_stat;
269 gss_qop_t qop_state;
270 int conf_state, conf_state2;
271 gss_iov_buffer_desc iov[5];
272 unsigned char *p;
273 int iov_len;
274 char header_data[9] = "ABCheader";
275 char trailer_data[10] = "trailerXYZ";
277 char token_data[16] = "0123456789abcdef";
279 memset(&iov, 0, sizeof(iov));
281 if (flags & USE_SIGN_ONLY) {
282 header.data = header_data;
283 header.length = 9;
284 trailer.data = trailer_data;
285 trailer.length = 10;
286 } else {
287 header.data = NULL;
288 header.length = 0;
289 trailer.data = NULL;
290 trailer.length = 0;
293 token.data = token_data;
294 token.length = 16;
296 iov_len = sizeof(iov)/sizeof(iov[0]);
298 memset(iov, 0, sizeof(iov));
300 if (flags & USE_HEADER_ONLY)
301 iov_len -= 1; /* skip trailer */
303 iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE;
305 if (header.length != 0) {
306 iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
307 iov[1].buffer.length = header.length;
308 iov[1].buffer.value = header.data;
309 } else {
310 iov[1].type = GSS_IOV_BUFFER_TYPE_EMPTY;
311 iov[1].buffer.length = 0;
312 iov[1].buffer.value = NULL;
314 iov[2].type = GSS_IOV_BUFFER_TYPE_DATA;
315 iov[2].buffer.length = token.length;
316 iov[2].buffer.value = token.data;
317 if (trailer.length != 0) {
318 iov[3].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
319 iov[3].buffer.length = trailer.length;
320 iov[3].buffer.value = trailer.data;
321 } else {
322 iov[3].type = GSS_IOV_BUFFER_TYPE_EMPTY;
323 iov[3].buffer.length = 0;
324 iov[3].buffer.value = NULL;
326 iov[4].type = GSS_IOV_BUFFER_TYPE_TRAILER | GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE;
327 iov[4].buffer.length = 0;
328 iov[4].buffer.value = 0;
330 maj_stat = gss_wrap_iov(&min_stat, cctx, flags & USE_CONF, 0, &conf_state,
331 iov, iov_len);
332 if (maj_stat != GSS_S_COMPLETE)
333 errx(1, "gss_wrap_iov failed");
335 token.length =
336 iov[0].buffer.length +
337 iov[1].buffer.length +
338 iov[2].buffer.length +
339 iov[3].buffer.length +
340 iov[4].buffer.length;
341 token.data = emalloc(token.length);
343 p = token.data;
344 memcpy(p, iov[0].buffer.value, iov[0].buffer.length);
345 p += iov[0].buffer.length;
346 memcpy(p, iov[1].buffer.value, iov[1].buffer.length);
347 p += iov[1].buffer.length;
348 memcpy(p, iov[2].buffer.value, iov[2].buffer.length);
349 p += iov[2].buffer.length;
350 memcpy(p, iov[3].buffer.value, iov[3].buffer.length);
351 p += iov[3].buffer.length;
352 memcpy(p, iov[4].buffer.value, iov[4].buffer.length);
353 p += iov[4].buffer.length;
355 assert(p - ((unsigned char *)token.data) == token.length);
357 if ((flags & (USE_SIGN_ONLY|FORCE_IOV)) == 0) {
358 gss_buffer_desc input, output;
360 input.value = token.data;
361 input.length = token.length;
363 maj_stat = gss_unwrap(&min_stat, sctx, &input,
364 &output, &conf_state2, &qop_state);
366 if (maj_stat != GSS_S_COMPLETE)
367 errx(1, "gss_unwrap failed: %s",
368 gssapi_err(maj_stat, min_stat, mechoid));
370 gss_release_buffer(&min_stat, &output);
371 } else {
372 maj_stat = gss_unwrap_iov(&min_stat, sctx, &conf_state2, &qop_state,
373 iov, iov_len);
375 if (maj_stat != GSS_S_COMPLETE)
376 errx(1, "gss_unwrap_iov failed: %x %s", flags,
377 gssapi_err(maj_stat, min_stat, mechoid));
380 if (conf_state2 != conf_state)
381 errx(1, "conf state wrong for iov: %x", flags);
384 free(token.data);
387 static void
388 getverifymic(gss_ctx_id_t cctx, gss_ctx_id_t sctx, gss_OID mechoid)
390 gss_buffer_desc input_token, output_token;
391 OM_uint32 min_stat, maj_stat;
392 gss_qop_t qop_state;
394 input_token.value = "bar";
395 input_token.length = 3;
397 maj_stat = gss_get_mic(&min_stat, cctx, 0, &input_token,
398 &output_token);
399 if (maj_stat != GSS_S_COMPLETE)
400 errx(1, "gss_get_mic failed: %s",
401 gssapi_err(maj_stat, min_stat, mechoid));
403 maj_stat = gss_verify_mic(&min_stat, sctx, &input_token,
404 &output_token, &qop_state);
405 if (maj_stat != GSS_S_COMPLETE)
406 errx(1, "gss_verify_mic failed: %s",
407 gssapi_err(maj_stat, min_stat, mechoid));
410 static void
411 empty_release(void)
413 gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
414 gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
415 gss_name_t name = GSS_C_NO_NAME;
416 gss_OID_set oidset = GSS_C_NO_OID_SET;
417 OM_uint32 junk;
419 gss_delete_sec_context(&junk, &ctx, NULL);
420 gss_release_cred(&junk, &cred);
421 gss_release_name(&junk, &name);
422 gss_release_oid_set(&junk, &oidset);
429 static struct getargs args[] = {
430 {"name-type",0, arg_string, &type_string, "type of name", NULL },
431 {"mech-type",0, arg_string, &mech_string, "type of mech", NULL },
432 {"ret-mech-type",0, arg_string, &ret_mech_string,
433 "type of return mech", NULL },
434 {"dns-canonicalize",0,arg_negative_flag, &dns_canon_flag,
435 "use dns to canonicalize", NULL },
436 {"mutual-auth",0, arg_flag, &mutual_auth_flag,"mutual auth", NULL },
437 {"dce-style",0, arg_flag, &dce_style_flag, "dce-style", NULL },
438 {"wrapunwrap",0, arg_flag, &wrapunwrap_flag, "wrap/unwrap", NULL },
439 {"iov", 0, arg_flag, &iov_flag, "wrap/unwrap iov", NULL },
440 {"getverifymic",0, arg_flag, &getverifymic_flag,
441 "get and verify mic", NULL },
442 {"delegate",0, arg_flag, &deleg_flag, "delegate credential", NULL },
443 {"policy-delegate",0, arg_flag, &policy_deleg_flag, "policy delegate credential", NULL },
444 {"server-no-delegate",0, arg_flag, &server_no_deleg_flag,
445 "server should get a credential", NULL },
446 {"gsskrb5-acceptor-identity", 0, arg_string, &gsskrb5_acceptor_identity, "keytab", NULL },
447 {"session-enctype", 0, arg_string, &session_enctype_string, "enctype", NULL },
448 {"client-time-offset", 0, arg_integer, &client_time_offset, "time", NULL },
449 {"server-time-offset", 0, arg_integer, &server_time_offset, "time", NULL },
450 {"max-loops", 0, arg_integer, &max_loops, "time", NULL },
451 {"version", 0, arg_flag, &version_flag, "print version", NULL },
452 {"verbose", 'v', arg_flag, &verbose_flag, "verbose", NULL },
453 {"help", 0, arg_flag, &help_flag, NULL, NULL }
456 static void
457 usage (int ret)
459 arg_printusage (args, sizeof(args)/sizeof(*args),
460 NULL, "service@host");
461 exit (ret);
465 main(int argc, char **argv)
467 int optind = 0;
468 OM_uint32 min_stat, maj_stat;
469 gss_ctx_id_t cctx, sctx;
470 void *ctx;
471 gss_OID nameoid, mechoid, actual_mech;
472 gss_cred_id_t deleg_cred = GSS_C_NO_CREDENTIAL;
474 setprogname(argv[0]);
476 cctx = sctx = GSS_C_NO_CONTEXT;
478 if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind))
479 usage(1);
481 if (help_flag)
482 usage (0);
484 if(version_flag){
485 print_version(NULL);
486 exit(0);
489 argc -= optind;
490 argv += optind;
492 if (argc != 1)
493 usage(1);
495 if (dns_canon_flag != -1)
496 gsskrb5_set_dns_canonicalize(dns_canon_flag);
498 if (type_string == NULL)
499 nameoid = GSS_C_NT_HOSTBASED_SERVICE;
500 else if (strcmp(type_string, "hostbased-service") == 0)
501 nameoid = GSS_C_NT_HOSTBASED_SERVICE;
502 else if (strcmp(type_string, "krb5-principal-name") == 0)
503 nameoid = GSS_KRB5_NT_PRINCIPAL_NAME;
504 else
505 errx(1, "%s not suppported", type_string);
507 if (mech_string == NULL)
508 mechoid = GSS_KRB5_MECHANISM;
509 else
510 mechoid = string_to_oid(mech_string);
512 if (gsskrb5_acceptor_identity)
513 gsskrb5_register_acceptor_identity(gsskrb5_acceptor_identity);
515 loop(mechoid, nameoid, argv[0], GSS_C_NO_CREDENTIAL,
516 &sctx, &cctx, &actual_mech, &deleg_cred);
518 if (verbose_flag)
519 printf("resulting mech: %s\n", oid_to_string(actual_mech));
521 if (ret_mech_string) {
522 gss_OID retoid;
524 retoid = string_to_oid(ret_mech_string);
526 if (gss_oid_equal(retoid, actual_mech) == 0)
527 errx(1, "actual_mech mech is not the expected type %s",
528 ret_mech_string);
531 /* XXX should be actual_mech */
532 if (gss_oid_equal(mechoid, GSS_KRB5_MECHANISM)) {
533 krb5_context context;
534 time_t time;
535 gss_buffer_desc authz_data;
536 gss_buffer_desc in, out1, out2;
537 krb5_keyblock *keyblock, *keyblock2;
538 krb5_timestamp now;
539 krb5_error_code ret;
541 ret = krb5_init_context(&context);
542 if (ret)
543 errx(1, "krb5_init_context");
545 ret = krb5_timeofday(context, &now);
546 if (ret)
547 errx(1, "krb5_timeofday failed");
549 /* client */
550 maj_stat = gss_krb5_export_lucid_sec_context(&min_stat,
551 &cctx,
552 1, /* version */
553 &ctx);
554 if (maj_stat != GSS_S_COMPLETE)
555 errx(1, "gss_krb5_export_lucid_sec_context failed: %s",
556 gssapi_err(maj_stat, min_stat, actual_mech));
559 maj_stat = gss_krb5_free_lucid_sec_context(&maj_stat, ctx);
560 if (maj_stat != GSS_S_COMPLETE)
561 errx(1, "gss_krb5_free_lucid_sec_context failed: %s",
562 gssapi_err(maj_stat, min_stat, actual_mech));
564 /* server */
565 maj_stat = gss_krb5_export_lucid_sec_context(&min_stat,
566 &sctx,
567 1, /* version */
568 &ctx);
569 if (maj_stat != GSS_S_COMPLETE)
570 errx(1, "gss_krb5_export_lucid_sec_context failed: %s",
571 gssapi_err(maj_stat, min_stat, actual_mech));
572 maj_stat = gss_krb5_free_lucid_sec_context(&min_stat, ctx);
573 if (maj_stat != GSS_S_COMPLETE)
574 errx(1, "gss_krb5_free_lucid_sec_context failed: %s",
575 gssapi_err(maj_stat, min_stat, actual_mech));
577 maj_stat = gsskrb5_extract_authtime_from_sec_context(&min_stat,
578 sctx,
579 &time);
580 if (maj_stat != GSS_S_COMPLETE)
581 errx(1, "gsskrb5_extract_authtime_from_sec_context failed: %s",
582 gssapi_err(maj_stat, min_stat, actual_mech));
584 if (time > now)
585 errx(1, "gsskrb5_extract_authtime_from_sec_context failed: "
586 "time authtime is before now: %ld %ld",
587 (long)time, (long)now);
589 maj_stat = gsskrb5_extract_service_keyblock(&min_stat,
590 sctx,
591 &keyblock);
592 if (maj_stat != GSS_S_COMPLETE)
593 errx(1, "gsskrb5_export_service_keyblock failed: %s",
594 gssapi_err(maj_stat, min_stat, actual_mech));
596 krb5_free_keyblock(context, keyblock);
598 maj_stat = gsskrb5_get_subkey(&min_stat,
599 sctx,
600 &keyblock);
601 if (maj_stat != GSS_S_COMPLETE
602 && (!(maj_stat == GSS_S_FAILURE && min_stat == GSS_KRB5_S_KG_NO_SUBKEY)))
603 errx(1, "gsskrb5_get_subkey server failed: %s",
604 gssapi_err(maj_stat, min_stat, actual_mech));
606 if (maj_stat != GSS_S_COMPLETE)
607 keyblock = NULL;
609 maj_stat = gsskrb5_get_subkey(&min_stat,
610 cctx,
611 &keyblock2);
612 if (maj_stat != GSS_S_COMPLETE
613 && (!(maj_stat == GSS_S_FAILURE && min_stat == GSS_KRB5_S_KG_NO_SUBKEY)))
614 errx(1, "gsskrb5_get_subkey client failed: %s",
615 gssapi_err(maj_stat, min_stat, actual_mech));
617 if (maj_stat != GSS_S_COMPLETE)
618 keyblock2 = NULL;
620 if (keyblock || keyblock2) {
621 if (keyblock == NULL)
622 errx(1, "server missing token keyblock");
623 if (keyblock2 == NULL)
624 errx(1, "client missing token keyblock");
626 if (keyblock->keytype != keyblock2->keytype)
627 errx(1, "enctype mismatch");
628 if (keyblock->keyvalue.length != keyblock2->keyvalue.length)
629 errx(1, "key length mismatch");
630 if (memcmp(keyblock->keyvalue.data, keyblock2->keyvalue.data,
631 keyblock2->keyvalue.length) != 0)
632 errx(1, "key data mismatch");
635 if (session_enctype_string) {
636 krb5_enctype enctype;
638 ret = krb5_string_to_enctype(context,
639 session_enctype_string,
640 &enctype);
642 if (ret)
643 krb5_err(context, 1, ret, "krb5_string_to_enctype");
645 if (enctype != keyblock->keytype)
646 errx(1, "keytype is not the expected %d != %d",
647 (int)enctype, (int)keyblock2->keytype);
650 if (keyblock)
651 krb5_free_keyblock(context, keyblock);
652 if (keyblock2)
653 krb5_free_keyblock(context, keyblock2);
655 maj_stat = gsskrb5_get_initiator_subkey(&min_stat,
656 sctx,
657 &keyblock);
658 if (maj_stat != GSS_S_COMPLETE
659 && (!(maj_stat == GSS_S_FAILURE && min_stat == GSS_KRB5_S_KG_NO_SUBKEY)))
660 errx(1, "gsskrb5_get_initiator_subkey failed: %s",
661 gssapi_err(maj_stat, min_stat, actual_mech));
663 if (maj_stat == GSS_S_COMPLETE)
664 krb5_free_keyblock(context, keyblock);
666 maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat,
667 sctx,
668 128,
669 &authz_data);
670 if (maj_stat == GSS_S_COMPLETE)
671 gss_release_buffer(&min_stat, &authz_data);
673 krb5_free_context(context);
676 memset(&out1, 0, sizeof(out1));
677 memset(&out2, 0, sizeof(out2));
679 in.value = "foo";
680 in.length = 3;
682 gss_pseudo_random(&min_stat, sctx, GSS_C_PRF_KEY_FULL, &in,
683 100, &out1);
684 gss_pseudo_random(&min_stat, cctx, GSS_C_PRF_KEY_FULL, &in,
685 100, &out2);
687 if (out1.length != out2.length)
688 errx(1, "prf len mismatch");
689 if (memcmp(out1.value, out2.value, out1.length) != 0)
690 errx(1, "prf data mismatch");
692 gss_release_buffer(&min_stat, &out1);
694 gss_pseudo_random(&min_stat, sctx, GSS_C_PRF_KEY_FULL, &in,
695 100, &out1);
697 if (out1.length != out2.length)
698 errx(1, "prf len mismatch");
699 if (memcmp(out1.value, out2.value, out1.length) != 0)
700 errx(1, "prf data mismatch");
702 gss_release_buffer(&min_stat, &out1);
703 gss_release_buffer(&min_stat, &out2);
705 in.value = "bar";
706 in.length = 3;
708 gss_pseudo_random(&min_stat, sctx, GSS_C_PRF_KEY_PARTIAL, &in,
709 100, &out1);
710 gss_pseudo_random(&min_stat, cctx, GSS_C_PRF_KEY_PARTIAL, &in,
711 100, &out2);
713 if (out1.length != out2.length)
714 errx(1, "prf len mismatch");
715 if (memcmp(out1.value, out2.value, out1.length) != 0)
716 errx(1, "prf data mismatch");
718 gss_release_buffer(&min_stat, &out1);
719 gss_release_buffer(&min_stat, &out2);
721 wrapunwrap_flag = 1;
722 getverifymic_flag = 1;
725 if (wrapunwrap_flag) {
726 wrapunwrap(cctx, sctx, 0, actual_mech);
727 wrapunwrap(cctx, sctx, 1, actual_mech);
728 wrapunwrap(sctx, cctx, 0, actual_mech);
729 wrapunwrap(sctx, cctx, 1, actual_mech);
732 if (iov_flag) {
733 wrapunwrap_iov(cctx, sctx, 0, actual_mech);
734 wrapunwrap_iov(cctx, sctx, USE_CONF, actual_mech);
735 wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY, actual_mech);
737 wrapunwrap_iov(cctx, sctx, FORCE_IOV, actual_mech);
738 wrapunwrap_iov(cctx, sctx, USE_CONF|FORCE_IOV, actual_mech);
739 wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY|FORCE_IOV, actual_mech);
741 wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY|USE_SIGN_ONLY, actual_mech);
744 if (getverifymic_flag) {
745 getverifymic(cctx, sctx, actual_mech);
746 getverifymic(cctx, sctx, actual_mech);
747 getverifymic(sctx, cctx, actual_mech);
748 getverifymic(sctx, cctx, actual_mech);
752 gss_delete_sec_context(&min_stat, &cctx, NULL);
753 gss_delete_sec_context(&min_stat, &sctx, NULL);
755 if (deleg_cred != GSS_C_NO_CREDENTIAL) {
756 gss_cred_id_t deleg_cred2 = GSS_C_NO_CREDENTIAL;
758 loop(mechoid, nameoid, argv[0], deleg_cred, &cctx, &sctx, &actual_mech, &deleg_cred2);
760 gss_release_cred(&min_stat, &deleg_cred2);
762 gss_delete_sec_context(&min_stat, &cctx, NULL);
763 gss_delete_sec_context(&min_stat, &sctx, NULL);
767 empty_release();
769 return 0;