aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sm/ChangeLog20
-rw-r--r--sm/call-agent.c8
-rw-r--r--sm/keydb.c247
-rw-r--r--sm/keylist.c14
-rw-r--r--sm/server.c58
-rw-r--r--sm/sign.c15
-rw-r--r--sm/verify.c34
7 files changed, 247 insertions, 149 deletions
diff --git a/sm/ChangeLog b/sm/ChangeLog
index e69de29bb..878002c5d 100644
--- a/sm/ChangeLog
+++ b/sm/ChangeLog
@@ -0,0 +1,20 @@
+2001-11-26 Werner Koch <[email protected]>
+
+ * keydb.c (keydb_add_resource): Create keybox
+
+ * keylist.c (gpgsm_list_keys): Fixed non-server keylisting.
+
+ * server.c (rc_to_assuan_status): New. Use it for all commands.
+
+
+ Copyright 2001 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+
diff --git a/sm/call-agent.c b/sm/call-agent.c
index c440f2bf1..16cc46fb7 100644
--- a/sm/call-agent.c
+++ b/sm/call-agent.c
@@ -470,16 +470,16 @@ request_reply (const char *line, struct membuf *membuf)
for (;len && *p != '%'; len--, p++)
;
put_membuf (membuf, buf, p-buf);
- buf = p;
if (len>2)
{ /* handle escaping */
unsigned char tmp[1];
- buf++;
- *tmp = xtoi_2 (buf);
- buf += 2;
+ p++;
+ *tmp = xtoi_2 (p);
+ p += 2;
len -= 3;
put_membuf (membuf, tmp, 1);
}
+ buf = p;
}
goto again;
}
diff --git a/sm/keydb.c b/sm/keydb.c
index b6501fe5f..a5f3f41d8 100644
--- a/sm/keydb.c
+++ b/sm/keydb.c
@@ -78,134 +78,130 @@ static void unlock_all (KEYDB_HANDLE hd);
int
keydb_add_resource (const char *url, int force, int secret)
{
- static int any_secret, any_public;
- const char *resname = url;
- char *filename = NULL;
- int rc = 0;
- KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
-/* const char *created_fname = NULL; */
-
- /* Do we have an URL?
- * gnupg-ring:filename := this is a plain keybox
- * filename := See what is is, but create as plain keybox.
- */
- if (strlen (resname) > 11) {
- if (!strncmp( resname, "gnupg-kbx:", 10) ) {
- rt = KEYDB_RESOURCE_TYPE_KEYBOX;
- resname += 11;
+ static int any_secret, any_public;
+ const char *resname = url;
+ char *filename = NULL;
+ int rc = 0;
+ FILE *fp;
+ KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
+ const char *created_fname = NULL;
+
+ /* Do we have an URL?
+ gnupg-kbx:filename := this is a plain keybox
+ filename := See what is is, but create as plain keybox.
+ */
+ if (strlen (resname) > 10)
+ {
+ if (!strncmp (resname, "gnupg-kbx:", 10) )
+ {
+ rt = KEYDB_RESOURCE_TYPE_KEYBOX;
+ resname += 10;
}
- #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
- else if (strchr (resname, ':')) {
- log_error ("invalid key resource URL `%s'\n", url );
- rc = GNUPG_General_Error;
- goto leave;
+#if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
+ else if (strchr (resname, ':'))
+ {
+ log_error ("invalid key resource URL `%s'\n", url );
+ rc = GNUPG_General_Error;
+ goto leave;
}
- #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
+#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
}
- if (*resname != DIRSEP_C ) { /* do tilde expansion etc */
- if (strchr(resname, DIRSEP_C) )
- filename = make_filename (resname, NULL);
- else
- filename = make_filename (opt.homedir, resname, NULL);
+ if (*resname != DIRSEP_C )
+ { /* do tilde expansion etc */
+ if (strchr(resname, DIRSEP_C) )
+ filename = make_filename (resname, NULL);
+ else
+ filename = make_filename (opt.homedir, resname, NULL);
}
- else
- filename = xstrdup (resname);
-
- if (!force)
- force = secret? !any_secret : !any_public;
-
- /* see whether we can determine the filetype */
- if (rt == KEYDB_RESOURCE_TYPE_NONE) {
- FILE *fp2 = fopen( filename, "rb" );
-
- if (fp2) {
- u32 magic;
-
- /* FIXME: check for the keybox magic */
- if (fread( &magic, 4, 1, fp2) == 1 )
- {
- if (magic == 0x13579ace || magic == 0xce9a5713)
- ; /* GDBM magic - no more support */
- else
- rt = KEYDB_RESOURCE_TYPE_KEYBOX;
- }
- else /* maybe empty: assume ring */
+ else
+ filename = xstrdup (resname);
+
+ if (!force)
+ force = secret? !any_secret : !any_public;
+
+ /* see whether we can determine the filetype */
+ if (rt == KEYDB_RESOURCE_TYPE_NONE)
+ {
+ FILE *fp2 = fopen( filename, "rb" );
+
+ if (fp2) {
+ u32 magic;
+
+ /* FIXME: check for the keybox magic */
+ if (fread( &magic, 4, 1, fp2) == 1 )
+ {
+ if (magic == 0x13579ace || magic == 0xce9a5713)
+ ; /* GDBM magic - no more support */
+ else
rt = KEYDB_RESOURCE_TYPE_KEYBOX;
- fclose (fp2);
- }
- else /* no file yet: create ring */
+ }
+ else /* maybe empty: assume ring */
rt = KEYDB_RESOURCE_TYPE_KEYBOX;
+ fclose (fp2);
+ }
+ else /* no file yet: create ring */
+ rt = KEYDB_RESOURCE_TYPE_KEYBOX;
}
-
- switch (rt) {
- case KEYDB_RESOURCE_TYPE_NONE:
- log_error ("unknown type of key resource `%s'\n", url );
- rc = GNUPG_General_Error;
- goto leave;
-
- case KEYDB_RESOURCE_TYPE_KEYBOX:
-#if 0
- fp = fopen (filename);
- if (!iobuf && !force) {
- rc = G10ERR_OPEN_FILE;
- goto leave;
- }
-
- if (!fp) {
- char *last_slash_in_filename;
-
- last_slash_in_filename = strrchr (filename, DIRSEP_C);
- *last_slash_in_filename = 0;
-
- if (access(filename, F_OK)) {
- /* on the first time we try to create the default
+
+ switch (rt)
+ {
+ case KEYDB_RESOURCE_TYPE_NONE:
+ log_error ("unknown type of key resource `%s'\n", url );
+ rc = GNUPG_General_Error;
+ goto leave;
+
+ case KEYDB_RESOURCE_TYPE_KEYBOX:
+ fp = fopen (filename, "rb");
+ if (!fp && !force)
+ {
+ rc = GNUPG_File_Open_Error;
+ goto leave;
+ }
+
+ if (!fp)
+ { /* no file */
+#if 0 /* no autocreate of the homedirectory yet */
+ {
+ char *last_slash_in_filename;
+
+ last_slash_in_filename = strrchr (filename, DIRSEP_C);
+ *last_slash_in_filename = 0;
+ if (access (filename, F_OK))
+ { /* on the first time we try to create the default
homedir and in this case the process will be
- terminated, so that on the next invocation it can
+ terminated, so that on the next invocation can
read the options file in on startup */
- try_make_homedir (filename);
- rc = G10ERR_OPEN_FILE;
- *last_slash_in_filename = DIRSEP_C;
- goto leave;
+ try_make_homedir (filename);
+ rc = GNUPG_File_Open_Error;
+ *last_slash_in_filename = DIRSEP_C;
+ goto leave;
+ }
+ *last_slash_in_filename = DIRSEP_C;
+ }
+#endif
+ fp = fopen (filename, "w");
+ if (!fp)
+ {
+ log_error (_("error creating keybox `%s': %s\n"),
+ filename, strerror(errno));
+ rc = GNUPG_File_Create_Error;
+ goto leave;
}
- *last_slash_in_filename = DIRSEP_C;
-
- iobuf = iobuf_create (filename);
- if (!iobuf) {
- log_error ( _("error creating keybox `%s': %s\n"),
- filename, strerror(errno));
- rc = G10ERR_OPEN_FILE;
- goto leave;
- }
- else {
- #ifndef HAVE_DOSISH_SYSTEM
- if (secret && !opt.preserve_permissionws) {
- if (chmod (filename, S_IRUSR | S_IWUSR) ) {
- log_error (_("changing permission of "
- " `%s' failed: %s\n"),
- filename, strerror(errno) );
- rc = G10ERR_WRITE_FILE;
- goto leave;
- }
- }
- #endif
- if (!opt.quiet)
- log_info (_("keybox `%s' created\n"), filename);
- created_fname = filename;
- }
+ if (!opt.quiet)
+ log_info (_("keybox `%s' created\n"), filename);
+ created_fname = filename;
}
- iobuf_close (iobuf);
- iobuf = NULL;
- if (created_fname) /* must invalidate that ugly cache */
- iobuf_ioctl (NULL, 2, 0, (char*)created_fname);
-#endif
+ fclose (fp);
+ fp = NULL;
+ /* now regsiter the file */
{
void *token = keybox_register_file (filename, secret);
if (!token)
; /* already registered - ignore it */
else if (used_resources >= MAX_KEYDB_RESOURCES)
- rc = GNUPG_Resource_Limit;
+ rc = GNUPG_Resource_Limit;
else
{
all_resources[used_resources].type = rt;
@@ -216,29 +212,26 @@ keydb_add_resource (const char *url, int force, int secret)
}
}
break;
-
- default:
- log_error ("resource type of `%s' not supported\n", url);
- rc = GNUPG_General_Error;
- goto leave;
+ default:
+ log_error ("resource type of `%s' not supported\n", url);
+ rc = GNUPG_Not_Supported;
+ goto leave;
}
- /* fixme: check directory permissions and print a warning */
+ /* fixme: check directory permissions and print a warning */
- leave:
- if (rc)
- log_error ("keyblock resource `%s': %s\n", filename, gnupg_strerror(rc));
- else if (secret)
- any_secret = 1;
- else
- any_public = 1;
- xfree (filename);
- return rc;
+ leave:
+ if (rc)
+ log_error ("keyblock resource `%s': %s\n", filename, gnupg_strerror(rc));
+ else if (secret)
+ any_secret = 1;
+ else
+ any_public = 1;
+ xfree (filename);
+ return rc;
}
-
-
KEYDB_HANDLE
keydb_new (int secret)
{
diff --git a/sm/keylist.c b/sm/keylist.c
index 19bc9dd40..98ae8eb67 100644
--- a/sm/keylist.c
+++ b/sm/keylist.c
@@ -168,13 +168,13 @@ gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp)
putc ('\n', fp);
lastresname = resname;
}
- if (ctrl->with_colons)
- list_cert_colon (cert, fp);
- else
- list_cert_colon (cert, fp);
- ksba_cert_release (cert);
- cert = NULL;
- }
+ }
+ if (ctrl->with_colons)
+ list_cert_colon (cert, fp);
+ else
+ list_cert_colon (cert, fp);
+ ksba_cert_release (cert);
+ cert = NULL;
}
while (!(rc = keydb_search_next (hd)));
if (rc && rc != -1)
diff --git a/sm/server.c b/sm/server.c
index e2f7ec086..e83506049 100644
--- a/sm/server.c
+++ b/sm/server.c
@@ -42,6 +42,45 @@ struct server_local_s {
int message_fd;
};
+/* Map GNUPG_xxx error codes to Assuan status codes */
+static int
+rc_to_assuan_status (int rc)
+{
+ switch (rc)
+ {
+ case 0: break;
+ case GNUPG_Bad_Certificate: rc = ASSUAN_Bad_Certificate; break;
+ case GNUPG_Bad_Certificate_Path: rc = ASSUAN_Bad_Certificate_Path; break;
+ case GNUPG_Missing_Certificate: rc = ASSUAN_Missing_Certificate; break;
+ case GNUPG_No_Data: rc = ASSUAN_No_Data_Available; break;
+ case GNUPG_Bad_Signature: rc = ASSUAN_Bad_Signature; break;
+ case GNUPG_Not_Implemented: rc = ASSUAN_Not_Implemented; break;
+ case GNUPG_No_Agent: rc = ASSUAN_No_Agent; break;
+ case GNUPG_Agent_Error: rc = ASSUAN_Agent_Error; break;
+ case GNUPG_No_Public_Key: rc = ASSUAN_No_Public_Key; break;
+ case GNUPG_No_Secret_Key: rc = ASSUAN_No_Secret_Key; break;
+
+ case GNUPG_Read_Error:
+ case GNUPG_Write_Error:
+ case GNUPG_IO_Error:
+ rc = ASSUAN_Server_IO_Error;
+ break;
+ case GNUPG_Out_Of_Core:
+ case GNUPG_Resource_Limit:
+ rc = ASSUAN_Server_Resource_Problem;
+ break;
+ case GNUPG_Bug:
+ case GNUPG_Internal_Error:
+ rc = ASSUAN_Server_Bug;
+ break;
+ default:
+ rc = ASSUAN_Server_Fault;
+ break;
+ }
+ return rc;
+}
+
+
/* RECIPIENT <userID>
@@ -116,15 +155,17 @@ cmd_decrypt (ASSUAN_CONTEXT ctx, char *line)
static int
cmd_verify (ASSUAN_CONTEXT ctx, char *line)
{
+ int rc;
CTRL ctrl = assuan_get_pointer (ctx);
int fd = assuan_get_input_fd (ctx);
if (fd == -1)
return set_error (No_Input, NULL);
- gpgsm_verify (assuan_get_pointer (ctx), fd, ctrl->server_local->message_fd);
+ rc = gpgsm_verify (assuan_get_pointer (ctx), fd,
+ ctrl->server_local->message_fd);
- return 0;
+ return rc_to_assuan_status (rc);
}
@@ -139,6 +180,7 @@ cmd_sign (ASSUAN_CONTEXT ctx, char *line)
int inp_fd, out_fd;
FILE *out_fp;
int detached;
+ int rc;
inp_fd = assuan_get_input_fd (ctx);
if (inp_fd == -1)
@@ -152,10 +194,10 @@ cmd_sign (ASSUAN_CONTEXT ctx, char *line)
out_fp = fdopen ( dup(out_fd), "w");
if (!out_fp)
return set_error (General_Error, "fdopen() failed");
- gpgsm_sign (assuan_get_pointer (ctx), inp_fd, detached, out_fp);
+ rc = gpgsm_sign (assuan_get_pointer (ctx), inp_fd, detached, out_fp);
fclose (out_fp);
- return 0;
+ return rc_to_assuan_status (rc);
}
@@ -168,14 +210,15 @@ cmd_sign (ASSUAN_CONTEXT ctx, char *line)
static int
cmd_import (ASSUAN_CONTEXT ctx, char *line)
{
+ int rc;
int fd = assuan_get_input_fd (ctx);
if (fd == -1)
return set_error (No_Input, NULL);
- gpgsm_import (assuan_get_pointer (ctx), fd);
+ rc = gpgsm_import (assuan_get_pointer (ctx), fd);
- return 0;
+ return rc_to_assuan_status (rc);
}
/* MESSAGE FD=<n>
@@ -211,7 +254,8 @@ cmd_listkeys (ASSUAN_CONTEXT ctx, char *line)
ctrl->with_colons = 1;
/* fixme: check that the returned data_fp is not NULL */
- gpgsm_list_keys (assuan_get_pointer (ctx), NULL, assuan_get_data_fp (ctx));
+ gpgsm_list_keys (assuan_get_pointer (ctx), NULL,
+ assuan_get_data_fp (ctx));
return 0;
}
diff --git a/sm/sign.c b/sm/sign.c
index f87f1ce48..a246511e3 100644
--- a/sm/sign.c
+++ b/sm/sign.c
@@ -244,16 +244,16 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
gcry_md_enable (data_md, algo);
}
+ signer = 0;
if (detached)
- { /* we hash the data right now so tha we can store the message
- digest. ksba_cms_build() takes this as an flag that deatched
+ { /* we hash the data right now so that we can store the message
+ digest. ksba_cms_build() takes this as an flag that detached
data is expected. */
unsigned char *digest;
size_t digest_len;
/* Fixme do this for all signers and get the algo to use from
the signer's certificate - does not make mich sense, bu we
should do this consistent as we have already done it above */
- signer = 0;
algo = GCRY_MD_SHA1;
hash_data (data_fd, data_md);
digest = gcry_md_read (data_md, algo);
@@ -274,7 +274,14 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
}
}
-
+ err = ksba_cms_set_signing_time (cms, signer, 0 /*now*/);
+ if (err)
+ {
+ log_error ("ksba_cms_set_signing_time failed: %s\n",
+ ksba_strerror (err));
+ rc = map_ksba_err (err);
+ goto leave;
+ }
do
{
diff --git a/sm/verify.c b/sm/verify.c
index 581cafeef..5b3a5a848 100644
--- a/sm/verify.c
+++ b/sm/verify.c
@@ -136,6 +136,28 @@ print_integer (unsigned char *p)
}
}
+static void
+print_time (time_t t)
+{
+
+ if (!t)
+ log_printf ("none");
+ else if ( t == (time_t)(-1) )
+ log_printf ("error");
+ else
+ {
+ struct tm *tp;
+
+ tp = gmtime (&t);
+ log_printf ("%04d-%02d-%02d %02d:%02d:%02d",
+ 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
+ tp->tm_hour, tp->tm_min, tp->tm_sec);
+ assert (!tp->tm_isdst);
+ }
+}
+
+
+
static void
hash_data (int fd, GCRY_MD_HD md)
@@ -316,6 +338,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
{
char *issuer = NULL;
char *sigval = NULL;
+ time_t sigtime;
unsigned char *serial;
char *msgdigest = NULL;
size_t msgdigestlen;
@@ -328,6 +351,17 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
print_integer (serial);
log_printf ("\n");
+ err = ksba_cms_get_signing_time (cms, signer, &sigtime);
+ if (err)
+ {
+ log_debug ("error getting signing time: %s\n", ksba_strerror (err));
+ sigtime = (time_t)-1;
+ }
+ log_debug ("signer %d - sigtime: ", signer);
+ print_time (sigtime);
+ log_printf ("\n");
+
+
err = ksba_cms_get_message_digest (cms, signer,
&msgdigest, &msgdigestlen);
if (err)