diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-10-08 19:57:53 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-10-08 19:57:53 +0000 |
commit | 3870e0504d069303681383a0ffdf9f37162fbdab (patch) | |
tree | 1dd6ee66cc014be30b8bb1293aa2b6619dc2a35c | |
parent | c19ecf6df45152d18c79244e33bfd3bf5299c2f0 (diff) | |
download | gnutls-3870e0504d069303681383a0ffdf9f37162fbdab.tar.gz |
several cleanups
-rw-r--r-- | lib/auth_dhe_rsa.c | 21 | ||||
-rw-r--r-- | lib/auth_x509.c | 44 | ||||
-rw-r--r-- | lib/gnutls.h.in | 2 | ||||
-rw-r--r-- | lib/gnutls_buffers.c | 5 | ||||
-rw-r--r-- | lib/gnutls_cert.c | 11 | ||||
-rw-r--r-- | lib/gnutls_cert.h | 1 | ||||
-rw-r--r-- | lib/gnutls_handshake.c | 16 | ||||
-rw-r--r-- | lib/gnutls_handshake.h | 1 | ||||
-rw-r--r-- | lib/gnutls_int.h | 6 | ||||
-rw-r--r-- | lib/gnutls_record.c | 2 | ||||
-rw-r--r-- | lib/gnutls_sig.c | 38 | ||||
-rw-r--r-- | lib/gnutls_sig.h | 6 |
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); |