[PATCH setup 0/3] setup.ini signing key rotation

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH setup 0/3] setup.ini signing key rotation

Jon TURNEY
Don't apply the patch [3/3], as that contains the pubkey from a random 3072D
key I generated to test this.

I'm not sure what best practice is for key generation at the moment.

Unfortunately, the existing code only handles DSA keys, which might conflict
with following that.

Jon Turney (3):
  Remove gpg-error-config-fake
  Restructure how we try keys in order for signature checking
  setup.ini signing key rotation

 crypto.cc             | 123 +++++++++++++++++++++++++-----------------
 cyg-old-pubkey.h      |  14 +++++
 cyg-pubkey.h          |  10 ++--
 cygwin-old.pub        | Bin 0 -> 964 bytes
 cygwin.pub            | Bin 964 -> 2248 bytes
 gpg-error-config-fake |  57 --------------------
 6 files changed, 93 insertions(+), 111 deletions(-)
 create mode 100644 cyg-old-pubkey.h
 create mode 100644 cygwin-old.pub
 delete mode 100755 gpg-error-config-fake

--
2.21.0

Reply | Threaded
Open this post in threaded view
|

[PATCH setup 1/3] Remove gpg-error-config-fake

Jon TURNEY
Unused since 1e0f90f9
---
 gpg-error-config-fake | 57 -------------------------------------------
 1 file changed, 57 deletions(-)
 delete mode 100755 gpg-error-config-fake

diff --git a/gpg-error-config-fake b/gpg-error-config-fake
deleted file mode 100755
index 7dcc92d..0000000
--- a/gpg-error-config-fake
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2008, Dave Korn.
-#
-#     This program is free software; you can redistribute it and/or modify
-#     it under the terms of the GNU General Public License as published by
-#     the Free Software Foundation; either version 2 of the License, or
-#     (at your option) any later version.
-#
-#     A copy of the GNU General Public License can be found at
-#     http://www.gnu.org/
-#
-# Written by Dave Korn <[hidden email]>
-#
-#
-# Fake gpg-error-config script redirects libgcrypt configure
-# process to look for our newly-built libgpg-error.  Crudely and
-# viciously hacked up by ripping the guts out of the original
-# until it does just enough to fool the libgcrypt configure
-# process into using our freshly-built libgpg-error for us.
-#
-
-output=""
-mydir=`dirname $0`
-while test $# -gt 0; do
-    case "$1" in
-        -*=*)
-            optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'`
-            ;;
-        *)
-            optarg=
-            ;;
-    esac
-
-    case $1 in
-        --version)
-            echo "1.6"
-            exit 0
-            ;;
-        --dir=*)
-            mydir="${1#--dir=}"
-            ;;
-        --cflags)
-            output="$output -I$mydir/./libgpg-error/src/"
-            ;;
-        --libs)
-            output="$output -L$mydir/./libgpg-error/src/.libs"
-            output="$output -lgpg-error"
-            ;;
-        *)
-            echo "What's a $1?"
-            ;;
-    esac
-    shift
-done
-
-echo $output
--
2.21.0

Reply | Threaded
Open this post in threaded view
|

[PATCH setup 2/3] Restructure how we try keys in order for signature checking

Jon TURNEY
In reply to this post by Jon TURNEY
Restructure how we try keys in order for signature checking, so we can
log which key signature was made by
---
 crypto.cc | 97 +++++++++++++++++++++++++++++--------------------------
 1 file changed, 51 insertions(+), 46 deletions(-)

