1 /* protect-tool.c - A tool to text the secret key protection
2 * Copyright (C) 2002 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
35 #define JNLIB_NEED_LOG_LOGV
42 enum cmd_and_opt_values
59 static const char *passphrase
= "abc";
61 static ARGPARSE_OPTS opts
[] = {
63 { 301, NULL
, 0, N_("@Options:\n ") },
65 { oVerbose
, "verbose", 0, "verbose" },
66 { oArmor
, "armor", 0, "write output in advanced format" },
67 { oPassphrase
, "passphrase", 2, "|STRING| Use passphrase STRING" },
68 { oProtect
, "protect", 256, "protect a private key"},
69 { oUnprotect
, "unprotect", 256, "unprotect a private key"},
70 { oShadow
, "shadow", 256, "create a shadow entry for a priblic key"},
71 { oShowShadowInfo
, "show-shadow-info", 256, "return the shadow info"},
77 my_strusage (int level
)
82 case 11: p
= "protect-tool (GnuPG)";
84 case 13: p
= VERSION
; break;
85 case 17: p
= PRINTABLE_OS_NAME
; break;
86 case 19: p
= _("Please report bugs to <" PACKAGE_BUGREPORT
">.\n");
89 case 40: p
= _("Usage: protect-tool [options] (-h for help)\n");
91 case 41: p
= _("Syntax: protect-tool [options] [args]]\n"
92 "INTERNAL USE ONLY!\n");
105 #ifdef USE_SIMPLE_GETTEXT
106 set_gettext_file( PACKAGE
);
109 /* gtk_set_locale (); HMMM: We have not yet called gtk_init */
110 bindtextdomain( PACKAGE
, GNUPG_LOCALEDIR
);
111 textdomain( PACKAGE
);
118 /* Used by gcry for logging */
120 my_gcry_logger (void *dummy
, int level
, const char *fmt
, va_list arg_ptr
)
122 /* translate the log levels */
125 case GCRY_LOG_CONT
: level
= JNLIB_LOG_CONT
; break;
126 case GCRY_LOG_INFO
: level
= JNLIB_LOG_INFO
; break;
127 case GCRY_LOG_WARN
: level
= JNLIB_LOG_WARN
; break;
128 case GCRY_LOG_ERROR
:level
= JNLIB_LOG_ERROR
; break;
129 case GCRY_LOG_FATAL
:level
= JNLIB_LOG_FATAL
; break;
130 case GCRY_LOG_BUG
: level
= JNLIB_LOG_BUG
; break;
131 case GCRY_LOG_DEBUG
:level
= JNLIB_LOG_DEBUG
; break;
132 default: level
= JNLIB_LOG_ERROR
; break; }
133 log_logv (level
, fmt
, arg_ptr
);
137 static unsigned char *
138 make_canonical (const char *fname
, const char *buf
, size_t buflen
)
143 unsigned char *result
;
145 rc
= gcry_sexp_sscan (&sexp
, &erroff
, buf
, buflen
);
148 log_error ("invalid S-Expression in `%s' (off=%u): %s\n",
149 fname
, (unsigned int)erroff
, gcry_strerror (rc
));
152 len
= gcry_sexp_sprint (sexp
, GCRYSEXP_FMT_CANON
, NULL
, 0);
154 result
= xmalloc (len
);
155 len
= gcry_sexp_sprint (sexp
, GCRYSEXP_FMT_CANON
, result
, len
);
157 gcry_sexp_release (sexp
);
162 make_advanced (const unsigned char *buf
, size_t buflen
)
167 unsigned char *result
;
169 rc
= gcry_sexp_sscan (&sexp
, &erroff
, buf
, buflen
);
172 log_error ("invalid canonical S-Expression (off=%u): %s\n",
173 (unsigned int)erroff
, gcry_strerror (rc
));
176 len
= gcry_sexp_sprint (sexp
, GCRYSEXP_FMT_ADVANCED
, NULL
, 0);
178 result
= xmalloc (len
);
179 len
= gcry_sexp_sprint (sexp
, GCRYSEXP_FMT_ADVANCED
, result
, len
);
181 gcry_sexp_release (sexp
);
186 static unsigned char *
187 read_key (const char *fname
)
195 fp
= fopen (fname
, "rb");
198 log_error ("can't open `%s': %s\n", fname
, strerror (errno
));
202 if (fstat (fileno(fp
), &st
))
204 log_error ("can't stat `%s': %s\n", fname
, strerror (errno
));
210 buf
= xmalloc (buflen
+1);
211 if (fread (buf
, buflen
, 1, fp
) != 1)
213 log_error ("error reading `%s': %s\n", fname
, strerror (errno
));
220 key
= make_canonical (fname
, buf
, buflen
);
228 read_and_protect (const char *fname
)
232 unsigned char *result
;
235 key
= read_key (fname
);
239 rc
= agent_protect (key
, passphrase
, &result
, &resultlen
);
243 log_error ("protecting the key failed: %s\n", gnupg_strerror (rc
));
249 char *p
= make_advanced (result
, resultlen
);
254 resultlen
= strlen (p
);
257 fwrite (result
, resultlen
, 1, stdout
);
263 read_and_unprotect (const char *fname
)
267 unsigned char *result
;
270 key
= read_key (fname
);
274 rc
= agent_unprotect (key
, passphrase
, &result
, &resultlen
);
278 log_error ("unprotecting the key failed: %s\n", gnupg_strerror (rc
));
284 char *p
= make_advanced (result
, resultlen
);
289 resultlen
= strlen (p
);
292 fwrite (result
, resultlen
, 1, stdout
);
299 read_and_shadow (const char *fname
)
303 unsigned char *result
;
306 key
= read_key (fname
);
310 rc
= agent_shadow_key (key
, "(8:313233342:43)", &result
);
314 log_error ("shadowing the key failed: %s\n", gnupg_strerror (rc
));
317 resultlen
= gcry_sexp_canon_len (result
, 0, NULL
,NULL
);
322 char *p
= make_advanced (result
, resultlen
);
327 resultlen
= strlen (p
);
330 fwrite (result
, resultlen
, 1, stdout
);
335 show_shadow_info (const char *fname
)
339 const unsigned char *info
;
342 key
= read_key (fname
);
346 rc
= agent_get_shadow_info (key
, &info
);
350 log_error ("get_shadow_info failed: %s\n", gnupg_strerror (rc
));
353 infolen
= gcry_sexp_canon_len (info
, 0, NULL
,NULL
);
358 char *p
= make_advanced (info
, infolen
);
361 fwrite (p
, strlen (p
), 1, stdout
);
365 fwrite (info
, infolen
, 1, stdout
);
370 show_file (const char *fname
)
376 key
= read_key (fname
);
379 keylen
= gcry_sexp_canon_len (key
, 0, NULL
,NULL
);
382 p
= make_advanced (key
, keylen
);
386 fwrite (p
, strlen (p
), 1, stdout
);
395 main (int argc
, char **argv
)
400 set_strusage (my_strusage
);
401 gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN
);
402 log_set_prefix ("protect-tool", 1);
405 if (!gcry_check_version ( "1.1.5" ) )
407 log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
408 "1.1.5", gcry_check_version (NULL
) );
411 gcry_set_log_handler (my_gcry_logger
, NULL
);
413 gcry_control (GCRYCTL_INIT_SECMEM
, 16384, 0);
417 pargs
.flags
= 1; /* do not remove the args */
418 while (arg_parse (&pargs
, opts
) )
422 case oVerbose
: opt
.verbose
++; break;
423 case oArmor
: opt_armor
=1; break;
425 case oProtect
: cmd
= oProtect
; break;
426 case oUnprotect
: cmd
= oUnprotect
; break;
427 case oShadow
: cmd
= oShadow
; break;
428 case oShowShadowInfo
: cmd
= oShowShadowInfo
; break;
430 case oPassphrase
: passphrase
= pargs
.r
.ret_str
; break;
432 default : pargs
.err
= 2; break;
435 if (log_get_errorcount(0))
442 read_and_protect (*argv
);
443 else if (cmd
== oUnprotect
)
444 read_and_unprotect (*argv
);
445 else if (cmd
== oShadow
)
446 read_and_shadow (*argv
);
447 else if (cmd
== oShowShadowInfo
)
448 show_shadow_info (*argv
);
458 rc
= rc
? rc
: log_get_errorcount(0)? 2 : 0;