X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=gcrypt.c;h=f30e8166b01badc08de69487dcb99645d4d15990;hp=45a1c67d20da0b6d229180de92be10644a63d082;hb=f0919ce4c6ca831e5a623ce2de9b9dd9f497cff1;hpb=ca006af72cef95b0aba3cad799badde47010a621 diff --git a/gcrypt.c b/gcrypt.c index 45a1c67d..f30e8166 100644 --- a/gcrypt.c +++ b/gcrypt.c @@ -15,6 +15,7 @@ #include "crypt.h" #include "crypt_backend.h" #include "fd.h" +#include "base64.h" //#define GCRYPT_DEBUG 1 @@ -58,16 +59,15 @@ void get_random_bytes_or_die(unsigned char *buf, int num) } /* - * This is called at the beginning of every program that uses libgcrypt. We - * don't have to initialize any random seed here, but we must initialize the - * gcrypt library. This task is performed by gcry_check_version() which can - * also check that the gcrypt library version is at least the minimal required - * version. This function also tells us whether we have to use our own OAEP - * padding code. + * This is called at the beginning of every program that uses libgcrypt. The + * call to gcry_check_version() initializes the gcrypt library and checks that + * we have at least the minimal required version. This function also tells us + * whether we have to use our own OAEP padding code. */ void init_random_seed_or_die(void) { const char *ver, *req_ver; + int seed; ver = gcry_check_version(NULL); req_ver = "1.4.0"; @@ -84,6 +84,8 @@ void init_random_seed_or_die(void) libgcrypt_has_oaep = false; rsa_decrypt_sexp = "(enc-val(rsa(a %m)))"; } + get_random_bytes_or_die((unsigned char *)&seed, sizeof(seed)); + srandom(seed); } /** S-expression for the public part of an RSA key. */ @@ -212,7 +214,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,12 +241,11 @@ static int decode_key(const char *key_file, const char *header_str, key[j++] = begin[i]; } key[j] = '\0'; - 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); @@ -257,6 +258,7 @@ unmap: free(blob); blob = NULL; } +out: *result = blob; return ret; } @@ -387,7 +389,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", @@ -585,7 +587,7 @@ static int get_asn_public_key(const char *key_file, struct asymmetric_key **resu 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); @@ -605,13 +607,9 @@ static int get_ssh_public_key(unsigned char *data, int size, gcry_sexp_t *result 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); + 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 +649,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: @@ -781,6 +779,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);