[git] GnuPG - branch, master, updated. gnupg-2.1.0-beta442-42-g03018ef

by Werner Koch cvs at cvs.gnupg.org
Mon Jun 30 16:43:45 CEST 2014


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  03018ef9eec75e4d91ea53c95547a77dedef8f80 (commit)
       via  aa5b4392aac99382d96be94782ae745e0a42484a (commit)
       via  3a01b220715b3d1a90d94353e4980ab5a1ea8f26 (commit)
      from  c434de4d83ccfaca8bde51de5c2ac8d9656e4e18 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 03018ef9eec75e4d91ea53c95547a77dedef8f80
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Jun 25 20:25:28 2014 +0200

    gpg: Auto-create revocation certificates.
    
    * configure.ac (GNUPG_OPENPGP_REVOC_DIR): New config define.
    * g10/revoke.c (create_revocation): Add arg "leadin".
    (gen_standard_revoke): New.
    * g10/openfile.c (get_openpgp_revocdir): New.
    (open_outfile): Add MODE value 3.
    * g10/keyid.c (hexfingerprint): New.
    * g10/keygen.c (do_generate_keypair): Call gen_standard_revoke.
    --
    
    GnuPG-bug-id: 1042

diff --git a/configure.ac b/configure.ac
index e26e51b..02e02bb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -444,7 +444,8 @@ AH_BOTTOM([
 #else
 #define GNUPG_DEFAULT_HOMEDIR "~/.gnupg"
 #endif
-#define GNUPG_PRIVATE_KEYS_DIR "private-keys-v1.d"
+#define GNUPG_PRIVATE_KEYS_DIR  "private-keys-v1.d"
+#define GNUPG_OPENPGP_REVOC_DIR "openpgp-revocs.d"
 
 /* For some systems (DOS currently), we hardcode the path here.  For
    POSIX systems the values are constructed by the Makefiles, so that
diff --git a/doc/gpg.texi b/doc/gpg.texi
index 9c52282..5efc16e 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -3106,6 +3106,15 @@ files; They all live in in the current home directory (@pxref{option
   @item ~/.gnupg/secring.gpg.lock
   The lock file for the secret keyring.
 
+  @item ~/.gnupg/openpgp-revocs.d/
+  This is the directory where gpg stores pre-generated revocation
+  certificates.  It is suggested to backup those certificates and if the
+  primary private key is not stored on the disk to move them to an
+  external storage device.  Anyone who can access theses files is able to
+  revoke the corresponding key.  You may want to print them out.  You
+  should backup all files in this directory and take care to keep this
+  backup closed away.
+
   @item /usr[/local]/share/gnupg/options.skel
   The skeleton options file.
 
diff --git a/g10/keydb.h b/g10/keydb.h
index b21d955..0cf6ca1 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -288,6 +288,7 @@ const char *colon_datestr_from_pk (PKT_public_key *pk);
 const char *colon_datestr_from_sig (PKT_signature *sig);
 const char *colon_expirestr_from_sig (PKT_signature *sig);
 byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len );
+char *hexfingerprint (PKT_public_key *pk);
 gpg_error_t keygrip_from_pk (PKT_public_key *pk, unsigned char *array);
 gpg_error_t hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip);
 
diff --git a/g10/keygen.c b/g10/keygen.c
index 35c1460..4509231 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -4000,6 +4000,8 @@ do_generate_keypair (struct para_data_s *para,
           update_ownertrust (pk, ((get_ownertrust (pk) & ~TRUST_MASK)
                                   | TRUST_ULTIMATE ));
 
+          gen_standard_revoke (pk);
+
           if (!opt.batch)
             {
               tty_printf (_("public and secret key created and signed.\n") );
diff --git a/g10/keyid.c b/g10/keyid.c
index 9c94bd6..6ce6f32 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -772,6 +772,20 @@ fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
 }
 
 
+/* Return an allocated buffer with the fingerprint of PK formatted as
+   a plain hexstring.  */
+char *
+hexfingerprint (PKT_public_key *pk)
+{
+  unsigned char fpr[MAX_FINGERPRINT_LEN];
+  size_t len;
+  char *result;
+
+  fingerprint_from_pk (pk, fpr, &len);
+  result = xmalloc (2 * len + 1);
+  bin2hex (fpr, len, result);
+  return result;
+}
 
 
 

diff --git a/g10/main.h b/g10/main.h
index ae0bc8c..e75f616 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -274,6 +274,7 @@ int open_outfile (int inp_fd, const char *iname, int mode,
                   int restrictedperm, iobuf_t *a);
 iobuf_t open_sigfile( const char *iname, progress_filter_context_t *pfx );
 void try_make_homedir( const char *fname );
+char *get_openpgp_revocdir (const char *home);
 
 /*-- seskey.c --*/
 void make_session_key( DEK *dek );
@@ -317,6 +318,7 @@ int enarmor_file( const char *fname );
 
 /*-- revoke.c --*/
 struct revocation_reason_info;
+int gen_standard_revoke (PKT_public_key *psk);
 int gen_revoke( const char *uname );
 int gen_desig_revoke( const char *uname, strlist_t locusr);
 int revocation_reason_build_cb( PKT_signature *sig, void *opaque );
diff --git a/g10/openfile.c b/g10/openfile.c
index 901387d..5a43648 100644
--- a/g10/openfile.c
+++ b/g10/openfile.c
@@ -174,9 +174,10 @@ ask_outfile_name( const char *name, size_t namelen )
  * Mode 0 = use ".gpg"
  *	1 = use ".asc"
  *	2 = use ".sig"
+ *      3 = use ".rev"
  *
  * If INP_FD is not -1 the function simply creates an IOBUF for that
- * file descriptor and ignorea INAME and MODE.  Note that INP_FD won't
+ * file descriptor and ignore INAME and MODE.  Note that INP_FD won't
  * be closed if the returned IOBUF is closed.  With RESTRICTEDPERM a
  * file will be created with mode 700 if possible.
  */
@@ -239,7 +240,8 @@ open_outfile (int inp_fd, const char *iname, int mode, int restrictedperm,
               const char *newsfx;
 
               newsfx = (mode==1 ? ".asc" :
-                        mode==2 ? ".sig" : ".gpg");
+                        mode==2 ? ".sig" :
+                        mode==3 ? ".rev" : ".gpg");
 
               buf = xmalloc (strlen(iname)+4+1);
               strcpy (buf, iname);
@@ -258,6 +260,7 @@ open_outfile (int inp_fd, const char *iname, int mode, int restrictedperm,
               buf = xstrconcat (iname,
                                 (mode==1 ? EXTSEP_S "asc" :
                                  mode==2 ? EXTSEP_S "sig" :
+                                 mode==3 ? EXTSEP_S "rev" :
                                  /*     */ EXTSEP_S GPGEXT_GPG),
                                 NULL);
             }
@@ -451,3 +454,24 @@ try_make_homedir (const char *fname)
       copy_options_file( fname );
     }
 }
