Commit d462a169 authored by Niels Möller's avatar Niels Möller

Random hacking. connection objects should no longer be considered

write handlers, instead the read_packet-handler has a reference
directly to the connection object.

Session key generation halfway written.

Rev: src/client_keyexchange.c:1.3
Rev: src/client_keyexchange.h:1.2
Rev: src/connection.h:1.11
Rev: src/keyexchange.c:1.8
Rev: src/keyexchange.h:1.9
Rev: src/publickey_crypto.c:1.7
Rev: src/publickey_crypto.h:1.6
Rev: src/read_packet.c:1.8
Rev: src/read_packet.h:1.5
parent cb961e3a
......@@ -29,6 +29,8 @@ static void do_handle_dh_reply(struct packet_handler *c,
{
struct dh_client *closure = (struct dh_client *) c;
struct verifier *v;
struct hash_instance *hash;;
struct lsh_string *s;
if (!dh_process_server_msg(&closure->dh, packet))
return send_disconnect(connection, "Bad dh-reply\r\n");
......@@ -45,10 +47,24 @@ static void do_handle_dh_reply(struct packet_handler *c,
/* FIXME: Same here */
return send_disconnect(connection, "Bad server host key\r\n");
/* Key exchange successful! */
/* Key exchange successful! Send a newkeys message, and install a
* handler for recieving the newkeys message. */
/* Record session id */
if (!connection->session_id)
connection->session_id = closure->dh.exchange_hash;
/* A hash instance initialized with the key, to be used for key generation */
hash = MAKE_HASH(closure->dh->method->hash);
s = ssh_format("%n", closure->dh->K);
HASH_UPDATE(hash, s->length, s->data);
lsh_string_free(s);
res = prepare_keys(connection, hash);
lsh_free(hash);
return res;
}
static void do_init_dh(struct keyexchange_algorithm *c,
......@@ -62,8 +78,7 @@ static void do_init_dh(struct keyexchange_algorithm *c,
dh->super.handler = do_handle_dh_reply;
init_diffie_hellman_instance(closure->dh, &dh->dh, connection);
dh->hash = MAKE_HASH(closure->hash);
dh->signature_algorithm = closure->signature_algorithm;
dh->verifier = closure->verifier;
/* Send client's message */
A_WRITE(connection->write, dh_make_client_msg(&dh->dh));
......@@ -78,3 +93,22 @@ static void do_init_dh(struct keyexchange_algorithm *c,
return WRITE_OK;
}
int prepare_keys_client(struct hash_instance *secret,
struct ssh_connection *connection)
{
/* FIXME: For DES, instantiating a crypto may fail, if the key
* happens to be weak. */
/* FIXME: No IV:s */
struct crypto_instance *crypt_client_to_server
= kex_make_encrypt(secret, KEX_ENCRYPTION_CLIENT_TO_SERVER, connection);
struct crypto_instance *crypt_server_to_client
= kex_make_decrypt(secret, KEX_ENCRYPTION_SERVER_TO_CLIENT, connection);
struct mac_instance *mac_client_to_server
= kex_make_mac(secret, KEX_MAC_CLIENT_TO_SERVER, connection);
struct mac_instance *mac_server_to_client
= kex_make_mac(secret, KEX_MAC_SERVER_TO_CLIENT, connection);
......@@ -45,7 +45,6 @@ struct dh_algorithm_client
{
struct keyexchange_algorithm super;
struct diffie_hellman_method dh;
struct hash_algorithm *hash;
struct lookup_verifier *verifier;
};
......@@ -54,7 +53,6 @@ struct dh_client
{
struct packet_handler super;
struct diffie_hellman_instance dh;
struct hash_instance *hash;
struct lookup_verifier *verifier;
struct packet_handler *saved_kexinit_handler;
};
......
......@@ -29,7 +29,14 @@ struct packet_handler
struct ssh_connection
{
#if 0
struct abstract_write super;
struct read_packet *reader; /* Needed for changing the decryption
* algorithms. Is there a better way?
* Perhaps one can keep this pointer
* inside the newkeys-handler? */
#endif
int type; /* CONNECTION_SERVER or CONNECTION_CLIENT */
......@@ -38,6 +45,11 @@ struct ssh_connection
struct lsh_string *server_version;
struct lsh_string *session_id;
/* Reading */
struct mac_instance *mac;
struct crypto_instance *crypto;
struct abstract_write *raw; /* Socket connected to the other end */
struct abstract_write *write; /* Where to send packets through the
......@@ -54,11 +66,12 @@ struct ssh_connection
UINT32 max_packet;
/* Key exchange */
int kex_state;
/* int kex_state; */
/* First element is the kexinit sent by the server */
struct kexinit *kexinits[2];
struct lsh_string *literal_kexinits[2];
struct newkeys_info *newkeys; /* Negotiated algorithms */
int ignore_one_packet;
......
......@@ -268,6 +268,87 @@ static int do_handle_kexinit(struct packet_hander *c,
}
}
/* FIXME: THis function can't handle IV:s at all */
struct lsh_string *kex_make_key(struct hash_instance *secret,
UINT32 key_length,
int type,
strut lsh_string *session_id)
{
/* Indexed by the KEX_* values */
static const char *tags = "CDEF";
struct lsh_string *key;
struct hash_instance *hash;
UINT8 *digest;
key = lsh_string_alloc(key_length);
if (!key_length)
return key;
hash = HASH_COPY(secret);
digest = alloca(hash->digest_size);
HASH_UPDATE(hash, tags + type, 1);
HASH_UPDATE(hash, session_id->length, session_id->data);
HASH_DIGEST(hash, digest);
if (key_length < hash->digest_size)
fatal("Not implemmented\n");
memcpy(key->data, digest, key_length);
lsh_free(hash);
return key;
}
struct crypto_instance *kex_make_encrypt(struct hash_instance *secret,
struct crypto_algorithm *algorithm,
int type,
struct ssh_connection *connection)
{
struct lsh_string *key = kex_make_key(secret, algorithm->key_size,
type, connection->session_id);
/* FIXME: No IV. Note that for DES, instantiating the crypto can
* fail, if the key happens to be weak. */
struct crypto_instance *crypt
= MAKE_ENCRYPT(algorithm, key->data);
lsh_string_free(key);
return crypt;
}
struct crypto_instance *kex_make_decrypt(struct hash_instance *secret,
struct crypto_algorithm *algorithm,
int type,
struct ssh_connection *connection)
{
struct lsh_string *key = kex_make_key(secret, algorithm->key_size,
type, connection->session_id);
/* FIXME: No IV. Note that for DES, instantiating the crypto can
* fail, if the key happens to be weak. */
struct crypto_instance *crypt
= MAKE_DECRYPT(algorithm, key->data);
lsh_string_free(key);
return crypt;
}
struct mac_instance *kex_make_mac(struct hash_instance *secret,
struct mac_algorithm *algorithm,
int type,
struct ssh_connection *connection)
{
struct lsh_string *key = kex_make_key(secret, algorithm->key_size,
type, connection->session_id);
struct mac_instance *mac
= MAKE_MAC(algorithm, key->data);
lsh_string_free(key);
return mac;
}
static int do_handle_newkeys(struct packet_handler *c,
struct ssh_connection *connection,
struct lsh_string *packet)
......
......@@ -87,17 +87,19 @@ struct handle_keyexinit
struct alist *algorithms;
};
struct handle_newkeys
struct newkeys_info
{
struct packet_handler super;
/* Algorithms for transmission */
struct crypto_algorithm *crypto;
struct mac_algorithm *mac;
struct crypto_algorithm *encryption_client_to_server;
struct crypto_algorithm *encryption_server_to_client;
struct mac_algorithm *mac_client_to_server;
struct mac_algorithm *mac_server_to_client;
#if 0
struct compression_algorithm *compressor;
struct compression_algorithm *compression_client_to_server;
struct compression_algorithm *compression_server_to_client;
#endif
};
struct packet_handler *make_kexinit_handler();
struct packet_handler *make_newkeys_handler();
......
......@@ -400,6 +400,8 @@ void init_diffie_hellman_instance(struct diffie_hellman_method *m,
self->method = m;
self->hash = MAKE_HASH(m->H);
self->exchange_hash = NULL;
HASH_UPDATE(self->hash,
c->client_version->length,
c->client_version->data);
......@@ -524,17 +526,20 @@ void dh_hash_digest(struct diffie_hellman_instance *self, UINT8 *digest)
struct lsh_string *dh_make_server_msg(struct diffie_hellman_instance *self,
struct signer *s)
{
UINT8 *digest;
struct lsh_string *msg;
dh_generate_secret(self, self->f);
digest = alloca(self->hash->hash_size);
dh_hash_digest(self, digest);
self->exchange_hash = lsh_string_alloc(self->hash->hash_size);
dh_hash_digest(self, exchange_hash->data);
return ssh_format("%c%S%n%fS",
SSH_MSG_KEXDH_REPLY,
self->server_key,
self->f, SIGN(s, self->hash->hash_size, digest));
self->f, SIGN(s,
self->exchange_hash->length,
self->exchange_hash->data));
}
int dh_process_server_msg(struct diffie_hellman_instance *self,
......
......@@ -71,6 +71,7 @@ struct diffie_hellman_instance
mpz_t secret; /* This side's secret exponent */
mpz_t lsh_string *K;
struct hash_instance *hash;
struct lsh_string *exchange_hash;
};
/* Creates client message */
......
......@@ -184,7 +184,7 @@ int do_read_packet(struct read_handler **h,
return 0;
}
if (!memcpy(mac,
if (!memcmp(mac,
closure->computed_mac + closure->pos,
n))
/* FIXME: Free resources */
......
......@@ -28,14 +28,18 @@
#include "abstract_io.h"
#include "abstract_crypto.h"
#include "newkeys.h"
struct read_packet
{
struct read_handler super; /* Super type */
int state;
UINT32 max_packet;
#if 0
UINT32 max_packet;
#endif
UINT32 sequence_number; /* Attached to read packets */
/* Buffer partial headers and packets. */
......@@ -43,15 +47,15 @@ struct read_packet
struct lsh_string *buffer;
UINT32 crypt_pos;
struct mac_instance *mac;
struct crypto_instance *crypto;
UINT8 *computed_mac; /* Must point to an area large enough to hold a mac */
#if 0
struct abstract_write *handler;
#endif
struct ssh_connection *connection;
};
struct read_handler *make_read_packet(struct abstract_write *handler,
UINT32 max_packet);
struct ssh_connection *connection);
#endif /* LSH_READ_PACKET_H_INCLUDED */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment