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