2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2010 Free
3 * Software Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
26 /* This file contains the RSA key exchange part of the certificate
30 #include "gnutls_int.h"
31 #include "gnutls_auth.h"
32 #include "gnutls_errors.h"
33 #include "gnutls_dh.h"
34 #include "gnutls_num.h"
35 #include "gnutls_datum.h"
36 #include "auth_cert.h"
37 #include <gnutls_pk.h>
38 #include <gnutls_algorithms.h>
39 #include <gnutls_global.h>
41 #include <gnutls_sig.h>
42 #include <gnutls_x509.h>
43 #include <gnutls_rsa_export.h>
44 #include <gnutls_state.h>
47 int _gnutls_gen_rsa_client_kx (gnutls_session_t, opaque **);
48 static int gen_rsa_export_server_kx (gnutls_session_t, opaque **);
49 static int proc_rsa_export_server_kx (gnutls_session_t, opaque *, size_t);
50 static int proc_rsa_export_client_kx (gnutls_session_t session, opaque * data,
53 const mod_auth_st rsa_export_auth_struct = {
55 _gnutls_gen_cert_server_certificate,
56 _gnutls_gen_cert_client_certificate,
57 gen_rsa_export_server_kx,
58 _gnutls_gen_rsa_client_kx,
59 _gnutls_gen_cert_client_cert_vrfy, /* gen client cert vrfy */
60 _gnutls_gen_cert_server_cert_req, /* server cert request */
62 _gnutls_proc_cert_server_certificate,
63 _gnutls_proc_cert_client_certificate,
64 proc_rsa_export_server_kx,
65 proc_rsa_export_client_kx, /* proc client kx */
66 _gnutls_proc_cert_client_cert_vrfy, /* proc client cert vrfy */
67 _gnutls_proc_cert_cert_req /* proc server cert request */
70 /* This function reads the RSA parameters from the private key
73 _gnutls_get_private_rsa_params (gnutls_session_t session,
74 bigint_t ** params, int *params_size)
77 gnutls_certificate_credentials_t cred;
78 gnutls_rsa_params_t rsa_params;
80 cred = (gnutls_certificate_credentials_t)
81 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
85 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
88 if (session->internals.selected_cert_list == NULL)
91 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
95 _gnutls_mpi_get_nbits (session->internals.
96 selected_cert_list[0].params[0]);
98 if (_gnutls_cipher_suite_get_kx_algo
99 (&session->security_parameters.current_cipher_suite)
100 != GNUTLS_KX_RSA_EXPORT || bits < 512)
103 return GNUTLS_E_INVALID_REQUEST;
107 _gnutls_certificate_get_rsa_params (cred->rsa_params,
108 cred->params_func, session);
110 if (rsa_params == NULL)
113 return GNUTLS_E_NO_TEMPORARY_RSA_PARAMS;
116 /* In the export case, we do use temporary RSA params
117 * of 512 bits size. The params in the certificate are
118 * used to sign this temporary stuff.
120 *params_size = RSA_PRIVATE_PARAMS;
121 *params = rsa_params->params;
127 proc_rsa_export_client_kx (gnutls_session_t session, opaque * data,
130 gnutls_datum_t plaintext;
131 gnutls_datum_t ciphertext;
135 int randomize_key = 0;
136 ssize_t data_size = _data_size;
138 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
142 ciphertext.data = data;
143 ciphertext.size = data_size;
149 DECR_LEN (data_size, 2);
150 ciphertext.data = &data[2];
151 dsize = _gnutls_read_uint16 (data);
153 if (dsize != data_size)
156 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
158 ciphertext.size = dsize;
161 ret = _gnutls_get_private_rsa_params (session, ¶ms, ¶ms_len);
168 ret = _gnutls_pkcs1_rsa_decrypt (&plaintext, &ciphertext, params, params_len, 2); /* btype==2 */
170 if (ret < 0 || plaintext.size != GNUTLS_MASTER_SIZE)
172 /* In case decryption fails then don't inform
173 * the peer. Just use a random key. (in order to avoid
174 * attack against pkcs-1 formating).
177 _gnutls_x509_log ("auth_rsa: Possible PKCS #1 format attack\n");
182 /* If the secret was properly formatted, then
183 * check the version number.
185 if (_gnutls_get_adv_version_major (session) != plaintext.data[0]
186 || _gnutls_get_adv_version_minor (session) != plaintext.data[1])
188 /* No error is returned here, if the version number check
189 * fails. We proceed normally.
190 * That is to defend against the attack described in the paper
191 * "Attacking RSA-based sessions in SSL/TLS" by Vlastimil Klima,
192 * Ondej Pokorny and Tomas Rosa.
196 ("auth_rsa: Possible PKCS #1 version check format attack\n");
200 if (randomize_key != 0)
202 session->key->key.size = GNUTLS_MASTER_SIZE;
203 session->key->key.data = gnutls_malloc (session->key->key.size);
204 if (session->key->key.data == NULL)
207 return GNUTLS_E_MEMORY_ERROR;
210 /* we do not need strong random numbers here.
212 ret = _gnutls_rnd (GNUTLS_RND_NONCE, session->key->key.data,
213 session->key->key.size);
223 session->key->key.data = plaintext.data;
224 session->key->key.size = plaintext.size;
227 /* This is here to avoid the version check attack
230 session->key->key.data[0] = _gnutls_get_adv_version_major (session);
231 session->key->key.data[1] = _gnutls_get_adv_version_minor (session);
237 gen_rsa_export_server_kx (gnutls_session_t session, opaque ** data)
239 gnutls_rsa_params_t rsa_params;
240 const bigint_t *rsa_mpis;
242 uint8_t *data_e, *data_m;
243 int ret = 0, data_size;
244 gnutls_cert *apr_cert_list;
245 gnutls_privkey_t apr_pkey;
246 int apr_cert_list_length;
247 gnutls_datum_t signature, ddata;
248 gnutls_certificate_credentials_t cred;
249 gnutls_sign_algorithm_t sign_algo;
250 unsigned int bits = 0;
252 cred = (gnutls_certificate_credentials_t)
253 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
257 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
260 /* find the appropriate certificate */
262 _gnutls_get_selected_cert (session, &apr_cert_list,
263 &apr_cert_list_length, &apr_pkey)) < 0)
269 /* abort sending this message if we have a certificate
270 * of 512 bits or less.
272 gnutls_privkey_get_pk_algorithm (apr_pkey, &bits);
273 if (apr_pkey && bits <= 512)
276 return GNUTLS_E_INT_RET_0;
280 _gnutls_certificate_get_rsa_params (cred->rsa_params, cred->params_func,
282 rsa_mpis = _gnutls_rsa_params_to_mpi (rsa_params);
283 if (rsa_mpis == NULL)
286 return GNUTLS_E_NO_TEMPORARY_RSA_PARAMS;
289 if ((ret = _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
290 sizeof (cert_auth_info_st), 0)) < 0)
296 _gnutls_rsa_export_set_pubkey (session, rsa_mpis[1], rsa_mpis[0]);
298 _gnutls_mpi_print (rsa_mpis[0], NULL, &n_m);
299 _gnutls_mpi_print (rsa_mpis[1], NULL, &n_e);
301 (*data) = gnutls_malloc (n_e + n_m + 4);
304 return GNUTLS_E_MEMORY_ERROR;
307 data_m = &(*data)[0];
308 _gnutls_mpi_print (rsa_mpis[0], &data_m[2], &n_m);
310 _gnutls_write_uint16 (n_m, data_m);
312 data_e = &data_m[2 + n_m];
313 _gnutls_mpi_print (rsa_mpis[1], &data_e[2], &n_e);
315 _gnutls_write_uint16 (n_e, data_e);
317 data_size = n_m + n_e + 4;
320 /* Generate the signature. */
323 ddata.size = data_size;
325 if (apr_cert_list_length > 0)
328 _gnutls_handshake_sign_data (session, &apr_cert_list[0],
329 apr_pkey, &ddata, &signature,
341 return data_size; /* do not put a signature - ILLEGAL! */
344 *data = gnutls_realloc_fast (*data, data_size + signature.size + 2);
347 _gnutls_free_datum (&signature);
349 return GNUTLS_E_MEMORY_ERROR;
352 _gnutls_write_datum16 (&((*data)[data_size]), signature);
353 data_size += signature.size + 2;
355 _gnutls_free_datum (&signature);
360 /* if the peer's certificate is of 512 bits or less, returns non zero.
363 _gnutls_peers_cert_less_512 (gnutls_session_t session)
365 gnutls_cert peer_cert;
367 cert_auth_info_t info = _gnutls_get_auth_info (session);
369 if (info == NULL || info->ncerts == 0)
372 /* we need this in order to get peer's certificate */
377 _gnutls_get_auth_info_gcert (&peer_cert,
378 session->security_parameters.cert_type,
379 info, CERT_NO_COPY)) < 0)
385 if (peer_cert.subject_pk_algorithm != GNUTLS_PK_RSA)
388 _gnutls_gcert_deinit (&peer_cert);
392 if (_gnutls_mpi_get_nbits (peer_cert.params[0]) <= 512)
394 _gnutls_gcert_deinit (&peer_cert);
398 _gnutls_gcert_deinit (&peer_cert);
404 proc_rsa_export_server_kx (gnutls_session_t session,
405 opaque * data, size_t _data_size)
412 gnutls_datum_t vparams, signature;
414 ssize_t data_size = _data_size;
415 cert_auth_info_t info;
416 gnutls_cert peer_cert;
418 info = _gnutls_get_auth_info (session);
419 if (info == NULL || info->ncerts == 0)
422 /* we need this in order to get peer's certificate */
423 return GNUTLS_E_INTERNAL_ERROR;
429 DECR_LEN (data_size, 2);
430 n_m = _gnutls_read_uint16 (&data[i]);
433 DECR_LEN (data_size, n_m);
437 DECR_LEN (data_size, 2);
438 n_e = _gnutls_read_uint16 (&data[i]);
441 DECR_LEN (data_size, n_e);
448 if (_gnutls_mpi_scan_nz (&session->key->rsa[0], data_m, _n_m) != 0)
451 return GNUTLS_E_MPI_SCAN_FAILED;
454 if (_gnutls_mpi_scan_nz (&session->key->rsa[1], data_e, _n_e) != 0)
457 return GNUTLS_E_MPI_SCAN_FAILED;
460 _gnutls_rsa_export_set_pubkey (session, session->key->rsa[1],
461 session->key->rsa[0]);
463 /* VERIFY SIGNATURE */
465 vparams.size = n_m + n_e + 4;
468 DECR_LEN (data_size, 2);
469 sigsize = _gnutls_read_uint16 (&data[vparams.size]);
471 DECR_LEN (data_size, sigsize);
472 signature.data = &data[vparams.size + 2];
473 signature.size = sigsize;
476 _gnutls_get_auth_info_gcert (&peer_cert,
477 session->security_parameters.cert_type,
478 info, CERT_NO_COPY)) < 0)
485 _gnutls_handshake_verify_data (session, &peer_cert, &vparams, &signature,
486 GNUTLS_SIGN_UNKNOWN);
488 _gnutls_gcert_deinit (&peer_cert);