]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Corrected bug in DHE key exchange which prevented from parsing the given certificates...
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 25 Aug 2002 18:08:46 +0000 (18:08 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 25 Aug 2002 18:08:46 +0000 (18:08 +0000)
20 files changed:
lib/Makefile.am
lib/auth_cert.h
lib/auth_dhe.c
lib/auth_rsa.c
lib/auth_rsa_export.c [new file with mode: 0644]
lib/gnutls.h.in.in
lib/gnutls_algorithms.c
lib/gnutls_cert.c
lib/gnutls_dh_primes.c
lib/gnutls_errors.c
lib/gnutls_errors_int.h
lib/gnutls_int.h
lib/gnutls_kx.c
lib/gnutls_rsa_export.c [new file with mode: 0644]
lib/gnutls_rsa_export.h [new file with mode: 0644]
lib/gnutls_state.c
lib/gnutls_state.h
lib/gnutls_ui.c
lib/gnutls_ui.h
lib/gnutls_x509.c

index eeaa75c25e2cac0f0a171ddc185d5495fe75a173..a59e6b1b13cc04aff39a5004b87c1469131242bc 100644 (file)
@@ -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
 
index e6f8425ff057a7d919913ce0a794f38440258ed5..73a05d5295a02a5c7137c7457ee33ccf84b5940f 100644 (file)
@@ -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.
                                                 */
index e597b770b4cf93ccb13a886aadf7f1d6f6162170..7bec8731c2c0e25d32801178ac4adab5c8cd86f4 100644 (file)
@@ -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;
                        }
index 66474e4c0ace6c91a87cfc6378d20480a2c9cdd2..efd3f689fe1e31e2b335779fd25dd0d57e5a48e6 100644 (file)
@@ -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 (file)
index 0000000..460dbfe
--- /dev/null
@@ -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;
+}
index b9544b340a45d479684c5e070767bc47d659bdcf..ec889d93fcb2a883d28d66315e684163bfd07a59 100644 (file)
@@ -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);
index 50c3191ae863643bab8b1a4135da4b7cfb10ec69..f8d5ec7402ba255cf17429d85a85d7d25901f429 100644 (file)
@@ -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,
index a189bef81657e37eec4dd47fcf235d7131845c24..cf84172f9a513134417b51f335ffb8404ccd2f84 100644 (file)
@@ -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}
index e1e051b05d85c0f6b2ac630319cf0f1291824de4..1aa0349ef0cd3a84a74710bf137500b4c0a87bd1 100644 (file)
@@ -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.
index 1ce51c758a2b24047382f3925a361a2c7f6273dd..01a49978f29b7f76b780ca6f396b20d25a351be6 100644 (file)
@@ -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),
index e13ee70d67ce40b8c06aaedcf3f716b3ed577879..f47bb4914f76412c83286c259750b35257883dc8 100644 (file)
@@ -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
 
index ef6649069506970fc8bd8c364b0af0a63781004b..f138813f8dfa79e1faa1e9ec6518caf37978251a 100644 (file)
@@ -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);
index 6570d5a458dbc3cd401ee23f68bccd071914f853..5ceac9226607b497726910ca1eeebfdb290b57c3 100644 (file)
@@ -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 (file)
index 0000000..c4b8b82
--- /dev/null
@@ -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 (file)
index 0000000..7bef5e8
--- /dev/null
@@ -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);
+
index 09dbcd7b52a44df3ca455ab3eb5bdbc9f6b9d989..63cb76fa1e0f031e1a36f54b9d17e641c1c83128 100644 (file)
@@ -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: {
index d1a704dc2d0f63099629115d3976860000c0a05c..36118ca655ff4422b785e1ec8edf3179c19ec390 100644 (file)
@@ -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);
index 9bce05c51d0bbf3db892dcc05fae7202ec60df6d..44c9e1937e7f7feeca3e98e1b05c508e8c0702d8 100644 (file)
@@ -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;
+}
index d672f228f1f2c676cf26d008f22e0c1b83a58604..7ea287c00f7fede511f036b9074f0610ba997d92 100644 (file)
@@ -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 *);
index d5ca2897d9a8842b62842c126253a8df6987ca5e..eae87d606a09b8ec7450e063663017ea014da3db 100644 (file)
@@ -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;