From f553ab861efaa14f3a07ffb074c9e640b9fc776a Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sun, 10 Jul 2016 22:23:45 +0200 Subject: [PATCH] crypto: Simplify asymetric key handling. get_asymmetric_key() and free_asymmetric_key() are public because para_server maintains a copy to the public key of each user so that the keys need to be loaded only once. On the other hand, for private keys (used in para_client) key allocation and freeing is performed implicitly in priv_decrypt(), and no reference to the key is ever returned. So the crypto API can be simplified by exposing the interface only for public keys. Hence this patch renames get_asymmetric_key() to get_public_key() and drops the "private" argument. Similarly, free_asymmetric_key() is renamed to free_public_key(). --- crypt.c | 19 +++++++++---------- crypt.h | 11 +++++------ gcrypt.c | 10 ++++------ user_list.c | 6 +++--- 4 files changed, 21 insertions(+), 25 deletions(-) diff --git a/crypt.c b/crypt.c index 085c0563..c15768a3 100644 --- a/crypt.c +++ b/crypt.c @@ -155,8 +155,7 @@ fail: return ret; } -int get_asymmetric_key(const char *key_file, int private, - struct asymmetric_key **result) +int get_public_key(const char *key_file, struct asymmetric_key **result) { struct asymmetric_key *key = NULL; void *map = NULL; @@ -166,10 +165,6 @@ int get_asymmetric_key(const char *key_file, int private, char *cp; key = para_malloc(sizeof(*key)); - if (private) { - ret = get_openssl_key(key_file, &key->rsa, LOAD_PRIVATE_KEY); - goto out; - } ret = mmap_full_file(key_file, O_RDONLY, &map, &map_size, NULL); if (ret < 0) goto out; @@ -210,7 +205,7 @@ out: return ret; } -void free_asymmetric_key(struct asymmetric_key *key) +void free_public_key(struct asymmetric_key *key) { if (!key) return; @@ -229,9 +224,12 @@ int priv_decrypt(const char *key_file, unsigned char *outbuf, return ret; if (inlen < 0) return -E_RSA; - ret = get_asymmetric_key(key_file, LOAD_PRIVATE_KEY, &priv); - if (ret < 0) + priv = para_malloc(sizeof(*priv)); + ret = get_openssl_key(key_file, &priv->rsa, LOAD_PRIVATE_KEY); + if (ret < 0) { + free(priv); return ret; + } /* * RSA is vulnerable to timing attacks. Generate a random blinding * factor to protect against this kind of attack. @@ -245,7 +243,8 @@ int priv_decrypt(const char *key_file, unsigned char *outbuf, if (ret <= 0) ret = -E_DECRYPT; out: - free_asymmetric_key(priv); + RSA_free(priv->rsa); + free(priv); return ret; } diff --git a/crypt.h b/crypt.h index 9be7a23e..6f3befdb 100644 --- a/crypt.h +++ b/crypt.h @@ -51,22 +51,21 @@ int priv_decrypt(const char *key_file, unsigned char *outbuf, * Read an asymmetric key from a file. * * \param key_file The file containing the key. - * \param private if non-zero, read the private key, otherwise the public key. * \param result The key structure is returned here. * * \return The size of the key on success, negative on errors. */ -int get_asymmetric_key(const char *key_file, int private, - struct asymmetric_key **result); +int get_public_key(const char *key_file, struct asymmetric_key **result); /** - * Deallocate an asymmetric key structure. + * Deallocate a public key. * * \param key Pointer to the key structure to free. * - * This must be called for any key obtained by get_asymmetric_key(). + * This should be called for keys obtained by get_public_key() if the key is no + * longer needed. */ -void free_asymmetric_key(struct asymmetric_key *key); +void free_public_key(struct asymmetric_key *key); /** diff --git a/gcrypt.c b/gcrypt.c index ba8aadc6..8bbc82f3 100644 --- a/gcrypt.c +++ b/gcrypt.c @@ -659,8 +659,7 @@ free_blob: return ret; } -int get_asymmetric_key(const char *key_file, int private, - struct asymmetric_key **result) +int get_public_key(const char *key_file, struct asymmetric_key **result) { int ret, ret2; void *map; @@ -669,8 +668,6 @@ int get_asymmetric_key(const char *key_file, int private, gcry_sexp_t sexp; struct asymmetric_key *key; - if (private) - return get_private_key(key_file, result); ret = mmap_full_file(key_file, O_RDONLY, &map, &map_size, NULL); if (ret < 0) return ret; @@ -700,7 +697,7 @@ unmap: return ret; } -void free_asymmetric_key(struct asymmetric_key *key) +void free_public_key(struct asymmetric_key *key) { if (!key) return; @@ -832,7 +829,8 @@ in_mpi_release: key_release: gcry_sexp_release(priv_key); free_key: - free_asymmetric_key(priv); + gcry_sexp_release(priv->sexp); + free(priv); return ret; } diff --git a/user_list.c b/user_list.c index 9c751244..23fe086f 100644 --- a/user_list.c +++ b/user_list.c @@ -48,7 +48,7 @@ static void populate_user_list(char *user_list_file) if (strcmp(w, "user")) continue; PARA_DEBUG_LOG("found entry for user %s\n", n); - ret = get_asymmetric_key(k, LOAD_PUBLIC_KEY, &pubkey); + ret = get_public_key(k, &pubkey); if (ret < 0) { PARA_NOTICE_LOG("skipping entry for user %s: %s\n", n, para_strerror(-ret)); @@ -63,7 +63,7 @@ static void populate_user_list(char *user_list_file) if (ret <= CHALLENGE_SIZE + 2 * SESSION_KEY_LEN + 41) { PARA_WARNING_LOG("public key %s too short (%d)\n", k, ret); - free_asymmetric_key(pubkey); + free_public_key(pubkey); continue; } u = para_malloc(sizeof(*u)); @@ -114,7 +114,7 @@ void init_user_list(char *user_list_file) list_for_each_entry_safe(u, tmp, &user_list, node) { list_del(&u->node); free(u->name); - free_asymmetric_key(u->pubkey); + free_public_key(u->pubkey); free(u); } } else -- 2.39.2