diff options
-rw-r--r-- | lib/auth_rsa.c | 22 | ||||
-rw-r--r-- | lib/gnutls_buffers.c | 1 | ||||
-rw-r--r-- | lib/gnutls_cipher.c | 16 | ||||
-rw-r--r-- | lib/gnutls_constate.c | 2 | ||||
-rw-r--r-- | lib/gnutls_errors.c | 1 | ||||
-rw-r--r-- | lib/gnutls_errors_int.h | 1 | ||||
-rw-r--r-- | lib/gnutls_handshake.c | 13 | ||||
-rw-r--r-- | lib/gnutls_int.h | 3 | ||||
-rw-r--r-- | lib/gnutls_kx.c | 2 | ||||
-rw-r--r-- | lib/gnutls_pk.c | 30 |
10 files changed, 57 insertions, 34 deletions
diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c index c21e8ad3f6..69e6e4689f 100644 --- a/lib/auth_rsa.c +++ b/lib/auth_rsa.c @@ -298,15 +298,21 @@ int proc_rsa_client_kx(GNUTLS_STATE state, opaque * data, int data_size) gnutls_datum ciphertext; int ret, dsize; - if (_gnutls_version_ssl3(gnutls_get_current_version(state)) == 0) { + if ( gnutls_get_current_version(state) == GNUTLS_SSL3) { /* SSL 3.0 */ ciphertext.data = data; ciphertext.size = data_size; } else { /* TLS 1 */ ciphertext.data = &data[2]; dsize = READuint16(data); - ciphertext.size = GMIN(dsize, data_size); + + if (dsize != data_size - 2) { + gnutls_assert(); + return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; + } + ciphertext.size = dsize; } + ret = _gnutls_pkcs1_rsa_decrypt(&plaintext, ciphertext, state->gnutls_key->u, state->gnutls_key->A, 2); /* btype==2 */ @@ -316,17 +322,21 @@ int proc_rsa_client_kx(GNUTLS_STATE state, opaque * data, int data_size) * the peer. Just use a random key. (in order to avoid * attack against pkcs-1 formating). */ +return ret; gnutls_assert(); +#ifdef DEBUG + _gnutls_log( "Possible PKCS-1 format attack\n"); +#endif RANDOMIZE_KEY(state->gnutls_key->key, secure_malloc); } else { ret = 0; if (plaintext.size != TLS_MASTER_SIZE) { /* WOW */ RANDOMIZE_KEY(state->gnutls_key->key, secure_malloc); } else { - if (_gnutls_get_adv_version_major( state) != plaintext.data[0]) - ret = GNUTLS_E_DECRYPTION_FAILED; - if (_gnutls_get_adv_version_minor( state) != plaintext.data[1]) + if (_gnutls_get_adv_version_major( state) != plaintext.data[0] || _gnutls_get_adv_version_minor( state) != plaintext.data[1]) { + gnutls_assert(); ret = GNUTLS_E_DECRYPTION_FAILED; + } if (ret != 0) { _gnutls_mpi_release(&state->gnutls_key->B); _gnutls_mpi_release(&state->gnutls_key->u); @@ -495,7 +505,7 @@ int gen_rsa_client_kx(GNUTLS_STATE state, opaque ** data) _gnutls_mpi_release(&state->gnutls_key->a); _gnutls_mpi_release(&state->gnutls_key->x); - if (_gnutls_version_ssl3(ver) == 0) { + if ( ver == GNUTLS_SSL3) { /* SSL 3.0 */ *data = sdata.data; return sdata.size; diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c index fcc7d82582..2b1a22f4fc 100644 --- a/lib/gnutls_buffers.c +++ b/lib/gnutls_buffers.c @@ -257,7 +257,6 @@ ssize_t _gnutls_Recv_int(int fd, GNUTLS_STATE state, ContentType type, Handshake return (sizeOfPtr - left); } -#warning "FIX THIS FUNCTION - too many reallocs()" /* Buffer for handshake packets. Keeps the packets in order * for finished messages to use them. */ diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c index bce865a4bc..5ebd2496e9 100644 --- a/lib/gnutls_cipher.c +++ b/lib/gnutls_cipher.c @@ -126,7 +126,7 @@ int _gnutls_compressed2TLSCiphertext(GNUTLS_STATE state, minor = _gnutls_version_get_minor(state->connection_state.version); major = _gnutls_version_get_major(state->connection_state.version); - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { /* SSL 3.0 */ + if ( state->connection_state.version == GNUTLS_SSL3) { /* SSL 3.0 */ td = gnutls_mac_init_ssl3(state->security_parameters. write_mac_algorithm, @@ -134,7 +134,7 @@ int _gnutls_compressed2TLSCiphertext(GNUTLS_STATE state, write_mac_secret.data, state->connection_state. write_mac_secret.size); - } else { + } else { /* TLS 1 */ td = gnutls_hmac_init(state->security_parameters. write_mac_algorithm, @@ -157,13 +157,13 @@ int _gnutls_compressed2TLSCiphertext(GNUTLS_STATE state, gnutls_hmac(td, UINT64DATA(seq_num), 8); gnutls_hmac(td, &type, 1); - if (_gnutls_version_ssl3(state->connection_state.version) != 0) { /* TLS 1.0 only */ + if ( state->connection_state.version != GNUTLS_SSL3) { /* TLS 1.0 only */ gnutls_hmac(td, &major, 1); gnutls_hmac(td, &minor, 1); } gnutls_hmac(td, &c_length, 2); gnutls_hmac(td, compressed.data, compressed.size); - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { /* SSL 3.0 */ + if ( state->connection_state.version == GNUTLS_SSL3) { /* SSL 3.0 */ gnutls_mac_deinit_ssl3(td, MAC); } else { gnutls_hmac_deinit(td, MAC); @@ -195,7 +195,7 @@ int _gnutls_compressed2TLSCiphertext(GNUTLS_STATE state, } /* make rand a multiple of blocksize */ - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { + if ( state->connection_state.version == GNUTLS_SSL3) { rand = 0; } else { rand = (rand / blocksize) * blocksize; @@ -258,7 +258,7 @@ int _gnutls_ciphertext2TLSCompressed(GNUTLS_STATE state, blocksize = _gnutls_cipher_get_block_size(state->security_parameters. read_bulk_cipher_algorithm); - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { + if ( state->connection_state.version == GNUTLS_SSL3) { td = gnutls_mac_init_ssl3(state->security_parameters. read_mac_algorithm, @@ -342,13 +342,13 @@ int _gnutls_ciphertext2TLSCompressed(GNUTLS_STATE state, gnutls_hmac(td, UINT64DATA(seq_num), 8); gnutls_hmac(td, &type, 1); - if (_gnutls_version_ssl3(state->connection_state.version) != 0) { /* TLS 1.0 only */ + if ( state->connection_state.version != GNUTLS_SSL3) { /* TLS 1.0 only */ gnutls_hmac(td, &major, 1); gnutls_hmac(td, &minor, 1); } gnutls_hmac(td, &c_length, 2); gnutls_hmac(td, data, compress->size); - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { /* SSL 3.0 */ + if ( state->connection_state.version == GNUTLS_SSL3) { /* SSL 3.0 */ gnutls_mac_deinit_ssl3(td, MAC); } else { gnutls_hmac_deinit(td, MAC); diff --git a/lib/gnutls_constate.c b/lib/gnutls_constate.c index a510486c37..a2784e759b 100644 --- a/lib/gnutls_constate.c +++ b/lib/gnutls_constate.c @@ -53,7 +53,7 @@ int _gnutls_set_keys(GNUTLS_STATE state, int hash_size, int IV_size, int key_siz memcpy(random, state->security_parameters.server_random, TLS_RANDOM_SIZE); memcpy(&random[TLS_RANDOM_SIZE], state->security_parameters.client_random, TLS_RANDOM_SIZE); - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { /* SSL 3 */ + if ( state->connection_state.version == GNUTLS_SSL3) { /* SSL 3 */ key_block = gnutls_ssl3_generate_random( state->security_parameters.master_secret, TLS_MASTER_SIZE, random, 2*TLS_RANDOM_SIZE, block_size); } else { /* TLS 1.0 */ diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c index 77dc4465c1..6e2289bfa9 100644 --- a/lib/gnutls_errors.c +++ b/lib/gnutls_errors.c @@ -69,6 +69,7 @@ static gnutls_error_entry error_algorithms[] = { GNUTLS_ERROR_ENTRY( GNUTLS_E_UNIMPLEMENTED_FEATURE, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_INSUFICIENT_CRED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_PWD_ERROR, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_PKCS1_WRONG_PAD, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_EXPIRED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_HASH_FAILED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_PARSING_ERROR, 1), diff --git a/lib/gnutls_errors_int.h b/lib/gnutls_errors_int.h index 6c9c21cfa2..066ea2c839 100644 --- a/lib/gnutls_errors_int.h +++ b/lib/gnutls_errors_int.h @@ -49,5 +49,6 @@ #define GNUTLS_E_PK_SIGNATURE_FAILED -46 #define GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION -47 #define GNUTLS_E_X509_KEY_USAGE_VIOLATION -48 +#define GNUTLS_E_PKCS1_WRONG_PAD -48 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -250 diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index f763a08cf4..6cbf35a114 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -388,7 +388,7 @@ int _gnutls_send_finished(SOCKET cd, GNUTLS_STATE state) int ret; int data_size; - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { + if ( state->connection_state.version == GNUTLS_SSL3) { data = _gnutls_ssl3_finished(state, state->security_parameters. @@ -429,7 +429,7 @@ int _gnutls_recv_finished(SOCKET cd, GNUTLS_STATE state) gnutls_assert(); return ret; } - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { + if ( state->connection_state.version == GNUTLS_SSL3) { data_size = 36; } else { data_size = 12; @@ -439,7 +439,7 @@ 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) { + if ( state->connection_state.version == GNUTLS_SSL3) { /* skip the bytes from the last message */ data = _gnutls_ssl3_finished(state, @@ -1695,12 +1695,7 @@ int _gnutls_remove_unwanted_ciphersuites(GNUTLS_STATE state, int alg_size; KXAlgorithm kx; - /* FIXME: remove algorithms depending on the keyUsage bits - * eg. - * if (cert.keyUsage & X509KEY_DIGITAL_SIGNATURE) - * we've got a sign-only key... (ok we need to check - * it more than that). - */ +#warning "make this function work to the client side too" if (state->security_parameters.entity == GNUTLS_CLIENT) return 0; diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 073058294d..7fc8242ff5 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -366,9 +366,6 @@ ssize_t gnutls_send_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha 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); -#define _gnutls_version_cmp( ver1, ver2) ver1==ver2?0:1 -#define _gnutls_version_ssl3(x) _gnutls_version_cmp(x, GNUTLS_SSL3) - /* These macros return the advertized TLS version of * the peer. */ diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c index 079040fd7b..4e55b35f87 100644 --- a/lib/gnutls_kx.c +++ b/lib/gnutls_kx.c @@ -55,7 +55,7 @@ char random[2*TLS_RANDOM_SIZE]; _gnutls_log( "SERVER RANDOM[%d]: %s\n", 32, _gnutls_bin2hex(state->security_parameters.server_random,32)); #endif - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { + if ( state->connection_state.version == GNUTLS_SSL3) { master = gnutls_ssl3_generate_random( premaster, premaster_size, random, 2*TLS_RANDOM_SIZE, TLS_MASTER_SIZE); diff --git a/lib/gnutls_pk.c b/lib/gnutls_pk.c index 0d42dd4f8d..30ec57d75b 100644 --- a/lib/gnutls_pk.c +++ b/lib/gnutls_pk.c @@ -127,8 +127,8 @@ int _gnutls_pkcs1_rsa_encrypt(gnutls_datum * ciphertext, gnutls_datum plaintext, /* Do PKCS-1 RSA decryption. * pkey is the private key and n the modulus. + * Can decrypt block type 1 and type packets. */ - int _gnutls_pkcs1_rsa_decrypt(gnutls_sdatum * plaintext, gnutls_datum ciphertext, MPI pkey, MPI n, int btype) { @@ -176,6 +176,7 @@ int _gnutls_pkcs1_rsa_decrypt(gnutls_sdatum * plaintext, gnutls_datum ciphertext * (use block type 'btype') */ + edata[0] = 0; esize++; @@ -186,11 +187,30 @@ int _gnutls_pkcs1_rsa_decrypt(gnutls_sdatum * plaintext, gnutls_datum ciphertext } ret = GNUTLS_E_DECRYPTION_FAILED; - for (i=2;i<esize;i++) { - if (edata[i]==0) { - ret = 0; - break; + switch(btype) { + case 2: + for (i = 2; i < esize; i++) { + if (edata[i] == 0) { + ret = 0; + break; + } } + break; + case 1: + for (i = 2; i < esize; i++) { + if (edata[i] == 0 && i > 2) { + ret = 0; + break; + } + if (edata[i] != 0xff) { + ret = GNUTLS_E_PKCS1_WRONG_PAD; + break; + } + } + break; + default: + gnutls_assert(); + return GNUTLS_E_UNKNOWN_ERROR; } i++; |