annotate mod_cloud_notify_encrypted/mod_cloud_notify_encrypted.lua @ 4330:e655581173be

mod_cloud_notify_encrypted: Fixes to the push notification syntax and payload
author Matthew Wild <mwild1@gmail.com>
date Wed, 13 Jan 2021 14:18:24 +0000
parents 2a5164162708
children 2e355540f8c8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4327
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 local base64 = require "util.encodings".base64;
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2 local ciphers = require "openssl.cipher";
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 local jid = require "util.jid";
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4 local json = require "util.json";
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5 local random = require "util.random";
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6 local st = require "util.stanza";
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8 local xmlns_jmi = "urn:xmpp:jingle-message:0";
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9 local xmlns_push = "urn:xmpp:push:0";
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10 local xmlns_push_encrypt = "tigase:push:encrypt:0";
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
11 local xmlns_push_encrypt_aes_128_gcm = "tigase:push:encrypt:aes-128-gcm";
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
12
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
13 -- https://xeps.tigase.net//docs/push-notifications/encrypt/#41-discovering-support
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
14 local function account_disco_info(event)
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15 event.reply:tag("feature", {var=xmlns_push_encrypt}):up();
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
16 event.reply:tag("feature", {var=xmlns_push_encrypt_aes_128_gcm}):up();
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
17 end
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18 module:hook("account-disco-info", account_disco_info);
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20 function handle_register(event)
4329
2a5164162708 mod_cloud_notify_encrypted: Fix the location of the <encrypt> element in push registrations
Matthew Wild <mwild1@gmail.com>
parents: 4327
diff changeset
21 local encrypt = event.stanza:get_child("enable", xmlns_push):get_child("encrypt", xmlns_push_encrypt);
4327
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22 if not encrypt then return; end
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24 local algorithm = encrypt.attr.alg;
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25 if algorithm ~= "aes-128-gcm" then
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26 event.origin.send(st.error_reply(
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27 event.stanza, "modify", "feature-not-implemented", "Unknown encryption algorithm"
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28 ));
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29 return false;
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
30 end
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32 local key_base64 = encrypt:get_text();
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33 local key_binary = base64.decode(key_base64);
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
34 if not key_binary or #key_binary ~= 16 then
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35 event.origin.send(st.error_reply(
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 event.stanza, "modify", "bad-request", "Invalid encryption key"
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37 ));
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38 return false;
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39 end
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41 event.push_info.encryption = {
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42 algorithm = algorithm;
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 key_base64 = key_base64;
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44 };
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45 end
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 function handle_push(event)
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 local encryption = event.push_info.encryption;
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 if not encryption then return; end
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 if encryption.algorithm ~= "aes-128-gcm" then
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52 event.reason = "Unsupported encryption algorithm: "..tostring(encryption.algorithm);
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 return true;
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 end
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56 local push_summary = event.push_summary;
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58 local original_stanza = event.original_stanza;
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 local push_payload = {
4330
e655581173be mod_cloud_notify_encrypted: Fixes to the push notification syntax and payload
Matthew Wild <mwild1@gmail.com>
parents: 4329
diff changeset
61 unread = tonumber(push_summary["message-count"]) or 1;
e655581173be mod_cloud_notify_encrypted: Fixes to the push notification syntax and payload
Matthew Wild <mwild1@gmail.com>
parents: 4329
diff changeset
62 sender = jid.bare(original_stanza.attr.from);
e655581173be mod_cloud_notify_encrypted: Fixes to the push notification syntax and payload
Matthew Wild <mwild1@gmail.com>
parents: 4329
diff changeset
63 message = body;
4327
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64 };
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66 if original_stanza.name == "message" then
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67 if original_stanza.attr.type == "groupchat" then
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 push_payload.type = "groupchat";
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69 push_payload.nickname = jid.resource(original_stanza.attr.from);
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70 elseif original_stanza.attr.type ~= "error" then
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 local jmi_propose = original_stanza:get_child("propose", xmlns_jmi);
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 if jmi_propose then
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73 push_payload.type = "call";
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74 push_payload.sid = jmi_propose.attr.id;
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75 else
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76 push_payload.type = "chat";
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
77 end
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78 end
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79 elseif original_stanza.name == "presence"
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80 and original_stanza.attr.type == "subscribe" then
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81 push_payload.type = "subscribe";
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 end
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
83
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
84 local iv = random.bytes(12);
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
85 local key_binary = base64.decode(encryption.key_base64);
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
86 local push_json = json.encode(push_payload);
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
87
4330
e655581173be mod_cloud_notify_encrypted: Fixes to the push notification syntax and payload
Matthew Wild <mwild1@gmail.com>
parents: 4329
diff changeset
88 -- FIXME: luaossl does not expose the EVP_CTRL_GCM_GET_TAG API, so we append 16 NUL bytes
e655581173be mod_cloud_notify_encrypted: Fixes to the push notification syntax and payload
Matthew Wild <mwild1@gmail.com>
parents: 4329
diff changeset
89 -- Siskin does not validate the tag anyway.
e655581173be mod_cloud_notify_encrypted: Fixes to the push notification syntax and payload
Matthew Wild <mwild1@gmail.com>
parents: 4329
diff changeset
90 local encrypted_payload = base64.encode(ciphers.new("AES-128-GCM"):encrypt(key_binary, iv):final(push_json)..string.rep("\0", 16));
4327
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
91 local encrypted_element = st.stanza("encrypted", { xmlns = xmlns_push_encrypt, iv = base64.encode(iv) })
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
92 :text(encrypted_payload);
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93 -- Replace the unencrypted notification with the encrypted one
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94 event.notification_stanza
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95 :get_child("pubsub", "http://jabber.org/protocol/pubsub")
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96 :get_child("publish")
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97 :get_child("item")
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
98 :remove_children("notification", xmlns_push)
4330
e655581173be mod_cloud_notify_encrypted: Fixes to the push notification syntax and payload
Matthew Wild <mwild1@gmail.com>
parents: 4329
diff changeset
99 :tag("notification", { xmlns = xmlns_push })
e655581173be mod_cloud_notify_encrypted: Fixes to the push notification syntax and payload
Matthew Wild <mwild1@gmail.com>
parents: 4329
diff changeset
100 :add_child(encrypted_element)
e655581173be mod_cloud_notify_encrypted: Fixes to the push notification syntax and payload
Matthew Wild <mwild1@gmail.com>
parents: 4329
diff changeset
101 :up();
4327
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
102 end
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
103
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
104 module:hook("cloud_notify/registration", handle_register);
beb3342f1137 mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
105 module:hook("cloud_notify/push", handle_push);