Verify callback is run in either side.
[gnutls.git] / lib / auth / rsa_export.c
blobd547e39d4506be4d58bcdca4fc36e695983889d2
1 /*
2 * Copyright (C) 2000-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* This file contains the RSA key exchange part of the certificate
24 * authentication.
27 #include "gnutls_int.h"
28 #include "gnutls_auth.h"
29 #include "gnutls_errors.h"
30 #include "gnutls_dh.h"
31 #include "gnutls_num.h"
32 #include "gnutls_datum.h"
33 #include <auth/cert.h>
34 #include <gnutls_pk.h>
35 #include <algorithms.h>
36 #include <gnutls_global.h>
37 #include "debug.h"
38 #include <gnutls_sig.h>
39 #include <gnutls_x509.h>
40 #include <gnutls_rsa_export.h>
41 #include <gnutls_state.h>
42 #include <random.h>
43 #include <abstract_int.h>
45 int _gnutls_gen_rsa_client_kx (gnutls_session_t, gnutls_buffer_st*);
46 static int gen_rsa_export_server_kx (gnutls_session_t, gnutls_buffer_st*);
47 static int proc_rsa_export_server_kx (gnutls_session_t, uint8_t *, size_t);
48 static int proc_rsa_export_client_kx (gnutls_session_t session, uint8_t * data,
49 size_t _data_size);
51 const mod_auth_st rsa_export_auth_struct = {
52 "RSA EXPORT",
53 _gnutls_gen_cert_server_crt,
54 _gnutls_gen_cert_client_crt,
55 gen_rsa_export_server_kx,
56 _gnutls_gen_rsa_client_kx,
57 _gnutls_gen_cert_client_crt_vrfy, /* gen client cert vrfy */
58 _gnutls_gen_cert_server_cert_req, /* server cert request */
60 _gnutls_proc_crt,
61 _gnutls_proc_crt,
62 proc_rsa_export_server_kx,
63 proc_rsa_export_client_kx, /* proc client kx */
64 _gnutls_proc_cert_client_crt_vrfy, /* proc client cert vrfy */
65 _gnutls_proc_cert_cert_req /* proc server cert request */
68 /* This function reads the RSA parameters from the private key
70 static int
71 _gnutls_get_private_rsa_params (gnutls_session_t session,
72 gnutls_pk_params_st** params)
74 int ret;
75 gnutls_certificate_credentials_t cred;
76 gnutls_rsa_params_t rsa_params;
78 cred = (gnutls_certificate_credentials_t)
79 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
80 if (cred == NULL)
82 gnutls_assert ();
83 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
86 if (session->internals.selected_cert_list == NULL)
88 gnutls_assert ();
89 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
92 ret = _gnutls_pubkey_is_over_rsa_512(session->internals.selected_cert_list[0].pubkey);
94 if (_gnutls_cipher_suite_get_kx_algo
95 (session->security_parameters.cipher_suite)
96 != GNUTLS_KX_RSA_EXPORT || ret < 0)
98 gnutls_assert ();
99 return GNUTLS_E_INVALID_REQUEST;
102 rsa_params =
103 _gnutls_certificate_get_rsa_params (cred->rsa_params,
104 cred->params_func, session);
105 /* EXPORT case: */
106 if (rsa_params == NULL)
108 gnutls_assert ();
109 return GNUTLS_E_NO_TEMPORARY_RSA_PARAMS;
112 /* In the export case, we do use temporary RSA params
113 * of 512 bits size. The params in the certificate are
114 * used to sign this temporary stuff.
116 *params = &rsa_params->params;
118 return 0;
122 proc_rsa_export_client_kx (gnutls_session_t session, uint8_t * data,
123 size_t _data_size)
125 gnutls_datum_t plaintext;
126 gnutls_datum_t ciphertext;
127 int ret, dsize;
128 gnutls_pk_params_st *params;
129 int randomize_key = 0;
130 ssize_t data_size = _data_size;
132 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
134 /* SSL 3.0
136 ciphertext.data = data;
137 ciphertext.size = data_size;
139 else
141 /* TLS 1.0
143 DECR_LEN (data_size, 2);
144 ciphertext.data = &data[2];
145 dsize = _gnutls_read_uint16 (data);
147 if (dsize != data_size)
149 gnutls_assert ();
150 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
152 ciphertext.size = dsize;
155 ret = _gnutls_get_private_rsa_params (session, &params);
156 if (ret < 0)
158 gnutls_assert ();
159 return ret;
162 ret = _gnutls_pk_decrypt (GNUTLS_PK_RSA, &plaintext, &ciphertext, params);
164 if (ret < 0 || plaintext.size != GNUTLS_MASTER_SIZE)
166 /* In case decryption fails then don't inform
167 * the peer. Just use a random key. (in order to avoid
168 * attack against pkcs-1 formating).
170 gnutls_assert ();
171 _gnutls_audit_log (session, "auth_rsa: Possible PKCS #1 format attack\n");
172 randomize_key = 1;
174 else
176 /* If the secret was properly formatted, then
177 * check the version number.
179 if (_gnutls_get_adv_version_major (session) != plaintext.data[0]
180 || _gnutls_get_adv_version_minor (session) != plaintext.data[1])
182 /* No error is returned here, if the version number check
183 * fails. We proceed normally.
184 * That is to defend against the attack described in the paper
185 * "Attacking RSA-based sessions in SSL/TLS" by Vlastimil Klima,
186 * Ondej Pokorny and Tomas Rosa.
188 gnutls_assert ();
189 _gnutls_audit_log
190 (session, "auth_rsa: Possible PKCS #1 version check format attack\n");
194 if (randomize_key != 0)
196 session->key->key.size = GNUTLS_MASTER_SIZE;
197 session->key->key.data = gnutls_malloc (session->key->key.size);
198 if (session->key->key.data == NULL)
200 gnutls_assert ();
201 return GNUTLS_E_MEMORY_ERROR;
204 /* we do not need strong random numbers here.
206 ret = _gnutls_rnd (GNUTLS_RND_NONCE, session->key->key.data,
207 session->key->key.size);
208 if (ret < 0)
210 gnutls_assert ();
211 return ret;
215 else
217 session->key->key.data = plaintext.data;
218 session->key->key.size = plaintext.size;
221 /* This is here to avoid the version check attack
222 * discussed above.
224 session->key->key.data[0] = _gnutls_get_adv_version_major (session);
225 session->key->key.data[1] = _gnutls_get_adv_version_minor (session);
227 return 0;
230 static int
231 gen_rsa_export_server_kx (gnutls_session_t session, gnutls_buffer_st* data)
233 gnutls_rsa_params_t rsa_params;
234 const gnutls_pk_params_st *rsa_mpis;
235 int ret = 0;
236 gnutls_pcert_st *apr_cert_list;
237 gnutls_privkey_t apr_pkey;
238 int apr_cert_list_length;
239 gnutls_datum_t signature, ddata;
240 gnutls_certificate_credentials_t cred;
241 gnutls_sign_algorithm_t sign_algo;
242 unsigned int bits = 0;
244 cred = (gnutls_certificate_credentials_t)
245 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
246 if (cred == NULL)
248 gnutls_assert ();
249 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
252 /* find the appropriate certificate */
253 if ((ret =
254 _gnutls_get_selected_cert (session, &apr_cert_list,
255 &apr_cert_list_length, &apr_pkey)) < 0)
257 gnutls_assert ();
258 return ret;
261 /* abort sending this message if we have a certificate
262 * of 512 bits or less.
264 gnutls_privkey_get_pk_algorithm (apr_pkey, &bits);
265 if (apr_pkey && bits <= 512)
267 gnutls_assert ();
268 return GNUTLS_E_INT_RET_0;
271 rsa_params =
272 _gnutls_certificate_get_rsa_params (cred->rsa_params, cred->params_func,
273 session);
274 rsa_mpis = _gnutls_rsa_params_to_mpi (rsa_params);
275 if (rsa_mpis == NULL)
277 gnutls_assert ();
278 return GNUTLS_E_NO_TEMPORARY_RSA_PARAMS;
281 if ((ret = _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
282 sizeof (cert_auth_info_st), 0)) < 0)
284 gnutls_assert ();
285 return ret;
288 _gnutls_rsa_export_set_pubkey (session, rsa_mpis->params[1], rsa_mpis->params[0]);
290 ret = _gnutls_buffer_append_mpi( data, 16, rsa_mpis->params[0], 0);
291 if (ret < 0)
292 return gnutls_assert_val(ret);
294 ret = _gnutls_buffer_append_mpi( data, 16, rsa_mpis->params[1], 0);
295 if (ret < 0)
296 return gnutls_assert_val(ret);
298 /* Generate the signature. */
300 ddata.data = data->data;
301 ddata.size = data->length;
303 if (apr_cert_list_length > 0)
305 if ((ret =
306 _gnutls_handshake_sign_data (session, &apr_cert_list[0],
307 apr_pkey, &ddata, &signature,
308 &sign_algo)) < 0)
310 gnutls_assert ();
311 return ret;
314 else
316 gnutls_assert ();
317 return data->length; /* do not put a signature - ILLEGAL! */
320 ret = _gnutls_buffer_append_data_prefix( data, 16, signature.data, signature.size);
321 _gnutls_free_datum (&signature);
323 if (ret < 0)
324 return gnutls_assert_val(ret);
326 return data->length;
329 /* if the peer's certificate is of 512 bits or less, returns non (0).
332 _gnutls_peers_cert_less_512 (gnutls_session_t session)
334 gnutls_pcert_st peer_cert;
335 int ret;
336 cert_auth_info_t info = _gnutls_get_auth_info (session);
338 if (info == NULL || info->ncerts == 0)
340 gnutls_assert ();
341 /* we need this in order to get peer's certificate */
342 return 0;
345 if ((ret =
346 _gnutls_get_auth_info_pcert (&peer_cert,
347 session->security_parameters.cert_type,
348 info)) < 0)
350 gnutls_assert ();
351 return 0;
354 if (gnutls_pubkey_get_pk_algorithm(peer_cert.pubkey, NULL) != GNUTLS_PK_RSA)
356 gnutls_assert ();
357 gnutls_pcert_deinit (&peer_cert);
358 return 0;
361 if (_gnutls_pubkey_is_over_rsa_512(peer_cert.pubkey) < 0)
363 gnutls_pcert_deinit (&peer_cert);
364 return 1;
367 gnutls_pcert_deinit (&peer_cert);
369 return 0;
372 static int
373 proc_rsa_export_server_kx (gnutls_session_t session,
374 uint8_t * data, size_t _data_size)
376 uint16_t n_m, n_e;
377 size_t _n_m, _n_e;
378 uint8_t *data_m;
379 uint8_t *data_e;
380 int i, sigsize;
381 gnutls_datum_t vparams, signature;
382 int ret;
383 ssize_t data_size = _data_size;
384 cert_auth_info_t info;
385 gnutls_pcert_st peer_cert;
387 info = _gnutls_get_auth_info (session);
388 if (info == NULL || info->ncerts == 0)
390 gnutls_assert ();
391 /* we need this in order to get peer's certificate */
392 return GNUTLS_E_INTERNAL_ERROR;
396 i = 0;
398 DECR_LEN (data_size, 2);
399 n_m = _gnutls_read_uint16 (&data[i]);
400 i += 2;
402 DECR_LEN (data_size, n_m);
403 data_m = &data[i];
404 i += n_m;
406 DECR_LEN (data_size, 2);
407 n_e = _gnutls_read_uint16 (&data[i]);
408 i += 2;
410 DECR_LEN (data_size, n_e);
411 data_e = &data[i];
413 _n_e = n_e;
414 _n_m = n_m;
416 if (_gnutls_mpi_scan_nz (&session->key->rsa[0], data_m, _n_m) != 0)
418 gnutls_assert ();
419 return GNUTLS_E_MPI_SCAN_FAILED;
422 if (_gnutls_mpi_scan_nz (&session->key->rsa[1], data_e, _n_e) != 0)
424 gnutls_assert ();
425 return GNUTLS_E_MPI_SCAN_FAILED;
428 _gnutls_rsa_export_set_pubkey (session, session->key->rsa[1],
429 session->key->rsa[0]);
431 /* VERIFY SIGNATURE */
433 vparams.size = n_m + n_e + 4;
434 vparams.data = data;
436 DECR_LEN (data_size, 2);
437 sigsize = _gnutls_read_uint16 (&data[vparams.size]);
439 DECR_LEN (data_size, sigsize);
440 signature.data = &data[vparams.size + 2];
441 signature.size = sigsize;
443 if ((ret =
444 _gnutls_get_auth_info_pcert (&peer_cert,
445 session->security_parameters.cert_type,
446 info)) < 0)
448 gnutls_assert ();
449 return ret;
452 ret =
453 _gnutls_handshake_verify_data (session, &peer_cert, &vparams, &signature,
454 GNUTLS_SIGN_UNKNOWN);
456 gnutls_pcert_deinit (&peer_cert);
457 if (ret < 0)
459 gnutls_assert ();
462 return ret;