aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--sm/fingerprint.c23
-rw-r--r--sm/gpgsm.c25
-rw-r--r--sm/gpgsm.h88
-rw-r--r--sm/import.c2
-rw-r--r--sm/server.c245
-rw-r--r--sm/verify.c52
6 files changed, 422 insertions, 13 deletions
diff --git a/sm/fingerprint.c b/sm/fingerprint.c
index 9453a6eab..a612f3b87 100644
--- a/sm/fingerprint.c
+++ b/sm/fingerprint.c
@@ -102,3 +102,26 @@ gpgsm_get_fingerprint_string (KsbaCert cert, int algo)
return buf;
}
+/* Return an allocated buffer with the formatted fungerprint as one
+ large hexnumber */
+char *
+gpgsm_get_fingerprint_hexstring (KsbaCert cert, int algo)
+{
+ unsigned char digest[MAX_DIGEST_LEN];
+ char *buf;
+ int len, i;
+
+ if (!algo)
+ algo = GCRY_MD_SHA1;
+
+ len = gcry_md_get_algo_dlen (algo);
+ assert (len <= MAX_DIGEST_LEN );
+ gpgsm_get_fingerprint (cert, algo, digest, NULL);
+ buf = xmalloc (len*3+1);
+ *buf = 0;
+ for (i=0; i < len; i++ )
+ sprintf (buf+strlen(buf), "%02X", digest[i]);
+ return buf;
+}
+
+
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index 329e80d9f..3a84777e1 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -319,6 +319,7 @@ static char *build_list (const char *text,
static void set_cmd (enum cmd_and_opt_values *ret_cmd,
enum cmd_and_opt_values new_cmd );
+static int check_special_filename (const char *fname);
static int open_read (const char *filename);
@@ -512,6 +513,7 @@ main ( int argc, char **argv)
char *def_cipher_string = NULL;
char *def_digest_string = NULL;
enum cmd_and_opt_values cmd = 0;
+ struct server_control_s ctrl;
/* FIXME: trap_unaligned ();*/
set_strusage (my_strusage);
@@ -583,6 +585,12 @@ main ( int argc, char **argv)
assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
+ /* Setup a default control structure */
+ memset (&ctrl, 0, sizeof ctrl);
+ ctrl.no_server = 1;
+ ctrl.status_fd = -1; /* not status output */
+
+ /* set the default option file */
if (default_config )
configname = make_filename (opt.homedir, "gpgsm.conf", NULL);
@@ -680,7 +688,7 @@ main ( int argc, char **argv)
case oDebug: opt.debug |= pargs.r.ret_ulong; break;
case oDebugAll: opt.debug = ~0; break;
- case oStatusFD: /* fixme: set_status_fd (pargs.r.ret_int );*/ break;
+ case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
case oLoggerFD: /* fixme: log_set_logfile (NULL, pargs.r.ret_int );*/ break;
case oWithFingerprint:
with_fpr=1; /*fall thru*/
@@ -930,11 +938,11 @@ main ( int argc, char **argv)
case aVerify:
if (!argc)
- gpgsm_verify (0, -1); /* normal signature from stdin */
+ gpgsm_verify (&ctrl, 0, -1); /* normal signature from stdin */
else if (argc == 1)
- gpgsm_verify (open_read (*argv), -1); /* normal signature */
+ gpgsm_verify (&ctrl, open_read (*argv), -1); /* normal signature */
else if (argc == 2) /* detached signature (sig, detached) */
- gpgsm_verify (open_read (*argv), open_read (argv[1]));
+ gpgsm_verify (&ctrl, open_read (*argv), open_read (argv[1]));
else
wrong_args (_("--verify [signature [detached_data]]"));
break;
@@ -992,8 +1000,13 @@ main ( int argc, char **argv)
break;
case aImport:
-/* import_keys (argc? argv:NULL, argc); */
- gpgsm_import (0);
+ if (!argc)
+ gpgsm_import (&ctrl, 0);
+ else
+ {
+ for (; argc; argc--, argv++)
+ gpgsm_import (&ctrl, open_read (*argv));
+ }
break;
case aExport:
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index 9c0c93375..5f7f56454 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -43,6 +43,78 @@ enum {
GPGSM_Conflict = 13,
};
+/* Status codes (shared with gpg) */
+enum {
+ STATUS_ENTER,
+ STATUS_LEAVE,
+ STATUS_ABORT,
+ STATUS_GOODSIG,
+ STATUS_BADSIG,
+ STATUS_ERRSIG,
+ STATUS_BADARMOR,
+ STATUS_RSA_OR_IDEA,
+ STATUS_SIGEXPIRED,
+ STATUS_KEYREVOKED,
+ STATUS_TRUST_UNDEFINED,
+ STATUS_TRUST_NEVER,
+ STATUS_TRUST_MARGINAL,
+ STATUS_TRUST_FULLY,
+ STATUS_TRUST_ULTIMATE,
+
+ STATUS_SHM_INFO,
+ STATUS_SHM_GET,
+ STATUS_SHM_GET_BOOL,
+ STATUS_SHM_GET_HIDDEN,
+
+ STATUS_NEED_PASSPHRASE,
+ STATUS_VALIDSIG,
+ STATUS_SIG_ID,
+ STATUS_ENC_TO,
+ STATUS_NODATA,
+ STATUS_BAD_PASSPHRASE,
+ STATUS_NO_PUBKEY,
+ STATUS_NO_SECKEY,
+ STATUS_NEED_PASSPHRASE_SYM,
+ STATUS_DECRYPTION_FAILED,
+ STATUS_DECRYPTION_OKAY,
+ STATUS_MISSING_PASSPHRASE,
+ STATUS_GOOD_PASSPHRASE,
+ STATUS_GOODMDC,
+ STATUS_BADMDC,
+ STATUS_ERRMDC,
+ STATUS_IMPORTED,
+ STATUS_IMPORT_RES,
+ STATUS_FILE_START,
+ STATUS_FILE_DONE,
+ STATUS_FILE_ERROR,
+
+ STATUS_BEGIN_DECRYPTION,
+ STATUS_END_DECRYPTION,
+ STATUS_BEGIN_ENCRYPTION,
+ STATUS_END_ENCRYPTION,
+
+ STATUS_DELETE_PROBLEM,
+ STATUS_GET_BOOL,
+ STATUS_GET_LINE,
+ STATUS_GET_HIDDEN,
+ STATUS_GOT_IT,
+ STATUS_PROGRESS,
+ STATUS_SIG_CREATED,
+ STATUS_SESSION_KEY,
+ STATUS_NOTATION_NAME,
+ STATUS_NOTATION_DATA,
+ STATUS_POLICY_URL,
+ STATUS_BEGIN_STREAM,
+ STATUS_END_STREAM,
+ STATUS_KEY_CREATED,
+ STATUS_USERID_HIN,
+ STATUS_UNEXPECTED,
+ STATUS_INV_RECP,
+ STATUS_NO_RECP,
+ STATUS_ALREADY_SIGNED,
+};
+
+
#define MAX_DIGEST_LEN 24
/* A large struct name "opt" to keep global flags */
@@ -98,15 +170,27 @@ struct {
#define DBG_CACHE (opt.debug & DBG_CACHE_VALUE)
#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE)
+struct server_local_s;
+
+struct server_control_s {
+ int no_server; /* we are not running under server control */
+ int status_fd; /* only for non-server mode */
+ struct server_local_s *server_local;
+};
+typedef struct server_control_s *CTRL;
+
+
/*-- gpgsm.c --*/
void gpgsm_exit (int rc);
/*-- server.c --*/
void gpgsm_server (void);
+void gpgsm_status (CTRL ctrl, int no, const char *text);
/*-- fingerprint --*/
char *gpgsm_get_fingerprint (KsbaCert cert, int algo, char *array, int *r_len);
char *gpgsm_get_fingerprint_string (KsbaCert cert, int algo);
+char *gpgsm_get_fingerprint_hexstring (KsbaCert cert, int algo);
/*-- certdump.c --*/
void gpgsm_dump_cert (const char *text, KsbaCert cert);
@@ -124,10 +208,10 @@ int gpgsm_validate_path (KsbaCert cert);
/*-- import.c --*/
-int gpgsm_import (int in_fd);
+int gpgsm_import (CTRL ctrl, int in_fd);
/*-- verify.c --*/
-int gpgsm_verify (int in_fd, int data_fd);
+int gpgsm_verify (CTRL ctrl, int in_fd, int data_fd);
diff --git a/sm/import.c b/sm/import.c
index 8913f8092..ba21312de 100644
--- a/sm/import.c
+++ b/sm/import.c
@@ -265,7 +265,7 @@ store_cert (KsbaCert cert)
int
-gpgsm_import (int in_fd)
+gpgsm_import (CTRL ctrl, int in_fd)
{
int rc;
KsbaReader reader = NULL;
diff --git a/sm/server.c b/sm/server.c
index c3b9f1559..c44de16da 100644
--- a/sm/server.c
+++ b/sm/server.c
@@ -30,6 +30,18 @@
#include "../assuan/assuan.h"
#define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t))
+#define digitp(a) ((a) >= '0' && (a) <= '9')
+
+
+/* The filepointer for status message used in non-server mode */
+static FILE *statusfp;
+
+/* Data used to assuciate an Assuan context with local server data */
+struct server_local_s {
+ ASSUAN_CONTEXT assuan_ctx;
+ int message_fd;
+};
+
/* RECIPIENT <userID>
@@ -104,12 +116,13 @@ cmd_decrypt (ASSUAN_CONTEXT ctx, char *line)
static int
cmd_verify (ASSUAN_CONTEXT ctx, char *line)
{
+ CTRL ctrl = assuan_get_pointer (ctx);
int fd = assuan_get_input_fd (ctx);
if (fd == -1)
return set_error (No_Input, NULL);
- gpgsm_verify (fd, -1);
+ gpgsm_verify (assuan_get_pointer (ctx), fd, ctrl->server_local->message_fd);
return 0;
}
@@ -141,8 +154,34 @@ cmd_import (ASSUAN_CONTEXT ctx, char *line)
if (fd == -1)
return set_error (No_Input, NULL);
- gpgsm_import (fd);
+ gpgsm_import (assuan_get_pointer (ctx), fd);
+
+ return 0;
+}
+
+/* MESSAGE FD=<n>
+
+ Set the file descriptor to read a message which is used with
+ detached signatures */
+static int
+cmd_message (ASSUAN_CONTEXT ctx, char *line)
+{
+ char *endp;
+ int fd;
+ CTRL ctrl = assuan_get_pointer (ctx);
+
+ if (strncmp (line, "FD=", 3))
+ return set_error (Syntax_Error, "FD=<n> expected");
+ line += 3;
+ if (!digitp (*line))
+ return set_error (Syntax_Error, "number required");
+ fd = strtoul (line, &endp, 10);
+ if (*endp)
+ return set_error (Syntax_Error, "garbage found");
+ if (fd == -1)
+ return set_error (No_Input, NULL);
+ ctrl->server_local->message_fd = fd;
return 0;
}
@@ -166,6 +205,7 @@ register_commands (ASSUAN_CONTEXT ctx)
{ "IMPORT", 0, cmd_import },
{ "", ASSUAN_CMD_INPUT, NULL },
{ "", ASSUAN_CMD_OUTPUT, NULL },
+ { "MESSAGE", 0, cmd_message },
{ NULL }
};
int i, j, rc;
@@ -189,6 +229,9 @@ gpgsm_server (void)
int rc;
int filedes[2];
ASSUAN_CONTEXT ctx;
+ struct server_control_s ctrl;
+
+ memset (&ctrl, 0, sizeof ctrl);
/* For now we use a simple pipe based server so that we can work
from scripts. We will later add options to run as a daemon and
@@ -210,6 +253,11 @@ gpgsm_server (void)
gpgsm_exit (2);
}
+ assuan_set_pointer (ctx, &ctrl);
+ ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local);
+ ctrl.server_local->assuan_ctx = ctx;
+ ctrl.server_local->message_fd = -1;
+
log_info ("Assuan started\n");
for (;;)
{
@@ -238,6 +286,199 @@ gpgsm_server (void)
}
+static const char *
+get_status_string ( int no )
+{
+ const char *s;
+
+ switch (no)
+ {
+ case STATUS_ENTER : s = "ENTER"; break;
+ case STATUS_LEAVE : s = "LEAVE"; break;
+ case STATUS_ABORT : s = "ABORT"; break;
+ case STATUS_GOODSIG: s = "GOODSIG"; break;
+ case STATUS_SIGEXPIRED: s = "SIGEXPIRED"; break;
+ case STATUS_KEYREVOKED: s = "KEYREVOKED"; break;
+ case STATUS_BADSIG : s = "BADSIG"; break;
+ case STATUS_ERRSIG : s = "ERRSIG"; break;
+ case STATUS_BADARMOR : s = "BADARMOR"; break;
+ case STATUS_RSA_OR_IDEA : s= "RSA_OR_IDEA"; break;
+ case STATUS_TRUST_UNDEFINED: s = "TRUST_UNDEFINED"; break;
+ case STATUS_TRUST_NEVER : s = "TRUST_NEVER"; break;
+ case STATUS_TRUST_MARGINAL : s = "TRUST_MARGINAL"; break;
+ case STATUS_TRUST_FULLY : s = "TRUST_FULLY"; break;
+ case STATUS_TRUST_ULTIMATE : s = "TRUST_ULTIMATE"; break;
+ case STATUS_GET_BOOL : s = "GET_BOOL"; break;
+ case STATUS_GET_LINE : s = "GET_LINE"; break;
+ case STATUS_GET_HIDDEN : s = "GET_HIDDEN"; break;
+ case STATUS_GOT_IT : s = "GOT_IT"; break;
+ case STATUS_SHM_INFO : s = "SHM_INFO"; break;
+ case STATUS_SHM_GET : s = "SHM_GET"; break;
+ case STATUS_SHM_GET_BOOL : s = "SHM_GET_BOOL"; break;
+ case STATUS_SHM_GET_HIDDEN : s = "SHM_GET_HIDDEN"; break;
+ case STATUS_NEED_PASSPHRASE: s = "NEED_PASSPHRASE"; break;
+ case STATUS_VALIDSIG : s = "VALIDSIG"; break;
+ case STATUS_SIG_ID : s = "SIG_ID"; break;
+ case STATUS_ENC_TO : s = "ENC_TO"; break;
+ case STATUS_NODATA : s = "NODATA"; break;
+ case STATUS_BAD_PASSPHRASE : s = "BAD_PASSPHRASE"; break;
+ case STATUS_NO_PUBKEY : s = "NO_PUBKEY"; break;
+ case STATUS_NO_SECKEY : s = "NO_SECKEY"; break;
+ case STATUS_NEED_PASSPHRASE_SYM: s = "NEED_PASSPHRASE_SYM"; break;
+ case STATUS_DECRYPTION_FAILED: s = "DECRYPTION_FAILED"; break;
+ case STATUS_DECRYPTION_OKAY: s = "DECRYPTION_OKAY"; break;
+ case STATUS_MISSING_PASSPHRASE: s = "MISSING_PASSPHRASE"; break;
+ case STATUS_GOOD_PASSPHRASE : s = "GOOD_PASSPHRASE"; break;
+ case STATUS_GOODMDC : s = "GOODMDC"; break;
+ case STATUS_BADMDC : s = "BADMDC"; break;
+ case STATUS_ERRMDC : s = "ERRMDC"; break;
+ case STATUS_IMPORTED : s = "IMPORTED"; break;
+ case STATUS_IMPORT_RES : s = "IMPORT_RES"; break;
+ case STATUS_FILE_START : s = "FILE_START"; break;
+ case STATUS_FILE_DONE : s = "FILE_DONE"; break;
+ case STATUS_FILE_ERROR : s = "FILE_ERROR"; break;
+ case STATUS_BEGIN_DECRYPTION:s = "BEGIN_DECRYPTION"; break;
+ case STATUS_END_DECRYPTION : s = "END_DECRYPTION"; break;
+ case STATUS_BEGIN_ENCRYPTION:s = "BEGIN_ENCRYPTION"; break;
+ case STATUS_END_ENCRYPTION : s = "END_ENCRYPTION"; break;
+ case STATUS_DELETE_PROBLEM : s = "DELETE_PROBLEM"; break;
+ case STATUS_PROGRESS : s = "PROGRESS"; break;
+ case STATUS_SIG_CREATED : s = "SIG_CREATED"; break;
+ case STATUS_SESSION_KEY : s = "SESSION_KEY"; break;
+ case STATUS_NOTATION_NAME : s = "NOTATION_NAME" ; break;
+ case STATUS_NOTATION_DATA : s = "NOTATION_DATA" ; break;
+ case STATUS_POLICY_URL : s = "POLICY_URL" ; break;
+ case STATUS_BEGIN_STREAM : s = "BEGIN_STREAM"; break;
+ case STATUS_END_STREAM : s = "END_STREAM"; break;
+ case STATUS_KEY_CREATED : s = "KEY_CREATED"; break;
+ case STATUS_UNEXPECTED : s = "UNEXPECTED"; break;
+ case STATUS_INV_RECP : s = "INV_RECP"; break;
+ case STATUS_NO_RECP : s = "NO_RECP"; break;
+ case STATUS_ALREADY_SIGNED : s = "ALREADY_SIGNED"; break;
+ default: s = "?"; break;
+ }
+ return s;
+}
+
+
+
+void
+gpgsm_status (CTRL ctrl, int no, const char *text)
+{
+ if (ctrl->no_server)
+ {
+ if (ctrl->status_fd == -1)
+ return; /* no status wanted */
+ if (!statusfp)
+ {
+ if (ctrl->status_fd == 1)
+ statusfp = stdout;
+ else if (ctrl->status_fd == 2)
+ statusfp = stderr;
+ else
+ statusfp = fdopen (ctrl->status_fd, "w");
+
+ if (!statusfp)
+ {
+ log_fatal ("can't open fd %d for status output: %s\n",
+ ctrl->status_fd, strerror(errno));
+ }
+ }
+
+ fputs ("[GNUPG:] ", statusfp);
+ fputs (get_status_string (no), statusfp);
+
+ if (text)
+ {
+ putc ( ' ', statusfp );
+ for (; *text; text++)
+ {
+ if (*text == '\n')
+ fputs ( "\\n", statusfp );
+ else if (*text == '\r')
+ fputs ( "\\r", statusfp );
+ else
+ putc ( *(const byte *)text, statusfp );
+ }
+ }
+ putc ('\n', statusfp);
+ fflush (statusfp);
+ }
+ else
+ {
+ ASSUAN_CONTEXT ctx = ctrl->server_local->assuan_ctx;
+
+ assuan_write_status (ctx, get_status_string (no), text);
+ }
+}
+
+
+#if 0
+/*
+ * Write a status line with a buffer using %XX escapes. If WRAP is >
+ * 0 wrap the line after this length. If STRING is not NULL it will
+ * be prepended to the buffer, no escaping is done for string.
+ * A wrap of -1 forces spaces not to be encoded as %20.
+ */
+void
+write_status_text_and_buffer ( int no, const char *string,
+ const char *buffer, size_t len, int wrap )
+{
+ const char *s, *text;
+ int esc, first;
+ int lower_limit = ' ';
+ size_t n, count, dowrap;
+
+ if( !statusfp )
+ return; /* not enabled */
+
+ if (wrap == -1) {
+ lower_limit--;
+ wrap = 0;
+ }
+
+ text = get_status_string (no);
+ count = dowrap = first = 1;
+ do {
+ if (dowrap) {
+ fprintf (statusfp, "[GNUPG:] %s ", text );
+ count = dowrap = 0;
+ if (first && string) {
+ fputs (string, statusfp);
+ count += strlen (string);
+ }
+ first = 0;
+ }
+ for (esc=0, s=buffer, n=len; n && !esc; s++, n-- ) {
+ if ( *s == '%' || *(const byte*)s <= lower_limit
+ || *(const byte*)s == 127 )
+ esc = 1;
+ if ( wrap && ++count > wrap ) {
+ dowrap=1;
+ break;
+ }
+ }
+ if (esc) {
+ s--; n++;
+ }
+ if (s != buffer)
+ fwrite (buffer, s-buffer, 1, statusfp );
+ if ( esc ) {
+ fprintf (statusfp, "%%%02X", *(const byte*)s );
+ s++; n--;
+ }
+ buffer = s;
+ len = n;
+ if ( dowrap && len )
+ putc ( '\n', statusfp );
+ } while ( len );
+
+ putc ('\n',statusfp);
+ fflush (statusfp);
+}
+#endif
+
+
diff --git a/sm/verify.c b/sm/verify.c
index ecbbba4f0..6b4ef5c09 100644
--- a/sm/verify.c
+++ b/sm/verify.c
@@ -38,6 +38,31 @@ struct reader_cb_parm_s {
FILE *fp;
};
+
+/* FIXME: Move this to jnlib */
+char *
+strtimestamp (time_t atime)
+{
+ char *buffer = xmalloc (15);
+
+ if (atime < 0)
+ {
+ strcpy (buffer, "????" "-??" "-??");
+ }
+ else
+ {
+ struct tm *tp;
+
+ tp = gmtime( &atime );
+ sprintf (buffer, "%04d-%02d-%02d",
+ 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday);
+ }
+ return buffer;
+}
+
+
+
+
/* FIXME: We need to write a generic reader callback which should be able
to detect and convert base-64 */
static int
@@ -142,7 +167,7 @@ hash_data (int fd, GCRY_MD_HD md)
/* Perform a verify operation. To verify detached signatures, data_fd
must be different than -1 */
int
-gpgsm_verify (int in_fd, int data_fd)
+gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
{
int i, rc;
KsbaError err;
@@ -289,6 +314,7 @@ gpgsm_verify (int in_fd, int data_fd)
unsigned char *serial;
char *msgdigest = NULL;
size_t msgdigestlen;
+ time_t sigcreated;
err = ksba_cms_get_issuer_serial (cms, signer, &issuer, &serial);
if (err)
@@ -346,6 +372,7 @@ gpgsm_verify (int in_fd, int data_fd)
{
log_error ("message digest attribute does not "
"match calculated one\n");
+ gpgsm_status (ctrl, STATUS_BADSIG, NULL);
goto next_signer;
}
@@ -355,7 +382,7 @@ gpgsm_verify (int in_fd, int data_fd)
log_error ("md_open failed: %s\n", gcry_strerror (-1));
goto next_signer;
}
- ksba_cms_set_hash_function (cms, gcry_md_write, md);
+ ksba_cms_set_hash_function (cms, HASH_FNC, md);
rc = ksba_cms_hash_signed_attrs (cms, signer);
if (rc)
{
@@ -375,16 +402,37 @@ gpgsm_verify (int in_fd, int data_fd)
if (rc)
{
log_error ("invalid signature: %s\n", gpgsm_strerror (rc));
+ gpgsm_status (ctrl, STATUS_BADSIG, NULL);
goto next_signer;
}
log_debug ("signature okay - checking certs\n");
+ gpgsm_status (ctrl, STATUS_GOODSIG, NULL);
+ {
+ char *buf, *fpr, *tstr;
+
+ fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
+ tstr = strtimestamp ( 42 /*fixme: get right time */);
+ buf = xmalloc ( strlen(fpr) + strlen (tstr) + 100);
+ sprintf (buf, "%s %s %lu", fpr, tstr, (unsigned long)42 );
+ xfree (tstr);
+ xfree (fpr);
+ gpgsm_status (ctrl, STATUS_VALIDSIG, buf);
+ xfree (buf);
+ }
+
rc = gpgsm_validate_path (cert);
if (rc)
{
log_error ("invalid certification path: %s\n", gpgsm_strerror (rc));
+ if (rc == GPGSM_Bad_Certificate_Path
+ || rc == GPGSM_Bad_Certificate)
+ gpgsm_status (ctrl, STATUS_TRUST_NEVER, NULL);
+ else
+ gpgsm_status (ctrl, STATUS_TRUST_UNDEFINED, NULL);
goto next_signer;
}
log_info ("signature is good\n");
+ gpgsm_status (ctrl, STATUS_TRUST_FULLY, NULL);
next_signer: