1 /* findkey.c - locate the secret key
2 * Copyright (C) 2001 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 agent_write_private_key (const unsigned char *grip
,
36 const void *buffer
, size_t length
, int force
)
43 for (i
=0; i
< 20; i
++)
44 sprintf (hexgrip
+2*i
, "%02X", grip
[i
]);
45 strcpy (hexgrip
+40, ".key");
47 fname
= make_filename (opt
.homedir
, "private-keys-v1.d", hexgrip
, NULL
);
49 fp
= fopen (fname
, "wb");
52 if (!access (fname
, F_OK
))
54 log_error ("secret key file `%s' already exists\n", fname
);
56 return seterr (General_Error
);
58 fp
= fopen (fname
, "wbx"); /* FIXME: the x is a GNU extension - let
59 configure check whether this actually
65 log_error ("can't create `%s': %s\n", fname
, strerror (errno
));
67 return seterr (File_Create_Error
);
70 if (fwrite (buffer
, length
, 1, fp
) != 1)
72 log_error ("error writing `%s': %s\n", fname
, strerror (errno
));
76 return seterr (File_Create_Error
);
80 log_error ("error closing `%s': %s\n", fname
, strerror (errno
));
83 return seterr (File_Create_Error
);
92 unprotect (unsigned char **keybuf
, const unsigned char *grip
)
94 struct pin_entry_info_s
*pi
;
96 unsigned char *result
;
102 for (i
=0; i
< 20; i
++)
103 sprintf (hexgrip
+2*i
, "%02X", grip
[i
]);
106 /* first try to get it from the cache - if there is none or we can't
107 unprotect it, we fall back to ask the user */
109 const char *pw
= agent_get_cache (hexgrip
);
112 rc
= agent_unprotect (*keybuf
, pw
, &result
, &resultlen
);
123 pi
= gcry_calloc_secure (1, sizeof (*pi
) + 100);
124 pi
->max_length
= 100;
125 pi
->min_digits
= 0; /* we want a real passphrase */
132 rc
= agent_askpin (NULL
, errtext
, pi
);
135 rc
= agent_unprotect (*keybuf
, pi
->pin
, &result
, &resultlen
);
138 agent_put_cache (hexgrip
, pi
->pin
, 0);
145 errtext
= pi
->min_digits
? trans ("Bad PIN") : trans ("Bad Passphrase");
147 while ((rc
== GNUPG_Bad_Passphrase
|| rc
== GNUPG_Bad_PIN
)
155 /* Return the secret key as an S-Exp after locating it using the grip.
156 Returns NULL if key is not available or the operation should be
157 diverted to a token. In the latter case shadow_info will point to
158 an allocated S-Expression with the shadow_info part from the
161 agent_key_from_file (const unsigned char *grip
, unsigned char **shadow_info
)
168 size_t len
, buflen
, erroff
;
170 char hexgrip
[40+4+1];
175 for (i
=0; i
< 20; i
++)
176 sprintf (hexgrip
+2*i
, "%02X", grip
[i
]);
177 strcpy (hexgrip
+40, ".key");
179 fname
= make_filename (opt
.homedir
, "private-keys-v1.d", hexgrip
, NULL
);
180 fp
= fopen (fname
, "rb");
183 log_error ("can't open `%s': %s\n", fname
, strerror (errno
));
188 if (fstat (fileno(fp
), &st
))
190 log_error ("can't stat `%s': %s\n", fname
, strerror (errno
));
197 buf
= xmalloc (buflen
+1);
198 if (fread (buf
, buflen
, 1, fp
) != 1)
200 log_error ("error reading `%s': %s\n", fname
, strerror (errno
));
207 rc
= gcry_sexp_sscan (&s_skey
, &erroff
, buf
, buflen
);
213 log_error ("failed to build S-Exp (off=%u): %s\n",
214 (unsigned int)erroff
, gcry_strerror (rc
));
217 len
= gcry_sexp_sprint (s_skey
, GCRYSEXP_FMT_CANON
, NULL
, 0);
219 buf
= xtrymalloc (len
);
222 gcry_sexp_release (s_skey
);
225 len
= gcry_sexp_sprint (s_skey
, GCRYSEXP_FMT_CANON
, buf
, len
);
227 gcry_sexp_release (s_skey
);
229 switch (agent_private_key_type (buf
))
231 case PRIVATE_KEY_CLEAR
:
232 break; /* no unprotection needed */
233 case PRIVATE_KEY_PROTECTED
:
234 rc
= unprotect (&buf
, grip
);
236 log_error ("failed to unprotect the secret key: %s\n",
237 gnupg_strerror (rc
));
239 case PRIVATE_KEY_SHADOWED
:
242 const unsigned char *s
;
245 rc
= agent_get_shadow_info (buf
, &s
);
248 n
= gcry_sexp_canon_len (s
, 0, NULL
,NULL
);
250 *shadow_info
= xtrymalloc (n
);
252 rc
= GNUPG_Out_Of_Core
;
255 memcpy (*shadow_info
, s
, n
);
260 log_error ("get_shadow_info failed: %s\n", gnupg_strerror (rc
));
262 rc
= -1; /* ugly interface: we return an error but keep a value
266 log_error ("invalid private key format\n");
267 rc
= GNUPG_Bad_Secret_Key
;
276 /* arggg FIXME: does scan support secure memory? */
277 rc
= gcry_sexp_sscan (&s_skey
, &erroff
,
278 buf
, gcry_sexp_canon_len (buf
, 0, NULL
, NULL
));
282 log_error ("failed to build S-Exp (off=%u): %s\n",
283 (unsigned int)erroff
, gcry_strerror (rc
));
290 /* Return the secret key as an S-Exp after locating it using the grip.
291 Returns NULL if key is not available. 0 = key is available */
293 agent_key_available (const unsigned char *grip
)
297 char hexgrip
[40+4+1];
299 for (i
=0; i
< 20; i
++)
300 sprintf (hexgrip
+2*i
, "%02X", grip
[i
]);
301 strcpy (hexgrip
+40, ".key");
303 fname
= make_filename (opt
.homedir
, "private-keys-v1.d", hexgrip
, NULL
);
304 i
= !access (fname
, R_OK
)? 0 : -1;