From: Andre Noll <maan@tuebingen.mpg.de>
Date: Sun, 10 Jul 2016 20:23:45 +0000 (+0200)
Subject: crypto: Simplify asymetric key handling.
X-Git-Tag: v0.6.0~14^2~3
X-Git-Url: https://git.tuebingen.mpg.de/?a=commitdiff_plain;h=f553ab861efaa14f3a07ffb074c9e640b9fc776a;p=paraslash.git

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().
---

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