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