Home | History | Annotate | Line # | Download | only in krb5
build_auth.c revision 1.1.1.1
      1 /*	$NetBSD: build_auth.c,v 1.1.1.1 2011/04/13 18:15:31 elric 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;
     47     size_t buf_size;
     48 
     49     ret = krb5_init_etype(context, &etypes.len, &etypes.val, NULL);
     50     if (ret)
     51 	return ret;
     52 
     53     ASN1_MALLOC_ENCODE(EtypeList, buf, buf_size, &etypes, &len, ret);
     54     if (ret) {
     55 	free_EtypeList(&etypes);
     56 	return ret;
     57     }
     58     if(buf_size != len)
     59 	krb5_abortx(context, "internal error in ASN.1 encoder");
     60     free_EtypeList(&etypes);
     61 
     62     ALLOC_SEQ(&ad, 1);
     63     if (ad.val == NULL) {
     64 	free(buf);
     65 	krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
     66 	return ENOMEM;
     67     }
     68 
     69     ad.val[0].ad_type = KRB5_AUTHDATA_GSS_API_ETYPE_NEGOTIATION;
     70     ad.val[0].ad_data.length = len;
     71     ad.val[0].ad_data.data = buf;
     72 
     73     ASN1_MALLOC_ENCODE(AD_IF_RELEVANT, buf, buf_size, &ad, &len, ret);
     74     if (ret) {
     75 	free_AuthorizationData(&ad);
     76 	return ret;
     77     }
     78     if(buf_size != len)
     79 	krb5_abortx(context, "internal error in ASN.1 encoder");
     80     free_AuthorizationData(&ad);
     81 
     82     ALLOC(*auth_data, 1);
     83     if (*auth_data == NULL) {
     84         free(buf);
     85 	krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
     86 	return ENOMEM;
     87     }
     88 
     89     ALLOC_SEQ(*auth_data, 1);
     90     if ((*auth_data)->val == NULL) {
     91         free(*auth_data);
     92 	free(buf);
     93 	krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
     94 	return ENOMEM;
     95     }
     96 
     97     (*auth_data)->val[0].ad_type = KRB5_AUTHDATA_IF_RELEVANT;
     98     (*auth_data)->val[0].ad_data.length = len;
     99     (*auth_data)->val[0].ad_data.data = buf;
    100 
    101     return 0;
    102 }
    103 
    104 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    105 _krb5_build_authenticator (krb5_context context,
    106 			   krb5_auth_context auth_context,
    107 			   krb5_enctype enctype,
    108 			   krb5_creds *cred,
    109 			   Checksum *cksum,
    110 			   krb5_data *result,
    111 			   krb5_key_usage usage)
    112 {
    113     Authenticator auth;
    114     u_char *buf = NULL;
    115     size_t buf_size;
    116     size_t len;
    117     krb5_error_code ret;
    118     krb5_crypto crypto;
    119 
    120     memset(&auth, 0, sizeof(auth));
    121 
    122     auth.authenticator_vno = 5;
    123     copy_Realm(&cred->client->realm, &auth.crealm);
    124     copy_PrincipalName(&cred->client->name, &auth.cname);
    125 
    126     krb5_us_timeofday (context, &auth.ctime, &auth.cusec);
    127 
    128     ret = krb5_auth_con_getlocalsubkey(context, auth_context, &auth.subkey);
    129     if(ret)
    130 	goto fail;
    131 
    132     if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
    133 	if(auth_context->local_seqnumber == 0)
    134 	    krb5_generate_seq_number (context,
    135 				      &cred->session,
    136 				      &auth_context->local_seqnumber);
    137 	ALLOC(auth.seq_number, 1);
    138 	if(auth.seq_number == NULL) {
    139 	    ret = ENOMEM;
    140 	    goto fail;
    141 	}
    142 	*auth.seq_number = auth_context->local_seqnumber;
    143     } else
    144 	auth.seq_number = NULL;
    145     auth.authorization_data = NULL;
    146 
    147     if (cksum) {
    148 	ALLOC(auth.cksum, 1);
    149 	if (auth.cksum == NULL) {
    150 	    ret = ENOMEM;
    151 	    goto fail;
    152 	}
    153 	ret = copy_Checksum(cksum, auth.cksum);
    154 	if (ret)
    155 	    goto fail;
    156 
    157 	if (auth.cksum->cksumtype == CKSUMTYPE_GSSAPI) {
    158 	    /*
    159 	     * This is not GSS-API specific, we only enable it for
    160 	     * GSS for now
    161 	     */
    162 	    ret = make_etypelist(context, &auth.authorization_data);
    163 	    if (ret)
    164 		goto fail;
    165 	}
    166     }
    167 
    168     /* XXX - Copy more to auth_context? */
    169 
    170     auth_context->authenticator->ctime = auth.ctime;
    171     auth_context->authenticator->cusec = auth.cusec;
    172 
    173     ASN1_MALLOC_ENCODE(Authenticator, buf, buf_size, &auth, &len, ret);
    174     if (ret)
    175 	goto fail;
    176     if(buf_size != len)
    177 	krb5_abortx(context, "internal error in ASN.1 encoder");
    178 
    179     ret = krb5_crypto_init(context, &cred->session, enctype, &crypto);
    180     if (ret)
    181 	goto fail;
    182     ret = krb5_encrypt (context,
    183 			crypto,
    184 			usage /* KRB5_KU_AP_REQ_AUTH */,
    185 			buf,
    186 			len,
    187 			result);
    188     krb5_crypto_destroy(context, crypto);
    189 
    190     if (ret)
    191 	goto fail;
    192 
    193  fail:
    194     free_Authenticator (&auth);
    195     free (buf);
    196 
    197     return ret;
    198 }
    199