diff --git a/crypto.cc b/crypto.cc
index 5a10e16..3720f01 100644
--- a/crypto.cc
+++ b/crypto.cc
@@ -431,17 +431,23 @@ add_key_from_sexpr (gcry_sexp_t key)
 bool
 verify_ini_file_sig (io_stream *ini_file, io_stream *ini_sig_file, HWND owner)
 {
-  /*  DSA public key in s-expr format.  */
-  gcry_sexp_t dsa_key;
-
   /*  Data returned from packet walker.  */
   struct sig_data sigdat;
 
-  /*  Vector of extra keys to use.  */
-  std::vector<gcry_sexp_t> keys_to_try;
+  /*  Vector of keys to use.  */
+  struct key_info
+  {
+    key_info(std::string _name, bool _builtin, gcry_sexp_t _key, bool _owned=FALSE) :
+      name(_name), builtin(_builtin), key(_key), owned(_owned)
+    {
+    }
 
-  /*  Vector of cached extra keys from last run.  */
-  static std::vector<gcry_sexp_t> input_keys;
+    std::string name;
+    bool builtin;  // if TRUE, we don't need to retain this key with add_key_from_sexpr()
+    gcry_sexp_t key;
+    bool owned;    // if TRUE, we own this key and should use gcry_sexp_release() on it
+  };
+  std::vector<struct key_info> keys_to_try;
 
   /*  Overall status of signature.  */
   bool sig_ok = false;
@@ -454,11 +460,16 @@ verify_ini_file_sig (io_stream *ini_file, io_stream *ini_sig_file, HWND owner)
   gcry_check_version (NULL);
 
   /* So first build the built-in key.  */
+  gcry_sexp_t dsa_key;
   rv = gcry_sexp_new (&dsa_key, cygwin_pubkey_sexpr, strlen (cygwin_pubkey_sexpr), 1);
   if (rv != GPG_ERR_NO_ERROR)
     {
       ERRKIND (owner, IDS_CRYPTO_ERROR, rv, "while creating pubkey s-expr.");
     }
+  else
+    {
+      keys_to_try.push_back (key_info("cygwin", TRUE, dsa_key));
+    }
 
 #if CRYPTODEBUGGING
   char sexprbuf[GPG_KEY_SEXPR_BUF_SIZE];
@@ -466,6 +477,10 @@ verify_ini_file_sig (io_stream *ini_file, io_stream *ini_sig_file, HWND owner)
   msg ("key:%d\n'%s'", n, sexprbuf);
 #endif /* CRYPTODEBUGGING */
 
+
+  /*  Vector of cached extra keys from last run.  */
+  static std::vector<gcry_sexp_t> input_keys;
+
   /* Next we should extract the keys from the extrakeys user
   setting, and flush it; we'll only return them to it if they
   get used.  OTOH, should we do this at all?  The user settings
@@ -504,6 +519,15 @@ verify_ini_file_sig (io_stream *ini_file, io_stream *ini_sig_file, HWND owner)
  }
     }
 
+  // We only use the untrusted keys if told to.
+  if (KeepUntrustedKeysOption || UntrustedKeysOption)
+    for (std::vector<gcry_sexp_t>::const_iterator it = input_keys.begin ();
+         it < input_keys.end ();
+         ++it)
+      {
+        keys_to_try.push_back (key_info ("saved key", FALSE, *it, FALSE));
+      }
+
   /* Next, there may have been command-line options. */
   std::vector<std::string> SexprExtraKeyStrings = SexprExtraKeyOption;
   for (std::vector<std::string>::const_iterator it
@@ -527,7 +551,7 @@ verify_ini_file_sig (io_stream *ini_file, io_stream *ini_sig_file, HWND owner)
   ExtraKeysSetting::instance().add_key (sexprbuf);
   msg ("key2:%d\n'%s'", n, sexprbuf);
 #endif /* CRYPTODEBUGGING */
-  keys_to_try.push_back (dsa_key2);
+  keys_to_try.push_back (key_info ("from command-line option --sexpr-pubkey", FALSE, dsa_key2));
  }
       else
  {
@@ -562,7 +586,7 @@ verify_ini_file_sig (io_stream *ini_file, io_stream *ini_sig_file, HWND owner)
       ExtraKeysSetting::instance().add_key (sexprbuf);
       msg ("key3:%d\n'%s'", n, sexprbuf);
 #endif /* CRYPTODEBUGGING */
-      keys_to_try.push_back (kdat.keys.back ());
+      keys_to_try.push_back (key_info ("from command-line option --pubkey", FALSE, kdat.keys.back ()));
       kdat.keys.pop_back ();
     }
  }
@@ -626,40 +650,22 @@ verify_ini_file_sig (io_stream *ini_file, io_stream *ini_sig_file, HWND owner)
       msg ("hash:%d\n'%s'", n, sexprbuf);
 #endif /* CRYPTODEBUGGING */
 
