summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-10-08 19:57:53 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-10-08 19:57:53 +0000
commit3870e0504d069303681383a0ffdf9f37162fbdab (patch)
tree1dd6ee66cc014be30b8bb1293aa2b6619dc2a35c
parentc19ecf6df45152d18c79244e33bfd3bf5299c2f0 (diff)
downloadgnutls-3870e0504d069303681383a0ffdf9f37162fbdab.tar.gz
several cleanups
-rw-r--r--lib/auth_dhe_rsa.c21
-rw-r--r--lib/auth_x509.c44
-rw-r--r--lib/gnutls.h.in2
-rw-r--r--lib/gnutls_buffers.c5
-rw-r--r--lib/gnutls_cert.c11
-rw-r--r--lib/gnutls_cert.h1
-rw-r--r--lib/gnutls_handshake.c16
-rw-r--r--lib/gnutls_handshake.h1
-rw-r--r--lib/gnutls_int.h6
-rw-r--r--lib/gnutls_record.c2
-rw-r--r--lib/gnutls_sig.c38
-rw-r--r--lib/gnutls_sig.h6
12 files changed, 99 insertions, 54 deletions
diff --git a/lib/auth_dhe_rsa.c b/lib/auth_dhe_rsa.c
index 68777f5e2c..4777d7a2ff 100644
--- a/lib/auth_dhe_rsa.c
+++ b/lib/auth_dhe_rsa.c
@@ -148,26 +148,13 @@ static int gen_dhe_rsa_server_kx(GNUTLS_STATE state, opaque ** data)
/* Generate the signature. */
- /* If our certificate supports signing
- */
- if (apr_cert_list != NULL)
- if (apr_cert_list[0].keyUsage != 0)
- if (!
- (apr_cert_list[0].
- keyUsage & X509KEY_DIGITAL_SIGNATURE)) {
- gnutls_assert();
- gnutls_free( *data);
- return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
- }
-
-
ddata.data = *data;
ddata.size = data_size;
if (apr_pkey != NULL) {
if ((ret =
_gnutls_generate_sig_params(
- state, apr_pkey, &ddata, &signature)) < 0) {
+ state, &apr_cert_list[0], apr_pkey, &ddata, &signature)) < 0) {
gnutls_assert();
gnutls_free( *data);
return ret;
@@ -313,12 +300,6 @@ static int proc_dhe_rsa_server_kx(GNUTLS_STATE state, opaque * data,
signature.data = &data[vparams.size+2];
signature.size = GMIN(data_size-vparams.size-2, sigsize);
- if (state->gnutls_internals.peer_cert.version == 0) { /* this is the only way to check
- * if it is initialized
- */
- gnutls_assert();
- return GNUTLS_E_X509_CERTIFICATE_ERROR;
- }
ret = _gnutls_verify_sig_params( state, &state->gnutls_internals.peer_cert, &vparams, &signature);
if (ret<0) {
gnutls_assert();
diff --git a/lib/auth_x509.c b/lib/auth_x509.c
index f34268f22c..f6bad788a1 100644
--- a/lib/auth_x509.c
+++ b/lib/auth_x509.c
@@ -507,6 +507,7 @@ int _gnutls_gen_x509_server_certificate(GNUTLS_STATE state, opaque ** data)
return pdatasize;
}
+
#define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) gnutls_free_cert(peer_certificate_list[x])
int _gnutls_proc_x509_server_certificate(GNUTLS_STATE state, opaque * data, int data_size)
{
@@ -639,15 +640,12 @@ int _gnutls_proc_x509_server_certificate(GNUTLS_STATE state, opaque * data, int
_gnutls_copy_x509_client_auth_info(info, &peer_certificate_list[0], verify);
- /* This works for the client
- */
- if ( peer_certificate_list[0].keyUsage != 0)
- if ( !(peer_certificate_list[0].keyUsage & X509KEY_KEY_ENCIPHERMENT)) {
- gnutls_assert();
- CLEAR_CERTS;
- gnutls_free(peer_certificate_list);
- return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
- }
+ if ( (ret=_gnutls_check_x509_key_usage( &peer_certificate_list[0], gnutls_get_current_kx( state))) < 0) {
+ gnutls_assert();
+ CLEAR_CERTS;
+ gnutls_free(peer_certificate_list);
+ return ret;
+ }
CLEAR_CERTS;
gnutls_free(peer_certificate_list);
@@ -656,7 +654,20 @@ int _gnutls_proc_x509_server_certificate(GNUTLS_STATE state, opaque * data, int
}
+#ifdef DEBUG
+# warning CHECK FOR DSS
+#endif
+
#define RSA_SIGN 1
+int _gnutls_check_supported_sign_algo( uint8 algo) {
+ switch(algo) {
+ case RSA_SIGN:
+ return 0;
+ }
+
+ return -1;
+}
+
int _gnutls_proc_x509_cert_req(GNUTLS_STATE state, opaque * data, int data_size)
{
int size, ret;
@@ -697,7 +708,7 @@ int _gnutls_proc_x509_cert_req(GNUTLS_STATE state, opaque * data, int data_size)
found = 0;
for (i = 0; i < size; i++, p++) {
DECR_LEN(dsize, 1);
- if (*p == RSA_SIGN)
+ if ( _gnutls_check_supported_sign_algo(*p)==0)
found = 1;
}
@@ -741,17 +752,8 @@ int _gnutls_gen_x509_client_cert_vrfy(GNUTLS_STATE state, opaque ** data)
return ret;
}
- /* If our certificate supports signing
- */
- if ( apr_cert_list != NULL)
- if ( apr_cert_list[0].keyUsage != 0)
- if ( !(apr_cert_list[0].keyUsage & X509KEY_DIGITAL_SIGNATURE)) {
- gnutls_assert();
- return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
- }
-
if (apr_pkey != NULL) {
- if ( (ret=_gnutls_generate_sig_from_hdata( state, apr_pkey, &signature)) < 0) {
+ if ( (ret=_gnutls_generate_sig_from_hdata( state, &apr_cert_list[0], apr_pkey, &signature)) < 0) {
gnutls_assert();
return ret;
}
@@ -793,7 +795,7 @@ gnutls_datum sig;
sig.data = pdata;
sig.size = size;
-
+
if ( (ret=_gnutls_verify_sig_hdata( state, &state->gnutls_internals.peer_cert, &sig, data_size+HANDSHAKE_HEADER_SIZE))<0) {
gnutls_assert();
return ret;
diff --git a/lib/gnutls.h.in b/lib/gnutls.h.in
index 5aba9aa750..f496a1465f 100644
--- a/lib/gnutls.h.in
+++ b/lib/gnutls.h.in
@@ -136,6 +136,8 @@ int gnutls_set_cache_expiration( GNUTLS_STATE state, int seconds);
int gnutls_set_db_name( GNUTLS_STATE state, char* filename);
int gnutls_clean_db( GNUTLS_STATE state);
+void gnutls_set_max_handshake_data_buffer_size( GNUTLS_STATE state, int max);
+
/* returns libgnutls version */
const char* gnutls_check_version();
diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c
index a044f316fc..f5a7d79cfc 100644
--- a/lib/gnutls_buffers.c
+++ b/lib/gnutls_buffers.c
@@ -377,6 +377,11 @@ int gnutls_insertHashDataBuffer( GNUTLS_STATE state, char *data, int length)
old_buffer = state->gnutls_internals.hash_buffer.size;
state->gnutls_internals.hash_buffer.size += length;
+ if (state->gnutls_internals.max_handshake_data_buffer_size > 0 && state->gnutls_internals.hash_buffer.size > state->gnutls_internals.max_handshake_data_buffer_size) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
#ifdef BUFFERS_DEBUG
_gnutls_log( "HASH BUFFER: Inserted %d bytes of Data\n", length);
#endif
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
index dac06a48ea..50a24b238d 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -919,9 +919,9 @@ int _gnutls_cert2gnutlsCert(gnutls_cert * gCert, gnutls_datum derCert)
}
/* Returns 0 if it's ok to use the KXAlgorithm with this cert
- * (using KeyUsage field). 1 otherwise.
+ * (using KeyUsage field).
*/
-static int _gnutls_check_x509_key_usage(gnutls_cert * cert,
+int _gnutls_check_x509_key_usage(gnutls_cert * cert,
KXAlgorithm alg)
{
if (_gnutls_map_kx_get_cred(alg) == GNUTLS_X509PKI) {
@@ -931,7 +931,7 @@ static int _gnutls_check_x509_key_usage(gnutls_cert * cert,
if (!
(cert->
keyUsage & X509KEY_KEY_ENCIPHERMENT))
- return 1;
+ return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
else
return 0;
}
@@ -941,13 +941,14 @@ static int _gnutls_check_x509_key_usage(gnutls_cert * cert,
if (!
(cert->
keyUsage & X509KEY_DIGITAL_SIGNATURE))
- return 1;
+ return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
else
return 0;
}
return 0;
default:
- return 1;
+ gnutls_assert();
+ return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
}
}
return 0;
diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h
index 0d7d6aaf90..2765d11229 100644
--- a/lib/gnutls_cert.h
+++ b/lib/gnutls_cert.h
@@ -58,5 +58,6 @@ int _gnutls_find_cert_list_index(gnutls_cert ** cert_list,
void _gnutls_int2str(int k, char* data);
int _gnutls_get_name_type( node_asn *rasn, char *root, gnutls_DN * dn);
void gnutls_free_cert(gnutls_cert cert);
+int _gnutls_check_x509_key_usage(gnutls_cert * cert, KXAlgorithm alg);
#endif
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index 49445002f6..bfbe5b505a 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -1821,3 +1821,19 @@ int _gnutls_remove_unwanted_ciphersuites(GNUTLS_STATE state,
return ret;
}
+
+/**
+ * gnutls_set_max_handshake_data_buffer_size - This function will set the maximum size of handshake message sequence
+ * @state: is a a &GNUTLS_STATE structure.
+ * @max: is the maximum number.
+ *
+ * This function will set the maximum size of the handshake message sequence.
+ * Since the handshake messages are kept into memory until the handshake is successful
+ * this function allows you to set the maximum number of bytes that will be kept.
+ * The default value is 128kb which is large enough. Set this to 0 if you do not want
+ * to set an upper limit.
+ *
+ **/
+void gnutls_set_max_handshake_data_buffer_size( GNUTLS_STATE state, int max) {
+ state->gnutls_internals.max_handshake_data_buffer_size = max;
+}
diff --git a/lib/gnutls_handshake.h b/lib/gnutls_handshake.h
index 9acae2b3fb..be08e0a35e 100644
--- a/lib/gnutls_handshake.h
+++ b/lib/gnutls_handshake.h
@@ -34,6 +34,7 @@ void _gnutls_set_server_random( GNUTLS_STATE state, uint8* random);
void _gnutls_set_client_random( GNUTLS_STATE state, uint8* random);
int _gnutls_create_random( opaque* dst);
int _gnutls_remove_unwanted_ciphersuites( GNUTLS_STATE state, GNUTLS_CipherSuite ** cipherSuites, int numCipherSuites);
+void gnutls_set_max_handshake_data_buffer_size( GNUTLS_STATE state, int max);
#define set_adv_version( state, major, minor) \
state->gnutls_internals.adv_version_major = data[pos]; \
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index b3c534ab95..f7fd11e351 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -41,6 +41,11 @@
#define MAX24 16777215
#define MAX16 65535
+/* The sequence of handshake messages should not
+ * be larger than this value.
+ */
+#define MAX_HANDSHAKE_DATA_BUFFER_SIZE 128*1024
+
#define TLS_RANDOM_SIZE 32
#define TLS_MAX_SESSION_ID_SIZE 32
#define TLS_MASTER_SIZE 48
@@ -376,6 +381,7 @@ typedef struct {
*/
int (*x509_client_cert_callback)(void*,void*,int, void*, int);
gnutls_cert peer_cert;
+ int max_handshake_data_buffer_size;
} GNUTLS_INTERNALS;
struct GNUTLS_STATE_INT {
diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c
index b1582e4a30..fd5f1688af 100644
--- a/lib/gnutls_record.c
+++ b/lib/gnutls_record.c
@@ -103,6 +103,8 @@ int gnutls_init(GNUTLS_STATE * state, ConnectionEnd con_end)
gnutls_set_lowat((*state), DEFAULT_LOWAT); /* the default for tcp */
+ gnutls_set_max_handshake_data_buffer_size( (*state), MAX_HANDSHAKE_DATA_BUFFER_SIZE);
+
/* everything else not initialized here is initialized
* as NULL or 0. This is why calloc is used.
*/
diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c
index 9a7ee522d0..fbd51b3600 100644
--- a/lib/gnutls_sig.c
+++ b/lib/gnutls_sig.c
@@ -39,7 +39,7 @@
/* Generates a signature of all the previous sended packets in the
* handshake procedure.
*/
-int _gnutls_generate_sig_from_hdata( GNUTLS_STATE state, gnutls_private_key *pkey, gnutls_datum *signature) {
+int _gnutls_generate_sig_from_hdata( GNUTLS_STATE state, gnutls_cert* cert, gnutls_private_key *pkey, gnutls_datum *signature) {
gnutls_datum data;
int size = gnutls_getHashDataBufferSize( state);
int ret;
@@ -53,7 +53,7 @@ int ret;
gnutls_readHashDataFromBuffer( state, data.data, data.size);
- ret = _gnutls_pkcs1_rsa_generate_sig( pkey, &data, signature);
+ ret = _gnutls_pkcs1_rsa_generate_sig( cert, pkey, &data, signature);
gnutls_free_datum( &data);
if (ret < 0) {
gnutls_assert();
@@ -67,7 +67,7 @@ int ret;
/* Generates a signature of all the random data and the parameters.
* Used in DHE_* ciphersuites.
*/
-int _gnutls_generate_sig_params( GNUTLS_STATE state, gnutls_private_key *pkey, gnutls_datum* params, gnutls_datum *signature)
+int _gnutls_generate_sig_params( GNUTLS_STATE state, gnutls_cert* cert, gnutls_private_key *pkey, gnutls_datum* params, gnutls_datum *signature)
{
gnutls_datum sdata;
int size = 2*TLS_RANDOM_SIZE;
@@ -84,7 +84,7 @@ int _gnutls_generate_sig_params( GNUTLS_STATE state, gnutls_private_key *pkey, g
memcpy( &sdata.data[TLS_RANDOM_SIZE], state->security_parameters.server_random, TLS_RANDOM_SIZE);
memcpy( &sdata.data[2*TLS_RANDOM_SIZE], params->data, params->size);
- ret = _gnutls_pkcs1_rsa_generate_sig( pkey, &sdata, signature);
+ ret = _gnutls_pkcs1_rsa_generate_sig( cert, pkey, &sdata, signature);
gnutls_free_datum( &sdata);
if (ret < 0) {
@@ -98,14 +98,26 @@ int _gnutls_generate_sig_params( GNUTLS_STATE state, gnutls_private_key *pkey, g
/* This will create a PKCS1 signature, as defined in the TLS protocol.
+ * Cert is the certificate of the corresponding private key. It is only checked if
+ * it supports signing.
*/
-int _gnutls_pkcs1_rsa_generate_sig( gnutls_private_key *pkey, const gnutls_datum *data, gnutls_datum *signature)
+int _gnutls_pkcs1_rsa_generate_sig( gnutls_cert* cert, gnutls_private_key *pkey, const gnutls_datum *data, gnutls_datum *signature)
{
int ret;
opaque digest[20+16];
gnutls_datum tmpdata;
GNUTLS_HASH_HANDLE td;
+ /* If our certificate supports signing
+ */
+
+ if ( cert != NULL)
+ if ( cert->keyUsage != 0)
+ if ( !(cert->keyUsage & X509KEY_DIGITAL_SIGNATURE)) {
+ gnutls_assert();
+ return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
+ }
+
switch(pkey->pk_algorithm) {
case GNUTLS_PK_RSA:
@@ -152,6 +164,22 @@ int _gnutls_pkcs1_rsa_verify_sig( gnutls_cert *cert, const gnutls_datum *data, g
opaque digest[20+16];
GNUTLS_HASH_HANDLE td;
+ if (cert->version == 0 || cert==NULL) { /* this is the only way to check
+ * if it is initialized
+ */
+ gnutls_assert();
+ return GNUTLS_E_X509_CERTIFICATE_ERROR;
+ }
+
+ /* If the certificate supports signing continue.
+ */
+ if ( cert != NULL)
+ if ( cert->keyUsage != 0)
+ if ( !(cert->keyUsage & X509KEY_DIGITAL_SIGNATURE)) {
+ gnutls_assert();
+ return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
+ }
+
switch(cert->subject_pk_algorithm) {
case GNUTLS_PK_RSA:
diff --git a/lib/gnutls_sig.h b/lib/gnutls_sig.h
index bb311c60d3..447908284c 100644
--- a/lib/gnutls_sig.h
+++ b/lib/gnutls_sig.h
@@ -3,9 +3,9 @@
# include <auth_x509.h>
CertificateStatus gnutls_x509_verify_signature(gnutls_cert* cert, gnutls_cert* issuer);
-int _gnutls_pkcs1_rsa_generate_sig( gnutls_private_key *pkey, const gnutls_datum *data, gnutls_datum *signature);
-int _gnutls_generate_sig_from_hdata( GNUTLS_STATE state, gnutls_private_key *pkey, gnutls_datum *signature);
-int _gnutls_generate_sig_params( GNUTLS_STATE state, gnutls_private_key *pkey, gnutls_datum* params, gnutls_datum *signature);
+int _gnutls_pkcs1_rsa_generate_sig( gnutls_cert*, gnutls_private_key *pkey, const gnutls_datum *data, gnutls_datum *signature);
+int _gnutls_generate_sig_from_hdata( GNUTLS_STATE state, gnutls_cert* cert, gnutls_private_key *pkey, gnutls_datum *signature);
+int _gnutls_generate_sig_params( GNUTLS_STATE state, gnutls_cert* cert, gnutls_private_key *pkey, gnutls_datum* params, gnutls_datum *signature);
int _gnutls_verify_sig_hdata( GNUTLS_STATE state, gnutls_cert *cert, gnutls_datum* signature, int ubuffer_size);
int _gnutls_verify_sig_params( GNUTLS_STATE state, gnutls_cert *cert, const gnutls_datum* params, gnutls_datum* signature);