00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "gnutls_int.h"
00031 #include "gnutls_auth_int.h"
00032 #include "gnutls_errors.h"
00033 #include "gnutls_dh.h"
00034 #include "gnutls_num.h"
00035 #include "gnutls_sig.h"
00036 #include <gnutls_datum.h>
00037 #include <gnutls_x509.h>
00038 #include <gnutls_state.h>
00039 #include <auth_dh_common.h>
00040 #include <gnutls_algorithms.h>
00041
00042
00043
00044 void
00045 MHD_gtls_free_dh_info (MHD_gtls_dh_info_st * dh)
00046 {
00047 dh->secret_bits = 0;
00048 MHD__gnutls_free_datum (&dh->prime);
00049 MHD__gnutls_free_datum (&dh->generator);
00050 MHD__gnutls_free_datum (&dh->public_key);
00051 }
00052
00053 int
00054 MHD_gtls_proc_dh_common_client_kx (MHD_gtls_session_t session,
00055 opaque * data, size_t _data_size,
00056 mpi_t g, mpi_t p)
00057 {
00058 uint16_t n_Y;
00059 size_t _n_Y;
00060 int ret;
00061 ssize_t data_size = _data_size;
00062
00063
00064 DECR_LEN (data_size, 2);
00065 n_Y = MHD_gtls_read_uint16 (&data[0]);
00066 _n_Y = n_Y;
00067
00068 DECR_LEN (data_size, n_Y);
00069 if (MHD_gtls_mpi_scan_nz (&session->key->client_Y, &data[2], &_n_Y))
00070 {
00071 MHD_gnutls_assert ();
00072 return GNUTLS_E_MPI_SCAN_FAILED;
00073 }
00074
00075 MHD_gtls_dh_set_peer_public (session, session->key->client_Y);
00076
00077 session->key->KEY =
00078 MHD_gtls_calc_dh_key (session->key->client_Y, session->key->dh_secret, p);
00079
00080 if (session->key->KEY == NULL)
00081 {
00082 MHD_gnutls_assert ();
00083 return GNUTLS_E_MEMORY_ERROR;
00084 }
00085
00086 MHD_gtls_mpi_release (&session->key->client_Y);
00087 MHD_gtls_mpi_release (&session->key->dh_secret);
00088
00089 ret = MHD_gtls_mpi_dprint (&session->key->key, session->key->KEY);
00090
00091 MHD_gtls_mpi_release (&session->key->KEY);
00092
00093 if (ret < 0)
00094 {
00095 return ret;
00096 }
00097
00098 return 0;
00099 }
00100
00101 int
00102 MHD_gtls_gen_dh_common_client_kx (MHD_gtls_session_t session, opaque ** data)
00103 {
00104 mpi_t x = NULL, X = NULL;
00105 size_t n_X;
00106 int ret;
00107
00108 *data = NULL;
00109
00110 X = MHD_gtls_calc_dh_secret (&x, session->key->client_g,
00111 session->key->client_p);
00112 if (X == NULL || x == NULL)
00113 {
00114 MHD_gnutls_assert ();
00115 ret = GNUTLS_E_MEMORY_ERROR;
00116 goto error;
00117 }
00118
00119 MHD_gtls_dh_set_secret_bits (session, MHD__gnutls_mpi_get_nbits (x));
00120
00121 MHD_gtls_mpi_print (NULL, &n_X, X);
00122 (*data) = MHD_gnutls_malloc (n_X + 2);
00123 if (*data == NULL)
00124 {
00125 ret = GNUTLS_E_MEMORY_ERROR;
00126 goto error;
00127 }
00128
00129 MHD_gtls_mpi_print (&(*data)[2], &n_X, X);
00130 MHD_gtls_mpi_release (&X);
00131
00132 MHD_gtls_write_uint16 (n_X, &(*data)[0]);
00133
00134
00135 session->key->KEY =
00136 MHD_gtls_calc_dh_key (session->key->client_Y, x, session->key->client_p);
00137
00138 MHD_gtls_mpi_release (&x);
00139 if (session->key->KEY == NULL)
00140 {
00141 MHD_gnutls_assert ();
00142 ret = GNUTLS_E_MEMORY_ERROR;
00143 goto error;
00144 }
00145
00146
00147 MHD_gtls_mpi_release (&session->key->client_Y);
00148 MHD_gtls_mpi_release (&session->key->client_p);
00149 MHD_gtls_mpi_release (&session->key->client_g);
00150
00151 ret = MHD_gtls_mpi_dprint (&session->key->key, session->key->KEY);
00152
00153 MHD_gtls_mpi_release (&session->key->KEY);
00154
00155 if (ret < 0)
00156 {
00157 MHD_gnutls_assert ();
00158 goto error;
00159 }
00160
00161 return n_X + 2;
00162
00163 error:
00164 MHD_gtls_mpi_release (&x);
00165 MHD_gtls_mpi_release (&X);
00166 MHD_gnutls_free (*data);
00167 *data = NULL;
00168 return ret;
00169 }
00170
00171 int
00172 MHD_gtls_proc_dh_common_server_kx (MHD_gtls_session_t session,
00173 opaque * data, size_t _data_size, int psk)
00174 {
00175 uint16_t n_Y, n_g, n_p;
00176 size_t _n_Y, _n_g, _n_p;
00177 uint8_t *data_p;
00178 uint8_t *data_g;
00179 uint8_t *data_Y;
00180 int i, bits, psk_size, ret;
00181 ssize_t data_size = _data_size;
00182
00183 i = 0;
00184
00185 if (psk != 0)
00186 {
00187 DECR_LEN (data_size, 2);
00188 psk_size = MHD_gtls_read_uint16 (&data[i]);
00189 DECR_LEN (data_size, psk_size);
00190 i += 2 + psk_size;
00191 }
00192
00193 DECR_LEN (data_size, 2);
00194 n_p = MHD_gtls_read_uint16 (&data[i]);
00195 i += 2;
00196
00197 DECR_LEN (data_size, n_p);
00198 data_p = &data[i];
00199 i += n_p;
00200
00201 DECR_LEN (data_size, 2);
00202 n_g = MHD_gtls_read_uint16 (&data[i]);
00203 i += 2;
00204
00205 DECR_LEN (data_size, n_g);
00206 data_g = &data[i];
00207 i += n_g;
00208
00209 DECR_LEN (data_size, 2);
00210 n_Y = MHD_gtls_read_uint16 (&data[i]);
00211 i += 2;
00212
00213 DECR_LEN (data_size, n_Y);
00214 data_Y = &data[i];
00215 i += n_Y;
00216
00217 _n_Y = n_Y;
00218 _n_g = n_g;
00219 _n_p = n_p;
00220
00221 if (MHD_gtls_mpi_scan_nz (&session->key->client_Y, data_Y, &_n_Y) != 0)
00222 {
00223 MHD_gnutls_assert ();
00224 return GNUTLS_E_MPI_SCAN_FAILED;
00225 }
00226
00227 if (MHD_gtls_mpi_scan_nz (&session->key->client_g, data_g, &_n_g) != 0)
00228 {
00229 MHD_gnutls_assert ();
00230 return GNUTLS_E_MPI_SCAN_FAILED;
00231 }
00232 if (MHD_gtls_mpi_scan_nz (&session->key->client_p, data_p, &_n_p) != 0)
00233 {
00234 MHD_gnutls_assert ();
00235 return GNUTLS_E_MPI_SCAN_FAILED;
00236 }
00237
00238 bits = MHD_gtls_dh_get_allowed_prime_bits (session);
00239 if (bits < 0)
00240 {
00241 MHD_gnutls_assert ();
00242 return bits;
00243 }
00244
00245 if (MHD__gnutls_mpi_get_nbits (session->key->client_p) < (size_t) bits)
00246 {
00247
00248
00249 MHD_gnutls_assert ();
00250 return GNUTLS_E_DH_PRIME_UNACCEPTABLE;
00251 }
00252
00253 MHD_gtls_dh_set_group (session, session->key->client_g,
00254 session->key->client_p);
00255 MHD_gtls_dh_set_peer_public (session, session->key->client_Y);
00256
00257 ret = n_Y + n_p + n_g + 6;
00258 if (psk != 0)
00259 ret += 2;
00260
00261 return ret;
00262 }
00263
00264
00265
00266 int
00267 MHD_gtls_dh_common_print_server_kx (MHD_gtls_session_t session,
00268 mpi_t g, mpi_t p, opaque ** data, int psk)
00269 {
00270 mpi_t x, X;
00271 size_t n_X, n_g, n_p;
00272 int ret, data_size, pos;
00273 uint8_t *pdata;
00274
00275 X = MHD_gtls_calc_dh_secret (&x, g, p);
00276 if (X == NULL || x == NULL)
00277 {
00278 MHD_gnutls_assert ();
00279 return GNUTLS_E_MEMORY_ERROR;
00280 }
00281
00282 session->key->dh_secret = x;
00283 MHD_gtls_dh_set_secret_bits (session, MHD__gnutls_mpi_get_nbits (x));
00284
00285 MHD_gtls_mpi_print (NULL, &n_g, g);
00286 MHD_gtls_mpi_print (NULL, &n_p, p);
00287 MHD_gtls_mpi_print (NULL, &n_X, X);
00288
00289 data_size = n_g + n_p + n_X + 6;
00290 if (psk != 0)
00291 data_size += 2;
00292
00293 (*data) = MHD_gnutls_malloc (data_size);
00294 if (*data == NULL)
00295 {
00296 MHD_gtls_mpi_release (&X);
00297 return GNUTLS_E_MEMORY_ERROR;
00298 }
00299
00300 pos = 0;
00301 pdata = *data;
00302
00303 if (psk != 0)
00304 {
00305 MHD_gtls_write_uint16 (0, &pdata[pos]);
00306 pos += 2;
00307 }
00308
00309 MHD_gtls_mpi_print (&pdata[pos + 2], &n_p, p);
00310 MHD_gtls_write_uint16 (n_p, &pdata[pos]);
00311
00312 pos += n_p + 2;
00313
00314 MHD_gtls_mpi_print (&pdata[pos + 2], &n_g, g);
00315 MHD_gtls_write_uint16 (n_g, &pdata[pos]);
00316
00317 pos += n_g + 2;
00318
00319 MHD_gtls_mpi_print (&pdata[pos + 2], &n_X, X);
00320 MHD_gtls_mpi_release (&X);
00321
00322 MHD_gtls_write_uint16 (n_X, &pdata[pos]);
00323
00324 ret = data_size;
00325
00326 return ret;
00327 }