Replace direct use of RC4 by stream cipher abstraction.
authorAndre Noll <maan@systemlinux.org>
Mon, 28 Feb 2011 21:54:08 +0000 (22:54 +0100)
committerAndre Noll <maan@systemlinux.org>
Sun, 27 Mar 2011 14:41:51 +0000 (16:41 +0200)
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.

15 files changed:
afs.c
afs.cmd
aft.c
attribute.c
audiod.c
blob.c
client.c
client.h
client_common.c
command.c
crypt.c
crypt.h
server.c
server.cmd
user_list.c

diff --git a/afs.c b/afs.c
index 0464eb7..c5a088c 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -9,7 +9,6 @@
 #include <regex.h>
 #include <signal.h>
 #include <fnmatch.h>
-#include <openssl/rc4.h>
 #include <osl.h>
 
 #include "server.cmdline.h"
diff --git a/afs.cmd b/afs.cmd
index f055199..8a2ae3b 100644 (file)
--- 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 b3dde13..3b2f917 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -8,7 +8,6 @@
 
 #include <regex.h>
 #include <dirent.h> /* readdir() */
-#include <openssl/rc4.h>
 #include <sys/mman.h>
 #include <fnmatch.h>
 #include <sys/shm.h>
index 2453691..bef25fc 100644 (file)
@@ -7,7 +7,6 @@
 /** \file attribute.c Attribute handling functions. */
 
 #include <regex.h>
-#include <openssl/rc4.h>
 #include <osl.h>
 
 #include "para.h"
index e5db0cd..40a35c6 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -9,7 +9,6 @@
 #include <sys/types.h>
 #include <dirent.h>
 #include <signal.h>
-#include <openssl/rc4.h>
 #include <stdbool.h>
 
 #include "para.h"
diff --git a/blob.c b/blob.c
index cbf2af4..cefd028 100644 (file)
--- a/blob.c
+++ b/blob.c
@@ -8,7 +8,6 @@
 
 #include <regex.h>
 #include <fnmatch.h>
-#include <openssl/rc4.h>
 #include <osl.h>
 
 #include "para.h"
index ec32cd4..b6a2f24 100644 (file)
--- a/client.c
+++ b/client.c
@@ -7,7 +7,6 @@
 /** \file client.c the client program used to connect to para_server */
 
 #include <regex.h>
-#include <openssl/rc4.h>
 #include <stdbool.h>
 
 #include "para.h"
index 667607e..78cfb5d 100644 (file)
--- a/client.h
+++ b/client.h
@@ -6,8 +6,6 @@
 
 /** \file client.h Common client functions and exported symbols from client_common.c. */
 
-#include <openssl/rc4.h>
-
 /** The different states of a connection from the view of the client. */
 enum {
        /** TCP connection is established. */
index 31bbc11..c55db47 100644 (file)
@@ -9,7 +9,6 @@
 #include <regex.h>
 #include <sys/types.h>
 #include <dirent.h>
-#include <openssl/rc4.h>
 
 #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,
index 688a039..2c9d29d 100644 (file)
--- a/command.c
+++ b/command.c
@@ -11,7 +11,6 @@
 #include <sys/time.h>
 #include <sys/types.h>
 #include <dirent.h>
-#include <openssl/rc4.h>
 #include <osl.h>
 #include <stdbool.h>
 
@@ -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 8986d0e..206b934 100644 (file)
--- 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 898e344..13a5505 100644 (file)
--- 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, ...);
index 35d6f19..0f2967b 100644 (file)
--- a/server.c
+++ b/server.c
@@ -65,7 +65,6 @@
 #include <signal.h>
 #include <dirent.h>
 #include <sys/time.h>
-#include <openssl/rc4.h>
 #include <regex.h>
 #include <osl.h>
 #include <stdbool.h>
index 73ee341..d3fad64 100644 (file)
@@ -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
 ---
index 4696a66..9cde1f6 100644 (file)
@@ -9,7 +9,6 @@
 #include <regex.h>
 #include <sys/types.h>
 #include <dirent.h>
-#include <openssl/rc4.h>
 
 #include "para.h"
 #include "error.h"