Coverage Report

Created: 2026-01-09 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnupg/g10/call-agent.c
Line
Count
Source
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
 * Copyright (C) 2020       g10 Code GmbH
5
 *
6
 * This file is part of GnuPG.
7
 *
8
 * GnuPG is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * GnuPG is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <config.h>
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <errno.h>
27
#include <unistd.h>
28
#include <time.h>
29
#ifdef HAVE_LOCALE_H
30
#include <locale.h>
31
#endif
32
33
#include "gpg.h"
34
#include <assuan.h>
35
#include "../common/util.h"
36
#include "../common/membuf.h"
37
#include "options.h"
38
#include "../common/i18n.h"
39
#include "../common/asshelp.h"
40
#include "../common/sysutils.h"
41
#include "call-agent.h"
42
#include "../common/status.h"
43
#include "../common/shareddefs.h"
44
#include "../common/host2net.h"
45
#include "../common/ttyio.h"
46
47
0
#define CONTROL_D ('D' - 'A' + 1)
48
49
50
static assuan_context_t agent_ctx = NULL;
51
static int did_early_card_test;
52
53
struct confirm_parm_s
54
{
55
  char *desc;
56
  char *ok;
57
  char *notok;
58
};
59
60
struct default_inq_parm_s
61
{
62
  ctrl_t ctrl;
63
  assuan_context_t ctx;
64
  struct {
65
    u32 *keyid;
66
    u32 *mainkeyid;
67
    int pubkey_algo;
68
  } keyinfo;
69
  struct confirm_parm_s *confirm;
70
};
71
72
struct cipher_parm_s
73
{
74
  struct default_inq_parm_s *dflt;
75
  assuan_context_t ctx;
76
  unsigned char *ciphertext;
77
  size_t ciphertextlen;
78
};
79
80
struct writecert_parm_s
81
{
82
  struct default_inq_parm_s *dflt;
83
  const unsigned char *certdata;
84
  size_t certdatalen;
85
};
86
87
struct writekey_parm_s
88
{
89
  struct default_inq_parm_s *dflt;
90
  const unsigned char *keydata;
91
  size_t keydatalen;
92
};
93
94
struct genkey_parm_s
95
{
96
  struct default_inq_parm_s *dflt;
97
  const char *keyparms;
98
  const char *passphrase;
99
};
100
101
struct import_key_parm_s
102
{
103
  struct default_inq_parm_s *dflt;
104
  const void *key;
105
  size_t keylen;
106
};
107
108
109
struct cache_nonce_parm_s
110
{
111
  char **cache_nonce_addr;
112
  char **passwd_nonce_addr;
113
};
114
115
116
static gpg_error_t learn_status_cb (void *opaque, const char *line);
117
118
119

120
/* If RC is not 0, write an appropriate status message. */
121
static void
122
status_sc_op_failure (int rc)
123
0
{
124
0
  switch (gpg_err_code (rc))
125
0
    {
126
0
    case 0:
127
0
      break;
128
0
    case GPG_ERR_CANCELED:
129
0
    case GPG_ERR_FULLY_CANCELED:
130
0
      write_status_text (STATUS_SC_OP_FAILURE, "1");
131
0
      break;
132
0
    case GPG_ERR_BAD_PIN:
133
0
    case GPG_ERR_BAD_RESET_CODE:
134
0
      write_status_text (STATUS_SC_OP_FAILURE, "2");
135
0
      break;
136
0
    default:
137
0
      write_status (STATUS_SC_OP_FAILURE);
138
0
      break;
139
0
    }
140
0
}
141
142
143
/* This is the default inquiry callback.  It mainly handles the
144
   Pinentry notifications.  */
145
static gpg_error_t
146
default_inq_cb (void *opaque, const char *line)
147
0
{
148
0
  gpg_error_t err = 0;
149
0
  struct default_inq_parm_s *parm = opaque;
150
0
  const char *s;
151
152
0
  if (has_leading_keyword (line, "PINENTRY_LAUNCHED"))
153
0
    {
154
0
      err = gpg_proxy_pinentry_notify (parm->ctrl, line);
155
0
      if (err)
156
0
        log_error (_("failed to proxy %s inquiry to client\n"),
157
0
                   "PINENTRY_LAUNCHED");
158
      /* We do not pass errors to avoid breaking other code.  */
159
0
    }
160
0
  else if ((has_leading_keyword (line, "PASSPHRASE")
161
0
            || has_leading_keyword (line, "NEW_PASSPHRASE"))
162
0
           && opt.pinentry_mode == PINENTRY_MODE_LOOPBACK)
163
0
    {
164
0
      assuan_begin_confidential (parm->ctx);
165
0
      if (have_static_passphrase ())
166
0
        {
167
0
          s = get_static_passphrase ();
168
0
          err = assuan_send_data (parm->ctx, s, strlen (s));
169
0
        }
170
0
      else
171
0
        {
172
0
          char *pw;
173
0
          char buf[32];
174
175
0
          if (parm->keyinfo.keyid)
176
0
            emit_status_need_passphrase (parm->ctrl,
177
0
                                         parm->keyinfo.keyid,
178
0
                                         parm->keyinfo.mainkeyid,
179
0
                                         parm->keyinfo.pubkey_algo);
180
181
0
          snprintf (buf, sizeof (buf), "%u", 100);
182
0
          write_status_text (STATUS_INQUIRE_MAXLEN, buf);
183
0
          pw = cpr_get_hidden ("passphrase.enter", _("Enter passphrase: "));
184
0
          cpr_kill_prompt ();
185
0
          if (*pw == CONTROL_D && !pw[1])
186
0
            err = gpg_error (GPG_ERR_CANCELED);
187
0
          else
188
0
            err = assuan_send_data (parm->ctx, pw, strlen (pw));
189
0
          xfree (pw);
190
0
        }
191
0
      assuan_end_confidential (parm->ctx);
192
0
    }
193
0
  else if ((s = has_leading_keyword (line, "CONFIRM"))
194
0
           && opt.pinentry_mode == PINENTRY_MODE_LOOPBACK
195
0
           && parm->confirm)
196
0
    {
197
0
      int ask = atoi (s);
198
0
      int yes;
199
200
0
      if (ask)
201
0
        {
202
0
          yes = cpr_get_answer_is_yes (NULL, parm->confirm->desc);
203
0
          if (yes)
204
0
            err = assuan_send_data (parm->ctx, NULL, 0);
205
0
          else
206
0
            err = gpg_error (GPG_ERR_NOT_CONFIRMED);
207
0
        }
208
0
      else
209
0
        {
210
0
          tty_printf ("%s", parm->confirm->desc);
211
0
          err = assuan_send_data (parm->ctx, NULL, 0);
212
0
        }
213
0
    }
214
0
  else
215
0
    log_debug ("ignoring gpg-agent inquiry '%s'\n", line);
216
217
0
  return err;
218
0
}
219
220
221
/* Print a warning if the server's version number is less than our
222
   version number.  Returns an error code on a connection problem.  */
223
static gpg_error_t
224
warn_version_mismatch (assuan_context_t ctx, const char *servername, int mode)
225
0
{
226
0
  return warn_server_version_mismatch (ctx, servername, mode,
227
0
                                       write_status_strings2, NULL,
228
0
                                       !opt.quiet);
229
0
}
230
231
232
0
#define FLAG_FOR_CARD_SUPPRESS_ERRORS 2
233
234
/* Try to connect to the agent via socket or fork it off and work by
235
   pipes.  Handle the server's initial greeting */
236
static int
237
start_agent (ctrl_t ctrl, int flag_for_card)
238
0
{
239
0
  int rc;
240
241
0
  (void)ctrl;  /* Not yet used.  */
242
243
  /* Fixme: We need a context for each thread or serialize the access
244
     to the agent. */
245
0
  if (agent_ctx)
246
0
    rc = 0;
247
0
  else
248
0
    {
249
0
      rc = start_new_gpg_agent (&agent_ctx,
250
0
                                GPG_ERR_SOURCE_DEFAULT,
251
0
                                opt.agent_program,
252
0
                                opt.lc_ctype, opt.lc_messages,
253
0
                                opt.session_env,
254
0
                                opt.autostart?ASSHELP_FLAG_AUTOSTART:0,
255
0
                                opt.verbose, DBG_IPC,
256
0
                                NULL, NULL);
257
0
      if (!opt.autostart && gpg_err_code (rc) == GPG_ERR_NO_AGENT)
258
0
        {
259
0
          static int shown;
260
261
0
          if (!shown)
262
0
            {
263
0
              shown = 1;
264
0
              log_info (_("no gpg-agent running in this session\n"));
265
0
            }
266
0
        }
267
0
      else if (!rc
268
0
               && !(rc = warn_version_mismatch (agent_ctx, GPG_AGENT_NAME, 0)))
269
0
        {
270
          /* Tell the agent that we support Pinentry notifications.
271
             No error checking so that it will work also with older
272
             agents.  */
273
0
          assuan_transact (agent_ctx, "OPTION allow-pinentry-notify",
274
0
                           NULL, NULL, NULL, NULL, NULL, NULL);
275
          /* Tell the agent about what version we are aware.  This is
276
             here used to indirectly enable GPG_ERR_FULLY_CANCELED.  */
277
0
          assuan_transact (agent_ctx, "OPTION agent-awareness=2.1.0",
278
0
                           NULL, NULL, NULL, NULL, NULL, NULL);
279
          /* Pass on the pinentry mode.  */
280
0
          if (opt.pinentry_mode)
281
0
            {
282
0
              char *tmp = xasprintf ("OPTION pinentry-mode=%s",
283
0
                                     str_pinentry_mode (opt.pinentry_mode));
284
0
              rc = assuan_transact (agent_ctx, tmp,
285
0
                               NULL, NULL, NULL, NULL, NULL, NULL);
286
0
              xfree (tmp);
287
0
              if (rc)
288
0
                {
289
0
                  log_error ("setting pinentry mode '%s' failed: %s\n",
290
0
                             str_pinentry_mode (opt.pinentry_mode),
291
0
                             gpg_strerror (rc));
292
0
                  write_status_error ("set_pinentry_mode", rc);
293
0
                }
294
0
            }
295
296
          /* Pass on the request origin.  */
297
0
          if (opt.request_origin)
298
0
            {
299
0
              char *tmp = xasprintf ("OPTION pretend-request-origin=%s",
300
0
                                     str_request_origin (opt.request_origin));
301
0
              rc = assuan_transact (agent_ctx, tmp,
302
0
                               NULL, NULL, NULL, NULL, NULL, NULL);
303
0
              xfree (tmp);
304
0
              if (rc)
305
0
                {
306
0
                  log_error ("setting request origin '%s' failed: %s\n",
307
0
                             str_request_origin (opt.request_origin),
308
0
                             gpg_strerror (rc));
309
0
                  write_status_error ("set_request_origin", rc);
310
0
                }
311
0
            }
312
313
          /* In DE_VS mode under Windows we require that the JENT RNG
314
           * is active.  */
315
#ifdef HAVE_W32_SYSTEM
316
          if (!rc && opt.compliance == CO_DE_VS)
317
            {
318
              if (assuan_transact (agent_ctx, "GETINFO jent_active",
319
                                   NULL, NULL, NULL, NULL, NULL, NULL))
320
                {
321
                  rc = gpg_error (GPG_ERR_FORBIDDEN);
322
                  log_error (_("%s is not compliant with %s mode\n"),
323
                             GPG_AGENT_NAME,
324
                             gnupg_compliance_option_string (opt.compliance));
325
                  write_status_error ("random-compliance", rc);
326
                }
327
            }
328
#endif /*HAVE_W32_SYSTEM*/
329
330
0
        }
331
0
    }
332
333
0
  if (!rc && flag_for_card && !did_early_card_test)
334
0
    {
335
      /* Request the serial number of the card for an early test.  */
336
0
      struct agent_card_info_s info;
337
338
0
      memset (&info, 0, sizeof info);
339
340
0
      if (!(flag_for_card & FLAG_FOR_CARD_SUPPRESS_ERRORS))
341
0
        rc = warn_version_mismatch (agent_ctx, SCDAEMON_NAME, 2);
342
0
      if (!rc)
343
0
        rc = assuan_transact (agent_ctx,
344
0
                              opt.flags.use_only_openpgp_card?
345
0
                              "SCD SERIALNO openpgp" : "SCD SERIALNO",
346
0
                              NULL, NULL, NULL, NULL,
347
0
                              learn_status_cb, &info);
348
0
      if (rc && !(flag_for_card & FLAG_FOR_CARD_SUPPRESS_ERRORS))
349
0
        {
350
0
          switch (gpg_err_code (rc))
351
0
            {
352
0
            case GPG_ERR_NOT_SUPPORTED:
353
0
            case GPG_ERR_NO_SCDAEMON:
354
0
              write_status_text (STATUS_CARDCTRL, "6");
355
0
              break;
356
0
            case GPG_ERR_OBJ_TERM_STATE:
357
0
              write_status_text (STATUS_CARDCTRL, "7");
358
0
              break;
359
0
            default:
360
0
              write_status_text (STATUS_CARDCTRL, "4");
361
0
              log_info ("selecting card failed: %s\n", gpg_strerror (rc));
362
0
              break;
363
0
            }
364
0
        }
365
366
0
      if (!rc && is_status_enabled () && info.serialno)
367
0
        {
368
0
          char *buf;
369
370
0
          buf = xasprintf ("3 %s", info.serialno);
371
0
          write_status_text (STATUS_CARDCTRL, buf);
372
0
          xfree (buf);
373
0
        }
374
375
0
      agent_release_card_info (&info);
376
377
0
      if (!rc)
378
0
        did_early_card_test = 1;
379
0
    }
380
381
382
0
  return rc;
383
0
}
384
385
386
/* Return a new malloced string by unescaping the string S.  Escaping
387
   is percent escaping and '+'/space mapping.  A binary nul will
388
   silently be replaced by a 0xFF.  Function returns NULL to indicate
389
   an out of memory status. */
390
static char *
391
unescape_status_string (const unsigned char *s)
392
0
{
393
0
  return percent_plus_unescape (s, 0xff);
394
0
}
395
396
397
/* Take a 20 or 32 byte hexencoded string and put it into the provided
398
 * FPRLEN byte long buffer FPR in binary format.  Returns the actual
399
 * used length of the FPR buffer or 0 on error.  */
400
static unsigned int
401
unhexify_fpr (const char *hexstr, unsigned char *fpr, unsigned int fprlen)
402
0
{
403
0
  const char *s;
404
0
  int n;
405
406
0
  for (s=hexstr, n=0; hexdigitp (s); s++, n++)
407
0
    ;
408
0
  if ((*s && *s != ' ') || !(n == 40 || n == 64))
409
0
    return 0; /* no fingerprint (invalid or wrong length). */
410
0
  for (s=hexstr, n=0; *s && n < fprlen; s += 2, n++)
411
0
    fpr[n] = xtoi_2 (s);
412
413
0
  return (n == 20 || n == 32)? n : 0;
414
0
}
415
416
/* Take the serial number from LINE and return it verbatim in a newly
417
   allocated string.  We make sure that only hex characters are
418
   returned. */
419
static char *
420
store_serialno (const char *line)
421
0
{
422
0
  const char *s;
423
0
  char *p;
424
425
0
  for (s=line; hexdigitp (s); s++)
426
0
    ;
427
0
  p = xtrymalloc (s + 1 - line);
428
0
  if (p)
429
0
    {
430
0
      memcpy (p, line, s-line);
431
0
      p[s-line] = 0;
432
0
    }
433
0
  return p;
434
0
}
435
436
437

