mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
Write status output, make verify work in server mode.
This commit is contained in:
parent
f375790d24
commit
0b17666145
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
25
sm/gpgsm.c
25
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:
|
||||
|
88
sm/gpgsm.h
88
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);
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
245
sm/server.c
245
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,11 +154,37 @@ 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
52
sm/verify.c
52
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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user