From: Nikos Mavrogiannopoulos Date: Wed, 1 Nov 2000 22:47:17 +0000 (+0000) Subject: Some more fixes and additions in order to interoperate with openssl X-Git-Tag: gnutls0-0-4~29 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=43972b9a13a4af13afbca080dcaf4fe31727bd43;p=thirdparty%2Fgnutls.git Some more fixes and additions in order to interoperate with openssl --- diff --git a/lib/Makefile.am b/lib/Makefile.am index 7b13218908..4e4e92a1c5 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -9,4 +9,4 @@ libgnutls_la_SOURCES = gnutls.c gnutls_compress.c debug.c gnutls_plaintext.c \ gnutls_cipher.c gnutls_buffers.c gnutls_handshake.c gnutls_num.c \ gnutls_errors.c gnutls_algorithms.c gnutls_dh.c gnutls_kx.c \ gnutls_priority.c gnutls_hash_int.c gnutls_cipher_int.c gnutls_der.c -libgnutls_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) +libgnutls_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) -ldmalloc diff --git a/lib/gnutls_algorithms.c b/lib/gnutls_algorithms.c index c97ada1db3..8b19372878 100644 --- a/lib/gnutls_algorithms.c +++ b/lib/gnutls_algorithms.c @@ -98,7 +98,7 @@ static gnutls_kx_algo_entry kx_algorithms[] = { GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_ANON_DH, 0, 1, 0, 0, 1, -1), GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_RSA, 1, 0, 1, 1, 0, -2), GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DHE_DSS, 1, 1, 1, 0, 0, -1), - GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DHE_RSA, 1, 1, 1, 0, 0, -2), + GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DHE_RSA, 1, 1, 1, 0, 0, -1), GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_DSS, 1, 0, 1, 0, 0, -2), GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_RSA, 1, 0, 1, 0, 0, -2), {0} @@ -363,6 +363,11 @@ void _gnutls_kx_set_priority(KXAlgorithm algorithm, int prio) GNUTLS_KX_ALG_LOOP(if (p->priority >= -1) p->priority=prio); } +void _gnutls_prio() +{ + GNUTLS_KX_LOOP(fprintf(stderr, "prio: %s/%d\n",p->name, p->priority)); +} + int _gnutls_kx_priority(KXAlgorithm algorithm) { @@ -604,7 +609,7 @@ static int _gnutls_compare_kx_algo(const void* i_A1, const void* i_A2) int _gnutls_supported_ciphersuites(GNUTLS_CipherSuite ** ciphers) { - int i, ret_count; + int i, ret_count, j=0; int count = _gnutls_cipher_suite_count(); GNUTLS_CipherSuite *tmp_ciphers; @@ -634,14 +639,17 @@ int _gnutls_supported_ciphersuites(GNUTLS_CipherSuite ** ciphers) qsort(tmp_ciphers, count, sizeof(GNUTLS_CipherSuite), _gnutls_compare_kx_algo); for (i = 0; i < count; i++) { - if (_gnutls_kx_priority( _gnutls_cipher_suite_get_kx_algo(tmp_ciphers[i])) < 0) break; - if (_gnutls_mac_priority( _gnutls_cipher_suite_get_mac_algo(tmp_ciphers[i])) < 0) break; - if (_gnutls_cipher_priority( _gnutls_cipher_suite_get_cipher_algo(tmp_ciphers[i])) < 0) break; - (*ciphers)[i].CipherSuite[0] = tmp_ciphers[i].CipherSuite[0]; - (*ciphers)[i].CipherSuite[1] = tmp_ciphers[i].CipherSuite[1]; + if (_gnutls_kx_priority( _gnutls_cipher_suite_get_kx_algo(tmp_ciphers[i])) < 0) continue; + if (_gnutls_mac_priority( _gnutls_cipher_suite_get_mac_algo(tmp_ciphers[i])) < 0) continue; + if (_gnutls_cipher_priority( _gnutls_cipher_suite_get_cipher_algo(tmp_ciphers[i])) < 0) continue; + + (*ciphers)[j].CipherSuite[0] = tmp_ciphers[i].CipherSuite[0]; + (*ciphers)[j].CipherSuite[1] = tmp_ciphers[i].CipherSuite[1]; +/* fprintf(stderr, "%d: %s\n", j, _gnutls_cipher_suite_get_name((*ciphers)[j])); */ + j++; } - ret_count=i; + ret_count=j; if (ret_count > 0 && ret_count != count) { *ciphers = gnutls_realloc(*ciphers, ret_count * sizeof(GNUTLS_CipherSuite)); diff --git a/lib/gnutls_dh.c b/lib/gnutls_dh.c index 534332e0ab..208b887229 100644 --- a/lib/gnutls_dh.c +++ b/lib/gnutls_dh.c @@ -2,6 +2,7 @@ * Copyright (C) 2000 Nikos Mavroyanopoulos * * This file is part of GNUTLS. + * someday was part of gsti * * GNUTLS is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,6 +21,9 @@ #include #include +#include + +#include /* Taken from gsti */ @@ -53,8 +57,10 @@ static const uint8 diffie_hellman_group1_prime[130] = { 0x04, 0x00, gnutls_mpi_release(g); */ -#define E_SIZE 1024 -#define X_SIZE 200 +/* #define E_SIZE 1024 */ +#define X_SIZE 512 + +#define gcry_mpi_alloc_like(x) gcry_mpi_new(gcry_mpi_get_nbits(x)) /**************** * Choose a random value x and calculate e = g^x mod p. @@ -66,7 +72,7 @@ MPI gnutls_calc_dh_secret(MPI * ret_x) MPI e, g, x, prime; size_t n = sizeof diffie_hellman_group1_prime; - if (gcry_mpi_scan(&prime, GCRYMPI_FMT_STD, + if (gcry_mpi_scan(&prime, GCRYMPI_FMT_USG, diffie_hellman_group1_prime, &n)) abort(); /*dump_mpi(stderr, "prime=", prime ); */ @@ -76,7 +82,10 @@ MPI gnutls_calc_dh_secret(MPI * ret_x) gcry_mpi_randomize(x, X_SIZE, GCRY_STRONG_RANDOM); /* fixme: set high bit of x and select a larger one */ - e = mpi_new(E_SIZE); +/* e = mpi_new(E_SIZE); */ + e = gcry_mpi_alloc_like(prime); + /* e = g^x mod prime */ + mpi_powm(e, g, x, prime); if (ret_x) @@ -96,7 +105,8 @@ MPI _gnutls_calc_dh_secret(MPI * ret_x, MPI g, MPI prime) gcry_mpi_randomize(x, X_SIZE, GCRY_STRONG_RANDOM); /* fixme: set high bit of x and select a larger one */ - e = mpi_new(E_SIZE); + e = gcry_mpi_alloc_like(prime); +/* e = mpi_new(E_SIZE); */ mpi_powm(e, g, x, prime); if (ret_x) @@ -112,7 +122,7 @@ MPI gnutls_get_dh_params(MPI * ret_p) MPI g, prime; size_t n = sizeof diffie_hellman_group1_prime; - if (gcry_mpi_scan(&prime, GCRYMPI_FMT_STD, + if (gcry_mpi_scan(&prime, GCRYMPI_FMT_USG, diffie_hellman_group1_prime, &n)) abort(); @@ -131,12 +141,15 @@ MPI gnutls_calc_dh_key(MPI f, MPI x) MPI k, prime; size_t n = sizeof diffie_hellman_group1_prime; - k = mpi_new(E_SIZE); /* FIXME: allocate in secure memory */ - if (gcry_mpi_scan(&prime, GCRYMPI_FMT_STD, - diffie_hellman_group1_prime, &n)) + if (gcry_mpi_scan(&prime, GCRYMPI_FMT_USG, + diffie_hellman_group1_prime, &n)) { + gnutls_assert(); abort(); + } /*dump_mpi(stderr, "prime=", prime ); */ + k = gcry_mpi_alloc_like(prime); +/* k = mpi_new(E_SIZE); FIXME: allocate in secure memory */ mpi_powm(k, f, x, prime); mpi_release(prime); return k; @@ -146,8 +159,8 @@ MPI _gnutls_calc_dh_key(MPI f, MPI x, MPI prime) { MPI k; - k = mpi_new(E_SIZE); /* FIXME: allocate in secure memory */ - +/* k = mpi_new(E_SIZE); FIXME: allocate in secure memory */ + k = gcry_mpi_alloc_like(prime); mpi_powm(k, f, x, prime); return k; } diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c index 3955b9d279..7ceec431ab 100644 --- a/lib/gnutls_errors.c +++ b/lib/gnutls_errors.c @@ -56,6 +56,7 @@ static gnutls_error_entry error_algorithms[] = { GNUTLS_ERROR_ENTRY( GNUTLS_E_ERROR_IN_FINISHED_PACKET, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_KX_ALGORITHM, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_MPI_SCAN_FAILED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNIMPLEMENTED_FEATURE, 1), {0} }; diff --git a/lib/gnutls_errors.h b/lib/gnutls_errors.h index be1d46301d..eac021ee6a 100644 --- a/lib/gnutls_errors.h +++ b/lib/gnutls_errors.h @@ -22,6 +22,7 @@ #define GNUTLS_E_UNKNOWN_KX_ALGORITHM -20 #define GNUTLS_E_UNKNOWN_CIPHER_SUITE -21 #define GNUTLS_E_UNWANTED_ALGORITHM -22 +#define GNUTLS_E_MPI_SCAN_FAILED -23 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -50 diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index 18ff569588..6d6f31e263 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -831,6 +831,15 @@ int gnutls_handshake(int cd, GNUTLS_STATE state) return ret; } + HASH(client_hash); + HASH(server_hash); + ret = _gnutls_send_client_certificate_verify( cd, state); + NOT_HASH(client_hash); + NOT_HASH(server_hash); + if (ret < 0) { + ERR("send client certificate verify", ret); + return ret; + } /* Send the CHANGE CIPHER SPEC PACKET */ ret = _gnutls_send_change_cipher_spec(cd, state); diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c index db2fa89632..912e33d4fc 100644 --- a/lib/gnutls_kx.c +++ b/lib/gnutls_kx.c @@ -63,12 +63,12 @@ int _gnutls_send_server_kx_message(int cd, GNUTLS_STATE state) X = gnutls_calc_dh_secret(&x); state->gnutls_internals.dh_secret = x; g = gnutls_get_dh_params(&p); - gcry_mpi_print(GCRYMPI_FMT_STD, NULL, &n_g, g); - gcry_mpi_print(GCRYMPI_FMT_STD, NULL, &n_p, p); - gcry_mpi_print(GCRYMPI_FMT_STD, NULL, &n_X, X); + gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_g, g); + gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_p, p); + gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_X, X); data = gnutls_malloc(n_g + n_p + n_X + 6); data_p = &data[0]; - gcry_mpi_print(GCRYMPI_FMT_STD, &data_p[2], + gcry_mpi_print(GCRYMPI_FMT_USG, &data_p[2], &n_p, p); gnutls_mpi_release(p); _n_p = n_p; @@ -79,7 +79,7 @@ int _gnutls_send_server_kx_message(int cd, GNUTLS_STATE state) memmove(data_p, &_n_p, 2); #endif data_g = &data_p[2 + n_p]; - gcry_mpi_print(GCRYMPI_FMT_STD, &data_g[2], + gcry_mpi_print(GCRYMPI_FMT_USG, &data_g[2], &n_g, g); gnutls_mpi_release(g); _n_g = n_g; @@ -90,7 +90,7 @@ int _gnutls_send_server_kx_message(int cd, GNUTLS_STATE state) memmove(data_g, &_n_g, 2); #endif data_X = &data_g[2 + n_g]; - gcry_mpi_print(GCRYMPI_FMT_STD, &data_X[2], + gcry_mpi_print(GCRYMPI_FMT_USG, &data_X[2], &n_X, X); gnutls_mpi_release(X); _n_X = n_X; @@ -150,21 +150,22 @@ int _gnutls_send_client_kx_message(int cd, GNUTLS_STATE state) gnutls_internals.client_g, state-> gnutls_internals.client_p); - gcry_mpi_print(GCRYMPI_FMT_STD, NULL, &n_X, X); - data = gnutls_malloc(n_X + 3); - gcry_mpi_print(GCRYMPI_FMT_STD, &data[3], &n_X, X); - data[0] = 1; /* extern */ + gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_X, X); + data = gnutls_malloc(n_X + 2); + gcry_mpi_print(GCRYMPI_FMT_USG, &data[2], &n_X, X); + data[0] = 1; /* extern - explicit since we do not have + certificate */ gnutls_mpi_release(X); _n_X = n_X; #ifndef WORDS_BIGENDIAN _n_X = byteswap16(_n_X); - memmove(&data[1], &_n_X, 2); + memmove(&data[0], &_n_X, 2); #else - memmove(&data[1], &_n_X, 2); + memmove(&data[0], &_n_X, 2); #endif ret = _gnutls_send_handshake(cd, state, data, - n_X + 3, + n_X + 2, GNUTLS_CLIENT_KEY_EXCHANGE); gnutls_free(data); /* calculate the key after sending the message */ @@ -172,10 +173,10 @@ int _gnutls_send_client_kx_message(int cd, GNUTLS_STATE state) _gnutls_calc_dh_key(state->gnutls_internals.client_Y, x, state->gnutls_internals.client_p); - gcry_mpi_print(GCRYMPI_FMT_STD, NULL, &premaster_size, + gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &premaster_size, state->gnutls_internals.KEY); premaster = secure_malloc(premaster_size); - gcry_mpi_print(GCRYMPI_FMT_STD, premaster, + gcry_mpi_print(GCRYMPI_FMT_USG, premaster, &premaster_size, state->gnutls_internals.KEY); /* THIS SHOULD BE DISCARDED */ @@ -208,6 +209,42 @@ int _gnutls_send_client_kx_message(int cd, GNUTLS_STATE state) } +/* This is the function for the client to send the certificate + * verify message + */ +int _gnutls_send_client_certificate_verify(int cd, GNUTLS_STATE state) +{ + uint8 *data; + int ret = 0; +#ifdef HARD_DEBUG + fprintf(stderr, "Sending client certificate verify message\n"); +#endif + switch (_gnutls_cipher_suite_get_kx_algo + (state->gnutls_internals.current_cipher_suite)) { + case GNUTLS_KX_DHE_DSS: + data=gnutls_malloc(20); + ret = + _gnutls_send_handshake(cd, state, data, + 20, + GNUTLS_CERTIFICATE_VERIFY); + gnutls_free(data); + break; + case GNUTLS_KX_DHE_RSA: + data=gnutls_malloc(20+16); + ret = + _gnutls_send_handshake(cd, state, data, + 20+16, + GNUTLS_CERTIFICATE_VERIFY); + gnutls_free(data); + break; + default: + ret = 0; + } + + return ret; +} + + int _gnutls_recv_server_kx_message(int cd, GNUTLS_STATE state) { KXAlgorithm algorithm; @@ -226,6 +263,7 @@ int _gnutls_recv_server_kx_message(int cd, GNUTLS_STATE state) _gnutls_cipher_suite_get_kx_algo (state->gnutls_internals.current_cipher_suite); /* Do key exchange only if the algorithm permits it */ + if (_gnutls_kx_server_key_exchange(algorithm) != 0) { switch (_gnutls_cipher_suite_get_kx_algo @@ -239,12 +277,14 @@ int _gnutls_recv_server_kx_message(int cd, GNUTLS_STATE state) GNUTLS_SERVER_KEY_EXCHANGE); if (ret < 0) return ret; + i = 0; memmove(&n_p, &data[i], 2); i += 2; #ifndef WORDS_BIGENDIAN n_p = byteswap16(n_p); #endif + data_p = &data[i]; i += n_p; if (i > datasize) { @@ -267,6 +307,7 @@ int _gnutls_recv_server_kx_message(int cd, GNUTLS_STATE state) #ifndef WORDS_BIGENDIAN n_Y = byteswap16(n_Y); #endif + data_Y = &data[i]; i += n_Y; if (i > datasize) { @@ -276,12 +317,24 @@ int _gnutls_recv_server_kx_message(int cd, GNUTLS_STATE state) _n_Y = n_Y; _n_g = n_g; _n_p = n_p; - gcry_mpi_scan(&state->gnutls_internals.client_Y, - GCRYMPI_FMT_STD, data_Y, &_n_Y); - gcry_mpi_scan(&state->gnutls_internals.client_g, - GCRYMPI_FMT_STD, data_g, &_n_g); - gcry_mpi_scan(&state->gnutls_internals.client_p, - GCRYMPI_FMT_STD, data_p, &_n_p); + + if (gcry_mpi_scan(&state->gnutls_internals.client_Y, + GCRYMPI_FMT_USG, data_Y, &_n_Y) != 0) { + gnutls_assert(); + return GNUTLS_E_MPI_SCAN_FAILED; + } + if (gcry_mpi_scan(&state->gnutls_internals.client_g, + GCRYMPI_FMT_USG, data_g, &_n_g) != 0) { + gnutls_assert(); + return GNUTLS_E_MPI_SCAN_FAILED; + } + if (gcry_mpi_scan(&state->gnutls_internals.client_p, + GCRYMPI_FMT_USG, data_p, &_n_p) != 0) { + gnutls_assert(); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + /* FIXME: We need to check signature in non-anonymous KX */ gnutls_free(data); break; default: @@ -337,17 +390,17 @@ int _gnutls_recv_client_kx_message(int cd, GNUTLS_STATE state) #endif _n_Y = n_Y; gcry_mpi_scan(&state->gnutls_internals.client_Y, - GCRYMPI_FMT_STD, &data[3], &_n_Y); + GCRYMPI_FMT_USG, &data[3], &_n_Y); state->gnutls_internals.KEY = gnutls_calc_dh_key(state-> gnutls_internals.client_Y, state-> gnutls_internals.dh_secret); - gcry_mpi_print(GCRYMPI_FMT_STD, NULL, + gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &premaster_size, state->gnutls_internals.KEY); premaster = secure_malloc(premaster_size); - gcry_mpi_print(GCRYMPI_FMT_STD, premaster, + gcry_mpi_print(GCRYMPI_FMT_USG, premaster, &premaster_size, state->gnutls_internals.KEY); /* THESE SHOULD BE DISCARDED */ diff --git a/lib/gnutls_kx.h b/lib/gnutls_kx.h index 0b583a207f..f2d4011de5 100644 --- a/lib/gnutls_kx.h +++ b/lib/gnutls_kx.h @@ -2,3 +2,4 @@ int _gnutls_send_server_kx_message(int cd, GNUTLS_STATE state); int _gnutls_send_client_kx_message(int cd, GNUTLS_STATE state); int _gnutls_recv_server_kx_message(int cd, GNUTLS_STATE state); int _gnutls_recv_client_kx_message(int cd, GNUTLS_STATE state); +int _gnutls_send_client_certificate_verify(int cd, GNUTLS_STATE state); diff --git a/src/cli.c b/src/cli.c index e32369be01..bfa15c80cd 100644 --- a/src/cli.c +++ b/src/cli.c @@ -56,15 +56,16 @@ int main() ERR(err, "connect"); gnutls_init(&state, GNUTLS_CLIENT); - gnutls_set_cipher_priority( 1, GNUTLS_3DES); - gnutls_set_kx_priority( 1, GNUTLS_KX_ANON_DH); + gnutls_set_cipher_priority( 2, GNUTLS_3DES, GNUTLS_ARCFOUR); +// gnutls_set_kx_priority( 1, GNUTLS_KX_ANON_DH); + gnutls_set_kx_priority( 3, GNUTLS_KX_ANON_DH, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA); gnutls_set_mac_priority(2, GNUTLS_MAC_SHA, GNUTLS_MAC_MD5); - ret = gnutls_handshake(sd, state); if (ret < 0) { fprintf(stderr, "Handshake has failed\n"); gnutls_perror(ret); + gnutls_deinit(&state); return 1; } else { fprintf(stderr, "Handshake was completed\n\n"); diff --git a/src/port.h b/src/port.h index 4ec8d46680..85a03107bf 100644 --- a/src/port.h +++ b/src/port.h @@ -1 +1 @@ -#define PORT 2222 +#define PORT 5555