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
);
328 else if (keywordlen
== 8 && !memcmp (keyword
, "KEY-ATTR", keywordlen
))
330 int keyno
, algo
, nbits
;
332 sscanf (line
, "%d %d %d", &keyno
, &algo
, &nbits
);
334 if (keyno
>= 0 && keyno
< DIM (parm
->key_attr
))
336 parm
->key_attr
[keyno
].algo
= algo
;
337 parm
->key_attr
[keyno
].nbits
= nbits
;
344 /* Call the agent to learn about a smartcard */
346 agent_learn (struct agent_card_info_s
*info
)
354 memset (info
, 0, sizeof *info
);
355 rc
= assuan_transact (agent_ctx
, "LEARN --send",
356 dummy_data_cb
, NULL
, default_inq_cb
, NULL
,
357 learn_status_cb
, info
);
358 /* Also try to get the key attributes. */
360 agent_scd_getattr ("KEY-ATTR", info
);
365 /* Call the agent to retrieve a data object. This function returns
366 the data in the same structure as used by the learn command. It is
367 allowed to update such a structure using this commmand. */
369 agent_scd_getattr (const char *name
, struct agent_card_info_s
*info
)
372 char line
[ASSUAN_LINELENGTH
];
375 return gpg_error (GPG_ERR_INV_VALUE
);
377 /* We assume that NAME does not need escaping. */
378 if (12 + strlen (name
) > DIM(line
)-1)
379 return gpg_error (GPG_ERR_TOO_LARGE
);
380 stpcpy (stpcpy (line
, "SCD GETATTR "), name
);
386 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, default_inq_cb
, NULL
,
387 learn_status_cb
, info
);
393 /* Send an setattr command to the SCdaemon. SERIALNO is not actually
394 used here but required by gpg 1.4's implementation of this code in
397 agent_scd_setattr (const char *name
,
398 const unsigned char *value
, size_t valuelen
,
399 const char *serialno
)
402 char line
[ASSUAN_LINELENGTH
];
407 if (!*name
|| !valuelen
)
408 return gpg_error (GPG_ERR_INV_VALUE
);
410 /* We assume that NAME does not need escaping. */
411 if (12 + strlen (name
) > DIM(line
)-1)
412 return gpg_error (GPG_ERR_TOO_LARGE
);
414 p
= stpcpy (stpcpy (line
, "SCD SETATTR "), name
);
416 for (; valuelen
; value
++, valuelen
--)
418 if (p
>= line
+ DIM(line
)-5 )
419 return gpg_error (GPG_ERR_TOO_LARGE
);
420 if (*value
< ' ' || *value
== '+' || *value
== '%')
422 sprintf (p
, "%%%02X", *value
);
425 else if (*value
== ' ')
436 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
437 default_inq_cb
, NULL
, NULL
, NULL
);
443 /* Handle a CERTDATA inquiry. Note, we only send the data,
444 assuan_transact takes care of flushing and writing the END
447 inq_writecert_parms (void *opaque
, const char *line
)
450 struct writecert_parm_s
*parm
= opaque
;
452 if (!strncmp (line
, "CERTDATA", 8) && (line
[8]==' '||!line
[8]))
454 rc
= assuan_send_data (parm
->ctx
, parm
->certdata
, parm
->certdatalen
);
457 rc
= default_inq_cb (opaque
, line
);
463 /* Send a WRITECERT command to the SCdaemon. */
465 agent_scd_writecert (const char *certidstr
,
466 const unsigned char *certdata
, size_t certdatalen
)
469 char line
[ASSUAN_LINELENGTH
];
470 struct writecert_parm_s parms
;
476 memset (&parms
, 0, sizeof parms
);
478 snprintf (line
, DIM(line
)-1, "SCD WRITECERT %s", certidstr
);
479 line
[DIM(line
)-1] = 0;
480 parms
.ctx
= agent_ctx
;
481 parms
.certdata
= certdata
;
482 parms
.certdatalen
= certdatalen
;
484 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
485 inq_writecert_parms
, &parms
, NULL
, NULL
);
493 /* Handle a KEYDATA inquiry. Note, we only send the data,
494 assuan_transact takes care of flushing and writing the end */
496 inq_writekey_parms (void *opaque
, const char *line
)
499 struct writekey_parm_s
*parm
= opaque
;
501 if (!strncmp (line
, "KEYDATA", 7) && (line
[7]==' '||!line
[7]))
503 rc
= assuan_send_data (parm
->ctx
, parm
->keydata
, parm
->keydatalen
);
506 rc
= default_inq_cb (opaque
, line
);
512 /* Send a WRITEKEY command to the SCdaemon. */
514 agent_scd_writekey (int keyno
, const char *serialno
,
515 const unsigned char *keydata
, size_t keydatalen
)
518 char line
[ASSUAN_LINELENGTH
];
519 struct writekey_parm_s parms
;
527 memset (&parms
, 0, sizeof parms
);
529 snprintf (line
, DIM(line
)-1, "SCD WRITEKEY --force OPENPGP.%d", keyno
);
530 line
[DIM(line
)-1] = 0;
531 parms
.ctx
= agent_ctx
;
532 parms
.keydata
= keydata
;
533 parms
.keydatalen
= keydatalen
;
535 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
536 inq_writekey_parms
, &parms
, NULL
, NULL
);
544 /* Status callback for the SCD GENKEY command. */
546 scd_genkey_cb (void *opaque
, const char *line
)
548 struct agent_card_genkey_s
*parm
= opaque
;
549 const char *keyword
= line
;
553 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
555 while (spacep (line
))
558 if (keywordlen
== 7 && !memcmp (keyword
, "KEY-FPR", keywordlen
))
560 parm
->fprvalid
= unhexify_fpr (line
, parm
->fpr
);
562 if (keywordlen
== 8 && !memcmp (keyword
, "KEY-DATA", keywordlen
))
565 const char *name
= line
;
567 while (*line
&& !spacep (line
))
569 while (spacep (line
))
572 rc
= gcry_mpi_scan (&a
, GCRYMPI_FMT_HEX
, line
, 0, NULL
);
574 log_error ("error parsing received key data: %s\n", gpg_strerror (rc
));
575 else if (*name
== 'n' && spacep (name
+1))
577 else if (*name
== 'e' && spacep (name
+1))
581 log_info ("unknown parameter name in received key data\n");
582 gcry_mpi_release (a
);
585 else if (keywordlen
== 14 && !memcmp (keyword
,"KEY-CREATED-AT", keywordlen
))
587 parm
->created_at
= (u32
)strtoul (line
, NULL
, 10);
593 /* Send a GENKEY command to the SCdaemon. SERIALNO is not used in
594 this implementation. If CREATEDATE has been given, it will be
595 passed to SCDAEMON so that the key can be created with this
596 timestamp; note the user needs to use the returned timestamp as old
597 versions of scddaemon don't support this option. */
599 agent_scd_genkey (struct agent_card_genkey_s
*info
, int keyno
, int force
,
600 const char *serialno
, u32 createtime
)
603 char line
[ASSUAN_LINELENGTH
];
604 gnupg_isotime_t tbuf
;
613 epoch2isotime (tbuf
, createtime
);
617 memset (info
, 0, sizeof *info
);
618 snprintf (line
, DIM(line
)-1, "SCD GENKEY %s%s %s %d",
619 *tbuf
? "--timestamp=":"", tbuf
,
622 line
[DIM(line
)-1] = 0;
624 memset (info
, 0, sizeof *info
);
625 rc
= assuan_transact (agent_ctx
, line
,
626 NULL
, NULL
, default_inq_cb
, NULL
,
627 scd_genkey_cb
, info
);
634 membuf_data_cb (void *opaque
, const void *buffer
, size_t length
)
636 membuf_t
*data
= opaque
;
639 put_membuf (data
, buffer
, length
);
643 /* Send a sign command to the scdaemon via gpg-agent's pass thru
646 agent_scd_pksign (const char *serialno
, int hashalgo
,
647 const unsigned char *indata
, size_t indatalen
,
648 unsigned char **r_buf
, size_t *r_buflen
)
651 char *p
, line
[ASSUAN_LINELENGTH
];
655 /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */
664 if (indatalen
*2 + 50 > DIM(line
))
665 return gpg_error (GPG_ERR_GENERAL
);
667 /* Send the serialno command to initialize the connection. We don't
668 care about the data returned. If the card has already been
669 initialized, this is a very fast command. We request the openpgp
670 card because that is what we expect. */
671 rc
= assuan_transact (agent_ctx
, "SCD SERIALNO openpgp",
672 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
676 sprintf (line
, "SCD SETDATA ");
677 p
= line
+ strlen (line
);
678 for (i
=0; i
< indatalen
; i
++, p
+= 2 )
679 sprintf (p
, "%02X", indata
[i
]);
680 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
684 init_membuf (&data
, 1024);
686 if (!hashalgo
) /* Temporary test hack. */
687 snprintf (line
, DIM(line
)-1, "SCD PKAUTH %s", serialno
);
690 snprintf (line
, DIM(line
)-1, "SCD PKSIGN %s%s",
691 hashalgo
== GCRY_MD_RMD160
? "--hash=rmd160 " : "",
693 line
[DIM(line
)-1] = 0;
694 rc
= assuan_transact (agent_ctx
, line
, membuf_data_cb
, &data
,
695 default_inq_cb
, NULL
, NULL
, NULL
);
698 xfree (get_membuf (&data
, &len
));
701 *r_buf
= get_membuf (&data
, r_buflen
);
707 /* Decrypt INDATA of length INDATALEN using the card identified by
708 SERIALNO. Return the plaintext in a nwly allocated buffer stored
709 at the address of R_BUF.
711 Note, we currently support only RSA or more exactly algorithms
712 taking one input data element. */
714 agent_scd_pkdecrypt (const char *serialno
,
715 const unsigned char *indata
, size_t indatalen
,
716 unsigned char **r_buf
, size_t *r_buflen
)
719 char *p
, line
[ASSUAN_LINELENGTH
];
728 /* FIXME: use secure memory where appropriate */
729 if (indatalen
*2 + 50 > DIM(line
))
730 return gpg_error (GPG_ERR_GENERAL
);
732 /* Send the serialno command to initialize the connection. We don't
733 care about the data returned. If the card has already been
734 initialized, this is a very fast command. We request the openpgp
735 card because that is what we expect. */
736 rc
= assuan_transact (agent_ctx
, "SCD SERIALNO openpgp",
737 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
741 sprintf (line
, "SCD SETDATA ");
742 p
= line
+ strlen (line
);
743 for (i
=0; i
< indatalen
; i
++, p
+= 2 )
744 sprintf (p
, "%02X", indata
[i
]);
745 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
749 init_membuf (&data
, 1024);
750 snprintf (line
, DIM(line
)-1, "SCD PKDECRYPT %s", serialno
);
751 line
[DIM(line
)-1] = 0;
752 rc
= assuan_transact (agent_ctx
, line
,
753 membuf_data_cb
, &data
,
754 default_inq_cb
, NULL
, NULL
, NULL
);
757 xfree (get_membuf (&data
, &len
));
760 *r_buf
= get_membuf (&data
, r_buflen
);
762 return gpg_error (GPG_ERR_ENOMEM
);
768 /* Change the PIN of an OpenPGP card or reset the retry counter.
769 CHVNO 1: Change the PIN
770 2: For v1 cards: Same as 1.
771 For v2 cards: Reset the PIN using the Reset Code.
772 3: Change the admin PIN
773 101: Set a new PIN and reset the retry counter
774 102: For v1 cars: Same as 101.
775 For v2 cards: Set a new Reset Code.
776 SERIALNO is not used.
779 agent_scd_change_pin (int chvno
, const char *serialno
)
782 char line
[ASSUAN_LINELENGTH
];
783 const char *reset
= "";
795 snprintf (line
, DIM(line
)-1, "SCD PASSWD %s %d", reset
, chvno
);
796 line
[DIM(line
)-1] = 0;
797 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
798 default_inq_cb
, NULL
, NULL
, NULL
);
803 /* Perform a CHECKPIN operation. SERIALNO should be the serial
804 number of the card - optionally followed by the fingerprint;
805 however the fingerprint is ignored here. */
807 agent_scd_checkpin (const char *serialno
)
810 char line
[ASSUAN_LINELENGTH
];
816 snprintf (line
, DIM(line
)-1, "SCD CHECKPIN %s", serialno
);
817 line
[DIM(line
)-1] = 0;
818 return assuan_transact (agent_ctx
, line
,
820 default_inq_cb
, NULL
, NULL
, NULL
);
824 /* Dummy function, only used by the gpg 1.4 implementation. */
826 agent_clear_pin_cache (const char *sn
)
834 /* Note: All strings shall be UTF-8. On success the caller needs to
835 free the string stored at R_PASSPHRASE. On error NULL will be
836 stored at R_PASSPHRASE and an appropriate fpf error code
839 agent_get_passphrase (const char *cache_id
,
842 const char *desc_msg
,
848 char line
[ASSUAN_LINELENGTH
];
855 *r_passphrase
= NULL
;
861 /* Check that the gpg-agent understands the repeat option. */
862 if (assuan_transact (agent_ctx
,
863 "GETINFO cmd_has_option GET_PASSPHRASE repeat",
864 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
))
865 return gpg_error (GPG_ERR_NOT_SUPPORTED
);
867 if (cache_id
&& *cache_id
)
868 if (!(arg1
= percent_plus_escape (cache_id
)))
870 if (err_msg
&& *err_msg
)
871 if (!(arg2
= percent_plus_escape (err_msg
)))
873 if (prompt
&& *prompt
)
874 if (!(arg3
= percent_plus_escape (prompt
)))
876 if (desc_msg
&& *desc_msg
)
877 if (!(arg4
= percent_plus_escape (desc_msg
)))
880 snprintf (line
, DIM(line
)-1,
881 "GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s",
883 check
? " --check --qualitybar":"",
888 line
[DIM(line
)-1] = 0;
894 init_membuf_secure (&data
, 64);
895 rc
= assuan_transact (agent_ctx
, line
,
896 membuf_data_cb
, &data
,
897 default_inq_cb
, NULL
, NULL
, NULL
);
900 xfree (get_membuf (&data
, NULL
));
903 put_membuf (&data
, "", 1);
904 *r_passphrase
= get_membuf (&data
, NULL
);
906 rc
= gpg_error_from_syserror ();
910 rc
= gpg_error_from_syserror ();
920 agent_clear_passphrase (const char *cache_id
)
923 char line
[ASSUAN_LINELENGTH
];
925 if (!cache_id
|| !*cache_id
)
932 snprintf (line
, DIM(line
)-1, "CLEAR_PASSPHRASE %s", cache_id
);
933 line
[DIM(line
)-1] = 0;
934 return assuan_transact (agent_ctx
, line
, NULL
, NULL
,
935 default_inq_cb
, NULL
, NULL
, NULL
);