diff options
Diffstat (limited to '')
| -rw-r--r-- | gpgme/Makefile.am | 1 | ||||
| -rw-r--r-- | gpgme/context.h | 2 | ||||
| -rw-r--r-- | gpgme/data.c | 139 | ||||
| -rw-r--r-- | gpgme/decrypt.c | 194 | ||||
| -rw-r--r-- | gpgme/gpgme.c | 3 | ||||
| -rw-r--r-- | gpgme/gpgme.h | 17 | ||||
| -rw-r--r-- | gpgme/key.c | 2 | ||||
| -rw-r--r-- | gpgme/ops.h | 3 | ||||
| -rw-r--r-- | gpgme/types.h | 4 | ||||
| -rw-r--r-- | gpgme/verify.c | 2 | ||||
| -rw-r--r-- | tests/Makefile.am | 4 | ||||
| -rw-r--r-- | tests/cipher-1.asc | 15 | ||||
| -rw-r--r-- | tests/t-decrypt.c | 88 | ||||
| -rw-r--r-- | tests/t-encrypt.c | 4 | ||||
| -rw-r--r-- | tests/t-verify.c | 9 | 
15 files changed, 452 insertions, 35 deletions
| diff --git a/gpgme/Makefile.am b/gpgme/Makefile.am index 547dcd44..d8f29b64 100644 --- a/gpgme/Makefile.am +++ b/gpgme/Makefile.am @@ -18,6 +18,7 @@ libgpgme_la_SOURCES = \  	data.c recipient.c \          wait.c wait.h \  	encrypt.c \ +	decrypt.c \  	verify.c \          key.c key.h \  	keylist.c \ diff --git a/gpgme/context.h b/gpgme/context.h index c0eec458..53773f67 100644 --- a/gpgme/context.h +++ b/gpgme/context.h @@ -28,6 +28,7 @@  typedef enum {      RESULT_TYPE_NONE = 0,      RESULT_TYPE_VERIFY, +    RESULT_TYPE_DECRYPT,  } ResultType; @@ -58,6 +59,7 @@ struct gpgme_context_s {      ResultType result_type;      union {          VerifyResult verify; +        DecryptResult decrypt;      } result;      GpgmeData notation;    /* last signature notation */ diff --git a/gpgme/data.c b/gpgme/data.c index de9c6323..4a8f6ed5 100644 --- a/gpgme/data.c +++ b/gpgme/data.c @@ -22,6 +22,10 @@  #include <stdio.h>  #include <stdlib.h>  #include <assert.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h>  #include "util.h"  #include "context.h" @@ -34,15 +38,31 @@                           || ((a) >= 'f' && (a) <= 'f') ) +GpgmeError +gpgme_data_new ( GpgmeData *r_dh ) +{ +    GpgmeData dh; + +    if (!r_dh) +        return mk_error (Invalid_Value); +    *r_dh = NULL; +    dh = xtrycalloc ( 1, sizeof *dh ); +    if (!dh) +        return mk_error (Out_Of_Core); +    dh->mode = GPGME_DATA_MODE_INOUT;  +    *r_dh = dh; +    return 0; +} +  /** - * gpgme_data_new: + * gpgme_data_new_from_mem:   * @r_dh:   Returns a new data object. - * @buffer: If not NULL, used to initialize the data object. + * @buffer: Initialize with this.   * @size: Size of the buffer   * @copy: Flag wether a copy of the buffer should be used.   *  - * Create a new data object and optionally initialize with data + * Create a new data object and initialize with data   * from the memory.  A @copy with value %TRUE creates a copy of the   * memory, a value of %FALSE uses the original memory of @buffer and the   * caller has to make sure that this buffer is valid until gpgme_release_data() @@ -51,37 +71,108 @@   * Return value:    **/  GpgmeError -gpgme_data_new ( GpgmeData *r_dh, const char *buffer, size_t size, int copy ) +gpgme_data_new_from_mem ( GpgmeData *r_dh, +                          const char *buffer, size_t size, int copy )  {      GpgmeData dh; +    GpgmeError err; +    if (!r_dh || !buffer) +        return mk_error (Invalid_Value);      *r_dh = NULL; -    dh = xtrycalloc ( 1, sizeof *dh ); -    if (!dh) -        return mk_error (Out_Of_Core); -    if ( buffer ) { -        dh->len  = size; -        if (copy) { -            dh->private_buffer = xtrymalloc ( size ); -            if ( !dh->private_buffer ) { -                xfree (dh); -                return mk_error (Out_Of_Core); -            } -            dh->private_len = size; -            memcpy (dh->private_buffer, buffer, size ); -            dh->data = dh->private_buffer; -            dh->writepos = size; -        } -        else { -            dh->data = buffer; +    err = gpgme_data_new ( &dh ); +    if (err) +        return err; +    dh->len  = size; +    if (copy) { +        dh->private_buffer = xtrymalloc ( size ); +        if ( !dh->private_buffer ) { +            gpgme_data_release (dh); +            return mk_error (Out_Of_Core);          } -        dh->type = GPGME_DATA_TYPE_MEM; +        dh->private_len = size; +        memcpy (dh->private_buffer, buffer, size ); +        dh->data = dh->private_buffer; +        dh->writepos = size;      } -    dh->mode = GPGME_DATA_MODE_INOUT;  +    else { +        dh->data = buffer; +    } +    dh->type = GPGME_DATA_TYPE_MEM; +          *r_dh = dh;      return 0;  } +GpgmeError +gpgme_data_new_from_file ( GpgmeData *r_dh, const char *fname, int copy ) +{ +    GpgmeData dh; +    GpgmeError err; +    struct stat st; +    FILE *fp; + +    if (!r_dh) +        return mk_error (Invalid_Value); +    *r_dh = NULL; +    /* We only support copy for now - in future we might want to honor the  +     * copy flag and just store a file pointer */ +    if (!copy) +        return mk_error (Not_Implemented); +    if (!fname) +        return mk_error (Invalid_Value); + +    err = gpgme_data_new ( &dh ); +    if (err) +        return err; + +    fp = fopen (fname, "rb"); +    if (!fp) { +        int save_errno = errno; +        gpgme_data_release (dh); +        errno = save_errno; +        return mk_error (File_Error); +    } + +    if( fstat(fileno(fp), &st) ) { +        int save_errno = errno; +        fclose (fp); +        gpgme_data_release (dh); +        errno = save_errno; +        return mk_error (File_Error); +    } + +    /* We should check the length of the file and don't allow for to +     * large files */ +    dh->private_buffer = xtrymalloc ( st.st_size ); +    if ( !dh->private_buffer ) { +        fclose (fp); +        gpgme_data_release (dh); +        return mk_error (Out_Of_Core); +    } +    dh->private_len = st.st_size; + +    if ( fread ( dh->private_buffer, dh->private_len, 1, fp ) != 1 ) { +        int save_errno = errno; +        fclose (fp); +        gpgme_data_release (dh); +        errno = save_errno; +        return mk_error (File_Error); +    } + +    fclose (fp); + +    dh->len = dh->private_len; +    dh->data = dh->private_buffer; +    dh->writepos = dh->len; +    dh->type = GPGME_DATA_TYPE_MEM; +     +    *r_dh = dh; +    return 0; +} + + +  /**   * gpgme_data_release:   * @dh: Data object  diff --git a/gpgme/decrypt.c b/gpgme/decrypt.c new file mode 100644 index 00000000..1d8a20e0 --- /dev/null +++ b/gpgme/decrypt.c @@ -0,0 +1,194 @@ +/* decrypt.c -  decrypt functions + *	Copyright (C) 2000 Werner Koch (dd9jn) + * + * 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 <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "util.h" +#include "context.h" +#include "ops.h" + + +struct decrypt_result_s { +    int no_passphrase; +    int okay; +    int failed; +}; + + +void +_gpgme_release_decrypt_result ( DecryptResult res ) +{ +    xfree (res); +} + + + +static void +decrypt_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args ) +{ +    if ( ctx->out_of_core ) +        return; +    if ( ctx->result_type == RESULT_TYPE_NONE ) { +        assert ( !ctx->result.decrypt ); +        ctx->result.decrypt = xtrycalloc ( 1, sizeof *ctx->result.decrypt ); +        if ( !ctx->result.decrypt ) { +            ctx->out_of_core = 1; +            return; +        } +        ctx->result_type = RESULT_TYPE_DECRYPT; +    } +    assert ( ctx->result_type == RESULT_TYPE_DECRYPT ); + +    switch (code) { +      case STATUS_EOF: +        break; + +      case STATUS_NEED_PASSPHRASE: +      case STATUS_NEED_PASSPHRASE_SYM: +        fprintf (stderr, "Ooops: Need a passphrase -  use the agent\n"); +        break; + +      case STATUS_MISSING_PASSPHRASE: +        fprintf (stderr, "Missing passphrase - stop\n");; +        ctx->result.decrypt->no_passphrase = 1; +        break; + +      case STATUS_DECRYPTION_OKAY: +        ctx->result.decrypt->okay = 1; +        break; + +      case STATUS_DECRYPTION_FAILED: +        ctx->result.decrypt->failed = 1; +        break; +         + +      default: +        /* ignore all other codes */ +        fprintf (stderr, "decrypt_status: code=%d not handled\n", code ); +        break; +    } +} + + + +GpgmeError +gpgme_op_decrypt_start ( GpgmeCtx c, GpgmeData ciph, GpgmeData plain ) +{ +    int rc = 0; +    int i; + +    fail_on_pending_request( c ); +    c->pending = 1; + +    _gpgme_release_result (c); +    c->out_of_core = 0; + +    /* do some checks */ +    assert ( !c->gpg ); +         +    /* create a process object */ +    rc = _gpgme_gpg_new ( &c->gpg ); +    if (rc) +        goto leave; + +    _gpgme_gpg_set_status_handler ( c->gpg, decrypt_status_handler, c ); + +    /* build the commandline */ +    _gpgme_gpg_add_arg ( c->gpg, "--decrypt" ); +    for ( i=0; i < c->verbosity; i++ ) +        _gpgme_gpg_add_arg ( c->gpg, "--verbose" ); +     +    /* Check the supplied data */ +    if ( !ciph || gpgme_data_get_type (ciph) == GPGME_DATA_TYPE_NONE ) { +        rc = mk_error (No_Data); +        goto leave; +    } + +    _gpgme_data_set_mode (ciph, GPGME_DATA_MODE_OUT ); +    if ( gpgme_data_get_type (plain) != GPGME_DATA_TYPE_NONE ) { +        rc = mk_error (Invalid_Value); +        goto leave; +    } +    _gpgme_data_set_mode (plain, GPGME_DATA_MODE_IN ); + +    /* Tell the gpg object about the data */ +    _gpgme_gpg_add_arg ( c->gpg, "--output" ); +    _gpgme_gpg_add_arg ( c->gpg, "-" ); +    _gpgme_gpg_add_data ( c->gpg, plain, 1 ); +    _gpgme_gpg_add_data ( c->gpg, ciph, 0 ); + +    /* and kick off the process */ +    rc = _gpgme_gpg_spawn ( c->gpg, c ); + + leave: +    if (rc) { +        c->pending = 0;  +        _gpgme_gpg_release ( c->gpg ); c->gpg = NULL; +    } +    return rc; +} + + +/** + * gpgme_op_decrypt: + * @c: The context + * @in: ciphertext input + * @out: plaintext output + *  + * This function decrypts @in to @out. + * Other parameters are take from the context @c. + * The function does wait for the result. + *  + * Return value:  0 on success or an errorcode.  + **/ +GpgmeError +gpgme_op_decrypt ( GpgmeCtx c, GpgmeData in, GpgmeData out ) +{ +    GpgmeError err = gpgme_op_decrypt_start ( c, in, out ); +    if ( !err ) { +        gpgme_wait (c, 1); +        if ( c->result_type != RESULT_TYPE_DECRYPT ) +            err = mk_error (General_Error); +        else if ( c->out_of_core ) +            err = mk_error (Out_Of_Core); +        else { +            assert ( c->result.decrypt ); +            if ( c->result.decrypt->failed )  +                err = mk_error (Decryption_Failed); +            else if (!c->result.decrypt->okay) +                err = mk_error (No_Data); +        } +        c->pending = 0; +    } +    return err; +} + + + + + + + + + diff --git a/gpgme/gpgme.c b/gpgme/gpgme.c index 4c1daa37..40b12c4b 100644 --- a/gpgme/gpgme.c +++ b/gpgme/gpgme.c @@ -82,6 +82,9 @@ _gpgme_release_result ( GpgmeCtx c )        case RESULT_TYPE_VERIFY:          _gpgme_release_verify_result ( c->result.verify );          break; +      case RESULT_TYPE_DECRYPT: +        _gpgme_release_decrypt_result ( c->result.decrypt ); +        break;      }      c->result.verify = NULL; diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h index 24642825..112d6074 100644 --- a/gpgme/gpgme.h +++ b/gpgme/gpgme.h @@ -59,6 +59,8 @@ typedef enum {      GPGME_Write_Error = 14,      GPGME_Invalid_Type = 15,      GPGME_Invalid_Mode = 16, +    GPGME_File_Error = 17,  /* errno is set in this case */ +    GPGME_Decryption_Failed = 18,  } GpgmeError;  typedef enum { @@ -95,8 +97,13 @@ GpgmeError   gpgme_recipients_add_name (GpgmeRecipients rset,  unsigned int gpgme_recipients_count ( const GpgmeRecipients rset );  /* Functions to handle data sources */ -GpgmeError    gpgme_data_new ( GpgmeData *r_dh, -                               const char *buffer, size_t size, int copy ); +GpgmeError    gpgme_data_new ( GpgmeData *r_dh ); +GpgmeError    gpgme_data_new_from_mem ( GpgmeData *r_dh, +                                        const char *buffer, size_t size, +                                        int copy ); +GpgmeError    gpgme_data_new_from_file ( GpgmeData *r_dh, +                                         const char *fname, +                                         int copy );  void          gpgme_data_release ( GpgmeData dh );  GpgmeDataType gpgme_data_get_type ( GpgmeData dh );  GpgmeError    gpgme_data_rewind ( GpgmeData dh ); @@ -108,8 +115,11 @@ char *gpgme_key_get_as_xml ( GpgmeKey key );  /* Basic GnuPG functions */ -GpgmeError gpgme_op_encrypt_start ( GpgmeCtx c, GpgmeRecipients recp, +GpgmeError gpgme_op_encrypt_start ( GpgmeCtx c, +                                    GpgmeRecipients recp,                                      GpgmeData in, GpgmeData out ); +GpgmeError gpgme_op_decrypt_start ( GpgmeCtx c, +                                    GpgmeData ciph, GpgmeData plain );  GpgmeError gpgme_op_verify_start ( GpgmeCtx c,                                     GpgmeData sig, GpgmeData text ); @@ -123,6 +133,7 @@ GpgmeError gpgme_op_keylist_next ( GpgmeCtx c, GpgmeKey *r_key );  /* Convenience functions for normal usage */  GpgmeError gpgme_op_encrypt ( GpgmeCtx c, GpgmeRecipients recp,                                GpgmeData in, GpgmeData out ); +GpgmeError gpgme_op_decrypt ( GpgmeCtx c, GpgmeData in, GpgmeData out );  GpgmeError gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text,                               GpgmeSigStat *r_status ); diff --git a/gpgme/key.c b/gpgme/key.c index 2f3971c6..c58e859d 100644 --- a/gpgme/key.c +++ b/gpgme/key.c @@ -254,7 +254,7 @@ gpgme_key_get_as_xml ( GpgmeKey key )      if ( !key )          return NULL; -    if ( gpgme_data_new ( &d, NULL, 0, 0 ) ) +    if ( gpgme_data_new ( &d ) )          return NULL;      _gpgme_data_append_string ( d, "<GnupgKeyblock>\n" diff --git a/gpgme/ops.h b/gpgme/ops.h index 1e67fc54..90c93e8f 100644 --- a/gpgme/ops.h +++ b/gpgme/ops.h @@ -62,6 +62,9 @@ void       _gpgme_key_release ( GpgmeKey key );  /*-- verify.c --*/  void _gpgme_release_verify_result ( VerifyResult res ); +/*-- decrypt.c --*/ +void _gpgme_release_decrypt_result ( DecryptResult res ); +  #endif /* OPS_H */ diff --git a/gpgme/types.h b/gpgme/types.h index 34103bce..1c73986d 100644 --- a/gpgme/types.h +++ b/gpgme/types.h @@ -47,6 +47,10 @@ typedef struct gpg_object_s *GpgObject;  struct verify_result_s;  typedef struct verify_result_s *VerifyResult; +/*-- decrypt.c --*/ +struct decrypt_result_s; +typedef struct decrypt_result_s *DecryptResult; +  /*-- key.c --*/ diff --git a/gpgme/verify.c b/gpgme/verify.c index 8ead4b36..a9f14ba3 100644 --- a/gpgme/verify.c +++ b/gpgme/verify.c @@ -50,7 +50,7 @@ add_notation ( GpgmeCtx ctx, GpgStatusCode code, const char *data )      GpgmeData dh = ctx->result.verify->notation;      if ( !dh ) { -        if ( gpgme_data_new ( &dh, NULL, 0,0) ) { +        if ( gpgme_data_new ( &dh ) ) {              ctx->out_of_core = 1;              return;          } diff --git a/tests/Makefile.am b/tests/Makefile.am index 74709b11..2f74e93f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,6 +1,8 @@  ## Process this file with automake to create Makefile.in -TESTS = t-encrypt t-verify t-keylist +TESTS = t-encrypt t-decrypt t-verify t-keylist + +EXTRA_DIST = cipher-1.asc  INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl diff --git a/tests/cipher-1.asc b/tests/cipher-1.asc new file mode 100644 index 00000000..f0a8ca45 --- /dev/null +++ b/tests/cipher-1.asc @@ -0,0 +1,15 @@ +-----BEGIN PGP MESSAGE----- +Version: GnuPG v1.0.4-2 (GNU/Linux) +Comment: For info see http://www.gnupg.org + +hQEOA2rm1+5GqHH4EAP/Tcqiuhvrjj+RFBKnWn2A7f1ztV17U2EngYFy8TbZYGNp +JoMNdpA7GNZs7iqc/x1epaZDKfaQwWEtARZmK/4nlhB48N+oZeKTm7PXIkRPqrCZ +3fxJjCJaU0yrNGuO345DOr0QwDImVhubVEkfgs8yXK2Szx2G8X3LmiaILHAqA2oD +/1ZqjY8k+ovrLL/qe8un/NTwzSjKIPVGR6mhLFXmj8fnp2kSsbo+Bhh4MczTRR6l +SA32z25vcakKu2qn5Wa4yDcx9NcMt8RHXzmfMDLj6UFq99QqKeLK2ywcIpY9p/GL +fQyaf7r3HTVugBSaoOzegLJ+L7MfWohrStkMeLnJQnro0nYBjADVcUQuSS4N3lst +Df3XrxxA/iJvxt4F9K27u4tp5U1HDg1CIxVrkMs92LBri3S6ZtfjdoqQ7QghFwGP +Kw1lKiWayM6NH9rcCKSgk4kl4P/2l3f78XeFgiywN7UGeSoH3BLMSv9gSxl5KrAz +d2imhTMrfEvZ +=y4ng +-----END PGP MESSAGE----- diff --git a/tests/t-decrypt.c b/tests/t-decrypt.c new file mode 100644 index 00000000..0b066f5e --- /dev/null +++ b/tests/t-decrypt.c @@ -0,0 +1,88 @@ +/* t-encrypt.c  - regression test + *	Copyright (C) 2000 Werner Koch (dd9jn) + * + * 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 <errno.h> + +#include "../gpgme/gpgme.h" + +#define fail_if_err(a) do { if(a) { int my_errno = errno; \ +            fprintf (stderr, "%s:%d: GpgmeError %s\n", \ +                 __FILE__, __LINE__, gpgme_strerror(a));   \ +            if ((a) == GPGME_File_Error)                       \ +                   fprintf (stderr, "\terrno=`%s'\n", strerror (my_errno)); \ +                   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); +} + + + +int  +main (int argc, char **argv ) +{ +    GpgmeCtx ctx; +    GpgmeError err; +    GpgmeData in, out; + +  do { +    err = gpgme_new (&ctx); +    fail_if_err (err); + +    err = gpgme_data_new_from_file ( &in, "cipher-1.asc", 1 ); +    fail_if_err (err); + +    err = gpgme_data_new ( &out ); +    fail_if_err (err); + +    err = gpgme_op_decrypt (ctx, in, out ); +    fail_if_err (err); + +    fflush (NULL); +    fputs ("Begin Result:\n", stdout ); +    print_data (out); +    fputs ("End Result.\n", stdout ); +    +    gpgme_data_release (in); +    gpgme_data_release (out); +    gpgme_release (ctx); +  } while ( argc > 1 && !strcmp( argv[1], "--loop" ) ); +    +    return 0; +} + + diff --git a/tests/t-encrypt.c b/tests/t-encrypt.c index 88ceaeee..01c5379e 100644 --- a/tests/t-encrypt.c +++ b/tests/t-encrypt.c @@ -61,10 +61,10 @@ main (int argc, char **argv )      err = gpgme_new (&ctx);      fail_if_err (err); -    err = gpgme_data_new ( &in, "Hallo Leute\n", 12, 0 ); +    err = gpgme_data_new_from_mem ( &in, "Hallo Leute\n", 12, 0 );      fail_if_err (err); -    err = gpgme_data_new ( &out, NULL, 0,0 ); +    err = gpgme_data_new ( &out );      fail_if_err (err);      err = gpgme_recipients_new (&rset); diff --git a/tests/t-verify.c b/tests/t-verify.c index 5ab6bbca..bc997236 100644 --- a/tests/t-verify.c +++ b/tests/t-verify.c @@ -105,9 +105,11 @@ main (int argc, char **argv )      fail_if_err (err);    do { -    err = gpgme_data_new ( &text, test_text1, strlen (test_text1), 0 ); +    err = gpgme_data_new_from_mem ( &text, +                                    test_text1, strlen (test_text1), 0 );      fail_if_err (err); -    err = gpgme_data_new ( &sig, test_sig1, strlen (test_sig1), 0 ); +    err = gpgme_data_new_from_mem ( &sig, +                                    test_sig1, strlen (test_sig1), 0 );      fail_if_err (err);      puts ("checking a valid message:\n"); @@ -119,7 +121,8 @@ main (int argc, char **argv )      puts ("checking a manipulated message:\n");      gpgme_data_release (text); -    err = gpgme_data_new ( &text, test_text1f, strlen (test_text1f), 0 ); +    err = gpgme_data_new_from_mem ( &text, +                                    test_text1f, strlen (test_text1f), 0 );      fail_if_err (err);      gpgme_data_rewind ( sig );      err = gpgme_op_verify (ctx, sig, text, &status ); | 
