diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2002-08-26 08:14:33 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2002-08-26 08:14:33 +0000 |
commit | 32b6675ea3193b6d445bb26957a9bbb66480a25a (patch) | |
tree | 2215070afd9f3591384dd4f40c8048c565feb247 | |
parent | bacee492e5dfe72b6ac78074de2ce7d946adaee2 (diff) | |
download | gnutls-32b6675ea3193b6d445bb26957a9bbb66480a25a.tar.gz |
Added support for RSA_EXPORT_WITH_RC4_EXPORT_MD5 with RSA certificates with modulus less than 512 bits. This change made the code a bit messy.
-rw-r--r-- | lib/auth_rsa.c | 62 | ||||
-rw-r--r-- | lib/auth_rsa_export.c | 63 | ||||
-rw-r--r-- | lib/gnutls_kx.c | 24 | ||||
-rw-r--r-- | lib/gnutls_rsa_export.h | 1 | ||||
-rw-r--r-- | lib/gnutls_state.c | 16 | ||||
-rw-r--r-- | lib/gnutls_state.h | 1 |
6 files changed, 137 insertions, 30 deletions
diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c index efd3f689fe..e1ceaf6121 100644 --- a/lib/auth_rsa.c +++ b/lib/auth_rsa.c @@ -77,25 +77,6 @@ CERTIFICATE_AUTH_INFO info; gnutls_cert peer_cert; int i; - if ( _gnutls_cipher_suite_get_kx_algo(state->security_parameters.current_cipher_suite) - == GNUTLS_KX_RSA_EXPORT) { - /* EXPORT case: */ - - if (state->gnutls_key->rsa[0] == NULL || - state->gnutls_key->rsa[1] == NULL) { - gnutls_assert(); - return GNUTLS_E_INTERNAL_ERROR; - } - - *params_len = 2; - for (i=0;i<*params_len;i++) { - params[i] = _gnutls_mpi_copy(state->gnutls_key->rsa[i]); - } - - return 0; - } - - /* normal non export case */ info = _gnutls_get_auth_info( state); @@ -132,6 +113,34 @@ int i; gnutls_assert(); return GNUTLS_E_INTERNAL_ERROR; } + + + /* EXPORT case: */ + if ( _gnutls_cipher_suite_get_kx_algo(state->security_parameters.current_cipher_suite) + == GNUTLS_KX_RSA_EXPORT && + _gnutls_mpi_get_nbits(peer_cert.params[0]) > 512) { + + _gnutls_free_cert( peer_cert); + + if (state->gnutls_key->rsa[0] == NULL || + state->gnutls_key->rsa[1] == NULL) { + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } + + if (*params_len < 2) { + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } + *params_len = 2; + for (i=0;i<*params_len;i++) { + params[i] = _gnutls_mpi_copy(state->gnutls_key->rsa[i]); + } + + return 0; + } + + /* end of export case */ if (*params_len < peer_cert.params_size) { gnutls_assert(); @@ -160,8 +169,15 @@ const GNUTLS_CERTIFICATE_CREDENTIALS cred; return GNUTLS_E_INSUFICIENT_CRED; } + if ( (index=state->gnutls_internals.selected_cert_index) < 0) { + gnutls_assert(); + return GNUTLS_E_UNKNOWN_ERROR; + } + if ( _gnutls_cipher_suite_get_kx_algo(state->security_parameters.current_cipher_suite) - == GNUTLS_KX_RSA_EXPORT) { + == GNUTLS_KX_RSA_EXPORT && + _gnutls_mpi_get_nbits(cred->cert_list[index][0].params[0]) > 512) { + /* EXPORT case: */ if (cred->rsa_params == NULL) { gnutls_assert(); @@ -175,12 +191,6 @@ const GNUTLS_CERTIFICATE_CREDENTIALS cred; } /* non export cipher suites. */ - - - if ( (index=state->gnutls_internals.selected_cert_index) < 0) { - gnutls_assert(); - return GNUTLS_E_UNKNOWN_ERROR; - } *params_size = cred->pkey[index].params_size; *params = cred->pkey[index].params; diff --git a/lib/auth_rsa_export.c b/lib/auth_rsa_export.c index 96a7cc9580..f181dbedb3 100644 --- a/lib/auth_rsa_export.c +++ b/lib/auth_rsa_export.c @@ -100,6 +100,13 @@ static int gen_rsa_export_server_kx(GNUTLS_STATE state, opaque ** data) return ret; } + /* abort sending this message if we have a certificate + * of 512 bits or less. + */ + if ( _gnutls_mpi_get_nbits( apr_pkey->params[0]) <= 512) { + return GNUTLS_E_INT_RET_0; + } + rsa_params = _gnutls_get_rsa_params( cred->rsa_params, 512); if (rsa_params == NULL) { gnutls_assert(); @@ -173,6 +180,58 @@ static int gen_rsa_export_server_kx(GNUTLS_STATE state, opaque ** data) return data_size; } +/* if the peer's certificate is of 512 bits or less, returns non zero. + */ +int _gnutls_peers_cert_less_512( GNUTLS_STATE state) +{ +gnutls_cert peer_cert; +int ret; +CERTIFICATE_AUTH_INFO info = _gnutls_get_auth_info( state); + + if (info == NULL || info->ncerts==0) { + gnutls_assert(); + /* we need this in order to get peer's certificate */ + return 0; + } + + switch( state->security_parameters.cert_type) { + case GNUTLS_CRT_X509: + if ((ret = + _gnutls_x509_cert2gnutls_cert( &peer_cert, + info->raw_certificate_list[0], CERT_NO_COPY)) < 0) { + gnutls_assert(); + return 0; + } + break; + + case GNUTLS_CRT_OPENPGP: + if (_E_gnutls_openpgp_cert2gnutls_cert==NULL) { + gnutls_assert(); + return GNUTLS_E_INIT_LIBEXTRA; + } + if ((ret = + _E_gnutls_openpgp_cert2gnutls_cert( &peer_cert, + info->raw_certificate_list[0])) < 0) { + gnutls_assert(); + return 0; + } + break; + + default: + gnutls_assert(); + return 0; + } + + if ( _gnutls_mpi_get_nbits( peer_cert.params[0]) + <= 512) { + _gnutls_free_cert( peer_cert); + return 1; + } + + _gnutls_free_cert( peer_cert); + + return 0; +} static int proc_rsa_export_server_kx(GNUTLS_STATE state, opaque * data, int data_size) @@ -184,15 +243,17 @@ static int proc_rsa_export_server_kx(GNUTLS_STATE state, opaque * data, int i, sigsize; gnutls_datum vparams, signature; int ret; - CERTIFICATE_AUTH_INFO info = _gnutls_get_auth_info( state); + CERTIFICATE_AUTH_INFO info; gnutls_cert peer_cert; + info = _gnutls_get_auth_info( state); if (info == NULL || info->ncerts==0) { gnutls_assert(); /* we need this in order to get peer's certificate */ return GNUTLS_E_UNKNOWN_ERROR; } + i = 0; DECR_LEN( data_size, 2); diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c index 5ceac92266..2fa4ec6784 100644 --- a/lib/gnutls_kx.c +++ b/lib/gnutls_kx.c @@ -34,6 +34,7 @@ #include <gnutls_state.h> #include <gnutls_datum.h> #include <gnutls_alert.h> +#include <gnutls_rsa_export.h> /* This file contains important thing for the TLS handshake procedure. */ @@ -103,6 +104,11 @@ int _gnutls_send_server_kx_message( GNUTLS_STATE state, int again) if (again == 0) { data_size = state->gnutls_internals.auth_struct->gnutls_generate_server_kx( state, &data); + if (data_size == GNUTLS_E_INT_RET_0) { + gnutls_assert(); + return 0; + } + if (data_size < 0) { gnutls_assert(); return data_size; @@ -302,24 +308,36 @@ int _gnutls_send_client_certificate_verify( GNUTLS_STATE state, int again) int _gnutls_recv_server_kx_message( GNUTLS_STATE state) { - uint8 *data; + uint8 *data = NULL; int datasize; int ret = 0; if (state->gnutls_internals.auth_struct->gnutls_process_server_kx!=NULL) { + /* EXCEPTION FOR RSA_EXPORT cipher suite + */ + if ( _gnutls_session_is_export( state) != 0 && + _gnutls_peers_cert_less_512(state) != 0) { + gnutls_assert(); + return 0; + } + ret = _gnutls_recv_handshake( state, &data, &datasize, GNUTLS_SERVER_KEY_EXCHANGE, MANDATORY_PACKET); - if (ret < 0) + if (ret < 0) { + gnutls_assert(); return ret; + } ret = state->gnutls_internals.auth_struct->gnutls_process_server_kx( state, data, datasize); gnutls_free(data); - if (ret < 0) + if (ret < 0) { + gnutls_assert(); return ret; + } } return ret; diff --git a/lib/gnutls_rsa_export.h b/lib/gnutls_rsa_export.h index 7bef5e8275..3c0800dacb 100644 --- a/lib/gnutls_rsa_export.h +++ b/lib/gnutls_rsa_export.h @@ -19,4 +19,5 @@ */ const GNUTLS_MPI* _gnutls_get_rsa_params(GNUTLS_RSA_PARAMS, int bits); +int _gnutls_peers_cert_less_512( GNUTLS_STATE state); diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c index 63cb76fa1e..2bd670bd25 100644 --- a/lib/gnutls_state.c +++ b/lib/gnutls_state.c @@ -37,6 +37,7 @@ #include <gnutls_state.h> #include <auth_cert.h> #include <auth_anon.h> +#include <gnutls_algorithms.h> #define CHECK_AUTH(auth, ret) if (gnutls_auth_get_type(state) != auth) { \ gnutls_assert(); \ @@ -693,6 +694,21 @@ int gnutls_session_is_resumed(GNUTLS_STATE state) return 0; } +/*- + * _gnutls_session_is_export - Used to check whether this session is of export grade + * @state: is a &GNUTLS_STATE structure. + * + * This function will return non zero if this session is of export grade. + * + -*/ +int _gnutls_session_is_export(GNUTLS_STATE state) +{ + if ( _gnutls_cipher_suite_get_kx_algo( state->security_parameters.current_cipher_suite) + == GNUTLS_KX_RSA_EXPORT) return 1; + + return 0; +} + /** * gnutls_state_get_ptr - Used to get the user pointer from the state structure * @state: is a &GNUTLS_STATE structure. diff --git a/lib/gnutls_state.h b/lib/gnutls_state.h index 36118ca655..bdb0bf27f8 100644 --- a/lib/gnutls_state.h +++ b/lib/gnutls_state.h @@ -30,6 +30,7 @@ void _gnutls_handshake_internal_state_clear( GNUTLS_STATE); int _gnutls_rsa_export_set_modulus_bits( GNUTLS_STATE state, int bits); int _gnutls_session_is_resumable( GNUTLS_STATE state); +int _gnutls_session_is_export( GNUTLS_STATE state); int _gnutls_openpgp_send_fingerprint( GNUTLS_STATE state); |