*** empty log message ***
[gnutls.git] / lib / auth_anon.c
blob7aa72f2619a49f6a3d534f286798f55316708315
1 /*
2 * Copyright (C) 2000,2001,2002 Nikos Mavroyanopoulos
4 * This file is part of GNUTLS.
6 * The GNUTLS library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * */
21 #include "gnutls_int.h"
23 #ifdef ENABLE_ANON
25 #include "gnutls_auth_int.h"
26 #include "gnutls_errors.h"
27 #include "gnutls_dh.h"
28 #include "auth_anon.h"
29 #include "gnutls_num.h"
30 #include "gnutls_mpi.h"
31 #include <gnutls_state.h>
33 int gen_anon_server_kx( GNUTLS_STATE, opaque**);
34 int gen_anon_client_kx( GNUTLS_STATE, opaque**);
35 int proc_anon_server_kx( GNUTLS_STATE, opaque*, int);
36 int proc_anon_client_kx( GNUTLS_STATE, opaque*, int);
38 const MOD_AUTH_STRUCT anon_auth_struct = {
39 "ANON",
40 NULL,
41 NULL,
42 gen_anon_server_kx,
43 NULL,
44 NULL,
45 gen_anon_client_kx,
46 NULL,
47 NULL,
49 NULL,
50 NULL, /* certificate */
51 proc_anon_server_kx,
52 NULL,
53 NULL,
54 proc_anon_client_kx,
55 NULL,
56 NULL
59 int gen_anon_server_kx( GNUTLS_STATE state, opaque** data) {
60 GNUTLS_MPI x, X, g, p;
61 int bits, ret;
62 size_t n_X, n_g, n_p;
63 uint8 *data_p;
64 uint8 *data_g;
65 uint8 *data_X;
66 ANON_SERVER_AUTH_INFO info;
67 const GNUTLS_ANON_SERVER_CREDENTIALS cred;
69 cred = _gnutls_get_cred(state->gnutls_key, GNUTLS_CRD_ANON, NULL);
70 if (cred == NULL) {
71 gnutls_assert();
72 return GNUTLS_E_INSUFICIENT_CRED;
75 bits = _gnutls_dh_get_prime_bits( state);
77 g = gnutls_get_dh_params( cred->dh_params, &p, bits);
78 if (g==NULL || p==NULL) {
79 gnutls_assert();
80 return GNUTLS_E_MEMORY_ERROR;
83 if ( (ret=_gnutls_auth_info_set( state, GNUTLS_CRD_ANON, sizeof( ANON_SERVER_AUTH_INFO_INT), 1)) < 0) {
84 gnutls_assert();
85 return ret;
88 info = _gnutls_get_auth_info( state);
89 if ((ret=_gnutls_dh_set_prime_bits( state, _gnutls_mpi_get_nbits(p))) < 0) {
90 gnutls_assert();
91 return ret;
94 X = gnutls_calc_dh_secret(&x, g, p);
95 if (X==NULL || x==NULL) {
96 gnutls_assert();
97 _gnutls_mpi_release( &g);
98 _gnutls_mpi_release( &p);
99 _gnutls_mpi_release( &x);
100 _gnutls_mpi_release( &X);
101 return GNUTLS_E_MEMORY_ERROR;
103 ret=_gnutls_dh_set_secret_bits( state, _gnutls_mpi_get_nbits(x));
104 if (ret<0) {
105 gnutls_assert();
106 return ret;
109 state->gnutls_key->dh_secret = x;
110 _gnutls_mpi_print( NULL, &n_g, g);
111 _gnutls_mpi_print( NULL, &n_p, p);
112 _gnutls_mpi_print( NULL, &n_X, X);
113 (*data) = gnutls_malloc(n_g + n_p + n_X + 6);
114 if (*data==NULL) {
115 _gnutls_mpi_release( &X);
116 _gnutls_mpi_release( &g);
117 _gnutls_mpi_release( &p);
118 return GNUTLS_E_MEMORY_ERROR;
120 data_p = &(*data)[0];
121 _gnutls_mpi_print( &data_p[2], &n_p, p);
122 _gnutls_mpi_release(&p);
124 _gnutls_write_uint16( n_p, data_p);
126 data_g = &data_p[2 + n_p];
127 _gnutls_mpi_print( &data_g[2], &n_g, g);
128 _gnutls_mpi_release(&g);
130 _gnutls_write_uint16( n_g, data_g);
132 data_X = &data_g[2 + n_g];
133 _gnutls_mpi_print( &data_X[2], &n_X, X);
134 _gnutls_mpi_release(&X);
136 _gnutls_write_uint16( n_X, data_X);
138 return n_p+n_g+n_X+6;
141 int gen_anon_client_kx( GNUTLS_STATE state, opaque** data) {
142 GNUTLS_MPI x, X;
143 size_t n_X;
144 int ret;
146 X = gnutls_calc_dh_secret(&x, state->gnutls_key->client_g,
147 state->gnutls_key->client_p);
149 if (X==NULL) {
150 gnutls_assert();
151 return GNUTLS_E_MEMORY_ERROR;
154 ret=_gnutls_dh_set_secret_bits( state, _gnutls_mpi_get_nbits(x));
155 if (ret<0) {
156 gnutls_assert();
157 return ret;
160 _gnutls_mpi_print( NULL, &n_X, X);
161 (*data) = gnutls_malloc(n_X + 2);
162 if (*data==NULL)
163 return GNUTLS_E_MEMORY_ERROR;
165 _gnutls_mpi_print( &(*data)[2], &n_X, X);
166 (*data)[0] = 1; /* extern - explicit since we do not have
167 certificate */
168 _gnutls_mpi_release(&X);
170 _gnutls_write_uint16( n_X, &(*data)[0]);
172 /* calculate the key after calculating the message */
173 state->gnutls_key->KEY = gnutls_calc_dh_key(state->gnutls_key->client_Y, x, state->gnutls_key->client_p);
174 if (state->gnutls_key->KEY==NULL)
175 return GNUTLS_E_MEMORY_ERROR;
177 /* THESE SHOULD BE DISCARDED */
178 _gnutls_mpi_release(&state->gnutls_key->client_Y);
179 _gnutls_mpi_release(&state->gnutls_key->client_p);
180 _gnutls_mpi_release(&state->gnutls_key->client_g);
182 ret = _gnutls_generate_key( state->gnutls_key);
183 _gnutls_mpi_release(&state->gnutls_key->KEY);
185 if (ret < 0) {
186 return ret;
188 return n_X+2;
191 int proc_anon_server_kx( GNUTLS_STATE state, opaque* data, int data_size) {
192 uint16 n_Y, n_g, n_p;
193 size_t _n_Y, _n_g, _n_p;
194 uint8 *data_p;
195 uint8 *data_g;
196 uint8 *data_Y;
197 int i, ret;
199 i = 0;
200 DECR_LEN( data_size, 2);
201 n_p = _gnutls_read_uint16( &data[i]);
202 i += 2;
204 DECR_LEN( data_size, n_p);
205 data_p = &data[i];
206 i += n_p;
207 if (i > data_size) {
208 gnutls_assert();
209 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
211 DECR_LEN( data_size, 2);
212 n_g = _gnutls_read_uint16( &data[i]);
213 i += 2;
215 DECR_LEN( data_size, n_g);
216 data_g = &data[i];
217 i += n_g;
219 DECR_LEN( data_size, 2);
220 n_Y = _gnutls_read_uint16( &data[i]);
221 i += 2;
223 DECR_LEN( data_size, n_Y);
224 data_Y = &data[i];
225 i += n_Y;
227 _n_Y = n_Y;
228 _n_g = n_g;
229 _n_p = n_p;
231 if (_gnutls_mpi_scan(&state->gnutls_key->client_Y, data_Y, &_n_Y) != 0 || state->gnutls_key->client_Y==NULL) {
232 gnutls_assert();
233 return GNUTLS_E_MPI_SCAN_FAILED;
236 if (_gnutls_mpi_scan(&state->gnutls_key->client_g, data_g, &_n_g) != 0 || state->gnutls_key->client_g==NULL) {
237 gnutls_assert();
238 return GNUTLS_E_MPI_SCAN_FAILED;
240 if (_gnutls_mpi_scan(&state->gnutls_key->client_p, data_p, &_n_p) != 0 || state->gnutls_key->client_p==NULL) {
241 gnutls_assert();
242 return GNUTLS_E_MPI_SCAN_FAILED;
246 /* set auth_info */
247 if ( (ret=_gnutls_auth_info_set( state, GNUTLS_CRD_ANON, sizeof( ANON_CLIENT_AUTH_INFO_INT), 1)) < 0) {
248 gnutls_assert();
249 return ret;
252 if ( _gnutls_mpi_get_nbits( state->gnutls_key->client_p) < _gnutls_dh_get_prime_bits( state)) {
253 /* the prime used by the peer is not acceptable
255 gnutls_assert();
256 return GNUTLS_E_DH_PRIME_UNACCEPTABLE;
259 ret=_gnutls_dh_set_prime_bits( state, _gnutls_mpi_get_nbits(
260 state->gnutls_key->client_p));
261 if (ret<0) {
262 gnutls_assert();
263 return ret;
266 ret=_gnutls_dh_set_peer_public_bits( state, _gnutls_mpi_get_nbits(
267 state->gnutls_key->client_Y));
268 if (ret<0) {
269 gnutls_assert();
270 return ret;
274 return 0;
277 int proc_anon_client_kx( GNUTLS_STATE state, opaque* data, int data_size) {
278 uint16 n_Y;
279 size_t _n_Y;
280 GNUTLS_MPI g, p;
281 int bits, ret;
282 const GNUTLS_ANON_SERVER_CREDENTIALS cred;
284 cred = _gnutls_get_cred(state->gnutls_key, GNUTLS_CRD_ANON, NULL);
285 if (cred == NULL) {
286 gnutls_assert();
287 return GNUTLS_E_INSUFICIENT_CRED;
290 bits = _gnutls_dh_get_prime_bits( state);
292 DECR_LEN( data_size, 2);
293 n_Y = _gnutls_read_uint16( &data[0]);
295 _n_Y = n_Y;
296 DECR_LEN( data_size, n_Y);
297 if (_gnutls_mpi_scan(&state->gnutls_key->client_Y, &data[2], &_n_Y) !=0 || state->gnutls_key->client_Y==NULL) {
298 gnutls_assert();
299 return GNUTLS_E_MPI_SCAN_FAILED;
302 g = gnutls_get_dh_params( cred->dh_params, &p, bits);
303 if (g==NULL) {
304 gnutls_assert();
305 return GNUTLS_E_MEMORY_ERROR;
308 ret=_gnutls_dh_set_peer_public_bits( state, _gnutls_mpi_get_nbits(state->gnutls_key->client_Y));
309 if (ret<0) {
310 gnutls_assert();
311 return ret;
314 state->gnutls_key->KEY = gnutls_calc_dh_key( state->gnutls_key->client_Y, state->gnutls_key->dh_secret, p);
315 if (state->gnutls_key->KEY==NULL)
316 return GNUTLS_E_MEMORY_ERROR;
318 _gnutls_mpi_release(&state->gnutls_key->client_Y);
319 _gnutls_mpi_release(&state->gnutls_key->dh_secret);
320 _gnutls_mpi_release(&p);
321 _gnutls_mpi_release(&g);
323 ret = _gnutls_generate_key( state->gnutls_key);
324 _gnutls_mpi_release(&state->gnutls_key->KEY);
326 if (ret < 0) {
327 return ret;
330 return 0;
333 #endif /* ENABLE_ANON */