1 /* protect-tool.c - A tool to test the secret key protection
2 * Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
33 #define JNLIB_NEED_LOG_LOGV
36 #include "simple-pwquery.h"
39 enum cmd_and_opt_values
65 struct rsa_secret_key_s
67 gcry_mpi_t n
; /* public modulus */
68 gcry_mpi_t e
; /* public exponent */
69 gcry_mpi_t d
; /* exponent */
70 gcry_mpi_t p
; /* prime p. */
71 gcry_mpi_t q
; /* prime q. */
72 gcry_mpi_t u
; /* inverse of p mod q. */
76 static char *opt_homedir
;
80 static int opt_no_fail_on_exist
;
81 static int opt_have_cert
;
82 static const char *opt_passphrase
;
83 static char *opt_prompt
;
84 static int opt_status_msg
;
86 static char *get_passphrase (int promptno
);
87 static void release_passphrase (char *pw
);
88 static int store_private_key (const unsigned char *grip
,
89 const void *buffer
, size_t length
, int force
);
92 static ARGPARSE_OPTS opts
[] = {
94 { 301, NULL
, 0, N_("@Options:\n ") },
96 { oVerbose
, "verbose", 0, "verbose" },
97 { oArmor
, "armor", 0, "write output in advanced format" },
98 { oPassphrase
, "passphrase", 2, "|STRING|use passphrase STRING" },
99 { oProtect
, "protect", 256, "protect a private key"},
100 { oUnprotect
, "unprotect", 256, "unprotect a private key"},
101 { oShadow
, "shadow", 256, "create a shadow entry for a priblic key"},
102 { oShowShadowInfo
, "show-shadow-info", 256, "return the shadow info"},
103 { oShowKeygrip
, "show-keygrip", 256, "show the \"keygrip\""},
105 { oP12Import
, "p12-import", 256, "import a PKCS-12 encoded private key"},
106 { oP12Export
, "p12-export", 256, "export a private key PKCS-12 encoded"},
107 { oHaveCert
, "have-cert", 0, "certificate to export provided on STDIN"},
108 { oStore
, "store", 0, "store the created key in the appropriate place"},
109 { oForce
, "force", 0, "force overwriting"},
110 { oNoFailOnExist
, "no-fail-on-exist", 0, "@" },
111 { oHomedir
, "homedir", 2, "@" },
112 { oPrompt
, "prompt", 2, "|ESCSTRING|use ESCSTRING as prompt in pinentry"},
113 { oStatusMsg
, "enable-status-msg", 0, "@"},
118 my_strusage (int level
)
123 case 11: p
= "gpg-protect-tool (GnuPG)";
125 case 13: p
= VERSION
; break;
126 case 17: p
= PRINTABLE_OS_NAME
; break;
127 case 19: p
= _("Please report bugs to <" PACKAGE_BUGREPORT
">.\n");
130 case 40: p
= _("Usage: gpg-protect-tool [options] (-h for help)\n");
132 case 41: p
= _("Syntax: gpg-protect-tool [options] [args]]\n"
133 "Secret key maintenance tool\n");
146 #ifdef USE_SIMPLE_GETTEXT
147 set_gettext_file( PACKAGE_GT
);
150 setlocale (LC_ALL
, "");
151 bindtextdomain (PACKAGE_GT
, LOCALEDIR
);
152 textdomain (PACKAGE_GT
);
159 /* Used by gcry for logging */
161 my_gcry_logger (void *dummy
, int level
, const char *fmt
, va_list arg_ptr
)
163 /* translate the log levels */
166 case GCRY_LOG_CONT
: level
= JNLIB_LOG_CONT
; break;
167 case GCRY_LOG_INFO
: level
= JNLIB_LOG_INFO
; break;
168 case GCRY_LOG_WARN
: level
= JNLIB_LOG_WARN
; break;
169 case GCRY_LOG_ERROR
:level
= JNLIB_LOG_ERROR
; break;
170 case GCRY_LOG_FATAL
:level
= JNLIB_LOG_FATAL
; break;
171 case GCRY_LOG_BUG
: level
= JNLIB_LOG_BUG
; break;
172 case GCRY_LOG_DEBUG
:level
= JNLIB_LOG_DEBUG
; break;
173 default: level
= JNLIB_LOG_ERROR
; break; }
174 log_logv (level
, fmt
, arg_ptr
);
179 /* print_mpi (const char *text, gcry_mpi_t a) */
182 /* void *bufaddr = &buf; */
185 /* rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a); */
187 /* log_info ("%s: [error printing number: %s]\n", text, gpg_strerror (rc)); */
190 /* log_info ("%s: %s\n", text, buf); */
191 /* gcry_free (buf); */
197 static unsigned char *
198 make_canonical (const char *fname
, const char *buf
, size_t buflen
)
203 unsigned char *result
;
205 rc
= gcry_sexp_sscan (&sexp
, &erroff
, buf
, buflen
);
208 log_error ("invalid S-Expression in `%s' (off=%u): %s\n",
209 fname
, (unsigned int)erroff
, gpg_strerror (rc
));
212 len
= gcry_sexp_sprint (sexp
, GCRYSEXP_FMT_CANON
, NULL
, 0);
214 result
= xmalloc (len
);
215 len
= gcry_sexp_sprint (sexp
, GCRYSEXP_FMT_CANON
, result
, len
);
217 gcry_sexp_release (sexp
);
222 make_advanced (const unsigned char *buf
, size_t buflen
)
227 unsigned char *result
;
229 rc
= gcry_sexp_sscan (&sexp
, &erroff
, buf
, buflen
);
232 log_error ("invalid canonical S-Expression (off=%u): %s\n",
233 (unsigned int)erroff
, gpg_strerror (rc
));
236 len
= gcry_sexp_sprint (sexp
, GCRYSEXP_FMT_ADVANCED
, NULL
, 0);
238 result
= xmalloc (len
);
239 len
= gcry_sexp_sprint (sexp
, GCRYSEXP_FMT_ADVANCED
, result
, len
);
241 gcry_sexp_release (sexp
);
247 read_file (const char *fname
, size_t *r_length
)
253 if (!strcmp (fname
, "-"))
255 size_t nread
, bufsize
= 0;
265 buf
= xmalloc (bufsize
);
267 buf
= xrealloc (buf
, bufsize
);
269 nread
= fread (buf
+buflen
, 1, NCHUNK
, fp
);
270 if (nread
< NCHUNK
&& ferror (fp
))
272 log_error ("error reading `[stdin]': %s\n", strerror (errno
));
278 while (nread
== NCHUNK
);
286 fp
= fopen (fname
, "rb");
289 log_error ("can't open `%s': %s\n", fname
, strerror (errno
));
293 if (fstat (fileno(fp
), &st
))
295 log_error ("can't stat `%s': %s\n", fname
, strerror (errno
));
301 buf
= xmalloc (buflen
+1);
302 if (fread (buf
, buflen
, 1, fp
) != 1)
304 log_error ("error reading `%s': %s\n", fname
, strerror (errno
));
317 static unsigned char *
318 read_key (const char *fname
)
324 buf
= read_file (fname
, &buflen
);
327 key
= make_canonical (fname
, buf
, buflen
);
335 read_and_protect (const char *fname
)
339 unsigned char *result
;
343 key
= read_key (fname
);
347 pw
= get_passphrase (1);
348 rc
= agent_protect (key
, pw
, &result
, &resultlen
);
349 release_passphrase (pw
);
353 log_error ("protecting the key failed: %s\n", gpg_strerror (rc
));
359 char *p
= make_advanced (result
, resultlen
);
364 resultlen
= strlen (p
);
367 fwrite (result
, resultlen
, 1, stdout
);
373 read_and_unprotect (const char *fname
)
377 unsigned char *result
;
381 key
= read_key (fname
);
385 rc
= agent_unprotect (key
, (pw
=get_passphrase (1)), &result
, &resultlen
);
386 release_passphrase (pw
);
391 log_info ("[PROTECT-TOOL:] bad-passphrase\n");
392 log_error ("unprotecting the key failed: %s\n", gpg_strerror (rc
));
398 char *p
= make_advanced (result
, resultlen
);
403 resultlen
= strlen (p
);
406 fwrite (result
, resultlen
, 1, stdout
);
413 read_and_shadow (const char *fname
)
417 unsigned char *result
;
420 key
= read_key (fname
);
424 rc
= agent_shadow_key (key
, "(8:313233342:43)", &result
);
428 log_error ("shadowing the key failed: %s\n", gpg_strerror (rc
));
431 resultlen
= gcry_sexp_canon_len (result
, 0, NULL
,NULL
);
436 char *p
= make_advanced (result
, resultlen
);
441 resultlen
= strlen (p
);
444 fwrite (result
, resultlen
, 1, stdout
);
449 show_shadow_info (const char *fname
)
453 const unsigned char *info
;
456 key
= read_key (fname
);
460 rc
= agent_get_shadow_info (key
, &info
);
464 log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc
));
467 infolen
= gcry_sexp_canon_len (info
, 0, NULL
,NULL
);
472 char *p
= make_advanced (info
, infolen
);
475 fwrite (p
, strlen (p
), 1, stdout
);
479 fwrite (info
, infolen
, 1, stdout
);
484 show_file (const char *fname
)
490 key
= read_key (fname
);
494 keylen
= gcry_sexp_canon_len (key
, 0, NULL
,NULL
);
497 p
= make_advanced (key
, keylen
);
501 fwrite (p
, strlen (p
), 1, stdout
);
507 show_keygrip (const char *fname
)
511 unsigned char grip
[20];
514 key
= read_key (fname
);
518 if (gcry_sexp_new (&private, key
, 0, 0))
520 log_error ("gcry_sexp_new failed\n");
525 if (!gcry_pk_get_keygrip (private, grip
))
527 log_error ("can't calculate keygrip\n");
530 gcry_sexp_release (private);
532 for (i
=0; i
< 20; i
++)
533 printf ("%02X", grip
[i
]);
539 rsa_key_check (struct rsa_secret_key_s
*skey
)
542 gcry_mpi_t t
= gcry_mpi_snew (0);
543 gcry_mpi_t t1
= gcry_mpi_snew (0);
544 gcry_mpi_t t2
= gcry_mpi_snew (0);
545 gcry_mpi_t phi
= gcry_mpi_snew (0);
547 /* check that n == p * q */
548 gcry_mpi_mul (t
, skey
->p
, skey
->q
);
549 if (gcry_mpi_cmp( t
, skey
->n
) )
551 log_error ("RSA oops: n != p * q\n");
555 /* check that p is less than q */
556 if (gcry_mpi_cmp (skey
->p
, skey
->q
) > 0)
560 log_info ("swapping secret primes\n");
561 tmp
= gcry_mpi_copy (skey
->p
);
562 gcry_mpi_set (skey
->p
, skey
->q
);
563 gcry_mpi_set (skey
->q
, tmp
);
564 gcry_mpi_release (tmp
);
565 /* and must recompute u of course */
566 gcry_mpi_invm (skey
->u
, skey
->p
, skey
->q
);
569 /* check that e divides neither p-1 nor q-1 */
570 gcry_mpi_sub_ui (t
, skey
->p
, 1 );
571 gcry_mpi_div (NULL
, t
, t
, skey
->e
, 0);
572 if (!gcry_mpi_cmp_ui( t
, 0) )
574 log_error ("RSA oops: e divides p-1\n");
577 gcry_mpi_sub_ui (t
, skey
->q
, 1);
578 gcry_mpi_div (NULL
, t
, t
, skey
->e
, 0);
579 if (!gcry_mpi_cmp_ui( t
, 0))
581 log_info ( "RSA oops: e divides q-1\n" );
585 /* check that d is correct. */
586 gcry_mpi_sub_ui (t1
, skey
->p
, 1);
587 gcry_mpi_sub_ui (t2
, skey
->q
, 1);
588 gcry_mpi_mul (phi
, t1
, t2
);
589 gcry_mpi_invm (t
, skey
->e
, phi
);
590 if (gcry_mpi_cmp (t
, skey
->d
))
591 { /* no: try universal exponent. */
592 gcry_mpi_gcd (t
, t1
, t2
);
593 gcry_mpi_div (t
, NULL
, phi
, t
, 0);
594 gcry_mpi_invm (t
, skey
->e
, t
);
595 if (gcry_mpi_cmp (t
, skey
->d
))
597 log_error ("RSA oops: bad secret exponent\n");
602 /* check for correctness of u */
603 gcry_mpi_invm (t
, skey
->p
, skey
->q
);
604 if (gcry_mpi_cmp (t
, skey
->u
))
606 log_info ( "RSA oops: bad u parameter\n");
611 log_info ("RSA secret key check failed\n");
613 gcry_mpi_release (t
);
614 gcry_mpi_release (t1
);
615 gcry_mpi_release (t2
);
616 gcry_mpi_release (phi
);
622 /* A callback used by p12_parse to return a certificate. */
624 import_p12_cert_cb (void *opaque
, const unsigned char *cert
, size_t certlen
)
626 struct b64state state
;
627 gpg_error_t err
, err2
;
629 err
= b64enc_start (&state
, stdout
, "CERTIFICATE");
631 err
= b64enc_write (&state
, cert
, certlen
);
632 err2
= b64enc_finish (&state
);
636 log_error ("error writing armored certificate: %s\n", gpg_strerror (err
));
640 import_p12_file (const char *fname
)
643 unsigned char *result
;
644 size_t buflen
, resultlen
;
648 struct rsa_secret_key_s sk
;
651 unsigned char grip
[20];
654 /* fixme: we should release some stuff on error */
656 buf
= read_file (fname
, &buflen
);
660 kparms
= p12_parse (buf
, buflen
, (pw
=get_passphrase (0)),
661 import_p12_cert_cb
, NULL
);
662 release_passphrase (pw
);
666 log_error ("error parsing or decrypting the PKCS-12 file\n");
669 for (i
=0; kparms
[i
]; i
++)
673 log_error ("invalid structure of private key\n");
678 /* print_mpi (" n", kparms[0]); */
679 /* print_mpi (" e", kparms[1]); */
680 /* print_mpi (" d", kparms[2]); */
681 /* print_mpi (" p", kparms[3]); */
682 /* print_mpi (" q", kparms[4]); */
683 /* print_mpi ("dmp1", kparms[5]); */
684 /* print_mpi ("dmq1", kparms[6]); */
685 /* print_mpi (" u", kparms[7]); */
693 if (rsa_key_check (&sk
))
695 /* print_mpi (" n", sk.n); */
696 /* print_mpi (" e", sk.e); */
697 /* print_mpi (" d", sk.d); */
698 /* print_mpi (" p", sk.p); */
699 /* print_mpi (" q", sk.q); */
700 /* print_mpi (" u", sk.u); */
702 /* Create an S-expresion from the parameters. */
703 rc
= gcry_sexp_build (&s_key
, NULL
,
704 "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
705 sk
.n
, sk
.e
, sk
.d
, sk
.p
, sk
.q
, sk
.u
, NULL
);
706 for (i
=0; i
< 8; i
++)
707 gcry_mpi_release (kparms
[i
]);
711 log_error ("failed to created S-expression from key: %s\n",
716 /* Compute the keygrip. */
717 if (!gcry_pk_get_keygrip (s_key
, grip
))
719 log_error ("can't calculate keygrip\n");
722 log_info ("keygrip: ");
723 for (i
=0; i
< 20; i
++)
724 log_printf ("%02X", grip
[i
]);
727 /* Convert to canonical encoding. */
728 buflen
= gcry_sexp_sprint (s_key
, GCRYSEXP_FMT_CANON
, NULL
, 0);
730 key
= gcry_xmalloc_secure (buflen
);
731 buflen
= gcry_sexp_sprint (s_key
, GCRYSEXP_FMT_CANON
, key
, buflen
);
733 gcry_sexp_release (s_key
);
736 rc
= agent_protect (key
, (pw
=get_passphrase (0)), &result
, &resultlen
);
737 release_passphrase (pw
);
741 log_error ("protecting the key failed: %s\n", gpg_strerror (rc
));
747 char *p
= make_advanced (result
, resultlen
);
752 resultlen
= strlen (p
);
756 store_private_key (grip
, result
, resultlen
, opt_force
);
758 fwrite (result
, resultlen
, 1, stdout
);
766 sexp_to_kparms (gcry_sexp_t sexp
)
768 gcry_sexp_t list
, l2
;
776 list
= gcry_sexp_find_token (sexp
, "private-key", 0 );
779 l2
= gcry_sexp_cadr (list
);
780 gcry_sexp_release (list
);
782 name
= gcry_sexp_nth_data (list
, 0, &n
);
783 if(!name
|| n
!= 3 || memcmp (name
, "rsa", 3))
785 gcry_sexp_release (list
);
789 /* Parameter names used with RSA. */
791 array
= xcalloc (strlen(elems
) + 1, sizeof *array
);
792 for (idx
=0, s
=elems
; *s
; s
++, idx
++ )
794 l2
= gcry_sexp_find_token (list
, s
, 1);
797 for (i
=0; i
<idx
; i
++)
798 gcry_mpi_release (array
[i
]);
800 gcry_sexp_release (list
);
801 return NULL
; /* required parameter not found */
803 array
[idx
] = gcry_sexp_nth_mpi (l2
, 1, GCRYMPI_FMT_USG
);
804 gcry_sexp_release (l2
);
807 for (i
=0; i
<idx
; i
++)
808 gcry_mpi_release (array
[i
]);
810 gcry_sexp_release (list
);
811 return NULL
; /* required parameter is invalid */
815 gcry_sexp_release (list
);
820 /* Check whether STRING is a KEYGRIP, i.e has the correct length and
821 does only consist of uppercase hex characters. */
823 is_keygrip (const char *string
)
827 for(i
=0; string
[i
] && i
< 41; i
++)
828 if (!strchr("01234567890ABCDEF", string
[i
]))
835 export_p12_file (const char *fname
)
838 gcry_mpi_t kparms
[9], *kp
;
842 struct rsa_secret_key_s sk
;
844 unsigned char *cert
= NULL
;
847 size_t keylen_for_wipe
= 0;
850 if ( is_keygrip (fname
) )
852 char hexgrip
[40+4+1];
855 assert (strlen(fname
) == 40);
856 strcpy (stpcpy (hexgrip
, fname
), ".key");
858 p
= make_filename (opt_homedir
, GNUPG_PRIVATE_KEYS_DIR
, hexgrip
, NULL
);
863 key
= read_key (fname
);
868 keytype
= agent_private_key_type (key
);
869 if (keytype
== PRIVATE_KEY_PROTECTED
)
871 unsigned char *tmpkey
;
874 rc
= agent_unprotect (key
, (pw
=get_passphrase (1)), &tmpkey
, &tmplen
);
875 release_passphrase (pw
);
878 log_error ("unprotecting key `%s' failed: %s\n",
879 fname
, gpg_strerror (rc
));
885 keylen_for_wipe
= tmplen
;
887 keytype
= agent_private_key_type (key
);
890 if (keytype
== PRIVATE_KEY_SHADOWED
)
892 log_error ("`%s' is a shadowed private key - can't export it\n", fname
);
893 wipememory (key
, keylen_for_wipe
);
897 else if (keytype
!= PRIVATE_KEY_CLEAR
)
899 log_error ("\%s' is not a private key\n", fname
);
900 wipememory (key
, keylen_for_wipe
);
908 cert
= read_file ("-", &certlen
);
911 wipememory (key
, keylen_for_wipe
);
918 if (gcry_sexp_new (&private, key
, 0, 0))
920 log_error ("gcry_sexp_new failed\n");
921 wipememory (key
, keylen_for_wipe
);
926 wipememory (key
, keylen_for_wipe
);
929 kp
= sexp_to_kparms (private);
930 gcry_sexp_release (private);
933 log_error ("error converting key parameters\n");
951 kparms
[5] = gcry_mpi_snew (0); /* compute d mod (p-1) */
952 gcry_mpi_sub_ui (kparms
[5], kparms
[3], 1);
953 gcry_mpi_mod (kparms
[5], sk
.d
, kparms
[5]);
954 kparms
[6] = gcry_mpi_snew (0); /* compute d mod (q-1) */
955 gcry_mpi_sub_ui (kparms
[6], kparms
[4], 1);
956 gcry_mpi_mod (kparms
[6], sk
.d
, kparms
[6]);
960 key
= p12_build (kparms
, cert
, certlen
, (pw
=get_passphrase (0)), &keylen
);
961 release_passphrase (pw
);
963 for (i
=0; i
< 8; i
++)
964 gcry_mpi_release (kparms
[i
]);
968 fwrite (key
, keylen
, 1, stdout
);
974 /* Do the percent and plus/space unescaping in place and return the
975 length of the valid buffer. */
977 percent_plus_unescape (unsigned char *string
)
979 unsigned char *p
= string
;
984 if (*string
== '%' && string
[1] && string
[2])
987 *p
++ = xtoi_2 (string
);
991 else if (*string
== '+')
1007 /* Remove percent and plus escaping and make sure that the reuslt is a
1008 string. This is done in place. Returns STRING. */
1010 percent_plus_unescape_string (char *string
)
1012 unsigned char *p
= string
;
1015 n
= percent_plus_unescape (p
);
1023 main (int argc
, char **argv
)
1025 ARGPARSE_ARGS pargs
;
1029 set_strusage (my_strusage
);
1030 gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN
);
1031 log_set_prefix ("gpg-protect-tool", 1);
1033 /* Try to auto set the character set. */
1034 set_native_charset (NULL
);
1038 if (!gcry_check_version (NEED_LIBGCRYPT_VERSION
) )
1040 log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
1041 NEED_LIBGCRYPT_VERSION
, gcry_check_version (NULL
) );
1044 gcry_set_log_handler (my_gcry_logger
, NULL
);
1046 gcry_control (GCRYCTL_INIT_SECMEM
, 16384, 0);
1050 opt_homedir
= read_w32_registry_string ( NULL
,
1051 "Software\\GNU\\GnuPG", "HomeDir" );
1053 opt_homedir
= getenv ("GNUPGHOME");
1055 if (!opt_homedir
|| !*opt_homedir
)
1056 opt_homedir
= GNUPG_DEFAULT_HOMEDIR
;
1061 pargs
.flags
= 1; /* (do not remove the args) */
1062 while (arg_parse (&pargs
, opts
) )
1064 switch (pargs
.r_opt
)
1066 case oVerbose
: opt
.verbose
++; break;
1067 case oArmor
: opt_armor
=1; break;
1068 case oHomedir
: opt_homedir
= pargs
.r
.ret_str
; break;
1070 case oProtect
: cmd
= oProtect
; break;
1071 case oUnprotect
: cmd
= oUnprotect
; break;
1072 case oShadow
: cmd
= oShadow
; break;
1073 case oShowShadowInfo
: cmd
= oShowShadowInfo
; break;
1074 case oShowKeygrip
: cmd
= oShowKeygrip
; break;
1075 case oP12Import
: cmd
= oP12Import
; break;
1076 case oP12Export
: cmd
= oP12Export
; break;
1078 case oPassphrase
: opt_passphrase
= pargs
.r
.ret_str
; break;
1079 case oStore
: opt_store
= 1; break;
1080 case oForce
: opt_force
= 1; break;
1081 case oNoFailOnExist
: opt_no_fail_on_exist
= 1; break;
1082 case oHaveCert
: opt_have_cert
= 1; break;
1083 case oPrompt
: opt_prompt
= pargs
.r
.ret_str
; break;
1084 case oStatusMsg
: opt_status_msg
= 1; break;
1086 default : pargs
.err
= 2; break;
1089 if (log_get_errorcount(0))
1099 opt_prompt
= percent_plus_unescape_string (xstrdup (opt_prompt
));
1101 if (cmd
== oProtect
)
1102 read_and_protect (fname
);
1103 else if (cmd
== oUnprotect
)
1104 read_and_unprotect (fname
);
1105 else if (cmd
== oShadow
)
1106 read_and_shadow (fname
);
1107 else if (cmd
== oShowShadowInfo
)
1108 show_shadow_info (fname
);
1109 else if (cmd
== oShowKeygrip
)
1110 show_keygrip (fname
);
1111 else if (cmd
== oP12Import
)
1112 import_p12_file (fname
);
1113 else if (cmd
== oP12Export
)
1114 export_p12_file (fname
);
1119 return 8; /*NOTREACHED*/
1125 rc
= rc
? rc
: log_get_errorcount(0)? 2 : 0;
1130 /* Return the passphrase string and ask the agent if it has not been
1131 set from the command line PROMPTNO select the prompt to display:
1133 1 = taken from the option --prompt
1136 get_passphrase (int promptno
)
1143 return xstrdup (opt_passphrase
);
1145 if (promptno
== 1 && opt_prompt
)
1148 desc
= _("Please enter the passphrase or the PIN\n"
1149 "needed to complete this operation.");
1151 pw
= simple_pwquery (NULL
,NULL
, _("Passphrase:"), desc
, &err
);
1155 log_error ("error while asking for the passphrase\n");
1157 log_info ("cancelled\n");
1165 release_passphrase (char *pw
)
1169 wipememory (pw
, strlen (pw
));
1175 store_private_key (const unsigned char *grip
,
1176 const void *buffer
, size_t length
, int force
)
1181 char hexgrip
[40+4+1];
1183 for (i
=0; i
< 20; i
++)
1184 sprintf (hexgrip
+2*i
, "%02X", grip
[i
]);
1185 strcpy (hexgrip
+40, ".key");
1187 fname
= make_filename (opt_homedir
, GNUPG_PRIVATE_KEYS_DIR
, hexgrip
, NULL
);
1189 fp
= fopen (fname
, "wb");
1192 if (!access (fname
, F_OK
))
1195 log_info ("[PROTECT-TOOL:] secretkey-exists\n");
1196 if (opt_no_fail_on_exist
)
1197 log_info ("secret key file `%s' already exists\n", fname
);
1199 log_error ("secret key file `%s' already exists\n", fname
);
1201 return opt_no_fail_on_exist
? 0 : -1;
1203 fp
= fopen (fname
, "wbx"); /* FIXME: the x is a GNU extension - let
1204 configure check whether this actually
1210 log_error ("can't create `%s': %s\n", fname
, strerror (errno
));
1215 if (fwrite (buffer
, length
, 1, fp
) != 1)
1217 log_error ("error writing `%s': %s\n", fname
, strerror (errno
));
1225 log_error ("error closing `%s': %s\n", fname
, strerror (errno
));
1230 log_info ("secret key stored as `%s'\n", fname
);
1233 log_info ("[PROTECT-TOOL:] secretkey-stored\n");