155682Smarkm/* 2233294Sstas * Copyright (c) 1997 - 2003 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 555682Smarkm * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 955682Smarkm * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 1655682Smarkm * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 2055682Smarkm * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 34233294Sstas#include "krb5_locl.h" 3555682Smarkm 36178825Sdfrstatic krb5_error_code 37178825Sdfrmake_etypelist(krb5_context context, 38178825Sdfr krb5_authdata **auth_data) 39178825Sdfr{ 40178825Sdfr EtypeList etypes; 41178825Sdfr krb5_error_code ret; 42178825Sdfr krb5_authdata ad; 43178825Sdfr u_char *buf; 44233294Sstas size_t len = 0; 45178825Sdfr size_t buf_size; 46233294Sstas 47233294Sstas ret = _krb5_init_etype(context, KRB5_PDU_NONE, 48233294Sstas &etypes.len, &etypes.val, 49233294Sstas NULL); 50178825Sdfr if (ret) 51178825Sdfr return ret; 52178825Sdfr 53178825Sdfr ASN1_MALLOC_ENCODE(EtypeList, buf, buf_size, &etypes, &len, ret); 54178825Sdfr if (ret) { 55178825Sdfr free_EtypeList(&etypes); 56178825Sdfr return ret; 57178825Sdfr } 58178825Sdfr if(buf_size != len) 59178825Sdfr krb5_abortx(context, "internal error in ASN.1 encoder"); 60178825Sdfr free_EtypeList(&etypes); 61178825Sdfr 62178825Sdfr ALLOC_SEQ(&ad, 1); 63178825Sdfr if (ad.val == NULL) { 64178825Sdfr free(buf); 65233294Sstas krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); 66178825Sdfr return ENOMEM; 67178825Sdfr } 68178825Sdfr 69178825Sdfr ad.val[0].ad_type = KRB5_AUTHDATA_GSS_API_ETYPE_NEGOTIATION; 70178825Sdfr ad.val[0].ad_data.length = len; 71178825Sdfr ad.val[0].ad_data.data = buf; 72178825Sdfr 73178825Sdfr ASN1_MALLOC_ENCODE(AD_IF_RELEVANT, buf, buf_size, &ad, &len, ret); 74178825Sdfr if (ret) { 75178825Sdfr free_AuthorizationData(&ad); 76178825Sdfr return ret; 77233294Sstas } 78178825Sdfr if(buf_size != len) 79178825Sdfr krb5_abortx(context, "internal error in ASN.1 encoder"); 80178825Sdfr free_AuthorizationData(&ad); 81178825Sdfr 82178825Sdfr ALLOC(*auth_data, 1); 83178825Sdfr if (*auth_data == NULL) { 84233294Sstas free(buf); 85233294Sstas krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); 86178825Sdfr return ENOMEM; 87178825Sdfr } 88178825Sdfr 89178825Sdfr ALLOC_SEQ(*auth_data, 1); 90178825Sdfr if ((*auth_data)->val == NULL) { 91233294Sstas free(*auth_data); 92178825Sdfr free(buf); 93233294Sstas krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); 94178825Sdfr return ENOMEM; 95178825Sdfr } 96178825Sdfr 97178825Sdfr (*auth_data)->val[0].ad_type = KRB5_AUTHDATA_IF_RELEVANT; 98178825Sdfr (*auth_data)->val[0].ad_data.length = len; 99178825Sdfr (*auth_data)->val[0].ad_data.data = buf; 100178825Sdfr 101178825Sdfr return 0; 102178825Sdfr} 103178825Sdfr 104233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 105233294Sstas_krb5_build_authenticator (krb5_context context, 106233294Sstas krb5_auth_context auth_context, 107233294Sstas krb5_enctype enctype, 108233294Sstas krb5_creds *cred, 109233294Sstas Checksum *cksum, 110233294Sstas krb5_data *result, 111233294Sstas krb5_key_usage usage) 11255682Smarkm{ 113233294Sstas Authenticator auth; 114178825Sdfr u_char *buf = NULL; 115178825Sdfr size_t buf_size; 116233294Sstas size_t len = 0; 117178825Sdfr krb5_error_code ret; 118178825Sdfr krb5_crypto crypto; 11955682Smarkm 120233294Sstas memset(&auth, 0, sizeof(auth)); 12155682Smarkm 122233294Sstas auth.authenticator_vno = 5; 123233294Sstas copy_Realm(&cred->client->realm, &auth.crealm); 124233294Sstas copy_PrincipalName(&cred->client->name, &auth.cname); 12555682Smarkm 126233294Sstas krb5_us_timeofday (context, &auth.ctime, &auth.cusec); 127233294Sstas 128233294Sstas ret = krb5_auth_con_getlocalsubkey(context, auth_context, &auth.subkey); 129178825Sdfr if(ret) 130178825Sdfr goto fail; 13155682Smarkm 132178825Sdfr if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) { 133178825Sdfr if(auth_context->local_seqnumber == 0) 134178825Sdfr krb5_generate_seq_number (context, 135233294Sstas &cred->session, 136178825Sdfr &auth_context->local_seqnumber); 137233294Sstas ALLOC(auth.seq_number, 1); 138233294Sstas if(auth.seq_number == NULL) { 139178825Sdfr ret = ENOMEM; 140178825Sdfr goto fail; 141178825Sdfr } 142233294Sstas *auth.seq_number = auth_context->local_seqnumber; 143178825Sdfr } else 144233294Sstas auth.seq_number = NULL; 145233294Sstas auth.authorization_data = NULL; 14655682Smarkm 147233294Sstas if (cksum) { 148233294Sstas ALLOC(auth.cksum, 1); 149233294Sstas if (auth.cksum == NULL) { 150233294Sstas ret = ENOMEM; 151233294Sstas goto fail; 152233294Sstas } 153233294Sstas ret = copy_Checksum(cksum, auth.cksum); 154178825Sdfr if (ret) 155178825Sdfr goto fail; 156233294Sstas 157233294Sstas if (auth.cksum->cksumtype == CKSUMTYPE_GSSAPI) { 158233294Sstas /* 159233294Sstas * This is not GSS-API specific, we only enable it for 160233294Sstas * GSS for now 161233294Sstas */ 162233294Sstas ret = make_etypelist(context, &auth.authorization_data); 163233294Sstas if (ret) 164233294Sstas goto fail; 165233294Sstas } 166178825Sdfr } 16755682Smarkm 168178825Sdfr /* XXX - Copy more to auth_context? */ 16955682Smarkm 170233294Sstas auth_context->authenticator->ctime = auth.ctime; 171233294Sstas auth_context->authenticator->cusec = auth.cusec; 17255682Smarkm 173233294Sstas ASN1_MALLOC_ENCODE(Authenticator, buf, buf_size, &auth, &len, ret); 174178825Sdfr if (ret) 175178825Sdfr goto fail; 176178825Sdfr if(buf_size != len) 177178825Sdfr krb5_abortx(context, "internal error in ASN.1 encoder"); 178103423Snectar 179178825Sdfr ret = krb5_crypto_init(context, &cred->session, enctype, &crypto); 180178825Sdfr if (ret) 181178825Sdfr goto fail; 182178825Sdfr ret = krb5_encrypt (context, 183178825Sdfr crypto, 184178825Sdfr usage /* KRB5_KU_AP_REQ_AUTH */, 185233294Sstas buf, 186178825Sdfr len, 187178825Sdfr result); 188178825Sdfr krb5_crypto_destroy(context, crypto); 18955682Smarkm 190178825Sdfr if (ret) 191178825Sdfr goto fail; 19255682Smarkm 193233294Sstas fail: 194233294Sstas free_Authenticator (&auth); 195178825Sdfr free (buf); 19655682Smarkm 197178825Sdfr return ret; 19855682Smarkm} 199