Program: gpgme
-Maintainer: <gpgme@g10code.com>
+Maintainer: wk@g10gnupg.org
FSF <gnu@gnu.org>
+
+ * New function gpgme_get_op_info which can be used to get the micalg
+ parameter needed for MOSS.
+
Noteworthy changes in version 0.2.2 (2001-06-12)
------------------------------------------------
another flag or a callback?
* There is no status response if we have no usable recipients - must
- add one to gpg so that gpgme_encrypt does return with an error.
-
+ add one to gpg so that gpgme_encrypt does return with an error.
\ No newline at end of file
Gpgcom currently support only encryption but will be extended to the
full range of operations GnuPG provides. The 2 examples should goive
yopu a hint on how to use it. We suggest that you always set armor to
-true, so that the returned text is a string. IF you don't use armor,
+true, so that the returned text is a string. If you don't use armor,
the "ciphertext" property will return an array with the binary
message.
gpg.plaintext = "This is the secret message." 'or: InputBox('Enter message:")
' Set the Recipient. You may also use a keyID or an fingerprint
-gpg.addrecipient "alice"
+gpg.AddRecipient "alice"
' And encrypt the stuff
gpg.encrypt
+2001-08-28 Werner Koch <wk@gnupg.org>
+
+ * gpgme.c, gpgme.h (gpgme_get_op_info): New.
+ (_gpgme_set_op_info): New.
+ (_gpgme_release_result): Reset the op_info here.
+ * sign.c (append_xml_siginfo): New.
+ (sign_status_handler): Store the sig create information.
+
2001-07-31 Werner Koch <wk@gnupg.org>
* encrypt.c (gpgme_op_encrypt): Hack to detect no valid recipients.
2001-07-30 Werner Koch <wk@gnupg.org>
- * gpgme.c (gpgme_get_armor,gpgme_get_texmode): New.
+ * gpgme.c (gpgme_get_armor,gpgme_get_textmode): New.
* rungpg.c (build_argv): Disable armor comments
* w32-io.c (build_commandline): Need to add quotes here
} result;
GpgmeData notation; /* last signature notation */
+ GpgmeData op_info; /* last operation info */
GpgmeKey tmp_key; /* used by keylist.c */
volatile int key_cond; /* something new is available */
c->result.verify = NULL;
c->result_type = RESULT_TYPE_NONE;
+ _gpgme_set_op_info (c, NULL);
}
return _gpgme_data_get_as_string ( c->notation );
}
+
+/**
+ * gpgme_get_op_info:
+ * @c: the context
+ * @reserved:
+ *
+ * Return information about the last information. The caller has to
+ * free the string. NULL is returned if there is not previous
+ * operation available or the operation has not yet finished.
+ *
+ * Here is a sample information we return:
+<GnupgOperationInfo>
+ <signature>
+ <detached/> <!-- or cleartext or standard -->
+ <algo>17</algo>
+ <hashalgo>2</hashalgo>
+ <micalg>pgp-sha1</micalg>
+ <sigclass>01</sigclass>
+ <created>9222222</created>
+ <fpr>121212121212121212</fpr>
+ </signature>
+</GnupgOperationInfo>
+ *
+ * Return value: NULL for no info available or an XML string
+ **/
+char *
+gpgme_get_op_info ( GpgmeCtx c, int reserved )
+{
+ if (!c || reserved)
+ return NULL; /*invalid value */
+
+ return _gpgme_data_get_as_string (c->op_info);
+}
+
+/*
+ * Store the data object with the operation info in the
+ * context. Caller should not use that object anymore.
+ */
+void
+_gpgme_set_op_info (GpgmeCtx c, GpgmeData info)
+{
+ assert (c);
+
+ gpgme_data_release (c->op_info);
+ c->op_info = NULL;
+
+ if (info)
+ c->op_info = info;
+}
+
+
/**
* gpgme_set_armor:
* @c: the contect
const char *gpgme_get_sig_status (GpgmeCtx c, int idx,
GpgmeSigStat *r_stat, time_t *r_created );
GpgmeError gpgme_get_sig_key (GpgmeCtx c, int idx, GpgmeKey *r_key);
-
-
+char *gpgme_get_op_info (GpgmeCtx c, int reserved);
/* Functions to handle recipients */
_gpgme_key_cache_add (GpgmeKey key)
{
struct subkey_s *k;
-#warning debug code
- if (!key || getenv("gpgme_no_cache") )
+
+ if (!key)
return;
/* FIXME: add locking */
/*add_tag_and_time (d, "expires", key->expires );*/
_gpgme_data_append_string (d, " </mainkey>\n");
- /* Now the user IDs. We are listing the last one firs becuase this is
+ /* Now the user IDs. We are listing the last one first because this is
* the primary one. */
for (u = key->uids; u && u->next; u = u->next )
;
/*-- gpgme.c --*/
void _gpgme_release_result ( GpgmeCtx c );
+void _gpgme_set_op_info (GpgmeCtx c, GpgmeData info);
/*-- wait.c --*/
GpgmeCtx _gpgme_wait_on_condition ( GpgmeCtx c,
#include "context.h"
#include "ops.h"
+#define SKIP_TOKEN_OR_RETURN(a) do { \
+ while (*(a) && *(a) != ' ') (a)++; \
+ while (*(a) == ' ') (a)++; \
+ if (!*(a)) \
+ return; /* oops */ \
+} while (0)
+
+
+
struct sign_result_s {
int no_passphrase;
char *userid_hint;
char *passphrase_info;
int bad_passphrase;
+ GpgmeData xmlinfo;
};
void
_gpgme_release_sign_result ( SignResult res )
{
+ gpgme_data_release (res->xmlinfo);
xfree (res->userid_hint);
xfree (res->passphrase_info);
xfree (res);
}
+/* parse the args and save the information
+ * <type> <pubkey algo> <hash algo> <class> <timestamp> <key fpr>
+ * in an XML structure. With args of NULL the xml structure is closed.
+ */
+static void
+append_xml_siginfo (GpgmeData *rdh, char *args)
+{
+ GpgmeData dh;
+ char helpbuf[100];
+ int i;
+ char *s;
+ unsigned long ul;
+
+ if ( !*rdh ) {
+ if (gpgme_data_new (rdh)) {
+ return; /* fixme: We are ignoring out-of-core */
+ }
+ dh = *rdh;
+ _gpgme_data_append_string (dh, "<GnupgOperationInfo>\n");
+ }
+ else {
+ dh = *rdh;
+ _gpgme_data_append_string (dh, " </signature>\n");
+ }
+
+ if (!args) { /* just close the XML containter */
+ _gpgme_data_append_string (dh, "</GnupgOperationInfo>\n");
+ return;
+ }
+
+ _gpgme_data_append_string (dh, " <signature>\n");
+
+ _gpgme_data_append_string (dh,
+ *args == 'D'? " <detached/>\n":
+ *args == 'C'? " <cleartext/>\n":
+ *args == 'S'? " <standard/>\n":"");
+ SKIP_TOKEN_OR_RETURN (args);
+
+ sprintf (helpbuf, " <algo>%d</algo>\n", atoi (args));
+ _gpgme_data_append_string (dh, helpbuf);
+ SKIP_TOKEN_OR_RETURN (args);
+
+ i = atoi (args);
+ sprintf (helpbuf, " <hashalgo>%d</hashalgo>\n", atoi (args));
+ _gpgme_data_append_string (dh, helpbuf);
+ switch (i) {
+ case 1: s = "pgp-md5"; break;
+ case 2: s = "pgp-sha1"; break;
+ case 3: s = "pgp-ripemd160"; break;
+ case 5: s = "pgp-md2"; break;
+ case 6: s = "pgp-tiger192"; break;
+ case 7: s = "pgp-haval-5-160"; break;
+ case 8: s = "pgp-sha256"; break;
+ case 9: s = "pgp-sha384"; break;
+ case 10: s = "pgp-sha512"; break;
+ default: s = "pgp-unknown"; break;
+ }
+ sprintf (helpbuf, " <micalg>%s</micalg>\n", s);
+ _gpgme_data_append_string (dh,helpbuf);
+ SKIP_TOKEN_OR_RETURN (args);
+
+ sprintf (helpbuf, " <sigclass>%.2s</sigclass>\n", args);
+ _gpgme_data_append_string (dh, helpbuf);
+ SKIP_TOKEN_OR_RETURN (args);
+
+ ul = strtoul (args, NULL, 10);
+ sprintf (helpbuf, " <created>%lu</created>\n", ul);
+ _gpgme_data_append_string (dh, helpbuf);
+ SKIP_TOKEN_OR_RETURN (args);
+
+ /* count the length of the finperprint */
+ for (i=0; args[i] && args[i] != ' '; i++)
+ ;
+ _gpgme_data_append_string (dh, " <fpr>");
+ _gpgme_data_append (dh, args, i);
+ _gpgme_data_append_string (dh, "</fpr>\n");
+}
+
+
static void
sign_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
switch (code) {
case STATUS_EOF:
+ if (ctx->result.sign->okay) {
+ append_xml_siginfo (&ctx->result.sign->xmlinfo, NULL);
+ _gpgme_set_op_info (ctx, ctx->result.sign->xmlinfo);
+ ctx->result.sign->xmlinfo = NULL;
+ }
break;
case STATUS_USERID_HINT:
case STATUS_SIG_CREATED:
/* fixme: we have no error return for multiple signatures */
+ append_xml_siginfo (&ctx->result.sign->xmlinfo, args);
ctx->result.sign->okay =1;
- /* parse the line and save the information
- * <type> <pubkey algo> <hash algo> <class> <timestamp> <key fpr>
- */
break;
default:
}
_gpgme_data_set_mode (out, GPGME_DATA_MODE_IN );
- /* Tell the gpg object about the data */
+ /* tell the gpg object about the data */
_gpgme_gpg_add_data ( c->gpg, in, 0 );
_gpgme_gpg_add_data ( c->gpg, out, 1 );
err = mk_error (No_Passphrase);
else if (!c->result.sign->okay)
err = mk_error (No_Data); /* Hmmm: choose a better error? */
+
}
c->pending = 0;
}
exit (1); } \
} while(0)
+static void
+print_op_info (GpgmeCtx c)
+{
+ char *s = gpgme_get_op_info (c, 0);
+
+ if (!s)
+ puts ("<!-- no operation info available -->");
+ else {
+ puts (s);
+ free (s);
+ }
+}
+
static void
print_data ( GpgmeData dh )
{
fail_if_err (err);
fflush (NULL);
fputs ("Begin Result:\n", stdout );
+ print_op_info (ctx);
print_data (out);
fputs ("End Result.\n", stdout );
gpgme_data_release (out);
err = gpgme_op_sign (ctx, in, out, GPGME_SIG_MODE_DETACH );
fail_if_err (err);
fflush (NULL);
+ print_op_info (ctx);
fputs ("Begin Result:\n", stdout );
print_data (out);
fputs ("End Result.\n", stdout );
err = gpgme_op_sign (ctx, in, out, GPGME_SIG_MODE_CLEAR );
fail_if_err (err);
fflush (NULL);
+ print_op_info (ctx);
fputs ("Begin Result:\n", stdout );
print_data (out);
fputs ("End Result.\n", stdout );