From: Nikos Mavrogiannopoulos Date: Mon, 8 Oct 2001 19:57:53 +0000 (+0000) Subject: several cleanups X-Git-Tag: gnutls_0_2_4~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3870e0504d069303681383a0ffdf9f37162fbdab;p=thirdparty%2Fgnutls.git several cleanups --- 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;xgnutls_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 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);