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