From d09716570fc81b71d6ad3d5f543b5f8acf1a5e33 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Mon, 28 Feb 2011 22:07:44 +0100 Subject: [PATCH] Replace RSA by an abstract asymmetric key structure. This declares the new structure asymmetric_key in crypt.h but does not define it. Instead, it is defined in crypt.c so that only the functions in this file can access the members of the structure directly. Functions which previously took an (openssl-specific) RSA pointer are changed to receive a pointer to struct asymmetric_key instead, removing the requirement to include an openssl header file before crypt.h can be included. --- client_common.c | 2 +- command.c | 2 +- crypt.c | 98 ++++++++++++++++++++++++++++--------------------- crypt.h | 19 ++++++---- user_list.c | 12 +++--- user_list.h | 10 ++--- 6 files changed, 81 insertions(+), 62 deletions(-) diff --git a/client_common.c b/client_common.c index a7115fd7..31bbc114 100644 --- a/client_common.c +++ b/client_common.c @@ -188,7 +188,7 @@ static void client_post_select(struct sched *s, struct task *t) if (ret < 0 || n == 0) goto out; PARA_INFO_LOG("<-- [challenge] (%zu bytes)\n", n); - ret = para_decrypt_buffer(ct->key_file, crypt_buf, + ret = priv_decrypt(ct->key_file, crypt_buf, (unsigned char *)buf, n); if (ret < 0) goto out; diff --git a/command.c b/command.c index 5217f9b4..688a039f 100644 --- a/command.c +++ b/command.c @@ -768,7 +768,7 @@ __noreturn void handle_connect(int fd, const char *peername) u = lookup_user(p); if (u) { get_random_bytes_or_die(rand_buf, sizeof(rand_buf)); - ret = para_encrypt_buffer(u->rsa, rand_buf, sizeof(rand_buf), + ret = pub_encrypt(u->pubkey, rand_buf, sizeof(rand_buf), (unsigned char *)buf); if (ret < 0) goto net_err; diff --git a/crypt.c b/crypt.c index cdcb6149..8986d0e7 100644 --- a/crypt.c +++ b/crypt.c @@ -4,7 +4,7 @@ * Licensed under the GPL v2. For licencing details see COPYING. */ -/** \file crypt.c openssl-based RSA encryption/decryption routines */ +/** \file crypt.c Openssl-based encryption/decryption routines. */ #include #include @@ -13,12 +13,18 @@ #include #include #include +#include #include "para.h" #include "error.h" #include "string.h" #include "crypt.h" #include "fd.h" + +struct asymmetric_key { + RSA *rsa; +}; + /** * Fill a buffer with random content. * @@ -102,50 +108,58 @@ static EVP_PKEY *load_key(const char *file, int private) } /** - * read an RSA key from a file + * Read an asymmetric key from a file. * - * \param key_file the file containing the key - * \param rsa RSA structure is returned here - * \param private if non-zero, read the private key, otherwise the public key + * \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 RSA key on success, negative on errors. + * \return The size of the key on success, negative on errors. * * \sa openssl(1), rsa(1). */ -int get_rsa_key(char *key_file, RSA **rsa, int private) +int get_asymmetric_key(const char *key_file, int private, + struct asymmetric_key **result) { - EVP_PKEY *key = load_key(key_file, private); + struct asymmetric_key *key; + RSA *rsa; + EVP_PKEY *pkey = load_key(key_file, private); - if (!key) + if (!pkey) return (private == LOAD_PRIVATE_KEY)? -E_PRIVATE_KEY : -E_PUBLIC_KEY; - *rsa = EVP_PKEY_get1_RSA(key); - EVP_PKEY_free(key); - if (!*rsa) + rsa = EVP_PKEY_get1_RSA(pkey); + EVP_PKEY_free(pkey); + if (!rsa) return -E_RSA; - return RSA_size(*rsa); + key = para_malloc(sizeof(*key)); + key->rsa = rsa; + *result = key; + return RSA_size(rsa); } /** - * free an RSA structure + * Deallocate an asymmetric key structure. * - * \param rsa pointer to the RSA struct to free + * \param key Pointer to the key structure to free. * - * This must be called for any key obtained by get_rsa_key(). + * This must be called for any key obtained by get_asymmetric_key(). */ -void rsa_free(RSA *rsa) +void free_asymmetric_key(struct asymmetric_key *key) { - if (rsa) - RSA_free(rsa); + if (!key) + return; + RSA_free(key->rsa); + free(key); } /** - * decrypt a buffer using an RSA key + * Decrypt a buffer using a private key. * - * \param key_file full path of the rsa key - * \param outbuf the output buffer - * \param inbuf the encrypted input buffer - * \param rsa_inlen the length of \a inbuf + * \param key_file Full path of the key. + * \param outbuf The output buffer. + * \param inbuf The encrypted input buffer. + * \param inlen The length of \a inbuf in bytes. * * The \a outbuf must be large enough to hold at least \a rsa_inlen bytes. * @@ -153,15 +167,15 @@ void rsa_free(RSA *rsa) * * \sa RSA_private_decrypt(3) **/ -int para_decrypt_buffer(char *key_file, unsigned char *outbuf, unsigned char *inbuf, - unsigned rsa_inlen) +int priv_decrypt(const char *key_file, unsigned char *outbuf, + unsigned char *inbuf, int inlen) { - RSA *rsa; - int ret, inlen = rsa_inlen; + struct asymmetric_key *priv; + int ret; if (inlen < 0) return -E_RSA; - ret = get_rsa_key(key_file, &rsa, LOAD_PRIVATE_KEY); + ret = get_asymmetric_key(key_file, LOAD_PRIVATE_KEY, &priv); if (ret < 0) return ret; /* @@ -169,37 +183,39 @@ int para_decrypt_buffer(char *key_file, unsigned char *outbuf, unsigned char *in * factor to protect against this kind of attack. */ ret = -E_BLINDING; - if (RSA_blinding_on(rsa, NULL) == 0) + if (RSA_blinding_on(priv->rsa, NULL) == 0) goto out; - ret = RSA_private_decrypt(inlen, inbuf, outbuf, rsa, RSA_PKCS1_OAEP_PADDING); - RSA_blinding_off(rsa); + ret = RSA_private_decrypt(inlen, inbuf, outbuf, priv->rsa, + RSA_PKCS1_OAEP_PADDING); + RSA_blinding_off(priv->rsa); if (ret <= 0) ret = -E_DECRYPT; out: - rsa_free(rsa); + free_asymmetric_key(priv); return ret; } /** - * encrypt a buffer using an RSA key + * Encrypt a buffer using an RSA key * - * \param rsa: public rsa key - * \param inbuf the input buffer - * \param len the length of \a inbuf - * \param outbuf the output buffer + * \param pub: The public key. + * \param inbuf The input buffer. + * \param len The length of \a inbuf. + * \param outbuf The output buffer. * - * \return The size of the encrypted data on success, negative on errors + * \return The size of the encrypted data on success, negative on errors. * * \sa RSA_public_encrypt(3) */ -int para_encrypt_buffer(RSA *rsa, unsigned char *inbuf, +int pub_encrypt(struct asymmetric_key *pub, unsigned char *inbuf, unsigned len, unsigned char *outbuf) { int ret, flen = len; /* RSA_public_encrypt expects a signed int */ if (flen < 0) return -E_ENCRYPT; - ret = RSA_public_encrypt(flen, inbuf, outbuf, rsa, RSA_PKCS1_OAEP_PADDING); + ret = RSA_public_encrypt(flen, inbuf, outbuf, pub->rsa, + RSA_PKCS1_OAEP_PADDING); return ret < 0? -E_ENCRYPT : ret; } diff --git a/crypt.h b/crypt.h index 6bd8179b..898e3446 100644 --- a/crypt.h +++ b/crypt.h @@ -4,16 +4,19 @@ * Licensed under the GPL v2. For licencing details see COPYING. */ -/** \file crypt.h prototypes for the RSA crypt functions */ +/** \file crypt.h Prototypes for paraslash crypto functions. */ -#include -int para_encrypt_buffer(RSA* rsa, unsigned char *inbuf, unsigned len, - unsigned char *outbuf); -int para_decrypt_buffer(char *key_file, unsigned char *outbuf, unsigned char *inbuf, - unsigned rsa_inlen); -int get_rsa_key(char *key_file, RSA **rsa, int private); +/** Opaque structure for public and private keys. */ +struct asymmetric_key; + +int pub_encrypt(struct asymmetric_key *pub, unsigned char *inbuf, + unsigned len, unsigned char *outbuf); +int priv_decrypt(const char *key_file, unsigned char *outbuf, + unsigned char *inbuf, int inlen); +int get_asymmetric_key(const char *key_file, int private, + struct asymmetric_key **result); +void free_asymmetric_key(struct asymmetric_key *key); -void rsa_free(RSA *rsa); void get_random_bytes_or_die(unsigned char *buf, int num); void init_random_seed_or_die(void); diff --git a/user_list.c b/user_list.c index fe1b946b..4696a669 100644 --- a/user_list.c +++ b/user_list.c @@ -41,7 +41,7 @@ static void populate_user_list(char *user_list_file) /* keyword, name, key, perms */ char w[255], n[255], k[255], p[255], tmp[4][255]; struct user *u; - RSA *rsa; + struct asymmetric_key *pubkey; ret = para_fgets(line, sizeof(line), file_ptr); if (ret <= 0) @@ -51,7 +51,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_rsa_key(k, &rsa, LOAD_PUBLIC_KEY); + ret = get_asymmetric_key(k, LOAD_PUBLIC_KEY, &pubkey); if (ret < 0) { PARA_NOTICE_LOG("skipping entry for user %s: %s\n", n, para_strerror(-ret)); @@ -64,14 +64,14 @@ static void populate_user_list(char *user_list_file) * which are too short. For details see RSA_public_encrypt(3). */ if (ret <= CHALLENGE_SIZE + 2 * RC4_KEY_LEN + 41) { - PARA_WARNING_LOG("rsa key %s too short (%d)\n", + PARA_WARNING_LOG("public key %s too short (%d)\n", k, ret); - rsa_free(rsa); + free_asymmetric_key(pubkey); continue; } u = para_malloc(sizeof(*u)); u->name = para_strdup(n); - u->rsa = rsa; + u->pubkey = pubkey; u->perms = 0; num = sscanf(p, "%200[A-Z_],%200[A-Z_],%200[A-Z_],%200[A-Z_]", tmp[0], tmp[1], tmp[2], tmp[3]); @@ -117,7 +117,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); - rsa_free(u->rsa); + free_asymmetric_key(u->pubkey); free(u); } } else diff --git a/user_list.h b/user_list.h index cce577a6..68fa21b2 100644 --- a/user_list.h +++ b/user_list.h @@ -20,13 +20,13 @@ enum {AFS_READ = 1, AFS_WRITE = 2, VSS_READ = 4, VSS_WRITE = 8}; * data needed to authenticate the user */ struct user { - /** the position of this user in the list of users */ + /** The position of this user in the list of users. */ struct list_head node; - /** the username */ + /** The username. */ char *name; - /** the public RSA key */ - RSA *rsa; - /** the privileges that this user has */ + /** The public key. */ + struct asymmetric_key *pubkey; + /** The privileges of this user. */ unsigned int perms; }; -- 2.30.2