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