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