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
21 #include "gnutls_int.h"
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
= {
50 NULL
, /* certificate */
59 int gen_anon_server_kx( GNUTLS_STATE state
, opaque
** data
) {
60 GNUTLS_MPI x
, X
, g
, p
;
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
);
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
) {
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) {
88 info
= _gnutls_get_auth_info( state
);
89 if ((ret
=_gnutls_dh_set_prime_bits( state
, _gnutls_mpi_get_nbits(p
))) < 0) {
94 X
= gnutls_calc_dh_secret(&x
, g
, p
);
95 if (X
==NULL
|| x
==NULL
) {
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
));
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);
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
) {
146 X
= gnutls_calc_dh_secret(&x
, state
->gnutls_key
->client_g
,
147 state
->gnutls_key
->client_p
);
151 return GNUTLS_E_MEMORY_ERROR
;
154 ret
=_gnutls_dh_set_secret_bits( state
, _gnutls_mpi_get_nbits(x
));
160 _gnutls_mpi_print( NULL
, &n_X
, X
);
161 (*data
) = gnutls_malloc(n_X
+ 2);
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
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
);
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
;
200 DECR_LEN( data_size
, 2);
201 n_p
= _gnutls_read_uint16( &data
[i
]);
204 DECR_LEN( data_size
, n_p
);
209 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
211 DECR_LEN( data_size
, 2);
212 n_g
= _gnutls_read_uint16( &data
[i
]);
215 DECR_LEN( data_size
, n_g
);
219 DECR_LEN( data_size
, 2);
220 n_Y
= _gnutls_read_uint16( &data
[i
]);
223 DECR_LEN( data_size
, n_Y
);
231 if (_gnutls_mpi_scan(&state
->gnutls_key
->client_Y
, data_Y
, &_n_Y
) != 0 || state
->gnutls_key
->client_Y
==NULL
) {
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
) {
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
) {
242 return GNUTLS_E_MPI_SCAN_FAILED
;
247 if ( (ret
=_gnutls_auth_info_set( state
, GNUTLS_CRD_ANON
, sizeof( ANON_CLIENT_AUTH_INFO_INT
), 1)) < 0) {
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
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
));
266 ret
=_gnutls_dh_set_peer_public_bits( state
, _gnutls_mpi_get_nbits(
267 state
->gnutls_key
->client_Y
));
277 int proc_anon_client_kx( GNUTLS_STATE state
, opaque
* data
, int data_size
) {
282 const GNUTLS_ANON_SERVER_CREDENTIALS cred
;
284 cred
= _gnutls_get_cred(state
->gnutls_key
, GNUTLS_CRD_ANON
, NULL
);
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]);
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
) {
299 return GNUTLS_E_MPI_SCAN_FAILED
;
302 g
= gnutls_get_dh_params( cred
->dh_params
, &p
, bits
);
305 return GNUTLS_E_MEMORY_ERROR
;
308 ret
=_gnutls_dh_set_peer_public_bits( state
, _gnutls_mpi_get_nbits(state
->gnutls_key
->client_Y
));
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
);
333 #endif /* ENABLE_ANON */