1 /* protect-tool.c - A tool to test the secret key protection
2 * Copyright (C) 2002, 2003, 2004, 2006 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 3 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, see <http://www.gnu.org/licenses/>.
34 #ifdef HAVE_LANGINFO_CODESET
37 #ifdef HAVE_DOSISH_SYSTEM
38 #include <fcntl.h> /* for setmode() */
41 #define JNLIB_NEED_LOG_LOGV
45 #include "get-passphrase.h"
49 enum cmd_and_opt_values
80 struct rsa_secret_key_s
82 gcry_mpi_t n
; /* public modulus */
83 gcry_mpi_t e
; /* public exponent */
84 gcry_mpi_t d
; /* exponent */
85 gcry_mpi_t p
; /* prime p. */
86 gcry_mpi_t q
; /* prime q. */
87 gcry_mpi_t u
; /* inverse of p mod q. */
91 static const char *opt_homedir
;
93 static int opt_canonical
;
96 static int opt_no_fail_on_exist
;
97 static int opt_have_cert
;
98 static const char *opt_passphrase
;
99 static char *opt_prompt
;
100 static int opt_status_msg
;
101 static const char *opt_p12_charset
;
102 static const char *opt_agent_program
;
104 static char *get_passphrase (int promptno
);
105 static void release_passphrase (char *pw
);
106 static int store_private_key (const unsigned char *grip
,
107 const void *buffer
, size_t length
, int force
);
110 static ARGPARSE_OPTS opts
[] = {
111 ARGPARSE_group (300, N_("@Commands:\n ")),
113 ARGPARSE_c (oProtect
, "protect", "protect a private key"),
114 ARGPARSE_c (oUnprotect
, "unprotect", "unprotect a private key"),
115 ARGPARSE_c (oShadow
, "shadow", "create a shadow entry for a public key"),
116 ARGPARSE_c (oShowShadowInfo
, "show-shadow-info", "return the shadow info"),
117 ARGPARSE_c (oShowKeygrip
, "show-keygrip", "show the \"keygrip\""),
118 ARGPARSE_c (oP12Import
, "p12-import",
119 "import a pkcs#12 encoded private key"),
120 ARGPARSE_c (oP12Export
, "p12-export",
121 "export a private key pkcs#12 encoded"),
123 ARGPARSE_group (301, N_("@\nOptions:\n ")),
125 ARGPARSE_s_n (oVerbose
, "verbose", "verbose"),
126 ARGPARSE_s_n (oArmor
, "armor", "write output in advanced format"),
127 ARGPARSE_s_n (oCanonical
, "canonical", "write output in canonical format"),
129 ARGPARSE_s_s (oPassphrase
, "passphrase", "|STRING|use passphrase STRING"),
130 ARGPARSE_s_s (oP12Charset
,"p12-charset",
131 "|NAME|set charset for a new PKCS#12 passphrase to NAME"),
132 ARGPARSE_s_n (oHaveCert
, "have-cert",
133 "certificate to export provided on STDIN"),
134 ARGPARSE_s_n (oStore
, "store",
135 "store the created key in the appropriate place"),
136 ARGPARSE_s_n (oForce
, "force",
137 "force overwriting"),
138 ARGPARSE_s_n (oNoFailOnExist
, "no-fail-on-exist", "@"),
139 ARGPARSE_s_s (oHomedir
, "homedir", "@"),
140 ARGPARSE_s_s (oPrompt
, "prompt",
141 "|ESCSTRING|use ESCSTRING as prompt in pinentry"),
142 ARGPARSE_s_n (oStatusMsg
, "enable-status-msg", "@"),
144 ARGPARSE_s_s (oAgentProgram
, "agent-program", "@"),
150 my_strusage (int level
)
155 case 11: p
= "gpg-protect-tool (GnuPG)";
157 case 13: p
= VERSION
; break;
158 case 17: p
= PRINTABLE_OS_NAME
; break;
159 case 19: p
= _("Please report bugs to <" PACKAGE_BUGREPORT
">.\n");
162 case 40: p
= _("Usage: gpg-protect-tool [options] (-h for help)\n");
164 case 41: p
= _("Syntax: gpg-protect-tool [options] [args]\n"
165 "Secret key maintenance tool\n");
175 /* print_mpi (const char *text, gcry_mpi_t a) */
178 /* void *bufaddr = &buf; */
181 /* rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a); */
183 /* log_info ("%s: [error printing number: %s]\n", text, gpg_strerror (rc)); */
186 /* log_info ("%s: %s\n", text, buf); */
187 /* gcry_free (buf); */
193 static unsigned char *
194 make_canonical (const char *fname
, const char *buf
, size_t buflen
)
199 unsigned char *result
;
201 rc
= gcry_sexp_sscan (&sexp
, &erroff
, buf
, buflen
);
204 log_error ("invalid S-Expression in `%s' (off=%u): %s\n",
205 fname
, (unsigned int)erroff
, gpg_strerror (rc
));
208 len
= gcry_sexp_sprint (sexp
, GCRYSEXP_FMT_CANON
, NULL
, 0);
210 result
= xmalloc (len
);
211 len
= gcry_sexp_sprint (sexp
, GCRYSEXP_FMT_CANON
, result
, len
);
213 gcry_sexp_release (sexp
);
218 make_advanced (const unsigned char *buf
, size_t buflen
)
225 rc
= gcry_sexp_sscan (&sexp
, &erroff
, (const char*)buf
, buflen
);
228 log_error ("invalid canonical S-Expression (off=%u): %s\n",
229 (unsigned int)erroff
, gpg_strerror (rc
));
232 len
= gcry_sexp_sprint (sexp
, GCRYSEXP_FMT_ADVANCED
, NULL
, 0);
234 result
= xmalloc (len
);
235 len
= gcry_sexp_sprint (sexp
, GCRYSEXP_FMT_ADVANCED
, result
, len
);
237 gcry_sexp_release (sexp
);
243 read_file (const char *fname
, size_t *r_length
)
249 if (!strcmp (fname
, "-"))
251 size_t nread
, bufsize
= 0;
254 #ifdef HAVE_DOSISH_SYSTEM
255 setmode ( fileno(fp
) , O_BINARY
);
264 buf
= xmalloc (bufsize
);
266 buf
= xrealloc (buf
, bufsize
);
268 nread
= fread (buf
+buflen
, 1, NCHUNK
, fp
);
269 if (nread
< NCHUNK
&& ferror (fp
))
271 log_error ("error reading `[stdin]': %s\n", strerror (errno
));
277 while (nread
== NCHUNK
);
285 fp
= fopen (fname
, "rb");
288 log_error ("can't open `%s': %s\n", fname
, strerror (errno
));
292 if (fstat (fileno(fp
), &st
))
294 log_error ("can't stat `%s': %s\n", fname
, strerror (errno
));
300 buf
= xmalloc (buflen
+1);
301 if (fread (buf
, buflen
, 1, fp
) != 1)
303 log_error ("error reading `%s': %s\n", fname
, strerror (errno
));
316 static unsigned char *
317 read_key (const char *fname
)
323 buf
= read_file (fname
, &buflen
);
326 key
= make_canonical (fname
, buf
, buflen
);
334 read_and_protect (const char *fname
)
338 unsigned char *result
;
342 key
= read_key (fname
);
346 pw
= get_passphrase (1);
347 rc
= agent_protect (key
, pw
, &result
, &resultlen
);
348 release_passphrase (pw
);
352 log_error ("protecting the key failed: %s\n", gpg_strerror (rc
));
358 char *p
= make_advanced (result
, resultlen
);
362 result
= (unsigned char*)p
;
363 resultlen
= strlen (p
);
366 fwrite (result
, resultlen
, 1, stdout
);
372 read_and_unprotect (const char *fname
)
376 unsigned char *result
;
379 gnupg_isotime_t protected_at
;
381 key
= read_key (fname
);
385 rc
= agent_unprotect (key
, (pw
=get_passphrase (1)),
386 protected_at
, &result
, &resultlen
);
387 release_passphrase (pw
);
392 log_info ("[PROTECT-TOOL:] bad-passphrase\n");
393 log_error ("unprotecting the key failed: %s\n", gpg_strerror (rc
));
397 log_info ("key protection done at %.4s-%.2s-%.2s %.2s:%.2s:%s\n",
398 protected_at
, protected_at
+4, protected_at
+6,
399 protected_at
+9, protected_at
+11, protected_at
+13);
404 char *p
= make_advanced (result
, resultlen
);
408 result
= (unsigned char*)p
;
409 resultlen
= strlen (p
);
412 fwrite (result
, resultlen
, 1, stdout
);
419 read_and_shadow (const char *fname
)
423 unsigned char *result
;
425 unsigned char dummy_info
[] = "(8:313233342:43)";
427 key
= read_key (fname
);
431 rc
= agent_shadow_key (key
, dummy_info
, &result
);
435 log_error ("shadowing the key failed: %s\n", gpg_strerror (rc
));
438 resultlen
= gcry_sexp_canon_len (result
, 0, NULL
,NULL
);
443 char *p
= make_advanced (result
, resultlen
);
447 result
= (unsigned char*)p
;
448 resultlen
= strlen (p
);
451 fwrite (result
, resultlen
, 1, stdout
);
456 show_shadow_info (const char *fname
)
460 const unsigned char *info
;
463 key
= read_key (fname
);
467 rc
= agent_get_shadow_info (key
, &info
);
471 log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc
));
474 infolen
= gcry_sexp_canon_len (info
, 0, NULL
,NULL
);
479 char *p
= make_advanced (info
, infolen
);
482 fwrite (p
, strlen (p
), 1, stdout
);
486 fwrite (info
, infolen
, 1, stdout
);
491 show_file (const char *fname
)
497 key
= read_key (fname
);
501 keylen
= gcry_sexp_canon_len (key
, 0, NULL
,NULL
);
506 fwrite (key
, keylen
, 1, stdout
);
510 p
= make_advanced (key
, keylen
);
513 fwrite (p
, strlen (p
), 1, stdout
);
521 show_keygrip (const char *fname
)
525 unsigned char grip
[20];
528 key
= read_key (fname
);
532 if (gcry_sexp_new (&private, key
, 0, 0))
534 log_error ("gcry_sexp_new failed\n");
539 if (!gcry_pk_get_keygrip (private, grip
))
541 log_error ("can't calculate keygrip\n");
544 gcry_sexp_release (private);
546 for (i
=0; i
< 20; i
++)
547 printf ("%02X", grip
[i
]);
553 rsa_key_check (struct rsa_secret_key_s
*skey
)
556 gcry_mpi_t t
= gcry_mpi_snew (0);
557 gcry_mpi_t t1
= gcry_mpi_snew (0);
558 gcry_mpi_t t2
= gcry_mpi_snew (0);
559 gcry_mpi_t phi
= gcry_mpi_snew (0);
561 /* check that n == p * q */
562 gcry_mpi_mul (t
, skey
->p
, skey
->q
);
563 if (gcry_mpi_cmp( t
, skey
->n
) )
565 log_error ("RSA oops: n != p * q\n");
569 /* check that p is less than q */
570 if (gcry_mpi_cmp (skey
->p
, skey
->q
) > 0)
574 log_info ("swapping secret primes\n");
575 tmp
= gcry_mpi_copy (skey
->p
);
576 gcry_mpi_set (skey
->p
, skey
->q
);
577 gcry_mpi_set (skey
->q
, tmp
);
578 gcry_mpi_release (tmp
);
579 /* and must recompute u of course */
580 gcry_mpi_invm (skey
->u
, skey
->p
, skey
->q
);
583 /* check that e divides neither p-1 nor q-1 */
584 gcry_mpi_sub_ui (t
, skey
->p
, 1 );
585 gcry_mpi_div (NULL
, t
, t
, skey
->e
, 0);
586 if (!gcry_mpi_cmp_ui( t
, 0) )
588 log_error ("RSA oops: e divides p-1\n");
591 gcry_mpi_sub_ui (t
, skey
->q
, 1);
592 gcry_mpi_div (NULL
, t
, t
, skey
->e
, 0);
593 if (!gcry_mpi_cmp_ui( t
, 0))
595 log_info ( "RSA oops: e divides q-1\n" );
599 /* check that d is correct. */
600 gcry_mpi_sub_ui (t1
, skey
->p
, 1);
601 gcry_mpi_sub_ui (t2
, skey
->q
, 1);
602 gcry_mpi_mul (phi
, t1
, t2
);
603 gcry_mpi_invm (t
, skey
->e
, phi
);
604 if (gcry_mpi_cmp (t
, skey
->d
))
605 { /* no: try universal exponent. */
606 gcry_mpi_gcd (t
, t1
, t2
);
607 gcry_mpi_div (t
, NULL
, phi
, t
, 0);
608 gcry_mpi_invm (t
, skey
->e
, t
);
609 if (gcry_mpi_cmp (t
, skey
->d
))
611 log_error ("RSA oops: bad secret exponent\n");
616 /* check for correctness of u */
617 gcry_mpi_invm (t
, skey
->p
, skey
->q
);
618 if (gcry_mpi_cmp (t
, skey
->u
))
620 log_info ( "RSA oops: bad u parameter\n");
625 log_info ("RSA secret key check failed\n");
627 gcry_mpi_release (t
);
628 gcry_mpi_release (t1
);
629 gcry_mpi_release (t2
);
630 gcry_mpi_release (phi
);
636 /* A callback used by p12_parse to return a certificate. */
638 import_p12_cert_cb (void *opaque
, const unsigned char *cert
, size_t certlen
)
640 struct b64state state
;
641 gpg_error_t err
, err2
;
645 err
= b64enc_start (&state
, stdout
, "CERTIFICATE");
647 err
= b64enc_write (&state
, cert
, certlen
);
648 err2
= b64enc_finish (&state
);
652 log_error ("error writing armored certificate: %s\n", gpg_strerror (err
));
656 import_p12_file (const char *fname
)
659 unsigned char *result
;
660 size_t buflen
, resultlen
, buf_off
;
664 struct rsa_secret_key_s sk
;
667 unsigned char grip
[20];
670 /* fixme: we should release some stuff on error */
672 buf
= read_file (fname
, &buflen
);
676 /* GnuPG 2.0.4 accidently created binary P12 files with the string
677 "The passphrase is %s encoded.\n\n" prepended to the ASN.1 data.
679 if (buflen
> 29 && !memcmp (buf
, "The passphrase is ", 18))
681 for (buf_off
=18; buf_off
< buflen
&& buf
[buf_off
] != '\n'; buf_off
++)
684 if (buf_off
< buflen
&& buf
[buf_off
] == '\n')
690 kparms
= p12_parse ((unsigned char*)buf
+buf_off
, buflen
-buf_off
,
691 (pw
=get_passphrase (2)),
692 import_p12_cert_cb
, NULL
);
693 release_passphrase (pw
);
697 log_error ("error parsing or decrypting the PKCS-12 file\n");
700 for (i
=0; kparms
[i
]; i
++)
704 log_error ("invalid structure of private key\n");
709 /* print_mpi (" n", kparms[0]); */
710 /* print_mpi (" e", kparms[1]); */
711 /* print_mpi (" d", kparms[2]); */
712 /* print_mpi (" p", kparms[3]); */
713 /* print_mpi (" q", kparms[4]); */
714 /* print_mpi ("dmp1", kparms[5]); */
715 /* print_mpi ("dmq1", kparms[6]); */
716 /* print_mpi (" u", kparms[7]); */
724 if (rsa_key_check (&sk
))
726 /* print_mpi (" n", sk.n); */
727 /* print_mpi (" e", sk.e); */
728 /* print_mpi (" d", sk.d); */
729 /* print_mpi (" p", sk.p); */
730 /* print_mpi (" q", sk.q); */
731 /* print_mpi (" u", sk.u); */
733 /* Create an S-expresion from the parameters. */
734 rc
= gcry_sexp_build (&s_key
, NULL
,
735 "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
736 sk
.n
, sk
.e
, sk
.d
, sk
.p
, sk
.q
, sk
.u
, NULL
);
737 for (i
=0; i
< 8; i
++)
738 gcry_mpi_release (kparms
[i
]);
742 log_error ("failed to created S-expression from key: %s\n",
747 /* Compute the keygrip. */
748 if (!gcry_pk_get_keygrip (s_key
, grip
))
750 log_error ("can't calculate keygrip\n");
753 log_info ("keygrip: ");
754 for (i
=0; i
< 20; i
++)
755 log_printf ("%02X", grip
[i
]);
758 /* Convert to canonical encoding. */
759 buflen
= gcry_sexp_sprint (s_key
, GCRYSEXP_FMT_CANON
, NULL
, 0);
761 key
= gcry_xmalloc_secure (buflen
);
762 buflen
= gcry_sexp_sprint (s_key
, GCRYSEXP_FMT_CANON
, key
, buflen
);
764 gcry_sexp_release (s_key
);
766 pw
= get_passphrase (4);
767 rc
= agent_protect (key
, pw
, &result
, &resultlen
);
768 release_passphrase (pw
);
772 log_error ("protecting the key failed: %s\n", gpg_strerror (rc
));
778 char *p
= make_advanced (result
, resultlen
);
782 result
= (unsigned char*)p
;
783 resultlen
= strlen (p
);
787 store_private_key (grip
, result
, resultlen
, opt_force
);
789 fwrite (result
, resultlen
, 1, stdout
);
797 sexp_to_kparms (gcry_sexp_t sexp
)
799 gcry_sexp_t list
, l2
;
807 list
= gcry_sexp_find_token (sexp
, "private-key", 0 );
810 l2
= gcry_sexp_cadr (list
);
811 gcry_sexp_release (list
);
813 name
= gcry_sexp_nth_data (list
, 0, &n
);
814 if(!name
|| n
!= 3 || memcmp (name
, "rsa", 3))
816 gcry_sexp_release (list
);
820 /* Parameter names used with RSA. */
822 array
= xcalloc (strlen(elems
) + 1, sizeof *array
);
823 for (idx
=0, s
=elems
; *s
; s
++, idx
++ )
825 l2
= gcry_sexp_find_token (list
, s
, 1);
828 for (i
=0; i
<idx
; i
++)
829 gcry_mpi_release (array
[i
]);
831 gcry_sexp_release (list
);
832 return NULL
; /* required parameter not found */
834 array
[idx
] = gcry_sexp_nth_mpi (l2
, 1, GCRYMPI_FMT_USG
);
835 gcry_sexp_release (l2
);
838 for (i
=0; i
<idx
; i
++)
839 gcry_mpi_release (array
[i
]);
841 gcry_sexp_release (list
);
842 return NULL
; /* required parameter is invalid */
846 gcry_sexp_release (list
);
851 /* Check whether STRING is a KEYGRIP, i.e has the correct length and
852 does only consist of uppercase hex characters. */
854 is_keygrip (const char *string
)
858 for(i
=0; string
[i
] && i
< 41; i
++)
859 if (!strchr("01234567890ABCDEF", string
[i
]))
866 export_p12_file (const char *fname
)
869 gcry_mpi_t kparms
[9], *kp
;
873 struct rsa_secret_key_s sk
;
875 unsigned char *cert
= NULL
;
878 size_t keylen_for_wipe
= 0;
881 if ( is_keygrip (fname
) )
883 char hexgrip
[40+4+1];
886 assert (strlen(fname
) == 40);
887 strcpy (stpcpy (hexgrip
, fname
), ".key");
889 p
= make_filename (opt_homedir
, GNUPG_PRIVATE_KEYS_DIR
, hexgrip
, NULL
);
894 key
= read_key (fname
);
899 keytype
= agent_private_key_type (key
);
900 if (keytype
== PRIVATE_KEY_PROTECTED
)
902 unsigned char *tmpkey
;
905 rc
= agent_unprotect (key
, (pw
=get_passphrase (1)),
906 NULL
, &tmpkey
, &tmplen
);
907 release_passphrase (pw
);
910 if (opt_status_msg
&& gpg_err_code (rc
) == GPG_ERR_BAD_PASSPHRASE
)
911 log_info ("[PROTECT-TOOL:] bad-passphrase\n");
912 log_error ("unprotecting key `%s' failed: %s\n",
913 fname
, gpg_strerror (rc
));
919 keylen_for_wipe
= tmplen
;
921 keytype
= agent_private_key_type (key
);
924 if (keytype
== PRIVATE_KEY_SHADOWED
)
926 log_error ("`%s' is a shadowed private key - can't export it\n", fname
);
927 wipememory (key
, keylen_for_wipe
);
931 else if (keytype
!= PRIVATE_KEY_CLEAR
)
933 log_error ("\%s' is not a private key\n", fname
);
934 wipememory (key
, keylen_for_wipe
);
942 cert
= (unsigned char*)read_file ("-", &certlen
);
945 wipememory (key
, keylen_for_wipe
);
952 if (gcry_sexp_new (&private, key
, 0, 0))
954 log_error ("gcry_sexp_new failed\n");
955 wipememory (key
, keylen_for_wipe
);
960 wipememory (key
, keylen_for_wipe
);
963 kp
= sexp_to_kparms (private);
964 gcry_sexp_release (private);
967 log_error ("error converting key parameters\n");
985 kparms
[5] = gcry_mpi_snew (0); /* compute d mod (p-1) */
986 gcry_mpi_sub_ui (kparms
[5], kparms
[3], 1);
987 gcry_mpi_mod (kparms
[5], sk
.d
, kparms
[5]);
988 kparms
[6] = gcry_mpi_snew (0); /* compute d mod (q-1) */
989 gcry_mpi_sub_ui (kparms
[6], kparms
[4], 1);
990 gcry_mpi_mod (kparms
[6], sk
.d
, kparms
[6]);
994 pw
= get_passphrase (3);
995 key
= p12_build (kparms
, cert
, certlen
, pw
, opt_p12_charset
, &keylen
);
996 release_passphrase (pw
);
998 for (i
=0; i
< 8; i
++)
999 gcry_mpi_release (kparms
[i
]);
1003 #ifdef HAVE_DOSISH_SYSTEM
1004 setmode ( fileno (stdout
) , O_BINARY
);
1006 fwrite (key
, keylen
, 1, stdout
);
1013 main (int argc
, char **argv
)
1015 ARGPARSE_ARGS pargs
;
1019 set_strusage (my_strusage
);
1020 gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN
);
1021 log_set_prefix ("gpg-protect-tool", 1);
1023 /* Make sure that our subsystems are ready. */
1025 init_common_subsystems ();
1027 if (!gcry_check_version (NEED_LIBGCRYPT_VERSION
) )
1029 log_fatal( _("%s is too old (need %s, have %s)\n"), "libgcrypt",
1030 NEED_LIBGCRYPT_VERSION
, gcry_check_version (NULL
) );
1033 setup_libgcrypt_logging ();
1034 gcry_control (GCRYCTL_INIT_SECMEM
, 16384, 0);
1037 opt_homedir
= default_homedir ();
1042 pargs
.flags
= 1; /* (do not remove the args) */
1043 while (arg_parse (&pargs
, opts
) )
1045 switch (pargs
.r_opt
)
1047 case oVerbose
: opt
.verbose
++; break;
1048 case oArmor
: opt_armor
=1; break;
1049 case oCanonical
: opt_canonical
=1; break;
1050 case oHomedir
: opt_homedir
= pargs
.r
.ret_str
; break;
1052 case oAgentProgram
: opt_agent_program
= pargs
.r
.ret_str
; break;
1054 case oProtect
: cmd
= oProtect
; break;
1055 case oUnprotect
: cmd
= oUnprotect
; break;
1056 case oShadow
: cmd
= oShadow
; break;
1057 case oShowShadowInfo
: cmd
= oShowShadowInfo
; break;
1058 case oShowKeygrip
: cmd
= oShowKeygrip
; break;
1059 case oP12Import
: cmd
= oP12Import
; break;
1060 case oP12Export
: cmd
= oP12Export
; break;
1061 case oP12Charset
: opt_p12_charset
= pargs
.r
.ret_str
; break;
1063 case oPassphrase
: opt_passphrase
= pargs
.r
.ret_str
; break;
1064 case oStore
: opt_store
= 1; break;
1065 case oForce
: opt_force
= 1; break;
1066 case oNoFailOnExist
: opt_no_fail_on_exist
= 1; break;
1067 case oHaveCert
: opt_have_cert
= 1; break;
1068 case oPrompt
: opt_prompt
= pargs
.r
.ret_str
; break;
1069 case oStatusMsg
: opt_status_msg
= 1; break;
1071 default: pargs
.err
= ARGPARSE_PRINT_ERROR
; break;
1074 if (log_get_errorcount (0))
1083 /* Set the information which can't be taken from envvars. */
1084 gnupg_prepare_get_passphrase (GPG_ERR_SOURCE_DEFAULT
,
1088 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
1091 opt_prompt
= percent_plus_unescape (opt_prompt
, 0);
1093 if (cmd
== oProtect
)
1094 read_and_protect (fname
);
1095 else if (cmd
== oUnprotect
)
1096 read_and_unprotect (fname
);
1097 else if (cmd
== oShadow
)
1098 read_and_shadow (fname
);
1099 else if (cmd
== oShowShadowInfo
)
1100 show_shadow_info (fname
);
1101 else if (cmd
== oShowKeygrip
)
1102 show_keygrip (fname
);
1103 else if (cmd
== oP12Import
)
1104 import_p12_file (fname
);
1105 else if (cmd
== oP12Export
)
1106 export_p12_file (fname
);
1111 return 8; /*NOTREACHED*/
1117 rc
= rc
? rc
: log_get_errorcount(0)? 2 : 0;
1122 /* Return the passphrase string and ask the agent if it has not been
1123 set from the command line PROMPTNO select the prompt to display:
1125 1 = taken from the option --prompt
1126 2 = for unprotecting a pkcs#12 object
1127 3 = for protecting a new pkcs#12 object
1128 4 = for protecting an imported pkcs#12 in our system
1131 get_passphrase (int promptno
)
1140 return xstrdup (opt_passphrase
);
1142 orig_codeset
= i18n_switchto_utf8 ();
1144 if (promptno
== 1 && opt_prompt
)
1148 else if (promptno
== 2)
1150 desc
= _("Please enter the passphrase to unprotect the "
1153 else if (promptno
== 3)
1155 desc
= _("Please enter the passphrase to protect the "
1156 "new PKCS#12 object.");
1159 else if (promptno
== 4)
1161 desc
= _("Please enter the passphrase to protect the "
1162 "imported object within the GnuPG system.");
1166 desc
= _("Please enter the passphrase or the PIN\n"
1167 "needed to complete this operation.");
1169 i18n_switchback (orig_codeset
);
1171 err
= gnupg_get_passphrase (NULL
, NULL
, _("Passphrase:"), desc
,
1172 repeat
, repeat
, 1, &pw
);
1175 if (gpg_err_code (err
) == GPG_ERR_CANCELED
)
1176 log_info (_("cancelled\n"));
1178 log_error (_("error while asking for the passphrase: %s\n"),
1179 gpg_strerror (err
));
1189 release_passphrase (char *pw
)
1193 wipememory (pw
, strlen (pw
));
1199 store_private_key (const unsigned char *grip
,
1200 const void *buffer
, size_t length
, int force
)
1205 char hexgrip
[40+4+1];
1207 for (i
=0; i
< 20; i
++)
1208 sprintf (hexgrip
+2*i
, "%02X", grip
[i
]);
1209 strcpy (hexgrip
+40, ".key");
1211 fname
= make_filename (opt_homedir
, GNUPG_PRIVATE_KEYS_DIR
, hexgrip
, NULL
);
1213 fp
= fopen (fname
, "wb");
1216 if (!access (fname
, F_OK
))
1219 log_info ("[PROTECT-TOOL:] secretkey-exists\n");
1220 if (opt_no_fail_on_exist
)
1221 log_info ("secret key file `%s' already exists\n", fname
);
1223 log_error ("secret key file `%s' already exists\n", fname
);
1225 return opt_no_fail_on_exist
? 0 : -1;
1227 fp
= fopen (fname
, "wbx"); /* FIXME: the x is a GNU extension - let
1228 configure check whether this actually
1234 log_error ("can't create `%s': %s\n", fname
, strerror (errno
));
1239 if (fwrite (buffer
, length
, 1, fp
) != 1)
1241 log_error ("error writing `%s': %s\n", fname
, strerror (errno
));
1249 log_error ("error closing `%s': %s\n", fname
, strerror (errno
));
1254 log_info ("secret key stored as `%s'\n", fname
);
1257 log_info ("[PROTECT-TOOL:] secretkey-stored\n");