438
/* This is a dummy data line callback.  */
439
static gpg_error_t
440
dummy_data_cb (void *opaque, const void *buffer, size_t length)
441
0
{
442
0
  (void)opaque;
443
0
  (void)buffer;
444
0
  (void)length;
445
0
  return 0;
446
0
}
447
448
/* A simple callback used to return the serialnumber of a card.  */
449
static gpg_error_t
450
get_serialno_cb (void *opaque, const char *line)
451
0
{
452
0
  char **serialno = opaque;
453
0
  const char *keyword = line;
454
0
  const char *s;
455
0
  int keywordlen, n;
456
457
0
  for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
458
0
    ;
459
0
  while (spacep (line))
460
0
    line++;
461
462
0
  if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
463
0
    {
464
0
      if (*serialno)
465
0
        return gpg_error (GPG_ERR_CONFLICT); /* Unexpected status line. */
466
0
      for (n=0,s=line; hexdigitp (s); s++, n++)
467
0
        ;
468
0
      if (!n || (n&1)|| !(spacep (s) || !*s) )
469
0
        return gpg_error (GPG_ERR_ASS_PARAMETER);
470
0
      *serialno = xtrymalloc (n+1);
471
0
      if (!*serialno)
472
0
        return out_of_core ();
473
0
      memcpy (*serialno, line, n);
474
0
      (*serialno)[n] = 0;
475
0
    }
476
477
0
  return 0;
478
0
}
479
480
481
482
/* Release the card info structure INFO. */
483
void
484
agent_release_card_info (struct agent_card_info_s *info)
485
0
{
486
0
  int i;
487
488
0
  if (!info)
489
0
    return;
490
491
0
  xfree (info->reader); info->reader = NULL;
492
0
  xfree (info->manufacturer_name); info->manufacturer_name = NULL;
493
0
  xfree (info->serialno); info->serialno = NULL;
494
0
  xfree (info->apptype); info->apptype = NULL;
495
0
  xfree (info->disp_name); info->disp_name = NULL;
496
0
  xfree (info->disp_lang); info->disp_lang = NULL;
497
0
  xfree (info->pubkey_url); info->pubkey_url = NULL;
498
0
  xfree (info->login_data); info->login_data = NULL;
499
0
  info->cafpr1len = info->cafpr2len = info->cafpr3len = 0;
500
0
  info->fpr1len = info->fpr2len = info->fpr3len = 0;
501
0
  for (i=0; i < DIM(info->private_do); i++)
502
0
    {
503
0
      xfree (info->private_do[i]);
504
0
      info->private_do[i] = NULL;
505
0
    }
506
0
  for (i=0; i < DIM(info->supported_keyalgo); i++)
507
0
    {
508
0
      free_strlist (info->supported_keyalgo[i]);
509
0
      info->supported_keyalgo[i] = NULL;
510
0
    }
511
0
}
512
513
514
static gpg_error_t
515
learn_status_cb (void *opaque, const char *line)
516
0
{
517
0
  struct agent_card_info_s *parm = opaque;
518
0
  const char *keyword = line;
519
0
  int keywordlen;
520
0
  int i;
521
0
  char *endp;
522
523
0
  for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
524
0
    ;
525
0
  while (spacep (line))
526
0
    line++;
527
528
0
  if (keywordlen == 6 && !memcmp (keyword, "READER", keywordlen))
529
0
    {
530
0
      xfree (parm->reader);
531
0
      parm->reader = unescape_status_string (line);
532
0
    }
533
0
  else if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
534
0
    {
535
0
      xfree (parm->serialno);
536
0
      parm->serialno = store_serialno (line);
537
0
      parm->is_v2 = (strlen (parm->serialno) >= 16
538
0
                     && (xtoi_2 (parm->serialno+12) == 0 /* Yubikey */
539
0
                         || xtoi_2 (parm->serialno+12) >= 2));
540
0
    }
541
0
  else if (keywordlen == 7 && !memcmp (keyword, "APPTYPE", keywordlen))
542
0
    {
543
0
      xfree (parm->apptype);
544
0
      parm->apptype = unescape_status_string (line);
545
0
    }
546
0
  else if (keywordlen == 10 && !memcmp (keyword, "APPVERSION", keywordlen))
547
0
    {
548
0
      unsigned int val = 0;
549
550
0
      sscanf (line, "%x", &val);
551
0
      parm->appversion = val;
552
0
    }
553
0
  else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen))
554
0
    {
555
0
      xfree (parm->disp_name);
556
0
      parm->disp_name = unescape_status_string (line);
557
0
    }
558
0
  else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen))
559
0
    {
560
0
      xfree (parm->disp_lang);
561
0
      parm->disp_lang = unescape_status_string (line);
562
0
    }
563
0
  else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen))
564
0
    {
565
0
      parm->disp_sex = *line == '1'? 1 : *line == '2' ? 2: 0;
566
0
    }
567
0
  else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen))
568
0
    {
569
0
      xfree (parm->pubkey_url);
570
0
      parm->pubkey_url = unescape_status_string (line);
571
0
    }
572
0
  else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen))
573
0
    {
574
0
      xfree (parm->login_data);
575
0
      parm->login_data = unescape_status_string (line);
576
0
    }
577
0
  else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen))
578
0
    {
579
0
      parm->sig_counter = strtoul (line, NULL, 0);
580
0
    }
581
0
  else if (keywordlen == 10 && !memcmp (keyword, "CHV-STATUS", keywordlen))
582
0
    {
583
0
      char *p, *buf;
584
585
0
      buf = p = unescape_status_string (line);
586
0
      if (buf)
587
0
        {
588
0
          while (spacep (p))
589
0
            p++;
590
0
          parm->chv1_cached = atoi (p);
591
0
          while (*p && !spacep (p))
592
0
            p++;
593
0
          while (spacep (p))
594
0
            p++;
595
0
          for (i=0; *p && i < 3; i++)
596
0
            {
597
0
              parm->chvmaxlen[i] = atoi (p);
598
0
              while (*p && !spacep (p))
599
0
                p++;
600
0
              while (spacep (p))
601
0
                p++;
602
0
            }
603
0
          for (i=0; *p && i < 3; i++)
604
0
            {
605
0
              parm->chvretry[i] = atoi (p);
606
0
              while (*p && !spacep (p))
607
0
                p++;
608
0
              while (spacep (p))
609
0
                p++;
610
0
            }
611
0
          xfree (buf);
612
0
        }
613
0
    }
614
0
  else if (keywordlen == 6 && !memcmp (keyword, "EXTCAP", keywordlen))
615
0
    {
616
0
      char *p, *p2, *buf;
617
0
      int abool;
618
619
0
      buf = p = unescape_status_string (line);
620
0
      if (buf)
621
0
        {
622
0
          for (p = strtok (buf, " "); p; p = strtok (NULL, " "))
623
0
            {
624
0
              p2 = strchr (p, '=');
625
0
              if (p2)
626
0
                {
627
0
                  *p2++ = 0;
628
0
                  abool = (*p2 == '1');
629
0
                  if (!strcmp (p, "ki"))
630
0
                    parm->extcap.ki = abool;
631
0
                  else if (!strcmp (p, "aac"))
632
0
                    parm->extcap.aac = abool;
633
0
                  else if (!strcmp (p, "bt"))
634
0
                    parm->extcap.bt = abool;
635
0
                  else if (!strcmp (p, "kdf"))
636
0
                    parm->extcap.kdf = abool;
637
0
                  else if (!strcmp (p, "si"))
638
0
                    parm->status_indicator = strtoul (p2, NULL, 10);
639
0
                }
640
0
            }
641
0
          xfree (buf);
642
0
        }
643
0
    }
644
0
  else if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
645
0
    {
646
0
      int no = atoi (line);
647
0
      while (*line && !spacep (line))
648
0
        line++;
649
0
      while (spacep (line))
650
0
        line++;
651
0
      if (no == 1)
652
0
        parm->fpr1len = unhexify_fpr (line, parm->fpr1, sizeof parm->fpr1);
653
0
      else if (no == 2)
654
0
        parm->fpr2len = unhexify_fpr (line, parm->fpr2, sizeof parm->fpr2);
655
0
      else if (no == 3)
656
0
        parm->fpr3len = unhexify_fpr (line, parm->fpr3, sizeof parm->fpr3);
657
0
    }
658
0
  else if (keywordlen == 8 && !memcmp (keyword, "KEY-TIME", keywordlen))
659
0
    {
660
0
      int no = atoi (line);
661
0
      while (* line && !spacep (line))
662
0
        line++;
663
0
      while (spacep (line))
664
0
        line++;
665
0
      if (no == 1)
666
0
        parm->fpr1time = strtoul (line, NULL, 10);
667
0
      else if (no == 2)
668
0
        parm->fpr2time = strtoul (line, NULL, 10);
669
0
      else if (no == 3)
670
0
        parm->fpr3time = strtoul (line, NULL, 10);
671
0
    }
672
0
  else if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen))
673
0
    {
674
0
      const char *hexgrp = line;
675
0
      int no;
676
677
0
      while (*line && !spacep (line))
678
0
        line++;
679
0
      while (spacep (line))
680
0
        line++;
681
0
      if (strncmp (line, "OPENPGP.", 8))
682
0
        ;
683
0
      else if ((no = atoi (line+8)) == 1)
684
0
        unhexify_fpr (hexgrp, parm->grp1, sizeof parm->grp1);
685
0
      else if (no == 2)
686
0
        unhexify_fpr (hexgrp, parm->grp2, sizeof parm->grp2);
687
0
      else if (no == 3)
688
0
        unhexify_fpr (hexgrp, parm->grp3, sizeof parm->grp3);
689
0
    }
690
0
  else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen))
691
0
    {
692
0
      int no = atoi (line);
693
0
      while (*line && !spacep (line))
694
0
        line++;
695
0
      while (spacep (line))
696
0
        line++;
697
0
      if (no == 1)
698
0
        parm->cafpr1len = unhexify_fpr (line, parm->cafpr1,sizeof parm->cafpr1);
699
0
      else if (no == 2)
700
0
        parm->cafpr2len = unhexify_fpr (line, parm->cafpr2,sizeof parm->cafpr2);
701
0
      else if (no == 3)
702
0
        parm->cafpr3len = unhexify_fpr (line, parm->cafpr3,sizeof parm->cafpr3);
703
0
    }
704
0
  else if (keywordlen == 8 && !memcmp (keyword, "KEY-ATTR", keywordlen))
705
0
    {
706
0
      int keyno = 0;
707
0
      int algo = PUBKEY_ALGO_RSA;
708
0
      int n = 0;
709
710
0
      sscanf (line, "%d %d %n", &keyno, &algo, &n);
711
0
      keyno--;
712
0
      if (keyno < 0 || keyno >= DIM (parm->key_attr))
713
0
        return 0;
714
715
0
      parm->key_attr[keyno].algo = algo;
716
0
      if (algo == PUBKEY_ALGO_RSA)
717
0
        parm->key_attr[keyno].nbits = strtoul (line+n+3, NULL, 10);
718
0
      else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA
719
0
               || algo == PUBKEY_ALGO_EDDSA)
720
0
        parm->key_attr[keyno].curve = openpgp_is_curve_supported (line + n,
721
0
                                                                  NULL, NULL);
722
0
    }
723
0
  else if (keywordlen == 12 && !memcmp (keyword, "PRIVATE-DO-", 11)
724
0
           && strchr("1234", keyword[11]))
725
0
    {
726
0
      int no = keyword[11] - '1';
727
0
      log_assert (no >= 0 && no <= 3);
728
0
      xfree (parm->private_do[no]);
729
0
      parm->private_do[no] = unescape_status_string (line);
730
0
    }
731
0
  else if (keywordlen == 12 && !memcmp (keyword, "MANUFACTURER", 12))
732
0
    {
733
0
      xfree (parm->manufacturer_name);
734
0
      parm->manufacturer_name = NULL;
735
0
      parm->manufacturer_id = strtoul (line, &endp, 0);
736
0
      while (endp && spacep (endp))
737
0
        endp++;
738
0
      if (endp && *endp)
739
0
        parm->manufacturer_name = xstrdup (endp);
740
0
    }
741
0
  else if (keywordlen == 3 && !memcmp (keyword, "KDF", 3))
742
0
    {
743
0
      unsigned char *data = unescape_status_string (line);
744
745
0
      if (data[2] != 0x03)
746
0
        parm->kdf_do_enabled = 0;
747
0
      else if (data[22] != 0x85)
748
0
        parm->kdf_do_enabled = 1;
749
0
      else
750
0
        parm->kdf_do_enabled = 2;
751
0
      xfree (data);
752
0
    }
753
0
  else if (keywordlen == 5 && !memcmp (keyword, "UIF-", 4)
754
0
           && strchr("123", keyword[4]))
755
0
    {
756
0
      unsigned char *data;
757
0
      int no = keyword[4] - '1';
758
759
0
      log_assert (no >= 0 && no <= 2);
760
0
      data = unescape_status_string (line);
761
0
      parm->uif[no] = (data[0] != 0xff);
762
0
      xfree (data);
763
0
    }
764
0
  else if (keywordlen == 13 && !memcmp (keyword, "KEY-ATTR-INFO", 13))
765
0
    {
766
0
      if (!strncmp (line, "OPENPGP.", 8))
767
0
        {
768
0
          int no;
769
770
0
          line += 8;
771
0
          no = atoi (line);
772
0
          if (no >= 1 && no <= 3)
773
0
            {
774
0
              no--;
775
0
              line++;
776
0
              while (spacep (line))
777
0
                line++;
778
0
              append_to_strlist (&parm->supported_keyalgo[no], xstrdup (line));
779
0
            }
780
0
        }
781
        /* Skip when it's not "OPENPGP.[123]".  */
782
0
    }
783
784
0
  return 0;
785
0
}
786
787
788
/* Call the scdaemon to learn about a smartcard.  Note that in
789
 * contradiction to the function's name, gpg-agent's LEARN command is
790
 * used and not the low-level "SCD LEARN".
791
 * Used by:
792
 *  card-util.c
793
 *  keyedit_menu
794
 *  card_store_key_with_backup  (With force to remove secret key data)
795
 */
796
int
797
agent_scd_learn (struct agent_card_info_s *info, int force)
798
0
{
799
0
  int rc;
800
0
  struct default_inq_parm_s parm;
801
0
  struct agent_card_info_s dummyinfo;
802
803
0
  if (!info)
804
0
    info = &dummyinfo;
805
0
  memset (info, 0, sizeof *info);
806
0
  memset (&parm, 0, sizeof parm);
807
808
0
  rc = start_agent (NULL, 1);
809
0
  if (rc)
810
0
    return rc;
811
812
0
  parm.ctx = agent_ctx;
813
0
  rc = assuan_transact (agent_ctx,
814
0
                        force ? "LEARN --sendinfo --force" : "LEARN --sendinfo",
815
0
                        dummy_data_cb, NULL, default_inq_cb, &parm,
816
0
                        learn_status_cb, info);
817
  /* Also try to get the key attributes.  */
818
0
  if (!rc)
819
0
    agent_scd_getattr ("KEY-ATTR", info);
820
821
0
  if (info == &dummyinfo)
822
0
    agent_release_card_info (info);
823
824
0
  return rc;
825
0
}
826
827
828

829
struct keypairinfo_cb_parm_s
830
{
831
  keypair_info_t kpinfo;
832
  keypair_info_t *kpinfo_tail;
833
};
834
835
836
/* Callback for the agent_scd_keypairinfo function.  */
837
static gpg_error_t
838
scd_keypairinfo_status_cb (void *opaque, const char *line)
839
0
{
840
0
  struct keypairinfo_cb_parm_s *parm = opaque;
841
0
  gpg_error_t err = 0;
842
0
  const char *keyword = line;
843
0
  int keywordlen;
844
0
  char *line_buffer = NULL;
845
0
  keypair_info_t kpi = NULL;
846
847
0
  for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
848
0
    ;
849
0
  while (spacep (line))
850
0
    line++;
851
852
0
  if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen))
853
0
    {
854
      /* The format of such a line is:
855
       *   KEYPAIRINFO <hexgrip> <keyref> [usage] [keytime] [algostr]
856
       */
857
0
      const char *fields[4];
858
0
      int nfields;
859
0
      const char *hexgrp, *keyref, *usage;
860
0
      time_t atime;
861
0
      u32 keytime;
862
863
0
      line_buffer = xtrystrdup (line);
864
0
      if (!line_buffer)
865
0
        {
866
0
          err = gpg_error_from_syserror ();
867
0
          goto leave;
868
0
        }
869
0
      if ((nfields = split_fields (line_buffer, fields, DIM (fields))) < 2)
870
0
        goto leave;  /* not enough args - invalid status line - ignore  */
871
872
0
      hexgrp = fields[0];
873
0
      keyref = fields[1];
874
0
      if (nfields > 2)
875
0
        usage = fields[2];
876
0
      else
877
0
        usage = "";
878
0
      if (nfields > 3)
879
0
        {
880
0
          atime = parse_timestamp (fields[3], NULL);
881
0
          if (atime == (time_t)(-1))
882
0
            atime = 0;
883
0
          keytime = atime;
884
0
        }
885
0
      else
886
0
        keytime = 0;
887
888
0
      kpi = xtrycalloc (1, sizeof *kpi);
889
0
      if (!kpi)
890
0
        {
891
0
          err = gpg_error_from_syserror ();
892
0
          goto leave;
893
0
        }
894
895
0
      if (*hexgrp == 'X' && !hexgrp[1])
896
0
        *kpi->keygrip = 0; /* No hexgrip.  */
897
0
      else if (strlen (hexgrp) == 2*KEYGRIP_LEN)
898
0
        mem2str (kpi->keygrip, hexgrp, sizeof kpi->keygrip);
899
0
      else
900
0
        {
901
0
          err = gpg_error (GPG_ERR_INV_DATA);
902
0
          goto leave;
903
0
        }
904
905
0
      if (!*keyref)
906
0
        {
907
0
          err = gpg_error (GPG_ERR_INV_DATA);
908
0
          goto leave;
909
0
        }
910
0
      kpi->idstr = xtrystrdup (keyref);
911
0
      if (!kpi->idstr)
912
0
        {
913
0
          err = gpg_error_from_syserror ();
914
0
          goto leave;
915
0
        }
916
917
      /* Parse and set the usage.  */
918
0
      for (; *usage; usage++)
919
0
        {
920
0
          switch (*usage)
921
0
            {
922
0
            case 's': kpi->usage |= GCRY_PK_USAGE_SIGN; break;
923
0
            case 'c': kpi->usage |= GCRY_PK_USAGE_CERT; break;
924
0
            case 'a': kpi->usage |= GCRY_PK_USAGE_AUTH; break;
925
0
            case 'e': kpi->usage |= GCRY_PK_USAGE_ENCR; break;
926
0
            }
927
0
        }
928
929
0
      kpi->keytime = keytime;
930
931
      /* Append to the list.  */
932
0
      *parm->kpinfo_tail = kpi;
933
0
      parm->kpinfo_tail = &kpi->next;
934
0
      kpi = NULL;
935
0
    }
