fade: Quiesce two gcc warnings.
[paraslash.git] / crypt.c
diff --git a/crypt.c b/crypt.c
index 1172ddc333fdb12f2010c11785c39f773561e777..cdcb6149d04254a0def3bcc903823f71ae3a89e5 100644 (file)
--- a/crypt.c
+++ b/crypt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005-2009 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2005-2011 Andre Noll <maan@systemlinux.org>
  *
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
@@ -65,11 +65,29 @@ void init_random_seed_or_die(void)
        srandom(seed);
 }
 
+static int check_key_file(const char *file, int private)
+{
+       struct stat st;
+
+       if (stat(file, &st) != 0)
+               return -ERRNO_TO_PARA_ERROR(errno);
+       if (private != LOAD_PRIVATE_KEY)
+               return 0;
+       if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0)
+               return -E_KEY_PERM;
+       return 1;
+}
+
 static EVP_PKEY *load_key(const char *file, int private)
 {
        BIO *key;
        EVP_PKEY *pkey = NULL;
+       int ret = check_key_file(file, private);
 
+       if (ret < 0) {
+               PARA_ERROR_LOG("%s\n", para_strerror(-ret));
+               return NULL;
+       }
        key = BIO_new(BIO_s_file());
        if (!key)
                return NULL;
@@ -185,6 +203,8 @@ int para_encrypt_buffer(RSA *rsa, unsigned char *inbuf,
        return ret < 0? -E_ENCRYPT : ret;
 }
 
+#define RC4_ALIGN 8
+
 /**
  * Encrypt and send a buffer.
  *
@@ -200,10 +220,16 @@ int rc4_send_bin_buffer(struct rc4_context *rc4c, const char *buf, size_t len)
 {
        int ret;
        unsigned char *tmp;
+       static unsigned char remainder[RC4_ALIGN];
+       size_t l1 = ROUND_DOWN(len, RC4_ALIGN), l2 = ROUND_UP(len, RC4_ALIGN);
 
        assert(len);
-       tmp = para_malloc(len);
-       RC4(&rc4c->send_key, len, (const unsigned char *)buf, tmp);
+       tmp = para_malloc(l2);
+       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);
+       }
        ret = write_all(rc4c->fd, (char *)tmp, &len);
        free(tmp);
        return ret;