-      // Well, we're actually there!  Try it against the main key.
-      rv = gcry_pk_verify (dsa_sig, dsa_hash, dsa_key);
-      // If not that, try any supplied on the commandline.
-      if (rv != GPG_ERR_NO_ERROR)
- {
-  std::vector<gcry_sexp_t>::iterator it;
-  for (it = keys_to_try.begin (); it < keys_to_try.end (); ++it)
-    {
-      MESSAGE ("Testing a key to try\n");
-      rv = gcry_pk_verify (dsa_sig, dsa_hash, *it);
-      if (rv != GPG_ERR_NO_ERROR)
- continue;
-      // Found it!  This key gets kept!
-      add_key_from_sexpr (*it);
-      break;
-    }
-
-  // We only use the untrusted keys if told to.
-  it = ((rv != GPG_ERR_NO_ERROR)
-    && (KeepUntrustedKeysOption || UntrustedKeysOption))
- ? input_keys.begin ()
- : input_keys.end ();
-  for ( ; it < input_keys.end (); ++it)
-    {
-      MESSAGE ("Testing an input key\n");
-      rv = gcry_pk_verify (dsa_sig, dsa_hash, *it);
-      if (rv != GPG_ERR_NO_ERROR)
- continue;
-      // Found it!  This key gets kept!
-      add_key_from_sexpr (*it);
-      break;
-    }
- }
-
+      // Well, we're actually there!
+      // Try it against each key in turn
+
+      std::vector<key_info>::iterator it;
+      for (it = keys_to_try.begin (); it < keys_to_try.end (); ++it)
+        {
+          MESSAGE ("Trying key %s\n", it->name.c_str());
+          rv = gcry_pk_verify (dsa_sig, dsa_hash, it->key);
+          if (rv != GPG_ERR_NO_ERROR)
+            continue;
+          // Found it!  This key gets kept!
+          LogBabblePrintf("Valid signature by key %s", it->name.c_str());
+          if (!it->builtin)
+            add_key_from_sexpr (it->key);
+          break;
+        }
       sig_ok = (rv == GPG_ERR_NO_ERROR);
 
 #if CRYPTODEBUGGING
@@ -676,7 +682,6 @@ verify_ini_file_sig (io_stream *ini_file, io_stream *ini_sig_file, HWND owner)
     }
 
   // Discard the temp data then.
-  gcry_sexp_release (dsa_key);
   if (sigdat.dsa_mpi_r)
     gcry_mpi_release (sigdat.dsa_mpi_r);
   if (sigdat.dsa_mpi_s)
@@ -685,10 +690,10 @@ verify_ini_file_sig (io_stream *ini_file, io_stream *ini_sig_file, HWND owner)
     gcry_md_close (sigdat.md);
   while (keys_to_try.size ())
     {
-      gcry_sexp_release (keys_to_try.back ());
+      if (keys_to_try.back ().owned)
+        gcry_sexp_release (keys_to_try.back ().key);
       keys_to_try.pop_back ();
     }
 
   return sig_ok;
 }
-
--
2.21.0

Reply | Threaded
Open this post in threaded view
|

[PATCH setup 3/3] setup.ini signing key rotation

Jon TURNEY
In reply to this post by Jon TURNEY
Verify that signature using a new key, or the old key (unless the
--disable-old-keys option is used)

$ gpg -u<whatever> --export >cygwin.pub
$ ./gpg-key-to-s-expr.sh -C ./cygwin.pub >cyg-pubkey.h
---
 crypto.cc        |  30 +++++++++++++++++++++++++-----
 cyg-old-pubkey.h |  14 ++++++++++++++
 cyg-pubkey.h     |  10 +++++-----
 cygwin-old.pub   | Bin 0 -> 964 bytes
 cygwin.pub       | Bin 964 -> 2248 bytes
 5 files changed, 44 insertions(+), 10 deletions(-)
 create mode 100644 cyg-old-pubkey.h
 create mode 100644 cygwin-old.pub

diff --git a/crypto.cc b/crypto.cc
index 3720f01..d356398 100644
--- a/crypto.cc
+++ b/crypto.cc
@@ -51,12 +51,18 @@ static BoolOption UntrustedKeysOption (false, 'u', "untrusted-keys",
  "Use untrusted saved extra keys");
 static BoolOption KeepUntrustedKeysOption (false, 'U', "keep-untrusted-keys",
  "Use untrusted keys and retain all");
+static BoolOption DisableOldKeysOption (false, '\0', "disable-old-keys",
+                                        "Disable old cygwin.com keys");
 
 /*  Embedded public half of Cygwin DSA signing key.  */