936
937
0
 leave:
938
0
  free_keypair_info (kpi);
939
0
  xfree (line_buffer);
940
0
  return err;
941
0
}
942
943
944
/* Read the keypairinfo lines of the current card directly from
945
 * scdaemon.  The list is returned as a string made up of the keygrip,
946
 * a space and the keyref.  The flags of the string carry the usage
947
 * bits.  If KEYREF is not NULL, only a single string is returned
948
 * which matches the given keyref. */
949
gpg_error_t
950
agent_scd_keypairinfo (ctrl_t ctrl, const char *keyref, keypair_info_t *r_list)
951
0
{
952
0
  gpg_error_t err;
953
0
  struct keypairinfo_cb_parm_s parm;
954
0
  struct default_inq_parm_s inq_parm;
955
0
  char line[ASSUAN_LINELENGTH];
956
957
0
  *r_list = NULL;
958
0
  err= start_agent (ctrl, 1);
959
0
  if (err)
960
0
    return err;
961
0
  memset (&inq_parm, 0, sizeof inq_parm);
962
0
  inq_parm.ctx = agent_ctx;
963
964
0
  parm.kpinfo = NULL;
965
0
  parm.kpinfo_tail = &parm.kpinfo;
966
967
0
  if (keyref)
968
0
    snprintf (line, DIM(line), "SCD READKEY --info-only %s", keyref);
969
0
  else
970
0
    snprintf (line, DIM(line), "SCD LEARN --keypairinfo");
971
972
0
  err = assuan_transact (agent_ctx, line,
973
0
                         NULL, NULL,
974
0
                         default_inq_cb, &inq_parm,
975
0
                         scd_keypairinfo_status_cb, &parm);
976
0
  if (!err && !parm.kpinfo)
977
0
    err = gpg_error (GPG_ERR_NO_DATA);
978
979
0
  if (err)
980
0
    free_keypair_info (parm.kpinfo);
981
0
  else
982
0
    *r_list = parm.kpinfo;
983
0
  return err;
984
0
}
985
986
987
988
/* Send an APDU to the current card.  On success the status word is
989
 * stored at R_SW unless R_SQ is NULL.  With HEXAPDU being NULL only a
990
 * RESET command is send to scd.  HEXAPDU may also be one of theseo
991
 * special strings:
992
 *
993
 *   "undefined"       :: Send the command "SCD SERIALNO undefined"
994
 *   "lock"            :: Send the command "SCD LOCK --wait"
995
 *   "trylock"         :: Send the command "SCD LOCK"
996
 *   "unlock"          :: Send the command "SCD UNLOCK"
997
 *   "reset-keep-lock" :: Send the command "SCD RESET --keep-lock"
998
 *
999
 * Used by:
1000
 *  card-util.c
1001
 */
1002
gpg_error_t
1003
agent_scd_apdu (const char *hexapdu, unsigned int *r_sw)
1004
0
{
1005
0
  gpg_error_t err;
1006
1007
  /* Start the agent but not with the card flag so that we do not
1008
     autoselect the openpgp application.  */
1009
0
  err = start_agent (NULL, 0);
1010
0
  if (err)
1011
0
    return err;
1012
1013
0
  if (!hexapdu)
1014
0
    {
1015
0
      err = assuan_transact (agent_ctx, "SCD RESET",
1016
0
                             NULL, NULL, NULL, NULL, NULL, NULL);
1017
1018
0
    }
1019
0
  else if (!strcmp (hexapdu, "reset-keep-lock"))
1020
0
    {
1021
0
      err = assuan_transact (agent_ctx, "SCD RESET --keep-lock",
1022
0
                             NULL, NULL, NULL, NULL, NULL, NULL);
1023
0
    }
1024
0
  else if (!strcmp (hexapdu, "lock"))
1025
0
    {
1026
0
      err = assuan_transact (agent_ctx, "SCD LOCK --wait",
1027
0
                             NULL, NULL, NULL, NULL, NULL, NULL);
1028
0
    }
1029
0
  else if (!strcmp (hexapdu, "trylock"))
1030
0
    {
1031
0
      err = assuan_transact (agent_ctx, "SCD LOCK",
1032
0
                             NULL, NULL, NULL, NULL, NULL, NULL);
1033
0
    }
1034
0
  else if (!strcmp (hexapdu, "unlock"))
1035
0
    {
1036
0
      err = assuan_transact (agent_ctx, "SCD UNLOCK",
1037
0
                             NULL, NULL, NULL, NULL, NULL, NULL);
1038
0
    }
1039
0
  else if (!strcmp (hexapdu, "undefined"))
1040
0
    {
1041
0
      err = assuan_transact (agent_ctx, "SCD SERIALNO undefined",
1042
0
                             NULL, NULL, NULL, NULL, NULL, NULL);
1043
0
    }
1044
0
  else
1045
0
    {
1046
0
      char line[ASSUAN_LINELENGTH];
1047
0
      membuf_t mb;
1048
0
      unsigned char *data;
1049
0
      size_t datalen;
1050
1051
0
      init_membuf (&mb, 256);
1052
1053
0
      snprintf (line, DIM(line), "SCD APDU %s", hexapdu);
1054
0
      err = assuan_transact (agent_ctx, line,
1055
0
                             put_membuf_cb, &mb, NULL, NULL, NULL, NULL);
1056
0
      if (!err)
1057
0
        {
1058
0
          data = get_membuf (&mb, &datalen);
1059
0
          if (!data)
1060
0
            err = gpg_error_from_syserror ();
1061
0
          else if (datalen < 2) /* Ooops */
1062
0
            err = gpg_error (GPG_ERR_CARD);
1063
0
          else
1064
0
            {
1065
0
              *r_sw = buf16_to_uint (data+datalen-2);
1066
0
            }
1067
0
          xfree (data);
1068
0
        }
1069
0
    }
1070
1071
0
  return err;
1072
0
}
1073
1074
int
1075
agent_keytotpm (ctrl_t ctrl, const char *hexgrip)
1076
0
{
1077
0
  int rc;
1078
0
  char line[ASSUAN_LINELENGTH];
1079
0
  struct default_inq_parm_s parm;
1080
1081
0
  snprintf(line, DIM(line), "KEYTOTPM %s\n", hexgrip);
1082
1083
0
  if (strchr (hexgrip, ','))
1084
0
    {
1085
0
      log_error ("storing a part of a composite key is not yet supported\n");
1086
0
      return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1087
0
    }
1088
1089
0
  rc = start_agent (ctrl, 0);
1090
0
  if (rc)
1091
0
    return rc;
1092
0
  parm.ctx = agent_ctx;
1093
0
  parm.ctrl = ctrl;
1094
1095
0
  rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, &parm,
1096
0
      NULL, NULL);
1097
0
  if (rc)
1098
0
    log_log (GPGRT_LOGLVL_ERROR, _("error from TPM: %s\n"), gpg_strerror (rc));
1099
0
  return rc;
1100
0
}
1101
1102
1103
/* Used by:
1104
 *  card_store_subkey
1105
 *  card_store_key_with_backup
1106
 */
1107
int
1108
agent_keytocard (const char *hexgrip, int keyno, int force,
1109
                 const char *serialno, const char *timestamp,
1110
                 const char *ecdh_param_str)
1111
0
{
1112
0
  int rc;
1113
0
  char line[ASSUAN_LINELENGTH];
1114
0
  struct default_inq_parm_s parm;
1115
1116
0
  memset (&parm, 0, sizeof parm);
1117
1118
0
  if (strchr (hexgrip, ','))
1119
0
    {
1120
0
      log_error ("storing a part of a composite key is not yet supported\n");
1121
0
      return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1122
0
    }
1123
1124
1125
0
  snprintf (line, DIM(line), "KEYTOCARD %s%s %s OPENPGP.%d %s%s%s",
1126
0
            force?"--force ": "", hexgrip, serialno, keyno, timestamp,
1127
0
            ecdh_param_str? " ":"", ecdh_param_str? ecdh_param_str:"");
1128
1129
0
  rc = start_agent (NULL, 1);
1130
0
  if (rc)
1131
0
    return rc;
1132
0
  parm.ctx = agent_ctx;
1133
1134
0
  rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, &parm,
1135
0
                        NULL, NULL);
1136
0
  status_sc_op_failure (rc);
1137
0
  return rc;
1138
0
}
1139
1140
1141

1142
/* Object used with the agent_scd_getattr_one.  */
1143
struct getattr_one_parm_s {
1144
  const char *keyword;  /* Keyword to look for.  */
1145
  char *data;           /* Malloced and unescaped data.  */
1146
  gpg_error_t err;      /* Error code or 0 on success. */
1147
};
1148
1149
1150
/* Callback for agent_scd_getattr_one.  */
1151
static gpg_error_t
1152
getattr_one_status_cb (void *opaque, const char *line)
1153
0
{
1154
0
  struct getattr_one_parm_s *parm = opaque;
1155
0
  const char *s;
1156
1157
0
  if (parm->data)
1158
0
    return 0; /* We want only the first occurrence.  */
1159
1160
0
  if ((s=has_leading_keyword (line, parm->keyword)))
1161
0
    {
1162
0
      parm->data = percent_plus_unescape (s, 0xff);
1163
0
      if (!parm->data)
1164
0
        parm->err = gpg_error_from_syserror ();
1165
0
    }
1166
1167
0
  return 0;
1168
0
}
1169
1170
1171
/* Simplified version of agent_scd_getattr.  This function returns
1172
 * only the first occurrence of the attribute NAME and stores it at
1173
 * R_VALUE.  A nul in the result is silennly replaced by 0xff.  On
1174
 * error NULL is stored at R_VALUE.  */
1175
gpg_error_t
1176
agent_scd_getattr_one (const char *name, char **r_value)
1177
0
{
1178
0
  gpg_error_t err;
1179
0
  char line[ASSUAN_LINELENGTH];
1180
0
  struct default_inq_parm_s inqparm;
1181
0
  struct getattr_one_parm_s parm;
1182
1183
0
  *r_value = NULL;
1184
1185
0
  if (!*name)
1186
0
    return gpg_error (GPG_ERR_INV_VALUE);
1187
1188
0
  memset (&inqparm, 0, sizeof inqparm);
1189
0
  inqparm.ctx = agent_ctx;
1190
1191
0
  memset (&parm, 0, sizeof parm);
1192
0
  parm.keyword = name;
1193
1194
  /* We assume that NAME does not need escaping. */
1195
0
  if (12 + strlen (name) > DIM(line)-1)
1196
0
    return gpg_error (GPG_ERR_TOO_LARGE);
1197
0
  stpcpy (stpcpy (line, "SCD GETATTR "), name);
1198
1199
0
  err = start_agent (NULL, 1);
1200
0
  if (err)
1201
0
    return err;
1202
1203
0
  err = assuan_transact (agent_ctx, line,
1204
0
                         NULL, NULL,
1205
0
                         default_inq_cb, &inqparm,
1206
0
                         getattr_one_status_cb, &parm);
1207
0
  if (!err && parm.err)
1208
0
    err = parm.err;
1209
0
  else if (!err && !parm.data)
1210
0
    err = gpg_error (GPG_ERR_NO_DATA);
1211
1212
0
  if (!err)
1213
0
    *r_value = parm.data;
1214
0
  else
1215
0
    xfree (parm.data);
1216
1217
0
  return err;
1218
0
}
1219
1220
1221

1222
/* Call the agent to retrieve a data object.  This function returns
1223
 * the data in the same structure as used by the learn command.  It is
1224
 * allowed to update such a structure using this command.
1225
 *
1226
 *  Used by:
1227
 *     build_sk_list
1228
 *     enum_secret_keys
1229
 *     get_signature_count
1230
 *     card-util.c
1231
 *     generate_keypair (KEY-ATTR)
1232
 *     card_store_key_with_backup (SERIALNO)
1233
 *     generate_card_subkeypair  (KEY-ATTR)
1234
 */
1235
int
1236
agent_scd_getattr (const char *name, struct agent_card_info_s *info)
1237
0
{
1238
0
  int rc;
1239
0
  char line[ASSUAN_LINELENGTH];
1240
0
  struct default_inq_parm_s parm;
1241
1242
0
  memset (&parm, 0, sizeof parm);
1243
1244
0
  if (!*name)
1245
0
    return gpg_error (GPG_ERR_INV_VALUE);
1246
1247
  /* We assume that NAME does not need escaping. */
1248
0
  if (12 + strlen (name) > DIM(line)-1)
1249
0
    return gpg_error (GPG_ERR_TOO_LARGE);
1250
0
  stpcpy (stpcpy (line, "SCD GETATTR "), name);
1251
1252
0
  rc = start_agent (NULL, 1);
1253
0
  if (rc)
1254
0
    return rc;
1255
1256
0
  parm.ctx = agent_ctx;
1257
0
  rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, &parm,
1258
0
                        learn_status_cb, info);
1259
0
  if (!rc && !strcmp (name, "KEY-FPR"))
1260
0
    {
1261
      /* Let the agent create the shadow keys if not yet done.  */
1262
0
      if (info->fpr1len)
1263
0
        assuan_transact (agent_ctx, "READKEY --card --no-data -- $SIGNKEYID",
1264
0
                         NULL, NULL, NULL, NULL, NULL, NULL);
1265
0
      if (info->fpr2len)
1266
0
        assuan_transact (agent_ctx, "READKEY --card --no-data -- $ENCRKEYID",
1267
0
                         NULL, NULL, NULL, NULL, NULL, NULL);
1268
0
    }
1269
1270
0
  return rc;
1271
0
}
1272
1273
1274

1275
/* Send an setattr command to the SCdaemon.
1276
 * Used by:
1277
 *   card-util.c
1278
 */
1279
gpg_error_t
1280
agent_scd_setattr (const char *name, const void *value_arg, size_t valuelen)
1281
0
{
1282
0
  gpg_error_t err;
1283
0
  const unsigned char *value = value_arg;
1284
0
  char line[ASSUAN_LINELENGTH];
1285
0
  char *p;
1286
0
  struct default_inq_parm_s parm;
1287
1288
0
  memset (&parm, 0, sizeof parm);
1289
1290
0
  if (!*name || !valuelen)
1291
0
    return gpg_error (GPG_ERR_INV_VALUE);
1292
1293
  /* We assume that NAME does not need escaping. */
1294
0
  if (12 + strlen (name) > DIM(line)-1)
1295
0
    return gpg_error (GPG_ERR_TOO_LARGE);
1296
1297
0
  p = stpcpy (stpcpy (line, "SCD SETATTR "), name);
1298
0
  *p++ = ' ';
1299
0
  for (; valuelen; value++, valuelen--)
1300
0
    {
1301
0
      if (p >= line + DIM(line)-5 )
1302
0
        return gpg_error (GPG_ERR_TOO_LARGE);
1303
0
      if (*value < ' ' || *value == '+' || *value == '%')
1304
0
        {
1305
0
          sprintf (p, "%%%02X", *value);
1306
0
          p += 3;
1307
0
        }
1308
0
      else if (*value == ' ')
1309
0
        *p++ = '+';
1310
0
      else
1311
0
        *p++ = *value;
1312
0
    }
1313
0
  *p = 0;
1314
1315
0
  err = start_agent (NULL, 1);
1316
0
  if (!err)
1317
0
    {
1318
0
      parm.ctx = agent_ctx;
1319
0
      err = assuan_transact (agent_ctx, line, NULL, NULL,
1320
0
                            default_inq_cb, &parm, NULL, NULL);
1321
0
    }
1322
1323
0
  status_sc_op_failure (err);
1324
0
  return err;
1325
0
}
1326
1327
1328

1329
/* Handle a CERTDATA inquiry.  Note, we only send the data,
1330
   assuan_transact takes care of flushing and writing the END
1331
   command. */
1332
static gpg_error_t
1333
inq_writecert_parms (void *opaque, const char *line)
1334
0
{
1335
0
  int rc;
1336
0
  struct writecert_parm_s *parm = opaque;
1337
1338
0
  if (has_leading_keyword (line, "CERTDATA"))
1339
0
    {
1340
0
      rc = assuan_send_data (parm->dflt->ctx,
1341
0
                             parm->certdata, parm->certdatalen);
1342
0
    }
1343
0
  else
1344
0
    rc = default_inq_cb (parm->dflt, line);
1345
1346
0
  return rc;
1347
0
}
1348
1349
1350
/* Send a WRITECERT command to the SCdaemon.
1351
 * Used by:
1352
 *  card-util.c
1353
 */
