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