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
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}
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)
{
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;
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));
* 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
#include <defines.h>
#include <gnutls_int.h>
+#include <gnutls_errors.h>
+
+#include <dmalloc.h>
/* Taken from gsti */
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.
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 ); */
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)
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)
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();
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;
{
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;
}
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}
};
#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
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);
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;
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;
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;
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 */
_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 */
}
+/* 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;
_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
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) {
#ifndef WORDS_BIGENDIAN
n_Y = byteswap16(n_Y);
#endif
+
data_Y = &data[i];
i += n_Y;
if (i > datasize) {
_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:
#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 */
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);
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");
-#define PORT 2222
+#define PORT 5555