1 /* call-agent.c - Divert GPG operations to the agent.
2 * Copyright (C) 2001, 2002, 2003, 2006, 2007,
3 * 2008 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"
47 static assuan_context_t agent_ctx
= NULL
;
52 const char *ciphertext
;
56 struct writecert_parm_s
59 const unsigned char *certdata
;
63 struct writekey_parm_s
66 const unsigned char *keydata
;
79 /* Try to connect to the agent via socket or fork it off and work by
80 pipes. Handle the server's initial greeting */
87 return 0; /* Fixme: We need a context for each thread or serialize
88 the access to the agent. */
90 rc
= start_new_gpg_agent (&agent_ctx
,
91 GPG_ERR_SOURCE_DEFAULT
,
94 opt
.display
, opt
.ttyname
, opt
.ttytype
,
95 opt
.lc_ctype
, opt
.lc_messages
,
96 opt
.xauthority
, opt
.pinentry_user_data
,
97 opt
.verbose
, DBG_ASSUAN
,
101 /* Tell the agent that we support Pinentry notifications. No
102 error checking so that it will work also with older
104 assuan_transact (agent_ctx
, "OPTION allow-pinentry-notify",
105 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
112 /* Return a new malloced string by unescaping the string S. Escaping
113 is percent escaping and '+'/space mapping. A binary nul will
114 silently be replaced by a 0xFF. Function returns NULL to indicate
115 an out of memory status. */
117 unescape_status_string (const unsigned char *s
)
119 return percent_plus_unescape (s
, 0xff);
123 /* Take a 20 byte hexencoded string and put it into the the provided
124 20 byte buffer FPR in binary format. */
126 unhexify_fpr (const char *hexstr
, unsigned char *fpr
)
131 for (s
=hexstr
, n
=0; hexdigitp (s
); s
++, n
++)
134 return 0; /* no fingerprint (invalid or wrong length). */
136 for (s
=hexstr
, n
=0; *s
; s
+= 2, n
++)
141 /* Take the serial number from LINE and return it verbatim in a newly
142 allocated string. We make sure that only hex characters are
145 store_serialno (const char *line
)
150 for (s
=line
; hexdigitp (s
); s
++)
152 p
= xtrymalloc (s
+ 1 - line
);
155 memcpy (p
, line
, s
-line
);
163 /* This is a dummy data line callback. */
165 dummy_data_cb (void *opaque
, const void *buffer
, size_t length
)
174 /* This is the default inquiry callback. It mainly handles the
175 Pinentry notifications. */
177 default_inq_cb (void *opaque
, const char *line
)
181 if (!strncmp (line
, "PINENTRY_LAUNCHED", 17) && (line
[17]==' '||!line
[17]))
183 /* There is no working server mode yet thus we use
184 AllowSetForegroundWindow window right here. We might want to
185 do this anyway in case gpg is called on the console. */
186 gnupg_allow_set_foregound_window ((pid_t
)strtoul (line
+17, NULL
, 10));
187 /* We do not pass errors to avoid breaking other code. */
190 log_debug ("ignoring gpg-agent inquiry `%s'\n", line
);
197 /* Release the card info structure INFO. */
199 agent_release_card_info (struct agent_card_info_s
*info
)
204 xfree (info
->serialno
); info
->serialno
= NULL
;
205 xfree (info
->apptype
); info
->apptype
= NULL
;
206 xfree (info
->disp_name
); info
->disp_name
= NULL
;
207 xfree (info
->disp_lang
); info
->disp_lang
= NULL
;
208 xfree (info
->pubkey_url
); info
->pubkey_url
= NULL
;
209 xfree (info
->login_data
); info
->login_data
= NULL
;
210 info
->cafpr1valid
= info
->cafpr2valid
= info
->cafpr3valid
= 0;
211 info
->fpr1valid
= info
->fpr2valid
= info
->fpr3valid
= 0;
215 learn_status_cb (void *opaque
, const char *line
)
217 struct agent_card_info_s
*parm
= opaque
;
218 const char *keyword
= line
;
222 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
224 while (spacep (line
))
227 if (keywordlen
== 8 && !memcmp (keyword
, "SERIALNO", keywordlen
))
229 xfree (parm
->serialno
);
230 parm
->serialno
= store_serialno (line
);
231 parm
->is_v2
= (strlen (parm
->serialno
) >= 16
232 && xtoi_2 (parm
->serialno
+12) >= 2 );
234 else if (keywordlen
== 7 && !memcmp (keyword
, "APPTYPE", keywordlen
))
236 xfree (parm
->apptype
);
237 parm
->apptype
= unescape_status_string (line
);
239 else if (keywordlen
== 9 && !memcmp (keyword
, "DISP-NAME", keywordlen
))
241 xfree (parm
->disp_name
);
242 parm
->disp_name
= unescape_status_string (line
);
244 else if (keywordlen
== 9 && !memcmp (keyword
, "DISP-LANG", keywordlen
))
246 xfree (parm
->disp_lang
);
247 parm
->disp_lang
= unescape_status_string (line
);
249 else if (keywordlen
== 8 && !memcmp (keyword
, "DISP-SEX", keywordlen
))
251 parm
->disp_sex
= *line
== '1'? 1 : *line
== '2' ? 2: 0;
253 else if (keywordlen
== 10 && !memcmp (keyword
, "PUBKEY-URL", keywordlen
))
255 xfree (parm
->pubkey_url
);
256 parm
->pubkey_url
= unescape_status_string (line
);
258 else if (keywordlen
== 10 && !memcmp (keyword
, "LOGIN-DATA", keywordlen
))
260 xfree (parm
->login_data
);
261 parm
->login_data
= unescape_status_string (line
);
263 else if (keywordlen
== 11 && !memcmp (keyword
, "SIG-COUNTER", keywordlen
))
265 parm
->sig_counter
= strtoul (line
, NULL
, 0);
267 else if (keywordlen
== 10 && !memcmp (keyword
, "CHV-STATUS", keywordlen
))
271 buf
= p
= unescape_status_string (line
);
276 parm
->chv1_cached
= atoi (p
);
277 while (*p
&& !spacep (p
))
281 for (i
=0; *p
&& i
< 3; i
++)
283 parm
->chvmaxlen
[i
] = atoi (p
);
284 while (*p
&& !spacep (p
))
289 for (i
=0; *p
&& i
< 3; i
++)
291 parm
->chvretry
[i
] = atoi (p
);
292 while (*p
&& !spacep (p
))
300 else if (keywordlen
== 7 && !memcmp (keyword
, "KEY-FPR", keywordlen
))
302 int no
= atoi (line
);
303 while (*line
&& !spacep (line
))
305 while (spacep (line
))
308 parm
->fpr1valid
= unhexify_fpr (line
, parm
->fpr1
);
310 parm
->fpr2valid
= unhexify_fpr (line
, parm
->fpr2
);
312 parm
->fpr3valid
= unhexify_fpr (line
, parm
->fpr3
);
314 else if (keywordlen
== 6 && !memcmp (keyword
, "CA-FPR", keywordlen
))
316 int no
= atoi (line
);
317 while (*line
&& !spacep (line
))
319 while (spacep (line
))
322 parm
->cafpr1valid
= unhexify_fpr (line
, parm
->cafpr1
);
324 parm
->cafpr2valid
= unhexify_fpr (line
, parm
->cafpr2
);
326 parm
->cafpr3valid
= unhexify_fpr (line
, parm
->cafpr3
);
332 /* Call the agent to learn about a smartcard */
334 agent_learn (struct agent_card_info_s
*info
)
342 memset (info
, 0, sizeof *info
);
343 rc
= assuan_transact (agent_ctx
, "LEARN --send",
344 dummy_data_cb
, NULL
, default_inq_cb
, NULL
,
345 learn_status_cb
, info
);
350 /* Call the agent to retrieve a data object. This function returns
351 the data in the same structure as used by the learn command. It is
352 allowed to update such a structure using this commmand. */
354 agent_scd_getattr (const char *name
, struct agent_card_info_s
*info
)
357 char line
[ASSUAN_LINELENGTH
];
360 return gpg_error (GPG_ERR_INV_VALUE
);
362 /* We assume that NAME does not need escaping. */
363 if (12 + strlen (name
) > DIM(line
)-1)
364 return gpg_error (GPG_ERR_TOO_LARGE
);
365 stpcpy (stpcpy (line
, "SCD GETATTR "), name
);
371 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, default_inq_cb
, NULL
,
372 learn_status_cb
, info
);
378 /* Send an setattr command to the SCdaemon. SERIALNO is not actually
379 used here but required by gpg 1.4's implementation of this code in
382 agent_scd_setattr (const char *name
,
383 const unsigned char *value
, size_t valuelen
,
384 const char *serialno
)
387 char line
[ASSUAN_LINELENGTH
];
392 if (!*name
|| !valuelen
)
393 return gpg_error (GPG_ERR_INV_VALUE
);
395 /* We assume that NAME does not need escaping. */
396 if (12 + strlen (name
) > DIM(line
)-1)
397 return gpg_error (GPG_ERR_TOO_LARGE
);
399 p
= stpcpy (stpcpy (line
, "SCD SETATTR "), name
);
401 for (; valuelen
; value
++, valuelen
--)
403 if (p
>= line
+ DIM(line
)-5 )
404 return gpg_error (GPG_ERR_TOO_LARGE
);
405 if (*value
< ' ' || *value
== '+' || *value
== '%')
407 sprintf (p
, "%%%02X", *value
);
410 else if (*value
== ' ')
421 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
422 default_inq_cb
, NULL
, NULL
, NULL
);
428 /* Handle a CERTDATA inquiry. Note, we only send the data,
429 assuan_transact takes care of flushing and writing the END
432 inq_writecert_parms (void *opaque
, const char *line
)
435 struct writecert_parm_s
*parm
= opaque
;
437 if (!strncmp (line
, "CERTDATA", 8) && (line
[8]==' '||!line
[8]))
439 rc
= assuan_send_data (parm
->ctx
, parm
->certdata
, parm
->certdatalen
);
442 rc
= default_inq_cb (opaque
, line
);
448 /* Send a WRITECERT command to the SCdaemon. */
450 agent_scd_writecert (const char *certidstr
,
451 const unsigned char *certdata
, size_t certdatalen
)
454 char line
[ASSUAN_LINELENGTH
];
455 struct writecert_parm_s parms
;
461 memset (&parms
, 0, sizeof parms
);
463 snprintf (line
, DIM(line
)-1, "SCD WRITECERT %s", certidstr
);
464 line
[DIM(line
)-1] = 0;
465 parms
.ctx
= agent_ctx
;
466 parms
.certdata
= certdata
;
467 parms
.certdatalen
= certdatalen
;
469 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
470 inq_writecert_parms
, &parms
, NULL
, NULL
);
478 /* Handle a KEYDATA inquiry. Note, we only send the data,
479 assuan_transact takes care of flushing and writing the end */
481 inq_writekey_parms (void *opaque
, const char *line
)
484 struct writekey_parm_s
*parm
= opaque
;
486 if (!strncmp (line
, "KEYDATA", 7) && (line
[7]==' '||!line
[7]))
488 rc
= assuan_send_data (parm
->ctx
, parm
->keydata
, parm
->keydatalen
);
491 rc
= default_inq_cb (opaque
, line
);
497 /* Send a WRITEKEY command to the SCdaemon. */
499 agent_scd_writekey (int keyno
, const char *serialno
,
500 const unsigned char *keydata
, size_t keydatalen
)
503 char line
[ASSUAN_LINELENGTH
];
504 struct writekey_parm_s parms
;
512 memset (&parms
, 0, sizeof parms
);
514 snprintf (line
, DIM(line
)-1, "SCD WRITEKEY --force OPENPGP.%d", keyno
);
515 line
[DIM(line
)-1] = 0;
516 parms
.ctx
= agent_ctx
;
517 parms
.keydata
= keydata
;
518 parms
.keydatalen
= keydatalen
;
520 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
521 inq_writekey_parms
, &parms
, NULL
, NULL
);
529 /* Status callback for the SCD GENKEY command. */
531 scd_genkey_cb (void *opaque
, const char *line
)
533 struct agent_card_genkey_s
*parm
= opaque
;
534 const char *keyword
= line
;
538 log_debug ("got status line `%s'\n", line
);
539 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
541 while (spacep (line
))
544 if (keywordlen
== 7 && !memcmp (keyword
, "KEY-FPR", keywordlen
))
546 parm
->fprvalid
= unhexify_fpr (line
, parm
->fpr
);
548 if (keywordlen
== 8 && !memcmp (keyword
, "KEY-DATA", keywordlen
))
551 const char *name
= line
;
553 while (*line
&& !spacep (line
))
555 while (spacep (line
))
558 rc
= gcry_mpi_scan (&a
, GCRYMPI_FMT_HEX
, line
, 0, NULL
);
560 log_error ("error parsing received key data: %s\n", gpg_strerror (rc
));
561 else if (*name
== 'n' && spacep (name
+1))
563 else if (*name
== 'e' && spacep (name
+1))
567 log_info ("unknown parameter name in received key data\n");
568 gcry_mpi_release (a
);
571 else if (keywordlen
== 14 && !memcmp (keyword
,"KEY-CREATED-AT", keywordlen
))
573 parm
->created_at
= (u32
)strtoul (line
, NULL
, 10);
579 /* Send a GENKEY command to the SCdaemon. SERIALNO is not used in
580 this implementation. If CREATEDATE has been given, it will be
581 passed to SCDAEMON so that the key can be created with this
582 timestamp; note the user needs to use the returned timestamp as old
583 versions of scddaemon don't support this option. */
585 agent_scd_genkey (struct agent_card_genkey_s
*info
, int keyno
, int force
,
586 const char *serialno
, u32 createtime
)
589 char line
[ASSUAN_LINELENGTH
];
590 gnupg_isotime_t tbuf
;
599 epoch2isotime (tbuf
, createtime
);
603 memset (info
, 0, sizeof *info
);
604 snprintf (line
, DIM(line
)-1, "SCD GENKEY %s%s %s %d",
605 *tbuf
? "--timestamp=":"", tbuf
,
608 line
[DIM(line
)-1] = 0;
610 memset (info
, 0, sizeof *info
);
611 rc
= assuan_transact (agent_ctx
, line
,
612 NULL
, NULL
, default_inq_cb
, NULL
,
613 scd_genkey_cb
, info
);
620 membuf_data_cb (void *opaque
, const void *buffer
, size_t length
)
622 membuf_t
*data
= opaque
;
625 put_membuf (data
, buffer
, length
);
629 /* Send a sign command to the scdaemon via gpg-agent's pass thru
632 agent_scd_pksign (const char *serialno
, int hashalgo
,
633 const unsigned char *indata
, size_t indatalen
,
634 unsigned char **r_buf
, size_t *r_buflen
)
637 char *p
, line
[ASSUAN_LINELENGTH
];
641 /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */
650 if (indatalen
*2 + 50 > DIM(line
))
651 return gpg_error (GPG_ERR_GENERAL
);
653 /* Send the serialno command to initialize the connection. We don't
654 care about the data returned. If the card has already been
655 initialized, this is a very fast command. We request the openpgp
656 card because that is waht we expect. */
657 rc
= assuan_transact (agent_ctx
, "SCD SERIALNO openpgp",
658 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
662 sprintf (line
, "SCD SETDATA ");
663 p
= line
+ strlen (line
);
664 for (i
=0; i
< indatalen
; i
++, p
+= 2 )
665 sprintf (p
, "%02X", indata
[i
]);
666 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
670 init_membuf (&data
, 1024);
672 if (!hashalgo
) /* Temporary test hack. */
673 snprintf (line
, DIM(line
)-1, "SCD PKAUTH %s", serialno
);
676 snprintf (line
, DIM(line
)-1, "SCD PKSIGN %s%s",
677 hashalgo
== GCRY_MD_RMD160
? "--hash=rmd160 " : "",
679 line
[DIM(line
)-1] = 0;
680 rc
= assuan_transact (agent_ctx
, line
, membuf_data_cb
, &data
,
681 default_inq_cb
, NULL
, NULL
, NULL
);
684 xfree (get_membuf (&data
, &len
));
687 *r_buf
= get_membuf (&data
, r_buflen
);
693 /* Decrypt INDATA of length INDATALEN using the card identified by
694 SERIALNO. Return the plaintext in a nwly allocated buffer stored
695 at the address of R_BUF.
697 Note, we currently support only RSA or more exactly algorithms
698 taking one input data element. */
700 agent_scd_pkdecrypt (const char *serialno
,
701 const unsigned char *indata
, size_t indatalen
,
702 unsigned char **r_buf
, size_t *r_buflen
)
705 char *p
, line
[ASSUAN_LINELENGTH
];
714 /* FIXME: use secure memory where appropriate */
715 if (indatalen
*2 + 50 > DIM(line
))
716 return gpg_error (GPG_ERR_GENERAL
);
718 /* Send the serialno command to initialize the connection. We don't
719 care about the data returned. If the card has already been
720 initialized, this is a very fast command. We request the openpgp
721 card because that is waht we expect. */
722 rc
= assuan_transact (agent_ctx
, "SCD SERIALNO openpgp",
723 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
727 sprintf (line
, "SCD SETDATA ");
728 p
= line
+ strlen (line
);
729 for (i
=0; i
< indatalen
; i
++, p
+= 2 )
730 sprintf (p
, "%02X", indata
[i
]);
731 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
735 init_membuf (&data
, 1024);
736 snprintf (line
, DIM(line
)-1, "SCD PKDECRYPT %s", serialno
);
737 line
[DIM(line
)-1] = 0;
738 rc
= assuan_transact (agent_ctx
, line
,
739 membuf_data_cb
, &data
,
740 default_inq_cb
, NULL
, NULL
, NULL
);
743 xfree (get_membuf (&data
, &len
));
746 *r_buf
= get_membuf (&data
, r_buflen
);
748 return gpg_error (GPG_ERR_ENOMEM
);
754 /* Change the PIN of an OpenPGP card or reset the retry counter.
755 CHVNO 1: Change the PIN
756 2: For v1 cards: Same as 1.
757 For v2 cards: Reset the PIN using the Reset Code.
758 3: Change the admin PIN
759 101: Set a new PIN and reset the retry counter
760 102: For v1 cars: Same as 101.
761 For v2 cards: Set a new Reset Code.
762 SERIALNO is not used.
765 agent_scd_change_pin (int chvno
, const char *serialno
)
768 char line
[ASSUAN_LINELENGTH
];
769 const char *reset
= "";
781 snprintf (line
, DIM(line
)-1, "SCD PASSWD %s %d", reset
, chvno
);
782 line
[DIM(line
)-1] = 0;
783 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
784 default_inq_cb
, NULL
, NULL
, NULL
);
789 /* Perform a CHECKPIN operation. SERIALNO should be the serial
790 number of the card - optionally followed by the fingerprint;
791 however the fingerprint is ignored here. */
793 agent_scd_checkpin (const char *serialno
)
796 char line
[ASSUAN_LINELENGTH
];
802 snprintf (line
, DIM(line
)-1, "SCD CHECKPIN %s", serialno
);
803 line
[DIM(line
)-1] = 0;
804 return assuan_transact (agent_ctx
, line
,
806 default_inq_cb
, NULL
, NULL
, NULL
);
810 /* Dummy function, only used by the gpg 1.4 implementation. */
812 agent_clear_pin_cache (const char *sn
)
820 /* Note: All strings shall be UTF-8. On success the caller needs to
821 free the string stored at R_PASSPHRASE. On error NULL will be
822 stored at R_PASSPHRASE and an appropriate fpf error code
825 agent_get_passphrase (const char *cache_id
,
828 const char *desc_msg
,
833 char line
[ASSUAN_LINELENGTH
];
840 *r_passphrase
= NULL
;
846 /* Check that the gpg-agent understands the repeat option. */
847 if (assuan_transact (agent_ctx
,
848 "GETINFO cmd_has_option GET_PASSPHRASE repeat",
849 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
))
850 return gpg_error (GPG_ERR_NOT_SUPPORTED
);
852 if (cache_id
&& *cache_id
)
853 if (!(arg1
= percent_plus_escape (cache_id
)))
855 if (err_msg
&& *err_msg
)
856 if (!(arg2
= percent_plus_escape (err_msg
)))
858 if (prompt
&& *prompt
)
859 if (!(arg3
= percent_plus_escape (prompt
)))
861 if (desc_msg
&& *desc_msg
)
862 if (!(arg4
= percent_plus_escape (desc_msg
)))
865 snprintf (line
, DIM(line
)-1,
866 "GET_PASSPHRASE --data --repeat=%d -- %s %s %s %s",
872 line
[DIM(line
)-1] = 0;
878 init_membuf_secure (&data
, 64);
879 rc
= assuan_transact (agent_ctx
, line
,
880 membuf_data_cb
, &data
,
881 default_inq_cb
, NULL
, NULL
, NULL
);
884 xfree (get_membuf (&data
, NULL
));
887 put_membuf (&data
, "", 1);
888 *r_passphrase
= get_membuf (&data
, NULL
);
890 rc
= gpg_error_from_syserror ();
894 rc
= gpg_error_from_syserror ();
904 agent_clear_passphrase (const char *cache_id
)
907 char line
[ASSUAN_LINELENGTH
];
909 if (!cache_id
|| !*cache_id
)
916 snprintf (line
, DIM(line
)-1, "CLEAR_PASSPHRASE %s", cache_id
);
917 line
[DIM(line
)-1] = 0;
918 return assuan_transact (agent_ctx
, line
, NULL
, NULL
,
919 default_inq_cb
, NULL
, NULL
, NULL
);