-static const char *cygwin_pubkey_sexpr =
+static const char *cygwin_pubkey_sexpr =
 #include "cyg-pubkey.h"
 ;
 
+static const char *cygwin_old_pubkey_sexpr =
+#include "cyg-old-pubkey.h"
+;
+
 /*  S-expr template for DSA pubkey.  */
 static const char *dsa_pubkey_templ = "(public-key (dsa (p %m) (q %m) (g %m) (y %m)))";
 
@@ -460,23 +466,37 @@ verify_ini_file_sig (io_stream *ini_file, io_stream *ini_sig_file, HWND owner)
   gcry_check_version (NULL);
 
   /* So first build the built-in key.  */
-  gcry_sexp_t dsa_key;
-  rv = gcry_sexp_new (&dsa_key, cygwin_pubkey_sexpr, strlen (cygwin_pubkey_sexpr), 1);
+  gcry_sexp_t cygwin_key;
+  rv = gcry_sexp_new (&cygwin_key, cygwin_pubkey_sexpr, strlen (cygwin_pubkey_sexpr), 1);
   if (rv != GPG_ERR_NO_ERROR)
     {
       ERRKIND (owner, IDS_CRYPTO_ERROR, rv, "while creating pubkey s-expr.");
     }
   else
     {
-      keys_to_try.push_back (key_info("cygwin", TRUE, dsa_key));
+      keys_to_try.push_back (key_info("cygwin", TRUE, cygwin_key));
     }
 
 #if CRYPTODEBUGGING
   char sexprbuf[GPG_KEY_SEXPR_BUF_SIZE];
-  n = gcry_sexp_sprint (dsa_key, GCRYSEXP_FMT_ADVANCED, sexprbuf, GPG_KEY_SEXPR_BUF_SIZE);
+  n = gcry_sexp_sprint (cygwin_key, GCRYSEXP_FMT_ADVANCED, sexprbuf, GPG_KEY_SEXPR_BUF_SIZE);
   msg ("key:%d\n'%s'", n, sexprbuf);
 #endif /* CRYPTODEBUGGING */
 
+  /* If not disabled, also try the old built-in key */
+  gcry_sexp_t cygwin_old_key;
+  if (!DisableOldKeysOption)
+    {
+      rv = gcry_sexp_new (&cygwin_old_key, cygwin_old_pubkey_sexpr, strlen (cygwin_old_pubkey_sexpr), 1);
+      if (rv != GPG_ERR_NO_ERROR)
+        {
+          ERRKIND (owner, IDS_CRYPTO_ERROR, rv, "while creating old pubkey s-expr.");
+        }
+      else
+        {
+          keys_to_try.push_back (key_info ("cygwin-old", TRUE, cygwin_old_key));
+        }
+    }
 
   /*  Vector of cached extra keys from last run.  */
   static std::vector<gcry_sexp_t> input_keys;
diff --git a/cyg-old-pubkey.h b/cyg-old-pubkey.h
new file mode 100644
index 0000000..6d79544
--- /dev/null
+++ b/cyg-old-pubkey.h
@@ -0,0 +1,14 @@
+
+/* Autogenerated from: ./cygwin.pub
+ * by: ./gpg-key-to-s-expr.sh
+ * at: Mon Jun 16 02:20:11 2008 */
+
+"(public-key "
+    "(dsa "
+        "(p #00b96e7de7db21b47aa365a60fc3ec39195d07c550164dd43e2c2ff36c5ca21242403716c8937a70d80cc142cb73498820dc8a1269acfdb1b3815cdb93047262788fd5fdddb095e03b47bf6daa3b55d61a4c6bfd74096716265311617b304e09977ec178abd22cc8b06821475f9e8ba8bebcbe26458cbcc293022b07fc5f4a91cb#) "
+        "(q #00d65d896bdd4fb133ba8ad55400260cbca3450871#) "
+        "(g #17a7506fa4611721f581ee0f01bd2f19218304846743481948192c73181d90e5716051a15eae3dca9ada22acf2fbc010d31c196aa8f9fb91c9c190ebece5167dbd2281eb73130c336ed5a627d0f7537902a81230f3881642ac7b654d150da32f8b7535f7506b346f6688f0917b9863d901d7a8746366667b53ede51802ff02e1#) "
+        "(y #2592db6bb37125ce400e66dad3c22eed0899cd47cff95589d577adcd106c805e4feaada954a103be18d41f657254bc2a182218a71e1eefcdfa8c4f69758068b416e4942d7ddd6398ec9b455cbbe7fb5cb943a04babc75bc3602bfef500014030cf5ee649939e690c6d5341bbc0155f14eb059d088e61070709b037f02cccf137#)"
+    ")"
+")"
+
diff --git a/cyg-pubkey.h b/cyg-pubkey.h
index 6d79544..b399b46 100644
--- a/cyg-pubkey.h
+++ b/cyg-pubkey.h
@@ -1,14 +1,14 @@
 
 /* Autogenerated from: ./cygwin.pub
  * by: ./gpg-key-to-s-expr.sh
- * at: Mon Jun 16 02:20:11 2008 */
+ * at: 21 Feb 2020 18:21:44 */
 
 "(public-key "
     "(dsa "
