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
64 struct rsa_secret_key_s
66 gcry_mpi_t n
; /* public modulus */
67 gcry_mpi_t e
; /* public exponent */
68 gcry_mpi_t d
; /* exponent */
69 gcry_mpi_t p
; /* prime p. */
70 gcry_mpi_t q
; /* prime q. */
71 gcry_mpi_t u
; /* inverse of p mod q. */
75 static char *opt_homedir
;
79 static int opt_no_fail_on_exist
;
80 static int opt_have_cert
;
81 static const char *opt_passphrase
;
82 static char *opt_prompt
;
84 static char *get_passphrase (int promptno
);
85 static void release_passphrase (char *pw
);
86 static int store_private_key (const unsigned char *grip
,
87 const void *buffer
, size_t length
, int force
);
90 static ARGPARSE_OPTS opts
[] = {
92 { 301, NULL
, 0, N_("@Options:\n ") },
94 { oVerbose
, "verbose", 0, "verbose" },
95 { oArmor
, "armor", 0, "write output in advanced format" },
96 { oPassphrase
, "passphrase", 2, "|STRING|use passphrase STRING" },
97 { oProtect
, "protect", 256, "protect a private key"},
98 { oUnprotect
, "unprotect", 256, "unprotect a private key"},
99 { oShadow
, "shadow", 256, "create a shadow entry for a priblic key"},
100 { oShowShadowInfo
, "show-shadow-info", 256, "return the shadow info"},
101 { oShowKeygrip
, "show-keygrip", 256, "show the \"keygrip\""},
103 { oP12Import
, "p12-import", 256, "import a PKCS-12 encoded private key"},
104 { oP12Export
, "p12-export", 256, "export a private key PKCS-12 encoded"},
105 { oHaveCert
, "have-cert", 0, "certificate to export provided on STDIN"},
106 { oStore
, "store", 0, "store the created key in the appropriate place"},
107 { oForce
, "force", 0, "force overwriting"},
108 { oNoFailOnExist
, "no-fail-on-exist", 0, "@" },
109 { oHomedir
, "homedir", 2, "@" },
110 { oPrompt
, "prompt", 2, "|ESCSTRING|use ESCSTRING as prompt in pinentry"},
115 my_strusage (int level
)
120 case 11: p
= "gpg-protect-tool (GnuPG)";
122 case 13: p
= VERSION
; break;
123 case 17: p
= PRINTABLE_OS_NAME
; break;
124 case 19: p
= _("Please report bugs to <" PACKAGE_BUGREPORT
">.\n");
127 case 40: p
= _("Usage: gpg-protect-tool [options] (-h for help)\n");
129 case 41: p
= _("Syntax: gpg-protect-tool [options] [args]]\n"
130 "Secret key maintenance tool\n");
143 #ifdef USE_SIMPLE_GETTEXT
144 set_gettext_file( PACKAGE
);
147 setlocale (LC_ALL
, "");
148 bindtextdomain (PACKAGE
, LOCALEDIR
);
149 textdomain (PACKAGE
);
156 /* Used by gcry for logging */
158 my_gcry_logger (void *dummy
, int level
, const char *fmt
, va_list arg_ptr
)
160 /* translate the log levels */
163 case GCRY_LOG_CONT
: level
= JNLIB_LOG_CONT
; break;
164 case GCRY_LOG_INFO
: level
= JNLIB_LOG_INFO
; break;
165 case GCRY_LOG_WARN
: level
= JNLIB_LOG_WARN
; break;
166 case GCRY_LOG_ERROR
:level
= JNLIB_LOG_ERROR
; break;
167 case GCRY_LOG_FATAL
:level
= JNLIB_LOG_FATAL
; break;
168 case GCRY_LOG_BUG
: level
= JNLIB_LOG_BUG
; break;
169 case GCRY_LOG_DEBUG
:level
= JNLIB_LOG_DEBUG
; break;
170 default: level
= JNLIB_LOG_ERROR
; break; }
171 log_logv (level
, fmt
, arg_ptr
);
176 /* print_mpi (const char *text, gcry_mpi_t a) */
179 /* void *bufaddr = &buf; */
182 /* rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a); */
184 /* log_info ("%s: [error printing number: %s]\n", text, gpg_strerror (rc)); */
187 /* log_info ("%s: %s\n", text, buf); */
188 /* gcry_free (buf); */
194 static unsigned char *
195 make_canonical (const char *fname
, const char *buf
, size_t buflen
)
200 unsigned char *result
;
202 rc
= gcry_sexp_sscan (&sexp
, &erroff
, buf
, buflen
);
205 log_error ("invalid S-Expression in `%s' (off=%u): %s\n",
206 fname
, (unsigned int)erroff
, gpg_strerror (rc
));
209 len
= gcry_sexp_sprint (sexp
, GCRYSEXP_FMT_CANON
, NULL
, 0);
211 result
= xmalloc (len
);
212 len
= gcry_sexp_sprint (sexp
, GCRYSEXP_FMT_CANON
, result
, len
);
214 gcry_sexp_release (sexp
);
219 make_advanced (const unsigned char *buf
, size_t buflen
)
224 unsigned char *result
;
226 rc
= gcry_sexp_sscan (&sexp
, &erroff
, buf
, buflen
);
229 log_error ("invalid canonical S-Expression (off=%u): %s\n",
230 (unsigned int)erroff
, gpg_strerror (rc
));
233 len
= gcry_sexp_sprint (sexp
, GCRYSEXP_FMT_ADVANCED
, NULL
, 0);
235 result
= xmalloc (len
);
236 len
= gcry_sexp_sprint (sexp
, GCRYSEXP_FMT_ADVANCED
, result
, len
);
238 gcry_sexp_release (sexp
);
244 read_file (const char *fname
, size_t *r_length
)
250 if (!strcmp (fname
, "-"))
252 size_t nread
, bufsize
= 0;
262 buf
= xmalloc (bufsize
);
264 buf
= xrealloc (buf
, bufsize
);
266 nread
= fread (buf
+buflen
, 1, NCHUNK
, fp
);
267 if (nread
< NCHUNK
&& ferror (fp
))
269 log_error ("error reading `[stdin]': %s\n", strerror (errno
));
275 while (nread
== NCHUNK
);
283 fp
= fopen (fname
, "rb");
286 log_error ("can't open `%s': %s\n", fname
, strerror (errno
));
290 if (fstat (fileno(fp
), &st
))
292 log_error ("can't stat `%s': %s\n", fname
, strerror (errno
));
298 buf
= xmalloc (buflen
+1);
299 if (fread (buf
, buflen
, 1, fp
) != 1)
301 log_error ("error reading `%s': %s\n", fname
, strerror (errno
));
314 static unsigned char *
315 read_key (const char *fname
)
321 buf
= read_file (fname
, &buflen
);
324 key
= make_canonical (fname
, buf
, buflen
);
332 read_and_protect (const char *fname
)
336 unsigned char *result
;
340 key
= read_key (fname
);
344 pw
= get_passphrase (1);
345 rc
= agent_protect (key
, pw
, &result
, &resultlen
);
346 release_passphrase (pw
);
350 log_error ("protecting the key failed: %s\n", gpg_strerror (rc
));
356 char *p
= make_advanced (result
, resultlen
);
361 resultlen
= strlen (p
);
364 fwrite (result
, resultlen
, 1, stdout
);
370 read_and_unprotect (const char *fname
)
374 unsigned char *result
;
378 key
= read_key (fname
);
382 rc
= agent_unprotect (key
, (pw
=get_passphrase (1)), &result
, &resultlen
);
383 release_passphrase (pw
);
387 log_error ("unprotecting the key failed: %s\n", gpg_strerror (rc
));
393 char *p
= make_advanced (result
, resultlen
);
398 resultlen
= strlen (p
);
401 fwrite (result
, resultlen
, 1, stdout
);
408 read_and_shadow (const char *fname
)
412 unsigned char *result
;
415 key
= read_key (fname
);
419 rc
= agent_shadow_key (key
, "(8:313233342:43)", &result
);
423 log_error ("shadowing the key failed: %s\n", gpg_strerror (rc
));
426 resultlen
= gcry_sexp_canon_len (result
, 0, NULL
,NULL
);
431 char *p
= make_advanced (result
, resultlen
);
436 resultlen
= strlen (p
);
439 fwrite (result
, resultlen
, 1, stdout
);
444 show_shadow_info (const char *fname
)
448 const unsigned char *info
;
451 key
= read_key (fname
);
455 rc
= agent_get_shadow_info (key
, &info
);
459 log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc
));
462 infolen
= gcry_sexp_canon_len (info
, 0, NULL
,NULL
);
467 char *p
= make_advanced (info
, infolen
);
470 fwrite (p
, strlen (p
), 1, stdout
);
474 fwrite (info
, infolen
, 1, stdout
);
479 show_file (const char *fname
)
485 key
= read_key (fname
);
489 keylen
= gcry_sexp_canon_len (key
, 0, NULL
,NULL
);
492 p
= make_advanced (key
, keylen
);
496 fwrite (p
, strlen (p
), 1, stdout
);
502 show_keygrip (const char *fname
)
506 unsigned char grip
[20];
509 key
= read_key (fname
);
513 if (gcry_sexp_new (&private, key
, 0, 0))
515 log_error ("gcry_sexp_new failed\n");
520 if (!gcry_pk_get_keygrip (private, grip
))
522 log_error ("can't calculate keygrip\n");
525 gcry_sexp_release (private);
527 for (i
=0; i
< 20; i
++)
528 printf ("%02X", grip
[i
]);
534 rsa_key_check (struct rsa_secret_key_s
*skey
)
537 gcry_mpi_t t
= gcry_mpi_snew (0);
538 gcry_mpi_t t1
= gcry_mpi_snew (0);
539 gcry_mpi_t t2
= gcry_mpi_snew (0);
540 gcry_mpi_t phi
= gcry_mpi_snew (0);
542 /* check that n == p * q */
543 gcry_mpi_mul (t
, skey
->p
, skey
->q
);
544 if (gcry_mpi_cmp( t
, skey
->n
) )
546 log_error ("RSA oops: n != p * q\n");
550 /* check that p is less than q */
551 if (gcry_mpi_cmp (skey
->p
, skey
->q
) > 0)
555 log_info ("swapping secret primes\n");
556 tmp
= gcry_mpi_copy (skey
->p
);
557 gcry_mpi_set (skey
->p
, skey
->q
);
558 gcry_mpi_set (skey
->q
, tmp
);
559 gcry_mpi_release (tmp
);
560 /* and must recompute u of course */
561 gcry_mpi_invm (skey
->u
, skey
->p
, skey
->q
);
564 /* check that e divides neither p-1 nor q-1 */
565 gcry_mpi_sub_ui (t
, skey
->p
, 1 );
566 gcry_mpi_div (NULL
, t
, t
, skey
->e
, 0);
567 if (!gcry_mpi_cmp_ui( t
, 0) )
569 log_error ("RSA oops: e divides p-1\n");
572 gcry_mpi_sub_ui (t
, skey
->q
, 1);
573 gcry_mpi_div (NULL
, t
, t
, skey
->e
, 0);
574 if (!gcry_mpi_cmp_ui( t
, 0))
576 log_info ( "RSA oops: e divides q-1\n" );
580 /* check that d is correct. */
581 gcry_mpi_sub_ui (t1
, skey
->p
, 1);
582 gcry_mpi_sub_ui (t2
, skey
->q
, 1);
583 gcry_mpi_mul (phi
, t1
, t2
);
584 gcry_mpi_invm (t
, skey
->e
, phi
);
585 if (gcry_mpi_cmp (t
, skey
->d
))
586 { /* no: try universal exponent. */
587 gcry_mpi_gcd (t
, t1
, t2
);
588 gcry_mpi_div (t
, NULL
, phi
, t
, 0);
589 gcry_mpi_invm (t
, skey
->e
, t
);
590 if (gcry_mpi_cmp (t
, skey
->d
))
592 log_error ("RSA oops: bad secret exponent\n");
597 /* check for correctness of u */
598 gcry_mpi_invm (t
, skey
->p
, skey
->q
);
599 if (gcry_mpi_cmp (t
, skey
->u
))
601 log_info ( "RSA oops: bad u parameter\n");
606 log_info ("RSA secret key check failed\n");
608 gcry_mpi_release (t
);
609 gcry_mpi_release (t1
);
610 gcry_mpi_release (t2
);
611 gcry_mpi_release (phi
);
617 /* A callback used by p12_parse to return a certificate. */
619 import_p12_cert_cb (void *opaque
, const unsigned char *cert
, size_t certlen
)
621 struct b64state state
;
622 gpg_error_t err
, err2
;
624 err
= b64enc_start (&state
, stdout
, "CERTIFICATE");
626 err
= b64enc_write (&state
, cert
, certlen
);
627 err2
= b64enc_finish (&state
);
631 log_error ("error writing armored certificate: %s\n", gpg_strerror (err
));
635 import_p12_file (const char *fname
)
638 unsigned char *result
;
639 size_t buflen
, resultlen
;
643 struct rsa_secret_key_s sk
;
646 unsigned char grip
[20];
649 /* fixme: we should release some stuff on error */
651 buf
= read_file (fname
, &buflen
);
655 kparms
= p12_parse (buf
, buflen
, (pw
=get_passphrase (0)),
656 import_p12_cert_cb
, NULL
);
657 release_passphrase (pw
);
661 log_error ("error parsing or decrypting the PKCS-12 file\n");
664 for (i
=0; kparms
[i
]; i
++)
668 log_error ("invalid structure of private key\n");
673 /* print_mpi (" n", kparms[0]); */
674 /* print_mpi (" e", kparms[1]); */
675 /* print_mpi (" d", kparms[2]); */
676 /* print_mpi (" p", kparms[3]); */
677 /* print_mpi (" q", kparms[4]); */
678 /* print_mpi ("dmp1", kparms[5]); */
679 /* print_mpi ("dmq1", kparms[6]); */
680 /* print_mpi (" u", kparms[7]); */
688 if (rsa_key_check (&sk
))
690 /* print_mpi (" n", sk.n); */
691 /* print_mpi (" e", sk.e); */
692 /* print_mpi (" d", sk.d); */
693 /* print_mpi (" p", sk.p); */
694 /* print_mpi (" q", sk.q); */
695 /* print_mpi (" u", sk.u); */
697 /* Create an S-expresion from the parameters. */
698 rc
= gcry_sexp_build (&s_key
, NULL
,
699 "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
700 sk
.n
, sk
.e
, sk
.d
, sk
.p
, sk
.q
, sk
.u
, NULL
);
701 for (i
=0; i
< 8; i
++)
702 gcry_mpi_release (kparms
[i
]);
706 log_error ("failed to created S-expression from key: %s\n",
711 /* Compute the keygrip. */
712 if (!gcry_pk_get_keygrip (s_key
, grip
))
714 log_error ("can't calculate keygrip\n");
717 log_info ("keygrip: ");
718 for (i
=0; i
< 20; i
++)
719 log_printf ("%02X", grip
[i
]);
722 /* Convert to canonical encoding. */
723 buflen
= gcry_sexp_sprint (s_key
, GCRYSEXP_FMT_CANON
, NULL
, 0);
725 key
= gcry_xmalloc_secure (buflen
);
726 buflen
= gcry_sexp_sprint (s_key
, GCRYSEXP_FMT_CANON
, key
, buflen
);
728 gcry_sexp_release (s_key
);
731 rc
= agent_protect (key
, (pw
=get_passphrase (0)), &result
, &resultlen
);
732 release_passphrase (pw
);
736 log_error ("protecting the key failed: %s\n", gpg_strerror (rc
));
742 char *p
= make_advanced (result
, resultlen
);
747 resultlen
= strlen (p
);
751 store_private_key (grip
, result
, resultlen
, opt_force
);
753 fwrite (result
, resultlen
, 1, stdout
);
761 sexp_to_kparms (gcry_sexp_t sexp
)
763 gcry_sexp_t list
, l2
;
771 list
= gcry_sexp_find_token (sexp
, "private-key", 0 );
774 l2
= gcry_sexp_cadr (list
);
775 gcry_sexp_release (list
);
777 name
= gcry_sexp_nth_data (list
, 0, &n
);
778 if(!name
|| n
!= 3 || memcmp (name
, "rsa", 3))
780 gcry_sexp_release (list
);
784 /* Parameter names used with RSA. */
786 array
= xcalloc (strlen(elems
) + 1, sizeof *array
);
787 for (idx
=0, s
=elems
; *s
; s
++, idx
++ )
789 l2
= gcry_sexp_find_token (list
, s
, 1);
792 for (i
=0; i
<idx
; i
++)
793 gcry_mpi_release (array
[i
]);
795 gcry_sexp_release (list
);
796 return NULL
; /* required parameter not found */
798 array
[idx
] = gcry_sexp_nth_mpi (l2
, 1, GCRYMPI_FMT_USG
);
799 gcry_sexp_release (l2
);
802 for (i
=0; i
<idx
; i
++)
803 gcry_mpi_release (array
[i
]);
805 gcry_sexp_release (list
);
806 return NULL
; /* required parameter is invalid */
810 gcry_sexp_release (list
);
815 /* Check whether STRING is a KEYGRIP, i.e has the correct length and
816 does only consist of uppercase hex characters. */
818 is_keygrip (const char *string
)
822 for(i
=0; string
[i
] && i
< 41; i
++)
823 if (!strchr("01234567890ABCDEF", string
[i
]))
830 export_p12_file (const char *fname
)
833 gcry_mpi_t kparms
[9], *kp
;
837 struct rsa_secret_key_s sk
;
839 unsigned char *cert
= NULL
;
842 size_t keylen_for_wipe
= 0;
845 if ( is_keygrip (fname
) )
847 char hexgrip
[40+4+1];
850 assert (strlen(fname
) == 40);
851 strcpy (stpcpy (hexgrip
, fname
), ".key");
853 p
= make_filename (opt_homedir
, GNUPG_PRIVATE_KEYS_DIR
, hexgrip
, NULL
);
858 key
= read_key (fname
);
863 keytype
= agent_private_key_type (key
);
864 if (keytype
== PRIVATE_KEY_PROTECTED
)
866 unsigned char *tmpkey
;
869 rc
= agent_unprotect (key
, (pw
=get_passphrase (1)), &tmpkey
, &tmplen
);
870 release_passphrase (pw
);
873 log_error ("unprotecting key `%s' failed: %s\n",
874 fname
, gpg_strerror (rc
));
880 keylen_for_wipe
= tmplen
;
882 keytype
= agent_private_key_type (key
);
885 if (keytype
== PRIVATE_KEY_SHADOWED
)
887 log_error ("`%s' is a shadowed private key - can't export it\n", fname
);
888 wipememory (key
, keylen_for_wipe
);
892 else if (keytype
!= PRIVATE_KEY_CLEAR
)
894 log_error ("\%s' is not a private key\n", fname
);
895 wipememory (key
, keylen_for_wipe
);
903 cert
= read_file ("-", &certlen
);
906 wipememory (key
, keylen_for_wipe
);
913 if (gcry_sexp_new (&private, key
, 0, 0))
915 log_error ("gcry_sexp_new failed\n");
916 wipememory (key
, keylen_for_wipe
);
921 wipememory (key
, keylen_for_wipe
);
924 kp
= sexp_to_kparms (private);
925 gcry_sexp_release (private);
928 log_error ("error converting key parameters\n");
946 kparms
[5] = gcry_mpi_snew (0); /* compute d mod (p-1) */
947 gcry_mpi_sub_ui (kparms
[5], kparms
[3], 1);
948 gcry_mpi_mod (kparms
[5], sk
.d
, kparms
[5]);
949 kparms
[6] = gcry_mpi_snew (0); /* compute d mod (q-1) */
950 gcry_mpi_sub_ui (kparms
[6], kparms
[4], 1);
951 gcry_mpi_mod (kparms
[6], sk
.d
, kparms
[6]);
955 key
= p12_build (kparms
, cert
, certlen
, (pw
=get_passphrase (0)), &keylen
);
956 release_passphrase (pw
);
958 for (i
=0; i
< 8; i
++)
959 gcry_mpi_release (kparms
[i
]);
963 fwrite (key
, keylen
, 1, stdout
);
969 /* Do the percent and plus/space unescaping in place and return the
970 length of the valid buffer. */
972 percent_plus_unescape (unsigned char *string
)
974 unsigned char *p
= string
;
979 if (*string
== '%' && string
[1] && string
[2])
982 *p
++ = xtoi_2 (string
);
986 else if (*string
== '+')
1002 /* Remove percent and plus escaping and make sure that the reuslt is a
1003 string. This is done in place. Returns STRING. */
1005 percent_plus_unescape_string (char *string
)
1007 unsigned char *p
= string
;
1010 n
= percent_plus_unescape (p
);
1018 main (int argc
, char **argv
)
1020 ARGPARSE_ARGS pargs
;
1024 set_strusage (my_strusage
);
1025 gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN
);
1026 log_set_prefix ("gpg-protect-tool", 1);
1028 /* Try to auto set the character set. */
1029 set_native_charset (NULL
);
1033 if (!gcry_check_version (NEED_LIBGCRYPT_VERSION
) )
1035 log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
1036 NEED_LIBGCRYPT_VERSION
, gcry_check_version (NULL
) );
1039 gcry_set_log_handler (my_gcry_logger
, NULL
);
1041 gcry_control (GCRYCTL_INIT_SECMEM
, 16384, 0);
1045 opt_homedir
= read_w32_registry_string ( NULL
,
1046 "Software\\GNU\\GnuPG", "HomeDir" );
1048 opt_homedir
= getenv ("GNUPGHOME");
1050 if (!opt_homedir
|| !*opt_homedir
)
1051 opt_homedir
= GNUPG_DEFAULT_HOMEDIR
;
1056 pargs
.flags
= 1; /* (do not remove the args) */
1057 while (arg_parse (&pargs
, opts
) )
1059 switch (pargs
.r_opt
)
1061 case oVerbose
: opt
.verbose
++; break;
1062 case oArmor
: opt_armor
=1; break;
1063 case oHomedir
: opt_homedir
= pargs
.r
.ret_str
; break;
1065 case oProtect
: cmd
= oProtect
; break;
1066 case oUnprotect
: cmd
= oUnprotect
; break;
1067 case oShadow
: cmd
= oShadow
; break;
1068 case oShowShadowInfo
: cmd
= oShowShadowInfo
; break;
1069 case oShowKeygrip
: cmd
= oShowKeygrip
; break;
1070 case oP12Import
: cmd
= oP12Import
; break;
1071 case oP12Export
: cmd
= oP12Export
; break;
1073 case oPassphrase
: opt_passphrase
= pargs
.r
.ret_str
; break;
1074 case oStore
: opt_store
= 1; break;
1075 case oForce
: opt_force
= 1; break;
1076 case oNoFailOnExist
: opt_no_fail_on_exist
= 1; break;
1077 case oHaveCert
: opt_have_cert
= 1; break;
1078 case oPrompt
: opt_prompt
= pargs
.r
.ret_str
; break;
1080 default : pargs
.err
= 2; break;
1083 if (log_get_errorcount(0))
1093 opt_prompt
= percent_plus_unescape_string (xstrdup (opt_prompt
));
1095 if (cmd
== oProtect
)
1096 read_and_protect (fname
);
1097 else if (cmd
== oUnprotect
)
1098 read_and_unprotect (fname
);
1099 else if (cmd
== oShadow
)
1100 read_and_shadow (fname
);
1101 else if (cmd
== oShowShadowInfo
)
1102 show_shadow_info (fname
);
1103 else if (cmd
== oShowKeygrip
)
1104 show_keygrip (fname
);
1105 else if (cmd
== oP12Import
)
1106 import_p12_file (fname
);
1107 else if (cmd
== oP12Export
)
1108 export_p12_file (fname
);
1113 return 8; /*NOTREACHED*/
1119 rc
= rc
? rc
: log_get_errorcount(0)? 2 : 0;
1124 /* Return the passphrase string and ask the agent if it has not been
1125 set from the command line PROMPTNO select the prompt to display:
1127 1 = taken from the option --prompt
1130 get_passphrase (int promptno
)
1137 return xstrdup (opt_passphrase
);
1139 if (promptno
== 1 && opt_prompt
)
1142 desc
= _("Please enter the passphrase or the PIN\n"
1143 "needed to complete this operation.");
1145 pw
= simple_pwquery (NULL
,NULL
, _("Passphrase:"), desc
, &err
);
1149 log_error ("error while asking for the passphrase\n");
1151 log_info ("cancelled\n");
1159 release_passphrase (char *pw
)
1163 wipememory (pw
, strlen (pw
));
1169 store_private_key (const unsigned char *grip
,
1170 const void *buffer
, size_t length
, int force
)
1175 char hexgrip
[40+4+1];
1177 for (i
=0; i
< 20; i
++)
1178 sprintf (hexgrip
+2*i
, "%02X", grip
[i
]);
1179 strcpy (hexgrip
+40, ".key");
1181 fname
= make_filename (opt_homedir
, GNUPG_PRIVATE_KEYS_DIR
, hexgrip
, NULL
);
1183 fp
= fopen (fname
, "wb");
1186 if (!access (fname
, F_OK
))
1188 if (opt_no_fail_on_exist
)
1189 log_info ("secret key file `%s' already exists\n", fname
);
1191 log_error ("secret key file `%s' already exists\n", fname
);
1193 return opt_no_fail_on_exist
? 0 : -1;
1195 fp
= fopen (fname
, "wbx"); /* FIXME: the x is a GNU extension - let
1196 configure check whether this actually
1202 log_error ("can't create `%s': %s\n", fname
, strerror (errno
));
1207 if (fwrite (buffer
, length
, 1, fp
) != 1)
1209 log_error ("error writing `%s': %s\n", fname
, strerror (errno
));
1217 log_error ("error closing `%s': %s\n", fname
, strerror (errno
));
1222 log_info ("secret key stored as `%s'\n", fname
);