1b528cefcSMark Murray /* 2*ae771770SStanislav Sedov * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan 3b528cefcSMark Murray * (Royal Institute of Technology, Stockholm, Sweden). 4b528cefcSMark Murray * All rights reserved. 5b528cefcSMark Murray * 6b528cefcSMark Murray * Redistribution and use in source and binary forms, with or without 7b528cefcSMark Murray * modification, are permitted provided that the following conditions 8b528cefcSMark Murray * are met: 9b528cefcSMark Murray * 10b528cefcSMark Murray * 1. Redistributions of source code must retain the above copyright 11b528cefcSMark Murray * notice, this list of conditions and the following disclaimer. 12b528cefcSMark Murray * 13b528cefcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright 14b528cefcSMark Murray * notice, this list of conditions and the following disclaimer in the 15b528cefcSMark Murray * documentation and/or other materials provided with the distribution. 16b528cefcSMark Murray * 17b528cefcSMark Murray * 3. Neither the name of the Institute nor the names of its contributors 18b528cefcSMark Murray * may be used to endorse or promote products derived from this software 19b528cefcSMark Murray * without specific prior written permission. 20b528cefcSMark Murray * 21b528cefcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22b528cefcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23b528cefcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24b528cefcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25b528cefcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26b528cefcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27b528cefcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28b528cefcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29b528cefcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30b528cefcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31b528cefcSMark Murray * SUCH DAMAGE. 32b528cefcSMark Murray */ 33b528cefcSMark Murray 34*ae771770SStanislav Sedov #include "krb5_locl.h" 35b528cefcSMark Murray 36c19800e8SDoug Rabson static krb5_error_code 37c19800e8SDoug Rabson make_etypelist(krb5_context context, 38c19800e8SDoug Rabson krb5_authdata **auth_data) 39c19800e8SDoug Rabson { 40c19800e8SDoug Rabson EtypeList etypes; 41c19800e8SDoug Rabson krb5_error_code ret; 42c19800e8SDoug Rabson krb5_authdata ad; 43c19800e8SDoug Rabson u_char *buf; 44*ae771770SStanislav Sedov size_t len = 0; 45c19800e8SDoug Rabson size_t buf_size; 46c19800e8SDoug Rabson 47*ae771770SStanislav Sedov ret = _krb5_init_etype(context, KRB5_PDU_NONE, 48*ae771770SStanislav Sedov &etypes.len, &etypes.val, 49*ae771770SStanislav Sedov NULL); 50c19800e8SDoug Rabson if (ret) 51c19800e8SDoug Rabson return ret; 52c19800e8SDoug Rabson 53c19800e8SDoug Rabson ASN1_MALLOC_ENCODE(EtypeList, buf, buf_size, &etypes, &len, ret); 54c19800e8SDoug Rabson if (ret) { 55c19800e8SDoug Rabson free_EtypeList(&etypes); 56c19800e8SDoug Rabson return ret; 57c19800e8SDoug Rabson } 58c19800e8SDoug Rabson if(buf_size != len) 59c19800e8SDoug Rabson krb5_abortx(context, "internal error in ASN.1 encoder"); 60c19800e8SDoug Rabson free_EtypeList(&etypes); 61c19800e8SDoug Rabson 62c19800e8SDoug Rabson ALLOC_SEQ(&ad, 1); 63c19800e8SDoug Rabson if (ad.val == NULL) { 64c19800e8SDoug Rabson free(buf); 65*ae771770SStanislav Sedov krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); 66c19800e8SDoug Rabson return ENOMEM; 67c19800e8SDoug Rabson } 68c19800e8SDoug Rabson 69c19800e8SDoug Rabson ad.val[0].ad_type = KRB5_AUTHDATA_GSS_API_ETYPE_NEGOTIATION; 70c19800e8SDoug Rabson ad.val[0].ad_data.length = len; 71c19800e8SDoug Rabson ad.val[0].ad_data.data = buf; 72c19800e8SDoug Rabson 73c19800e8SDoug Rabson ASN1_MALLOC_ENCODE(AD_IF_RELEVANT, buf, buf_size, &ad, &len, ret); 74c19800e8SDoug Rabson if (ret) { 75c19800e8SDoug Rabson free_AuthorizationData(&ad); 76c19800e8SDoug Rabson return ret; 77c19800e8SDoug Rabson } 78c19800e8SDoug Rabson if(buf_size != len) 79c19800e8SDoug Rabson krb5_abortx(context, "internal error in ASN.1 encoder"); 80c19800e8SDoug Rabson free_AuthorizationData(&ad); 81c19800e8SDoug Rabson 82c19800e8SDoug Rabson ALLOC(*auth_data, 1); 83c19800e8SDoug Rabson if (*auth_data == NULL) { 84*ae771770SStanislav Sedov free(buf); 85*ae771770SStanislav Sedov krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); 86c19800e8SDoug Rabson return ENOMEM; 87c19800e8SDoug Rabson } 88c19800e8SDoug Rabson 89c19800e8SDoug Rabson ALLOC_SEQ(*auth_data, 1); 90c19800e8SDoug Rabson if ((*auth_data)->val == NULL) { 91*ae771770SStanislav Sedov free(*auth_data); 92c19800e8SDoug Rabson free(buf); 93*ae771770SStanislav Sedov krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); 94c19800e8SDoug Rabson return ENOMEM; 95c19800e8SDoug Rabson } 96c19800e8SDoug Rabson 97c19800e8SDoug Rabson (*auth_data)->val[0].ad_type = KRB5_AUTHDATA_IF_RELEVANT; 98c19800e8SDoug Rabson (*auth_data)->val[0].ad_data.length = len; 99c19800e8SDoug Rabson (*auth_data)->val[0].ad_data.data = buf; 100c19800e8SDoug Rabson 101c19800e8SDoug Rabson return 0; 102c19800e8SDoug Rabson } 103c19800e8SDoug Rabson 104*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 105*ae771770SStanislav Sedov _krb5_build_authenticator (krb5_context context, 106b528cefcSMark Murray krb5_auth_context auth_context, 107b528cefcSMark Murray krb5_enctype enctype, 108b528cefcSMark Murray krb5_creds *cred, 109b528cefcSMark Murray Checksum *cksum, 1105e9cd1aeSAssar Westerlund krb5_data *result, 1115e9cd1aeSAssar Westerlund krb5_key_usage usage) 112b528cefcSMark Murray { 113*ae771770SStanislav Sedov Authenticator auth; 114b528cefcSMark Murray u_char *buf = NULL; 115b528cefcSMark Murray size_t buf_size; 116*ae771770SStanislav Sedov size_t len = 0; 117b528cefcSMark Murray krb5_error_code ret; 118b528cefcSMark Murray krb5_crypto crypto; 119b528cefcSMark Murray 120*ae771770SStanislav Sedov memset(&auth, 0, sizeof(auth)); 121b528cefcSMark Murray 122*ae771770SStanislav Sedov auth.authenticator_vno = 5; 123*ae771770SStanislav Sedov copy_Realm(&cred->client->realm, &auth.crealm); 124*ae771770SStanislav Sedov copy_PrincipalName(&cred->client->name, &auth.cname); 125b528cefcSMark Murray 126*ae771770SStanislav Sedov krb5_us_timeofday (context, &auth.ctime, &auth.cusec); 127b528cefcSMark Murray 128*ae771770SStanislav Sedov ret = krb5_auth_con_getlocalsubkey(context, auth_context, &auth.subkey); 129b528cefcSMark Murray if(ret) 130b528cefcSMark Murray goto fail; 131b528cefcSMark Murray 132b528cefcSMark Murray if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) { 133c19800e8SDoug Rabson if(auth_context->local_seqnumber == 0) 134b528cefcSMark Murray krb5_generate_seq_number (context, 135b528cefcSMark Murray &cred->session, 136b528cefcSMark Murray &auth_context->local_seqnumber); 137*ae771770SStanislav Sedov ALLOC(auth.seq_number, 1); 138*ae771770SStanislav Sedov if(auth.seq_number == NULL) { 139c19800e8SDoug Rabson ret = ENOMEM; 140c19800e8SDoug Rabson goto fail; 141c19800e8SDoug Rabson } 142*ae771770SStanislav Sedov *auth.seq_number = auth_context->local_seqnumber; 143b528cefcSMark Murray } else 144*ae771770SStanislav Sedov auth.seq_number = NULL; 145*ae771770SStanislav Sedov auth.authorization_data = NULL; 146b528cefcSMark Murray 147*ae771770SStanislav Sedov if (cksum) { 148*ae771770SStanislav Sedov ALLOC(auth.cksum, 1); 149*ae771770SStanislav Sedov if (auth.cksum == NULL) { 150*ae771770SStanislav Sedov ret = ENOMEM; 151*ae771770SStanislav Sedov goto fail; 152*ae771770SStanislav Sedov } 153*ae771770SStanislav Sedov ret = copy_Checksum(cksum, auth.cksum); 154*ae771770SStanislav Sedov if (ret) 155*ae771770SStanislav Sedov goto fail; 156*ae771770SStanislav Sedov 157*ae771770SStanislav Sedov if (auth.cksum->cksumtype == CKSUMTYPE_GSSAPI) { 158c19800e8SDoug Rabson /* 159c19800e8SDoug Rabson * This is not GSS-API specific, we only enable it for 160c19800e8SDoug Rabson * GSS for now 161c19800e8SDoug Rabson */ 162*ae771770SStanislav Sedov ret = make_etypelist(context, &auth.authorization_data); 1630cadf2f4SJacques Vidrine if (ret) 164b528cefcSMark Murray goto fail; 165c19800e8SDoug Rabson } 166*ae771770SStanislav Sedov } 167c19800e8SDoug Rabson 168c19800e8SDoug Rabson /* XXX - Copy more to auth_context? */ 169c19800e8SDoug Rabson 170*ae771770SStanislav Sedov auth_context->authenticator->ctime = auth.ctime; 171*ae771770SStanislav Sedov auth_context->authenticator->cusec = auth.cusec; 172c19800e8SDoug Rabson 173*ae771770SStanislav Sedov ASN1_MALLOC_ENCODE(Authenticator, buf, buf_size, &auth, &len, ret); 174c19800e8SDoug Rabson if (ret) 175c19800e8SDoug Rabson goto fail; 176c19800e8SDoug Rabson if(buf_size != len) 177c19800e8SDoug Rabson krb5_abortx(context, "internal error in ASN.1 encoder"); 178b528cefcSMark Murray 179b528cefcSMark Murray ret = krb5_crypto_init(context, &cred->session, enctype, &crypto); 1805e9cd1aeSAssar Westerlund if (ret) 1815e9cd1aeSAssar Westerlund goto fail; 182b528cefcSMark Murray ret = krb5_encrypt (context, 183b528cefcSMark Murray crypto, 1845e9cd1aeSAssar Westerlund usage /* KRB5_KU_AP_REQ_AUTH */, 185*ae771770SStanislav Sedov buf, 186b528cefcSMark Murray len, 187b528cefcSMark Murray result); 188b528cefcSMark Murray krb5_crypto_destroy(context, crypto); 189b528cefcSMark Murray 190b528cefcSMark Murray if (ret) 191b528cefcSMark Murray goto fail; 192b528cefcSMark Murray 193*ae771770SStanislav Sedov fail: 194*ae771770SStanislav Sedov free_Authenticator (&auth); 195b528cefcSMark Murray free (buf); 196b528cefcSMark Murray 197b528cefcSMark Murray return ret; 198b528cefcSMark Murray } 199