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