aboutsummaryrefslogtreecommitdiffstats
path: root/agent/command.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--agent/command.c84
1 files changed, 78 insertions, 6 deletions
diff --git a/agent/command.c b/agent/command.c
index 80e13182d..4e3da80a4 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -32,6 +32,10 @@
#include "agent.h"
#include "../assuan/assuan.h"
+/* maximum allowed size of the inquired ciphertext */
+#define MAXLEN_CIPHERTEXT 4096
+
+
#define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t))
#define digitp(a) ((a) >= '0' && (a) <= '9')
#define hexdigitp(a) (digitp (a) \
@@ -55,18 +59,62 @@ struct server_local_s {
};
+/* Map GNUPG_xxx error codes to Assuan status codes
+ FIXME: duplicated from ../sm/server.c */
+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_Invalid_Data: rc = ASSUAN_Invalid_Data; 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;
+}
+
+
+
static void
reset_notify (ASSUAN_CONTEXT ctx)
{
CTRL ctrl = assuan_get_pointer (ctx);
memset (ctrl->keygrip, 0, 20);
+ ctrl->have_keygrip = 0;
ctrl->digest.valuelen = 0;
}
/* SIGKEY <hexstring_with_keygrip>
-
- Set the key used for a sign operation */
+ SETKEY <hexstring_with_keygrip>
+
+ Set the key used for a sign or decrypt operation */
static int
cmd_sigkey (ASSUAN_CONTEXT ctx, char *line)
{
@@ -89,6 +137,7 @@ cmd_sigkey (ASSUAN_CONTEXT ctx, char *line)
buf = ctrl->keygrip;
for (p=line, n=0; n < 20; p += 2, n++)
buf[n] = xtoi_2 (p);
+ ctrl->have_keygrip = 1;
return 0;
}
@@ -140,17 +189,38 @@ cmd_sethash (ASSUAN_CONTEXT ctx, char *line)
/* PKSIGN <options>
Perform the actual sign operation. Neither input nor output are
- sensitive to to eavesdropping */
+ sensitive to eavesdropping */
static int
cmd_pksign (ASSUAN_CONTEXT ctx, char *line)
{
int rc;
CTRL ctrl = assuan_get_pointer (ctx);
- /* fixme: check that all required data is available */
rc = agent_pksign (ctrl, assuan_get_data_fp (ctx));
- /* fixme: return an error */
- return 0;
+ return rc_to_assuan_status (rc);
+}
+
+/* PKDECRYPT <options>
+
+ Perform the actual decrypt operation. Input is not
+ sensitive to eavesdropping */
+static int
+cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line)
+{
+ int rc;
+ CTRL ctrl = assuan_get_pointer (ctx);
+ char *value;
+ size_t valuelen;
+
+ /* First inquire the data to decrypt */
+ rc = assuan_inquire (ctx, "CIPHERTEXT",
+ &value, &valuelen, MAXLEN_CIPHERTEXT);
+ if (rc)
+ return rc;
+
+ rc = agent_pkdecrypt (ctrl, value, valuelen, assuan_get_data_fp (ctx));
+ xfree (value);
+ return rc_to_assuan_status (rc);
}
@@ -165,8 +235,10 @@ register_commands (ASSUAN_CONTEXT ctx)
int (*handler)(ASSUAN_CONTEXT, char *line);
} table[] = {
{ "SIGKEY", 0, cmd_sigkey },
+ { "SETKEY", 0, cmd_sigkey },
{ "SETHASH", 0, cmd_sethash },
{ "PKSIGN", 0, cmd_pksign },
+ { "PKDECRYPT", 0, cmd_pkdecrypt },
{ "", ASSUAN_CMD_INPUT, NULL },
{ "", ASSUAN_CMD_OUTPUT, NULL },
{ NULL }