-        "(p #00b96e7de7db21b47aa365a60fc3ec39195d07c550164dd43e2c2ff36c5ca21242403716c8937a70d80cc142cb73498820dc8a1269acfdb1b3815cdb93047262788fd5fdddb095e03b47bf6daa3b55d61a4c6bfd74096716265311617b304e09977ec178abd22cc8b06821475f9e8ba8bebcbe26458cbcc293022b07fc5f4a91cb#) "
-        "(q #00d65d896bdd4fb133ba8ad55400260cbca3450871#) "
-        "(g #17a7506fa4611721f581ee0f01bd2f19218304846743481948192c73181d90e5716051a15eae3dca9ada22acf2fbc010d31c196aa8f9fb91c9c190ebece5167dbd2281eb73130c336ed5a627d0f7537902a81230f3881642ac7b654d150da32f8b7535f7506b346f6688f0917b9863d901d7a8746366667b53ede51802ff02e1#) "
-        "(y #2592db6bb37125ce400e66dad3c22eed0899cd47cff95589d577adcd106c805e4feaada954a103be18d41f657254bc2a182218a71e1eefcdfa8c4f69758068b416e4942d7ddd6398ec9b455cbbe7fb5cb943a04babc75bc3602bfef500014030cf5ee649939e690c6d5341bbc0155f14eb059d088e61070709b037f02cccf137#)"
+        "(p #0095e219b21f4f0a9b3e269f58ab5c798fbab0ed74de2fa48520896567f206dc17e4784149da45ca99508e70ee5d7467acdf7f7732916b1aa45d8d075fbd6f7fb27bf918caacff54782526147439e9d9e657b9108ca50e1a196c79c4044bf46489351b80232fb607c6c1abf65e989fe7e8d08a0cbbf38d575bdfdbfb7496fd91c5ca745ab97c67a6ba49fca2b047dc39125ad241357b22626ba423bfe0cc611bf965edf87f22201df5c6e49d7b5ef1a336bc3c9b85f235c5478064ef49c8a52b96dc9d5655336b89a11de78ca2f70e2b4eae7c693c9cc3c4e01ef7d2a3d87dd616ee6979fe2a0877a8dc2704772cf0a3f4ab3f7869cc53f5524318e9e3369f8c460bd15169293702d29f9af1c972505700c71785eb9505be27871e7860f64a7df99da7401e63c94e79849542e76ca52915e4fb96483fad412dd81dedb85d41d822a81310f76b84c1d4aec2a41af9e032ef4f60e390588b72e0c639be660ec7367f471a1fa259046fcb801119231e91f6bbc249c2334dbd765e84da5e8199926873#) "
+        "(q #00df8be11219c6ebbca90bf1d6321214db2065f37f52022792af293e33c7e0c8b9#) "
+        "(g #4075a598e2a9aa622d6010ce18b34592f479479826f0c0c37fe2157b27f397b35f20909e74673e552da09872abc38ebe41c41be69aec846479bff451a5f7a8440e4f23c280a8fe3cd397d6ae022332a82b508b4c6d0631f204715b8477a2525a0b734b6d912cccc140f614bb64cb2444b539fd43b0d594fc03aee66890055f5cb39857d4f48d99a0f732fd8dd757ecdf6ebd0ba319fea64ee3b530ec56aea345517ff30e4372619cf1eeb381daeee6f0a2e17a41429fb0fa0378f7ba91820ff02ebb85f64b46160ea84a03c7309f37aad2475571a4df2e8077d18a4493b9f701b8f7329147b8dd6f2e2d669f2fb342bb6513c33740201a316edc3d814a47710df64b29b6f3f5a36a93f65f05d573c8dd8a96c1d556b29ff5724985bad23c272db1f4ec592ba769ed5b94f3e8e82f941f4fba148699f9aaeecd0628cd383252d36bc694b589161c2df2dfaf1049ddd56ab23813745d83e0221a03eddb8d39d000d4fa7f4059dca43fc107fd6564c5590587c87bb583d8a5f947819009bfcd3728#) "
+        "(y #00835f79a9e8260abbe2b723f7981dfd90b210fd661f148ec38bc0707473b9447dd3c55b2a47f8782bfc085e99fa124b70152d4fb8f8f4d93393004d333c661d58d53ee6c14c61c68880e9d7057dd02e10a6c3a3aa9a73db108047048b2e454d85599cd3e4217878800482d57366e693e3f63827fc7ce47cc9cb2ff58295311003d69809974ca42f7f307d27bfa414f91a5f47b6f9e71d434d312646d324cc0e1dc9167efa3bff98f6252b0da587373c7c157426521094afe23ab792b011dcfdb03a0e6924c66e51ad09ffe616c311ac8e1b2884eb4f6415b59e56868988f1809f5831da13d16f416f0e526275653846ce2d324e7c411a52b0e7dac4124077c6c00872251178b0944e0f1693472127234b9de24cff4ffd5892fd3847c86ef7d012af2b01d84cdbaf6f80c660dcd802942e8c89523325464bb3bdcb89dbeb721c6116d81196cdeafce8c6dec4f84acf5bce068d1010bfd903e0102a712097a3c557220e03eae5e08ec7ddf847c46c79011e088431ccf74665f31728d0846df4ce5e#)"
     ")"
 ")"
 
