* protect.c (do_encryption): Use gcry_create_nonce instad of the
[gnupg.git] / agent / genkey.c
index 630e0e3..1417abb 100644 (file)
@@ -1,5 +1,5 @@
 /* pksign.c - Generate a keypair
- *     Copyright (C) 2002 Free Software Foundation, Inc.
+ *     Copyright (C) 2002, 2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include <assert.h>
 
 #include "agent.h"
-
+#include "i18n.h"
 
 static int
-store_key (GCRY_SEXP private, const char *passphrase)
+store_key (gcry_sexp_t private, const char *passphrase, int force)
 {
   int rc;
   char *buf;
@@ -40,14 +40,14 @@ store_key (GCRY_SEXP private, const char *passphrase)
   if ( !gcry_pk_get_keygrip (private, grip) )
     {
       log_error ("can't calculate keygrip\n");
-      return seterr (General_Error);
+      return gpg_error (GPG_ERR_GENERAL);
     }
 
   len = gcry_sexp_sprint (private, GCRYSEXP_FMT_CANON, NULL, 0);
   assert (len);
   buf = gcry_malloc_secure (len);
   if (!buf)
-      return seterr (Out_Of_Core);
+      return out_of_core ();
   len = gcry_sexp_sprint (private, GCRYSEXP_FMT_CANON, buf, len);
   assert (len);
 
@@ -65,13 +65,13 @@ store_key (GCRY_SEXP private, const char *passphrase)
       buf = p;
     }
 
-  rc = agent_write_private_key (grip, buf, len, 0);
+  rc = agent_write_private_key (grip, buf, len, force);
   xfree (buf);
   return rc;
 }
 
 /* Callback function to compare the first entered PIN with the one
-   currently beeing entered. */
+   currently being entered. */
 static int
 reenter_compare_cb (struct pin_entry_info_s *pi)
 {
@@ -79,7 +79,7 @@ reenter_compare_cb (struct pin_entry_info_s *pi)
 
   if (!strcmp (pin1, pi->pin))
     return 0; /* okay */
-  pi->cb_errtext = trans ("does not match - try again");
+  pi->cb_errtext = _("does not match - try again");
   return -1;
 }
 
@@ -91,7 +91,7 @@ int
 agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
               FILE *outfp) 
 {
-  GCRY_SEXP s_keyparam, s_key, s_private, s_public;
+  gcry_sexp_t s_keyparam, s_key, s_private, s_public;
   struct pin_entry_info_s *pi, *pi2;
   int rc;
   size_t len;
@@ -100,15 +100,15 @@ agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
   rc = gcry_sexp_sscan (&s_keyparam, NULL, keyparam, keyparamlen);
   if (rc)
     {
-      log_error ("failed to convert keyparam: %s\n", gcry_strerror (rc));
-      return seterr (Invalid_Data);
+      log_error ("failed to convert keyparam: %s\n", gpg_strerror (rc));
+      return gpg_error (GPG_ERR_INV_DATA);
     }
 
   /* Get the passphrase now, cause key generation may take a while. */
   {
-    const char *text1 = trans ("Please enter the passphrase to%0A"
+    const char *text1 = _("Please enter the passphrase to%0A"
                                "to protect your new key");
-    const char *text2 = trans ("Please re-enter this passphrase");
+    const char *text2 = _("Please re-enter this passphrase");
 
     pi = gcry_calloc_secure (2, sizeof (*pi) + 100);
     pi2 = pi + (sizeof *pi + 100);
@@ -119,9 +119,9 @@ agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
     pi2->check_cb = reenter_compare_cb;
     pi2->check_cb_arg = pi->pin;
 
-    rc = agent_askpin (text1, pi);
+    rc = agent_askpin (ctrl, text1, pi);
     if (!rc)
-      rc = agent_askpin (text2, pi2);
+      rc = agent_askpin (ctrl, text2, pi2);
     if (rc)
       return rc;
     if (!*pi->pin)
@@ -135,9 +135,9 @@ agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
   gcry_sexp_release (s_keyparam);
   if (rc)
     {
-      log_error ("key generation failed: %s\n", gcry_strerror (rc));
+      log_error ("key generation failed: %s\n", gpg_strerror (rc));
       xfree (pi);
-      return map_gcry_err (rc);
+      return rc;
     }
 
   /* break out the parts */
@@ -147,7 +147,7 @@ agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
       log_error ("key generation failed: invalid return value\n");
       gcry_sexp_release (s_key);
       xfree (pi);
-      return seterr (Invalid_Data);
+      return gpg_error (GPG_ERR_INV_DATA);
     }
   s_public = gcry_sexp_find_token (s_key, "public-key", 0);
   if (!s_public)
@@ -156,13 +156,13 @@ agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
       gcry_sexp_release (s_private);
       gcry_sexp_release (s_key);
       xfree (pi);
-      return seterr (Invalid_Data);
+      return gpg_error (GPG_ERR_INV_DATA);
     }
   gcry_sexp_release (s_key); s_key = NULL;
   
   /* store the secret key */
   log_debug ("storing private key\n");
-  rc = store_key (s_private, pi? pi->pin:NULL);
+  rc = store_key (s_private, pi? pi->pin:NULL, 0);
   xfree (pi); pi = NULL;
   gcry_sexp_release (s_private);
   if (rc)
@@ -175,22 +175,24 @@ agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
   log_debug ("returning public key\n");
   len = gcry_sexp_sprint (s_public, GCRYSEXP_FMT_CANON, NULL, 0);
   assert (len);
-  buf = xmalloc (len);
+  buf = xtrymalloc (len);
   if (!buf)
     {
+      gpg_error_t tmperr = out_of_core ();
       gcry_sexp_release (s_private);
       gcry_sexp_release (s_public);
-      return seterr (Out_Of_Core);
+      return tmperr;
     }
   len = gcry_sexp_sprint (s_public, GCRYSEXP_FMT_CANON, buf, len);
   assert (len);
   if (fwrite (buf, len, 1, outfp) != 1)
     {
+      gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
       log_error ("error writing public key: %s\n", strerror (errno));
       gcry_sexp_release (s_private);
       gcry_sexp_release (s_public);
       xfree (buf);
-      return seterr (File_Create_Error);
+      return tmperr;
     }
   gcry_sexp_release (s_public);
   xfree (buf);
@@ -198,3 +200,41 @@ agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
   return 0;
 }
 
+
+\f
+/* Apply a new passpahrse to the key S_SKEY and store it. */
+int
+agent_protect_and_store (CTRL ctrl, gcry_sexp_t s_skey) 
+{
+  struct pin_entry_info_s *pi, *pi2;
+  int rc;
+
+  {
+    const char *text1 = _("Please enter the new passphrase");
+    const char *text2 = _("Please re-enter this passphrase");
+
+    pi = gcry_calloc_secure (2, sizeof (*pi) + 100);
+    pi2 = pi + (sizeof *pi + 100);
+    pi->max_length = 100;
+    pi->max_tries = 3;
+    pi2->max_length = 100;
+    pi2->max_tries = 3;
+    pi2->check_cb = reenter_compare_cb;
+    pi2->check_cb_arg = pi->pin;
+
+    rc = agent_askpin (ctrl, text1, pi);
+    if (!rc)
+      rc = agent_askpin (ctrl, text2, pi2);
+    if (rc)
+      return rc;
+    if (!*pi->pin)
+      {
+        xfree (pi);
+        pi = NULL; /* User does not want a passphrase. */
+      }
+  }
+
+  rc = store_key (s_skey, pi? pi->pin:NULL, 1);
+  xfree (pi);
+  return 0;
+}