+
+
+/* Get and if needed create a string with the directory used to store
+   openpgp revocations.  */
+char *
+get_openpgp_revocdir (const char *home)
+{
+  char *fname;
+  struct stat statbuf;
+
+  fname = make_filename (home, GNUPG_OPENPGP_REVOC_DIR, NULL);
+  if (stat (fname, &statbuf) && errno == ENOENT)
+    {
+      if (gnupg_mkdir (fname, "-rwx"))
+        log_error (_("can't create directory '%s': %s\n"),
+                   fname, strerror (errno) );
+      else if (!opt.quiet)
+        log_info (_("directory '%s' created\n"), fname);
+    }
+  return fname;
+}
diff --git a/g10/passphrase.c b/g10/passphrase.c
index 280d8a9..9d3f497 100644
--- a/g10/passphrase.c
+++ b/g10/passphrase.c
@@ -633,7 +633,8 @@ emit_status_need_passphrase (u32 *keyid, u32 *mainkeyid, int pubkey_algo)
 
 /* Return an allocated utf-8 string describing the key PK.  If ESCAPED
    is true spaces and control characters are percent or plus escaped.
-   MODE 0 is for the common prompt, MODE 1 for the import prompt. */
+   MODE describes the use of the key description; use one of the
+   FORMAT_KEYDESC_ macros. */
 char *
 gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped)
 {
diff --git a/g10/revoke.c b/g10/revoke.c
index 069453e..bf5e33b 100644
--- a/g10/revoke.c
+++ b/g10/revoke.c
@@ -436,12 +436,14 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
    revocation reason.  PSK is the public primary key - we expect that
    a corresponding secret key is available.  KEYBLOCK is the entire
    KEYBLOCK which is used in PGP mode to write a a minimal key and not
-   just the naked revocation signature; it may be NULL.  */
+   just the naked revocation signature; it may be NULL.  If LEADINTEXT
+   is not NULL, it is written right before the (armored) output.*/
 static int
 create_revocation (const char *filename,
                    struct revocation_reason_info *reason,
                    PKT_public_key *psk,
-                   kbnode_t keyblock)
+                   kbnode_t keyblock,
+                   const char *leadintext, int suffix)
 {
   int rc;
   iobuf_t out = NULL;
@@ -451,9 +453,12 @@ create_revocation (const char *filename,
 
   afx = new_armor_context ();
 
-  if ((rc = open_outfile (-1, filename, 0, 1, &out)))
+  if ((rc = open_outfile (-1, filename, suffix, 1, &out)))
     goto leave;
 
+  if (leadintext )
+    iobuf_writestr (out, leadintext);
+
   afx->what = 1;
   afx->hdrlines = "Comment: This is a revocation certificate\n";
   push_armor_filter (afx, out);
@@ -502,6 +507,81 @@ create_revocation (const char *filename,
 }
 
 
+/* This function is used to generate a standard revocation certificate
+   by gpg's interactive key generation function.  The certificate is
+   stored at a dedicated place in a slightly modified form to avoid an
+   accidental import.  PSK is the primary key; a corresponding secret
+   key must be available.  */
+int
+gen_standard_revoke (PKT_public_key *psk)
+{
+  int rc;
+  estream_t memfp;
+  struct revocation_reason_info reason;
+  char *dir, *tmpstr, *fname;
+  void *leadin;
+  size_t len;
+  u32 keyid[2];
+  char pkstrbuf[PUBKEY_STRING_SIZE];
+  char *orig_codeset;
+
+  dir = get_openpgp_revocdir (opt.homedir);
+  tmpstr = hexfingerprint (psk);
+  fname = xstrconcat (dir, DIRSEP_S, tmpstr, NULL);
+  xfree (tmpstr);
+  xfree (dir);
+
+  keyid_from_pk (psk, keyid);
+
+  memfp = es_fopenmem (0, "r+");
+  if (!memfp)
+    log_fatal ("error creating memory stream\n");
+
+  orig_codeset = i18n_switchto_utf8 ();
+
+  es_fprintf (memfp, "%s\n\n",
+              _("This is a revocation certificate for the OpenPGP key:"));
+
+  es_fprintf (memfp, "pub  %s/%s %s\n",
+              pubkey_string (psk, pkstrbuf, sizeof pkstrbuf),
+              keystr (keyid),
+              datestr_from_pk (psk));
+
+  print_fingerprint (memfp, psk, 3);
+
+  tmpstr = get_user_id (keyid, &len);
+  es_fprintf (memfp, "uid%*s%.*s\n\n",
+              (int)keystrlen () + 10, "",
+              (int)len, tmpstr);
+  xfree (tmpstr);
+
+  es_fprintf (memfp, "%s\n\n%s\n\n:",
+     _("Use it to revoke this key in case of a compromise or loss of\n"
+       "the secret key.  However, if the secret key is still accessible,\n"
+       "it is better to generate a new revocation certificate and give\n"
+       "a reason for the revocation."),
+     _("To avoid an accidental use of this file, a colon has been inserted\n"
+       "before the 5 dashes below.  Remove this colon with a text editor\n"
+       "before making use of this revocation certificate."));
+
+  es_putc (0, memfp);
+
+  i18n_switchback (orig_codeset);
+
+  if (es_fclose_snatch (memfp, &leadin, NULL))
+    log_fatal ("error snatching memory stream\n");
+
+  reason.code = 0x00; /* No particular reason.  */
+  reason.desc = NULL;
+  rc = create_revocation (fname, &reason, psk, NULL, leadin, 3);
+  xfree (leadin);
+  xfree (fname);
+
+  return rc;
+}
+
+
+
 /****************
  * Generate a revocation certificate for UNAME
  */
@@ -582,7 +662,7 @@ gen_revoke (const char *uname)
   if (!opt.armor)
     tty_printf (_("ASCII armored output forced.\n"));
 
-  rc = create_revocation (NULL, reason, psk, keyblock);
+  rc = create_revocation (NULL, reason, psk, keyblock, NULL, 0);
   if (rc)
     goto leave;
 
diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am
index ea1d54f..4b1c219 100644
--- a/tests/openpgp/Makefile.am
+++ b/tests/openpgp/Makefile.am
@@ -77,7 +77,7 @@ CLEANFILES = prepared.stamp x y yy z out err  $(data_files) \
 	     gnupg-test.stop pubring.gpg~ random_seed gpg-agent.log
 
 clean-local:
-	-rm -rf private-keys-v1.d
+	-rm -rf private-keys-v1.d openpgp-revocs.d
 
 
 # We need to depend on a couple of programs so that the tests don't

commit aa5b4392aac99382d96be94782ae745e0a42484a
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Jun 25 20:25:28 2014 +0200

    estream: Fix minor glitch in "%.*s" format.
    
    * common/estream-printf.c (pr_string): Take care of non-nul terminated
    strings.

diff --git a/common/estream-printf.c b/common/estream-printf.c
index 11e6d75..c03f70e 100644
--- a/common/estream-printf.c
+++ b/common/estream-printf.c
@@ -1209,7 +1209,9 @@ pr_string (estream_printf_out_t outfnc, void *outfncarg,
     string = "(null)";
   if (arg->precision >= 0)
     {
-      for (n=0,s=string; *s && n < arg->precision; s++)
+      /* Test for nul after N so that we can pass a non-nul terminated
+         string.  */
+      for (n=0,s=string; n < arg->precision && *s; s++)
         n++;
     }
   else

commit 3a01b220715b3d1a90d94353e4980ab5a1ea8f26
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Jun 25 20:25:28 2014 +0200

    gpg: Rearrange code in gen_revoke.
    
    * g10/revoke.c (gen_revoke): Factor some code out to ...
    (create_revocation): new.

diff --git a/g10/revoke.c b/g10/revoke.c
index 1c52dda..069453e 100644
--- a/g10/revoke.c
+++ b/g10/revoke.c
@@ -431,6 +431,77 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
 }
 
 
+/* Common core to create the revocation. FILENAME may be NULL to write
+   to stdout or the filename given by --output.  REASON describes the
+   revocation reason.  PSK is the public primary key - we expect that
+   a corresponding secret key is available.  KEYBLOCK is the entire
+   KEYBLOCK which is used in PGP mode to write a a minimal key and not
+   just the naked revocation signature; it may be NULL.  */
+static int
+create_revocation (const char *filename,
+                   struct revocation_reason_info *reason,
+                   PKT_public_key *psk,
+                   kbnode_t keyblock)
+{
+  int rc;
+  iobuf_t out = NULL;
+  armor_filter_context_t *afx;
+  PKT_signature *sig = NULL;
+  PACKET pkt;
+
+  afx = new_armor_context ();
+
+  if ((rc = open_outfile (-1, filename, 0, 1, &out)))
+    goto leave;
+
+  afx->what = 1;
+  afx->hdrlines = "Comment: This is a revocation certificate\n";
+  push_armor_filter (afx, out);
+
+  rc = make_keysig_packet (&sig, psk, NULL, NULL, psk, 0x20, 0,
+                           opt.force_v4_certs? 4:0,
+                           0, 0,
+                           revocation_reason_build_cb, reason, NULL);
+  if (rc)
+    {
+      log_error (_("make_keysig_packet failed: %s\n"), g10_errstr (rc));
+      goto leave;
+    }
+
+  if (keyblock && (PGP2 || PGP6 || PGP7 || PGP8))
+    {
+      /* Use a minimal pk for PGPx mode, since PGP can't import bare
+         revocation certificates. */
+      rc = export_minimal_pk (out, keyblock, sig, NULL);
+      if (rc)
+        goto leave;
+    }
+  else
+    {
+      init_packet (&pkt);
+      pkt.pkttype = PKT_SIGNATURE;
+      pkt.pkt.signature = sig;
+
+      rc = build_packet (out, &pkt);
+      if (rc)
+        {
+          log_error (_("build_packet failed: %s\n"), g10_errstr (rc));
+          goto leave;
+        }
+    }
+
+ leave:
+  if (sig)
+    free_seckey_enc (sig);
+  if (rc)
+    iobuf_cancel (out);
+  else
+    iobuf_close (out);
+  release_armor_context (afx);
+  return rc;
+}
+
+
 /****************
  * Generate a revocation certificate for UNAME
  */
@@ -438,12 +509,8 @@ int
 gen_revoke (const char *uname)
 {
   int rc = 0;
-  armor_filter_context_t *afx;
-  PACKET pkt;
   PKT_public_key *psk;
-  PKT_signature *sig = NULL;
   u32 keyid[2];
-  iobuf_t out = NULL;
   kbnode_t keyblock = NULL;
   kbnode_t node;
   KEYDB_HANDLE kdbhd;
@@ -456,9 +523,6 @@ gen_revoke (const char *uname)
       return G10ERR_GENERAL;
     }
 
-  afx = new_armor_context ();
-  init_packet( &pkt );
-
   /* Search the userid; we don't want the whole getkey stuff here.  */
   kdbhd = keydb_new ();
   rc = classify_user_id (uname, &desc, 1);
@@ -518,44 +582,9 @@ gen_revoke (const char *uname)
   if (!opt.armor)
     tty_printf (_("ASCII armored output forced.\n"));
 
-  if ((rc = open_outfile (-1, NULL, 0, 1, &out )))
-    goto leave;
-
-  afx->what = 1;
-  afx->hdrlines = "Comment: A revocation certificate should follow\n";
-  push_armor_filter (afx, out);
-
-  /* create it */
-  rc = make_keysig_packet (&sig, psk, NULL, NULL, psk, 0x20, 0,
-                           opt.force_v4_certs?4:0, 0, 0,
-                           revocation_reason_build_cb, reason, NULL);
+  rc = create_revocation (NULL, reason, psk, keyblock);
   if (rc)
-    {
-      log_error (_("make_keysig_packet failed: %s\n"), g10_errstr (rc));
-      goto leave;
-    }
-
-  if (PGP2 || PGP6 || PGP7 || PGP8)
-    {
-      /* Use a minimal pk for PGPx mode, since PGP can't import bare
-         revocation certificates. */
-      rc = export_minimal_pk (out, keyblock, sig, NULL);
-      if(rc)
-        goto leave;
-    }
-  else
-    {
-      init_packet( &pkt );
-      pkt.pkttype = PKT_SIGNATURE;
-      pkt.pkt.signature = sig;
-
-      rc = build_packet (out, &pkt);
-      if (rc)
-        {
-          log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
-          goto leave;
-        }
-    }
+    goto leave;
 
   /* and issue a usage notice */
   tty_printf (_(
@@ -567,16 +596,9 @@ gen_revoke (const char *uname)
 "your machine might store the data and make it available to others!\n"));
 
  leave:
-  if (sig)
-    free_seckey_enc (sig);
   release_kbnode (keyblock);
   keydb_release (kdbhd);
-  if (rc)
-    iobuf_cancel(out);
-  else
-    iobuf_close(out);
   release_revocation_reason_info( reason );
-  release_armor_context (afx);
   return rc;
 }
 

-----------------------------------------------------------------------

Summary of changes:
 common/estream-printf.c   |    4 +-
 configure.ac              |    3 +-
 doc/gpg.texi              |    9 ++
 g10/keydb.h               |    1 +
 g10/keygen.c              |    2 +
 g10/keyid.c               |   14 ++++
 g10/main.h                |    2 +
 g10/openfile.c            |   28 ++++++-
 g10/passphrase.c          |    3 +-
 g10/revoke.c              |  204 +++++++++++++++++++++++++++++++++------------
 tests/openpgp/Makefile.am |    2 +-
 11 files changed, 215 insertions(+), 57 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list