aboutsummaryrefslogtreecommitdiffstats
path: root/gpgme/sign.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--gpgme/sign.c102
1 files changed, 98 insertions, 4 deletions
diff --git a/gpgme/sign.c b/gpgme/sign.c
index f71e0d64..b92ea806 100644
--- a/gpgme/sign.c
+++ b/gpgme/sign.c
@@ -29,6 +29,15 @@
#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;
@@ -37,18 +46,99 @@ struct sign_result_s {
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 )
@@ -68,6 +158,11 @@ 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:
@@ -98,10 +193,8 @@ sign_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
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:
@@ -242,7 +335,7 @@ gpgme_op_sign_start ( GpgmeCtx c, GpgmeData in, GpgmeData out,
}
_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 );
@@ -295,6 +388,7 @@ gpgme_op_sign ( GpgmeCtx c, GpgmeData in, GpgmeData out, GpgmeSigMode mode )
err = mk_error (No_Passphrase);
else if (!c->result.sign->okay)
err = mk_error (No_Data); /* Hmmm: choose a better error? */
+
}
c->pending = 0;
}