X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=crypt.c;h=a19b5ac31f98331ea136c9a8d8bebcadcd006ee4;hp=653b1a2452cdc85215d916c1abd35f641800dcf1;hb=78882bd94652b156e55e6385a33cd5126c439651;hpb=ade45974506ffedcd057f336fbcf71941d77b09c diff --git a/crypt.c b/crypt.c index 653b1a24..a19b5ac3 100644 --- a/crypt.c +++ b/crypt.c @@ -1,32 +1,15 @@ /* - * Copyright (C) 2005-2006 Andre Noll + * Copyright (C) 2005-2008 Andre Noll * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Licensed under the GPL v2. For licencing details see COPYING. */ /** \file crypt.c openssl-based RSA encryption/decryption routines */ -#include #include "para.h" #include "error.h" #include "string.h" - -/** \cond used to distinguish between loading of private/public key */ -#define LOAD_PUBLIC_KEY 0 -#define LOAD_PRIVATE_KEY 1 -/** \endcond **/ +#include "crypt.h" static EVP_PKEY *load_key(const char *file, int private) { @@ -46,12 +29,24 @@ static EVP_PKEY *load_key(const char *file, int private) return pkey; } -static int get_key(char *key_file, RSA **rsa, int private) +/** + * read an RSA 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 + * + * \return The size of the RSA key on success, negative on errors. + * + * \sa openssl(1), rsa(1). + */ +int get_rsa_key(char *key_file, RSA **rsa, int private) { EVP_PKEY *key = load_key(key_file, private); if (!key) - return (private == LOAD_PRIVATE_KEY)? -E_PRIVATE_KEY : -E_PUBLIC_KEY; + return (private == LOAD_PRIVATE_KEY)? -E_PRIVATE_KEY + : -E_PUBLIC_KEY; *rsa = EVP_PKEY_get1_RSA(key); EVP_PKEY_free(key); if (!*rsa) @@ -59,6 +54,19 @@ static int get_key(char *key_file, RSA **rsa, int private) return RSA_size(*rsa); } +/** + * free an RSA structure + * + * \param rsa pointer to the RSA struct to free + * + * This must be called for any key obtained by get_rsa_key(). + */ +void rsa_free(RSA *rsa) +{ + if (rsa) + RSA_free(rsa); +} + /** * decrypt a buffer using an RSA key * @@ -74,14 +82,18 @@ static int get_key(char *key_file, RSA **rsa, int private) * \sa RSA_private_decrypt(3) **/ int para_decrypt_buffer(char *key_file, unsigned char *outbuf, unsigned char *inbuf, - int rsa_inlen) + unsigned rsa_inlen) { RSA *rsa; - int ret = get_key(key_file, &rsa, LOAD_PRIVATE_KEY); + int ret, inlen = rsa_inlen; + if (inlen < 0) + return -E_RSA; + ret = get_rsa_key(key_file, &rsa, LOAD_PRIVATE_KEY); if (ret < 0) return ret; - ret = RSA_private_decrypt(rsa_inlen, inbuf, outbuf, rsa, RSA_PKCS1_PADDING); + ret = RSA_private_decrypt(inlen, inbuf, outbuf, rsa, RSA_PKCS1_PADDING); + rsa_free(rsa); return (ret > 0)? ret : -E_DECRYPT; } @@ -98,7 +110,7 @@ int para_decrypt_buffer(char *key_file, unsigned char *outbuf, unsigned char *in * \sa para_decrypt_buffer() */ int para_decrypt_challenge(char *key_file, long unsigned *challenge_nr, - unsigned char *inbuf, int rsa_inlen) + unsigned char *inbuf, unsigned rsa_inlen) { unsigned char *rsa_out = OPENSSL_malloc(rsa_inlen + 1); int ret = para_decrypt_buffer(key_file, rsa_out, inbuf, rsa_inlen); @@ -115,7 +127,7 @@ int para_decrypt_challenge(char *key_file, long unsigned *challenge_nr, /** * encrypt a buffer using an RSA key * - * \param key_file full path of the rsa key + * \param rsa: public rsa key * \param inbuf the input buffer * \param len the length of \a inbuf * \param outbuf the output buffer @@ -124,22 +136,21 @@ int para_decrypt_challenge(char *key_file, long unsigned *challenge_nr, * * \sa RSA_public_encrypt(3) */ -int para_encrypt_buffer(char *key_file, unsigned char *inbuf, - const unsigned len, unsigned char *outbuf) +int para_encrypt_buffer(RSA *rsa, unsigned char *inbuf, + unsigned len, unsigned char *outbuf) { - RSA *rsa; - int ret = get_key(key_file, &rsa, LOAD_PUBLIC_KEY); + int ret, flen = len; /* RSA_public_encrypt expects a signed int */ - if (ret < 0) - return ret; - ret = RSA_public_encrypt(len, inbuf, outbuf, rsa, RSA_PKCS1_PADDING); + if (flen < 0) + return -E_ENCRYPT; + ret = RSA_public_encrypt(flen, inbuf, outbuf, rsa, RSA_PKCS1_PADDING); return ret < 0? -E_ENCRYPT : ret; } /** * encrypt the given challenge number * - * \param key_file full path of the rsa key + * \param rsa: public rsa key * \param challenge_nr the number to be encrypted * \param outbuf the output buffer * @@ -150,11 +161,11 @@ int para_encrypt_buffer(char *key_file, unsigned char *inbuf, * \sa para_encrypt_buffer() * */ -int para_encrypt_challenge(char *key_file, long unsigned challenge_nr, +int para_encrypt_challenge(RSA* rsa, long unsigned challenge_nr, unsigned char *outbuf) { unsigned char *inbuf = (unsigned char*) make_message("%lu", challenge_nr); - int ret = para_encrypt_buffer(key_file, inbuf, strlen((char *)inbuf), outbuf); + int ret = para_encrypt_buffer(rsa, inbuf, strlen((char *)inbuf), outbuf); free(inbuf); return ret; }