diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index ed126a84..9ce48eeb 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,29 @@ +2001-11-22 Marcus Brinkmann + + * engine.c (_gpgme_engine_op_decrypt): Implement CMS case. + (_gpgme_engine_op_delete): Likewise. + (_gpgme_engine_op_encrypt): Likewise. + (_gpgme_engine_op_export): Likewise. + (_gpgme_engine_op_genkey): Likewise. + (_gpgme_engine_op_keylist): Likewise. + (_gpgme_engine_op_sign): Likewise. + (_gpgme_engine_op_trustlist): Likewise. + + * engine-gpgsm.c (_gpgme_gpgsm_op_encrypt): New function. + (gpgsm_assuan_simple_command): Likewise. + (gpgsm_set_recipients): Likewise. + (gpgsm_set_fd): Reimplement using gpgsm_assuan_simple_command. + (_gpgme_gpgsm_op_delete): New function. + (_gpgme_gpgsm_op_export): Likewise. + (_gpgme_gpgsm_op_genkey): Likewise. + (_gpgme_gpgsm_op_sign): Likewise. + (_gpgme_gpgsm_op_keylist): Likewise. + (_gpgme_gpgsm_op_trustlist): Likewise. + (_gpgme_gpgsm_release): Release command. + (_gpgme_gpgsm_op_decrypt): Allocate command. + (_gpgme_gpgsm_op_import): Likewise. + (gpgsm_status_handler): Also treat `ERR' strings as EOF. + 2001-11-22 Marcus Brinkmann * gpgme.h (gpgme_set_protocol): New prototype. diff --git a/gpgme/engine-gpgsm.c b/gpgme/engine-gpgsm.c index fcdb667c..7390f36f 100644 --- a/gpgme/engine-gpgsm.c +++ b/gpgme/engine-gpgsm.c @@ -46,6 +46,7 @@ #include "ops.h" #include "wait.h" #include "io.h" +#include "key.h" #include "engine-gpgsm.h" @@ -175,17 +176,16 @@ _gpgme_gpgsm_release (GpgsmObject gpgsm) _gpgme_io_close (gpgsm->message_fd); assuan_pipe_disconnect (gpgsm->assuan_ctx); + + xfree (gpgsm->command); xfree (gpgsm); } -#define COMMANDLINELEN 40 static AssuanError -gpgsm_set_fd (ASSUAN_CONTEXT ctx, const char *which, int fd) +gpgsm_assuan_simple_command (ASSUAN_CONTEXT ctx, char *line) { AssuanError err; - char line[COMMANDLINELEN]; - snprintf (line, COMMANDLINELEN, "%s FD=%i", which, fd); err = _assuan_write_line (ctx, line); if (err) return err; @@ -206,6 +206,16 @@ gpgsm_set_fd (ASSUAN_CONTEXT ctx, const char *which, int fd) return ASSUAN_General_Error; } +#define COMMANDLINELEN 40 +static AssuanError +gpgsm_set_fd (ASSUAN_CONTEXT ctx, const char *which, int fd) +{ + char line[COMMANDLINELEN]; + + snprintf (line, COMMANDLINELEN, "%s FD=%i", which, fd); + return gpgsm_assuan_simple_command (ctx, line); +} + GpgmeError _gpgme_gpgsm_op_decrypt (GpgsmObject gpgsm, GpgmeData ciph, GpgmeData plain) { @@ -214,6 +224,10 @@ _gpgme_gpgsm_op_decrypt (GpgsmObject gpgsm, GpgmeData ciph, GpgmeData plain) if (!gpgsm) return mk_error (Invalid_Value); + gpgsm->command = xtrystrdup ("DECRYPT"); + if (!gpgsm->command) + return mk_error (Out_Of_Core); + gpgsm->input_data = ciph; err = gpgsm_set_fd (gpgsm->assuan_ctx, "INPUT", gpgsm->input_fd_server); if (err) @@ -225,10 +239,101 @@ _gpgme_gpgsm_op_decrypt (GpgsmObject gpgsm, GpgmeData ciph, GpgmeData plain) _gpgme_io_close (gpgsm->message_fd); gpgsm->message_fd = -1; - gpgsm->command = "DECRYPT"; return 0; } +GpgmeError +_gpgme_gpgsm_op_delete (GpgsmObject gpgsm, GpgmeKey key, int allow_secret) +{ + /* FIXME */ + return mk_error (Not_Implemented); +} + +static AssuanError +gpgsm_set_recipients (ASSUAN_CONTEXT ctx, GpgmeRecipients recp) +{ + AssuanError err; + char *line; + int linelen; + struct user_id_s *r; + + linelen = 10 + 40 + 1; /* "RECIPIENT " + guess + '\0'. */ + line = xtrymalloc (10 + 40 + 1); + if (!line) + return ASSUAN_Out_Of_Core; + strcpy (line, "RECIPIENT "); + for (r = recp->list; r; r = r->next) + { + int newlen = 11 + strlen (r->name); + if (linelen < newlen) + { + char *newline = xtryrealloc (line, newlen); + if (! newline) + { + xfree (line); + return ASSUAN_Out_Of_Core; + } + line = newline; + linelen = newlen; + } + strcpy (&line[10], r->name); + + err = gpgsm_assuan_simple_command (ctx, line); + if (err) + { + xfree (line); + return err; + } + } + return 0; +} + +GpgmeError +_gpgme_gpgsm_op_encrypt (GpgsmObject gpgsm, GpgmeRecipients recp, + GpgmeData plain, GpgmeData ciph, int use_armor) +{ + AssuanError err; + + if (!gpgsm) + return mk_error (Invalid_Value); + + gpgsm->command = xtrystrdup (use_armor ? "ENCRYPT armor" : "ENCRYPT"); + if (!gpgsm->command) + return mk_error (Out_Of_Core); + + gpgsm->input_data = plain; + err = gpgsm_set_fd (gpgsm->assuan_ctx, "INPUT", gpgsm->input_fd_server); + if (err) + return mk_error (General_Error); /* FIXME */ + gpgsm->output_data = ciph; + err = gpgsm_set_fd (gpgsm->assuan_ctx, "OUTPUT", gpgsm->output_fd_server); + if (err) + return mk_error (General_Error); /* FIXME */ + _gpgme_io_close (gpgsm->message_fd); + gpgsm->message_fd = -1; + + err = gpgsm_set_recipients (gpgsm->assuan_ctx, recp); + if (err) + return mk_error (General_Error); + + return 0; +} + +GpgmeError +_gpgme_gpgsm_op_export (GpgsmObject gpgsm, GpgmeRecipients recp, + GpgmeData keydata, int use_armor) +{ + /* FIXME */ + return mk_error (Not_Implemented); +} + +GpgmeError +_gpgme_gpgsm_op_genkey (GpgsmObject gpgsm, GpgmeData help_data, int use_armor) +{ + /* FIXME */ + return mk_error (Not_Implemented); +} + GpgmeError _gpgme_gpgsm_op_import (GpgsmObject gpgsm, GpgmeData keydata) { @@ -237,6 +342,10 @@ _gpgme_gpgsm_op_import (GpgsmObject gpgsm, GpgmeData keydata) if (!gpgsm) return mk_error (Invalid_Value); + gpgsm->command = xtrystrdup ("IMPORT"); + if (!gpgsm->command) + return mk_error (Out_Of_Core); + gpgsm->input_data = keydata; err = gpgsm_set_fd (gpgsm->assuan_ctx, "INPUT", gpgsm->input_fd_server); if (err) @@ -246,10 +355,48 @@ _gpgme_gpgsm_op_import (GpgsmObject gpgsm, GpgmeData keydata) _gpgme_io_close (gpgsm->message_fd); gpgsm->message_fd = -1; - gpgsm->command = "DECRYPT"; return 0; } +GpgmeError +_gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern, + int secret_only, int keylist_mode) +{ + char *line; + + line = xtrymalloc (9 + strlen (pattern) + 1); /* "LISTKEYS " + p + '\0'. */ + if (!line) + return mk_error (Out_Of_Core); + strcpy (line, "LISTKEYS "); + strcpy (&line[9], pattern); + + _gpgme_io_close (gpgsm->input_fd); + gpgsm->input_fd = -1; + _gpgme_io_close (gpgsm->output_fd); + gpgsm->output_fd = -1; + _gpgme_io_close (gpgsm->message_fd); + gpgsm->message_fd = -1; + + gpgsm->command = line; + return 0; +} + +GpgmeError +_gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, GpgmeData out, + GpgmeSigMode mode, int use_armor, + int use_textmode, GpgmeCtx ctx /* FIXME */) +{ + /* FIXME */ + return mk_error (Not_Implemented); +} + +GpgmeError +_gpgme_gpgsm_op_trustlist (GpgsmObject gpgsm, const char *pattern) +{ + /* FIXME */ + return mk_error (Not_Implemented); +} + GpgmeError _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, GpgmeData text) { @@ -258,6 +405,10 @@ _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, GpgmeData text) if (!gpgsm) return mk_error (Invalid_Value); + gpgsm->command = xtrystrdup ("VERIFY"); + if (!gpgsm->command) + return mk_error (Out_Of_Core); + gpgsm->input_data = sig; err = gpgsm_set_fd (gpgsm->assuan_ctx, "INPUT", gpgsm->input_fd_server); if (err) @@ -269,7 +420,6 @@ _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, GpgmeData text) _gpgme_io_close (gpgsm->output_fd); gpgsm->output_fd = -1; - gpgsm->command = "VERIFY"; return 0; } @@ -287,10 +437,15 @@ gpgsm_status_handler (void *opaque, int pid, int fd) if (actx->inbound.line[0] == '#' || !actx->inbound.linelen) return 0; /* FIXME */ - if (actx->inbound.linelen >= 2 - && actx->inbound.line[0] == 'O' && actx->inbound.line[1] == 'K' - && (actx->inbound.line[2] == '\0' || actx->inbound.line[2] == ' ')) + if ((actx->inbound.linelen >= 2 + && actx->inbound.line[0] == 'O' && actx->inbound.line[1] == 'K' + && (actx->inbound.line[2] == '\0' || actx->inbound.line[2] == ' ')) + || (actx->inbound.linelen >= 3 + && actx->inbound.line[0] == 'E' && actx->inbound.line[1] == 'R' + && actx->inbound.line[2] == 'R' + && (actx->inbound.line[3] == '\0' || actx->inbound.line[3] == ' '))) { + /* FIXME Save error somewhere. */ if (gpgsm->status.fnc) gpgsm->status.fnc (gpgsm->status.fnc_value, STATUS_EOF, ""); return 1; @@ -396,12 +551,59 @@ _gpgme_gpgsm_op_decrypt (GpgsmObject gpgsm, GpgmeData ciph, GpgmeData plain) return mk_error (Invalid_Engine); } +GpgmeError +_gpgme_gpgsm_op_delete (GpgsmObject gpgsm, GpgmeKey key, int allow_secret) +{ + return mk_error (Invalid_Engine); +} + +GpgmeError +_gpgme_gpgsm_op_encrypt (GpgsmObject gpgsm, GpgmeRecipients recp, + GpgmeData plain, GpgmeData ciph, int use_armor) +{ + return mk_error (Invalid_Engine); +} + +GpgmeError +_gpgme_gpgsm_op_export (GpgsmObject gpgsm, GpgmeRecipients recp, + GpgmeData keydata, int use_armor) +{ + return mk_error (Invalid_Engine); +} + +GpgmeError +_gpgme_gpgsm_op_genkey (GpgsmObject gpgsm, GpgmeData help_data, int use_armor) +{ + return mk_error (Invalid_Engine); +} + GpgmeError _gpgme_gpgsm_op_import (GpgsmObject gpgsm, GpgmeData keydata) { return mk_error (Invalid_Engine); } +GpgmeError +_gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern, + int secret_only, int keylist_mode) +{ + return mk_error (Invalid_Engine); +} + +GpgmeError +_gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, GpgmeData out, + GpgmeSigMode mode, int use_armor, + int use_textmode, GpgmeCtx ctx /* FIXME */) +{ + return mk_error (Invalid_Engine); +} + +GpgmeError +_gpgme_gpgsm_op_trustlist (GpgsmObject gpgsm, const char *pattern) +{ + return mk_error (Invalid_Engine); +} + GpgmeError _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, GpgmeData text) { diff --git a/gpgme/engine-gpgsm.h b/gpgme/engine-gpgsm.h index 5feada86..bd6dd1e7 100644 --- a/gpgme/engine-gpgsm.h +++ b/gpgme/engine-gpgsm.h @@ -34,23 +34,26 @@ void _gpgme_gpgsm_release (GpgsmObject gpg); void _gpgme_gpgsm_set_status_handler (GpgsmObject gpgsm, GpgStatusHandler fnc, void *fnc_value); GpgmeError _gpgme_gpgsm_op_decrypt (GpgsmObject gpgsm, GpgmeData ciph, - GpgmeData plain); -GpgmeError _gpgme_gpgsm_op_delete (GpgsmObject gpgsm, GpgmeKey key, int allow_secret); + GpgmeData plain); +GpgmeError _gpgme_gpgsm_op_delete (GpgsmObject gpgsm, GpgmeKey key, + int allow_secret); GpgmeError _gpgme_gpgsm_op_encrypt (GpgsmObject gpgsm, GpgmeRecipients recp, - GpgmeData plain, GpgmeData ciph, - int use_armor); + GpgmeData plain, GpgmeData ciph, + int use_armor); GpgmeError _gpgme_gpgsm_op_export (GpgsmObject gpgsm, GpgmeRecipients recp, - GpgmeData keydata, int use_armor); + GpgmeData keydata, int use_armor); GpgmeError _gpgme_gpgsm_op_genkey (GpgsmObject gpgsm, GpgmeData help_data, - int use_armor); + int use_armor); GpgmeError _gpgme_gpgsm_op_import (GpgsmObject gpgsm, GpgmeData keydata); GpgmeError _gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern, - int secret_only, int keylist_mode); -GpgmeError _gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, GpgmeData out, - GpgmeSigMode mode, int use_armor, - int use_textmode, GpgmeCtx ctx /* FIXME */); + int secret_only, int keylist_mode); +GpgmeError _gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, + GpgmeData out, + GpgmeSigMode mode, int use_armor, + int use_textmode, GpgmeCtx ctx /* FIXME */); GpgmeError _gpgme_gpgsm_op_trustlist (GpgsmObject gpgsm, const char *pattern); -GpgmeError _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, GpgmeData text); +GpgmeError _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, + GpgmeData text); GpgmeError _gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque); #endif /* ENGINE_GPGSM_H */ diff --git a/gpgme/engine.c b/gpgme/engine.c index 74951058..08fb9515 100644 --- a/gpgme/engine.c +++ b/gpgme/engine.c @@ -248,8 +248,7 @@ _gpgme_engine_op_decrypt (EngineObject engine, GpgmeData ciph, GpgmeData plain) case GPGME_PROTOCOL_OpenPGP: return _gpgme_gpg_op_decrypt (engine->engine.gpg, ciph, plain); case GPGME_PROTOCOL_CMS: - /* FIXME */ - break; + return _gpgme_gpgsm_op_decrypt (engine->engine.gpgsm, ciph, plain); default: break; } @@ -267,8 +266,7 @@ _gpgme_engine_op_delete (EngineObject engine, GpgmeKey key, int allow_secret) case GPGME_PROTOCOL_OpenPGP: return _gpgme_gpg_op_delete (engine->engine.gpg, key, allow_secret); case GPGME_PROTOCOL_CMS: - /* FIXME */ - break; + return _gpgme_gpgsm_op_delete (engine->engine.gpgsm, key, allow_secret); default: break; } @@ -288,8 +286,8 @@ _gpgme_engine_op_encrypt (EngineObject engine, GpgmeRecipients recp, return _gpgme_gpg_op_encrypt (engine->engine.gpg, recp, plain, ciph, use_armor); case GPGME_PROTOCOL_CMS: - /* FIXME */ - break; + return _gpgme_gpgsm_op_encrypt (engine->engine.gpgsm, recp, plain, ciph, + use_armor); default: break; } @@ -309,8 +307,8 @@ _gpgme_engine_op_export (EngineObject engine, GpgmeRecipients recp, return _gpgme_gpg_op_export (engine->engine.gpg, recp, keydata, use_armor); case GPGME_PROTOCOL_CMS: - /* FIXME */ - break; + return _gpgme_gpgsm_op_export (engine->engine.gpgsm, recp, keydata, + use_armor); default: break; } @@ -328,8 +326,7 @@ _gpgme_engine_op_genkey (EngineObject engine, GpgmeData help_data, int use_armor case GPGME_PROTOCOL_OpenPGP: return _gpgme_gpg_op_genkey (engine->engine.gpg, help_data, use_armor); case GPGME_PROTOCOL_CMS: - /* FIXME */ - break; + return _gpgme_gpgsm_op_genkey (engine->engine.gpgsm, help_data, use_armor); default: break; } @@ -347,8 +344,7 @@ _gpgme_engine_op_import (EngineObject engine, GpgmeData keydata) case GPGME_PROTOCOL_OpenPGP: return _gpgme_gpg_op_import (engine->engine.gpg, keydata); case GPGME_PROTOCOL_CMS: - /* FIXME */ - break; + return _gpgme_gpgsm_op_import (engine->engine.gpgsm, keydata); default: break; } @@ -368,8 +364,8 @@ _gpgme_engine_op_keylist (EngineObject engine, const char *pattern, int secret_o return _gpgme_gpg_op_keylist (engine->engine.gpg, pattern, secret_only, keylist_mode); case GPGME_PROTOCOL_CMS: - /* FIXME */ - break; + return _gpgme_gpgsm_op_keylist (engine->engine.gpgsm, pattern, secret_only, + keylist_mode); default: break; } @@ -390,7 +386,8 @@ _gpgme_engine_op_sign (EngineObject engine, GpgmeData in, GpgmeData out, return _gpgme_gpg_op_sign (engine->engine.gpg, in, out, mode, use_armor, use_textmode, ctx); case GPGME_PROTOCOL_CMS: - /* FIXME */ + return _gpgme_gpgsm_op_sign (engine->engine.gpgsm, in, out, mode, + use_armor, use_textmode, ctx); break; default: break; @@ -409,8 +406,7 @@ _gpgme_engine_op_trustlist (EngineObject engine, const char *pattern) case GPGME_PROTOCOL_OpenPGP: return _gpgme_gpg_op_trustlist (engine->engine.gpg, pattern); case GPGME_PROTOCOL_CMS: - /* FIXME */ - break; + return _gpgme_gpgsm_op_trustlist (engine->engine.gpgsm, pattern); default: break; }