gnutls_x509_*_set_dn_by_oid() functions have a raw_flag parameter added. Some other...
[gnutls.git] / lib / auth_dh_common.c
blob287c5c4191284f890279cabf033f187406dbc80c
1 /*
2 * Copyright (C) 2002,2003 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
22 /* This file contains common stuff in Ephemeral Diffie Hellman (DHE) and
23 * Anonymous DH key exchange(DHA). These are used in the handshake procedure
24 * of the certificate and anoymous authentication.
27 #include "gnutls_int.h"
28 #include "gnutls_auth_int.h"
29 #include "gnutls_errors.h"
30 #include "gnutls_dh.h"
31 #include "gnutls_num.h"
32 #include "gnutls_sig.h"
33 #include <gnutls_datum.h>
34 #include <gnutls_x509.h>
35 #include <gnutls_extra.h>
36 #include <gnutls_state.h>
37 #include <auth_dh_common.h>
39 int _gnutls_proc_dh_common_client_kx(gnutls_session session, opaque * data,
40 size_t _data_size, GNUTLS_MPI g, GNUTLS_MPI p)
42 uint16 n_Y;
43 size_t _n_Y;
44 int ret;
45 ssize_t data_size = _data_size;
48 DECR_LEN( data_size, 2);
49 n_Y = _gnutls_read_uint16(&data[0]);
50 _n_Y = n_Y;
52 DECR_LEN( data_size, n_Y);
53 if (_gnutls_mpi_scan(&session->key->client_Y, &data[2], &_n_Y)) {
54 gnutls_assert();
55 return GNUTLS_E_MPI_SCAN_FAILED;
58 ret=_gnutls_dh_set_peer_public_bits( session, _gnutls_mpi_get_nbits(
59 session->key->client_Y));
60 if (ret<0) {
61 gnutls_assert();
62 return ret;
66 session->key->KEY =
67 gnutls_calc_dh_key(session->key->client_Y,
68 session->key->dh_secret, p);
70 if (session->key->KEY == NULL) {
71 gnutls_assert();
72 return GNUTLS_E_MEMORY_ERROR;
75 _gnutls_mpi_release(&session->key->client_Y);
76 _gnutls_mpi_release(&session->key->dh_secret);
78 ret = _gnutls_generate_session_key(session->key);
79 _gnutls_mpi_release(&session->key->KEY);
81 if (ret < 0) {
82 return ret;
85 return 0;
88 int _gnutls_gen_dh_common_client_kx(gnutls_session session, opaque ** data)
90 GNUTLS_MPI x, X;
91 size_t n_X;
92 int ret;
94 X = gnutls_calc_dh_secret(&x, session->key->client_g,
95 session->key->client_p);
96 if (X == NULL || x == NULL) {
97 gnutls_assert();
98 _gnutls_mpi_release(&x);
99 _gnutls_mpi_release(&X);
100 return GNUTLS_E_MEMORY_ERROR;
103 ret=_gnutls_dh_set_secret_bits( session, _gnutls_mpi_get_nbits(x));
104 if (ret<0) {
105 gnutls_assert();
106 return ret;
109 _gnutls_mpi_print( NULL, &n_X, X);
110 (*data) = gnutls_malloc(n_X + 2);
111 if (*data == NULL) {
112 _gnutls_mpi_release(&x);
113 _gnutls_mpi_release(&X);
114 return GNUTLS_E_MEMORY_ERROR;
117 _gnutls_mpi_print( &(*data)[2], &n_X, X);
118 _gnutls_mpi_release(&X);
120 _gnutls_write_uint16(n_X, &(*data)[0]);
122 /* calculate the key after calculating the message */
123 session->key->KEY =
124 gnutls_calc_dh_key(session->key->client_Y, x,
125 session->key->client_p);
127 _gnutls_mpi_release(&x);
128 if (session->key->KEY == NULL) {
129 gnutls_assert();
130 gnutls_free(*data); *data = NULL;
131 return GNUTLS_E_MEMORY_ERROR;
134 ret=_gnutls_dh_set_peer_public_bits( session, _gnutls_mpi_get_nbits(
135 session->key->client_Y));
136 if (ret<0) {
137 gnutls_assert();
138 failed:
139 gnutls_free(*data); *data = NULL;
140 return ret;
144 /* THESE SHOULD BE DISCARDED */
145 _gnutls_mpi_release(&session->key->client_Y);
146 _gnutls_mpi_release(&session->key->client_p);
147 _gnutls_mpi_release(&session->key->client_g);
149 ret = _gnutls_generate_session_key(session->key);
150 _gnutls_mpi_release(&session->key->KEY);
152 if (ret < 0) {
153 goto failed;
156 return n_X + 2;
159 int _gnutls_proc_dh_common_server_kx( gnutls_session session, opaque* data, size_t _data_size)
161 uint16 n_Y, n_g, n_p;
162 size_t _n_Y, _n_g, _n_p;
163 uint8 *data_p;
164 uint8 *data_g;
165 uint8 *data_Y;
166 int i, ret, bits;
167 ssize_t data_size = _data_size;
169 i = 0;
170 DECR_LEN( data_size, 2);
171 n_p = _gnutls_read_uint16( &data[i]);
172 i += 2;
174 DECR_LEN( data_size, n_p);
175 data_p = &data[i];
176 i += n_p;
177 if (i > data_size) {
178 gnutls_assert();
179 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
181 DECR_LEN( data_size, 2);
182 n_g = _gnutls_read_uint16( &data[i]);
183 i += 2;
185 DECR_LEN( data_size, n_g);
186 data_g = &data[i];
187 i += n_g;
189 DECR_LEN( data_size, 2);
190 n_Y = _gnutls_read_uint16( &data[i]);
191 i += 2;
193 DECR_LEN( data_size, n_Y);
194 data_Y = &data[i];
195 i += n_Y;
197 _n_Y = n_Y;
198 _n_g = n_g;
199 _n_p = n_p;
201 if (_gnutls_mpi_scan(&session->key->client_Y, data_Y, &_n_Y) != 0 || session->key->client_Y==NULL) {
202 gnutls_assert();
203 return GNUTLS_E_MPI_SCAN_FAILED;
206 if (_gnutls_mpi_scan(&session->key->client_g, data_g, &_n_g) != 0 || session->key->client_g==NULL) {
207 gnutls_assert();
208 return GNUTLS_E_MPI_SCAN_FAILED;
210 if (_gnutls_mpi_scan(&session->key->client_p, data_p, &_n_p) != 0 || session->key->client_p==NULL) {
211 gnutls_assert();
212 return GNUTLS_E_MPI_SCAN_FAILED;
215 bits = _gnutls_dh_get_prime_bits( session);
216 if (bits < 0) {
217 gnutls_assert();
218 return bits;
221 if ( _gnutls_mpi_get_nbits( session->key->client_p) < (size_t)bits) {
222 /* the prime used by the peer is not acceptable
224 gnutls_assert();
225 return GNUTLS_E_DH_PRIME_UNACCEPTABLE;
228 ret=_gnutls_dh_set_prime_bits( session, _gnutls_mpi_get_nbits(
229 session->key->client_p));
230 if (ret<0) {
231 gnutls_assert();
232 return ret;
235 ret=_gnutls_dh_set_peer_public_bits( session, _gnutls_mpi_get_nbits(
236 session->key->client_Y));
237 if (ret<0) {
238 gnutls_assert();
239 return ret;
242 return n_Y + n_p + n_g + 6;
245 int _gnutls_dh_common_print_server_kx( gnutls_session session,
246 GNUTLS_MPI g, GNUTLS_MPI p, opaque** data)
248 GNUTLS_MPI x, X;
249 size_t n_X, n_g, n_p;
250 int ret;
251 uint8 *data_p;
252 uint8 *data_g;
253 uint8 *data_X;
255 X = gnutls_calc_dh_secret(&x, g, p);
256 if (X == NULL || x == NULL) {
257 gnutls_assert();
258 return GNUTLS_E_MEMORY_ERROR;
261 session->key->dh_secret = x;
262 ret= _gnutls_dh_set_secret_bits( session, _gnutls_mpi_get_nbits(x));
263 if (ret < 0) {
264 gnutls_assert();
265 _gnutls_mpi_release(&X);
266 return ret;
269 _gnutls_mpi_print( NULL, &n_g, g);
270 _gnutls_mpi_print( NULL, &n_p, p);
271 _gnutls_mpi_print( NULL, &n_X, X);
272 (*data) = gnutls_malloc(n_g + n_p + n_X + 6);
273 if (*data == NULL) {
274 _gnutls_mpi_release(&X);
275 return GNUTLS_E_MEMORY_ERROR;
278 data_p = &(*data)[0];
279 _gnutls_mpi_print( &data_p[2], &n_p, p);
281 _gnutls_write_uint16(n_p, data_p);
283 data_g = &data_p[2 + n_p];
284 _gnutls_mpi_print( &data_g[2], &n_g, g);
286 _gnutls_write_uint16(n_g, data_g);
288 data_X = &data_g[2 + n_g];
289 _gnutls_mpi_print( &data_X[2], &n_X, X);
290 _gnutls_mpi_release(&X);
292 _gnutls_write_uint16(n_X, data_X);
294 ret = n_p + n_g + n_X + 6;
296 return ret;