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). */
135 for (s
=hexstr
, n
=0; *s
; s
+= 2, n
++)
140 /* Take the serial number from LINE and return it verbatim in a newly
141 allocated string. We make sure that only hex characters are
144 store_serialno (const char *line
)
149 for (s
=line
; hexdigitp (s
); s
++)
151 p
= xtrymalloc (s
+ 1 - line
);
154 memcpy (p
, line
, s
-line
);
162 /* This is a dummy data line callback. */
164 dummy_data_cb (void *opaque
, const void *buffer
, size_t length
)
173 /* This is the default inquiry callback. It mainly handles the
174 Pinentry notifications. */
176 default_inq_cb (void *opaque
, const char *line
)
180 if (!strncmp (line
, "PINENTRY_LAUNCHED", 17) && (line
[17]==' '||!line
[17]))
182 /* There is no working server mode yet thus we use
183 AllowSetForegroundWindow window right here. We might want to
184 do this anyway in case gpg is called on the console. */
185 gnupg_allow_set_foregound_window ((pid_t
)strtoul (line
+17, NULL
, 10));
186 /* We do not pass errors to avoid breaking other code. */
189 log_debug ("ignoring gpg-agent inquiry `%s'\n", line
);
196 /* Release the card info structure INFO. */
198 agent_release_card_info (struct agent_card_info_s
*info
)
203 xfree (info
->serialno
); info
->serialno
= NULL
;
204 xfree (info
->apptype
); info
->apptype
= NULL
;
205 xfree (info
->disp_name
); info
->disp_name
= NULL
;
206 xfree (info
->disp_lang
); info
->disp_lang
= NULL
;
207 xfree (info
->pubkey_url
); info
->pubkey_url
= NULL
;
208 xfree (info
->login_data
); info
->login_data
= NULL
;
209 info
->cafpr1valid
= info
->cafpr2valid
= info
->cafpr3valid
= 0;
210 info
->fpr1valid
= info
->fpr2valid
= info
->fpr3valid
= 0;
214 learn_status_cb (void *opaque
, const char *line
)
216 struct agent_card_info_s
*parm
= opaque
;
217 const char *keyword
= line
;
221 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
223 while (spacep (line
))
226 if (keywordlen
== 8 && !memcmp (keyword
, "SERIALNO", keywordlen
))
228 xfree (parm
->serialno
);
229 parm
->serialno
= store_serialno (line
);
230 parm
->is_v2
= (strlen (parm
->serialno
) >= 16
231 && xtoi_2 (parm
->serialno
+12) >= 2 );
233 else if (keywordlen
== 7 && !memcmp (keyword
, "APPTYPE", keywordlen
))
235 xfree (parm
->apptype
);
236 parm
->apptype
= unescape_status_string (line
);
238 else if (keywordlen
== 9 && !memcmp (keyword
, "DISP-NAME", keywordlen
))
240 xfree (parm
->disp_name
);
241 parm
->disp_name
= unescape_status_string (line
);
243 else if (keywordlen
== 9 && !memcmp (keyword
, "DISP-LANG", keywordlen
))
245 xfree (parm
->disp_lang
);
246 parm
->disp_lang
= unescape_status_string (line
);
248 else if (keywordlen
== 8 && !memcmp (keyword
, "DISP-SEX", keywordlen
))
250 parm
->disp_sex
= *line
== '1'? 1 : *line
== '2' ? 2: 0;
252 else if (keywordlen
== 10 && !memcmp (keyword
, "PUBKEY-URL", keywordlen
))
254 xfree (parm
->pubkey_url
);
255 parm
->pubkey_url
= unescape_status_string (line
);
257 else if (keywordlen
== 10 && !memcmp (keyword
, "LOGIN-DATA", keywordlen
))
259 xfree (parm
->login_data
);
260 parm
->login_data
= unescape_status_string (line
);
262 else if (keywordlen
== 11 && !memcmp (keyword
, "SIG-COUNTER", keywordlen
))
264 parm
->sig_counter
= strtoul (line
, NULL
, 0);
266 else if (keywordlen
== 10 && !memcmp (keyword
, "CHV-STATUS", keywordlen
))
270 buf
= p
= unescape_status_string (line
);
275 parm
->chv1_cached
= atoi (p
);
276 while (*p
&& !spacep (p
))
280 for (i
=0; *p
&& i
< 3; i
++)
282 parm
->chvmaxlen
[i
] = atoi (p
);
283 while (*p
&& !spacep (p
))
288 for (i
=0; *p
&& i
< 3; i
++)
290 parm
->chvretry
[i
] = atoi (p
);
291 while (*p
&& !spacep (p
))
299 else if (keywordlen
== 7 && !memcmp (keyword
, "KEY-FPR", keywordlen
))
301 int no
= atoi (line
);
302 while (*line
&& !spacep (line
))
304 while (spacep (line
))
307 parm
->fpr1valid
= unhexify_fpr (line
, parm
->fpr1
);
309 parm
->fpr2valid
= unhexify_fpr (line
, parm
->fpr2
);
311 parm
->fpr3valid
= unhexify_fpr (line
, parm
->fpr3
);
313 else if (keywordlen
== 6 && !memcmp (keyword
, "CA-FPR", keywordlen
))
315 int no
= atoi (line
);
316 while (*line
&& !spacep (line
))
318 while (spacep (line
))
321 parm
->cafpr1valid
= unhexify_fpr (line
, parm
->cafpr1
);
323 parm
->cafpr2valid
= unhexify_fpr (line
, parm
->cafpr2
);
325 parm
->cafpr3valid
= unhexify_fpr (line
, parm
->cafpr3
);
327 else if (keywordlen
== 8 && !memcmp (keyword
, "KEY-ATTR", keywordlen
))
329 int keyno
, algo
, nbits
;
331 sscanf (line
, "%d %d %d", &keyno
, &algo
, &nbits
);
333 if (keyno
>= 0 && keyno
< DIM (parm
->key_attr
))
335 parm
->key_attr
[keyno
].algo
= algo
;
336 parm
->key_attr
[keyno
].nbits
= nbits
;
343 /* Call the agent to learn about a smartcard */
345 agent_learn (struct agent_card_info_s
*info
)
353 memset (info
, 0, sizeof *info
);
354 rc
= assuan_transact (agent_ctx
, "LEARN --send",
355 dummy_data_cb
, NULL
, default_inq_cb
, NULL
,
356 learn_status_cb
, info
);
357 /* Also try to get the key attributes. */
359 agent_scd_getattr ("KEY-ATTR", info
);
364 /* Call the agent to retrieve a data object. This function returns
365 the data in the same structure as used by the learn command. It is
366 allowed to update such a structure using this commmand. */
368 agent_scd_getattr (const char *name
, struct agent_card_info_s
*info
)
371 char line
[ASSUAN_LINELENGTH
];
374 return gpg_error (GPG_ERR_INV_VALUE
);
376 /* We assume that NAME does not need escaping. */
377 if (12 + strlen (name
) > DIM(line
)-1)
378 return gpg_error (GPG_ERR_TOO_LARGE
);
379 stpcpy (stpcpy (line
, "SCD GETATTR "), name
);
385 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, default_inq_cb
, NULL
,
386 learn_status_cb
, info
);
392 /* Send an setattr command to the SCdaemon. SERIALNO is not actually
393 used here but required by gpg 1.4's implementation of this code in
396 agent_scd_setattr (const char *name
,
397 const unsigned char *value
, size_t valuelen
,
398 const char *serialno
)
401 char line
[ASSUAN_LINELENGTH
];
406 if (!*name
|| !valuelen
)
407 return gpg_error (GPG_ERR_INV_VALUE
);
409 /* We assume that NAME does not need escaping. */
410 if (12 + strlen (name
) > DIM(line
)-1)
411 return gpg_error (GPG_ERR_TOO_LARGE
);
413 p
= stpcpy (stpcpy (line
, "SCD SETATTR "), name
);
415 for (; valuelen
; value
++, valuelen
--)
417 if (p
>= line
+ DIM(line
)-5 )
418 return gpg_error (GPG_ERR_TOO_LARGE
);
419 if (*value
< ' ' || *value
== '+' || *value
== '%')
421 sprintf (p
, "%%%02X", *value
);
424 else if (*value
== ' ')
435 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
436 default_inq_cb
, NULL
, NULL
, NULL
);
442 /* Handle a CERTDATA inquiry. Note, we only send the data,
443 assuan_transact takes care of flushing and writing the END
446 inq_writecert_parms (void *opaque
, const char *line
)
449 struct writecert_parm_s
*parm
= opaque
;
451 if (!strncmp (line
, "CERTDATA", 8) && (line
[8]==' '||!line
[8]))
453 rc
= assuan_send_data (parm
->ctx
, parm
->certdata
, parm
->certdatalen
);
456 rc
= default_inq_cb (opaque
, line
);
462 /* Send a WRITECERT command to the SCdaemon. */
464 agent_scd_writecert (const char *certidstr
,
465 const unsigned char *certdata
, size_t certdatalen
)
468 char line
[ASSUAN_LINELENGTH
];
469 struct writecert_parm_s parms
;
475 memset (&parms
, 0, sizeof parms
);
477 snprintf (line
, DIM(line
)-1, "SCD WRITECERT %s", certidstr
);
478 line
[DIM(line
)-1] = 0;
479 parms
.ctx
= agent_ctx
;
480 parms
.certdata
= certdata
;
481 parms
.certdatalen
= certdatalen
;
483 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
484 inq_writecert_parms
, &parms
, NULL
, NULL
);
491 /* Handle a KEYDATA inquiry. Note, we only send the data,
492 assuan_transact takes care of flushing and writing the end */
494 inq_writekey_parms (void *opaque
, const char *line
)
497 struct writekey_parm_s
*parm
= opaque
;
499 if (!strncmp (line
, "KEYDATA", 7) && (line
[7]==' '||!line
[7]))
501 rc
= assuan_send_data (parm
->ctx
, parm
->keydata
, parm
->keydatalen
);
504 rc
= default_inq_cb (opaque
, line
);
510 /* Send a WRITEKEY command to the SCdaemon. */
512 agent_scd_writekey (int keyno
, const char *serialno
,
513 const unsigned char *keydata
, size_t keydatalen
)
516 char line
[ASSUAN_LINELENGTH
];
517 struct writekey_parm_s parms
;
525 memset (&parms
, 0, sizeof parms
);
527 snprintf (line
, DIM(line
)-1, "SCD WRITEKEY --force OPENPGP.%d", keyno
);
528 line
[DIM(line
)-1] = 0;
529 parms
.ctx
= agent_ctx
;
530 parms
.keydata
= keydata
;
531 parms
.keydatalen
= keydatalen
;
533 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
534 inq_writekey_parms
, &parms
, NULL
, NULL
);
541 /* Status callback for the SCD GENKEY command. */
543 scd_genkey_cb (void *opaque
, const char *line
)
545 struct agent_card_genkey_s
*parm
= opaque
;
546 const char *keyword
= line
;
550 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
552 while (spacep (line
))
555 if (keywordlen
== 7 && !memcmp (keyword
, "KEY-FPR", keywordlen
))
557 parm
->fprvalid
= unhexify_fpr (line
, parm
->fpr
);
559 if (keywordlen
== 8 && !memcmp (keyword
, "KEY-DATA", keywordlen
))
562 const char *name
= line
;
564 while (*line
&& !spacep (line
))
566 while (spacep (line
))
569 rc
= gcry_mpi_scan (&a
, GCRYMPI_FMT_HEX
, line
, 0, NULL
);
571 log_error ("error parsing received key data: %s\n", gpg_strerror (rc
));
572 else if (*name
== 'n' && spacep (name
+1))
574 else if (*name
== 'e' && spacep (name
+1))
578 log_info ("unknown parameter name in received key data\n");
579 gcry_mpi_release (a
);
582 else if (keywordlen
== 14 && !memcmp (keyword
,"KEY-CREATED-AT", keywordlen
))
584 parm
->created_at
= (u32
)strtoul (line
, NULL
, 10);
590 /* Send a GENKEY command to the SCdaemon. SERIALNO is not used in
591 this implementation. If CREATEDATE has been given, it will be
592 passed to SCDAEMON so that the key can be created with this
593 timestamp; note the user needs to use the returned timestamp as old
594 versions of scddaemon don't support this option. */
596 agent_scd_genkey (struct agent_card_genkey_s
*info
, int keyno
, int force
,
597 const char *serialno
, u32 createtime
)
600 char line
[ASSUAN_LINELENGTH
];
601 gnupg_isotime_t tbuf
;
610 epoch2isotime (tbuf
, createtime
);
614 memset (info
, 0, sizeof *info
);
615 snprintf (line
, DIM(line
)-1, "SCD GENKEY %s%s %s %d",
616 *tbuf
? "--timestamp=":"", tbuf
,
619 line
[DIM(line
)-1] = 0;
621 memset (info
, 0, sizeof *info
);
622 rc
= assuan_transact (agent_ctx
, line
,
623 NULL
, NULL
, default_inq_cb
, NULL
,
624 scd_genkey_cb
, info
);
631 membuf_data_cb (void *opaque
, const void *buffer
, size_t length
)
633 membuf_t
*data
= opaque
;
636 put_membuf (data
, buffer
, length
);
640 /* Send a sign command to the scdaemon via gpg-agent's pass thru
643 agent_scd_pksign (const char *serialno
, int hashalgo
,
644 const unsigned char *indata
, size_t indatalen
,
645 unsigned char **r_buf
, size_t *r_buflen
)
648 char *p
, line
[ASSUAN_LINELENGTH
];
652 /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */
661 if (indatalen
*2 + 50 > DIM(line
))
662 return gpg_error (GPG_ERR_GENERAL
);
664 /* Send the serialno command to initialize the connection. We don't
665 care about the data returned. If the card has already been
666 initialized, this is a very fast command. We request the openpgp
667 card because that is what we expect. */
668 rc
= assuan_transact (agent_ctx
, "SCD SERIALNO openpgp",
669 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
673 sprintf (line
, "SCD SETDATA ");
674 p
= line
+ strlen (line
);
675 for (i
=0; i
< indatalen
; i
++, p
+= 2 )
676 sprintf (p
, "%02X", indata
[i
]);
677 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
681 init_membuf (&data
, 1024);
683 if (!hashalgo
) /* Temporary test hack. */
684 snprintf (line
, DIM(line
)-1, "SCD PKAUTH %s", serialno
);
687 snprintf (line
, DIM(line
)-1, "SCD PKSIGN %s%s",
688 hashalgo
== GCRY_MD_RMD160
? "--hash=rmd160 " : "",
690 line
[DIM(line
)-1] = 0;
691 rc
= assuan_transact (agent_ctx
, line
, membuf_data_cb
, &data
,
692 default_inq_cb
, NULL
, NULL
, NULL
);
695 xfree (get_membuf (&data
, &len
));
698 *r_buf
= get_membuf (&data
, r_buflen
);
704 /* Decrypt INDATA of length INDATALEN using the card identified by
705 SERIALNO. Return the plaintext in a nwly allocated buffer stored
706 at the address of R_BUF.
708 Note, we currently support only RSA or more exactly algorithms
709 taking one input data element. */
711 agent_scd_pkdecrypt (const char *serialno
,
712 const unsigned char *indata
, size_t indatalen
,
713 unsigned char **r_buf
, size_t *r_buflen
)
716 char *p
, line
[ASSUAN_LINELENGTH
];
725 /* FIXME: use secure memory where appropriate */
726 if (indatalen
*2 + 50 > DIM(line
))
727 return gpg_error (GPG_ERR_GENERAL
);
729 /* Send the serialno command to initialize the connection. We don't
730 care about the data returned. If the card has already been
731 initialized, this is a very fast command. We request the openpgp
732 card because that is what we expect. */
733 rc
= assuan_transact (agent_ctx
, "SCD SERIALNO openpgp",
734 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
738 sprintf (line
, "SCD SETDATA ");
739 p
= line
+ strlen (line
);
740 for (i
=0; i
< indatalen
; i
++, p
+= 2 )
741 sprintf (p
, "%02X", indata
[i
]);
742 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
746 init_membuf (&data
, 1024);
747 snprintf (line
, DIM(line
)-1, "SCD PKDECRYPT %s", serialno
);
748 line
[DIM(line
)-1] = 0;
749 rc
= assuan_transact (agent_ctx
, line
,
750 membuf_data_cb
, &data
,
751 default_inq_cb
, NULL
, NULL
, NULL
);
754 xfree (get_membuf (&data
, &len
));
757 *r_buf
= get_membuf (&data
, r_buflen
);
759 return gpg_error (GPG_ERR_ENOMEM
);
766 /* Send a READCERT command to the SCdaemon. */
768 agent_scd_readcert (const char *certidstr
,
769 void **r_buf
, size_t *r_buflen
)
772 char line
[ASSUAN_LINELENGTH
];
781 init_membuf (&data
, 2048);
783 snprintf (line
, DIM(line
)-1, "SCD READCERT %s", certidstr
);
784 line
[DIM(line
)-1] = 0;
785 rc
= assuan_transact (agent_ctx
, line
,
786 membuf_data_cb
, &data
,
787 default_inq_cb
, NULL
, NULL
, NULL
);
790 xfree (get_membuf (&data
, &len
));
793 *r_buf
= get_membuf (&data
, r_buflen
);
795 return gpg_error (GPG_ERR_ENOMEM
);
802 /* Change the PIN of an OpenPGP card or reset the retry counter.
803 CHVNO 1: Change the PIN
804 2: For v1 cards: Same as 1.
805 For v2 cards: Reset the PIN using the Reset Code.
806 3: Change the admin PIN
807 101: Set a new PIN and reset the retry counter
808 102: For v1 cars: Same as 101.
809 For v2 cards: Set a new Reset Code.
810 SERIALNO is not used.
813 agent_scd_change_pin (int chvno
, const char *serialno
)
816 char line
[ASSUAN_LINELENGTH
];
817 const char *reset
= "";
829 snprintf (line
, DIM(line
)-1, "SCD PASSWD %s %d", reset
, chvno
);
830 line
[DIM(line
)-1] = 0;
831 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
832 default_inq_cb
, NULL
, NULL
, NULL
);
837 /* Perform a CHECKPIN operation. SERIALNO should be the serial
838 number of the card - optionally followed by the fingerprint;
839 however the fingerprint is ignored here. */
841 agent_scd_checkpin (const char *serialno
)
844 char line
[ASSUAN_LINELENGTH
];
850 snprintf (line
, DIM(line
)-1, "SCD CHECKPIN %s", serialno
);
851 line
[DIM(line
)-1] = 0;
852 return assuan_transact (agent_ctx
, line
,
854 default_inq_cb
, NULL
, NULL
, NULL
);
858 /* Dummy function, only used by the gpg 1.4 implementation. */
860 agent_clear_pin_cache (const char *sn
)
868 /* Note: All strings shall be UTF-8. On success the caller needs to
869 free the string stored at R_PASSPHRASE. On error NULL will be
870 stored at R_PASSPHRASE and an appropriate fpf error code
873 agent_get_passphrase (const char *cache_id
,
876 const char *desc_msg
,
882 char line
[ASSUAN_LINELENGTH
];
889 *r_passphrase
= NULL
;
895 /* Check that the gpg-agent understands the repeat option. */
896 if (assuan_transact (agent_ctx
,
897 "GETINFO cmd_has_option GET_PASSPHRASE repeat",
898 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
))
899 return gpg_error (GPG_ERR_NOT_SUPPORTED
);
901 if (cache_id
&& *cache_id
)
902 if (!(arg1
= percent_plus_escape (cache_id
)))
904 if (err_msg
&& *err_msg
)
905 if (!(arg2
= percent_plus_escape (err_msg
)))
907 if (prompt
&& *prompt
)
908 if (!(arg3
= percent_plus_escape (prompt
)))
910 if (desc_msg
&& *desc_msg
)
911 if (!(arg4
= percent_plus_escape (desc_msg
)))
914 snprintf (line
, DIM(line
)-1,
915 "GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s",
917 check
? " --check --qualitybar":"",
922 line
[DIM(line
)-1] = 0;
928 init_membuf_secure (&data
, 64);
929 rc
= assuan_transact (agent_ctx
, line
,
930 membuf_data_cb
, &data
,
931 default_inq_cb
, NULL
, NULL
, NULL
);
934 xfree (get_membuf (&data
, NULL
));
937 put_membuf (&data
, "", 1);
938 *r_passphrase
= get_membuf (&data
, NULL
);
940 rc
= gpg_error_from_syserror ();
944 rc
= gpg_error_from_syserror ();
954 agent_clear_passphrase (const char *cache_id
)
957 char line
[ASSUAN_LINELENGTH
];
959 if (!cache_id
|| !*cache_id
)
966 snprintf (line
, DIM(line
)-1, "CLEAR_PASSPHRASE %s", cache_id
);
967 line
[DIM(line
)-1] = 0;
968 return assuan_transact (agent_ctx
, line
, NULL
, NULL
,
969 default_inq_cb
, NULL
, NULL
, NULL
);