agent: Only one confirmation prompt for an empty passphrase.
[gnupg.git] / agent / genkey.c
1 /* genkey.c - Generate a keypair
2  * Copyright (C) 2002, 2003, 2004, 2007, 2010 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 #include <config.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <assert.h>
27
28 #include "agent.h"
29 #include "i18n.h"
30 #include "exechelp.h"
31 #include "sysutils.h"
32
33 static int
34 store_key (gcry_sexp_t private, const char *passphrase, int force,
35         unsigned long s2k_count)
36 {
37   int rc;
38   unsigned char *buf;
39   size_t len;
40   unsigned char grip[20];
41
42   if ( !gcry_pk_get_keygrip (private, grip) )
43     {
44       log_error ("can't calculate keygrip\n");
45       return gpg_error (GPG_ERR_GENERAL);
46     }
47
48   len = gcry_sexp_sprint (private, GCRYSEXP_FMT_CANON, NULL, 0);
49   assert (len);
50   buf = gcry_malloc_secure (len);
51   if (!buf)
52       return out_of_core ();
53   len = gcry_sexp_sprint (private, GCRYSEXP_FMT_CANON, buf, len);
54   assert (len);
55
56   if (passphrase)
57     {
58       unsigned char *p;
59
60       rc = agent_protect (buf, passphrase, &p, &len, s2k_count);
61       if (rc)
62         {
63           xfree (buf);
64           return rc;
65         }
66       xfree (buf);
67       buf = p;
68     }
69
70   rc = agent_write_private_key (grip, buf, len, force);
71   xfree (buf);
72   return rc;
73 }
74
75
76 /* Count the number of non-alpha characters in S.  Control characters
77    and non-ascii characters are not considered.  */
78 static size_t
79 nonalpha_count (const char *s)
80 {
81   size_t n;
82
83   for (n=0; *s; s++)
84     if (isascii (*s) && ( isdigit (*s) || ispunct (*s) ))
85       n++;
86
87   return n;
88 }
89
90
91 /* Check PW against a list of pattern.  Return 0 if PW does not match
92    these pattern.  */
93 static int
94 check_passphrase_pattern (ctrl_t ctrl, const char *pw)
95 {
96   gpg_error_t err = 0;
97   const char *pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CHECK_PATTERN);
98   FILE *infp;
99   const char *argv[10];
100   pid_t pid;
101   int result, i;
102
103   (void)ctrl;
104
105   infp = gnupg_tmpfile ();
106   if (!infp)
107     {
108       err = gpg_error_from_syserror ();
109       log_error (_("error creating temporary file: %s\n"), gpg_strerror (err));
110       return 1; /* Error - assume password should not be used.  */
111     }
112
113   if (fwrite (pw, strlen (pw), 1, infp) != 1)
114     {
115       err = gpg_error_from_syserror ();
116       log_error (_("error writing to temporary file: %s\n"),
117                  gpg_strerror (err));
118       fclose (infp);
119       return 1; /* Error - assume password should not be used.  */
120     }
121   fseek (infp, 0, SEEK_SET);
122   clearerr (infp);
123
124   i = 0;
125   argv[i++] = "--null";
126   argv[i++] = "--",
127   argv[i++] = opt.check_passphrase_pattern,
128   argv[i] = NULL;
129   assert (i < sizeof argv);
130
131   if (gnupg_spawn_process_fd (pgmname, argv, fileno (infp), -1, -1, &pid))
132     result = 1; /* Execute error - assume password should no be used.  */
133   else if (gnupg_wait_process (pgmname, pid, 1, NULL))
134     result = 1; /* Helper returned an error - probably a match.  */
135   else
136     result = 0; /* Success; i.e. no match.  */
137   gnupg_release_process (pid);
138
139   /* Overwrite our temporary file. */
140   fseek (infp, 0, SEEK_SET);
141   clearerr (infp);
142   for (i=((strlen (pw)+99)/100)*100; i > 0; i--)
143     putc ('\xff', infp);
144   fflush (infp);
145   fclose (infp);
146   return result;
147 }
148
149
150 static int
151 take_this_one_anyway2 (ctrl_t ctrl, const char *desc, const char *anyway_btn)
152 {
153   gpg_error_t err;
154
155   if (opt.enforce_passphrase_constraints)
156     {
157       err = agent_show_message (ctrl, desc, _("Enter new passphrase"));
158       if (!err)
159         err = gpg_error (GPG_ERR_CANCELED);
160     }
161   else
162     err = agent_get_confirmation (ctrl, desc,
163                                   anyway_btn, _("Enter new passphrase"), 0);
164   return err;
165 }
166
167
168 static int
169 take_this_one_anyway (ctrl_t ctrl, const char *desc)
170 {
171   return take_this_one_anyway2 (ctrl, desc, _("Take this one anyway"));
172 }
173
174
175 /* Check whether the passphrase PW is suitable. Returns 0 if the
176    passphrase is suitable and true if it is not and the user should be
177    asked to provide a different one.  If SILENT is set, no message are
178    displayed.  */
179 int
180 check_passphrase_constraints (ctrl_t ctrl, const char *pw, int silent)
181 {
182   gpg_error_t err;
183   unsigned int minlen = opt.min_passphrase_len;
184   unsigned int minnonalpha = opt.min_passphrase_nonalpha;
185
186   if (!pw)
187     pw = "";
188
189   /* The first check is to warn about an empty passphrase. */
190   if (!*pw)
191     {
192       const char *desc = (opt.enforce_passphrase_constraints?
193                           _("You have not entered a passphrase!%0A"
194                             "An empty passphrase is not allowed.") :
195                           _("You have not entered a passphrase - "
196                             "this is in general a bad idea!%0A"
197                             "Please confirm that you do not want to "
198                             "have any protection on your key."));
199
200       if (silent)
201         return gpg_error (GPG_ERR_INV_PASSPHRASE);
202
203       return take_this_one_anyway2 (ctrl, desc,
204                                    _("Yes, protection is not needed"));
205     }
206
207   if (utf8_charcount (pw) < minlen )
208     {
209       char *desc;
210
211       if (silent)
212         return gpg_error (GPG_ERR_INV_PASSPHRASE);
213
214       desc = xtryasprintf
215         ( ngettext ("Warning: You have entered an insecure passphrase.%%0A"
216                     "A passphrase should be at least %u character long.",
217                     "Warning: You have entered an insecure passphrase.%%0A"
218                     "A passphrase should be at least %u characters long.",
219                     minlen), minlen );
220       if (!desc)
221         return gpg_error_from_syserror ();
222       err = take_this_one_anyway (ctrl, desc);
223       xfree (desc);
224       if (err)
225         return err;
226     }
227
228   if (nonalpha_count (pw) < minnonalpha )
229     {
230       char *desc;
231
232       if (silent)
233         return gpg_error (GPG_ERR_INV_PASSPHRASE);
234
235       desc = xtryasprintf
236         ( ngettext ("Warning: You have entered an insecure passphrase.%%0A"
237                     "A passphrase should contain at least %u digit or%%0A"
238                     "special character.",
239                     "Warning: You have entered an insecure passphrase.%%0A"
240                     "A passphrase should contain at least %u digits or%%0A"
241                     "special characters.",
242                     minnonalpha), minnonalpha );
243       if (!desc)
244         return gpg_error_from_syserror ();
245       err = take_this_one_anyway (ctrl, desc);
246       xfree (desc);
247       if (err)
248         return err;
249     }
250
251   /* If configured check the passphrase against a list of known words
252      and pattern.  The actual test is done by an external program.
253      The warning message is generic to give the user no hint on how to
254      circumvent this list.  */
255   if (*pw && opt.check_passphrase_pattern &&
256       check_passphrase_pattern (ctrl, pw))
257     {
258       const char *desc =
259         /* */     _("Warning: You have entered an insecure passphrase.%%0A"
260                     "A passphrase may not be a known term or match%%0A"
261                     "certain pattern.");
262
263       if (silent)
264         return gpg_error (GPG_ERR_INV_PASSPHRASE);
265
266       err = take_this_one_anyway (ctrl, desc);
267       if (err)
268         return err;
269     }
270
271   return 0;
272 }
273
274
275 /* Callback function to compare the first entered PIN with the one
276    currently being entered. */
277 static int
278 reenter_compare_cb (struct pin_entry_info_s *pi)
279 {
280   const char *pin1 = pi->check_cb_arg;
281
282   if (!strcmp (pin1, pi->pin))
283     return 0; /* okay */
284   return -1;
285 }
286
287
288 /* Ask the user for a new passphrase using PROMPT.  On success the
289    function returns 0 and store the passphrase at R_PASSPHRASE; if the
290    user opted not to use a passphrase NULL will be stored there.  The
291    user needs to free the returned string.  In case of an error and
292    error code is returned and NULL stored at R_PASSPHRASE.  */
293 gpg_error_t
294 agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
295                           char **r_passphrase)
296 {
297   gpg_error_t err;
298   const char *text1 = prompt;
299   const char *text2 = _("Please re-enter this passphrase");
300   const char *initial_errtext = NULL;
301   struct pin_entry_info_s *pi, *pi2;
302
303   *r_passphrase = NULL;
304
305   if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
306     {
307         size_t size;
308         size_t len = 100;
309         unsigned char *buffer;
310
311         err = pinentry_loopback(ctrl, "NEW_PASSPHRASE", &buffer, &size, len);
312         if (!err)
313           {
314             if (size)
315               {
316                 buffer[size] = 0;
317                 *r_passphrase = buffer;
318               }
319             else
320                 *r_passphrase = NULL;
321           }
322         return err;
323     }
324
325   pi = gcry_calloc_secure (2, sizeof (*pi) + 100);
326   pi2 = pi + (sizeof *pi + 100);
327   pi->max_length = 100;
328   pi->max_tries = 3;
329   pi->with_qualitybar = 1;
330   pi2->max_length = 100;
331   pi2->max_tries = 3;
332   pi2->check_cb = reenter_compare_cb;
333   pi2->check_cb_arg = pi->pin;
334
335  next_try:
336   err = agent_askpin (ctrl, text1, NULL, initial_errtext, pi);
337   initial_errtext = NULL;
338   if (!err)
339     {
340       if (check_passphrase_constraints (ctrl, pi->pin, 0))
341         {
342           pi->failed_tries = 0;
343           pi2->failed_tries = 0;
344           goto next_try;
345         }
346       /* Unless the passphrase is empty, ask to confirm it.  */
347       if (pi->pin && *pi->pin)
348         {
349           err = agent_askpin (ctrl, text2, NULL, NULL, pi2);
350           if (err == -1)
351             { /* The re-entered one did not match and the user did not
352                  hit cancel. */
353               initial_errtext = _("does not match - try again");
354               goto next_try;
355             }
356         }
357     }
358
359   if (!err && *pi->pin)
360     {
361       /* User wants a passphrase. */
362       *r_passphrase = xtrystrdup (pi->pin);
363       if (!*r_passphrase)
364         err = gpg_error_from_syserror ();
365     }
366   xfree (pi);
367   return err;
368 }
369
370
371
372 /* Generate a new keypair according to the parameters given in
373    KEYPARAM.  If CACHE_NONCE is given first try to lookup a passphrase
374    using the cache nonce.  If NO_PROTECTION is true the key will not
375    be protected by a passphrase.  */
376 int
377 agent_genkey (ctrl_t ctrl, const char *cache_nonce,
378               const char *keyparam, size_t keyparamlen, int no_protection,
379               int preset, membuf_t *outbuf)
380 {
381   gcry_sexp_t s_keyparam, s_key, s_private, s_public;
382   char *passphrase;
383   int rc;
384   size_t len;
385   char *buf;
386
387   rc = gcry_sexp_sscan (&s_keyparam, NULL, keyparam, keyparamlen);
388   if (rc)
389     {
390       log_error ("failed to convert keyparam: %s\n", gpg_strerror (rc));
391       return gpg_error (GPG_ERR_INV_DATA);
392     }
393
394   /* Get the passphrase now, cause key generation may take a while. */
395   if (no_protection || !cache_nonce)
396     passphrase = NULL;
397   else
398     passphrase = agent_get_cache (cache_nonce, CACHE_MODE_NONCE);
399
400   if (passphrase || no_protection)
401     rc = 0;
402   else
403     rc = agent_ask_new_passphrase (ctrl,
404                                    _("Please enter the passphrase to%0A"
405                                      "protect your new key"),
406                                    &passphrase);
407   if (rc)
408     return rc;
409
410   rc = gcry_pk_genkey (&s_key, s_keyparam );
411   gcry_sexp_release (s_keyparam);
412   if (rc)
413     {
414       log_error ("key generation failed: %s\n", gpg_strerror (rc));
415       xfree (passphrase);
416       return rc;
417     }
418
419   /* break out the parts */
420   s_private = gcry_sexp_find_token (s_key, "private-key", 0);
421   if (!s_private)
422     {
423       log_error ("key generation failed: invalid return value\n");
424       gcry_sexp_release (s_key);
425       xfree (passphrase);
426       return gpg_error (GPG_ERR_INV_DATA);
427     }
428   s_public = gcry_sexp_find_token (s_key, "public-key", 0);
429   if (!s_public)
430     {
431       log_error ("key generation failed: invalid return value\n");
432       gcry_sexp_release (s_private);
433       gcry_sexp_release (s_key);
434       xfree (passphrase);
435       return gpg_error (GPG_ERR_INV_DATA);
436     }
437   gcry_sexp_release (s_key); s_key = NULL;
438
439   /* store the secret key */
440   if (DBG_CRYPTO)
441     log_debug ("storing private key\n");
442   rc = store_key (s_private, passphrase, 0, ctrl->s2k_count);
443   if (!rc)
444     {
445       if (!cache_nonce)
446         {
447           char tmpbuf[12];
448           gcry_create_nonce (tmpbuf, 12);
449           cache_nonce = bin2hex (tmpbuf, 12, NULL);
450         }
451       if (cache_nonce
452           && !no_protection
453           && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
454                                passphrase, ctrl->cache_ttl_opt_preset))
455         agent_write_status (ctrl, "CACHE_NONCE", cache_nonce, NULL);
456       if (preset && !no_protection)
457         {
458           unsigned char grip[20];
459           char hexgrip[40+1];
460           if (gcry_pk_get_keygrip (s_private, grip))
461             {
462               bin2hex(grip, 20, hexgrip);
463               rc = agent_put_cache (hexgrip, CACHE_MODE_ANY, passphrase,
464                                     ctrl->cache_ttl_opt_preset);
465             }
466         }
467     }
468   xfree (passphrase);
469   passphrase = NULL;
470   gcry_sexp_release (s_private);
471   if (rc)
472     {
473       gcry_sexp_release (s_public);
474       return rc;
475     }
476
477   /* return the public key */
478   if (DBG_CRYPTO)
479     log_debug ("returning public key\n");
480   len = gcry_sexp_sprint (s_public, GCRYSEXP_FMT_CANON, NULL, 0);
481   assert (len);
482   buf = xtrymalloc (len);
483   if (!buf)
484     {
485       gpg_error_t tmperr = out_of_core ();
486       gcry_sexp_release (s_private);
487       gcry_sexp_release (s_public);
488       return tmperr;
489     }
490   len = gcry_sexp_sprint (s_public, GCRYSEXP_FMT_CANON, buf, len);
491   assert (len);
492   put_membuf (outbuf, buf, len);
493   gcry_sexp_release (s_public);
494   xfree (buf);
495
496   return 0;
497 }
498
499
500 \f
501 /* Apply a new passphrase to the key S_SKEY and store it.  If
502    PASSPHRASE_ADDR and *PASSPHRASE_ADDR are not NULL, use that
503    passphrase.  If PASSPHRASE_ADDR is not NULL store a newly entered
504    passphrase at that address. */
505 gpg_error_t
506 agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey,
507                          char **passphrase_addr)
508 {
509   gpg_error_t err;
510
511   if (passphrase_addr && *passphrase_addr)
512     {
513       /* Take an empty string as request not to protect the key.  */
514       err = store_key (s_skey, **passphrase_addr? *passphrase_addr:NULL, 1,
515               ctrl->s2k_count);
516     }
517   else
518     {
519       char *pass = NULL;
520
521       if (passphrase_addr)
522         {
523           xfree (*passphrase_addr);
524           *passphrase_addr = NULL;
525         }
526       err = agent_ask_new_passphrase (ctrl,
527                                       _("Please enter the new passphrase"),
528                                       &pass);
529       if (!err)
530         err = store_key (s_skey, pass, 1, ctrl->s2k_count);
531       if (!err && passphrase_addr)
532         *passphrase_addr = pass;
533       else
534         xfree (pass);
535     }
536
537   return err;
538 }