diff options
Diffstat (limited to 'lib/auth_rsa_export.c')
-rw-r--r-- | lib/auth_rsa_export.c | 495 |
1 files changed, 0 insertions, 495 deletions
diff --git a/lib/auth_rsa_export.c b/lib/auth_rsa_export.c deleted file mode 100644 index ed35fcc3d4..0000000000 --- a/lib/auth_rsa_export.c +++ /dev/null @@ -1,495 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2010 Free - * Software Foundation, Inc. - * - * Author: Nikos Mavrogiannopoulos - * - * This file is part of GnuTLS. - * - * The GnuTLS is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA - * - */ - -/* This file contains the RSA key exchange part of the certificate - * authentication. - */ - -#include "gnutls_int.h" -#include "gnutls_auth.h" -#include "gnutls_errors.h" -#include "gnutls_dh.h" -#include "gnutls_num.h" -#include "gnutls_datum.h" -#include "auth_cert.h" -#include <gnutls_pk.h> -#include <gnutls_algorithms.h> -#include <gnutls_global.h> -#include "debug.h" -#include <gnutls_sig.h> -#include <gnutls_x509.h> -#include <gnutls_rsa_export.h> -#include <gnutls_state.h> -#include <random.h> - -int _gnutls_gen_rsa_client_kx (gnutls_session_t, opaque **); -static int gen_rsa_export_server_kx (gnutls_session_t, opaque **); -static int proc_rsa_export_server_kx (gnutls_session_t, opaque *, size_t); -static int proc_rsa_export_client_kx (gnutls_session_t session, opaque * data, - size_t _data_size); - -const mod_auth_st rsa_export_auth_struct = { - "RSA EXPORT", - _gnutls_gen_cert_server_certificate, - _gnutls_gen_cert_client_certificate, - gen_rsa_export_server_kx, - _gnutls_gen_rsa_client_kx, - _gnutls_gen_cert_client_cert_vrfy, /* gen client cert vrfy */ - _gnutls_gen_cert_server_cert_req, /* server cert request */ - - _gnutls_proc_cert_server_certificate, - _gnutls_proc_cert_client_certificate, - proc_rsa_export_server_kx, - proc_rsa_export_client_kx, /* proc client kx */ - _gnutls_proc_cert_client_cert_vrfy, /* proc client cert vrfy */ - _gnutls_proc_cert_cert_req /* proc server cert request */ -}; - -/* This function reads the RSA parameters from the private key - */ -static int -_gnutls_get_private_rsa_params (gnutls_session_t session, - bigint_t ** params, int *params_size) -{ - int bits; - gnutls_certificate_credentials_t cred; - gnutls_rsa_params_t rsa_params; - - cred = (gnutls_certificate_credentials_t) - _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL); - if (cred == NULL) - { - gnutls_assert (); - return GNUTLS_E_INSUFFICIENT_CREDENTIALS; - } - - if (session->internals.selected_cert_list == NULL) - { - gnutls_assert (); - return GNUTLS_E_INSUFFICIENT_CREDENTIALS; - } - - bits = - _gnutls_mpi_get_nbits (session->internals. - selected_cert_list[0].params[0]); - - if (_gnutls_cipher_suite_get_kx_algo - (&session->security_parameters.current_cipher_suite) - != GNUTLS_KX_RSA_EXPORT || bits < 512) - { - gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; - } - - rsa_params = - _gnutls_certificate_get_rsa_params (cred->rsa_params, - cred->params_func, session); - /* EXPORT case: */ - if (rsa_params == NULL) - { - gnutls_assert (); - return GNUTLS_E_NO_TEMPORARY_RSA_PARAMS; - } - - /* In the export case, we do use temporary RSA params - * of 512 bits size. The params in the certificate are - * used to sign this temporary stuff. - */ - *params_size = RSA_PRIVATE_PARAMS; - *params = rsa_params->params; - - return 0; -} - -int -proc_rsa_export_client_kx (gnutls_session_t session, opaque * data, - size_t _data_size) -{ - gnutls_datum_t plaintext; - gnutls_datum_t ciphertext; - int ret, dsize; - bigint_t *params; - int params_len; - int randomize_key = 0; - ssize_t data_size = _data_size; - - if (gnutls_protocol_get_version (session) == GNUTLS_SSL3) - { - /* SSL 3.0 - */ - ciphertext.data = data; - ciphertext.size = data_size; - } - else - { - /* TLS 1.0 - */ - DECR_LEN (data_size, 2); - ciphertext.data = &data[2]; - dsize = _gnutls_read_uint16 (data); - - if (dsize != data_size) - { - gnutls_assert (); - return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; - } - ciphertext.size = dsize; - } - - ret = _gnutls_get_private_rsa_params (session, ¶ms, ¶ms_len); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - - ret = _gnutls_pkcs1_rsa_decrypt (&plaintext, &ciphertext, params, params_len, 2); /* btype==2 */ - - if (ret < 0 || plaintext.size != GNUTLS_MASTER_SIZE) - { - /* In case decryption fails then don't inform - * the peer. Just use a random key. (in order to avoid - * attack against pkcs-1 formating). - */ - gnutls_assert (); - _gnutls_x509_log ("auth_rsa: Possible PKCS #1 format attack\n"); - randomize_key = 1; - } - else - { - /* If the secret was properly formatted, then - * check the version number. - */ - if (_gnutls_get_adv_version_major (session) != plaintext.data[0] - || _gnutls_get_adv_version_minor (session) != plaintext.data[1]) - { - /* No error is returned here, if the version number check - * fails. We proceed normally. - * That is to defend against the attack described in the paper - * "Attacking RSA-based sessions in SSL/TLS" by Vlastimil Klima, - * Ondej Pokorny and Tomas Rosa. - */ - gnutls_assert (); - _gnutls_x509_log - ("auth_rsa: Possible PKCS #1 version check format attack\n"); - } - } - - if (randomize_key != 0) - { - session->key->key.size = GNUTLS_MASTER_SIZE; - session->key->key.data = gnutls_malloc (session->key->key.size); - if (session->key->key.data == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - /* we do not need strong random numbers here. - */ - ret = _gnutls_rnd (GNUTLS_RND_NONCE, session->key->key.data, - session->key->key.size); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - - } - else - { - session->key->key.data = plaintext.data; - session->key->key.size = plaintext.size; - } - - /* This is here to avoid the version check attack - * discussed above. - */ - session->key->key.data[0] = _gnutls_get_adv_version_major (session); - session->key->key.data[1] = _gnutls_get_adv_version_minor (session); - - return 0; -} - -static int -gen_rsa_export_server_kx (gnutls_session_t session, opaque ** data) -{ - gnutls_rsa_params_t rsa_params; - const bigint_t *rsa_mpis; - size_t n_e, n_m; - uint8_t *data_e, *data_m; - int ret = 0, data_size; - gnutls_cert *apr_cert_list; - gnutls_privkey_t apr_pkey; - int apr_cert_list_length; - gnutls_datum_t signature, ddata; - gnutls_certificate_credentials_t cred; - gnutls_sign_algorithm_t sign_algo; - unsigned int bits = 0; - - cred = (gnutls_certificate_credentials_t) - _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL); - if (cred == NULL) - { - gnutls_assert (); - return GNUTLS_E_INSUFFICIENT_CREDENTIALS; - } - - /* find the appropriate certificate */ - if ((ret = - _gnutls_get_selected_cert (session, &apr_cert_list, - &apr_cert_list_length, &apr_pkey)) < 0) - { - gnutls_assert (); - return ret; - } - - /* abort sending this message if we have a certificate - * of 512 bits or less. - */ - gnutls_privkey_get_pk_algorithm (apr_pkey, &bits); - if (apr_pkey && bits <= 512) - { - gnutls_assert (); - return GNUTLS_E_INT_RET_0; - } - - rsa_params = - _gnutls_certificate_get_rsa_params (cred->rsa_params, cred->params_func, - session); - rsa_mpis = _gnutls_rsa_params_to_mpi (rsa_params); - if (rsa_mpis == NULL) - { - gnutls_assert (); - return GNUTLS_E_NO_TEMPORARY_RSA_PARAMS; - } - - if ((ret = _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE, - sizeof (cert_auth_info_st), 0)) < 0) - { - gnutls_assert (); - return ret; - } - - _gnutls_rsa_export_set_pubkey (session, rsa_mpis[1], rsa_mpis[0]); - - _gnutls_mpi_print (rsa_mpis[0], NULL, &n_m); - _gnutls_mpi_print (rsa_mpis[1], NULL, &n_e); - - (*data) = gnutls_malloc (n_e + n_m + 4); - if (*data == NULL) - { - return GNUTLS_E_MEMORY_ERROR; - } - - data_m = &(*data)[0]; - _gnutls_mpi_print (rsa_mpis[0], &data_m[2], &n_m); - - _gnutls_write_uint16 (n_m, data_m); - - data_e = &data_m[2 + n_m]; - _gnutls_mpi_print (rsa_mpis[1], &data_e[2], &n_e); - - _gnutls_write_uint16 (n_e, data_e); - - data_size = n_m + n_e + 4; - - - /* Generate the signature. */ - - ddata.data = *data; - ddata.size = data_size; - - if (apr_cert_list_length > 0) - { - if ((ret = - _gnutls_handshake_sign_data (session, &apr_cert_list[0], - apr_pkey, &ddata, &signature, - &sign_algo)) < 0) - { - gnutls_assert (); - gnutls_free (*data); - *data = NULL; - return ret; - } - } - else - { - gnutls_assert (); - return data_size; /* do not put a signature - ILLEGAL! */ - } - - *data = gnutls_realloc_fast (*data, data_size + signature.size + 2); - if (*data == NULL) - { - _gnutls_free_datum (&signature); - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - _gnutls_write_datum16 (&((*data)[data_size]), signature); - data_size += signature.size + 2; - - _gnutls_free_datum (&signature); - - return data_size; -} - -/* if the peer's certificate is of 512 bits or less, returns non zero. - */ -int -_gnutls_peers_cert_less_512 (gnutls_session_t session) -{ - gnutls_cert peer_cert; - int ret; - cert_auth_info_t info = _gnutls_get_auth_info (session); - - if (info == NULL || info->ncerts == 0) - { - gnutls_assert (); - /* we need this in order to get peer's certificate */ - return 0; - } - - if ((ret = - _gnutls_get_auth_info_gcert (&peer_cert, - session->security_parameters.cert_type, - info, CERT_NO_COPY)) < 0) - { - gnutls_assert (); - return 0; - } - - if (peer_cert.subject_pk_algorithm != GNUTLS_PK_RSA) - { - gnutls_assert (); - _gnutls_gcert_deinit (&peer_cert); - return 0; - } - - if (_gnutls_mpi_get_nbits (peer_cert.params[0]) <= 512) - { - _gnutls_gcert_deinit (&peer_cert); - return 1; - } - - _gnutls_gcert_deinit (&peer_cert); - - return 0; -} - -static int -proc_rsa_export_server_kx (gnutls_session_t session, - opaque * data, size_t _data_size) -{ - uint16_t n_m, n_e; - size_t _n_m, _n_e; - uint8_t *data_m; - uint8_t *data_e; - int i, sigsize; - gnutls_datum_t vparams, signature; - int ret; - ssize_t data_size = _data_size; - cert_auth_info_t info; - gnutls_cert peer_cert; - - info = _gnutls_get_auth_info (session); - if (info == NULL || info->ncerts == 0) - { - gnutls_assert (); - /* we need this in order to get peer's certificate */ - return GNUTLS_E_INTERNAL_ERROR; - } - - - i = 0; - - DECR_LEN (data_size, 2); - n_m = _gnutls_read_uint16 (&data[i]); - i += 2; - - DECR_LEN (data_size, n_m); - data_m = &data[i]; - i += n_m; - - DECR_LEN (data_size, 2); - n_e = _gnutls_read_uint16 (&data[i]); - i += 2; - - DECR_LEN (data_size, n_e); - data_e = &data[i]; - i += n_e; - - _n_e = n_e; - _n_m = n_m; - - if (_gnutls_mpi_scan_nz (&session->key->rsa[0], data_m, _n_m) != 0) - { - gnutls_assert (); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - if (_gnutls_mpi_scan_nz (&session->key->rsa[1], data_e, _n_e) != 0) - { - gnutls_assert (); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - _gnutls_rsa_export_set_pubkey (session, session->key->rsa[1], - session->key->rsa[0]); - - /* VERIFY SIGNATURE */ - - vparams.size = n_m + n_e + 4; - vparams.data = data; - - DECR_LEN (data_size, 2); - sigsize = _gnutls_read_uint16 (&data[vparams.size]); - - DECR_LEN (data_size, sigsize); - signature.data = &data[vparams.size + 2]; - signature.size = sigsize; - - if ((ret = - _gnutls_get_auth_info_gcert (&peer_cert, - session->security_parameters.cert_type, - info, CERT_NO_COPY)) < 0) - { - gnutls_assert (); - return ret; - } - - ret = - _gnutls_handshake_verify_data (session, &peer_cert, &vparams, &signature, - GNUTLS_SIGN_UNKNOWN); - - _gnutls_gcert_deinit (&peer_cert); - if (ret < 0) - { - gnutls_assert (); - } - - return ret; -} |