Fixed EOF detection for encrypted packets.
[gnupg.git] / g10 / call-agent.c
blob5ee7f8e063de6f35cf56b0670a080424b2919ba8
1 /* call-agent.c - Divert GPG operations to the agent.
2 * Copyright (C) 2001, 2002, 2003, 2006, 2007,
3 * 2008, 2009 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
7 * GnuPG is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * GnuPG is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <unistd.h>
27 #include <time.h>
28 #include <assert.h>
29 #ifdef HAVE_LOCALE_H
30 #include <locale.h>
31 #endif
33 #include "gpg.h"
34 #include <assuan.h>
35 #include "util.h"
36 #include "membuf.h"
37 #include "options.h"
38 #include "i18n.h"
39 #include "asshelp.h"
40 #include "sysutils.h"
41 #include "call-agent.h"
42 #include "status.h"
44 #ifndef DBG_ASSUAN
45 # define DBG_ASSUAN 1
46 #endif
48 static assuan_context_t agent_ctx = NULL;
49 static int did_early_card_test;
51 struct cipher_parm_s
53 assuan_context_t ctx;
54 const char *ciphertext;
55 size_t ciphertextlen;
58 struct writecert_parm_s
60 assuan_context_t ctx;
61 const unsigned char *certdata;
62 size_t certdatalen;
65 struct writekey_parm_s
67 assuan_context_t ctx;
68 const unsigned char *keydata;
69 size_t keydatalen;
72 struct genkey_parm_s
74 assuan_context_t ctx;
75 const char *sexp;
76 size_t sexplen;
80 static gpg_error_t learn_status_cb (void *opaque, const char *line);
84 /* If RC is not 0, write an appropriate status message. */
85 static void
86 status_sc_op_failure (int rc)
88 switch (gpg_err_code (rc))
90 case 0:
91 break;
92 case GPG_ERR_CANCELED:
93 write_status_text (STATUS_SC_OP_FAILURE, "1");
94 break;
95 case GPG_ERR_BAD_PIN:
96 write_status_text (STATUS_SC_OP_FAILURE, "2");
97 break;
98 default:
99 write_status (STATUS_SC_OP_FAILURE);
100 break;
107 /* Try to connect to the agent via socket or fork it off and work by
108 pipes. Handle the server's initial greeting */
109 static int
110 start_agent (int for_card)
112 int rc;
114 /* Fixme: We need a context for each thread or serialize the access
115 to the agent. */
116 if (agent_ctx)
117 rc = 0;
118 else
120 rc = start_new_gpg_agent (&agent_ctx,
121 GPG_ERR_SOURCE_DEFAULT,
122 opt.homedir,
123 opt.agent_program,
124 opt.lc_ctype, opt.lc_messages,
125 opt.session_env,
126 opt.verbose, DBG_ASSUAN,
127 NULL, NULL);
128 if (!rc)
130 /* Tell the agent that we support Pinentry notifications.
131 No error checking so that it will work also with older
132 agents. */
133 assuan_transact (agent_ctx, "OPTION allow-pinentry-notify",
134 NULL, NULL, NULL, NULL, NULL, NULL);
138 if (!rc && for_card && !did_early_card_test)
140 /* Request the serial number of the card for an early test. */
141 struct agent_card_info_s info;
143 memset (&info, 0, sizeof info);
144 rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
145 NULL, NULL, NULL, NULL,
146 learn_status_cb, &info);
147 if (rc)
149 switch (gpg_err_code (rc))
151 case GPG_ERR_NOT_SUPPORTED:
152 case GPG_ERR_NO_SCDAEMON:
153 write_status_text (STATUS_CARDCTRL, "6");
154 break;
155 default:
156 write_status_text (STATUS_CARDCTRL, "4");
157 log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
158 break;
162 if (!rc && is_status_enabled () && info.serialno)
164 char *buf;
166 buf = xasprintf ("3 %s", info.serialno);
167 write_status_text (STATUS_CARDCTRL, buf);
168 xfree (buf);
171 agent_release_card_info (&info);
173 if (!rc)
174 did_early_card_test = 1;
178 return rc;
182 /* Return a new malloced string by unescaping the string S. Escaping
183 is percent escaping and '+'/space mapping. A binary nul will
184 silently be replaced by a 0xFF. Function returns NULL to indicate
185 an out of memory status. */
186 static char *
187 unescape_status_string (const unsigned char *s)
189 return percent_plus_unescape (s, 0xff);
193 /* Take a 20 byte hexencoded string and put it into the the provided
194 20 byte buffer FPR in binary format. */
195 static int
196 unhexify_fpr (const char *hexstr, unsigned char *fpr)
198 const char *s;
199 int n;
201 for (s=hexstr, n=0; hexdigitp (s); s++, n++)
203 if (*s || (n != 40))
204 return 0; /* no fingerprint (invalid or wrong length). */
205 for (s=hexstr, n=0; *s; s += 2, n++)
206 fpr[n] = xtoi_2 (s);
207 return 1; /* okay */
210 /* Take the serial number from LINE and return it verbatim in a newly
211 allocated string. We make sure that only hex characters are
212 returned. */
213 static char *
214 store_serialno (const char *line)
216 const char *s;
217 char *p;
219 for (s=line; hexdigitp (s); s++)
221 p = xtrymalloc (s + 1 - line);
222 if (p)
224 memcpy (p, line, s-line);
225 p[s-line] = 0;
227 return p;
232 /* This is a dummy data line callback. */
233 static gpg_error_t
234 dummy_data_cb (void *opaque, const void *buffer, size_t length)
236 (void)opaque;
237 (void)buffer;
238 (void)length;
239 return 0;
242 /* A simple callback used to return the serialnumber of a card. */
243 static gpg_error_t
244 get_serialno_cb (void *opaque, const char *line)
246 char **serialno = opaque;
247 const char *keyword = line;
248 const char *s;
249 int keywordlen, n;
251 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
253 while (spacep (line))
254 line++;
256 if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
258 if (*serialno)
259 return gpg_error (GPG_ERR_CONFLICT); /* Unexpected status line. */
260 for (n=0,s=line; hexdigitp (s); s++, n++)
262 if (!n || (n&1)|| !(spacep (s) || !*s) )
263 return gpg_error (GPG_ERR_ASS_PARAMETER);
264 *serialno = xtrymalloc (n+1);
265 if (!*serialno)
266 return out_of_core ();
267 memcpy (*serialno, line, n);
268 (*serialno)[n] = 0;
271 return 0;
275 /* This is the default inquiry callback. It mainly handles the
276 Pinentry notifications. */
277 static gpg_error_t
278 default_inq_cb (void *opaque, const char *line)
280 (void)opaque;
282 if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17]))
284 /* There is no working server mode yet thus we use
285 AllowSetForegroundWindow window right here. We might want to
286 do this anyway in case gpg is called on the console. */
287 gnupg_allow_set_foregound_window ((pid_t)strtoul (line+17, NULL, 10));
288 /* We do not pass errors to avoid breaking other code. */
290 else
291 log_debug ("ignoring gpg-agent inquiry `%s'\n", line);
293 return 0;
298 /* Release the card info structure INFO. */
299 void
300 agent_release_card_info (struct agent_card_info_s *info)
302 if (!info)
303 return;
305 xfree (info->serialno); info->serialno = NULL;
306 xfree (info->apptype); info->apptype = NULL;
307 xfree (info->disp_name); info->disp_name = NULL;
308 xfree (info->disp_lang); info->disp_lang = NULL;
309 xfree (info->pubkey_url); info->pubkey_url = NULL;
310 xfree (info->login_data); info->login_data = NULL;
311 info->cafpr1valid = info->cafpr2valid = info->cafpr3valid = 0;
312 info->fpr1valid = info->fpr2valid = info->fpr3valid = 0;
315 static gpg_error_t
316 learn_status_cb (void *opaque, const char *line)
318 struct agent_card_info_s *parm = opaque;
319 const char *keyword = line;
320 int keywordlen;
321 int i;
323 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
325 while (spacep (line))
326 line++;
328 if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
330 xfree (parm->serialno);
331 parm->serialno = store_serialno (line);
332 parm->is_v2 = (strlen (parm->serialno) >= 16
333 && xtoi_2 (parm->serialno+12) >= 2 );
335 else if (keywordlen == 7 && !memcmp (keyword, "APPTYPE", keywordlen))
337 xfree (parm->apptype);
338 parm->apptype = unescape_status_string (line);
340 else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen))
342 xfree (parm->disp_name);
343 parm->disp_name = unescape_status_string (line);
345 else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen))
347 xfree (parm->disp_lang);
348 parm->disp_lang = unescape_status_string (line);
350 else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen))
352 parm->disp_sex = *line == '1'? 1 : *line == '2' ? 2: 0;
354 else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen))
356 xfree (parm->pubkey_url);
357 parm->pubkey_url = unescape_status_string (line);
359 else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen))
361 xfree (parm->login_data);
362 parm->login_data = unescape_status_string (line);
364 else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen))
366 parm->sig_counter = strtoul (line, NULL, 0);
368 else if (keywordlen == 10 && !memcmp (keyword, "CHV-STATUS", keywordlen))
370 char *p, *buf;
372 buf = p = unescape_status_string (line);
373 if (buf)
375 while (spacep (p))
376 p++;
377 parm->chv1_cached = atoi (p);
378 while (*p && !spacep (p))
379 p++;
380 while (spacep (p))
381 p++;
382 for (i=0; *p && i < 3; i++)
384 parm->chvmaxlen[i] = atoi (p);
385 while (*p && !spacep (p))
386 p++;
387 while (spacep (p))
388 p++;
390 for (i=0; *p && i < 3; i++)
392 parm->chvretry[i] = atoi (p);
393 while (*p && !spacep (p))
394 p++;
395 while (spacep (p))
396 p++;
398 xfree (buf);
401 else if (keywordlen == 6 && !memcmp (keyword, "EXTCAP", keywordlen))
403 char *p, *p2, *buf;
404 int abool;
406 buf = p = unescape_status_string (line);
407 if (buf)
409 for (p = strtok (buf, " "); p; p = strtok (NULL, " "))
411 p2 = strchr (p, '=');
412 if (p2)
414 *p2++ = 0;
415 abool = (*p2 == '1');
416 if (!strcmp (p, "ki"))
417 parm->extcap.ki = abool;
418 else if (!strcmp (p, "aac"))
419 parm->extcap.aac = abool;
422 xfree (buf);
425 else if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
427 int no = atoi (line);
428 while (*line && !spacep (line))
429 line++;
430 while (spacep (line))
431 line++;
432 if (no == 1)
433 parm->fpr1valid = unhexify_fpr (line, parm->fpr1);
434 else if (no == 2)
435 parm->fpr2valid = unhexify_fpr (line, parm->fpr2);
436 else if (no == 3)
437 parm->fpr3valid = unhexify_fpr (line, parm->fpr3);
439 else if (keywordlen == 8 && !memcmp (keyword, "KEY-TIME", keywordlen))
441 int no = atoi (line);
442 while (* line && !spacep (line))
443 line++;
444 while (spacep (line))
445 line++;
446 if (no == 1)
447 parm->fpr1time = strtoul (line, NULL, 10);
448 else if (no == 2)
449 parm->fpr2time = strtoul (line, NULL, 10);
450 else if (no == 3)
451 parm->fpr3time = strtoul (line, NULL, 10);
453 else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen))
455 int no = atoi (line);
456 while (*line && !spacep (line))
457 line++;
458 while (spacep (line))
459 line++;
460 if (no == 1)
461 parm->cafpr1valid = unhexify_fpr (line, parm->cafpr1);
462 else if (no == 2)
463 parm->cafpr2valid = unhexify_fpr (line, parm->cafpr2);
464 else if (no == 3)
465 parm->cafpr3valid = unhexify_fpr (line, parm->cafpr3);
467 else if (keywordlen == 8 && !memcmp (keyword, "KEY-ATTR", keywordlen))
469 int keyno, algo, nbits;
471 sscanf (line, "%d %d %d", &keyno, &algo, &nbits);
472 keyno--;
473 if (keyno >= 0 && keyno < DIM (parm->key_attr))
475 parm->key_attr[keyno].algo = algo;
476 parm->key_attr[keyno].nbits = nbits;
480 return 0;
483 /* Call the agent to learn about a smartcard */
485 agent_learn (struct agent_card_info_s *info)
487 int rc;
489 rc = start_agent (1);
490 if (rc)
491 return rc;
493 /* Send the serialno command to initialize the connection. We don't
494 care about the data returned. If the card has already been
495 initialized, this is a very fast command. The main reason we
496 need to do this here is to handle a card removed case so that an
497 "l" command in --card-edit can be used to show ta newly inserted
498 card. We request the openpgp card because that is what we
499 expect. */
500 rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
501 NULL, NULL, NULL, NULL, NULL, NULL);
502 if (rc)
503 return rc;
506 memset (info, 0, sizeof *info);
507 rc = assuan_transact (agent_ctx, "SCD LEARN --force",
508 dummy_data_cb, NULL, default_inq_cb, NULL,
509 learn_status_cb, info);
510 /* Also try to get the key attributes. */
511 if (!rc)
512 agent_scd_getattr ("KEY-ATTR", info);
514 return rc;
517 /* Call the agent to retrieve a data object. This function returns
518 the data in the same structure as used by the learn command. It is
519 allowed to update such a structure using this commmand. */
521 agent_scd_getattr (const char *name, struct agent_card_info_s *info)
523 int rc;
524 char line[ASSUAN_LINELENGTH];
526 if (!*name)
527 return gpg_error (GPG_ERR_INV_VALUE);
529 /* We assume that NAME does not need escaping. */
530 if (12 + strlen (name) > DIM(line)-1)
531 return gpg_error (GPG_ERR_TOO_LARGE);
532 stpcpy (stpcpy (line, "SCD GETATTR "), name);
534 rc = start_agent (1);
535 if (rc)
536 return rc;
538 rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, NULL,
539 learn_status_cb, info);
541 return rc;
545 /* Send an setattr command to the SCdaemon. SERIALNO is not actually
546 used here but required by gpg 1.4's implementation of this code in
547 cardglue.c. */
549 agent_scd_setattr (const char *name,
550 const unsigned char *value, size_t valuelen,
551 const char *serialno)
553 int rc;
554 char line[ASSUAN_LINELENGTH];
555 char *p;
557 (void)serialno;
559 if (!*name || !valuelen)
560 return gpg_error (GPG_ERR_INV_VALUE);
562 /* We assume that NAME does not need escaping. */
563 if (12 + strlen (name) > DIM(line)-1)
564 return gpg_error (GPG_ERR_TOO_LARGE);
566 p = stpcpy (stpcpy (line, "SCD SETATTR "), name);
567 *p++ = ' ';
568 for (; valuelen; value++, valuelen--)
570 if (p >= line + DIM(line)-5 )
571 return gpg_error (GPG_ERR_TOO_LARGE);
572 if (*value < ' ' || *value == '+' || *value == '%')
574 sprintf (p, "%%%02X", *value);
575 p += 3;
577 else if (*value == ' ')
578 *p++ = '+';
579 else
580 *p++ = *value;
582 *p = 0;
584 rc = start_agent (1);
585 if (!rc)
587 rc = assuan_transact (agent_ctx, line, NULL, NULL,
588 default_inq_cb, NULL, NULL, NULL);
591 status_sc_op_failure (rc);
592 return rc;
597 /* Handle a CERTDATA inquiry. Note, we only send the data,
598 assuan_transact takes care of flushing and writing the END
599 command. */
600 static gpg_error_t
601 inq_writecert_parms (void *opaque, const char *line)
603 int rc;
604 struct writecert_parm_s *parm = opaque;
606 if (!strncmp (line, "CERTDATA", 8) && (line[8]==' '||!line[8]))
608 rc = assuan_send_data (parm->ctx, parm->certdata, parm->certdatalen);
610 else
611 rc = default_inq_cb (opaque, line);
613 return rc;
617 /* Send a WRITECERT command to the SCdaemon. */
618 int
619 agent_scd_writecert (const char *certidstr,
620 const unsigned char *certdata, size_t certdatalen)
622 int rc;
623 char line[ASSUAN_LINELENGTH];
624 struct writecert_parm_s parms;
626 rc = start_agent (1);
627 if (rc)
628 return rc;
630 memset (&parms, 0, sizeof parms);
632 snprintf (line, DIM(line)-1, "SCD WRITECERT %s", certidstr);
633 line[DIM(line)-1] = 0;
634 parms.ctx = agent_ctx;
635 parms.certdata = certdata;
636 parms.certdatalen = certdatalen;
638 rc = assuan_transact (agent_ctx, line, NULL, NULL,
639 inq_writecert_parms, &parms, NULL, NULL);
641 return rc;
646 /* Handle a KEYDATA inquiry. Note, we only send the data,
647 assuan_transact takes care of flushing and writing the end */
648 static gpg_error_t
649 inq_writekey_parms (void *opaque, const char *line)
651 int rc;
652 struct writekey_parm_s *parm = opaque;
654 if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7]))
656 rc = assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen);
658 else
659 rc = default_inq_cb (opaque, line);
661 return rc;
665 /* Send a WRITEKEY command to the SCdaemon. */
666 int
667 agent_scd_writekey (int keyno, const char *serialno,
668 const unsigned char *keydata, size_t keydatalen)
670 int rc;
671 char line[ASSUAN_LINELENGTH];
672 struct writekey_parm_s parms;
674 (void)serialno;
676 rc = start_agent (1);
677 if (rc)
678 return rc;
680 memset (&parms, 0, sizeof parms);
682 snprintf (line, DIM(line)-1, "SCD WRITEKEY --force OPENPGP.%d", keyno);
683 line[DIM(line)-1] = 0;
684 parms.ctx = agent_ctx;
685 parms.keydata = keydata;
686 parms.keydatalen = keydatalen;
688 rc = assuan_transact (agent_ctx, line, NULL, NULL,
689 inq_writekey_parms, &parms, NULL, NULL);
691 status_sc_op_failure (rc);
692 return rc;
697 /* Status callback for the SCD GENKEY command. */
698 static gpg_error_t
699 scd_genkey_cb (void *opaque, const char *line)
701 struct agent_card_genkey_s *parm = opaque;
702 const char *keyword = line;
703 int keywordlen;
704 gpg_error_t rc;
706 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
708 while (spacep (line))
709 line++;
711 if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
713 parm->fprvalid = unhexify_fpr (line, parm->fpr);
715 else if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen))
717 gcry_mpi_t a;
718 const char *name = line;
720 while (*line && !spacep (line))
721 line++;
722 while (spacep (line))
723 line++;
725 rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL);
726 if (rc)
727 log_error ("error parsing received key data: %s\n", gpg_strerror (rc));
728 else if (*name == 'n' && spacep (name+1))
729 parm->n = a;
730 else if (*name == 'e' && spacep (name+1))
731 parm->e = a;
732 else
734 log_info ("unknown parameter name in received key data\n");
735 gcry_mpi_release (a);
738 else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
740 parm->created_at = (u32)strtoul (line, NULL, 10);
742 else if (keywordlen == 8 && !memcmp (keyword, "PROGRESS", keywordlen))
744 write_status_text (STATUS_PROGRESS, line);
747 return 0;
750 /* Send a GENKEY command to the SCdaemon. SERIALNO is not used in
751 this implementation. If CREATEDATE has been given, it will be
752 passed to SCDAEMON so that the key can be created with this
753 timestamp; note the user needs to use the returned timestamp as old
754 versions of scddaemon don't support this option. */
756 agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
757 const char *serialno, u32 createtime)
759 int rc;
760 char line[ASSUAN_LINELENGTH];
761 gnupg_isotime_t tbuf;
763 (void)serialno;
765 rc = start_agent (1);
766 if (rc)
767 return rc;
769 if (createtime)
770 epoch2isotime (tbuf, createtime);
771 else
772 *tbuf = 0;
774 memset (info, 0, sizeof *info);
775 snprintf (line, DIM(line)-1, "SCD GENKEY %s%s %s %d",
776 *tbuf? "--timestamp=":"", tbuf,
777 force? "--force":"",
778 keyno);
779 line[DIM(line)-1] = 0;
781 memset (info, 0, sizeof *info);
782 rc = assuan_transact (agent_ctx, line,
783 NULL, NULL, default_inq_cb, NULL,
784 scd_genkey_cb, info);
786 status_sc_op_failure (rc);
787 return rc;
793 /* Issue an SCD SERIALNO openpgp command and if SERIALNO is not NULL
794 ask the user to insert the requested card. */
795 gpg_error_t
796 select_openpgp (const char *serialno)
798 gpg_error_t err;
800 /* Send the serialno command to initialize the connection. Without
801 a given S/N we don't care about the data returned. If the card
802 has already been initialized, this is a very fast command. We
803 request the openpgp card because that is what we expect.
805 Note that an opt.limit_card_insert_tries of 1 means: No tries at
806 all whereas 0 means do not limit the number of tries. Due to the
807 sue of a pinentry prompt with a cancel option we use it here in a
808 boolean sense. */
809 if (!serialno || opt.limit_card_insert_tries == 1)
810 err = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
811 NULL, NULL, NULL, NULL, NULL, NULL);
812 else
814 char *this_sn = NULL;
815 char *desc;
816 int ask;
817 char *want_sn;
818 char *p;
820 want_sn = xtrystrdup (serialno);
821 if (!want_sn)
822 return gpg_error_from_syserror ();
823 p = strchr (want_sn, '/');
824 if (p)
825 *p = 0;
829 ask = 0;
830 err = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
831 NULL, NULL, NULL, NULL,
832 get_serialno_cb, &this_sn);
833 if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT)
834 ask = 1;
835 else if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED)
836 ask = 2;
837 else if (err)
839 else if (this_sn)
841 if (strcmp (want_sn, this_sn))
842 ask = 2;
845 xfree (this_sn);
846 this_sn = NULL;
848 if (ask)
850 char *formatted = NULL;
851 char *ocodeset = i18n_switchto_utf8 ();
853 if (!strncmp (want_sn, "D27600012401", 12)
854 && strlen (want_sn) == 32 )
855 formatted = xtryasprintf ("(%.4s) %.8s",
856 want_sn + 16, want_sn + 20);
858 err = 0;
859 desc = xtryasprintf
860 ("%s:\n\n"
861 " \"%s\"",
862 ask == 1
863 ? _("Please insert the card with serial number")
864 : _("Please remove the current card and "
865 "insert the one with serial number"),
866 formatted? formatted : want_sn);
867 if (!desc)
868 err = gpg_error_from_syserror ();
869 xfree (formatted);
870 i18n_switchback (ocodeset);
871 if (!err)
872 err = gpg_agent_get_confirmation (desc);
873 xfree (desc);
876 while (ask && !err);
877 xfree (want_sn);
880 return err;
885 static gpg_error_t
886 membuf_data_cb (void *opaque, const void *buffer, size_t length)
888 membuf_t *data = opaque;
890 if (buffer)
891 put_membuf (data, buffer, length);
892 return 0;
895 /* Send a sign command to the scdaemon via gpg-agent's pass thru
896 mechanism. */
898 agent_scd_pksign (const char *serialno, int hashalgo,
899 const unsigned char *indata, size_t indatalen,
900 unsigned char **r_buf, size_t *r_buflen)
902 int rc, i;
903 char *p, line[ASSUAN_LINELENGTH];
904 membuf_t data;
905 size_t len;
907 /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */
909 *r_buf = NULL;
910 *r_buflen = 0;
912 rc = start_agent (1);
913 if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT
914 || gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED)
915 rc = 0; /* We check later. */
916 if (rc)
917 return rc;
919 if (indatalen*2 + 50 > DIM(line))
920 return gpg_error (GPG_ERR_GENERAL);
922 rc = select_openpgp (serialno);
923 if (rc)
924 return rc;
926 sprintf (line, "SCD SETDATA ");
927 p = line + strlen (line);
928 for (i=0; i < indatalen ; i++, p += 2 )
929 sprintf (p, "%02X", indata[i]);
930 rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
931 if (rc)
932 return rc;
934 init_membuf (&data, 1024);
935 #if 0
936 if (!hashalgo) /* Temporary test hack. */
937 snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno);
938 else
939 #endif
940 snprintf (line, DIM(line)-1, "SCD PKSIGN %s%s",
941 hashalgo == GCRY_MD_RMD160? "--hash=rmd160 " : "",
942 serialno);
943 line[DIM(line)-1] = 0;
944 rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data,
945 default_inq_cb, NULL, NULL, NULL);
946 if (rc)
948 xfree (get_membuf (&data, &len));
950 else
951 *r_buf = get_membuf (&data, r_buflen);
953 status_sc_op_failure (rc);
954 return rc;
958 /* Decrypt INDATA of length INDATALEN using the card identified by
959 SERIALNO. Return the plaintext in a nwly allocated buffer stored
960 at the address of R_BUF.
962 Note, we currently support only RSA or more exactly algorithms
963 taking one input data element. */
965 agent_scd_pkdecrypt (const char *serialno,
966 const unsigned char *indata, size_t indatalen,
967 unsigned char **r_buf, size_t *r_buflen)
969 int rc, i;
970 char *p, line[ASSUAN_LINELENGTH];
971 membuf_t data;
972 size_t len;
974 *r_buf = NULL;
975 rc = start_agent (1);
976 if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT
977 || gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED)
978 rc = 0; /* We check later. */
979 if (rc)
980 return rc;
982 /* FIXME: use secure memory where appropriate */
983 if (indatalen*2 + 50 > DIM(line))
984 return gpg_error (GPG_ERR_GENERAL);
986 rc = select_openpgp (serialno);
987 if (rc)
988 return rc;
990 sprintf (line, "SCD SETDATA ");
991 p = line + strlen (line);
992 for (i=0; i < indatalen ; i++, p += 2 )
993 sprintf (p, "%02X", indata[i]);
994 rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
995 if (rc)
996 return rc;
998 init_membuf (&data, 1024);
999 snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno);
1000 line[DIM(line)-1] = 0;
1001 rc = assuan_transact (agent_ctx, line,
1002 membuf_data_cb, &data,
1003 default_inq_cb, NULL, NULL, NULL);
1004 if (rc)
1006 xfree (get_membuf (&data, &len));
1008 else
1010 *r_buf = get_membuf (&data, r_buflen);
1011 if (!*r_buf)
1012 rc = gpg_error (GPG_ERR_ENOMEM);
1015 status_sc_op_failure (rc);
1016 return rc;
1021 /* Send a READCERT command to the SCdaemon. */
1022 int
1023 agent_scd_readcert (const char *certidstr,
1024 void **r_buf, size_t *r_buflen)
1026 int rc;
1027 char line[ASSUAN_LINELENGTH];
1028 membuf_t data;
1029 size_t len;
1031 *r_buf = NULL;
1032 rc = start_agent (1);
1033 if (rc)
1034 return rc;
1036 init_membuf (&data, 2048);
1038 snprintf (line, DIM(line)-1, "SCD READCERT %s", certidstr);
1039 line[DIM(line)-1] = 0;
1040 rc = assuan_transact (agent_ctx, line,
1041 membuf_data_cb, &data,
1042 default_inq_cb, NULL, NULL, NULL);
1043 if (rc)
1045 xfree (get_membuf (&data, &len));
1046 return rc;
1048 *r_buf = get_membuf (&data, r_buflen);
1049 if (!*r_buf)
1050 return gpg_error (GPG_ERR_ENOMEM);
1052 return 0;
1057 /* Change the PIN of an OpenPGP card or reset the retry counter.
1058 CHVNO 1: Change the PIN
1059 2: For v1 cards: Same as 1.
1060 For v2 cards: Reset the PIN using the Reset Code.
1061 3: Change the admin PIN
1062 101: Set a new PIN and reset the retry counter
1063 102: For v1 cars: Same as 101.
1064 For v2 cards: Set a new Reset Code.
1065 SERIALNO is not used.
1068 agent_scd_change_pin (int chvno, const char *serialno)
1070 int rc;
1071 char line[ASSUAN_LINELENGTH];
1072 const char *reset = "";
1074 (void)serialno;
1076 if (chvno >= 100)
1077 reset = "--reset";
1078 chvno %= 100;
1080 rc = start_agent (1);
1081 if (rc)
1082 return rc;
1084 snprintf (line, DIM(line)-1, "SCD PASSWD %s %d", reset, chvno);
1085 line[DIM(line)-1] = 0;
1086 rc = assuan_transact (agent_ctx, line, NULL, NULL,
1087 default_inq_cb, NULL, NULL, NULL);
1088 status_sc_op_failure (rc);
1089 return rc;
1093 /* Perform a CHECKPIN operation. SERIALNO should be the serial
1094 number of the card - optionally followed by the fingerprint;
1095 however the fingerprint is ignored here. */
1097 agent_scd_checkpin (const char *serialno)
1099 int rc;
1100 char line[ASSUAN_LINELENGTH];
1102 rc = start_agent (1);
1103 if (rc)
1104 return rc;
1106 snprintf (line, DIM(line)-1, "SCD CHECKPIN %s", serialno);
1107 line[DIM(line)-1] = 0;
1108 rc = assuan_transact (agent_ctx, line,
1109 NULL, NULL,
1110 default_inq_cb, NULL, NULL, NULL);
1111 status_sc_op_failure (rc);
1112 return rc;
1116 /* Dummy function, only used by the gpg 1.4 implementation. */
1117 void
1118 agent_clear_pin_cache (const char *sn)
1120 (void)sn;
1126 /* Note: All strings shall be UTF-8. On success the caller needs to
1127 free the string stored at R_PASSPHRASE. On error NULL will be
1128 stored at R_PASSPHRASE and an appropriate fpf error code
1129 returned. */
1130 gpg_error_t
1131 agent_get_passphrase (const char *cache_id,
1132 const char *err_msg,
1133 const char *prompt,
1134 const char *desc_msg,
1135 int repeat,
1136 int check,
1137 char **r_passphrase)
1139 int rc;
1140 char line[ASSUAN_LINELENGTH];
1141 char *arg1 = NULL;
1142 char *arg2 = NULL;
1143 char *arg3 = NULL;
1144 char *arg4 = NULL;
1145 membuf_t data;
1147 *r_passphrase = NULL;
1149 rc = start_agent (0);
1150 if (rc)
1151 return rc;
1153 /* Check that the gpg-agent understands the repeat option. */
1154 if (assuan_transact (agent_ctx,
1155 "GETINFO cmd_has_option GET_PASSPHRASE repeat",
1156 NULL, NULL, NULL, NULL, NULL, NULL))
1157 return gpg_error (GPG_ERR_NOT_SUPPORTED);
1159 if (cache_id && *cache_id)
1160 if (!(arg1 = percent_plus_escape (cache_id)))
1161 goto no_mem;
1162 if (err_msg && *err_msg)
1163 if (!(arg2 = percent_plus_escape (err_msg)))
1164 goto no_mem;
1165 if (prompt && *prompt)
1166 if (!(arg3 = percent_plus_escape (prompt)))
1167 goto no_mem;
1168 if (desc_msg && *desc_msg)
1169 if (!(arg4 = percent_plus_escape (desc_msg)))
1170 goto no_mem;
1172 snprintf (line, DIM(line)-1,
1173 "GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s",
1174 repeat,
1175 check? " --check --qualitybar":"",
1176 arg1? arg1:"X",
1177 arg2? arg2:"X",
1178 arg3? arg3:"X",
1179 arg4? arg4:"X");
1180 line[DIM(line)-1] = 0;
1181 xfree (arg1);
1182 xfree (arg2);
1183 xfree (arg3);
1184 xfree (arg4);
1186 init_membuf_secure (&data, 64);
1187 rc = assuan_transact (agent_ctx, line,
1188 membuf_data_cb, &data,
1189 default_inq_cb, NULL, NULL, NULL);
1191 if (rc)
1192 xfree (get_membuf (&data, NULL));
1193 else
1195 put_membuf (&data, "", 1);
1196 *r_passphrase = get_membuf (&data, NULL);
1197 if (!*r_passphrase)
1198 rc = gpg_error_from_syserror ();
1200 return rc;
1201 no_mem:
1202 rc = gpg_error_from_syserror ();
1203 xfree (arg1);
1204 xfree (arg2);
1205 xfree (arg3);
1206 xfree (arg4);
1207 return rc;
1211 gpg_error_t
1212 agent_clear_passphrase (const char *cache_id)
1214 int rc;
1215 char line[ASSUAN_LINELENGTH];
1217 if (!cache_id || !*cache_id)
1218 return 0;
1220 rc = start_agent (0);
1221 if (rc)
1222 return rc;
1224 snprintf (line, DIM(line)-1, "CLEAR_PASSPHRASE %s", cache_id);
1225 line[DIM(line)-1] = 0;
1226 return assuan_transact (agent_ctx, line, NULL, NULL,
1227 default_inq_cb, NULL, NULL, NULL);
1231 /* Ask the agent to pop up a confirmation dialog with the text DESC
1232 and an okay and cancel button. */
1233 gpg_error_t
1234 gpg_agent_get_confirmation (const char *desc)
1236 int rc;
1237 char *tmp;
1238 char line[ASSUAN_LINELENGTH];
1240 rc = start_agent (0);
1241 if (rc)
1242 return rc;
1244 tmp = percent_plus_escape (desc);
1245 if (!tmp)
1246 return gpg_error_from_syserror ();
1247 snprintf (line, DIM(line)-1, "GET_CONFIRMATION %s", tmp);
1248 line[DIM(line)-1] = 0;
1249 xfree (tmp);
1251 rc = assuan_transact (agent_ctx, line, NULL, NULL,
1252 default_inq_cb, NULL, NULL, NULL);
1253 return rc;