1354
int
1355
agent_scd_writecert (const char *certidstr,
1356
                     const unsigned char *certdata, size_t certdatalen)
1357
0
{
1358
0
  int rc;
1359
0
  char line[ASSUAN_LINELENGTH];
1360
0
  struct writecert_parm_s parms;
1361
0
  struct default_inq_parm_s dfltparm;
1362
1363
0
  memset (&dfltparm, 0, sizeof dfltparm);
1364
1365
0
  rc = start_agent (NULL, 1);
1366
0
  if (rc)
1367
0
    return rc;
1368
1369
0
  memset (&parms, 0, sizeof parms);
1370
1371
0
  snprintf (line, DIM(line), "SCD WRITECERT %s", certidstr);
1372
0
  dfltparm.ctx = agent_ctx;
1373
0
  parms.dflt = &dfltparm;
1374
0
  parms.certdata = certdata;
1375
0
  parms.certdatalen = certdatalen;
1376
1377
0
  rc = assuan_transact (agent_ctx, line, NULL, NULL,
1378
0
                        inq_writecert_parms, &parms, NULL, NULL);
1379
1380
0
  return rc;
1381
0
}
1382
1383
1384

1385
/* Status callback for the SCD GENKEY command. */
1386
static gpg_error_t
1387
scd_genkey_cb (void *opaque, const char *line)
1388
0
{
1389
0
  u32 *createtime = opaque;
1390
0
  const char *keyword = line;
1391
0
  int keywordlen;
1392
1393
0
  for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1394
0
    ;
1395
0
  while (spacep (line))
1396
0
    line++;
1397
1398
0
 if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
1399
0
    {
1400
0
      *createtime = (u32)strtoul (line, NULL, 10);
1401
0
    }
1402
0
  else if (keywordlen == 8 && !memcmp (keyword, "PROGRESS", keywordlen))
1403
0
    {
1404
0
      write_status_text (STATUS_PROGRESS, line);
1405
0
    }
1406
1407
0
  return 0;
1408
0
}
1409
1410
/* Send a GENKEY command to the SCdaemon.  If *CREATETIME is not 0,
1411
 * the value will be passed to SCDAEMON with --timestamp option so that
1412
 * the key is created with this.  Otherwise, timestamp was generated by
1413
 * SCDEAMON.  On success, creation time is stored back to
1414
 * CREATETIME.
1415
 * Used by:
1416
 *   gen_card_key
1417
 */
1418
int
1419
agent_scd_genkey (int keyno, int force, u32 *createtime)
1420
0
{
1421
0
  int rc;
1422
0
  char line[ASSUAN_LINELENGTH];
1423
0
  gnupg_isotime_t tbuf;
1424
0
  struct default_inq_parm_s dfltparm;
1425
1426
0
  memset (&dfltparm, 0, sizeof dfltparm);
1427
1428
0
  rc = start_agent (NULL, 1);
1429
0
  if (rc)
1430
0
    return rc;
1431
1432
0
  if (*createtime)
1433
0
    epoch2isotime (tbuf, *createtime);
1434
0
  else
1435
0
    *tbuf = 0;
1436
1437
0
  snprintf (line, DIM(line), "SCD GENKEY %s%s %s %d",
1438
0
            *tbuf? "--timestamp=":"", tbuf,
1439
0
            force? "--force":"",
1440
0
            keyno);
1441
1442
0
  dfltparm.ctx = agent_ctx;
1443
0
  rc = assuan_transact (agent_ctx, line,
1444
0
                        NULL, NULL, default_inq_cb, &dfltparm,
1445
0
                        scd_genkey_cb, createtime);
1446
1447
0
  status_sc_op_failure (rc);
1448
0
  return rc;
1449
0
}
1450
1451
1452

1453
/* Return the serial number of the card or an appropriate error.  The
1454
 * serial number is returned as a hexstring.  With DEMAND the active
1455
 * card is switched to the card with that serialno.
1456
 * Used by:
1457
 *   card-util.c
1458
 *   build_sk_list
1459
 *   enum_secret_keys
1460
 */
1461
int
1462
agent_scd_serialno (char **r_serialno, const char *demand)
1463
0
{
1464
0
  int err;
1465
0
  char *serialno = NULL;
1466
0
  char line[ASSUAN_LINELENGTH];
1467
1468
0
  if (r_serialno)
1469
0
    *r_serialno = NULL;
1470
1471
0
  err = start_agent (NULL, (1 | FLAG_FOR_CARD_SUPPRESS_ERRORS));
1472
0
  if (err)
1473
0
    return err;
1474
1475
0
  if (!demand)
1476
0
    strcpy (line, "SCD SERIALNO");
1477
0
  else
1478
0
    snprintf (line, DIM(line), "SCD SERIALNO --demand=%s", demand);
1479
1480
0
  err = assuan_transact (agent_ctx, line,
1481
0
                         NULL, NULL, NULL, NULL,
1482
0
                         get_serialno_cb, &serialno);
1483
0
  if (err)
1484
0
    {
1485
0
      xfree (serialno);
1486
0
      return err;
1487
0
    }
1488
1489
0
  if (r_serialno)
1490
0
    *r_serialno = serialno;
1491
0
  else
1492
0
    xfree (serialno);
1493
1494
0
  return 0;
1495
0
}
1496
1497
1498

1499
/* Send a READCERT command to the SCdaemon.
1500
 * Used by:
1501
 *  card-util.c
1502
 */
1503
int
1504
agent_scd_readcert (const char *certidstr,
1505
                    void **r_buf, size_t *r_buflen)
1506
0
{
1507
0
  int rc;
1508
0
  char line[ASSUAN_LINELENGTH];
1509
0
  membuf_t data;
1510
0
  size_t len;
1511
0
  struct default_inq_parm_s dfltparm;
1512
1513
0
  memset (&dfltparm, 0, sizeof dfltparm);
1514
1515
0
  *r_buf = NULL;
1516
0
  rc = start_agent (NULL, 1);
1517
0
  if (rc)
1518
0
    return rc;
1519
1520
0
  dfltparm.ctx = agent_ctx;
1521
1522
0
  init_membuf (&data, 2048);
1523
1524
0
  snprintf (line, DIM(line), "SCD READCERT %s", certidstr);
1525
0
  rc = assuan_transact (agent_ctx, line,
1526
0
                        put_membuf_cb, &data,
1527
0
                        default_inq_cb, &dfltparm,
1528
0
                        NULL, NULL);
1529
0
  if (rc)
1530
0
    {
1531
0
      xfree (get_membuf (&data, &len));
1532
0
      return rc;
1533
0
    }
1534
0
  *r_buf = get_membuf (&data, r_buflen);
1535
0
  if (!*r_buf)
1536
0
    return gpg_error (GPG_ERR_ENOMEM);
1537
1538
0
  return 0;
1539
0
}
1540
1541
1542
/* Callback for the agent_scd_readkey function.  */
1543
static gpg_error_t
1544
readkey_status_cb (void *opaque, const char *line)
1545
0
{
1546
0
  u32 *keytimep = opaque;
1547
0
  gpg_error_t err = 0;
1548
0
  const char *args;
1549
0
  char *line_buffer = NULL;
1550
1551
  /* FIXME: Get that info from the KEYPAIRINFO line.  */
1552
0
  if ((args = has_leading_keyword (line, "KEYPAIRINFO"))
1553
0
      && !*keytimep)
1554
0
    {
1555
      /* The format of such a line is:
1556
       *   KEYPAIRINFO <hexgrip> <keyref> [usage] [keytime]
1557
       *
1558
       * Note that we use only the first valid KEYPAIRINFO line.  More
1559
       * lines are possible if a second card carries the same key.
1560
       */
1561
0
      const char *fields[4];
1562
0
      int nfields;
1563
0
      time_t atime;
1564
1565
0
      line_buffer = xtrystrdup (line);
1566
0
      if (!line_buffer)
1567
0
        {
1568
0
          err = gpg_error_from_syserror ();
1569
0
          goto leave;
1570
0
        }
1571
0
      if ((nfields = split_fields (line_buffer, fields, DIM (fields))) < 4)
1572
0
        goto leave;  /* not enough args - ignore  */
1573
1574
0
      if (nfields > 3)
1575
0
        {
1576
0
          atime = parse_timestamp (fields[3], NULL);
1577
0
          if (atime == (time_t)(-1))
1578
0
            atime = 0;
1579
0
          *keytimep = atime;
1580
0
        }
1581
0
      else
1582
0
        *keytimep = 0;
1583
0
    }
1584
1585
0
 leave:
1586
0
  xfree (line_buffer);
1587
0
  return err;
1588
0
}
1589
1590
1591
/* This is a variant of agent_readkey which sends a READKEY command
1592
 * directly Scdaemon.  On success a new s-expression is stored at
1593
 * R_RESULT.  If R_KEYTIME is not NULL the key cresation time of an
1594
 * OpenPGP card is stored there - if that is not known 0 is stored.
1595
 * In the latter case it is allowed to pass NULL for R_RESULT.  */
1596
gpg_error_t
1597
agent_scd_readkey (ctrl_t ctrl, const char *keyrefstr,
1598
                   gcry_sexp_t *r_result, u32 *r_keytime)
1599
0
{
1600
0
  gpg_error_t err;
1601
0
  char line[ASSUAN_LINELENGTH];
1602
0
  membuf_t data;
1603
0
  unsigned char *buf;
1604
0
  size_t len, buflen;
1605
0
  struct default_inq_parm_s dfltparm;
1606
0
  u32 keytime;
1607
1608
0
  memset (&dfltparm, 0, sizeof dfltparm);
1609
0
  dfltparm.ctx = agent_ctx;
1610
1611
0
  if (r_result)
1612
0
    *r_result = NULL;
1613
0
  if (r_keytime)
1614
0
    *r_keytime = 0;
1615
0
  err = start_agent (ctrl, 1);
1616
0
  if (err)
1617
0
    return err;
1618
1619
0
  init_membuf (&data, 1024);
1620
0
  snprintf (line, DIM(line),
1621
0
            "SCD READKEY --info%s -- %s",
1622
0
            r_result? "":"-only", keyrefstr);
1623
0
  keytime = 0;
1624
0
  err = assuan_transact (agent_ctx, line,
1625
0
                         put_membuf_cb, &data,
1626
0
                         default_inq_cb, &dfltparm,
1627
0
                         readkey_status_cb, &keytime);
1628
0
  if (err)
1629
0
    {
1630
0
      xfree (get_membuf (&data, &len));
1631
0
      return err;
1632
0
    }
1633
0
  buf = get_membuf (&data, &buflen);
1634
0
  if (!buf)
1635
0
    return gpg_error_from_syserror ();
1636
1637
0
  if (r_result)
1638
0
    err = gcry_sexp_new (r_result, buf, buflen, 0);
1639
0
  else
1640
0
    err = 0;
1641
0
  xfree (buf);
1642
1643
0
  if (!err && r_keytime)
1644
0
    *r_keytime = keytime;
1645
0
  return err;
1646
0
}
1647
1648
1649

1650
struct card_cardlist_parm_s {
1651
  int error;
1652
  strlist_t list;
1653
};
1654
1655
1656
/* Callback function for agent_card_cardlist.  */
1657
static gpg_error_t
1658
card_cardlist_cb (void *opaque, const char *line)
1659
0
{
1660
0
  struct card_cardlist_parm_s *parm = opaque;
1661
0
  const char *keyword = line;
1662
0
  int keywordlen;
1663
1664
0
  for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1665
0
    ;
1666
0
  while (spacep (line))
1667
0
    line++;
1668
1669
0
  if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
1670
0
    {
1671
0
      const char *s;
1672
0
      int n;
1673
1674
0
      for (n=0,s=line; hexdigitp (s); s++, n++)
1675
0
        ;
1676
1677
0
      if (!n || (n&1) || *s)
1678
0
        parm->error = gpg_error (GPG_ERR_ASS_PARAMETER);
1679
0
      else
1680
0
        add_to_strlist (&parm->list, line);
1681
0
    }
1682
1683
0
  return 0;
1684
0
}
1685
1686
1687
/* Return a list of currently available cards.
1688
 * Used by:
1689
 *   card-util.c
1690
 *   skclist.c
1691
 */
1692
int
1693
agent_scd_cardlist (strlist_t *result)
1694
0
{
1695
0
  int err;
1696
0
  char line[ASSUAN_LINELENGTH];
1697
0
  struct card_cardlist_parm_s parm;
1698
1699
0
  memset (&parm, 0, sizeof parm);
1700
0
  *result = NULL;
1701
0
  err = start_agent (NULL, 1 | FLAG_FOR_CARD_SUPPRESS_ERRORS);
1702
0
  if (err)
1703
0
    return err;
1704
1705
0
  strcpy (line, "SCD GETINFO card_list");
1706
1707
0
  err = assuan_transact (agent_ctx, line,
1708
0
                         NULL, NULL, NULL, NULL,
1709
0
                         card_cardlist_cb, &parm);
1710
0
  if (!err && parm.error)
1711
0
    err = parm.error;
1712
1713
0
  if (!err)
1714
0
    *result = parm.list;
1715
0
  else
1716
0
    free_strlist (parm.list);
1717
1718
0
  return 0;
1719
0
}
1720
1721
1722
/* Make the app APPNAME the one on the card.  This is sometimes
1723
 * required to make sure no other process has switched a card to
1724
 * another application.  The only useful APPNAME is "openpgp".  */
1725
gpg_error_t
1726
agent_scd_switchapp (const char *appname)
1727
0
{
1728
0
  int err;
1729
0
  char line[ASSUAN_LINELENGTH];
1730
1731
0
  if (appname && !*appname)
1732
0
    appname = NULL;
1733
1734
0
  err = start_agent (NULL, (1 | FLAG_FOR_CARD_SUPPRESS_ERRORS));
1735
0
  if (err)
1736
0
    return err;
1737
1738
0
  snprintf (line, DIM(line), "SCD SWITCHAPP --%s%s",
1739
0
            appname? " ":"", appname? appname:"");
1740
0
  return assuan_transact (agent_ctx, line,
1741
0
                          NULL, NULL, NULL, NULL,
1742
0
                          NULL, NULL);
1743
0
}
1744
1745
1746

1747
struct card_keyinfo_parm_s {
1748
  int error;
1749
  keypair_info_t list;
1750
};
1751
1752
/* Callback function for agent_card_keylist.  */
1753
static gpg_error_t
1754
card_keyinfo_cb (void *opaque, const char *line)
1755
0
{
1756
0
  gpg_error_t err = 0;
1757
0
  struct card_keyinfo_parm_s *parm = opaque;
1758
0
  const char *keyword = line;
1759
0
  int keywordlen;
1760
0
  keypair_info_t keyinfo = NULL;
1761
1762
0
  for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1763
0
    ;
1764
0
  while (spacep (line))
1765
0
    line++;
1766
1767
0
  if (keywordlen == 7 && !memcmp (keyword, "KEYINFO", keywordlen))
1768
0
    {
1769
0
      const char *s;
1770
0
      int n;
1771
0
      keypair_info_t *l_p = &parm->list;
1772
1773
0
      while ((*l_p))
1774
0
        l_p = &(*l_p)->next;
1775
1776
0
      keyinfo = xtrycalloc (1, sizeof *keyinfo);
1777
0
      if (!keyinfo)
1778
0
        goto alloc_error;
1779
1780
0
      for (n=0,s=line; hexdigitp (s); s++, n++)
1781
0
        ;
1782
1783
0
      if (n != 40)
1784
0
        goto parm_error;
1785
1786
0
      memcpy (keyinfo->keygrip, line, 40);
1787
0
      keyinfo->keygrip[40] = 0;
1788
1789
0
      line = s;
1790
1791
0
      if (!*line)
1792
0
        goto parm_error;
1793
1794
0
      while (spacep (line))
1795
0
        line++;
1796
1797
0
      if (*line++ != 'T')
1798
0
        goto parm_error;
1799
1800
0
      if (!*line)
1801
0
        goto parm_error;
1802
1803
0
      while (spacep (line))
1804
0
        line++;
1805
1806
0
      for (n=0,s=line; hexdigitp (s); s++, n++)
1807
0
        ;
1808
1809
0
      if (!n)
1810
0
        goto parm_error;
1811
1812
0
      keyinfo->serialno = xtrymalloc (n+1);
1813
0
      if (!keyinfo->serialno)
1814
0
        goto alloc_error;
1815
1816
0
      memcpy (keyinfo->serialno, line, n);
1817
0
      keyinfo->serialno[n] = 0;
1818
1819
0
      line = s;
1820
1821
0
      if (!*line)
1822
0
        goto parm_error;
1823
1824
0
      while (spacep (line))
1825
0
        line++;
1826
1827
0
      if (!*line)
1828
0
        goto parm_error;
1829
1830
0
      keyinfo->idstr = xtrystrdup (line);
1831
0
      if (!keyinfo->idstr)
1832
0
        goto alloc_error;
1833
1834
0
      *l_p = keyinfo;
1835
0
    }
1836
1837
0
  return err;
1838
1839
0
 alloc_error:
1840
0
  xfree (keyinfo);
1841
0
  if (!parm->error)
1842
0
    parm->error = gpg_error_from_syserror ();
1843
0
  return 0;
1844
1845
0
 parm_error:
1846
0
  xfree (keyinfo);
1847
0
  if (!parm->error)
1848
0
    parm->error = gpg_error (GPG_ERR_ASS_PARAMETER);
1849
0
  return 0;
1850
0
}
1851
1852
1853
/* Free a keypair info list.  */
1854
void
1855
free_keypair_info (keypair_info_t l)
1856
0
{
1857
0
  keypair_info_t l_next;
1858
1859
0
  for (; l; l = l_next)
1860
0
    {
1861
0
      l_next = l->next;
1862
0
      xfree (l->serialno);
1863
0
      xfree (l->idstr);
1864
0
      xfree (l);
1865
0
    }
1866
0
}
1867
1868
/* Call the scdaemon to check if a key of KEYGRIP is available, or
1869
   retrieve list of available keys on cards.  With CAP, we can limit
1870
   keys with specified capability.  On success, the allocated
1871
   structure is stored at RESULT.  On error, an error code is returned
1872
   and NULL is stored at RESULT.  */
