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
)
121 buffer
= d
= xtrymalloc (strlen (s
)+1);
126 if (*s
== '%' && s
[1] && s
[2])
148 /* Take a 20 byte hexencoded string and put it into the the provided
149 20 byte buffer FPR in binary format. */
151 unhexify_fpr (const char *hexstr
, unsigned char *fpr
)
156 for (s
=hexstr
, n
=0; hexdigitp (s
); s
++, n
++)
159 return 0; /* no fingerprint (invalid or wrong length). */
161 for (s
=hexstr
, n
=0; *s
; s
+= 2, n
++)
166 /* Take the serial number from LINE and return it verbatim in a newly
167 allocated string. We make sure that only hex characters are
170 store_serialno (const char *line
)
175 for (s
=line
; hexdigitp (s
); s
++)
177 p
= xtrymalloc (s
+ 1 - line
);
180 memcpy (p
, line
, s
-line
);
188 /* This is a dummy data line callback. */
190 dummy_data_cb (void *opaque
, const void *buffer
, size_t length
)
199 /* This is the default inquiry callback. It mainly handles the
200 Pinentry notifications. */
202 default_inq_cb (void *opaque
, const char *line
)
206 if (!strncmp (line
, "PINENTRY_LAUNCHED", 17) && (line
[17]==' '||!line
[17]))
208 /* There is no working server mode yet thus we use
209 AllowSetForegroundWindow window right here. We might want to
210 do this anyway in case gpg is called on the console. */
211 gnupg_allow_set_foregound_window ((pid_t
)strtoul (line
+17, NULL
, 10));
212 /* We do not pass errors to avoid breaking other code. */
215 log_debug ("ignoring gpg-agent inquiry `%s'\n", line
);
222 /* Release the card info structure INFO. */
224 agent_release_card_info (struct agent_card_info_s
*info
)
229 xfree (info
->serialno
); info
->serialno
= NULL
;
230 xfree (info
->apptype
); info
->apptype
= NULL
;
231 xfree (info
->disp_name
); info
->disp_name
= NULL
;
232 xfree (info
->disp_lang
); info
->disp_lang
= NULL
;
233 xfree (info
->pubkey_url
); info
->pubkey_url
= NULL
;
234 xfree (info
->login_data
); info
->login_data
= NULL
;
235 info
->cafpr1valid
= info
->cafpr2valid
= info
->cafpr3valid
= 0;
236 info
->fpr1valid
= info
->fpr2valid
= info
->fpr3valid
= 0;
240 learn_status_cb (void *opaque
, const char *line
)
242 struct agent_card_info_s
*parm
= opaque
;
243 const char *keyword
= line
;
247 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
249 while (spacep (line
))
252 if (keywordlen
== 8 && !memcmp (keyword
, "SERIALNO", keywordlen
))
254 xfree (parm
->serialno
);
255 parm
->serialno
= store_serialno (line
);
256 parm
->is_v2
= (strlen (parm
->serialno
) >= 16
257 && xtoi_2 (parm
->serialno
+12) >= 2 );
259 else if (keywordlen
== 7 && !memcmp (keyword
, "APPTYPE", keywordlen
))
261 xfree (parm
->apptype
);
262 parm
->apptype
= unescape_status_string (line
);
264 else if (keywordlen
== 9 && !memcmp (keyword
, "DISP-NAME", keywordlen
))
266 xfree (parm
->disp_name
);
267 parm
->disp_name
= unescape_status_string (line
);
269 else if (keywordlen
== 9 && !memcmp (keyword
, "DISP-LANG", keywordlen
))
271 xfree (parm
->disp_lang
);
272 parm
->disp_lang
= unescape_status_string (line
);
274 else if (keywordlen
== 8 && !memcmp (keyword
, "DISP-SEX", keywordlen
))
276 parm
->disp_sex
= *line
== '1'? 1 : *line
== '2' ? 2: 0;
278 else if (keywordlen
== 10 && !memcmp (keyword
, "PUBKEY-URL", keywordlen
))
280 xfree (parm
->pubkey_url
);
281 parm
->pubkey_url
= unescape_status_string (line
);
283 else if (keywordlen
== 10 && !memcmp (keyword
, "LOGIN-DATA", keywordlen
))
285 xfree (parm
->login_data
);
286 parm
->login_data
= unescape_status_string (line
);
288 else if (keywordlen
== 11 && !memcmp (keyword
, "SIG-COUNTER", keywordlen
))
290 parm
->sig_counter
= strtoul (line
, NULL
, 0);
292 else if (keywordlen
== 10 && !memcmp (keyword
, "CHV-STATUS", keywordlen
))
296 buf
= p
= unescape_status_string (line
);
301 parm
->chv1_cached
= atoi (p
);
302 while (*p
&& !spacep (p
))
306 for (i
=0; *p
&& i
< 3; i
++)
308 parm
->chvmaxlen
[i
] = atoi (p
);
309 while (*p
&& !spacep (p
))
314 for (i
=0; *p
&& i
< 3; i
++)
316 parm
->chvretry
[i
] = atoi (p
);
317 while (*p
&& !spacep (p
))
325 else if (keywordlen
== 7 && !memcmp (keyword
, "KEY-FPR", keywordlen
))
327 int no
= atoi (line
);
328 while (*line
&& !spacep (line
))
330 while (spacep (line
))
333 parm
->fpr1valid
= unhexify_fpr (line
, parm
->fpr1
);
335 parm
->fpr2valid
= unhexify_fpr (line
, parm
->fpr2
);
337 parm
->fpr3valid
= unhexify_fpr (line
, parm
->fpr3
);
339 else if (keywordlen
== 6 && !memcmp (keyword
, "CA-FPR", keywordlen
))
341 int no
= atoi (line
);
342 while (*line
&& !spacep (line
))
344 while (spacep (line
))
347 parm
->cafpr1valid
= unhexify_fpr (line
, parm
->cafpr1
);
349 parm
->cafpr2valid
= unhexify_fpr (line
, parm
->cafpr2
);
351 parm
->cafpr3valid
= unhexify_fpr (line
, parm
->cafpr3
);
357 /* Call the agent to learn about a smartcard */
359 agent_learn (struct agent_card_info_s
*info
)
367 memset (info
, 0, sizeof *info
);
368 rc
= assuan_transact (agent_ctx
, "LEARN --send",
369 dummy_data_cb
, NULL
, default_inq_cb
, NULL
,
370 learn_status_cb
, info
);
375 /* Call the agent to retrieve a data object. This function returns
376 the data in the same structure as used by the learn command. It is
377 allowed to update such a structure using this commmand. */
379 agent_scd_getattr (const char *name
, struct agent_card_info_s
*info
)
382 char line
[ASSUAN_LINELENGTH
];
385 return gpg_error (GPG_ERR_INV_VALUE
);
387 /* We assume that NAME does not need escaping. */
388 if (12 + strlen (name
) > DIM(line
)-1)
389 return gpg_error (GPG_ERR_TOO_LARGE
);
390 stpcpy (stpcpy (line
, "SCD GETATTR "), name
);
396 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, default_inq_cb
, NULL
,
397 learn_status_cb
, info
);
403 /* Send an setattr command to the SCdaemon. SERIALNO is not actually
404 used here but required by gpg 1.4's implementation of this code in
407 agent_scd_setattr (const char *name
,
408 const unsigned char *value
, size_t valuelen
,
409 const char *serialno
)
412 char line
[ASSUAN_LINELENGTH
];
417 if (!*name
|| !valuelen
)
418 return gpg_error (GPG_ERR_INV_VALUE
);
420 /* We assume that NAME does not need escaping. */
421 if (12 + strlen (name
) > DIM(line
)-1)
422 return gpg_error (GPG_ERR_TOO_LARGE
);
424 p
= stpcpy (stpcpy (line
, "SCD SETATTR "), name
);
426 for (; valuelen
; value
++, valuelen
--)
428 if (p
>= line
+ DIM(line
)-5 )
429 return gpg_error (GPG_ERR_TOO_LARGE
);
430 if (*value
< ' ' || *value
== '+' || *value
== '%')
432 sprintf (p
, "%%%02X", *value
);
435 else if (*value
== ' ')
446 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
447 default_inq_cb
, NULL
, NULL
, NULL
);
453 /* Handle a CERTDATA inquiry. Note, we only send the data,
454 assuan_transact takes care of flushing and writing the END
457 inq_writecert_parms (void *opaque
, const char *line
)
460 struct writecert_parm_s
*parm
= opaque
;
462 if (!strncmp (line
, "CERTDATA", 8) && (line
[8]==' '||!line
[8]))
464 rc
= assuan_send_data (parm
->ctx
, parm
->certdata
, parm
->certdatalen
);
467 rc
= default_inq_cb (opaque
, line
);
473 /* Send a WRITECERT command to the SCdaemon. */
475 agent_scd_writecert (const char *certidstr
,
476 const unsigned char *certdata
, size_t certdatalen
)
479 char line
[ASSUAN_LINELENGTH
];
480 struct writecert_parm_s parms
;
486 memset (&parms
, 0, sizeof parms
);
488 snprintf (line
, DIM(line
)-1, "SCD WRITECERT %s", certidstr
);
489 line
[DIM(line
)-1] = 0;
490 parms
.ctx
= agent_ctx
;
491 parms
.certdata
= certdata
;
492 parms
.certdatalen
= certdatalen
;
494 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
495 inq_writecert_parms
, &parms
, NULL
, NULL
);
503 /* Handle a KEYDATA inquiry. Note, we only send the data,
504 assuan_transact takes care of flushing and writing the end */
506 inq_writekey_parms (void *opaque
, const char *line
)
509 struct writekey_parm_s
*parm
= opaque
;
511 if (!strncmp (line
, "KEYDATA", 7) && (line
[7]==' '||!line
[7]))
513 rc
= assuan_send_data (parm
->ctx
, parm
->keydata
, parm
->keydatalen
);
516 rc
= default_inq_cb (opaque
, line
);
522 /* Send a WRITEKEY command to the SCdaemon. */
524 agent_scd_writekey (int keyno
, const char *serialno
,
525 const unsigned char *keydata
, size_t keydatalen
)
528 char line
[ASSUAN_LINELENGTH
];
529 struct writekey_parm_s parms
;
537 memset (&parms
, 0, sizeof parms
);
539 snprintf (line
, DIM(line
)-1, "SCD WRITEKEY --force OPENPGP.%d", keyno
);
540 line
[DIM(line
)-1] = 0;
541 parms
.ctx
= agent_ctx
;
542 parms
.keydata
= keydata
;
543 parms
.keydatalen
= keydatalen
;
545 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
546 inq_writekey_parms
, &parms
, NULL
, NULL
);
554 /* Status callback for the SCD GENKEY command. */
556 scd_genkey_cb (void *opaque
, const char *line
)
558 struct agent_card_genkey_s
*parm
= opaque
;
559 const char *keyword
= line
;
563 log_debug ("got status line `%s'\n", line
);
564 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
566 while (spacep (line
))
569 if (keywordlen
== 7 && !memcmp (keyword
, "KEY-FPR", keywordlen
))
571 parm
->fprvalid
= unhexify_fpr (line
, parm
->fpr
);
573 if (keywordlen
== 8 && !memcmp (keyword
, "KEY-DATA", keywordlen
))
576 const char *name
= line
;
578 while (*line
&& !spacep (line
))
580 while (spacep (line
))
583 rc
= gcry_mpi_scan (&a
, GCRYMPI_FMT_HEX
, line
, 0, NULL
);
585 log_error ("error parsing received key data: %s\n", gpg_strerror (rc
));
586 else if (*name
== 'n' && spacep (name
+1))
588 else if (*name
== 'e' && spacep (name
+1))
592 log_info ("unknown parameter name in received key data\n");
593 gcry_mpi_release (a
);
596 else if (keywordlen
== 14 && !memcmp (keyword
,"KEY-CREATED-AT", keywordlen
))
598 parm
->created_at
= (u32
)strtoul (line
, NULL
, 10);
604 /* Send a GENKEY command to the SCdaemon. SERIALNO is not used in
605 this implementation. If CREATEDATE has been given, it will be
606 passed to SCDAEMON so that the key can be created with this
607 timestamp; note the user needs to use the returned timestamp as old
608 versions of scddaemon don't support this option. */
610 agent_scd_genkey (struct agent_card_genkey_s
*info
, int keyno
, int force
,
611 const char *serialno
, u32 createtime
)
614 char line
[ASSUAN_LINELENGTH
];
615 gnupg_isotime_t tbuf
;
624 epoch2isotime (tbuf
, createtime
);
628 memset (info
, 0, sizeof *info
);
629 snprintf (line
, DIM(line
)-1, "SCD GENKEY %s%s %s %d",
630 *tbuf
? "--timestamp=":"", tbuf
,
633 line
[DIM(line
)-1] = 0;
635 memset (info
, 0, sizeof *info
);
636 rc
= assuan_transact (agent_ctx
, line
,
637 NULL
, NULL
, default_inq_cb
, NULL
,
638 scd_genkey_cb
, info
);
645 membuf_data_cb (void *opaque
, const void *buffer
, size_t length
)
647 membuf_t
*data
= opaque
;
650 put_membuf (data
, buffer
, length
);
654 /* Send a sign command to the scdaemon via gpg-agent's pass thru
657 agent_scd_pksign (const char *serialno
, int hashalgo
,
658 const unsigned char *indata
, size_t indatalen
,
659 unsigned char **r_buf
, size_t *r_buflen
)
662 char *p
, line
[ASSUAN_LINELENGTH
];
666 /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */
675 if (indatalen
*2 + 50 > DIM(line
))
676 return gpg_error (GPG_ERR_GENERAL
);
678 /* Send the serialno command to initialize the connection. We don't
679 care about the data returned. If the card has already been
680 initialized, this is a very fast command. We request the openpgp
681 card because that is waht we expect. */
682 rc
= assuan_transact (agent_ctx
, "SCD SERIALNO openpgp",
683 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
687 sprintf (line
, "SCD SETDATA ");
688 p
= line
+ strlen (line
);
689 for (i
=0; i
< indatalen
; i
++, p
+= 2 )
690 sprintf (p
, "%02X", indata
[i
]);
691 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
695 init_membuf (&data
, 1024);
697 if (!hashalgo
) /* Temporary test hack. */
698 snprintf (line
, DIM(line
)-1, "SCD PKAUTH %s", serialno
);
701 snprintf (line
, DIM(line
)-1, "SCD PKSIGN %s%s",
702 hashalgo
== GCRY_MD_RMD160
? "--hash=rmd160 " : "",
704 line
[DIM(line
)-1] = 0;
705 rc
= assuan_transact (agent_ctx
, line
, membuf_data_cb
, &data
,
706 default_inq_cb
, NULL
, NULL
, NULL
);
709 xfree (get_membuf (&data
, &len
));
712 *r_buf
= get_membuf (&data
, r_buflen
);
718 /* Decrypt INDATA of length INDATALEN using the card identified by
719 SERIALNO. Return the plaintext in a nwly allocated buffer stored
720 at the address of R_BUF.
722 Note, we currently support only RSA or more exactly algorithms
723 taking one input data element. */
725 agent_scd_pkdecrypt (const char *serialno
,
726 const unsigned char *indata
, size_t indatalen
,
727 unsigned char **r_buf
, size_t *r_buflen
)
730 char *p
, line
[ASSUAN_LINELENGTH
];
739 /* FIXME: use secure memory where appropriate */
740 if (indatalen
*2 + 50 > DIM(line
))
741 return gpg_error (GPG_ERR_GENERAL
);
743 /* Send the serialno command to initialize the connection. We don't
744 care about the data returned. If the card has already been
745 initialized, this is a very fast command. We request the openpgp
746 card because that is waht we expect. */
747 rc
= assuan_transact (agent_ctx
, "SCD SERIALNO openpgp",
748 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
752 sprintf (line
, "SCD SETDATA ");
753 p
= line
+ strlen (line
);
754 for (i
=0; i
< indatalen
; i
++, p
+= 2 )
755 sprintf (p
, "%02X", indata
[i
]);
756 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
760 init_membuf (&data
, 1024);
761 snprintf (line
, DIM(line
)-1, "SCD PKDECRYPT %s", serialno
);
762 line
[DIM(line
)-1] = 0;
763 rc
= assuan_transact (agent_ctx
, line
,
764 membuf_data_cb
, &data
,
765 default_inq_cb
, NULL
, NULL
, NULL
);
768 xfree (get_membuf (&data
, &len
));
771 *r_buf
= get_membuf (&data
, r_buflen
);
773 return gpg_error (GPG_ERR_ENOMEM
);
779 /* Change the PIN of an OpenPGP card or reset the retry counter.
780 CHVNO 1: Change the PIN
781 2: For v1 cards: Same as 1.
782 For v2 cards: Reset the PIN using the Reset Code.
783 3: Change the admin PIN
784 101: Set a new PIN and reset the retry counter
785 102: For v1 cars: Same as 101.
786 For v2 cards: Set a new Reset Code.
787 SERIALNO is not used.
790 agent_scd_change_pin (int chvno
, const char *serialno
)
793 char line
[ASSUAN_LINELENGTH
];
794 const char *reset
= "";
806 snprintf (line
, DIM(line
)-1, "SCD PASSWD %s %d", reset
, chvno
);
807 line
[DIM(line
)-1] = 0;
808 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
809 default_inq_cb
, NULL
, NULL
, NULL
);
814 /* Perform a CHECKPIN operation. SERIALNO should be the serial
815 number of the card - optionally followed by the fingerprint;
816 however the fingerprint is ignored here. */
818 agent_scd_checkpin (const char *serialno
)
821 char line
[ASSUAN_LINELENGTH
];
827 snprintf (line
, DIM(line
)-1, "SCD CHECKPIN %s", serialno
);
828 line
[DIM(line
)-1] = 0;
829 return assuan_transact (agent_ctx
, line
,
831 default_inq_cb
, NULL
, NULL
, NULL
);
835 /* Dummy function, only used by the gpg 1.4 implementation. */
837 agent_clear_pin_cache (const char *sn
)
845 /* Note: All strings shall be UTF-8. On success the caller needs to
846 free the string stored at R_PASSPHRASE. On error NULL will be
847 stored at R_PASSPHRASE and an appropriate fpf error code
850 agent_get_passphrase (const char *cache_id
,
853 const char *desc_msg
,
858 char line
[ASSUAN_LINELENGTH
];
865 *r_passphrase
= NULL
;
871 /* Check that the gpg-agent understands the repeat option. */
872 if (assuan_transact (agent_ctx
,
873 "GETINFO cmd_has_option GET_PASSPHRASE repeat",
874 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
))
875 return gpg_error (GPG_ERR_NOT_SUPPORTED
);
877 if (cache_id
&& *cache_id
)
878 if (!(arg1
= percent_plus_escape (cache_id
)))
880 if (err_msg
&& *err_msg
)
881 if (!(arg2
= percent_plus_escape (err_msg
)))
883 if (prompt
&& *prompt
)
884 if (!(arg3
= percent_plus_escape (prompt
)))
886 if (desc_msg
&& *desc_msg
)
887 if (!(arg4
= percent_plus_escape (desc_msg
)))
890 snprintf (line
, DIM(line
)-1,
891 "GET_PASSPHRASE --data --repeat=%d -- %s %s %s %s",
897 line
[DIM(line
)-1] = 0;
903 init_membuf_secure (&data
, 64);
904 rc
= assuan_transact (agent_ctx
, line
,
905 membuf_data_cb
, &data
,
906 default_inq_cb
, NULL
, NULL
, NULL
);
909 xfree (get_membuf (&data
, NULL
));
912 put_membuf (&data
, "", 1);
913 *r_passphrase
= get_membuf (&data
, NULL
);
915 rc
= gpg_error_from_syserror ();
919 rc
= gpg_error_from_syserror ();
929 agent_clear_passphrase (const char *cache_id
)
932 char line
[ASSUAN_LINELENGTH
];
934 if (!cache_id
|| !*cache_id
)
941 snprintf (line
, DIM(line
)-1, "CLEAR_PASSPHRASE %s", cache_id
);
942 line
[DIM(line
)-1] = 0;
943 return assuan_transact (agent_ctx
, line
, NULL
, NULL
,
944 default_inq_cb
, NULL
, NULL
, NULL
);