Path: blob/main/crypto/krb5/src/tests/gssapi/t_iov.c
34914 views
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1/* tests/gssapi/t_iov.c - Test program for IOV functions */2/*3* Copyright (C) 2013 by the Massachusetts Institute of Technology.4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9*10* * Redistributions of source code must retain the above copyright11* notice, this list of conditions and the following disclaimer.12*13* * Redistributions in binary form must reproduce the above copyright14* notice, this list of conditions and the following disclaimer in15* the documentation and/or other materials provided with the16* distribution.17*18* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS19* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT20* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS21* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE22* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,23* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES24* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR25* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)26* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,27* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)28* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED29* OF THE POSSIBILITY OF SUCH DAMAGE.30*/3132#include <stdio.h>33#include <stdlib.h>34#include <string.h>35#include <stddef.h>36#include "common.h"3738/* Concatenate iov (except for sign-only buffers) into a contiguous token. */39static void40concat_iov(gss_iov_buffer_desc *iov, size_t iovlen, char **buf_out,41size_t *len_out)42{43size_t len, i;44char *buf;4546/* Concatenate the result into a contiguous buffer. */47len = 0;48for (i = 0; i < iovlen; i++) {49if (GSS_IOV_BUFFER_TYPE(iov[i].type) != GSS_IOV_BUFFER_TYPE_SIGN_ONLY)50len += iov[i].buffer.length;51}52buf = malloc(len);53if (buf == NULL)54errout("malloc failed");55len = 0;56for (i = 0; i < iovlen; i++) {57if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_SIGN_ONLY)58continue;59memcpy(buf + len, iov[i].buffer.value, iov[i].buffer.length);60len += iov[i].buffer.length;61}62*buf_out = buf;63*len_out = len;64}6566static void67check_encrypted(const char *msg, int conf, const char *buf, const char *plain)68{69int same = memcmp(buf, plain, strlen(plain)) == 0;7071if ((conf && same) || (!conf && !same))72errout(msg);73}7475/*76* Wrap str in standard form (HEADER | DATA | PADDING | TRAILER) using the77* caller-provided array iov, which must have space for four elements. Library78* allocation will be used for the header/padding/trailer buffers, so the79* caller must check and free them.80*/81static void82wrap_std(gss_ctx_id_t ctx, char *str, gss_iov_buffer_desc *iov, int conf)83{84OM_uint32 minor, major;85int oconf;8687/* Lay out iov array. */88iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_FLAG_ALLOCATE;89iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;90iov[1].buffer.value = str;91iov[1].buffer.length = strlen(str);92iov[2].type = GSS_IOV_BUFFER_TYPE_PADDING | GSS_IOV_BUFFER_FLAG_ALLOCATE;93iov[3].type = GSS_IOV_BUFFER_TYPE_TRAILER | GSS_IOV_BUFFER_FLAG_ALLOCATE;9495/* Wrap. This will allocate header/padding/trailer buffers as necessary96* and encrypt str in place. */97major = gss_wrap_iov(&minor, ctx, conf, GSS_C_QOP_DEFAULT, &oconf, iov, 4);98check_gsserr("gss_wrap_iov(std)", major, minor);99if (oconf != conf)100errout("gss_wrap_iov(std) conf");101}102103/* Create standard tokens using gss_wrap_iov and ctx1, and make sure we can104* unwrap them using ctx2 in all of the supported ways. */105static void106test_standard_wrap(gss_ctx_id_t ctx1, gss_ctx_id_t ctx2, int conf)107{108OM_uint32 major, minor;109gss_iov_buffer_desc iov[4], stiov[2];110gss_qop_t qop;111gss_buffer_desc input, output;112const char *string1 = "The swift brown fox jumped over the lazy dog.";113const char *string2 = "Now is the time!";114const char *string3 = "x";115const char *string4 = "!@#";116char data[1024], *fulltoken;117size_t len;118int oconf;119ptrdiff_t offset;120121/* Wrap a standard token and unwrap it using the iov array. */122memcpy(data, string1, strlen(string1) + 1);123wrap_std(ctx1, data, iov, conf);124check_encrypted("gss_wrap_iov(std1) encryption", conf, data, string1);125major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, iov, 4);126check_gsserr("gss_unwrap_iov(std1)", major, minor);127if (oconf != conf || qop != GSS_C_QOP_DEFAULT)128errout("gss_unwrap_iov(std1) conf/qop");129if (iov[1].buffer.value != data || iov[1].buffer.length != strlen(string1))130errout("gss_unwrap_iov(std1) data buffer");131if (memcmp(data, string1, iov[1].buffer.length) != 0)132errout("gss_unwrap_iov(std1) decryption");133(void)gss_release_iov_buffer(&minor, iov, 4);134135/* Wrap a standard token and unwrap it using gss_unwrap(). */136memcpy(data, string2, strlen(string2) + 1);137wrap_std(ctx1, data, iov, conf);138concat_iov(iov, 4, &fulltoken, &len);139input.value = fulltoken;140input.length = len;141major = gss_unwrap(&minor, ctx2, &input, &output, &oconf, &qop);142check_gsserr("gss_unwrap(std2)", major, minor);143if (oconf != conf || qop != GSS_C_QOP_DEFAULT)144errout("gss_unwrap(std2) conf/qop");145if (output.length != strlen(string2) ||146memcmp(output.value, string2, output.length) != 0)147errout("gss_unwrap(std2) decryption");148(void)gss_release_buffer(&minor, &output);149(void)gss_release_iov_buffer(&minor, iov, 4);150free(fulltoken);151152/* Wrap a standard token and unwrap it using a stream buffer. */153memcpy(data, string3, strlen(string3) + 1);154wrap_std(ctx1, data, iov, conf);155concat_iov(iov, 4, &fulltoken, &len);156stiov[0].type = GSS_IOV_BUFFER_TYPE_STREAM;157stiov[0].buffer.value = fulltoken;158stiov[0].buffer.length = len;159stiov[1].type = GSS_IOV_BUFFER_TYPE_DATA;160major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, stiov, 2);161check_gsserr("gss_unwrap_iov(std3)", major, minor);162if (oconf != conf || qop != GSS_C_QOP_DEFAULT)163errout("gss_unwrap_iov(std3) conf/qop");164if (stiov[1].buffer.length != strlen(string3) ||165memcmp(stiov[1].buffer.value, string3, strlen(string3)) != 0)166errout("gss_unwrap_iov(std3) decryption");167offset = (char *)stiov[1].buffer.value - fulltoken;168if (offset < 0 || (size_t)offset > len)169errout("gss_unwrap_iov(std3) offset");170(void)gss_release_iov_buffer(&minor, iov, 4);171free(fulltoken);172173/* Wrap a token using gss_wrap and unwrap it using a stream buffer with174* allocation and copying. */175input.value = (char *)string4;176input.length = strlen(string4);177major = gss_wrap(&minor, ctx1, conf, GSS_C_QOP_DEFAULT, &input, &oconf,178&output);179check_gsserr("gss_wrap(std4)", major, minor);180if (oconf != conf)181errout("gss_wrap(std4) conf");182stiov[0].type = GSS_IOV_BUFFER_TYPE_STREAM;183stiov[0].buffer = output;184stiov[1].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE;185major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, stiov, 2);186check_gsserr("gss_unwrap_iov(std4)", major, minor);187if (!(GSS_IOV_BUFFER_FLAGS(stiov[1].type) & GSS_IOV_BUFFER_FLAG_ALLOCATED))188errout("gss_unwrap_iov(std4) allocated");189if (oconf != conf || qop != GSS_C_QOP_DEFAULT)190errout("gss_unwrap_iov(std4) conf/qop");191if (stiov[1].buffer.length != strlen(string4) ||192memcmp(stiov[1].buffer.value, string4, strlen(string4)) != 0)193errout("gss_unwrap_iov(std4) decryption");194(void)gss_release_buffer(&minor, &output);195(void)gss_release_iov_buffer(&minor, stiov, 2);196}197198/*199* Wrap an AEAD token (HEADER | SIGN_ONLY | DATA | PADDING | TRAILER) using the200* caller-provided array iov, which must have space for five elements, and the201* caller-provided buffer data, which must be big enough to handle the test202* inputs. Library allocation will not be used.203*/204static void205wrap_aead(gss_ctx_id_t ctx, const char *sign, const char *wrap,206gss_iov_buffer_desc *iov, char *data, int conf)207{208OM_uint32 major, minor;209int oconf;210char *ptr;211212/* Lay out iov array. */213iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER;214iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;215iov[1].buffer.value = (char *)sign;216iov[1].buffer.length = strlen(sign);217iov[2].type = GSS_IOV_BUFFER_TYPE_DATA;218iov[2].buffer.value = (char *)wrap;219iov[2].buffer.length = strlen(wrap);220iov[3].type = GSS_IOV_BUFFER_TYPE_PADDING;221iov[4].type = GSS_IOV_BUFFER_TYPE_TRAILER;222223/* Get header/padding/trailer lengths. */224major = gss_wrap_iov_length(&minor, ctx, conf, GSS_C_QOP_DEFAULT, &oconf,225iov, 5);226check_gsserr("gss_wrap_iov_length(aead)", major, minor);227if (oconf != conf)228errout("gss_wrap_iov_length(aead) conf");229if (iov[1].buffer.value != sign || iov[1].buffer.length != strlen(sign))230errout("gss_wrap_iov_length(aead) sign-only buffer");231if (iov[2].buffer.value != wrap || iov[2].buffer.length != strlen(wrap))232errout("gss_wrap_iov_length(aead) data buffer");233234/* Set iov buffer pointers using returned lengths. */235iov[0].buffer.value = data;236ptr = data + iov[0].buffer.length;237memcpy(ptr, wrap, strlen(wrap));238iov[2].buffer.value = ptr;239ptr += iov[2].buffer.length;240iov[3].buffer.value = ptr;241ptr += iov[3].buffer.length;242iov[4].buffer.value = ptr;243244/* Wrap the AEAD token. */245major = gss_wrap_iov(&minor, ctx, conf, GSS_C_QOP_DEFAULT, &oconf, iov, 5);246check_gsserr("gss_wrap_iov(aead)", major, minor);247if (oconf != conf)248errout("gss_wrap_iov(aead) conf");249if (iov[1].buffer.value != sign || iov[1].buffer.length != strlen(sign))250errout("gss_wrap_iov(aead) sign-only buffer");251if (iov[2].buffer.length != strlen(wrap))252errout("gss_wrap_iov(aead) data buffer");253check_encrypted("gss_wrap_iov(aead) encryption", conf, iov[2].buffer.value,254wrap);255}256257/* Create AEAD tokens using gss_wrap_iov and ctx1, and make sure we can unwrap258* them using ctx2 in all of the supported ways. */259static void260test_aead(gss_ctx_id_t ctx1, gss_ctx_id_t ctx2, int conf)261{262OM_uint32 major, minor;263gss_iov_buffer_desc iov[5], stiov[3];264gss_qop_t qop;265gss_buffer_desc input, assoc, output;266const char *sign = "This data is only signed.";267const char *wrap = "This data is wrapped in-place.";268char data[1024], *fulltoken;269size_t len;270int oconf;271ptrdiff_t offset;272273/* Wrap an AEAD token and unwrap it using the IOV array. */274wrap_aead(ctx1, sign, wrap, iov, data, conf);275major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, iov, 5);276check_gsserr("gss_unwrap_iov(aead1)", major, minor);277if (oconf != conf || qop != GSS_C_QOP_DEFAULT)278errout("gss_unwrap_iov(aead1) conf/qop");279if (iov[1].buffer.value != sign || iov[1].buffer.length != strlen(sign))280errout("gss_unwrap_iov(aead1) sign-only buffer");281if (iov[2].buffer.length != strlen(wrap) ||282memcmp(iov[2].buffer.value, wrap, iov[2].buffer.length) != 0)283errout("gss_unwrap_iov(aead1) decryption");284285/* Wrap an AEAD token and unwrap it using gss_unwrap_aead. */286wrap_aead(ctx1, sign, wrap, iov, data, conf);287concat_iov(iov, 5, &fulltoken, &len);288input.value = fulltoken;289input.length = len;290assoc.value = (char *)sign;291assoc.length = strlen(sign);292major = gss_unwrap_aead(&minor, ctx2, &input, &assoc, &output, &oconf,293&qop);294check_gsserr("gss_unwrap_aead(aead2)", major, minor);295if (output.length != strlen(wrap) ||296memcmp(output.value, wrap, output.length) != 0)297errout("gss_unwrap_aead(aead2) decryption");298free(fulltoken);299(void)gss_release_buffer(&minor, &output);300301/* Wrap an AEAD token and unwrap it using a stream buffer. */302wrap_aead(ctx1, sign, wrap, iov, data, conf);303concat_iov(iov, 5, &fulltoken, &len);304stiov[0].type = GSS_IOV_BUFFER_TYPE_STREAM;305stiov[0].buffer.value = fulltoken;306stiov[0].buffer.length = len;307stiov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;308stiov[1].buffer.value = (char *)sign;309stiov[1].buffer.length = strlen(sign);310stiov[2].type = GSS_IOV_BUFFER_TYPE_DATA;311major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, stiov, 3);312check_gsserr("gss_unwrap_iov(aead3)", major, minor);313if (oconf != conf || qop != GSS_C_QOP_DEFAULT)314errout("gss_unwrap_iov(aead3) conf/qop");315if (stiov[2].buffer.length != strlen(wrap) ||316memcmp(stiov[2].buffer.value, wrap, strlen(wrap)) != 0)317errout("gss_unwrap_iov(aead3) decryption");318offset = (char *)stiov[2].buffer.value - fulltoken;319if (offset < 0 || (size_t)offset > len)320errout("gss_unwrap_iov(aead3) offset");321free(fulltoken);322(void)gss_release_iov_buffer(&minor, iov, 4);323324/* Wrap a token using gss_wrap_aead and unwrap it using a stream buffer325* with allocation and copying. */326input.value = (char *)wrap;327input.length = strlen(wrap);328assoc.value = (char *)sign;329assoc.length = strlen(sign);330major = gss_wrap_aead(&minor, ctx1, conf, GSS_C_QOP_DEFAULT, &assoc,331&input, &oconf, &output);332check_gsserr("gss_wrap_aead(aead4)", major, minor);333if (oconf != conf)334errout("gss_wrap(aead4) conf");335stiov[0].type = GSS_IOV_BUFFER_TYPE_STREAM;336stiov[0].buffer = output;337stiov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;338stiov[1].buffer = assoc;339stiov[2].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE;340major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, stiov, 3);341check_gsserr("gss_unwrap_iov(aead4)", major, minor);342if (!(GSS_IOV_BUFFER_FLAGS(stiov[2].type) & GSS_IOV_BUFFER_FLAG_ALLOCATED))343errout("gss_unwrap_iov(aead4) allocated");344if (oconf != conf || qop != GSS_C_QOP_DEFAULT)345errout("gss_unwrap_iov(aead4) conf/qop");346if (stiov[2].buffer.length != strlen(wrap) ||347memcmp(stiov[2].buffer.value, wrap, strlen(wrap)) != 0)348errout("gss_unwrap_iov(aead4) decryption");349(void)gss_release_buffer(&minor, &output);350(void)gss_release_iov_buffer(&minor, stiov, 3);351}352353/*354* Get a MIC for sign1, sign2, and sign3 using the caller-provided array iov,355* which must have space for four elements, and the caller-provided buffer356* data, which must be big enough for the MIC. If data is NULL, the library357* will be asked to allocate the MIC buffer. The MIC will be located in358* iov[3].buffer.359*/360static void361mic(gss_ctx_id_t ctx, const char *sign1, const char *sign2, const char *sign3,362gss_iov_buffer_desc *iov, char *data)363{364OM_uint32 minor, major;365krb5_boolean allocated;366367/* Lay out iov array. */368iov[0].type = GSS_IOV_BUFFER_TYPE_DATA;369iov[0].buffer.value = (char *)sign1;370iov[0].buffer.length = strlen(sign1);371iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;372iov[1].buffer.value = (char *)sign2;373iov[1].buffer.length = strlen(sign2);374iov[2].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;375iov[2].buffer.value = (char *)sign3;376iov[2].buffer.length = strlen(sign3);377iov[3].type = GSS_IOV_BUFFER_TYPE_MIC_TOKEN;378if (data == NULL) {379/* Ask the library to allocate the MIC buffer. */380iov[3].type |= GSS_IOV_BUFFER_FLAG_ALLOCATE;381} else {382/* Get the MIC length and use the caller-provided buffer. */383major = gss_get_mic_iov_length(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 4);384check_gsserr("gss_get_mic_iov_length", major, minor);385iov[3].buffer.value = data;386}387major = gss_get_mic_iov(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 4);388check_gsserr("gss_get_mic_iov", major, minor);389allocated = (GSS_IOV_BUFFER_FLAGS(iov[3].type) &390GSS_IOV_BUFFER_FLAG_ALLOCATED) != 0;391if (allocated != (data == NULL))392errout("gss_get_mic_iov allocated");393}394395static void396test_mic(gss_ctx_id_t ctx1, gss_ctx_id_t ctx2)397{398OM_uint32 major, minor;399gss_iov_buffer_desc iov[4];400gss_qop_t qop;401gss_buffer_desc concatbuf, micbuf;402const char *sign1 = "Data and sign-only ";403const char *sign2 = "buffers are treated ";404const char *sign3 = "equally by gss_get_mic_iov";405char concat[1024], data[1024];406407(void)snprintf(concat, sizeof(concat), "%s%s%s", sign1, sign2, sign3);408concatbuf.value = concat;409concatbuf.length = strlen(concat);410411/* MIC with a caller-provided buffer and verify with the IOV array. */412mic(ctx1, sign1, sign2, sign3, iov, data);413major = gss_verify_mic_iov(&minor, ctx2, &qop, iov, 4);414check_gsserr("gss_verify_mic_iov(mic1)", major, minor);415if (qop != GSS_C_QOP_DEFAULT)416errout("gss_verify_mic_iov(mic1) qop");417418/* MIC with an allocated buffer and verify with gss_verify_mic. */419mic(ctx1, sign1, sign2, sign3, iov, NULL);420major = gss_verify_mic(&minor, ctx2, &concatbuf, &iov[3].buffer, &qop);421check_gsserr("gss_verify_mic(mic2)", major, minor);422if (qop != GSS_C_QOP_DEFAULT)423errout("gss_verify_mic(mic2) qop");424(void)gss_release_iov_buffer(&minor, iov, 4);425426/* MIC with gss_c_get_mic and verify using the IOV array (which is still427* mostly set up from the last call to mic(). */428major = gss_get_mic(&minor, ctx1, GSS_C_QOP_DEFAULT, &concatbuf, &micbuf);429check_gsserr("gss_get_mic(mic3)", major, minor);430iov[3].buffer = micbuf;431major = gss_verify_mic_iov(&minor, ctx2, &qop, iov, 4);432check_gsserr("gss_verify_mic_iov(mic3)", major, minor);433if (qop != GSS_C_QOP_DEFAULT)434errout("gss_verify_mic_iov(mic3) qop");435(void)gss_release_buffer(&minor, &micbuf);436}437438/* Create a DCE-style token and make sure we can unwrap it. */439static void440test_dce(gss_ctx_id_t ctx1, gss_ctx_id_t ctx2, int conf)441{442OM_uint32 major, minor;443gss_iov_buffer_desc iov[4];444gss_qop_t qop;445const char *sign1 = "First data to be signed";446const char *sign2 = "Second data to be signed";447const char *wrap = "This data must align to 16 bytes";448int oconf;449char data[1024];450451/* Wrap a SIGN_ONLY_1 | DATA | SIGN_ONLY_2 | HEADER token. */452memcpy(data, wrap, strlen(wrap) + 1);453iov[0].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;454iov[0].buffer.value = (char *)sign1;455iov[0].buffer.length = strlen(sign1);456iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;457iov[1].buffer.value = data;458iov[1].buffer.length = strlen(wrap);459iov[2].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;460iov[2].buffer.value = (char *)sign2;461iov[2].buffer.length = strlen(sign2);462iov[3].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_FLAG_ALLOCATE;463major = gss_wrap_iov(&minor, ctx1, conf, GSS_C_QOP_DEFAULT, &oconf, iov,4644);465check_gsserr("gss_wrap_iov(dce)", major, minor);466if (oconf != conf)467errout("gss_wrap_iov(dce) conf");468if (iov[0].buffer.value != sign1 || iov[0].buffer.length != strlen(sign1))469errout("gss_wrap_iov(dce) sign1 buffer");470if (iov[1].buffer.value != data || iov[1].buffer.length != strlen(wrap))471errout("gss_wrap_iov(dce) data buffer");472if (iov[2].buffer.value != sign2 || iov[2].buffer.length != strlen(sign2))473errout("gss_wrap_iov(dce) sign2 buffer");474check_encrypted("gss_wrap_iov(dce) encryption", conf, data, wrap);475476/* Make sure we can unwrap it. */477major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, iov, 4);478check_gsserr("gss_unwrap_iov(std1)", major, minor);479if (oconf != conf || qop != GSS_C_QOP_DEFAULT)480errout("gss_unwrap_iov(std1) conf/qop");481if (iov[0].buffer.value != sign1 || iov[0].buffer.length != strlen(sign1))482errout("gss_unwrap_iov(dce) sign1 buffer");483if (iov[1].buffer.value != data || iov[1].buffer.length != strlen(wrap))484errout("gss_unwrap_iov(dce) data buffer");485if (iov[2].buffer.value != sign2 || iov[2].buffer.length != strlen(sign2))486errout("gss_unwrap_iov(dce) sign2 buffer");487if (memcmp(data, wrap, iov[1].buffer.length) != 0)488errout("gss_unwrap_iov(dce) decryption");489(void)gss_release_iov_buffer(&minor, iov, 4);490}491492int493main(int argc, char *argv[])494{495OM_uint32 minor, flags;496gss_OID mech = &mech_krb5;497gss_name_t tname;498gss_ctx_id_t ictx, actx;499500/* Parse arguments. */501argv++;502if (*argv != NULL && strcmp(*argv, "-s") == 0) {503mech = &mech_spnego;504argv++;505}506if (*argv == NULL || *(argv + 1) != NULL)507errout("Usage: t_iov [-s] targetname");508tname = import_name(*argv);509510flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_MUTUAL_FLAG;511establish_contexts(mech, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, tname,512flags, &ictx, &actx, NULL, NULL, NULL);513514/* Test standard token wrapping and unwrapping in both directions, with and515* without confidentiality. */516test_standard_wrap(ictx, actx, 0);517test_standard_wrap(ictx, actx, 1);518test_standard_wrap(actx, ictx, 0);519test_standard_wrap(actx, ictx, 1);520521/* Test AEAD wrapping. */522test_aead(ictx, actx, 0);523test_aead(ictx, actx, 1);524test_aead(actx, ictx, 0);525test_aead(actx, ictx, 1);526527/* Test MIC tokens. */528test_mic(ictx, actx);529test_mic(actx, ictx);530531/* Test DCE wrapping with DCE-style contexts. */532(void)gss_delete_sec_context(&minor, &ictx, NULL);533(void)gss_delete_sec_context(&minor, &actx, NULL);534flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_DCE_STYLE;535establish_contexts(mech, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, tname,536flags, &ictx, &actx, NULL, NULL, NULL);537test_dce(ictx, actx, 0);538test_dce(ictx, actx, 1);539test_dce(actx, ictx, 0);540test_dce(actx, ictx, 1);541542(void)gss_release_name(&minor, &tname);543(void)gss_delete_sec_context(&minor, &ictx, NULL);544(void)gss_delete_sec_context(&minor, &actx, NULL);545return 0;546}547548549