]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - gcrypt.c
gcrypt: Let decode_key() return blob size through additional argument.
[paraslash.git] / gcrypt.c
index b21cf72272b6cfdaaf84adab464d11d882607c9c..9b05a9494c23503702f88b27716468942b15d805 100644 (file)
--- a/gcrypt.c
+++ b/gcrypt.c
@@ -56,7 +56,7 @@ void get_random_bytes_or_die(unsigned char *buf, int num)
  * call to gcry_check_version() initializes the gcrypt library and checks that
  * we have at least the minimal required version.
  */
-void init_random_seed_or_die(void)
+void crypt_init(void)
 {
        const char *req_ver = "1.5.0";
        int seed;
@@ -66,10 +66,29 @@ void init_random_seed_or_die(void)
                        req_ver, gcry_check_version(NULL));
                exit(EXIT_FAILURE);
        }
+
+       /*
+        * Allocate a pool of secure memory. This also drops privileges where
+        * needed.
+        */
+       gcry_control(GCRYCTL_INIT_SECMEM, 65536, 0);
+
+       /* Tell Libgcrypt that initialization has completed. */
+       gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
+
        get_random_bytes_or_die((unsigned char *)&seed, sizeof(seed));
        srandom(seed);
 }
 
+void crypt_shutdown(void)
+{
+       /*
+        * WK does not see a way to apply a patch for the sake of Valgrind, so
+        * as of 2018 libgrypt has no deinitialization routine to free the
+        * resources on exit.
+        */
+}
+
 /** S-expression for the public part of an RSA key. */
 #define RSA_PUBKEY_SEXP "(public-key (rsa (n %m) (e %m)))"
 /** S-expression for a private RSA key. */
@@ -87,12 +106,17 @@ static const char *gcrypt_strerror(gcry_error_t gret)
        return gcry_strerror(gcry_err_code(gret));
 }
 
-static int decode_key(const char *key_file, const char *header_str,
-               const char *footer_str, unsigned char **result)
+/** Private keys start with this header. */
+#define PRIVATE_KEY_HEADER "-----BEGIN RSA PRIVATE KEY-----"
+/** Private keys end with this footer. */
+#define PRIVATE_KEY_FOOTER "-----END RSA PRIVATE KEY-----"
+
+static int decode_key(const char *key_file, unsigned char **result,
+               size_t *blob_size)
 {
        int ret, ret2, i, j;
        void *map;
-       size_t map_size, key_size, blob_size;
+       size_t map_size, key_size;
        unsigned char *blob = NULL;
        char *begin, *footer, *key;
 
@@ -100,13 +124,13 @@ static int decode_key(const char *key_file, const char *header_str,
        if (ret < 0)
                goto out;
        ret = -E_KEY_MARKER;
-       if (strncmp(map, header_str, strlen(header_str)))
+       if (strncmp(map, PRIVATE_KEY_HEADER, strlen(PRIVATE_KEY_HEADER)))
                goto unmap;
-       footer = strstr(map, footer_str);
+       footer = strstr(map, PRIVATE_KEY_FOOTER);
        ret = -E_KEY_MARKER;
        if (!footer)
                goto unmap;
-       begin = map + strlen(header_str);
+       begin = map + strlen(PRIVATE_KEY_HEADER);
        /* skip whitespace at the beginning */
        for (; begin < footer; begin++) {
                if (para_isspace(*begin))
@@ -125,15 +149,8 @@ static int decode_key(const char *key_file, const char *header_str,
                key[j++] = begin[i];
        }
        key[j] = '\0';
-       ret = base64_decode(key, j, (char **)&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);
-       blob = NULL;
 unmap:
        ret2 = para_munmap(map, map_size);
        if (ret >= 0 && ret2 < 0)
@@ -218,7 +235,7 @@ static int read_bignum(unsigned char *start, unsigned char *end, gcry_mpi_t *bn,
        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",
+               PARA_ERROR_LOG("gcry_mpi_scan: %s\n",
                        gcry_strerror(gcry_err_code(gret)));
                return-E_MPI_SCAN;
        }
@@ -271,28 +288,21 @@ static int find_privkey_bignum_offset(const unsigned char *data, int len)
        return p - data;
 }
 
-/** Private keys start with this header. */
-#define PRIVATE_KEY_HEADER "-----BEGIN RSA PRIVATE KEY-----"
-/** Private keys end with this footer. */
-#define PRIVATE_KEY_FOOTER "-----END RSA PRIVATE KEY-----"
-
 static int get_private_key(const char *key_file, struct asymmetric_key **result)
 {
        gcry_mpi_t n = NULL, e = NULL, d = NULL, p = NULL, q = NULL,
                u = NULL;
        unsigned char *blob, *cp, *end;
-       int blob_size, ret, n_size;
+       int ret, n_size;
        gcry_error_t gret;
-       size_t erroff;
+       size_t erroff, blob_size;
        gcry_sexp_t sexp;
        struct asymmetric_key *key;
 
        *result = NULL;
-       ret = decode_key(key_file, PRIVATE_KEY_HEADER, PRIVATE_KEY_FOOTER,
-               &blob);
+       ret = decode_key(key_file, &blob, &blob_size);
        if (ret < 0)
                return ret;
-       blob_size = ret;
        end = blob + blob_size;
        ret = find_privkey_bignum_offset(blob, blob_size);
        if (ret < 0)
@@ -406,7 +416,7 @@ int apc_get_pubkey(const char *key_file, struct asymmetric_key **result)
                ret = -E_SEXP_BUILD;
                goto release_n;
        }
-       ret = nr_scanned / 32 * 32;
+       ret = ROUND_DOWN(nr_scanned, 32);
        PARA_INFO_LOG("successfully read %d bit ssh public key\n", ret * 8);
        key = para_malloc(sizeof(*key));
        key->num_bytes = ret;