1873
gpg_error_t
1874
agent_scd_keyinfo (const char *keygrip, int cap,
1875
                   keypair_info_t *result)
1876
0
{
1877
0
  int err;
1878
0
  struct card_keyinfo_parm_s parm;
1879
0
  char line[ASSUAN_LINELENGTH];
1880
0
  char *list_option;
1881
1882
0
  *result = NULL;
1883
1884
0
  switch (cap)
1885
0
    {
1886
0
    case                  0: list_option = "--list";      break;
1887
0
    case GCRY_PK_USAGE_SIGN: list_option = "--list=sign"; break;
1888
0
    case GCRY_PK_USAGE_ENCR: list_option = "--list=encr"; break;
1889
0
    case GCRY_PK_USAGE_AUTH: list_option = "--list=auth"; break;
1890
0
    default:                 return gpg_error (GPG_ERR_INV_VALUE);
1891
0
    }
1892
1893
0
  memset (&parm, 0, sizeof parm);
1894
0
  snprintf (line, sizeof line, "SCD KEYINFO %s",
1895
0
            keygrip ? keygrip : list_option);
1896
1897
0
  err = start_agent (NULL, 1 | FLAG_FOR_CARD_SUPPRESS_ERRORS);
1898
0
  if (err)
1899
0
    return err;
1900
1901
0
  err = assuan_transact (agent_ctx, line,
1902
0
                         NULL, NULL, NULL, NULL,
1903
0
                         card_keyinfo_cb, &parm);
1904
0
  if (!err && parm.error)
1905
0
    err = parm.error;
1906
1907
0
  if (!err)
1908
0
    *result = parm.list;
1909
0
  else
1910
0
    free_keypair_info (parm.list);
1911
1912
0
  return err;
1913
0
}
1914

1915
/* Change the PIN of an OpenPGP card or reset the retry counter.
1916
 * CHVNO 1: Change the PIN
1917
 *       2: For v1 cards: Same as 1.
1918
 *          For v2 cards: Reset the PIN using the Reset Code.
1919
 *       3: Change the admin PIN
1920
 *     101: Set a new PIN and reset the retry counter
1921
 *     102: For v1 cars: Same as 101.
1922
 *          For v2 cards: Set a new Reset Code.
1923
 * SERIALNO is not used.
1924
 * Used by:
1925
 *  card-util.c
1926
 */
1927
int
1928
agent_scd_change_pin (int chvno, const char *serialno)
1929
0
{
1930
0
  int rc;
1931
0
  char line[ASSUAN_LINELENGTH];
1932
0
  const char *reset = "";
1933
0
  struct default_inq_parm_s dfltparm;
1934
1935
0
  memset (&dfltparm, 0, sizeof dfltparm);
1936
1937
0
  (void)serialno;
1938
1939
0
  if (chvno >= 100)
1940
0
    reset = "--reset";
1941
0
  chvno %= 100;
1942
1943
0
  rc = start_agent (NULL, 1);
1944
0
  if (rc)
1945
0
    return rc;
1946
0
  dfltparm.ctx = agent_ctx;
1947
1948
0
  snprintf (line, DIM(line), "SCD PASSWD %s %d", reset, chvno);
1949
0
  rc = assuan_transact (agent_ctx, line,
1950
0
                        NULL, NULL,
1951
0
                        default_inq_cb, &dfltparm,
1952
0
                        NULL, NULL);
1953
0
  status_sc_op_failure (rc);
1954
0
  return rc;
1955
0
}
1956
1957
1958
/* Perform a CHECKPIN operation.  SERIALNO should be the serial
1959
 * number of the card - optionally followed by the fingerprint;
1960
 * however the fingerprint is ignored here.
1961
 * Used by:
1962
 *  card-util.c
1963
 */
1964
int
1965
agent_scd_checkpin  (const char *serialno)
1966
0
{
1967
0
  int rc;
1968
0
  char line[ASSUAN_LINELENGTH];
1969
0
  struct default_inq_parm_s dfltparm;
1970
1971
0
  memset (&dfltparm, 0, sizeof dfltparm);
1972
1973
0
  rc = start_agent (NULL, 1);
1974
0
  if (rc)
1975
0
    return rc;
1976
0
  dfltparm.ctx = agent_ctx;
1977
1978
0
  snprintf (line, DIM(line), "SCD CHECKPIN %s", serialno);
1979
0
  rc = assuan_transact (agent_ctx, line,
1980
0
                        NULL, NULL,
1981
0
                        default_inq_cb, &dfltparm,
1982
0
                        NULL, NULL);
1983
0
  status_sc_op_failure (rc);
1984
0
  return rc;
1985
0
}
1986
1987
1988

1989
/* Note: All strings shall be UTF-8. On success the caller needs to
1990
   free the string stored at R_PASSPHRASE. On error NULL will be
1991
   stored at R_PASSPHRASE and an appropriate error code returned.
1992
   Only called from passphrase.c:passphrase_get - see there for more
1993
   comments on this ugly API. */
1994
gpg_error_t
1995
agent_get_passphrase (const char *cache_id,
1996
                      const char *err_msg,
1997
                      const char *prompt,
1998
                      const char *desc_msg,
1999
                      int newsymkey,
2000
                      int repeat,
2001
                      int check,
2002
                      char **r_passphrase)
2003
0
{
2004
0
  int rc;
2005
0
  char line[ASSUAN_LINELENGTH];
2006
0
  char *arg1 = NULL;
2007
0
  char *arg2 = NULL;
2008
0
  char *arg3 = NULL;
2009
0
  char *arg4 = NULL;
2010
0
  membuf_t data;
2011
0
  struct default_inq_parm_s dfltparm;
2012
0
  int have_newsymkey, wasconf;
2013
2014
0
  memset (&dfltparm, 0, sizeof dfltparm);
2015
2016
0
  *r_passphrase = NULL;
2017
2018
0
  rc = start_agent (NULL, 0);
2019
0
  if (rc)
2020
0
    return rc;
2021
0
  dfltparm.ctx = agent_ctx;
2022
2023
  /* Check that the gpg-agent understands the repeat option.  */
2024
0
  if (assuan_transact (agent_ctx,
2025
0
                       "GETINFO cmd_has_option GET_PASSPHRASE repeat",
2026
0
                       NULL, NULL, NULL, NULL, NULL, NULL))
2027
0
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
2028
0
  have_newsymkey = !(assuan_transact
2029
0
                     (agent_ctx,
2030
0
                      "GETINFO cmd_has_option GET_PASSPHRASE newsymkey",
2031
0
                      NULL, NULL, NULL, NULL, NULL, NULL));
2032
2033
0
  if (cache_id && *cache_id)
2034
0
    if (!(arg1 = percent_plus_escape (cache_id)))
2035
0
      goto no_mem;
2036
0
  if (err_msg && *err_msg)
2037
0
    if (!(arg2 = percent_plus_escape (err_msg)))
2038
0
      goto no_mem;
2039
0
  if (prompt && *prompt)
2040
0
    if (!(arg3 = percent_plus_escape (prompt)))
2041
0
      goto no_mem;
2042
0
  if (desc_msg && *desc_msg)
2043
0
    if (!(arg4 = percent_plus_escape (desc_msg)))
2044
0
      goto no_mem;
2045
2046
  /* CHECK && REPEAT or NEWSYMKEY is here an indication that a new
2047
   * passphrase for symmetric encryption is requested; if the agent
2048
   * supports this we enable the modern API by also passing --newsymkey.  */
2049
0
  snprintf (line, DIM(line),
2050
0
            "GET_PASSPHRASE --data --repeat=%d%s%s -- %s %s %s %s",
2051
0
            repeat,
2052
0
            ((repeat && check) || newsymkey)? " --check":"",
2053
0
            (have_newsymkey && newsymkey)? " --newsymkey":"",
2054
0
            arg1? arg1:"X",
2055
0
            arg2? arg2:"X",
2056
0
            arg3? arg3:"X",
2057
0
            arg4? arg4:"X");
2058
0
  xfree (arg1);
2059
0
  xfree (arg2);
2060
0
  xfree (arg3);
2061
0
  xfree (arg4);
2062
2063
0
  init_membuf_secure (&data, 64);
2064
0
  wasconf = assuan_get_flag (agent_ctx, ASSUAN_CONFIDENTIAL);
2065
0
  assuan_begin_confidential (agent_ctx);
2066
0
  rc = assuan_transact (agent_ctx, line,
2067
0
                        put_membuf_cb, &data,
2068
0
                        default_inq_cb, &dfltparm,
2069
0
                        NULL, NULL);
2070
0
  if (!wasconf)
2071
0
    assuan_end_confidential (agent_ctx);
2072
2073
0
  if (rc)
2074
0
    xfree (get_membuf (&data, NULL));
2075
0
  else
2076
0
    {
2077
0
      put_membuf (&data, "", 1);
2078
0
      *r_passphrase = get_membuf (&data, NULL);
2079
0
      if (!*r_passphrase)
2080
0
        rc = gpg_error_from_syserror ();
2081
0
    }
2082
0
  return rc;
2083
0
 no_mem:
2084
0
  rc = gpg_error_from_syserror ();
2085
0
  xfree (arg1);
2086
0
  xfree (arg2);
2087
0
  xfree (arg3);
2088
0
  xfree (arg4);
2089
0
  return rc;
2090
0
}
2091
2092
2093
gpg_error_t
2094
agent_clear_passphrase (const char *cache_id)
2095
0
{
2096
0
  int rc;
2097
0
  char line[ASSUAN_LINELENGTH];
2098
0
  struct default_inq_parm_s dfltparm;
2099
2100
0
  memset (&dfltparm, 0, sizeof dfltparm);
2101
2102
0
  if (!cache_id || !*cache_id)
2103
0
    return 0;
2104
2105
0
  rc = start_agent (NULL, 0);
2106
0
  if (rc)
2107
0
    return rc;
2108
0
  dfltparm.ctx = agent_ctx;
2109
2110
0
  snprintf (line, DIM(line), "CLEAR_PASSPHRASE %s", cache_id);
2111
0
  return assuan_transact (agent_ctx, line,
2112
0
                          NULL, NULL,
2113
0
                          default_inq_cb, &dfltparm,
2114
0
                          NULL, NULL);
2115
0
}
2116
2117
2118
/* Ask the agent to pop up a confirmation dialog with the text DESC
2119
   and an okay and cancel button. */
2120
gpg_error_t
2121
gpg_agent_get_confirmation (const char *desc)
2122
0
{
2123
0
  int rc;
2124
0
  char *tmp;
2125
0
  char line[ASSUAN_LINELENGTH];
2126
0
  struct default_inq_parm_s dfltparm;
2127
2128
0
  memset (&dfltparm, 0, sizeof dfltparm);
2129
2130
0
  rc = start_agent (NULL, 0);
2131
0
  if (rc)
2132
0
    return rc;
2133
0
  dfltparm.ctx = agent_ctx;
2134
2135
0
  tmp = percent_plus_escape (desc);
2136
0
  if (!tmp)
2137
0
    return gpg_error_from_syserror ();
2138
0
  snprintf (line, DIM(line), "GET_CONFIRMATION %s", tmp);
2139
0
  xfree (tmp);
2140
2141
0
  rc = assuan_transact (agent_ctx, line,
2142
0
                        NULL, NULL,
2143
0
                        default_inq_cb, &dfltparm,
2144
0
                        NULL, NULL);
2145
0
  return rc;
2146
0
}
2147
2148
2149
/* Return the S2K iteration count as computed by gpg-agent.  On error
2150
 * print a warning and return a default value. */
2151
unsigned long
2152
agent_get_s2k_count (void)
2153
0
{
2154
0
  gpg_error_t err;
2155
0
  membuf_t data;
2156
0
  char *buf;
2157
0
  unsigned long count = 0;
2158
2159
0
  err = start_agent (NULL, 0);
2160
0
  if (err)
2161
0
    goto leave;
2162
2163
0
  init_membuf (&data, 32);
2164
0
  err = assuan_transact (agent_ctx, "GETINFO s2k_count",
2165
0
                        put_membuf_cb, &data,
2166
0
                        NULL, NULL, NULL, NULL);
2167
0
  if (err)
2168
0
    xfree (get_membuf (&data, NULL));
2169
0
  else
2170
0
    {
2171
0
      put_membuf (&data, "", 1);
2172
0
      buf = get_membuf (&data, NULL);
2173
0
      if (!buf)
2174
0
        err = gpg_error_from_syserror ();
2175
0
      else
2176
0
        {
2177
0
          count = strtoul (buf, NULL, 10);
2178
0
          xfree (buf);
2179
0
        }
2180
0
    }
2181
2182
0
 leave:
2183
0
  if (err || count < 65536)
2184
0
    {
2185
      /* Don't print an error if an older agent is used.  */
2186
0
      if (err && gpg_err_code (err) != GPG_ERR_ASS_PARAMETER)
2187
0
        log_error (_("problem with the agent: %s\n"), gpg_strerror (err));
2188
2189
      /* Default to 65536 which was used up to 2.0.13.  */
2190
0
      count = 65536;
2191
0
    }
2192
2193
0
  return count;
2194
0
}
2195
2196
2197

2198
struct keyinfo_data_parm_s
2199
{
2200
  char *serialno;
2201
  int is_smartcard;
2202
  int passphrase_cached;
2203
  int cleartext;
2204
  int card_available;
2205
};
2206
2207
2208
static gpg_error_t
2209
keyinfo_status_cb (void *opaque, const char *line)
2210
0
{
2211
0
  struct keyinfo_data_parm_s *data = opaque;
2212
0
  char *s;
2213
2214
0
  if ((s = has_leading_keyword (line, "KEYINFO")) && data)
2215
0
    {
2216
      /* Parse the arguments:
2217
       *      0        1        2        3       4          5
2218
       *   <keygrip> <type> <serialno> <idstr> <cached> <protection>
2219
       *
2220
       *      6        7        8
2221
       *   <sshfpr>  <ttl>  <flags>
2222
       */
2223
0
      const char *fields[9];
2224
2225
0
      if (split_fields (s, fields, DIM (fields)) == 9)
2226
0
        {
2227
0
          data->is_smartcard = (fields[1][0] == 'T');
2228
0
          if (data->is_smartcard && !data->serialno && strcmp (fields[2], "-"))
2229
0
            data->serialno = xtrystrdup (fields[2]);
2230
          /* '1' for cached */
2231
0
          data->passphrase_cached = (fields[4][0] == '1');
2232
          /* 'P' for protected, 'C' for clear */
2233
0
          data->cleartext = (fields[5][0] == 'C');
2234
          /* 'A' for card is available */
2235
0
          data->card_available = (fields[8][0] == 'A');
2236
0
        }
2237
0
    }
2238
0
  return 0;
2239
0
}
2240
2241
2242
/* Ask the agent whether a secret key for the given public key is
2243
 * available.  Returns 0 if not available.  Bigger value is preferred.
2244
 * Will never return a value less than 0.   Defined return values are:
2245
 *  0 := No key or error
2246
 *  1 := Key available
2247
 *  2 := Key available on a smartcard
2248
 *  3 := Key available and passphrase cached
2249
 *  4 := Key available on current smartcard
2250
 */
