summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS11
-rw-r--r--configure.in4
-rw-r--r--doc/examples/Makefile.am2
-rw-r--r--doc/tex/Makefile.am2
-rw-r--r--doc/tex/auth.tex62
-rw-r--r--doc/tex/examples.tex7
-rw-r--r--doc/tex/preparation.tex62
-rw-r--r--includes/gnutls/x509.h1
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/auth_anon.c8
-rw-r--r--lib/auth_anon.h7
-rw-r--r--lib/auth_cert.h9
-rw-r--r--lib/auth_dhe.c8
-rw-r--r--lib/auth_rsa.c6
-rw-r--r--lib/auth_rsa_export.c18
-rw-r--r--lib/gnutls.h.in.in6
-rw-r--r--lib/gnutls_anon_cred.c32
-rw-r--r--lib/gnutls_cert.c63
-rw-r--r--lib/gnutls_cert.h2
-rw-r--r--lib/gnutls_dh.h1
-rw-r--r--lib/gnutls_dh_primes.c24
-rw-r--r--lib/gnutls_global.c8
-rw-r--r--lib/gnutls_int.h59
-rw-r--r--lib/gnutls_rsa_export.c15
-rw-r--r--lib/gnutls_rsa_export.h1
-rw-r--r--lib/gnutls_sig.c19
-rw-r--r--lib/gnutls_state.c65
-rw-r--r--lib/gnutls_ui.c39
-rw-r--r--lib/gnutls_ui.h18
-rw-r--r--lib/x509/privkey.c45
-rw-r--r--lib/x509/privkey.h1
-rw-r--r--libextra/openpgp/openpgp.c2
-rw-r--r--libextra/openpgp/xml.c4
-rw-r--r--libgcrypt.m447
-rw-r--r--src/Makefile.am6
-rw-r--r--src/certtool.c34
-rw-r--r--src/crypt.c36
-rw-r--r--src/getpass.c52
-rw-r--r--src/getpass.h1
-rw-r--r--src/serv.c30
40 files changed, 683 insertions, 136 deletions
diff --git a/NEWS b/NEWS
index 48524d23fe..a45c3a42b5 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,13 @@
-Version 1.0.8
+Version 1.0.9
+- Added gnutls_certificate_set_params_function() and
+ gnutls_anon_set_params_function() that set the RSA or DH
+ parameters using a callback.
+- Added functions gnutls_rsa_params_cpy(), gnutls_dh_params_cpy()
+ and gnutls_x509_privkey_cpy().
+- Corrected a compilation issue when opencdk was installed in a
+ non standard directory.
+
+Version 1.0.8 (28/02/2004)
- Corrected bug in mutual certificate authentication in SSL 3.0.
Version 1.0.7 (25/02/2004)
diff --git a/configure.in b/configure.in
index 859f667db3..518a6597bc 100644
--- a/configure.in
+++ b/configure.in
@@ -12,7 +12,7 @@ AC_DEFINE_UNQUOTED(T_OS, "$target_os", [OS name])
dnl Gnutls Version
GNUTLS_MAJOR_VERSION=1
GNUTLS_MINOR_VERSION=0
-GNUTLS_MICRO_VERSION=8
+GNUTLS_MICRO_VERSION=9
GNUTLS_VERSION=$GNUTLS_MAJOR_VERSION.$GNUTLS_MINOR_VERSION.$GNUTLS_MICRO_VERSION
AC_DEFINE_UNQUOTED(GNUTLS_VERSION, "$GNUTLS_VERSION", [version of gnutls])
@@ -30,7 +30,7 @@ AM_MAINTAINER_MODE
dnl This is the library version
GNUTLS_MOST_RECENT_INTERFACE=13
GNUTLS_CURRENT_INTERFACE_IMPLEMENTATION_NUMBER=$GNUTLS_MICRO_VERSION
-GNUTLS_OLDEST_INTERFACE=10
+GNUTLS_OLDEST_INTERFACE=11
AC_SUBST(GNUTLS_MAJOR_VERSION)
diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am
index 9b365b0f9f..c463d15043 100644
--- a/doc/examples/Makefile.am
+++ b/doc/examples/Makefile.am
@@ -1,4 +1,4 @@
EXTRA_DIST = ex-alert.c ex-client-resume.c ex-client-srp.c ex-client1.c \
ex-client2.c ex-x509-info.c ex-rfc2818.c ex-serv-export.c ex-serv-pgp.c \
- ex-serv-srp.c ex-serv1.c ex-pgp-keyserver.c ex-cert-select.c \
+ ex-serv-srp.c ex-serv1.c ex-cert-select.c \
ex-crq.c ex-session-info.c ex-pkcs12.c
diff --git a/doc/tex/Makefile.am b/doc/tex/Makefile.am
index 7227d8a12c..53c37c1a90 100644
--- a/doc/tex/Makefile.am
+++ b/doc/tex/Makefile.am
@@ -7,7 +7,7 @@ EXTRA_DIST = gnutls.tex gnutls.ps \
EXAMPLE_OBJECTS = ex-alert.tex ex-client-srp.tex ex-serv-export.tex \
ex-client2.tex ex-x509-info.tex ex-rfc2818.tex \
ex-serv1.tex ex-client-resume.tex ex-serv-srp.tex \
- ex-serv-pgp.tex ex-pgp-keyserver.tex ex-cert-select.tex \
+ ex-serv-pgp.tex ex-cert-select.tex \
ex-crq.tex ex-session-info.tex ex-pkcs12.tex
TEX_OBJECTS = gnutls.tex ../../lib/gnutls-api.tex fdl.tex ../../lib/x509/x509-api.tex \
diff --git a/doc/tex/auth.tex b/doc/tex/auth.tex
index 7a6f08a3ee..7e925ed62c 100644
--- a/doc/tex/auth.tex
+++ b/doc/tex/auth.tex
@@ -86,3 +86,65 @@ KX\_ANON\_DH & CRD\_ANON & CRD\_ANON
\label{fig:kxcred}
\end{figure}
+
+
+
+\section{Parameters stored in credentials}
+
+Several parameters such as the ones used for Diffie-Hellman authentication
+are stored within the credentials structures, so all sessions can access
+them. Those parameters are stored in structures such as {\bf gnutls\_dh\_params}
+and {\bf gnutls\_rsa\_params}, and functions like
+\printfunc{gnutls_certificate_set_dh_params}{gnutls\_certificate\_set\_dh\_params}
+and
+\printfunc{gnutls_certificate_set_rsa_export_params}{gnutls\_certificate\_set\_rsa\_export\_params}
+can be used to associate those parameters with the given credentials structure.
+\par
+Since those parameters need to be renewed from time to time and a
+global structure such as the credentials, may not be easy to modify
+since it is accessible by all sessions, an alternative interface is
+available using a callback function.
+This can be set using the
+\printfunc{gnutls_certificate_set_params_function}{gnutls\_certificate\_set\_params\_function}.
+An example is shown below.
+
+\begin{verbatim}
+#include <gnutls.h>
+
+gnutls_rsa_params rsa_params;
+gnutls_dh_params dh_params;
+
+/* This function will be called once a session requests DH
+ * or RSA parameters. The parameters returned (if any) will
+ * be used for the first handshake only.
+ */
+static int get_params( gnutls_session session, gnutls_params_type type,
+ gnutls_params_st *st)
+{
+ if (type == GNUTLS_PARAMS_RSA_EXPORT)
+ st->params.rsa_export = rsa_params;
+ else if (type == GNUTLS_PARAMS_DH)
+ st->params.dh = dh_params;
+ else return -1;
+
+ st->type = type;
+ /* do not deinitialize those parameters.
+ */
+ st->deinit = 0;
+
+ return 0;
+}
+
+int main()
+{
+ gnutls_certificate_credentials cert_cred;
+
+ initialize_params();
+
+ /* ...
+ */
+
+ gnutls_certificate_set_params_function( cert_cred, get_params);
+
+}
+\end{verbatim}
diff --git a/doc/tex/examples.tex b/doc/tex/examples.tex
index 544b502616..940b2b66b7 100644
--- a/doc/tex/examples.tex
+++ b/doc/tex/examples.tex
@@ -90,13 +90,6 @@ is separate for simplicity.
\section{Miscellaneous examples}
-\subsection{A callback which\index{OpenPGP!Key retrieval} retrieves OpenPGP keys}
-The following example is a callback function which retrieves {\bf OpenPGP} keys from
-a public key server. This is useful when a client connected to an OpenPGP \tls{} server
-and sent its key fingerprint instead of the whole key. With this callback the \tls{}
-server can retrieve the key from a public key server.
-\input{ex-pgp-keyserver}
-
\subsection{Checking for an alert}
This is a function that checks if an alert has been received
in the current session.
diff --git a/doc/tex/preparation.tex b/doc/tex/preparation.tex
index 7afeaf2c99..f356441705 100644
--- a/doc/tex/preparation.tex
+++ b/doc/tex/preparation.tex
@@ -69,3 +69,65 @@ specifying both options to `libgnutls-config':
gcc -o foo foo.c `libgnutls-config --cflags --libs`
\end{verbatim}
+
+\section{Multi-threaded applications}
+
+Although the \gnutls{} library is thread safe by design, some parts of the crypto
+backend, such as the random generator, are not. Since \emph{libgcrypt 1.1.92}
+there was an automatic detection of the thread library used by the
+application, so most applications wouldn't need to do any changes to
+ensure thread-safety. Due to the unportability of the automatic thread
+detection, this was removed from later releases of \emph{libgcrypt}, so
+applications have now to register callback functions to ensure proper locking
+in sensitive parts of \emph{libgcrypt}.
+\par
+There are helper macros to help you properly initialize the libraries.
+Examples are shown below.
+\begin{itemize}
+
+\item POSIX threads
+\begin{verbatim}
+#include <gnutls.h>
+#include <gcrypt.h>
+#include <errno.h>
+#include <pthread.h>
+GCRY_THREAD_OPTION_PTHREAD_IMPL;
+
+int main()
+{
+ /* The order matters.
+ */
+ gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
+ gnutls_global_init();
+}
+\end{verbatim}
+
+\item GNU PTH threads
+\begin{verbatim}
+#include <gnutls.h>
+#include <gcrypt.h>
+#include <errno.h>
+#include <pth.h>
+GCRY_THREAD_OPTION_PTH_IMPL;
+
+int main()
+{
+ gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
+ gnutls_global_init();
+}
+\end{verbatim}
+
+\item Other thread packages
+\begin{verbatim}
+/* The gcry_thread_cbs structure must have been
+ * initialized.
+ */
+static struct gcry_thread_cbs gcry_threads_other = { ... };
+
+int main()
+{
+ gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_other);
+}
+\end{verbatim}
+\end{itemize}
+
diff --git a/includes/gnutls/x509.h b/includes/gnutls/x509.h
index ab8346d3c9..75a6647cf4 100644
--- a/includes/gnutls/x509.h
+++ b/includes/gnutls/x509.h
@@ -311,6 +311,7 @@ typedef enum gnutls_pkcs_encrypt_flags {
int gnutls_x509_privkey_init(gnutls_x509_privkey * key);
void gnutls_x509_privkey_deinit(gnutls_x509_privkey key);
+int gnutls_x509_privkey_cpy(gnutls_x509_privkey dst, gnutls_x509_privkey src);
int gnutls_x509_privkey_import(gnutls_x509_privkey key, const gnutls_datum * data,
gnutls_x509_crt_fmt format);
int gnutls_x509_privkey_import_pkcs8(gnutls_x509_privkey key, const gnutls_datum * data,
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 9a55b33fc7..27e7daeb5e 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -1,4 +1,4 @@
-INCLUDES = -I../libextra -Iminitasn1/ -I../includes $(LIBGCRYPT_CFLAGS)
+INCLUDES = -I../libextra -Iminitasn1/ -I../includes $(LIBOPENCDK_CFLAGS) $(LIBGCRYPT_CFLAGS)
bin_SCRIPTS = libgnutls-config
m4datadir = $(datadir)/aclocal
diff --git a/lib/auth_anon.c b/lib/auth_anon.c
index a49df2092c..9f6983a5b3 100644
--- a/lib/auth_anon.c
+++ b/lib/auth_anon.c
@@ -63,6 +63,7 @@ static int gen_anon_server_kx( gnutls_session session, opaque** data) {
GNUTLS_MPI g, p;
const GNUTLS_MPI *mpis;
int ret;
+ gnutls_dh_params dh_params;
const gnutls_anon_server_credentials cred;
cred = _gnutls_get_cred(session->key, GNUTLS_CRD_ANON, NULL);
@@ -71,7 +72,8 @@ static int gen_anon_server_kx( gnutls_session session, opaque** data) {
return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
}
- mpis = _gnutls_get_dh_params( cred->dh_params);
+ dh_params = _gnutls_anon_get_dh_params( cred, session);
+ mpis = _gnutls_get_dh_params( dh_params);
if (mpis == NULL) {
gnutls_assert();
return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
@@ -106,6 +108,7 @@ const gnutls_anon_server_credentials cred;
int bits;
int ret;
GNUTLS_MPI p, g;
+gnutls_dh_params dh_params;
const GNUTLS_MPI *mpis;
bits = _gnutls_dh_get_prime_bits( session);
@@ -116,7 +119,8 @@ const GNUTLS_MPI *mpis;
return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
}
- mpis = _gnutls_get_dh_params( cred->dh_params);
+ dh_params = _gnutls_anon_get_dh_params( cred, session);
+ mpis = _gnutls_get_dh_params( dh_params);
if (mpis == NULL) {
gnutls_assert();
return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
diff --git a/lib/auth_anon.h b/lib/auth_anon.h
index 2bfd0f53e5..29c4114338 100644
--- a/lib/auth_anon.h
+++ b/lib/auth_anon.h
@@ -3,6 +3,10 @@
typedef struct {
gnutls_dh_params dh_params;
+ /* this callback is used to retrieve the DH or RSA
+ * parameters.
+ */
+ gnutls_params_function * params_func;
} ANON_SERVER_CREDENTIALS_INT;
#define gnutls_anon_server_credentials ANON_SERVER_CREDENTIALS_INT*
@@ -18,3 +22,6 @@ typedef ANON_CLIENT_AUTH_INFO ANON_SERVER_AUTH_INFO;
typedef struct ANON_CLIENT_AUTH_INFO_INT ANON_CLIENT_AUTH_INFO_INT;
typedef ANON_CLIENT_AUTH_INFO_INT ANON_SERVER_AUTH_INFO_INT;
+
+gnutls_dh_params _gnutls_anon_get_dh_params(const gnutls_anon_server_credentials sc,
+ gnutls_session session);
diff --git a/lib/auth_cert.h b/lib/auth_cert.h
index d99991a9b7..a27dbffc92 100644
--- a/lib/auth_cert.h
+++ b/lib/auth_cert.h
@@ -35,6 +35,10 @@ typedef int gnutls_certificate_server_retrieve_function(
typedef struct {
gnutls_dh_params dh_params;
gnutls_rsa_params rsa_params;
+ /* this callback is used to retrieve the DH or RSA
+ * parameters.
+ */
+ gnutls_params_function * params_func;
gnutls_cert ** cert_list;
/* contains a list of a list of certificates.
@@ -127,5 +131,10 @@ void _gnutls_selected_certs_set( gnutls_session session,
#define _gnutls_proc_cert_client_certificate _gnutls_proc_cert_server_certificate
+gnutls_rsa_params _gnutls_certificate_get_rsa_params(const gnutls_certificate_credentials sc,
+ gnutls_session session);
+gnutls_dh_params _gnutls_certificate_get_dh_params(const gnutls_certificate_credentials sc,
+ gnutls_session session);
+
#endif
diff --git a/lib/auth_dhe.c b/lib/auth_dhe.c
index 79f499156f..bc7eede562 100644
--- a/lib/auth_dhe.c
+++ b/lib/auth_dhe.c
@@ -89,6 +89,7 @@ static int gen_dhe_server_kx(gnutls_session session, opaque ** data)
gnutls_datum signature, ddata;
CERTIFICATE_AUTH_INFO info;
const gnutls_certificate_credentials cred;
+ gnutls_dh_params dh_params;
cred = _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, NULL);
if (cred == NULL) {
@@ -107,7 +108,8 @@ static int gen_dhe_server_kx(gnutls_session session, opaque ** data)
return ret;
}
- mpis = _gnutls_get_dh_params( cred->dh_params);
+ dh_params = _gnutls_certificate_get_dh_params( cred, session);
+ mpis = _gnutls_get_dh_params( dh_params);
if (mpis == NULL) {
gnutls_assert();
return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
@@ -237,6 +239,7 @@ const gnutls_certificate_credentials cred;
int ret;
GNUTLS_MPI p, g;
const GNUTLS_MPI *mpis;
+gnutls_dh_params dh_params;
bits = _gnutls_dh_get_prime_bits( session);
@@ -246,7 +249,8 @@ const GNUTLS_MPI *mpis;
return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
}
- mpis = _gnutls_get_dh_params( cred->dh_params);
+ dh_params = _gnutls_certificate_get_dh_params( cred, session);
+ mpis = _gnutls_get_dh_params( dh_params);
if (mpis == NULL) {
gnutls_assert();
return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c
index 5931460274..6547651c34 100644
--- a/lib/auth_rsa.c
+++ b/lib/auth_rsa.c
@@ -137,6 +137,7 @@ int _gnutls_get_private_rsa_params(gnutls_session session, GNUTLS_MPI **params,
{
int bits;
const gnutls_certificate_credentials cred;
+gnutls_rsa_params rsa_params;
cred = _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, NULL);
if (cred == NULL) {
@@ -155,8 +156,9 @@ const gnutls_certificate_credentials cred;
== GNUTLS_KX_RSA_EXPORT &&
bits > 512) {
+ rsa_params = _gnutls_certificate_get_rsa_params( cred, session);
/* EXPORT case: */
- if (cred->rsa_params == NULL) {
+ if (rsa_params == NULL) {
gnutls_assert();
return GNUTLS_E_NO_TEMPORARY_RSA_PARAMS;
}
@@ -166,7 +168,7 @@ const gnutls_certificate_credentials cred;
* used to sign this temporary stuff.
*/
*params_size = RSA_PRIVATE_PARAMS;
- *params = cred->rsa_params->params;
+ *params = rsa_params->params;
return 0;
}
diff --git a/lib/auth_rsa_export.c b/lib/auth_rsa_export.c
index 340c7e5aa3..84d09f36a6 100644
--- a/lib/auth_rsa_export.c
+++ b/lib/auth_rsa_export.c
@@ -67,7 +67,8 @@ const MOD_AUTH_STRUCT rsa_export_auth_struct = {
static int gen_rsa_export_server_kx(gnutls_session session, opaque ** data)
{
- const GNUTLS_MPI *rsa_params;
+ gnutls_rsa_params rsa_params;
+ const GNUTLS_MPI *rsa_mpis;
size_t n_e, n_m;
uint8 *data_e, *data_m;
int ret = 0, data_size;
@@ -101,8 +102,9 @@ static int gen_rsa_export_server_kx(gnutls_session session, opaque ** data)
return GNUTLS_E_INT_RET_0;
}
- rsa_params = _gnutls_get_rsa_params( cred->rsa_params);
- if (rsa_params == NULL) {
+ rsa_params = _gnutls_certificate_get_rsa_params( cred, session);
+ rsa_mpis = _gnutls_get_rsa_params( rsa_params);
+ if (rsa_mpis == NULL) {
gnutls_assert();
return GNUTLS_E_NO_TEMPORARY_RSA_PARAMS;
}
@@ -114,14 +116,14 @@ static int gen_rsa_export_server_kx(gnutls_session session, opaque ** data)
}
info = _gnutls_get_auth_info( session);
- ret=_gnutls_rsa_export_set_modulus_bits( session, _gnutls_mpi_get_nbits(rsa_params[0]));
+ ret=_gnutls_rsa_export_set_modulus_bits( session, _gnutls_mpi_get_nbits(rsa_mpis[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]);
+ _gnutls_mpi_print( NULL, &n_m, rsa_mpis[0]);
+ _gnutls_mpi_print( NULL, &n_e, rsa_mpis[1]);
(*data) = gnutls_malloc(n_e + n_m + 4);
if (*data == NULL) {
@@ -129,12 +131,12 @@ static int gen_rsa_export_server_kx(gnutls_session session, opaque ** data)
}
data_m = &(*data)[0];
- _gnutls_mpi_print( &data_m[2], &n_m, rsa_params[0]);
+ _gnutls_mpi_print( &data_m[2], &n_m, rsa_mpis[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_mpi_print( &data_e[2], &n_e, rsa_mpis[1]);
_gnutls_write_uint16(n_e, data_e);
diff --git a/lib/gnutls.h.in.in b/lib/gnutls.h.in.in
index e4183ee103..c5682ea772 100644
--- a/lib/gnutls.h.in.in
+++ b/lib/gnutls.h.in.in
@@ -70,6 +70,10 @@ typedef enum gnutls_kx_algorithm { GNUTLS_KX_RSA=1, GNUTLS_KX_DHE_DSS,
GNUTLS_KX_RSA_EXPORT, GNUTLS_KX_SRP_RSA, GNUTLS_KX_SRP_DSS
} gnutls_kx_algorithm;
+typedef enum gnutls_params_type { GNUTLS_PARAMS_RSA_EXPORT=1,
+ GNUTLS_PARAMS_DH
+} gnutls_params_type;
+
typedef enum gnutls_credentials_type { GNUTLS_CRD_CERTIFICATE=1, GNUTLS_CRD_ANON, GNUTLS_CRD_SRP } gnutls_credentials_type;
typedef enum gnutls_mac_algorithm { GNUTLS_MAC_NULL=1,
@@ -436,12 +440,14 @@ int gnutls_dh_params_export_pkcs3( gnutls_dh_params params,
gnutls_x509_crt_fmt format, unsigned char* params_data, size_t* params_data_size);
int gnutls_dh_params_export_raw(gnutls_dh_params params,
gnutls_datum * prime, gnutls_datum * generator, unsigned int *bits);
+int gnutls_dh_params_cpy(gnutls_dh_params dst, gnutls_dh_params src);
/* RSA params
*/
int gnutls_rsa_params_init(gnutls_rsa_params * rsa_params);
void gnutls_rsa_params_deinit(gnutls_rsa_params rsa_params);
+int gnutls_rsa_params_cpy(gnutls_rsa_params dst, gnutls_rsa_params src);
int gnutls_rsa_params_import_raw(gnutls_rsa_params rsa_params,
const gnutls_datum *m, const gnutls_datum *e,
const gnutls_datum *d, const gnutls_datum *p,
diff --git a/lib/gnutls_anon_cred.c b/lib/gnutls_anon_cred.c
index 42b61bdf74..835c23ae18 100644
--- a/lib/gnutls_anon_cred.c
+++ b/lib/gnutls_anon_cred.c
@@ -40,11 +40,41 @@ static const int anon_dummy;
* This structure is complex enough to manipulate directly thus
* this helper function is provided in order to free (deallocate) it.
**/
-void gnutls_anon_free_server_credentials( gnutls_anon_server_credentials sc) {
+void gnutls_anon_free_server_credentials( gnutls_anon_server_credentials sc)
+{
gnutls_free( sc);
}
+/*-
+ * _gnutls_anon_get_dh_params - Returns the DH parameters pointer
+ * @sc: is an &gnutls_certificate_credentials structure.
+ *
+ * This function will return the dh parameters pointer.
+ *
+ -*/
+gnutls_dh_params _gnutls_anon_get_dh_params(const gnutls_anon_server_credentials sc,
+ gnutls_session session)
+{
+gnutls_params_st params;
+int ret;
+
+ if (session->internals.params.anon_dh_params)
+ return session->internals.params.anon_dh_params;
+
+ if (sc->dh_params) {
+ session->internals.params.anon_dh_params = sc->dh_params;
+ } else if (sc->params_func) {
+ ret = sc->params_func( session, GNUTLS_PARAMS_DH, &params);
+ if (ret == 0 && params.type == GNUTLS_PARAMS_DH) {
+ session->internals.params.anon_dh_params = params.params.dh;
+ session->internals.params.free_anon_dh_params = params.deinit;
+ }
+ }
+
+ return session->internals.params.anon_dh_params;
+}
+
/**
* gnutls_anon_allocate_server_credentials - Used to allocate an gnutls_anon_server_credentials structure
* @sc: is a pointer to an &gnutls_anon_server_credentials structure.
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
index a7a2297780..67d1520da2 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -124,6 +124,69 @@ void gnutls_certificate_free_ca_names(gnutls_certificate_credentials sc)
_gnutls_free_datum( &sc->x509_rdn_sequence);
}
+/*-
+ * _gnutls_certificate_get_dh_params - Returns the DH parameters pointer
+ * @sc: is an &gnutls_certificate_credentials structure.
+ *
+ * This function will return the dh parameters pointer. This will read the
+ * credentials structure, and cache the output to the session, so later
+ * calls would not examine the credentials (or call a callback).
+ *
+ -*/
+gnutls_dh_params _gnutls_certificate_get_dh_params(const gnutls_certificate_credentials sc,
+ gnutls_session session)
+{
+gnutls_params_st params;
+int ret;
+
+ if (session->internals.params.cert_dh_params) {
+ return session->internals.params.cert_dh_params;
+ }
+
+ if (sc->dh_params) {
+ session->internals.params.cert_dh_params = sc->dh_params;
+ } else if (sc->params_func) {
+ ret = sc->params_func( session, GNUTLS_PARAMS_DH, &params);
+ if (ret == 0 && params.type == GNUTLS_PARAMS_DH) {
+ session->internals.params.cert_dh_params = params.params.dh;
+ session->internals.params.free_cert_dh_params = params.deinit;
+ }
+ }
+
+ return session->internals.params.cert_dh_params;
+}
+
+/*-
+ * _gnutls_certificate_get_rsa_params - Returns the RSA parameters pointer
+ * @sc: is an &gnutls_certificate_credentials structure.
+ *
+ * This function will return the rsa parameters pointer.
+ *
+ -*/
+gnutls_rsa_params _gnutls_certificate_get_rsa_params(const gnutls_certificate_credentials sc,
+ gnutls_session session)
+{
+gnutls_params_st params;
+int ret;
+
+ if (session->internals.params.rsa_params) {
+ return session->internals.params.rsa_params;
+ }
+
+ if (sc->rsa_params) {
+ session->internals.params.rsa_params = sc->rsa_params;
+ } else if (sc->params_func) {
+ ret = sc->params_func( session, GNUTLS_PARAMS_RSA_EXPORT, &params);
+ if (ret == 0 && params.type == GNUTLS_PARAMS_RSA_EXPORT) {
+ session->internals.params.rsa_params = params.params.rsa_export;
+ session->internals.params.free_rsa_params = params.deinit;
+ }
+ }
+
+ return session->internals.params.rsa_params;
+}
+
+
/**
* gnutls_certificate_free_credentials - Used to free an allocated gnutls_certificate_credentials structure
* @sc: is an &gnutls_certificate_credentials structure.
diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h
index 96218ff479..c1384f17b3 100644
--- a/lib/gnutls_cert.h
+++ b/lib/gnutls_cert.h
@@ -98,5 +98,5 @@ int _gnutls_raw_cert_to_gcert(gnutls_cert * gcert, gnutls_certificate_type type,
const gnutls_datum *raw_cert, int flags /* OR of ConvFlags */);
int _gnutls_raw_privkey_to_gkey(gnutls_privkey * key, gnutls_certificate_type type,
const gnutls_datum *raw_key, int key_enc /* DER or PEM */);
-
+
#endif
diff --git a/lib/gnutls_dh.h b/lib/gnutls_dh.h
index f556dbee56..3cf53c7881 100644
--- a/lib/gnutls_dh.h
+++ b/lib/gnutls_dh.h
@@ -22,3 +22,4 @@ const GNUTLS_MPI* _gnutls_get_dh_params(gnutls_dh_params);
GNUTLS_MPI gnutls_calc_dh_secret( GNUTLS_MPI *ret_x, GNUTLS_MPI g, GNUTLS_MPI prime );
GNUTLS_MPI gnutls_calc_dh_key( GNUTLS_MPI f, GNUTLS_MPI x, GNUTLS_MPI prime );
int _gnutls_dh_generate_prime(GNUTLS_MPI *ret_g, GNUTLS_MPI* ret_n, uint bits);
+void gnutls_dh_params_deinit(gnutls_dh_params dh_params);
diff --git a/lib/gnutls_dh_primes.c b/lib/gnutls_dh_primes.c
index 785b0b1fdc..b91a1cae0d 100644
--- a/lib/gnutls_dh_primes.c
+++ b/lib/gnutls_dh_primes.c
@@ -205,6 +205,30 @@ void gnutls_dh_params_deinit(gnutls_dh_params dh_params)
}
/**
+ * gnutls_dh_params_cpy - This function will copy a DH parameters structure
+ * @dst: Is the destination structure, which should be initialized.
+ * @src: Is the source structure
+ *
+ * This function will copy the DH parameters structure from source
+ * to destination.
+ *
+ **/
+int gnutls_dh_params_cpy(gnutls_dh_params dst, gnutls_dh_params src)
+{
+ if (src == NULL)
+ return GNUTLS_E_INVALID_REQUEST;
+
+ dst->params[0] = _gnutls_mpi_copy(src->params[0]);
+ dst->params[1] = _gnutls_mpi_copy(src->params[1]);
+
+ if (dst->params[0]==NULL || dst->params[1] == NULL)
+ return GNUTLS_E_MEMORY_ERROR;
+
+ return 0;
+}
+
+
+/**
* gnutls_dh_params_generate2 - This function will generate new DH parameters
* @params: Is the structure that the DH parameters will be stored
* @bits: is the prime's number of bits
diff --git a/lib/gnutls_global.c b/lib/gnutls_global.c
index 0c6bf8525a..9a5c98b1ab 100644
--- a/lib/gnutls_global.c
+++ b/lib/gnutls_global.c
@@ -168,8 +168,14 @@ int gnutls_global_init( void)
_gnutls_init++;
if (gcry_control( GCRYCTL_ANY_INITIALIZATION_P) == 0) {
- if (gcry_check_version(GNUTLS_GCRYPT_VERSION)==NULL) {
+ const char* p;
+ p = strchr( GNUTLS_GCRYPT_VERSION, ':');
+ if (p==NULL) p = GNUTLS_GCRYPT_VERSION;
+ else p++;
+
+ if (gcry_check_version(p)==NULL) {
gnutls_assert();
+ _gnutls_debug_log("Checking for libgcrypt failed '%s'\n", p);
return GNUTLS_E_INCOMPATIBLE_GCRYPT_LIBRARY;
}
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 91c0e8585b..09d9f6faba 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -174,6 +174,10 @@ typedef enum gnutls_kx_algorithm { GNUTLS_KX_RSA=1, GNUTLS_KX_DHE_DSS,
GNUTLS_KX_RSA_EXPORT, GNUTLS_KX_SRP_RSA, GNUTLS_KX_SRP_DSS
} gnutls_kx_algorithm;
+typedef enum gnutls_params_type { GNUTLS_PARAMS_RSA_EXPORT=1,
+ GNUTLS_PARAMS_DH
+} gnutls_params_type;
+
typedef enum gnutls_mac_algorithm { GNUTLS_MAC_UNKNOWN=0, GNUTLS_MAC_NULL=1,
GNUTLS_MAC_MD5, GNUTLS_MAC_SHA, GNUTLS_MAC_RMD160
} gnutls_mac_algorithm;
@@ -427,6 +431,38 @@ typedef int certificate_server_select_func(struct gnutls_session_int*,
typedef int srp_server_select_func(struct gnutls_session_int*,
const char**, const char**, unsigned int);
+/* DH and RSA parameters types.
+ */
+typedef struct {
+ /* [0] is the prime, [1] is the generator.
+ */
+ GNUTLS_MPI params[2];
+} _gnutls_dh_params;
+
+#define gnutls_dh_params _gnutls_dh_params*
+
+#define gnutls_rsa_params gnutls_x509_privkey
+
+typedef struct gnutls_internal_params {
+ gnutls_dh_params anon_dh_params;
+ int free_anon_dh_params;
+ gnutls_dh_params cert_dh_params;
+ int free_cert_dh_params;
+ gnutls_rsa_params rsa_params;
+ int free_rsa_params;
+} gnutls_internal_params;
+
+typedef struct gnutls_params_st {
+ gnutls_params_type type;
+ union params {
+ gnutls_dh_params dh;
+ gnutls_rsa_params rsa_export;
+ } params;
+ int deinit;
+} gnutls_params_st;
+
+
+
typedef struct {
opaque header[HANDSHAKE_HEADER_SIZE];
/* this holds the number of bytes in the handshake_header[] */
@@ -631,7 +667,7 @@ typedef struct {
/* This is used to set an arbitary version in the RSA
* PMS secret. Can be used by clients to test whether the
- * server checks that version.
+ * server checks that version. (** only used in gnutls-cli-debug)
*/
opaque rsa_pms_version[2];
@@ -643,6 +679,12 @@ typedef struct {
*/
int handshake_restarted;
+ /* Here we cache the DH or RSA parameters got from the
+ * credentials structure, or from a callback. That is to
+ * minimize external calls.
+ */
+ gnutls_internal_params params;
+
/* If you add anything here, check _gnutls_handshake_internal_state_clear().
*/
} GNUTLS_INTERNALS;
@@ -657,18 +699,10 @@ struct gnutls_session_int {
typedef struct gnutls_session_int *gnutls_session;
-typedef struct {
- /* [0] is the prime, [1] is the generator.
- */
- GNUTLS_MPI params[2];
-} _gnutls_dh_params;
-
-#define gnutls_dh_params _gnutls_dh_params*
-#define gnutls_rsa_params gnutls_x509_privkey
-
-/* functions */
+/* functions
+ */
void _gnutls_set_current_version(gnutls_session session, gnutls_protocol_version version);
gnutls_protocol_version gnutls_protocol_get_version(gnutls_session session);
void _gnutls_free_auth_info( gnutls_session session);
@@ -692,4 +726,7 @@ gnutls_protocol_version _gnutls_get_adv_version( gnutls_session);
int gnutls_fingerprint(gnutls_digest_algorithm algo, const gnutls_datum* data,
void* result, size_t* result_size);
+typedef int gnutls_params_function(gnutls_session, gnutls_params_type,
+ gnutls_params_st*);
+
#endif /* GNUTLS_INT_H */
diff --git a/lib/gnutls_rsa_export.c b/lib/gnutls_rsa_export.c
index 05e82535ef..fa1ed8b853 100644
--- a/lib/gnutls_rsa_export.c
+++ b/lib/gnutls_rsa_export.c
@@ -29,6 +29,7 @@
#include <gnutls_datum.h>
#include <gnutls_rsa_export.h>
#include "x509/x509.h"
+#include "x509/privkey.h"
#include "debug.h"
/* This function takes a number of bits and returns a supported
@@ -202,6 +203,20 @@ void gnutls_rsa_params_deinit(gnutls_rsa_params rsa_params)
}
/**
+ * gnutls_rsa_params_cpy - This function will copy an RSA parameters structure
+ * @dst: Is the destination structure, which should be initialized.
+ * @src: Is the source structure
+ *
+ * This function will copy the RSA parameters structure from source
+ * to destination.
+ *
+ **/
+int gnutls_rsa_params_cpy(gnutls_rsa_params dst, gnutls_rsa_params src)
+{
+ return gnutls_x509_privkey_cpy( dst, src);
+}
+
+/**
* gnutls_rsa_params_generate2 - This function will generate temporary RSA parameters
* @params: The structure where the parameters will be stored
* @bits: is the prime's number of bits
diff --git a/lib/gnutls_rsa_export.h b/lib/gnutls_rsa_export.h
index 57897d32bb..765610e1a7 100644
--- a/lib/gnutls_rsa_export.h
+++ b/lib/gnutls_rsa_export.h
@@ -21,4 +21,5 @@
const GNUTLS_MPI* _gnutls_get_rsa_params(gnutls_rsa_params);
int _gnutls_peers_cert_less_512( gnutls_session session);
int _gnutls_rsa_generate_params(GNUTLS_MPI* resarr, int* resarr_len, int bits);
+void gnutls_rsa_params_deinit(gnutls_rsa_params rsa_params);
diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c
index 1c6306f4c7..ab362df3b8 100644
--- a/lib/gnutls_sig.c
+++ b/lib/gnutls_sig.c
@@ -105,14 +105,16 @@ gnutls_protocol_version ver = gnutls_protocol_get_version( session);
/* Generates a signature of all the random data and the parameters.
* Used in DHE_* ciphersuites.
*/
-int _gnutls_tls_sign_params( gnutls_session session, gnutls_cert* cert, gnutls_privkey* pkey, gnutls_datum* params, gnutls_datum *signature)
+int _gnutls_tls_sign_params( gnutls_session session,
+ gnutls_cert* cert, gnutls_privkey* pkey,
+ gnutls_datum* params, gnutls_datum *signature)
{
gnutls_datum dconcat;
int ret;
GNUTLS_MAC_HANDLE td_md5;
GNUTLS_MAC_HANDLE td_sha;
opaque concat[36];
-
+gnutls_protocol_version ver = gnutls_protocol_get_version( session);
td_sha = _gnutls_hash_init( GNUTLS_MAC_SHA);
if (td_sha == NULL) {
@@ -124,7 +126,16 @@ opaque concat[36];
_gnutls_hash( td_sha, session->security_parameters.server_random, TLS_RANDOM_SIZE);
_gnutls_hash( td_sha, params->data, params->size);
- _gnutls_hash_deinit(td_sha, &concat[16]);
+ if (ver == GNUTLS_SSL3) {
+ ret = _gnutls_generate_master( session, 1);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ _gnutls_mac_deinit_ssl3_handshake( td_sha, &concat[16], session->security_parameters.master_secret, TLS_MASTER_SIZE);
+ } else
+ _gnutls_hash_deinit(td_sha, &concat[16]);
switch (cert->subject_pk_algorithm) {
case GNUTLS_PK_RSA:
@@ -333,9 +344,9 @@ gnutls_protocol_version ver = gnutls_protocol_get_version( session);
}
return ret;
-
}
+
/* Generates a signature of all the random data and the parameters.
* Used in DHE_* ciphersuites.
*/
diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c
index d63893d55b..a16172bbd1 100644
--- a/lib/gnutls_state.c
+++ b/lib/gnutls_state.c
@@ -40,13 +40,15 @@
#include <auth_cert.h>
#include <auth_anon.h>
#include <gnutls_algorithms.h>
+#include <gnutls_rsa_export.h>
#define CHECK_AUTH(auth, ret) if (gnutls_auth_get_type(session) != auth) { \
gnutls_assert(); \
return ret; \
}
-void _gnutls_session_cert_type_set( gnutls_session session, gnutls_certificate_type ct) {
+void _gnutls_session_cert_type_set( gnutls_session session, gnutls_certificate_type ct)
+{
session->security_parameters.cert_type = ct;
}
@@ -68,7 +70,8 @@ gnutls_cipher_algorithm gnutls_cipher_get( gnutls_session session) {
* is by default X.509, unless it is negotiated as a TLS extension.
*
**/
-gnutls_certificate_type gnutls_certificate_type_get( gnutls_session session) {
+gnutls_certificate_type gnutls_certificate_type_get( gnutls_session session)
+{
return session->security_parameters.cert_type;
}
@@ -78,7 +81,8 @@ gnutls_certificate_type gnutls_certificate_type_get( gnutls_session session) {
*
* Returns the key exchange algorithm used in the last handshake.
**/
-gnutls_kx_algorithm gnutls_kx_get( gnutls_session session) {
+gnutls_kx_algorithm gnutls_kx_get( gnutls_session session)
+{
return session->security_parameters.kx_algorithm;
}
@@ -88,7 +92,8 @@ gnutls_kx_algorithm gnutls_kx_get( gnutls_session session) {
*
* Returns the currently used mac algorithm.
**/
-gnutls_mac_algorithm gnutls_mac_get( gnutls_session session) {
+gnutls_mac_algorithm gnutls_mac_get( gnutls_session session)
+{
return session->security_parameters.read_mac_algorithm;
}
@@ -98,11 +103,14 @@ gnutls_mac_algorithm gnutls_mac_get( gnutls_session session) {
*
* Returns the currently used compression method.
**/
-gnutls_compression_method gnutls_compression_get( gnutls_session session) {
+gnutls_compression_method gnutls_compression_get( gnutls_session session)
+{
return session->security_parameters.read_compression_algorithm;
}
-int _gnutls_session_cert_type_supported( gnutls_session session, gnutls_certificate_type cert_type) {
+int _gnutls_session_cert_type_supported( gnutls_session session,
+ gnutls_certificate_type cert_type)
+{
uint i;
if (session->internals.cert_type_priority.algorithms==0 && cert_type ==
@@ -118,11 +126,30 @@ uint i;
return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
}
+/* this function deinitializes all the internal parameters stored
+ * in a session struct.
+ */
+inline
+static void deinit_internal_params( gnutls_session session)
+{
+ if (session->internals.params.free_anon_dh_params)
+ gnutls_dh_params_deinit( session->internals.params.anon_dh_params);
+
+ if (session->internals.params.free_cert_dh_params)
+ gnutls_dh_params_deinit( session->internals.params.cert_dh_params);
+
+ if (session->internals.params.rsa_params)
+ gnutls_rsa_params_deinit( session->internals.params.rsa_params);
+
+ memset( &session->internals.params, 0, sizeof( session->internals.params));
+}
+
/* This function will clear all the variables in internals
* structure within the session, which depend on the current handshake.
* This is used to allow further handshakes.
*/
-void _gnutls_handshake_internal_state_clear( gnutls_session session) {
+void _gnutls_handshake_internal_state_clear( gnutls_session session)
+{
session->internals.extensions_sent_size = 0;
/* by default no selected certificate */
@@ -145,6 +172,8 @@ void _gnutls_handshake_internal_state_clear( gnutls_session session) {
session->internals.handshake_restarted = 0;
session->internals.resumable = RESUME_TRUE;
+
+ deinit_internal_params( session);
}
@@ -262,6 +291,7 @@ void _gnutls_deinit(gnutls_session session)
/* remove auth info firstly */
_gnutls_free_auth_info(session );
+ _gnutls_handshake_internal_state_clear( session);
_gnutls_handshake_io_buffer_clear( session);
_gnutls_free_datum(&session->connection_state.read_mac_secret);
@@ -348,11 +378,13 @@ void gnutls_deinit(gnutls_session session)
}
-int _gnutls_dh_get_prime_bits( gnutls_session session) {
+int _gnutls_dh_get_prime_bits( gnutls_session session)
+{
return session->internals.dh_prime_bits;
}
-int _gnutls_dh_set_peer_public_bits( gnutls_session session, uint bits) {
+int _gnutls_dh_set_peer_public_bits( gnutls_session session, uint bits)
+{
switch( gnutls_auth_get_type( session)) {
case GNUTLS_CRD_ANON: {
ANON_SERVER_AUTH_INFO info;
@@ -380,7 +412,8 @@ int _gnutls_dh_set_peer_public_bits( gnutls_session session, uint bits) {
return 0;
}
-int _gnutls_dh_set_secret_bits( gnutls_session session, uint bits) {
+int _gnutls_dh_set_secret_bits( gnutls_session session, uint bits)
+{
switch( gnutls_auth_get_type( session)) {
case GNUTLS_CRD_ANON: {
ANON_SERVER_AUTH_INFO info;
@@ -408,7 +441,8 @@ int _gnutls_dh_set_secret_bits( gnutls_session session, uint bits) {
return 0;
}
-int _gnutls_rsa_export_set_modulus_bits( gnutls_session session, uint bits) {
+int _gnutls_rsa_export_set_modulus_bits( gnutls_session session, uint bits)
+{
CERTIFICATE_AUTH_INFO info;
info = _gnutls_get_auth_info(session);
@@ -462,7 +496,8 @@ int _gnutls_dh_set_prime_bits( gnutls_session session, uint bits)
* server can obtain the client's key.
*
**/
-void gnutls_openpgp_send_key(gnutls_session session, gnutls_openpgp_key_status status) {
+void gnutls_openpgp_send_key(gnutls_session session, gnutls_openpgp_key_status status)
+{
session->internals.pgp_fingerprint = status;
}
@@ -480,11 +515,13 @@ void gnutls_openpgp_send_key(gnutls_session session, gnutls_openpgp_key_status s
* certificate with X.509 certificates.
*
**/
-void gnutls_certificate_send_x509_rdn_sequence(gnutls_session session, int status) {
+void gnutls_certificate_send_x509_rdn_sequence(gnutls_session session, int status)
+{
session->internals.ignore_rdn_sequence = status;
}
-int _gnutls_openpgp_send_fingerprint(gnutls_session session) {
+int _gnutls_openpgp_send_fingerprint(gnutls_session session)
+{
return session->internals.pgp_fingerprint;
}
diff --git a/lib/gnutls_ui.c b/lib/gnutls_ui.c
index f29eab87d8..1752c5c826 100644
--- a/lib/gnutls_ui.c
+++ b/lib/gnutls_ui.c
@@ -319,7 +319,8 @@ int gnutls_fingerprint(gnutls_digest_algorithm algo, const gnutls_datum* data,
* cipher suites.
*
**/
-void gnutls_anon_set_server_dh_params( gnutls_anon_server_credentials res, gnutls_dh_params dh_params) {
+void gnutls_anon_set_server_dh_params( gnutls_anon_server_credentials res, gnutls_dh_params dh_params)
+{
res->dh_params = dh_params;
}
@@ -333,11 +334,45 @@ void gnutls_anon_set_server_dh_params( gnutls_anon_server_credentials res, gnutl
* cipher suites.
*
**/
-void gnutls_certificate_set_dh_params(gnutls_certificate_credentials res, gnutls_dh_params dh_params) {
+void gnutls_certificate_set_dh_params(gnutls_certificate_credentials res, gnutls_dh_params dh_params)
+{
res->dh_params = dh_params;
}
/**
+ * gnutls_certificate_set_params_function - This function will set the DH or RSA parameters callback
+ * @res: is a gnutls_certificate_credentials structure
+ * @func: is the function to be called
+ *
+ * This function will set a callback in order for the server to get the
+ * diffie hellman or RSA parameters for certificate authentication. The callback
+ * should return zero on success.
+ *
+ **/
+void gnutls_certificate_set_params_function(gnutls_certificate_credentials res,
+ gnutls_params_function* func)
+{
+ res->params_func = func;
+}
+
+/**
+ * gnutls_anon_set_params_function - This function will set the DH parameters callback
+ * @res: is a gnutls_certificate_credentials structure
+ * @func: is the function to be called
+ *
+ * This function will set a callback in order for the server to get the
+ * diffie hellman parameters for anonymous authentication. The callback should
+ * return zero on success.
+ *
+ **/
+void gnutls_anon_set_params_function(gnutls_anon_server_credentials res,
+ gnutls_params_function* func)
+{
+ res->params_func = func;
+}
+
+
+/**
* gnutls_certificate_set_verify_flags - This function will set the flags to be used at certificate verification
* @res: is a gnutls_certificate_credentials structure
* @flags: are the flagsis a structure that holds diffie hellman parameters.
diff --git a/lib/gnutls_ui.h b/lib/gnutls_ui.h
index 8b7e0bd052..26a33345e4 100644
--- a/lib/gnutls_ui.h
+++ b/lib/gnutls_ui.h
@@ -131,6 +131,24 @@ int gnutls_pem_base64_decode_alloc(const char *header,
#define GNUTLS_KEY_ENCIPHER_ONLY 1
#define GNUTLS_KEY_DECIPHER_ONLY 32768
+typedef struct gnutls_params_st {
+ gnutls_params_type type;
+ union params {
+ gnutls_dh_params dh;
+ gnutls_rsa_params rsa_export;
+ } params;
+ int deinit;
+} gnutls_params_st;
+
+typedef int gnutls_params_function(gnutls_session, gnutls_params_type,
+ gnutls_params_st*);
+
+void gnutls_certificate_set_params_function(gnutls_certificate_credentials res,
+ gnutls_params_function* func);
+void gnutls_anon_set_params_function(gnutls_certificate_credentials res,
+ gnutls_params_function* func);
+
+
# endif /* LIBGNUTLS_VERSION */
diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c
index 4798e221dd..70fe0ddc64 100644
--- a/lib/x509/privkey.c
+++ b/lib/x509/privkey.c
@@ -82,6 +82,51 @@ int i;
gnutls_free(key);
}
+/**
+ * gnutls_x509_privkey_cpy - This function copies a private key
+ * @dst: The destination key, which should be initialized.
+ * @src: The source key
+ *
+ * This function will copy a private key from source to destination key.
+ *
+ **/
+int gnutls_x509_privkey_cpy(gnutls_x509_privkey dst, gnutls_x509_privkey src)
+{
+int i, ret;
+
+ if (!src || !dst) return GNUTLS_E_INVALID_REQUEST;
+
+ for (i = 0; i < src->params_size; i++) {
+ dst->params[i] = _gnutls_mpi_copy( src->params[i]);
+ if (dst->params[i] == NULL) return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ dst->params_size = src->params_size;
+ dst->pk_algorithm = src->pk_algorithm;
+
+ switch( dst->pk_algorithm) {
+ case GNUTLS_PK_DSA:
+ ret = _encode_dsa( &dst->key, dst->params);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ break;
+ case GNUTLS_PK_RSA:
+ ret = _encode_rsa( &dst->key, dst->params);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ break;
+ default:
+ gnutls_assert();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ return 0;
+}
+
/* Converts an RSA PKCS#1 key to
* an internal structure (gnutls_private_key)
*/
diff --git a/lib/x509/privkey.h b/lib/x509/privkey.h
index 56dfd26190..b667326047 100644
--- a/lib/x509/privkey.h
+++ b/lib/x509/privkey.h
@@ -12,3 +12,4 @@ int gnutls_x509_privkey_import(gnutls_x509_privkey key, const gnutls_datum * dat
gnutls_x509_crt_fmt format);
ASN1_TYPE _gnutls_privkey_decode_pkcs1_rsa_key( const gnutls_datum *raw_key,
gnutls_x509_privkey pkey);
+int gnutls_x509_privkey_cpy(gnutls_x509_privkey dst, gnutls_x509_privkey src);
diff --git a/libextra/openpgp/openpgp.c b/libextra/openpgp/openpgp.c
index 5ebdab7625..3aac1bd6cf 100644
--- a/libextra/openpgp/openpgp.c
+++ b/libextra/openpgp/openpgp.c
@@ -449,7 +449,7 @@ gnutls_openpgp_key_get_id( gnutls_openpgp_key key,
{
cdk_packet_t pkt;
cdk_pkt_pubkey_t pk = NULL;
- unsigned long kid[2];
+ unsigned int kid[2];
if( !key || !keyid ) {
gnutls_assert( );
diff --git a/libextra/openpgp/xml.c b/libextra/openpgp/xml.c
index d95e10e85a..251bd25b6d 100644
--- a/libextra/openpgp/xml.c
+++ b/libextra/openpgp/xml.c
@@ -140,7 +140,7 @@ xml_add_key( gnutls_string *xmlkey, int ext, cdk_pkt_pubkey_t pk, int sub )
const char *algo, *s;
char keyid[16], fpr[41], tmp[32];
uint8 fingerpr[20];
- unsigned long kid[2];
+ unsigned int kid[2];
int i = 0, rc = 0;
if( !xmlkey || !pk ) {
@@ -254,7 +254,7 @@ xml_add_sig( gnutls_string *xmlkey, int ext, cdk_pkt_signature_t sig )
{
const char *algo, *s;
char tmp[32], keyid[16];
- unsigned long kid[2];
+ unsigned int kid[2];
int rc = 0;
if( !xmlkey || !sig ) {
diff --git a/libgcrypt.m4 b/libgcrypt.m4
index 0e8ab5803d..e5f2a43c06 100644
--- a/libgcrypt.m4
+++ b/libgcrypt.m4
@@ -1,5 +1,5 @@
dnl Autoconf macros for libgcrypt
-dnl Copyright (C) 2002 Free Software Foundation, Inc.
+dnl Copyright (C) 2002, 2004 Free Software Foundation, Inc.
dnl
dnl This file is free software; as a special exception the author gives
dnl unlimited permission to copy and/or distribute it, with or without
@@ -12,7 +12,13 @@ dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION,
dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
-dnl Test for liblibgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS
+dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS.
+dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed
+dnl with the API version to also check the API compatibility. Example:
+dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed
+dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using
+dnl this features allows to prevent build against newer versions of libgcrypt
+dnl with a changed API.
dnl
AC_DEFUN(AM_PATH_LIBGCRYPT,
[ AC_ARG_WITH(libgcrypt-prefix,
@@ -26,7 +32,15 @@ AC_DEFUN(AM_PATH_LIBGCRYPT,
fi
AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config, no)
- min_libgcrypt_version=ifelse([$1], ,0.4.4,$1)
+ tmp=ifelse([$1], ,1:1.2.0,$1)
+ if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
+ req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'`
+ min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'`
+ else
+ req_libgcrypt_api=0
+ min_libgcrypt_version="$tmp"
+ fi
+
AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version)
ok=no
if test "$LIBGCRYPT_CONFIG" != "no" ; then
@@ -36,7 +50,7 @@ AC_DEFUN(AM_PATH_LIBGCRYPT,
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
req_micro=`echo $min_libgcrypt_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
- libgcrypt_config_version=`$LIBGCRYPT_CONFIG $libgcrypt_config_args --version`
+ libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version`
major=`echo $libgcrypt_config_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
minor=`echo $libgcrypt_config_version | \
@@ -60,14 +74,33 @@ AC_DEFUN(AM_PATH_LIBGCRYPT,
fi
fi
if test $ok = yes; then
- LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG $libgcrypt_config_args --cflags`
- LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG $libgcrypt_config_args --libs`
AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+ if test $ok = yes; then
+ # If we have a recent libgcrypt, we should also check that the
+ # API is compatible
+ if test "$req_libgcrypt_api" -gt 0 ; then
+ tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0`
+ if test "$tmp" -gt 0 ; then
+ AC_MSG_CHECKING([LIBGCRYPT API version])
+ if test "$req_libgcrypt_api" -eq "$tmp" ; then
+ AC_MSG_RESULT(okay)
+ else
+ ok=no
+ AC_MSG_RESULT([does not match (want=$req_libgcrypt_api got=$tmp)])
+ fi
+ fi
+ fi
+ fi
+ if test $ok = yes; then
+ LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags`
+ LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs`
ifelse([$2], , :, [$2])
else
LIBGCRYPT_CFLAGS=""
LIBGCRYPT_LIBS=""
- AC_MSG_RESULT(no)
ifelse([$3], , :, [$3])
fi
AC_SUBST(LIBGCRYPT_CFLAGS)
diff --git a/src/Makefile.am b/src/Makefile.am
index 4fc8d385be..78ecd3862c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,7 +1,7 @@
EXTRA_DIST = common.h crypt.gaa crypt-gaa.h README.srpcrypt \
README cli.gaa cli-gaa.h serv-gaa.h serv.gaa tls_test.gaa \
tls_test-gaa.h tests.h gnutls-http-serv list.h certtool-gaa.h \
- certtool.gaa
+ certtool.gaa getpass.h
SUBDIRS = srp x509 openpgp
@@ -10,7 +10,7 @@ INCLUDES = -I../lib -I../libtasn1/lib -I../includes $(LIBOPENCDK_CFLAGS)
bin_PROGRAMS = gnutls-serv gnutls-cli gnutls-srpcrypt gnutls-cli-debug certtool
gnutls_serv_SOURCES = serv-gaa.c serv.c common.c
gnutls_serv_LDADD = ../lib/libgnutls.la ../libextra/libgnutls-extra.la $(LIBGCRYPT_LIBS) $(LIBOPENCDK_LIBS) $(SERV_LIBS)
-gnutls_srpcrypt_SOURCES = crypt-gaa.c crypt.c
+gnutls_srpcrypt_SOURCES = crypt-gaa.c crypt.c getpass.c
gnutls_srpcrypt_LDADD = ../lib/libgnutls.la ../libextra/libgnutls-extra.la $(LIBGCRYPT_LIBS) $(LIBOPENCDK_LIBS)
gnutls_cli_SOURCES = cli-gaa.c cli.c common.c
gnutls_cli_LDADD = ../lib/libgnutls.la ../libextra/libgnutls-extra.la $(LIBGCRYPT_LIBS) $(LIBOPENCDK_LIBS) $(SERV_LIBS)
@@ -22,7 +22,7 @@ noinst_PROGRAMS = retcodes
retcodes_SOURCES = retcodes.c
retcodes_LDADD = ../lib/libgnutls.la $(LIBGCRYPT_LIBS)
-certtool_SOURCES = certtool-gaa.c certtool.c prime.c
+certtool_SOURCES = certtool-gaa.c certtool.c prime.c getpass.c
certtool_LDADD = ../lib/libgnutls.la $(LIBGCRYPT_LIBS)
diff --git a/src/certtool.c b/src/certtool.c
index 6546765cb0..ec677f838c 100644
--- a/src/certtool.c
+++ b/src/certtool.c
@@ -32,6 +32,7 @@
#include "certtool-gaa.h"
#include <gnutls/pkcs12.h>
#include <unistd.h>
+#include <getpass.h>
static void print_crl_info( gnutls_x509_crl crl, FILE* out, int all);
int generate_prime(int bits);
@@ -138,33 +139,6 @@ int len;
return input;
}
-static const char* read_pass( const char* input_str)
-{
-#ifndef HAVE_GETPASS
-static char input[128];
-#endif
-const char* pass;
-
- if (info.pass) return info.pass;
-
-#ifndef HAVE_GETPASS
-
- fputs( input_str, stderr);
- fgets( input, sizeof(input), stdin);
-
- input[strlen(input)-1] = 0;
-
- if (strlen(input)==0 || input[0]=='\n') return NULL;
-
- return input;
-#else
- pass = getpass(input_str);
- if (pass == NULL || strlen(pass)==0 || pass[0]=='\n') return NULL;
-
- return pass;
-#endif
-}
-
static int read_yesno( const char* input_str)
{
char input[128];
@@ -742,14 +716,14 @@ int ret;
if (info.outcert_format) out_cert_format = GNUTLS_X509_FMT_DER;
else out_cert_format = GNUTLS_X509_FMT_PEM;
+ gnutls_global_set_log_function( tls_log_func);
+ gnutls_global_set_log_level(info.debug);
+
if ((ret=gnutls_global_init()) < 0) {
fprintf(stderr, "global_init: %s\n", gnutls_strerror(ret));
exit(1);
}
- gnutls_global_set_log_function( tls_log_func);
- gnutls_global_set_log_level(info.debug);
-
switch( info.action) {
case 0:
generate_self_signed();
diff --git a/src/crypt.c b/src/crypt.c
index 893804f338..5fc86ef0aa 100644
--- a/src/crypt.c
+++ b/src/crypt.c
@@ -39,6 +39,7 @@ int main (int argc, char **argv)
#include <gnutls/extra.h>
#include <gcrypt.h> /* for randomize */
#include <crypt-gaa.h>
+#include <getpass.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -50,35 +51,16 @@ int main (int argc, char **argv)
# include <windows.h>
#endif
-#ifdef _WIN32
-
-# define getpass read_str
-
-static const char* read_str( const char* input_str)
-{
-static char input[128];
-
- fputs( input_str, stderr);
- fgets( input, sizeof(input), stdin);
-
- input[strlen(input)-1] = 0;
-
- if (strlen(input)==0) return NULL;
-
- return input;
-}
-#endif
-
#define _MAX(x,y) (x>y?x:y)
/* This may need some rewrite. A lot of stuff which should be here
* are in the library, which is not good.
*/
-int crypt_int(char *username, char *passwd, int salt,
+int crypt_int(const char *username, const char *passwd, int salt,
char *tpasswd_conf, char *tpasswd, int uindex);
static int read_conf_values(gnutls_datum * g, gnutls_datum * n, char *str);
-static int _verify_passwd_int(char* username, char* passwd, char* verifier, char* salt,
+static int _verify_passwd_int(const char* username, const char* passwd, char* verifier, char* salt,
const gnutls_datum* g, const gnutls_datum* n);
@@ -158,7 +140,7 @@ int generate_create_conf(char *tpasswd_conf)
*
* index is the index of the prime-generator pair in tpasswd.conf
*/
-static int _verify_passwd_int(char* username, char* passwd, char* verifier,
+static int _verify_passwd_int(const char* username, const char* passwd, char* verifier,
char* salt, const gnutls_datum* g, const gnutls_datum* n)
{
char _salt[1024];
@@ -278,7 +260,7 @@ unsigned int i;
/* Parses the tpasswd files, in order to verify the given
* username/password pair.
*/
-int verify_passwd(char *conffile, char *tpasswd, char *username, char *passwd)
+int verify_passwd(char *conffile, char *tpasswd, char *username, const char *passwd)
{
FILE *fd;
char line[5 * 1024];
@@ -368,7 +350,7 @@ int verify_passwd(char *conffile, char *tpasswd, char *username, char *passwd)
int main(int argc, char **argv)
{
gaainfo info;
- char *passwd;
+ const char *passwd;
int salt, ret;
struct passwd *pwd;
@@ -417,7 +399,7 @@ int main(int argc, char **argv)
salt = 16;
- passwd = getpass("Enter password: ");
+ passwd = read_pass("Enter password: ");
/* not ready yet */
if (info.verify != 0) {
@@ -431,7 +413,7 @@ int main(int argc, char **argv)
}
-char* _srp_crypt( char* username, char* passwd, int salt_size,
+char* _srp_crypt( const char* username, const char* passwd, int salt_size,
const gnutls_datum* g, const gnutls_datum* n)
{
char salt[128];
@@ -481,7 +463,7 @@ gnutls_datum verifier, txt_verifier;
}
-int crypt_int(char *username, char *passwd, int salt_size,
+int crypt_int(const char *username, const char *passwd, int salt_size,
char *tpasswd_conf, char *tpasswd, int uindex)
{
FILE *fd;
diff --git a/src/getpass.c b/src/getpass.c
new file mode 100644
index 0000000000..6ce6dde4e4
--- /dev/null
+++ b/src/getpass.c
@@ -0,0 +1,52 @@
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifndef _WIN32
+# include <termios.h>
+# include <unistd.h>
+#endif
+
+#define OUT_STREAM stdout
+
+const char *read_pass(char *msg)
+{
+#ifndef _WIN32
+ struct termios old, new;
+#endif
+ static char input[128];
+ char *p;
+
+ fputs(msg, stderr);
+
+#ifndef _WIN32
+ /* Turn echoing off and fail if we can't. */
+ if (tcgetattr(fileno(OUT_STREAM), &old) != 0) {
+ perror("tcgetattr");
+ exit(1);
+ }
+
+ new = old;
+ new.c_lflag &= ~ECHO;
+ if (tcsetattr(fileno(OUT_STREAM), TCSAFLUSH, &new) != 0) {
+ perror("tcsetattr");
+ exit(1);
+ }
+#endif
+
+ /* Read the password. */
+ p = fgets(input, sizeof(input), stdin);
+
+#ifndef _WIN32
+ /* Restore terminal. */
+ (void) tcsetattr(fileno(OUT_STREAM), TCSAFLUSH, &old);
+#endif
+
+ if (p == NULL || strlen(p) == 0 || p[0] == '\n')
+ return NULL;
+
+ /* overwrite the newline */
+ input[strlen(p) - 1] = 0;
+
+ return p;
+}
diff --git a/src/getpass.h b/src/getpass.h
new file mode 100644
index 0000000000..3562b688c1
--- /dev/null
+++ b/src/getpass.h
@@ -0,0 +1 @@
+const char* read_pass (char *msg);
diff --git a/src/serv.c b/src/serv.c
index 8128731074..6cfbd6ca02 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -156,8 +156,8 @@ static void listener_free(listener_item * j)
* otherwise we should add them here.
*/
-gnutls_dh_params dh_params;
-gnutls_rsa_params rsa_params;
+gnutls_dh_params dh_params = NULL;
+gnutls_rsa_params rsa_params = NULL;
static int generate_dh_primes(void)
{
@@ -225,6 +225,22 @@ static void read_dh_params(void)
}
+static int get_params( gnutls_session session, gnutls_params_type type,
+ gnutls_params_st *st)
+{
+
+ if (type == GNUTLS_PARAMS_RSA_EXPORT)
+ st->params.rsa_export = rsa_params;
+ else if (type == GNUTLS_PARAMS_DH)
+ st->params.dh = dh_params;
+ else return -1;
+
+ st->type = type;
+ st->deinit = 0;
+
+ return 0;
+}
+
static int generate_rsa_params(void)
{
if (gnutls_rsa_params_init(&rsa_params) < 0) {
@@ -666,8 +682,10 @@ int main(int argc, char **argv)
}
if (generate != 0 || read_dh_params != NULL) {
- gnutls_certificate_set_dh_params(cert_cred, dh_params);
- gnutls_certificate_set_rsa_export_params(cert_cred, rsa_params);
+ gnutls_certificate_set_params_function( cert_cred, get_params);
+/* gnutls_certificate_set_dh_params(cert_cred, dh_params);
+ * gnutls_certificate_set_rsa_export_params(cert_cred, rsa_params);
+ */
}
/* this is a password file (created with the included srpcrypt utility)
@@ -691,7 +709,9 @@ int main(int argc, char **argv)
#ifdef ENABLE_ANON
gnutls_anon_allocate_server_credentials(&dh_cred);
if (generate != 0)
- gnutls_anon_set_server_dh_params(dh_cred, dh_params);
+ gnutls_anon_set_params_function( dh_cred, get_params);
+
+/* gnutls_anon_set_server_dh_params(dh_cred, dh_params); */
#endif
h = listen_socket(name, port);