1 /* pksign.c - Generate a keypair
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
34 store_key (gcry_sexp_t
private, const char *passphrase
, int force
)
39 unsigned char grip
[20];
41 if ( !gcry_pk_get_keygrip (private, grip
) )
43 log_error ("can't calculate keygrip\n");
44 return gpg_error (GPG_ERR_GENERAL
);
47 len
= gcry_sexp_sprint (private, GCRYSEXP_FMT_CANON
, NULL
, 0);
49 buf
= gcry_malloc_secure (len
);
51 return out_of_core ();
52 len
= gcry_sexp_sprint (private, GCRYSEXP_FMT_CANON
, buf
, len
);
59 rc
= agent_protect (buf
, passphrase
, &p
, &len
);
69 rc
= agent_write_private_key (grip
, buf
, len
, force
);
74 /* Callback function to compare the first entered PIN with the one
75 currently being entered. */
77 reenter_compare_cb (struct pin_entry_info_s
*pi
)
79 const char *pin1
= pi
->check_cb_arg
;
81 if (!strcmp (pin1
, pi
->pin
))
88 /* Generate a new keypair according to the parameters given in
91 agent_genkey (ctrl_t ctrl
, const char *keyparam
, size_t keyparamlen
,
94 gcry_sexp_t s_keyparam
, s_key
, s_private
, s_public
;
95 struct pin_entry_info_s
*pi
, *pi2
;
100 rc
= gcry_sexp_sscan (&s_keyparam
, NULL
, keyparam
, keyparamlen
);
103 log_error ("failed to convert keyparam: %s\n", gpg_strerror (rc
));
104 return gpg_error (GPG_ERR_INV_DATA
);
107 /* Get the passphrase now, cause key generation may take a while. */
109 const char *text1
= _("Please enter the passphrase to%0A"
110 "to protect your new key");
111 const char *text2
= _("Please re-enter this passphrase");
112 const char *initial_errtext
= NULL
;
114 pi
= gcry_calloc_secure (2, sizeof (*pi
) + 100);
115 pi2
= pi
+ (sizeof *pi
+ 100);
116 pi
->max_length
= 100;
118 pi2
->max_length
= 100;
120 pi2
->check_cb
= reenter_compare_cb
;
121 pi2
->check_cb_arg
= pi
->pin
;
124 rc
= agent_askpin (ctrl
, text1
, NULL
, initial_errtext
, pi
);
125 initial_errtext
= NULL
;
128 rc
= agent_askpin (ctrl
, text2
, NULL
, NULL
, pi2
);
130 { /* The re-entered one did not match and the user did not
132 initial_errtext
= _("does not match - try again");
141 pi
= NULL
; /* User does not want a passphrase. */
145 rc
= gcry_pk_genkey (&s_key
, s_keyparam
);
146 gcry_sexp_release (s_keyparam
);
149 log_error ("key generation failed: %s\n", gpg_strerror (rc
));
154 /* break out the parts */
155 s_private
= gcry_sexp_find_token (s_key
, "private-key", 0);
158 log_error ("key generation failed: invalid return value\n");
159 gcry_sexp_release (s_key
);
161 return gpg_error (GPG_ERR_INV_DATA
);
163 s_public
= gcry_sexp_find_token (s_key
, "public-key", 0);
166 log_error ("key generation failed: invalid return value\n");
167 gcry_sexp_release (s_private
);
168 gcry_sexp_release (s_key
);
170 return gpg_error (GPG_ERR_INV_DATA
);
172 gcry_sexp_release (s_key
); s_key
= NULL
;
174 /* store the secret key */
176 log_debug ("storing private key\n");
177 rc
= store_key (s_private
, pi
? pi
->pin
:NULL
, 0);
178 xfree (pi
); pi
= NULL
;
179 gcry_sexp_release (s_private
);
182 gcry_sexp_release (s_public
);
186 /* return the public key */
188 log_debug ("returning public key\n");
189 len
= gcry_sexp_sprint (s_public
, GCRYSEXP_FMT_CANON
, NULL
, 0);
191 buf
= xtrymalloc (len
);
194 gpg_error_t tmperr
= out_of_core ();
195 gcry_sexp_release (s_private
);
196 gcry_sexp_release (s_public
);
199 len
= gcry_sexp_sprint (s_public
, GCRYSEXP_FMT_CANON
, buf
, len
);
201 put_membuf (outbuf
, buf
, len
);
202 gcry_sexp_release (s_public
);
210 /* Apply a new passpahrse to the key S_SKEY and store it. */
212 agent_protect_and_store (ctrl_t ctrl
, gcry_sexp_t s_skey
)
214 struct pin_entry_info_s
*pi
, *pi2
;
218 const char *text1
= _("Please enter the new passphrase");
219 const char *text2
= _("Please re-enter this passphrase");
220 const char *initial_errtext
= NULL
;
222 pi
= gcry_calloc_secure (2, sizeof (*pi
) + 100);
223 pi2
= pi
+ (sizeof *pi
+ 100);
224 pi
->max_length
= 100;
226 pi2
->max_length
= 100;
228 pi2
->check_cb
= reenter_compare_cb
;
229 pi2
->check_cb_arg
= pi
->pin
;
232 rc
= agent_askpin (ctrl
, text1
, NULL
, initial_errtext
, pi
);
235 rc
= agent_askpin (ctrl
, text2
, NULL
, NULL
, pi2
);
237 { /* The re-entered one did not match and the user did not
239 initial_errtext
= _("does not match - try again");
248 pi
= NULL
; /* User does not want a passphrase. */
252 rc
= store_key (s_skey
, pi
? pi
->pin
:NULL
, 1);