2251
int
2252
agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk)
2253
0
{
2254
0
  gpg_error_t err;
2255
0
  char line[ASSUAN_LINELENGTH];
2256
0
  char *hexgrip, *p;
2257
0
  struct keyinfo_data_parm_s keyinfo;
2258
0
  int result, result2;
2259
2260
0
  memset (&keyinfo, 0, sizeof keyinfo);
2261
2262
0
  err = start_agent (ctrl, 0);
2263
0
  if (err)
2264
0
    return 0;
2265
2266
0
  err = hexkeygrip_from_pk (pk, &hexgrip);
2267
0
  if (err)
2268
0
    return 0;
2269
0
  if ((p=strchr (hexgrip, ',')))
2270
0
    *p++ = 0;
2271
2272
0
  snprintf (line, sizeof line, "KEYINFO %s", hexgrip);
2273
2274
0
  err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL,
2275
0
                         keyinfo_status_cb, &keyinfo);
2276
0
  xfree (keyinfo.serialno);
2277
0
  if (err)
2278
0
    result = 0;
2279
0
  else if (keyinfo.card_available)
2280
0
    result = 4;
2281
0
  else if (keyinfo.passphrase_cached)
2282
0
    result = 3;
2283
0
  else if (keyinfo.is_smartcard)
2284
0
    result = 2;
2285
0
  else
2286
0
    result = 1;
2287
2288
0
  if (!p)
2289
0
    {
2290
0
      xfree (hexgrip);
2291
0
      return result;  /* Not a dual algo - we are ready.  */
2292
0
    }
2293
2294
  /* Now check the second keygrip.  */
2295
0
  memset (&keyinfo, 0, sizeof keyinfo);
2296
0
  snprintf (line, sizeof line, "KEYINFO %s", p);
2297
2298
0
  err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL,
2299
0
                         keyinfo_status_cb, &keyinfo);
2300
0
  xfree (keyinfo.serialno);
2301
0
  if (err)
2302
0
    result2 = 0;
2303
0
  else if (keyinfo.card_available)
2304
0
    result2 = 4;
2305
0
  else if (keyinfo.passphrase_cached)
2306
0
    result2 = 3;
2307
0
  else if (keyinfo.is_smartcard)
2308
0
    result2 = 2;
2309
0
  else
2310
0
    result2 = 1;
2311
2312
0
  xfree (hexgrip);
2313
2314
0
  if (result == result2)
2315
0
    return result;  /* Both keys have the same status.  */
2316
0
  else if (!result && result2)
2317
0
    return 0;       /* Only first key available - return no key.  */
2318
0
  else if (result && !result2)
2319
0
    return 0;       /* Only second key not available - return no key.  */
2320
0
  else if (result == 4 || result == 2)
2321
0
    return result;  /* First key on card - don't care where the second is.  */
2322
0
  else
2323
0
    return result;
2324
0
}
2325
2326
2327
/* Ask the agent whether a secret key is available for any of the
2328
   keys (primary or sub) in KEYBLOCK.  Returns 0 if available.  */
2329
gpg_error_t
2330
agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock)
2331
0
{
2332
0
  gpg_error_t err;
2333
0
  char line[ASSUAN_LINELENGTH];
2334
0
  char *p;
2335
0
  kbnode_t kbctx, node;
2336
0
  int nkeys;  /* (always zero in secret_keygrips mode)  */
2337
0
  unsigned char grip[KEYGRIP_LEN];
2338
0
  unsigned char grip2[KEYGRIP_LEN];
2339
0
  int grip2_valid;
2340
0
  const unsigned char *s;
2341
0
  unsigned int n;
2342
2343
0
  err = start_agent (ctrl, 0);
2344
0
  if (err)
2345
0
    return err;
2346
2347
  /* If we have not yet issued a "HAVEKEY --list" do that now.  We use
2348
   * a more or less arbitrary limit of 1000 keys.  */
2349
0
  if (ctrl && !ctrl->secret_keygrips && !ctrl->no_more_secret_keygrips)
2350
0
    {
2351
0
      membuf_t data;
2352
2353
0
      init_membuf (&data, 4096);
2354
0
      err = assuan_transact (agent_ctx, "HAVEKEY --list=1000",
2355
0
                             put_membuf_cb, &data,
2356
0
                             NULL, NULL, NULL, NULL);
2357
0
      if (err)
2358
0
        xfree (get_membuf (&data, NULL));
2359
0
      else
2360
0
        {
2361
0
          ctrl->secret_keygrips = get_membuf (&data,
2362
0
                                              &ctrl->secret_keygrips_len);
2363
0
          if (!ctrl->secret_keygrips)
2364
0
            err = gpg_error_from_syserror ();
2365
0
          if ((ctrl->secret_keygrips_len % 20))
2366
0
            {
2367
0
              err = gpg_error (GPG_ERR_INV_DATA);
2368
0
              xfree (ctrl->secret_keygrips);
2369
0
              ctrl->secret_keygrips = NULL;
2370
0
            }
2371
0
        }
2372
0
      if (err)
2373
0
        {
2374
0
          if (!opt.quiet)
2375
0
            log_info ("problem with fast path key listing: %s - ignored\n",
2376
0
                      gpg_strerror (err));
2377
0
          err = 0;
2378
0
        }
2379
      /* We want to do this only once.  */
2380
0
      ctrl->no_more_secret_keygrips = 1;
2381
0
    }
2382
2383
0
  err = gpg_error (GPG_ERR_NO_SECKEY); /* Just in case no key was
2384
                                          found in KEYBLOCK.  */
2385
0
  p = stpcpy (line, "HAVEKEY");
2386
0
  for (kbctx=NULL, nkeys=0; (node = walk_kbnode (keyblock, &kbctx, 0)); )
2387
0
    if (node->pkt->pkttype == PKT_PUBLIC_KEY
2388
0
        || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
2389
0
        || node->pkt->pkttype == PKT_SECRET_KEY
2390
0
        || node->pkt->pkttype == PKT_SECRET_SUBKEY)
2391
0
      {
2392
0
        if (ctrl && ctrl->secret_keygrips)
2393
0
          {
2394
            /* We got an array with all secret keygrips.  Check this.  */
2395
0
            err = keygrip_from_pk (node->pkt->pkt.public_key, grip, 0);
2396
0
            if (err)
2397
0
              return err;
2398
0
            err = keygrip_from_pk (node->pkt->pkt.public_key, grip2, 1);
2399
0
            if (err && gpg_err_code (err) != GPG_ERR_FALSE)
2400
0
              return err;
2401
0
            grip2_valid = !err;
2402
2403
0
            for (s=ctrl->secret_keygrips, n = 0;
2404
0
                 n < ctrl->secret_keygrips_len;
2405
0
                 s += 20, n += 20)
2406
0
              {
2407
0
                if (!memcmp (s, grip, 20))
2408
0
                  return 0;
2409
0
                if (grip2_valid && !memcmp (s, grip2, 20))
2410
0
                  return 0;
2411
0
              }
2412
0
            err = gpg_error (GPG_ERR_NO_SECKEY);
2413
            /* Keep on looping over the keyblock.  Never bump nkeys.  */
2414
0
          }
2415
0
        else
2416
0
          {
2417
0
            if (nkeys
2418
0
                && ((p - line) + 4*KEYGRIP_LEN+1+1) > (ASSUAN_LINELENGTH - 2))
2419
0
              {
2420
0
                err = assuan_transact (agent_ctx, line,
2421
0
                                       NULL, NULL, NULL, NULL, NULL, NULL);
2422
0
                if (err != gpg_err_code (GPG_ERR_NO_SECKEY))
2423
0
                  break; /* Seckey available or unexpected error - ready.  */
2424
0
                p = stpcpy (line, "HAVEKEY");
2425
0
                nkeys = 0;
2426
0
              }
2427
2428
0
            err = keygrip_from_pk (node->pkt->pkt.public_key, grip, 0);
2429
0
            if (err)
2430
0
              return err;
2431
0
            *p++ = ' ';
2432
0
            bin2hex (grip, 20, p);
2433
0
            p += 40;
2434
0
            nkeys++;
2435
2436
0
            err = keygrip_from_pk (node->pkt->pkt.public_key, grip2, 1);
2437
0
            if (err)
2438
0
              {
2439
0
                if (gpg_err_code (err) == GPG_ERR_FALSE) /* No second keygrip.  */
2440
0
                  err = 0;
2441
0
                else
2442
0
                  return err;
2443
0
              }
2444
0
            else /* Add the second keygrip from dual algos.  */
2445
0
              {
2446
0
                *p++ = ' ';
2447
0
                bin2hex (grip2, 20, p);
2448
0
                p += 40;
2449
0
                nkeys++;
2450
0
              }
2451
0
          }
2452
0
      }
2453
2454
0
  if (!err && nkeys)
2455
0
    err = assuan_transact (agent_ctx, line,
2456
0
                           NULL, NULL, NULL, NULL, NULL, NULL);
2457
2458
0
  return err;
2459
0
}
2460
2461
2462

2463
/* Return the serial number for a secret key.  If the returned serial
2464
   number is NULL, the key is not stored on a smartcard.  Caller needs
2465
   to free R_SERIALNO.
2466
2467
   if r_cleartext is not NULL, the referenced int will be set to 1 if
2468
   the agent's copy of the key is stored in the clear, or 0 otherwise
2469
*/
2470
gpg_error_t
2471
agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
2472
                   char **r_serialno, int *r_cleartext)
2473
0
{
2474
0
  gpg_error_t err;
2475
0
  char line[ASSUAN_LINELENGTH];
2476
0
  struct keyinfo_data_parm_s keyinfo;
2477
0
  const char *s;
2478
2479
0
  memset (&keyinfo, 0,sizeof keyinfo);
2480
2481
0
  *r_serialno = NULL;
2482
2483
0
  err = start_agent (ctrl, 0);
2484
0
  if (err)
2485
0
    return err;
2486
2487
0
  if (!hexkeygrip)
2488
0
    return gpg_error (GPG_ERR_INV_VALUE);
2489
0
  s = strchr (hexkeygrip, ',');
2490
0
  if (!s)
2491
0
    s = hexkeygrip + strlen (hexkeygrip);
2492
0
  if (s - hexkeygrip != 40)
2493
0
    return gpg_error (GPG_ERR_INV_VALUE);
2494
2495
  /* Note that for a dual algo we only get info for the first key.
2496
   * FIXME: We need to see how we can show the status of the second
2497
   * key in a key listing. */
2498
0
  snprintf (line, DIM(line), "KEYINFO %.40s", hexkeygrip);
2499
2500
0
  err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL,
2501
0
                         keyinfo_status_cb, &keyinfo);
2502
0
  if (!err && keyinfo.serialno)
2503
0
    {
2504
      /* Sanity check for bad characters.  */
2505
0
      if (strpbrk (keyinfo.serialno, ":\n\r"))
2506
0
        err = GPG_ERR_INV_VALUE;
2507
0
    }
2508
0
  if (err)
2509
0
    xfree (keyinfo.serialno);
2510
0
  else
2511
0
    {
2512
0
      *r_serialno = keyinfo.serialno;
2513
0
      if (r_cleartext)
2514
0
        *r_cleartext = keyinfo.cleartext;
2515
0
    }
2516
0
  return err;
2517
0
}
2518
2519

2520
/* Status callback for agent_import_key, agent_export_key and
2521
   agent_genkey.  */
2522
static gpg_error_t
2523
cache_nonce_status_cb (void *opaque, const char *line)
2524
0
{
2525
0
  struct cache_nonce_parm_s *parm = opaque;
2526
0
  const char *s;
2527
2528
0
  if ((s = has_leading_keyword (line, "CACHE_NONCE")))
2529
0
    {
2530
0
      if (parm->cache_nonce_addr)
2531
0
        {
2532
0
          xfree (*parm->cache_nonce_addr);
2533
0
          *parm->cache_nonce_addr = xtrystrdup (s);
2534
0
        }
2535
0
    }
2536
0
  else if ((s = has_leading_keyword (line, "PASSWD_NONCE")))
2537
0
    {
2538
0
      if (parm->passwd_nonce_addr)
2539
0
        {
2540
0
          xfree (*parm->passwd_nonce_addr);
2541
0
          *parm->passwd_nonce_addr = xtrystrdup (s);
2542
0
        }
2543
0
    }
2544
0
  else if ((s = has_leading_keyword (line, "PROGRESS")))
2545
0
    {
2546
0
      if (opt.enable_progress_filter)
2547
0
        write_status_text (STATUS_PROGRESS, s);
2548
0
    }
2549
2550
0
  return 0;
2551
0
}
2552
2553
2554

2555
/* Handle a KEYPARMS inquiry.  Note, we only send the data,
2556
   assuan_transact takes care of flushing and writing the end */
2557
static gpg_error_t
2558
inq_genkey_parms (void *opaque, const char *line)
2559
0
{
2560
0
  struct genkey_parm_s *parm = opaque;
2561
0
  gpg_error_t err;
2562
2563
0
  if (has_leading_keyword (line, "KEYPARAM"))
2564
0
    {
2565
0
      err = assuan_send_data (parm->dflt->ctx,
2566
0
                              parm->keyparms, strlen (parm->keyparms));
2567
0
    }
2568
0
  else if (has_leading_keyword (line, "NEWPASSWD") && parm->passphrase)
2569
0
    {
2570
0
      err = assuan_send_data (parm->dflt->ctx,
2571
0
                              parm->passphrase,  strlen (parm->passphrase));
2572
0
    }
2573
0
  else
2574
0
    err = default_inq_cb (parm->dflt, line);
2575
2576
0
  return err;
2577
0
}
2578
2579
2580
/* Call the agent to generate a new key.  KEYPARMS is the usual
2581
   S-expression giving the parameters of the key.  gpg-agent passes it
2582
   gcry_pk_genkey.  If NO_PROTECTION is true the agent is advised not
2583
   to protect the generated key.  If NO_PROTECTION is not set and
2584
   PASSPHRASE is not NULL the agent is requested to protect the key
2585
   with that passphrase instead of asking for one.  TIMESTAMP is the
2586
   creation time of the key or zero.  */
2587
gpg_error_t
2588
agent_genkey (ctrl_t ctrl, char **cache_nonce_addr, char **passwd_nonce_addr,
2589
              const char *keyparms, int no_protection,
2590
              const char *passphrase, time_t timestamp, gcry_sexp_t *r_pubkey)
2591
0
{
2592
0
  gpg_error_t err;
2593
0
  struct genkey_parm_s gk_parm;
2594
0
  struct cache_nonce_parm_s cn_parm;
2595
0
  struct default_inq_parm_s dfltparm;
2596
0
  membuf_t data;
2597
0
  size_t len;
2598
0
  unsigned char *buf;
2599
0
  char timestamparg[16 + 16];  /* The 2nd 16 is sizeof(gnupg_isotime_t) */
2600
0
  char line[ASSUAN_LINELENGTH];
2601
2602
0
  memset (&dfltparm, 0, sizeof dfltparm);
2603
0
  dfltparm.ctrl = ctrl;
2604
2605
0
  *r_pubkey = NULL;
2606
0
  err = start_agent (ctrl, 0);
2607
0
  if (err)
2608
0
    return err;
2609
0
  dfltparm.ctx = agent_ctx;
2610
2611
  /* Do not use our cache of secret keygrips anymore - this command
2612
   * would otherwise requiring to update that cache.  */
2613
0
  if (ctrl && ctrl->secret_keygrips)
2614
0
    {
2615
0
      xfree (ctrl->secret_keygrips);
2616
0
      ctrl->secret_keygrips = 0;
2617
0
    }
2618
2619
0
  if (timestamp)
2620
0
    {
2621
0
      strcpy (timestamparg, " --timestamp=");
2622
0
      epoch2isotime (timestamparg+13, timestamp);
2623
0
    }
2624
0
  else
2625
0
    *timestamparg = 0;
2626
2627
0
  if (passwd_nonce_addr && *passwd_nonce_addr)
2628
0
    ; /* A RESET would flush the passwd nonce cache.  */
2629
0
  else
2630
0
    {
2631
0
      err = assuan_transact (agent_ctx, "RESET",
2632
0
                             NULL, NULL, NULL, NULL, NULL, NULL);
2633
0
      if (err)
2634
0
        return err;
2635
0
    }
2636
2637
0
  init_membuf (&data, 1024);
2638
0
  gk_parm.dflt     = &dfltparm;
2639
0
  gk_parm.keyparms = keyparms;
2640
0
  gk_parm.passphrase = passphrase;
2641
0
  snprintf (line, sizeof line, "GENKEY%s%s%s%s%s%s",
2642
0
            *timestamparg? timestamparg : "",
2643
0
            no_protection? " --no-protection" :
2644
0
            passphrase   ? " --inq-passwd" :
2645
0
            /*          */ "",
2646
0
            passwd_nonce_addr && *passwd_nonce_addr? " --passwd-nonce=":"",
2647
0
            passwd_nonce_addr && *passwd_nonce_addr? *passwd_nonce_addr:"",
2648
0
            cache_nonce_addr && *cache_nonce_addr? " ":"",
2649
0
            cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"");
2650
0
  cn_parm.cache_nonce_addr = cache_nonce_addr;
2651
0
  cn_parm.passwd_nonce_addr = NULL;
2652
0
  err = assuan_transact (agent_ctx, line,
2653
0
                         put_membuf_cb, &data,
2654
0
                         inq_genkey_parms, &gk_parm,
2655
0
                         cache_nonce_status_cb, &cn_parm);
2656
0
  if (err)
2657
0
    {
2658
0
      xfree (get_membuf (&data, &len));
2659
0
      return err;
2660
0
    }
2661
2662
0
  buf = get_membuf (&data, &len);
2663
0
  if (!buf)
2664
0
    err = gpg_error_from_syserror ();
2665
0
  else
2666
0
    {
2667
0
      err = gcry_sexp_sscan (r_pubkey, NULL, buf, len);
2668
0
      xfree (buf);
2669
0
    }
2670
0
  return err;
2671
0
}
2672
2673
2674
/* Add the Link attribute to both given keys.  */
2675
gpg_error_t
2676
agent_crosslink_keys (ctrl_t ctrl, const char *hexgrip1, const char *hexgrip2)
2677
0
{
2678
0
  gpg_error_t err;
2679
0
  char line[ASSUAN_LINELENGTH];
2680
2681
0
  err = start_agent (ctrl, 0);
2682
0
  if (err)
2683
0
    goto leave;
2684
2685
0
  snprintf (line, sizeof line, "KEYATTR %s Link: %s", hexgrip1, hexgrip2);
2686
0
  err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
2687
0
  if (err)
2688
0
    goto leave;
2689
2690
0
  snprintf (line, sizeof line, "KEYATTR %s Link: %s", hexgrip2, hexgrip1);
2691
0
  err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
2692
2693
0
 leave:
2694
0
  return err;
2695
0
}
2696
2697
2698

