Line data Source code
1 : /* call-agent.c - Divert GPG operations to the agent.
2 : * Copyright (C) 2001-2003, 2006-2011, 2013 Free Software Foundation, Inc.
3 : * Copyright (C) 2013-2015 Werner Koch
4 : *
5 : * This file is part of GnuPG.
6 : *
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.
11 : *
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.
16 : *
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/>.
19 : */
20 :
21 : #include <config.h>
22 : #include <stdio.h>
23 : #include <stdlib.h>
24 : #include <string.h>
25 : #include <errno.h>
26 : #include <unistd.h>
27 : #include <time.h>
28 : #ifdef HAVE_LOCALE_H
29 : #include <locale.h>
30 : #endif
31 :
32 : #include "gpg.h"
33 : #include <assuan.h>
34 : #include "util.h"
35 : #include "membuf.h"
36 : #include "options.h"
37 : #include "i18n.h"
38 : #include "asshelp.h"
39 : #include "sysutils.h"
40 : #include "call-agent.h"
41 : #include "status.h"
42 : #include "../common/shareddefs.h"
43 : #include "host2net.h"
44 :
45 : #define CONTROL_D ('D' - 'A' + 1)
46 :
47 :
48 : static assuan_context_t agent_ctx = NULL;
49 : static int did_early_card_test;
50 :
51 : struct default_inq_parm_s
52 : {
53 : ctrl_t ctrl;
54 : assuan_context_t ctx;
55 : struct {
56 : u32 *keyid;
57 : u32 *mainkeyid;
58 : int pubkey_algo;
59 : } keyinfo;
60 : };
61 :
62 : struct cipher_parm_s
63 : {
64 : struct default_inq_parm_s *dflt;
65 : assuan_context_t ctx;
66 : unsigned char *ciphertext;
67 : size_t ciphertextlen;
68 : };
69 :
70 : struct writecert_parm_s
71 : {
72 : struct default_inq_parm_s *dflt;
73 : const unsigned char *certdata;
74 : size_t certdatalen;
75 : };
76 :
77 : struct writekey_parm_s
78 : {
79 : struct default_inq_parm_s *dflt;
80 : const unsigned char *keydata;
81 : size_t keydatalen;
82 : };
83 :
84 : struct genkey_parm_s
85 : {
86 : struct default_inq_parm_s *dflt;
87 : const char *keyparms;
88 : const char *passphrase;
89 : };
90 :
91 : struct import_key_parm_s
92 : {
93 : struct default_inq_parm_s *dflt;
94 : const void *key;
95 : size_t keylen;
96 : };
97 :
98 :
99 : struct cache_nonce_parm_s
100 : {
101 : char **cache_nonce_addr;
102 : char **passwd_nonce_addr;
103 : };
104 :
105 :
106 : struct scd_genkey_parm_s
107 : {
108 : struct agent_card_genkey_s *cgk;
109 : char *savedbytes; /* Malloced space to save key parameter chunks. */
110 : };
111 :
112 :
113 : static gpg_error_t learn_status_cb (void *opaque, const char *line);
114 :
115 :
116 :
117 : /* If RC is not 0, write an appropriate status message. */
118 : static void
119 0 : status_sc_op_failure (int rc)
120 : {
121 0 : switch (gpg_err_code (rc))
122 : {
123 : case 0:
124 0 : break;
125 : case GPG_ERR_CANCELED:
126 : case GPG_ERR_FULLY_CANCELED:
127 0 : write_status_text (STATUS_SC_OP_FAILURE, "1");
128 0 : break;
129 : case GPG_ERR_BAD_PIN:
130 0 : write_status_text (STATUS_SC_OP_FAILURE, "2");
131 0 : break;
132 : default:
133 0 : write_status (STATUS_SC_OP_FAILURE);
134 0 : break;
135 : }
136 0 : }
137 :
138 :
139 : /* This is the default inquiry callback. It mainly handles the
140 : Pinentry notifications. */
141 : static gpg_error_t
142 1 : default_inq_cb (void *opaque, const char *line)
143 : {
144 1 : gpg_error_t err = 0;
145 1 : struct default_inq_parm_s *parm = opaque;
146 :
147 1 : if (has_leading_keyword (line, "PINENTRY_LAUNCHED"))
148 : {
149 1 : err = gpg_proxy_pinentry_notify (parm->ctrl, line);
150 1 : if (err)
151 0 : log_error (_("failed to proxy %s inquiry to client\n"),
152 : "PINENTRY_LAUNCHED");
153 : /* We do not pass errors to avoid breaking other code. */
154 : }
155 0 : else if ((has_leading_keyword (line, "PASSPHRASE")
156 0 : || has_leading_keyword (line, "NEW_PASSPHRASE"))
157 0 : && opt.pinentry_mode == PINENTRY_MODE_LOOPBACK)
158 : {
159 0 : if (have_static_passphrase ())
160 : {
161 0 : const char *s = get_static_passphrase ();
162 0 : err = assuan_send_data (parm->ctx, s, strlen (s));
163 : }
164 : else
165 : {
166 : char *pw;
167 : char buf[32];
168 :
169 0 : if (parm->keyinfo.keyid)
170 0 : emit_status_need_passphrase (parm->keyinfo.keyid,
171 : parm->keyinfo.mainkeyid,
172 : parm->keyinfo.pubkey_algo);
173 :
174 0 : snprintf (buf, sizeof (buf), "%u", 100);
175 0 : write_status_text (STATUS_INQUIRE_MAXLEN, buf);
176 0 : pw = cpr_get_hidden ("passphrase.enter", _("Enter passphrase: "));
177 0 : cpr_kill_prompt ();
178 0 : if (*pw == CONTROL_D && !pw[1])
179 0 : err = gpg_error (GPG_ERR_CANCELED);
180 : else
181 0 : err = assuan_send_data (parm->ctx, pw, strlen (pw));
182 0 : xfree (pw);
183 : }
184 : }
185 : else
186 0 : log_debug ("ignoring gpg-agent inquiry '%s'\n", line);
187 :
188 1 : return err;
189 : }
190 :
191 :
192 : /* Check whether gnome-keyring hijacked the gpg-agent. */
193 : static void
194 443 : check_hijacking (assuan_context_t ctx)
195 : {
196 : membuf_t mb;
197 : char *string;
198 :
199 443 : init_membuf (&mb, 64);
200 :
201 : /* AGENT_ID is a command implemented by gnome-keyring-daemon. It
202 : does not return any data but an OK line with a remark. */
203 443 : if (assuan_transact (ctx, "AGENT_ID",
204 : put_membuf_cb, &mb, NULL, NULL, NULL, NULL))
205 : {
206 443 : xfree (get_membuf (&mb, NULL));
207 886 : return; /* Error - Probably not hijacked. */
208 : }
209 0 : put_membuf (&mb, "", 1);
210 0 : string = get_membuf (&mb, NULL);
211 0 : if (!string || !*string)
212 : {
213 : /* Definitely hijacked - show a warning prompt. */
214 : static int shown;
215 0 : const char warn1[] =
216 : "The GNOME keyring manager hijacked the GnuPG agent.";
217 0 : const char warn2[] =
218 : "GnuPG will not work properly - please configure that "
219 : "tool to not interfere with the GnuPG system!";
220 0 : log_info ("WARNING: %s\n", warn1);
221 0 : log_info ("WARNING: %s\n", warn2);
222 : /* (GPG_ERR_SOURCRE_GPG, GPG_ERR_NO_AGENT) */
223 0 : write_status_text (STATUS_ERROR, "check_hijacking 33554509");
224 0 : xfree (string);
225 0 : string = strconcat (warn1, "\n\n", warn2, NULL);
226 0 : if (string && !shown && !opt.batch)
227 : {
228 : /* NB: The Pinentry based prompt will only work if a
229 : gnome-keyring manager passes invalid commands on to the
230 : original gpg-agent. */
231 : char *cmd, *cmdargs;
232 :
233 0 : cmdargs = percent_plus_escape (string);
234 0 : cmd = strconcat ("GET_CONFIRMATION ", cmdargs, NULL);
235 0 : xfree (cmdargs);
236 0 : if (cmd)
237 : {
238 : struct default_inq_parm_s dfltparm;
239 :
240 0 : memset (&dfltparm, 0, sizeof dfltparm);
241 0 : dfltparm.ctx = ctx;
242 0 : assuan_transact (ctx, cmd, NULL, NULL,
243 : default_inq_cb, &dfltparm,
244 : NULL, NULL);
245 0 : xfree (cmd);
246 0 : shown = 1;
247 : }
248 : }
249 : }
250 0 : xfree (string);
251 : }
252 :
253 :
254 :
255 : /* Print a warning if the server's version number is less than our
256 : version number. Returns an error code on a connection problem. */
257 : static gpg_error_t
258 443 : warn_version_mismatch (assuan_context_t ctx, const char *servername, int mode)
259 : {
260 : gpg_error_t err;
261 : char *serverversion;
262 443 : const char *myversion = strusage (13);
263 :
264 443 : err = get_assuan_server_version (ctx, mode, &serverversion);
265 443 : if (err)
266 0 : log_error (_("error getting version from '%s': %s\n"),
267 : servername, gpg_strerror (err));
268 443 : else if (!compare_version_strings (serverversion, myversion))
269 : {
270 : char *warn;
271 :
272 0 : warn = xtryasprintf (_("server '%s' is older than us (%s < %s)"),
273 : servername, serverversion, myversion);
274 0 : if (!warn)
275 0 : err = gpg_error_from_syserror ();
276 : else
277 : {
278 0 : log_info (_("WARNING: %s\n"), warn);
279 0 : write_status_strings (STATUS_WARNING, "server_version_mismatch 0",
280 : " ", warn, NULL);
281 0 : xfree (warn);
282 : }
283 : }
284 443 : xfree (serverversion);
285 443 : return err;
286 : }
287 :
288 :
289 : /* Try to connect to the agent via socket or fork it off and work by
290 : pipes. Handle the server's initial greeting */
291 : static int
292 1517 : start_agent (ctrl_t ctrl, int for_card)
293 : {
294 : int rc;
295 :
296 : (void)ctrl; /* Not yet used. */
297 :
298 : /* Fixme: We need a context for each thread or serialize the access
299 : to the agent. */
300 1517 : if (agent_ctx)
301 1074 : rc = 0;
302 : else
303 : {
304 886 : rc = start_new_gpg_agent (&agent_ctx,
305 : GPG_ERR_SOURCE_DEFAULT,
306 : opt.agent_program,
307 443 : opt.lc_ctype, opt.lc_messages,
308 : opt.session_env,
309 443 : opt.autostart, opt.verbose, DBG_IPC,
310 : NULL, NULL);
311 443 : if (!opt.autostart && gpg_err_code (rc) == GPG_ERR_NO_AGENT)
312 0 : {
313 : static int shown;
314 :
315 0 : if (!shown)
316 : {
317 0 : shown = 1;
318 0 : log_info (_("no gpg-agent running in this session\n"));
319 : }
320 : }
321 443 : else if (!rc
322 443 : && !(rc = warn_version_mismatch (agent_ctx, GPG_AGENT_NAME, 0)))
323 : {
324 : /* Tell the agent that we support Pinentry notifications.
325 : No error checking so that it will work also with older
326 : agents. */
327 443 : assuan_transact (agent_ctx, "OPTION allow-pinentry-notify",
328 : NULL, NULL, NULL, NULL, NULL, NULL);
329 : /* Tell the agent about what version we are aware. This is
330 : here used to indirectly enable GPG_ERR_FULLY_CANCELED. */
331 443 : assuan_transact (agent_ctx, "OPTION agent-awareness=2.1.0",
332 : NULL, NULL, NULL, NULL, NULL, NULL);
333 : /* Pass on the pinentry mode. */
334 443 : if (opt.pinentry_mode)
335 : {
336 0 : char *tmp = xasprintf ("OPTION pinentry-mode=%s",
337 0 : str_pinentry_mode (opt.pinentry_mode));
338 0 : rc = assuan_transact (agent_ctx, tmp,
339 : NULL, NULL, NULL, NULL, NULL, NULL);
340 0 : xfree (tmp);
341 0 : if (rc)
342 : {
343 0 : log_error ("setting pinentry mode '%s' failed: %s\n",
344 0 : str_pinentry_mode (opt.pinentry_mode),
345 : gpg_strerror (rc));
346 0 : write_status_error ("set_pinentry_mode", rc);
347 : }
348 : }
349 :
350 443 : check_hijacking (agent_ctx);
351 : }
352 : }
353 :
354 1517 : if (!rc && for_card && !did_early_card_test)
355 : {
356 : /* Request the serial number of the card for an early test. */
357 : struct agent_card_info_s info;
358 :
359 0 : memset (&info, 0, sizeof info);
360 :
361 0 : rc = warn_version_mismatch (agent_ctx, SCDAEMON_NAME, 2);
362 0 : if (!rc)
363 0 : rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
364 : NULL, NULL, NULL, NULL,
365 : learn_status_cb, &info);
366 0 : if (rc)
367 : {
368 0 : switch (gpg_err_code (rc))
369 : {
370 : case GPG_ERR_NOT_SUPPORTED:
371 : case GPG_ERR_NO_SCDAEMON:
372 0 : write_status_text (STATUS_CARDCTRL, "6");
373 0 : break;
374 : case GPG_ERR_OBJ_TERM_STATE:
375 0 : write_status_text (STATUS_CARDCTRL, "7");
376 0 : break;
377 : default:
378 0 : write_status_text (STATUS_CARDCTRL, "4");
379 0 : log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
380 0 : break;
381 : }
382 : }
383 :
384 0 : if (!rc && is_status_enabled () && info.serialno)
385 : {
386 : char *buf;
387 :
388 0 : buf = xasprintf ("3 %s", info.serialno);
389 0 : write_status_text (STATUS_CARDCTRL, buf);
390 0 : xfree (buf);
391 : }
392 :
393 0 : agent_release_card_info (&info);
394 :
395 0 : if (!rc)
396 0 : did_early_card_test = 1;
397 : }
398 :
399 :
400 1517 : return rc;
401 : }
402 :
403 :
404 : /* Return a new malloced string by unescaping the string S. Escaping
405 : is percent escaping and '+'/space mapping. A binary nul will
406 : silently be replaced by a 0xFF. Function returns NULL to indicate
407 : an out of memory status. */
408 : static char *
409 0 : unescape_status_string (const unsigned char *s)
410 : {
411 0 : return percent_plus_unescape (s, 0xff);
412 : }
413 :
414 :
415 : /* Take a 20 byte hexencoded string and put it into the the provided
416 : 20 byte buffer FPR in binary format. */
417 : static int
418 0 : unhexify_fpr (const char *hexstr, unsigned char *fpr)
419 : {
420 : const char *s;
421 : int n;
422 :
423 0 : for (s=hexstr, n=0; hexdigitp (s); s++, n++)
424 : ;
425 0 : if (*s || (n != 40))
426 0 : return 0; /* no fingerprint (invalid or wrong length). */
427 0 : for (s=hexstr, n=0; *s; s += 2, n++)
428 0 : fpr[n] = xtoi_2 (s);
429 0 : return 1; /* okay */
430 : }
431 :
432 : /* Take the serial number from LINE and return it verbatim in a newly
433 : allocated string. We make sure that only hex characters are
434 : returned. */
435 : static char *
436 0 : store_serialno (const char *line)
437 : {
438 : const char *s;
439 : char *p;
440 :
441 0 : for (s=line; hexdigitp (s); s++)
442 : ;
443 0 : p = xtrymalloc (s + 1 - line);
444 0 : if (p)
445 : {
446 0 : memcpy (p, line, s-line);
447 0 : p[s-line] = 0;
448 : }
449 0 : return p;
450 : }
451 :
452 :
453 :
454 : /* This is a dummy data line callback. */
455 : static gpg_error_t
456 0 : dummy_data_cb (void *opaque, const void *buffer, size_t length)
457 : {
458 : (void)opaque;
459 : (void)buffer;
460 : (void)length;
461 0 : return 0;
462 : }
463 :
464 : /* A simple callback used to return the serialnumber of a card. */
465 : static gpg_error_t
466 0 : get_serialno_cb (void *opaque, const char *line)
467 : {
468 0 : char **serialno = opaque;
469 0 : const char *keyword = line;
470 : const char *s;
471 : int keywordlen, n;
472 :
473 0 : for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
474 : ;
475 0 : while (spacep (line))
476 0 : line++;
477 :
478 0 : if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
479 : {
480 0 : if (*serialno)
481 0 : return gpg_error (GPG_ERR_CONFLICT); /* Unexpected status line. */
482 0 : for (n=0,s=line; hexdigitp (s); s++, n++)
483 : ;
484 0 : if (!n || (n&1)|| !(spacep (s) || !*s) )
485 0 : return gpg_error (GPG_ERR_ASS_PARAMETER);
486 0 : *serialno = xtrymalloc (n+1);
487 0 : if (!*serialno)
488 0 : return out_of_core ();
489 0 : memcpy (*serialno, line, n);
490 0 : (*serialno)[n] = 0;
491 : }
492 :
493 0 : return 0;
494 : }
495 :
496 :
497 :
498 : /* Release the card info structure INFO. */
499 : void
500 0 : agent_release_card_info (struct agent_card_info_s *info)
501 : {
502 : int i;
503 :
504 0 : if (!info)
505 0 : return;
506 :
507 0 : xfree (info->reader); info->reader = NULL;
508 0 : xfree (info->serialno); info->serialno = NULL;
509 0 : xfree (info->apptype); info->apptype = NULL;
510 0 : xfree (info->disp_name); info->disp_name = NULL;
511 0 : xfree (info->disp_lang); info->disp_lang = NULL;
512 0 : xfree (info->pubkey_url); info->pubkey_url = NULL;
513 0 : xfree (info->login_data); info->login_data = NULL;
514 0 : info->cafpr1valid = info->cafpr2valid = info->cafpr3valid = 0;
515 0 : info->fpr1valid = info->fpr2valid = info->fpr3valid = 0;
516 0 : for (i=0; i < DIM(info->private_do); i++)
517 : {
518 0 : xfree (info->private_do[i]);
519 0 : info->private_do[i] = NULL;
520 : }
521 : }
522 :
523 :
524 : static gpg_error_t
525 0 : learn_status_cb (void *opaque, const char *line)
526 : {
527 0 : struct agent_card_info_s *parm = opaque;
528 0 : const char *keyword = line;
529 : int keywordlen;
530 : int i;
531 :
532 0 : for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
533 : ;
534 0 : while (spacep (line))
535 0 : line++;
536 :
537 0 : if (keywordlen == 6 && !memcmp (keyword, "READER", keywordlen))
538 : {
539 0 : xfree (parm->reader);
540 0 : parm->reader = unescape_status_string (line);
541 : }
542 0 : else if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
543 : {
544 0 : xfree (parm->serialno);
545 0 : parm->serialno = store_serialno (line);
546 0 : parm->is_v2 = (strlen (parm->serialno) >= 16
547 0 : && xtoi_2 (parm->serialno+12) >= 2 );
548 : }
549 0 : else if (keywordlen == 7 && !memcmp (keyword, "APPTYPE", keywordlen))
550 : {
551 0 : xfree (parm->apptype);
552 0 : parm->apptype = unescape_status_string (line);
553 : }
554 0 : else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen))
555 : {
556 0 : xfree (parm->disp_name);
557 0 : parm->disp_name = unescape_status_string (line);
558 : }
559 0 : else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen))
560 : {
561 0 : xfree (parm->disp_lang);
562 0 : parm->disp_lang = unescape_status_string (line);
563 : }
564 0 : else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen))
565 : {
566 0 : parm->disp_sex = *line == '1'? 1 : *line == '2' ? 2: 0;
567 : }
568 0 : else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen))
569 : {
570 0 : xfree (parm->pubkey_url);
571 0 : parm->pubkey_url = unescape_status_string (line);
572 : }
573 0 : else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen))
574 : {
575 0 : xfree (parm->login_data);
576 0 : parm->login_data = unescape_status_string (line);
577 : }
578 0 : else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen))
579 : {
580 0 : parm->sig_counter = strtoul (line, NULL, 0);
581 : }
582 0 : else if (keywordlen == 10 && !memcmp (keyword, "CHV-STATUS", keywordlen))
583 0 : {
584 : char *p, *buf;
585 :
586 0 : buf = p = unescape_status_string (line);
587 0 : if (buf)
588 : {
589 0 : while (spacep (p))
590 0 : p++;
591 0 : parm->chv1_cached = atoi (p);
592 0 : while (*p && !spacep (p))
593 0 : p++;
594 0 : while (spacep (p))
595 0 : p++;
596 0 : for (i=0; *p && i < 3; i++)
597 : {
598 0 : parm->chvmaxlen[i] = atoi (p);
599 0 : while (*p && !spacep (p))
600 0 : p++;
601 0 : while (spacep (p))
602 0 : p++;
603 : }
604 0 : for (i=0; *p && i < 3; i++)
605 : {
606 0 : parm->chvretry[i] = atoi (p);
607 0 : while (*p && !spacep (p))
608 0 : p++;
609 0 : while (spacep (p))
610 0 : p++;
611 : }
612 0 : xfree (buf);
613 : }
614 : }
615 0 : else if (keywordlen == 6 && !memcmp (keyword, "EXTCAP", keywordlen))
616 0 : {
617 : char *p, *p2, *buf;
618 : int abool;
619 :
620 0 : buf = p = unescape_status_string (line);
621 0 : if (buf)
622 : {
623 0 : for (p = strtok (buf, " "); p; p = strtok (NULL, " "))
624 : {
625 0 : p2 = strchr (p, '=');
626 0 : if (p2)
627 : {
628 0 : *p2++ = 0;
629 0 : abool = (*p2 == '1');
630 0 : if (!strcmp (p, "ki"))
631 0 : parm->extcap.ki = abool;
632 0 : else if (!strcmp (p, "aac"))
633 0 : parm->extcap.aac = abool;
634 0 : else if (!strcmp (p, "si"))
635 0 : parm->status_indicator = strtoul (p2, NULL, 10);
636 : }
637 : }
638 0 : xfree (buf);
639 : }
640 : }
641 0 : else if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
642 0 : {
643 0 : int no = atoi (line);
644 0 : while (*line && !spacep (line))
645 0 : line++;
646 0 : while (spacep (line))
647 0 : line++;
648 0 : if (no == 1)
649 0 : parm->fpr1valid = unhexify_fpr (line, parm->fpr1);
650 0 : else if (no == 2)
651 0 : parm->fpr2valid = unhexify_fpr (line, parm->fpr2);
652 0 : else if (no == 3)
653 0 : parm->fpr3valid = unhexify_fpr (line, parm->fpr3);
654 : }
655 0 : else if (keywordlen == 8 && !memcmp (keyword, "KEY-TIME", keywordlen))
656 0 : {
657 0 : int no = atoi (line);
658 0 : while (* line && !spacep (line))
659 0 : line++;
660 0 : while (spacep (line))
661 0 : line++;
662 0 : if (no == 1)
663 0 : parm->fpr1time = strtoul (line, NULL, 10);
664 0 : else if (no == 2)
665 0 : parm->fpr2time = strtoul (line, NULL, 10);
666 0 : else if (no == 3)
667 0 : parm->fpr3time = strtoul (line, NULL, 10);
668 : }
669 0 : else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen))
670 0 : {
671 0 : int no = atoi (line);
672 0 : while (*line && !spacep (line))
673 0 : line++;
674 0 : while (spacep (line))
675 0 : line++;
676 0 : if (no == 1)
677 0 : parm->cafpr1valid = unhexify_fpr (line, parm->cafpr1);
678 0 : else if (no == 2)
679 0 : parm->cafpr2valid = unhexify_fpr (line, parm->cafpr2);
680 0 : else if (no == 3)
681 0 : parm->cafpr3valid = unhexify_fpr (line, parm->cafpr3);
682 : }
683 0 : else if (keywordlen == 8 && !memcmp (keyword, "KEY-ATTR", keywordlen))
684 0 : {
685 0 : int keyno = 0;
686 0 : int algo = PUBKEY_ALGO_RSA;
687 0 : int n = 0;
688 :
689 0 : sscanf (line, "%d %d %n", &keyno, &algo, &n);
690 0 : keyno--;
691 0 : if (keyno < 0 || keyno >= DIM (parm->key_attr))
692 0 : return 0;
693 :
694 0 : parm->key_attr[keyno].algo = algo;
695 0 : if (algo == PUBKEY_ALGO_RSA)
696 0 : parm->key_attr[keyno].nbits = strtoul (line+n+3, NULL, 10);
697 0 : else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA
698 0 : || algo == PUBKEY_ALGO_EDDSA)
699 : {
700 : const char *curve;
701 :
702 0 : for (i = 0; (curve = openpgp_enum_curves (&i));)
703 0 : if (!strcmp (curve, line+n))
704 0 : break;
705 :
706 0 : parm->key_attr[keyno].curve = curve;
707 : }
708 : }
709 0 : else if (keywordlen == 12 && !memcmp (keyword, "PRIVATE-DO-", 11)
710 0 : && strchr("1234", keyword[11]))
711 : {
712 0 : int no = keyword[11] - '1';
713 0 : log_assert (no >= 0 && no <= 3);
714 0 : xfree (parm->private_do[no]);
715 0 : parm->private_do[no] = unescape_status_string (line);
716 : }
717 :
718 0 : return 0;
719 : }
720 :
721 : /* Call the scdaemon to learn about a smartcard */
722 : int
723 0 : agent_scd_learn (struct agent_card_info_s *info, int force)
724 : {
725 : int rc;
726 : struct default_inq_parm_s parm;
727 : struct agent_card_info_s dummyinfo;
728 :
729 0 : if (!info)
730 0 : info = &dummyinfo;
731 0 : memset (info, 0, sizeof *info);
732 0 : memset (&parm, 0, sizeof parm);
733 :
734 0 : rc = start_agent (NULL, 1);
735 0 : if (rc)
736 0 : return rc;
737 :
738 : /* Send the serialno command to initialize the connection. We don't
739 : care about the data returned. If the card has already been
740 : initialized, this is a very fast command. The main reason we
741 : need to do this here is to handle a card removed case so that an
742 : "l" command in --card-edit can be used to show ta newly inserted
743 : card. We request the openpgp card because that is what we
744 : expect. */
745 0 : rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
746 : NULL, NULL, NULL, NULL, NULL, NULL);
747 0 : if (rc)
748 0 : return rc;
749 :
750 0 : parm.ctx = agent_ctx;
751 0 : rc = assuan_transact (agent_ctx,
752 : force ? "LEARN --sendinfo --force" : "LEARN --sendinfo",
753 : dummy_data_cb, NULL, default_inq_cb, &parm,
754 : learn_status_cb, info);
755 : /* Also try to get the key attributes. */
756 0 : if (!rc)
757 0 : agent_scd_getattr ("KEY-ATTR", info);
758 :
759 0 : if (info == &dummyinfo)
760 0 : agent_release_card_info (info);
761 :
762 0 : return rc;
763 : }
764 :
765 :
766 : /* Send an APDU to the current card. On success the status word is
767 : stored at R_SW. With HEXAPDU being NULL only a RESET command is
768 : send to scd. With HEXAPDU being the string "undefined" the command
769 : "SERIALNO undefined" is send to scd. */
770 : gpg_error_t
771 0 : agent_scd_apdu (const char *hexapdu, unsigned int *r_sw)
772 : {
773 : gpg_error_t err;
774 :
775 : /* Start the agent but not with the card flag so that we do not
776 : autoselect the openpgp application. */
777 0 : err = start_agent (NULL, 0);
778 0 : if (err)
779 0 : return err;
780 :
781 0 : if (!hexapdu)
782 : {
783 0 : err = assuan_transact (agent_ctx, "SCD RESET",
784 : NULL, NULL, NULL, NULL, NULL, NULL);
785 :
786 : }
787 0 : else if (!strcmp (hexapdu, "undefined"))
788 : {
789 0 : err = assuan_transact (agent_ctx, "SCD SERIALNO undefined",
790 : NULL, NULL, NULL, NULL, NULL, NULL);
791 : }
792 : else
793 : {
794 : char line[ASSUAN_LINELENGTH];
795 : membuf_t mb;
796 : unsigned char *data;
797 : size_t datalen;
798 :
799 0 : init_membuf (&mb, 256);
800 :
801 0 : snprintf (line, DIM(line)-1, "SCD APDU %s", hexapdu);
802 0 : err = assuan_transact (agent_ctx, line,
803 : put_membuf_cb, &mb, NULL, NULL, NULL, NULL);
804 0 : if (!err)
805 : {
806 0 : data = get_membuf (&mb, &datalen);
807 0 : if (!data)
808 0 : err = gpg_error_from_syserror ();
809 0 : else if (datalen < 2) /* Ooops */
810 0 : err = gpg_error (GPG_ERR_CARD);
811 : else
812 : {
813 0 : *r_sw = buf16_to_uint (data+datalen-2);
814 : }
815 0 : xfree (data);
816 : }
817 : }
818 :
819 0 : return err;
820 : }
821 :
822 :
823 : int
824 0 : agent_keytocard (const char *hexgrip, int keyno, int force,
825 : const char *serialno, const char *timestamp)
826 : {
827 : int rc;
828 : char line[ASSUAN_LINELENGTH];
829 : struct default_inq_parm_s parm;
830 :
831 0 : memset (&parm, 0, sizeof parm);
832 0 : parm.ctx = agent_ctx;
833 :
834 0 : snprintf (line, DIM(line)-1, "KEYTOCARD %s%s %s OPENPGP.%d %s",
835 : force?"--force ": "", hexgrip, serialno, keyno, timestamp);
836 0 : line[DIM(line)-1] = 0;
837 :
838 0 : rc = start_agent (NULL, 1);
839 0 : if (rc)
840 0 : return rc;
841 :
842 0 : rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, &parm,
843 : NULL, NULL);
844 0 : if (rc)
845 0 : return rc;
846 :
847 0 : return rc;
848 : }
849 :
850 : /* Call the agent to retrieve a data object. This function returns
851 : the data in the same structure as used by the learn command. It is
852 : allowed to update such a structure using this commmand. */
853 : int
854 0 : agent_scd_getattr (const char *name, struct agent_card_info_s *info)
855 : {
856 : int rc;
857 : char line[ASSUAN_LINELENGTH];
858 : struct default_inq_parm_s parm;
859 :
860 0 : memset (&parm, 0, sizeof parm);
861 :
862 0 : if (!*name)
863 0 : return gpg_error (GPG_ERR_INV_VALUE);
864 :
865 : /* We assume that NAME does not need escaping. */
866 0 : if (12 + strlen (name) > DIM(line)-1)
867 0 : return gpg_error (GPG_ERR_TOO_LARGE);
868 0 : stpcpy (stpcpy (line, "SCD GETATTR "), name);
869 :
870 0 : rc = start_agent (NULL, 1);
871 0 : if (rc)
872 0 : return rc;
873 :
874 0 : parm.ctx = agent_ctx;
875 0 : rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, &parm,
876 : learn_status_cb, info);
877 :
878 0 : return rc;
879 : }
880 :
881 :
882 : /* Send an setattr command to the SCdaemon. SERIALNO is not actually
883 : used here but required by gpg 1.4's implementation of this code in
884 : cardglue.c. */
885 : int
886 0 : agent_scd_setattr (const char *name,
887 : const unsigned char *value, size_t valuelen,
888 : const char *serialno)
889 : {
890 : int rc;
891 : char line[ASSUAN_LINELENGTH];
892 : char *p;
893 : struct default_inq_parm_s parm;
894 :
895 0 : memset (&parm, 0, sizeof parm);
896 :
897 : (void)serialno;
898 :
899 0 : if (!*name || !valuelen)
900 0 : return gpg_error (GPG_ERR_INV_VALUE);
901 :
902 : /* We assume that NAME does not need escaping. */
903 0 : if (12 + strlen (name) > DIM(line)-1)
904 0 : return gpg_error (GPG_ERR_TOO_LARGE);
905 :
906 0 : p = stpcpy (stpcpy (line, "SCD SETATTR "), name);
907 0 : *p++ = ' ';
908 0 : for (; valuelen; value++, valuelen--)
909 : {
910 0 : if (p >= line + DIM(line)-5 )
911 0 : return gpg_error (GPG_ERR_TOO_LARGE);
912 0 : if (*value < ' ' || *value == '+' || *value == '%')
913 : {
914 0 : sprintf (p, "%%%02X", *value);
915 0 : p += 3;
916 : }
917 0 : else if (*value == ' ')
918 0 : *p++ = '+';
919 : else
920 0 : *p++ = *value;
921 : }
922 0 : *p = 0;
923 :
924 0 : rc = start_agent (NULL, 1);
925 0 : if (!rc)
926 : {
927 0 : parm.ctx = agent_ctx;
928 0 : rc = assuan_transact (agent_ctx, line, NULL, NULL,
929 : default_inq_cb, &parm, NULL, NULL);
930 : }
931 :
932 0 : status_sc_op_failure (rc);
933 0 : return rc;
934 : }
935 :
936 :
937 :
938 : /* Handle a CERTDATA inquiry. Note, we only send the data,
939 : assuan_transact takes care of flushing and writing the END
940 : command. */
941 : static gpg_error_t
942 0 : inq_writecert_parms (void *opaque, const char *line)
943 : {
944 : int rc;
945 0 : struct writecert_parm_s *parm = opaque;
946 :
947 0 : if (has_leading_keyword (line, "CERTDATA"))
948 : {
949 0 : rc = assuan_send_data (parm->dflt->ctx,
950 0 : parm->certdata, parm->certdatalen);
951 : }
952 : else
953 0 : rc = default_inq_cb (parm->dflt, line);
954 :
955 0 : return rc;
956 : }
957 :
958 :
959 : /* Send a WRITECERT command to the SCdaemon. */
960 : int
961 0 : agent_scd_writecert (const char *certidstr,
962 : const unsigned char *certdata, size_t certdatalen)
963 : {
964 : int rc;
965 : char line[ASSUAN_LINELENGTH];
966 : struct writecert_parm_s parms;
967 : struct default_inq_parm_s dfltparm;
968 :
969 0 : memset (&dfltparm, 0, sizeof dfltparm);
970 :
971 0 : rc = start_agent (NULL, 1);
972 0 : if (rc)
973 0 : return rc;
974 :
975 0 : memset (&parms, 0, sizeof parms);
976 :
977 0 : snprintf (line, DIM(line)-1, "SCD WRITECERT %s", certidstr);
978 0 : line[DIM(line)-1] = 0;
979 0 : dfltparm.ctx = agent_ctx;
980 0 : parms.dflt = &dfltparm;
981 0 : parms.certdata = certdata;
982 0 : parms.certdatalen = certdatalen;
983 :
984 0 : rc = assuan_transact (agent_ctx, line, NULL, NULL,
985 : inq_writecert_parms, &parms, NULL, NULL);
986 :
987 0 : return rc;
988 : }
989 :
990 :
991 :
992 : /* Handle a KEYDATA inquiry. Note, we only send the data,
993 : assuan_transact takes care of flushing and writing the end */
994 : static gpg_error_t
995 0 : inq_writekey_parms (void *opaque, const char *line)
996 : {
997 : int rc;
998 0 : struct writekey_parm_s *parm = opaque;
999 :
1000 0 : if (has_leading_keyword (line, "KEYDATA"))
1001 : {
1002 0 : rc = assuan_send_data (parm->dflt->ctx, parm->keydata, parm->keydatalen);
1003 : }
1004 : else
1005 0 : rc = default_inq_cb (parm->dflt, line);
1006 :
1007 0 : return rc;
1008 : }
1009 :
1010 :
1011 : /* Send a WRITEKEY command to the SCdaemon. */
1012 : int
1013 0 : agent_scd_writekey (int keyno, const char *serialno,
1014 : const unsigned char *keydata, size_t keydatalen)
1015 : {
1016 : int rc;
1017 : char line[ASSUAN_LINELENGTH];
1018 : struct writekey_parm_s parms;
1019 : struct default_inq_parm_s dfltparm;
1020 :
1021 0 : memset (&dfltparm, 0, sizeof dfltparm);
1022 :
1023 : (void)serialno;
1024 :
1025 0 : rc = start_agent (NULL, 1);
1026 0 : if (rc)
1027 0 : return rc;
1028 :
1029 0 : memset (&parms, 0, sizeof parms);
1030 :
1031 0 : snprintf (line, DIM(line)-1, "SCD WRITEKEY --force OPENPGP.%d", keyno);
1032 0 : line[DIM(line)-1] = 0;
1033 0 : dfltparm.ctx = agent_ctx;
1034 0 : parms.dflt = &dfltparm;
1035 0 : parms.keydata = keydata;
1036 0 : parms.keydatalen = keydatalen;
1037 :
1038 0 : rc = assuan_transact (agent_ctx, line, NULL, NULL,
1039 : inq_writekey_parms, &parms, NULL, NULL);
1040 :
1041 0 : status_sc_op_failure (rc);
1042 0 : return rc;
1043 : }
1044 :
1045 :
1046 :
1047 : static gpg_error_t
1048 0 : scd_genkey_cb_append_savedbytes (struct scd_genkey_parm_s *parm,
1049 : const char *line)
1050 : {
1051 0 : gpg_error_t err = 0;
1052 : char *p;
1053 :
1054 0 : if (!parm->savedbytes)
1055 : {
1056 0 : parm->savedbytes = xtrystrdup (line);
1057 0 : if (!parm->savedbytes)
1058 0 : err = gpg_error_from_syserror ();
1059 : }
1060 : else
1061 : {
1062 0 : p = xtrymalloc (strlen (parm->savedbytes) + strlen (line) + 1);
1063 0 : if (!p)
1064 0 : err = gpg_error_from_syserror ();
1065 : else
1066 : {
1067 0 : strcpy (stpcpy (p, parm->savedbytes), line);
1068 0 : xfree (parm->savedbytes);
1069 0 : parm->savedbytes = p;
1070 : }
1071 : }
1072 :
1073 0 : return err;
1074 : }
1075 :
1076 : /* Status callback for the SCD GENKEY command. */
1077 : static gpg_error_t
1078 0 : scd_genkey_cb (void *opaque, const char *line)
1079 : {
1080 0 : struct scd_genkey_parm_s *parm = opaque;
1081 0 : const char *keyword = line;
1082 : int keywordlen;
1083 0 : gpg_error_t rc = 0;
1084 :
1085 0 : for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1086 : ;
1087 0 : while (spacep (line))
1088 0 : line++;
1089 :
1090 0 : if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
1091 : {
1092 0 : parm->cgk->fprvalid = unhexify_fpr (line, parm->cgk->fpr);
1093 : }
1094 0 : else if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen))
1095 0 : {
1096 : gcry_mpi_t a;
1097 0 : const char *name = line;
1098 :
1099 0 : while (*line && !spacep (line))
1100 0 : line++;
1101 0 : while (spacep (line))
1102 0 : line++;
1103 :
1104 0 : if (*name == '-' && spacep (name+1))
1105 0 : rc = scd_genkey_cb_append_savedbytes (parm, line);
1106 : else
1107 : {
1108 0 : if (parm->savedbytes)
1109 : {
1110 0 : rc = scd_genkey_cb_append_savedbytes (parm, line);
1111 0 : if (!rc)
1112 0 : rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX,
1113 0 : parm->savedbytes, 0, NULL);
1114 : }
1115 : else
1116 0 : rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL);
1117 0 : if (rc)
1118 0 : log_error ("error parsing received key data: %s\n",
1119 : gpg_strerror (rc));
1120 0 : else if (*name == 'n' && spacep (name+1))
1121 0 : parm->cgk->n = a;
1122 0 : else if (*name == 'e' && spacep (name+1))
1123 0 : parm->cgk->e = a;
1124 : else
1125 : {
1126 0 : log_info ("unknown parameter name in received key data\n");
1127 0 : gcry_mpi_release (a);
1128 0 : rc = gpg_error (GPG_ERR_INV_PARAMETER);
1129 : }
1130 :
1131 0 : xfree (parm->savedbytes);
1132 0 : parm->savedbytes = NULL;
1133 : }
1134 : }
1135 0 : else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
1136 : {
1137 0 : parm->cgk->created_at = (u32)strtoul (line, NULL, 10);
1138 : }
1139 0 : else if (keywordlen == 8 && !memcmp (keyword, "PROGRESS", keywordlen))
1140 : {
1141 0 : write_status_text (STATUS_PROGRESS, line);
1142 : }
1143 :
1144 0 : return rc;
1145 : }
1146 :
1147 : /* Send a GENKEY command to the SCdaemon. SERIALNO is not used in
1148 : this implementation. If CREATEDATE is not 0, it will be passed to
1149 : SCDAEMON so that the key is created with this timestamp. INFO will
1150 : receive information about the generated key. */
1151 : int
1152 0 : agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
1153 : const char *serialno, u32 createtime)
1154 : {
1155 : int rc;
1156 : char line[ASSUAN_LINELENGTH];
1157 : gnupg_isotime_t tbuf;
1158 : struct scd_genkey_parm_s parms;
1159 : struct default_inq_parm_s dfltparm;
1160 :
1161 0 : memset (&dfltparm, 0, sizeof dfltparm);
1162 :
1163 : (void)serialno;
1164 :
1165 0 : memset (&parms, 0, sizeof parms);
1166 0 : parms.cgk = info;
1167 :
1168 0 : rc = start_agent (NULL, 1);
1169 0 : if (rc)
1170 0 : return rc;
1171 :
1172 0 : if (createtime)
1173 0 : epoch2isotime (tbuf, createtime);
1174 : else
1175 0 : *tbuf = 0;
1176 :
1177 0 : snprintf (line, DIM(line)-1, "SCD GENKEY %s%s %s %d",
1178 0 : *tbuf? "--timestamp=":"", tbuf,
1179 : force? "--force":"",
1180 : keyno);
1181 0 : line[DIM(line)-1] = 0;
1182 :
1183 0 : dfltparm.ctx = agent_ctx;
1184 0 : memset (info, 0, sizeof *info);
1185 0 : rc = assuan_transact (agent_ctx, line,
1186 : NULL, NULL, default_inq_cb, &dfltparm,
1187 : scd_genkey_cb, &parms);
1188 :
1189 0 : xfree (parms.savedbytes);
1190 :
1191 0 : status_sc_op_failure (rc);
1192 0 : return rc;
1193 : }
1194 :
1195 :
1196 :
1197 :
1198 : /* Issue an SCD SERIALNO openpgp command and if SERIALNO is not NULL
1199 : ask the user to insert the requested card. */
1200 : gpg_error_t
1201 0 : select_openpgp (const char *serialno)
1202 : {
1203 : gpg_error_t err;
1204 :
1205 : /* Send the serialno command to initialize the connection. Without
1206 : a given S/N we don't care about the data returned. If the card
1207 : has already been initialized, this is a very fast command. We
1208 : request the openpgp card because that is what we expect.
1209 :
1210 : Note that an opt.limit_card_insert_tries of 1 means: No tries at
1211 : all whereas 0 means do not limit the number of tries. Due to the
1212 : sue of a pinentry prompt with a cancel option we use it here in a
1213 : boolean sense. */
1214 0 : if (!serialno || opt.limit_card_insert_tries == 1)
1215 0 : err = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
1216 : NULL, NULL, NULL, NULL, NULL, NULL);
1217 : else
1218 : {
1219 0 : char *this_sn = NULL;
1220 : char *desc;
1221 : int ask;
1222 : char *want_sn;
1223 : char *p;
1224 :
1225 0 : want_sn = xtrystrdup (serialno);
1226 0 : if (!want_sn)
1227 0 : return gpg_error_from_syserror ();
1228 0 : p = strchr (want_sn, '/');
1229 0 : if (p)
1230 0 : *p = 0;
1231 :
1232 : do
1233 : {
1234 0 : ask = 0;
1235 0 : err = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
1236 : NULL, NULL, NULL, NULL,
1237 : get_serialno_cb, &this_sn);
1238 0 : if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT)
1239 0 : ask = 1;
1240 0 : else if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED)
1241 0 : ask = 2;
1242 0 : else if (err)
1243 : ;
1244 0 : else if (this_sn)
1245 : {
1246 0 : if (strcmp (want_sn, this_sn))
1247 0 : ask = 2;
1248 : }
1249 :
1250 0 : xfree (this_sn);
1251 0 : this_sn = NULL;
1252 :
1253 0 : if (ask)
1254 : {
1255 0 : char *formatted = NULL;
1256 0 : char *ocodeset = i18n_switchto_utf8 ();
1257 :
1258 0 : if (!strncmp (want_sn, "D27600012401", 12)
1259 0 : && strlen (want_sn) == 32 )
1260 0 : formatted = xtryasprintf ("(%.4s) %.8s",
1261 : want_sn + 16, want_sn + 20);
1262 :
1263 0 : err = 0;
1264 0 : desc = xtryasprintf
1265 : ("%s:\n\n"
1266 : " \"%s\"",
1267 : ask == 1
1268 : ? _("Please insert the card with serial number")
1269 : : _("Please remove the current card and "
1270 : "insert the one with serial number"),
1271 : formatted? formatted : want_sn);
1272 0 : if (!desc)
1273 0 : err = gpg_error_from_syserror ();
1274 0 : xfree (formatted);
1275 0 : i18n_switchback (ocodeset);
1276 0 : if (!err)
1277 0 : err = gpg_agent_get_confirmation (desc);
1278 0 : xfree (desc);
1279 : }
1280 : }
1281 0 : while (ask && !err);
1282 0 : xfree (want_sn);
1283 : }
1284 :
1285 0 : return err;
1286 : }
1287 :
1288 :
1289 :
1290 : /* Send a READCERT command to the SCdaemon. */
1291 : int
1292 0 : agent_scd_readcert (const char *certidstr,
1293 : void **r_buf, size_t *r_buflen)
1294 : {
1295 : int rc;
1296 : char line[ASSUAN_LINELENGTH];
1297 : membuf_t data;
1298 : size_t len;
1299 : struct default_inq_parm_s dfltparm;
1300 :
1301 0 : memset (&dfltparm, 0, sizeof dfltparm);
1302 :
1303 0 : *r_buf = NULL;
1304 0 : rc = start_agent (NULL, 1);
1305 0 : if (rc)
1306 0 : return rc;
1307 :
1308 0 : dfltparm.ctx = agent_ctx;
1309 :
1310 0 : init_membuf (&data, 2048);
1311 :
1312 0 : snprintf (line, DIM(line)-1, "SCD READCERT %s", certidstr);
1313 0 : line[DIM(line)-1] = 0;
1314 0 : rc = assuan_transact (agent_ctx, line,
1315 : put_membuf_cb, &data,
1316 : default_inq_cb, &dfltparm,
1317 : NULL, NULL);
1318 0 : if (rc)
1319 : {
1320 0 : xfree (get_membuf (&data, &len));
1321 0 : return rc;
1322 : }
1323 0 : *r_buf = get_membuf (&data, r_buflen);
1324 0 : if (!*r_buf)
1325 0 : return gpg_error (GPG_ERR_ENOMEM);
1326 :
1327 0 : return 0;
1328 : }
1329 :
1330 :
1331 :
1332 : /* Change the PIN of an OpenPGP card or reset the retry counter.
1333 : CHVNO 1: Change the PIN
1334 : 2: For v1 cards: Same as 1.
1335 : For v2 cards: Reset the PIN using the Reset Code.
1336 : 3: Change the admin PIN
1337 : 101: Set a new PIN and reset the retry counter
1338 : 102: For v1 cars: Same as 101.
1339 : For v2 cards: Set a new Reset Code.
1340 : SERIALNO is not used.
1341 : */
1342 : int
1343 0 : agent_scd_change_pin (int chvno, const char *serialno)
1344 : {
1345 : int rc;
1346 : char line[ASSUAN_LINELENGTH];
1347 0 : const char *reset = "";
1348 : struct default_inq_parm_s dfltparm;
1349 :
1350 0 : memset (&dfltparm, 0, sizeof dfltparm);
1351 :
1352 : (void)serialno;
1353 :
1354 0 : if (chvno >= 100)
1355 0 : reset = "--reset";
1356 0 : chvno %= 100;
1357 :
1358 0 : rc = start_agent (NULL, 1);
1359 0 : if (rc)
1360 0 : return rc;
1361 0 : dfltparm.ctx = agent_ctx;
1362 :
1363 0 : snprintf (line, DIM(line)-1, "SCD PASSWD %s %d", reset, chvno);
1364 0 : line[DIM(line)-1] = 0;
1365 0 : rc = assuan_transact (agent_ctx, line,
1366 : NULL, NULL,
1367 : default_inq_cb, &dfltparm,
1368 : NULL, NULL);
1369 0 : status_sc_op_failure (rc);
1370 0 : return rc;
1371 : }
1372 :
1373 :
1374 : /* Perform a CHECKPIN operation. SERIALNO should be the serial
1375 : number of the card - optionally followed by the fingerprint;
1376 : however the fingerprint is ignored here. */
1377 : int
1378 0 : agent_scd_checkpin (const char *serialno)
1379 : {
1380 : int rc;
1381 : char line[ASSUAN_LINELENGTH];
1382 : struct default_inq_parm_s dfltparm;
1383 :
1384 0 : memset (&dfltparm, 0, sizeof dfltparm);
1385 :
1386 0 : rc = start_agent (NULL, 1);
1387 0 : if (rc)
1388 0 : return rc;
1389 0 : dfltparm.ctx = agent_ctx;
1390 :
1391 0 : snprintf (line, DIM(line)-1, "SCD CHECKPIN %s", serialno);
1392 0 : line[DIM(line)-1] = 0;
1393 0 : rc = assuan_transact (agent_ctx, line,
1394 : NULL, NULL,
1395 : default_inq_cb, &dfltparm,
1396 : NULL, NULL);
1397 0 : status_sc_op_failure (rc);
1398 0 : return rc;
1399 : }
1400 :
1401 :
1402 : /* Dummy function, only used by the gpg 1.4 implementation. */
1403 : void
1404 0 : agent_clear_pin_cache (const char *sn)
1405 : {
1406 : (void)sn;
1407 0 : }
1408 :
1409 :
1410 :
1411 :
1412 : /* Note: All strings shall be UTF-8. On success the caller needs to
1413 : free the string stored at R_PASSPHRASE. On error NULL will be
1414 : stored at R_PASSPHRASE and an appropriate fpf error code
1415 : returned. */
1416 : gpg_error_t
1417 0 : agent_get_passphrase (const char *cache_id,
1418 : const char *err_msg,
1419 : const char *prompt,
1420 : const char *desc_msg,
1421 : int repeat,
1422 : int check,
1423 : char **r_passphrase)
1424 : {
1425 : int rc;
1426 : char line[ASSUAN_LINELENGTH];
1427 0 : char *arg1 = NULL;
1428 0 : char *arg2 = NULL;
1429 0 : char *arg3 = NULL;
1430 0 : char *arg4 = NULL;
1431 : membuf_t data;
1432 : struct default_inq_parm_s dfltparm;
1433 :
1434 0 : memset (&dfltparm, 0, sizeof dfltparm);
1435 :
1436 0 : *r_passphrase = NULL;
1437 :
1438 0 : rc = start_agent (NULL, 0);
1439 0 : if (rc)
1440 0 : return rc;
1441 0 : dfltparm.ctx = agent_ctx;
1442 :
1443 : /* Check that the gpg-agent understands the repeat option. */
1444 0 : if (assuan_transact (agent_ctx,
1445 : "GETINFO cmd_has_option GET_PASSPHRASE repeat",
1446 : NULL, NULL, NULL, NULL, NULL, NULL))
1447 0 : return gpg_error (GPG_ERR_NOT_SUPPORTED);
1448 :
1449 0 : if (cache_id && *cache_id)
1450 0 : if (!(arg1 = percent_plus_escape (cache_id)))
1451 0 : goto no_mem;
1452 0 : if (err_msg && *err_msg)
1453 0 : if (!(arg2 = percent_plus_escape (err_msg)))
1454 0 : goto no_mem;
1455 0 : if (prompt && *prompt)
1456 0 : if (!(arg3 = percent_plus_escape (prompt)))
1457 0 : goto no_mem;
1458 0 : if (desc_msg && *desc_msg)
1459 0 : if (!(arg4 = percent_plus_escape (desc_msg)))
1460 0 : goto no_mem;
1461 :
1462 0 : snprintf (line, DIM(line)-1,
1463 : "GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s",
1464 : repeat,
1465 : check? " --check --qualitybar":"",
1466 : arg1? arg1:"X",
1467 : arg2? arg2:"X",
1468 : arg3? arg3:"X",
1469 : arg4? arg4:"X");
1470 0 : line[DIM(line)-1] = 0;
1471 0 : xfree (arg1);
1472 0 : xfree (arg2);
1473 0 : xfree (arg3);
1474 0 : xfree (arg4);
1475 :
1476 0 : init_membuf_secure (&data, 64);
1477 0 : rc = assuan_transact (agent_ctx, line,
1478 : put_membuf_cb, &data,
1479 : default_inq_cb, &dfltparm,
1480 : NULL, NULL);
1481 :
1482 0 : if (rc)
1483 0 : xfree (get_membuf (&data, NULL));
1484 : else
1485 : {
1486 0 : put_membuf (&data, "", 1);
1487 0 : *r_passphrase = get_membuf (&data, NULL);
1488 0 : if (!*r_passphrase)
1489 0 : rc = gpg_error_from_syserror ();
1490 : }
1491 0 : return rc;
1492 : no_mem:
1493 0 : rc = gpg_error_from_syserror ();
1494 0 : xfree (arg1);
1495 0 : xfree (arg2);
1496 0 : xfree (arg3);
1497 0 : xfree (arg4);
1498 0 : return rc;
1499 : }
1500 :
1501 :
1502 : gpg_error_t
1503 0 : agent_clear_passphrase (const char *cache_id)
1504 : {
1505 : int rc;
1506 : char line[ASSUAN_LINELENGTH];
1507 : struct default_inq_parm_s dfltparm;
1508 :
1509 0 : memset (&dfltparm, 0, sizeof dfltparm);
1510 :
1511 0 : if (!cache_id || !*cache_id)
1512 0 : return 0;
1513 :
1514 0 : rc = start_agent (NULL, 0);
1515 0 : if (rc)
1516 0 : return rc;
1517 0 : dfltparm.ctx = agent_ctx;
1518 :
1519 0 : snprintf (line, DIM(line)-1, "CLEAR_PASSPHRASE %s", cache_id);
1520 0 : line[DIM(line)-1] = 0;
1521 0 : return assuan_transact (agent_ctx, line,
1522 : NULL, NULL,
1523 : default_inq_cb, &dfltparm,
1524 : NULL, NULL);
1525 : }
1526 :
1527 :
1528 : /* Ask the agent to pop up a confirmation dialog with the text DESC
1529 : and an okay and cancel button. */
1530 : gpg_error_t
1531 0 : gpg_agent_get_confirmation (const char *desc)
1532 : {
1533 : int rc;
1534 : char *tmp;
1535 : char line[ASSUAN_LINELENGTH];
1536 : struct default_inq_parm_s dfltparm;
1537 :
1538 0 : memset (&dfltparm, 0, sizeof dfltparm);
1539 :
1540 0 : rc = start_agent (NULL, 0);
1541 0 : if (rc)
1542 0 : return rc;
1543 0 : dfltparm.ctx = agent_ctx;
1544 :
1545 0 : tmp = percent_plus_escape (desc);
1546 0 : if (!tmp)
1547 0 : return gpg_error_from_syserror ();
1548 0 : snprintf (line, DIM(line)-1, "GET_CONFIRMATION %s", tmp);
1549 0 : line[DIM(line)-1] = 0;
1550 0 : xfree (tmp);
1551 :
1552 0 : rc = assuan_transact (agent_ctx, line,
1553 : NULL, NULL,
1554 : default_inq_cb, &dfltparm,
1555 : NULL, NULL);
1556 0 : return rc;
1557 : }
1558 :
1559 :
1560 : /* Return the S2K iteration count as computed by gpg-agent. */
1561 : gpg_error_t
1562 3 : agent_get_s2k_count (unsigned long *r_count)
1563 : {
1564 : gpg_error_t err;
1565 : membuf_t data;
1566 : char *buf;
1567 :
1568 3 : *r_count = 0;
1569 :
1570 3 : err = start_agent (NULL, 0);
1571 3 : if (err)
1572 0 : return err;
1573 :
1574 3 : init_membuf (&data, 32);
1575 3 : err = assuan_transact (agent_ctx, "GETINFO s2k_count",
1576 : put_membuf_cb, &data,
1577 : NULL, NULL, NULL, NULL);
1578 3 : if (err)
1579 0 : xfree (get_membuf (&data, NULL));
1580 : else
1581 : {
1582 3 : put_membuf (&data, "", 1);
1583 3 : buf = get_membuf (&data, NULL);
1584 3 : if (!buf)
1585 0 : err = gpg_error_from_syserror ();
1586 : else
1587 : {
1588 3 : *r_count = strtoul (buf, NULL, 10);
1589 3 : xfree (buf);
1590 : }
1591 : }
1592 3 : return err;
1593 : }
1594 :
1595 :
1596 :
1597 : /* Ask the agent whether a secret key for the given public key is
1598 : available. Returns 0 if available. */
1599 : gpg_error_t
1600 592 : agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk)
1601 : {
1602 : gpg_error_t err;
1603 : char line[ASSUAN_LINELENGTH];
1604 : char *hexgrip;
1605 :
1606 592 : err = start_agent (ctrl, 0);
1607 592 : if (err)
1608 0 : return err;
1609 :
1610 592 : err = hexkeygrip_from_pk (pk, &hexgrip);
1611 592 : if (err)
1612 0 : return err;
1613 :
1614 592 : snprintf (line, sizeof line, "HAVEKEY %s", hexgrip);
1615 592 : xfree (hexgrip);
1616 :
1617 592 : err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1618 592 : return err;
1619 : }
1620 :
1621 : /* Ask the agent whether a secret key is available for any of the
1622 : keys (primary or sub) in KEYBLOCK. Returns 0 if available. */
1623 : gpg_error_t
1624 413 : agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock)
1625 : {
1626 : gpg_error_t err;
1627 : char line[ASSUAN_LINELENGTH];
1628 : char *p;
1629 : kbnode_t kbctx, node;
1630 : int nkeys;
1631 : unsigned char grip[20];
1632 :
1633 413 : err = start_agent (ctrl, 0);
1634 413 : if (err)
1635 0 : return err;
1636 :
1637 413 : err = gpg_error (GPG_ERR_NO_SECKEY); /* Just in case no key was
1638 : found in KEYBLOCK. */
1639 413 : p = stpcpy (line, "HAVEKEY");
1640 3303 : for (kbctx=NULL, nkeys=0; (node = walk_kbnode (keyblock, &kbctx, 0)); )
1641 2477 : if (node->pkt->pkttype == PKT_PUBLIC_KEY
1642 2064 : || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
1643 1623 : || node->pkt->pkttype == PKT_SECRET_KEY
1644 1623 : || node->pkt->pkttype == PKT_SECRET_SUBKEY)
1645 : {
1646 854 : if (nkeys && ((p - line) + 41) > (ASSUAN_LINELENGTH - 2))
1647 : {
1648 0 : err = assuan_transact (agent_ctx, line,
1649 : NULL, NULL, NULL, NULL, NULL, NULL);
1650 0 : if (err != gpg_err_code (GPG_ERR_NO_SECKEY))
1651 0 : break; /* Seckey available or unexpected error - ready. */
1652 0 : p = stpcpy (line, "HAVEKEY");
1653 0 : nkeys = 0;
1654 : }
1655 :
1656 854 : err = keygrip_from_pk (node->pkt->pkt.public_key, grip);
1657 854 : if (err)
1658 0 : return err;
1659 854 : *p++ = ' ';
1660 854 : bin2hex (grip, 20, p);
1661 854 : p += 40;
1662 854 : nkeys++;
1663 : }
1664 :
1665 413 : if (!err && nkeys)
1666 413 : err = assuan_transact (agent_ctx, line,
1667 : NULL, NULL, NULL, NULL, NULL, NULL);
1668 :
1669 413 : return err;
1670 : }
1671 :
1672 :
1673 :
1674 : struct keyinfo_data_parm_s
1675 : {
1676 : char *serialno;
1677 : int cleartext;
1678 : };
1679 :
1680 :
1681 : static gpg_error_t
1682 52 : keyinfo_status_cb (void *opaque, const char *line)
1683 : {
1684 52 : struct keyinfo_data_parm_s *data = opaque;
1685 : int is_smartcard;
1686 : char *s;
1687 :
1688 52 : if ((s = has_leading_keyword (line, "KEYINFO")) && data)
1689 : {
1690 : /* Parse the arguments:
1691 : * 0 1 2 3 4 5
1692 : * <keygrip> <type> <serialno> <idstr> <cached> <protection>
1693 : */
1694 : char *fields[6];
1695 :
1696 52 : if (split_fields (s, fields, DIM (fields)) == 6)
1697 : {
1698 52 : is_smartcard = (fields[1][0] == 'T');
1699 52 : if (is_smartcard && !data->serialno && strcmp (fields[2], "-"))
1700 0 : data->serialno = xtrystrdup (fields[2]);
1701 : /* 'P' for protected, 'C' for clear */
1702 52 : data->cleartext = (fields[5][0] == 'C');
1703 : }
1704 : }
1705 52 : return 0;
1706 : }
1707 :
1708 :
1709 : /* Return the serial number for a secret key. If the returned serial
1710 : number is NULL, the key is not stored on a smartcard. Caller needs
1711 : to free R_SERIALNO.
1712 :
1713 : if r_cleartext is not NULL, the referenced int will be set to 1 if
1714 : the agent's copy of the key is stored in the clear, or 0 otherwise
1715 : */
1716 : gpg_error_t
1717 52 : agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
1718 : char **r_serialno, int *r_cleartext)
1719 : {
1720 : gpg_error_t err;
1721 : char line[ASSUAN_LINELENGTH];
1722 : struct keyinfo_data_parm_s keyinfo;
1723 :
1724 52 : memset (&keyinfo, 0,sizeof keyinfo);
1725 :
1726 52 : *r_serialno = NULL;
1727 :
1728 52 : err = start_agent (ctrl, 0);
1729 52 : if (err)
1730 0 : return err;
1731 :
1732 52 : if (!hexkeygrip || strlen (hexkeygrip) != 40)
1733 0 : return gpg_error (GPG_ERR_INV_VALUE);
1734 :
1735 52 : snprintf (line, DIM(line)-1, "KEYINFO %s", hexkeygrip);
1736 52 : line[DIM(line)-1] = 0;
1737 :
1738 52 : err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL,
1739 : keyinfo_status_cb, &keyinfo);
1740 52 : if (!err && keyinfo.serialno)
1741 : {
1742 : /* Sanity check for bad characters. */
1743 0 : if (strpbrk (keyinfo.serialno, ":\n\r"))
1744 0 : err = GPG_ERR_INV_VALUE;
1745 : }
1746 52 : if (err)
1747 0 : xfree (keyinfo.serialno);
1748 : else
1749 : {
1750 52 : *r_serialno = keyinfo.serialno;
1751 52 : if (r_cleartext)
1752 5 : *r_cleartext = keyinfo.cleartext;
1753 : }
1754 52 : return err;
1755 : }
1756 :
1757 :
1758 : /* Status callback for agent_import_key, agent_export_key and
1759 : agent_genkey. */
1760 : static gpg_error_t
1761 421 : cache_nonce_status_cb (void *opaque, const char *line)
1762 : {
1763 421 : struct cache_nonce_parm_s *parm = opaque;
1764 : const char *s;
1765 :
1766 421 : if ((s = has_leading_keyword (line, "CACHE_NONCE")))
1767 : {
1768 2 : if (parm->cache_nonce_addr)
1769 : {
1770 2 : xfree (*parm->cache_nonce_addr);
1771 2 : *parm->cache_nonce_addr = xtrystrdup (s);
1772 : }
1773 : }
1774 419 : else if ((s = has_leading_keyword (line, "PASSWD_NONCE")))
1775 : {
1776 0 : if (parm->passwd_nonce_addr)
1777 : {
1778 0 : xfree (*parm->passwd_nonce_addr);
1779 0 : *parm->passwd_nonce_addr = xtrystrdup (s);
1780 : }
1781 : }
1782 419 : else if ((s = has_leading_keyword (line, "PROGRESS")))
1783 : {
1784 416 : if (opt.enable_progress_filter)
1785 0 : write_status_text (STATUS_PROGRESS, s);
1786 : }
1787 :
1788 421 : return 0;
1789 : }
1790 :
1791 :
1792 :
1793 : /* Handle a KEYPARMS inquiry. Note, we only send the data,
1794 : assuan_transact takes care of flushing and writing the end */
1795 : static gpg_error_t
1796 3 : inq_genkey_parms (void *opaque, const char *line)
1797 : {
1798 3 : struct genkey_parm_s *parm = opaque;
1799 : gpg_error_t err;
1800 :
1801 3 : if (has_leading_keyword (line, "KEYPARAM"))
1802 : {
1803 6 : err = assuan_send_data (parm->dflt->ctx,
1804 3 : parm->keyparms, strlen (parm->keyparms));
1805 : }
1806 0 : else if (has_leading_keyword (line, "NEWPASSWD") && parm->passphrase)
1807 : {
1808 0 : err = assuan_send_data (parm->dflt->ctx,
1809 0 : parm->passphrase, strlen (parm->passphrase));
1810 : }
1811 : else
1812 0 : err = default_inq_cb (parm->dflt, line);
1813 :
1814 3 : return err;
1815 : }
1816 :
1817 :
1818 : /* Call the agent to generate a new key. KEYPARMS is the usual
1819 : S-expression giving the parameters of the key. gpg-agent passes it
1820 : gcry_pk_genkey. If NO_PROTECTION is true the agent is advised not
1821 : to protect the generated key. If NO_PROTECTION is not set and
1822 : PASSPHRASE is not NULL the agent is requested to protect the key
1823 : with that passphrase instead of asking for one. */
1824 : gpg_error_t
1825 3 : agent_genkey (ctrl_t ctrl, char **cache_nonce_addr, char **passwd_nonce_addr,
1826 : const char *keyparms, int no_protection,
1827 : const char *passphrase, gcry_sexp_t *r_pubkey)
1828 : {
1829 : gpg_error_t err;
1830 : struct genkey_parm_s gk_parm;
1831 : struct cache_nonce_parm_s cn_parm;
1832 : struct default_inq_parm_s dfltparm;
1833 : membuf_t data;
1834 : size_t len;
1835 : unsigned char *buf;
1836 : char line[ASSUAN_LINELENGTH];
1837 :
1838 3 : memset (&dfltparm, 0, sizeof dfltparm);
1839 3 : dfltparm.ctrl = ctrl;
1840 :
1841 3 : *r_pubkey = NULL;
1842 3 : err = start_agent (ctrl, 0);
1843 3 : if (err)
1844 0 : return err;
1845 3 : dfltparm.ctx = agent_ctx;
1846 :
1847 3 : if (passwd_nonce_addr && *passwd_nonce_addr)
1848 : ; /* A RESET would flush the passwd nonce cache. */
1849 : else
1850 : {
1851 3 : err = assuan_transact (agent_ctx, "RESET",
1852 : NULL, NULL, NULL, NULL, NULL, NULL);
1853 3 : if (err)
1854 0 : return err;
1855 : }
1856 :
1857 3 : init_membuf (&data, 1024);
1858 3 : gk_parm.dflt = &dfltparm;
1859 3 : gk_parm.keyparms = keyparms;
1860 3 : gk_parm.passphrase = passphrase;
1861 3 : snprintf (line, sizeof line, "GENKEY%s%s%s%s%s",
1862 : no_protection? " --no-protection" :
1863 0 : passphrase ? " --inq-passwd" :
1864 : /* */ "",
1865 0 : passwd_nonce_addr && *passwd_nonce_addr? " --passwd-nonce=":"",
1866 0 : passwd_nonce_addr && *passwd_nonce_addr? *passwd_nonce_addr:"",
1867 3 : cache_nonce_addr && *cache_nonce_addr? " ":"",
1868 3 : cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"");
1869 3 : cn_parm.cache_nonce_addr = cache_nonce_addr;
1870 3 : cn_parm.passwd_nonce_addr = NULL;
1871 3 : err = assuan_transact (agent_ctx, line,
1872 : put_membuf_cb, &data,
1873 : inq_genkey_parms, &gk_parm,
1874 : cache_nonce_status_cb, &cn_parm);
1875 3 : if (err)
1876 : {
1877 0 : xfree (get_membuf (&data, &len));
1878 0 : return err;
1879 : }
1880 :
1881 3 : buf = get_membuf (&data, &len);
1882 3 : if (!buf)
1883 0 : err = gpg_error_from_syserror ();
1884 : else
1885 : {
1886 3 : err = gcry_sexp_sscan (r_pubkey, NULL, buf, len);
1887 3 : xfree (buf);
1888 : }
1889 3 : return err;
1890 : }
1891 :
1892 :
1893 :
1894 : /* Call the agent to read the public key part for a given keygrip. If
1895 : FROMCARD is true, the key is directly read from the current
1896 : smartcard. In this case HEXKEYGRIP should be the keyID
1897 : (e.g. OPENPGP.3). */
1898 : gpg_error_t
1899 0 : agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip,
1900 : unsigned char **r_pubkey)
1901 : {
1902 : gpg_error_t err;
1903 : membuf_t data;
1904 : size_t len;
1905 : unsigned char *buf;
1906 : char line[ASSUAN_LINELENGTH];
1907 : struct default_inq_parm_s dfltparm;
1908 :
1909 0 : memset (&dfltparm, 0, sizeof dfltparm);
1910 0 : dfltparm.ctrl = ctrl;
1911 :
1912 0 : *r_pubkey = NULL;
1913 0 : err = start_agent (ctrl, 0);
1914 0 : if (err)
1915 0 : return err;
1916 0 : dfltparm.ctx = agent_ctx;
1917 :
1918 0 : err = assuan_transact (agent_ctx, "RESET",NULL, NULL, NULL, NULL, NULL, NULL);
1919 0 : if (err)
1920 0 : return err;
1921 :
1922 0 : snprintf (line, DIM(line)-1, "%sREADKEY %s", fromcard? "SCD ":"", hexkeygrip);
1923 :
1924 0 : init_membuf (&data, 1024);
1925 0 : err = assuan_transact (agent_ctx, line,
1926 : put_membuf_cb, &data,
1927 : default_inq_cb, &dfltparm,
1928 : NULL, NULL);
1929 0 : if (err)
1930 : {
1931 0 : xfree (get_membuf (&data, &len));
1932 0 : return err;
1933 : }
1934 0 : buf = get_membuf (&data, &len);
1935 0 : if (!buf)
1936 0 : return gpg_error_from_syserror ();
1937 0 : if (!gcry_sexp_canon_len (buf, len, NULL, NULL))
1938 : {
1939 0 : xfree (buf);
1940 0 : return gpg_error (GPG_ERR_INV_SEXP);
1941 : }
1942 0 : *r_pubkey = buf;
1943 0 : return 0;
1944 : }
1945 :
1946 :
1947 :
1948 : /* Call the agent to do a sign operation using the key identified by
1949 : the hex string KEYGRIP. DESC is a description of the key to be
1950 : displayed if the agent needs to ask for the PIN. DIGEST and
1951 : DIGESTLEN is the hash value to sign and DIGESTALGO the algorithm id
1952 : used to compute the digest. If CACHE_NONCE is used the agent is
1953 : advised to first try a passphrase associated with that nonce. */
1954 : gpg_error_t
1955 136 : agent_pksign (ctrl_t ctrl, const char *cache_nonce,
1956 : const char *keygrip, const char *desc,
1957 : u32 *keyid, u32 *mainkeyid, int pubkey_algo,
1958 : unsigned char *digest, size_t digestlen, int digestalgo,
1959 : gcry_sexp_t *r_sigval)
1960 : {
1961 : gpg_error_t err;
1962 : char line[ASSUAN_LINELENGTH];
1963 : membuf_t data;
1964 : struct default_inq_parm_s dfltparm;
1965 :
1966 136 : memset (&dfltparm, 0, sizeof dfltparm);
1967 136 : dfltparm.ctrl = ctrl;
1968 136 : dfltparm.keyinfo.keyid = keyid;
1969 136 : dfltparm.keyinfo.mainkeyid = mainkeyid;
1970 136 : dfltparm.keyinfo.pubkey_algo = pubkey_algo;
1971 :
1972 136 : *r_sigval = NULL;
1973 136 : err = start_agent (ctrl, 0);
1974 136 : if (err)
1975 0 : return err;
1976 136 : dfltparm.ctx = agent_ctx;
1977 :
1978 136 : if (digestlen*2 + 50 > DIM(line))
1979 0 : return gpg_error (GPG_ERR_GENERAL);
1980 :
1981 136 : err = assuan_transact (agent_ctx, "RESET",
1982 : NULL, NULL, NULL, NULL, NULL, NULL);
1983 136 : if (err)
1984 0 : return err;
1985 :
1986 136 : snprintf (line, DIM(line)-1, "SIGKEY %s", keygrip);
1987 136 : line[DIM(line)-1] = 0;
1988 136 : err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1989 136 : if (err)
1990 0 : return err;
1991 :
1992 136 : if (desc)
1993 : {
1994 136 : snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
1995 136 : line[DIM(line)-1] = 0;
1996 136 : err = assuan_transact (agent_ctx, line,
1997 : NULL, NULL, NULL, NULL, NULL, NULL);
1998 136 : if (err)
1999 0 : return err;
2000 : }
2001 :
2002 136 : snprintf (line, sizeof line, "SETHASH %d ", digestalgo);
2003 136 : bin2hex (digest, digestlen, line + strlen (line));
2004 136 : err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
2005 136 : if (err)
2006 0 : return err;
2007 :
2008 136 : init_membuf (&data, 1024);
2009 :
2010 136 : snprintf (line, sizeof line, "PKSIGN%s%s",
2011 : cache_nonce? " -- ":"",
2012 : cache_nonce? cache_nonce:"");
2013 136 : err = assuan_transact (agent_ctx, line,
2014 : put_membuf_cb, &data,
2015 : default_inq_cb, &dfltparm,
2016 : NULL, NULL);
2017 136 : if (err)
2018 0 : xfree (get_membuf (&data, NULL));
2019 : else
2020 : {
2021 : unsigned char *buf;
2022 : size_t len;
2023 :
2024 136 : buf = get_membuf (&data, &len);
2025 136 : if (!buf)
2026 0 : err = gpg_error_from_syserror ();
2027 : else
2028 : {
2029 136 : err = gcry_sexp_sscan (r_sigval, NULL, buf, len);
2030 136 : xfree (buf);
2031 : }
2032 : }
2033 136 : return err;
2034 : }
2035 :
2036 :
2037 :
2038 : /* Handle a CIPHERTEXT inquiry. Note, we only send the data,
2039 : assuan_transact takes care of flushing and writing the END. */
2040 : static gpg_error_t
2041 259 : inq_ciphertext_cb (void *opaque, const char *line)
2042 : {
2043 259 : struct cipher_parm_s *parm = opaque;
2044 : int rc;
2045 :
2046 259 : if (has_leading_keyword (line, "CIPHERTEXT"))
2047 : {
2048 259 : assuan_begin_confidential (parm->ctx);
2049 518 : rc = assuan_send_data (parm->dflt->ctx,
2050 259 : parm->ciphertext, parm->ciphertextlen);
2051 259 : assuan_end_confidential (parm->ctx);
2052 : }
2053 : else
2054 0 : rc = default_inq_cb (parm->dflt, line);
2055 :
2056 259 : return rc;
2057 : }
2058 :
2059 :
2060 : /* Check whether there is any padding info from the agent. */
2061 : static gpg_error_t
2062 259 : padding_info_cb (void *opaque, const char *line)
2063 : {
2064 259 : int *r_padding = opaque;
2065 : const char *s;
2066 :
2067 259 : if ((s=has_leading_keyword (line, "PADDING")))
2068 : {
2069 0 : *r_padding = atoi (s);
2070 : }
2071 :
2072 259 : return 0;
2073 : }
2074 :
2075 :
2076 : /* Call the agent to do a decrypt operation using the key identified
2077 : by the hex string KEYGRIP and the input data S_CIPHERTEXT. On the
2078 : success the decoded value is stored verbatim at R_BUF and its
2079 : length at R_BUF; the callers needs to release it. KEYID, MAINKEYID
2080 : and PUBKEY_ALGO are used to construct additional promots or status
2081 : messages. The padding information is stored at R_PADDING with -1
2082 : for not known. */
2083 : gpg_error_t
2084 259 : agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
2085 : u32 *keyid, u32 *mainkeyid, int pubkey_algo,
2086 : gcry_sexp_t s_ciphertext,
2087 : unsigned char **r_buf, size_t *r_buflen, int *r_padding)
2088 : {
2089 : gpg_error_t err;
2090 : char line[ASSUAN_LINELENGTH];
2091 : membuf_t data;
2092 : size_t n, len;
2093 : char *p, *buf, *endp;
2094 : struct default_inq_parm_s dfltparm;
2095 :
2096 259 : memset (&dfltparm, 0, sizeof dfltparm);
2097 259 : dfltparm.ctrl = ctrl;
2098 259 : dfltparm.keyinfo.keyid = keyid;
2099 259 : dfltparm.keyinfo.mainkeyid = mainkeyid;
2100 259 : dfltparm.keyinfo.pubkey_algo = pubkey_algo;
2101 :
2102 259 : if (!keygrip || strlen(keygrip) != 40
2103 259 : || !s_ciphertext || !r_buf || !r_buflen || !r_padding)
2104 0 : return gpg_error (GPG_ERR_INV_VALUE);
2105 :
2106 259 : *r_buf = NULL;
2107 259 : *r_padding = -1;
2108 :
2109 259 : err = start_agent (ctrl, 0);
2110 259 : if (err)
2111 0 : return err;
2112 259 : dfltparm.ctx = agent_ctx;
2113 :
2114 259 : err = assuan_transact (agent_ctx, "RESET",
2115 : NULL, NULL, NULL, NULL, NULL, NULL);
2116 259 : if (err)
2117 0 : return err;
2118 :
2119 259 : snprintf (line, sizeof line, "SETKEY %s", keygrip);
2120 259 : err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
2121 259 : if (err)
2122 0 : return err;
2123 :
2124 259 : if (desc)
2125 : {
2126 259 : snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
2127 259 : line[DIM(line)-1] = 0;
2128 259 : err = assuan_transact (agent_ctx, line,
2129 : NULL, NULL, NULL, NULL, NULL, NULL);
2130 259 : if (err)
2131 0 : return err;
2132 : }
2133 :
2134 259 : init_membuf_secure (&data, 1024);
2135 : {
2136 : struct cipher_parm_s parm;
2137 :
2138 259 : parm.dflt = &dfltparm;
2139 259 : parm.ctx = agent_ctx;
2140 259 : err = make_canon_sexp (s_ciphertext, &parm.ciphertext, &parm.ciphertextlen);
2141 259 : if (err)
2142 0 : return err;
2143 259 : err = assuan_transact (agent_ctx, "PKDECRYPT",
2144 : put_membuf_cb, &data,
2145 : inq_ciphertext_cb, &parm,
2146 : padding_info_cb, r_padding);
2147 259 : xfree (parm.ciphertext);
2148 : }
2149 259 : if (err)
2150 : {
2151 0 : xfree (get_membuf (&data, &len));
2152 0 : return err;
2153 : }
2154 :
2155 259 : put_membuf (&data, "", 1); /* Make sure it is 0 terminated. */
2156 259 : buf = get_membuf (&data, &len);
2157 259 : if (!buf)
2158 0 : return gpg_error_from_syserror ();
2159 259 : log_assert (len); /* (we forced Nul termination.) */
2160 :
2161 259 : if (*buf != '(')
2162 : {
2163 0 : xfree (buf);
2164 0 : return gpg_error (GPG_ERR_INV_SEXP);
2165 : }
2166 :
2167 259 : if (len < 13 || memcmp (buf, "(5:value", 8) ) /* "(5:valueN:D)\0" */
2168 : {
2169 0 : xfree (buf);
2170 0 : return gpg_error (GPG_ERR_INV_SEXP);
2171 : }
2172 259 : len -= 10; /* Count only the data of the second part. */
2173 259 : p = buf + 8; /* Skip leading parenthesis and the value tag. */
2174 :
2175 259 : n = strtoul (p, &endp, 10);
2176 259 : if (!n || *endp != ':')
2177 : {
2178 0 : xfree (buf);
2179 0 : return gpg_error (GPG_ERR_INV_SEXP);
2180 : }
2181 259 : endp++;
2182 259 : if (endp-p+n > len)
2183 : {
2184 0 : xfree (buf);
2185 0 : return gpg_error (GPG_ERR_INV_SEXP); /* Oops: Inconsistent S-Exp. */
2186 : }
2187 :
2188 259 : memmove (buf, endp, n);
2189 :
2190 259 : *r_buflen = n;
2191 259 : *r_buf = buf;
2192 259 : return 0;
2193 : }
2194 :
2195 :
2196 :
2197 : /* Retrieve a key encryption key from the agent. With FOREXPORT true
2198 : the key shall be used for export, with false for import. On success
2199 : the new key is stored at R_KEY and its length at R_KEKLEN. */
2200 : gpg_error_t
2201 20 : agent_keywrap_key (ctrl_t ctrl, int forexport, void **r_kek, size_t *r_keklen)
2202 : {
2203 : gpg_error_t err;
2204 : membuf_t data;
2205 : size_t len;
2206 : unsigned char *buf;
2207 : char line[ASSUAN_LINELENGTH];
2208 : struct default_inq_parm_s dfltparm;
2209 :
2210 20 : memset (&dfltparm, 0, sizeof dfltparm);
2211 20 : dfltparm.ctrl = ctrl;
2212 :
2213 20 : *r_kek = NULL;
2214 20 : err = start_agent (ctrl, 0);
2215 20 : if (err)
2216 0 : return err;
2217 20 : dfltparm.ctx = agent_ctx;
2218 :
2219 20 : snprintf (line, DIM(line)-1, "KEYWRAP_KEY %s",
2220 : forexport? "--export":"--import");
2221 :
2222 20 : init_membuf_secure (&data, 64);
2223 20 : err = assuan_transact (agent_ctx, line,
2224 : put_membuf_cb, &data,
2225 : default_inq_cb, &dfltparm,
2226 : NULL, NULL);
2227 20 : if (err)
2228 : {
2229 0 : xfree (get_membuf (&data, &len));
2230 0 : return err;
2231 : }
2232 20 : buf = get_membuf (&data, &len);
2233 20 : if (!buf)
2234 0 : return gpg_error_from_syserror ();
2235 20 : *r_kek = buf;
2236 20 : *r_keklen = len;
2237 20 : return 0;
2238 : }
2239 :
2240 :
2241 :
2242 : /* Handle the inquiry for an IMPORT_KEY command. */
2243 : static gpg_error_t
2244 31 : inq_import_key_parms (void *opaque, const char *line)
2245 : {
2246 31 : struct import_key_parm_s *parm = opaque;
2247 : gpg_error_t err;
2248 :
2249 31 : if (has_leading_keyword (line, "KEYDATA"))
2250 : {
2251 31 : err = assuan_send_data (parm->dflt->ctx, parm->key, parm->keylen);
2252 : }
2253 : else
2254 0 : err = default_inq_cb (parm->dflt, line);
2255 :
2256 31 : return err;
2257 : }
2258 :
2259 :
2260 : /* Call the agent to import a key into the agent. */
2261 : gpg_error_t
2262 31 : agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr,
2263 : const void *key, size_t keylen, int unattended, int force)
2264 : {
2265 : gpg_error_t err;
2266 : struct import_key_parm_s parm;
2267 : struct cache_nonce_parm_s cn_parm;
2268 : char line[ASSUAN_LINELENGTH];
2269 : struct default_inq_parm_s dfltparm;
2270 :
2271 31 : memset (&dfltparm, 0, sizeof dfltparm);
2272 31 : dfltparm.ctrl = ctrl;
2273 :
2274 31 : err = start_agent (ctrl, 0);
2275 31 : if (err)
2276 0 : return err;
2277 31 : dfltparm.ctx = agent_ctx;
2278 :
2279 31 : if (desc)
2280 : {
2281 31 : snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
2282 31 : line[DIM(line)-1] = 0;
2283 31 : err = assuan_transact (agent_ctx, line,
2284 : NULL, NULL, NULL, NULL, NULL, NULL);
2285 31 : if (err)
2286 0 : return err;
2287 : }
2288 :
2289 31 : parm.dflt = &dfltparm;
2290 31 : parm.key = key;
2291 31 : parm.keylen = keylen;
2292 :
2293 31 : snprintf (line, sizeof line, "IMPORT_KEY%s%s%s%s",
2294 : unattended? " --unattended":"",
2295 : force? " --force":"",
2296 31 : cache_nonce_addr && *cache_nonce_addr? " ":"",
2297 31 : cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"");
2298 31 : cn_parm.cache_nonce_addr = cache_nonce_addr;
2299 31 : cn_parm.passwd_nonce_addr = NULL;
2300 31 : err = assuan_transact (agent_ctx, line,
2301 : NULL, NULL,
2302 : inq_import_key_parms, &parm,
2303 : cache_nonce_status_cb, &cn_parm);
2304 31 : return err;
2305 : }
2306 :
2307 :
2308 :
2309 : /* Receive a secret key from the agent. HEXKEYGRIP is the hexified
2310 : keygrip, DESC a prompt to be displayed with the agent's passphrase
2311 : question (needs to be plus+percent escaped). if OPENPGP_PROTECTED
2312 : is not zero, ensure that the key material is returned in RFC
2313 : 4880-compatible passphrased-protected form. If CACHE_NONCE_ADDR is
2314 : not NULL the agent is advised to first try a passphrase associated
2315 : with that nonce. On success the key is stored as a canonical
2316 : S-expression at R_RESULT and R_RESULTLEN. */
2317 : gpg_error_t
2318 5 : agent_export_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
2319 : int openpgp_protected, char **cache_nonce_addr,
2320 : unsigned char **r_result, size_t *r_resultlen)
2321 : {
2322 : gpg_error_t err;
2323 : struct cache_nonce_parm_s cn_parm;
2324 : membuf_t data;
2325 : size_t len;
2326 : unsigned char *buf;
2327 : char line[ASSUAN_LINELENGTH];
2328 : struct default_inq_parm_s dfltparm;
2329 :
2330 5 : memset (&dfltparm, 0, sizeof dfltparm);
2331 5 : dfltparm.ctrl = ctrl;
2332 :
2333 5 : *r_result = NULL;
2334 :
2335 5 : err = start_agent (ctrl, 0);
2336 5 : if (err)
2337 0 : return err;
2338 5 : dfltparm.ctx = agent_ctx;
2339 :
2340 5 : if (desc)
2341 : {
2342 5 : snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
2343 5 : err = assuan_transact (agent_ctx, line,
2344 : NULL, NULL, NULL, NULL, NULL, NULL);
2345 5 : if (err)
2346 0 : return err;
2347 : }
2348 :
2349 7 : snprintf (line, DIM(line)-1, "EXPORT_KEY %s%s%s %s",
2350 : openpgp_protected ? "--openpgp ":"",
2351 5 : cache_nonce_addr && *cache_nonce_addr? "--cache-nonce=":"",
2352 5 : cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"",
2353 : hexkeygrip);
2354 :
2355 5 : init_membuf_secure (&data, 1024);
2356 5 : cn_parm.cache_nonce_addr = cache_nonce_addr;
2357 5 : cn_parm.passwd_nonce_addr = NULL;
2358 5 : err = assuan_transact (agent_ctx, line,
2359 : put_membuf_cb, &data,
2360 : default_inq_cb, &dfltparm,
2361 : cache_nonce_status_cb, &cn_parm);
2362 5 : if (err)
2363 : {
2364 0 : xfree (get_membuf (&data, &len));
2365 0 : return err;
2366 : }
2367 5 : buf = get_membuf (&data, &len);
2368 5 : if (!buf)
2369 0 : return gpg_error_from_syserror ();
2370 5 : *r_result = buf;
2371 5 : *r_resultlen = len;
2372 5 : return 0;
2373 : }
2374 :
2375 :
2376 :
2377 : /* Ask the agent to delete the key identified by HEXKEYGRIP. If DESC
2378 : is not NULL, display DESC instead of the default description
2379 : message. If FORCE is true the agent is advised not to ask for
2380 : confirmation. */
2381 : gpg_error_t
2382 0 : agent_delete_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
2383 : int force)
2384 : {
2385 : gpg_error_t err;
2386 : char line[ASSUAN_LINELENGTH];
2387 : struct default_inq_parm_s dfltparm;
2388 :
2389 0 : memset (&dfltparm, 0, sizeof dfltparm);
2390 0 : dfltparm.ctrl = ctrl;
2391 :
2392 0 : err = start_agent (ctrl, 0);
2393 0 : if (err)
2394 0 : return err;
2395 :
2396 0 : if (!hexkeygrip || strlen (hexkeygrip) != 40)
2397 0 : return gpg_error (GPG_ERR_INV_VALUE);
2398 :
2399 0 : if (desc)
2400 : {
2401 0 : snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
2402 0 : err = assuan_transact (agent_ctx, line,
2403 : NULL, NULL, NULL, NULL, NULL, NULL);
2404 0 : if (err)
2405 0 : return err;
2406 : }
2407 :
2408 0 : snprintf (line, DIM(line)-1, "DELETE_KEY%s %s",
2409 : force? " --force":"", hexkeygrip);
2410 0 : err = assuan_transact (agent_ctx, line, NULL, NULL,
2411 : default_inq_cb, &dfltparm,
2412 : NULL, NULL);
2413 0 : return err;
2414 : }
2415 :
2416 :
2417 :
2418 : /* Ask the agent to change the passphrase of the key identified by
2419 : * HEXKEYGRIP. If DESC is not NULL, display DESC instead of the
2420 : * default description message. If CACHE_NONCE_ADDR is not NULL the
2421 : * agent is advised to first try a passphrase associated with that
2422 : * nonce. If PASSWD_NONCE_ADDR is not NULL the agent will try to use
2423 : * the passphrase associated with that nonce for the new passphrase.
2424 : * If VERIFY is true the passphrase is only verified. */
2425 : gpg_error_t
2426 0 : agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc, int verify,
2427 : char **cache_nonce_addr, char **passwd_nonce_addr)
2428 : {
2429 : gpg_error_t err;
2430 : struct cache_nonce_parm_s cn_parm;
2431 : char line[ASSUAN_LINELENGTH];
2432 : struct default_inq_parm_s dfltparm;
2433 :
2434 0 : memset (&dfltparm, 0, sizeof dfltparm);
2435 0 : dfltparm.ctrl = ctrl;
2436 :
2437 0 : err = start_agent (ctrl, 0);
2438 0 : if (err)
2439 0 : return err;
2440 0 : dfltparm.ctx = agent_ctx;
2441 :
2442 0 : if (!hexkeygrip || strlen (hexkeygrip) != 40)
2443 0 : return gpg_error (GPG_ERR_INV_VALUE);
2444 :
2445 0 : if (desc)
2446 : {
2447 0 : snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
2448 0 : err = assuan_transact (agent_ctx, line,
2449 : NULL, NULL, NULL, NULL, NULL, NULL);
2450 0 : if (err)
2451 0 : return err;
2452 : }
2453 :
2454 0 : if (verify)
2455 0 : snprintf (line, DIM(line)-1, "PASSWD %s%s --verify %s",
2456 0 : cache_nonce_addr && *cache_nonce_addr? "--cache-nonce=":"",
2457 0 : cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"",
2458 : hexkeygrip);
2459 : else
2460 0 : snprintf (line, DIM(line)-1, "PASSWD %s%s %s%s %s",
2461 0 : cache_nonce_addr && *cache_nonce_addr? "--cache-nonce=":"",
2462 0 : cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"",
2463 0 : passwd_nonce_addr && *passwd_nonce_addr? "--passwd-nonce=":"",
2464 0 : passwd_nonce_addr && *passwd_nonce_addr? *passwd_nonce_addr:"",
2465 : hexkeygrip);
2466 0 : cn_parm.cache_nonce_addr = cache_nonce_addr;
2467 0 : cn_parm.passwd_nonce_addr = passwd_nonce_addr;
2468 0 : err = assuan_transact (agent_ctx, line, NULL, NULL,
2469 : default_inq_cb, &dfltparm,
2470 : cache_nonce_status_cb, &cn_parm);
2471 0 : return err;
2472 : }
2473 :
2474 :
2475 : /* Return the version reported by gpg-agent. */
2476 : gpg_error_t
2477 3 : agent_get_version (ctrl_t ctrl, char **r_version)
2478 : {
2479 : gpg_error_t err;
2480 :
2481 3 : err = start_agent (ctrl, 0);
2482 3 : if (err)
2483 0 : return err;
2484 :
2485 3 : err = get_assuan_server_version (agent_ctx, 0, r_version);
2486 3 : return err;
2487 : }
|