From 037059c8a25ce134af1eaa6c3fa8ac96b9f7e0b6 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Mon, 28 Feb 2011 22:54:08 +0100 Subject: [PATCH] Replace direct use of RC4 by stream cipher abstraction. This introduces the new struct stream_cipher in crypt.h as well as two functions stream_cipher_new() and stream_cipher_free() which initialize a new stream cipher structure and deallocate such a structure, respectively. The users of RC4 are changed to call the new abstract functions, so they become independent from openssl. Consequently the affected files need no include openssl/rc4.h any more. --- afs.c | 1 - afs.cmd | 2 +- aft.c | 1 - attribute.c | 1 - audiod.c | 1 - blob.c | 1 - client.c | 1 - client.h | 2 -- client_common.c | 11 ++++++----- command.c | 11 ++++++----- crypt.c | 34 +++++++++++++++++++++++++++++++--- crypt.h | 19 +++++++++++++------ server.c | 1 - server.cmd | 2 +- user_list.c | 1 - 15 files changed, 58 insertions(+), 31 deletions(-) diff --git a/afs.c b/afs.c index 0464eb77..c5a088cb 100644 --- a/afs.c +++ b/afs.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include "server.cmdline.h" diff --git a/afs.cmd b/afs.cmd index f0551998..8a2ae3b3 100644 --- a/afs.cmd +++ b/afs.cmd @@ -3,7 +3,7 @@ SF: afs.c aft.c attribute.c HC: Prototypes for the commands of the audio file selector. CC: Array of commands for the audio file selector. AT: server_command -SI: openssl/rc4 osl regex +SI: osl regex IN: para error crypt command string afh afs server list user_list SN: list of afs commands TM: mood lyr img pl diff --git a/aft.c b/aft.c index b3dde137..3b2f9172 100644 --- a/aft.c +++ b/aft.c @@ -8,7 +8,6 @@ #include #include /* readdir() */ -#include #include #include #include diff --git a/attribute.c b/attribute.c index 24536911..bef25fc0 100644 --- a/attribute.c +++ b/attribute.c @@ -7,7 +7,6 @@ /** \file attribute.c Attribute handling functions. */ #include -#include #include #include "para.h" diff --git a/audiod.c b/audiod.c index e5db0cd2..40a35c6a 100644 --- a/audiod.c +++ b/audiod.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include "para.h" diff --git a/blob.c b/blob.c index cbf2af49..cefd0288 100644 --- a/blob.c +++ b/blob.c @@ -8,7 +8,6 @@ #include #include -#include #include #include "para.h" diff --git a/client.c b/client.c index ec32cd41..b6a2f241 100644 --- a/client.c +++ b/client.c @@ -7,7 +7,6 @@ /** \file client.c the client program used to connect to para_server */ #include -#include #include #include "para.h" diff --git a/client.h b/client.h index 667607e2..78cfb5d8 100644 --- a/client.h +++ b/client.h @@ -6,8 +6,6 @@ /** \file client.h Common client functions and exported symbols from client_common.c. */ -#include - /** The different states of a connection from the view of the client. */ enum { /** TCP connection is established. */ diff --git a/client_common.c b/client_common.c index 31bbc114..c55db47b 100644 --- a/client_common.c +++ b/client_common.c @@ -9,7 +9,6 @@ #include #include #include -#include #include "para.h" #include "error.h" @@ -42,6 +41,8 @@ void client_close(struct client_task *ct) return; if (ct->rc4c.fd >= 0) close(ct->rc4c.fd); + stream_cipher_free(ct->rc4c.recv); + stream_cipher_free(ct->rc4c.send); free(ct->user); free(ct->config_file); free(ct->key_file); @@ -193,10 +194,10 @@ static void client_post_select(struct sched *s, struct task *t) if (ret < 0) goto out; sha1_hash((char *)crypt_buf, CHALLENGE_SIZE, challenge_sha1); - RC4_set_key(&ct->rc4c.send_key, RC4_KEY_LEN, - crypt_buf + CHALLENGE_SIZE); - RC4_set_key(&ct->rc4c.recv_key, RC4_KEY_LEN, - crypt_buf + CHALLENGE_SIZE + RC4_KEY_LEN); + ct->rc4c.send = stream_cipher_new(crypt_buf + CHALLENGE_SIZE, + RC4_KEY_LEN); + ct->rc4c.recv = stream_cipher_new(crypt_buf + CHALLENGE_SIZE + + RC4_KEY_LEN, RC4_KEY_LEN); hash_to_asc(challenge_sha1, buf); PARA_INFO_LOG("--> %s\n", buf); ret = send_bin_buffer(ct->rc4c.fd, (char *)challenge_sha1, diff --git a/command.c b/command.c index 688a039f..2c9d29df 100644 --- a/command.c +++ b/command.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -809,10 +808,10 @@ __noreturn void handle_connect(int fd, const char *peername) /* auth successful */ alarm(0); PARA_INFO_LOG("good auth for %s\n", u->name); - /* init rc4 keys with the second part of the random buffer */ - RC4_set_key(&rc4c.recv_key, RC4_KEY_LEN, rand_buf + CHALLENGE_SIZE); - RC4_set_key(&rc4c.send_key, RC4_KEY_LEN, rand_buf + CHALLENGE_SIZE - + RC4_KEY_LEN); + /* init stream cipher keys with the second part of the random buffer */ + rc4c.recv = stream_cipher_new(rand_buf + CHALLENGE_SIZE, RC4_KEY_LEN); + rc4c.send = stream_cipher_new(rand_buf + CHALLENGE_SIZE + RC4_KEY_LEN, + RC4_KEY_LEN); ret = rc4_send_buffer(&rc4c, PROCEED_MSG); if (ret < 0) goto net_err; @@ -849,6 +848,8 @@ net_err: PARA_NOTICE_LOG("%s\n", para_strerror(-ret)); out: free(command); + stream_cipher_free(rc4c.recv); + stream_cipher_free(rc4c.send); mutex_lock(mmd_mutex); if (cmd && (cmd->perms & AFS_WRITE) && ret >= 0) mmd->events++; diff --git a/crypt.c b/crypt.c index 8986d0e7..206b9348 100644 --- a/crypt.c +++ b/crypt.c @@ -220,6 +220,34 @@ int pub_encrypt(struct asymmetric_key *pub, unsigned char *inbuf, } #define RC4_ALIGN 8 +struct stream_cipher { + RC4_KEY key; +}; + +/** + * Allocate and initialize a stream cipher structure. + * + * \param data The key. + * \param len The size of the key. + * + * \return A new stream cipher structure. + */ +struct stream_cipher *stream_cipher_new(const unsigned char *data, int len) +{ + struct stream_cipher *sc = para_malloc(sizeof(*sc)); + RC4_set_key(&sc->key, len, data); + return sc; +} + +/** + * Deallocate a stream cipher structure. + * + * \param sc A stream cipher previously obtained by stream_cipher_new(). + */ +void stream_cipher_free(struct stream_cipher *sc) +{ + free(sc); +} /** * Encrypt and send a buffer. @@ -241,10 +269,10 @@ int rc4_send_bin_buffer(struct rc4_context *rc4c, const char *buf, size_t len) assert(len); tmp = para_malloc(l2); - RC4(&rc4c->send_key, l1, (const unsigned char *)buf, tmp); + RC4(&rc4c->send->key, l1, (const unsigned char *)buf, tmp); if (len > l1) { memcpy(remainder, buf + l1, len - l1); - RC4(&rc4c->send_key, len - l1, remainder, tmp + l1); + RC4(&rc4c->send->key, len - l1, remainder, tmp + l1); } ret = write_all(rc4c->fd, (char *)tmp, &len); free(tmp); @@ -301,7 +329,7 @@ int rc4_recv_bin_buffer(struct rc4_context *rc4c, char *buf, size_t size) ssize_t ret = recv(rc4c->fd, tmp, size, 0); if (ret > 0) - RC4(&rc4c->recv_key, ret, tmp, (unsigned char *)buf); + RC4(&rc4c->recv->key, ret, tmp, (unsigned char *)buf); else if (ret < 0) ret = -ERRNO_TO_PARA_ERROR(errno); free(tmp); diff --git a/crypt.h b/crypt.h index 898e3446..13a5505c 100644 --- a/crypt.h +++ b/crypt.h @@ -20,21 +20,28 @@ void free_asymmetric_key(struct asymmetric_key *key); void get_random_bytes_or_die(unsigned char *buf, int num); void init_random_seed_or_die(void); +struct stream_cipher; + /** * Used on the server-side for client-server communication encryption. * - * The traffic between (the forked child of) para_server and the remote - * client process is crypted by a RC4 session key. This structure contains - * the RC4 keys and the file descriptor for which these keys should be used. + * The traffic between (the forked child of) para_server and the remote client + * process is crypted by a symmetric session key. This structure contains the + * keys for the stream cipher and the file descriptor for which these keys + * should be used. */ struct rc4_context { /** The socket file descriptor. */ int fd; - /** Key used for sending data. */ - RC4_KEY recv_key; /** Key used for receiving data. */ - RC4_KEY send_key; + struct stream_cipher *recv; + /** Key used for sending data. */ + struct stream_cipher *send; }; + +struct stream_cipher *stream_cipher_new(const unsigned char *data, int len); +void stream_cipher_free(struct stream_cipher *sc); + int rc4_send_bin_buffer(struct rc4_context *rc4c, const char *buf, size_t len); int rc4_send_buffer(struct rc4_context *rc4c, const char *buf); __printf_2_3 int rc4_send_va_buffer(struct rc4_context *rc4c, const char *fmt, ...); diff --git a/server.c b/server.c index 35d6f191..0f2967b3 100644 --- a/server.c +++ b/server.c @@ -65,7 +65,6 @@ #include #include #include -#include #include #include #include diff --git a/server.cmd b/server.cmd index 73ee3417..d3fad648 100644 --- a/server.cmd +++ b/server.cmd @@ -3,7 +3,7 @@ SF: command.c HC: prototypes for the server command handlers CC: array of server commands AT: server_command -SI: openssl/rc4 osl regex +SI: osl regex IN: para error crypt command string afh afs server list user_list SN: list of server commands --- diff --git a/user_list.c b/user_list.c index 4696a669..9cde1f62 100644 --- a/user_list.c +++ b/user_list.c @@ -9,7 +9,6 @@ #include #include #include -#include #include "para.h" #include "error.h" -- 2.39.5