summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-08-05 20:40:11 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-08-05 20:40:11 +0000
commit8fa8ed88631f45c133308f6db731520830713fb9 (patch)
tree14420c4d1933724c25ed2ef815d7b7d71c2521f2
parent93330469787a8b39a6f8c82f65305c7625487806 (diff)
downloadgnutls-8fa8ed88631f45c133308f6db731520830713fb9.tar.gz
several cleanups and updates in the handshake protocol implementation
iolaiiiiiCVS: ----------------------------------------------------------------------
-rw-r--r--lib/auth_anon.c75
-rw-r--r--lib/auth_anon.h2
-rw-r--r--lib/auth_rsa.c195
-rw-r--r--lib/auth_srp.c66
-rw-r--r--lib/auth_srp.h7
-rw-r--r--lib/auth_x509.h5
-rw-r--r--lib/ext_srp.c4
-rw-r--r--lib/gnutls_algorithms.c16
-rw-r--r--lib/gnutls_auth.h34
-rw-r--r--lib/gnutls_cert.c24
-rw-r--r--lib/gnutls_cert.h2
-rw-r--r--lib/gnutls_handshake.c324
-rw-r--r--lib/gnutls_int.h39
-rw-r--r--lib/gnutls_kx.c58
-rw-r--r--lib/gnutls_kx.h1
-rw-r--r--lib/gnutls_record.c11
-rw-r--r--lib/gnutls_ui.c13
17 files changed, 463 insertions, 413 deletions
diff --git a/lib/auth_anon.c b/lib/auth_anon.c
index 18eaf5afaf..e195d347cb 100644
--- a/lib/auth_anon.c
+++ b/lib/auth_anon.c
@@ -28,10 +28,10 @@
#define DEFAULT_BITS 1024
-int gen_anon_server_kx( GNUTLS_KEY, opaque**);
-int gen_anon_client_kx( GNUTLS_KEY, opaque**);
-int proc_anon_server_kx( GNUTLS_KEY, opaque*, int);
-int proc_anon_client_kx( GNUTLS_KEY, opaque*, int);
+int gen_anon_server_kx( GNUTLS_STATE, opaque**);
+int gen_anon_client_kx( GNUTLS_STATE, opaque**);
+int proc_anon_server_kx( GNUTLS_STATE, opaque*, int);
+int proc_anon_client_kx( GNUTLS_STATE, opaque*, int);
MOD_AUTH_STRUCT anon_auth_struct = {
"ANON",
@@ -42,6 +42,7 @@ MOD_AUTH_STRUCT anon_auth_struct = {
gen_anon_client_kx,
NULL,
NULL,
+
NULL, /* certificate */
proc_anon_server_kx,
NULL,
@@ -57,14 +58,14 @@ MOD_AUTH_STRUCT anon_auth_struct = {
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) {
+ 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) {
+int gen_anon_server_kx( GNUTLS_STATE state, opaque** data) {
MPI x, X, g, p;
int bits;
size_t n_X, n_g, n_p;
@@ -73,7 +74,7 @@ int gen_anon_server_kx( GNUTLS_KEY key, opaque** data) {
uint8 *data_X;
const ANON_SERVER_CREDENTIALS cred;
- cred = _gnutls_get_cred( key, GNUTLS_ANON, NULL);
+ cred = _gnutls_get_cred( state->gnutls_key, GNUTLS_ANON, NULL);
if (cred==NULL) {
bits = DEFAULT_BITS; /* default */
} else {
@@ -82,13 +83,13 @@ int gen_anon_server_kx( GNUTLS_KEY key, opaque** data) {
g = gnutls_get_dh_params(&p, bits);
- key->auth_info = gnutls_malloc(sizeof(ANON_SERVER_AUTH_INFO));
- if (key->auth_info==NULL) return GNUTLS_E_MEMORY_ERROR;
- ((ANON_SERVER_AUTH_INFO*)key->auth_info)->dh_bits = gcry_mpi_get_nbits(p);
- key->auth_info_size = sizeof(ANON_SERVER_AUTH_INFO);
+ state->gnutls_key->auth_info = gnutls_malloc(sizeof(ANON_SERVER_AUTH_INFO));
+ if (state->gnutls_key->auth_info==NULL) return GNUTLS_E_MEMORY_ERROR;
+ ((ANON_SERVER_AUTH_INFO*)state->gnutls_key->auth_info)->dh_bits = gcry_mpi_get_nbits(p);
+ state->gnutls_key->auth_info_size = sizeof(ANON_SERVER_AUTH_INFO);
X = gnutls_calc_dh_secret(&x, g, p);
- key->dh_secret = x;
+ state->gnutls_key->dh_secret = x;
gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_g, g);
gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_p, p);
gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_X, X);
@@ -114,13 +115,13 @@ int gen_anon_server_kx( GNUTLS_KEY key, opaque** data) {
return n_p+n_g+n_X+6;
}
-int gen_anon_client_kx( GNUTLS_KEY key, opaque** data) {
+int gen_anon_client_kx( GNUTLS_STATE state, opaque** data) {
MPI x, X;
size_t n_X;
int ret;
- X = gnutls_calc_dh_secret(&x, key->client_g,
- key->client_p);
+ X = gnutls_calc_dh_secret(&x, state->gnutls_key->client_g,
+ state->gnutls_key->client_p);
gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_X, X);
(*data) = gnutls_malloc(n_X + 2);
@@ -133,15 +134,15 @@ int ret;
WRITEuint16( n_X, &(*data)[0]);
/* calculate the key after calculating the message */
- key->KEY = gnutls_calc_dh_key(key->client_Y, x, key->client_p);
+ state->gnutls_key->KEY = gnutls_calc_dh_key(state->gnutls_key->client_Y, x, state->gnutls_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(&state->gnutls_key->client_Y);
+ _gnutls_mpi_release(&state->gnutls_key->client_p);
+ _gnutls_mpi_release(&state->gnutls_key->client_g);
- ret = _gnutls_generate_key( key);
- _gnutls_mpi_release(&key->KEY);
+ ret = _gnutls_generate_key( state->gnutls_key);
+ _gnutls_mpi_release(&state->gnutls_key->KEY);
if (ret < 0) {
return ret;
@@ -149,7 +150,7 @@ int ret;
return n_X+2;
}
-int proc_anon_server_kx( GNUTLS_KEY key, opaque* data, int data_size) {
+int proc_anon_server_kx( GNUTLS_STATE state, opaque* data, int data_size) {
uint16 n_Y, n_g, n_p;
size_t _n_Y, _n_g, _n_p;
uint8 *data_p;
@@ -191,28 +192,28 @@ int proc_anon_server_kx( GNUTLS_KEY key, opaque* data, int data_size) {
_n_g = n_g;
_n_p = n_p;
- if (gcry_mpi_scan(&key->client_Y,
+ if (gcry_mpi_scan(&state->gnutls_key->client_Y,
GCRYMPI_FMT_USG, data_Y, &_n_Y) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
- if (gcry_mpi_scan(&key->client_g,
+ if (gcry_mpi_scan(&state->gnutls_key->client_g,
GCRYMPI_FMT_USG, data_g, &_n_g) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
- if (gcry_mpi_scan(&key->client_p,
+ if (gcry_mpi_scan(&state->gnutls_key->client_p,
GCRYMPI_FMT_USG, data_p, &_n_p) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
/* set auth_info */
- key->auth_info = gnutls_malloc(sizeof(ANON_CLIENT_AUTH_INFO));
- if (key->auth_info==NULL) return GNUTLS_E_MEMORY_ERROR;
- ((ANON_CLIENT_AUTH_INFO*)key->auth_info)->dh_bits = gcry_mpi_get_nbits(key->client_p);
- key->auth_info_size = sizeof(ANON_CLIENT_AUTH_INFO);
+ state->gnutls_key->auth_info = gnutls_malloc(sizeof(ANON_CLIENT_AUTH_INFO));
+ if (state->gnutls_key->auth_info==NULL) return GNUTLS_E_MEMORY_ERROR;
+ ((ANON_CLIENT_AUTH_INFO*)state->gnutls_key->auth_info)->dh_bits = gcry_mpi_get_nbits(state->gnutls_key->client_p);
+ state->gnutls_key->auth_info_size = sizeof(ANON_CLIENT_AUTH_INFO);
/* We should check signature in non-anonymous KX
* this is anonymous however
@@ -221,14 +222,14 @@ int proc_anon_server_kx( GNUTLS_KEY key, opaque* data, int data_size) {
return 0;
}
-int proc_anon_client_kx( GNUTLS_KEY key, opaque* data, int data_size) {
+int proc_anon_client_kx( GNUTLS_STATE state, opaque* data, int data_size) {
uint16 n_Y;
size_t _n_Y;
MPI g, p;
int bits, ret;
const ANON_SERVER_CREDENTIALS cred;
- cred = _gnutls_get_cred( key, GNUTLS_ANON, NULL);
+ cred = _gnutls_get_cred( state->gnutls_key, GNUTLS_ANON, NULL);
if (cred==NULL) {
bits = DEFAULT_BITS; /* default */
} else {
@@ -247,22 +248,22 @@ int proc_anon_client_kx( GNUTLS_KEY key, opaque* data, int data_size) {
n_Y = READuint16( &data[0]);
_n_Y = n_Y;
- if (gcry_mpi_scan(&key->client_Y,
+ if (gcry_mpi_scan(&state->gnutls_key->client_Y,
GCRYMPI_FMT_USG, &data[2], &_n_Y)) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
g = gnutls_get_dh_params(&p, bits);
- key->KEY = gnutls_calc_dh_key( key->client_Y, key->dh_secret, p);
+ state->gnutls_key->KEY = gnutls_calc_dh_key( state->gnutls_key->client_Y, state->gnutls_key->dh_secret, p);
- _gnutls_mpi_release(&key->client_Y);
- _gnutls_mpi_release(&key->dh_secret);
+ _gnutls_mpi_release(&state->gnutls_key->client_Y);
+ _gnutls_mpi_release(&state->gnutls_key->dh_secret);
_gnutls_mpi_release(&p);
_gnutls_mpi_release(&g);
- ret = _gnutls_generate_key( key);
- _gnutls_mpi_release(&key->KEY);
+ ret = _gnutls_generate_key( state->gnutls_key);
+ _gnutls_mpi_release(&state->gnutls_key->KEY);
if (ret < 0) {
return ret;
diff --git a/lib/auth_anon.h b/lib/auth_anon.h
index d127b35740..ef29ddee82 100644
--- a/lib/auth_anon.h
+++ b/lib/auth_anon.h
@@ -1,5 +1,5 @@
/* this is not to be included by gnutls_anon.c */
-extern MOD_AUTH_STRUCT anon_auth_struct;
+#include <gnutls_auth.h>
typedef struct {
int dh_bits;
diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c
index 87b3f2bbc3..ee80b6cea4 100644
--- a/lib/auth_rsa.c
+++ b/lib/auth_rsa.c
@@ -34,10 +34,11 @@
#include <x509_verify.h>
#include "debug.h"
-int gen_rsa_certificate(GNUTLS_KEY, opaque **);
-int gen_rsa_client_kx(GNUTLS_KEY, opaque **);
-int proc_rsa_client_kx(GNUTLS_KEY, opaque *, int);
-int proc_rsa_certificate(GNUTLS_KEY, opaque *, int);
+int gen_rsa_certificate(GNUTLS_STATE, opaque **);
+int proc_rsa_cert_req(GNUTLS_STATE, opaque *, int);
+int gen_rsa_client_kx(GNUTLS_STATE, opaque **);
+int proc_rsa_client_kx(GNUTLS_STATE, opaque *, int);
+int proc_rsa_certificate(GNUTLS_STATE, opaque *, int);
MOD_AUTH_STRUCT rsa_auth_struct = {
"RSA",
@@ -47,14 +48,15 @@ MOD_AUTH_STRUCT rsa_auth_struct = {
NULL, /* gen client kx0 */
gen_rsa_client_kx,
NULL, /* gen client cert vrfy */
- NULL, /* gen server cert vrfy */
+ NULL,
+
proc_rsa_certificate,
NULL, /* proc server kx */
NULL, /* proc server kx2 */
NULL, /* proc client kx0 */
proc_rsa_client_kx, /* proc client kx */
NULL, /* proc client cert vrfy */
- NULL /* proc server cert vrfy */
+ proc_rsa_cert_req /* proc server cert request */
};
typedef struct {
@@ -65,7 +67,7 @@ typedef struct {
/* This function extracts the RSA parameters from the given(?) certificate.
*/
-static int _gnutls_get_rsa_params(GNUTLS_KEY key, RSA_Params * params,
+static int _gnutls_get_rsa_params( RSA_Params * params,
MPI * mod, MPI * exp, gnutls_datum cert)
{
int ret = 0, result;
@@ -212,44 +214,42 @@ static int _gnutls_get_rsa_params(GNUTLS_KEY key, RSA_Params * params,
* to the gnutls_private_key structure.
*/
static int _gnutls_get_private_rsa_params(GNUTLS_KEY key,
- gnutls_private_key pkey)
+ gnutls_private_key *pkey)
{
- key->u = gcry_mpi_copy(pkey.params[0]);
- key->A = gcry_mpi_copy(pkey.params[1]);
+ key->u = gcry_mpi_copy(pkey->params[0]);
+ key->A = gcry_mpi_copy(pkey->params[1]);
return 0;
}
-int gen_rsa_certificate(GNUTLS_KEY key, opaque ** data)
+int gen_rsa_certificate(GNUTLS_STATE state, opaque ** data)
{
const X509PKI_CREDENTIALS cred;
- int ret, i, pdatasize;
+ int ret, i, ind, pdatasize;
opaque *pdata;
gnutls_cert *apr_cert_list;
- gnutls_private_key apr_pkey;
+ gnutls_private_key *apr_pkey;
int apr_cert_list_length;
- /* FIXME: This does not work for clients - yet
- */
- cred = _gnutls_get_cred(key, GNUTLS_X509PKI, NULL);
+ cred = _gnutls_get_cred(state->gnutls_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;
+ apr_cert_list = NULL;
+ apr_cert_list_length = 0;
+ apr_pkey = NULL;
+ } else {
+ ind = _gnutls_find_cert_list_index( cred->cert_list, cred->ncerts, state->security_parameters.extensions.dnsname);
+ apr_cert_list = cred->cert_list[ind];
+ apr_cert_list_length = cred->cert_list_length[ind];
+ apr_pkey = &cred->pkey[ind];
}
- /* 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 < apr_cert_list_length; i++) {
ret += apr_cert_list[i].raw.size + 3;
@@ -274,10 +274,13 @@ int gen_rsa_certificate(GNUTLS_KEY key, opaque ** data)
pdatasize = ret;
/* read the rsa parameters now, since later we will
- * now know which certificate we used!
+ * not know which certificate we used!
*/
- ret = _gnutls_get_private_rsa_params(key, apr_pkey);
-
+ if (i!=0) /* if we parsed at least one certificate */
+ ret = _gnutls_get_private_rsa_params(state->gnutls_key, apr_pkey);
+ else
+ ret = 0;
+
if (ret < 0) {
gnutls_assert();
return ret;
@@ -292,15 +295,13 @@ int gen_rsa_certificate(GNUTLS_KEY key, opaque ** data)
return GNUTLS_E_MEMORY_ERROR; \
}
-int proc_rsa_client_kx(GNUTLS_KEY key, opaque * data, int data_size)
+int proc_rsa_client_kx(GNUTLS_STATE state, opaque * data, int data_size)
{
gnutls_sdatum plaintext;
gnutls_datum ciphertext;
int ret, dsize;
- if (_gnutls_version_ssl3
- (_gnutls_version_get(key->version.major, key->version.minor))
- == 0) {
+ if (_gnutls_version_ssl3( gnutls_get_current_version( state)) == 0) {
/* SSL 3.0 */
ciphertext.data = data;
ciphertext.size = data_size;
@@ -310,8 +311,8 @@ int proc_rsa_client_kx(GNUTLS_KEY key, opaque * data, int data_size)
ciphertext.size = GMIN(dsize, data_size);
}
ret =
- _gnutls_pkcs1_rsa_decrypt(&plaintext, ciphertext, key->u,
- key->A, 2); /* btype==2 */
+ _gnutls_pkcs1_rsa_decrypt(&plaintext, ciphertext, state->gnutls_key->u,
+ state->gnutls_key->A, 2); /* btype==2 */
if (ret < 0) {
/* in case decryption fails then don't inform
@@ -319,36 +320,40 @@ int proc_rsa_client_kx(GNUTLS_KEY key, opaque * data, int data_size)
* attack against pkcs-1 formating).
*/
gnutls_assert();
- RANDOMIZE_KEY(key->key, secure_malloc);
+ RANDOMIZE_KEY(state->gnutls_key->key, secure_malloc);
} else {
ret = 0;
if (plaintext.size != TLS_MASTER_SIZE) { /* WOW */
- RANDOMIZE_KEY(key->key, secure_malloc);
+ RANDOMIZE_KEY(state->gnutls_key->key, secure_malloc);
} else {
- if (key->version.major != plaintext.data[0])
+ GNUTLS_Version ver;
+
+ ver = gnutls_get_current_version( state);
+
+ if ( _gnutls_version_get_major( ver) != plaintext.data[0])
ret = GNUTLS_E_DECRYPTION_FAILED;
- if (key->version.minor != plaintext.data[1])
+ if ( _gnutls_version_get_minor( ver) != plaintext.data[1])
ret = GNUTLS_E_DECRYPTION_FAILED;
if (ret != 0) {
- _gnutls_mpi_release(&key->B);
- _gnutls_mpi_release(&key->u);
- _gnutls_mpi_release(&key->A);
+ _gnutls_mpi_release(&state->gnutls_key->B);
+ _gnutls_mpi_release(&state->gnutls_key->u);
+ _gnutls_mpi_release(&state->gnutls_key->A);
gnutls_assert();
return ret;
}
- key->key.data = plaintext.data;
- key->key.size = plaintext.size;
+ state->gnutls_key->key.data = plaintext.data;
+ state->gnutls_key->key.size = plaintext.size;
}
}
- _gnutls_mpi_release(&key->A);
- _gnutls_mpi_release(&key->B);
- _gnutls_mpi_release(&key->u);
+ _gnutls_mpi_release(&state->gnutls_key->A);
+ _gnutls_mpi_release(&state->gnutls_key->B);
+ _gnutls_mpi_release(&state->gnutls_key->u);
return 0;
}
-int proc_rsa_certificate(GNUTLS_KEY key, opaque * data, int data_size)
+int proc_rsa_certificate(GNUTLS_STATE state, opaque * data, int data_size)
{
int size, len, ret;
opaque *p = data;
@@ -361,18 +366,19 @@ int proc_rsa_certificate(GNUTLS_KEY key, opaque * data, int data_size)
gnutls_datum tmp;
CertificateStatus verify;
- cred = _gnutls_get_cred(key, GNUTLS_X509PKI, NULL);
+ cred = _gnutls_get_cred(state->gnutls_key, GNUTLS_X509PKI, NULL);
if (cred == NULL) {
gnutls_assert();
return GNUTLS_E_INSUFICIENT_CRED;
}
- key->auth_info = gnutls_calloc(1, sizeof(X509PKI_CLIENT_AUTH_INFO));
- if (key->auth_info == NULL) {
+ if (state->gnutls_key->auth_info==NULL)
+ state->gnutls_key->auth_info = gnutls_calloc(1, sizeof(X509PKI_CLIENT_AUTH_INFO));
+ if (state->gnutls_key->auth_info == NULL) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
}
- key->auth_info_size = sizeof(X509PKI_CLIENT_AUTH_INFO);
+ state->gnutls_key->auth_info_size = sizeof(X509PKI_CLIENT_AUTH_INFO);
DECR_LEN(dsize, 3);
size = READuint24(p);
@@ -383,7 +389,7 @@ int proc_rsa_certificate(GNUTLS_KEY key, opaque * data, int data_size)
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
- info = key->auth_info;
+ info = state->gnutls_key->auth_info;
i = dsize;
len = READuint24(p);
@@ -440,7 +446,7 @@ int proc_rsa_certificate(GNUTLS_KEY key, opaque * data, int data_size)
/* store the required parameters for the handshake
*/
if ((ret =
- _gnutls_get_rsa_params(key, NULL, &key->A, &key->u,
+ _gnutls_get_rsa_params( NULL, &state->gnutls_key->A, &state->gnutls_key->u,
peer_certificate_list[0].raw)) < 0) {
gnutls_assert();
gnutls_free( peer_certificate_list);
@@ -463,13 +469,14 @@ int proc_rsa_certificate(GNUTLS_KEY key, opaque * data, int data_size)
/* return RSA(random) using the peers public key
*/
-int gen_rsa_client_kx(GNUTLS_KEY key, opaque ** data)
+int gen_rsa_client_kx(GNUTLS_STATE state, opaque ** data)
{
- X509PKI_CLIENT_AUTH_INFO *auth = key->auth_info;
+ X509PKI_CLIENT_AUTH_INFO *auth = state->gnutls_key->auth_info;
gnutls_datum sdata; /* data to send */
MPI pkey, n;
int ret;
-
+ GNUTLS_Version ver;
+
if (auth == NULL) {
/* this shouldn't have happened. The proc_certificate
* function should have detected that.
@@ -478,24 +485,25 @@ int gen_rsa_client_kx(GNUTLS_KEY key, opaque ** data)
return GNUTLS_E_INSUFICIENT_CRED;
}
- RANDOMIZE_KEY(key->key, secure_malloc);
- key->key.data[0] = key->version.major;
- key->key.data[1] = key->version.minor;
+ RANDOMIZE_KEY(state->gnutls_key->key, secure_malloc);
+
+ ver = gnutls_get_current_version( state);
+
+ state->gnutls_key->key.data[0] = _gnutls_version_get_major( ver);
+ state->gnutls_key->key.data[1] = _gnutls_version_get_minor( ver);
if ((ret =
- _gnutls_pkcs1_rsa_encrypt(&sdata, key->key, key->u, key->A, 2)) < 0) {
+ _gnutls_pkcs1_rsa_encrypt(&sdata, state->gnutls_key->key, state->gnutls_key->u, state->gnutls_key->A, 2)) < 0) {
gnutls_assert();
_gnutls_mpi_release(&pkey);
_gnutls_mpi_release(&n);
return ret;
}
- _gnutls_mpi_release(&key->A);
- _gnutls_mpi_release(&key->u);
+ _gnutls_mpi_release(&state->gnutls_key->A);
+ _gnutls_mpi_release(&state->gnutls_key->u);
- if (_gnutls_version_ssl3
- (_gnutls_version_get(key->version.major, key->version.minor))
- == 0) {
+ if (_gnutls_version_ssl3( ver) == 0) {
/* SSL 3.0 */
*data = sdata.data;
return sdata.size;
@@ -513,3 +521,62 @@ int gen_rsa_client_kx(GNUTLS_KEY key, opaque ** data)
}
}
+
+#define RSA_SIGN 1
+
+int proc_rsa_cert_req(GNUTLS_STATE state, opaque * data, int data_size)
+{
+ int size;
+ opaque *p = data;
+ const X509PKI_CREDENTIALS cred;
+ int dsize = data_size;
+ int i;
+ int found;
+
+ cred = _gnutls_get_cred(state->gnutls_key, GNUTLS_X509PKI, NULL);
+ if (cred == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_INSUFICIENT_CRED;
+ }
+
+ state->gnutls_key->certificate_requested = 1;
+
+ if (state->gnutls_key->auth_info==NULL)
+ state->gnutls_key->auth_info = gnutls_calloc(1, sizeof(X509PKI_CLIENT_AUTH_INFO));
+ if (state->gnutls_key->auth_info == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+ state->gnutls_key->auth_info_size = sizeof(X509PKI_CLIENT_AUTH_INFO);
+
+ DECR_LEN(dsize, 1);
+ size = p[0];
+ p += 1;
+
+ found = 0;
+ for (i=0;i<size;i++,p++) {
+ DECR_LEN( dsize, 1);
+ if (*p==RSA_SIGN) found=1;
+ }
+
+ if (found==0) {
+ gnutls_assert();
+ return GNUTLS_E_UNKNOWN_KX_ALGORITHM;
+ }
+
+
+
+ DECR_LEN(dsize, 2);
+ size = READuint16(p);
+ p += 2;
+fprintf(stderr, "DN size: %d\n", size);
+
+ if (size == 0) {
+ return 0;
+ }
+
+#warning "FIND CERTIFICATE TO SEND"
+//fprintf(stderr, "DN: %s\n", _gnutls_bin2hex( p, size));
+
+ return 0;
+}
diff --git a/lib/auth_srp.c b/lib/auth_srp.c
index bfb74eb011..ca793f48aa 100644
--- a/lib/auth_srp.c
+++ b/lib/auth_srp.c
@@ -21,17 +21,18 @@
#include "gnutls_int.h"
#include "gnutls_errors.h"
#include "auth_srp_passwd.h"
-#include "auth_srp.h"
+#include "gnutls_auth.h"
#include "gnutls_auth_int.h"
#include "gnutls_srp.h"
#include "debug.h"
#include "gnutls_num.h"
+#include "auth_srp.h"
-int gen_srp_server_kx2(GNUTLS_KEY, opaque **);
-int gen_srp_client_kx0(GNUTLS_KEY, opaque **);
+int gen_srp_server_kx2(GNUTLS_STATE, opaque **);
+int gen_srp_client_kx0(GNUTLS_STATE, opaque **);
-int proc_srp_server_kx2(GNUTLS_KEY, opaque *, int);
-int proc_srp_client_kx0(GNUTLS_KEY, opaque *, int);
+int proc_srp_server_kx2(GNUTLS_STATE, opaque *, int);
+int proc_srp_client_kx0(GNUTLS_STATE, opaque *, int);
MOD_AUTH_STRUCT srp_auth_struct = {
"SRP",
@@ -42,6 +43,7 @@ MOD_AUTH_STRUCT srp_auth_struct = {
NULL,
NULL,
NULL,
+
NULL, /* certificate */
NULL,
proc_srp_server_kx2,
@@ -52,17 +54,17 @@ MOD_AUTH_STRUCT srp_auth_struct = {
};
-#define _b key->b
-#define B key->B
-#define _a key->a
-#define A key->A
-#define N key->client_p
-#define G key->client_g
-#define V key->x
-#define S key->KEY
+#define _b state->gnutls_key->b
+#define B state->gnutls_key->B
+#define _a state->gnutls_key->a
+#define A state->gnutls_key->A
+#define N state->gnutls_key->client_p
+#define G state->gnutls_key->client_g
+#define V state->gnutls_key->x
+#define S state->gnutls_key->KEY
/* Send the first key exchange message ( g, n, s) and append the verifier algorithm number */
-int gen_srp_server_hello(GNUTLS_KEY key, opaque ** data)
+int gen_srp_server_hello(GNUTLS_STATE state, opaque ** data)
{
size_t n_g, n_n, n_s;
size_t ret;
@@ -72,11 +74,11 @@ int gen_srp_server_hello(GNUTLS_KEY key, opaque ** data)
GNUTLS_SRP_PWD_ENTRY *pwd_entry;
int err;
- if (key->auth_info == NULL) {
+ if (state->gnutls_key->auth_info == NULL) {
return GNUTLS_E_INSUFICIENT_CRED;
}
- pwd_entry = _gnutls_srp_pwd_read_entry( key, ((SRP_SERVER_AUTH_INFO*)key->auth_info)->username, &err);
+ pwd_entry = _gnutls_srp_pwd_read_entry( state->gnutls_key, ((SRP_SERVER_AUTH_INFO*)state->gnutls_key->auth_info)->username, &err);
if (pwd_entry == NULL) {
if (err==0)
@@ -151,7 +153,7 @@ int gen_srp_server_hello(GNUTLS_KEY key, opaque ** data)
}
/* send the second key exchange message */
-int gen_srp_server_kx2(GNUTLS_KEY key, opaque ** data)
+int gen_srp_server_kx2(GNUTLS_STATE state, opaque ** data)
{
int ret;
size_t n_b;
@@ -173,18 +175,18 @@ int gen_srp_server_kx2(GNUTLS_KEY key, opaque ** data)
WRITEuint16( n_b, data_b);
/* calculate u */
- key->u = _gnutls_calc_srp_u(B);
+ state->gnutls_key->u = _gnutls_calc_srp_u(B);
/* S = (A * v^u) ^ b % N */
- S = _gnutls_calc_srp_S1( A, _b, key->u, V, N);
+ S = _gnutls_calc_srp_S1( A, _b, state->gnutls_key->u, V, N);
mpi_release(A);
mpi_release(_b);
mpi_release(V);
- mpi_release(key->u);
+ mpi_release(state->gnutls_key->u);
mpi_release(B);
- ret = _gnutls_generate_key( key);
+ ret = _gnutls_generate_key( state->gnutls_key);
_gnutls_mpi_release( &S);
if (ret < 0)
@@ -195,14 +197,14 @@ int gen_srp_server_kx2(GNUTLS_KEY key, opaque ** data)
/* return A = g^a % N */
-int gen_srp_client_kx0(GNUTLS_KEY key, opaque ** data)
+int gen_srp_client_kx0(GNUTLS_STATE state, opaque ** data)
{
size_t n_a;
uint8 *data_a;
char *username;
char *password;
const SRP_CLIENT_CREDENTIALS cred =
- _gnutls_get_cred(key, GNUTLS_SRP, NULL);
+ _gnutls_get_cred(state->gnutls_key, GNUTLS_SRP, NULL);
if (cred == NULL)
return GNUTLS_E_INSUFICIENT_CRED;
@@ -232,7 +234,7 @@ int gen_srp_client_kx0(GNUTLS_KEY key, opaque ** data)
}
/* receive the first key exchange message ( g, n, s) */
-int proc_srp_server_hello(GNUTLS_KEY key, const opaque * data, int data_size)
+int proc_srp_server_hello(GNUTLS_STATE state, const opaque * data, int data_size)
{
uint16 n_s, n_g, n_n;
size_t _n_s, _n_g, _n_n;
@@ -245,7 +247,7 @@ int proc_srp_server_hello(GNUTLS_KEY key, const opaque * data, int data_size)
char *username;
char *password;
const SRP_CLIENT_CREDENTIALS cred =
- _gnutls_get_cred(key, GNUTLS_SRP, NULL);
+ _gnutls_get_cred(state->gnutls_key, GNUTLS_SRP, NULL);
if (cred == NULL)
return GNUTLS_E_INSUFICIENT_CRED;
@@ -310,7 +312,7 @@ int proc_srp_server_hello(GNUTLS_KEY key, const opaque * data, int data_size)
*/
_gnutls_calc_srp_x( username, password, (opaque*)data_s, n_s, pwd_algo, &_n_g, hd);
- if (gcry_mpi_scan(&key->x, GCRYMPI_FMT_USG, hd, &_n_g) != 0) {
+ if (gcry_mpi_scan(&state->gnutls_key->x, GCRYMPI_FMT_USG, hd, &_n_g) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
@@ -319,7 +321,7 @@ int proc_srp_server_hello(GNUTLS_KEY key, const opaque * data, int data_size)
}
/* just read A and put it to state */
-int proc_srp_client_kx0(GNUTLS_KEY key, opaque * data, int data_size)
+int proc_srp_client_kx0(GNUTLS_STATE state, opaque * data, int data_size)
{
size_t _n_A;
@@ -334,7 +336,7 @@ 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)
+int proc_srp_server_kx2(GNUTLS_STATE state, opaque * data, int data_size)
{
size_t _n_B;
int ret;
@@ -347,18 +349,18 @@ int proc_srp_server_kx2(GNUTLS_KEY key, opaque * data, int data_size)
}
/* calculate u */
- key->u = _gnutls_calc_srp_u( B);
+ state->gnutls_key->u = _gnutls_calc_srp_u( B);
/* S = (B - g^x) ^ (a + u * x) % N */
- S = _gnutls_calc_srp_S2( B, G, key->x, _a, key->u, N);
+ S = _gnutls_calc_srp_S2( B, G, state->gnutls_key->x, _a, state->gnutls_key->u, N);
mpi_release(A);
mpi_release(_b);
mpi_release(V);
- mpi_release(key->u);
+ mpi_release(state->gnutls_key->u);
mpi_release(B);
- ret = _gnutls_generate_key( key);
+ ret = _gnutls_generate_key( state->gnutls_key);
_gnutls_mpi_release(&S);
if (ret < 0)
diff --git a/lib/auth_srp.h b/lib/auth_srp.h
index ea7e683fe0..0d182daa78 100644
--- a/lib/auth_srp.h
+++ b/lib/auth_srp.h
@@ -1,5 +1,4 @@
-/* this is not to be included by gnutls_anon.c */
-extern MOD_AUTH_STRUCT srp_auth_struct;
+#include <gnutls_auth.h>
typedef struct {
char* username;
@@ -20,5 +19,5 @@ typedef struct {
char username[256];
} SRP_SERVER_AUTH_INFO;
-int gen_srp_server_hello(GNUTLS_KEY, opaque **);
-int proc_srp_server_hello(GNUTLS_KEY, const opaque *, int);
+int proc_srp_server_hello(GNUTLS_STATE state, const opaque * data, int data_size);
+int gen_srp_server_hello(GNUTLS_STATE state, opaque ** data);
diff --git a/lib/auth_x509.h b/lib/auth_x509.h
index e8e139caab..80d7d2efc7 100644
--- a/lib/auth_x509.h
+++ b/lib/auth_x509.h
@@ -1,9 +1,7 @@
#ifndef AUTH_X509_H
# define AUTH_X509_H
# include "gnutls_cert.h"
-
-/* this is not to be included by gnutls_anon.c */
-extern MOD_AUTH_STRUCT rsa_auth_struct;
+# include "gnutls_auth.h"
/* This structure may be complex but, it's the only way to
* support a server that has multiple certificates
@@ -42,6 +40,7 @@ typedef struct {
time_t peer_certificate_expiration_time;
char subjectAltName[X509_CN_SIZE];
unsigned char keyUsage;
+ int certificate_requested;
} X509PKI_CLIENT_AUTH_INFO;
void _gnutls_copy_x509_client_auth_info( X509PKI_CLIENT_AUTH_INFO* info, gnutls_cert* cert, CertificateStatus verify);
diff --git a/lib/ext_srp.c b/lib/ext_srp.c
index 50dc7e8bb7..be2034bc0e 100644
--- a/lib/ext_srp.c
+++ b/lib/ext_srp.c
@@ -58,7 +58,7 @@ int _gnutls_srp_recv_params( GNUTLS_STATE state, const opaque* data, int data_si
}
} else { /* client side reading server hello extensions */
if (state->gnutls_internals.resumed==RESUME_FALSE)
- return proc_srp_server_hello( state->gnutls_key, data, data_size);
+ return proc_srp_server_hello( state, data, data_size);
else /* we do not need to process this if
* we are resuming.
*/
@@ -95,7 +95,7 @@ int _gnutls_srp_send_params( GNUTLS_STATE state, opaque** data) {
return 0; /* no data to send */
if (state->gnutls_internals.resumed==RESUME_FALSE)
- return gen_srp_server_hello( state->gnutls_key, data);
+ return gen_srp_server_hello( state, data);
else
return 0;
}
diff --git a/lib/gnutls_algorithms.c b/lib/gnutls_algorithms.c
index 66331682e5..8163801ffb 100644
--- a/lib/gnutls_algorithms.c
+++ b/lib/gnutls_algorithms.c
@@ -23,12 +23,6 @@
#include "gnutls_errors.h"
#include "gnutls_cert.h"
-/* include all the kx handler's definitions */
-#include "auth_anon.h"
-/* #include "auth_dhe_dss.h" */
-#include "auth_srp.h"
-#include "auth_x509.h"
-
#define MAX_CIPHER 256
#define MAX_MAC 256
#define MAX_KX 256
@@ -187,6 +181,10 @@ struct gnutls_kx_algo_entry {
};
typedef struct gnutls_kx_algo_entry gnutls_kx_algo_entry;
+extern MOD_AUTH_STRUCT rsa_auth_struct;
+extern MOD_AUTH_STRUCT anon_auth_struct;
+extern MOD_AUTH_STRUCT srp_auth_struct;
+
static const gnutls_kx_algo_entry kx_algorithms[] = {
GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_ANON, &anon_auth_struct),
GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_RSA, &rsa_auth_struct),
@@ -787,12 +785,6 @@ int _gnutls_version_get_major(GNUTLS_Version version)
}
/* Version Functions */
-int _gnutls_version_cmp(GNUTLS_Version ver1, GNUTLS_Version ver2)
-{
- if (ver1 != ver2)
- return 1;
- return 0;
-}
int
_gnutls_version_is_supported(GNUTLS_STATE state,
diff --git a/lib/gnutls_auth.h b/lib/gnutls_auth.h
index bffd973ff5..8017c50eb8 100644
--- a/lib/gnutls_auth.h
+++ b/lib/gnutls_auth.h
@@ -1,23 +1,23 @@
#ifndef GNUTLS_AUTH_H
- #define GNUTLS_AUTH_H
-typedef struct {
+# define GNUTLS_AUTH_H
+
+typedef struct MOD_AUTH_STRUCT_INT {
char* name; /* null terminated */
- int (*gnutls_generate_certificate)( GNUTLS_KEY, opaque**);
- int (*gnutls_generate_server_kx)( GNUTLS_KEY, opaque**);
- int (*gnutls_generate_server_kx2)( GNUTLS_KEY, opaque**); /* used in SRP */
- int (*gnutls_generate_client_kx0)( GNUTLS_KEY, opaque**);
- int (*gnutls_generate_client_kx)( GNUTLS_KEY, opaque**); /* used in SRP */
- int (*gnutls_generate_client_cert_vrfy) ( GNUTLS_KEY, opaque**);
- int (*gnutls_generate_server_cert_vrfy) ( GNUTLS_KEY, opaque**);
+ int (*gnutls_generate_certificate)( GNUTLS_STATE, opaque**);
+ int (*gnutls_generate_server_kx)( GNUTLS_STATE, opaque**);
+ int (*gnutls_generate_server_kx2)( GNUTLS_STATE, opaque**); /* used in SRP */
+ int (*gnutls_generate_client_kx0)( GNUTLS_STATE, opaque**);
+ int (*gnutls_generate_client_kx)( GNUTLS_STATE, opaque**); /* used in SRP */
+ int (*gnutls_generate_client_cert_vrfy) ( GNUTLS_STATE, opaque**);
+ int (*gnutls_generate_server_certificate_request) ( GNUTLS_STATE, opaque**);
- int (*gnutls_process_certificate)( GNUTLS_KEY, opaque*, int);
- int (*gnutls_process_server_kx)( GNUTLS_KEY, opaque*, int);
- int (*gnutls_process_server_kx2)( GNUTLS_KEY, opaque*, int);
- int (*gnutls_process_client_kx0)( GNUTLS_KEY, opaque*, int);
- int (*gnutls_process_client_kx)( GNUTLS_KEY, opaque*, int);
- int (*gnutls_process_client_cert_vrfy) ( GNUTLS_KEY, opaque*, int);
- int (*gnutls_process_server_cert_vrfy) ( GNUTLS_KEY, opaque*, int);
+ int (*gnutls_process_certificate)( GNUTLS_STATE, opaque*, int);
+ int (*gnutls_process_server_kx)( GNUTLS_STATE, opaque*, int);
+ int (*gnutls_process_server_kx2)( GNUTLS_STATE, opaque*, int);
+ int (*gnutls_process_client_kx0)( GNUTLS_STATE, opaque*, int);
+ int (*gnutls_process_client_kx)( GNUTLS_STATE, opaque*, int);
+ int (*gnutls_process_client_cert_vrfy) ( GNUTLS_STATE, opaque*, int);
+ int (*gnutls_process_server_certificate_request) ( GNUTLS_STATE, opaque*, int);
} MOD_AUTH_STRUCT;
-
#endif
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
index 8a66fb4528..81604fa1ac 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -825,7 +825,7 @@ int _gnutls_cert_supported_kx(gnutls_cert * cert, KXAlgorithm ** alg,
return 0;
}
-/* finds a certificate in the cert list that contains
+/* finds a certificate in the cert lists that contains
* common_name (or subjectAltName) field similar to name
*/
gnutls_cert *_gnutls_find_cert(gnutls_cert ** cert_list,
@@ -835,7 +835,7 @@ gnutls_cert *_gnutls_find_cert(gnutls_cert ** cert_list,
int i;
for (i = 0; i < cert_list_length; i++) {
- if (cert_list[i][0].cert_info.common_name[0] != 0) {
+ if (cert_list[i][0].cert_info.common_name[0] != 0 || cert_list[i][0].subjectAltName[0]!=0) {
if (strcasecmp(cert_list[i][0].cert_info.common_name, name) == 0 || strcasecmp(cert_list[i][0].subjectAltName, name) == 0) {
cert = &cert_list[i][0];
break;
@@ -845,3 +845,23 @@ gnutls_cert *_gnutls_find_cert(gnutls_cert ** cert_list,
return cert;
}
+/* finds the index of a certificate in the cert lists that contains
+ * common_name (or subjectAltName) field similar to name
+ */
+int _gnutls_find_cert_list_index(gnutls_cert ** cert_list,
+ int cert_list_length, char *name)
+{
+ int index = 0;
+ int i;
+
+ for (i = 0; i < cert_list_length; i++) {
+ if (cert_list[i][0].cert_info.common_name[0] != 0 || cert_list[i][0].subjectAltName[0]!=0) {
+ if (strcasecmp(cert_list[i][0].cert_info.common_name, name) == 0 || strcasecmp(cert_list[i][0].subjectAltName, name) == 0) {
+ index = i;
+ break;
+ }
+ }
+ }
+ return index;
+}
+
diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h
index 41057f94ae..b0bd67ab0b 100644
--- a/lib/gnutls_cert.h
+++ b/lib/gnutls_cert.h
@@ -51,6 +51,8 @@ int _gnutls_cert_supported_kx(gnutls_cert* cert, KXAlgorithm **alg, int *alg_siz
PKAlgorithm _gnutls_map_pk_get_pk(KXAlgorithm kx_algorithm);
int _gnutls_cert2gnutlsCert(gnutls_cert * gCert, gnutls_datum derCert);
gnutls_cert* _gnutls_find_cert( gnutls_cert** cert_list, int cert_list_length, char* name);
+int _gnutls_find_cert_list_index(gnutls_cert ** cert_list,
+ int cert_list_length, char *name);
#define MAX_INT_DIGITS 4
void _gnutls_int2str(int k, char* data);
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index 317bca45c8..f934a1b470 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -51,7 +51,7 @@
static int _gnutls_server_SelectSuite(GNUTLS_STATE state, opaque ret[2],
char *data, int datalen);
int _gnutls_server_SelectCompMethod(GNUTLS_STATE state,
- CompressionMethod * ret, opaque * data,
+ CompressionMethod * ret, opaque * data,
int datalen);
/* this will copy the required values for resuming to
@@ -79,12 +79,12 @@ static void resume_copy_required_values(GNUTLS_STATE state)
state->gnutls_internals.compression_method =
state->gnutls_internals.resumed_security_parameters.
- read_compression_algorithm; /* or write_compression_algorithm
- * they are the same
- */
+ read_compression_algorithm; /* or write_compression_algorithm
+ * they are the same
+ */
state->security_parameters.entity = state->gnutls_internals.resumed_security_parameters.entity;
-
+
memcpy(state->security_parameters.session_id,
state->gnutls_internals.resumed_security_parameters.
session_id, sizeof(state->security_parameters.session_id));
@@ -99,18 +99,12 @@ void _gnutls_set_server_random(GNUTLS_STATE state, uint8 * random)
{
memcpy(state->security_parameters.server_random, random,
TLS_RANDOM_SIZE);
- if (state->gnutls_key != NULL)
- memcpy(state->gnutls_key->server_random, random,
- TLS_RANDOM_SIZE);
}
void _gnutls_set_client_random(GNUTLS_STATE state, uint8 * random)
{
memcpy(state->security_parameters.client_random, random,
TLS_RANDOM_SIZE);
- if (state->gnutls_key != NULL)
- memcpy(state->gnutls_key->client_random, random,
- TLS_RANDOM_SIZE);
}
/* Calculate The SSL3 Finished message */
@@ -248,12 +242,11 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
if (state->gnutls_internals.v2_hello != 0) { /* version 2.0 */
return _gnutls_read_client_hello_v2(state, data, datalen);
}
-
DECR_LEN(len, 2);
#ifdef HANDSHAKE_DEBUG
- _gnutls_log( "Client's version: %d.%d\n", data[pos],
- data[pos + 1]);
+ _gnutls_log("Client's version: %d.%d\n", data[pos],
+ data[pos + 1]);
#endif
version = _gnutls_version_get(data[pos], data[pos + 1]);
@@ -263,7 +256,7 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
/* If he requested something we do not support
* then we send him the lowest we support.
*/
- ver = _gnutls_version_lowest( state);
+ ver = _gnutls_version_lowest(state);
} else {
ver = version;
}
@@ -271,11 +264,10 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
/* he should have send us the highest version
* he supports.
*/
- if (ver==GNUTLS_VERSION_UNKNOWN || ver > version) {
+ if (ver == GNUTLS_VERSION_UNKNOWN || ver > version) {
gnutls_assert();
return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
}
-
_gnutls_set_current_version(state, ver);
pos += 2;
@@ -297,7 +289,6 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
gnutls_assert();
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
-
DECR_LEN(len, session_id_len);
ret =
_gnutls_server_restore_session(state, &data[pos],
@@ -332,8 +323,6 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
gnutls_assert();
return ret;
}
-
-
/* check if the credentials (username, public key etc. are ok)
*/
if (_gnutls_get_kx_cred
@@ -344,7 +333,6 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
gnutls_assert();
return GNUTLS_E_INSUFICIENT_CRED;
}
-
/* set the MOD_AUTH_STRUCT to the appropriate struct
* according to the KX algorithm. This is needed since all the
* handshake functions are read from there;
@@ -356,12 +344,11 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
if (state->gnutls_internals.auth_struct == NULL) {
#ifdef HANDSHAKE_DEBUG
_gnutls_log(
- "Cannot find the appropriate handler for the KX algorithm\n");
+ "Cannot find the appropriate handler for the KX algorithm\n");
#endif
gnutls_assert();
return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
}
-
DECR_LEN(len, 1);
memcpy(&z, &data[pos++], 1); /* z is the number of compression methods */
@@ -371,9 +358,9 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
compression_method,
&data[pos], z);
#ifdef HANDSHAKE_DEBUG
- _gnutls_log( "Selected Compression Method: %s\n",
- gnutls_compression_get_name(state->gnutls_internals.
- compression_method));
+ _gnutls_log("Selected Compression Method: %s\n",
+ gnutls_compression_get_name(state->gnutls_internals.
+ compression_method));
#endif
pos += z;
@@ -381,13 +368,11 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
gnutls_assert();
return ret;
}
-
- ret = _gnutls_parse_extensions(state, &data[pos], len); /* len is the rest of the parsed length */
+ ret = _gnutls_parse_extensions(state, &data[pos], len); /* len is the rest of the parsed length */
if (ret < 0) {
gnutls_assert();
return ret;
}
-
return ret;
}
@@ -411,7 +396,7 @@ int _gnutls_send_finished(SOCKET cd, GNUTLS_STATE state)
} else { /* TLS 1.0 */
data =
_gnutls_finished(state,
- state->security_parameters.entity, 0);
+ state->security_parameters.entity, 0);
data_size = 12;
}
@@ -444,7 +429,6 @@ int _gnutls_recv_finished(SOCKET cd, GNUTLS_STATE state)
gnutls_assert();
return ret;
}
-
if (_gnutls_version_ssl3(state->connection_state.version) == 0) {
data_size = 36;
} else {
@@ -455,7 +439,6 @@ int _gnutls_recv_finished(SOCKET cd, GNUTLS_STATE state)
gnutls_assert();
return GNUTLS_E_ERROR_IN_FINISHED_PACKET;
}
-
if (_gnutls_version_ssl3(state->connection_state.version) == 0) {
/* skip the bytes from the last message */
data =
@@ -476,7 +459,6 @@ int _gnutls_recv_finished(SOCKET cd, GNUTLS_STATE state)
gnutls_assert();
ret = GNUTLS_E_ERROR_IN_FINISHED_PACKET;
}
-
gnutls_free(data);
gnutls_free(vrfy);
@@ -501,16 +483,16 @@ static int _gnutls_server_SelectSuite(GNUTLS_STATE state, opaque ret[2],
x = _gnutls_remove_unwanted_ciphersuites(state, &ciphers, x);
#ifdef HANDSHAKE_DEBUG
- _gnutls_log( "Requested cipher suites: \n");
+ _gnutls_log("Requested cipher suites: \n");
for (j = 0; j < datalen; j += 2)
- _gnutls_log( "\t%s\n",
- _gnutls_cipher_suite_get_name(*
- ((GNUTLS_CipherSuite
- *) & data[j])));
- _gnutls_log( "Supported cipher suites: \n");
+ _gnutls_log("\t%s\n",
+ _gnutls_cipher_suite_get_name(*
+ ((GNUTLS_CipherSuite
+ *) & data[j])));
+ _gnutls_log("Supported cipher suites: \n");
for (j = 0; j < x; j++)
- _gnutls_log( "\t%s\n",
- _gnutls_cipher_suite_get_name(ciphers[j]));
+ _gnutls_log("\t%s\n",
+ _gnutls_cipher_suite_get_name(ciphers[j]));
#endif
memset(ret, '\0', 2);
@@ -519,10 +501,10 @@ static int _gnutls_server_SelectSuite(GNUTLS_STATE state, opaque ret[2],
if (memcmp(ciphers[i].CipherSuite, &data[j], 2) ==
0) {
#ifdef HANDSHAKE_DEBUG
- _gnutls_log( "Selected cipher suite: ");
- _gnutls_log( "%s\n",
- _gnutls_cipher_suite_get_name(*
- ((GNUTLS_CipherSuite *) & data[j])));
+ _gnutls_log("Selected cipher suite: ");
+ _gnutls_log("%s\n",
+ _gnutls_cipher_suite_get_name(*
+ ((GNUTLS_CipherSuite *) & data[j])));
#endif
memcpy(ret, ciphers[i].CipherSuite, 2);
gnutls_free(ciphers);
@@ -542,7 +524,7 @@ static int _gnutls_server_SelectSuite(GNUTLS_STATE state, opaque ret[2],
/* This selects the best supported compression method from the ones provided */
int _gnutls_server_SelectCompMethod(GNUTLS_STATE state,
- CompressionMethod * ret, opaque * data,
+ CompressionMethod * ret, opaque * data,
int datalen)
{
int x, i, j;
@@ -592,8 +574,8 @@ int _gnutls_send_handshake(SOCKET cd, GNUTLS_STATE state, void *i_data,
memcpy(&data[pos], i_data, i_datasize - 4);
#ifdef HANDSHAKE_DEBUG
- _gnutls_log( "Handshake: %s was send [%ld bytes]\n",
- _gnutls_handshake2str(type), i_datasize);
+ _gnutls_log("Handshake: %s was send [%ld bytes]\n",
+ _gnutls_handshake2str(type), i_datasize);
#endif
/* Here we keep the handshake messages in order to hash them later!
@@ -633,14 +615,13 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
if (ret <= 0) {
gnutls_assert();
gnutls_free(dataptr);
- return (ret < 0)?ret:GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ return (ret < 0) ? ret : GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
if (ret != SSL2_HEADERS) {
gnutls_assert();
gnutls_free(dataptr);
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
-
if (state->gnutls_internals.v2_hello == 0
|| type != GNUTLS_CLIENT_HELLO) {
@@ -652,14 +633,13 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
if (ret <= 0) {
gnutls_assert();
gnutls_free(dataptr);
- return (ret<0)?ret:GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ return (ret < 0) ? ret : GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
if (ret != HANDSHAKE_HEADERS_SIZE - SSL2_HEADERS) {
gnutls_assert();
gnutls_free(dataptr);
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
-
recv_type = dataptr[0];
if (recv_type != type) {
@@ -667,13 +647,12 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
gnutls_free(dataptr);
return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
}
-
length32 = READuint24(&dataptr[1]);
#ifdef HANDSHAKE_DEBUG
- _gnutls_log( "Handshake: %s was received [%ld bytes]\n",
- _gnutls_handshake2str(dataptr[0]),
- length32 + HANDSHAKE_HEADERS_SIZE);
+ _gnutls_log("Handshake: %s was received [%ld bytes]\n",
+ _gnutls_handshake2str(dataptr[0]),
+ length32 + HANDSHAKE_HEADERS_SIZE);
#endif
@@ -685,12 +664,12 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
recv_type = dataptr[0];
#ifdef HANDSHAKE_DEBUG
_gnutls_log(
- "Handshake: %s(v2) was received [%ld bytes]\n",
- _gnutls_handshake2str(recv_type),
- length32 + handshake_headers);
+ "Handshake: %s(v2) was received [%ld bytes]\n",
+ _gnutls_handshake2str(recv_type),
+ length32 + handshake_headers);
#endif
- if (recv_type != GNUTLS_CLIENT_HELLO) { /* it should be one or nothing */
+ if (recv_type != GNUTLS_CLIENT_HELLO) { /* it should be one or nothing */
gnutls_assert();
return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
}
@@ -701,7 +680,6 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
}
-
if (length32 > 0 && data != NULL)
*data = gnutls_malloc(length32);
@@ -757,12 +735,8 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
break;
case GNUTLS_CERTIFICATE_REQUEST:
#ifdef HANDSHAKE_DEBUG
- _gnutls_log( "Requested Client Certificate!\n");
+ _gnutls_log("Requested Client Certificate!\n");
#endif
- /* FIXME: just ignore that message for the time being
- * we have to parse it and the store the needed information
- */
- state->gnutls_internals.certificate_requested = 1;
ret = length32;
break;
default:
@@ -800,7 +774,6 @@ int gnutls_rehandshake(SOCKET cd, GNUTLS_STATE state)
gnutls_assert();
return ret;
}
-
/* begin handshake procedure again */
ret = gnutls_handshake(cd, state);
@@ -825,8 +798,7 @@ static int _gnutls_read_server_hello(GNUTLS_STATE state, char *data,
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
#ifdef HANDSHAKE_DEBUG
- _gnutls_log( "Server's version: %d.%d\n", data[pos],
- data[pos + 1]);
+ _gnutls_log("Server's version: %d.%d\n", data[pos], data[pos + 1]);
#endif
DECR_LEN(len, 2);
version = _gnutls_version_get(data[pos], data[pos + 1]);
@@ -849,13 +821,12 @@ static int _gnutls_read_server_hello(GNUTLS_STATE state, char *data,
gnutls_assert();
return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
}
-
DECR_LEN(len, session_id_len);
#ifdef HANDSHAKE_DEBUG
- _gnutls_log( "SessionID length: %d\n", session_id_len);
- _gnutls_log( "SessionID: %s\n",
- _gnutls_bin2hex(&data[pos], session_id_len));
+ _gnutls_log("SessionID length: %d\n", session_id_len);
+ _gnutls_log("SessionID: %s\n",
+ _gnutls_bin2hex(&data[pos], session_id_len));
#endif
if ((state->gnutls_internals.resumed_security_parameters.
session_id_size > 0)
@@ -877,7 +848,7 @@ static int _gnutls_read_server_hello(GNUTLS_STATE state, char *data,
return 0;
} else {
/* keep the new session id */
- state->gnutls_internals.resumed = RESUME_FALSE; /* we are not resuming */
+ state->gnutls_internals.resumed = RESUME_FALSE; /* we are not resuming */
state->security_parameters.session_id_size =
session_id_len;
memcpy(state->security_parameters.session_id,
@@ -901,17 +872,16 @@ static int _gnutls_read_server_hello(GNUTLS_STATE state, char *data,
gnutls_assert();
return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
}
-
memcpy(state->security_parameters.
current_cipher_suite.CipherSuite,
cipher_suite.CipherSuite, 2);
#ifdef HANDSHAKE_DEBUG
- _gnutls_log( "Selected cipher suite: ");
- _gnutls_log( "%s\n",
- _gnutls_cipher_suite_get_name(state->
- security_parameters.
- current_cipher_suite));
+ _gnutls_log("Selected cipher suite: ");
+ _gnutls_log("%s\n",
+ _gnutls_cipher_suite_get_name(state->
+ security_parameters.
+ current_cipher_suite));
#endif
/* check if the credentials (username, public key etc. are ok).
@@ -926,7 +896,6 @@ static int _gnutls_read_server_hello(GNUTLS_STATE state, char *data,
gnutls_assert();
return GNUTLS_E_INSUFICIENT_CRED;
}
-
/* set the MOD_AUTH_STRUCT to the appropriate struct
* according to the KX algorithm. This is needed since all the
* handshake functions are read from there;
@@ -937,13 +906,11 @@ static int _gnutls_read_server_hello(GNUTLS_STATE state, char *data,
if (state->gnutls_internals.auth_struct == NULL) {
#ifdef HANDSHAKE_DEBUG
_gnutls_log(
- "Cannot find the appropriate handler for the KX algorithm\n");
+ "Cannot find the appropriate handler for the KX algorithm\n");
#endif
gnutls_assert();
return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
}
-
-
/* move to compression */
z = 1;
DECR_LEN(len, 1);
@@ -969,18 +936,16 @@ static int _gnutls_read_server_hello(GNUTLS_STATE state, char *data,
gnutls_free(cipher_suites);
gnutls_free(compression_methods);
- ret = _gnutls_parse_extensions(state, &data[pos], len); /* len is the rest of the parsed length */
+ ret = _gnutls_parse_extensions(state, &data[pos], len); /* len is the rest of the parsed length */
if (ret < 0) {
gnutls_assert();
return ret;
}
-
return ret;
}
-static int _gnutls_send_client_hello(SOCKET cd, GNUTLS_STATE state)
-{
+static int _gnutls_send_client_hello(SOCKET cd, GNUTLS_STATE state) {
char *data = NULL;
opaque *extdata;
int extdatalen;
@@ -994,10 +959,10 @@ static int _gnutls_send_client_hello(SOCKET cd, GNUTLS_STATE state)
GNUTLS_Version hver;
opaque *SessionID =
- state->gnutls_internals.resumed_security_parameters.session_id;
+ state->gnutls_internals.resumed_security_parameters.session_id;
uint8 session_id_len =
- state->gnutls_internals.resumed_security_parameters.
- session_id_size;
+ state->gnutls_internals.resumed_security_parameters.
+ session_id_size;
if (SessionID == NULL)
session_id_len = 0;
@@ -1010,9 +975,9 @@ static int _gnutls_send_client_hello(SOCKET cd, GNUTLS_STATE state)
hver = _gnutls_version_max(state);
data[pos++] =
- _gnutls_version_get_major( hver);
+ _gnutls_version_get_major(hver);
data[pos++] =
- _gnutls_version_get_minor( hver);
+ _gnutls_version_get_minor(hver);
_gnutls_create_random(random);
_gnutls_set_client_random(state, random);
@@ -1066,7 +1031,6 @@ static int _gnutls_send_client_hello(SOCKET cd, GNUTLS_STATE state)
memcpy(&data[pos], extdata, extdatalen);
gnutls_free(extdata);
}
-
ret =
_gnutls_send_handshake(cd, state, data, datalen,
GNUTLS_CLIENT_HELLO);
@@ -1077,8 +1041,7 @@ static int _gnutls_send_client_hello(SOCKET cd, GNUTLS_STATE state)
return ret;
}
-static int _gnutls_send_server_hello(SOCKET cd, GNUTLS_STATE state)
-{
+static int _gnutls_send_server_hello(SOCKET cd, GNUTLS_STATE state) {
char *data = NULL;
opaque *extdata;
int extdatalen;
@@ -1110,8 +1073,8 @@ static int _gnutls_send_server_hello(SOCKET cd, GNUTLS_STATE state)
pos += session_id_len;
#ifdef HANDSHAKE_DEBUG
- _gnutls_log( "Handshake: SessionID: %s\n",
- _gnutls_bin2hex(SessionID, session_id_len));
+ _gnutls_log("Handshake: SessionID: %s\n",
+ _gnutls_bin2hex(SessionID, session_id_len));
#endif
datalen += 2;
@@ -1137,7 +1100,6 @@ static int _gnutls_send_server_hello(SOCKET cd, GNUTLS_STATE state)
memcpy(&data[pos], extdata, extdatalen);
gnutls_free(extdata);
}
-
ret =
_gnutls_send_handshake(cd, state, data, datalen,
GNUTLS_SERVER_HELLO);
@@ -1147,8 +1109,7 @@ static int _gnutls_send_server_hello(SOCKET cd, GNUTLS_STATE state)
return ret;
}
-int _gnutls_send_hello(SOCKET cd, GNUTLS_STATE state)
-{
+int _gnutls_send_hello(SOCKET cd, GNUTLS_STATE state) {
int ret;
if (state->security_parameters.entity == GNUTLS_CLIENT) {
@@ -1166,8 +1127,7 @@ int _gnutls_send_hello(SOCKET cd, GNUTLS_STATE state)
* and gnutls_internals.compression_method.
*/
int _gnutls_recv_hello(SOCKET cd, GNUTLS_STATE state, char *data,
- int datalen)
-{
+ int datalen) {
int ret;
if (state->security_parameters.entity == GNUTLS_CLIENT) {
@@ -1191,7 +1151,7 @@ int _gnutls_recv_hello(SOCKET cd, GNUTLS_STATE state, char *data,
}
/* The packets in gnutls_handshake
- *
+
* Client Server
*
* ClientHello -------->
@@ -1213,7 +1173,7 @@ int _gnutls_recv_hello(SOCKET cd, GNUTLS_STATE state, char *data,
* <-------- Finished
*
*/
-
+
/**
* gnutls_handshake - This the main function in the handshake protocol.
* @cd: is a connection descriptor, as returned by socket().
@@ -1225,8 +1185,7 @@ int _gnutls_recv_hello(SOCKET cd, GNUTLS_STATE state, char *data,
* This function will fail if any problem is encountered,
* and the connection should be terminated.
**/
-int gnutls_handshake(SOCKET cd, GNUTLS_STATE state)
-{
+int gnutls_handshake(SOCKET cd, GNUTLS_STATE state) {
int ret;
ret = gnutls_handshake_begin(cd, state);
@@ -1256,21 +1215,20 @@ int gnutls_handshake(SOCKET cd, GNUTLS_STATE state)
* continue the handshake - eg. even if the certificate cannot
* be verified- by calling gnutls_handshake_finish().
*/
-int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state)
-{
+int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state) {
int ret;
if (state->security_parameters.entity == GNUTLS_CLIENT) {
#ifdef HANDSHAKE_DEBUG
if (state->gnutls_internals.resumed_security_parameters.
session_id_size > 0)
- _gnutls_log( "Ask to resume: %s\n",
- _gnutls_bin2hex(state->gnutls_internals.
- resumed_security_parameters.
- session_id,
- state->gnutls_internals.
- resumed_security_parameters.
- session_id_size));
+ _gnutls_log("Ask to resume: %s\n",
+ _gnutls_bin2hex(state->gnutls_internals.
+ resumed_security_parameters.
+ session_id,
+ state->gnutls_internals.
+ resumed_security_parameters.
+ session_id_size));
#endif
ret = _gnutls_send_hello(cd, state);
if (ret < 0) {
@@ -1279,7 +1237,6 @@ int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state)
gnutls_clearHashDataBuffer(state);
return ret;
}
-
/* receive the server hello */
ret =
_gnutls_recv_handshake(cd, state, NULL, NULL,
@@ -1290,7 +1247,6 @@ int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state)
gnutls_clearHashDataBuffer(state);
return ret;
}
-
/* RECV CERTIFICATE */
if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
ret = _gnutls_recv_certificate(cd, state);
@@ -1312,7 +1268,6 @@ int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state)
gnutls_clearHashDataBuffer(state);
return ret;
}
-
ret = _gnutls_send_hello(cd, state);
if (ret < 0) {
ERR("send hello", ret);
@@ -1320,7 +1275,6 @@ int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state)
gnutls_clearHashDataBuffer(state);
return ret;
}
-
/* NOTE: these should not be send if we are resuming */
/* SEND CERTIFICATE + KEYEXCHANGE + CERTIFICATE_REQUEST */
@@ -1333,8 +1287,6 @@ int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state)
gnutls_clearHashDataBuffer(state);
return ret;
}
-
-
/* send server key exchange (A) */
if (state->gnutls_internals.resumed == RESUME_FALSE)
ret = _gnutls_send_server_kx_message(cd, state);
@@ -1344,7 +1296,6 @@ int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state)
gnutls_clearHashDataBuffer(state);
return ret;
}
-
/* FIXME: Send certificate request */
/* Added for SRP which uses a different handshake */
@@ -1357,7 +1308,6 @@ int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state)
gnutls_clearHashDataBuffer(state);
return ret;
}
-
/* send server key exchange (B) */
if (state->gnutls_internals.resumed == RESUME_FALSE)
ret = _gnutls_send_server_kx_message2(cd, state);
@@ -1367,7 +1317,6 @@ int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state)
gnutls_clearHashDataBuffer(state);
return ret;
}
-
/* FIXME: request - and get - a client certificate */
return 0;
}
@@ -1376,35 +1325,29 @@ int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state)
/* This function sends the final handshake packets and initializes connection
*/
static int _gnutls_send_handshake_final(SOCKET cd, GNUTLS_STATE state,
- int init)
-{
+ int init) {
int ret = 0;
/* Send the CHANGE CIPHER SPEC PACKET */
- ret = _gnutls_send_change_cipher_spec(cd, state);
+ ret = _gnutls_send_change_cipher_spec(cd, state);
if (ret < 0) {
ERR("send ChangeCipherSpec", ret);
gnutls_assert();
return ret;
}
-
/* Initialize the connection state (start encryption) - in case of client
- */
- if (init == TRUE) {
+ */ if (init == TRUE) {
ret = _gnutls_connection_state_init(state);
if (ret < 0) {
gnutls_assert();
return ret;
}
}
-
ret = _gnutls_write_connection_state_init(state);
if (ret < 0) {
gnutls_assert();
return ret;
}
-
-
/* send the finished message */
ret = _gnutls_send_finished(cd, state);
if (ret < 0) {
@@ -1418,35 +1361,30 @@ static int _gnutls_send_handshake_final(SOCKET cd, GNUTLS_STATE state,
/* This function receives the final handshake packets
*/
static int _gnutls_recv_handshake_final(SOCKET cd, GNUTLS_STATE state,
- int init)
-{
+ int init) {
int ret = 0;
char ch;
- ret =
- gnutls_recv_int(cd, state, GNUTLS_CHANGE_CIPHER_SPEC, -1,
- &ch, 1, 0);
+ ret =
+ gnutls_recv_int(cd, state, GNUTLS_CHANGE_CIPHER_SPEC, -1,
+ &ch, 1, 0);
if (ret <= 0) {
ERR("recv ChangeCipherSpec", ret);
gnutls_assert();
- return (ret<0)?ret:GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ return (ret < 0) ? ret : GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
-
- /* Initialize the connection state (start encryption) - in case of server */
- if (init == TRUE) {
+ /* Initialize the connection state (start encryption) - in case of server */ if (init == TRUE) {
ret = _gnutls_connection_state_init(state);
if (ret < 0) {
gnutls_assert();
return ret;
}
}
-
ret = _gnutls_read_connection_state_init(state);
if (ret < 0) {
gnutls_assert();
return ret;
}
-
ret = _gnutls_recv_finished(cd, state);
if (ret < 0) {
ERR("recv finished", ret);
@@ -1466,8 +1404,7 @@ static int _gnutls_recv_handshake_final(SOCKET cd, GNUTLS_STATE state,
* you have somehow verified the identity of the peer.
* This function will fail if any problem is encountered.
*/
-int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state)
-{
+int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state) {
int ret = 0;
if (state->security_parameters.entity == GNUTLS_CLIENT) {
@@ -1482,10 +1419,9 @@ int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state)
return ret;
}
-
- /* Added for SRP */
-
- /* send the client key exchange for SRP */
+ /* Added for SRP,
+ * send the client key exchange for SRP
+ */
if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
ret = _gnutls_send_client_kx_message0(cd, state);
if (ret < 0) {
@@ -1495,6 +1431,17 @@ int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state)
return ret;
}
+#warning "FIX THIS REQUEST"
+ /* receive the server certificate request */
+ if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ ret = _gnutls_recv_server_certificate_request(cd, state);
+ if (ret < 0) {
+ gnutls_assert();
+ ERR("recv server certificate request message", ret);
+ gnutls_clearHashDataBuffer(state);
+ return ret;
+ }
+
/* receive the server key exchange (B) (SRP only) */
if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
ret = _gnutls_recv_server_kx_message2(cd, state);
@@ -1504,22 +1451,19 @@ int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state)
gnutls_clearHashDataBuffer(state);
return ret;
}
-
-
/* FIXME: receive certificate request */
/* receive the server hello done */
if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
ret =
_gnutls_recv_handshake(cd, state, NULL, NULL,
- GNUTLS_SERVER_HELLO_DONE);
+ GNUTLS_SERVER_HELLO_DONE);
if (ret < 0) {
gnutls_assert();
ERR("recv server hello done", ret);
gnutls_clearHashDataBuffer(state);
return ret;
}
-
/* send our certificate - if any
*/
if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
@@ -1530,7 +1474,6 @@ int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state)
gnutls_clearHashDataBuffer(state);
return ret;
}
-
if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
ret = _gnutls_send_client_kx_message(cd, state);
if (ret < 0) {
@@ -1539,7 +1482,6 @@ int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state)
gnutls_clearHashDataBuffer(state);
return ret;
}
-
/* send client certificate verify */
if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
ret =
@@ -1551,21 +1493,19 @@ int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state)
gnutls_clearHashDataBuffer(state);
return ret;
}
-
} else { /* SERVER SIDE */
/* send the server hello done */
if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
ret =
_gnutls_send_handshake(cd, state, NULL, 0,
- GNUTLS_SERVER_HELLO_DONE);
+ GNUTLS_SERVER_HELLO_DONE);
if (ret < 0) {
gnutls_assert();
ERR("send server hello done", ret);
gnutls_clearHashDataBuffer(state);
return ret;
}
-
/* RECV CERTIFICATE + KEYEXCHANGE + CERTIFICATE_VERIFY */
/* receive the client key exchange message */
@@ -1577,8 +1517,6 @@ int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state)
gnutls_clearHashDataBuffer(state);
return ret;
}
-
-
}
/* send and recv the change cipher spec and finished messages */
@@ -1598,7 +1536,6 @@ int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state)
return GNUTLS_E_AUTH_FAILED;
return ret;
}
-
ret = _gnutls_send_handshake_final(cd, state, FALSE);
if (ret < 0) {
gnutls_assert();
@@ -1613,7 +1550,6 @@ int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state)
gnutls_clearHashDataBuffer(state);
return ret;
}
-
ret = _gnutls_recv_handshake_final(cd, state, FALSE);
if (ret < 0) {
gnutls_assert();
@@ -1630,47 +1566,43 @@ int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state)
/* in order to support session resuming */
_gnutls_server_register_current_session(state);
}
-
/* clear handshake buffer */
gnutls_clearHashDataBuffer(state);
return ret;
}
-int _gnutls_generate_session_id(char *session_id, uint8 * len)
-{
+int _gnutls_generate_session_id(char *session_id, uint8 * len) {
opaque rand[TLS_RANDOM_SIZE];
if (_gnutls_get_random(rand, TLS_RANDOM_SIZE, GNUTLS_WEAK_RANDOM) <
0) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
}
-
memcpy(session_id, rand, TLS_RANDOM_SIZE);
*len = TLS_RANDOM_SIZE;
#ifdef HANDSHAKE_DEBUG
- _gnutls_log( "Generated SessionID: %s\n",
- _gnutls_bin2hex(session_id, TLS_RANDOM_SIZE));
+ _gnutls_log("Generated SessionID: %s\n",
+ _gnutls_bin2hex(session_id, TLS_RANDOM_SIZE));
#endif
return 0;
}
#define RENEGOTIATE
int _gnutls_recv_hello_request(SOCKET cd, GNUTLS_STATE state, void *data,
- uint32 data_size)
-{
+ uint32 data_size) {
#ifndef RENEGOTIATE
int ret;
/* only client should receive that */
if (state->security_parameters.entity == GNUTLS_SERVER)
- return GNUTLS_E_UNEXPECTED_PACKET;
+ return GNUTLS_E_UNEXPECTED_PACKET;
/* just return an alert that we don't like that */
- ret =
- gnutls_send_alert(cd, state, GNUTLS_WARNING,
- GNUTLS_NO_RENEGOTIATION);
+ ret =
+ gnutls_send_alert(cd, state, GNUTLS_WARNING,
+ GNUTLS_NO_RENEGOTIATION);
if (ret < 0) {
gnutls_assert();
return ret;
@@ -1684,12 +1616,10 @@ int _gnutls_recv_hello_request(SOCKET cd, GNUTLS_STATE state, void *data,
gnutls_assert();
return GNUTLS_E_UNEXPECTED_PACKET;
}
-
if (data_size < 1) {
gnutls_assert();
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
-
type = ((uint8 *) data)[0];
if (type == GNUTLS_HELLO_REQUEST)
return gnutls_handshake(cd, state);
@@ -1703,17 +1633,18 @@ int _gnutls_recv_hello_request(SOCKET cd, GNUTLS_STATE state, void *data,
/* This function will remove algorithms that are not supported by
* the requested authentication method. We only remove algorithm if
* we receive client hello extensions (dnsname).
+ *
+ * or if we have a certificate with keyUsage bits (not ready yet)
*/
int _gnutls_remove_unwanted_ciphersuites(GNUTLS_STATE state,
GNUTLS_CipherSuite **
- cipherSuites, int numCipherSuites)
-{
+ cipherSuites, int numCipherSuites) {
int ret = 0;
GNUTLS_CipherSuite *newSuite;
int newSuiteSize = 0, i, j, keep;
const X509PKI_CREDENTIALS x509_cred;
- gnutls_cert *cert=NULL;
+ gnutls_cert *cert = NULL;
KXAlgorithm *alg;
int alg_size;
KXAlgorithm kx;
@@ -1724,9 +1655,9 @@ int _gnutls_remove_unwanted_ciphersuites(GNUTLS_STATE state,
* we've got a sign-only key... (ok we need to check
* it more than that).
*/
-
+
if (state->security_parameters.entity == GNUTLS_CLIENT)
- return 0;
+ return 0;
/* if we should use a specific certificate,
* we should remove all algorithms that are not supported
@@ -1748,13 +1679,11 @@ int _gnutls_remove_unwanted_ciphersuites(GNUTLS_STATE state,
cert =
(gnutls_cert *) _gnutls_find_cert(x509_cred->cert_list,
x509_cred->ncerts,
- state->security_parameters.
+ state->security_parameters.
extensions.dnsname);
}
-
-
- if (cert == NULL && x509_cred->cert_list!=NULL) { /* if no such cert, use the first in the list
- */
+ if (cert == NULL && x509_cred->cert_list != NULL) { /* if no such cert, use the first in the list
+ */
cert = &x509_cred->cert_list[0][0];
/* get all the key exchange algorithms that are
@@ -1764,12 +1693,11 @@ int _gnutls_remove_unwanted_ciphersuites(GNUTLS_STATE state,
gnutls_assert();
return ret;
}
-
} else {
- /* No certificate was found
- */
- alg_size = 0;
- alg = NULL;
+ /* No certificate was found
+ */
+ alg_size = 0;
+ alg = NULL;
}
@@ -1780,7 +1708,7 @@ int _gnutls_remove_unwanted_ciphersuites(GNUTLS_STATE state,
kx = _gnutls_cipher_suite_get_kx_algo((*cipherSuites)[i]);
keep = 0;
- if (_gnutls_map_kx_get_cred( kx) == GNUTLS_X509PKI) {
+ if (_gnutls_map_kx_get_cred(kx) == GNUTLS_X509PKI) {
keep = 1; /* do not keep */
if (x509_cred != NULL)
for (j = 0; j < alg_size; j++) {
@@ -1789,10 +1717,10 @@ int _gnutls_remove_unwanted_ciphersuites(GNUTLS_STATE state,
break;
}
}
- } else /* if it is defined but had no credentials
- */
- if ( _gnutls_get_kx_cred( state->gnutls_key, kx, NULL)==NULL)
- keep = 1;
+ } else
+ /* if it is defined but had no credentials
+ */ if (_gnutls_get_kx_cred(state->gnutls_key, kx, NULL) == NULL)
+ keep = 1;
if (keep == 0) {
memcpy(newSuite[newSuiteSize].CipherSuite,
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index e3860ab844..5497cde7da 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -30,9 +30,9 @@
#define HARD_DEBUG
#define BUFFERS_DEBUG
#define RECORD_DEBUG
-#define HANDSHAKE_DEBUG
+#define HANDSHAKE_DEBUG*/
#define DEBUG
-*/
+
#define SOCKET int
#define LIST ...
@@ -71,6 +71,7 @@
#endif
#include <gnutls_mem.h>
+#include <gnutls_ui.h>
#define DECR_LEN(len, x) len-=x; if (len<0) {gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;}
@@ -141,7 +142,7 @@ typedef struct {
uint8 minor;
} ProtocolVersion;
-typedef struct {
+struct GNUTLS_KEY_INT {
/* For DH KX */
gnutls_datum key;
MPI KEY;
@@ -172,22 +173,24 @@ typedef struct {
*/
uint8 crypt_algo;
- /* These are needed in RSA and DH signature calculation
- */
- opaque server_random[TLS_RANDOM_SIZE];
- opaque client_random[TLS_RANDOM_SIZE];
- ProtocolVersion version;
-
AUTH_CRED* cred; /* used to specify keys/certificates etc */
-} GNUTLS_KEY_A;
-typedef GNUTLS_KEY_A* GNUTLS_KEY;
+
+ int certificate_requested;
+ /* some ciphersuites use this
+ * to provide client authentication.
+ * 1 if client auth was requested
+ * by the peer, 0 otherwise
+ */
+};
+typedef struct GNUTLS_KEY_INT* GNUTLS_KEY;
/* STATE (cont) */
#include <gnutls_hash_int.h>
#include <gnutls_cipher_int.h>
-#include <gnutls_auth.h>
+
+//#include <gnutls_auth.h>
typedef struct {
uint8 CipherSuite[2];
@@ -305,28 +308,27 @@ typedef struct {
ResumableSession resumed; /* TRUE or FALSE - if we are resuming a session */
SecurityParameters resumed_security_parameters;
- int certificate_requested; /* non zero if client certificate was requested */
/* sockets internals */
int lowat;
/* gdbm */
char* db_name;
int expire_time;
- MOD_AUTH_STRUCT* auth_struct; /* used in handshake packets and KX algorithms */
+ struct MOD_AUTH_STRUCT_INT* auth_struct; /* used in handshake packets and KX algorithms */
int v2_hello; /* set 0 normally - 1 if v2 hello was received - server side only */
#ifdef HAVE_LIBGDBM
GDBM_FILE db_reader;
#endif
} GNUTLS_INTERNALS;
-typedef struct {
+struct GNUTLS_STATE_INT {
SecurityParameters security_parameters;
CipherSpecs cipher_specs;
ConnectionState connection_state;
GNUTLS_INTERNALS gnutls_internals;
GNUTLS_KEY gnutls_key;
-} GNUTLS_STATE_INT;
+};
-typedef GNUTLS_STATE_INT *GNUTLS_STATE;
+typedef struct GNUTLS_STATE_INT *GNUTLS_STATE;
/* Record Protocol */
@@ -345,7 +347,8 @@ GNUTLS_Version gnutls_get_current_version(GNUTLS_STATE state);
ssize_t gnutls_send_int(SOCKET cd, GNUTLS_STATE state, ContentType type, HandshakeType htype, const void* data, size_t sizeofdata, int flags);
ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, HandshakeType, char* data, size_t sizeofdata, int flags);
int _gnutls_send_change_cipher_spec(SOCKET cd, GNUTLS_STATE state);
-int _gnutls_version_cmp(GNUTLS_Version ver1, GNUTLS_Version ver2);
+
+#define _gnutls_version_cmp( ver1, ver2) ver1==ver2?0:1
#define _gnutls_version_ssl3(x) _gnutls_version_cmp(x, GNUTLS_SSL3)
#endif /* GNUTLS_INT_H */
diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c
index 30b8f666ac..1963ed9786 100644
--- a/lib/gnutls_kx.c
+++ b/lib/gnutls_kx.c
@@ -102,7 +102,7 @@ int _gnutls_send_server_kx_message(SOCKET cd, GNUTLS_STATE state)
#endif
- data_size = state->gnutls_internals.auth_struct->gnutls_generate_server_kx( state->gnutls_key, &data);
+ data_size = state->gnutls_internals.auth_struct->gnutls_generate_server_kx( state, &data);
if (data_size < 0) {
gnutls_assert();
@@ -127,7 +127,7 @@ int _gnutls_send_server_kx_message2(SOCKET cd, GNUTLS_STATE state)
int ret = 0;
if (state->gnutls_internals.auth_struct->gnutls_generate_server_kx2 != NULL) {
- data_size = state->gnutls_internals.auth_struct->gnutls_generate_server_kx2( state->gnutls_key, &data);
+ data_size = state->gnutls_internals.auth_struct->gnutls_generate_server_kx2( state, &data);
#ifdef HANDSHAKE_DEBUG
_gnutls_log( "Sending server KX message2\n");
@@ -165,7 +165,7 @@ int _gnutls_send_client_kx_message(SOCKET cd, GNUTLS_STATE state)
_gnutls_log( "Sending client KX message\n");
#endif
- data_size = state->gnutls_internals.auth_struct->gnutls_generate_client_kx( state->gnutls_key, &data);
+ data_size = state->gnutls_internals.auth_struct->gnutls_generate_client_kx( state, &data);
if (data_size < 0) {
gnutls_assert();
return data_size;
@@ -197,7 +197,7 @@ int _gnutls_send_client_kx_message0(SOCKET cd, GNUTLS_STATE state)
_gnutls_log( "Sending client KX message0\n");
#endif
- data_size = state->gnutls_internals.auth_struct->gnutls_generate_client_kx0( state->gnutls_key, &data);
+ data_size = state->gnutls_internals.auth_struct->gnutls_generate_client_kx0( state, &data);
if (data_size < 0) {
gnutls_assert();
return data_size;
@@ -212,8 +212,6 @@ int _gnutls_send_client_kx_message0(SOCKET cd, GNUTLS_STATE state)
/* This is the function for the client to send the certificate
* verify message
- * FIXME: this function does almost nothing except sending garbage to
- * peer.
*/
int _gnutls_send_client_certificate_verify(SOCKET cd, GNUTLS_STATE state)
{
@@ -227,7 +225,7 @@ int _gnutls_send_client_certificate_verify(SOCKET cd, GNUTLS_STATE state)
/* if certificate verify is not needed just exit
*/
- if (state->gnutls_internals.certificate_requested==0) return 0;
+ if (state->gnutls_key->certificate_requested==0) return 0;
if (state->gnutls_internals.auth_struct->gnutls_generate_client_cert_vrfy==NULL) {
return 0; /* this algorithm does not support cli_cert_vrfy
@@ -237,7 +235,7 @@ int _gnutls_send_client_certificate_verify(SOCKET cd, GNUTLS_STATE state)
#ifdef HANDSHAKE_DEBUG
_gnutls_log( "Sending client certificate verify message\n");
#endif
- data_size = state->gnutls_internals.auth_struct->gnutls_generate_client_cert_vrfy( state->gnutls_key, &data);
+ data_size = state->gnutls_internals.auth_struct->gnutls_generate_client_cert_vrfy( state, &data);
if (data_size < 0)
return data_size;
ret =
@@ -270,7 +268,36 @@ int _gnutls_recv_server_kx_message(SOCKET cd, GNUTLS_STATE state)
return ret;
- ret = state->gnutls_internals.auth_struct->gnutls_process_server_kx( state->gnutls_key, data, datasize);
+ ret = state->gnutls_internals.auth_struct->gnutls_process_server_kx( state, data, datasize);
+ gnutls_free(data);
+ if (ret < 0)
+ return ret;
+
+ }
+ return ret;
+}
+
+int _gnutls_recv_server_certificate_request(SOCKET cd, GNUTLS_STATE state)
+{
+ uint8 *data;
+ int datasize;
+ int ret = 0;
+
+ if (state->gnutls_internals.auth_struct->gnutls_process_server_certificate_request!=NULL) {
+
+#ifdef HANDSHAKE_DEBUG
+ _gnutls_log( "Receiving Server Certificate request message\n");
+#endif
+
+ ret =
+ _gnutls_recv_handshake(cd, state, &data,
+ &datasize,
+ GNUTLS_CERTIFICATE_REQUEST);
+ if (ret <= 0)
+ return ret;
+
+
+ ret = state->gnutls_internals.auth_struct->gnutls_process_server_certificate_request( state, data, datasize);
gnutls_free(data);
if (ret < 0)
return ret;
@@ -300,7 +327,7 @@ int _gnutls_recv_server_kx_message2(SOCKET cd, GNUTLS_STATE state)
return ret;
- ret = state->gnutls_internals.auth_struct->gnutls_process_server_kx2( state->gnutls_key, data, datasize);
+ ret = state->gnutls_internals.auth_struct->gnutls_process_server_kx2( state, data, datasize);
gnutls_free(data);
if (ret < 0)
return ret;
@@ -330,7 +357,7 @@ int _gnutls_recv_client_kx_message(SOCKET cd, GNUTLS_STATE state)
if (ret < 0)
return ret;
- ret = state->gnutls_internals.auth_struct->gnutls_process_client_kx( state->gnutls_key, data, datasize);
+ ret = state->gnutls_internals.auth_struct->gnutls_process_client_kx( state, data, datasize);
gnutls_free(data);
if (ret < 0)
return ret;
@@ -361,7 +388,7 @@ int _gnutls_recv_client_kx_message0(SOCKET cd, GNUTLS_STATE state)
if (ret < 0)
return ret;
- ret = state->gnutls_internals.auth_struct->gnutls_process_client_kx0( state->gnutls_key, data, datasize);
+ ret = state->gnutls_internals.auth_struct->gnutls_process_client_kx0( state, data, datasize);
gnutls_free(data);
if (ret < 0)
return ret;
@@ -386,8 +413,7 @@ int _gnutls_send_certificate(SOCKET cd, GNUTLS_STATE state)
_gnutls_log( "Sending certificate message\n");
#endif
-
- data_size = state->gnutls_internals.auth_struct->gnutls_generate_certificate( state->gnutls_key, &data);
+ data_size = state->gnutls_internals.auth_struct->gnutls_generate_certificate( state, &data);
if (data_size < 0) {
gnutls_assert();
@@ -422,7 +448,7 @@ int _gnutls_recv_certificate(SOCKET cd, GNUTLS_STATE state)
return ret;
}
- ret = state->gnutls_internals.auth_struct->gnutls_process_certificate( state->gnutls_key, data, datasize);
+ ret = state->gnutls_internals.auth_struct->gnutls_process_certificate( state, data, datasize);
gnutls_free(data);
if (ret < 0) {
gnutls_assert();
@@ -436,7 +462,7 @@ int _gnutls_recv_certificate(SOCKET cd, GNUTLS_STATE state)
int _gnutls_send_client_certificate(SOCKET cd, GNUTLS_STATE state)
{
- if (state->gnutls_internals.certificate_requested == 0)
+ if (state->gnutls_key->certificate_requested == 0)
return 0;
#ifdef HANDSHAKE_DEBUG
diff --git a/lib/gnutls_kx.h b/lib/gnutls_kx.h
index 122a50dce6..010d528d5a 100644
--- a/lib/gnutls_kx.h
+++ b/lib/gnutls_kx.h
@@ -31,4 +31,5 @@ int _gnutls_send_certificate(int cd, GNUTLS_STATE state);
int _gnutls_generate_master( GNUTLS_STATE state);
int _gnutls_recv_certificate(SOCKET cd, GNUTLS_STATE state);
int _gnutls_send_client_certificate(SOCKET cd, GNUTLS_STATE state);
+int _gnutls_recv_server_certificate_request(SOCKET cd, GNUTLS_STATE state);
diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c
index 160a6916ca..8e14630c69 100644
--- a/lib/gnutls_record.c
+++ b/lib/gnutls_record.c
@@ -51,10 +51,6 @@ GNUTLS_Version ver;
void _gnutls_set_current_version(GNUTLS_STATE state, GNUTLS_Version version) {
state->connection_state.version = version;
- if (state->gnutls_key!=NULL) {
- state->gnutls_key->version.major = _gnutls_version_get_major(version);
- state->gnutls_key->version.minor = _gnutls_version_get_minor(version);
- }
}
/**
@@ -86,7 +82,7 @@ int gnutls_set_lowat(GNUTLS_STATE state, int num) {
int gnutls_init(GNUTLS_STATE * state, ConnectionEnd con_end)
{
- *state = gnutls_calloc(1, sizeof(GNUTLS_STATE_INT));
+ *state = gnutls_calloc(1, sizeof(struct GNUTLS_STATE_INT));
(*state)->security_parameters.entity = con_end;
@@ -104,7 +100,7 @@ int gnutls_init(GNUTLS_STATE * state, ConnectionEnd con_end)
gnutls_set_protocol_priority( *state, GNUTLS_TLS1, 0); /* default */
- (*state)->gnutls_key = gnutls_calloc(1, sizeof(GNUTLS_KEY_A));
+ (*state)->gnutls_key = gnutls_calloc(1, sizeof(struct GNUTLS_KEY_INT));
(*state)->gnutls_internals.resumed = RESUME_FALSE;
@@ -187,7 +183,7 @@ int gnutls_deinit(GNUTLS_STATE state)
GNUTLS_FREE(state->gnutls_internals.db_name);
- memset( state, 0, sizeof(GNUTLS_STATE_INT));
+ memset( state, 0, sizeof(struct GNUTLS_STATE_INT));
GNUTLS_FREE(state);
return 0;
}
@@ -452,6 +448,7 @@ ssize_t gnutls_send_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha
WRITEuint16( cipher_size, &headers[3]);
+#warning "CHECK if the double write breaks other implementations"
if (_gnutls_Write(cd, headers, HEADER_SIZE, flags) != HEADER_SIZE) {
state->gnutls_internals.valid_connection = VALID_FALSE;
state->gnutls_internals.resumable = RESUME_FALSE;
diff --git a/lib/gnutls_ui.c b/lib/gnutls_ui.c
index d9ff103488..33efe099d7 100644
--- a/lib/gnutls_ui.c
+++ b/lib/gnutls_ui.c
@@ -162,6 +162,19 @@ unsigned char gnutls_x509pki_client_get_key_usage( const X509PKI_CLIENT_AUTH_INF
return info->keyUsage;
}
+/**
+ * gnutls_x509pki_client_get_certificate_request_status - This function returns the certificate request status
+ * @info: is an X509PKI_CLIENT_AUTH_INFO structure
+ *
+ * This function will return 0 if the peer (server) did not requested client
+ * authentication or 1 otherwise.
+ *
+ **/
+unsigned char gnutls_x509pki_client_get_certificate_request_status( const X509PKI_CLIENT_AUTH_INFO* info) {
+ if (info==NULL) return GNUTLS_E_UNKNOWN_ERROR;
+ return info->certificate_requested;
+}
+
/**
* gnutls_x509pki_client_get_subject_alt_name - This function returns the peer's alternative name