Commit | Line | Data |
---|---|---|
1acfda2f LLB |
1 | From d4e86dc91e1d8a940dc40872fe94ef9ac0fed1b5 Mon Sep 17 00:00:00 2001 |
2 | From: Michael Gratton <mike@vee.net> | |
3 | Date: Tue, 25 Aug 2020 03:54:09 +0000 | |
4 | Subject: [PATCH] Merge branch 'mjog/866-self-signed-certificates' into | |
5 | 'mainline' | |
6 | ||
7 | Fix invalid certificate pinning when GCR support is unavailable | |
8 | ||
9 | Closes #866 | |
10 | ||
11 | See merge request GNOME/geary!529 | |
12 | ||
13 | (cherry picked from commit 423a55b00f1dc6bee9dc17e67c0aea6f42387a77) | |
14 | ||
15 | 5088adfe Application.CertificateManager: Rename some methods for clarity | |
16 | 0d957559 Application.CertificateManager: Check locally pinned certs for equality | |
17 | --- | |
18 | .../application-certificate-manager.vala | 44 +++++++++---------- | |
19 | 1 file changed, 22 insertions(+), 22 deletions(-) | |
20 | ||
21 | diff --git a/src/client/application/application-certificate-manager.vala b/src/client/application/application-certificate-manager.vala | |
22 | index 4881d73c0..65f6af4fa 100644 | |
23 | --- a/src/client/application/application-certificate-manager.vala | |
24 | +++ b/src/client/application/application-certificate-manager.vala | |
25 | @@ -381,8 +381,8 @@ private class Application.TlsDatabase : GLib.TlsDatabase { | |
26 | GLib.TlsCertificateFlags ret = this.parent.verify_chain( | |
27 | chain, purpose, identity, interaction, flags, cancellable | |
28 | ); | |
29 | - if (should_verify(ret, purpose, identity) && | |
30 | - verify(chain, identity, cancellable)) { | |
31 | + if (check_pinned(ret, purpose, identity) && | |
32 | + is_pinned(chain, identity, cancellable)) { | |
33 | ret = 0; | |
34 | } | |
35 | return ret; | |
36 | @@ -399,16 +399,16 @@ private class Application.TlsDatabase : GLib.TlsDatabase { | |
37 | GLib.TlsCertificateFlags ret = yield this.parent.verify_chain_async( | |
38 | chain, purpose, identity, interaction, flags, cancellable | |
39 | ); | |
40 | - if (should_verify(ret, purpose, identity) && | |
41 | - yield verify_async(chain, identity, cancellable)) { | |
42 | + if (check_pinned(ret, purpose, identity) && | |
43 | + yield is_pinned_async(chain, identity, cancellable)) { | |
44 | ret = 0; | |
45 | } | |
46 | return ret; | |
47 | } | |
48 | ||
49 | - private inline bool should_verify(GLib.TlsCertificateFlags parent_ret, | |
50 | - string purpose, | |
51 | - GLib.SocketConnectable? identity) { | |
52 | + private inline bool check_pinned(GLib.TlsCertificateFlags parent_ret, | |
53 | + string purpose, | |
54 | + GLib.SocketConnectable? identity) { | |
55 | // If the parent didn't verify, check for a locally pinned | |
56 | // cert if it looks like we should, but always reject revoked | |
57 | // certs | |
58 | @@ -420,22 +420,22 @@ private class Application.TlsDatabase : GLib.TlsDatabase { | |
59 | ); | |
60 | } | |
61 | ||
62 | - private bool verify(GLib.TlsCertificate chain, | |
63 | - GLib.SocketConnectable identity, | |
64 | - GLib.Cancellable? cancellable) | |
65 | + private bool is_pinned(GLib.TlsCertificate chain, | |
66 | + GLib.SocketConnectable identity, | |
67 | + GLib.Cancellable? cancellable) | |
68 | throws GLib.Error { | |
69 | - bool is_verified = false; | |
70 | + bool is_pinned = false; | |
71 | string id = to_name(identity); | |
72 | TrustContext? context = null; | |
73 | lock (this.pinned_certs) { | |
74 | context = this.pinned_certs.get(id); | |
75 | if (context != null) { | |
76 | - is_verified = true; | |
77 | + is_pinned = context.certificate.is_same(chain); | |
78 | } else { | |
79 | // Cert not found in memory, check with GCR if | |
80 | // enabled. | |
81 | if (this.use_gcr) { | |
82 | - is_verified = gcr_trust_is_certificate_pinned( | |
83 | + is_pinned = gcr_trust_is_certificate_pinned( | |
84 | new Gcr.SimpleCertificate(chain.certificate.data), | |
85 | GLib.TlsDatabase.PURPOSE_AUTHENTICATE_SERVER, | |
86 | id, | |
87 | @@ -443,7 +443,7 @@ private class Application.TlsDatabase : GLib.TlsDatabase { | |
88 | ); | |
89 | } | |
90 | ||
91 | - if (!is_verified) { | |
92 | + if (!is_pinned) { | |
93 | // Cert is not pinned in memory or in GCR, so look | |
94 | // for it on disk. Do this even if GCR support is | |
95 | // enabled, since if the cert was previously saved | |
96 | @@ -453,7 +453,7 @@ private class Application.TlsDatabase : GLib.TlsDatabase { | |
97 | this.store_dir, id, cancellable | |
98 | ); | |
99 | this.pinned_certs.set(id, context); | |
100 | - is_verified = true; | |
101 | + is_pinned = context.certificate.is_same(chain); | |
102 | } catch (GLib.IOError.NOT_FOUND err) { | |
103 | // Cert was not found saved, so it not pinned | |
104 | } catch (GLib.Error err) { | |
105 | @@ -465,18 +465,18 @@ private class Application.TlsDatabase : GLib.TlsDatabase { | |
106 | } | |
107 | } | |
108 | } | |
109 | - return is_verified; | |
110 | + return is_pinned; | |
111 | } | |
112 | ||
113 | - private async bool verify_async(GLib.TlsCertificate chain, | |
114 | - GLib.SocketConnectable identity, | |
115 | - GLib.Cancellable? cancellable) | |
116 | + private async bool is_pinned_async(GLib.TlsCertificate chain, | |
117 | + GLib.SocketConnectable identity, | |
118 | + GLib.Cancellable? cancellable) | |
119 | throws GLib.Error { | |
120 | - bool is_valid = false; | |
121 | + bool pinned = false; | |
122 | yield Geary.Nonblocking.Concurrent.global.schedule_async(() => { | |
123 | - is_valid = verify(chain, identity, cancellable); | |
124 | + pinned = is_pinned(chain, identity, cancellable); | |
125 | }, cancellable); | |
126 | - return is_valid; | |
127 | + return pinned; | |
128 | } | |
129 | ||
130 | private TrustContext? lookup_id(string id) { | |
131 | -- | |
132 | GitLab | |
133 |