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