1 | /*
|
---|
2 | * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
|
---|
3 | * (Royal Institute of Technology, Stockholm, Sweden).
|
---|
4 | * All rights reserved.
|
---|
5 | *
|
---|
6 | * Redistribution and use in source and binary forms, with or without
|
---|
7 | * modification, are permitted provided that the following conditions
|
---|
8 | * are met:
|
---|
9 | *
|
---|
10 | * 1. Redistributions of source code must retain the above copyright
|
---|
11 | * notice, this list of conditions and the following disclaimer.
|
---|
12 | *
|
---|
13 | * 2. Redistributions in binary form must reproduce the above copyright
|
---|
14 | * notice, this list of conditions and the following disclaimer in the
|
---|
15 | * documentation and/or other materials provided with the distribution.
|
---|
16 | *
|
---|
17 | * 3. Neither the name of the Institute nor the names of its contributors
|
---|
18 | * may be used to endorse or promote products derived from this software
|
---|
19 | * without specific prior written permission.
|
---|
20 | *
|
---|
21 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
---|
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
---|
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
---|
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
---|
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
---|
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
---|
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
---|
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
---|
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
---|
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
---|
31 | * SUCH DAMAGE.
|
---|
32 | */
|
---|
33 |
|
---|
34 | #include "krb5_locl.h"
|
---|
35 |
|
---|
36 | static krb5_error_code
|
---|
37 | make_etypelist(krb5_context context,
|
---|
38 | krb5_authdata **auth_data)
|
---|
39 | {
|
---|
40 | EtypeList etypes;
|
---|
41 | krb5_error_code ret;
|
---|
42 | krb5_authdata ad;
|
---|
43 | u_char *buf;
|
---|
44 | size_t len = 0;
|
---|
45 | size_t buf_size;
|
---|
46 |
|
---|
47 | ret = _krb5_init_etype(context, KRB5_PDU_NONE,
|
---|
48 | &etypes.len, &etypes.val,
|
---|
49 | 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 = 0;
|
---|
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 | }
|
---|