inquire_sec_context_by_oid.c revision 256281
1230557Sjimharris/* 2230557Sjimharris * Copyright (c) 2004, PADL Software Pty Ltd. 3230557Sjimharris * All rights reserved. 4230557Sjimharris * 5230557Sjimharris * Redistribution and use in source and binary forms, with or without 6230557Sjimharris * modification, are permitted provided that the following conditions 7230557Sjimharris * are met: 8230557Sjimharris * 9230557Sjimharris * 1. Redistributions of source code must retain the above copyright 10230557Sjimharris * notice, this list of conditions and the following disclaimer. 11230557Sjimharris * 12230557Sjimharris * 2. Redistributions in binary form must reproduce the above copyright 13230557Sjimharris * notice, this list of conditions and the following disclaimer in the 14230557Sjimharris * documentation and/or other materials provided with the distribution. 15230557Sjimharris * 16230557Sjimharris * 3. Neither the name of PADL Software nor the names of its contributors 17230557Sjimharris * may be used to endorse or promote products derived from this software 18230557Sjimharris * without specific prior written permission. 19230557Sjimharris * 20230557Sjimharris * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND 21230557Sjimharris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22230557Sjimharris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23230557Sjimharris * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE 24230557Sjimharris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25230557Sjimharris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26230557Sjimharris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27230557Sjimharris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28230557Sjimharris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29230557Sjimharris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30230557Sjimharris * SUCH DAMAGE. 31230557Sjimharris */ 32230557Sjimharris 33230557Sjimharris#include "gsskrb5_locl.h" 34230557Sjimharris 35230557Sjimharrisstatic int 36230557Sjimharrisoid_prefix_equal(gss_OID oid_enc, gss_OID prefix_enc, unsigned *suffix) 37230557Sjimharris{ 38230557Sjimharris int ret; 39230557Sjimharris heim_oid oid; 40230557Sjimharris heim_oid prefix; 41230557Sjimharris 42230557Sjimharris *suffix = 0; 43230557Sjimharris 44230557Sjimharris ret = der_get_oid(oid_enc->elements, oid_enc->length, 45230557Sjimharris &oid, NULL); 46230557Sjimharris if (ret) { 47230557Sjimharris return 0; 48230557Sjimharris } 49230557Sjimharris 50230557Sjimharris ret = der_get_oid(prefix_enc->elements, prefix_enc->length, 51230557Sjimharris &prefix, NULL); 52230557Sjimharris if (ret) { 53230557Sjimharris der_free_oid(&oid); 54230557Sjimharris return 0; 55230557Sjimharris } 56230557Sjimharris 57230557Sjimharris ret = 0; 58230557Sjimharris 59230557Sjimharris if (oid.length - 1 == prefix.length) { 60230557Sjimharris *suffix = oid.components[oid.length - 1]; 61230557Sjimharris oid.length--; 62230557Sjimharris ret = (der_heim_oid_cmp(&oid, &prefix) == 0); 63230557Sjimharris oid.length++; 64230557Sjimharris } 65230557Sjimharris 66230557Sjimharris der_free_oid(&oid); 67230557Sjimharris der_free_oid(&prefix); 68230557Sjimharris 69230557Sjimharris return ret; 70230557Sjimharris} 71230557Sjimharris 72230557Sjimharrisstatic OM_uint32 inquire_sec_context_tkt_flags 73230557Sjimharris (OM_uint32 *minor_status, 74230557Sjimharris const gsskrb5_ctx context_handle, 75230557Sjimharris gss_buffer_set_t *data_set) 76230557Sjimharris{ 77230557Sjimharris OM_uint32 tkt_flags; 78230557Sjimharris unsigned char buf[4]; 79230557Sjimharris gss_buffer_desc value; 80230557Sjimharris 81230557Sjimharris HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); 82230557Sjimharris 83230557Sjimharris if (context_handle->ticket == NULL) { 84230557Sjimharris HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 85230557Sjimharris _gsskrb5_set_status(EINVAL, "No ticket from which to obtain flags"); 86230557Sjimharris *minor_status = EINVAL; 87230557Sjimharris return GSS_S_BAD_MECH; 88230557Sjimharris } 89230557Sjimharris 90230557Sjimharris tkt_flags = TicketFlags2int(context_handle->ticket->ticket.flags); 91230557Sjimharris HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 92230557Sjimharris 93230557Sjimharris _gsskrb5_encode_om_uint32(tkt_flags, buf); 94230557Sjimharris value.length = sizeof(buf); 95230557Sjimharris value.value = buf; 96230557Sjimharris 97230557Sjimharris return gss_add_buffer_set_member(minor_status, 98230557Sjimharris &value, 99230557Sjimharris data_set); 100230557Sjimharris} 101230557Sjimharris 102230557Sjimharrisenum keytype { ACCEPTOR_KEY, INITIATOR_KEY, TOKEN_KEY }; 103230557Sjimharris 104230557Sjimharrisstatic OM_uint32 inquire_sec_context_get_subkey 105230557Sjimharris (OM_uint32 *minor_status, 106230557Sjimharris const gsskrb5_ctx context_handle, 107230557Sjimharris krb5_context context, 108230557Sjimharris enum keytype keytype, 109230557Sjimharris gss_buffer_set_t *data_set) 110230557Sjimharris{ 111230557Sjimharris krb5_keyblock *key = NULL; 112230557Sjimharris krb5_storage *sp = NULL; 113230557Sjimharris krb5_data data; 114230557Sjimharris OM_uint32 maj_stat = GSS_S_COMPLETE; 115230557Sjimharris krb5_error_code ret; 116230557Sjimharris 117230557Sjimharris krb5_data_zero(&data); 118230557Sjimharris 119230557Sjimharris sp = krb5_storage_emem(); 120230557Sjimharris if (sp == NULL) { 121230557Sjimharris _gsskrb5_clear_status(); 122230557Sjimharris ret = ENOMEM; 123230557Sjimharris goto out; 124230557Sjimharris } 125230557Sjimharris 126230557Sjimharris HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); 127230557Sjimharris switch(keytype) { 128230557Sjimharris case ACCEPTOR_KEY: 129230557Sjimharris ret = _gsskrb5i_get_acceptor_subkey(context_handle, context, &key); 130230557Sjimharris break; 131230557Sjimharris case INITIATOR_KEY: 132230557Sjimharris ret = _gsskrb5i_get_initiator_subkey(context_handle, context, &key); 133230557Sjimharris break; 134230557Sjimharris case TOKEN_KEY: 135230557Sjimharris ret = _gsskrb5i_get_token_key(context_handle, context, &key); 136230557Sjimharris break; 137230557Sjimharris default: 138230557Sjimharris _gsskrb5_set_status(EINVAL, "%d is not a valid subkey type", keytype); 139230557Sjimharris ret = EINVAL; 140230557Sjimharris break; 141230557Sjimharris } 142230557Sjimharris HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 143230557Sjimharris if (ret) 144230557Sjimharris goto out; 145230557Sjimharris if (key == NULL) { 146230557Sjimharris _gsskrb5_set_status(EINVAL, "have no subkey of type %d", keytype); 147230557Sjimharris ret = EINVAL; 148230557Sjimharris goto out; 149230557Sjimharris } 150230557Sjimharris 151230557Sjimharris ret = krb5_store_keyblock(sp, *key); 152230557Sjimharris krb5_free_keyblock (context, key); 153230557Sjimharris if (ret) 154230557Sjimharris goto out; 155230557Sjimharris 156230557Sjimharris ret = krb5_storage_to_data(sp, &data); 157230557Sjimharris if (ret) 158230557Sjimharris goto out; 159230557Sjimharris 160230557Sjimharris { 161230557Sjimharris gss_buffer_desc value; 162230557Sjimharris 163230557Sjimharris value.length = data.length; 164230557Sjimharris value.value = data.data; 165230557Sjimharris 166230557Sjimharris maj_stat = gss_add_buffer_set_member(minor_status, 167230557Sjimharris &value, 168230557Sjimharris data_set); 169230557Sjimharris } 170230557Sjimharris 171230557Sjimharrisout: 172230557Sjimharris krb5_data_free(&data); 173230557Sjimharris if (sp) 174230557Sjimharris krb5_storage_free(sp); 175230557Sjimharris if (ret) { 176230557Sjimharris *minor_status = ret; 177230557Sjimharris maj_stat = GSS_S_FAILURE; 178230557Sjimharris } 179230557Sjimharris return maj_stat; 180230557Sjimharris} 181230557Sjimharris 182230557Sjimharrisstatic OM_uint32 inquire_sec_context_get_sspi_session_key 183230557Sjimharris (OM_uint32 *minor_status, 184230557Sjimharris const gsskrb5_ctx context_handle, 185230557Sjimharris krb5_context context, 186230557Sjimharris gss_buffer_set_t *data_set) 187230557Sjimharris{ 188230557Sjimharris krb5_keyblock *key; 189230557Sjimharris OM_uint32 maj_stat = GSS_S_COMPLETE; 190230557Sjimharris krb5_error_code ret; 191230557Sjimharris gss_buffer_desc value; 192230557Sjimharris 193230557Sjimharris HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); 194230557Sjimharris ret = _gsskrb5i_get_token_key(context_handle, context, &key); 195230557Sjimharris HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 196230557Sjimharris 197230557Sjimharris if (ret) 198230557Sjimharris goto out; 199230557Sjimharris if (key == NULL) { 200230557Sjimharris ret = EINVAL; 201230557Sjimharris goto out; 202230557Sjimharris } 203230557Sjimharris 204230557Sjimharris value.length = key->keyvalue.length; 205230557Sjimharris value.value = key->keyvalue.data; 206230557Sjimharris 207230557Sjimharris maj_stat = gss_add_buffer_set_member(minor_status, 208230557Sjimharris &value, 209230557Sjimharris data_set); 210230557Sjimharris krb5_free_keyblock(context, key); 211230557Sjimharris 212230557Sjimharris /* MIT also returns the enctype encoded as an OID in data_set[1] */ 213230557Sjimharris 214230557Sjimharrisout: 215230557Sjimharris if (ret) { 216230557Sjimharris *minor_status = ret; 217230557Sjimharris maj_stat = GSS_S_FAILURE; 218230557Sjimharris } 219230557Sjimharris return maj_stat; 220230557Sjimharris} 221230557Sjimharris 222230557Sjimharrisstatic OM_uint32 inquire_sec_context_authz_data 223230557Sjimharris (OM_uint32 *minor_status, 224230557Sjimharris const gsskrb5_ctx context_handle, 225230557Sjimharris krb5_context context, 226230557Sjimharris unsigned ad_type, 227230557Sjimharris gss_buffer_set_t *data_set) 228230557Sjimharris{ 229230557Sjimharris krb5_data data; 230230557Sjimharris gss_buffer_desc ad_data; 231230557Sjimharris OM_uint32 ret; 232230557Sjimharris 233230557Sjimharris *minor_status = 0; 234230557Sjimharris *data_set = GSS_C_NO_BUFFER_SET; 235230557Sjimharris 236230557Sjimharris HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); 237230557Sjimharris if (context_handle->ticket == NULL) { 238230557Sjimharris HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 239230557Sjimharris *minor_status = EINVAL; 240230557Sjimharris _gsskrb5_set_status(EINVAL, "No ticket to obtain authz data from"); 241230557Sjimharris return GSS_S_NO_CONTEXT; 242230557Sjimharris } 243230557Sjimharris 244230557Sjimharris ret = krb5_ticket_get_authorization_data_type(context, 245230557Sjimharris context_handle->ticket, 246230557Sjimharris ad_type, 247230557Sjimharris &data); 248230557Sjimharris HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 249230557Sjimharris if (ret) { 250230557Sjimharris *minor_status = ret; 251230557Sjimharris return GSS_S_FAILURE; 252230557Sjimharris } 253230557Sjimharris 254230557Sjimharris ad_data.value = data.data; 255230557Sjimharris ad_data.length = data.length; 256230557Sjimharris 257230557Sjimharris ret = gss_add_buffer_set_member(minor_status, 258230557Sjimharris &ad_data, 259230557Sjimharris data_set); 260230557Sjimharris 261230557Sjimharris krb5_data_free(&data); 262230557Sjimharris 263230557Sjimharris return ret; 264230557Sjimharris} 265230557Sjimharris 266230557Sjimharrisstatic OM_uint32 inquire_sec_context_has_updated_spnego 267230557Sjimharris (OM_uint32 *minor_status, 268230557Sjimharris const gsskrb5_ctx context_handle, 269230557Sjimharris gss_buffer_set_t *data_set) 270230557Sjimharris{ 271230557Sjimharris int is_updated = 0; 272230557Sjimharris 273230557Sjimharris *minor_status = 0; 274230557Sjimharris *data_set = GSS_C_NO_BUFFER_SET; 275230557Sjimharris 276230557Sjimharris /* 277230557Sjimharris * For Windows SPNEGO implementations, both the initiator and the 278230557Sjimharris * acceptor are assumed to have been updated if a "newer" [CLAR] or 279230557Sjimharris * different enctype is negotiated for use by the Kerberos GSS-API 280230557Sjimharris * mechanism. 281230557Sjimharris */ 282230557Sjimharris HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); 283230557Sjimharris is_updated = (context_handle->more_flags & IS_CFX); 284230557Sjimharris if (is_updated == 0) { 285230557Sjimharris krb5_keyblock *acceptor_subkey; 286230557Sjimharris 287230557Sjimharris if (context_handle->more_flags & LOCAL) 288230557Sjimharris acceptor_subkey = context_handle->auth_context->remote_subkey; 289230557Sjimharris else 290230557Sjimharris acceptor_subkey = context_handle->auth_context->local_subkey; 291230557Sjimharris 292230557Sjimharris if (acceptor_subkey != NULL) 293230557Sjimharris is_updated = (acceptor_subkey->keytype != 294230557Sjimharris context_handle->auth_context->keyblock->keytype); 295230557Sjimharris } 296230557Sjimharris HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 297230557Sjimharris 298230557Sjimharris return is_updated ? GSS_S_COMPLETE : GSS_S_FAILURE; 299230557Sjimharris} 300230557Sjimharris 301230557Sjimharris/* 302230557Sjimharris * 303230557Sjimharris */ 304230557Sjimharris 305230557Sjimharrisstatic OM_uint32 306230557Sjimharrisexport_lucid_sec_context_v1(OM_uint32 *minor_status, 307230557Sjimharris gsskrb5_ctx context_handle, 308230557Sjimharris krb5_context context, 309230557Sjimharris gss_buffer_set_t *data_set) 310230557Sjimharris{ 311230557Sjimharris krb5_storage *sp = NULL; 312230557Sjimharris OM_uint32 major_status = GSS_S_COMPLETE; 313230557Sjimharris krb5_error_code ret; 314230557Sjimharris krb5_keyblock *key = NULL; 315230557Sjimharris int32_t number; 316230557Sjimharris int is_cfx; 317230557Sjimharris krb5_data data; 318230557Sjimharris 319230557Sjimharris *minor_status = 0; 320230557Sjimharris 321230557Sjimharris HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); 322230557Sjimharris 323230557Sjimharris is_cfx = (context_handle->more_flags & IS_CFX); 324230557Sjimharris 325230557Sjimharris sp = krb5_storage_emem(); 326230557Sjimharris if (sp == NULL) { 327230557Sjimharris _gsskrb5_clear_status(); 328230557Sjimharris ret = ENOMEM; 329230557Sjimharris goto out; 330230557Sjimharris } 331230557Sjimharris 332230557Sjimharris ret = krb5_store_int32(sp, 1); 333230557Sjimharris if (ret) goto out; 334230557Sjimharris ret = krb5_store_int32(sp, (context_handle->more_flags & LOCAL) ? 1 : 0); 335230557Sjimharris if (ret) goto out; 336230557Sjimharris ret = krb5_store_int32(sp, context_handle->lifetime); 337230557Sjimharris if (ret) goto out; 338230557Sjimharris krb5_auth_con_getlocalseqnumber (context, 339230557Sjimharris context_handle->auth_context, 340230557Sjimharris &number); 341230557Sjimharris ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */ 342230557Sjimharris if (ret) goto out; 343230557Sjimharris ret = krb5_store_uint32(sp, (uint32_t)number); 344230557Sjimharris if (ret) goto out; 345230557Sjimharris krb5_auth_con_getremoteseqnumber (context, 346230557Sjimharris context_handle->auth_context, 347230557Sjimharris &number); 348230557Sjimharris ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */ 349230557Sjimharris if (ret) goto out; 350230557Sjimharris ret = krb5_store_uint32(sp, (uint32_t)number); 351230557Sjimharris if (ret) goto out; 352230557Sjimharris ret = krb5_store_int32(sp, (is_cfx) ? 1 : 0); 353230557Sjimharris if (ret) goto out; 354230557Sjimharris 355230557Sjimharris ret = _gsskrb5i_get_token_key(context_handle, context, &key); 356230557Sjimharris if (ret) goto out; 357230557Sjimharris 358230557Sjimharris if (is_cfx == 0) { 359230557Sjimharris int sign_alg, seal_alg; 360230557Sjimharris 361230557Sjimharris switch (key->keytype) { 362230557Sjimharris case ETYPE_DES_CBC_CRC: 363230557Sjimharris case ETYPE_DES_CBC_MD4: 364230557Sjimharris case ETYPE_DES_CBC_MD5: 365230557Sjimharris sign_alg = 0; 366230557Sjimharris seal_alg = 0; 367230557Sjimharris break; 368230557Sjimharris case ETYPE_DES3_CBC_MD5: 369230557Sjimharris case ETYPE_DES3_CBC_SHA1: 370230557Sjimharris sign_alg = 4; 371230557Sjimharris seal_alg = 2; 372230557Sjimharris break; 373230557Sjimharris case ETYPE_ARCFOUR_HMAC_MD5: 374230557Sjimharris case ETYPE_ARCFOUR_HMAC_MD5_56: 375230557Sjimharris sign_alg = 17; 376230557Sjimharris seal_alg = 16; 377230557Sjimharris break; 378230557Sjimharris default: 379230557Sjimharris sign_alg = -1; 380230557Sjimharris seal_alg = -1; 381230557Sjimharris break; 382230557Sjimharris } 383230557Sjimharris ret = krb5_store_int32(sp, sign_alg); 384230557Sjimharris if (ret) goto out; 385230557Sjimharris ret = krb5_store_int32(sp, seal_alg); 386230557Sjimharris if (ret) goto out; 387230557Sjimharris /* ctx_key */ 388230557Sjimharris ret = krb5_store_keyblock(sp, *key); 389230557Sjimharris if (ret) goto out; 390230557Sjimharris } else { 391230557Sjimharris int subkey_p = (context_handle->more_flags & ACCEPTOR_SUBKEY) ? 1 : 0; 392230557Sjimharris 393230557Sjimharris /* have_acceptor_subkey */ 394230557Sjimharris ret = krb5_store_int32(sp, subkey_p); 395230557Sjimharris if (ret) goto out; 396230557Sjimharris /* ctx_key */ 397230557Sjimharris ret = krb5_store_keyblock(sp, *key); 398230557Sjimharris if (ret) goto out; 399230557Sjimharris /* acceptor_subkey */ 400230557Sjimharris if (subkey_p) { 401230557Sjimharris ret = krb5_store_keyblock(sp, *key); 402230557Sjimharris if (ret) goto out; 403230557Sjimharris } 404230557Sjimharris } 405230557Sjimharris ret = krb5_storage_to_data(sp, &data); 406230557Sjimharris if (ret) goto out; 407230557Sjimharris 408230557Sjimharris { 409230557Sjimharris gss_buffer_desc ad_data; 410230557Sjimharris 411230557Sjimharris ad_data.value = data.data; 412230557Sjimharris ad_data.length = data.length; 413230557Sjimharris 414230557Sjimharris ret = gss_add_buffer_set_member(minor_status, &ad_data, data_set); 415230557Sjimharris krb5_data_free(&data); 416230557Sjimharris if (ret) 417230557Sjimharris goto out; 418230557Sjimharris } 419230557Sjimharris 420230557Sjimharrisout: 421230557Sjimharris if (key) 422230557Sjimharris krb5_free_keyblock (context, key); 423230557Sjimharris if (sp) 424230557Sjimharris krb5_storage_free(sp); 425230557Sjimharris if (ret) { 426230557Sjimharris *minor_status = ret; 427230557Sjimharris major_status = GSS_S_FAILURE; 428230557Sjimharris } 429230557Sjimharris HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); 430230557Sjimharris return major_status; 431230557Sjimharris} 432230557Sjimharris 433230557Sjimharrisstatic OM_uint32 434230557Sjimharrisget_authtime(OM_uint32 *minor_status, 435230557Sjimharris gsskrb5_ctx ctx, 436230557Sjimharris gss_buffer_set_t *data_set) 437230557Sjimharris 438230557Sjimharris{ 439230557Sjimharris gss_buffer_desc value; 440230557Sjimharris unsigned char buf[4]; 441230557Sjimharris OM_uint32 authtime; 442230557Sjimharris 443230557Sjimharris HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); 444230557Sjimharris if (ctx->ticket == NULL) { 445230557Sjimharris HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 446230557Sjimharris _gsskrb5_set_status(EINVAL, "No ticket to obtain auth time from"); 447230557Sjimharris *minor_status = EINVAL; 448230557Sjimharris return GSS_S_FAILURE; 449230557Sjimharris } 450230557Sjimharris 451230557Sjimharris authtime = ctx->ticket->ticket.authtime; 452230557Sjimharris 453230557Sjimharris HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 454230557Sjimharris 455230557Sjimharris _gsskrb5_encode_om_uint32(authtime, buf); 456230557Sjimharris value.length = sizeof(buf); 457230557Sjimharris value.value = buf; 458230557Sjimharris 459230557Sjimharris return gss_add_buffer_set_member(minor_status, 460230557Sjimharris &value, 461230557Sjimharris data_set); 462230557Sjimharris} 463230557Sjimharris 464230557Sjimharris 465230557Sjimharrisstatic OM_uint32 466230557Sjimharrisget_service_keyblock 467230557Sjimharris (OM_uint32 *minor_status, 468230557Sjimharris gsskrb5_ctx ctx, 469230557Sjimharris gss_buffer_set_t *data_set) 470230557Sjimharris{ 471230557Sjimharris krb5_storage *sp = NULL; 472230557Sjimharris krb5_data data; 473230557Sjimharris OM_uint32 maj_stat = GSS_S_COMPLETE; 474230557Sjimharris krb5_error_code ret = EINVAL; 475230557Sjimharris 476230557Sjimharris sp = krb5_storage_emem(); 477230557Sjimharris if (sp == NULL) { 478230557Sjimharris _gsskrb5_clear_status(); 479230557Sjimharris *minor_status = ENOMEM; 480230557Sjimharris return GSS_S_FAILURE; 481230557Sjimharris } 482230557Sjimharris 483230557Sjimharris HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); 484230557Sjimharris if (ctx->service_keyblock == NULL) { 485230557Sjimharris HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 486230557Sjimharris krb5_storage_free(sp); 487230557Sjimharris _gsskrb5_set_status(EINVAL, "No service keyblock on gssapi context"); 488230557Sjimharris *minor_status = EINVAL; 489230557Sjimharris return GSS_S_FAILURE; 490230557Sjimharris } 491230557Sjimharris 492230557Sjimharris krb5_data_zero(&data); 493230557Sjimharris 494230557Sjimharris ret = krb5_store_keyblock(sp, *ctx->service_keyblock); 495230557Sjimharris 496230557Sjimharris HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 497230557Sjimharris 498230557Sjimharris if (ret) 499230557Sjimharris goto out; 500230557Sjimharris 501230557Sjimharris ret = krb5_storage_to_data(sp, &data); 502230557Sjimharris if (ret) 503230557Sjimharris goto out; 504230557Sjimharris 505230557Sjimharris { 506230557Sjimharris gss_buffer_desc value; 507230557Sjimharris 508230557Sjimharris value.length = data.length; 509230557Sjimharris value.value = data.data; 510230557Sjimharris 511230557Sjimharris maj_stat = gss_add_buffer_set_member(minor_status, 512230557Sjimharris &value, 513230557Sjimharris data_set); 514230557Sjimharris } 515230557Sjimharris 516230557Sjimharrisout: 517230557Sjimharris krb5_data_free(&data); 518230557Sjimharris if (sp) 519230557Sjimharris krb5_storage_free(sp); 520230557Sjimharris if (ret) { 521230557Sjimharris *minor_status = ret; 522230557Sjimharris maj_stat = GSS_S_FAILURE; 523230557Sjimharris } 524230557Sjimharris return maj_stat; 525230557Sjimharris} 526230557Sjimharris/* 527230557Sjimharris * 528230557Sjimharris */ 529230557Sjimharris 530230557SjimharrisOM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_sec_context_by_oid 531230557Sjimharris (OM_uint32 *minor_status, 532230557Sjimharris const gss_ctx_id_t context_handle, 533230557Sjimharris const gss_OID desired_object, 534230557Sjimharris gss_buffer_set_t *data_set) 535230557Sjimharris{ 536230557Sjimharris krb5_context context; 537230557Sjimharris const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; 538230557Sjimharris unsigned suffix; 539230557Sjimharris 540230557Sjimharris if (ctx == NULL) { 541 *minor_status = EINVAL; 542 return GSS_S_NO_CONTEXT; 543 } 544 545 GSSAPI_KRB5_INIT (&context); 546 547 if (gss_oid_equal(desired_object, GSS_KRB5_GET_TKT_FLAGS_X)) { 548 return inquire_sec_context_tkt_flags(minor_status, 549 ctx, 550 data_set); 551 } else if (gss_oid_equal(desired_object, GSS_C_PEER_HAS_UPDATED_SPNEGO)) { 552 return inquire_sec_context_has_updated_spnego(minor_status, 553 ctx, 554 data_set); 555 } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_SUBKEY_X)) { 556 return inquire_sec_context_get_subkey(minor_status, 557 ctx, 558 context, 559 TOKEN_KEY, 560 data_set); 561 } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_INITIATOR_SUBKEY_X)) { 562 return inquire_sec_context_get_subkey(minor_status, 563 ctx, 564 context, 565 INITIATOR_KEY, 566 data_set); 567 } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_ACCEPTOR_SUBKEY_X)) { 568 return inquire_sec_context_get_subkey(minor_status, 569 ctx, 570 context, 571 ACCEPTOR_KEY, 572 data_set); 573 } else if (gss_oid_equal(desired_object, GSS_C_INQ_SSPI_SESSION_KEY)) { 574 return inquire_sec_context_get_sspi_session_key(minor_status, 575 ctx, 576 context, 577 data_set); 578 } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_AUTHTIME_X)) { 579 return get_authtime(minor_status, ctx, data_set); 580 } else if (oid_prefix_equal(desired_object, 581 GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X, 582 &suffix)) { 583 return inquire_sec_context_authz_data(minor_status, 584 ctx, 585 context, 586 suffix, 587 data_set); 588 } else if (oid_prefix_equal(desired_object, 589 GSS_KRB5_EXPORT_LUCID_CONTEXT_X, 590 &suffix)) { 591 if (suffix == 1) 592 return export_lucid_sec_context_v1(minor_status, 593 ctx, 594 context, 595 data_set); 596 *minor_status = 0; 597 return GSS_S_FAILURE; 598 } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_SERVICE_KEYBLOCK_X)) { 599 return get_service_keyblock(minor_status, ctx, data_set); 600 } else { 601 *minor_status = 0; 602 return GSS_S_FAILURE; 603 } 604} 605 606