Fixed configure.ac again (I broke it with my last change). Added first cut at gpg decryption routine.

git-svn-id: file:///home/mbr/svn/fwknop/trunk@45 510a4753-2344-4c79-9c09-4d669213fbeb
This commit is contained in:
Damien Stuart 2009-01-26 03:39:47 +00:00
parent 54e1f22a80
commit 10b308b2d5
4 changed files with 166 additions and 21 deletions

View File

@ -56,33 +56,23 @@ AC_CHECK_FUNCS([bzero gettimeofday memmove memset strchr strcspn strdup strndup
# Check for gpgme
#AM_PATH_GPGME
#GPGME_SUPPORT="yes"
AC_ARG_WITH([gpgme],
[AS_HELP_STRING([--with-gpgme],
[support for gpg encryption using libgpgme @<:@default=check@:>@])],
[],
[with_gpgme=check])
LIBGPGME=
have_gpgme=yes
AS_IF([test "x$with_gpgme" != xno],
[AC_CHECK_LIB([gpgme], [gpgme_check_version],
[AC_SUBST([LIBGPGME], ["-lgpgme"])
AC_DEFINE([HAVE_LIBGPGME], [1],
[Define if you have libgpgme])
],
[],
[if test "x$with_gpgme" != xcheck; then
AC_MSG_FAILURE(
[--with-gpgme was given, but test for gpgme failed])
else
have_gpgme=no
fi
])])
have_gpgme=
if test "x$LIBGPGME" == "x"; then
have_gpgme=no
else
have_gpgme=yes
fi
])], [have_gpgme=no])
AC_CONFIG_FILES([Makefile
fko/Makefile

View File

@ -208,6 +208,53 @@ _gpg_encrypt(fko_ctx_t ctx, const char *enc_key)
return(FKO_SUCCESS);
}
/* Prep and encrypt using gpgme
*/
int
_gpg_decrypt(fko_ctx_t ctx, const char *dec_key, int b64_len)
{
unsigned char *cipher;
size_t cipher_len, pt_len;
/* First make sure we have signer and recipient keys set.
if(ctx->gpg_signer == NULL || ctx->gpg_recipient == NULL)
return(FKO_ERROR_MISSING_GPG_KEY_DATA);
*/
/* Create a bucket for the (base64) decoded encrypted data and get the
* raw cipher data.
*/
cipher = malloc(strlen(ctx->encrypted_msg));
if(cipher == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
cipher_len = b64_decode(ctx->encrypted_msg, cipher, b64_len);
/* Create a bucket for the plaintext data and decrypt the message
* data into it.
*/
ctx->encoded_msg = malloc(cipher_len);
if(ctx->encoded_msg == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
pt_len = gpgme_decrypt(cipher, cipher_len,
ctx->gpg_signer, ctx->gpg_recipient,
dec_key, (unsigned char**)&ctx->encoded_msg, &cipher_len
);
/* Done with cipher...
*/
free(cipher);
/* XXX: We could put some kind of sanity check of the decrypted
* data here
*/
/* Call fko_decode and return the results.
*/
return(fko_decode_spa_data(ctx));
}
#endif /* HAVE_LIBGPGME */
/* Set the SPA encryption type.
@ -314,8 +361,7 @@ fko_decrypt_spa_data(fko_ctx_t ctx, const char *dec_key)
{
ctx->encryption_type = FKO_ENCRYPTION_GPG;
#if HAVE_LIBGPGME
return(FKO_ERROR_UNSUPPORTED_FEATURE);
//return(_gpg_decrypt(ctx, dec_key));
return(_gpg_decrypt(ctx, dec_key, b64_len));
#else
return(FKO_ERROR_UNSUPPORTED_FEATURE);
#endif

View File

@ -28,17 +28,17 @@
#if HAVE_LIBGPGME
//#include <locale.h>
#include <gpgme.h>
#include "gpgme_funcs.h"
/* Callback function that supplies the password when gpgme needs it.
*/
gpgme_error_t
get_gpg_pw(
passphrase_cb(
void *hook, const char *uid_hint, const char *passphrase_info,
int prev_was_bad, int fd)
{
/* We only need to try once as it is fed by the program
* (for now --DSS).
*/
@ -250,7 +250,7 @@ gpgme_encrypt(
/* Set the passphrase callback.
*/
gpgme_set_passphrase_cb(gpg_ctx, get_gpg_pw, pw);
gpgme_set_passphrase_cb(gpg_ctx, passphrase_cb, (void*)pw);
err = gpgme_op_encrypt_sign(gpg_ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST, plaintext, data);
if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
@ -261,6 +261,8 @@ gpgme_encrypt(
return(gpg_err_code(err));
}
gpgme_data_release(plaintext);
/* Get the encrypted data and its length from the gpgme data object.
*/
tmp_buf = gpgme_data_release_and_get_mem(data, out_len);
@ -282,6 +284,113 @@ gpgme_encrypt(
return(res);
}
/* The main GPG encryption routine for libfko.
*/
int
gpgme_decrypt(
unsigned char *indata, size_t in_len, const char *signer, const char *recip,
const char *pw, unsigned char **out, size_t *out_len)
{
char *tmp_buf;
int res;
gpgme_ctx_t gpg_ctx;
gpgme_error_t err;
gpgme_data_t cipher, plaintext;
gpgme_decrypt_result_t decrypt_result;
gpgme_verify_result_t verify_result;
/* Because the gpgme manual says you should.
*/
gpgme_check_version(NULL);
//setlocale(LC_ALL, "");
//gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL));
/* Check for OpenPGP support
*/
err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
{
/* GPG engine is not available. */
return(gpg_err_code(err));
}
/* Create our gpgme context
*/
err = gpgme_new(&gpg_ctx);
if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
{
return(gpg_err_code(err));
}
//gpgme_set_armor(gpg_ctx, 0);
err = gpgme_data_new(&plaintext);
if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
{
gpgme_release(gpg_ctx);
return(gpg_err_code(err));
}
/* Initialize the cipher data (place into gpgme_data object)
*/
err = gpgme_data_new_from_mem(&cipher, (char*)indata, in_len, 0);
if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
{
gpgme_release(gpg_ctx);
return(gpg_err_code(err));
}
/* Set the passphrase callback.
*/
gpgme_set_passphrase_cb(gpg_ctx, passphrase_cb, (void*)pw);
/* Now decrypt and verify.
*/
err = gpgme_op_decrypt_verify(gpg_ctx, cipher, plaintext);
if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
{
gpgme_release(gpg_ctx);
return(gpg_err_code(err));
}
gpgme_data_release(cipher);
decrypt_result = gpgme_op_decrypt_result (gpg_ctx);
/* TODO: Do something with this (like the sample below)
if (decrypt_result->unsupported_algorithm)
{
fprintf (stderr, "%s:%i: unsupported algorithm: %s\n",
__FILE__, __LINE__, decrypt_result->unsupported_algorithm);
}
*/
verify_result = gpgme_op_verify_result (gpg_ctx);
//TODO: Do something with this too (or not)
/* Get the encrypted data and its length from the gpgme data object.
*/
tmp_buf = gpgme_data_release_and_get_mem(plaintext, out_len);
*out = malloc(*out_len); /* Note: this is freed when the context is destroyed */
if(*out == NULL)
{
res = -2;
}
else
{
res = 0;
memcpy(*out, tmp_buf, *out_len);
}
gpgme_free(tmp_buf);
gpgme_release(gpg_ctx);
return(res);
}
#endif /* HAVE_LIBGPGME */
/***EOF***/

View File

@ -27,7 +27,7 @@
#include "fko_common.h"
int gpgme_encrypt(unsigned char *in, size_t len, const char *signer, const char *recip, const char *pw, unsigned char **out, size_t *out_len);
int gpgme_decrypt(unsigned char *in, size_t len, const char *pw, unsigned char **out, size_t *out_len);
int gpgme_decrypt(unsigned char *in, size_t len, const char *signer, const char *recip, const char *pw, unsigned char **out, size_t *out_len);
#endif /* GPGME_FUNCS_H */