Fix dangling/unused bindings in `(gnutls)'.
[gnutls.git] / lib / auth_rsa.c
blob40dbf53ceaca0988dcc684867dc2d99c037bef9a
1 /*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library 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 2.1 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
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
25 /* This file contains the RSA key exchange part of the certificate
26 * authentication.
29 #include "gnutls_int.h"
30 #include "gnutls_auth_int.h"
31 #include "gnutls_errors.h"
32 #include "gnutls_dh.h"
33 #include "gnutls_num.h"
34 #include "libtasn1.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>
40 #include "debug.h"
41 #include <gnutls_sig.h>
42 #include <gnutls_x509.h>
43 #include <gc.h>
45 int _gnutls_gen_rsa_client_kx (gnutls_session_t, opaque **);
46 int _gnutls_proc_rsa_client_kx (gnutls_session_t, opaque *, size_t);
48 const mod_auth_st rsa_auth_struct = {
49 "RSA",
50 _gnutls_gen_cert_server_certificate,
51 _gnutls_gen_cert_client_certificate,
52 NULL, /* gen server kx */
53 _gnutls_gen_rsa_client_kx,
54 _gnutls_gen_cert_client_cert_vrfy, /* gen client cert vrfy */
55 _gnutls_gen_cert_server_cert_req, /* server cert request */
57 _gnutls_proc_cert_server_certificate,
58 _gnutls_proc_cert_client_certificate,
59 NULL, /* proc server kx */
60 _gnutls_proc_rsa_client_kx, /* proc client kx */
61 _gnutls_proc_cert_client_cert_vrfy, /* proc client cert vrfy */
62 _gnutls_proc_cert_cert_req /* proc server cert request */
65 /* This function reads the RSA parameters from peer's certificate;
67 int
68 _gnutls_get_public_rsa_params (gnutls_session_t session,
69 mpi_t params[MAX_PUBLIC_PARAMS_SIZE],
70 int *params_len)
72 int ret;
73 cert_auth_info_t info;
74 gnutls_cert peer_cert;
75 int i;
77 /* normal non export case */
79 info = _gnutls_get_auth_info (session);
81 if (info == NULL || info->ncerts == 0)
83 gnutls_assert ();
84 return GNUTLS_E_INTERNAL_ERROR;
87 ret =
88 _gnutls_raw_cert_to_gcert (&peer_cert,
89 session->security_parameters.cert_type,
90 &info->raw_certificate_list[0],
91 CERT_ONLY_PUBKEY | CERT_NO_COPY);
93 if (ret < 0)
95 gnutls_assert ();
96 return ret;
100 /* EXPORT case: */
101 if (_gnutls_cipher_suite_get_kx_algo
102 (&session->security_parameters.current_cipher_suite)
103 == GNUTLS_KX_RSA_EXPORT
104 && _gnutls_mpi_get_nbits (peer_cert.params[0]) > 512)
107 _gnutls_gcert_deinit (&peer_cert);
109 if (session->key->rsa[0] == NULL || session->key->rsa[1] == NULL)
111 gnutls_assert ();
112 return GNUTLS_E_INTERNAL_ERROR;
115 if (*params_len < 2)
117 gnutls_assert ();
118 return GNUTLS_E_INTERNAL_ERROR;
120 *params_len = 2;
121 for (i = 0; i < *params_len; i++)
123 params[i] = _gnutls_mpi_copy (session->key->rsa[i]);
126 return 0;
129 /* end of export case */
131 if (*params_len < peer_cert.params_size)
133 gnutls_assert ();
134 return GNUTLS_E_INTERNAL_ERROR;
136 *params_len = peer_cert.params_size;
138 for (i = 0; i < *params_len; i++)
140 params[i] = _gnutls_mpi_copy (peer_cert.params[i]);
142 _gnutls_gcert_deinit (&peer_cert);
144 return 0;
147 /* This function reads the RSA parameters from the private key
150 _gnutls_get_private_rsa_params (gnutls_session_t session,
151 mpi_t ** params, int *params_size)
153 int bits;
154 gnutls_certificate_credentials_t cred;
155 gnutls_rsa_params_t rsa_params;
157 cred = (gnutls_certificate_credentials_t)
158 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
159 if (cred == NULL)
161 gnutls_assert ();
162 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
165 if (session->internals.selected_cert_list == NULL)
167 gnutls_assert ();
168 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
171 bits =
172 _gnutls_mpi_get_nbits (session->internals.selected_cert_list[0].
173 params[0]);
175 if (_gnutls_cipher_suite_get_kx_algo
176 (&session->security_parameters.current_cipher_suite)
177 == GNUTLS_KX_RSA_EXPORT && bits > 512)
180 rsa_params =
181 _gnutls_certificate_get_rsa_params (cred->rsa_params,
182 cred->params_func, session);
183 /* EXPORT case: */
184 if (rsa_params == NULL)
186 gnutls_assert ();
187 return GNUTLS_E_NO_TEMPORARY_RSA_PARAMS;
190 /* In the export case, we do use temporary RSA params
191 * of 512 bits size. The params in the certificate are
192 * used to sign this temporary stuff.
194 *params_size = RSA_PRIVATE_PARAMS;
195 *params = rsa_params->params;
197 return 0;
200 /* non export cipher suites. */
202 *params_size = session->internals.selected_key->params_size;
203 *params = session->internals.selected_key->params;
205 return 0;
209 _gnutls_proc_rsa_client_kx (gnutls_session_t session, opaque * data,
210 size_t _data_size)
212 gnutls_datum_t plaintext;
213 gnutls_datum_t ciphertext;
214 int ret, dsize;
215 mpi_t *params;
216 int params_len;
217 int randomize_key = 0;
218 ssize_t data_size = _data_size;
220 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
222 /* SSL 3.0
224 ciphertext.data = data;
225 ciphertext.size = data_size;
227 else
229 /* TLS 1.0
231 DECR_LEN (data_size, 2);
232 ciphertext.data = &data[2];
233 dsize = _gnutls_read_uint16 (data);
235 if (dsize != data_size)
237 gnutls_assert ();
238 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
240 ciphertext.size = dsize;
243 ret = _gnutls_get_private_rsa_params (session, &params, &params_len);
244 if (ret < 0)
246 gnutls_assert ();
247 return ret;
250 ret = _gnutls_pkcs1_rsa_decrypt (&plaintext, &ciphertext, params, params_len, 2); /* btype==2 */
252 if (ret < 0 || plaintext.size != TLS_MASTER_SIZE)
254 /* In case decryption fails then don't inform
255 * the peer. Just use a random key. (in order to avoid
256 * attack against pkcs-1 formating).
258 gnutls_assert ();
259 _gnutls_x509_log ("auth_rsa: Possible PKCS #1 format attack\n");
260 randomize_key = 1;
262 else
264 /* If the secret was properly formatted, then
265 * check the version number.
267 if (_gnutls_get_adv_version_major (session) != plaintext.data[0]
268 || _gnutls_get_adv_version_minor (session) != plaintext.data[1])
270 /* No error is returned here, if the version number check
271 * fails. We proceed normally.
272 * That is to defend against the attack described in the paper
273 * "Attacking RSA-based sessions in SSL/TLS" by Vlastimil Klima,
274 * Ondej Pokorny and Tomas Rosa.
276 gnutls_assert ();
277 _gnutls_x509_log
278 ("auth_rsa: Possible PKCS #1 version check format attack\n");
282 if (randomize_key != 0)
284 session->key->key.size = TLS_MASTER_SIZE;
285 session->key->key.data = gnutls_malloc (session->key->key.size);
286 if (session->key->key.data == NULL)
288 gnutls_assert ();
289 return GNUTLS_E_MEMORY_ERROR;
292 /* we do not need strong random numbers here.
294 if (gc_nonce (session->key->key.data, session->key->key.size) != GC_OK)
296 gnutls_assert ();
297 return GNUTLS_E_RANDOM_FAILED;
301 else
303 session->key->key.data = plaintext.data;
304 session->key->key.size = plaintext.size;
307 /* This is here to avoid the version check attack
308 * discussed above.
310 session->key->key.data[0] = _gnutls_get_adv_version_major (session);
311 session->key->key.data[1] = _gnutls_get_adv_version_minor (session);
313 return 0;
318 /* return RSA(random) using the peers public key
321 _gnutls_gen_rsa_client_kx (gnutls_session_t session, opaque ** data)
323 cert_auth_info_t auth = session->key->auth_info;
324 gnutls_datum_t sdata; /* data to send */
325 mpi_t params[MAX_PUBLIC_PARAMS_SIZE];
326 int params_len = MAX_PUBLIC_PARAMS_SIZE;
327 int ret, i;
328 gnutls_protocol_t ver;
330 if (auth == NULL)
332 /* this shouldn't have happened. The proc_certificate
333 * function should have detected that.
335 gnutls_assert ();
336 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
339 session->key->key.size = TLS_MASTER_SIZE;
340 session->key->key.data = gnutls_secure_malloc (session->key->key.size);
342 if (session->key->key.data == NULL)
344 gnutls_assert ();
345 return GNUTLS_E_MEMORY_ERROR;
348 if (gc_pseudo_random (session->key->key.data,
349 session->key->key.size) != GC_OK)
351 gnutls_assert ();
352 return GNUTLS_E_RANDOM_FAILED;
355 ver = _gnutls_get_adv_version (session);
357 if (session->internals.rsa_pms_version[0] == 0)
359 session->key->key.data[0] = _gnutls_version_get_major (ver);
360 session->key->key.data[1] = _gnutls_version_get_minor (ver);
362 else
363 { /* use the version provided */
364 session->key->key.data[0] = session->internals.rsa_pms_version[0];
365 session->key->key.data[1] = session->internals.rsa_pms_version[1];
368 /* move RSA parameters to key (session).
370 if ((ret =
371 _gnutls_get_public_rsa_params (session, params, &params_len)) < 0)
373 gnutls_assert ();
374 return ret;
377 if ((ret =
378 _gnutls_pkcs1_rsa_encrypt (&sdata, &session->key->key,
379 params, params_len, 2)) < 0)
381 gnutls_assert ();
382 return ret;
385 for (i = 0; i < params_len; i++)
386 _gnutls_mpi_release (&params[i]);
388 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
390 /* SSL 3.0 */
391 *data = sdata.data;
392 return sdata.size;
394 else
395 { /* TLS 1 */
396 *data = gnutls_malloc (sdata.size + 2);
397 if (*data == NULL)
399 _gnutls_free_datum (&sdata);
400 return GNUTLS_E_MEMORY_ERROR;
402 _gnutls_write_datum16 (*data, sdata);
403 ret = sdata.size + 2;
404 _gnutls_free_datum (&sdata);
405 return ret;