+ * gpgme_op_encrypt can be called with RECIPIENTS being 0. In this
+ case, symmetric encryption is performed. Note that this requires a
+ passphrase from the user.
+
+ * Interface changes relative to the 0.3.4 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+gpgme_op_encrypt EXTENDED: Symmetric encryption possible
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
Noteworthy changes in version 0.3.4 (2002-03-04)
------------------------------------------------
+2002-03-06 Marcus Brinkmann <marcus@g10code.de>
+
+ * gpgme.texi (Encrypting a Plaintext): Document symmetric
+ encryption.
+
2002-03-06 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Error Strings): Add example.
information about the invalid recipients is available with
@code{gpgme_get_op_info}. @xref{Detailed Results}.
+If @var{recp} is @code{NULL}, symmetric rather than public key
+encryption is performed. Symmetrically encrypted cipher text can be
+deciphered with @code{gpgme_op_decrypt}. Note that in this case the
+crypto backend needs to retrieve a passphrase from the user.
+Symmetric encryption is currently only supported for the OpenPGP
+crypto backend.
+
The function returns @code{GPGME_No_Error} if the ciphertext could be
created successfully, @code{GPGME_Invalid_Value} if @var{ctx},
@var{rset}, @var{plain} or @var{cipher} is not a valid pointer,
+2002-03-06 Marcus Brinkmann <marcus@g10code.de>
+
+ * encrypt.c (_gpgme_encrypt_sym_status_handler): New function.
+ (gpgme_op_encrypt_start): New variable SYMMETRIC, set it if RECP
+ is null, and if it is set, use _gpgme_encrypt_sym_status_handler
+ as status handler and run _gpgme_passphrase_start.
+ * rungpg.c (_gpgme_gpg_op_encrypt): If RECP is zero, do symmetric
+ encryption.
+ * engine-gpgsm.c (_gpgme_gpgsm_op_encrypt): If RECP is zero,
+ return error value.
+
+ * rungpg.c (_gpgme_gpg_op_verify): Add "--" argument.
+
2002-03-03 Marcus Brinkmann <marcus@g10code.de>
* passphrase.c (_gpgme_passphrase_status_handler): Also set the
}
+void
+_gpgme_encrypt_sym_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
+{
+ _gpgme_passphrase_status_handler (ctx, code, args);
+}
+
+
GpgmeError
gpgme_op_encrypt_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData plain,
GpgmeData ciph)
{
int err = 0;
+ int symmetric = 0;
fail_on_pending_request (ctx);
ctx->pending = 1;
_gpgme_release_result (ctx);
/* Do some checks. */
- if (!gpgme_recipients_count (recp))
+ if (!recp)
+ symmetric = 1;
+ else if (!gpgme_recipients_count (recp))
{
- /* Fixme: In this case we should do symmentric encryption. */
err = mk_error (No_Recipients);
goto leave;
}
if (err)
goto leave;
- _gpgme_engine_set_status_handler (ctx->engine, _gpgme_encrypt_status_handler,
+ if (symmetric)
+ {
+ err = _gpgme_passphrase_start (ctx);
+ if (err)
+ goto leave;
+ }
+
+ _gpgme_engine_set_status_handler (ctx->engine,
+ symmetric
+ ? _gpgme_encrypt_sym_status_handler
+ : _gpgme_encrypt_status_handler,
ctx);
_gpgme_engine_set_verbosity (ctx->engine, ctx->verbosity);
if (!gpgsm)
return mk_error (Invalid_Value);
+ if (!recp)
+ return mk_error (Not_Implemented);
gpgsm->command = xtrystrdup ("ENCRYPT");
if (!gpgsm->command)
GpgmeData plain, GpgmeData ciph, int use_armor)
{
GpgmeError err;
+ int symmetric = !recp;
+
+ err = _gpgme_gpg_add_arg (gpg, symmetric ? "--symmetric" : "--encrypt");
- err = _gpgme_gpg_add_arg (gpg, "--encrypt");
if (!err && use_armor)
err = _gpgme_gpg_add_arg (gpg, "--armor");
- /* If we know that all recipients are valid (full or ultimate trust)
- * we can suppress further checks */
- if (!err && _gpgme_recipients_all_valid (recp))
- err = _gpgme_gpg_add_arg (gpg, "--always-trust");
+ if (!symmetric)
+ {
+ /* If we know that all recipients are valid (full or ultimate trust)
+ we can suppress further checks. */
+ if (!err && !symmetric && _gpgme_recipients_all_valid (recp))
+ err = _gpgme_gpg_add_arg (gpg, "--always-trust");
- if (!err)
- err = _gpgme_append_gpg_args_from_recipients (gpg, recp);
+ if (!err)
+ err = _gpgme_append_gpg_args_from_recipients (gpg, recp);
+ }
/* Tell the gpg object about the data. */
if (!err)
err = _gpgme_gpg_add_arg (gpg, "--output");
if (!err)
err = _gpgme_gpg_add_arg (gpg, "-");
+ if (!err)
+ err = _gpgme_gpg_add_arg (gpg, "--");
if (!err)
err = _gpgme_gpg_add_data (gpg, sig, 0);
if (!err)
+2002-03-06 Marcus Brinkmann <marcus@g10code.de>
+
+ * gpg/t-encrypt-sym.c: New file.
+ * gpg/Makefile.am (TESTS): Add t-encrypt-sym.
+
2002-03-05 Marcus Brinkmann <marcus@g10code.de>
* gpg/Makefile.am (CLEANFILES): Remove random_seed, which is now
TESTS_ENVIRONMENT = GNUPGHOME=.
-TESTS = t-encrypt t-encrypt-sign t-sign t-signers t-decrypt t-verify \
- t-decrypt-verify t-keylist t-export t-import t-trustlist
+TESTS = t-encrypt t-encrypt-sym t-encrypt-sign t-sign t-signers \
+ t-decrypt t-verify t-decrypt-verify t-keylist t-export \
+ t-import t-trustlist
CLEANFILES = secring.gpg pubring.gpg trustdb.gpg
DISTCLEANFILES = pubring.gpg~ random_seed
--- /dev/null
+/* t-encrypt.c - regression test
+ * Copyright (C) 2000 Werner Koch (dd9jn)
+ * Copyright (C) 2001 g10 Code GmbH
+ *
+ * This file is part of GPGME.
+ *
+ * GPGME 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.
+ *
+ * GPGME 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-1307, USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <gpgme.h>
+
+#define fail_if_err(a) do { if(a) { \
+ fprintf (stderr, "%s:%d: GpgmeError %s\n", \
+ __FILE__, __LINE__, gpgme_strerror(a)); \
+ exit (1); } \
+ } while(0)
+
+static void
+print_data (GpgmeData dh)
+{
+ char buf[100];
+ size_t nread;
+ GpgmeError err;
+
+ err = gpgme_data_rewind (dh);
+ fail_if_err (err);
+ while (!(err = gpgme_data_read (dh, buf, 100, &nread)))
+ fwrite ( buf, nread, 1, stdout );
+ if (err != GPGME_EOF)
+ fail_if_err (err);
+}
+
+
+static const char *
+passphrase_cb ( void *opaque, const char *desc, void **r_hd )
+{
+ const char *pass;
+
+ if ( !desc ) {
+ /* cleanup by looking at *r_hd */
+
+
+ return NULL;
+ }
+
+ pass = "abc";
+ fprintf (stderr, "%% requesting passphrase for `%s': ", desc );
+ fprintf (stderr, "sending `%s'\n", pass );
+
+ return pass;
+}
+
+
+int
+main (int argc, char **argv)
+{
+ GpgmeCtx ctx;
+ GpgmeError err;
+ GpgmeData plain, cipher;
+ const char *text = "Hallo Leute\n";
+ char *text2;
+ int i;
+
+ err = gpgme_check_engine ();
+ fail_if_err (err);
+
+ do
+ {
+ err = gpgme_new (&ctx);
+ fail_if_err (err);
+ gpgme_set_armor (ctx, 1);
+ if (!getenv("GPG_AGENT_INFO"))
+ gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL);
+
+ err = gpgme_data_new_from_mem (&plain, text, strlen (text), 0);
+ fail_if_err (err);
+
+ err = gpgme_data_new (&cipher);
+ fail_if_err (err);
+
+ err = gpgme_op_encrypt (ctx, 0, plain, cipher);
+ fail_if_err (err);
+
+ fflush (NULL);
+ fputs ("Begin Result Encryption:\n", stdout);
+ print_data (cipher);
+ fputs ("End Result.\n", stdout);
+
+ err = gpgme_data_rewind (cipher);
+ fail_if_err (err);
+
+ gpgme_data_release (plain);
+ err = gpgme_data_new (&plain);
+ fail_if_err (err);
+
+ err = gpgme_op_decrypt (ctx, cipher, plain);
+ fail_if_err (err);
+
+ fputs ("Begin Result Decryption:\n", stdout);
+ print_data (plain);
+ fputs ("End Result.\n", stdout);
+
+ text2 = gpgme_data_release_and_get_mem (plain, &i);
+ if (strncmp (text, text2, i))
+ {
+ fprintf (stderr, "%s:%d: Wrong plaintext\n", __FILE__, __LINE__);
+ exit (1);
+ }
+
+ gpgme_data_release (cipher);
+ gpgme_release (ctx);
+ }
+ while (argc > 1 && !strcmp (argv[1], "--loop"));
+
+ return 0;
+}
+
+