agent: Use different translation func for Pinentry strings.
[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, L_("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, L_("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, L_("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                           L_("You have not entered a passphrase!%0A"
200                              "An empty passphrase is not allowed.") :
201                           L_("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                                          L_("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 = xtrystrdup (L_("A passphrase may not be a known term or match%0A"
275                             "certain pattern."));
276       if (!msg3)
277         {
278           err = gpg_error_from_syserror ();
279           goto leave;
280         }
281     }
282
283   if (failed_constraint && (msg1 || msg2 || msg3))
284     {
285       char *msg;
286       size_t n;
287
288       msg = strconcat
289         (L_("Warning: You have entered an insecure passphrase."),
290          "%0A%0A",
291          msg1? msg1 : "", msg1? "%0A" : "",
292          msg2? msg2 : "", msg2? "%0A" : "",
293          msg3? msg3 : "", msg3? "%0A" : "",
294          NULL);
295       if (!msg)
296         {
297           err = gpg_error_from_syserror ();
298           goto leave;
299         }
300       /* Strip a trailing "%0A".  */
301       n = strlen (msg);
302       if (n > 3 && !strcmp (msg + n - 3, "%0A"))
303         msg[n-3] = 0;
304
305       err = 1;
306       if (opt.enforce_passphrase_constraints)
307         *failed_constraint = msg;
308       else
309         {
310           err = take_this_one_anyway (ctrl, msg);
311           xfree (msg);
312         }
313     }
314
315  leave:
316   xfree (msg1);
317   xfree (msg2);
318   xfree (msg3);
319   return err;
320 }
321
322
323 /* Callback function to compare the first entered PIN with the one
324    currently being entered. */
325 static int
326 reenter_compare_cb (struct pin_entry_info_s *pi)
327 {
328   const char *pin1 = pi->check_cb_arg;
329
330   if (!strcmp (pin1, pi->pin))
331     return 0; /* okay */
332   return -1;
333 }
334
335
336 /* Ask the user for a new passphrase using PROMPT.  On success the
337    function returns 0 and store the passphrase at R_PASSPHRASE; if the
338    user opted not to use a passphrase NULL will be stored there.  The
339    user needs to free the returned string.  In case of an error and
340    error code is returned and NULL stored at R_PASSPHRASE.  */
341 gpg_error_t
342 agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
343                           char **r_passphrase)
344 {
345   gpg_error_t err;
346   const char *text1 = prompt;
347   const char *text2 = L_("Please re-enter this passphrase");
348   char *initial_errtext = NULL;
349   struct pin_entry_info_s *pi, *pi2;
350
351   *r_passphrase = NULL;
352
353   if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
354     {
355         size_t size;
356         size_t len = 100;
357         unsigned char *buffer;
358
359         err = pinentry_loopback(ctrl, "NEW_PASSPHRASE", &buffer, &size, len);
360         if (!err)
361           {
362             if (size)
363               {
364                 buffer[size] = 0;
365                 *r_passphrase = buffer;
366               }
367             else
368                 *r_passphrase = NULL;
369           }
370         return err;
371     }
372
373   pi = gcry_calloc_secure (2, sizeof (*pi) + 100);
374   pi2 = pi + (sizeof *pi + 100);
375   pi->max_length = 100;
376   pi->max_tries = 3;
377   pi->with_qualitybar = 1;
378   pi->with_repeat = 1;
379   pi2->max_length = 100;
380   pi2->max_tries = 3;
381   pi2->check_cb = reenter_compare_cb;
382   pi2->check_cb_arg = pi->pin;
383
384  next_try:
385   err = agent_askpin (ctrl, text1, NULL, initial_errtext, pi, NULL, 0);
386   xfree (initial_errtext);
387   initial_errtext = NULL;
388   if (!err)
389     {
390       if (check_passphrase_constraints (ctrl, pi->pin, &initial_errtext))
391         {
392           pi->failed_tries = 0;
393           pi2->failed_tries = 0;
394           goto next_try;
395         }
396       /* Unless the passphrase is empty or the pinentry told us that
397          it already did the repetition check, ask to confirm it.  */
398       if (*pi->pin && !pi->repeat_okay)
399         {
400           err = agent_askpin (ctrl, text2, NULL, NULL, pi2, NULL, 0);
401           if (err == -1)
402             { /* The re-entered one did not match and the user did not
403                  hit cancel. */
404               initial_errtext = xtrystrdup (L_("does not match - try again"));
405               if (initial_errtext)
406                 goto next_try;
407               err = gpg_error_from_syserror ();
408             }
409         }
410     }
411
412   if (!err && *pi->pin)
413     {
414       /* User wants a passphrase. */
415       *r_passphrase = xtrystrdup (pi->pin);
416       if (!*r_passphrase)
417         err = gpg_error_from_syserror ();
418     }
419
420   xfree (initial_errtext);
421   xfree (pi);
422   return err;
423 }
424
425
426
427 /* Generate a new keypair according to the parameters given in
428    KEYPARAM.  If CACHE_NONCE is given first try to lookup a passphrase
429    using the cache nonce.  If NO_PROTECTION is true the key will not
430    be protected by a passphrase.  If OVERRIDE_PASSPHRASE is true that
431    passphrase will be used for the new key.  */
432 int
433 agent_genkey (ctrl_t ctrl, const char *cache_nonce,
434               const char *keyparam, size_t keyparamlen, int no_protection,
435               const char *override_passphrase, int preset, membuf_t *outbuf)
436 {
437   gcry_sexp_t s_keyparam, s_key, s_private, s_public;
438   char *passphrase_buffer = NULL;
439   const char *passphrase;
440   int rc;
441   size_t len;
442   char *buf;
443
444   rc = gcry_sexp_sscan (&s_keyparam, NULL, keyparam, keyparamlen);
445   if (rc)
446     {
447       log_error ("failed to convert keyparam: %s\n", gpg_strerror (rc));
448       return gpg_error (GPG_ERR_INV_DATA);
449     }
450
451   /* Get the passphrase now, cause key generation may take a while. */
452   if (override_passphrase)
453     passphrase = override_passphrase;
454   else if (no_protection || !cache_nonce)
455     passphrase = NULL;
456   else
457     {
458       passphrase_buffer = agent_get_cache (cache_nonce, CACHE_MODE_NONCE);
459       passphrase = passphrase_buffer;
460     }
461
462   if (passphrase || no_protection)
463     ;
464   else
465     {
466       rc = agent_ask_new_passphrase (ctrl,
467                                      L_("Please enter the passphrase to%0A"
468                                         "protect your new key"),
469                                      &passphrase_buffer);
470       if (rc)
471         return rc;
472       passphrase = passphrase_buffer;
473     }
474
475   rc = gcry_pk_genkey (&s_key, s_keyparam );
476   gcry_sexp_release (s_keyparam);
477   if (rc)
478     {
479       log_error ("key generation failed: %s\n", gpg_strerror (rc));
480       xfree (passphrase_buffer);
481       return rc;
482     }
483
484   /* break out the parts */
485   s_private = gcry_sexp_find_token (s_key, "private-key", 0);
486   if (!s_private)
487     {
488       log_error ("key generation failed: invalid return value\n");
489       gcry_sexp_release (s_key);
490       xfree (passphrase_buffer);
491       return gpg_error (GPG_ERR_INV_DATA);
492     }
493   s_public = gcry_sexp_find_token (s_key, "public-key", 0);
494   if (!s_public)
495     {
496       log_error ("key generation failed: invalid return value\n");
497       gcry_sexp_release (s_private);
498       gcry_sexp_release (s_key);
499       xfree (passphrase_buffer);
500       return gpg_error (GPG_ERR_INV_DATA);
501     }
502   gcry_sexp_release (s_key); s_key = NULL;
503
504   /* store the secret key */
505   if (DBG_CRYPTO)
506     log_debug ("storing private key\n");
507   rc = store_key (s_private, passphrase, 0, ctrl->s2k_count);
508   if (!rc)
509     {
510       if (!cache_nonce)
511         {
512           char tmpbuf[12];
513           gcry_create_nonce (tmpbuf, 12);
514           cache_nonce = bin2hex (tmpbuf, 12, NULL);
515         }
516       if (cache_nonce
517           && !no_protection
518           && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
519                                passphrase, ctrl->cache_ttl_opt_preset))
520         agent_write_status (ctrl, "CACHE_NONCE", cache_nonce, NULL);
521       if (preset && !no_protection)
522         {
523           unsigned char grip[20];
524           char hexgrip[40+1];
525           if (gcry_pk_get_keygrip (s_private, grip))
526             {
527               bin2hex(grip, 20, hexgrip);
528               rc = agent_put_cache (hexgrip, CACHE_MODE_ANY, passphrase,
529                                     ctrl->cache_ttl_opt_preset);
530             }
531         }
532     }
533   xfree (passphrase_buffer);
534   passphrase_buffer = NULL;
535   passphrase = NULL;
536   gcry_sexp_release (s_private);
537   if (rc)
538     {
539       gcry_sexp_release (s_public);
540       return rc;
541     }
542
543   /* return the public key */
544   if (DBG_CRYPTO)
545     log_debug ("returning public key\n");
546   len = gcry_sexp_sprint (s_public, GCRYSEXP_FMT_CANON, NULL, 0);
547   assert (len);
548   buf = xtrymalloc (len);
549   if (!buf)
550     {
551       gpg_error_t tmperr = out_of_core ();
552       gcry_sexp_release (s_private);
553       gcry_sexp_release (s_public);
554       return tmperr;
555     }
556   len = gcry_sexp_sprint (s_public, GCRYSEXP_FMT_CANON, buf, len);
557   assert (len);
558   put_membuf (outbuf, buf, len);
559   gcry_sexp_release (s_public);
560   xfree (buf);
561
562   return 0;
563 }
564
565
566 \f
567 /* Apply a new passphrase to the key S_SKEY and store it.  If
568    PASSPHRASE_ADDR and *PASSPHRASE_ADDR are not NULL, use that
569    passphrase.  If PASSPHRASE_ADDR is not NULL store a newly entered
570    passphrase at that address. */
571 gpg_error_t
572 agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey,
573                          char **passphrase_addr)
574 {
575   gpg_error_t err;
576
577   if (passphrase_addr && *passphrase_addr)
578     {
579       /* Take an empty string as request not to protect the key.  */
580       err = store_key (s_skey, **passphrase_addr? *passphrase_addr:NULL, 1,
581               ctrl->s2k_count);
582     }
583   else
584     {
585       char *pass = NULL;
586
587       if (passphrase_addr)
588         {
589           xfree (*passphrase_addr);
590           *passphrase_addr = NULL;
591         }
592       err = agent_ask_new_passphrase (ctrl,
593                                       L_("Please enter the new passphrase"),
594                                       &pass);
595       if (!err)
596         err = store_key (s_skey, pass, 1, ctrl->s2k_count);
597       if (!err && passphrase_addr)
598         *passphrase_addr = pass;
599       else
600         xfree (pass);
601     }
602
603   return err;
604 }