summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-08-07 07:30:53 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-08-07 07:30:53 +0000
commitedb7b3a0c735885e85bcde45e9f0a4d441382b46 (patch)
tree484578091a9cfadee62277acefe5e8e4379931fb
parentdbf6c9afc21a9e22dc660f4686b8348a489d3e0e (diff)
downloadgnutls-edb7b3a0c735885e85bcde45e9f0a4d441382b46.tar.gz
ssl3 fixes and several others.
-rw-r--r--lib/auth_rsa.c22
-rw-r--r--lib/gnutls_buffers.c1
-rw-r--r--lib/gnutls_cipher.c16
-rw-r--r--lib/gnutls_constate.c2
-rw-r--r--lib/gnutls_errors.c1
-rw-r--r--lib/gnutls_errors_int.h1
-rw-r--r--lib/gnutls_handshake.c13
-rw-r--r--lib/gnutls_int.h3
-rw-r--r--lib/gnutls_kx.c2
-rw-r--r--lib/gnutls_pk.c30
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++;