diff options
-rw-r--r-- | lib/Makefile.am | 6 | ||||
-rw-r--r-- | lib/auth_cert.h | 5 | ||||
-rw-r--r-- | lib/auth_dhe.c | 2 | ||||
-rw-r--r-- | lib/auth_rsa.c | 60 | ||||
-rw-r--r-- | lib/auth_rsa_export.c | 294 | ||||
-rw-r--r-- | lib/gnutls.h.in.in | 20 | ||||
-rw-r--r-- | lib/gnutls_algorithms.c | 9 | ||||
-rw-r--r-- | lib/gnutls_cert.c | 1 | ||||
-rw-r--r-- | lib/gnutls_dh_primes.c | 8 | ||||
-rw-r--r-- | lib/gnutls_errors.c | 1 | ||||
-rw-r--r-- | lib/gnutls_errors_int.h | 1 | ||||
-rw-r--r-- | lib/gnutls_int.h | 24 | ||||
-rw-r--r-- | lib/gnutls_kx.c | 4 | ||||
-rw-r--r-- | lib/gnutls_rsa_export.c | 440 | ||||
-rw-r--r-- | lib/gnutls_rsa_export.h | 22 | ||||
-rw-r--r-- | lib/gnutls_state.c | 17 | ||||
-rw-r--r-- | lib/gnutls_state.h | 2 | ||||
-rw-r--r-- | lib/gnutls_ui.c | 38 | ||||
-rw-r--r-- | lib/gnutls_ui.h | 3 | ||||
-rw-r--r-- | lib/gnutls_x509.c | 4 |
20 files changed, 932 insertions, 29 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index eeaa75c25e..a59e6b1b13 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -18,7 +18,7 @@ EXTRA_DIST = debug.h gnutls_compress.h defines.h gnutls.asn pkix.asn \ gnutls_sig.h gnutls_mem.h x509_extensions.h gnutls_ui.h \ gnutls-api.tex io_debug.h ext_max_record.h gnutls_session_pack.h \ gnutls_alert.h gnutls_str.h gnutls_state.h gnutls_x509.h \ - ext_cert_type.h + ext_cert_type.h gnutls_rsa_export.h lib_LTLIBRARIES = libgnutls.la @@ -35,8 +35,8 @@ COBJECTS = gnutls_record.c gnutls_compress.c debug.c \ x509_sig_check.c pkix_asn1_tab.c gnutls_asn1_tab.c gnutls_mem.c \ x509_extensions.c auth_cert.c gnutls_ui.c gnutls_sig.c auth_dhe.c \ gnutls_dh_primes.c ext_max_record.c gnutls_alert.c gnutls_int_compat.c \ - gnutls_str.c gnutls_state.c gnutls_x509.c \ - ext_cert_type.c x509_xml.c + gnutls_str.c gnutls_state.c gnutls_x509.c ext_cert_type.c \ + x509_xml.c gnutls_rsa_export.c auth_rsa_export.c # Separate so we can create the documentation diff --git a/lib/auth_cert.h b/lib/auth_cert.h index e6f8425ff0..73a05d5295 100644 --- a/lib/auth_cert.h +++ b/lib/auth_cert.h @@ -8,6 +8,7 @@ */ typedef struct { GNUTLS_DH_PARAMS dh_params; + GNUTLS_RSA_PARAMS rsa_params; gnutls_cert ** cert_list; /* contains a list of a list of certificates. @@ -46,7 +47,7 @@ typedef struct { /* holds a sequence of the * RDNs of the CAs above. * This is better than - * generating it every time. + * generating on every handshake. */ gnutls_datum x509_rdn_sequence; } CERTIFICATE_CREDENTIALS_INT; @@ -61,6 +62,8 @@ typedef struct CERTIFICATE_AUTH_INFO_INT { int dh_secret_bits; /* bits of the DH (if DHE_RSA is used) */ int dh_prime_bits; int dh_peer_public_bits; + + int rsa_export_modulus_bits; gnutls_datum* raw_certificate_list; /* holds the raw certificate of the * peer. */ diff --git a/lib/auth_dhe.c b/lib/auth_dhe.c index e597b770b4..7bec8731c2 100644 --- a/lib/auth_dhe.c +++ b/lib/auth_dhe.c @@ -394,7 +394,7 @@ static int proc_dhe_server_kx(GNUTLS_STATE state, opaque * data, case GNUTLS_CRT_X509: if ((ret = _gnutls_x509_cert2gnutls_cert( &peer_cert, - info->raw_certificate_list[0], CERT_ONLY_PUBKEY|CERT_NO_COPY)) < 0) { + info->raw_certificate_list[0], CERT_NO_COPY)) < 0) { gnutls_assert(); return ret; } diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c index 66474e4c0a..efd3f689fe 100644 --- a/lib/auth_rsa.c +++ b/lib/auth_rsa.c @@ -41,9 +41,8 @@ #include <gnutls_x509.h> #include <gnutls_extra.h> -int gen_rsa_client_kx(GNUTLS_STATE, opaque **); -int proc_rsa_client_kx(GNUTLS_STATE, opaque *, int); - +int _gnutls_gen_rsa_client_kx(GNUTLS_STATE, opaque **); +int _gnutls_proc_rsa_client_kx(GNUTLS_STATE, opaque *, int); const MOD_AUTH_STRUCT rsa_auth_struct = { "RSA", @@ -52,7 +51,7 @@ const MOD_AUTH_STRUCT rsa_auth_struct = { NULL, /* gen server kx */ NULL, /* gen server kx2 */ NULL, /* gen client kx0 */ - gen_rsa_client_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 */ @@ -61,7 +60,7 @@ const MOD_AUTH_STRUCT rsa_auth_struct = { NULL, /* proc server kx */ NULL, /* proc server kx2 */ NULL, /* proc client kx0 */ - proc_rsa_client_kx, /* proc client kx */ + _gnutls_proc_rsa_client_kx, /* proc client kx */ _gnutls_proc_cert_client_cert_vrfy, /* proc client cert vrfy */ _gnutls_proc_cert_cert_req /* proc server cert request */ }; @@ -71,12 +70,36 @@ extern OPENPGP_CERT2GNUTLS_CERT _E_gnutls_openpgp_cert2gnutls_cert; /* This function reads the RSA parameters from peer's certificate; */ -static int _gnutls_get_public_rsa_params(GNUTLS_STATE state, GNUTLS_MPI params[MAX_PARAMS_SIZE], int* params_len) +int _gnutls_get_public_rsa_params(GNUTLS_STATE state, GNUTLS_MPI params[MAX_PARAMS_SIZE], int* params_len) { int ret; -CERTIFICATE_AUTH_INFO info = _gnutls_get_auth_info( state); +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); + if (info==NULL || info->ncerts==0) { gnutls_assert(); return GNUTLS_E_UNKNOWN_ERROR; @@ -126,7 +149,7 @@ int i; /* This function reads the RSA parameters from the private key */ -static int _gnutls_get_private_rsa_params(GNUTLS_STATE state, GNUTLS_MPI **params, int* params_size) +int _gnutls_get_private_rsa_params(GNUTLS_STATE state, GNUTLS_MPI **params, int* params_size) { int index; const GNUTLS_CERTIFICATE_CREDENTIALS cred; @@ -137,6 +160,23 @@ const GNUTLS_CERTIFICATE_CREDENTIALS cred; return GNUTLS_E_INSUFICIENT_CRED; } + if ( _gnutls_cipher_suite_get_kx_algo(state->security_parameters.current_cipher_suite) + == GNUTLS_KX_RSA_EXPORT) { + /* EXPORT case: */ + if (cred->rsa_params == NULL) { + gnutls_assert(); + return GNUTLS_E_NO_TEMPORARY_RSA_PARAMS; + } + + *params_size = RSA_PRIVATE_PARAMS; + *params = cred->rsa_params->params; + + return 0; + } + + /* non export cipher suites. */ + + if ( (index=state->gnutls_internals.selected_cert_index) < 0) { gnutls_assert(); return GNUTLS_E_UNKNOWN_ERROR; @@ -157,7 +197,7 @@ const GNUTLS_CERTIFICATE_CREDENTIALS cred; return GNUTLS_E_MEMORY_ERROR; \ } -int proc_rsa_client_kx(GNUTLS_STATE state, opaque * data, int data_size) +int _gnutls_proc_rsa_client_kx(GNUTLS_STATE state, opaque * data, int data_size) { gnutls_sdatum plaintext; gnutls_datum ciphertext; @@ -224,7 +264,7 @@ int proc_rsa_client_kx(GNUTLS_STATE state, opaque * data, int data_size) /* return RSA(random) using the peers public key */ -int gen_rsa_client_kx(GNUTLS_STATE state, opaque ** data) +int _gnutls_gen_rsa_client_kx(GNUTLS_STATE state, opaque ** data) { CERTIFICATE_AUTH_INFO auth = state->gnutls_key->auth_info; gnutls_datum sdata; /* data to send */ diff --git a/lib/auth_rsa_export.c b/lib/auth_rsa_export.c new file mode 100644 index 0000000000..460dbfecac --- /dev/null +++ b/lib/auth_rsa_export.c @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2000,2001,2002 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS. + * + * The GNUTLS library 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* This file contains the RSA key exchange part of the certificate + * authentication. + */ + +#include "gnutls_int.h" +#include "gnutls_auth_int.h" +#include "gnutls_errors.h" +#include "gnutls_dh.h" +#include "gnutls_num.h" +#include "libtasn1.h" +#include "gnutls_datum.h" +#include "auth_cert.h" +#include <gnutls_random.h> +#include <gnutls_pk.h> +#include <gnutls_algorithms.h> +#include <gnutls_global.h> +#include <x509_verify.h> +#include "debug.h" +#include <gnutls_sig.h> +#include <gnutls_x509.h> +#include <gnutls_extra.h> +#include <gnutls_rsa_export.h> +#include <gnutls_state.h> + +int _gnutls_gen_rsa_client_kx(GNUTLS_STATE, opaque **); +int _gnutls_proc_rsa_client_kx(GNUTLS_STATE, opaque *, int); +static int gen_rsa_export_server_kx(GNUTLS_STATE, opaque **); +static int proc_rsa_export_server_kx(GNUTLS_STATE, opaque *, int); + +const MOD_AUTH_STRUCT rsa_export_auth_struct = { + "RSA EXPORT", + _gnutls_gen_cert_server_certificate, + _gnutls_gen_cert_client_certificate, + gen_rsa_export_server_kx, + NULL, /* gen server kx2 */ + NULL, /* gen client kx0 */ + _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, + NULL, /* proc server kx2 */ + NULL, /* proc client kx0 */ + _gnutls_proc_rsa_client_kx, /* proc client kx */ + _gnutls_proc_cert_client_cert_vrfy, /* proc client cert vrfy */ + _gnutls_proc_cert_cert_req /* proc server cert request */ +}; + +extern OPENPGP_CERT2GNUTLS_CERT _E_gnutls_openpgp_cert2gnutls_cert; + + +static int gen_rsa_export_server_kx(GNUTLS_STATE state, opaque ** data) +{ + const GNUTLS_MPI *rsa_params; + size_t n_e, n_m; + uint8 *data_e, *data_m; + int ret = 0, data_size; + gnutls_cert *apr_cert_list; + gnutls_private_key *apr_pkey; + int apr_cert_list_length; + gnutls_datum signature, ddata; + CERTIFICATE_AUTH_INFO info; + const GNUTLS_CERTIFICATE_CREDENTIALS cred; + + cred = _gnutls_get_cred(state->gnutls_key, GNUTLS_CRD_CERTIFICATE, NULL); + if (cred == NULL) { + gnutls_assert(); + return GNUTLS_E_INSUFICIENT_CRED; + } + + /* find the appropriate certificate */ + if ((ret = + _gnutls_find_apr_cert(state, &apr_cert_list, + &apr_cert_list_length, + &apr_pkey)) < 0) { + gnutls_assert(); + return ret; + } + + rsa_params = _gnutls_get_rsa_params( cred->rsa_params, 512); + if (rsa_params == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + if ( (ret=_gnutls_auth_info_set( state, GNUTLS_CRD_CERTIFICATE, sizeof( CERTIFICATE_AUTH_INFO_INT), 0)) < 0) { + gnutls_assert(); + return ret; + } + + info = _gnutls_get_auth_info( state); + ret=_gnutls_rsa_export_set_modulus_bits( state, _gnutls_mpi_get_nbits(rsa_params[0])); + if (ret<0) { + gnutls_assert(); + return ret; + } + + _gnutls_mpi_print( NULL, &n_m, rsa_params[0]); + _gnutls_mpi_print( NULL, &n_e, rsa_params[1]); + + (*data) = gnutls_malloc(n_e + n_m + 4); + if (*data == NULL) { + return GNUTLS_E_MEMORY_ERROR; + } + + data_m = &(*data)[0]; + _gnutls_mpi_print( &data_m[2], &n_m, rsa_params[0]); + + _gnutls_write_uint16(n_m, data_m); + + data_e = &data_m[2 + n_m]; + _gnutls_mpi_print( &data_e[2], &n_e, rsa_params[1]); + + _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_pkey != NULL) { + if ((ret = + _gnutls_generate_sig_params(state, &apr_cert_list[0], + apr_pkey, &ddata, + &signature)) < 0) { + gnutls_assert(); + gnutls_free(*data); + return ret; + } + } else { + gnutls_assert(); + return data_size; /* do not put a signature - ILLEGAL! */ + } + + *data = gnutls_realloc(*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; +} + + +static int proc_rsa_export_server_kx(GNUTLS_STATE state, opaque * data, + int data_size) +{ + uint16 n_m, n_e; + size_t _n_m, _n_e; + uint8 *data_m; + uint8 *data_e; + int i, sigsize; + gnutls_datum vparams, signature; + int ret; + CERTIFICATE_AUTH_INFO info = _gnutls_get_auth_info( state); + gnutls_cert peer_cert; + + 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); + n_m = _gnutls_read_uint16(&data[i]); + i += 2; + + DECR_LEN( data_size, n_m); + data_m = &data[i]; + i += n_m; + if (i > data_size) { + gnutls_assert(); + return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; + } + + 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; + if (i > data_size) { + gnutls_assert(); + return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; + } + + _n_e = n_e; + _n_m = n_m; + + if (_gnutls_mpi_scan(&state->gnutls_key->rsa[0], data_m, &_n_m) != 0) { + gnutls_assert(); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + if (_gnutls_mpi_scan(&state->gnutls_key->rsa[1], data_e, &_n_e) != 0) { + gnutls_assert(); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + ret=_gnutls_rsa_export_set_modulus_bits( state, _gnutls_mpi_get_nbits( + state->gnutls_key->rsa[0])); + if (ret<0) { + gnutls_assert(); + return ret; + } + + /* 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; + + 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 ret; + } + 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 ret; + } + break; + + default: + gnutls_assert(); + return GNUTLS_E_UNKNOWN_ERROR; + } + + ret = + _gnutls_verify_sig_params(state, + &peer_cert, + &vparams, &signature); + + _gnutls_free_cert( peer_cert); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + return ret; +} diff --git a/lib/gnutls.h.in.in b/lib/gnutls.h.in.in index b9544b340a..ec889d93fc 100644 --- a/lib/gnutls.h.in.in +++ b/lib/gnutls.h.in.in @@ -42,7 +42,8 @@ typedef enum GNUTLS_BulkCipherAlgorithm { GNUTLS_CIPHER_NULL=1, } GNUTLS_BulkCipherAlgorithm; typedef enum GNUTLS_KXAlgorithm { GNUTLS_KX_RSA=1, GNUTLS_KX_DHE_DSS, - GNUTLS_KX_DHE_RSA, GNUTLS_KX_ANON_DH, GNUTLS_KX_SRP + GNUTLS_KX_DHE_RSA, GNUTLS_KX_ANON_DH, GNUTLS_KX_SRP, + GNUTLS_KX_RSA_EXPORT } GNUTLS_KXAlgorithm; typedef enum GNUTLS_CredType { GNUTLS_CRD_CERTIFICATE=1, GNUTLS_CRD_ANON, GNUTLS_CRD_SRP } GNUTLS_CredType; @@ -111,6 +112,9 @@ typedef struct GNUTLS_STATE_INT* GNUTLS_STATE; struct GNUTLS_DH_PARAMS_INT; typedef struct GNUTLS_DH_PARAMS_INT* GNUTLS_DH_PARAMS; +struct GNUTLS_RSA_PARAMS_INT; +typedef struct GNUTLS_RSA_PARAMS_INT* GNUTLS_RSA_PARAMS; + typedef struct { unsigned char * data; int size; @@ -266,6 +270,7 @@ int gnutls_certificate_allocate_cred( GNUTLS_CERTIFICATE_CREDENTIALS *sc); #define gnutls_certificate_allocate_sc gnutls_certificate_allocate_cred int gnutls_certificate_set_dh_params(GNUTLS_CERTIFICATE_CREDENTIALS res, GNUTLS_DH_PARAMS); +int gnutls_certificate_set_rsa_params(GNUTLS_CERTIFICATE_CREDENTIALS res, GNUTLS_RSA_PARAMS rsa_params); int gnutls_certificate_set_x509_trust_file( GNUTLS_CERTIFICATE_CREDENTIALS res, const char* CAFILE, GNUTLS_X509_CertificateFmt); @@ -297,11 +302,24 @@ typedef void (*GNUTLS_LOG_FUNC)( const char*); void gnutls_global_set_log_function( GNUTLS_LOG_FUNC log_func); #define gnutls_global_set_log_func gnutls_global_set_log_function +/* DH params */ int gnutls_dh_params_set( GNUTLS_DH_PARAMS, gnutls_datum prime, gnutls_datum generator, int bits); int gnutls_dh_params_init( GNUTLS_DH_PARAMS*); void gnutls_dh_params_deinit( GNUTLS_DH_PARAMS); int gnutls_dh_params_generate( gnutls_datum* prime, gnutls_datum* generator, int bits); +/* RSA params */ +int gnutls_rsa_params_set(GNUTLS_RSA_PARAMS rsa_params, + gnutls_datum m, gnutls_datum e, gnutls_datum d, + gnutls_datum p, gnutls_datum q, gnutls_datum u, + int bits); +int gnutls_rsa_params_generate(gnutls_datum * m, gnutls_datum *e, + gnutls_datum *d, gnutls_datum *p, gnutls_datum* q, + gnutls_datum* u, int bits); +int gnutls_rsa_params_init(GNUTLS_RSA_PARAMS * rsa_params); +void gnutls_rsa_params_deinit(GNUTLS_RSA_PARAMS rsa_params); + + typedef ssize_t (*GNUTLS_PULL_FUNC)(GNUTLS_TRANSPORT_PTR, void*, size_t); typedef ssize_t (*GNUTLS_PUSH_FUNC)(GNUTLS_TRANSPORT_PTR, const void*, size_t); void gnutls_transport_set_ptr(GNUTLS_STATE state, GNUTLS_TRANSPORT_PTR ptr); diff --git a/lib/gnutls_algorithms.c b/lib/gnutls_algorithms.c index 50c3191ae8..f8d5ec7402 100644 --- a/lib/gnutls_algorithms.c +++ b/lib/gnutls_algorithms.c @@ -34,6 +34,7 @@ typedef struct { static const gnutls_cred_map cred_mappings[] = { { GNUTLS_KX_ANON_DH, GNUTLS_CRD_ANON }, { GNUTLS_KX_RSA, GNUTLS_CRD_CERTIFICATE }, + { GNUTLS_KX_RSA_EXPORT, GNUTLS_CRD_CERTIFICATE }, { GNUTLS_KX_DHE_DSS, GNUTLS_CRD_CERTIFICATE }, { GNUTLS_KX_DHE_RSA, GNUTLS_CRD_CERTIFICATE }, { GNUTLS_KX_SRP, GNUTLS_CRD_SRP }, @@ -162,6 +163,7 @@ static const gnutls_compression_entry compression_algorithms[] = { extern MOD_AUTH_STRUCT rsa_auth_struct; +extern MOD_AUTH_STRUCT rsa_export_auth_struct; extern MOD_AUTH_STRUCT dhe_rsa_auth_struct; extern MOD_AUTH_STRUCT dhe_dss_auth_struct; extern MOD_AUTH_STRUCT anon_auth_struct; @@ -175,6 +177,7 @@ gnutls_kx_algo_entry _gnutls_kx_algorithms[MAX_KX_ALGOS] = { { "Anon DH", GNUTLS_KX_ANON_DH, &anon_auth_struct }, #endif { "RSA", GNUTLS_KX_RSA, &rsa_auth_struct }, + { "RSA EXPORT", GNUTLS_KX_RSA_EXPORT, &rsa_export_auth_struct }, { "DHE RSA", GNUTLS_KX_DHE_RSA, &dhe_rsa_auth_struct }, { "DHE DSS", GNUTLS_KX_DHE_DSS, &dhe_dss_auth_struct }, {0} @@ -243,7 +246,7 @@ typedef struct { #define GNUTLS_RSA_ARCFOUR_MD5 { 0x00, 0x04 } #define GNUTLS_RSA_3DES_EDE_CBC_SHA { 0x00, 0x0A } -#define GNUTLS_RSA_ARCFOUR_EXPORT_MD5 { 0x00, 0x03 } +#define GNUTLS_RSA_EXPORT_ARCFOUR_EXPORT_MD5 { 0x00, 0x03 } /* draft-ietf-tls-ciphersuite-05: */ @@ -363,9 +366,9 @@ static const gnutls_cipher_suite_entry cs_algorithms[] = { GNUTLS_CIPHER_NULL, GNUTLS_KX_RSA, GNUTLS_MAC_MD5, GNUTLS_SSL3), - GNUTLS_CIPHER_SUITE_ENTRY(GNUTLS_RSA_ARCFOUR_EXPORT_MD5, + GNUTLS_CIPHER_SUITE_ENTRY(GNUTLS_RSA_EXPORT_ARCFOUR_EXPORT_MD5, GNUTLS_CIPHER_ARCFOUR_EXPORT, - GNUTLS_KX_RSA, GNUTLS_MAC_MD5, GNUTLS_SSL3), + GNUTLS_KX_RSA_EXPORT, GNUTLS_MAC_MD5, GNUTLS_SSL3), GNUTLS_CIPHER_SUITE_ENTRY(GNUTLS_RSA_ARCFOUR_SHA, GNUTLS_CIPHER_ARCFOUR, diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c index a189bef816..cf84172f9a 100644 --- a/lib/gnutls_cert.c +++ b/lib/gnutls_cert.c @@ -55,6 +55,7 @@ typedef struct { */ static const gnutls_pk_map pk_mappings[] = { {GNUTLS_KX_RSA, GNUTLS_PK_RSA}, + {GNUTLS_KX_RSA_EXPORT, GNUTLS_PK_RSA}, {GNUTLS_KX_DHE_RSA, GNUTLS_PK_RSA}, {GNUTLS_KX_DHE_DSS, GNUTLS_PK_DSA}, {0} diff --git a/lib/gnutls_dh_primes.c b/lib/gnutls_dh_primes.c index e1e051b05d..1aa0349ef0 100644 --- a/lib/gnutls_dh_primes.c +++ b/lib/gnutls_dh_primes.c @@ -623,10 +623,10 @@ int gnutls_dh_params_init(GNUTLS_DH_PARAMS * dh_params) } /** - * gnutls_dh_params_deinit - This function will initialize the DH parameters - * @dh_params: Is a structure that will hold the prime numbers + * gnutls_dh_params_deinit - This function will deinitialize the DH parameters + * @dh_params: Is a structure that holds the prime numbers * - * This function will initialize the DH parameters structure. + * This function will deinitialize the DH parameters structure. * **/ void gnutls_dh_params_deinit(GNUTLS_DH_PARAMS dh_params) @@ -663,7 +663,7 @@ void gnutls_dh_params_deinit(GNUTLS_DH_PARAMS dh_params) * the Diffie-Hellman key exchange. The new parameters will be allocated using * malloc and will be stored in the appropriate datum. * This function is normally very slow. An other function - * (gnutls_dh_replace_params()) should be called in order to replace the + * (gnutls_dh_params_set()) should be called in order to replace the * included DH primes in the gnutls library. * * Note that the bits value should be one of 768, 1024, 2048, 3072 or 4096. diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c index 1ce51c758a..01a49978f2 100644 --- a/lib/gnutls_errors.c +++ b/lib/gnutls_errors.c @@ -65,6 +65,7 @@ static gnutls_error_entry error_algorithms[] = { GNUTLS_ERROR_ENTRY( GNUTLS_E_WARNING_ALERT_RECEIVED, 0), GNUTLS_ERROR_ENTRY( GNUTLS_E_ERROR_IN_FINISHED_PACKET, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_NO_CERTIFICATE_FOUND, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_NO_TEMPORARY_RSA_PARAMS, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_KX_ALGORITHM, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_MPI_SCAN_FAILED, 1), diff --git a/lib/gnutls_errors_int.h b/lib/gnutls_errors_int.h index e13ee70d67..f47bb4914f 100644 --- a/lib/gnutls_errors_int.h +++ b/lib/gnutls_errors_int.h @@ -85,6 +85,7 @@ #define GNUTLS_E_INIT_LIBEXTRA -82 #define GNUTLS_E_LIBRARY_VERSION_MISMATCH -82 #define GNUTLS_E_EXPORT_CIPHER_SUITE -83 +#define GNUTLS_E_NO_TEMPORARY_RSA_PARAMS -84 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -250 diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index ef66490695..f138813f8d 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -37,6 +37,9 @@ #define DEBUG */ +#define HANDSHAKE_DEBUG // Prints some information on handshake +#define DEBUG + /* It might be a good idea to replace int with void* * here. */ @@ -165,7 +168,8 @@ typedef enum Extensions { GNUTLS_EXTENSION_MAX_RECORD_SIZE=1, GNUTLS_EXTENSION_S } Extensions; typedef enum KXAlgorithm { GNUTLS_KX_RSA=1, GNUTLS_KX_DHE_DSS, - GNUTLS_KX_DHE_RSA, GNUTLS_KX_ANON_DH, GNUTLS_KX_SRP + GNUTLS_KX_DHE_RSA, GNUTLS_KX_ANON_DH, GNUTLS_KX_SRP, + GNUTLS_KX_RSA_EXPORT } KXAlgorithm; #define GNUTLS_KXAlgorithm KXAlgorithm @@ -247,9 +251,9 @@ struct GNUTLS_KEY_INT { MPI b; MPI a; MPI x; - - /* RSA: does not use these. + /* RSA: e, m */ + MPI rsa[2]; /* this is used to hold the peers authentication data */ @@ -316,6 +320,11 @@ typedef struct { /* if you add anything in Security_Parameters struct, then * also modify CPY_COMMON in gnutls_constate.c */ + +/* Note that the security parameters structure is set up after the + * handshake has finished. The only value you may depend on while + * the handshake is in progress is the cipher suite value. + */ typedef struct { ConnectionEnd entity; KXAlgorithm kx_algorithm; @@ -604,6 +613,15 @@ typedef struct { #define GNUTLS_DH_PARAMS _GNUTLS_DH_PARAMS* + +typedef struct { + int bits; + MPI params[RSA_PRIVATE_PARAMS]; +} _GNUTLS_RSA_PARAMS; + +#define GNUTLS_RSA_PARAMS _GNUTLS_RSA_PARAMS* + + /* functions */ void _gnutls_set_current_version(GNUTLS_STATE state, GNUTLS_Version version); GNUTLS_Version gnutls_protocol_get_version(GNUTLS_STATE state); diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c index 6570d5a458..5ceac92266 100644 --- a/lib/gnutls_kx.c +++ b/lib/gnutls_kx.c @@ -102,7 +102,7 @@ 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 < 0) { gnutls_assert(); return data_size; @@ -315,9 +315,9 @@ int _gnutls_recv_server_kx_message( GNUTLS_STATE state) if (ret < 0) return ret; - ret = state->gnutls_internals.auth_struct->gnutls_process_server_kx( state, data, datasize); gnutls_free(data); + if (ret < 0) return ret; diff --git a/lib/gnutls_rsa_export.c b/lib/gnutls_rsa_export.c new file mode 100644 index 0000000000..c4b8b82056 --- /dev/null +++ b/lib/gnutls_rsa_export.c @@ -0,0 +1,440 @@ +/* + * Copyright (C) 2002 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS. + * + * The GNUTLS library 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* This file contains code for RSA temporary keys. These keys are + * only used in export cipher suites. + */ + +#include <gnutls_int.h> +#include <gnutls_errors.h> +#include <gnutls_datum.h> +#include "debug.h" + +/* This function takes a number of bits and returns a supported + * number of bits. Ie a number of bits that we have a prime in the + * dh_primes structure. + */ +static int supported_bits[] = { 512, 0 }; +static int normalize_bits(int bits) +{ + if (bits >= 512) + bits = 512; + + return bits; +} + + +/* returns e and m, depends on the requested bits. + * We only support limited key sizes. + */ +const GNUTLS_MPI* _gnutls_get_rsa_params(GNUTLS_RSA_PARAMS rsa_params, int bits) +{ + if (rsa_params == NULL) { + gnutls_assert(); + return NULL; + } + + bits = normalize_bits(bits); + + return rsa_params->params; + +} + +/* resarr will contain: modulus(0), public exponent(1), private exponent(2), + * prime1 - p (3), prime2 - q(4), u (5). + */ +int _gnutls_rsa_generate_params(GNUTLS_MPI* resarr, int bits) +{ + + int ret; + GCRY_SEXP parms, key, list; + + ret = gcry_sexp_build( &parms, NULL, "(genkey(rsa(nbits %d)))", bits); + if (ret != 0) { + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } + + /* generate the RSA key */ + ret = gcry_pk_genkey( &key, parms); + gcry_sexp_release( parms); + + if (ret != 0) { + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } + + list = gcry_sexp_find_token( key, "n", 0); + if (list == NULL) { + gnutls_assert(); + gcry_sexp_release( key); + return GNUTLS_E_UNKNOWN_ERROR; + } + + resarr[0] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + list = gcry_sexp_find_token( key, "e", 0); + if (list == NULL) { + gnutls_assert(); + gcry_sexp_release( key); + return GNUTLS_E_UNKNOWN_ERROR; + } + + resarr[1] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + list = gcry_sexp_find_token( key, "d", 0); + if (list == NULL) { + gnutls_assert(); + gcry_sexp_release( key); + return GNUTLS_E_UNKNOWN_ERROR; + } + + resarr[2] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + list = gcry_sexp_find_token( key, "p", 0); + if (list == NULL) { + gnutls_assert(); + gcry_sexp_release( key); + return GNUTLS_E_UNKNOWN_ERROR; + } + + resarr[3] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + + list = gcry_sexp_find_token( key, "q", 0); + if (list == NULL) { + gnutls_assert(); + gcry_sexp_release( key); + return GNUTLS_E_UNKNOWN_ERROR; + } + + resarr[4] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + + list = gcry_sexp_find_token( key, "u", 0); + if (list == NULL) { + gnutls_assert(); + gcry_sexp_release( key); + return GNUTLS_E_UNKNOWN_ERROR; + } + + resarr[5] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + gcry_sexp_release(key); + + return 0; + +} + +/* returns a negative value if the bits is not supported + */ +static int check_bits(int bits) +{ + int i = 0; + do { + if (supported_bits[i] == bits) + return 0; + i++; + } while (supported_bits[i] != 0); + + gnutls_assert(); + return GNUTLS_E_INVALID_PARAMETERS; +} + +#define FREE_PRIVATE_PARAMS for (i=0;i<RSA_PRIVATE_PARAMS;i++) \ + _gnutls_mpi_release(&rsa_params->params[i]) + + +/** + * gnutls_rsa_params_set - This function will replace the old RSA parameters + * @rsa_params: Is a structure will hold the parameters + * @m: holds the modulus + * @e: holds the public exponent + * @d: holds the private exponent + * @p: holds the first prime (p) + * @q: holds the second prime (q) + * @u: holds the coefficient + * @bits: is the prime's number of bits + * + * This function will replace the pair of prime and generator for use in + * the Diffie-Hellman key exchange. The new parameters should be stored in the + * appropriate gnutls_datum. + * + * Note that the bits value should be one of 768, 1024, 2048, 3072 or 4096. + * + **/ +int gnutls_rsa_params_set(GNUTLS_RSA_PARAMS rsa_params, + gnutls_datum m, gnutls_datum e, + gnutls_datum d, gnutls_datum p, gnutls_datum q, gnutls_datum u, + int bits) +{ + int i = 0; + size_t siz = 0; + + if (check_bits(bits) < 0) { + gnutls_assert(); + return GNUTLS_E_INVALID_PARAMETERS; + } + + for (i=0;i<RSA_PRIVATE_PARAMS;i++) { + _gnutls_mpi_release(&rsa_params->params[i]); + } + + siz = m.size; + if (_gnutls_mpi_scan(&rsa_params->params[0], m.data, &siz)) { + gnutls_assert(); + FREE_PRIVATE_PARAMS; + return GNUTLS_E_MPI_SCAN_FAILED; + } + + siz = e.size; + if (_gnutls_mpi_scan(&rsa_params->params[1], e.data, &siz)) { + gnutls_assert(); + FREE_PRIVATE_PARAMS; + return GNUTLS_E_MPI_SCAN_FAILED; + } + + siz = d.size; + if (_gnutls_mpi_scan(&rsa_params->params[2], d.data, &siz)) { + gnutls_assert(); + FREE_PRIVATE_PARAMS; + return GNUTLS_E_MPI_SCAN_FAILED; + } + + siz = p.size; + if (_gnutls_mpi_scan(&rsa_params->params[3], p.data, &siz)) { + gnutls_assert(); + FREE_PRIVATE_PARAMS; + return GNUTLS_E_MPI_SCAN_FAILED; + } + + siz = q.size; + if (_gnutls_mpi_scan(&rsa_params->params[4], q.data, &siz)) { + gnutls_assert(); + FREE_PRIVATE_PARAMS; + return GNUTLS_E_MPI_SCAN_FAILED; + } + + siz = u.size; + if (_gnutls_mpi_scan(&rsa_params->params[5], u.data, &siz)) { + gnutls_assert(); + FREE_PRIVATE_PARAMS; + return GNUTLS_E_MPI_SCAN_FAILED; + } + + return 0; + +} + +/** + * gnutls_rsa_params_init - This function will initialize the temporary RSA parameters + * @rsa_params: Is a structure that will hold the parameters + * + * This function will initialize the temporary RSA parameters structure. + * + **/ +int gnutls_rsa_params_init(GNUTLS_RSA_PARAMS * rsa_params) +{ + + *rsa_params = gnutls_calloc( 1, sizeof(_GNUTLS_RSA_PARAMS)); + if (*rsa_params==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + return 0; + +} + +/** + * gnutls_rsa_params_deinit - This function will deinitialize the RSA parameters + * @rsa_params: Is a structure that holds the parameters + * + * This function will deinitialize the RSA parameters structure. + * + **/ +void gnutls_rsa_params_deinit(GNUTLS_RSA_PARAMS rsa_params) +{ +int i; + + if (rsa_params == NULL) + return; + + for (i=0; i< RSA_PRIVATE_PARAMS;i++) + _gnutls_mpi_release( &rsa_params->params[i]); + + gnutls_free(rsa_params); + +} + +#define FREE_ALL_MPIS for (i=0;i<sizeof(rsa_params)/sizeof(GNUTLS_MPI);i++) \ + _gnutls_mpi_release( &rsa_params[i]) \ + +/** + * gnutls_rsa_params_generate - This function will generate temporary RSA parameters + * @m: will hold the modulus + * @e: will hold the public exponent + * @d: will hold the private exponent + * @p: will hold the first prime (p) + * @q: will hold the second prime (q) + * @u: will hold the coefficient + * @bits: is the prime's number of bits + * + * This function will generate new temporary RSA parameters for use in + * RSA-EXPORT ciphersuites. The new parameters will be allocated using + * malloc and will be stored in the appropriate datum. + * This function is normally slow. An other function + * (gnutls_rsa_params_set()) should be called in order to use the + * generated RSA parameters. + * + * Note that the bits value should be 512. + * Also note that the generation of new RSA parameters is only usefull + * to servers. Clients use the parameters sent by the server, thus it's + * no use calling this in client side. + * + **/ +int gnutls_rsa_params_generate(gnutls_datum * m, gnutls_datum *e, + gnutls_datum *d, gnutls_datum *p, gnutls_datum* q, + gnutls_datum* u, int bits) +{ + + GNUTLS_MPI rsa_params[RSA_PRIVATE_PARAMS]; + size_t siz; + int i, ret; + + if (check_bits(bits) < 0) { + gnutls_assert(); + return GNUTLS_E_INVALID_PARAMETERS; + } + + ret = _gnutls_rsa_generate_params( rsa_params, bits); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + siz = 0; + _gnutls_mpi_print(NULL, &siz, rsa_params[0]); + + m->data = malloc(siz); + if (m->data == NULL) { + FREE_ALL_MPIS; + return GNUTLS_E_MEMORY_ERROR; + } + + m->size = siz; + _gnutls_mpi_print( m->data, &siz, rsa_params[0]); + + /* E */ + siz = 0; + _gnutls_mpi_print(NULL, &siz, rsa_params[1]); + + e->data = malloc(siz); + if (e->data == NULL) { + FREE_ALL_MPIS; + gnutls_free_datum( m); + return GNUTLS_E_MEMORY_ERROR; + } + + e->size = siz; + _gnutls_mpi_print( e->data, &siz, rsa_params[1]); + + /* D */ + siz = 0; + _gnutls_mpi_print(NULL, &siz, rsa_params[2]); + + d->data = malloc(siz); + if (d->data == NULL) { + FREE_ALL_MPIS; + gnutls_free_datum( m); + gnutls_free_datum( e); + return GNUTLS_E_MEMORY_ERROR; + } + + d->size = siz; + _gnutls_mpi_print( d->data, &siz, rsa_params[2]); + + /* P */ + siz = 0; + _gnutls_mpi_print(NULL, &siz, rsa_params[3]); + + p->data = malloc(siz); + if (p->data == NULL) { + FREE_ALL_MPIS; + gnutls_free_datum( m); + gnutls_free_datum( e); + gnutls_free_datum( d); + return GNUTLS_E_MEMORY_ERROR; + } + + p->size = siz; + _gnutls_mpi_print(p->data, &siz, rsa_params[3]); + + /* Q */ + siz = 0; + _gnutls_mpi_print(NULL, &siz, rsa_params[4]); + + q->data = malloc(siz); + if (q->data == NULL) { + FREE_ALL_MPIS; + gnutls_free_datum( m); + gnutls_free_datum( e); + gnutls_free_datum( d); + gnutls_free_datum( p); + return GNUTLS_E_MEMORY_ERROR; + } + + q->size = siz; + _gnutls_mpi_print(q->data, &siz, rsa_params[4]); + + /* U */ + siz = 0; + _gnutls_mpi_print(NULL, &siz, rsa_params[5]); + + u->data = malloc(siz); + if (u->data == NULL) { + FREE_ALL_MPIS; + gnutls_free_datum( m); + gnutls_free_datum( e); + gnutls_free_datum( d); + gnutls_free_datum( p); + gnutls_free_datum( q); + return GNUTLS_E_MEMORY_ERROR; + } + + u->size = siz; + _gnutls_mpi_print(u->data, &siz, rsa_params[5]); + + FREE_ALL_MPIS; + + _gnutls_log("Generated %d bits modulus %s, exponent %s.\n", + bits, _gnutls_bin2hex(m->data, m->size), + _gnutls_bin2hex( e->data, e->size)); + + return 0; + +} diff --git a/lib/gnutls_rsa_export.h b/lib/gnutls_rsa_export.h new file mode 100644 index 0000000000..7bef5e8275 --- /dev/null +++ b/lib/gnutls_rsa_export.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2000,2002 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS. + * + * GNUTLS is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GNUTLS 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +const GNUTLS_MPI* _gnutls_get_rsa_params(GNUTLS_RSA_PARAMS, int bits); + diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c index 09dbcd7b52..63cb76fa1e 100644 --- a/lib/gnutls_state.c +++ b/lib/gnutls_state.c @@ -283,6 +283,10 @@ void _gnutls_deinit(GNUTLS_STATE state) _gnutls_mpi_release(&state->gnutls_key->B); _gnutls_mpi_release(&state->gnutls_key->b); + /* RSA */ + _gnutls_mpi_release(&state->gnutls_key->rsa[0]); + _gnutls_mpi_release(&state->gnutls_key->rsa[1]); + _gnutls_mpi_release(&state->gnutls_key->dh_secret); _gnutls_free(state->gnutls_key); @@ -380,6 +384,19 @@ int _gnutls_dh_set_secret_bits( GNUTLS_STATE state, int bits) { return 0; } +int _gnutls_rsa_export_set_modulus_bits( GNUTLS_STATE state, int bits) { + CERTIFICATE_AUTH_INFO info; + + info = _gnutls_get_auth_info(state); + if (info == NULL) + return GNUTLS_E_UNKNOWN_ERROR; + + info->rsa_export_modulus_bits = bits; + + return 0; +} + + int _gnutls_dh_set_prime_bits( GNUTLS_STATE state, int bits) { switch( gnutls_auth_get_type( state)) { case GNUTLS_CRD_ANON: { diff --git a/lib/gnutls_state.h b/lib/gnutls_state.h index d1a704dc2d..36118ca655 100644 --- a/lib/gnutls_state.h +++ b/lib/gnutls_state.h @@ -27,6 +27,8 @@ int _gnutls_dh_get_prime_bits( GNUTLS_STATE state); void gnutls_dh_set_prime_bits( GNUTLS_STATE state, int bits); 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_openpgp_send_fingerprint( GNUTLS_STATE state); diff --git a/lib/gnutls_ui.c b/lib/gnutls_ui.c index 9bce05c51d..44c9e1937e 100644 --- a/lib/gnutls_ui.c +++ b/lib/gnutls_ui.c @@ -119,6 +119,27 @@ int gnutls_dh_get_secret_bits(GNUTLS_STATE state) } } + +/** + * gnutls_rsa_export_get_modulus_bits - This function returns the bits used in RSA-export key exchange + * @state: is a gnutls state + * + * This function will return the bits used in the last RSA-EXPORT key exchange + * with the peer. + * Returns a negative value in case of an error. + * + **/ +int gnutls_rsa_export_get_modulus_bits(GNUTLS_STATE state) +{ +CERTIFICATE_AUTH_INFO info; + + info = _gnutls_get_auth_info(state); + if (info == NULL) + return GNUTLS_E_UNKNOWN_ERROR; + + return info->rsa_export_modulus_bits; +} + /** * gnutls_dh_get_peers_public_bits - This function returns the bits used in DH authentication * @state: is a gnutls state @@ -287,7 +308,7 @@ void gnutls_anon_set_server_dh_params( GNUTLS_ANON_SERVER_CREDENTIALS res, GNUTL } /** - * gnutls_certificate_set_server_dh_params - This function will set the DH parameters for a server to use + * gnutls_certificate_set_dh_params - This function will set the DH parameters for a server to use * @res: is a GNUTLS_CERTIFICATE_CREDENTIALS structure * @dh_params: is a structure that holds diffie hellman parameters. * @@ -300,3 +321,18 @@ int gnutls_certificate_set_dh_params(GNUTLS_CERTIFICATE_CREDENTIALS res, GNUTLS_ res->dh_params = dh_params; return 0; } + +/** + * gnutls_certificate_set_rsa_params - This function will set the RSA parameters for a server to use + * @res: is a GNUTLS_CERTIFICATE_CREDENTIALS structure + * @rsa_params: is a structure that holds temporary RSA parameters. + * + * This function will set the temporary RSA parameters for a certificate + * server to use. These parameters will be used in RSA-EXPORT + * cipher suites. + * + **/ +int gnutls_certificate_set_rsa_params(GNUTLS_CERTIFICATE_CREDENTIALS res, GNUTLS_RSA_PARAMS rsa_params) { + res->rsa_params = rsa_params; + return 0; +} diff --git a/lib/gnutls_ui.h b/lib/gnutls_ui.h index d672f228f1..7ea287c00f 100644 --- a/lib/gnutls_ui.h +++ b/lib/gnutls_ui.h @@ -66,6 +66,9 @@ int gnutls_dh_get_prime_bits( GNUTLS_STATE); int gnutls_dh_get_secret_bits( GNUTLS_STATE); int gnutls_dh_get_peers_public_bits( GNUTLS_STATE); +/* RSA */ +int gnutls_rsa_export_get_modulus_bits(GNUTLS_STATE state); + /* X509PKI */ void gnutls_certificate_client_set_select_function( GNUTLS_STATE, gnutls_certificate_client_select_function *); diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c index d5ca2897d9..eae87d606a 100644 --- a/lib/gnutls_x509.c +++ b/lib/gnutls_x509.c @@ -2166,6 +2166,10 @@ int _gnutls_check_x509_key_usage(const gnutls_cert * cert, return 0; } return 0; + + case GNUTLS_KX_RSA_EXPORT: + return 0; + default: gnutls_assert(); return GNUTLS_E_X509_KEY_USAGE_VIOLATION; |