agent: Minor fix for Windows.
[gnupg.git] / agent / command.c
1 /* command.c - gpg-agent command handler
2  * Copyright (C) 2001-2011 Free Software Foundation, Inc.
3  * Copyright (C) 2001-2013 Werner Koch
4  * Copyright (C) 2015 g10 Code GmbH.
5  *
6  * This file is part of GnuPG.
7  *
8  * GnuPG is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * GnuPG is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, see <https://www.gnu.org/licenses/>.
20  */
21
22 /* FIXME: we should not use the default assuan buffering but setup
23    some buffering in secure mempory to protect session keys etc. */
24
25 #include <config.h>
26
27 #include <errno.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <unistd.h>
33 #include <assert.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <dirent.h>
37
38 #include "agent.h"
39 #include <assuan.h>
40 #include "../common/i18n.h"
41 #include "cvt-openpgp.h"
42 #include "../common/ssh-utils.h"
43 #include "../common/asshelp.h"
44 #include "../common/server-help.h"
45
46
47 /* Maximum allowed size of the inquired ciphertext.  */
48 #define MAXLEN_CIPHERTEXT 4096
49 /* Maximum allowed size of the key parameters.  */
50 #define MAXLEN_KEYPARAM 1024
51 /* Maximum allowed size of key data as used in inquiries (bytes). */
52 #define MAXLEN_KEYDATA 8192
53 /* The size of the import/export KEK key (in bytes).  */
54 #define KEYWRAP_KEYSIZE (128/8)
55
56 /* A shortcut to call assuan_set_error using an gpg_err_code_t and a
57    text string.  */
58 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
59
60 /* Check that the maximum digest length we support has at least the
61    length of the keygrip.  */
62 #if MAX_DIGEST_LEN < 20
63 #error MAX_DIGEST_LEN shorter than keygrip
64 #endif
65
66 /* Data used to associate an Assuan context with local server data.
67    This is this modules local part of the server_control_s struct.  */
68 struct server_local_s
69 {
70   /* Our Assuan context.  */
71   assuan_context_t assuan_ctx;
72
73   /* If this flag is true, the passphrase cache is used for signing
74      operations.  It defaults to true but may be set on a per
75      connection base.  The global option opt.ignore_cache_for_signing
76      takes precedence over this flag.  */
77   unsigned int use_cache_for_signing : 1;
78
79   /* Flag to suppress I/O logging during a command.  */
80   unsigned int pause_io_logging : 1;
81
82   /* Flag indicating that the connection is from ourselves.  */
83   unsigned int connect_from_self : 1;
84
85   /* Helper flag for io_monitor to allow suppressing of our own
86    * greeting in some cases.  See io_monitor for details.  */
87   unsigned int greeting_seen : 1;
88
89   /* If this flag is set to true the agent will be terminated after
90      the end of the current session.  */
91   unsigned int stopme : 1;
92
93   /* Flag indicating whether pinentry notifications shall be done. */
94   unsigned int allow_pinentry_notify : 1;
95
96   /* An allocated description for the next key operation.  This is
97      used if a pinnetry needs to be popped up.  */
98   char *keydesc;
99
100   /* Malloced KEK (Key-Encryption-Key) for the import_key command.  */
101   void *import_key;
102
103   /* Malloced KEK for the export_key command.  */
104   void *export_key;
105
106   /* Client is aware of the error code GPG_ERR_FULLY_CANCELED.  */
107   int allow_fully_canceled;
108
109   /* Last CACHE_NONCE sent as status (malloced).  */
110   char *last_cache_nonce;
111
112   /* Last PASSWD_NONCE sent as status (malloced). */
113   char *last_passwd_nonce;
114 };
115
116
117 /* An entry for the getval/putval commands. */
118 struct putval_item_s
119 {
120   struct putval_item_s *next;
121   size_t off;  /* Offset to the value into DATA.  */
122   size_t len;  /* Length of the value.  */
123   char d[1];   /* Key | Nul | value.  */
124 };
125
126
127 /* A list of key value pairs fpr the getval/putval commands.  */
128 static struct putval_item_s *putval_list;
129
130
131 \f
132 /* To help polling clients, we keep track of the number of certain
133    events.  This structure keeps those counters.  The counters are
134    integers and there should be no problem if they are overflowing as
135    callers need to check only whether a counter changed.  The actual
136    values are not meaningful. */
137 struct
138 {
139   /* Incremented if any of the other counters below changed. */
140   unsigned int any;
141
142   /* Incremented if a key is added or removed from the internal privat
143      key database. */
144   unsigned int key;
145
146   /* Incremented if a change of the card readers stati has been
147      detected. */
148   unsigned int card;
149
150 } eventcounter;
151
152
153 \f
154 /*  Local prototypes.  */
155 static int command_has_option (const char *cmd, const char *cmdopt);
156
157
158
159 \f
160 /* Release the memory buffer MB but first wipe out the used memory. */
161 static void
162 clear_outbuf (membuf_t *mb)
163 {
164   void *p;
165   size_t n;
166
167   p = get_membuf (mb, &n);
168   if (p)
169     {
170       wipememory (p, n);
171       xfree (p);
172     }
173 }
174
175
176 /* Write the content of memory buffer MB as assuan data to CTX and
177    wipe the buffer out afterwards. */
178 static gpg_error_t
179 write_and_clear_outbuf (assuan_context_t ctx, membuf_t *mb)
180 {
181   gpg_error_t ae;
182   void *p;
183   size_t n;
184
185   p = get_membuf (mb, &n);
186   if (!p)
187     return out_of_core ();
188   ae = assuan_send_data (ctx, p, n);
189   memset (p, 0, n);
190   xfree (p);
191   return ae;
192 }
193
194
195 /* Clear the nonces used to enable the passphrase cache for certain
196    multi-command command sequences.  */
197 static void
198 clear_nonce_cache (ctrl_t ctrl)
199 {
200   if (ctrl->server_local->last_cache_nonce)
201     {
202       agent_put_cache (ctrl->server_local->last_cache_nonce,
203                        CACHE_MODE_NONCE, NULL, 0);
204       xfree (ctrl->server_local->last_cache_nonce);
205       ctrl->server_local->last_cache_nonce = NULL;
206     }
207   if (ctrl->server_local->last_passwd_nonce)
208     {
209       agent_put_cache (ctrl->server_local->last_passwd_nonce,
210                        CACHE_MODE_NONCE, NULL, 0);
211       xfree (ctrl->server_local->last_passwd_nonce);
212       ctrl->server_local->last_passwd_nonce = NULL;
213     }
214 }
215
216
217 /* This function is called by Libassuan whenever the client sends a
218    reset.  It has been registered similar to the other Assuan
219    commands.  */
220 static gpg_error_t
221 reset_notify (assuan_context_t ctx, char *line)
222 {
223   ctrl_t ctrl = assuan_get_pointer (ctx);
224
225   (void) line;
226
227   memset (ctrl->keygrip, 0, 20);
228   ctrl->have_keygrip = 0;
229   ctrl->digest.valuelen = 0;
230
231   xfree (ctrl->server_local->keydesc);
232   ctrl->server_local->keydesc = NULL;
233
234   clear_nonce_cache (ctrl);
235
236   return 0;
237 }
238
239
240 /* Replace all '+' by a blank in the string S. */
241 static void
242 plus_to_blank (char *s)
243 {
244   for (; *s; s++)
245     {
246       if (*s == '+')
247         *s = ' ';
248     }
249 }
250
251
252 /* Parse a hex string.  Return an Assuan error code or 0 on success and the
253    length of the parsed string in LEN. */
254 static int
255 parse_hexstring (assuan_context_t ctx, const char *string, size_t *len)
256 {
257   const char *p;
258   size_t n;
259
260   /* parse the hash value */
261   for (p=string, n=0; hexdigitp (p); p++, n++)
262     ;
263   if (*p != ' ' && *p != '\t' && *p)
264     return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
265   if ((n&1))
266     return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
267   *len = n;
268   return 0;
269 }
270
271
272 /* Parse the keygrip in STRING into the provided buffer BUF.  BUF must
273    provide space for 20 bytes.  BUF is not changed if the function
274    returns an error. */
275 static int
276 parse_keygrip (assuan_context_t ctx, const char *string, unsigned char *buf)
277 {
278   int rc;
279   size_t n = 0;
280
281   rc = parse_hexstring (ctx, string, &n);
282   if (rc)
283     return rc;
284   n /= 2;
285   if (n != 20)
286     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of keygrip");
287
288   if (hex2bin (string, buf, 20) < 0)
289     return set_error (GPG_ERR_BUG, "hex2bin");
290
291   return 0;
292 }
293
294
295 /* Write an Assuan status line.  KEYWORD is the first item on the
296    status line.  The following arguments are all separated by a space
297    in the output.  The last argument must be a NULL.  Linefeeds and
298    carriage returns characters (which are not allowed in an Assuan
299    status line) are silently quoted in C-style.  */
300 gpg_error_t
301 agent_write_status (ctrl_t ctrl, const char *keyword, ...)
302 {
303   gpg_error_t err = 0;
304   va_list arg_ptr;
305   const char *text;
306   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
307   char buf[950], *p;
308   size_t n;
309
310   va_start (arg_ptr, keyword);
311
312   p = buf;
313   n = 0;
314   while ( (text = va_arg (arg_ptr, const char *)) )
315     {
316       if (n)
317         {
318           *p++ = ' ';
319           n++;
320         }
321       for ( ; *text && n < DIM (buf)-3; n++, text++)
322         {
323           if (*text == '\n')
324             {
325               *p++ = '\\';
326               *p++ = 'n';
327             }
328           else if (*text == '\r')
329             {
330               *p++ = '\\';
331               *p++ = 'r';
332             }
333           else
334             *p++ = *text;
335         }
336     }
337   *p = 0;
338   err = assuan_write_status (ctx, keyword, buf);
339
340   va_end (arg_ptr);
341   return err;
342 }
343
344
345 /* This function is similar to print_assuan_status but takes a CTRL
346    arg instead of an assuan context as first argument.  */
347 gpg_error_t
348 agent_print_status (ctrl_t ctrl, const char *keyword, const char *format, ...)
349 {
350   gpg_error_t err;
351   va_list arg_ptr;
352   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
353
354   va_start (arg_ptr, format);
355   err = vprint_assuan_status (ctx, keyword, format, arg_ptr);
356   va_end (arg_ptr);
357   return err;
358 }
359
360
361 /* Helper to notify the client about a launched Pinentry.  Because
362    that might disturb some older clients, this is only done if enabled
363    via an option.  Returns an gpg error code. */
364 gpg_error_t
365 agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid, const char *extra)
366 {
367   char line[256];
368
369   if (!ctrl || !ctrl->server_local
370       || !ctrl->server_local->allow_pinentry_notify)
371     return 0;
372   snprintf (line, DIM(line), "PINENTRY_LAUNCHED %lu%s%s",
373             pid, extra?" ":"", extra? extra:"");
374   return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0);
375 }
376
377
378 /* An agent progress callback for Libgcrypt.  This has been registered
379  * to be called via the progress dispatcher mechanism from
380  * gpg-agent.c  */
381 static void
382 progress_cb (ctrl_t ctrl, const char *what, int printchar,
383              int current, int total)
384 {
385   if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
386     ;
387   else if (printchar == '\n' && what && !strcmp (what, "primegen"))
388     agent_print_status (ctrl, "PROGRESS", "%.20s X 100 100", what);
389   else
390     agent_print_status (ctrl, "PROGRESS", "%.20s %c %d %d",
391                         what, printchar=='\n'?'X':printchar, current, total);
392 }
393
394
395 /* Helper to print a message while leaving a command.  Note that this
396  * function does not call assuan_set_error; the caller may do this
397  * prior to calling us.  */
398 static gpg_error_t
399 leave_cmd (assuan_context_t ctx, gpg_error_t err)
400 {
401   if (err)
402     {
403       const char *name = assuan_get_command_name (ctx);
404       if (!name)
405         name = "?";
406
407       /* Not all users of gpg-agent know about the fully canceled
408          error code; map it back if needed.  */
409       if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
410         {
411           ctrl_t ctrl = assuan_get_pointer (ctx);
412
413           if (!ctrl->server_local->allow_fully_canceled)
414             err = gpg_err_make (gpg_err_source (err), GPG_ERR_CANCELED);
415         }
416
417       /* Most code from common/ does not know the error source, thus
418          we fix this here.  */
419       if (gpg_err_source (err) == GPG_ERR_SOURCE_UNKNOWN)
420         err = gpg_err_make (GPG_ERR_SOURCE_DEFAULT, gpg_err_code (err));
421
422       if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
423         log_error ("command '%s' failed: %s\n", name,
424                    gpg_strerror (err));
425       else
426         log_error ("command '%s' failed: %s <%s>\n", name,
427                    gpg_strerror (err), gpg_strsource (err));
428     }
429   return err;
430 }
431
432
433 \f
434 static const char hlp_geteventcounter[] =
435   "GETEVENTCOUNTER\n"
436   "\n"
437   "Return a status line named EVENTCOUNTER with the current values\n"
438   "of all event counters.  The values are decimal numbers in the range\n"
439   "0 to UINT_MAX and wrapping around to 0.  The actual values should\n"
440   "not be relied upon, they shall only be used to detect a change.\n"
441   "\n"
442   "The currently defined counters are:\n"
443   "\n"
444   "ANY  - Incremented with any change of any of the other counters.\n"
445   "KEY  - Incremented for added or removed private keys.\n"
446   "CARD - Incremented for changes of the card readers stati.";
447 static gpg_error_t
448 cmd_geteventcounter (assuan_context_t ctx, char *line)
449 {
450   ctrl_t ctrl = assuan_get_pointer (ctx);
451
452   (void)line;
453
454   if (ctrl->restricted)
455     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
456
457   return agent_print_status (ctrl, "EVENTCOUNTER", "%u %u %u",
458                              eventcounter.any,
459                              eventcounter.key,
460                              eventcounter.card);
461 }
462
463
464 /* This function should be called once for all key removals or
465    additions.  This function is assured not to do any context
466    switches. */
467 void
468 bump_key_eventcounter (void)
469 {
470   eventcounter.key++;
471   eventcounter.any++;
472 }
473
474
475 /* This function should be called for all card reader status
476    changes.  This function is assured not to do any context
477    switches. */
478 void
479 bump_card_eventcounter (void)
480 {
481   eventcounter.card++;
482   eventcounter.any++;
483 }
484
485
486
487 \f
488 static const char hlp_istrusted[] =
489   "ISTRUSTED <hexstring_with_fingerprint>\n"
490   "\n"
491   "Return OK when we have an entry with this fingerprint in our\n"
492   "trustlist";
493 static gpg_error_t
494 cmd_istrusted (assuan_context_t ctx, char *line)
495 {
496   ctrl_t ctrl = assuan_get_pointer (ctx);
497   int rc, n, i;
498   char *p;
499   char fpr[41];
500
501   /* Parse the fingerprint value. */
502   for (p=line,n=0; hexdigitp (p); p++, n++)
503     ;
504   if (*p || !(n == 40 || n == 32))
505     return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint");
506   i = 0;
507   if (n==32)
508     {
509       strcpy (fpr, "00000000");
510       i += 8;
511     }
512   for (p=line; i < 40; p++, i++)
513     fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
514   fpr[i] = 0;
515   rc = agent_istrusted (ctrl, fpr, NULL);
516   if (!rc || gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
517     return rc;
518   else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF )
519     return gpg_error (GPG_ERR_NOT_TRUSTED);
520   else
521     return leave_cmd (ctx, rc);
522 }
523
524
525 static const char hlp_listtrusted[] =
526   "LISTTRUSTED\n"
527   "\n"
528   "List all entries from the trustlist.";
529 static gpg_error_t
530 cmd_listtrusted (assuan_context_t ctx, char *line)
531 {
532   ctrl_t ctrl = assuan_get_pointer (ctx);
533   int rc;
534
535   (void)line;
536
537   if (ctrl->restricted)
538     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
539
540   rc = agent_listtrusted (ctx);
541   return leave_cmd (ctx, rc);
542 }
543
544
545 static const char hlp_martrusted[] =
546   "MARKTRUSTED <hexstring_with_fingerprint> <flag> <display_name>\n"
547   "\n"
548   "Store a new key in into the trustlist.";
549 static gpg_error_t
550 cmd_marktrusted (assuan_context_t ctx, char *line)
551 {
552   ctrl_t ctrl = assuan_get_pointer (ctx);
553   int rc, n, i;
554   char *p;
555   char fpr[41];
556   int flag;
557
558   if (ctrl->restricted)
559     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
560
561   /* parse the fingerprint value */
562   for (p=line,n=0; hexdigitp (p); p++, n++)
563     ;
564   if (!spacep (p) || !(n == 40 || n == 32))
565     return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint");
566   i = 0;
567   if (n==32)
568     {
569       strcpy (fpr, "00000000");
570       i += 8;
571     }
572   for (p=line; i < 40; p++, i++)
573     fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
574   fpr[i] = 0;
575
576   while (spacep (p))
577     p++;
578   flag = *p++;
579   if ( (flag != 'S' && flag != 'P') || !spacep (p) )
580     return set_error (GPG_ERR_ASS_PARAMETER, "invalid flag - must be P or S");
581   while (spacep (p))
582     p++;
583
584   rc = agent_marktrusted (ctrl, p, fpr, flag);
585   return leave_cmd (ctx, rc);
586 }
587
588
589
590 \f
591 static const char hlp_havekey[] =
592   "HAVEKEY <hexstrings_with_keygrips>\n"
593   "\n"
594   "Return success if at least one of the secret keys with the given\n"
595   "keygrips is available.";
596 static gpg_error_t
597 cmd_havekey (assuan_context_t ctx, char *line)
598 {
599   gpg_error_t err;
600   unsigned char buf[20];
601
602   do
603     {
604       err = parse_keygrip (ctx, line, buf);
605       if (err)
606         return err;
607
608       if (!agent_key_available (buf))
609         return 0; /* Found.  */
610
611       while (*line && *line != ' ' && *line != '\t')
612         line++;
613       while (*line == ' ' || *line == '\t')
614         line++;
615     }
616   while (*line);
617
618   /* No leave_cmd() here because errors are expected and would clutter
619      the log.  */
620   return gpg_error (GPG_ERR_NO_SECKEY);
621 }
622
623
624 static const char hlp_sigkey[] =
625   "SIGKEY <hexstring_with_keygrip>\n"
626   "SETKEY <hexstring_with_keygrip>\n"
627   "\n"
628   "Set the  key used for a sign or decrypt operation.";
629 static gpg_error_t
630 cmd_sigkey (assuan_context_t ctx, char *line)
631 {
632   int rc;
633   ctrl_t ctrl = assuan_get_pointer (ctx);
634
635   rc = parse_keygrip (ctx, line, ctrl->keygrip);
636   if (rc)
637     return rc;
638   ctrl->have_keygrip = 1;
639   return 0;
640 }
641
642
643 static const char hlp_setkeydesc[] =
644   "SETKEYDESC plus_percent_escaped_string\n"
645   "\n"
646   "Set a description to be used for the next PKSIGN, PKDECRYPT, IMPORT_KEY\n"
647   "or EXPORT_KEY operation if this operation requires a passphrase.  If\n"
648   "this command is not used a default text will be used.  Note, that\n"
649   "this description implictly selects the label used for the entry\n"
650   "box; if the string contains the string PIN (which in general will\n"
651   "not be translated), \"PIN\" is used, otherwise the translation of\n"
652   "\"passphrase\" is used.  The description string should not contain\n"
653   "blanks unless they are percent or '+' escaped.\n"
654   "\n"
655   "The description is only valid for the next PKSIGN, PKDECRYPT,\n"
656   "IMPORT_KEY, EXPORT_KEY, or DELETE_KEY operation.";
657 static gpg_error_t
658 cmd_setkeydesc (assuan_context_t ctx, char *line)
659 {
660   ctrl_t ctrl = assuan_get_pointer (ctx);
661   char *desc, *p;
662
663   for (p=line; *p == ' '; p++)
664     ;
665   desc = p;
666   p = strchr (desc, ' ');
667   if (p)
668     *p = 0; /* We ignore any garbage; we might late use it for other args. */
669
670   if (!*desc)
671     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
672
673   /* Note, that we only need to replace the + characters and should
674      leave the other escaping in place because the escaped string is
675      send verbatim to the pinentry which does the unescaping (but not
676      the + replacing) */
677   plus_to_blank (desc);
678
679   xfree (ctrl->server_local->keydesc);
680
681   if (ctrl->restricted)
682     {
683       ctrl->server_local->keydesc = strconcat
684         ((ctrl->restricted == 2
685          ? _("Note: Request from the web browser.")
686          : _("Note: Request from a remote site.")  ), "%0A%0A", desc, NULL);
687     }
688   else
689     ctrl->server_local->keydesc = xtrystrdup (desc);
690   if (!ctrl->server_local->keydesc)
691     return out_of_core ();
692   return 0;
693 }
694
695
696 static const char hlp_sethash[] =
697   "SETHASH (--hash=<name>)|(<algonumber>) <hexstring>\n"
698   "\n"
699   "The client can use this command to tell the server about the data\n"
700   "(which usually is a hash) to be signed.";
701 static gpg_error_t
702 cmd_sethash (assuan_context_t ctx, char *line)
703 {
704   int rc;
705   size_t n;
706   char *p;
707   ctrl_t ctrl = assuan_get_pointer (ctx);
708   unsigned char *buf;
709   char *endp;
710   int algo;
711
712   /* Parse the alternative hash options which may be used instead of
713      the algo number.  */
714   if (has_option_name (line, "--hash"))
715     {
716       if (has_option (line, "--hash=sha1"))
717         algo = GCRY_MD_SHA1;
718       else if (has_option (line, "--hash=sha224"))
719         algo = GCRY_MD_SHA224;
720       else if (has_option (line, "--hash=sha256"))
721         algo = GCRY_MD_SHA256;
722       else if (has_option (line, "--hash=sha384"))
723         algo = GCRY_MD_SHA384;
724       else if (has_option (line, "--hash=sha512"))
725         algo = GCRY_MD_SHA512;
726       else if (has_option (line, "--hash=rmd160"))
727         algo = GCRY_MD_RMD160;
728       else if (has_option (line, "--hash=md5"))
729         algo = GCRY_MD_MD5;
730       else if (has_option (line, "--hash=tls-md5sha1"))
731         algo = MD_USER_TLS_MD5SHA1;
732       else
733         return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
734     }
735   else
736     algo = 0;
737
738   line = skip_options (line);
739
740   if (!algo)
741     {
742       /* No hash option has been given: require an algo number instead  */
743       algo = (int)strtoul (line, &endp, 10);
744       for (line = endp; *line == ' ' || *line == '\t'; line++)
745         ;
746       if (!algo || gcry_md_test_algo (algo))
747         return set_error (GPG_ERR_UNSUPPORTED_ALGORITHM, NULL);
748     }
749   ctrl->digest.algo = algo;
750   ctrl->digest.raw_value = 0;
751
752   /* Parse the hash value. */
753   n = 0;
754   rc = parse_hexstring (ctx, line, &n);
755   if (rc)
756     return rc;
757   n /= 2;
758   if (algo == MD_USER_TLS_MD5SHA1 && n == 36)
759     ;
760   else if (n != 16 && n != 20 && n != 24
761            && n != 28 && n != 32 && n != 48 && n != 64)
762     return set_error (GPG_ERR_ASS_PARAMETER, "unsupported length of hash");
763
764   if (n > MAX_DIGEST_LEN)
765     return set_error (GPG_ERR_ASS_PARAMETER, "hash value to long");
766
767   buf = ctrl->digest.value;
768   ctrl->digest.valuelen = n;
769   for (p=line, n=0; n < ctrl->digest.valuelen; p += 2, n++)
770     buf[n] = xtoi_2 (p);
771   for (; n < ctrl->digest.valuelen; n++)
772     buf[n] = 0;
773   return 0;
774 }
775
776
777 static const char hlp_pksign[] =
778   "PKSIGN [<options>] [<cache_nonce>]\n"
779   "\n"
780   "Perform the actual sign operation.  Neither input nor output are\n"
781   "sensitive to eavesdropping.";
782 static gpg_error_t
783 cmd_pksign (assuan_context_t ctx, char *line)
784 {
785   int rc;
786   cache_mode_t cache_mode = CACHE_MODE_NORMAL;
787   ctrl_t ctrl = assuan_get_pointer (ctx);
788   membuf_t outbuf;
789   char *cache_nonce = NULL;
790   char *p;
791
792   line = skip_options (line);
793
794   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
795     ;
796   *p = '\0';
797   if (*line)
798     cache_nonce = xtrystrdup (line);
799
800   if (opt.ignore_cache_for_signing)
801     cache_mode = CACHE_MODE_IGNORE;
802   else if (!ctrl->server_local->use_cache_for_signing)
803     cache_mode = CACHE_MODE_IGNORE;
804
805   init_membuf (&outbuf, 512);
806
807   rc = agent_pksign (ctrl, cache_nonce, ctrl->server_local->keydesc,
808                      &outbuf, cache_mode);
809   if (rc)
810     clear_outbuf (&outbuf);
811   else
812     rc = write_and_clear_outbuf (ctx, &outbuf);
813
814   xfree (cache_nonce);
815   xfree (ctrl->server_local->keydesc);
816   ctrl->server_local->keydesc = NULL;
817   return leave_cmd (ctx, rc);
818 }
819
820
821 static const char hlp_pkdecrypt[] =
822   "PKDECRYPT [<options>]\n"
823   "\n"
824   "Perform the actual decrypt operation.  Input is not\n"
825   "sensitive to eavesdropping.";
826 static gpg_error_t
827 cmd_pkdecrypt (assuan_context_t ctx, char *line)
828 {
829   int rc;
830   ctrl_t ctrl = assuan_get_pointer (ctx);
831   unsigned char *value;
832   size_t valuelen;
833   membuf_t outbuf;
834   int padding;
835
836   (void)line;
837
838   /* First inquire the data to decrypt */
839   rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%u", MAXLEN_CIPHERTEXT);
840   if (!rc)
841     rc = assuan_inquire (ctx, "CIPHERTEXT",
842                         &value, &valuelen, MAXLEN_CIPHERTEXT);
843   if (rc)
844     return rc;
845
846   init_membuf (&outbuf, 512);
847
848   rc = agent_pkdecrypt (ctrl, ctrl->server_local->keydesc,
849                         value, valuelen, &outbuf, &padding);
850   xfree (value);
851   if (rc)
852     clear_outbuf (&outbuf);
853   else
854     {
855       if (padding != -1)
856         rc = print_assuan_status (ctx, "PADDING", "%d", padding);
857       else
858         rc = 0;
859       if (!rc)
860         rc = write_and_clear_outbuf (ctx, &outbuf);
861     }
862   xfree (ctrl->server_local->keydesc);
863   ctrl->server_local->keydesc = NULL;
864   return leave_cmd (ctx, rc);
865 }
866
867
868 static const char hlp_genkey[] =
869   "GENKEY [--no-protection] [--preset] [--inq-passwd]\n"
870   "       [--passwd-nonce=<s>] [<cache_nonce>]\n"
871   "\n"
872   "Generate a new key, store the secret part and return the public\n"
873   "part.  Here is an example transaction:\n"
874   "\n"
875   "  C: GENKEY\n"
876   "  S: INQUIRE KEYPARAM\n"
877   "  C: D (genkey (rsa (nbits  2048)))\n"
878   "  C: END\n"
879   "  S: D (public-key\n"
880   "  S: D   (rsa (n 326487324683264) (e 10001)))\n"
881   "  S: OK key created\n"
882   "\n"
883   "When the --preset option is used the passphrase for the generated\n"
884   "key will be added to the cache.  When --inq-passwd is used an inquire\n"
885   "with the keyword NEWPASSWD is used to request the passphrase for the\n"
886   "new key.  When a --passwd-nonce is used, the corresponding cached\n"
887   "passphrase is used to protect the new key.";
888 static gpg_error_t
889 cmd_genkey (assuan_context_t ctx, char *line)
890 {
891   ctrl_t ctrl = assuan_get_pointer (ctx);
892   int rc;
893   int no_protection;
894   unsigned char *value;
895   size_t valuelen;
896   unsigned char *newpasswd = NULL;
897   membuf_t outbuf;
898   char *cache_nonce = NULL;
899   char *passwd_nonce = NULL;
900   int opt_preset;
901   int opt_inq_passwd;
902   size_t n;
903   char *p, *pend;
904   int c;
905
906   if (ctrl->restricted)
907     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
908
909   no_protection = has_option (line, "--no-protection");
910   opt_preset = has_option (line, "--preset");
911   opt_inq_passwd = has_option (line, "--inq-passwd");
912   passwd_nonce = option_value (line, "--passwd-nonce");
913   if (passwd_nonce)
914     {
915       for (pend = passwd_nonce; *pend && !spacep (pend); pend++)
916         ;
917       c = *pend;
918       *pend = '\0';
919       passwd_nonce = xtrystrdup (passwd_nonce);
920       *pend = c;
921       if (!passwd_nonce)
922         {
923           rc = gpg_error_from_syserror ();
924           goto leave;
925         }
926     }
927   line = skip_options (line);
928
929   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
930     ;
931   *p = '\0';
932   if (*line)
933     cache_nonce = xtrystrdup (line);
934
935   /* First inquire the parameters */
936   rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%u", MAXLEN_KEYPARAM);
937   if (!rc)
938     rc = assuan_inquire (ctx, "KEYPARAM", &value, &valuelen, MAXLEN_KEYPARAM);
939   if (rc)
940     return rc;
941
942   init_membuf (&outbuf, 512);
943
944   /* If requested, ask for the password to be used for the key.  If
945      this is not used the regular Pinentry mechanism is used.  */
946   if (opt_inq_passwd && !no_protection)
947     {
948       /* (N is used as a dummy) */
949       assuan_begin_confidential (ctx);
950       rc = assuan_inquire (ctx, "NEWPASSWD", &newpasswd, &n, 256);
951       assuan_end_confidential (ctx);
952       if (rc)
953         goto leave;
954       if (!*newpasswd)
955         {
956           /* Empty password given - switch to no-protection mode.  */
957           xfree (newpasswd);
958           newpasswd = NULL;
959           no_protection = 1;
960         }
961
962     }
963   else if (passwd_nonce)
964     newpasswd = agent_get_cache (passwd_nonce, CACHE_MODE_NONCE);
965
966   rc = agent_genkey (ctrl, cache_nonce, (char*)value, valuelen, no_protection,
967                      newpasswd, opt_preset, &outbuf);
968
969  leave:
970   if (newpasswd)
971     {
972       /* Assuan_inquire does not allow us to read into secure memory
973          thus we need to wipe it ourself.  */
974       wipememory (newpasswd, strlen (newpasswd));
975       xfree (newpasswd);
976     }
977   xfree (value);
978   if (rc)
979     clear_outbuf (&outbuf);
980   else
981     rc = write_and_clear_outbuf (ctx, &outbuf);
982   xfree (cache_nonce);
983   xfree (passwd_nonce);
984   return leave_cmd (ctx, rc);
985 }
986
987
988
989 \f
990 static const char hlp_readkey[] =
991   "READKEY <hexstring_with_keygrip>\n"
992   "        --card <keyid>\n"
993   "\n"
994   "Return the public key for the given keygrip or keyid.\n"
995   "With --card, private key file with card information will be created.";
996 static gpg_error_t
997 cmd_readkey (assuan_context_t ctx, char *line)
998 {
999   ctrl_t ctrl = assuan_get_pointer (ctx);
1000   int rc;
1001   unsigned char grip[20];
1002   gcry_sexp_t s_pkey = NULL;
1003   unsigned char *pkbuf = NULL;
1004   char *serialno = NULL;
1005   size_t pkbuflen;
1006   const char *opt_card;
1007
1008   if (ctrl->restricted)
1009     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
1010
1011   opt_card = has_option_name (line, "--card");
1012   line = skip_options (line);
1013
1014   if (opt_card)
1015     {
1016       const char *keyid = opt_card;
1017
1018       rc = agent_card_getattr (ctrl, "SERIALNO", &serialno);
1019       if (rc)
1020         {
1021           log_error (_("error getting serial number of card: %s\n"),
1022                      gpg_strerror (rc));
1023           goto leave;
1024         }
1025
1026       rc = agent_card_readkey (ctrl, keyid, &pkbuf);
1027       if (rc)
1028         goto leave;
1029       pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
1030       rc = gcry_sexp_sscan (&s_pkey, NULL, (char*)pkbuf, pkbuflen);
1031       if (rc)
1032         goto leave;
1033
1034       if (!gcry_pk_get_keygrip (s_pkey, grip))
1035         {
1036           rc = gcry_pk_testkey (s_pkey);
1037           if (rc == 0)
1038             rc = gpg_error (GPG_ERR_INTERNAL);
1039
1040           goto leave;
1041         }
1042
1043       rc = agent_write_shadow_key (grip, serialno, keyid, pkbuf, 0);
1044       if (rc)
1045         goto leave;
1046
1047       rc = assuan_send_data (ctx, pkbuf, pkbuflen);
1048     }
1049   else
1050     {
1051       rc = parse_keygrip (ctx, line, grip);
1052       if (rc)
1053         goto leave;
1054
1055       rc = agent_public_key_from_file (ctrl, grip, &s_pkey);
1056       if (!rc)
1057         {
1058           pkbuflen = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
1059           log_assert (pkbuflen);
1060           pkbuf = xtrymalloc (pkbuflen);
1061           if (!pkbuf)
1062             rc = gpg_error_from_syserror ();
1063           else
1064             {
1065               gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, pkbuf, pkbuflen);
1066               rc = assuan_send_data (ctx, pkbuf, pkbuflen);
1067             }
1068         }
1069     }
1070
1071  leave:
1072   xfree (serialno);
1073   xfree (pkbuf);
1074   gcry_sexp_release (s_pkey);
1075   return leave_cmd (ctx, rc);
1076 }
1077
1078
1079 \f
1080 static const char hlp_keyinfo[] =
1081   "KEYINFO [--[ssh-]list] [--data] [--ssh-fpr] [--with-ssh] <keygrip>\n"
1082   "\n"
1083   "Return information about the key specified by the KEYGRIP.  If the\n"
1084   "key is not available GPG_ERR_NOT_FOUND is returned.  If the option\n"
1085   "--list is given the keygrip is ignored and information about all\n"
1086   "available keys are returned.  If --ssh-list is given information\n"
1087   "about all keys listed in the sshcontrol are returned.  With --with-ssh\n"
1088   "information from sshcontrol is always added to the info. Unless --data\n"
1089   "is given, the information is returned as a status line using the format:\n"
1090   "\n"
1091   "  KEYINFO <keygrip> <type> <serialno> <idstr> <cached> <protection> <fpr>\n"
1092   "\n"
1093   "KEYGRIP is the keygrip.\n"
1094   "\n"
1095   "TYPE is describes the type of the key:\n"
1096   "    'D' - Regular key stored on disk,\n"
1097   "    'T' - Key is stored on a smartcard (token),\n"
1098   "    'X' - Unknown type,\n"
1099   "    '-' - Key is missing.\n"
1100   "\n"
1101   "SERIALNO is an ASCII string with the serial number of the\n"
1102   "         smartcard.  If the serial number is not known a single\n"
1103   "         dash '-' is used instead.\n"
1104   "\n"
1105   "IDSTR is the IDSTR used to distinguish keys on a smartcard.  If it\n"
1106   "      is not known a dash is used instead.\n"
1107   "\n"
1108   "CACHED is 1 if the passphrase for the key was found in the key cache.\n"
1109   "       If not, a '-' is used instead.\n"
1110   "\n"
1111   "PROTECTION describes the key protection type:\n"
1112   "    'P' - The key is protected with a passphrase,\n"
1113   "    'C' - The key is not protected,\n"
1114   "    '-' - Unknown protection.\n"
1115   "\n"
1116   "FPR returns the formatted ssh-style fingerprint of the key.  It is only\n"
1117   "    printed if the option --ssh-fpr has been used.  It defaults to '-'.\n"
1118   "\n"
1119   "TTL is the TTL in seconds for that key or '-' if n/a.\n"
1120   "\n"
1121   "FLAGS is a word consisting of one-letter flags:\n"
1122   "      'D' - The key has been disabled,\n"
1123   "      'S' - The key is listed in sshcontrol (requires --with-ssh),\n"
1124   "      'c' - Use of the key needs to be confirmed,\n"
1125   "      '-' - No flags given.\n"
1126   "\n"
1127   "More information may be added in the future.";
1128 static gpg_error_t
1129 do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
1130                 int data, int with_ssh_fpr, int in_ssh,
1131                 int ttl, int disabled, int confirm)
1132 {
1133   gpg_error_t err;
1134   char hexgrip[40+1];
1135   char *fpr = NULL;
1136   int keytype;
1137   unsigned char *shadow_info = NULL;
1138   char *serialno = NULL;
1139   char *idstr = NULL;
1140   const char *keytypestr;
1141   const char *cached;
1142   const char *protectionstr;
1143   char *pw;
1144   int missing_key = 0;
1145   char ttlbuf[20];
1146   char flagsbuf[5];
1147
1148   err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info);
1149   if (err)
1150     {
1151       if (in_ssh && gpg_err_code (err) == GPG_ERR_NOT_FOUND)
1152         missing_key = 1;
1153       else
1154         goto leave;
1155     }
1156
1157   /* Reformat the grip so that we use uppercase as good style. */
1158   bin2hex (grip, 20, hexgrip);
1159
1160   if (ttl > 0)
1161     snprintf (ttlbuf, sizeof ttlbuf, "%d", ttl);
1162   else
1163     strcpy (ttlbuf, "-");
1164
1165   *flagsbuf = 0;
1166   if (disabled)
1167     strcat (flagsbuf, "D");
1168   if (in_ssh)
1169     strcat (flagsbuf, "S");
1170   if (confirm)
1171     strcat (flagsbuf, "c");
1172   if (!*flagsbuf)
1173     strcpy (flagsbuf, "-");
1174
1175
1176   if (missing_key)
1177     {
1178       protectionstr = "-"; keytypestr = "-";
1179     }
1180   else
1181     {
1182       switch (keytype)
1183         {
1184         case PRIVATE_KEY_CLEAR:
1185         case PRIVATE_KEY_OPENPGP_NONE:
1186           protectionstr = "C"; keytypestr = "D";
1187           break;
1188         case PRIVATE_KEY_PROTECTED: protectionstr = "P"; keytypestr = "D";
1189           break;
1190         case PRIVATE_KEY_SHADOWED: protectionstr = "-"; keytypestr = "T";
1191           break;
1192         default: protectionstr = "-"; keytypestr = "X";
1193           break;
1194         }
1195     }
1196
1197   /* Compute the ssh fingerprint if requested.  */
1198   if (with_ssh_fpr)
1199     {
1200       gcry_sexp_t key;
1201
1202       if (!agent_raw_key_from_file (ctrl, grip, &key))
1203         {
1204           ssh_get_fingerprint_string (key, GCRY_MD_MD5, &fpr);
1205           gcry_sexp_release (key);
1206         }
1207     }
1208
1209   /* Here we have a little race by doing the cache check separately
1210      from the retrieval function.  Given that the cache flag is only a
1211      hint, it should not really matter.  */
1212   pw = agent_get_cache (hexgrip, CACHE_MODE_NORMAL);
1213   cached = pw ? "1" : "-";
1214   xfree (pw);
1215
1216   if (shadow_info)
1217     {
1218       err = parse_shadow_info (shadow_info, &serialno, &idstr, NULL);
1219       if (err)
1220         goto leave;
1221     }
1222
1223   if (!data)
1224     err = agent_write_status (ctrl, "KEYINFO",
1225                               hexgrip,
1226                               keytypestr,
1227                               serialno? serialno : "-",
1228                               idstr? idstr : "-",
1229                               cached,
1230                               protectionstr,
1231                               fpr? fpr : "-",
1232                               ttlbuf,
1233                               flagsbuf,
1234                               NULL);
1235   else
1236     {
1237       char *string;
1238
1239       string = xtryasprintf ("%s %s %s %s %s %s %s %s %s\n",
1240                              hexgrip, keytypestr,
1241                              serialno? serialno : "-",
1242                              idstr? idstr : "-", cached, protectionstr,
1243                              fpr? fpr : "-",
1244                              ttlbuf,
1245                              flagsbuf);
1246       if (!string)
1247         err = gpg_error_from_syserror ();
1248       else
1249         err = assuan_send_data (ctx, string, strlen(string));
1250       xfree (string);
1251     }
1252
1253  leave:
1254   xfree (fpr);
1255   xfree (shadow_info);
1256   xfree (serialno);
1257   xfree (idstr);
1258   return err;
1259 }
1260
1261
1262 /* Entry int for the command KEYINFO.  This function handles the
1263    command option processing.  For details see hlp_keyinfo above.  */
1264 static gpg_error_t
1265 cmd_keyinfo (assuan_context_t ctx, char *line)
1266 {
1267   ctrl_t ctrl = assuan_get_pointer (ctx);
1268   int err;
1269   unsigned char grip[20];
1270   DIR *dir = NULL;
1271   int list_mode;
1272   int opt_data, opt_ssh_fpr, opt_with_ssh;
1273   ssh_control_file_t cf = NULL;
1274   char hexgrip[41];
1275   int disabled, ttl, confirm, is_ssh;
1276
1277   if (ctrl->restricted)
1278     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
1279
1280   if (has_option (line, "--ssh-list"))
1281     list_mode = 2;
1282   else
1283     list_mode = has_option (line, "--list");
1284   opt_data = has_option (line, "--data");
1285   opt_ssh_fpr = has_option (line, "--ssh-fpr");
1286   opt_with_ssh = has_option (line, "--with-ssh");
1287   line = skip_options (line);
1288
1289   if (opt_with_ssh || list_mode == 2)
1290     cf = ssh_open_control_file ();
1291
1292   if (list_mode == 2)
1293     {
1294       if (cf)
1295         {
1296           while (!ssh_read_control_file (cf, hexgrip,
1297                                          &disabled, &ttl, &confirm))
1298             {
1299               if (hex2bin (hexgrip, grip, 20) < 0 )
1300                 continue; /* Bad hex string.  */
1301               err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr, 1,
1302                                     ttl, disabled, confirm);
1303               if (err)
1304                 goto leave;
1305             }
1306         }
1307       err = 0;
1308     }
1309   else if (list_mode)
1310     {
1311       char *dirname;
1312       struct dirent *dir_entry;
1313
1314       dirname = make_filename_try (gnupg_homedir (),
1315                                    GNUPG_PRIVATE_KEYS_DIR, NULL);
1316       if (!dirname)
1317         {
1318           err = gpg_error_from_syserror ();
1319           goto leave;
1320         }
1321       dir = opendir (dirname);
1322       if (!dir)
1323         {
1324           err = gpg_error_from_syserror ();
1325           xfree (dirname);
1326           goto leave;
1327         }
1328       xfree (dirname);
1329
1330       while ( (dir_entry = readdir (dir)) )
1331         {
1332           if (strlen (dir_entry->d_name) != 44
1333               || strcmp (dir_entry->d_name + 40, ".key"))
1334             continue;
1335           strncpy (hexgrip, dir_entry->d_name, 40);
1336           hexgrip[40] = 0;
1337
1338           if ( hex2bin (hexgrip, grip, 20) < 0 )
1339             continue; /* Bad hex string.  */
1340
1341           disabled = ttl = confirm = is_ssh = 0;
1342           if (opt_with_ssh)
1343             {
1344               err = ssh_search_control_file (cf, hexgrip,
1345                                              &disabled, &ttl, &confirm);
1346               if (!err)
1347                 is_ssh = 1;
1348               else if (gpg_err_code (err) != GPG_ERR_NOT_FOUND)
1349                 goto leave;
1350             }
1351
1352           err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr, is_ssh,
1353                                 ttl, disabled, confirm);
1354           if (err)
1355             goto leave;
1356         }
1357       err = 0;
1358     }
1359   else
1360     {
1361       err = parse_keygrip (ctx, line, grip);
1362       if (err)
1363         goto leave;
1364       disabled = ttl = confirm = is_ssh = 0;
1365       if (opt_with_ssh)
1366         {
1367           err = ssh_search_control_file (cf, line,
1368                                          &disabled, &ttl, &confirm);
1369           if (!err)
1370             is_ssh = 1;
1371           else if (gpg_err_code (err) != GPG_ERR_NOT_FOUND)
1372             goto leave;
1373         }
1374
1375       err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr, is_ssh,
1376                             ttl, disabled, confirm);
1377     }
1378
1379  leave:
1380   ssh_close_control_file (cf);
1381   if (dir)
1382     closedir (dir);
1383   if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
1384     leave_cmd (ctx, err);
1385   return err;
1386 }
1387
1388
1389 \f
1390 /* Helper for cmd_get_passphrase.  */
1391 static int
1392 send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw)
1393 {
1394   size_t n;
1395   int rc;
1396
1397   assuan_begin_confidential (ctx);
1398   n = strlen (pw);
1399   if (via_data)
1400     rc = assuan_send_data (ctx, pw, n);
1401   else
1402     {
1403       char *p = xtrymalloc_secure (n*2+1);
1404       if (!p)
1405         rc = gpg_error_from_syserror ();
1406       else
1407         {
1408           bin2hex (pw, n, p);
1409           rc = assuan_set_okay_line (ctx, p);
1410           xfree (p);
1411         }
1412     }
1413   return rc;
1414 }
1415
1416
1417 static const char hlp_get_passphrase[] =
1418   "GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]]\n"
1419   "               [--qualitybar] <cache_id>\n"
1420   "               [<error_message> <prompt> <description>]\n"
1421   "\n"
1422   "This function is usually used to ask for a passphrase to be used\n"
1423   "for conventional encryption, but may also be used by programs which\n"
1424   "need specal handling of passphrases.  This command uses a syntax\n"
1425   "which helps clients to use the agent with minimum effort.  The\n"
1426   "agent either returns with an error or with a OK followed by the hex\n"
1427   "encoded passphrase.  Note that the length of the strings is\n"
1428   "implicitly limited by the maximum length of a command.\n"
1429   "\n"
1430   "If the option \"--data\" is used the passphrase is returned by usual\n"
1431   "data lines and not on the okay line.\n"
1432   "\n"
1433   "If the option \"--check\" is used the passphrase constraints checks as\n"
1434   "implemented by gpg-agent are applied.  A check is not done if the\n"
1435   "passphrase has been found in the cache.\n"
1436   "\n"
1437   "If the option \"--no-ask\" is used and the passphrase is not in the\n"
1438   "cache the user will not be asked to enter a passphrase but the error\n"
1439   "code GPG_ERR_NO_DATA is returned.  \n"
1440   "\n"
1441   "If the option \"--qualitybar\" is used a visual indication of the\n"
1442   "entered passphrase quality is shown.  (Unless no minimum passphrase\n"
1443   "length has been configured.)";
1444 static gpg_error_t
1445 cmd_get_passphrase (assuan_context_t ctx, char *line)
1446 {
1447   ctrl_t ctrl = assuan_get_pointer (ctx);
1448   int rc;
1449   char *pw;
1450   char *response;
1451   char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
1452   const char *desc2 = _("Please re-enter this passphrase");
1453   char *p;
1454   int opt_data, opt_check, opt_no_ask, opt_qualbar;
1455   int opt_repeat = 0;
1456   char *entry_errtext = NULL;
1457
1458   if (ctrl->restricted)
1459     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
1460
1461   opt_data = has_option (line, "--data");
1462   opt_check = has_option (line, "--check");
1463   opt_no_ask = has_option (line, "--no-ask");
1464   if (has_option_name (line, "--repeat"))
1465     {
1466       p = option_value (line, "--repeat");
1467       if (p)
1468         opt_repeat = atoi (p);
1469       else
1470         opt_repeat = 1;
1471     }
1472   opt_qualbar = has_option (line, "--qualitybar");
1473   line = skip_options (line);
1474
1475   cacheid = line;
1476   p = strchr (cacheid, ' ');
1477   if (p)
1478     {
1479       *p++ = 0;
1480       while (*p == ' ')
1481         p++;
1482       errtext = p;
1483       p = strchr (errtext, ' ');
1484       if (p)
1485         {
1486           *p++ = 0;
1487           while (*p == ' ')
1488             p++;
1489           prompt = p;
1490           p = strchr (prompt, ' ');
1491           if (p)
1492             {
1493               *p++ = 0;
1494               while (*p == ' ')
1495                 p++;
1496               desc = p;
1497               p = strchr (desc, ' ');
1498               if (p)
1499                 *p = 0; /* Ignore trailing garbage. */
1500             }
1501         }
1502     }
1503   if (!*cacheid || strlen (cacheid) > 50)
1504     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1505   if (!desc)
1506     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1507
1508   if (!strcmp (cacheid, "X"))
1509     cacheid = NULL;
1510   if (!strcmp (errtext, "X"))
1511     errtext = NULL;
1512   if (!strcmp (prompt, "X"))
1513     prompt = NULL;
1514   if (!strcmp (desc, "X"))
1515     desc = NULL;
1516
1517   pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_USER) : NULL;
1518   if (pw)
1519     {
1520       rc = send_back_passphrase (ctx, opt_data, pw);
1521       xfree (pw);
1522     }
1523   else if (opt_no_ask)
1524     rc = gpg_error (GPG_ERR_NO_DATA);
1525   else
1526     {
1527       /* Note, that we only need to replace the + characters and
1528          should leave the other escaping in place because the escaped
1529          string is send verbatim to the pinentry which does the
1530          unescaping (but not the + replacing) */
1531       if (errtext)
1532         plus_to_blank (errtext);
1533       if (prompt)
1534         plus_to_blank (prompt);
1535       if (desc)
1536         plus_to_blank (desc);
1537
1538     next_try:
1539       rc = agent_get_passphrase (ctrl, &response, desc, prompt,
1540                                  entry_errtext? entry_errtext:errtext,
1541                                  opt_qualbar, cacheid, CACHE_MODE_USER);
1542       xfree (entry_errtext);
1543       entry_errtext = NULL;
1544       if (!rc)
1545         {
1546           int i;
1547
1548           if (opt_check
1549               && check_passphrase_constraints (ctrl, response, &entry_errtext))
1550             {
1551               xfree (response);
1552               goto next_try;
1553             }
1554           for (i = 0; i < opt_repeat; i++)
1555             {
1556               char *response2;
1557
1558               if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
1559                 break;
1560
1561               rc = agent_get_passphrase (ctrl, &response2, desc2, prompt,
1562                                          errtext, 0,
1563                                          cacheid, CACHE_MODE_USER);
1564               if (rc)
1565                 break;
1566               if (strcmp (response2, response))
1567                 {
1568                   xfree (response2);
1569                   xfree (response);
1570                   entry_errtext = try_percent_escape
1571                     (_("does not match - try again"), NULL);
1572                   if (!entry_errtext)
1573                     {
1574                       rc = gpg_error_from_syserror ();
1575                       break;
1576                     }
1577                   goto next_try;
1578                 }
1579               xfree (response2);
1580             }
1581           if (!rc)
1582             {
1583               if (cacheid)
1584                 agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
1585               rc = send_back_passphrase (ctx, opt_data, response);
1586             }
1587           xfree (response);
1588         }
1589     }
1590
1591   return leave_cmd (ctx, rc);
1592 }
1593
1594
1595 static const char hlp_clear_passphrase[] =
1596   "CLEAR_PASSPHRASE [--mode=normal] <cache_id>\n"
1597   "\n"
1598   "may be used to invalidate the cache entry for a passphrase.  The\n"
1599   "function returns with OK even when there is no cached passphrase.\n"
1600   "The --mode=normal option is used to clear an entry for a cacheid\n"
1601   "added by the agent.\n";
1602 static gpg_error_t
1603 cmd_clear_passphrase (assuan_context_t ctx, char *line)
1604 {
1605   ctrl_t ctrl = assuan_get_pointer (ctx);
1606   char *cacheid = NULL;
1607   char *p;
1608   int opt_normal;
1609
1610   if (ctrl->restricted)
1611     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
1612
1613   opt_normal = has_option (line, "--mode=normal");
1614   line = skip_options (line);
1615
1616   /* parse the stuff */
1617   for (p=line; *p == ' '; p++)
1618     ;
1619   cacheid = p;
1620   p = strchr (cacheid, ' ');
1621   if (p)
1622     *p = 0; /* ignore garbage */
1623   if (!*cacheid || strlen (cacheid) > 50)
1624     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1625
1626   agent_put_cache (cacheid, opt_normal ? CACHE_MODE_NORMAL : CACHE_MODE_USER,
1627                    NULL, 0);
1628
1629   agent_clear_passphrase (ctrl, cacheid,
1630                           opt_normal ? CACHE_MODE_NORMAL : CACHE_MODE_USER);
1631
1632   return 0;
1633 }
1634
1635
1636 static const char hlp_get_confirmation[] =
1637   "GET_CONFIRMATION <description>\n"
1638   "\n"
1639   "This command may be used to ask for a simple confirmation.\n"
1640   "DESCRIPTION is displayed along with a Okay and Cancel button.  This\n"
1641   "command uses a syntax which helps clients to use the agent with\n"
1642   "minimum effort.  The agent either returns with an error or with a\n"
1643   "OK.  Note, that the length of DESCRIPTION is implicitly limited by\n"
1644   "the maximum length of a command. DESCRIPTION should not contain\n"
1645   "any spaces, those must be encoded either percent escaped or simply\n"
1646   "as '+'.";
1647 static gpg_error_t
1648 cmd_get_confirmation (assuan_context_t ctx, char *line)
1649 {
1650   ctrl_t ctrl = assuan_get_pointer (ctx);
1651   int rc;
1652   char *desc = NULL;
1653   char *p;
1654
1655   if (ctrl->restricted)
1656     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
1657
1658   /* parse the stuff */
1659   for (p=line; *p == ' '; p++)
1660     ;
1661   desc = p;
1662   p = strchr (desc, ' ');
1663   if (p)
1664     *p = 0; /* We ignore any garbage -may be later used for other args. */
1665
1666   if (!*desc)
1667     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1668
1669   if (!strcmp (desc, "X"))
1670     desc = NULL;
1671
1672   /* Note, that we only need to replace the + characters and should
1673      leave the other escaping in place because the escaped string is
1674      send verbatim to the pinentry which does the unescaping (but not
1675      the + replacing) */
1676   if (desc)
1677     plus_to_blank (desc);
1678
1679   rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0);
1680   return leave_cmd (ctx, rc);
1681 }
1682
1683
1684 \f
1685 static const char hlp_learn[] =
1686   "LEARN [--send] [--sendinfo] [--force]\n"
1687   "\n"
1688   "Learn something about the currently inserted smartcard.  With\n"
1689   "--sendinfo information about the card is returned; with --send\n"
1690   "the available certificates are returned as D lines; with --force\n"
1691   "private key storage will be updated by the result.";
1692 static gpg_error_t
1693 cmd_learn (assuan_context_t ctx, char *line)
1694 {
1695   ctrl_t ctrl = assuan_get_pointer (ctx);
1696   gpg_error_t err;
1697   int send, sendinfo, force;
1698
1699   send = has_option (line, "--send");
1700   sendinfo = send? 1 : has_option (line, "--sendinfo");
1701   force = has_option (line, "--force");
1702
1703   if (ctrl->restricted)
1704     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
1705
1706   err = agent_handle_learn (ctrl, send, sendinfo? ctx : NULL, force);
1707   return leave_cmd (ctx, err);
1708 }
1709
1710
1711 \f
1712 static const char hlp_passwd[] =
1713   "PASSWD [--cache-nonce=<c>] [--passwd-nonce=<s>] [--preset]\n"
1714   "       [--verify] <hexkeygrip>\n"
1715   "\n"
1716   "Change the passphrase/PIN for the key identified by keygrip in LINE.  If\n"
1717   "--preset is used then the new passphrase will be added to the cache.\n"
1718   "If --verify is used the command asks for the passphrase and verifies\n"
1719   "that the passphrase valid.\n";
1720 static gpg_error_t
1721 cmd_passwd (assuan_context_t ctx, char *line)
1722 {
1723   ctrl_t ctrl = assuan_get_pointer (ctx);
1724   gpg_error_t err;
1725   int c;
1726   char *cache_nonce = NULL;
1727   char *passwd_nonce = NULL;
1728   unsigned char grip[20];
1729   gcry_sexp_t s_skey = NULL;
1730   unsigned char *shadow_info = NULL;
1731   char *passphrase = NULL;
1732   char *pend;
1733   int opt_preset, opt_verify;
1734
1735   if (ctrl->restricted)
1736     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
1737
1738   opt_preset = has_option (line, "--preset");
1739   cache_nonce = option_value (line, "--cache-nonce");
1740   opt_verify = has_option (line, "--verify");
1741   if (cache_nonce)
1742     {
1743       for (pend = cache_nonce; *pend && !spacep (pend); pend++)
1744         ;
1745       c = *pend;
1746       *pend = '\0';
1747       cache_nonce = xtrystrdup (cache_nonce);
1748       *pend = c;
1749       if (!cache_nonce)
1750         {
1751           err = gpg_error_from_syserror ();
1752           goto leave;
1753         }
1754     }
1755
1756   passwd_nonce = option_value (line, "--passwd-nonce");
1757   if (passwd_nonce)
1758     {
1759       for (pend = passwd_nonce; *pend && !spacep (pend); pend++)
1760         ;
1761       c = *pend;
1762       *pend = '\0';
1763       passwd_nonce = xtrystrdup (passwd_nonce);
1764       *pend = c;
1765       if (!passwd_nonce)
1766         {
1767           err = gpg_error_from_syserror ();
1768           goto leave;
1769         }
1770     }
1771
1772   line = skip_options (line);
1773
1774   err = parse_keygrip (ctx, line, grip);
1775   if (err)
1776     goto leave;
1777
1778   ctrl->in_passwd++;
1779   err = agent_key_from_file (ctrl,
1780                              opt_verify? NULL : cache_nonce,
1781                              ctrl->server_local->keydesc,
1782                              grip, &shadow_info, CACHE_MODE_IGNORE, NULL,
1783                              &s_skey, &passphrase);
1784   if (err)
1785     ;
1786   else if (shadow_info)
1787     {
1788       log_error ("changing a smartcard PIN is not yet supported\n");
1789       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1790     }
1791   else if (opt_verify)
1792     {
1793       /* All done.  */
1794       if (passphrase)
1795         {
1796           if (!passwd_nonce)
1797             {
1798               char buf[12];
1799               gcry_create_nonce (buf, 12);
1800               passwd_nonce = bin2hex (buf, 12, NULL);
1801             }
1802           if (passwd_nonce
1803               && !agent_put_cache (passwd_nonce, CACHE_MODE_NONCE,
1804                                    passphrase, CACHE_TTL_NONCE))
1805             {
1806               assuan_write_status (ctx, "PASSWD_NONCE", passwd_nonce);
1807               xfree (ctrl->server_local->last_passwd_nonce);
1808               ctrl->server_local->last_passwd_nonce = passwd_nonce;
1809               passwd_nonce = NULL;
1810             }
1811         }
1812     }
1813   else
1814     {
1815       char *newpass = NULL;
1816
1817       if (passwd_nonce)
1818         newpass = agent_get_cache (passwd_nonce, CACHE_MODE_NONCE);
1819       err = agent_protect_and_store (ctrl, s_skey, &newpass);
1820       if (!err && passphrase)
1821         {
1822           /* A passphrase existed on the old key and the change was
1823              successful.  Return a nonce for that old passphrase to
1824              let the caller try to unprotect the other subkeys with
1825              the same key.  */
1826           if (!cache_nonce)
1827             {
1828               char buf[12];
1829               gcry_create_nonce (buf, 12);
1830               cache_nonce = bin2hex (buf, 12, NULL);
1831             }
1832           if (cache_nonce
1833               && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
1834                                    passphrase, CACHE_TTL_NONCE))
1835             {
1836               assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
1837               xfree (ctrl->server_local->last_cache_nonce);
1838               ctrl->server_local->last_cache_nonce = cache_nonce;
1839               cache_nonce = NULL;
1840             }
1841           if (newpass)
1842             {
1843               /* If we have a new passphrase (which might be empty) we
1844                  store it under a passwd nonce so that the caller may
1845                  send that nonce again to use it for another key. */
1846               if (!passwd_nonce)
1847                 {
1848                   char buf[12];
1849                   gcry_create_nonce (buf, 12);
1850                   passwd_nonce = bin2hex (buf, 12, NULL);
1851                 }
1852               if (passwd_nonce
1853                   && !agent_put_cache (passwd_nonce, CACHE_MODE_NONCE,
1854                                        newpass, CACHE_TTL_NONCE))
1855                 {
1856                   assuan_write_status (ctx, "PASSWD_NONCE", passwd_nonce);
1857                   xfree (ctrl->server_local->last_passwd_nonce);
1858                   ctrl->server_local->last_passwd_nonce = passwd_nonce;
1859                   passwd_nonce = NULL;
1860                 }
1861             }
1862         }
1863       if (!err && opt_preset)
1864         {
1865           char hexgrip[40+1];
1866           bin2hex(grip, 20, hexgrip);
1867           err = agent_put_cache (hexgrip, CACHE_MODE_ANY, newpass,
1868                                  ctrl->cache_ttl_opt_preset);
1869         }
1870       xfree (newpass);
1871     }
1872   ctrl->in_passwd--;
1873
1874   xfree (ctrl->server_local->keydesc);
1875   ctrl->server_local->keydesc = NULL;
1876
1877  leave:
1878   xfree (passphrase);
1879   gcry_sexp_release (s_skey);
1880   xfree (shadow_info);
1881   xfree (cache_nonce);
1882   xfree (passwd_nonce);
1883   return leave_cmd (ctx, err);
1884 }
1885
1886
1887 static const char hlp_preset_passphrase[] =
1888   "PRESET_PASSPHRASE [--inquire] <string_or_keygrip> <timeout> [<hexstring>]\n"
1889   "\n"
1890   "Set the cached passphrase/PIN for the key identified by the keygrip\n"
1891   "to passwd for the given time, where -1 means infinite and 0 means\n"
1892   "the default (currently only a timeout of -1 is allowed, which means\n"
1893   "to never expire it).  If passwd is not provided, ask for it via the\n"
1894   "pinentry module unless --inquire is passed in which case the passphrase\n"
1895   "is retrieved from the client via a server inquire.\n";
1896 static gpg_error_t
1897 cmd_preset_passphrase (assuan_context_t ctx, char *line)
1898 {
1899   ctrl_t ctrl = assuan_get_pointer (ctx);
1900   int rc;
1901   char *grip_clear = NULL;
1902   unsigned char *passphrase = NULL;
1903   int ttl;
1904   size_t len;
1905   int opt_inquire;
1906
1907   if (ctrl->restricted)
1908     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
1909
1910   if (!opt.allow_preset_passphrase)
1911     return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase");
1912
1913   opt_inquire = has_option (line, "--inquire");
1914   line = skip_options (line);
1915   grip_clear = line;
1916   while (*line && (*line != ' ' && *line != '\t'))
1917     line++;
1918   if (!*line)
1919     return gpg_error (GPG_ERR_MISSING_VALUE);
1920   *line = '\0';
1921   line++;
1922   while (*line && (*line == ' ' || *line == '\t'))
1923     line++;
1924
1925   /* Currently, only infinite timeouts are allowed.  */
1926   ttl = -1;
1927   if (line[0] != '-' || line[1] != '1')
1928     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1929   line++;
1930   line++;
1931   while (!(*line != ' ' && *line != '\t'))
1932     line++;
1933
1934   /* Syntax check the hexstring.  */
1935   len = 0;
1936   rc = parse_hexstring (ctx, line, &len);
1937   if (rc)
1938     return rc;
1939   line[len] = '\0';
1940
1941   /* If there is a passphrase, use it.  Currently, a passphrase is
1942      required.  */
1943   if (*line)
1944     {
1945       if (opt_inquire)
1946         {
1947           rc = set_error (GPG_ERR_ASS_PARAMETER,
1948                           "both --inquire and passphrase specified");
1949           goto leave;
1950         }
1951
1952       /* Do in-place conversion.  */
1953       passphrase = line;
1954       if (!hex2str (passphrase, passphrase, strlen (passphrase)+1, NULL))
1955         rc = set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
1956     }
1957   else if (opt_inquire)
1958     {
1959       /* Note that the passphrase will be truncated at any null byte and the
1960        * limit is 480 characters. */
1961       size_t maxlen = 480;
1962
1963       rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%zu", maxlen);
1964       if (!rc)
1965         rc = assuan_inquire (ctx, "PASSPHRASE", &passphrase, &len, maxlen);
1966     }
1967   else
1968     rc = set_error (GPG_ERR_NOT_IMPLEMENTED, "passphrase is required");
1969
1970   if (!rc)
1971     {
1972       rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl);
1973       if (opt_inquire)
1974         xfree (passphrase);
1975     }
1976
1977 leave:
1978   return leave_cmd (ctx, rc);
1979 }
1980
1981
1982 \f
1983 static const char hlp_scd[] =
1984   "SCD <commands to pass to the scdaemon>\n"
1985   " \n"
1986   "This is a general quote command to redirect everything to the\n"
1987   "SCdaemon.";
1988 static gpg_error_t
1989 cmd_scd (assuan_context_t ctx, char *line)
1990 {
1991   ctrl_t ctrl = assuan_get_pointer (ctx);
1992   int rc;
1993
1994   if (ctrl->restricted)
1995     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
1996
1997   rc = divert_generic_cmd (ctrl, line, ctx);
1998
1999   return rc;
2000 }
2001
2002
2003 \f
2004 static const char hlp_keywrap_key[] =
2005   "KEYWRAP_KEY [--clear] <mode>\n"
2006   "\n"
2007   "Return a key to wrap another key.  For now the key is returned\n"
2008   "verbatim and thus makes not much sense because an eavesdropper on\n"
2009   "the gpg-agent connection will see the key as well as the wrapped key.\n"
2010   "However, this function may either be equipped with a public key\n"
2011   "mechanism or not used at all if the key is a pre-shared key.  In any\n"
2012   "case wrapping the import and export of keys is a requirement for\n"
2013   "certain cryptographic validations and thus useful.  The key persists\n"
2014   "until a RESET command but may be cleared using the option --clear.\n"
2015   "\n"
2016   "Supported modes are:\n"
2017   "  --import  - Return a key to import a key into gpg-agent\n"
2018   "  --export  - Return a key to export a key from gpg-agent";
2019 static gpg_error_t
2020 cmd_keywrap_key (assuan_context_t ctx, char *line)
2021 {
2022   ctrl_t ctrl = assuan_get_pointer (ctx);
2023   gpg_error_t err = 0;
2024   int clearopt = has_option (line, "--clear");
2025
2026   if (ctrl->restricted)
2027     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2028
2029   assuan_begin_confidential (ctx);
2030   if (has_option (line, "--import"))
2031     {
2032       xfree (ctrl->server_local->import_key);
2033       if (clearopt)
2034         ctrl->server_local->import_key = NULL;
2035       else if (!(ctrl->server_local->import_key =
2036                  gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
2037         err = gpg_error_from_syserror ();
2038       else
2039         err = assuan_send_data (ctx, ctrl->server_local->import_key,
2040                                 KEYWRAP_KEYSIZE);
2041     }
2042   else if (has_option (line, "--export"))
2043     {
2044       xfree (ctrl->server_local->export_key);
2045       if (clearopt)
2046         ctrl->server_local->export_key = NULL;
2047       else if (!(ctrl->server_local->export_key =
2048             gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
2049         err = gpg_error_from_syserror ();
2050       else
2051         err = assuan_send_data (ctx, ctrl->server_local->export_key,
2052                                 KEYWRAP_KEYSIZE);
2053     }
2054   else
2055     err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for MODE");
2056   assuan_end_confidential (ctx);
2057
2058   return leave_cmd (ctx, err);
2059 }
2060
2061
2062 \f
2063 static const char hlp_import_key[] =
2064   "IMPORT_KEY [--unattended] [--force] [<cache_nonce>]\n"
2065   "\n"
2066   "Import a secret key into the key store.  The key is expected to be\n"
2067   "encrypted using the current session's key wrapping key (cf. command\n"
2068   "KEYWRAP_KEY) using the AESWRAP-128 algorithm.  This function takes\n"
2069   "no arguments but uses the inquiry \"KEYDATA\" to ask for the actual\n"
2070   "key data.  The unwrapped key must be a canonical S-expression.  The\n"
2071   "option --unattended tries to import the key as-is without any\n"
2072   "re-encryption.  Existing key can be overwritten with --force.";
2073 static gpg_error_t
2074 cmd_import_key (assuan_context_t ctx, char *line)
2075 {
2076   ctrl_t ctrl = assuan_get_pointer (ctx);
2077   gpg_error_t err;
2078   int opt_unattended;
2079   int force;
2080   unsigned char *wrappedkey = NULL;
2081   size_t wrappedkeylen;
2082   gcry_cipher_hd_t cipherhd = NULL;
2083   unsigned char *key = NULL;
2084   size_t keylen, realkeylen;
2085   char *passphrase = NULL;
2086   unsigned char *finalkey = NULL;
2087   size_t finalkeylen;
2088   unsigned char grip[20];
2089   gcry_sexp_t openpgp_sexp = NULL;
2090   char *cache_nonce = NULL;
2091   char *p;
2092
2093   if (ctrl->restricted)
2094     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2095
2096   if (!ctrl->server_local->import_key)
2097     {
2098       err = gpg_error (GPG_ERR_MISSING_KEY);
2099       goto leave;
2100     }
2101
2102   opt_unattended = has_option (line, "--unattended");
2103   force = has_option (line, "--force");
2104   line = skip_options (line);
2105
2106   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
2107     ;
2108   *p = '\0';
2109   if (*line)
2110     cache_nonce = xtrystrdup (line);
2111
2112   assuan_begin_confidential (ctx);
2113   err = assuan_inquire (ctx, "KEYDATA",
2114                         &wrappedkey, &wrappedkeylen, MAXLEN_KEYDATA);
2115   assuan_end_confidential (ctx);
2116   if (err)
2117     goto leave;
2118   if (wrappedkeylen < 24)
2119     {
2120       err = gpg_error (GPG_ERR_INV_LENGTH);
2121       goto leave;
2122     }
2123   keylen = wrappedkeylen - 8;
2124   key = xtrymalloc_secure (keylen);
2125   if (!key)
2126     {
2127       err = gpg_error_from_syserror ();
2128       goto leave;
2129     }
2130
2131   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
2132                           GCRY_CIPHER_MODE_AESWRAP, 0);
2133   if (err)
2134     goto leave;
2135   err = gcry_cipher_setkey (cipherhd,
2136                             ctrl->server_local->import_key, KEYWRAP_KEYSIZE);
2137   if (err)
2138     goto leave;
2139   err = gcry_cipher_decrypt (cipherhd, key, keylen, wrappedkey, wrappedkeylen);
2140   if (err)
2141     goto leave;
2142   gcry_cipher_close (cipherhd);
2143   cipherhd = NULL;
2144   xfree (wrappedkey);
2145   wrappedkey = NULL;
2146
2147   realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
2148   if (!realkeylen)
2149     goto leave; /* Invalid canonical encoded S-expression.  */
2150
2151   err = keygrip_from_canon_sexp (key, realkeylen, grip);
2152   if (err)
2153     {
2154       /* This might be due to an unsupported S-expression format.
2155          Check whether this is openpgp-private-key and trigger that
2156          import code.  */
2157       if (!gcry_sexp_sscan (&openpgp_sexp, NULL, key, realkeylen))
2158         {
2159           const char *tag;
2160           size_t taglen;
2161
2162           tag = gcry_sexp_nth_data (openpgp_sexp, 0, &taglen);
2163           if (tag && taglen == 19 && !memcmp (tag, "openpgp-private-key", 19))
2164             ;
2165           else
2166             {
2167               gcry_sexp_release (openpgp_sexp);
2168               openpgp_sexp = NULL;
2169             }
2170         }
2171       if (!openpgp_sexp)
2172         goto leave; /* Note that ERR is still set.  */
2173     }
2174
2175
2176   if (openpgp_sexp)
2177     {
2178       /* In most cases the key is encrypted and thus the conversion
2179          function from the OpenPGP format to our internal format will
2180          ask for a passphrase.  That passphrase will be returned and
2181          used to protect the key using the same code as for regular
2182          key import. */
2183
2184       xfree (key);
2185       key = NULL;
2186       err = convert_from_openpgp (ctrl, openpgp_sexp, force, grip,
2187                                   ctrl->server_local->keydesc, cache_nonce,
2188                                   &key, opt_unattended? NULL : &passphrase);
2189       if (err)
2190         goto leave;
2191       realkeylen = gcry_sexp_canon_len (key, 0, NULL, &err);
2192       if (!realkeylen)
2193         goto leave; /* Invalid canonical encoded S-expression.  */
2194       if (passphrase)
2195         {
2196           assert (!opt_unattended);
2197           if (!cache_nonce)
2198             {
2199               char buf[12];
2200               gcry_create_nonce (buf, 12);
2201               cache_nonce = bin2hex (buf, 12, NULL);
2202             }
2203           if (cache_nonce
2204               && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
2205                                    passphrase, CACHE_TTL_NONCE))
2206             assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
2207         }
2208     }
2209   else if (opt_unattended)
2210     {
2211       err = set_error (GPG_ERR_ASS_PARAMETER,
2212                        "\"--unattended\" may only be used with OpenPGP keys");
2213       goto leave;
2214     }
2215   else
2216     {
2217       if (!force && !agent_key_available (grip))
2218         err = gpg_error (GPG_ERR_EEXIST);
2219       else
2220         {
2221           char *prompt = xtryasprintf
2222             (_("Please enter the passphrase to protect the "
2223                "imported object within the %s system."), GNUPG_NAME);
2224           if (!prompt)
2225             err = gpg_error_from_syserror ();
2226           else
2227             err = agent_ask_new_passphrase (ctrl, prompt, &passphrase);
2228           xfree (prompt);
2229         }
2230       if (err)
2231         goto leave;
2232     }
2233
2234   if (passphrase)
2235     {
2236       err = agent_protect (key, passphrase, &finalkey, &finalkeylen,
2237                            ctrl->s2k_count, -1);
2238       if (!err)
2239         err = agent_write_private_key (grip, finalkey, finalkeylen, force);
2240     }
2241   else
2242     err = agent_write_private_key (grip, key, realkeylen, force);
2243
2244  leave:
2245   gcry_sexp_release (openpgp_sexp);
2246   xfree (finalkey);
2247   xfree (passphrase);
2248   xfree (key);
2249   gcry_cipher_close (cipherhd);
2250   xfree (wrappedkey);
2251   xfree (cache_nonce);
2252   xfree (ctrl->server_local->keydesc);
2253   ctrl->server_local->keydesc = NULL;
2254   return leave_cmd (ctx, err);
2255 }
2256
2257
2258 \f
2259 static const char hlp_export_key[] =
2260   "EXPORT_KEY [--cache-nonce=<nonce>] [--openpgp] <hexstring_with_keygrip>\n"
2261   "\n"
2262   "Export a secret key from the key store.  The key will be encrypted\n"
2263   "using the current session's key wrapping key (cf. command KEYWRAP_KEY)\n"
2264   "using the AESWRAP-128 algorithm.  The caller needs to retrieve that key\n"
2265   "prior to using this command.  The function takes the keygrip as argument.\n"
2266   "\n"
2267   "If --openpgp is used, the secret key material will be exported in RFC 4880\n"
2268   "compatible passphrase-protected form.  Without --openpgp, the secret key\n"
2269   "material will be exported in the clear (after prompting the user to unlock\n"
2270   "it, if needed).\n";
2271 static gpg_error_t
2272 cmd_export_key (assuan_context_t ctx, char *line)
2273 {
2274   ctrl_t ctrl = assuan_get_pointer (ctx);
2275   gpg_error_t err;
2276   unsigned char grip[20];
2277   gcry_sexp_t s_skey = NULL;
2278   unsigned char *key = NULL;
2279   size_t keylen;
2280   gcry_cipher_hd_t cipherhd = NULL;
2281   unsigned char *wrappedkey = NULL;
2282   size_t wrappedkeylen;
2283   int openpgp;
2284   char *cache_nonce;
2285   char *passphrase = NULL;
2286   unsigned char *shadow_info = NULL;
2287   char *pend;
2288   int c;
2289
2290   if (ctrl->restricted)
2291     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2292
2293   openpgp = has_option (line, "--openpgp");
2294   cache_nonce = option_value (line, "--cache-nonce");
2295   if (cache_nonce)
2296     {
2297       for (pend = cache_nonce; *pend && !spacep (pend); pend++)
2298         ;
2299       c = *pend;
2300       *pend = '\0';
2301       cache_nonce = xtrystrdup (cache_nonce);
2302       *pend = c;
2303       if (!cache_nonce)
2304         {
2305           err = gpg_error_from_syserror ();
2306           goto leave;
2307         }
2308     }
2309   line = skip_options (line);
2310
2311   if (!ctrl->server_local->export_key)
2312     {
2313       err = set_error (GPG_ERR_MISSING_KEY, "did you run KEYWRAP_KEY ?");
2314       goto leave;
2315     }
2316
2317   err = parse_keygrip (ctx, line, grip);
2318   if (err)
2319     goto leave;
2320
2321   if (agent_key_available (grip))
2322     {
2323       err = gpg_error (GPG_ERR_NO_SECKEY);
2324       goto leave;
2325     }
2326
2327   /* Get the key from the file.  With the openpgp flag we also ask for
2328      the passphrase so that we can use it to re-encrypt it.  */
2329   err = agent_key_from_file (ctrl, cache_nonce,
2330                              ctrl->server_local->keydesc, grip,
2331                              &shadow_info, CACHE_MODE_IGNORE, NULL, &s_skey,
2332                              openpgp ? &passphrase : NULL);
2333   if (err)
2334     goto leave;
2335   if (shadow_info)
2336     {
2337       /* Key is on a smartcard.  */
2338       err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
2339       goto leave;
2340     }
2341
2342   if (openpgp)
2343     {
2344       /* The openpgp option changes the key format into the OpenPGP
2345          key transfer format.  The result is already a padded
2346          canonical S-expression.  */
2347       if (!passphrase)
2348         {
2349           err = agent_ask_new_passphrase
2350             (ctrl, _("This key (or subkey) is not protected with a passphrase."
2351                      "  Please enter a new passphrase to export it."),
2352              &passphrase);
2353           if (err)
2354             goto leave;
2355         }
2356       err = convert_to_openpgp (ctrl, s_skey, passphrase, &key, &keylen);
2357       if (!err && passphrase)
2358         {
2359           if (!cache_nonce)
2360             {
2361               char buf[12];
2362               gcry_create_nonce (buf, 12);
2363               cache_nonce = bin2hex (buf, 12, NULL);
2364             }
2365           if (cache_nonce
2366               && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
2367                                    passphrase, CACHE_TTL_NONCE))
2368             {
2369               assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
2370               xfree (ctrl->server_local->last_cache_nonce);
2371               ctrl->server_local->last_cache_nonce = cache_nonce;
2372               cache_nonce = NULL;
2373             }
2374         }
2375     }
2376   else
2377     {
2378       /* Convert into a canonical S-expression and wrap that.  */
2379       err = make_canon_sexp_pad (s_skey, 1, &key, &keylen);
2380     }
2381   if (err)
2382     goto leave;
2383   gcry_sexp_release (s_skey);
2384   s_skey = NULL;
2385
2386   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
2387                           GCRY_CIPHER_MODE_AESWRAP, 0);
2388   if (err)
2389     goto leave;
2390   err = gcry_cipher_setkey (cipherhd,
2391                             ctrl->server_local->export_key, KEYWRAP_KEYSIZE);
2392   if (err)
2393     goto leave;
2394
2395   wrappedkeylen = keylen + 8;
2396   wrappedkey = xtrymalloc (wrappedkeylen);
2397   if (!wrappedkey)
2398     {
2399       err = gpg_error_from_syserror ();
2400       goto leave;
2401     }
2402
2403   err = gcry_cipher_encrypt (cipherhd, wrappedkey, wrappedkeylen, key, keylen);
2404   if (err)
2405     goto leave;
2406   xfree (key);
2407   key = NULL;
2408   gcry_cipher_close (cipherhd);
2409   cipherhd = NULL;
2410
2411   assuan_begin_confidential (ctx);
2412   err = assuan_send_data (ctx, wrappedkey, wrappedkeylen);
2413   assuan_end_confidential (ctx);
2414
2415
2416  leave:
2417   xfree (cache_nonce);
2418   xfree (passphrase);
2419   xfree (wrappedkey);
2420   gcry_cipher_close (cipherhd);
2421   xfree (key);
2422   gcry_sexp_release (s_skey);
2423   xfree (ctrl->server_local->keydesc);
2424   ctrl->server_local->keydesc = NULL;
2425   xfree (shadow_info);
2426
2427   return leave_cmd (ctx, err);
2428 }
2429
2430
2431 \f
2432 static const char hlp_delete_key[] =
2433   "DELETE_KEY [--force|--stub-only] <hexstring_with_keygrip>\n"
2434   "\n"
2435   "Delete a secret key from the key store.  If --force is used\n"
2436   "and a loopback pinentry is allowed, the agent will not ask\n"
2437   "the user for confirmation.  If --stub-only is used the key will\n"
2438   "only be deleted if it is a reference to a token.";
2439 static gpg_error_t
2440 cmd_delete_key (assuan_context_t ctx, char *line)
2441 {
2442   ctrl_t ctrl = assuan_get_pointer (ctx);
2443   gpg_error_t err;
2444   int force, stub_only;
2445   unsigned char grip[20];
2446
2447   if (ctrl->restricted)
2448     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2449
2450   force = has_option (line, "--force");
2451   stub_only = has_option (line, "--stub-only");
2452   line = skip_options (line);
2453
2454   /* If the use of a loopback pinentry has been disabled, we assume
2455    * that a silent deletion of keys shall also not be allowed.  */
2456   if (!opt.allow_loopback_pinentry)
2457     force = 0;
2458
2459   err = parse_keygrip (ctx, line, grip);
2460   if (err)
2461     goto leave;
2462
2463   err = agent_delete_key (ctrl, ctrl->server_local->keydesc, grip,
2464                           force, stub_only);
2465   if (err)
2466     goto leave;
2467
2468  leave:
2469   xfree (ctrl->server_local->keydesc);
2470   ctrl->server_local->keydesc = NULL;
2471
2472   return leave_cmd (ctx, err);
2473 }
2474
2475
2476 \f
2477 #if SIZEOF_TIME_T > SIZEOF_UNSIGNED_LONG
2478 #define KEYTOCARD_TIMESTAMP_FORMAT "(10:created-at10:%010llu))"
2479 #else
2480 #define KEYTOCARD_TIMESTAMP_FORMAT "(10:created-at10:%010lu))"
2481 #endif
2482
2483 static const char hlp_keytocard[] =
2484   "KEYTOCARD [--force] <hexstring_with_keygrip> <serialno> <id> <timestamp>\n"
2485   "\n";
2486 static gpg_error_t
2487 cmd_keytocard (assuan_context_t ctx, char *line)
2488 {
2489   ctrl_t ctrl = assuan_get_pointer (ctx);
2490   int force;
2491   gpg_error_t err = 0;
2492   unsigned char grip[20];
2493   gcry_sexp_t s_skey = NULL;
2494   unsigned char *keydata;
2495   size_t keydatalen;
2496   const char *serialno, *timestamp_str, *id;
2497   unsigned char *shadow_info = NULL;
2498   time_t timestamp;
2499
2500   if (ctrl->restricted)
2501     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2502
2503   force = has_option (line, "--force");
2504   line = skip_options (line);
2505
2506   err = parse_keygrip (ctx, line, grip);
2507   if (err)
2508     goto leave;
2509
2510   if (agent_key_available (grip))
2511     {
2512       err =gpg_error (GPG_ERR_NO_SECKEY);
2513       goto leave;
2514     }
2515
2516   /* Fixme: Replace the parsing code by split_fields().  */
2517   line += 40;
2518   while (*line && (*line == ' ' || *line == '\t'))
2519     line++;
2520   serialno = line;
2521   while (*line && (*line != ' ' && *line != '\t'))
2522     line++;
2523   if (!*line)
2524     {
2525       err = gpg_error (GPG_ERR_MISSING_VALUE);
2526       goto leave;
2527     }
2528   *line = '\0';
2529   line++;
2530   while (*line && (*line == ' ' || *line == '\t'))
2531     line++;
2532   id = line;
2533   while (*line && (*line != ' ' && *line != '\t'))
2534     line++;
2535   if (!*line)
2536     {
2537       err = gpg_error (GPG_ERR_MISSING_VALUE);
2538       goto leave;
2539     }
2540   *line = '\0';
2541   line++;
2542   while (*line && (*line == ' ' || *line == '\t'))
2543     line++;
2544   timestamp_str = line;
2545   while (*line && (*line != ' ' && *line != '\t'))
2546     line++;
2547   if (*line)
2548     *line = '\0';
2549
2550   if ((timestamp = isotime2epoch (timestamp_str)) == (time_t)(-1))
2551     {
2552       err = gpg_error (GPG_ERR_INV_TIME);
2553       goto leave;
2554     }
2555
2556   err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip,
2557                              &shadow_info, CACHE_MODE_IGNORE, NULL,
2558                              &s_skey, NULL);
2559   if (err)
2560     {
2561       xfree (shadow_info);
2562       goto leave;
2563     }
2564   if (shadow_info)
2565     {
2566       /* Key is on a smartcard already.  */
2567       xfree (shadow_info);
2568       gcry_sexp_release (s_skey);
2569       err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
2570       goto leave;
2571     }
2572
2573   keydatalen =  gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0);
2574   keydata = xtrymalloc_secure (keydatalen + 30);
2575   if (keydata == NULL)
2576     {
2577       err = gpg_error_from_syserror ();
2578       gcry_sexp_release (s_skey);
2579       goto leave;
2580     }
2581
2582   gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, keydata, keydatalen);
2583   gcry_sexp_release (s_skey);
2584   keydatalen--;                 /* Decrement for last '\0'.  */
2585   /* Add timestamp "created-at" in the private key */
2586   snprintf (keydata+keydatalen-1, 30, KEYTOCARD_TIMESTAMP_FORMAT, timestamp);
2587   keydatalen += 10 + 19 - 1;
2588   err = divert_writekey (ctrl, force, serialno, id, keydata, keydatalen);
2589   xfree (keydata);
2590
2591  leave:
2592   return leave_cmd (ctx, err);
2593 }
2594
2595
2596 \f
2597 static const char hlp_getval[] =
2598   "GETVAL <key>\n"
2599   "\n"
2600   "Return the value for KEY from the special environment as created by\n"
2601   "PUTVAL.";
2602 static gpg_error_t
2603 cmd_getval (assuan_context_t ctx, char *line)
2604 {
2605   ctrl_t ctrl = assuan_get_pointer (ctx);
2606   int rc = 0;
2607   char *key = NULL;
2608   char *p;
2609   struct putval_item_s *vl;
2610
2611   if (ctrl->restricted)
2612     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2613
2614   for (p=line; *p == ' '; p++)
2615     ;
2616   key = p;
2617   p = strchr (key, ' ');
2618   if (p)
2619     {
2620       *p++ = 0;
2621       for (; *p == ' '; p++)
2622         ;
2623       if (*p)
2624         return set_error (GPG_ERR_ASS_PARAMETER, "too many arguments");
2625     }
2626   if (!*key)
2627     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2628
2629
2630   for (vl=putval_list; vl; vl = vl->next)
2631     if ( !strcmp (vl->d, key) )
2632       break;
2633
2634   if (vl) /* Got an entry. */
2635     rc = assuan_send_data (ctx, vl->d+vl->off, vl->len);
2636   else
2637     return gpg_error (GPG_ERR_NO_DATA);
2638
2639   return leave_cmd (ctx, rc);
2640 }
2641
2642
2643 static const char hlp_putval[] =
2644   "PUTVAL <key> [<percent_escaped_value>]\n"
2645   "\n"
2646   "The gpg-agent maintains a kind of environment which may be used to\n"
2647   "store key/value pairs in it, so that they can be retrieved later.\n"
2648   "This may be used by helper daemons to daemonize themself on\n"
2649   "invocation and register them with gpg-agent.  Callers of the\n"
2650   "daemon's service may now first try connect to get the information\n"
2651   "for that service from gpg-agent through the GETVAL command and then\n"
2652   "try to connect to that daemon.  Only if that fails they may start\n"
2653   "an own instance of the service daemon. \n"
2654   "\n"
2655   "KEY is an arbitrary symbol with the same syntax rules as keys\n"
2656   "for shell environment variables.  PERCENT_ESCAPED_VALUE is the\n"
2657   "corresponding value; they should be similar to the values of\n"
2658   "envronment variables but gpg-agent does not enforce any\n"
2659   "restrictions.  If that value is not given any value under that KEY\n"
2660   "is removed from this special environment.";
2661 static gpg_error_t
2662 cmd_putval (assuan_context_t ctx, char *line)
2663 {
2664   ctrl_t ctrl = assuan_get_pointer (ctx);
2665   int rc = 0;
2666   char *key = NULL;
2667   char *value = NULL;
2668   size_t valuelen = 0;
2669   char *p;
2670   struct putval_item_s *vl, *vlprev;
2671
2672   if (ctrl->restricted)
2673     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2674
2675   for (p=line; *p == ' '; p++)
2676     ;
2677   key = p;
2678   p = strchr (key, ' ');
2679   if (p)
2680     {
2681       *p++ = 0;
2682       for (; *p == ' '; p++)
2683         ;
2684       if (*p)
2685         {
2686           value = p;
2687           p = strchr (value, ' ');
2688           if (p)
2689             *p = 0;
2690           valuelen = percent_plus_unescape_inplace (value, 0);
2691         }
2692     }
2693   if (!*key)
2694     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2695
2696
2697   for (vl=putval_list,vlprev=NULL; vl; vlprev=vl, vl = vl->next)
2698     if ( !strcmp (vl->d, key) )
2699       break;
2700
2701   if (vl) /* Delete old entry. */
2702     {
2703       if (vlprev)
2704         vlprev->next = vl->next;
2705       else
2706         putval_list = vl->next;
2707       xfree (vl);
2708     }
2709
2710   if (valuelen) /* Add entry. */
2711     {
2712       vl = xtrymalloc (sizeof *vl + strlen (key) + valuelen);
2713       if (!vl)
2714         rc = gpg_error_from_syserror ();
2715       else
2716         {
2717           vl->len = valuelen;
2718           vl->off = strlen (key) + 1;
2719           strcpy (vl->d, key);
2720           memcpy (vl->d + vl->off, value, valuelen);
2721           vl->next = putval_list;
2722           putval_list = vl;
2723         }
2724     }
2725
2726   return leave_cmd (ctx, rc);
2727 }
2728
2729
2730
2731 \f
2732 static const char hlp_updatestartuptty[] =
2733   "UPDATESTARTUPTTY\n"
2734   "\n"
2735   "Set startup TTY and X11 DISPLAY variables to the values of this\n"
2736   "session.  This command is useful to pull future pinentries to\n"
2737   "another screen.  It is only required because there is no way in the\n"
2738   "ssh-agent protocol to convey this information.";
2739 static gpg_error_t
2740 cmd_updatestartuptty (assuan_context_t ctx, char *line)
2741 {
2742   ctrl_t ctrl = assuan_get_pointer (ctx);
2743   gpg_error_t err = 0;
2744   session_env_t se;
2745   char *lc_ctype = NULL;
2746   char *lc_messages = NULL;
2747   int iterator;
2748   const char *name;
2749
2750   (void)line;
2751
2752   if (ctrl->restricted)
2753     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2754
2755   se = session_env_new ();
2756   if (!se)
2757     err = gpg_error_from_syserror ();
2758
2759   iterator = 0;
2760   while (!err && (name = session_env_list_stdenvnames (&iterator, NULL)))
2761     {
2762       const char *value = session_env_getenv (ctrl->session_env, name);
2763       if (value)
2764         err = session_env_setenv (se, name, value);
2765     }
2766
2767   if (!err && ctrl->lc_ctype)
2768     if (!(lc_ctype = xtrystrdup (ctrl->lc_ctype)))
2769       err = gpg_error_from_syserror ();
2770
2771   if (!err && ctrl->lc_messages)
2772     if (!(lc_messages = xtrystrdup (ctrl->lc_messages)))
2773       err = gpg_error_from_syserror ();
2774
2775   if (err)
2776     {
2777       session_env_release (se);
2778       xfree (lc_ctype);
2779       xfree (lc_messages);
2780     }
2781   else
2782     {
2783       session_env_release (opt.startup_env);
2784       opt.startup_env = se;
2785       xfree (opt.startup_lc_ctype);
2786       opt.startup_lc_ctype = lc_ctype;
2787       xfree (opt.startup_lc_messages);
2788       opt.startup_lc_messages = lc_messages;
2789     }
2790
2791   return err;
2792 }
2793
2794
2795 \f
2796 static const char hlp_killagent[] =
2797   "KILLAGENT\n"
2798   "\n"
2799   "Stop the agent.";
2800 static gpg_error_t
2801 cmd_killagent (assuan_context_t ctx, char *line)
2802 {
2803   ctrl_t ctrl = assuan_get_pointer (ctx);
2804
2805   (void)line;
2806
2807   if (ctrl->restricted)
2808     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2809
2810   ctrl->server_local->stopme = 1;
2811   assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
2812   return 0;
2813 }
2814
2815
2816 static const char hlp_reloadagent[] =
2817   "RELOADAGENT\n"
2818   "\n"
2819   "This command is an alternative to SIGHUP\n"
2820   "to reload the configuration.";
2821 static gpg_error_t
2822 cmd_reloadagent (assuan_context_t ctx, char *line)
2823 {
2824   ctrl_t ctrl = assuan_get_pointer (ctx);
2825
2826   (void)line;
2827
2828   if (ctrl->restricted)
2829     return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2830
2831   agent_sighup_action ();
2832   return 0;
2833 }
2834
2835
2836 \f
2837 static const char hlp_getinfo[] =
2838   "GETINFO <what>\n"
2839   "\n"
2840   "Multipurpose function to return a variety of information.\n"
2841   "Supported values for WHAT are:\n"
2842   "\n"
2843   "  version     - Return the version of the program.\n"
2844   "  pid         - Return the process id of the server.\n"
2845   "  socket_name - Return the name of the socket.\n"
2846   "  ssh_socket_name - Return the name of the ssh socket.\n"
2847   "  scd_running - Return OK if the SCdaemon is already running.\n"
2848   "  s2k_count   - Return the calibrated S2K count.\n"
2849   "  std_env_names   - List the names of the standard environment.\n"
2850   "  std_session_env - List the standard session environment.\n"
2851   "  std_startup_env - List the standard startup environment.\n"
2852   "  cmd_has_option\n"
2853   "              - Returns OK if the command CMD implements the option OPT.\n"
2854   "  connections - Return number of active connections.\n"
2855   "  jent_active - Returns OK if Libgcrypt's JENT is active.\n"
2856   "  restricted  - Returns OK if the connection is in restricted mode.\n";
2857 static gpg_error_t
2858 cmd_getinfo (assuan_context_t ctx, char *line)
2859 {
2860   ctrl_t ctrl = assuan_get_pointer (ctx);
2861   int rc = 0;
2862
2863   if (!strcmp (line, "version"))
2864     {
2865       const char *s = VERSION;
2866       rc = assuan_send_data (ctx, s, strlen (s));
2867     }
2868   else if (!strncmp (line, "cmd_has_option", 14)
2869            && (line[14] == ' ' || line[14] == '\t' || !line[14]))
2870     {
2871       char *cmd, *cmdopt;
2872       line += 14;
2873       while (*line == ' ' || *line == '\t')
2874         line++;
2875       if (!*line)
2876         rc = gpg_error (GPG_ERR_MISSING_VALUE);
2877       else
2878         {
2879           cmd = line;
2880           while (*line && (*line != ' ' && *line != '\t'))
2881             line++;
2882           if (!*line)
2883             rc = gpg_error (GPG_ERR_MISSING_VALUE);
2884           else
2885             {
2886               *line++ = 0;
2887               while (*line == ' ' || *line == '\t')
2888                 line++;
2889               if (!*line)
2890                 rc = gpg_error (GPG_ERR_MISSING_VALUE);
2891               else
2892                 {
2893                   cmdopt = line;
2894                   if (!command_has_option (cmd, cmdopt))
2895                     rc = gpg_error (GPG_ERR_GENERAL);
2896                 }
2897             }
2898         }
2899     }
2900   else if (!strcmp (line, "s2k_count"))
2901     {
2902       char numbuf[50];
2903
2904       snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ());
2905       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2906     }
2907   else if (!strcmp (line, "restricted"))
2908     {
2909       rc = ctrl->restricted? 0 : gpg_error (GPG_ERR_GENERAL);
2910     }
2911   else if (ctrl->restricted)
2912     {
2913       rc = gpg_error (GPG_ERR_FORBIDDEN);
2914     }
2915   /* All sub-commands below are not allowed in restricted mode.  */
2916   else if (!strcmp (line, "pid"))
2917     {
2918       char numbuf[50];
2919
2920       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2921       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2922     }
2923   else if (!strcmp (line, "socket_name"))
2924     {
2925       const char *s = get_agent_socket_name ();
2926
2927       if (s)
2928         rc = assuan_send_data (ctx, s, strlen (s));
2929       else
2930         rc = gpg_error (GPG_ERR_NO_DATA);
2931     }
2932   else if (!strcmp (line, "ssh_socket_name"))
2933     {
2934       const char *s = get_agent_ssh_socket_name ();
2935
2936       if (s)
2937         rc = assuan_send_data (ctx, s, strlen (s));
2938       else
2939         rc = gpg_error (GPG_ERR_NO_DATA);
2940     }
2941   else if (!strcmp (line, "scd_running"))
2942     {
2943       rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL);
2944     }
2945   else if (!strcmp (line, "std_env_names"))
2946     {
2947       int iterator;
2948       const char *name;
2949
2950       iterator = 0;
2951       while ((name = session_env_list_stdenvnames (&iterator, NULL)))
2952         {
2953           rc = assuan_send_data (ctx, name, strlen (name)+1);
2954           if (!rc)
2955             rc = assuan_send_data (ctx, NULL, 0);
2956           if (rc)
2957             break;
2958         }
2959     }
2960   else if (!strcmp (line, "std_session_env")
2961            || !strcmp (line, "std_startup_env"))
2962     {
2963       int iterator;
2964       const char *name, *value;
2965       char *string;
2966
2967       iterator = 0;
2968       while ((name = session_env_list_stdenvnames (&iterator, NULL)))
2969         {
2970           value = session_env_getenv_or_default
2971             (line[5] == 't'? opt.startup_env:ctrl->session_env, name, NULL);
2972           if (value)
2973             {
2974               string = xtryasprintf ("%s=%s", name, value);
2975               if (!string)
2976                 rc = gpg_error_from_syserror ();
2977               else
2978                 {
2979                   rc = assuan_send_data (ctx, string, strlen (string)+1);
2980                   if (!rc)
2981                     rc = assuan_send_data (ctx, NULL, 0);
2982                 }
2983               if (rc)
2984                 break;
2985             }
2986         }
2987     }
2988   else if (!strcmp (line, "connections"))
2989     {
2990       char numbuf[20];
2991
2992       snprintf (numbuf, sizeof numbuf, "%d",
2993                 get_agent_active_connection_count ());
2994       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2995     }
2996   else if (!strcmp (line, "jent_active"))
2997     {
2998 #if GCRYPT_VERSION_NUMBER >= 0x010800
2999       char *buf;
3000       char *fields[5];
3001
3002       buf = gcry_get_config (0, "rng-type");
3003       if (buf
3004           && split_fields_colon (buf, fields, DIM (fields)) >= 5
3005           && atoi (fields[4]) > 0)
3006         rc = 0;
3007       else
3008         rc = gpg_error (GPG_ERR_FALSE);
3009       gcry_free (buf);
3010 #else
3011       rc = gpg_error (GPG_ERR_FALSE);
3012 #endif
3013     }
3014   else
3015     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
3016   return rc;
3017 }
3018
3019
3020 \f
3021 /* This function is called by Libassuan to parse the OPTION command.
3022    It has been registered similar to the other Assuan commands.  */
3023 static gpg_error_t
3024 option_handler (assuan_context_t ctx, const char *key, const char *value)
3025 {
3026   ctrl_t ctrl = assuan_get_pointer (ctx);
3027   gpg_error_t err = 0;
3028
3029   if (!strcmp (key, "agent-awareness"))
3030     {
3031       /* The value is a version string telling us of which agent
3032          version the caller is aware of.  */
3033       ctrl->server_local->allow_fully_canceled =
3034         gnupg_compare_version (value, "2.1.0");
3035     }
3036   else if (ctrl->restricted)
3037     {
3038       err = gpg_error (GPG_ERR_FORBIDDEN);
3039     }
3040   /* All options below are not allowed in restricted mode.  */
3041   else if (!strcmp (key, "putenv"))
3042     {
3043       /* Change the session's environment to be used for the
3044          Pinentry.  Valid values are:
3045           <NAME>            Delete envvar NAME
3046           <KEY>=            Set envvar NAME to the empty string
3047           <KEY>=<VALUE>     Set envvar NAME to VALUE
3048       */
3049       err = session_env_putenv (ctrl->session_env, value);
3050     }
3051   else if (!strcmp (key, "display"))
3052     {
3053       err = session_env_setenv (ctrl->session_env, "DISPLAY", value);
3054     }
3055   else if (!strcmp (key, "ttyname"))
3056     {
3057       if (!opt.keep_tty)
3058         err = session_env_setenv (ctrl->session_env, "GPG_TTY", value);
3059     }
3060   else if (!strcmp (key, "ttytype"))
3061     {
3062       if (!opt.keep_tty)
3063         err = session_env_setenv (ctrl->session_env, "TERM", value);
3064     }
3065   else if (!strcmp (key, "lc-ctype"))
3066     {
3067       if (ctrl->lc_ctype)
3068         xfree (ctrl->lc_ctype);
3069       ctrl->lc_ctype = xtrystrdup (value);
3070       if (!ctrl->lc_ctype)
3071         return out_of_core ();
3072     }
3073   else if (!strcmp (key, "lc-messages"))
3074     {
3075       if (ctrl->lc_messages)
3076         xfree (ctrl->lc_messages);
3077       ctrl->lc_messages = xtrystrdup (value);
3078       if (!ctrl->lc_messages)
3079         return out_of_core ();
3080     }
3081   else if (!strcmp (key, "xauthority"))
3082     {
3083       err = session_env_setenv (ctrl->session_env, "XAUTHORITY", value);
3084     }
3085   else if (!strcmp (key, "pinentry-user-data"))
3086     {
3087       err = session_env_setenv (ctrl->session_env, "PINENTRY_USER_DATA", value);
3088     }
3089   else if (!strcmp (key, "use-cache-for-signing"))
3090     ctrl->server_local->use_cache_for_signing = *value? !!atoi (value) : 0;
3091   else if (!strcmp (key, "allow-pinentry-notify"))
3092     ctrl->server_local->allow_pinentry_notify = 1;
3093   else if (!strcmp (key, "pinentry-mode"))
3094     {
3095       int tmp = parse_pinentry_mode (value);
3096       if (tmp == -1)
3097         err = gpg_error (GPG_ERR_INV_VALUE);
3098       else if (tmp == PINENTRY_MODE_LOOPBACK && !opt.allow_loopback_pinentry)
3099         err = gpg_error (GPG_ERR_NOT_SUPPORTED);
3100       else
3101         ctrl->pinentry_mode = tmp;
3102     }
3103   else if (!strcmp (key, "cache-ttl-opt-preset"))
3104     {
3105       ctrl->cache_ttl_opt_preset = *value? atoi (value) : 0;
3106     }
3107   else if (!strcmp (key, "s2k-count"))
3108     {
3109       ctrl->s2k_count = *value? strtoul(value, NULL, 10) : 0;
3110       if (ctrl->s2k_count && ctrl->s2k_count < 65536)
3111         {
3112           ctrl->s2k_count = 0;
3113         }
3114     }
3115   else
3116     err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
3117
3118   return err;
3119 }
3120
3121
3122
3123 \f
3124 /* Called by libassuan after all commands. ERR is the error from the
3125    last assuan operation and not the one returned from the command. */
3126 static void
3127 post_cmd_notify (assuan_context_t ctx, gpg_error_t err)
3128 {
3129   ctrl_t ctrl = assuan_get_pointer (ctx);
3130
3131   (void)err;
3132
3133   /* Switch off any I/O monitor controlled logging pausing. */
3134   ctrl->server_local->pause_io_logging = 0;
3135 }
3136
3137
3138 /* This function is called by libassuan for all I/O.  We use it here
3139    to disable logging for the GETEVENTCOUNTER commands.  This is so
3140    that the debug output won't get cluttered by this primitive
3141    command.  */
3142 static unsigned int
3143 io_monitor (assuan_context_t ctx, void *hook, int direction,
3144             const char *line, size_t linelen)
3145 {
3146   ctrl_t ctrl = assuan_get_pointer (ctx);
3147
3148   (void) hook;
3149
3150   /* We want to suppress all Assuan log messages for connections from
3151    * self.  However, assuan_get_pid works only after
3152    * assuan_accept. Now, assuan_accept already logs a line ending with
3153    * the process id.  We use this hack here to get the peers pid so
3154    * that we can compare it to our pid.  We should add an assuan
3155    * function to return the pid for a file descriptor and use that to
3156    * detect connections to self.  */
3157   if (ctx && !ctrl->server_local->greeting_seen
3158       && direction == ASSUAN_IO_TO_PEER)
3159     {
3160       ctrl->server_local->greeting_seen = 1;
3161       if (linelen > 32
3162           && !strncmp (line, "OK Pleased to meet you, process ", 32)
3163           && strtoul (line+32, NULL, 10) == getpid ())
3164         return ASSUAN_IO_MONITOR_NOLOG;
3165     }
3166
3167
3168   /* Do not log self-connections.  This makes the log cleaner because
3169    * we won't see the check-our-own-socket calls.  */
3170   if (ctx && ctrl->server_local->connect_from_self)
3171     return ASSUAN_IO_MONITOR_NOLOG;
3172
3173   /* Note that we only check for the uppercase name.  This allows the user to
3174      see the logging for debugging if using a non-upercase command
3175      name. */
3176   if (ctx && direction == ASSUAN_IO_FROM_PEER
3177       && linelen >= 15
3178       && !strncmp (line, "GETEVENTCOUNTER", 15)
3179       && (linelen == 15 || spacep (line+15)))
3180     {
3181       ctrl->server_local->pause_io_logging = 1;
3182     }
3183
3184   return ctrl->server_local->pause_io_logging? ASSUAN_IO_MONITOR_NOLOG : 0;
3185 }
3186
3187
3188 /* Return true if the command CMD implements the option OPT.  */
3189 static int
3190 command_has_option (const char *cmd, const char *cmdopt)
3191 {
3192   if (!strcmp (cmd, "GET_PASSPHRASE"))
3193     {
3194       if (!strcmp (cmdopt, "repeat"))
3195           return 1;
3196     }
3197
3198   return 0;
3199 }
3200
3201
3202 /* Tell Libassuan about our commands.  Also register the other Assuan
3203    handlers. */
3204 static int
3205 register_commands (assuan_context_t ctx)
3206 {
3207   static struct {
3208     const char *name;
3209     assuan_handler_t handler;
3210     const char * const help;
3211   } table[] = {
3212     { "GETEVENTCOUNTER",cmd_geteventcounter, hlp_geteventcounter },
3213     { "ISTRUSTED",      cmd_istrusted, hlp_istrusted },
3214     { "HAVEKEY",        cmd_havekey,   hlp_havekey },
3215     { "KEYINFO",        cmd_keyinfo,   hlp_keyinfo },
3216     { "SIGKEY",         cmd_sigkey,    hlp_sigkey },
3217     { "SETKEY",         cmd_sigkey,    hlp_sigkey },
3218     { "SETKEYDESC",     cmd_setkeydesc,hlp_setkeydesc },
3219     { "SETHASH",        cmd_sethash,   hlp_sethash },
3220     { "PKSIGN",         cmd_pksign,    hlp_pksign },
3221     { "PKDECRYPT",      cmd_pkdecrypt, hlp_pkdecrypt },
3222     { "GENKEY",         cmd_genkey,    hlp_genkey },
3223     { "READKEY",        cmd_readkey,   hlp_readkey },
3224     { "GET_PASSPHRASE", cmd_get_passphrase, hlp_get_passphrase },
3225     { "PRESET_PASSPHRASE", cmd_preset_passphrase, hlp_preset_passphrase },
3226     { "CLEAR_PASSPHRASE", cmd_clear_passphrase,   hlp_clear_passphrase },
3227     { "GET_CONFIRMATION", cmd_get_confirmation,   hlp_get_confirmation },
3228     { "LISTTRUSTED",    cmd_listtrusted, hlp_listtrusted },
3229     { "MARKTRUSTED",    cmd_marktrusted, hlp_martrusted },
3230     { "LEARN",          cmd_learn,     hlp_learn },
3231     { "PASSWD",         cmd_passwd,    hlp_passwd },
3232     { "INPUT",          NULL },
3233     { "OUTPUT",         NULL },
3234     { "SCD",            cmd_scd,       hlp_scd },
3235     { "KEYWRAP_KEY",    cmd_keywrap_key, hlp_keywrap_key },
3236     { "IMPORT_KEY",     cmd_import_key, hlp_import_key },
3237     { "EXPORT_KEY",     cmd_export_key, hlp_export_key },
3238     { "DELETE_KEY",     cmd_delete_key, hlp_delete_key },
3239     { "GETVAL",         cmd_getval,    hlp_getval },
3240     { "PUTVAL",         cmd_putval,    hlp_putval },
3241     { "UPDATESTARTUPTTY",  cmd_updatestartuptty, hlp_updatestartuptty },
3242     { "KILLAGENT",      cmd_killagent,  hlp_killagent },
3243     { "RELOADAGENT",    cmd_reloadagent,hlp_reloadagent },
3244     { "GETINFO",        cmd_getinfo,   hlp_getinfo },
3245     { "KEYTOCARD",      cmd_keytocard, hlp_keytocard },
3246     { NULL }
3247   };
3248   int i, rc;
3249
3250   for (i=0; table[i].name; i++)
3251     {
3252       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
3253                                     table[i].help);
3254       if (rc)
3255         return rc;
3256     }
3257   assuan_register_post_cmd_notify (ctx, post_cmd_notify);
3258   assuan_register_reset_notify (ctx, reset_notify);
3259   assuan_register_option_handler (ctx, option_handler);
3260   return 0;
3261 }
3262
3263
3264 /* Startup the server.  If LISTEN_FD and FD is given as -1, this is a
3265    simple piper server, otherwise it is a regular server.  CTRL is the
3266    control structure for this connection; it has only the basic
3267    initialization. */
3268 void
3269 start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
3270 {
3271   int rc;
3272   assuan_context_t ctx = NULL;
3273
3274   if (ctrl->restricted)
3275     {
3276       if (agent_copy_startup_env (ctrl))
3277         return;
3278     }
3279
3280   rc = assuan_new (&ctx);
3281   if (rc)
3282     {
3283       log_error ("failed to allocate assuan context: %s\n", gpg_strerror (rc));
3284       agent_exit (2);
3285     }
3286
3287   if (listen_fd == GNUPG_INVALID_FD && fd == GNUPG_INVALID_FD)
3288     {
3289       assuan_fd_t filedes[2];
3290
3291       filedes[0] = assuan_fdopen (0);
3292       filedes[1] = assuan_fdopen (1);
3293       rc = assuan_init_pipe_server (ctx, filedes);
3294     }
3295   else if (listen_fd != GNUPG_INVALID_FD)
3296     {
3297       rc = assuan_init_socket_server (ctx, listen_fd, 0);
3298       /* FIXME: Need to call assuan_sock_set_nonce for Windows.  But
3299          this branch is currently not used.  */
3300     }
3301   else
3302     {
3303       rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
3304     }
3305   if (rc)
3306     {
3307       log_error ("failed to initialize the server: %s\n",
3308                  gpg_strerror(rc));
3309       agent_exit (2);
3310     }
3311   rc = register_commands (ctx);
3312   if (rc)
3313     {
3314       log_error ("failed to register commands with Assuan: %s\n",
3315                  gpg_strerror(rc));
3316       agent_exit (2);
3317     }
3318
3319   assuan_set_pointer (ctx, ctrl);
3320   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
3321   ctrl->server_local->assuan_ctx = ctx;
3322   ctrl->server_local->use_cache_for_signing = 1;
3323
3324   ctrl->digest.raw_value = 0;
3325
3326   assuan_set_io_monitor (ctx, io_monitor, NULL);
3327   agent_set_progress_cb (progress_cb, ctrl);
3328
3329   for (;;)
3330     {
3331       pid_t client_pid;
3332
3333       rc = assuan_accept (ctx);
3334       if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1)
3335         {
3336           break;
3337         }
3338       else if (rc)
3339         {
3340           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
3341           break;
3342         }
3343
3344       client_pid = assuan_get_pid (ctx);
3345       ctrl->server_local->connect_from_self = (client_pid == getpid ());
3346       if (client_pid != ASSUAN_INVALID_PID)
3347         ctrl->client_pid = (unsigned long)client_pid;
3348       else
3349         ctrl->client_pid = 0;
3350
3351       rc = assuan_process (ctx);
3352       if (rc)
3353         {
3354           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
3355           continue;
3356         }
3357     }
3358
3359   /* Reset the nonce caches.  */
3360   clear_nonce_cache (ctrl);
3361
3362   /* Reset the SCD if needed. */
3363   agent_reset_scd (ctrl);
3364
3365   /* Reset the pinentry (in case of popup messages). */
3366   agent_reset_query (ctrl);
3367
3368   /* Cleanup.  */
3369   assuan_release (ctx);
3370   xfree (ctrl->server_local->keydesc);
3371   xfree (ctrl->server_local->import_key);
3372   xfree (ctrl->server_local->export_key);
3373   if (ctrl->server_local->stopme)
3374     agent_exit (0);
3375   xfree (ctrl->server_local);
3376   ctrl->server_local = NULL;
3377 }
3378
3379
3380 /* Helper for the pinentry loopback mode.  It merely passes the
3381    parameters on to the client.  */
3382 gpg_error_t
3383 pinentry_loopback(ctrl_t ctrl, const char *keyword,
3384                   unsigned char **buffer, size_t *size,
3385                   size_t max_length)
3386 {
3387   gpg_error_t rc;
3388   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
3389
3390   rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%zu", max_length);
3391   if (rc)
3392     return rc;
3393
3394   assuan_begin_confidential (ctx);
3395   rc = assuan_inquire (ctx, keyword, buffer, size, max_length);
3396   assuan_end_confidential (ctx);
3397   return rc;
3398 }