diff options
Diffstat (limited to '')
-rw-r--r-- | agent/command.c | 84 |
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 } |