play: Convert com_ls() to lopsub.
[paraslash.git] / gcrypt.c
index a96db362278b1dae70e7aec87a920aac1c402e54..7c19aeb0c3edc022c5b0f0425a202e37fd38d906 100644 (file)
--- a/gcrypt.c
+++ b/gcrypt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2013 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2011 Andre Noll <maan@tuebingen.mpg.de>
  *
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
@@ -15,6 +15,7 @@
 #include "crypt.h"
 #include "crypt_backend.h"
 #include "fd.h"
+#include "base64.h"
 
 //#define GCRYPT_DEBUG 1
 
@@ -26,7 +27,7 @@ static void dump_buffer(const char *msg, unsigned char *buf, int len)
 {
        int i;
 
-       fprintf(stderr, "%s (%u bytes): ", msg, len);
+       fprintf(stderr, "%s (%d bytes): ", msg, len);
        for (i = 0; i < len; i++)
                fprintf(stderr, "%02x ", buf[i]);
        fprintf(stderr, "\n");
@@ -87,7 +88,7 @@ void init_random_seed_or_die(void)
 }
 
 /** S-expression for the public part of an RSA key. */
-#define RSA_PUBKEY_SEXP  "(public-key (rsa (n %m) (e %m)))"
+#define RSA_PUBKEY_SEXP "(public-key (rsa (n %m) (e %m)))"
 /** S-expression for a private RSA key. */
 #define RSA_PRIVKEY_SEXP "(private-key (rsa (n %m) (e %m) (d %m) (p %m) (q %m) (u %m)))"
 
