summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--lib/auth_cert.c44
-rw-r--r--lib/gnutls_cert.c43
-rw-r--r--lib/gnutls_cert.h2
-rw-r--r--lib/gnutls_extensions.c41
-rw-r--r--lib/gnutls_extensions.h2
-rw-r--r--lib/gnutls_handshake.c66
-rw-r--r--lib/gnutls_sig.c20
8 files changed, 106 insertions, 113 deletions
diff --git a/NEWS b/NEWS
index 141924c583..6b20c6b2bc 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
Version 1.0.10
- Corrected bug in RSA parameters handling which could cause
unexpected crashes.
+- Corrected bug in SSL 3.0 authentication.
Version 1.0.9 (29/03/2004)
- Added gnutls_certificate_set_params_function() and
diff --git a/lib/auth_cert.c b/lib/auth_cert.c
index f35bfaeeef..8b6392d125 100644
--- a/lib/auth_cert.c
+++ b/lib/auth_cert.c
@@ -122,6 +122,48 @@ static int _gnutls_check_pk_algo_in_list(const gnutls_pk_algorithm *pk_algos,
return -1;
}
+/* Returns the issuer's Distinguished name in odn, of the certificate
+ * specified in cert.
+ */
+static int _gnutls_cert_get_issuer_dn(gnutls_cert * cert, gnutls_datum * odn )
+{
+ ASN1_TYPE dn;
+ int len, result;
+ int start, end;
+
+ if ((result=asn1_create_element
+ (_gnutls_get_pkix(), "PKIX1.Certificate", &dn)) != ASN1_SUCCESS) {
+ gnutls_assert();
+ return _gnutls_asn2err(result);
+ }
+
+ result = asn1_der_decoding(&dn, cert->raw.data, cert->raw.size, NULL);
+ if (result != ASN1_SUCCESS) {
+ /* couldn't decode DER */
+ gnutls_assert();
+ asn1_delete_structure(&dn);
+ return _gnutls_asn2err(result);
+ }
+
+ result = asn1_der_decoding_startEnd(dn, cert->raw.data, cert->raw.size,
+ "tbsCertificate.issuer", &start,
+ &end);
+
+ if (result != ASN1_SUCCESS) {
+ /* couldn't decode DER */
+ gnutls_assert();
+ asn1_delete_structure(&dn);
+ return _gnutls_asn2err(result);
+ }
+ asn1_delete_structure(&dn);
+
+ len = end - start + 1;
+
+ odn->size = len;
+ odn->data = &cert->raw.data[start];
+
+ return 0;
+}
/* Locates the most appropriate x509 certificate using the
@@ -151,7 +193,7 @@ static int _find_x509_cert(const gnutls_certificate_credentials cred,
for (i = 0; i < cred->ncerts; i++) {
for (j = 0; j < cred->cert_list_length[i]; j++) {
if ((result =
- _gnutls_cert_get_dn(&cred->
+ _gnutls_cert_get_issuer_dn(&cred->
cert_list[i][j],
&odn)) < 0) {
gnutls_assert();
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
index 67d1520da2..4fcc0312d2 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -775,46 +775,3 @@ void _gnutls_gcert_deinit(gnutls_cert *cert)
_gnutls_free_datum(&cert->raw);
}
-
-/* Returns the issuer's Distinguished name in odn, of the certificate
- * specified in cert.
- */
-int _gnutls_cert_get_dn(gnutls_cert * cert, gnutls_datum * odn )
-{
- ASN1_TYPE dn;
- int len, result;
- int start, end;
-
- if ((result=asn1_create_element
- (_gnutls_get_pkix(), "PKIX1.Certificate", &dn)) != ASN1_SUCCESS) {
- gnutls_assert();
- return _gnutls_asn2err(result);
- }
-
- result = asn1_der_decoding(&dn, cert->raw.data, cert->raw.size, NULL);
- if (result != ASN1_SUCCESS) {
- /* couldn't decode DER */
- gnutls_assert();
- asn1_delete_structure(&dn);
- return _gnutls_asn2err(result);
- }
-
- result = asn1_der_decoding_startEnd(dn, cert->raw.data, cert->raw.size,
- "tbsCertificate.issuer", &start,
- &end);
-
- if (result != ASN1_SUCCESS) {
- /* couldn't decode DER */
- gnutls_assert();
- asn1_delete_structure(&dn);
- return _gnutls_asn2err(result);
- }
- asn1_delete_structure(&dn);
-
- len = end - start + 1;
-
- odn->size = len;
- odn->data = &cert->raw.data[start];
-
- return 0;
-}
diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h
index c1384f17b3..803eca5033 100644
--- a/lib/gnutls_cert.h
+++ b/lib/gnutls_cert.h
@@ -86,8 +86,6 @@ int _gnutls_x509_raw_cert_to_gcert(gnutls_cert * gcert, const gnutls_datum *derC
int _gnutls_x509_crt_to_gcert(gnutls_cert * gcert, gnutls_x509_crt cert,
unsigned int flags);
-int _gnutls_cert_get_dn(gnutls_cert * cert, gnutls_datum * odn);
-
void _gnutls_gkey_deinit(gnutls_privkey *key);
void _gnutls_gcert_deinit(gnutls_cert *cert);
diff --git a/lib/gnutls_extensions.c b/lib/gnutls_extensions.c
index d13e89cd86..515ecb7032 100644
--- a/lib/gnutls_extensions.c
+++ b/lib/gnutls_extensions.c
@@ -174,20 +174,29 @@ static void _gnutls_extension_list_add( gnutls_session session, uint16 type) {
}
}
-int _gnutls_gen_extensions( gnutls_session session, opaque** data) {
+int _gnutls_gen_extensions( gnutls_session session, opaque* data, size_t data_size)
+{
int next, size;
uint16 pos=0;
-opaque sdata[1024];
-int sdata_size = sizeof(sdata);
+opaque *sdata;
+int sdata_size;
ext_send_func ext_send;
- (*data) = gnutls_malloc(2); /* allocate size for size */
- if ((*data)==NULL) {
+ if (data_size < 2) {
gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
+ return GNUTLS_E_INTERNAL_ERROR;
}
+ /* allocate enough data for each extension.
+ */
+ sdata_size = data_size;
+ sdata = gnutls_malloc( sdata_size);
+ if (sdata == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
pos+=2;
next = MAX_EXT_TYPES; /* maximum supported extensions */
do {
@@ -196,21 +205,21 @@ ext_send_func ext_send;
if (ext_send == NULL) continue;
size = ext_send( session, sdata, sdata_size);
if (size > 0) {
- (*data) = gnutls_realloc_fast( (*data), pos+size+4);
- if ((*data)==NULL) {
+ if (data_size < pos+(size_t)size+4) {
gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
+ gnutls_free(sdata);
+ return GNUTLS_E_INTERNAL_ERROR;
}
/* write extension type */
- _gnutls_write_uint16( next, &(*data)[pos]);
+ _gnutls_write_uint16( next, &data[pos]);
pos+=2;
/* write size */
- _gnutls_write_uint16( size, &(*data)[pos]);
+ _gnutls_write_uint16( size, &data[pos]);
pos+=2;
- memcpy( &(*data)[pos], sdata, size);
+ memcpy( &data[pos], sdata, size);
pos+=size;
/* add this extension to the extension list
@@ -221,7 +230,7 @@ ext_send_func ext_send;
_gnutls_extension_get_name(next));
} else if (size < 0) {
gnutls_assert();
- gnutls_free(*data); *data = NULL;
+ gnutls_free(sdata);
return size;
}
@@ -230,13 +239,13 @@ ext_send_func ext_send;
size = pos;
pos-=2; /* remove the size of the size header! */
- _gnutls_write_uint16( pos, (*data));
+ _gnutls_write_uint16( pos, data);
if (size==2) { /* empty */
size = 0;
- gnutls_free(*data);
- (*data) = NULL;
}
+
+ gnutls_free( sdata);
return size;
}
diff --git a/lib/gnutls_extensions.h b/lib/gnutls_extensions.h
index 3ea42a7739..f87bc80cbd 100644
--- a/lib/gnutls_extensions.h
+++ b/lib/gnutls_extensions.h
@@ -22,7 +22,7 @@
const char *_gnutls_extension_get_name(uint16 type);
int _gnutls_parse_extensions( gnutls_session, const opaque*, int);
-int _gnutls_gen_extensions( gnutls_session session, opaque** data);
+int _gnutls_gen_extensions( gnutls_session session, opaque* data, size_t data_size);
typedef int (*ext_recv_func)( gnutls_session, const opaque*, size_t); /* recv data */
typedef int (*ext_send_func)( gnutls_session, opaque*, size_t); /* send data */
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index 937f1af337..74d90419ad 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -1339,7 +1339,7 @@ static int _gnutls_read_server_hello(gnutls_session session, opaque *data,
* Needed in client hello messages. Returns the new data length.
*/
static int _gnutls_copy_ciphersuites(gnutls_session session,
- opaque ** ret_data)
+ opaque * ret_data, size_t ret_data_size)
{
int ret, i;
GNUTLS_CipherSuite *cipher_suites;
@@ -1381,21 +1381,18 @@ static int _gnutls_copy_ciphersuites(gnutls_session session,
datalen += sizeof(uint16) + cipher_num;
- *ret_data = gnutls_malloc(datalen);
- if (*ret_data == NULL) {
+ if ((size_t)datalen > ret_data_size) {
gnutls_assert();
- gnutls_free(cipher_suites);
- return GNUTLS_E_MEMORY_ERROR;
+ return GNUTLS_E_INTERNAL_ERROR;
}
-
- _gnutls_write_uint16(cipher_num, *ret_data);
+
+ _gnutls_write_uint16(cipher_num, ret_data);
pos += 2;
for (i = 0; i < (cipher_num / 2); i++) {
- memcpy( &(*ret_data)[pos], cipher_suites[i].CipherSuite, 2);
+ memcpy( &ret_data[pos], cipher_suites[i].CipherSuite, 2);
pos += 2;
}
-
gnutls_free(cipher_suites);
return datalen;
@@ -1406,7 +1403,7 @@ static int _gnutls_copy_ciphersuites(gnutls_session session,
* Needed in hello messages. Returns the new data length.
*/
static int _gnutls_copy_comp_methods(gnutls_session session,
- opaque ** ret_data)
+ opaque * ret_data, size_t ret_data_size)
{
int ret, i;
uint8 *compression_methods, comp_num;
@@ -1425,17 +1422,15 @@ static int _gnutls_copy_comp_methods(gnutls_session session,
datalen = pos = 0;
datalen += comp_num + 1;
- *ret_data = gnutls_malloc(datalen);
- if (*ret_data == NULL) {
+ if ((size_t)datalen > ret_data_size) {
gnutls_assert();
- gnutls_free(compression_methods);
- return GNUTLS_E_MEMORY_ERROR;
+ return GNUTLS_E_INTERNAL_ERROR;
}
- (*ret_data)[pos++] = comp_num; /* put the number of compression methods */
+ ret_data[pos++] = comp_num; /* put the number of compression methods */
for (i = 0; i < comp_num; i++) {
- (*ret_data)[pos++] = compression_methods[i];
+ ret_data[pos++] = compression_methods[i];
}
gnutls_free(compression_methods);
@@ -1443,17 +1438,22 @@ static int _gnutls_copy_comp_methods(gnutls_session session,
return datalen;
}
+/* This should be sufficient by now. It should hold all the extensions
+ * plus the headers in a hello message.
+ */
+#define MAX_EXT_DATA_LENGTH 1024
+
/* This function sends the client hello handshake message.
*/
static int _gnutls_send_client_hello(gnutls_session session, int again)
{
opaque *data = NULL;
- opaque *extdata = NULL;
int extdatalen;
int pos = 0;
int datalen = 0, ret = 0;
opaque random[TLS_RANDOM_SIZE];
gnutls_protocol_version hver;
+ opaque extdata[MAX_EXT_DATA_LENGTH];
opaque *SessionID =
session->internals.resumed_security_parameters.session_id;
@@ -1535,18 +1535,16 @@ static int _gnutls_send_client_hello(gnutls_session session, int again)
/* Copy the ciphersuites.
*/
- extdatalen = _gnutls_copy_ciphersuites(session, &extdata);
+ extdatalen = _gnutls_copy_ciphersuites(session, extdata, sizeof(extdata));
if (extdatalen > 0) {
datalen += extdatalen;
data = gnutls_realloc_fast(data, datalen);
if (data == NULL) {
gnutls_assert();
- gnutls_free(extdata);
return GNUTLS_E_MEMORY_ERROR;
}
memcpy(&data[pos], extdata, extdatalen);
- gnutls_free(extdata);
pos += extdatalen;
} else {
@@ -1560,18 +1558,16 @@ static int _gnutls_send_client_hello(gnutls_session session, int again)
/* Copy the compression methods.
*/
- extdatalen = _gnutls_copy_comp_methods(session, &extdata);
+ extdatalen = _gnutls_copy_comp_methods(session, extdata, sizeof(extdata));
if (extdatalen > 0) {
datalen += extdatalen;
data = gnutls_realloc_fast(data, datalen);
if (data == NULL) {
gnutls_assert();
- gnutls_free(extdata);
return GNUTLS_E_MEMORY_ERROR;
}
memcpy(&data[pos], extdata, extdatalen);
- gnutls_free(extdata);
pos += extdatalen;
} else {
@@ -1585,19 +1581,17 @@ static int _gnutls_send_client_hello(gnutls_session session, int again)
/* Generate and copy TLS extensions.
*/
if (hver >= GNUTLS_TLS1) {
- extdatalen = _gnutls_gen_extensions(session, &extdata);
+ extdatalen = _gnutls_gen_extensions(session, extdata, sizeof(extdata));
if (extdatalen > 0) {
datalen += extdatalen;
data = gnutls_realloc_fast(data, datalen);
if (data == NULL) {
gnutls_assert();
- gnutls_free(extdata);
return GNUTLS_E_MEMORY_ERROR;
}
memcpy(&data[pos], extdata, extdatalen);
- gnutls_free(extdata);
} else if (extdatalen < 0) {
gnutls_assert();
gnutls_free(data);
@@ -1617,7 +1611,7 @@ static int _gnutls_send_client_hello(gnutls_session session, int again)
static int _gnutls_send_server_hello(gnutls_session session, int again)
{
opaque *data = NULL;
- opaque *extdata = NULL;
+ opaque extdata[MAX_EXT_DATA_LENGTH];
int extdatalen;
int pos = 0;
int datalen, ret = 0;
@@ -1654,7 +1648,7 @@ static int _gnutls_send_server_hello(gnutls_session session, int again)
if (again == 0) {
datalen = 2 + session_id_len + 1 + TLS_RANDOM_SIZE + 3;
- extdatalen = _gnutls_gen_extensions(session, &extdata);
+ extdatalen = _gnutls_gen_extensions(session, extdata, sizeof(extdata));
if (extdatalen < 0) {
gnutls_assert();
@@ -1664,7 +1658,6 @@ static int _gnutls_send_server_hello(gnutls_session session, int again)
data = gnutls_alloca(datalen + extdatalen);
if (data == NULL) {
gnutls_assert();
- gnutls_free(extdata);
return GNUTLS_E_MEMORY_ERROR;
}
@@ -1705,7 +1698,6 @@ static int _gnutls_send_server_hello(gnutls_session session, int again)
datalen += extdatalen;
memcpy(&data[pos], extdata, extdatalen);
- gnutls_free(extdata);
}
}
@@ -1823,7 +1815,9 @@ int gnutls_rehandshake(gnutls_session session)
return 0;
}
-static int _gnutls_abort_handshake( gnutls_session session, int ret) {
+inline
+static int _gnutls_abort_handshake( gnutls_session session, int ret)
+{
if ( ((ret==GNUTLS_E_WARNING_ALERT_RECEIVED) &&
( gnutls_alert_get(session) == GNUTLS_A_NO_RENEGOTIATION))
|| ret==GNUTLS_E_GOT_APPLICATION_DATA)
@@ -1900,10 +1894,11 @@ int gnutls_handshake(gnutls_session session)
}
if (ret < 0) {
/* In the case of a rehandshake abort
- * we should reset the handshake's session
+ * we should reset the handshake's internal state.
*/
if (_gnutls_abort_handshake( session, ret) == 0)
STATE = STATE0;
+
return ret;
}
@@ -1912,6 +1907,7 @@ int gnutls_handshake(gnutls_session session)
if (ret < 0) {
if (_gnutls_abort_handshake( session, ret) == 0)
STATE = STATE0;
+
return ret;
}
@@ -2359,8 +2355,8 @@ inline static int check_server_params( gnutls_session session, gnutls_kx_algorit
_gnutls_get_cred(session->key, cred_type, NULL);
if (x509_cred != NULL) {
- dh_params = x509_cred->dh_params;
- rsa_params = x509_cred->rsa_params;
+ dh_params = _gnutls_certificate_get_dh_params(x509_cred, session);
+ rsa_params = _gnutls_certificate_get_rsa_params(x509_cred, session);
}
/* Check also if the certificate supports the
@@ -2382,7 +2378,7 @@ inline static int check_server_params( gnutls_session session, gnutls_kx_algorit
_gnutls_get_cred(session->key, cred_type, NULL);
if (anon_cred != NULL) {
- dh_params = anon_cred->dh_params;
+ dh_params = _gnutls_anon_get_dh_params(anon_cred, session);
}
} else return 0; /* no need for params */
diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c
index ab362df3b8..8f1b26728e 100644
--- a/lib/gnutls_sig.c
+++ b/lib/gnutls_sig.c
@@ -33,6 +33,7 @@
#include <debug.h>
#include <gnutls_buffers.h>
#include <gnutls_sig.h>
+#include <gnutls_kx.h>
static
int _gnutls_tls_sign( gnutls_cert* cert, gnutls_privkey* pkey, const gnutls_datum* hash_concat, gnutls_datum *signature);
@@ -105,16 +106,14 @@ gnutls_protocol_version ver = gnutls_protocol_get_version( session);
/* Generates a signature of all the random data and the parameters.
* Used in DHE_* ciphersuites.
*/
-int _gnutls_tls_sign_params( gnutls_session session,
- gnutls_cert* cert, gnutls_privkey* pkey,
- gnutls_datum* params, gnutls_datum *signature)
+int _gnutls_tls_sign_params( gnutls_session session, gnutls_cert* cert, gnutls_privkey* pkey, gnutls_datum* params, gnutls_datum *signature)
{
gnutls_datum dconcat;
int ret;
GNUTLS_MAC_HANDLE td_md5;
GNUTLS_MAC_HANDLE td_sha;
opaque concat[36];
-gnutls_protocol_version ver = gnutls_protocol_get_version( session);
+
td_sha = _gnutls_hash_init( GNUTLS_MAC_SHA);
if (td_sha == NULL) {
@@ -126,16 +125,7 @@ gnutls_protocol_version ver = gnutls_protocol_get_version( session);
_gnutls_hash( td_sha, session->security_parameters.server_random, TLS_RANDOM_SIZE);
_gnutls_hash( td_sha, params->data, params->size);
- if (ver == GNUTLS_SSL3) {
- ret = _gnutls_generate_master( session, 1);
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
-
- _gnutls_mac_deinit_ssl3_handshake( td_sha, &concat[16], session->security_parameters.master_secret, TLS_MASTER_SIZE);
- } else
- _gnutls_hash_deinit(td_sha, &concat[16]);
+ _gnutls_hash_deinit(td_sha, &concat[16]);
switch (cert->subject_pk_algorithm) {
case GNUTLS_PK_RSA:
@@ -344,8 +334,8 @@ gnutls_protocol_version ver = gnutls_protocol_get_version( session);
}
return ret;
-}
+}
/* Generates a signature of all the random data and the parameters.
* Used in DHE_* ciphersuites.