summary refs log tree commit diff
path: root/gnu/packages/patches/geary-CVE-2020-24661.patch
blob: 6cbc224786e46af329a043bf6a8099f4c084d922 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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