@@ -97,7 +98,7 @@ static void mgf1(unsigned char *seed, size_t seed_len, unsigned result_len,
 {
        gcry_error_t gret;
        gcry_md_hd_t handle;
-       size_t n;;
+       size_t n;
        unsigned char *md;
        unsigned char octet_string[4], *rp = result, *end = rp + result_len;
 
@@ -212,7 +213,7 @@ static int decode_key(const char *key_file, const char *header_str,
 
        ret = mmap_full_file(key_file, O_RDONLY, &map, &map_size, NULL);
        if (ret < 0)
-               return ret;
+               goto out;
        ret = -E_KEY_MARKER;
        if (strncmp(map, header_str, strlen(header_str)))
                goto unmap;
@@ -239,13 +240,11 @@ static int decode_key(const char *key_file, const char *header_str,
                key[j++] = begin[i];
        }
        key[j] = '\0';
-       //PARA_CRIT_LOG("key: %s\n", key);
-       blob_size = key_size * 2;
-       blob = para_malloc(blob_size);
-       ret = base64_decode(key, blob, blob_size);
+       ret = base64_decode(key, j, (char **)&blob, &blob_size);
        free(key);
        if (ret < 0)
                goto free_unmap;
+       ret = blob_size;
        goto unmap;
 free_unmap:
        free(blob);
@@ -258,6 +257,7 @@ unmap:
                free(blob);
                blob = NULL;
        }
+out:
        *result = blob;
        return ret;
 }
@@ -275,14 +275,14 @@ enum asn1_types {
 /* bit 6 has value 0 */
 static inline bool is_primitive(unsigned char c)
 {
-       return ((c & (1<<6)) == 0);
+       return (c & (1<<6)) == 0;
 }
 
 static inline bool is_primitive_integer(unsigned char c)
 {
        if (!is_primitive(c))
                return false;
-       return ((c & 0x1f) == ASN1_TYPE_INTEGER);
+       return (c & 0x1f) == ASN1_TYPE_INTEGER;
 }
 
 /* Bit 8 is zero (and bits 7-1 give the length) */
@@ -305,7 +305,7 @@ static int find_pubkey_bignum_offset(const unsigned char *data, int len)
 {
        const unsigned char *p = data, *end = data + len;
 
-       /* the whole thing istarts with one sequence */
+       /* the whole thing starts with one sequence */
        if (*p != ASN1_TYPE_SEQUENCE)
                return -E_ASN1_PARSE;
        p++;
@@ -388,7 +388,7 @@ static int read_bignum(unsigned char *start, unsigned char *end, gcry_mpi_t *bn,
                for (i = 0; i < num_bytes; i++, cp++)
                        bn_size = (bn_size << 8) + *cp;
        }
-       PARA_DEBUG_LOG("bn_size %d (0x%x)\n", bn_size, bn_size);
+       PARA_DEBUG_LOG("bn_size %d (0x%x)\n", bn_size, (unsigned)bn_size);
        gret = gcry_mpi_scan(bn, GCRYMPI_FMT_STD, cp, bn_size, NULL);
        if (gret) {
                PARA_ERROR_LOG("%s while scanning n\n",
@@ -429,7 +429,7 @@ static int find_privkey_bignum_offset(const unsigned char *data, int len)
        if (p >= end)
                return -E_ASN1_PARSE;
 
-       /* Skip next integer  */
+       /* skip next integer */
        if (*p != ASN1_TYPE_INTEGER)
                return -E_ASN1_PARSE;
        p++;
@@ -583,9 +583,10 @@ static int get_asn_public_key(const char *key_file, struct asymmetric_key **resu
        }
        key = para_malloc(sizeof(*key));
        key->sexp = sexp;
+       key->num_bytes = n_size;
        *result = key;
        ret = n_size;
-       PARA_INFO_LOG("successfully read %u bit asn public key\n", n_size * 8);
+       PARA_INFO_LOG("successfully read %d bit asn public key\n", n_size * 8);
 
 release_e:
        gcry_mpi_release(e);
@@ -604,14 +605,10 @@ static int get_ssh_public_key(unsigned char *data, int size, gcry_sexp_t *result
        size_t nr_scanned, erroff, decoded_size;
        gcry_mpi_t e = NULL, n = NULL;
 
-       PARA_DEBUG_LOG("decoding %d byte  public rsa-ssh key\n", size);
-       if (size > INT_MAX / 4)
-               return -ERRNO_TO_PARA_ERROR(EOVERFLOW);
-       blob = para_malloc(2 * size);
-       ret = uudecode((char *)data, blob, 2 * size);
+       PARA_DEBUG_LOG("decoding %d byte public rsa-ssh key\n", size);
+       ret = uudecode((char *)data, size, (char **)&blob, &decoded_size);
        if (ret < 0)
                goto free_blob;
-       decoded_size = ret;
        end = blob + decoded_size;
        dump_buffer("decoded key", blob, decoded_size);
        ret = check_ssh_key_header(blob, decoded_size);
@@ -651,7 +648,7 @@ static int get_ssh_public_key(unsigned char *data, int size, gcry_sexp_t *result
                goto release_n;
        }
        ret = nr_scanned / 32 * 32;
-       PARA_INFO_LOG("successfully read %u bit ssh public key\n", ret * 8);
+       PARA_INFO_LOG("successfully read %d bit ssh public key\n", ret * 8);
 release_n:
        gcry_mpi_release(n);
 release_e:
@@ -758,13 +755,13 @@ static int decode_rsa(gcry_sexp_t sexp, int key_size, unsigned char *outbuf,
 
        PARA_DEBUG_LOG("decrypted buffer before unpad (%d bytes):\n",
                key_size);
-       dump_buffer("non-unpadded decrypted buffer", oaep_buf, key_size);;
+       dump_buffer("non-unpadded decrypted buffer", oaep_buf, key_size);
        ret = unpad_oaep(oaep_buf, key_size, outbuf, nbytes);
        if (ret < 0)
                goto out_mpi_release;
        PARA_DEBUG_LOG("decrypted buffer after unpad (%zu bytes):\n",
                *nbytes);
-       dump_buffer("unpadded decrypted buffer", outbuf, *nbytes);;
+       dump_buffer("unpadded decrypted buffer", outbuf, *nbytes);
        ret = 1;
 out_mpi_release:
        gcry_mpi_release(out_mpi);
@@ -781,6 +778,9 @@ int priv_decrypt(const char *key_file, unsigned char *outbuf,
        gcry_sexp_t in, out, priv_key;
        size_t nbytes;
 
+       ret = check_key_file(key_file, true);
+       if (ret < 0)
+               return ret;
        PARA_INFO_LOG("decrypting %d byte input\n", inlen);
        /* key_file -> asymmetric key priv */
        ret = get_private_key(key_file, &priv);
@@ -912,11 +912,25 @@ struct stream_cipher {
        gcry_cipher_hd_t handle;
 };
 
-struct stream_cipher *sc_new(const unsigned char *data, int len)
+struct stream_cipher *sc_new(const unsigned char *data, int len,
+               bool use_aes)
 {
        gcry_error_t gret;
-
        struct stream_cipher *sc = para_malloc(sizeof(*sc));
+
+       if (use_aes) {
+               assert(len >= 2 * AES_CRT128_BLOCK_SIZE);
+               gret = gcry_cipher_open(&sc->handle, GCRY_CIPHER_AES128,
+                       GCRY_CIPHER_MODE_CTR, 0);
+               assert(gret == 0);
+               gret = gcry_cipher_setkey(sc->handle, data,
+                       AES_CRT128_BLOCK_SIZE);
+               assert(gret == 0);
+               gret = gcry_cipher_setctr(sc->handle,
+                       data + AES_CRT128_BLOCK_SIZE, AES_CRT128_BLOCK_SIZE);
+               assert(gret == 0);
+               return sc;
+       }
        gret = gcry_cipher_open(&sc->handle, GCRY_CIPHER_ARCFOUR,
                GCRY_CIPHER_MODE_STREAM, 0);
        if (gret) {