ecf676eff06680156c4d4f6aa4ebbb89b60bc533
[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 = 0;
183   unsigned int minlen = opt.min_passphrase_len;
184   unsigned int minnonalpha = opt.min_passphrase_nonalpha;
185   char *msg1 = NULL;
186   char *msg2 = NULL;
187   char *msg3 = NULL;
188
189   if (!pw)
190     pw = "";
191
192   /* The first check is to warn about an empty passphrase. */
193   if (!*pw)
194     {
195       const char *desc = (opt.enforce_passphrase_constraints?
196                           _("You have not entered a passphrase!%0A"
197                             "An empty passphrase is not allowed.") :
198                           _("You have not entered a passphrase - "
199                             "this is in general a bad idea!%0A"
200                             "Please confirm that you do not want to "
201                             "have any protection on your key."));
202
203       if (silent)
204         return gpg_error (GPG_ERR_INV_PASSPHRASE);
205
206       err = take_this_one_anyway2 (ctrl, desc,
207                                    _("Yes, protection is not needed"));
208       goto leave;
209     }
210
211   /* Now check the constraints and collect the error messages unless
212      in in silent mode which returns immediately.  */
213   if (utf8_charcount (pw) < minlen )
214     {
215       if (silent)
216         {
217           err = gpg_error (GPG_ERR_INV_PASSPHRASE);
218           goto leave;
219         }
220
221       msg1 = xtryasprintf
222         ( ngettext ("A passphrase should be at least %u character long.",
223                     "A passphrase should be at least %u characters long.",
224                     minlen), minlen );
225       if (!msg1)
226         {
227           err = gpg_error_from_syserror ();
228           goto leave;
229         }
230     }
231
232   if (nonalpha_count (pw) < minnonalpha )
233     {
234       if (silent)
235         {
236           err = gpg_error (GPG_ERR_INV_PASSPHRASE);
237           goto leave;
238         }
239
240       msg2 = xtryasprintf
241         ( ngettext ("A passphrase should contain at least %u digit or%%0A"
242                     "special character.",
243                     "A passphrase should contain at least %u digits or%%0A"
244                     "special characters.",
245                     minnonalpha), minnonalpha );
246       if (!msg2)
247         {
248           err = gpg_error_from_syserror ();
249           goto leave;
250         }
251     }
252
253   /* If configured check the passphrase against a list of known words
254      and pattern.  The actual test is done by an external program.
255      The warning message is generic to give the user no hint on how to
256      circumvent this list.  */
257   if (*pw && opt.check_passphrase_pattern &&
258       check_passphrase_pattern (ctrl, pw))
259     {
260       if (silent)
261         {
262           err = gpg_error (GPG_ERR_INV_PASSPHRASE);
263           goto leave;
264         }
265
266       msg3 = xtryasprintf
267         (_("A passphrase may not be a known term or match%%0A"
268            "certain pattern."));
269       if (!msg3)
270         {
271           err = gpg_error_from_syserror ();
272           goto leave;
273         }
274     }
275
276   if (msg1 || msg2 || msg3)
277     {
278       char *msg;
279       size_t n;
280
281       msg = strconcat
282         (_("Warning: You have entered an insecure passphrase."),
283          "%0A%0A",
284          msg1? msg1 : "", msg1? "%0A" : "",
285          msg2? msg2 : "", msg2? "%0A" : "",
286          msg3? msg3 : "", msg3? "%0A" : "",
287          NULL);
288       if (!msg)
289         {
290           err = gpg_error_from_syserror ();
291           goto leave;
292         }
293       /* Strip a trailing "%0A".  */
294       n = strlen (msg);
295       if (n > 3 && !strcmp (msg + n - 3, "%0A"))
296         msg[n-3] = 0;
297
298       /* Show error messages.  */
299       err = take_this_one_anyway (ctrl, msg);
300       xfree (msg);
301     }
302
303  leave:
304   xfree (msg1);
305   xfree (msg2);
306   xfree (msg3);
307   return err;
308 }
309
310
311 /* Callback function to compare the first entered PIN with the one
312    currently being entered. */
313 static int
314 reenter_compare_cb (struct pin_entry_info_s *pi)
315 {
316   const char *pin1 = pi->check_cb_arg;
317
318   if (!strcmp (pin1, pi->pin))
319     return 0; /* okay */
320   return -1;
321 }
322
323
324 /* Ask the user for a new passphrase using PROMPT.  On success the
325    function returns 0 and store the passphrase at R_PASSPHRASE; if the
326    user opted not to use a passphrase NULL will be stored there.  The
327    user needs to free the returned string.  In case of an error and
328    error code is returned and NULL stored at R_PASSPHRASE.  */
329 gpg_error_t
330 agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
331                           char **r_passphrase)
332 {
333   gpg_error_t err;
334   const char *text1 = prompt;
335   const char *text2 = _("Please re-enter this passphrase");
336   const char *initial_errtext = NULL;
337   struct pin_entry_info_s *pi, *pi2;
338
339   *r_passphrase = NULL;
340
341   if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
342     {
343         size_t size;
344         size_t len = 100;
345         unsigned char *buffer;
346
347         err = pinentry_loopback(ctrl, "NEW_PASSPHRASE", &buffer, &size, len);
348         if (!err)
349           {
350             if (size)
351               {
352                 buffer[size] = 0;
353                 *r_passphrase = buffer;
354               }
355             else
356                 *r_passphrase = NULL;
357           }
358         return err;
359     }
360
361   pi = gcry_calloc_secure (2, sizeof (*pi) + 100);
362   pi2 = pi + (sizeof *pi + 100);
363   pi->max_length = 100;
364   pi->max_tries = 3;
365   pi->with_qualitybar = 1;
366   pi->with_repeat = 1;
367   pi2->max_length = 100;
368   pi2->max_tries = 3;
369   pi2->check_cb = reenter_compare_cb;
370   pi2->check_cb_arg = pi->pin;
371
372  next_try:
373   err = agent_askpin (ctrl, text1, NULL, initial_errtext, pi);
374   initial_errtext = NULL;
375   if (!err)
376     {
377       if (check_passphrase_constraints (ctrl, pi->pin, 0))
378         {
379           pi->failed_tries = 0;
380           pi2->failed_tries = 0;
381           goto next_try;
382         }
383       /* Unless the passphrase is empty or the pinentry told us that
384          it already did the repetition check, ask to confirm it.  */
385       if (*pi->pin && !pi->repeat_okay)
386         {
387           err = agent_askpin (ctrl, text2, NULL, NULL, pi2);
388           if (err == -1)
389             { /* The re-entered one did not match and the user did not
390                  hit cancel. */
391               initial_errtext = _("does not match - try again");
392               goto next_try;
393             }
394         }
395     }
396
397   if (!err && *pi->pin)
398     {
399       /* User wants a passphrase. */
400       *r_passphrase = xtrystrdup (pi->pin);
401       if (!*r_passphrase)
402         err = gpg_error_from_syserror ();
403     }
404   xfree (pi);
405   return err;
406 }
407
408
409
410 /* Generate a new keypair according to the parameters given in
411    KEYPARAM.  If CACHE_NONCE is given first try to lookup a passphrase
412    using the cache nonce.  If NO_PROTECTION is true the key will not
413    be protected by a passphrase.  If OVERRIDE_PASSPHRASE is true that
414    passphrase will be used for the new key.  */
415 int
416 agent_genkey (ctrl_t ctrl, const char *cache_nonce,
417               const char *keyparam, size_t keyparamlen, int no_protection,
418               const char *override_passphrase, int preset, membuf_t *outbuf)
419 {
420   gcry_sexp_t s_keyparam, s_key, s_private, s_public;
421   char *passphrase_buffer = NULL;
422   const char *passphrase;
423   int rc;
424   size_t len;
425   char *buf;
426
427   rc = gcry_sexp_sscan (&s_keyparam, NULL, keyparam, keyparamlen);
428   if (rc)
429     {
430       log_error ("failed to convert keyparam: %s\n", gpg_strerror (rc));
431       return gpg_error (GPG_ERR_INV_DATA);
432     }
433
434   /* Get the passphrase now, cause key generation may take a while. */
435   if (override_passphrase)
436     passphrase = override_passphrase;
437   else if (no_protection || !cache_nonce)
438     passphrase = NULL;
439   else
440     {
441       passphrase_buffer = agent_get_cache (cache_nonce, CACHE_MODE_NONCE);
442       passphrase = passphrase_buffer;
443     }
444
445   if (passphrase || no_protection)
446     ;
447   else
448     {
449       rc = agent_ask_new_passphrase (ctrl,
450                                      _("Please enter the passphrase to%0A"
451                                        "protect your new key"),
452                                      &passphrase_buffer);
453       if (rc)
454         return rc;
455       passphrase = passphrase_buffer;
456     }
457
458   rc = gcry_pk_genkey (&s_key, s_keyparam );
459   gcry_sexp_release (s_keyparam);
460   if (rc)
461     {
462       log_error ("key generation failed: %s\n", gpg_strerror (rc));
463       xfree (passphrase_buffer);
464       return rc;
465     }
466
467   /* break out the parts */
468   s_private = gcry_sexp_find_token (s_key, "private-key", 0);
469   if (!s_private)
470     {
471       log_error ("key generation failed: invalid return value\n");
472       gcry_sexp_release (s_key);
473       xfree (passphrase_buffer);
474       return gpg_error (GPG_ERR_INV_DATA);
475     }
476   s_public = gcry_sexp_find_token (s_key, "public-key", 0);
477   if (!s_public)
478     {
479       log_error ("key generation failed: invalid return value\n");
480       gcry_sexp_release (s_private);
481       gcry_sexp_release (s_key);
482       xfree (passphrase_buffer);
483       return gpg_error (GPG_ERR_INV_DATA);
484     }
485   gcry_sexp_release (s_key); s_key = NULL;
486
487   /* store the secret key */
488   if (DBG_CRYPTO)
489     log_debug ("storing private key\n");
490   rc = store_key (s_private, passphrase, 0, ctrl->s2k_count);
491   if (!rc)
492     {
493       if (!cache_nonce)
494         {
495           char tmpbuf[12];
496           gcry_create_nonce (tmpbuf, 12);
497           cache_nonce = bin2hex (tmpbuf, 12, NULL);
498         }
499       if (cache_nonce
500           && !no_protection
501           && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
502                                passphrase, ctrl->cache_ttl_opt_preset))
503         agent_write_status (ctrl, "CACHE_NONCE", cache_nonce, NULL);
504       if (preset && !no_protection)
505         {
506           unsigned char grip[20];
507           char hexgrip[40+1];
508           if (gcry_pk_get_keygrip (s_private, grip))
509             {
510               bin2hex(grip, 20, hexgrip);
511               rc = agent_put_cache (hexgrip, CACHE_MODE_ANY, passphrase,
512                                     ctrl->cache_ttl_opt_preset);
513             }
514         }
515     }
516   xfree (passphrase_buffer);
517   passphrase_buffer = NULL;
518   passphrase = NULL;
519   gcry_sexp_release (s_private);
520   if (rc)
521     {
522       gcry_sexp_release (s_public);
523       return rc;
524     }
525
526   /* return the public key */
527   if (DBG_CRYPTO)
528     log_debug ("returning public key\n");
529   len = gcry_sexp_sprint (s_public, GCRYSEXP_FMT_CANON, NULL, 0);
530   assert (len);
531   buf = xtrymalloc (len);
532   if (!buf)
533     {
534       gpg_error_t tmperr = out_of_core ();
535       gcry_sexp_release (s_private);
536       gcry_sexp_release (s_public);
537       return tmperr;
538     }
539   len = gcry_sexp_sprint (s_public, GCRYSEXP_FMT_CANON, buf, len);
540   assert (len);
541   put_membuf (outbuf, buf, len);
542   gcry_sexp_release (s_public);
543   xfree (buf);
544
545   return 0;
546 }
547
548
549 \f
550 /* Apply a new passphrase to the key S_SKEY and store it.  If
551    PASSPHRASE_ADDR and *PASSPHRASE_ADDR are not NULL, use that
552    passphrase.  If PASSPHRASE_ADDR is not NULL store a newly entered
553    passphrase at that address. */
554 gpg_error_t
555 agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey,
556                          char **passphrase_addr)
557 {
558   gpg_error_t err;
559
560   if (passphrase_addr && *passphrase_addr)
561     {
562       /* Take an empty string as request not to protect the key.  */
563       err = store_key (s_skey, **passphrase_addr? *passphrase_addr:NULL, 1,
564               ctrl->s2k_count);
565     }
566   else
567     {
568       char *pass = NULL;
569
570       if (passphrase_addr)
571         {
572           xfree (*passphrase_addr);
573           *passphrase_addr = NULL;
574         }
575       err = agent_ask_new_passphrase (ctrl,
576                                       _("Please enter the new passphrase"),
577                                       &pass);
578       if (!err)
579         err = store_key (s_skey, pass, 1, ctrl->s2k_count);
580       if (!err && passphrase_addr)
581         *passphrase_addr = pass;
582       else
583         xfree (pass);
584     }
585
586   return err;
587 }