summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Makefile.am6
-rw-r--r--lib/auth_cert.h5
-rw-r--r--lib/auth_dhe.c2
-rw-r--r--lib/auth_rsa.c60
-rw-r--r--lib/auth_rsa_export.c294
-rw-r--r--lib/gnutls.h.in.in20
-rw-r--r--lib/gnutls_algorithms.c9
-rw-r--r--lib/gnutls_cert.c1
-rw-r--r--lib/gnutls_dh_primes.c8
-rw-r--r--lib/gnutls_errors.c1
-rw-r--r--lib/gnutls_errors_int.h1
-rw-r--r--lib/gnutls_int.h24
-rw-r--r--lib/gnutls_kx.c4
-rw-r--r--lib/gnutls_rsa_export.c440
-rw-r--r--lib/gnutls_rsa_export.h22
-rw-r--r--lib/gnutls_state.c17
-rw-r--r--lib/gnutls_state.h2
-rw-r--r--lib/gnutls_ui.c38
-rw-r--r--lib/gnutls_ui.h3
-rw-r--r--lib/gnutls_x509.c4
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;