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