Home | History | Annotate | Line # | Download | only in krb5
build_auth.c revision 1.1.1.1.12.1
      1 /*	$NetBSD: build_auth.c,v 1.1.1.1.12.1 2017/08/30 06:54:30 snj 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     copy_Realm(&cred->client->realm, &auth.crealm);
    123     copy_PrincipalName(&cred->client->name, &auth.cname);
    124 
    125     krb5_us_timeofday (context, &auth.ctime, &auth.cusec);
    126 
    127     ret = krb5_auth_con_getlocalsubkey(context, auth_context, &auth.subkey);
    128     if(ret)
    129 	goto fail;
    130 
    131     if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
    132 	if(auth_context->local_seqnumber == 0)
    133 	    krb5_generate_seq_number (context,
    134 				      &cred->session,
    135 				      &auth_context->local_seqnumber);
    136 	ALLOC(auth.seq_number, 1);
    137 	if(auth.seq_number == NULL) {
    138 	    ret = krb5_enomem(context);
    139 	    goto fail;
    140 	}
    141 	*auth.seq_number = auth_context->local_seqnumber;
    142     } else
    143 	auth.seq_number = NULL;
    144     auth.authorization_data = NULL;
    145 
    146     if (cksum) {
    147 	ALLOC(auth.cksum, 1);
    148 	if (auth.cksum == NULL) {
    149 	    ret = krb5_enomem(context);
    150 	    goto fail;
    151 	}
    152 	ret = copy_Checksum(cksum, auth.cksum);
    153 	if (ret)
    154 	    goto fail;
    155 
    156 	if (auth.cksum->cksumtype == CKSUMTYPE_GSSAPI) {
    157 	    /*
    158 	     * This is not GSS-API specific, we only enable it for
    159 	     * GSS for now
    160 	     */
    161 	    ret = make_etypelist(context, &auth.authorization_data);
    162 	    if (ret)
    163 		goto fail;
    164 	}
    165     }
    166 
    167     /* XXX - Copy more to auth_context? */
    168 
    169     auth_context->authenticator->ctime = auth.ctime;
    170     auth_context->authenticator->cusec = auth.cusec;
    171 
    172     ASN1_MALLOC_ENCODE(Authenticator, buf, buf_size, &auth, &len, ret);
    173     if (ret)
    174 	goto fail;
    175     if(buf_size != len)
    176 	krb5_abortx(context, "internal error in ASN.1 encoder");
    177 
    178     ret = krb5_crypto_init(context, &cred->session, enctype, &crypto);
    179     if (ret)
    180 	goto fail;
    181     ret = krb5_encrypt (context,
    182 			crypto,
    183 			usage /* KRB5_KU_AP_REQ_AUTH */,
    184 			buf,
    185 			len,
    186 			result);
    187     krb5_crypto_destroy(context, crypto);
    188 
    189     if (ret)
    190 	goto fail;
    191 
    192  fail:
    193     free_Authenticator (&auth);
    194     free (buf);
    195 
    196     return ret;
    197 }
    198