summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-06-16 12:11:33 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-06-16 12:11:33 +0000
commit549279f8d2f32acd54699cccbf1e3ace9e0da515 (patch)
treeb3561339427890dc10c7f761a5e6fc494c235a06
parent780c45c9fcc8719cb13f6ff5abcc73b7725de5df (diff)
downloadgnutls-549279f8d2f32acd54699cccbf1e3ace9e0da515.tar.gz
more rsa fixes.
Added dnsname extension.
-rw-r--r--lib/Makefile.am6
-rw-r--r--lib/auth_anon.c57
-rw-r--r--lib/auth_dhe_dss.c18
-rw-r--r--lib/auth_rsa.c94
-rw-r--r--lib/auth_srp.c17
-rw-r--r--lib/auth_x509.h30
-rw-r--r--lib/defines.h4
-rw-r--r--lib/ext_dnsname.c77
-rw-r--r--lib/ext_dnsname.h2
-rw-r--r--lib/gnutls.c2
-rw-r--r--lib/gnutls.h.in18
-rw-r--r--lib/gnutls_auth_int.h2
-rw-r--r--lib/gnutls_dh.c17
-rw-r--r--lib/gnutls_extensions.c2
-rw-r--r--lib/gnutls_handshake.c55
-rw-r--r--lib/gnutls_int.h31
-rw-r--r--lib/gnutls_kx.c46
-rw-r--r--lib/gnutls_kx.h1
-rw-r--r--lib/gnutls_srp.c25
19 files changed, 343 insertions, 161 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 1e81f3857a..ae4a52eeb3 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -13,7 +13,8 @@ EXTRA_DIST = debug.h gnutls_compress.h defines.h gnutls_plaintext.h \
gnutls_auth_int.h crypt_bcrypt.h gnutls_random.h crypt_srpsha1.h \
cert_b64.h gnutls_srp.h auth_srp.h auth_srp_passwd.h gnutls_v2_compat.h \
crypt.h libgnutls-config.in libgnutls.m4 gnutls.h.in gnutls_errors_int.h \
- cert_asn1.h cert_der.h gnutls_datum.h auth_x509.c
+ cert_asn1.h cert_der.h gnutls_datum.h auth_x509.h gnutls_gcry.h \
+ ext_dnsname.h
lib_LTLIBRARIES = libgnutls.la
libgnutls_la_SOURCES = gnutls.c gnutls_compress.c debug.c gnutls_plaintext.c \
gnutls_cipher.c gnutls_buffers.c gnutls_handshake.c gnutls_num.c \
@@ -23,6 +24,7 @@ libgnutls_la_SOURCES = gnutls.c gnutls_compress.c debug.c gnutls_plaintext.c \
auth_anon.c auth_dhe_dss.c gnutls_extensions.c ext_srp.c gnutls_auth.c \
crypt_bcrypt.c crypt.c gnutls_random.c crypt_srpsha1.c gnutls_srp.c \
auth_srp.c auth_srp_passwd.c gnutls_v2_compat.c auth_srp_sb64.c \
- cert_ASN.y cert_asn1.c cert_der.c gnutls_datum.c auth_rsa.c
+ cert_ASN.y cert_asn1.c cert_der.c gnutls_datum.c auth_rsa.c \
+ gnutls_gcry.c ext_dnsname.c
libgnutls_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
diff --git a/lib/auth_anon.c b/lib/auth_anon.c
index 43dd30d7f8..1efd201d48 100644
--- a/lib/auth_anon.c
+++ b/lib/auth_anon.c
@@ -25,6 +25,7 @@
#include "gnutls_dh.h"
#include "auth_anon.h"
#include "gnutls_num.h"
+#include "gnutls_gcry.h"
#define DEFAULT_BITS 1024
@@ -50,6 +51,19 @@ MOD_AUTH_STRUCT anon_auth_struct = {
NULL
};
+/* this function will copy an MPI key to
+ * opaque data.
+ */
+int _gnutls_generate_key(GNUTLS_KEY key) {
+ gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &key->key.size, key->KEY);
+ key->key.data = secure_malloc( key->key.size);
+ if (key->key.data==NULL) {
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+ gcry_mpi_print(GCRYMPI_FMT_USG, key->key.data, &key->key.size, key->KEY);
+ return 0;
+}
+
int gen_anon_server_kx( GNUTLS_KEY key, opaque** data) {
GNUTLS_MPI x, X, g, p;
int bits;
@@ -81,19 +95,19 @@ int gen_anon_server_kx( GNUTLS_KEY key, opaque** data) {
(*data) = gnutls_malloc(n_g + n_p + n_X + 6);
data_p = &(*data)[0];
gcry_mpi_print(GCRYMPI_FMT_USG, &data_p[2], &n_p, p);
- gnutls_mpi_release(p);
+ _gnutls_mpi_release(&p);
WRITEuint16( n_p, data_p);
data_g = &data_p[2 + n_p];
gcry_mpi_print(GCRYMPI_FMT_USG, &data_g[2], &n_g, g);
- gnutls_mpi_release(g);
+ _gnutls_mpi_release(&g);
WRITEuint16( n_g, data_g);
data_X = &data_g[2 + n_g];
gcry_mpi_print(GCRYMPI_FMT_USG, &data_X[2], &n_X, X);
- gnutls_mpi_release(X);
+ _gnutls_mpi_release(&X);
WRITEuint16( n_X, data_X);
@@ -103,6 +117,7 @@ int gen_anon_server_kx( GNUTLS_KEY key, opaque** data) {
int gen_anon_client_kx( GNUTLS_KEY key, opaque** data) {
GNUTLS_MPI x, X;
size_t n_X;
+int ret;
X = gnutls_calc_dh_secret(&x, key->client_g,
key->client_p);
@@ -113,7 +128,7 @@ size_t n_X;
gcry_mpi_print(GCRYMPI_FMT_USG, &(*data)[2], &n_X, X);
(*data)[0] = 1; /* extern - explicit since we do not have
certificate */
- gnutls_mpi_release(X);
+ _gnutls_mpi_release(&X);
WRITEuint16( n_X, &(*data)[0]);
@@ -121,13 +136,16 @@ size_t n_X;
key->KEY = gnutls_calc_dh_key(key->client_Y, x, key->client_p);
/* THESE SHOULD BE DISCARDED */
- gnutls_mpi_release(key->client_Y);
- gnutls_mpi_release(key->client_p);
- gnutls_mpi_release(key->client_g);
- key->client_Y = NULL;
- key->client_p = NULL;
- key->client_g = NULL;
+ _gnutls_mpi_release(&key->client_Y);
+ _gnutls_mpi_release(&key->client_p);
+ _gnutls_mpi_release(&key->client_g);
+
+ ret = _gnutls_generate_key( key);
+ _gnutls_mpi_release(&key->KEY);
+ if (ret < 0) {
+ return ret;
+ }
return n_X+2;
}
@@ -207,7 +225,7 @@ int proc_anon_client_kx( GNUTLS_KEY key, opaque* data, int data_size) {
uint16 n_Y;
size_t _n_Y;
MPI g, p;
- int bits;
+ int bits, ret;
const ANON_SERVER_CREDENTIALS * cred;
cred = _gnutls_get_cred( key, GNUTLS_ANON, NULL);
@@ -238,12 +256,17 @@ int proc_anon_client_kx( GNUTLS_KEY key, opaque* data, int data_size) {
g = gnutls_get_dh_params(&p, bits);
key->KEY = gnutls_calc_dh_key( key->client_Y, key->dh_secret, p);
- gnutls_mpi_release(key->client_Y);
- gnutls_mpi_release(key->dh_secret);
- gnutls_mpi_release(p);
- gnutls_mpi_release(g);
- key->client_Y = NULL;
- key->dh_secret = NULL;
+ _gnutls_mpi_release(&key->client_Y);
+ _gnutls_mpi_release(&key->dh_secret);
+ _gnutls_mpi_release(&p);
+ _gnutls_mpi_release(&g);
+
+ ret = _gnutls_generate_key( key);
+ _gnutls_mpi_release(&key->KEY);
+
+ if (ret < 0) {
+ return ret;
+ }
return 0;
}
diff --git a/lib/auth_dhe_dss.c b/lib/auth_dhe_dss.c
index 24520ce9dc..dd008e3114 100644
--- a/lib/auth_dhe_dss.c
+++ b/lib/auth_dhe_dss.c
@@ -92,19 +92,19 @@ int gen_dhe_dss_server_kx( GNUTLS_KEY key, opaque** data) {
(*data) = gnutls_malloc(n_g + n_p + n_X + 6);
data_p = &(*data)[0];
gcry_mpi_print(GCRYMPI_FMT_USG, &data_p[2], &n_p, p);
- gnutls_mpi_release(p);
+ _gnutls_mpi_release(p);
WRITEuint16( n_p, data_p);
data_g = &data_p[2 + n_p];
gcry_mpi_print(GCRYMPI_FMT_USG, &data_g[2], &n_g, g);
- gnutls_mpi_release(g);
+ _gnutls_mpi_release(g);
WRITEuint16( n_g, data_g);
data_X = &data_g[2 + n_g];
gcry_mpi_print(GCRYMPI_FMT_USG, &data_X[2], &n_X, X);
- gnutls_mpi_release(X);
+ _gnutls_mpi_release(X);
WRITEuint16( n_X, data_X);
@@ -126,7 +126,7 @@ size_t n_X;
gcry_mpi_print(GCRYMPI_FMT_USG, &(*data)[2], &n_X, X);
(*data)[0] = 1; /* extern - explicit since we do not have
certificate */
- gnutls_mpi_release(X);
+ _gnutls_mpi_release(X);
WRITEuint16( n_X, &(*data)[0]);
@@ -134,9 +134,9 @@ size_t n_X;
key->KEY = _gnutls_calc_dh_key(key->client_Y, x, key->client_p);
/* THESE SHOULD BE DISCARDED */
- gnutls_mpi_release(key->client_Y);
- gnutls_mpi_release(key->client_p);
- gnutls_mpi_release(key->client_g);
+ _gnutls_mpi_release(key->client_Y);
+ _gnutls_mpi_release(key->client_p);
+ _gnutls_mpi_release(key->client_g);
key->client_Y = NULL;
key->client_p = NULL;
key->client_g = NULL;
@@ -248,8 +248,8 @@ int proc_dhe_dss_client_kx( GNUTLS_KEY key, opaque* data, int data_size) {
mpi_release(g);
mpi_release(p);
- gnutls_mpi_release(key->client_Y);
- gnutls_mpi_release(key->dh_secret);
+ _gnutls_mpi_release(key->client_Y);
+ _gnutls_mpi_release(key->dh_secret);
key->client_Y = NULL;
key->dh_secret = NULL;
diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c
index 7d4c3aa3b5..9b72d9ceea 100644
--- a/lib/auth_rsa.c
+++ b/lib/auth_rsa.c
@@ -23,7 +23,6 @@
#include "gnutls_auth_int.h"
#include "gnutls_errors.h"
#include "gnutls_dh.h"
-#include "auth_anon.h"
#include "gnutls_num.h"
#include "cert_asn1.h"
#include "cert_der.h"
@@ -106,7 +105,7 @@ int _gnutls_calc_rsa_signature( GNUTLS_KEY key, const opaque* data, int data_siz
return ret;
}
-
+#if 0
/* This function reads the RSA parameters from the given(?) certificate.
*/
static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_datum cert)
@@ -179,20 +178,20 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_d
gnutls_assert();
delete_structure("rsapublickey");
gnutls_free_datum(&params->rsa_modulus);
- gcry_mpi_release(key->A);
+ _gnutls_mpi_release(&key->A);
return GNUTLS_E_PARSING_ERROR;
}
if (gcry_mpi_scan(&key->B,
GCRYMPI_FMT_USG, str, &len) != 0) {
gnutls_assert();
- gcry_mpi_release(key->A);
+ _gnutls_mpi_release(&key->A);
gnutls_free_datum(&params->rsa_modulus);
delete_structure("rsapublickey");
return GNUTLS_E_MPI_SCAN_FAILED;
}
if (gnutls_set_datum(&params->rsa_exponent, str, len) < 0) {
- gcry_mpi_release(key->A);
+ _gnutls_mpi_release(&key->A);
gnutls_free_datum(&params->rsa_modulus);
delete_structure("rsapublickey");
return GNUTLS_E_MEMORY_ERROR;
@@ -206,6 +205,7 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_d
return ret;
}
+#endif
/* This function reads the RSA parameters from the given private key
* cert is not a certificate but a der structure containing the private
@@ -246,7 +246,7 @@ static int _gnutls_get_private_rsa_params( GNUTLS_KEY key, gnutls_datum cert)
if (result != ASN_OK) {
gnutls_assert();
delete_structure("rsa_key");
- gcry_mpi_release(key->u);
+ _gnutls_mpi_release(&key->u);
return GNUTLS_E_PARSING_ERROR;
}
@@ -254,7 +254,7 @@ static int _gnutls_get_private_rsa_params( GNUTLS_KEY key, gnutls_datum cert)
GCRYMPI_FMT_USG, str, &len) != 0) {
gnutls_assert();
delete_structure("rsa_key");
- gcry_mpi_release(key->u);
+ _gnutls_mpi_release(&key->u);
return GNUTLS_E_MPI_SCAN_FAILED;
}
@@ -314,20 +314,33 @@ int gen_rsa_server_kx(GNUTLS_KEY key, opaque ** data)
int gen_rsa_certificate(GNUTLS_KEY key, opaque ** data)
{
- RSA_Params params;
const X509PKI_SERVER_CREDENTIALS *cred;
int ret, i;
opaque* pdata;
-
+ gnutls_datum* apr_cert_list;
+ gnutls_datum apr_pkey;
+ int apr_cert_list_length;
+
cred = _gnutls_get_cred(key, GNUTLS_X509PKI, NULL);
if (cred == NULL) {
gnutls_assert();
return GNUTLS_E_INSUFICIENT_CRED;
}
+ if (cred->ncerts==0) {
+ gnutls_assert();
+ return GNUTLS_E_INSUFICIENT_CRED;
+ }
+
+ /* FIXME: FIND APPROPRIATE CERTIFICATE - depending on hostname
+ */
+ apr_cert_list = cred->cert_list[0];
+ apr_cert_list_length = cred->cert_list_length[0];
+ apr_pkey = cred->pkey[0];
+
ret = 3;
- for (i=0;i<cred->cert_list_size;i++) {
- ret += cred->cert_list[i].size + 3;
+ for (i=0;i<apr_cert_list_length;i++) {
+ ret += apr_cert_list[i].size + 3;
/* hold size
* for uint24 */
}
@@ -342,64 +355,35 @@ int gen_rsa_certificate(GNUTLS_KEY key, opaque ** data)
WRITEuint24( ret-3, pdata);
pdata+=3;
- for (i=0;i<cred->cert_list_size;i++) {
- WRITEdatum24( pdata, cred->cert_list[i]);
- pdata += 3 + cred->cert_list[i].size;
- }
-
- return ret;
-}
-
-
-int proc_anon_client_kx( GNUTLS_KEY key, opaque* data, int data_size) {
- uint16 n_Y;
- size_t _n_Y;
- MPI g, p;
- int bits;
- const RSA_SERVER_CREDENTIALS * cred;
-
- cred = _gnutls_get_cred(key, GNUTLS_X509PKI, NULL);
- if (cred == NULL) {
- gnutls_assert();
- return GNUTLS_E_INSUFICIENT_CRED;
+ for (i=0;i<apr_cert_list_length;i++) {
+ WRITEdatum24( pdata, apr_cert_list[i]);
+ pdata += 3 + apr_cert_list[i].size;
}
+ /* read the rsa parameters now, since later we will
+ * now know which certificate we used!
+ */
ret =
- _gnutls_get_rsa_params(key, &params, cred->cert_list[0]);
+ _gnutls_get_private_rsa_params(key, apr_pkey);
if (ret < 0) {
gnutls_assert();
return ret;
}
-#if 0 /* removed. I do not know why - maybe I didn't get the protocol,
- * but openssl does not use that byte
- */
- if (data[0] != 1) {
- gnutls_assert();
- return GNUTLS_E_UNIMPLEMENTED_FEATURE;
- }
-#endif
+ return ret;
+}
+
- n_Y = READuint16( &data[0]);
+int proc_rsa_client_kx( GNUTLS_KEY key, opaque* data, int data_size) {
+ const X509PKI_SERVER_CREDENTIALS * cred;
- _n_Y = n_Y;
- if (gcry_mpi_scan(&key->client_Y,
- GCRYMPI_FMT_USG, &data[2], &_n_Y)) {
+ cred = _gnutls_get_cred(key, GNUTLS_X509PKI, NULL);
+ if (cred == NULL) {
gnutls_assert();
- return GNUTLS_E_MPI_SCAN_FAILED;
+ return GNUTLS_E_INSUFICIENT_CRED;
}
- g = gnutls_get_dh_params(&p, bits);
- key->KEY = gnutls_calc_dh_key( key->client_Y, key->dh_secret, p);
-
- gnutls_mpi_release(key->client_Y);
- gnutls_mpi_release(key->dh_secret);
- gnutls_mpi_release(p);
- gnutls_mpi_release(g);
- key->client_Y = NULL;
- key->dh_secret = NULL;
-
return 0;
}
diff --git a/lib/auth_srp.c b/lib/auth_srp.c
index c8fd2cef6b..08d1d3b697 100644
--- a/lib/auth_srp.c
+++ b/lib/auth_srp.c
@@ -149,6 +149,7 @@ int gen_srp_server_kx(GNUTLS_KEY key, opaque ** data)
/* send the second key exchange message */
int gen_srp_server_kx2(GNUTLS_KEY key, opaque ** data)
{
+ int ret;
size_t n_b;
uint8 *data_b;
@@ -179,6 +180,12 @@ int gen_srp_server_kx2(GNUTLS_KEY key, opaque ** data)
mpi_release(key->u);
mpi_release(B);
+ ret = _gnutls_generate_key( key);
+ _gnutls_mpi_release(&S);
+
+ if (ret < 0)
+ return ret;
+
return n_b + 2;
}
@@ -330,7 +337,8 @@ int proc_srp_client_kx0(GNUTLS_KEY key, opaque * data, int data_size)
int proc_srp_server_kx2(GNUTLS_KEY key, opaque * data, int data_size)
{
size_t _n_B;
-
+ int ret;
+
_n_B = READuint16( &data[0]);
if (gcry_mpi_scan(&B, GCRYMPI_FMT_USG, &data[2], &_n_B)) {
@@ -349,6 +357,13 @@ int proc_srp_server_kx2(GNUTLS_KEY key, opaque * data, int data_size)
mpi_release(V);
mpi_release(key->u);
mpi_release(B);
+
+ ret = _gnutls_generate_key( key);
+ _gnutls_mpi_release(&S);
+
+ if (ret < 0)
+ return ret;
+
return 0;
}
diff --git a/lib/auth_x509.h b/lib/auth_x509.h
index a6f5550111..8cfd1aed89 100644
--- a/lib/auth_x509.h
+++ b/lib/auth_x509.h
@@ -1,12 +1,34 @@
/* this is not to be included by gnutls_anon.c */
extern MOD_AUTH_STRUCT x509pki_auth_struct;
+/* This structure may be complex but, it's the only way to
+ * support a server that has multiple certificates
+ */
typedef struct {
- gnutls_datum * cert_list;
- int cert_list_size;
- gnutls_datum pkey; /* private key */
+ gnutls_datum ** cert_list;
+ /* contains a list of a list of certificates.
+ * eg: [0] certificate1, certificate11, certificate111
+ * (if more than one, one certificate certifies the one before)
+ * [1] certificate2, certificate22, ...
+ */
+ int * cert_list_length;
+ /* contains the number of the certificates in one
+ * row.
+ */
+ int ncerts; /* contains the number of columns in cert_list.
+ */
+ gnutls_datum * pkey; /* private keys. It contains ncerts private
+ * keys. pkey[i] corresponds to certificate in
+ * cert_list[i][0].
+ */
} X509PKI_SERVER_CREDENTIALS;
typedef struct {
- int dh_bits;
+ opaque dnsname[256];
+} X509PKI_CLIENT_CREDENTIALS;
+
+typedef struct {
+ opaque dnsname[256]; /* the client may send us the
+ * hostname he thinks he connected to.
+ */
} X509PKI_AUTH_INFO;
diff --git a/lib/defines.h b/lib/defines.h
index 9a16d69774..cfbb8bbf4e 100644
--- a/lib/defines.h
+++ b/lib/defines.h
@@ -49,10 +49,6 @@
# include <gdbm.h>
#endif
-#ifdef USE_GCRYPT
-# include <gcrypt.h>
-#endif
-
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
diff --git a/lib/ext_dnsname.c b/lib/ext_dnsname.c
new file mode 100644
index 0000000000..4218877d59
--- /dev/null
+++ b/lib/ext_dnsname.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2001 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
+ */
+
+#include <defines.h>
+#include "gnutls_int.h"
+#include "gnutls_auth_int.h"
+#include "auth_x509.h"
+#include "gnutls_errors.h"
+
+int _gnutls_dnsname_recv_params( GNUTLS_STATE state, const opaque* data, int data_size) {
+ uint8 len;
+ if (state->security_parameters.entity == GNUTLS_SERVER) {
+ if (data_size > 0) {
+ state->gnutls_key->auth_info = gnutls_calloc(1, sizeof(X509PKI_AUTH_INFO));
+ if (state->gnutls_key->auth_info==NULL) return GNUTLS_E_MEMORY_ERROR;
+
+ if (sizeof( ((X509PKI_AUTH_INFO*)state->gnutls_key->auth_info)->dnsname) > data_size) {
+ len = data[0];
+ if (len > data_size) {
+ gnutls_assert();
+ return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ }
+ memcpy( ((X509PKI_AUTH_INFO*)state->gnutls_key->auth_info)->dnsname, &data[1], len);
+ ((X509PKI_AUTH_INFO*)state->gnutls_key->auth_info)->dnsname[len]=0; /* null terminated */
+ state->gnutls_key->auth_info_size = sizeof(X509PKI_AUTH_INFO);
+ } else {
+ state->gnutls_key->auth_info_size = 0;
+ gnutls_free(state->gnutls_key->auth_info);
+ state->gnutls_key->auth_info = NULL;
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+ }
+ }
+ return 0;
+}
+
+/* returns data_size or a negative number on failure
+ * data is allocated localy
+ */
+int _gnutls_dnsname_send_params( GNUTLS_STATE state, opaque** data) {
+ uint8 len;
+ /* this function sends the client extension data (dnsname) */
+ if (state->security_parameters.entity == GNUTLS_CLIENT) {
+ const X509PKI_CLIENT_CREDENTIALS* cred = _gnutls_get_cred( state->gnutls_key, GNUTLS_X509PKI, NULL);
+
+ (*data) = NULL;
+
+ if (cred==NULL) return 0;
+
+ if (cred->dnsname!=NULL) { /* send dnsname */
+ len = strlen(cred->dnsname);
+ (*data) = gnutls_malloc(len+1); /* hold the size also */
+ (*data)[0] = len;
+ memcpy( &(*data)[1], cred->dnsname, len);
+ return len + 1;
+ }
+ }
+ return 0;
+}
diff --git a/lib/ext_dnsname.h b/lib/ext_dnsname.h
new file mode 100644
index 0000000000..89ae8bcfcc
--- /dev/null
+++ b/lib/ext_dnsname.h
@@ -0,0 +1,2 @@
+int _gnutls_dnsname_recv_params( GNUTLS_STATE state, const opaque* data, int data_size);
+int _gnutls_dnsname_send_params( GNUTLS_STATE state, opaque** data);
diff --git a/lib/gnutls.c b/lib/gnutls.c
index 07e6a69cad..71dd379ef3 100644
--- a/lib/gnutls.c
+++ b/lib/gnutls.c
@@ -50,6 +50,8 @@ GNUTLS_Version ver;
void gnutls_set_current_version(GNUTLS_STATE state, GNUTLS_Version version) {
state->connection_state.version = version;
+ state->gnutls_key->version.major = _gnutls_version_get_major(version);
+ state->gnutls_key->version.minor = _gnutls_version_get_minor(version);
}
int gnutls_is_secure_memory(const void* mem) {
diff --git a/lib/gnutls.h.in b/lib/gnutls.h.in
index 1e26a50282..90406998d1 100644
--- a/lib/gnutls.h.in
+++ b/lib/gnutls.h.in
@@ -142,9 +142,21 @@ typedef struct {
} ANON_AUTH_INFO;
typedef struct {
- gnutls_datum * cert_list;
- int cert_list_size;
- gnutls_datum pkey; /* private key */
+ gnutls_datum ** cert_list;
+ /* contains a list of a list of certificates.
+ * eg: [0] certificate1, certificate11, certificate111
+ * (if more than one, one certificate certifies the one before)
+ * [1] certificate2, certificate22, ...
+ */
+ int * cert_list_length;
+ /* contains the number of the certificates in one
+ * row.
+ */
+ int ncerts; /* contains the number of columns in cert_list.
+ */
+ gnutls_datum * pkey; /* private keys. It contains ncerts private
+ * keys.
+ */
} X509PKI_SERVER_CREDENTIALS;
/* error codes appended here */
diff --git a/lib/gnutls_auth_int.h b/lib/gnutls_auth_int.h
index 2b34b6160c..1deb4da09f 100644
--- a/lib/gnutls_auth_int.h
+++ b/lib/gnutls_auth_int.h
@@ -2,4 +2,4 @@ int gnutls_clear_creds( GNUTLS_STATE state);
int gnutls_set_cred( GNUTLS_STATE state, CredType type, void* cred);
const void *_gnutls_get_cred( GNUTLS_KEY key, CredType kx, int* err);
const void *_gnutls_get_kx_cred( GNUTLS_KEY key, KXAlgorithm algo, int *err);
-
+int _gnutls_generate_key(GNUTLS_KEY key);
diff --git a/lib/gnutls_dh.c b/lib/gnutls_dh.c
index 3137de71c3..a66a1d4180 100644
--- a/lib/gnutls_dh.c
+++ b/lib/gnutls_dh.c
@@ -22,8 +22,7 @@
#include <defines.h>
#include <gnutls_int.h>
#include <gnutls_errors.h>
-
-/* Taken from gsti */
+#include <gnutls_gcry.h>
#define DH_G_1024 2
#define DH_G_4096 5
@@ -235,8 +234,8 @@ const uint8 diffie_hellman_prime_2048[256] = {
X = gnutls_calc_dh_secret(&x, g, p);
// now we can calculate the shared secret
key = gnutls_calc_dh_key(Y, x, g, p);
- gnutls_mpi_release(x);
- gnutls_mpi_release(g);
+ _gnutls_mpi_release(x);
+ _gnutls_mpi_release(g);
*/
@@ -266,7 +265,7 @@ MPI gnutls_calc_dh_secret(MPI * ret_x, MPI g, MPI prime)
if (ret_x)
*ret_x = x;
else
- gcry_mpi_release(x);
+ _gnutls_mpi_release(&x);
return e;
}
@@ -299,7 +298,7 @@ MPI gnutls_get_dh_params(MPI * ret_p, int bits)
if (ret_p)
*ret_p = prime;
else
- gcry_mpi_release(prime);
+ _gnutls_mpi_release(&prime);
return g;
case 2048:
n = sizeof diffie_hellman_prime_2048;
@@ -315,7 +314,7 @@ MPI gnutls_get_dh_params(MPI * ret_p, int bits)
if (ret_p)
*ret_p = prime;
else
- gcry_mpi_release(prime);
+ _gnutls_mpi_release(&prime);
return g;
case 3072:
n = sizeof diffie_hellman_prime_3072;
@@ -331,7 +330,7 @@ MPI gnutls_get_dh_params(MPI * ret_p, int bits)
if (ret_p)
*ret_p = prime;
else
- gcry_mpi_release(prime);
+ _gnutls_mpi_release(&prime);
return g;
case 4096:
n = sizeof diffie_hellman_prime_4096;
@@ -347,7 +346,7 @@ MPI gnutls_get_dh_params(MPI * ret_p, int bits)
if (ret_p)
*ret_p = prime;
else
- gcry_mpi_release(prime);
+ _gnutls_mpi_release(&prime);
return g;
default:
gnutls_assert();
diff --git a/lib/gnutls_extensions.c b/lib/gnutls_extensions.c
index 026648afac..3f67464e65 100644
--- a/lib/gnutls_extensions.c
+++ b/lib/gnutls_extensions.c
@@ -23,6 +23,7 @@
#include "gnutls_extensions.h"
#include "gnutls_errors.h"
#include "ext_srp.h"
+#include "ext_dnsname.h"
#include "gnutls_num.h"
/* Key Exchange Section */
@@ -39,6 +40,7 @@ typedef struct {
#define MAX_EXT 20 /* maximum supported extension */
static gnutls_extension_entry extensions[] = {
GNUTLS_EXTENSION_ENTRY(GNUTLS_EXTENSION_SRP, _gnutls_srp_recv_params, _gnutls_srp_send_params),
+ GNUTLS_EXTENSION_ENTRY(GNUTLS_EXTENSION_DNSNAME, _gnutls_dnsname_recv_params, _gnutls_dnsname_send_params),
{0}
};
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index a05c6a9179..46cf3e663d 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -50,6 +50,15 @@
static int SelectSuite(GNUTLS_STATE state, opaque ret[2], char *data, int datalen);
static int SelectCompMethod(GNUTLS_STATE state, CompressionMethod * ret, opaque * data, int datalen);
+static void set_server_random( GNUTLS_STATE state, uint8* random) {
+ memcpy( state->security_parameters.server_random, random, 32);
+ memcpy( state->gnutls_key->server_random, random, 32);
+}
+static void set_client_random( GNUTLS_STATE state, uint8* random) {
+ memcpy( state->security_parameters.client_random, random, 32);
+ memcpy( state->gnutls_key->client_random, random, 32);
+}
+
/* Calculate The SSL3 Finished message */
#define SSL3_CLIENT_MSG "CLNT"
#define SSL3_SERVER_MSG "SRVR"
@@ -144,6 +153,24 @@ void *_gnutls_finished(GNUTLS_STATE state, int type, int skip)
return data;
}
+/* this function will produce 32 bytes of random data
+ * and put it to dst.
+ */
+static int create_random( opaque* dst) {
+uint32 tim;
+opaque* rand;
+
+ tim = time(NULL);
+ /* generate server random value */
+ WRITEuint32( tim, dst);
+
+ rand = _gnutls_get_random(28, GNUTLS_STRONG_RANDOM);
+ memcpy( &dst[4], rand, 28);
+
+ _gnutls_free_rand(rand);
+
+ return 0;
+}
/* Read a client hello
* client hello must be a known version client hello
@@ -161,10 +188,10 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
int ret = 0;
uint16 sizeOfSuites;
GNUTLS_Version version;
- char *rand;
int len = datalen;
int err;
-
+ opaque random[32];
+
if (state->gnutls_internals.v2_hello!=0) { /* version 2.0 */
return _gnutls_read_client_hello_v2(state, data, datalen);
}
@@ -189,15 +216,12 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
pos += 2;
DECR_LEN(len, 32);
- memcpy(state->security_parameters.client_random, &data[pos], 32);
+ set_client_random( state, &data[pos]);
pos += 32;
- /* generate server random value */
- WRITEuint32( time(NULL), state->security_parameters.server_random);
+ create_random( random);
+ set_server_random( state, random);
- rand = _gnutls_get_random(28, GNUTLS_STRONG_RANDOM);
- memcpy(&state->security_parameters.server_random[4], rand, 28);
- _gnutls_free_rand(rand);
state->security_parameters.timestamp = time(NULL);
DECR_LEN(len, 1);
@@ -761,8 +785,7 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale
pos += 2;
DECR_LEN(len, 32);
- memcpy(state->security_parameters.server_random,
- &data[pos], 32);
+ set_server_random( state, &data[pos]);
pos += 32;
DECR_LEN(len, 1);
@@ -902,7 +925,6 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale
int _gnutls_send_hello(int cd, GNUTLS_STATE state)
{
- char *rand;
char *data = NULL;
opaque *extdata;
int extdatalen;
@@ -912,6 +934,7 @@ int _gnutls_send_hello(int cd, GNUTLS_STATE state)
uint8 *compression_methods;
int i, datalen, ret = 0;
uint16 x;
+ opaque random[32];
if (state->security_parameters.entity == GNUTLS_CLIENT) {
opaque * SessionID = state->gnutls_internals.resumed_security_parameters.session_id;
@@ -932,13 +955,9 @@ int _gnutls_send_hello(int cd, GNUTLS_STATE state)
_gnutls_version_get_minor(state->connection_state.
version);
- WRITEuint32( time(NULL), state->security_parameters.client_random);
-
- rand = _gnutls_get_random(28, GNUTLS_STRONG_RANDOM);
- memcpy(&state->security_parameters.client_random[4], rand,
- 28);
- _gnutls_free_rand(rand);
-
+ create_random( random);
+ set_client_random( state, random);
+
state->security_parameters.timestamp = time(0);
memcpy(&data[pos],
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 403cc1c208..8fac4a42e8 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -49,7 +49,11 @@
#define MAX_RECV_SIZE 18432+HEADER_SIZE /* 2^14+2048+HEADER_SIZE */
#ifdef USE_DMALLOC
-#include <dmalloc.h>
+# include <dmalloc.h>
+#endif
+
+#ifdef USE_GCRYPT
+# include <gnutls_gcry.h>
#endif
#define GNUTLS_MPI MPI
@@ -106,7 +110,7 @@ typedef struct {
/* STATE */
typedef enum ConnectionEnd { GNUTLS_SERVER, GNUTLS_CLIENT } ConnectionEnd;
typedef enum BulkCipherAlgorithm { GNUTLS_NULL_CIPHER=1, GNUTLS_ARCFOUR, GNUTLS_3DES, GNUTLS_RIJNDAEL, GNUTLS_TWOFISH, GNUTLS_RIJNDAEL256 } BulkCipherAlgorithm;
-typedef enum Extensions { GNUTLS_EXTENSION_SRP=7 } Extensions;
+typedef enum Extensions { GNUTLS_EXTENSION_SRP=7, GNUTLS_EXTENSION_DNSNAME } Extensions;
typedef enum KXAlgorithm { GNUTLS_KX_RSA=1, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_DH_DSS, GNUTLS_KX_DH_RSA, GNUTLS_KX_DH_ANON, GNUTLS_KX_SRP } KXAlgorithm;
typedef enum CredType { GNUTLS_X509PKI=1, GNUTLS_ANON, GNUTLS_SRP } CredType;
typedef enum CipherType { CIPHER_STREAM, CIPHER_BLOCK } CipherType;
@@ -125,8 +129,15 @@ typedef struct {
void* next;
} AUTH_CRED;
+
+typedef struct {
+ uint8 major;
+ uint8 minor;
+} ProtocolVersion;
+
typedef struct {
/* For DH KX */
+ gnutls_datum key;
MPI KEY;
MPI client_Y;
MPI client_g;
@@ -149,14 +160,15 @@ typedef struct {
*/
void* auth_info;
int auth_info_size; /* needed in order to store to db for restoring */
-
uint8 crypt_algo;
-
+
/* These are needed in RSA and DH signature calculation
*/
opaque server_random[32];
opaque client_random[32];
- AUTH_CRED* cred; /* used in srp, etc */
+ ProtocolVersion version;
+
+ AUTH_CRED* cred; /* used to specify keys/certificates etc */
} GNUTLS_KEY_A;
typedef GNUTLS_KEY_A* GNUTLS_KEY;
@@ -278,11 +290,6 @@ typedef enum ContentType { GNUTLS_CHANGE_CIPHER_SPEC=20, GNUTLS_ALERT, GNUTLS_HA
GNUTLS_APPLICATION_DATA } ContentType;
typedef struct {
- uint8 major;
- uint8 minor;
-} ProtocolVersion;
-
-typedef struct {
uint8 type;
ProtocolVersion version;
uint16 length;
@@ -321,8 +328,4 @@ int _gnutls_send_change_cipher_spec(int cd, GNUTLS_STATE state);
int _gnutls_version_cmp(GNUTLS_Version ver1, GNUTLS_Version ver2);
#define _gnutls_version_ssl3(x) _gnutls_version_cmp(x, GNUTLS_SSL3)
-#ifndef gcry_mpi_alloc_like
-# define gcry_mpi_alloc_like(x) gcry_mpi_new(gcry_mpi_get_nbits(x))
-#endif
-
#endif /* GNUTLS_INT_H */
diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c
index 9d6d0a26dd..fa5b7e1708 100644
--- a/lib/gnutls_kx.c
+++ b/lib/gnutls_kx.c
@@ -26,6 +26,7 @@
#include "gnutls_errors.h"
#include "gnutls_algorithms.h"
#include "debug.h"
+#include "gnutls_gcry.h"
#define MASTER_SECRET "master secret"
@@ -43,13 +44,8 @@ char random[64];
memmove(&random[32], state->security_parameters.server_random, 32);
/* generate premaster */
- gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &premaster_size, state->gnutls_key->KEY);
- premaster = secure_malloc(premaster_size);
- gcry_mpi_print(GCRYMPI_FMT_USG, premaster, &premaster_size, state->gnutls_key->KEY);
-
- /* THIS SHOULD BE DISCARDED */
- gnutls_mpi_release(state->gnutls_key->KEY);
- state->gnutls_key->KEY = NULL;
+ premaster_size = state->gnutls_key->key.size;
+ premaster = state->gnutls_key->key.data;
#ifdef HARD_DEBUG
fprintf(stderr, "PREMASTER SECRET: ");
@@ -69,6 +65,9 @@ char random[64];
random, 64, 48);
}
secure_free(premaster);
+ state->gnutls_key->key.size = 0;
+ state->gnutls_key->key.data = NULL;
+
#ifdef HARD_DEBUG
fprintf(stderr, "MASTER SECRET: %s\n", _gnutls_bin2hex(master, 48));
#endif
@@ -96,11 +95,6 @@ int _gnutls_send_server_kx_message(int cd, GNUTLS_STATE state)
if (state->gnutls_internals.auth_struct->gnutls_generate_server_kx==NULL)
return 0;
- /* copy random bytes - some algorithms need that.
- */
- memcpy( state->gnutls_key->server_random, state->security_parameters.server_random, 32);
- memcpy( state->gnutls_key->client_random, state->security_parameters.client_random, 32);
-
data_size = state->gnutls_internals.auth_struct->gnutls_generate_server_kx( state->gnutls_key, &data);
if (data_size < 0) {
@@ -412,3 +406,31 @@ int _gnutls_recv_client_kx_message0(int cd, GNUTLS_STATE state)
return ret;
}
+/* This is called when we want send our certificate
+ */
+int _gnutls_send_certificate(int cd, GNUTLS_STATE state)
+{
+ uint8 *data = NULL;
+ int data_size = 0;
+ int ret = 0;
+
+#ifdef HARD_DEBUG
+ fprintf(stderr, "Sending certificate message\n");
+#endif
+
+
+ if (state->gnutls_internals.auth_struct->gnutls_generate_certificate==NULL)
+ return 0;
+
+ data_size = state->gnutls_internals.auth_struct->gnutls_generate_certificate( state->gnutls_key, &data);
+
+ if (data_size < 0) {
+ gnutls_assert();
+ return data_size;
+ }
+
+ ret = _gnutls_send_handshake(cd, state, data, data_size, GNUTLS_CERTIFICATE);
+ gnutls_free(data);
+
+ return data_size;
+}
diff --git a/lib/gnutls_kx.h b/lib/gnutls_kx.h
index 325a7861f6..6408832a35 100644
--- a/lib/gnutls_kx.h
+++ b/lib/gnutls_kx.h
@@ -27,3 +27,4 @@ int _gnutls_recv_server_kx_message2(int cd, GNUTLS_STATE state);
int _gnutls_recv_client_kx_message(int cd, GNUTLS_STATE state);
int _gnutls_recv_client_kx_message0(int cd, GNUTLS_STATE state);
int _gnutls_send_client_certificate_verify(int cd, GNUTLS_STATE state);
+int _gnutls_send_certificate(int cd, GNUTLS_STATE state);
diff --git a/lib/gnutls_srp.c b/lib/gnutls_srp.c
index 31a269d3d2..8577c49262 100644
--- a/lib/gnutls_srp.c
+++ b/lib/gnutls_srp.c
@@ -24,6 +24,7 @@
#include <crypt_bcrypt.h>
#include <gnutls_srp.h>
#include <auth_srp_passwd.h>
+#include <gnutls_gcry.h>
#include "debug.h"
/* These should be added in gcrypt.h */
@@ -111,8 +112,8 @@ int _gnutls_srp_gn(opaque ** ret_g, opaque ** ret_n, int bits)
gnutls_free(tmp);
}
- gcry_mpi_release(g);
- gcry_mpi_release(prime);
+ _gnutls_mpi_release(&g);
+ _gnutls_mpi_release(&prime);
return 0;
@@ -135,7 +136,7 @@ int _gnutls_srp_gx(opaque * text, int textsize, opaque ** result, MPI g,
/* e = g^x mod prime (n) */
gcry_mpi_powm(e, g, x, prime);
- gcry_mpi_release(x);
+ _gnutls_mpi_release(&x);
gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &result_size, e);
if (result != NULL) {
@@ -143,7 +144,7 @@ int _gnutls_srp_gx(opaque * text, int textsize, opaque ** result, MPI g,
gcry_mpi_print(GCRYMPI_FMT_USG, *result, &result_size, e);
}
- gcry_mpi_release(e);
+ _gnutls_mpi_release(&e);
return result_size;
@@ -170,12 +171,12 @@ MPI _gnutls_calc_srp_B(MPI * ret_b, MPI g, MPI n, MPI v)
gcry_mpi_powm(tmpB, g, b, n);
gcry_mpi_addm(B, v, tmpB, n);
- gcry_mpi_release(tmpB);
+ _gnutls_mpi_release(&tmpB);
if (ret_b)
*ret_b = b;
else
- gcry_mpi_release(b);
+ _gnutls_mpi_release(&b);
return B;
}
@@ -220,10 +221,10 @@ MPI _gnutls_calc_srp_S1(MPI A, MPI b, MPI u, MPI v, MPI n)
gcry_mpi_powm(tmp1, v, u, n);
gcry_mpi_mulm(tmp2, A, tmp1, n);
- gcry_mpi_release(tmp1);
+ _gnutls_mpi_release(&tmp1);
gcry_mpi_powm(S, tmp2, b, n);
- gcry_mpi_release(tmp2);
+ _gnutls_mpi_release(&tmp2);
return S;
}
@@ -247,7 +248,7 @@ MPI _gnutls_calc_srp_A(MPI * a, MPI g, MPI n)
if (a != NULL)
*a = tmpa;
else
- gcry_mpi_release(tmpa);
+ _gnutls_mpi_release(&tmpa);
return A;
}
@@ -312,11 +313,11 @@ MPI _gnutls_calc_srp_S2(MPI B, MPI g, MPI x, MPI a, MPI u, MPI n)
gcry_mpi_mul(tmp1, u, x);
gcry_mpi_add(tmp4, a, tmp1);
- gcry_mpi_release(tmp1);
+ _gnutls_mpi_release(&tmp1);
gcry_mpi_powm(S, tmp2, tmp4, n);
- gcry_mpi_release(tmp2);
- gcry_mpi_release(tmp4);
+ _gnutls_mpi_release(&tmp2);
+ _gnutls_mpi_release(&tmp4);
return S;
}