diff --git a/cygwin-old.pub b/cygwin-old.pub
new file mode 100644
index 0000000000000000000000000000000000000000..8372e5fd2ed9388910d9a685bac9066a74a147e4
GIT binary patch
literal 964
zcmV;#13Ubg0ipy*Qu=QZ1OT~iedpUDw0fgurVqpHIT>9C#ZVSa)IKaP^K4wA5<);X
z7RZx&aM%pNLd$bWh#=gG5^1dcv9p0(+mi%xVt9|${oSyY;5$dZZK^v})*4J}{d5Uu
z7A8{>VS6x6373Asc&pMZ$gpT3M_-<csJ^_uCPj?A!jl3k2mD`3k;?#})?JBf-A}PI
zx{B3Q045B)qeTdD1N|4LP;aDR7a{e5?hgUIFBu_&1cYZpNEt{OEOQtgkmYe;QK4S0
zJ<6KeBCPWJz!1|M8EUBc`;p1Pkn8N_7Ja=Uf$MV<3^Q)krYF$%Q+WcY5-{_K7DB9h
zWla?gqc4kfHTO_!G;d~z@R56%W7z@MsB~jyW_wfZ<ro700^tMxC6e1~vvDQPKn`Zw
z)50$82${`C&-qn})pxDU5Nv>6PwK6yRG|aD7}OtSa#Xx37$O*_9v<(_`ixI$b%1EJ
z7UYyIecfZ2?3+bgyXX5{xkI2!tH)czU@QLh00BTS&tB$9lb&e|ZBs$Jz!hH<>jj+%
zj$sD}39vWtEX?sYv>HQsXLo6CAUtDvXLo6CKx27lcWG`eV{dIfh+YH}5dr`n1p-J?
z`fmao0|pBT2nPcK0~G=T0~P`S0v-VZ7k~f?2@t8GV*h7gLArMt0HCIQ1hz!yCG>w4
zXsMkr;D45bQ7-_WPOM*BqWX#Xb+|kzAIp5)^kb0~h(-hu5dr`P1p-J?{-^*72@p-v
zg5_#Bj6Pxh0HDFX0LaEg_&lK)Iz{Wi_#7x_N236s>e~j`8l&CBq@aYJ?fuE-|2uzA
zxd9CXNK*Q65Ci~<oWo1psnqYf=_cxkky9BE{yNY5j5ZX~gezMZ8=stS1#5qD5=~0m
zO%~PMT=|}tpTVNdl!YTzfPn>K_&((=FNXrIX74d}n@NZB+NeKjs<8JHTHtR+3DJ0u
z&<JIveCa{Nlr3;%0n@y}9e{g0dQW6;n!^kzRD&Ttopd_@0|f*AD_*Xw!5=37Q@ouR
z4U+)xYR$uKLx^^UC=~k5?d^*O<`xt%emi0mpQ}KCctggV&i4E{@lIO*J#(9_%YWRP
z95r}zbZUw1uG)s)u02XAD`%f>%9LTR6^~?D?^Y@wnK#`(qNPR!K0cwjlZyo=RFV|S
zi_&B`!qHlp9K2mPh)Dz(5dr`S1p-J?`fvgp3;+rV5UHYK|7T!9x_aOMo+)TpDVR#0
m6f7ayxI-JFleUamZ~&mNmhA<x_YVJWfUWBc>$pNo3{d(WT&$b`

literal 0
HcmV?d00001

diff --git a/cygwin.pub b/cygwin.pub
index 8372e5fd2ed9388910d9a685bac9066a74a147e4..f0167d25e62aa16913479cc8c22f9da753c1118a 100644
GIT binary patch
literal 2248
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
WLsc>q&!Rd`=RFUh(Y@J6=meiScrxGs

literal 964
zcmV;#13Ubg0ipy*Qu=QZ1OT~iedpUDw0fgurVqpHIT>9C#ZVSa)IKaP^K4wA5<);X
z7RZx&aM%pNLd$bWh#=gG5^1dcv9p0(+mi%xVt9|${oSyY;5$dZZK^v})*4J}{d5Uu
z7A8{>VS6x6373Asc&pMZ$gpT3M_-<csJ^_uCPj?A!jl3k2mD`3k;?#})?JBf-A}PI
zx{B3Q045B)qeTdD1N|4LP;aDR7a{e5?hgUIFBu_&1cYZpNEt{OEOQtgkmYe;QK4S0
zJ<6KeBCPWJz!1|M8EUBc`;p1Pkn8N_7Ja=Uf$MV<3^Q)krYF$%Q+WcY5-{_K7DB9h
zWla?gqc4kfHTO_!G;d~z@R56%W7z@MsB~jyW_wfZ<ro700^tMxC6e1~vvDQPKn`Zw
z)50$82${`C&-qn})pxDU5Nv>6PwK6yRG|aD7}OtSa#Xx37$O*_9v<(_`ixI$b%1EJ
z7UYyIecfZ2?3+bgyXX5{xkI2!tH)czU@QLh00BTS&tB$9lb&e|ZBs$Jz!hH<>jj+%
zj$sD}39vWtEX?sYv>HQsXLo6CAUtDvXLo6CKx27lcWG`eV{dIfh+YH}5dr`n1p-J?
z`fmao0|pBT2nPcK0~G=T0~P`S0v-VZ7k~f?2@t8GV*h7gLArMt0HCIQ1hz!yCG>w4
zXsMkr;D45bQ7-_WPOM*BqWX#Xb+|kzAIp5)^kb0~h(-hu5dr`P1p-J?{-^*72@p-v
zg5_#Bj6Pxh0HDFX0LaEg_&lK)Iz{Wi_#7x_N236s>e~j`8l&CBq@aYJ?fuE-|2uzA
zxd9CXNK*Q65Ci~<oWo1psnqYf=_cxkky9BE{yNY5j5ZX~gezMZ8=stS1#5qD5=~0m
zO%~PMT=|}tpTVNdl!YTzfPn>K_&((=FNXrIX74d}n@NZB+NeKjs<8JHTHtR+3DJ0u
z&<JIveCa{Nlr3;%0n@y}9e{g0dQW6;n!^kzRD&Ttopd_@0|f*AD_*Xw!5=37Q@ouR
z4U+)xYR$uKLx^^UC=~k5?d^*O<`xt%emi0mpQ}KCctggV&i4E{@lIO*J#(9_%YWRP
z95r}zbZUw1uG)s)u02XAD`%f>%9LTR6^~?D?^Y@wnK#`(qNPR!K0cwjlZyo=RFV|S
zi_&B`!qHlp9K2mPh)Dz(5dr`S1p-J?`fvgp3;+rV5UHYK|7T!9x_aOMo+)TpDVR#0
m6f7ayxI-JFleUamZ~&mNmhA<x_YVJWfUWBc>$pNo3{d(WT&$b`

--
2.21.0