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/>.
41 #include "call-agent.h"
48 static assuan_context_t agent_ctx
= NULL
;
49 static int did_early_card_test
;
54 const char *ciphertext
;
58 struct writecert_parm_s
61 const unsigned char *certdata
;
65 struct writekey_parm_s
68 const unsigned char *keydata
;
80 static int learn_status_cb (void *opaque
, const char *line
);
84 /* If RC is not 0, write an appropriate status message. */
86 status_sc_op_failure (int rc
)
88 switch (gpg_err_code (rc
))
92 case GPG_ERR_CANCELED
:
93 write_status_text (STATUS_SC_OP_FAILURE
, "1");
96 write_status_text (STATUS_SC_OP_FAILURE
, "2");
99 write_status (STATUS_SC_OP_FAILURE
);
107 /* Try to connect to the agent via socket or fork it off and work by
108 pipes. Handle the server's initial greeting */
110 start_agent (int for_card
)
114 /* Fixme: We need a context for each thread or serialize the access
120 rc
= start_new_gpg_agent (&agent_ctx
,
121 GPG_ERR_SOURCE_DEFAULT
,
124 opt
.lc_ctype
, opt
.lc_messages
,
126 opt
.verbose
, DBG_ASSUAN
,
130 /* Tell the agent that we support Pinentry notifications.
131 No error checking so that it will work also with older
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
);
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");
156 write_status_text (STATUS_CARDCTRL
, "4");
157 log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc
));
162 if (!rc
&& is_status_enabled () && info
.serialno
)
166 buf
= xasprintf ("3 %s", info
.serialno
);
167 write_status_text (STATUS_CARDCTRL
, buf
);
171 agent_release_card_info (&info
);
174 did_early_card_test
= 1;
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. */
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. */
196 unhexify_fpr (const char *hexstr
, unsigned char *fpr
)
201 for (s
=hexstr
, n
=0; hexdigitp (s
); s
++, n
++)
204 return 0; /* no fingerprint (invalid or wrong length). */
205 for (s
=hexstr
, n
=0; *s
; s
+= 2, n
++)
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
214 store_serialno (const char *line
)
219 for (s
=line
; hexdigitp (s
); s
++)
221 p
= xtrymalloc (s
+ 1 - line
);
224 memcpy (p
, line
, s
-line
);
232 /* This is a dummy data line callback. */
234 dummy_data_cb (void *opaque
, const void *buffer
, size_t length
)
242 /* A simple callback used to return the serialnumber of a card. */
244 get_serialno_cb (void *opaque
, const char *line
)
246 char **serialno
= opaque
;
247 const char *keyword
= line
;
251 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
253 while (spacep (line
))
256 if (keywordlen
== 8 && !memcmp (keyword
, "SERIALNO", keywordlen
))
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);
266 return out_of_core ();
267 memcpy (*serialno
, line
, n
);
275 /* This is the default inquiry callback. It mainly handles the
276 Pinentry notifications. */
278 default_inq_cb (void *opaque
, const char *line
)
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. */
291 log_debug ("ignoring gpg-agent inquiry `%s'\n", line
);
298 /* Release the card info structure INFO. */
300 agent_release_card_info (struct agent_card_info_s
*info
)
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;
316 learn_status_cb (void *opaque
, const char *line
)
318 struct agent_card_info_s
*parm
= opaque
;
319 const char *keyword
= line
;
323 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
325 while (spacep (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
))
372 buf
= p
= unescape_status_string (line
);
377 parm
->chv1_cached
= atoi (p
);
378 while (*p
&& !spacep (p
))
382 for (i
=0; *p
&& i
< 3; i
++)
384 parm
->chvmaxlen
[i
] = atoi (p
);
385 while (*p
&& !spacep (p
))
390 for (i
=0; *p
&& i
< 3; i
++)
392 parm
->chvretry
[i
] = atoi (p
);
393 while (*p
&& !spacep (p
))
401 else if (keywordlen
== 6 && !memcmp (keyword
, "EXTCAP", keywordlen
))
406 buf
= p
= unescape_status_string (line
);
409 for (p
= strtok (buf
, " "); p
; p
= strtok (NULL
, " "))
411 p2
= strchr (p
, '=');
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
;
425 else if (keywordlen
== 7 && !memcmp (keyword
, "KEY-FPR", keywordlen
))
427 int no
= atoi (line
);
428 while (*line
&& !spacep (line
))
430 while (spacep (line
))
433 parm
->fpr1valid
= unhexify_fpr (line
, parm
->fpr1
);
435 parm
->fpr2valid
= unhexify_fpr (line
, parm
->fpr2
);
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
))
444 while (spacep (line
))
447 parm
->fpr1time
= strtoul (line
, NULL
, 10);
449 parm
->fpr2time
= strtoul (line
, NULL
, 10);
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
))
458 while (spacep (line
))
461 parm
->cafpr1valid
= unhexify_fpr (line
, parm
->cafpr1
);
463 parm
->cafpr2valid
= unhexify_fpr (line
, parm
->cafpr2
);
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
);
473 if (keyno
>= 0 && keyno
< DIM (parm
->key_attr
))
475 parm
->key_attr
[keyno
].algo
= algo
;
476 parm
->key_attr
[keyno
].nbits
= nbits
;
483 /* Call the agent to learn about a smartcard */
485 agent_learn (struct agent_card_info_s
*info
)
489 rc
= start_agent (1);
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
500 rc
= assuan_transact (agent_ctx
, "SCD SERIALNO openpgp",
501 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
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. */
512 agent_scd_getattr ("KEY-ATTR", info
);
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
)
524 char line
[ASSUAN_LINELENGTH
];
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);
538 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, default_inq_cb
, NULL
,
539 learn_status_cb
, info
);
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
549 agent_scd_setattr (const char *name
,
550 const unsigned char *value
, size_t valuelen
,
551 const char *serialno
)
554 char line
[ASSUAN_LINELENGTH
];
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
);
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
);
577 else if (*value
== ' ')
584 rc
= start_agent (1);
587 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
588 default_inq_cb
, NULL
, NULL
, NULL
);
591 status_sc_op_failure (rc
);
597 /* Handle a CERTDATA inquiry. Note, we only send the data,
598 assuan_transact takes care of flushing and writing the END
601 inq_writecert_parms (void *opaque
, const char *line
)
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
);
611 rc
= default_inq_cb (opaque
, line
);
617 /* Send a WRITECERT command to the SCdaemon. */
619 agent_scd_writecert (const char *certidstr
,
620 const unsigned char *certdata
, size_t certdatalen
)
623 char line
[ASSUAN_LINELENGTH
];
624 struct writecert_parm_s parms
;
626 rc
= start_agent (1);
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
);
646 /* Handle a KEYDATA inquiry. Note, we only send the data,
647 assuan_transact takes care of flushing and writing the end */
649 inq_writekey_parms (void *opaque
, const char *line
)
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
);
659 rc
= default_inq_cb (opaque
, line
);
665 /* Send a WRITEKEY command to the SCdaemon. */
667 agent_scd_writekey (int keyno
, const char *serialno
,
668 const unsigned char *keydata
, size_t keydatalen
)
671 char line
[ASSUAN_LINELENGTH
];
672 struct writekey_parm_s parms
;
676 rc
= start_agent (1);
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
);
697 /* Status callback for the SCD GENKEY command. */
699 scd_genkey_cb (void *opaque
, const char *line
)
701 struct agent_card_genkey_s
*parm
= opaque
;
702 const char *keyword
= line
;
706 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
708 while (spacep (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
))
718 const char *name
= line
;
720 while (*line
&& !spacep (line
))
722 while (spacep (line
))
725 rc
= gcry_mpi_scan (&a
, GCRYMPI_FMT_HEX
, line
, 0, NULL
);
727 log_error ("error parsing received key data: %s\n", gpg_strerror (rc
));
728 else if (*name
== 'n' && spacep (name
+1))
730 else if (*name
== 'e' && spacep (name
+1))
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
);
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
)
760 char line
[ASSUAN_LINELENGTH
];
761 gnupg_isotime_t tbuf
;
765 rc
= start_agent (1);
770 epoch2isotime (tbuf
, createtime
);
774 memset (info
, 0, sizeof *info
);
775 snprintf (line
, DIM(line
)-1, "SCD GENKEY %s%s %s %d",
776 *tbuf
? "--timestamp=":"", tbuf
,
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
);
793 /* Issue an SCD SERIALNO openpgp command and if SERIALNO is not NULL
794 ask the user to insert the requested card. */
796 select_openpgp (const char *serialno
)
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
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
);
814 char *this_sn
= NULL
;
820 want_sn
= xtrystrdup (serialno
);
822 return gpg_error_from_syserror ();
823 p
= strchr (want_sn
, '/');
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
)
835 else if (gpg_err_code (err
) == GPG_ERR_NOT_SUPPORTED
)
841 if (strcmp (want_sn
, this_sn
))
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);
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
);
868 err
= gpg_error_from_syserror ();
870 i18n_switchback (ocodeset
);
872 err
= gpg_agent_get_confirmation (desc
);
886 membuf_data_cb (void *opaque
, const void *buffer
, size_t length
)
888 membuf_t
*data
= opaque
;
891 put_membuf (data
, buffer
, length
);
895 /* Send a sign command to the scdaemon via gpg-agent's pass thru
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
)
903 char *p
, line
[ASSUAN_LINELENGTH
];
907 /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */
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. */
919 if (indatalen
*2 + 50 > DIM(line
))
920 return gpg_error (GPG_ERR_GENERAL
);
922 rc
= select_openpgp (serialno
);
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
);
934 init_membuf (&data
, 1024);
936 if (!hashalgo
) /* Temporary test hack. */
937 snprintf (line
, DIM(line
)-1, "SCD PKAUTH %s", serialno
);
940 snprintf (line
, DIM(line
)-1, "SCD PKSIGN %s%s",
941 hashalgo
== GCRY_MD_RMD160
? "--hash=rmd160 " : "",
943 line
[DIM(line
)-1] = 0;
944 rc
= assuan_transact (agent_ctx
, line
, membuf_data_cb
, &data
,
945 default_inq_cb
, NULL
, NULL
, NULL
);
948 xfree (get_membuf (&data
, &len
));
951 *r_buf
= get_membuf (&data
, r_buflen
);
953 status_sc_op_failure (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
)
970 char *p
, line
[ASSUAN_LINELENGTH
];
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. */
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
);
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
);
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
);
1006 xfree (get_membuf (&data
, &len
));
1010 *r_buf
= get_membuf (&data
, r_buflen
);
1012 rc
= gpg_error (GPG_ERR_ENOMEM
);
1015 status_sc_op_failure (rc
);
1021 /* Send a READCERT command to the SCdaemon. */
1023 agent_scd_readcert (const char *certidstr
,
1024 void **r_buf
, size_t *r_buflen
)
1027 char line
[ASSUAN_LINELENGTH
];
1032 rc
= start_agent (1);
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
);
1045 xfree (get_membuf (&data
, &len
));
1048 *r_buf
= get_membuf (&data
, r_buflen
);
1050 return gpg_error (GPG_ERR_ENOMEM
);
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
)
1071 char line
[ASSUAN_LINELENGTH
];
1072 const char *reset
= "";
1080 rc
= start_agent (1);
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
);
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
)
1100 char line
[ASSUAN_LINELENGTH
];
1102 rc
= start_agent (1);
1106 snprintf (line
, DIM(line
)-1, "SCD CHECKPIN %s", serialno
);
1107 line
[DIM(line
)-1] = 0;
1108 rc
= assuan_transact (agent_ctx
, line
,
1110 default_inq_cb
, NULL
, NULL
, NULL
);
1111 status_sc_op_failure (rc
);
1116 /* Dummy function, only used by the gpg 1.4 implementation. */
1118 agent_clear_pin_cache (const char *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
1131 agent_get_passphrase (const char *cache_id
,
1132 const char *err_msg
,
1134 const char *desc_msg
,
1137 char **r_passphrase
)
1140 char line
[ASSUAN_LINELENGTH
];
1147 *r_passphrase
= NULL
;
1149 rc
= start_agent (0);
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
)))
1162 if (err_msg
&& *err_msg
)
1163 if (!(arg2
= percent_plus_escape (err_msg
)))
1165 if (prompt
&& *prompt
)
1166 if (!(arg3
= percent_plus_escape (prompt
)))
1168 if (desc_msg
&& *desc_msg
)
1169 if (!(arg4
= percent_plus_escape (desc_msg
)))
1172 snprintf (line
, DIM(line
)-1,
1173 "GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s",
1175 check
? " --check --qualitybar":"",
1180 line
[DIM(line
)-1] = 0;
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
);
1192 xfree (get_membuf (&data
, NULL
));
1195 put_membuf (&data
, "", 1);
1196 *r_passphrase
= get_membuf (&data
, NULL
);
1198 rc
= gpg_error_from_syserror ();
1202 rc
= gpg_error_from_syserror ();
1212 agent_clear_passphrase (const char *cache_id
)
1215 char line
[ASSUAN_LINELENGTH
];
1217 if (!cache_id
|| !*cache_id
)
1220 rc
= start_agent (0);
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. */
1234 gpg_agent_get_confirmation (const char *desc
)
1238 char line
[ASSUAN_LINELENGTH
];
1240 rc
= start_agent (0);
1244 tmp
= percent_plus_escape (desc
);
1246 return gpg_error_from_syserror ();
1247 snprintf (line
, DIM(line
)-1, "GET_CONFIRMATION %s", tmp
);
1248 line
[DIM(line
)-1] = 0;
1251 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
1252 default_inq_cb
, NULL
, NULL
, NULL
);