Line data Source code
1 : /* card-util.c - Utility functions for the OpenPGP card.
2 : * Copyright (C) 2003-2005, 2009 Free Software Foundation, Inc.
3 : * Copyright (C) 2003-2005, 2009 Werner Koch
4 : *
5 : * This file is part of GnuPG.
6 : *
7 : * GnuPG is free software; you can redistribute it and/or modify
8 : * it under the terms of the GNU General Public License as published by
9 : * the Free Software Foundation; either version 3 of the License, or
10 : * (at your option) any later version.
11 : *
12 : * GnuPG is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU General Public License
18 : * along with this program; if not, see <https://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include <config.h>
22 : #include <stdio.h>
23 : #include <stdlib.h>
24 : #include <string.h>
25 : #include <errno.h>
26 : #ifdef HAVE_LIBREADLINE
27 : # define GNUPG_LIBREADLINE_H_INCLUDED
28 : # include <readline/readline.h>
29 : #endif /*HAVE_LIBREADLINE*/
30 :
31 : #if GNUPG_MAJOR_VERSION != 1
32 : # include "gpg.h"
33 : #endif /*GNUPG_MAJOR_VERSION != 1*/
34 : #include "util.h"
35 : #include "i18n.h"
36 : #include "ttyio.h"
37 : #include "status.h"
38 : #include "options.h"
39 : #include "main.h"
40 : #include "keyserver-internal.h"
41 :
42 : #if GNUPG_MAJOR_VERSION == 1
43 : # include "cardglue.h"
44 : #else /*GNUPG_MAJOR_VERSION!=1*/
45 : # include "call-agent.h"
46 : #endif /*GNUPG_MAJOR_VERSION!=1*/
47 :
48 : #define CONTROL_D ('D' - 'A' + 1)
49 :
50 :
51 : static void
52 0 : write_sc_op_status (gpg_error_t err)
53 : {
54 0 : switch (gpg_err_code (err))
55 : {
56 : case 0:
57 0 : write_status (STATUS_SC_OP_SUCCESS);
58 0 : break;
59 : #if GNUPG_MAJOR_VERSION != 1
60 : case GPG_ERR_CANCELED:
61 : case GPG_ERR_FULLY_CANCELED:
62 0 : write_status_text (STATUS_SC_OP_FAILURE, "1");
63 0 : break;
64 : case GPG_ERR_BAD_PIN:
65 0 : write_status_text (STATUS_SC_OP_FAILURE, "2");
66 0 : break;
67 : default:
68 0 : write_status (STATUS_SC_OP_FAILURE);
69 0 : break;
70 : #endif /* GNUPG_MAJOR_VERSION != 1 */
71 : }
72 0 : }
73 :
74 :
75 : /* Change the PIN of a an OpenPGP card. This is an interactive
76 : function. */
77 : void
78 0 : change_pin (int unblock_v2, int allow_admin)
79 : {
80 : struct agent_card_info_s info;
81 : int rc;
82 :
83 0 : rc = agent_scd_learn (&info, 0);
84 0 : if (rc)
85 : {
86 0 : log_error (_("OpenPGP card not available: %s\n"),
87 : gpg_strerror (rc));
88 0 : return;
89 : }
90 :
91 0 : log_info (_("OpenPGP card no. %s detected\n"),
92 0 : info.serialno? info.serialno : "[none]");
93 :
94 0 : agent_clear_pin_cache (info.serialno);
95 :
96 0 : if (opt.batch)
97 : {
98 0 : agent_release_card_info (&info);
99 0 : log_error (_("can't do this in batch mode\n"));
100 0 : return;
101 : }
102 :
103 :
104 0 : if (unblock_v2)
105 : {
106 0 : if (!info.is_v2)
107 0 : log_error (_("This command is only available for version 2 cards\n"));
108 0 : else if (!info.chvretry[1])
109 0 : log_error (_("Reset Code not or not anymore available\n"));
110 : else
111 : {
112 0 : rc = agent_scd_change_pin (2, info.serialno);
113 0 : write_sc_op_status (rc);
114 0 : if (rc)
115 0 : tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
116 : else
117 0 : tty_printf ("PIN changed.\n");
118 : }
119 : }
120 0 : else if (!allow_admin)
121 : {
122 0 : rc = agent_scd_change_pin (1, info.serialno);
123 0 : write_sc_op_status (rc);
124 0 : if (rc)
125 0 : tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
126 : else
127 0 : tty_printf ("PIN changed.\n");
128 : }
129 : else
130 : for (;;)
131 : {
132 : char *answer;
133 :
134 0 : tty_printf ("\n");
135 0 : tty_printf ("1 - change PIN\n"
136 : "2 - unblock PIN\n"
137 : "3 - change Admin PIN\n"
138 : "4 - set the Reset Code\n"
139 : "Q - quit\n");
140 0 : tty_printf ("\n");
141 :
142 0 : answer = cpr_get("cardutil.change_pin.menu",_("Your selection? "));
143 0 : cpr_kill_prompt();
144 0 : if (strlen (answer) != 1)
145 0 : continue;
146 :
147 0 : if (*answer == '1')
148 : {
149 : /* Change PIN. */
150 0 : rc = agent_scd_change_pin (1, info.serialno);
151 0 : write_sc_op_status (rc);
152 0 : if (rc)
153 0 : tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
154 : else
155 0 : tty_printf ("PIN changed.\n");
156 : }
157 0 : else if (*answer == '2')
158 : {
159 : /* Unblock PIN. */
160 0 : rc = agent_scd_change_pin (101, info.serialno);
161 0 : write_sc_op_status (rc);
162 0 : if (rc)
163 0 : tty_printf ("Error unblocking the PIN: %s\n", gpg_strerror (rc));
164 : else
165 0 : tty_printf ("PIN unblocked and new PIN set.\n");
166 : }
167 0 : else if (*answer == '3')
168 : {
169 : /* Change Admin PIN. */
170 0 : rc = agent_scd_change_pin (3, info.serialno);
171 0 : write_sc_op_status (rc);
172 0 : if (rc)
173 0 : tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
174 : else
175 0 : tty_printf ("PIN changed.\n");
176 : }
177 0 : else if (*answer == '4')
178 : {
179 : /* Set a new Reset Code. */
180 0 : rc = agent_scd_change_pin (102, info.serialno);
181 0 : write_sc_op_status (rc);
182 0 : if (rc)
183 0 : tty_printf ("Error setting the Reset Code: %s\n",
184 : gpg_strerror (rc));
185 : else
186 0 : tty_printf ("Reset Code set.\n");
187 : }
188 0 : else if (*answer == 'q' || *answer == 'Q')
189 : {
190 : break;
191 : }
192 0 : }
193 :
194 0 : agent_release_card_info (&info);
195 : }
196 :
197 : static const char *
198 0 : get_manufacturer (unsigned int no)
199 : {
200 : /* Note: Make sure that there is no colon or linefeed in the string. */
201 0 : switch (no)
202 : {
203 0 : case 0x0001: return "PPC Card Systems";
204 0 : case 0x0002: return "Prism";
205 0 : case 0x0003: return "OpenFortress";
206 0 : case 0x0004: return "Wewid";
207 0 : case 0x0005: return "ZeitControl";
208 0 : case 0x0006: return "Yubico";
209 0 : case 0x0007: return "OpenKMS";
210 0 : case 0x0008: return "LogoEmail";
211 0 : case 0x0009: return "Fidesmo";
212 0 : case 0x000A: return "Dangerous Things";
213 :
214 0 : case 0x002A: return "Magrathea";
215 :
216 0 : case 0x1337: return "Warsaw Hackerspace";
217 0 : case 0x2342: return "warpzone"; /* hackerspace Muenster. */
218 0 : case 0xF517: return "FSIJ";
219 :
220 : /* 0x0000 and 0xFFFF are defined as test cards per spec,
221 : 0xFF00 to 0xFFFE are assigned for use with randomly created
222 : serial numbers. */
223 : case 0x0000:
224 0 : case 0xffff: return "test card";
225 0 : default: return (no & 0xff00) == 0xff00? "unmanaged S/N range":"unknown";
226 : }
227 : }
228 :
229 :
230 : static void
231 0 : print_sha1_fpr (estream_t fp, const unsigned char *fpr)
232 : {
233 : int i;
234 :
235 0 : if (fpr)
236 : {
237 0 : for (i=0; i < 20 ; i+=2, fpr += 2 )
238 : {
239 0 : if (i == 10 )
240 0 : tty_fprintf (fp, " ");
241 0 : tty_fprintf (fp, " %02X%02X", *fpr, fpr[1]);
242 : }
243 : }
244 : else
245 0 : tty_fprintf (fp, " [none]");
246 0 : tty_fprintf (fp, "\n");
247 0 : }
248 :
249 :
250 : static void
251 0 : print_sha1_fpr_colon (estream_t fp, const unsigned char *fpr)
252 : {
253 : int i;
254 :
255 0 : if (fpr)
256 : {
257 0 : for (i=0; i < 20 ; i++, fpr++)
258 0 : es_fprintf (fp, "%02X", *fpr);
259 : }
260 0 : es_putc (':', fp);
261 0 : }
262 :
263 :
264 : static void
265 0 : print_name (estream_t fp, const char *text, const char *name)
266 : {
267 0 : tty_fprintf (fp, "%s", text);
268 :
269 : /* FIXME: tty_printf_utf8_string2 eats everything after and
270 : including an @ - e.g. when printing an url. */
271 0 : if (name && *name)
272 : {
273 0 : if (fp)
274 0 : print_utf8_buffer2 (fp, name, strlen (name), '\n');
275 : else
276 0 : tty_print_utf8_string2 (NULL, name, strlen (name), 0);
277 : }
278 : else
279 0 : tty_fprintf (fp, _("[not set]"));
280 0 : tty_fprintf (fp, "\n");
281 0 : }
282 :
283 : static void
284 0 : print_isoname (estream_t fp, const char *text,
285 : const char *tag, const char *name)
286 : {
287 0 : if (opt.with_colons)
288 0 : es_fprintf (fp, "%s:", tag);
289 : else
290 0 : tty_fprintf (fp, "%s", text);
291 :
292 0 : if (name && *name)
293 0 : {
294 0 : char *p, *given, *buf = xstrdup (name);
295 :
296 0 : given = strstr (buf, "<<");
297 0 : for (p=buf; *p; p++)
298 0 : if (*p == '<')
299 0 : *p = ' ';
300 0 : if (given && given[2])
301 : {
302 0 : *given = 0;
303 0 : given += 2;
304 0 : if (opt.with_colons)
305 0 : es_write_sanitized (fp, given, strlen (given), ":", NULL);
306 0 : else if (fp)
307 0 : print_utf8_buffer2 (fp, given, strlen (given), '\n');
308 : else
309 0 : tty_print_utf8_string2 (NULL, given, strlen (given), 0);
310 :
311 0 : if (opt.with_colons)
312 0 : es_putc (':', fp);
313 0 : else if (*buf)
314 0 : tty_fprintf (fp, " ");
315 : }
316 :
317 0 : if (opt.with_colons)
318 0 : es_write_sanitized (fp, buf, strlen (buf), ":", NULL);
319 0 : else if (fp)
320 0 : print_utf8_buffer2 (fp, buf, strlen (buf), '\n');
321 : else
322 0 : tty_print_utf8_string2 (NULL, buf, strlen (buf), 0);
323 0 : xfree (buf);
324 : }
325 : else
326 : {
327 0 : if (opt.with_colons)
328 0 : es_putc (':', fp);
329 : else
330 0 : tty_fprintf (fp, _("[not set]"));
331 : }
332 :
333 0 : if (opt.with_colons)
334 0 : es_fputs (":\n", fp);
335 : else
336 0 : tty_fprintf (fp, "\n");
337 0 : }
338 :
339 : /* Return true if the SHA1 fingerprint FPR consists only of zeroes. */
340 : static int
341 0 : fpr_is_zero (const char *fpr)
342 : {
343 : int i;
344 :
345 0 : for (i=0; i < 20 && !fpr[i]; i++)
346 : ;
347 0 : return (i == 20);
348 : }
349 :
350 :
351 : /* Return true if the SHA1 fingerprint FPR consists only of 0xFF. */
352 : static int
353 0 : fpr_is_ff (const char *fpr)
354 : {
355 : int i;
356 :
357 0 : for (i=0; i < 20 && fpr[i] == '\xff'; i++)
358 : ;
359 0 : return (i == 20);
360 : }
361 :
362 :
363 : /* Print all available information about the current card. */
364 : void
365 0 : card_status (estream_t fp, char *serialno, size_t serialnobuflen)
366 : {
367 : struct agent_card_info_s info;
368 0 : PKT_public_key *pk = xcalloc (1, sizeof *pk);
369 0 : kbnode_t keyblock = NULL;
370 : int rc;
371 : unsigned int uval;
372 : const unsigned char *thefpr;
373 : int i;
374 :
375 0 : if (serialno && serialnobuflen)
376 0 : *serialno = 0;
377 :
378 0 : rc = agent_scd_learn (&info, 0);
379 0 : if (rc)
380 : {
381 0 : if (opt.with_colons)
382 0 : es_fputs ("AID:::\n", fp);
383 0 : log_error (_("OpenPGP card not available: %s\n"), gpg_strerror (rc));
384 0 : xfree (pk);
385 0 : return;
386 : }
387 :
388 0 : if (opt.with_colons)
389 0 : es_fprintf (fp, "Reader:%s:", info.reader? info.reader : "");
390 : else
391 0 : tty_fprintf (fp, "Reader ...........: %s\n",
392 0 : info.reader? info.reader : "[none]");
393 0 : if (opt.with_colons)
394 0 : es_fprintf (fp, "AID:%s:", info.serialno? info.serialno : "");
395 : else
396 0 : tty_fprintf (fp, "Application ID ...: %s\n",
397 0 : info.serialno? info.serialno : "[none]");
398 0 : if (!info.serialno || strncmp (info.serialno, "D27600012401", 12)
399 0 : || strlen (info.serialno) != 32 )
400 : {
401 0 : if (info.apptype && !strcmp (info.apptype, "NKS"))
402 : {
403 0 : if (opt.with_colons)
404 0 : es_fputs ("netkey-card:\n", fp);
405 0 : log_info ("this is a NetKey card\n");
406 : }
407 0 : else if (info.apptype && !strcmp (info.apptype, "DINSIG"))
408 : {
409 0 : if (opt.with_colons)
410 0 : es_fputs ("dinsig-card:\n", fp);
411 0 : log_info ("this is a DINSIG compliant card\n");
412 : }
413 0 : else if (info.apptype && !strcmp (info.apptype, "P15"))
414 : {
415 0 : if (opt.with_colons)
416 0 : es_fputs ("pkcs15-card:\n", fp);
417 0 : log_info ("this is a PKCS#15 compliant card\n");
418 : }
419 0 : else if (info.apptype && !strcmp (info.apptype, "GELDKARTE"))
420 : {
421 0 : if (opt.with_colons)
422 0 : es_fputs ("geldkarte-card:\n", fp);
423 0 : log_info ("this is a Geldkarte compliant card\n");
424 : }
425 : else
426 : {
427 0 : if (opt.with_colons)
428 0 : es_fputs ("unknown:\n", fp);
429 : }
430 0 : log_info ("not an OpenPGP card\n");
431 0 : agent_release_card_info (&info);
432 0 : xfree (pk);
433 0 : return;
434 : }
435 :
436 0 : if (!serialno)
437 : ;
438 0 : else if (strlen (serialno)+1 > serialnobuflen)
439 0 : log_error ("serial number longer than expected\n");
440 : else
441 0 : strcpy (serialno, info.serialno);
442 :
443 0 : if (opt.with_colons)
444 0 : es_fputs ("openpgp-card:\n", fp);
445 :
446 :
447 0 : if (opt.with_colons)
448 : {
449 0 : es_fprintf (fp, "version:%.4s:\n", info.serialno+12);
450 0 : uval = xtoi_2(info.serialno+16)*256 + xtoi_2 (info.serialno+18);
451 0 : es_fprintf (fp, "vendor:%04x:%s:\n", uval, get_manufacturer (uval));
452 0 : es_fprintf (fp, "serial:%.8s:\n", info.serialno+20);
453 :
454 0 : print_isoname (fp, "Name of cardholder: ", "name", info.disp_name);
455 :
456 0 : es_fputs ("lang:", fp);
457 0 : if (info.disp_lang)
458 0 : es_write_sanitized (fp, info.disp_lang, strlen (info.disp_lang),
459 : ":", NULL);
460 0 : es_fputs (":\n", fp);
461 :
462 0 : es_fprintf (fp, "sex:%c:\n", (info.disp_sex == 1? 'm':
463 0 : info.disp_sex == 2? 'f' : 'u'));
464 :
465 0 : es_fputs ("url:", fp);
466 0 : if (info.pubkey_url)
467 0 : es_write_sanitized (fp, info.pubkey_url, strlen (info.pubkey_url),
468 : ":", NULL);
469 0 : es_fputs (":\n", fp);
470 :
471 0 : es_fputs ("login:", fp);
472 0 : if (info.login_data)
473 0 : es_write_sanitized (fp, info.login_data, strlen (info.login_data),
474 : ":", NULL);
475 0 : es_fputs (":\n", fp);
476 :
477 0 : es_fprintf (fp, "forcepin:%d:::\n", !info.chv1_cached);
478 0 : for (i=0; i < DIM (info.key_attr); i++)
479 0 : if (info.key_attr[i].algo == PUBKEY_ALGO_RSA)
480 0 : es_fprintf (fp, "keyattr:%d:%d:%u:\n", i+1,
481 : info.key_attr[i].algo, info.key_attr[i].nbits);
482 0 : else if (info.key_attr[i].algo == PUBKEY_ALGO_ECDH
483 0 : || info.key_attr[i].algo == PUBKEY_ALGO_ECDSA
484 0 : || info.key_attr[i].algo == PUBKEY_ALGO_EDDSA)
485 0 : es_fprintf (fp, "keyattr:%d:%d:%s:\n", i+1,
486 : info.key_attr[i].algo, info.key_attr[i].curve);
487 0 : es_fprintf (fp, "maxpinlen:%d:%d:%d:\n",
488 : info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
489 0 : es_fprintf (fp, "pinretry:%d:%d:%d:\n",
490 : info.chvretry[0], info.chvretry[1], info.chvretry[2]);
491 0 : es_fprintf (fp, "sigcount:%lu:::\n", info.sig_counter);
492 :
493 0 : for (i=0; i < 4; i++)
494 : {
495 0 : if (info.private_do[i])
496 : {
497 0 : es_fprintf (fp, "private_do:%d:", i+1);
498 0 : es_write_sanitized (fp, info.private_do[i],
499 0 : strlen (info.private_do[i]), ":", NULL);
500 0 : es_fputs (":\n", fp);
501 : }
502 : }
503 :
504 0 : es_fputs ("cafpr:", fp);
505 0 : print_sha1_fpr_colon (fp, info.cafpr1valid? info.cafpr1:NULL);
506 0 : print_sha1_fpr_colon (fp, info.cafpr2valid? info.cafpr2:NULL);
507 0 : print_sha1_fpr_colon (fp, info.cafpr3valid? info.cafpr3:NULL);
508 0 : es_putc ('\n', fp);
509 0 : es_fputs ("fpr:", fp);
510 0 : print_sha1_fpr_colon (fp, info.fpr1valid? info.fpr1:NULL);
511 0 : print_sha1_fpr_colon (fp, info.fpr2valid? info.fpr2:NULL);
512 0 : print_sha1_fpr_colon (fp, info.fpr3valid? info.fpr3:NULL);
513 0 : es_putc ('\n', fp);
514 0 : es_fprintf (fp, "fprtime:%lu:%lu:%lu:\n",
515 0 : (unsigned long)info.fpr1time, (unsigned long)info.fpr2time,
516 0 : (unsigned long)info.fpr3time);
517 : }
518 : else
519 : {
520 0 : tty_fprintf (fp, "Version ..........: %.1s%c.%.1s%c\n",
521 0 : info.serialno[12] == '0'?"":info.serialno+12,
522 0 : info.serialno[13],
523 0 : info.serialno[14] == '0'?"":info.serialno+14,
524 0 : info.serialno[15]);
525 0 : tty_fprintf (fp, "Manufacturer .....: %s\n",
526 0 : get_manufacturer (xtoi_2(info.serialno+16)*256
527 0 : + xtoi_2 (info.serialno+18)));
528 0 : tty_fprintf (fp, "Serial number ....: %.8s\n", info.serialno+20);
529 :
530 0 : print_isoname (fp, "Name of cardholder: ", "name", info.disp_name);
531 0 : print_name (fp, "Language prefs ...: ", info.disp_lang);
532 0 : tty_fprintf (fp, "Sex ..............: %s\n",
533 0 : info.disp_sex == 1? _("male"):
534 0 : info.disp_sex == 2? _("female") : _("unspecified"));
535 0 : print_name (fp, "URL of public key : ", info.pubkey_url);
536 0 : print_name (fp, "Login data .......: ", info.login_data);
537 0 : if (info.private_do[0])
538 0 : print_name (fp, "Private DO 1 .....: ", info.private_do[0]);
539 0 : if (info.private_do[1])
540 0 : print_name (fp, "Private DO 2 .....: ", info.private_do[1]);
541 0 : if (info.private_do[2])
542 0 : print_name (fp, "Private DO 3 .....: ", info.private_do[2]);
543 0 : if (info.private_do[3])
544 0 : print_name (fp, "Private DO 4 .....: ", info.private_do[3]);
545 0 : if (info.cafpr1valid)
546 : {
547 0 : tty_fprintf (fp, "CA fingerprint %d .:", 1);
548 0 : print_sha1_fpr (fp, info.cafpr1);
549 : }
550 0 : if (info.cafpr2valid)
551 : {
552 0 : tty_fprintf (fp, "CA fingerprint %d .:", 2);
553 0 : print_sha1_fpr (fp, info.cafpr2);
554 : }
555 0 : if (info.cafpr3valid)
556 : {
557 0 : tty_fprintf (fp, "CA fingerprint %d .:", 3);
558 0 : print_sha1_fpr (fp, info.cafpr3);
559 : }
560 0 : tty_fprintf (fp, "Signature PIN ....: %s\n",
561 0 : info.chv1_cached? _("not forced"): _("forced"));
562 0 : if (info.key_attr[0].algo)
563 : {
564 0 : tty_fprintf (fp, "Key attributes ...:");
565 0 : for (i=0; i < DIM (info.key_attr); i++)
566 0 : if (info.key_attr[i].algo == PUBKEY_ALGO_RSA)
567 0 : tty_fprintf (fp, " rsa%u", info.key_attr[i].nbits);
568 0 : else if (info.key_attr[i].algo == PUBKEY_ALGO_ECDH
569 0 : || info.key_attr[i].algo == PUBKEY_ALGO_ECDSA
570 0 : || info.key_attr[i].algo == PUBKEY_ALGO_EDDSA)
571 : {
572 0 : const char *curve_for_print = "?";
573 :
574 0 : if (info.key_attr[i].curve)
575 : {
576 : const char *oid;
577 0 : oid = openpgp_curve_to_oid (info.key_attr[i].curve, NULL);
578 0 : if (oid)
579 0 : curve_for_print = openpgp_oid_to_curve (oid, 0);
580 : }
581 0 : tty_fprintf (fp, " %s", curve_for_print);
582 : }
583 0 : tty_fprintf (fp, "\n");
584 : }
585 0 : tty_fprintf (fp, "Max. PIN lengths .: %d %d %d\n",
586 : info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
587 0 : tty_fprintf (fp, "PIN retry counter : %d %d %d\n",
588 : info.chvretry[0], info.chvretry[1], info.chvretry[2]);
589 0 : tty_fprintf (fp, "Signature counter : %lu\n", info.sig_counter);
590 0 : tty_fprintf (fp, "Signature key ....:");
591 0 : print_sha1_fpr (fp, info.fpr1valid? info.fpr1:NULL);
592 0 : if (info.fpr1valid && info.fpr1time)
593 0 : tty_fprintf (fp, " created ....: %s\n",
594 : isotimestamp (info.fpr1time));
595 0 : tty_fprintf (fp, "Encryption key....:");
596 0 : print_sha1_fpr (fp, info.fpr2valid? info.fpr2:NULL);
597 0 : if (info.fpr2valid && info.fpr2time)
598 0 : tty_fprintf (fp, " created ....: %s\n",
599 : isotimestamp (info.fpr2time));
600 0 : tty_fprintf (fp, "Authentication key:");
601 0 : print_sha1_fpr (fp, info.fpr3valid? info.fpr3:NULL);
602 0 : if (info.fpr3valid && info.fpr3time)
603 0 : tty_fprintf (fp, " created ....: %s\n",
604 : isotimestamp (info.fpr3time));
605 0 : tty_fprintf (fp, "General key info..: ");
606 :
607 0 : thefpr = (info.fpr1valid? info.fpr1 : info.fpr2valid? info.fpr2 :
608 0 : info.fpr3valid? info.fpr3 : NULL);
609 : /* If the fingerprint is all 0xff, the key has no asssociated
610 : OpenPGP certificate. */
611 0 : if ( thefpr && !fpr_is_ff (thefpr)
612 0 : && !get_pubkey_byfprint (pk, &keyblock, thefpr, 20))
613 : {
614 0 : print_pubkey_info (fp, pk);
615 0 : if (keyblock)
616 0 : print_card_key_info (fp, keyblock);
617 : }
618 : else
619 0 : tty_fprintf (fp, "[none]\n");
620 : }
621 :
622 0 : release_kbnode (keyblock);
623 0 : free_public_key (pk);
624 0 : agent_release_card_info (&info);
625 : }
626 :
627 :
628 : static char *
629 0 : get_one_name (const char *prompt1, const char *prompt2)
630 : {
631 : char *name;
632 : int i;
633 :
634 : for (;;)
635 : {
636 0 : name = cpr_get (prompt1, prompt2);
637 0 : if (!name)
638 0 : return NULL;
639 0 : trim_spaces (name);
640 0 : cpr_kill_prompt ();
641 0 : for (i=0; name[i] && name[i] >= ' ' && name[i] <= 126; i++)
642 : ;
643 :
644 : /* The name must be in Latin-1 and not UTF-8 - lacking the code
645 : to ensure this we restrict it to ASCII. */
646 0 : if (name[i])
647 0 : tty_printf (_("Error: Only plain ASCII is currently allowed.\n"));
648 0 : else if (strchr (name, '<'))
649 0 : tty_printf (_("Error: The \"<\" character may not be used.\n"));
650 0 : else if (strstr (name, " "))
651 0 : tty_printf (_("Error: Double spaces are not allowed.\n"));
652 : else
653 0 : return name;
654 0 : xfree (name);
655 0 : }
656 : }
657 :
658 :
659 :
660 : static int
661 0 : change_name (void)
662 : {
663 0 : char *surname = NULL, *givenname = NULL;
664 : char *isoname, *p;
665 : int rc;
666 :
667 0 : surname = get_one_name ("keygen.smartcard.surname",
668 0 : _("Cardholder's surname: "));
669 0 : givenname = get_one_name ("keygen.smartcard.givenname",
670 0 : _("Cardholder's given name: "));
671 0 : if (!surname || !givenname || (!*surname && !*givenname))
672 : {
673 0 : xfree (surname);
674 0 : xfree (givenname);
675 0 : return -1; /*canceled*/
676 : }
677 :
678 0 : isoname = xmalloc ( strlen (surname) + 2 + strlen (givenname) + 1);
679 0 : strcpy (stpcpy (stpcpy (isoname, surname), "<<"), givenname);
680 0 : xfree (surname);
681 0 : xfree (givenname);
682 0 : for (p=isoname; *p; p++)
683 0 : if (*p == ' ')
684 0 : *p = '<';
685 :
686 0 : if (strlen (isoname) > 39 )
687 : {
688 0 : tty_printf (_("Error: Combined name too long "
689 : "(limit is %d characters).\n"), 39);
690 0 : xfree (isoname);
691 0 : return -1;
692 : }
693 :
694 0 : rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname), NULL );
695 0 : if (rc)
696 0 : log_error ("error setting Name: %s\n", gpg_strerror (rc));
697 :
698 0 : xfree (isoname);
699 0 : return rc;
700 : }
701 :
702 :
703 : static int
704 0 : change_url (void)
705 : {
706 : char *url;
707 : int rc;
708 :
709 0 : url = cpr_get ("cardedit.change_url", _("URL to retrieve public key: "));
710 0 : if (!url)
711 0 : return -1;
712 0 : trim_spaces (url);
713 0 : cpr_kill_prompt ();
714 :
715 0 : if (strlen (url) > 254 )
716 : {
717 0 : tty_printf (_("Error: URL too long "
718 : "(limit is %d characters).\n"), 254);
719 0 : xfree (url);
720 0 : return -1;
721 : }
722 :
723 0 : rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url), NULL );
724 0 : if (rc)
725 0 : log_error ("error setting URL: %s\n", gpg_strerror (rc));
726 0 : xfree (url);
727 0 : write_sc_op_status (rc);
728 0 : return rc;
729 : }
730 :
731 :
732 : /* Fetch the key from the URL given on the card or try to get it from
733 : the default keyserver. */
734 : static int
735 0 : fetch_url (ctrl_t ctrl)
736 : {
737 : int rc;
738 : struct agent_card_info_s info;
739 :
740 0 : memset(&info,0,sizeof(info));
741 :
742 0 : rc=agent_scd_getattr("PUBKEY-URL",&info);
743 0 : if(rc)
744 0 : log_error("error retrieving URL from card: %s\n",gpg_strerror(rc));
745 : else
746 : {
747 0 : rc=agent_scd_getattr("KEY-FPR",&info);
748 0 : if(rc)
749 0 : log_error("error retrieving key fingerprint from card: %s\n",
750 : gpg_strerror(rc));
751 0 : else if (info.pubkey_url && *info.pubkey_url)
752 0 : {
753 0 : strlist_t sl = NULL;
754 :
755 0 : add_to_strlist (&sl, info.pubkey_url);
756 0 : rc = keyserver_fetch (ctrl, sl);
757 0 : free_strlist (sl);
758 : }
759 0 : else if (info.fpr1valid)
760 : {
761 0 : rc = keyserver_import_fprint (ctrl, info.fpr1, 20, opt.keyserver, 0);
762 : }
763 : }
764 :
765 0 : return rc;
766 : }
767 :
768 :
769 : /* Read data from file FNAME up to MAXLEN characters. On error return
770 : -1 and store NULL at R_BUFFER; on success return the number of
771 : bytes read and store the address of a newly allocated buffer at
772 : R_BUFFER. */
773 : static int
774 0 : get_data_from_file (const char *fname, size_t maxlen, char **r_buffer)
775 : {
776 : estream_t fp;
777 : char *data;
778 : int n;
779 :
780 0 : *r_buffer = NULL;
781 :
782 0 : fp = es_fopen (fname, "rb");
783 : #if GNUPG_MAJOR_VERSION == 1
784 : if (fp && is_secured_file (fileno (fp)))
785 : {
786 : fclose (fp);
787 : fp = NULL;
788 : errno = EPERM;
789 : }
790 : #endif
791 0 : if (!fp)
792 : {
793 0 : tty_printf (_("can't open '%s': %s\n"), fname, strerror (errno));
794 0 : return -1;
795 : }
796 :
797 0 : data = xtrymalloc (maxlen? maxlen:1);
798 0 : if (!data)
799 : {
800 0 : tty_printf (_("error allocating enough memory: %s\n"), strerror (errno));
801 0 : es_fclose (fp);
802 0 : return -1;
803 : }
804 :
805 0 : if (maxlen)
806 0 : n = es_fread (data, 1, maxlen, fp);
807 : else
808 0 : n = 0;
809 0 : es_fclose (fp);
810 0 : if (n < 0)
811 : {
812 0 : tty_printf (_("error reading '%s': %s\n"), fname, strerror (errno));
813 0 : xfree (data);
814 0 : return -1;
815 : }
816 0 : *r_buffer = data;
817 0 : return n;
818 : }
819 :
820 :
821 : /* Write LENGTH bytes from BUFFER to file FNAME. Return 0 on
822 : success. */
823 : static int
824 0 : put_data_to_file (const char *fname, const void *buffer, size_t length)
825 : {
826 : estream_t fp;
827 :
828 0 : fp = es_fopen (fname, "wb");
829 : #if GNUPG_MAJOR_VERSION == 1
830 : if (fp && is_secured_file (fileno (fp)))
831 : {
832 : fclose (fp);
833 : fp = NULL;
834 : errno = EPERM;
835 : }
836 : #endif
837 0 : if (!fp)
838 : {
839 0 : tty_printf (_("can't create '%s': %s\n"), fname, strerror (errno));
840 0 : return -1;
841 : }
842 :
843 0 : if (length && es_fwrite (buffer, length, 1, fp) != 1)
844 : {
845 0 : tty_printf (_("error writing '%s': %s\n"), fname, strerror (errno));
846 0 : es_fclose (fp);
847 0 : return -1;
848 : }
849 0 : es_fclose (fp);
850 0 : return 0;
851 : }
852 :
853 :
854 : static int
855 0 : change_login (const char *args)
856 : {
857 : char *data;
858 : int n;
859 : int rc;
860 :
861 0 : if (args && *args == '<') /* Read it from a file */
862 : {
863 0 : for (args++; spacep (args); args++)
864 : ;
865 0 : n = get_data_from_file (args, 254, &data);
866 0 : if (n < 0)
867 0 : return -1;
868 : }
869 : else
870 : {
871 0 : data = cpr_get ("cardedit.change_login",
872 0 : _("Login data (account name): "));
873 0 : if (!data)
874 0 : return -1;
875 0 : trim_spaces (data);
876 0 : cpr_kill_prompt ();
877 0 : n = strlen (data);
878 : }
879 :
880 0 : if (n > 254 )
881 : {
882 0 : tty_printf (_("Error: Login data too long "
883 : "(limit is %d characters).\n"), 254);
884 0 : xfree (data);
885 0 : return -1;
886 : }
887 :
888 0 : rc = agent_scd_setattr ("LOGIN-DATA", data, n, NULL );
889 0 : if (rc)
890 0 : log_error ("error setting login data: %s\n", gpg_strerror (rc));
891 0 : xfree (data);
892 0 : write_sc_op_status (rc);
893 0 : return rc;
894 : }
895 :
896 : static int
897 0 : change_private_do (const char *args, int nr)
898 : {
899 0 : char do_name[] = "PRIVATE-DO-X";
900 : char *data;
901 : int n;
902 : int rc;
903 :
904 0 : log_assert (nr >= 1 && nr <= 4);
905 0 : do_name[11] = '0' + nr;
906 :
907 0 : if (args && (args = strchr (args, '<'))) /* Read it from a file */
908 : {
909 0 : for (args++; spacep (args); args++)
910 : ;
911 0 : n = get_data_from_file (args, 254, &data);
912 0 : if (n < 0)
913 0 : return -1;
914 : }
915 : else
916 : {
917 0 : data = cpr_get ("cardedit.change_private_do",
918 0 : _("Private DO data: "));
919 0 : if (!data)
920 0 : return -1;
921 0 : trim_spaces (data);
922 0 : cpr_kill_prompt ();
923 0 : n = strlen (data);
924 : }
925 :
926 0 : if (n > 254 )
927 : {
928 0 : tty_printf (_("Error: Private DO too long "
929 : "(limit is %d characters).\n"), 254);
930 0 : xfree (data);
931 0 : return -1;
932 : }
933 :
934 0 : rc = agent_scd_setattr (do_name, data, n, NULL );
935 0 : if (rc)
936 0 : log_error ("error setting private DO: %s\n", gpg_strerror (rc));
937 0 : xfree (data);
938 0 : write_sc_op_status (rc);
939 0 : return rc;
940 : }
941 :
942 :
943 : static int
944 0 : change_cert (const char *args)
945 : {
946 : char *data;
947 : int n;
948 : int rc;
949 :
950 0 : if (args && *args == '<') /* Read it from a file */
951 : {
952 0 : for (args++; spacep (args); args++)
953 : ;
954 0 : n = get_data_from_file (args, 16384, &data);
955 0 : if (n < 0)
956 0 : return -1;
957 : }
958 : else
959 : {
960 0 : tty_printf ("usage error: redirection to file required\n");
961 0 : return -1;
962 : }
963 :
964 0 : rc = agent_scd_writecert ("OPENPGP.3", data, n);
965 0 : if (rc)
966 0 : log_error ("error writing certificate to card: %s\n", gpg_strerror (rc));
967 0 : xfree (data);
968 0 : write_sc_op_status (rc);
969 0 : return rc;
970 : }
971 :
972 :
973 : static int
974 0 : read_cert (const char *args)
975 : {
976 : const char *fname;
977 : void *buffer;
978 : size_t length;
979 : int rc;
980 :
981 0 : if (args && *args == '>') /* Write it to a file */
982 : {
983 0 : for (args++; spacep (args); args++)
984 : ;
985 0 : fname = args;
986 : }
987 : else
988 : {
989 0 : tty_printf ("usage error: redirection to file required\n");
990 0 : return -1;
991 : }
992 :
993 0 : rc = agent_scd_readcert ("OPENPGP.3", &buffer, &length);
994 0 : if (rc)
995 0 : log_error ("error reading certificate from card: %s\n", gpg_strerror (rc));
996 : else
997 0 : rc = put_data_to_file (fname, buffer, length);
998 0 : xfree (buffer);
999 0 : write_sc_op_status (rc);
1000 0 : return rc;
1001 : }
1002 :
1003 :
1004 : static int
1005 0 : change_lang (void)
1006 : {
1007 : char *data, *p;
1008 : int rc;
1009 :
1010 0 : data = cpr_get ("cardedit.change_lang",
1011 0 : _("Language preferences: "));
1012 0 : if (!data)
1013 0 : return -1;
1014 0 : trim_spaces (data);
1015 0 : cpr_kill_prompt ();
1016 :
1017 0 : if (strlen (data) > 8 || (strlen (data) & 1))
1018 : {
1019 0 : tty_printf (_("Error: invalid length of preference string.\n"));
1020 0 : xfree (data);
1021 0 : return -1;
1022 : }
1023 :
1024 0 : for (p=data; *p && *p >= 'a' && *p <= 'z'; p++)
1025 : ;
1026 0 : if (*p)
1027 : {
1028 0 : tty_printf (_("Error: invalid characters in preference string.\n"));
1029 0 : xfree (data);
1030 0 : return -1;
1031 : }
1032 :
1033 0 : rc = agent_scd_setattr ("DISP-LANG", data, strlen (data), NULL );
1034 0 : if (rc)
1035 0 : log_error ("error setting lang: %s\n", gpg_strerror (rc));
1036 0 : xfree (data);
1037 0 : write_sc_op_status (rc);
1038 0 : return rc;
1039 : }
1040 :
1041 :
1042 : static int
1043 0 : change_sex (void)
1044 : {
1045 : char *data;
1046 : const char *str;
1047 : int rc;
1048 :
1049 0 : data = cpr_get ("cardedit.change_sex",
1050 0 : _("Sex ((M)ale, (F)emale or space): "));
1051 0 : if (!data)
1052 0 : return -1;
1053 0 : trim_spaces (data);
1054 0 : cpr_kill_prompt ();
1055 :
1056 0 : if (!*data)
1057 0 : str = "9";
1058 0 : else if ((*data == 'M' || *data == 'm') && !data[1])
1059 0 : str = "1";
1060 0 : else if ((*data == 'F' || *data == 'f') && !data[1])
1061 0 : str = "2";
1062 : else
1063 : {
1064 0 : tty_printf (_("Error: invalid response.\n"));
1065 0 : xfree (data);
1066 0 : return -1;
1067 : }
1068 :
1069 0 : rc = agent_scd_setattr ("DISP-SEX", str, 1, NULL );
1070 0 : if (rc)
1071 0 : log_error ("error setting sex: %s\n", gpg_strerror (rc));
1072 0 : xfree (data);
1073 0 : write_sc_op_status (rc);
1074 0 : return rc;
1075 : }
1076 :
1077 :
1078 : static int
1079 0 : change_cafpr (int fprno)
1080 : {
1081 : char *data;
1082 : const char *s;
1083 : int i, c, rc;
1084 : unsigned char fpr[20];
1085 :
1086 0 : data = cpr_get ("cardedit.change_cafpr", _("CA fingerprint: "));
1087 0 : if (!data)
1088 0 : return -1;
1089 0 : trim_spaces (data);
1090 0 : cpr_kill_prompt ();
1091 :
1092 0 : for (i=0, s=data; i < 20 && *s; )
1093 : {
1094 0 : while (spacep(s))
1095 0 : s++;
1096 0 : if (*s == ':')
1097 0 : s++;
1098 0 : while (spacep(s))
1099 0 : s++;
1100 0 : c = hextobyte (s);
1101 0 : if (c == -1)
1102 0 : break;
1103 0 : fpr[i++] = c;
1104 0 : s += 2;
1105 : }
1106 0 : xfree (data);
1107 0 : if (i != 20 || *s)
1108 : {
1109 0 : tty_printf (_("Error: invalid formatted fingerprint.\n"));
1110 0 : return -1;
1111 : }
1112 :
1113 0 : rc = agent_scd_setattr (fprno==1?"CA-FPR-1":
1114 : fprno==2?"CA-FPR-2":
1115 : fprno==3?"CA-FPR-3":"x", fpr, 20, NULL );
1116 0 : if (rc)
1117 0 : log_error ("error setting cafpr: %s\n", gpg_strerror (rc));
1118 0 : write_sc_op_status (rc);
1119 0 : return rc;
1120 : }
1121 :
1122 :
1123 :
1124 : static void
1125 0 : toggle_forcesig (void)
1126 : {
1127 : struct agent_card_info_s info;
1128 : int rc;
1129 : int newstate;
1130 :
1131 0 : memset (&info, 0, sizeof info);
1132 0 : rc = agent_scd_getattr ("CHV-STATUS", &info);
1133 0 : if (rc)
1134 : {
1135 0 : log_error ("error getting current status: %s\n", gpg_strerror (rc));
1136 0 : return;
1137 : }
1138 0 : newstate = !info.chv1_cached;
1139 0 : agent_release_card_info (&info);
1140 :
1141 0 : rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1, NULL);
1142 0 : if (rc)
1143 0 : log_error ("error toggling signature PIN flag: %s\n", gpg_strerror (rc));
1144 0 : write_sc_op_status (rc);
1145 : }
1146 :
1147 :
1148 : /* Helper for the key generation/edit functions. */
1149 : static int
1150 0 : get_info_for_key_operation (struct agent_card_info_s *info)
1151 : {
1152 : int rc;
1153 :
1154 0 : memset (info, 0, sizeof *info);
1155 0 : rc = agent_scd_getattr ("SERIALNO", info);
1156 0 : if (rc || !info->serialno || strncmp (info->serialno, "D27600012401", 12)
1157 0 : || strlen (info->serialno) != 32 )
1158 : {
1159 0 : log_error (_("key operation not possible: %s\n"),
1160 0 : rc ? gpg_strerror (rc) : _("not an OpenPGP card"));
1161 0 : return rc? rc: -1;
1162 : }
1163 0 : rc = agent_scd_getattr ("KEY-FPR", info);
1164 0 : if (!rc)
1165 0 : rc = agent_scd_getattr ("CHV-STATUS", info);
1166 0 : if (!rc)
1167 0 : rc = agent_scd_getattr ("DISP-NAME", info);
1168 0 : if (!rc)
1169 0 : rc = agent_scd_getattr ("EXTCAP", info);
1170 0 : if (!rc)
1171 0 : rc = agent_scd_getattr ("KEY-ATTR", info);
1172 0 : if (rc)
1173 0 : log_error (_("error getting current key info: %s\n"), gpg_strerror (rc));
1174 0 : return rc;
1175 : }
1176 :
1177 :
1178 : /* Helper for the key generation/edit functions. */
1179 : static int
1180 0 : check_pin_for_key_operation (struct agent_card_info_s *info, int *forced_chv1)
1181 : {
1182 0 : int rc = 0;
1183 :
1184 0 : agent_clear_pin_cache (info->serialno);
1185 :
1186 0 : *forced_chv1 = !info->chv1_cached;
1187 0 : if (*forced_chv1)
1188 : { /* Switch off the forced mode so that during key generation we
1189 : don't get bothered with PIN queries for each
1190 : self-signature. */
1191 0 : rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1, info->serialno);
1192 0 : if (rc)
1193 : {
1194 0 : log_error ("error clearing forced signature PIN flag: %s\n",
1195 : gpg_strerror (rc));
1196 0 : *forced_chv1 = 0;
1197 : }
1198 : }
1199 :
1200 0 : if (!rc)
1201 : {
1202 : /* Check the PIN now, so that we won't get asked later for each
1203 : binding signature. */
1204 0 : rc = agent_scd_checkpin (info->serialno);
1205 0 : if (rc)
1206 : {
1207 0 : log_error ("error checking the PIN: %s\n", gpg_strerror (rc));
1208 0 : write_sc_op_status (rc);
1209 : }
1210 : }
1211 0 : return rc;
1212 : }
1213 :
1214 : /* Helper for the key generation/edit functions. */
1215 : static void
1216 0 : restore_forced_chv1 (int *forced_chv1)
1217 : {
1218 : int rc;
1219 :
1220 0 : if (*forced_chv1)
1221 : { /* Switch back to forced state. */
1222 0 : rc = agent_scd_setattr ("CHV-STATUS-1", "", 1, NULL);
1223 0 : if (rc)
1224 : {
1225 0 : log_error ("error setting forced signature PIN flag: %s\n",
1226 : gpg_strerror (rc));
1227 : }
1228 : }
1229 0 : }
1230 :
1231 :
1232 : /* Helper for the key generation/edit functions. */
1233 : static void
1234 0 : show_card_key_info (struct agent_card_info_s *info)
1235 : {
1236 0 : tty_fprintf (NULL, "Signature key ....:");
1237 0 : print_sha1_fpr (NULL, info->fpr1valid? info->fpr1:NULL);
1238 0 : tty_fprintf (NULL, "Encryption key....:");
1239 0 : print_sha1_fpr (NULL, info->fpr2valid? info->fpr2:NULL);
1240 0 : tty_fprintf (NULL, "Authentication key:");
1241 0 : print_sha1_fpr (NULL, info->fpr3valid? info->fpr3:NULL);
1242 0 : tty_printf ("\n");
1243 0 : }
1244 :
1245 :
1246 : /* Helper for the key generation/edit functions. */
1247 : static int
1248 0 : replace_existing_key_p (struct agent_card_info_s *info, int keyno)
1249 : {
1250 0 : log_assert (keyno >= 0 && keyno <= 3);
1251 :
1252 0 : if ((keyno == 1 && info->fpr1valid)
1253 0 : || (keyno == 2 && info->fpr2valid)
1254 0 : || (keyno == 3 && info->fpr3valid))
1255 : {
1256 0 : tty_printf ("\n");
1257 0 : log_info ("WARNING: such a key has already been stored on the card!\n");
1258 0 : tty_printf ("\n");
1259 0 : if ( !cpr_get_answer_is_yes( "cardedit.genkeys.replace_key",
1260 0 : _("Replace existing key? (y/N) ")))
1261 0 : return -1;
1262 0 : return 1;
1263 : }
1264 0 : return 0;
1265 : }
1266 :
1267 :
1268 : static void
1269 0 : show_keysize_warning (void)
1270 : {
1271 : static int shown;
1272 :
1273 0 : if (shown)
1274 0 : return;
1275 0 : shown = 1;
1276 0 : tty_printf
1277 0 : (_("Note: There is no guarantee that the card "
1278 : "supports the requested size.\n"
1279 : " If the key generation does not succeed, "
1280 : "please check the\n"
1281 : " documentation of your card to see what "
1282 : "sizes are allowed.\n"));
1283 : }
1284 :
1285 :
1286 : /* Ask for the size of a card key. NBITS is the current size
1287 : configured for the card. KEYNO is the number of the key used to
1288 : select the prompt. Returns 0 to use the default size (i.e. NBITS)
1289 : or the selected size. */
1290 : static unsigned int
1291 0 : ask_card_rsa_keysize (int keyno, unsigned int nbits)
1292 : {
1293 0 : unsigned int min_nbits = 1024;
1294 0 : unsigned int max_nbits = 4096;
1295 : char *prompt, *answer;
1296 : unsigned int req_nbits;
1297 :
1298 : for (;;)
1299 : {
1300 0 : prompt = xasprintf
1301 : (keyno == 0?
1302 : _("What keysize do you want for the Signature key? (%u) "):
1303 : keyno == 1?
1304 : _("What keysize do you want for the Encryption key? (%u) "):
1305 : _("What keysize do you want for the Authentication key? (%u) "),
1306 : nbits);
1307 0 : answer = cpr_get ("cardedit.genkeys.size", prompt);
1308 0 : cpr_kill_prompt ();
1309 0 : req_nbits = *answer? atoi (answer): nbits;
1310 0 : xfree (prompt);
1311 0 : xfree (answer);
1312 :
1313 0 : if (req_nbits != nbits && (req_nbits % 32) )
1314 : {
1315 0 : req_nbits = ((req_nbits + 31) / 32) * 32;
1316 0 : tty_printf (_("rounded up to %u bits\n"), req_nbits);
1317 : }
1318 :
1319 0 : if (req_nbits == nbits)
1320 0 : return 0; /* Use default. */
1321 :
1322 0 : if (req_nbits < min_nbits || req_nbits > max_nbits)
1323 : {
1324 0 : tty_printf (_("%s keysizes must be in the range %u-%u\n"),
1325 : "RSA", min_nbits, max_nbits);
1326 : }
1327 : else
1328 : {
1329 0 : tty_printf (_("The card will now be re-configured "
1330 : "to generate a key of %u bits\n"), req_nbits);
1331 0 : show_keysize_warning ();
1332 0 : return req_nbits;
1333 : }
1334 0 : }
1335 : }
1336 :
1337 :
1338 : /* Change the size of key KEYNO (0..2) to NBITS and show an error
1339 : message if that fails. */
1340 : static gpg_error_t
1341 0 : do_change_rsa_keysize (int keyno, unsigned int nbits)
1342 : {
1343 : gpg_error_t err;
1344 : char args[100];
1345 :
1346 0 : snprintf (args, sizeof args, "--force %d 1 rsa%u", keyno+1, nbits);
1347 0 : err = agent_scd_setattr ("KEY-ATTR", args, strlen (args), NULL);
1348 0 : if (err)
1349 0 : log_error (_("error changing size of key %d to %u bits: %s\n"),
1350 : keyno+1, nbits, gpg_strerror (err));
1351 0 : return err;
1352 : }
1353 :
1354 :
1355 : static void
1356 0 : generate_card_keys (ctrl_t ctrl)
1357 : {
1358 : struct agent_card_info_s info;
1359 : int forced_chv1;
1360 : int want_backup;
1361 : int keyno;
1362 :
1363 0 : if (get_info_for_key_operation (&info))
1364 0 : return;
1365 :
1366 0 : if (info.extcap.ki)
1367 : {
1368 : char *answer;
1369 :
1370 : /* FIXME: Should be something like cpr_get_bool so that a status
1371 : GET_BOOL will be emitted. */
1372 0 : answer = cpr_get ("cardedit.genkeys.backup_enc",
1373 0 : _("Make off-card backup of encryption key? (Y/n) "));
1374 :
1375 0 : want_backup = answer_is_yes_no_default (answer, 1/*(default to Yes)*/);
1376 0 : cpr_kill_prompt ();
1377 0 : xfree (answer);
1378 : }
1379 : else
1380 0 : want_backup = 0;
1381 :
1382 0 : if ( (info.fpr1valid && !fpr_is_zero (info.fpr1))
1383 0 : || (info.fpr2valid && !fpr_is_zero (info.fpr2))
1384 0 : || (info.fpr3valid && !fpr_is_zero (info.fpr3)))
1385 : {
1386 0 : tty_printf ("\n");
1387 0 : log_info (_("Note: keys are already stored on the card!\n"));
1388 0 : tty_printf ("\n");
1389 0 : if ( !cpr_get_answer_is_yes ("cardedit.genkeys.replace_keys",
1390 0 : _("Replace existing keys? (y/N) ")))
1391 : {
1392 0 : agent_release_card_info (&info);
1393 0 : return;
1394 : }
1395 : }
1396 :
1397 : /* If no displayed name has been set, we assume that this is a fresh
1398 : card and print a hint about the default PINs. */
1399 0 : if (!info.disp_name || !*info.disp_name)
1400 : {
1401 0 : tty_printf ("\n");
1402 0 : tty_printf (_("Please note that the factory settings of the PINs are\n"
1403 : " PIN = '%s' Admin PIN = '%s'\n"
1404 : "You should change them using the command --change-pin\n"),
1405 : "123456", "12345678");
1406 0 : tty_printf ("\n");
1407 : }
1408 :
1409 0 : if (check_pin_for_key_operation (&info, &forced_chv1))
1410 0 : goto leave;
1411 :
1412 : /* If the cards features changeable key attributes, we ask for the
1413 : key size. */
1414 0 : if (info.is_v2 && info.extcap.aac)
1415 : {
1416 : unsigned int nbits;
1417 :
1418 0 : for (keyno = 0; keyno < DIM (info.key_attr); keyno++)
1419 : {
1420 0 : if (info.key_attr[keyno].algo == PUBKEY_ALGO_RSA)
1421 : {
1422 0 : nbits = ask_card_rsa_keysize (keyno, info.key_attr[keyno].nbits);
1423 0 : if (nbits && do_change_rsa_keysize (keyno, nbits))
1424 : {
1425 : /* Error: Better read the default key size again. */
1426 0 : agent_release_card_info (&info);
1427 0 : if (get_info_for_key_operation (&info))
1428 0 : goto leave;
1429 : /* Ask again for this key size. */
1430 0 : keyno--;
1431 : }
1432 : }
1433 : }
1434 : /* Note that INFO has not be synced. However we will only use
1435 : the serialnumber and thus it won't harm. */
1436 : }
1437 :
1438 0 : generate_keypair (ctrl, 1, NULL, info.serialno, want_backup);
1439 :
1440 : leave:
1441 0 : agent_release_card_info (&info);
1442 0 : restore_forced_chv1 (&forced_chv1);
1443 : }
1444 :
1445 :
1446 : /* This function is used by the key edit menu to generate an arbitrary
1447 : subkey. */
1448 : gpg_error_t
1449 0 : card_generate_subkey (KBNODE pub_keyblock)
1450 : {
1451 : gpg_error_t err;
1452 : struct agent_card_info_s info;
1453 0 : int forced_chv1 = 0;
1454 : int keyno;
1455 :
1456 0 : err = get_info_for_key_operation (&info);
1457 0 : if (err)
1458 0 : return err;
1459 :
1460 0 : show_card_key_info (&info);
1461 :
1462 0 : tty_printf (_("Please select the type of key to generate:\n"));
1463 :
1464 0 : tty_printf (_(" (1) Signature key\n"));
1465 0 : tty_printf (_(" (2) Encryption key\n"));
1466 0 : tty_printf (_(" (3) Authentication key\n"));
1467 :
1468 : for (;;)
1469 : {
1470 0 : char *answer = cpr_get ("cardedit.genkeys.subkeytype",
1471 0 : _("Your selection? "));
1472 0 : cpr_kill_prompt();
1473 0 : if (*answer == CONTROL_D)
1474 : {
1475 0 : xfree (answer);
1476 0 : err = gpg_error (GPG_ERR_CANCELED);
1477 0 : goto leave;
1478 : }
1479 0 : keyno = *answer? atoi(answer): 0;
1480 0 : xfree(answer);
1481 0 : if (keyno >= 1 && keyno <= 3)
1482 0 : break; /* Okay. */
1483 0 : tty_printf(_("Invalid selection.\n"));
1484 0 : }
1485 :
1486 0 : if (replace_existing_key_p (&info, keyno) < 0)
1487 : {
1488 0 : err = gpg_error (GPG_ERR_CANCELED);
1489 0 : goto leave;
1490 : }
1491 :
1492 0 : err = check_pin_for_key_operation (&info, &forced_chv1);
1493 0 : if (err)
1494 0 : goto leave;
1495 :
1496 : /* If the cards features changeable key attributes, we ask for the
1497 : key size. */
1498 0 : if (info.is_v2 && info.extcap.aac)
1499 : {
1500 0 : if (info.key_attr[keyno-1].algo == PUBKEY_ALGO_RSA)
1501 : {
1502 : unsigned int nbits;
1503 :
1504 : ask_again:
1505 0 : nbits = ask_card_rsa_keysize (keyno-1, info.key_attr[keyno-1].nbits);
1506 0 : if (nbits && do_change_rsa_keysize (keyno-1, nbits))
1507 : {
1508 : /* Error: Better read the default key size again. */
1509 0 : agent_release_card_info (&info);
1510 0 : err = get_info_for_key_operation (&info);
1511 0 : if (err)
1512 0 : goto leave;
1513 0 : goto ask_again;
1514 : }
1515 : }
1516 : /* Note that INFO has not be synced. However we will only use
1517 : the serialnumber and thus it won't harm. */
1518 : }
1519 :
1520 0 : err = generate_card_subkeypair (pub_keyblock, keyno, info.serialno);
1521 :
1522 : leave:
1523 0 : agent_release_card_info (&info);
1524 0 : restore_forced_chv1 (&forced_chv1);
1525 0 : return err;
1526 : }
1527 :
1528 :
1529 : /* Store the key at NODE into the smartcard and modify NODE to
1530 : carry the serialno stuff instead of the actual secret key
1531 : parameters. USE is the usage for that key; 0 means any
1532 : usage. */
1533 : int
1534 0 : card_store_subkey (KBNODE node, int use)
1535 : {
1536 : struct agent_card_info_s info;
1537 0 : int okay = 0;
1538 : unsigned int nbits;
1539 : int allow_keyno[3];
1540 : int keyno;
1541 : PKT_public_key *pk;
1542 : gpg_error_t err;
1543 : char *hexgrip;
1544 : int rc;
1545 : gnupg_isotime_t timebuf;
1546 :
1547 0 : log_assert (node->pkt->pkttype == PKT_PUBLIC_KEY
1548 : || node->pkt->pkttype == PKT_PUBLIC_SUBKEY);
1549 :
1550 0 : pk = node->pkt->pkt.public_key;
1551 :
1552 0 : if (get_info_for_key_operation (&info))
1553 0 : return 0;
1554 :
1555 0 : if (!info.extcap.ki)
1556 : {
1557 0 : tty_printf ("The card does not support the import of keys\n");
1558 0 : tty_printf ("\n");
1559 0 : goto leave;
1560 : }
1561 :
1562 0 : nbits = nbits_from_pk (pk);
1563 :
1564 0 : if (!info.is_v2 && nbits != 1024)
1565 : {
1566 0 : tty_printf ("You may only store a 1024 bit RSA key on the card\n");
1567 0 : tty_printf ("\n");
1568 0 : goto leave;
1569 : }
1570 :
1571 0 : allow_keyno[0] = (!use || (use & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_CERT)));
1572 0 : allow_keyno[1] = (!use || (use & (PUBKEY_USAGE_ENC)));
1573 0 : allow_keyno[2] = (!use || (use & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_AUTH)));
1574 :
1575 0 : tty_printf (_("Please select where to store the key:\n"));
1576 :
1577 0 : if (allow_keyno[0])
1578 0 : tty_printf (_(" (1) Signature key\n"));
1579 0 : if (allow_keyno[1])
1580 0 : tty_printf (_(" (2) Encryption key\n"));
1581 0 : if (allow_keyno[2])
1582 0 : tty_printf (_(" (3) Authentication key\n"));
1583 :
1584 : for (;;)
1585 : {
1586 0 : char *answer = cpr_get ("cardedit.genkeys.storekeytype",
1587 0 : _("Your selection? "));
1588 0 : cpr_kill_prompt();
1589 0 : if (*answer == CONTROL_D || !*answer)
1590 : {
1591 0 : xfree (answer);
1592 0 : goto leave;
1593 : }
1594 0 : keyno = *answer? atoi(answer): 0;
1595 0 : xfree(answer);
1596 0 : if (keyno >= 1 && keyno <= 3 && allow_keyno[keyno-1])
1597 : {
1598 0 : if (info.is_v2 && !info.extcap.aac
1599 0 : && info.key_attr[keyno-1].nbits != nbits)
1600 : {
1601 0 : tty_printf ("Key does not match the card's capability.\n");
1602 : }
1603 : else
1604 : break; /* Okay. */
1605 : }
1606 : else
1607 0 : tty_printf(_("Invalid selection.\n"));
1608 0 : }
1609 :
1610 0 : if ((rc = replace_existing_key_p (&info, keyno)) < 0)
1611 0 : goto leave;
1612 :
1613 0 : err = hexkeygrip_from_pk (pk, &hexgrip);
1614 0 : if (err)
1615 0 : goto leave;
1616 :
1617 0 : epoch2isotime (timebuf, (time_t)pk->timestamp);
1618 0 : rc = agent_keytocard (hexgrip, keyno, rc, info.serialno, timebuf);
1619 :
1620 0 : if (rc)
1621 0 : log_error (_("KEYTOCARD failed: %s\n"), gpg_strerror (rc));
1622 : else
1623 0 : okay = 1;
1624 0 : xfree (hexgrip);
1625 :
1626 : leave:
1627 0 : agent_release_card_info (&info);
1628 0 : return okay;
1629 : }
1630 :
1631 :
1632 :
1633 : /* Direct sending of an hex encoded APDU with error printing. */
1634 : static gpg_error_t
1635 0 : send_apdu (const char *hexapdu, const char *desc, unsigned int ignore)
1636 : {
1637 : gpg_error_t err;
1638 : unsigned int sw;
1639 :
1640 0 : err = agent_scd_apdu (hexapdu, &sw);
1641 0 : if (err)
1642 0 : tty_printf ("sending card command %s failed: %s\n", desc,
1643 : gpg_strerror (err));
1644 0 : else if (!hexapdu || !strcmp (hexapdu, "undefined"))
1645 : ;
1646 0 : else if (ignore == 0xffff)
1647 : ; /* Ignore all status words. */
1648 0 : else if (sw != 0x9000)
1649 : {
1650 0 : switch (sw)
1651 : {
1652 0 : case 0x6285: err = gpg_error (GPG_ERR_OBJ_TERM_STATE); break;
1653 0 : case 0x6982: err = gpg_error (GPG_ERR_BAD_PIN); break;
1654 0 : case 0x6985: err = gpg_error (GPG_ERR_USE_CONDITIONS); break;
1655 0 : default: err = gpg_error (GPG_ERR_CARD);
1656 : }
1657 0 : if (!(ignore && ignore == sw))
1658 0 : tty_printf ("card command %s failed: %s (0x%04x)\n", desc,
1659 : gpg_strerror (err), sw);
1660 : }
1661 0 : return err;
1662 : }
1663 :
1664 :
1665 : /* Do a factory reset after confirmation. */
1666 : static void
1667 0 : factory_reset (void)
1668 : {
1669 : struct agent_card_info_s info;
1670 : gpg_error_t err;
1671 0 : char *answer = NULL;
1672 0 : int termstate = 0;
1673 : int i;
1674 :
1675 : /* The code below basically does the same what this
1676 : gpg-connect-agent script does:
1677 :
1678 : scd reset
1679 : scd serialno undefined
1680 : scd apdu 00 A4 04 00 06 D2 76 00 01 24 01
1681 : scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
1682 : scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
1683 : scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
1684 : scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
1685 : scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
1686 : scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
1687 : scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
1688 : scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
1689 : scd apdu 00 e6 00 00
1690 : scd reset
1691 : scd serialno undefined
1692 : scd apdu 00 A4 04 00 06 D2 76 00 01 24 01
1693 : scd apdu 00 44 00 00
1694 : /echo Card has been reset to factory defaults
1695 :
1696 : but tries to find out something about the card first.
1697 : */
1698 :
1699 0 : err = agent_scd_learn (&info, 0);
1700 0 : if (gpg_err_code (err) == GPG_ERR_OBJ_TERM_STATE
1701 0 : && gpg_err_source (err) == GPG_ERR_SOURCE_SCD)
1702 0 : termstate = 1;
1703 0 : else if (err)
1704 : {
1705 0 : log_error (_("OpenPGP card not available: %s\n"), gpg_strerror (err));
1706 0 : return;
1707 : }
1708 :
1709 0 : if (!termstate)
1710 : {
1711 0 : log_info (_("OpenPGP card no. %s detected\n"),
1712 0 : info.serialno? info.serialno : "[none]");
1713 0 : if (!(info.status_indicator == 3 || info.status_indicator == 5))
1714 : {
1715 : /* Note: We won't see status-indicator 3 here because it is not
1716 : possible to select a card application in termination state. */
1717 0 : log_error (_("This command is not supported by this card\n"));
1718 0 : goto leave;
1719 : }
1720 :
1721 0 : tty_printf ("\n");
1722 0 : log_info (_("Note: This command destroys all keys stored on the card!\n"));
1723 0 : tty_printf ("\n");
1724 0 : if (!cpr_get_answer_is_yes ("cardedit.factory-reset.proceed",
1725 0 : _("Continue? (y/N) ")))
1726 0 : goto leave;
1727 :
1728 :
1729 0 : answer = cpr_get ("cardedit.factory-reset.really",
1730 0 : _("Really do a factory reset? (enter \"yes\") "));
1731 0 : cpr_kill_prompt ();
1732 0 : trim_spaces (answer);
1733 0 : if (strcmp (answer, "yes"))
1734 0 : goto leave;
1735 :
1736 : /* We need to select a card application before we can send APDUs
1737 : to the card without scdaemon doing anything on its own. */
1738 0 : err = send_apdu (NULL, "RESET", 0);
1739 0 : if (err)
1740 0 : goto leave;
1741 0 : err = send_apdu ("undefined", "dummy select ", 0);
1742 0 : if (err)
1743 0 : goto leave;
1744 :
1745 : /* Select the OpenPGP application. */
1746 0 : err = send_apdu ("00A4040006D27600012401", "SELECT AID", 0);
1747 0 : if (err)
1748 0 : goto leave;
1749 :
1750 : /* Do some dummy verifies with wrong PINs to set the retry
1751 : counter to zero. We can't easily use the card version 2.1
1752 : feature of presenting the admin PIN to allow the terminate
1753 : command because there is no machinery in scdaemon to catch
1754 : the verify command and ask for the PIN when the "APDU"
1755 : command is used. */
1756 0 : for (i=0; i < 4; i++)
1757 0 : send_apdu ("00200081084040404040404040", "VERIFY", 0xffff);
1758 0 : for (i=0; i < 4; i++)
1759 0 : send_apdu ("00200083084040404040404040", "VERIFY", 0xffff);
1760 :
1761 : /* Send terminate datafile command. */
1762 0 : err = send_apdu ("00e60000", "TERMINATE DF", 0x6985);
1763 0 : if (err)
1764 0 : goto leave;
1765 : }
1766 :
1767 : /* The card is in termination state - reset and select again. */
1768 0 : err = send_apdu (NULL, "RESET", 0);
1769 0 : if (err)
1770 0 : goto leave;
1771 0 : err = send_apdu ("undefined", "dummy select", 0);
1772 0 : if (err)
1773 0 : goto leave;
1774 :
1775 : /* Select the OpenPGP application. (no error checking here). */
1776 0 : send_apdu ("00A4040006D27600012401", "SELECT AID", 0xffff);
1777 :
1778 : /* Send activate datafile command. This is used without
1779 : confirmation if the card is already in termination state. */
1780 0 : err = send_apdu ("00440000", "ACTIVATE DF", 0);
1781 0 : if (err)
1782 0 : goto leave;
1783 :
1784 : /* Finally we reset the card reader once more. */
1785 0 : err = send_apdu (NULL, "RESET", 0);
1786 0 : if (err)
1787 0 : goto leave;
1788 :
1789 : leave:
1790 0 : xfree (answer);
1791 0 : agent_release_card_info (&info);
1792 : }
1793 :
1794 :
1795 :
1796 : /* Data used by the command parser. This needs to be outside of the
1797 : function scope to allow readline based command completion. */
1798 : enum cmdids
1799 : {
1800 : cmdNOP = 0,
1801 : cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG, cmdVERIFY,
1802 : cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR,
1803 : cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT,
1804 : cmdREADCERT, cmdUNBLOCK, cmdFACTORYRESET,
1805 : cmdINVCMD
1806 : };
1807 :
1808 : static struct
1809 : {
1810 : const char *name;
1811 : enum cmdids id;
1812 : int admin_only;
1813 : const char *desc;
1814 : } cmds[] =
1815 : {
1816 : { "quit" , cmdQUIT , 0, N_("quit this menu")},
1817 : { "q" , cmdQUIT , 0, NULL },
1818 : { "admin" , cmdADMIN , 0, N_("show admin commands")},
1819 : { "help" , cmdHELP , 0, N_("show this help")},
1820 : { "?" , cmdHELP , 0, NULL },
1821 : { "list" , cmdLIST , 0, N_("list all available data")},
1822 : { "l" , cmdLIST , 0, NULL },
1823 : { "debug" , cmdDEBUG , 0, NULL },
1824 : { "name" , cmdNAME , 1, N_("change card holder's name")},
1825 : { "url" , cmdURL , 1, N_("change URL to retrieve key")},
1826 : { "fetch" , cmdFETCH , 0, N_("fetch the key specified in the card URL")},
1827 : { "login" , cmdLOGIN , 1, N_("change the login name")},
1828 : { "lang" , cmdLANG , 1, N_("change the language preferences")},
1829 : { "sex" , cmdSEX , 1, N_("change card holder's sex")},
1830 : { "cafpr" , cmdCAFPR , 1, N_("change a CA fingerprint")},
1831 : { "forcesig", cmdFORCESIG, 1, N_("toggle the signature force PIN flag")},
1832 : { "generate", cmdGENERATE, 1, N_("generate new keys")},
1833 : { "passwd" , cmdPASSWD, 0, N_("menu to change or unblock the PIN")},
1834 : { "verify" , cmdVERIFY, 0, N_("verify the PIN and list all data")},
1835 : { "unblock" , cmdUNBLOCK,0, N_("unblock the PIN using a Reset Code") },
1836 : { "factory-reset", cmdFACTORYRESET, 1, N_("destroy all keys and data")},
1837 : /* Note, that we do not announce these command yet. */
1838 : { "privatedo", cmdPRIVATEDO, 0, NULL },
1839 : { "readcert", cmdREADCERT, 0, NULL },
1840 : { "writecert", cmdWRITECERT, 1, NULL },
1841 : { NULL, cmdINVCMD, 0, NULL }
1842 : };
1843 :
1844 :
1845 : #ifdef HAVE_LIBREADLINE
1846 :
1847 : /* These two functions are used by readline for command completion. */
1848 :
1849 : static char *
1850 0 : command_generator(const char *text,int state)
1851 : {
1852 : static int list_index,len;
1853 : const char *name;
1854 :
1855 : /* If this is a new word to complete, initialize now. This includes
1856 : saving the length of TEXT for efficiency, and initializing the
1857 : index variable to 0. */
1858 0 : if(!state)
1859 : {
1860 0 : list_index=0;
1861 0 : len=strlen(text);
1862 : }
1863 :
1864 : /* Return the next partial match */
1865 0 : while((name=cmds[list_index].name))
1866 : {
1867 : /* Only complete commands that have help text */
1868 0 : if(cmds[list_index++].desc && strncmp(name,text,len)==0)
1869 0 : return strdup(name);
1870 : }
1871 :
1872 0 : return NULL;
1873 : }
1874 :
1875 : static char **
1876 0 : card_edit_completion(const char *text, int start, int end)
1877 : {
1878 : (void)end;
1879 : /* If we are at the start of a line, we try and command-complete.
1880 : If not, just do nothing for now. */
1881 :
1882 0 : if(start==0)
1883 0 : return rl_completion_matches(text,command_generator);
1884 :
1885 0 : rl_attempted_completion_over=1;
1886 :
1887 0 : return NULL;
1888 : }
1889 : #endif /*HAVE_LIBREADLINE*/
1890 :
1891 : /* Menu to edit all user changeable values on an OpenPGP card. Only
1892 : Key creation is not handled here. */
1893 : void
1894 0 : card_edit (ctrl_t ctrl, strlist_t commands)
1895 : {
1896 0 : enum cmdids cmd = cmdNOP;
1897 0 : int have_commands = !!commands;
1898 0 : int redisplay = 1;
1899 0 : char *answer = NULL;
1900 0 : int allow_admin=0;
1901 : char serialnobuf[50];
1902 :
1903 :
1904 0 : if (opt.command_fd != -1)
1905 : ;
1906 0 : else if (opt.batch && !have_commands)
1907 : {
1908 0 : log_error(_("can't do this in batch mode\n"));
1909 0 : goto leave;
1910 : }
1911 :
1912 : for (;;)
1913 : {
1914 : int arg_number;
1915 0 : const char *arg_string = "";
1916 0 : const char *arg_rest = "";
1917 : char *p;
1918 : int i;
1919 : int cmd_admin_only;
1920 :
1921 0 : tty_printf("\n");
1922 0 : if (redisplay )
1923 : {
1924 0 : if (opt.with_colons)
1925 : {
1926 0 : card_status (es_stdout, serialnobuf, DIM (serialnobuf));
1927 0 : fflush (stdout);
1928 : }
1929 : else
1930 : {
1931 0 : card_status (NULL, serialnobuf, DIM (serialnobuf));
1932 0 : tty_printf("\n");
1933 : }
1934 0 : redisplay = 0;
1935 : }
1936 :
1937 : do
1938 : {
1939 0 : xfree (answer);
1940 0 : if (have_commands)
1941 : {
1942 0 : if (commands)
1943 : {
1944 0 : answer = xstrdup (commands->d);
1945 0 : commands = commands->next;
1946 : }
1947 0 : else if (opt.batch)
1948 : {
1949 0 : answer = xstrdup ("quit");
1950 : }
1951 : else
1952 0 : have_commands = 0;
1953 : }
1954 :
1955 0 : if (!have_commands)
1956 : {
1957 0 : tty_enable_completion (card_edit_completion);
1958 0 : answer = cpr_get_no_help("cardedit.prompt", _("gpg/card> "));
1959 0 : cpr_kill_prompt();
1960 0 : tty_disable_completion ();
1961 : }
1962 0 : trim_spaces(answer);
1963 : }
1964 0 : while ( *answer == '#' );
1965 :
1966 0 : arg_number = 0; /* Yes, here is the init which egcc complains about */
1967 0 : cmd_admin_only = 0;
1968 0 : if (!*answer)
1969 0 : cmd = cmdLIST; /* Default to the list command */
1970 0 : else if (*answer == CONTROL_D)
1971 0 : cmd = cmdQUIT;
1972 : else
1973 : {
1974 0 : if ((p=strchr (answer,' ')))
1975 : {
1976 0 : *p++ = 0;
1977 0 : trim_spaces (answer);
1978 0 : trim_spaces (p);
1979 0 : arg_number = atoi(p);
1980 0 : arg_string = p;
1981 0 : arg_rest = p;
1982 0 : while (digitp (arg_rest))
1983 0 : arg_rest++;
1984 0 : while (spacep (arg_rest))
1985 0 : arg_rest++;
1986 : }
1987 :
1988 0 : for (i=0; cmds[i].name; i++ )
1989 0 : if (!ascii_strcasecmp (answer, cmds[i].name ))
1990 0 : break;
1991 :
1992 0 : cmd = cmds[i].id;
1993 0 : cmd_admin_only = cmds[i].admin_only;
1994 : }
1995 :
1996 0 : if (!allow_admin && cmd_admin_only)
1997 : {
1998 0 : tty_printf ("\n");
1999 0 : tty_printf (_("Admin-only command\n"));
2000 0 : continue;
2001 : }
2002 :
2003 0 : switch (cmd)
2004 : {
2005 : case cmdHELP:
2006 0 : for (i=0; cmds[i].name; i++ )
2007 0 : if(cmds[i].desc
2008 0 : && (!cmds[i].admin_only || (cmds[i].admin_only && allow_admin)))
2009 0 : tty_printf("%-14s %s\n", cmds[i].name, _(cmds[i].desc) );
2010 0 : break;
2011 :
2012 : case cmdADMIN:
2013 0 : if ( !strcmp (arg_string, "on") )
2014 0 : allow_admin = 1;
2015 0 : else if ( !strcmp (arg_string, "off") )
2016 0 : allow_admin = 0;
2017 0 : else if ( !strcmp (arg_string, "verify") )
2018 : {
2019 : /* Force verification of the Admin Command. However,
2020 : this is only done if the retry counter is at initial
2021 : state. */
2022 0 : char *tmp = xmalloc (strlen (serialnobuf) + 6 + 1);
2023 0 : strcpy (stpcpy (tmp, serialnobuf), "[CHV3]");
2024 0 : allow_admin = !agent_scd_checkpin (tmp);
2025 0 : xfree (tmp);
2026 : }
2027 : else /* Toggle. */
2028 0 : allow_admin=!allow_admin;
2029 0 : if(allow_admin)
2030 0 : tty_printf(_("Admin commands are allowed\n"));
2031 : else
2032 0 : tty_printf(_("Admin commands are not allowed\n"));
2033 0 : break;
2034 :
2035 : case cmdVERIFY:
2036 0 : agent_scd_checkpin (serialnobuf);
2037 0 : redisplay = 1;
2038 0 : break;
2039 :
2040 : case cmdLIST:
2041 0 : redisplay = 1;
2042 0 : break;
2043 :
2044 : case cmdNAME:
2045 0 : change_name ();
2046 0 : break;
2047 :
2048 : case cmdURL:
2049 0 : change_url ();
2050 0 : break;
2051 :
2052 : case cmdFETCH:
2053 0 : fetch_url (ctrl);
2054 0 : break;
2055 :
2056 : case cmdLOGIN:
2057 0 : change_login (arg_string);
2058 0 : break;
2059 :
2060 : case cmdLANG:
2061 0 : change_lang ();
2062 0 : break;
2063 :
2064 : case cmdSEX:
2065 0 : change_sex ();
2066 0 : break;
2067 :
2068 : case cmdCAFPR:
2069 0 : if ( arg_number < 1 || arg_number > 3 )
2070 0 : tty_printf ("usage: cafpr N\n"
2071 : " 1 <= N <= 3\n");
2072 : else
2073 0 : change_cafpr (arg_number);
2074 0 : break;
2075 :
2076 : case cmdPRIVATEDO:
2077 0 : if ( arg_number < 1 || arg_number > 4 )
2078 0 : tty_printf ("usage: privatedo N\n"
2079 : " 1 <= N <= 4\n");
2080 : else
2081 0 : change_private_do (arg_string, arg_number);
2082 0 : break;
2083 :
2084 : case cmdWRITECERT:
2085 0 : if ( arg_number != 3 )
2086 0 : tty_printf ("usage: writecert 3 < FILE\n");
2087 : else
2088 0 : change_cert (arg_rest);
2089 0 : break;
2090 :
2091 : case cmdREADCERT:
2092 0 : if ( arg_number != 3 )
2093 0 : tty_printf ("usage: readcert 3 > FILE\n");
2094 : else
2095 0 : read_cert (arg_rest);
2096 0 : break;
2097 :
2098 : case cmdFORCESIG:
2099 0 : toggle_forcesig ();
2100 0 : break;
2101 :
2102 : case cmdGENERATE:
2103 0 : generate_card_keys (ctrl);
2104 0 : break;
2105 :
2106 : case cmdPASSWD:
2107 0 : change_pin (0, allow_admin);
2108 0 : break;
2109 :
2110 : case cmdUNBLOCK:
2111 0 : change_pin (1, allow_admin);
2112 0 : break;
2113 :
2114 : case cmdFACTORYRESET:
2115 0 : factory_reset ();
2116 0 : break;
2117 :
2118 : case cmdQUIT:
2119 0 : goto leave;
2120 :
2121 : case cmdNOP:
2122 0 : break;
2123 :
2124 : case cmdINVCMD:
2125 : default:
2126 0 : tty_printf ("\n");
2127 0 : tty_printf (_("Invalid command (try \"help\")\n"));
2128 0 : break;
2129 : } /* End command switch. */
2130 0 : } /* End of main menu loop. */
2131 :
2132 : leave:
2133 0 : xfree (answer);
2134 0 : }
|