2699
/* Call the agent to read the public key part for a given keygrip.
2700
 * Values from FROMCARD:
2701
 *   0 - Standard
2702
 *   1 - The key is read from the current card
2703
 *       via the agent and a stub file is created.
2704
 */
2705
gpg_error_t
2706
agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip,
2707
               unsigned char **r_pubkey)
2708
0
{
2709
0
  gpg_error_t err;
2710
0
  membuf_t data;
2711
0
  size_t len;
2712
0
  unsigned char *buf;
2713
0
  char line[ASSUAN_LINELENGTH];
2714
0
  struct default_inq_parm_s dfltparm;
2715
2716
0
  memset (&dfltparm, 0, sizeof dfltparm);
2717
0
  dfltparm.ctrl = ctrl;
2718
2719
0
  *r_pubkey = NULL;
2720
0
  err = start_agent (ctrl, 0);
2721
0
  if (err)
2722
0
    return err;
2723
0
  dfltparm.ctx = agent_ctx;
2724
2725
0
  err = assuan_transact (agent_ctx, "RESET",NULL, NULL, NULL, NULL, NULL, NULL);
2726
0
  if (err)
2727
0
    return err;
2728
2729
0
  if (fromcard)
2730
0
    snprintf (line, DIM(line), "READKEY --card -- %s", hexkeygrip);
2731
0
  else
2732
0
    snprintf (line, DIM(line), "READKEY -- %s", hexkeygrip);
2733
2734
0
  init_membuf (&data, 1024);
2735
0
  err = assuan_transact (agent_ctx, line,
2736
0
                         put_membuf_cb, &data,
2737
0
                         default_inq_cb, &dfltparm,
2738
0
                         NULL, NULL);
2739
0
  if (err)
2740
0
    {
2741
0
      xfree (get_membuf (&data, &len));
2742
0
      return err;
2743
0
    }
2744
0
  buf = get_membuf (&data, &len);
2745
0
  if (!buf)
2746
0
    return gpg_error_from_syserror ();
2747
0
  if (!gcry_sexp_canon_len (buf, len, NULL, NULL))
2748
0
    {
2749
0
      xfree (buf);
2750
0
      return gpg_error (GPG_ERR_INV_SEXP);
2751
0
    }
2752
0
  *r_pubkey = buf;
2753
0
  return 0;
2754
0
}
2755
2756
2757

2758
/* Call the agent to do a sign operation using the key identified by
2759
   the hex string KEYGRIP.  DESC is a description of the key to be
2760
   displayed if the agent needs to ask for the PIN.  DIGEST and
2761
   DIGESTLEN is the hash value to sign and DIGESTALGO the algorithm id
2762
   used to compute the digest.  If CACHE_NONCE is used the agent is
2763
   advised to first try a passphrase associated with that nonce. */
2764
gpg_error_t
2765
agent_pksign (ctrl_t ctrl, const char *cache_nonce,
2766
              const char *keygrip, const char *desc,
2767
              u32 *keyid, u32 *mainkeyid, int pubkey_algo,
2768
              unsigned char *digest, size_t digestlen, int digestalgo,
2769
              gcry_sexp_t *r_sigval)
2770
0
{
2771
0
  gpg_error_t err;
2772
0
  char line[ASSUAN_LINELENGTH];
2773
0
  membuf_t data;
2774
0
  struct default_inq_parm_s dfltparm;
2775
2776
0
  memset (&dfltparm, 0, sizeof dfltparm);
2777
0
  dfltparm.ctrl = ctrl;
2778
0
  dfltparm.keyinfo.keyid       = keyid;
2779
0
  dfltparm.keyinfo.mainkeyid   = mainkeyid;
2780
0
  dfltparm.keyinfo.pubkey_algo = pubkey_algo;
2781
2782
0
  *r_sigval = NULL;
2783
0
  err = start_agent (ctrl, 0);
2784
0
  if (err)
2785
0
    return err;
2786
0
  dfltparm.ctx = agent_ctx;
2787
2788
0
  if (digestlen*2 + 50 > DIM(line))
2789
0
    return gpg_error (GPG_ERR_GENERAL);
2790
2791
0
  err = assuan_transact (agent_ctx, "RESET",
2792
0
                         NULL, NULL, NULL, NULL, NULL, NULL);
2793
0
  if (err)
2794
0
    return err;
2795
2796
0
  snprintf (line, DIM(line), "SIGKEY %s", keygrip);
2797
0
  err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
2798
0
  if (err)
2799
0
    return err;
2800
2801
0
  if (desc)
2802
0
    {
2803
0
      snprintf (line, DIM(line), "SETKEYDESC %s", desc);
2804
0
      err = assuan_transact (agent_ctx, line,
2805
0
                            NULL, NULL, NULL, NULL, NULL, NULL);
2806
0
      if (err)
2807
0
        return err;
2808
0
    }
2809
2810
0
  snprintf (line, sizeof line, "SETHASH %d ", digestalgo);
2811
0
  bin2hex (digest, digestlen, line + strlen (line));
2812
0
  err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
2813
0
  if (err)
2814
0
    return err;
2815
2816
0
  init_membuf (&data, 1024);
2817
2818
0
  snprintf (line, sizeof line, "PKSIGN%s%s",
2819
0
            cache_nonce? " -- ":"",
2820
0
            cache_nonce? cache_nonce:"");
2821
2822
0
  if (DBG_CLOCK)
2823
0
    log_clock ("enter signing");
2824
0
  err = assuan_transact (agent_ctx, line,
2825
0
                         put_membuf_cb, &data,
2826
0
                         default_inq_cb, &dfltparm,
2827
0
                         NULL, NULL);
2828
0
  if (DBG_CLOCK)
2829
0
    log_clock ("leave signing");
2830
2831
0
  if (err)
2832
0
    xfree (get_membuf (&data, NULL));
2833
0
  else
2834
0
    {
2835
0
      unsigned char *buf;
2836
0
      size_t len;
2837
2838
0
      buf = get_membuf (&data, &len);
2839
0
      if (!buf)
2840
0
        err = gpg_error_from_syserror ();
2841
0
      else
2842
0
        {
2843
0
          err = gcry_sexp_sscan (r_sigval, NULL, buf, len);
2844
0
          xfree (buf);
2845
0
        }
2846
0
    }
2847
0
  return err;
2848
0
}
2849
2850
2851

2852
/* Handle a CIPHERTEXT inquiry.  Note, we only send the data,
2853
   assuan_transact takes care of flushing and writing the END. */
2854
static gpg_error_t
2855
inq_ciphertext_cb (void *opaque, const char *line)
2856
0
{
2857
0
  struct cipher_parm_s *parm = opaque;
2858
0
  int rc;
2859
2860
0
  if (has_leading_keyword (line, "CIPHERTEXT"))
2861
0
    {
2862
0
      assuan_begin_confidential (parm->ctx);
2863
0
      rc = assuan_send_data (parm->dflt->ctx,
2864
0
                             parm->ciphertext, parm->ciphertextlen);
2865
0
      assuan_end_confidential (parm->ctx);
2866
0
    }
2867
0
  else
2868
0
    rc = default_inq_cb (parm->dflt, line);
2869
2870
0
  return rc;
2871
0
}
2872
2873
2874
/* Check whether there is any padding info from the agent.  */
2875
static gpg_error_t
2876
padding_info_cb (void *opaque, const char *line)
2877
0
{
2878
0
  int *r_padding = opaque;
2879
0
  const char *s;
2880
2881
0
  if ((s=has_leading_keyword (line, "PADDING")))
2882
0
    {
2883
0
      *r_padding = atoi (s);
2884
0
    }
2885
2886
0
  return 0;
2887
0
}
2888
2889
2890
/* Call the agent to do a decrypt operation using the key identified
2891
   by the hex string KEYGRIP and the input data S_CIPHERTEXT.  On the
2892
   success the decoded value is stored verbatim at R_BUF and its
2893
   length at R_BUF; the callers needs to release it.  KEYID, MAINKEYID
2894
   and PUBKEY_ALGO are used to construct additional promots or status
2895
   messages.   The padding information is stored at R_PADDING with -1
2896
   for not known.  */
2897
gpg_error_t
2898
agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
2899
                 u32 *keyid, u32 *mainkeyid, int pubkey_algo,
2900
                 gcry_sexp_t s_ciphertext,
2901
                 unsigned char **r_buf, size_t *r_buflen, int *r_padding)
2902
0
{
2903
0
  gpg_error_t err;
2904
0
  char line[ASSUAN_LINELENGTH];
2905
0
  membuf_t data;
2906
0
  size_t n, len;
2907
0
  char *p, *buf, *endp;
2908
0
  const char *keygrip2 = NULL;
2909
0
  struct default_inq_parm_s dfltparm;
2910
0
  const char *cmdline;
2911
2912
0
  memset (&dfltparm, 0, sizeof dfltparm);
2913
0
  dfltparm.ctrl = ctrl;
2914
0
  dfltparm.keyinfo.keyid       = keyid;
2915
0
  dfltparm.keyinfo.mainkeyid   = mainkeyid;
2916
0
  dfltparm.keyinfo.pubkey_algo = pubkey_algo;
2917
2918
0
  if (!keygrip || !s_ciphertext || !r_buf || !r_buflen || !r_padding)
2919
0
    return gpg_error (GPG_ERR_INV_VALUE);
2920
2921
0
  *r_buf = NULL;
2922
0
  *r_padding = -1;
2923
2924
  /* Parse the keygrip in case of a dual algo.  */
2925
0
  keygrip2 = strchr (keygrip, ',');
2926
0
  if (!keygrip2)
2927
0
    keygrip2 = keygrip + strlen (keygrip);
2928
0
  if (keygrip2 - keygrip != 40)
2929
0
    return gpg_error (GPG_ERR_INV_VALUE);
2930
0
  if (*keygrip2)
2931
0
    {
2932
0
      keygrip2++;
2933
0
      if (strlen (keygrip2) != 40)
2934
0
        return gpg_error (GPG_ERR_INV_VALUE);
2935
0
    }
2936
2937
0
  if (*keygrip2)
2938
0
    cmdline = "PKDECRYPT --kem=PQC-PGP";
2939
0
  else if (pubkey_algo  == PUBKEY_ALGO_ECDH)
2940
0
    cmdline = "PKDECRYPT --kem=PGP";
2941
0
  else
2942
0
    cmdline = "PKDECRYPT";
2943
2944
0
  err = start_agent (ctrl, 0);
2945
0
  if (err)
2946
0
    return err;
2947
0
  dfltparm.ctx = agent_ctx;
2948
2949
0
  err = assuan_transact (agent_ctx, "RESET",
2950
0
                         NULL, NULL, NULL, NULL, NULL, NULL);
2951
0
  if (err)
2952
0
    return err;
2953
2954
0
  snprintf (line, sizeof line, "SETKEY %.40s", keygrip);
2955
0
  err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
2956
0
  if (err)
2957
0
    return err;
2958
2959
0
  if (*keygrip2)
2960
0
    {
2961
0
      snprintf (line, sizeof line, "SETKEY --another %.40s", keygrip2);
2962
0
      err = assuan_transact (agent_ctx, line, NULL, NULL,NULL,NULL,NULL,NULL);
2963
0
      if (err)
2964
0
        return err;
2965
0
    }
2966
2967
0
  if (desc)
2968
0
    {
2969
0
      snprintf (line, DIM(line), "SETKEYDESC %s", desc);
2970
0
      err = assuan_transact (agent_ctx, line,
2971
0
                            NULL, NULL, NULL, NULL, NULL, NULL);
2972
0
      if (err)
2973
0
        return err;
2974
0
    }
2975
2976
0
  init_membuf_secure (&data, 1024);
2977
0
  {
2978
0
    struct cipher_parm_s parm;
2979
2980
0
    parm.dflt = &dfltparm;
2981
0
    parm.ctx = agent_ctx;
2982
0
    err = make_canon_sexp (s_ciphertext, &parm.ciphertext, &parm.ciphertextlen);
2983
0
    if (err)
2984
0
      return err;
2985
0
    err = assuan_transact (agent_ctx, cmdline,
2986
0
                           put_membuf_cb, &data,
2987
0
                           inq_ciphertext_cb, &parm,
2988
0
                           padding_info_cb, r_padding);
2989
0
    xfree (parm.ciphertext);
2990
0
  }
2991
0
  if (err)
2992
0
    {
2993
0
      xfree (get_membuf (&data, &len));
2994
0
      return err;
2995
0
    }
2996
2997
0
  buf = get_membuf (&data, &len);
2998
0
  if (!buf)
2999
0
    return gpg_error_from_syserror ();
3000
3001
0
  if (len == 0 || *buf != '(')
3002
0
    {
3003
0
      xfree (buf);
3004
0
      return gpg_error (GPG_ERR_INV_SEXP);
3005
0
    }
3006
3007
0
  if (len < 12 || memcmp (buf, "(5:value", 8) ) /* "(5:valueN:D)" */
3008
0
    {
3009
0
      xfree (buf);
3010
0
      return gpg_error (GPG_ERR_INV_SEXP);
3011
0
    }
3012
0
  while (buf[len-1] == 0)
3013
0
    len--;
3014
0
  if (buf[len-1] != ')')
3015
0
    return gpg_error (GPG_ERR_INV_SEXP);
3016
0
  len--; /* Drop the final close-paren. */
3017
0
  p = buf + 8; /* Skip leading parenthesis and the value tag. */
3018
0
  len -= 8;   /* Count only the data of the second part. */
3019
3020
0
  n = strtoul (p, &endp, 10);
3021
0
  if (!n || *endp != ':')
3022
0
    {
3023
0
      xfree (buf);
3024
0
      return gpg_error (GPG_ERR_INV_SEXP);
3025
0
    }
3026
0
  endp++;
3027
0
  if (endp-p+n > len)
3028
0
    {
3029
0
      xfree (buf);
3030
0
      return gpg_error (GPG_ERR_INV_SEXP); /* Oops: Inconsistent S-Exp. */
3031
0
    }
3032
3033
0
  memmove (buf, endp, n);
3034
3035
0
  *r_buflen = n;
3036
0
  *r_buf = buf;
3037
0
  return 0;
3038
0
}
3039
3040
3041

3042
/* Retrieve a key encryption key from the agent.  With FOREXPORT true
3043
   the key shall be used for export, with false for import.  On success
3044
   the new key is stored at R_KEY and its length at R_KEKLEN.  */
3045
gpg_error_t
3046
agent_keywrap_key (ctrl_t ctrl, int forexport, void **r_kek, size_t *r_keklen)
3047
0
{
3048
0
  gpg_error_t err;
3049
0
  membuf_t data;
3050
0
  size_t len;
3051
0
  unsigned char *buf;
3052
0
  char line[ASSUAN_LINELENGTH];
3053
0
  struct default_inq_parm_s dfltparm;
3054
3055
0
  memset (&dfltparm, 0, sizeof dfltparm);
3056
0
  dfltparm.ctrl = ctrl;
3057
3058
0
  *r_kek = NULL;
3059
0
  err = start_agent (ctrl, 0);
3060
0
  if (err)
3061
0
    return err;
3062
0
  dfltparm.ctx = agent_ctx;
3063
3064
0
  snprintf (line, DIM(line), "KEYWRAP_KEY %s",
3065
0
            forexport? "--export":"--import");
3066
3067
0
  init_membuf_secure (&data, 64);
3068
0
  err = assuan_transact (agent_ctx, line,
3069
0
                         put_membuf_cb, &data,
3070
0
                         default_inq_cb, &dfltparm,
3071
0
                         NULL, NULL);
3072
0
  if (err)
3073
0
    {
3074
0
      xfree (get_membuf (&data, &len));
3075
0
      return err;
3076
0
    }
3077
0
  buf = get_membuf (&data, &len);
3078
0
  if (!buf)
3079
0
    return gpg_error_from_syserror ();
3080
0
  *r_kek = buf;
3081
0
  *r_keklen = len;
3082
0
  return 0;
3083
0
}
3084
3085
3086

