summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--gnu/local.mk1
-rw-r--r--gnu/packages/gnome.scm3
-rw-r--r--gnu/packages/patches/geary-CVE-2020-24661.patch133
3 files changed, 136 insertions, 1 deletions
diff --git a/gnu/local.mk b/gnu/local.mk
index eae602a01e..a68981e48d 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1057,6 +1057,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/gd-fix-tests-on-i686.patch		\
   %D%/packages/patches/gd-brect-bounds.patch			\
   %D%/packages/patches/gdm-default-session.patch		\
+  %D%/packages/patches/geary-CVE-2020-24661.patch		\
   %D%/packages/patches/genimage-signedness.patch		\
   %D%/packages/patches/geoclue-config.patch			\
   %D%/packages/patches/ghc-8.0-fall-back-to-madv_dontneed.patch	\
diff --git a/gnu/packages/gnome.scm b/gnu/packages/gnome.scm
index 50edf9ebd9..d58aa9956b 100644
--- a/gnu/packages/gnome.scm
+++ b/gnu/packages/gnome.scm
@@ -11339,7 +11339,8 @@ these services on the Guix System.")
               (file-name (git-file-name name version))
               (sha256
                (base32
-                "01cc921kyh3zxz07biqbdzkjgmdcc36kwjyajm4y382a75cl5zg7"))))
+                "01cc921kyh3zxz07biqbdzkjgmdcc36kwjyajm4y382a75cl5zg7"))
+              (patches (search-patches "geary-CVE-2020-24661.patch"))))
     (build-system meson-build-system)
     (arguments
      `(#:glib-or-gtk? #t
diff --git a/gnu/packages/patches/geary-CVE-2020-24661.patch b/gnu/packages/patches/geary-CVE-2020-24661.patch
new file mode 100644
index 0000000000..6cbc224786
--- /dev/null
+++ b/gnu/packages/patches/geary-CVE-2020-24661.patch
@@ -0,0 +1,133 @@
+From d4e86dc91e1d8a940dc40872fe94ef9ac0fed1b5 Mon Sep 17 00:00:00 2001
+From: Michael Gratton <mike@vee.net>
+Date: Tue, 25 Aug 2020 03:54:09 +0000
+Subject: [PATCH] Merge branch 'mjog/866-self-signed-certificates' into
+ 'mainline'
+
+Fix invalid certificate pinning when GCR support is unavailable
+
+Closes #866
+
+See merge request GNOME/geary!529
+
+(cherry picked from commit 423a55b00f1dc6bee9dc17e67c0aea6f42387a77)
+
+5088adfe Application.CertificateManager: Rename some methods for clarity
+0d957559 Application.CertificateManager: Check locally pinned certs for equality
+---
+ .../application-certificate-manager.vala      | 44 +++++++++----------
+ 1 file changed, 22 insertions(+), 22 deletions(-)
+
+diff --git a/src/client/application/application-certificate-manager.vala b/src/client/application/application-certificate-manager.vala
+index 4881d73c0..65f6af4fa 100644
+--- a/src/client/application/application-certificate-manager.vala
++++ b/src/client/application/application-certificate-manager.vala
+@@ -381,8 +381,8 @@ private class Application.TlsDatabase : GLib.TlsDatabase {
+         GLib.TlsCertificateFlags ret = this.parent.verify_chain(
+             chain, purpose, identity, interaction, flags, cancellable
+         );
+-        if (should_verify(ret, purpose, identity) &&
+-            verify(chain, identity, cancellable)) {
++        if (check_pinned(ret, purpose, identity) &&
++            is_pinned(chain, identity, cancellable)) {
+             ret = 0;
+         }
+         return ret;
+@@ -399,16 +399,16 @@ private class Application.TlsDatabase : GLib.TlsDatabase {
+         GLib.TlsCertificateFlags ret = yield this.parent.verify_chain_async(
+             chain, purpose, identity, interaction, flags, cancellable
+         );
+-        if (should_verify(ret, purpose, identity) &&
+-            yield verify_async(chain, identity, cancellable)) {
++        if (check_pinned(ret, purpose, identity) &&
++            yield is_pinned_async(chain, identity, cancellable)) {
+             ret = 0;
+         }
+         return ret;
+     }
+ 
+-    private inline bool should_verify(GLib.TlsCertificateFlags parent_ret,
+-                                      string purpose,
+-                                      GLib.SocketConnectable? identity) {
++    private inline bool check_pinned(GLib.TlsCertificateFlags parent_ret,
++                                     string purpose,
++                                     GLib.SocketConnectable? identity) {
+         // If the parent didn't verify, check for a locally pinned
+         // cert if it looks like we should, but always reject revoked
+         // certs
+@@ -420,22 +420,22 @@ private class Application.TlsDatabase : GLib.TlsDatabase {
+         );
+     }
+ 
+-    private bool verify(GLib.TlsCertificate chain,
+-                        GLib.SocketConnectable identity,
+-                        GLib.Cancellable? cancellable)
++    private bool is_pinned(GLib.TlsCertificate chain,
++                           GLib.SocketConnectable identity,
++                           GLib.Cancellable? cancellable)
+         throws GLib.Error {
+-        bool is_verified = false;
++        bool is_pinned = false;
+         string id = to_name(identity);
+         TrustContext? context = null;
+         lock (this.pinned_certs) {
+             context = this.pinned_certs.get(id);
+             if (context != null) {
+-                is_verified = true;
++                is_pinned = context.certificate.is_same(chain);
+             } else {
+                 // Cert not found in memory, check with GCR if
+                 // enabled.
+                 if (this.use_gcr) {
+-                    is_verified = gcr_trust_is_certificate_pinned(
++                    is_pinned = gcr_trust_is_certificate_pinned(
+                         new Gcr.SimpleCertificate(chain.certificate.data),
+                         GLib.TlsDatabase.PURPOSE_AUTHENTICATE_SERVER,
+                         id,
+@@ -443,7 +443,7 @@ private class Application.TlsDatabase : GLib.TlsDatabase {
+                     );
+                 }
+ 
+-                if (!is_verified) {
++                if (!is_pinned) {
+                     // Cert is not pinned in memory or in GCR, so look
+                     // for it on disk. Do this even if GCR support is
+                     // enabled, since if the cert was previously saved
+@@ -453,7 +453,7 @@ private class Application.TlsDatabase : GLib.TlsDatabase {
+                             this.store_dir, id, cancellable
+                         );
+                         this.pinned_certs.set(id, context);
+-                        is_verified = true;
++                        is_pinned = context.certificate.is_same(chain);
+                     } catch (GLib.IOError.NOT_FOUND err) {
+                         // Cert was not found saved, so it not pinned
+                     } catch (GLib.Error err) {
+@@ -465,18 +465,18 @@ private class Application.TlsDatabase : GLib.TlsDatabase {
+                 }
+             }
+         }
+-        return is_verified;
++        return is_pinned;
+     }
+ 
+-    private async bool verify_async(GLib.TlsCertificate chain,
+-                                    GLib.SocketConnectable identity,
+-                                    GLib.Cancellable? cancellable)
++    private async bool is_pinned_async(GLib.TlsCertificate chain,
++                                       GLib.SocketConnectable identity,
++                                       GLib.Cancellable? cancellable)
+         throws GLib.Error {
+-        bool is_valid = false;
++        bool pinned = false;
+         yield Geary.Nonblocking.Concurrent.global.schedule_async(() => {
+-                is_valid = verify(chain, identity, cancellable);
++                pinned = is_pinned(chain, identity, cancellable);
+             }, cancellable);
+-        return is_valid;
++        return pinned;
+     }
+ 
+     private TrustContext? lookup_id(string id) {
+-- 
+GitLab
+