diff options
Diffstat (limited to '')
-rw-r--r-- | gpgme/sign.c | 102 |
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; } |