3087
/* Handle the inquiry for an IMPORT_KEY command.  */
3088
static gpg_error_t
3089
inq_import_key_parms (void *opaque, const char *line)
3090
0
{
3091
0
  struct import_key_parm_s *parm = opaque;
3092
0
  gpg_error_t err;
3093
3094
0
  if (has_leading_keyword (line, "KEYDATA"))
3095
0
    {
3096
0
      err = assuan_send_data (parm->dflt->ctx, parm->key, parm->keylen);
3097
0
    }
3098
0
  else
3099
0
    err = default_inq_cb (parm->dflt, line);
3100
3101
0
  return err;
3102
0
}
3103
3104
3105
/* Call the agent to import a key into the agent.  */
3106
gpg_error_t
3107
agent_import_key (ctrl_t ctrl, const char *desc, int mode1003,
3108
                  char **cache_nonce_addr,
3109
                  const void *key, size_t keylen, int unattended, int force,
3110
      u32 *keyid, u32 *mainkeyid, int pubkey_algo, u32 timestamp)
3111
0
{
3112
0
  gpg_error_t err;
3113
0
  struct import_key_parm_s parm;
3114
0
  struct cache_nonce_parm_s cn_parm;
3115
0
  char timestamparg[16 + 16];  /* The 2nd 16 is sizeof(gnupg_isotime_t) */
3116
0
  char line[ASSUAN_LINELENGTH];
3117
0
  struct default_inq_parm_s dfltparm;
3118
3119
0
  memset (&dfltparm, 0, sizeof dfltparm);
3120
0
  dfltparm.ctrl = ctrl;
3121
0
  dfltparm.keyinfo.keyid       = keyid;
3122
0
  dfltparm.keyinfo.mainkeyid   = mainkeyid;
3123
0
  dfltparm.keyinfo.pubkey_algo = pubkey_algo;
3124
3125
0
  err = start_agent (ctrl, 0);
3126
0
  if (err)
3127
0
    return err;
3128
0
  dfltparm.ctx = agent_ctx;
3129
3130
  /* Check that the gpg-agent supports the --mode1003 option.  */
3131
0
  if (mode1003 && assuan_transact (agent_ctx,
3132
0
                                   "GETINFO cmd_has_option IMPORT_KEY mode1003",
3133
0
                                   NULL, NULL, NULL, NULL, NULL, NULL))
3134
0
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
3135
3136
  /* Do not use our cache of secret keygrips anymore - this command
3137
   * would otherwise requiring to update that cache.  */
3138
0
  if (ctrl && ctrl->secret_keygrips)
3139
0
    {
3140
0
      xfree (ctrl->secret_keygrips);
3141
0
      ctrl->secret_keygrips = 0;
3142
0
    }
3143
3144
0
  if (timestamp)
3145
0
    {
3146
0
      strcpy (timestamparg, " --timestamp=");
3147
0
      epoch2isotime (timestamparg+13, timestamp);
3148
0
    }
3149
0
  else
3150
0
    *timestamparg = 0;
3151
3152
0
  if (desc)
3153
0
    {
3154
0
      snprintf (line, DIM(line), "SETKEYDESC %s", desc);
3155
0
      err = assuan_transact (agent_ctx, line,
3156
0
                            NULL, NULL, NULL, NULL, NULL, NULL);
3157
0
      if (err)
3158
0
        return err;
3159
0
    }
3160
3161
0
  parm.dflt   = &dfltparm;
3162
0
  parm.key    = key;
3163
0
  parm.keylen = keylen;
3164
3165
0
  snprintf (line, sizeof line, "IMPORT_KEY%s%s%s%s%s%s",
3166
0
            *timestamparg? timestamparg : "",
3167
0
            unattended? " --unattended":"",
3168
0
            mode1003? " --mode1003":"",
3169
0
            force? " --force":"",
3170
0
            cache_nonce_addr && *cache_nonce_addr? " ":"",
3171
0
            cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"");
3172
0
  cn_parm.cache_nonce_addr = cache_nonce_addr;
3173
0
  cn_parm.passwd_nonce_addr = NULL;
3174
0
  err = assuan_transact (agent_ctx, line,
3175
0
                         NULL, NULL,
3176
0
                         inq_import_key_parms, &parm,
3177
0
                         cache_nonce_status_cb, &cn_parm);
3178
0
  return err;
3179
0
}
3180
3181
3182

3183
/* Receive a secret key from the agent.  HEXKEYGRIP is the hexified
3184
   keygrip, DESC a prompt to be displayed with the agent's passphrase
3185
   question (needs to be plus+percent escaped).  if OPENPGP_PROTECTED
3186
   is not zero, ensure that the key material is returned in RFC
3187
   4880-compatible passphrased-protected form; if instead MODE1003 is
3188
   not zero the raw gpg-agent private key format is requested (either
3189
   protected or unprotected).  If CACHE_NONCE_ADDR is not NULL the
3190
   agent is advised to first try a passphrase associated with that
3191
   nonce.  On success the key is stored as a canonical S-expression at
3192
   R_RESULT and R_RESULTLEN.  */
3193
gpg_error_t
3194
agent_export_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
3195
                  int openpgp_protected, int mode1003, char **cache_nonce_addr,
3196
                  unsigned char **r_result, size_t *r_resultlen,
3197
      u32 *keyid, u32 *mainkeyid, int pubkey_algo)
3198
0
{
3199
0
  gpg_error_t err;
3200
0
  struct cache_nonce_parm_s cn_parm;
3201
0
  membuf_t data;
3202
0
  size_t len;
3203
0
  unsigned char *buf;
3204
0
  char line[ASSUAN_LINELENGTH];
3205
0
  struct default_inq_parm_s dfltparm;
3206
3207
0
  memset (&dfltparm, 0, sizeof dfltparm);
3208
0
  dfltparm.ctrl = ctrl;
3209
0
  dfltparm.keyinfo.keyid       = keyid;
3210
0
  dfltparm.keyinfo.mainkeyid   = mainkeyid;
3211
0
  dfltparm.keyinfo.pubkey_algo = pubkey_algo;
3212
3213
0
  *r_result = NULL;
3214
3215
0
  err = start_agent (ctrl, 0);
3216
0
  if (err)
3217
0
    return err;
3218
0
  dfltparm.ctx = agent_ctx;
3219
3220
  /* Check that the gpg-agent supports the --mode1003 option.  */
3221
0
  if (mode1003 && assuan_transact (agent_ctx,
3222
0
                                   "GETINFO cmd_has_option EXPORT_KEY mode1003",
3223
0
                                   NULL, NULL, NULL, NULL, NULL, NULL))
3224
0
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
3225
3226
0
  if (desc)
3227
0
    {
3228
0
      snprintf (line, DIM(line), "SETKEYDESC %s", desc);
3229
0
      err = assuan_transact (agent_ctx, line,
3230
0
                             NULL, NULL, NULL, NULL, NULL, NULL);
3231
0
      if (err)
3232
0
        return err;
3233
0
    }
3234
3235
0
  snprintf (line, DIM(line), "EXPORT_KEY %s%s%s %s",
3236
0
            mode1003? "--mode1003" : openpgp_protected ? "--openpgp ":"",
3237
0
            cache_nonce_addr && *cache_nonce_addr? " --cache-nonce=":"",
3238
0
            cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"",
3239
0
            hexkeygrip);
3240
3241
0
  init_membuf_secure (&data, 1024);
3242
0
  cn_parm.cache_nonce_addr = cache_nonce_addr;
3243
0
  cn_parm.passwd_nonce_addr = NULL;
3244
0
  err = assuan_transact (agent_ctx, line,
3245
0
                         put_membuf_cb, &data,
3246
0
                         default_inq_cb, &dfltparm,
3247
0
                         cache_nonce_status_cb, &cn_parm);
3248
0
  if (err)
3249
0
    {
3250
0
      xfree (get_membuf (&data, &len));
3251
0
      return err;
3252
0
    }
3253
0
  buf = get_membuf (&data, &len);
3254
0
  if (!buf)
3255
0
    return gpg_error_from_syserror ();
3256
0
  *r_result = buf;
3257
0
  *r_resultlen = len;
3258
0
  return 0;
3259
0
}
3260
3261
3262
/* Status callback for handling confirmation.  */
3263
static gpg_error_t
3264
confirm_status_cb (void *opaque, const char *line)
3265
0
{
3266
0
  struct confirm_parm_s *parm = opaque;
3267
0
  const char *s;
3268
3269
0
  if ((s = has_leading_keyword (line, "SETDESC")))
3270
0
    {
3271
0
      xfree (parm->desc);
3272
0
      parm->desc = unescape_status_string (s);
3273
0
    }
3274
0
  else if ((s = has_leading_keyword (line, "SETOK")))
3275
0
    {
3276
0
      xfree (parm->ok);
3277
0
      parm->ok = unescape_status_string (s);
3278
0
    }
3279
0
  else if ((s = has_leading_keyword (line, "SETNOTOK")))
3280
0
    {
3281
0
      xfree (parm->notok);
3282
0
      parm->notok = unescape_status_string (s);
3283
0
    }
3284
3285
0
  return 0;
3286
0
}
3287

3288
/* Ask the agent to delete the key identified by HEXKEYGRIP.  If DESC
3289
   is not NULL, display DESC instead of the default description
3290
   message.  If FORCE is true the agent is advised not to ask for
3291
   confirmation. */
3292
gpg_error_t
3293
agent_delete_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
3294
                  int force)
3295
0
{
3296
0
  gpg_error_t err;
3297
0
  char line[ASSUAN_LINELENGTH];
3298
0
  struct default_inq_parm_s dfltparm;
3299
0
  struct confirm_parm_s confirm_parm;
3300
3301
0
  memset (&confirm_parm, 0, sizeof confirm_parm);
3302
0
  memset (&dfltparm, 0, sizeof dfltparm);
3303
0
  dfltparm.ctrl = ctrl;
3304
0
  dfltparm.confirm = &confirm_parm;
3305
3306
0
  err = start_agent (ctrl, 0);
3307
0
  if (err)
3308
0
    return err;
3309
0
  dfltparm.ctx = agent_ctx;
3310
3311
0
  if (!hexkeygrip || strlen (hexkeygrip) != 40)
3312
0
    return gpg_error (GPG_ERR_INV_VALUE);
3313
3314
0
  if (desc)
3315
0
    {
3316
0
      snprintf (line, DIM(line), "SETKEYDESC %s", desc);
3317
0
      err = assuan_transact (agent_ctx, line,
3318
0
                             NULL, NULL, NULL, NULL, NULL, NULL);
3319
0
      if (err)
3320
0
        return err;
3321
0
    }
3322
3323
  /* FIXME: Shall we add support to DELETE_KEY for composite keys?  */
3324
0
  snprintf (line, DIM(line), "DELETE_KEY%s %s",
3325
0
            force? " --force":"", hexkeygrip);
3326
0
  err = assuan_transact (agent_ctx, line, NULL, NULL,
3327
0
                         default_inq_cb, &dfltparm,
3328
0
                         confirm_status_cb, &confirm_parm);
3329
0
  xfree (confirm_parm.desc);
3330
0
  xfree (confirm_parm.ok);
3331
0
  xfree (confirm_parm.notok);
3332
0
  return err;
3333
0
}
3334
3335
3336

3337
/* Ask the agent to change the passphrase of the key identified by
3338
 * HEXKEYGRIP.  If DESC is not NULL, display DESC instead of the
3339
 * default description message.  If CACHE_NONCE_ADDR is not NULL the
3340
 * agent is advised to first try a passphrase associated with that
3341
 * nonce.  If PASSWD_NONCE_ADDR is not NULL the agent will try to use
3342
 * the passphrase associated with that nonce for the new passphrase.
3343
 * If VERIFY is true the passphrase is only verified.  */
3344
gpg_error_t
3345
agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc, int verify,
3346
              char **cache_nonce_addr, char **passwd_nonce_addr)
3347
0
{
3348
0
  gpg_error_t err;
3349
0
  struct cache_nonce_parm_s cn_parm;
3350
0
  char line[ASSUAN_LINELENGTH];
3351
0
  struct default_inq_parm_s dfltparm;
3352
3353
0
  memset (&dfltparm, 0, sizeof dfltparm);
3354
0
  dfltparm.ctrl = ctrl;
3355
3356
0
  err = start_agent (ctrl, 0);
3357
0
  if (err)
3358
0
    return err;
3359
0
  dfltparm.ctx = agent_ctx;
3360
3361
0
  if (!hexkeygrip || strlen (hexkeygrip) != 40)
3362
0
    return gpg_error (GPG_ERR_INV_VALUE);
3363
3364
0
  if (desc)
3365
0
    {
3366
0
      snprintf (line, DIM(line), "SETKEYDESC %s", desc);
3367
0
      err = assuan_transact (agent_ctx, line,
3368
0
                             NULL, NULL, NULL, NULL, NULL, NULL);
3369
0
      if (err)
3370
0
        return err;
3371
0
    }
3372
3373
0
  if (verify)
3374
0
    snprintf (line, DIM(line), "PASSWD %s%s --verify %s",
3375
0
              cache_nonce_addr && *cache_nonce_addr? "--cache-nonce=":"",
3376
0
              cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"",
3377
0
              hexkeygrip);
3378
0
  else
3379
0
    snprintf (line, DIM(line), "PASSWD %s%s %s%s %s",
3380
0
              cache_nonce_addr && *cache_nonce_addr? "--cache-nonce=":"",
3381
0
              cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"",
3382
0
              passwd_nonce_addr && *passwd_nonce_addr? "--passwd-nonce=":"",
3383
0
              passwd_nonce_addr && *passwd_nonce_addr? *passwd_nonce_addr:"",
3384
0
              hexkeygrip);
3385
0
  cn_parm.cache_nonce_addr = cache_nonce_addr;
3386
0
  cn_parm.passwd_nonce_addr = passwd_nonce_addr;
3387
0
  err = assuan_transact (agent_ctx, line, NULL, NULL,
3388
0
                         default_inq_cb, &dfltparm,
3389
0
                         cache_nonce_status_cb, &cn_parm);
3390
0
  return err;
3391
0
}
3392
3393
3394
/* Enable or disable the ephemeral mode.  In ephemeral mode keys are
3395
 * created,searched and used in a per-session key store and not in the
3396
 * on-disk file.  Set ENABLE to 1 to enable this mode, to 0 to disable
3397
 * this mode and to -1 to only query the current mode.  If R_PREVIOUS
3398
 * is given the previously used state of the ephemeral mode is stored
3399
 * at that address.  */
3400
gpg_error_t
3401
agent_set_ephemeral_mode (ctrl_t ctrl, int enable, int *r_previous)
3402
0
{
3403
0
  gpg_error_t err;
3404
3405
0
  err = start_agent (ctrl, 0);
3406
0
  if (err)
3407
0
    goto leave;
3408
3409
0
  if (r_previous)
3410
0
    {
3411
0
      err = assuan_transact (agent_ctx, "GETINFO ephemeral",
3412
0
                             NULL, NULL, NULL, NULL, NULL, NULL);
3413
0
      if (!err)
3414
0
        *r_previous = 1;
3415
0
      else if (gpg_err_code (err) == GPG_ERR_FALSE)
3416
0
        *r_previous = 0;
3417
0
      else
3418
0
        goto leave;
3419
0
    }
3420
3421
  /* Skip setting if we are only querying or if the mode is already set. */
3422
0
  if (enable == -1 || (r_previous && !!*r_previous == !!enable))
3423
0
    err = 0;
3424
0
  else
3425
0
    err = assuan_transact (agent_ctx,
3426
0
                           enable? "OPTION ephemeral=1" : "OPTION ephemeral=0",
3427
0
                           NULL, NULL, NULL, NULL, NULL, NULL);
3428
0
 leave:
3429
0
  return err;
3430
0
}
3431
3432
3433
/* Return the version reported by gpg-agent.  */
3434
gpg_error_t
3435
agent_get_version (ctrl_t ctrl, char **r_version)
3436
0
{
3437
0
  gpg_error_t err;
3438
3439
0
  err = start_agent (ctrl, 0);
3440
0
  if (err)
3441
0
    return err;
3442
3443
0
  err = get_assuan_server_version (agent_ctx, 0, r_version);
3444
0
  return err;
3445
0
}